diff options
-rw-r--r-- | src/gobang.go | 17 | ||||
-rw-r--r-- | tests/gobang.go | 335 |
2 files changed, 334 insertions, 18 deletions
diff --git a/src/gobang.go b/src/gobang.go index 57a087d..2217236 100644 --- a/src/gobang.go +++ b/src/gobang.go @@ -15,7 +15,6 @@ import ( "runtime/debug" "slices" "strings" - "syscall" "time" "guuid" @@ -57,6 +56,7 @@ var ( testOutput io.Writer = os.Stderr testExitFn = os.Exit + randomReader = rand.Reader SourceInfoSkip = 3 @@ -116,11 +116,13 @@ func SomeFnError(fns ...func() error) error { return SomeError(errs...) } -func Random(length int) []byte { +func Random(length int) ([]byte, error) { buffer := make([]byte, length) - _, err := io.ReadFull(rand.Reader, buffer) - FatalIf(err) - return buffer + _, err := io.ReadFull(randomReader, buffer) + if err != nil { + return nil, err + } + return buffer, nil } func sourceInfo(skip int) slog.Attr { @@ -393,6 +395,7 @@ func TAssertEqualI[T any](givenarr []T, expectedarr []T) { expectedarr[givenlen:], ) testExitFn(100) + return } if givenlen > expectedlen { @@ -404,6 +407,7 @@ func TAssertEqualI[T any](givenarr []T, expectedarr []T) { givenarr[expectedlen:], ) testExitFn(100) + return } for i, _ := range givenarr { @@ -497,8 +501,7 @@ func Fatal(err error) { "error", err, "stack", string(debug.Stack()), ) - syscall.Kill(os.Getpid(), syscall.SIGABRT) - os.Exit(3) + panic(err) } func FatalIf(err error) { diff --git a/tests/gobang.go b/tests/gobang.go index d67b99f..a817889 100644 --- a/tests/gobang.go +++ b/tests/gobang.go @@ -6,6 +6,7 @@ import ( "fmt" "log/slog" "os" + "slices" "strings" "time" @@ -171,10 +172,25 @@ func test_Random() { Testing("we get the desired output size", func() { for i := 0; i < 100; i++ { - buffer := Random(i) + buffer, err := Random(i) + TErrorIf(err) TAssertEqual(len(buffer), i) } }) + + Testing("error on bad randomReader value", func() { + savedReader := randomReader + randomReader = strings.NewReader("abc") + + rand1, err1 := Random(3) + rand2, err2 := Random(3) + TErrorIf(err1) + TErrorNil(err2) + TAssertEqual(rand1, []byte{ 0x61, 0x62, 0x63 }) + TAssertEqual(rand2, []byte(nil)) + + randomReader = savedReader + }) } func test_sourceInfo() { @@ -502,7 +518,10 @@ func test_MakeGauge() { TErrorIf(err) TAssertEqual(data["level"].(string), "ERROR") - TAssertEqual(data["msg" ].(string), "Gauge went negative") + TAssertEqual( + data["msg" ].(string), + "Gauge went negative", + ) TAssertEqual(data["kind" ].(string), "log") TAssertEqual(data["type" ].(string), "process-metric") TAssertEqual(int(data["value"].(float64)), -1) @@ -593,11 +612,9 @@ func test_TestStart() { } func withSavedColour() func() { - println("antes") const NAME = "NO_COLOUR" savedEnvvar := os.Getenv(NAME) return func() { - println("depois") os.Setenv(NAME, savedEnvvar) } } @@ -657,15 +674,178 @@ func test_terr() { } func test_TAssertEqual() { - // FIXME + TestStart("TAssertEqual()") + + Testing("noop on equal things", func() { + TAssertEqual(1, 1) + TAssertEqual("s", "s") + TAssertEqual([]byte{ 0x12 }, []byte{ 0x12 }) + }) + + Testing("fail on unequal", func() { + var n int + exitFn := func(val int) { + n = val + } + + w := new(strings.Builder) + + savedExitFn := testExitFn + savedOutput := testOutput + testExitFn = exitFn + testOutput = w + + TAssertEqual([]byte(nil), nil) + + testExitFn = savedExitFn + testOutput = savedOutput + + given := strings.Split(w.String(), "\n")[1:] + + TAssertEqual(n, 100) + TAssertEqual(given, []string{ + "given != expected", + "given: []byte(nil)", + "expected: <nil>", + "", + }) + }) } func test_TAssertEqualS() { - // FIXME + TestStart("TAssertEqualS()") + + Testing("noop for equal things", func() { + TAssertEqualS(true, true, "ignored") + }) + + Testing("fail with message on unequal", func() { + var n int + exitFn := func(val int) { + n = val + } + + w := new(strings.Builder) + + savedExitFn := testExitFn + savedOutput := testOutput + testExitFn = exitFn + testOutput = w + + TAssertEqualS("a", []byte("a"), "custom string") + + testExitFn = savedExitFn + testOutput = savedOutput + + given := strings.Split(w.String(), "\n")[1:] + + TAssertEqual(n, 100) + TAssertEqual(given, []string{ + "message: custom string", + "given != expected", + "given: \"a\"", + "expected: []byte{0x61}", + "", + }) + }) } func test_TAssertEqualI() { - // FIXME + TestStart("TAssertEqualI()") + + Testing("noop for equal slices", func() { + TAssertEqualI([]string{}, []string{}) + TAssertEqualI([]string{"", "a", "b"}, []string{"", "a", "b"}) + }) + + Testing("fail when `given` has less elements", func() { + var n int + exitFn := func(val int) { + n = val + } + + w := new(strings.Builder) + + savedExitFn := testExitFn + savedOutput := testOutput + testExitFn = exitFn + testOutput = w + + TAssertEqualI([]string{"a"}, []string{"a", "b", "c"}) + + testExitFn = savedExitFn + testOutput = savedOutput + + given := strings.Split(w.String(), "\n")[1:] + + TAssertEqual(n, 100) + TAssertEqual(given, []string{ + "expected has 2 more elements:", + `[]string{"b", "c"}`, + "", + }) + }) + + Testing("fail when `given` has more elements", func() { + var n int + exitFn := func(val int) { + n = val + } + + w := new(strings.Builder) + + savedExitFn := testExitFn + savedOutput := testOutput + testExitFn = exitFn + testOutput = w + + TAssertEqualI([]int{1, 2, 3, 4}, []int{5, 6, 7}) + + testExitFn = savedExitFn + testOutput = savedOutput + + given := strings.Split(w.String(), "\n")[1:] + + TAssertEqual(n, 100) + TAssertEqual(given, []string{ + "given has 1 more elements:", + "[]int{4}", + "", + }) + }) + + Testing("fail when nth element is different", func() { + var n int + exitFn := func(val int) { + n = val + } + + w := new(strings.Builder) + + savedExitFn := testExitFn + savedOutput := testOutput + testExitFn = exitFn + testOutput = w + + TAssertEqualI([]int{1, 2, 10, 4, 100}, []int{1, 2, 3, 4, 5}) + + testExitFn = savedExitFn + testOutput = savedOutput + + given := strings.Split(w.String(), "\n") + given = slices.Concat(given[1:4], given[5:]) + + TAssertEqual(n, 100) + TAssertEqual(given, []string{ + "given != expected (i = 2)", + "given: 10", + "expected: 3", + "given != expected (i = 4)", + "given: 100", + "expected: 5", + "", + }) + }) } func test_TErrorIf() { @@ -785,7 +965,10 @@ func test_SetLoggerOutput() { file := src["file"].(string) const FILENAME = "tests/gobang.go" TAssertEqual(file[len(file) - len(FILENAME):], FILENAME) - TAssertEqual(src["function"].(string), "gobang.test_SetLoggerOutput.func1") + TAssertEqual( + src["function"].(string), + "gobang.test_SetLoggerOutput.func1", + ) line := src["line"].(float64) TAssertEqual(line > 0, true) @@ -819,7 +1002,10 @@ func test_SetLoggerOutput() { err := json.Unmarshal([]byte(s.String()), &data) TErrorIf(err) - TAssertEqual(data["one"].(map[string]interface{})["key"].(string), "value") + TAssertEqual( + data["one"].(map[string]interface{})["key"].(string), + "value", + ) }) Testing("the puuid is the same across calls to the logger", func() { @@ -840,7 +1026,8 @@ func test_SetLoggerOutput() { err := json.Unmarshal([]byte(str), &data) TErrorIf(err) - return data["info"].(map[string]interface{})["puuid"].(string) + return data["info"]. + (map[string]interface{})["puuid"].(string) } puuid1 := puuidFromString(log1) @@ -875,7 +1062,9 @@ func test_levelFromString() { Testing("fallback for unexpected values", func() { var fallback LogLevel = 123 - theLevel := levelFromString(string(Random(10)), fallback) + rand, err := Random(10) + TErrorIf(err) + theLevel := levelFromString(string(rand), fallback) TAssertEqual(theLevel, fallback) }) } @@ -978,7 +1167,125 @@ func test_setMetric() { TAssertEqual(emitMetric, false) }) +} +func test_Fatal() { + TestStart("Fatal()") + + Testing("error and panic", func() { + savedLogger := slog.Default() + savedLevel := level + + w := new(strings.Builder) + SetLoggerOutput(w) + level = LevelError + + defer func() { + r := recover() + TAssertEqual(r == nil, false) + + slog.SetDefault(savedLogger) + level = savedLevel + + TAssertEqual(len(w.String()) == 0, false) + }() + + Fatal(nil) + TErrorNil(nil) + }) +} + +func test_FatalIf() { + TestStart("FatalIf()") + + Testing("noop on nil", func() { + FatalIf(nil) + }) + + Testing("error and panic otherwise", func() { + savedLogger := slog.Default() + savedLevel := level + + w := new(strings.Builder) + SetLoggerOutput(w) + level = LevelError + + myErr := errors.New("the error") + + defer func() { + r := recover() + TAssertEqual(r, myErr) + + slog.SetDefault(savedLogger) + level = savedLevel + + TAssertEqual(len(w.String()) == 0, false) + }() + + FatalIf(myErr) + TErrorNil(nil) + }) +} + +func test_Assert() { + TestStart("Assert()") + + Testing("noop if true", func() { + Assert(true, "ignored") + }) + + Testing("error and panic if false", func() { + savedLogger := slog.Default() + savedLevel := level + + w := new(strings.Builder) + SetLoggerOutput(w) + level = LevelError + + const errMsg = "assert error message" + + defer func() { + r := recover() + TAssertEqual(r.(error).Error(), errMsg) + + slog.SetDefault(savedLogger) + level = savedLevel + + TAssertEqual(len(w.String()) == 0, false) + }() + + Assert(1 == 2, errMsg) + TErrorNil(nil) + }) +} + +func test_Unreachable() { + TestStart("Unreachable()") + + Testing("always has error and panic", func() { + savedLogger := slog.Default() + savedLevel := level + + w := new(strings.Builder) + SetLoggerOutput(w) + level = LevelError + + defer func() { + r := recover() + TAssertEqual( + r.(error).Error(), + "Unreachable code was reached", + ) + + slog.SetDefault(savedLogger) + level = savedLevel + + TAssertEqual(len(w.String()) == 0, false) + }() + + Unreachable() + TErrorNil(nil) + }) } func test_setHostname() { @@ -995,6 +1302,8 @@ func test_setHostname() { func MainTest() { + Init() + test_Clamp() test_ValidateSQLTablePrefix() test_WrapErrors() @@ -1026,5 +1335,9 @@ func MainTest() { test_setLogLevel() test_SetLevel() test_setMetric() + test_Fatal() + test_FatalIf() + test_Assert() + test_Unreachable() test_setHostname() } |