From 3c852eb0fad9bdb6082370cc9d1ef119157f77c7 Mon Sep 17 00:00:00 2001 From: Gabriel Bizdoc Date: Tue, 9 Dec 2025 01:50:24 +0200 Subject: [PATCH] include tests --- year25/tests/.gitignore | 2 + year25/tests/bench_test.go | 43 +++++++ year25/tests/main_test.go | 251 +++++++++++++++++++++++++++++++++++++ year25/tests/utils_test.go | 82 ++++++++++++ 4 files changed, 378 insertions(+) create mode 100644 year25/tests/.gitignore create mode 100644 year25/tests/bench_test.go create mode 100644 year25/tests/main_test.go create mode 100644 year25/tests/utils_test.go diff --git a/year25/tests/.gitignore b/year25/tests/.gitignore new file mode 100644 index 0000000..83cb173 --- /dev/null +++ b/year25/tests/.gitignore @@ -0,0 +1,2 @@ +data +main.go \ No newline at end of file diff --git a/year25/tests/bench_test.go b/year25/tests/bench_test.go new file mode 100644 index 0000000..8d57650 --- /dev/null +++ b/year25/tests/bench_test.go @@ -0,0 +1,43 @@ +package main_test + +import ( + "bytes" + "io" + "testing" + + "git.bizdoc.ro/gabi-public/Advent-of-Code.git/aoc" + "git.bizdoc.ro/gabi-public/Advent-of-Code.git/year25" +) + +func BenchmarkDay(b *testing.B) { + var tests = []TestCase{ + { + Name: "Day1 Part 2 slow", + File: "day1", + Want: 6858, + Handler: year25.Day1Part2Slow, + }, + { + Name: "Day1 Part 2 fast", + File: "day1", + Want: 6858, + Handler: year25.Day1Part2Fast, + }, + } + buff, _ := io.ReadAll(getInput("day1")) + r := bytes.NewReader(buff) + r.Reset(buff) + + ctx := aoc.Context{Body: r} + for _, test := range tests { + b.Run(test.Name, func(b *testing.B) { + for b.Loop() { + r.Reset(buff) + if test.Handler == nil { + b.Fatalf("%s handler is nil", test.Name) + } + _, _ = test.Handler(ctx) + } + }) + } +} diff --git a/year25/tests/main_test.go b/year25/tests/main_test.go new file mode 100644 index 0000000..4fa81d1 --- /dev/null +++ b/year25/tests/main_test.go @@ -0,0 +1,251 @@ +package main_test + +import ( + "testing" + + "git.bizdoc.ro/gabi-public/Advent-of-Code.git/aoc" + "git.bizdoc.ro/gabi-public/Advent-of-Code.git/year25" +) + +func TestDays(t *testing.T) { + logger := DiscardLogger + //logger := DefaultLogger + //var skipExperiments = true + //const skipExperiments = false + + var tests = []TestCase{ + { + Name: "Day1 Part 1 example", + File: "day01_example", + Want: 3, + Handler: year25.Day1Part1, + }, + { + Name: "Day1 Part 1", + File: "day01", + Want: 1191, + Handler: year25.Day1Part1, + }, + { + Name: "Day1 Part 2 example", + File: "day01_example", + Want: 6, + Handler: year25.Day1Part2Slow, + }, + { + Name: "Day1 Part 2", + File: "day01", + Want: 6858, + Handler: year25.Day1Part2Slow, + }, + { + Name: "Day1 Part 2 example", + File: "day01_example", + Want: 6, + Handler: year25.Day1Part2Fast, + }, + { + Name: "Day1 Part 2", + File: "day01", + Want: 6858, + Handler: year25.Day1Part2Fast, + }, + { + Name: "Day2 Part 1 Example", + File: "day02_example", + Want: 1227775554, + Handler: year25.Day2Part1, + }, + { + Name: "Day2 Part 1", + File: "day02", + Want: 31839939622, + Handler: year25.Day2Part1, + }, + { + Name: "Day2 Part 2 Example", + File: "day02_example", + Want: 4174379265, + Handler: year25.Day2Part2, + }, + { + Name: "Day2 Part 2", + File: "day02", + Want: 41662374059, + Handler: year25.Day2Part2, + }, + { + Name: "Day2 Part 1 Simple Version", + File: "day02", + Want: 31839939622, + Handler: year25.Day2Part1Simple, + }, + { + Name: "Day2 Part 2 Simple Version", + File: "day02", + Want: 41662374059, + Handler: year25.Day2Part2Simple, + }, + + { + Name: "Day3 Part 1 Example", + File: "day03_example", + Want: 357, + Handler: year25.Day3Part1, + }, + { + Name: "Day3 Part 1", + File: "day03", + Want: 17427, + Handler: year25.Day3Part1, + }, + + { + Name: "Day3 Part 2 Example", + File: "day03_example", + Want: 3121910778619, + Handler: year25.Day3Part2, + }, + { + Name: "Day3 Part 2", + File: "day03", + Want: 173161749617495, + Handler: year25.Day3Part2, + }, + { + Name: "Day3 Part 2 Compact", + File: "day03_example", + Want: 3121910778619, + Handler: func(ctx aoc.Context) (any, error) { + s, _ := ctx.BodyString() + return year25.Day3Compact(s, 12) + }, + }, + + { + Name: "Day4 Part 1 Example", + File: "day04_example", + Want: 13, + Handler: year25.Day4Part1, + }, + { + Name: "Day4 Part 1", + File: "day04", + Want: 1445, + Handler: year25.Day4Part1, + }, + + { + Name: "Day4 Part 2 Example", + File: "day04_example", + Want: 43, + Handler: year25.Day4Part2, + }, + { + Name: "Day4 Part 2", + File: "day04", + Want: 8317, + Handler: year25.Day4Part2, + }, + { + Name: "Day5 Part 1 Example", + File: "day05_example", + Want: 3, + Handler: handler(year25.Day5Part1), + }, + { + Name: "Day5 Part 1", + File: "day05", + Want: 775, + Handler: handler(year25.Day5Part1), + }, + { + Name: "Day5 Part 2 Example", + File: "day05_example", + Want: 14, + Handler: handler(year25.Day5Part2), + }, + { + Name: "Day5 Part 2", + File: "day05", + Want: 350684792662845, + Handler: handler(year25.Day5Part2), + }, + { + Name: "Day6 Part 1 Example", + File: "day06_example", + Want: 4277556, + Handler: handler(year25.Day6Part1), + }, + { + Name: "Day6 Part 1", + File: "day06", + Want: 4412382293768, + Handler: handler(year25.Day6Part1), + }, + { + Name: "Day6 Part 2 Example", + File: "day06_example", + Want: 3263827, + Handler: handler(year25.Day6Part2), + }, + { + Name: "Day6 Part 2", + File: "day06", + Want: 7858808482092, + Handler: handler(year25.Day6Part2), + }, + + { + Name: "Day7 Part 1 Example", + File: "day07_example", + Want: 21, + Handler: handler(year25.Day7Part1), + }, + { + Name: "Day7 Part 1", + File: "day07", + Want: 1672, + Handler: handler(year25.Day7Part1), + }, + { + Name: "Day7 Part 2 Example", + File: "day07_example", + Want: 40, + Handler: handler(year25.Day7Part2), + }, + { + Name: "Day7 Part 2", + File: "day07", + Want: 231229866702355, + Handler: handler(year25.Day7Part2), + }, + + { + Name: "Day8 Part 1 Example", + File: "day08_example", + Want: 40, + Handler: handler2(10, year25.Day8Part1), + }, + { + Name: "Day8 Part 1", + File: "day08", + Want: 54180, + Handler: handler2(1_000, year25.Day8Part1), + }, + { + Name: "Day8 Part 2 Example", + File: "day08_example", + Want: 25272, + Handler: handler(year25.Day8Part2), + }, + { + Name: "Day8 Part 2", + File: "day08", + Want: 25325968, + Handler: handler(year25.Day8Part2), + }, + } + + runTestCase(t, tests, logger) +} diff --git a/year25/tests/utils_test.go b/year25/tests/utils_test.go new file mode 100644 index 0000000..b353767 --- /dev/null +++ b/year25/tests/utils_test.go @@ -0,0 +1,82 @@ +package main_test + +import ( + "bytes" + "fmt" + "io" + "log" + "os" + "testing" + "time" + + "git.bizdoc.ro/gabi-public/Advent-of-Code.git/aoc" +) + +func getInput(name string) io.Reader { + name = fmt.Sprintf("./data/%s.txt", name) + input, err := os.ReadFile(name) + if err != nil { + panic(err) + } + return bytes.NewReader(input) +} + +func assert(t *testing.T, err error, a, b any) { + t.Helper() + + if err != nil { + t.Error(err) + } + want := fmt.Sprintf("%v", a) + got := fmt.Sprintf("%v", b) + if got != want { + err = fmt.Errorf("want %s, got %s", want, got) + t.Error(err) + } +} + +type TestCase struct { + Name string + File string + Want any + Handler func(ctx aoc.Context) (any, error) +} + +var StderrLogger = log.New(os.Stderr, "", 0) +var DiscardLogger = log.New(io.Discard, "", 0) + +func handler[T any](f func(ctx aoc.Context) (T, error)) func(ctx aoc.Context) (any, error) { + return func(c aoc.Context) (any, error) { + return f(c) + } +} + +func handler2[T any, K any](param T, f func(ctx aoc.Context, param T) (K, error)) func(ctx aoc.Context) (any, error) { + return func(c aoc.Context) (any, error) { + return f(c, param) + } +} + +func runTestCase(t *testing.T, cases []TestCase, l *log.Logger) { + t.Helper() + var totalTime time.Duration + defer func() { + t.Log("Total time:", totalTime.String()) + }() + for _, test := range cases { + t.Run(test.Name, func(t *testing.T) { + start := time.Now() + defer func() { + end := time.Since(start) + t.Log("elapsed:", end) + totalTime += end + }() + input := getInput(test.File) + if test.Handler == nil { + t.Fatalf("%s handler is nil", test.Name) + } + got, err := test.Handler(aoc.Context{Body: input, Logger: l}) + assert(t, err, test.Want, got) + }) + } +}