summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--deps.mk36
-rw-r--r--src/gobang.go58
-rw-r--r--tests/benchmarks/heredoc/gobang.go4
l---------tests/benchmarks/heredoc/main.go1
-rw-r--r--tests/functional/metrics/gobang.go4
l---------tests/functional/metrics/main.go1
-rw-r--r--tests/fuzz/count-leading-chars/gobang.go30
l---------tests/fuzz/count-leading-chars/main.go1
-rw-r--r--tests/fuzz/heredoc/gobang.go30
l---------tests/fuzz/heredoc/main.go1
-rw-r--r--tests/gobang.go37
11 files changed, 195 insertions, 8 deletions
diff --git a/deps.mk b/deps.mk
index 6e54d19..8e6b837 100644
--- a/deps.mk
+++ b/deps.mk
@@ -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)
})