package main import "testing" func TestMatchLineExact(t *testing.T) { if !matchLine("hello", "hello") { t.Error("exact match should pass") } if matchLine("hello", "world") { t.Error("exact mismatch should fail") } } func TestMatchLineInlineWildcard(t *testing.T) { if !matchLine("Homebrew 5...", "Homebrew 5.1.0") { t.Error("trailing wildcard should match") } if !matchLine("...world", "hello world") { t.Error("leading wildcard should match") } if !matchLine("a...b...c", "aXXbYYc") { t.Error("multiple wildcards should match") } if matchLine("a...c", "aXXd") { t.Error("should not match when suffix differs") } } func TestMatchLinePreservesLiteralDots(t *testing.T) { if !matchLine("match ...", "match ...") { t.Error("literal ... should match itself") } } func TestMatchOutputEmpty(t *testing.T) { if !matchOutput(nil, nil) { t.Error("both empty should match") } if !matchOutput([]string{}, []string{}) { t.Error("both empty slices should match") } } func TestMatchOutputExact(t *testing.T) { if !matchOutput([]string{"hello", "world"}, []string{"hello", "world"}) { t.Error("exact match should pass") } if matchOutput([]string{"hello"}, []string{"world"}) { t.Error("mismatch should fail") } } func TestMatchOutputExtraActual(t *testing.T) { if matchOutput([]string{"hello"}, []string{"hello", "world"}) { t.Error("extra actual lines should fail") } } func TestMatchOutputExtraExpected(t *testing.T) { if matchOutput([]string{"hello", "world"}, []string{"hello"}) { t.Error("extra expected lines should fail") } } func TestMatchOutputMultilineWildcard(t *testing.T) { if !matchOutput([]string{"first", "...", "last"}, []string{"first", "a", "b", "c", "last"}) { t.Error("multiline wildcard should match multiple lines") } if !matchOutput([]string{"first", "...", "last"}, []string{"first", "last"}) { t.Error("multiline wildcard should match zero lines") } if !matchOutput([]string{"..."}, []string{"a", "b", "c"}) { t.Error("standalone wildcard should match anything") } if !matchOutput([]string{"..."}, nil) { t.Error("standalone wildcard should match empty") } } func TestMatchOutputMixed(t *testing.T) { expected := []string{"one", "...", "three"} actual := []string{"one", "two", "three"} if !matchOutput(expected, actual) { t.Error("mixed wildcard should match") } } func TestMatchOutputWildcardAtEnd(t *testing.T) { if !matchOutput([]string{"start", "..."}, []string{"start", "a", "b"}) { t.Error("trailing wildcard should match remaining lines") } } func TestMatchOutputInlineAndMultiline(t *testing.T) { expected := []string{"Homebrew 5...", "..."} actual := []string{"Homebrew 5.1.0", "extra line"} if !matchOutput(expected, actual) { t.Error("inline + multiline wildcards should work together") } } func TestMatchOutputConsecutiveWildcards(t *testing.T) { // This would hang before memoization (exponential backtracking) expected := []string{"...", "...", "...", "...", "end"} actual := make([]string, 200) for i := range actual { actual[i] = "line" } // "end" is not in actual, so this should return false — quickly. if matchOutput(expected, actual) { t.Error("should not match when final line is missing") } } func TestDiffBasic(t *testing.T) { d := diff([]string{"hello"}, []string{"world"}) if len(d) != 2 { t.Fatalf("expected 2 diff lines, got %d", len(d)) } if d[0].Kind != "expected" || d[0].Text != "hello" { t.Errorf("d[0] = %+v", d[0]) } if d[1].Kind != "actual" || d[1].Text != "world" { t.Errorf("d[1] = %+v", d[1]) } } func TestDiffEqual(t *testing.T) { d := diff([]string{"hello"}, []string{"hello"}) if len(d) != 1 || d[0].Kind != "equal" { t.Errorf("expected equal, got %+v", d) } } func TestDiffContext(t *testing.T) { d := diff([]string{"..."}, []string{"a", "b"}) if len(d) != 3 { t.Fatalf("expected 3 diff lines, got %d: %+v", len(d), d) } if d[0].Kind != "context" || d[0].Text != "..." { t.Errorf("d[0] = %+v", d[0]) } if d[1].Kind != "context" || d[1].Text != "a" { t.Errorf("d[1] = %+v", d[1]) } if d[2].Kind != "context" || d[2].Text != "b" { t.Errorf("d[2] = %+v", d[2]) } }