diff options
-rw-r--r-- | deps.mk | 36 | ||||
-rw-r--r-- | src/gobang.go | 58 | ||||
-rw-r--r-- | tests/benchmarks/heredoc/gobang.go | 4 | ||||
l--------- | tests/benchmarks/heredoc/main.go | 1 | ||||
-rw-r--r-- | tests/functional/metrics/gobang.go | 4 | ||||
l--------- | tests/functional/metrics/main.go | 1 | ||||
-rw-r--r-- | tests/fuzz/count-leading-chars/gobang.go | 30 | ||||
l--------- | tests/fuzz/count-leading-chars/main.go | 1 | ||||
-rw-r--r-- | tests/fuzz/heredoc/gobang.go | 30 | ||||
l--------- | tests/fuzz/heredoc/main.go | 1 | ||||
-rw-r--r-- | tests/gobang.go | 37 |
11 files changed, 195 insertions, 8 deletions
@@ -1,25 +1,61 @@ libs.go = \ src/gobang.go \ + tests/benchmarks/heredoc/gobang.go \ + tests/functional/metrics/gobang.go \ + tests/fuzz/count-leading-chars/gobang.go \ + tests/fuzz/heredoc/gobang.go \ tests/gobang.go \ mains.go = \ + tests/benchmarks/heredoc/main.go \ + tests/functional/metrics/main.go \ + tests/fuzz/count-leading-chars/main.go \ + tests/fuzz/heredoc/main.go \ tests/main.go \ functional/lib.go = \ + tests/functional/metrics/gobang.go \ functional/main.go = \ + tests/functional/metrics/main.go \ fuzz/lib.go = \ + tests/fuzz/count-leading-chars/gobang.go \ + tests/fuzz/heredoc/gobang.go \ fuzz/main.go = \ + tests/fuzz/count-leading-chars/main.go \ + tests/fuzz/heredoc/main.go \ benchmarks/lib.go = \ + tests/benchmarks/heredoc/gobang.go \ benchmarks/main.go = \ + tests/benchmarks/heredoc/main.go \ src/gobang.a: src/gobang.go +tests/benchmarks/heredoc/gobang.a: tests/benchmarks/heredoc/gobang.go +tests/benchmarks/heredoc/main.a: tests/benchmarks/heredoc/main.go +tests/functional/metrics/gobang.a: tests/functional/metrics/gobang.go +tests/functional/metrics/main.a: tests/functional/metrics/main.go +tests/fuzz/count-leading-chars/gobang.a: tests/fuzz/count-leading-chars/gobang.go +tests/fuzz/count-leading-chars/main.a: tests/fuzz/count-leading-chars/main.go +tests/fuzz/heredoc/gobang.a: tests/fuzz/heredoc/gobang.go +tests/fuzz/heredoc/main.a: tests/fuzz/heredoc/main.go tests/gobang.a: tests/gobang.go tests/main.a: tests/main.go +tests/benchmarks/heredoc/main.bin: tests/benchmarks/heredoc/main.a +tests/functional/metrics/main.bin: tests/functional/metrics/main.a +tests/fuzz/count-leading-chars/main.bin: tests/fuzz/count-leading-chars/main.a +tests/fuzz/heredoc/main.bin: tests/fuzz/heredoc/main.a tests/main.bin: tests/main.a +tests/benchmarks/heredoc/main.bin-check: tests/benchmarks/heredoc/main.bin +tests/functional/metrics/main.bin-check: tests/functional/metrics/main.bin +tests/fuzz/count-leading-chars/main.bin-check: tests/fuzz/count-leading-chars/main.bin +tests/fuzz/heredoc/main.bin-check: tests/fuzz/heredoc/main.bin tests/main.bin-check: tests/main.bin +tests/benchmarks/heredoc/main.a: tests/benchmarks/heredoc/$(NAME).a +tests/functional/metrics/main.a: tests/functional/metrics/$(NAME).a +tests/fuzz/count-leading-chars/main.a: tests/fuzz/count-leading-chars/$(NAME).a +tests/fuzz/heredoc/main.a: tests/fuzz/heredoc/$(NAME).a tests/main.a: tests/$(NAME).a diff --git a/src/gobang.go b/src/gobang.go index 3c705b7..88b4c57 100644 --- a/src/gobang.go +++ b/src/gobang.go @@ -76,8 +76,64 @@ var ( +func countLeadingChar(s string, c byte) int { + n := 0 + for { + if len(s) == n { + return n + } + + if s[n] == c { + n++ + continue + } else { + return n + } + } +} + +func countLeadingTabs(s string) int { + return countLeadingChar(s, '\t') +} + +func notEmptyString(s string) bool { + return len(s) > 0 +} + func Heredoc(s string) string { - return strings.Trim(strings.ReplaceAll(s, "\t", ""), "\n") + "\n" + lines := strings.Split(s, "\n") + if lines[0] == "" { + lines = lines[1:] + } + length := len(lines) + if length > 0 && lines[length - 1] == "" { + lines = lines[:length - 1] + } + if len(lines) == 0 { + lines = append(lines, "") + } + last := lines[len(lines) - 1] + if len(last) > 0 && countLeadingTabs(last) == len(last) { + lines = lines[:len(lines) - 1] + } + if len(lines) == 0 { + lines = append(lines, "") + } + + countableLines := Map(countLeadingTabs, Filter(notEmptyString, lines)) + if len(countableLines) == 0 { + countableLines = append(countableLines, 0) + } + minIndentation := slices.Min(countableLines) + trimmedLines := Map(func(s string) string { + if len(s) == 0 { + return s + } else { + return s[minIndentation:] + } + }, lines) + return strings.Join(trimmedLines, "\n") + "\n" + } func SetOf[T comparable](values ...T) SetT[T] { diff --git a/tests/benchmarks/heredoc/gobang.go b/tests/benchmarks/heredoc/gobang.go new file mode 100644 index 0000000..7a4743a --- /dev/null +++ b/tests/benchmarks/heredoc/gobang.go @@ -0,0 +1,4 @@ +package gobang + +func MainTest() { +} diff --git a/tests/benchmarks/heredoc/main.go b/tests/benchmarks/heredoc/main.go new file mode 120000 index 0000000..f67563d --- /dev/null +++ b/tests/benchmarks/heredoc/main.go @@ -0,0 +1 @@ +../../main.go
\ No newline at end of file diff --git a/tests/functional/metrics/gobang.go b/tests/functional/metrics/gobang.go new file mode 100644 index 0000000..7a4743a --- /dev/null +++ b/tests/functional/metrics/gobang.go @@ -0,0 +1,4 @@ +package gobang + +func MainTest() { +} diff --git a/tests/functional/metrics/main.go b/tests/functional/metrics/main.go new file mode 120000 index 0000000..f67563d --- /dev/null +++ b/tests/functional/metrics/main.go @@ -0,0 +1 @@ +../../main.go
\ No newline at end of file diff --git a/tests/fuzz/count-leading-chars/gobang.go b/tests/fuzz/count-leading-chars/gobang.go new file mode 100644 index 0000000..5b9736d --- /dev/null +++ b/tests/fuzz/count-leading-chars/gobang.go @@ -0,0 +1,30 @@ +package gobang + +import ( + "os" + "testing" + "testing/internal/testdeps" +) + + + +func fn(f *testing.F) { + f.Fuzz(func(t *testing.T, s string, c byte) { + countLeadingChar(s, c) + }) +} + + + +func MainTest() { + fuzzTargets := []testing.InternalFuzzTarget{ + { "count-leading-char", fn }, + } + + deps := testdeps.TestDeps{} + tests := []testing.InternalTest {} + benchmarks := []testing.InternalBenchmark{} + examples := []testing.InternalExample {} + m := testing.MainStart(deps, tests, benchmarks, fuzzTargets, examples) + os.Exit(m.Run()) +} diff --git a/tests/fuzz/count-leading-chars/main.go b/tests/fuzz/count-leading-chars/main.go new file mode 120000 index 0000000..f67563d --- /dev/null +++ b/tests/fuzz/count-leading-chars/main.go @@ -0,0 +1 @@ +../../main.go
\ No newline at end of file diff --git a/tests/fuzz/heredoc/gobang.go b/tests/fuzz/heredoc/gobang.go new file mode 100644 index 0000000..e4cb9c6 --- /dev/null +++ b/tests/fuzz/heredoc/gobang.go @@ -0,0 +1,30 @@ +package gobang + +import ( + "os" + "testing" + "testing/internal/testdeps" +) + + + +func fn(f *testing.F) { + f.Fuzz(func(t *testing.T, s string) { + Heredoc(s) + }) +} + + + +func MainTest() { + fuzzTargets := []testing.InternalFuzzTarget{ + { "heredoc", fn }, + } + + deps := testdeps.TestDeps{} + tests := []testing.InternalTest {} + benchmarks := []testing.InternalBenchmark{} + examples := []testing.InternalExample {} + m := testing.MainStart(deps, tests, benchmarks, fuzzTargets, examples) + os.Exit(m.Run()) +} diff --git a/tests/fuzz/heredoc/main.go b/tests/fuzz/heredoc/main.go new file mode 120000 index 0000000..f67563d --- /dev/null +++ b/tests/fuzz/heredoc/main.go @@ -0,0 +1 @@ +../../main.go
\ No newline at end of file diff --git a/tests/gobang.go b/tests/gobang.go index 7391475..e0fde2f 100644 --- a/tests/gobang.go +++ b/tests/gobang.go @@ -28,20 +28,43 @@ func test_Heredoc() { and end `) - expected := ` Start - and - end -` + expected := " Start\n and\n end\n" TAssertEqual(given, expected) }) - Testing("removes ALL tabs", func() { - given := Heredoc(` + Testing("removes only indenting tabs", func() { + given1 := Heredoc(` Tab here> <within the line `) + const expected1 = "Tab here> <within the line\n" + + given2 := Heredoc(` + some + uneven + indentation + `) + const expected2 = "some\n\tuneven\n\t\tindentation\n" + + given3 := Heredoc(` + some + mixed + indentation + `) + const expected3 = "\tsome\n mixed\n\t\tindentation\n" + + TAssertEqual(given1, expected1) + TAssertEqual(given2, expected2) + TAssertEqual(given3, expected3) + }) - expected := "Tab here><within the line\n" + Testing("empty lines are removed", func() { + given := Heredoc(` + line 1 + + line 2 + `) + const expected = "line 1\n\nline 2\n" TAssertEqual(given, expected) }) |