From 7de40d99cf8197b51a5c3f169292c98b04af6fbc Mon Sep 17 00:00:00 2001 From: Andrey Nering Date: Mon, 2 Jun 2025 18:02:42 -0300 Subject: [PATCH] chore: having some fun with the `go-udiff` package --- go.mod | 1 + go.sum | 4 +- internal/exp/diff/diff.go | 1 + .../DefaultContextLines/Content.golden | 11 +++ .../DefaultContextLines/JSON.golden | 40 ++++++++ .../DefaultContextLinesPlusOne/Content.golden | 12 +++ .../DefaultContextLinesPlusOne/JSON.golden | 44 +++++++++ .../DefaultContextLinesPlusTwo/Content.golden | 13 +++ .../DefaultContextLinesPlusTwo/JSON.golden | 48 ++++++++++ .../diff/testdata/TestUdiff/Unified.golden | 11 +++ internal/exp/diff/udiff_test.go | 92 +++++++++++++++++++ 11 files changed, 275 insertions(+), 2 deletions(-) create mode 100644 internal/exp/diff/diff.go create mode 100644 internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLines/Content.golden create mode 100644 internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLines/JSON.golden create mode 100644 internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLinesPlusOne/Content.golden create mode 100644 internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLinesPlusOne/JSON.golden create mode 100644 internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLinesPlusTwo/Content.golden create mode 100644 internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLinesPlusTwo/JSON.golden create mode 100644 internal/exp/diff/testdata/TestUdiff/Unified.golden create mode 100644 internal/exp/diff/udiff_test.go diff --git a/go.mod b/go.mod index 82994450a85848a8b1be260b8d1611dec023ac1d..866c30da7e92eefaad23d3fd715bed3533e5f9f4 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( github.com/charmbracelet/glamour v0.9.1 github.com/charmbracelet/lipgloss v1.1.0 github.com/charmbracelet/x/ansi v0.8.0 + github.com/charmbracelet/x/exp/golden v0.0.0-20250602192518-9e722df69bbb github.com/fsnotify/fsnotify v1.8.0 github.com/go-logfmt/logfmt v0.6.0 github.com/google/uuid v1.6.0 diff --git a/go.sum b/go.sum index 8b7e307442ad96a69ff3471fe8164a1ba2a46e8a..3c742d185d7cf35460c7e1dc3d321e2f91013d41 100644 --- a/go.sum +++ b/go.sum @@ -82,8 +82,8 @@ github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2ll github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q= github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8= github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= -github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ= -github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U= +github.com/charmbracelet/x/exp/golden v0.0.0-20250602192518-9e722df69bbb h1:GT/STWThMsrOfYQnhnIPb165e/g1waAp0gNMFvEO6WI= +github.com/charmbracelet/x/exp/golden v0.0.0-20250602192518-9e722df69bbb/go.mod h1:929X+xY3LeoOZrDWIBVZcx/zyS0CYtyLiUIvE4VbKC0= github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= diff --git a/internal/exp/diff/diff.go b/internal/exp/diff/diff.go new file mode 100644 index 0000000000000000000000000000000000000000..f8689a22b662733cb979bd47da00b4c2a7828625 --- /dev/null +++ b/internal/exp/diff/diff.go @@ -0,0 +1 @@ +package diff diff --git a/internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLines/Content.golden b/internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLines/Content.golden new file mode 100644 index 0000000000000000000000000000000000000000..b0d3d504a4dc9e8aabb220d7b03f699e7286e765 --- /dev/null +++ b/internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLines/Content.golden @@ -0,0 +1,11 @@ +--- main.go ++++ main.go +@@ -5,5 +5,6 @@ + ) + + func main() { +- fmt.Println("Hello, World!") ++ content := "Hello, World!" ++ fmt.Println(content) + } +\ No newline at end of file diff --git a/internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLines/JSON.golden b/internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLines/JSON.golden new file mode 100644 index 0000000000000000000000000000000000000000..dc02fd23ed304cfcf868dd661f685ad7dbb6754f --- /dev/null +++ b/internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLines/JSON.golden @@ -0,0 +1,40 @@ +{ + "From": "main.go", + "To": "main.go", + "Hunks": [ + { + "FromLine": 5, + "ToLine": 5, + "Lines": [ + { + "Kind": 2, + "Content": "\t)\n" + }, + { + "Kind": 2, + "Content": "\n" + }, + { + "Kind": 2, + "Content": "\tfunc main() {\n" + }, + { + "Kind": 0, + "Content": "\t\tfmt.Println(\"Hello, World!\")\n" + }, + { + "Kind": 1, + "Content": "\t\tcontent := \"Hello, World!\"\n" + }, + { + "Kind": 1, + "Content": "\t\tfmt.Println(content)\n" + }, + { + "Kind": 2, + "Content": "\t}" + } + ] + } + ] +} diff --git a/internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLinesPlusOne/Content.golden b/internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLinesPlusOne/Content.golden new file mode 100644 index 0000000000000000000000000000000000000000..95ab1aca68b72158f829ef6391dc30771e3ace52 --- /dev/null +++ b/internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLinesPlusOne/Content.golden @@ -0,0 +1,12 @@ +--- main.go ++++ main.go +@@ -4,6 +4,7 @@ + "fmt" + ) + + func main() { +- fmt.Println("Hello, World!") ++ content := "Hello, World!" ++ fmt.Println(content) + } +\ No newline at end of file diff --git a/internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLinesPlusOne/JSON.golden b/internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLinesPlusOne/JSON.golden new file mode 100644 index 0000000000000000000000000000000000000000..20adf2e182705257388d13baba06198367f4c9b7 --- /dev/null +++ b/internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLinesPlusOne/JSON.golden @@ -0,0 +1,44 @@ +{ + "From": "main.go", + "To": "main.go", + "Hunks": [ + { + "FromLine": 4, + "ToLine": 4, + "Lines": [ + { + "Kind": 2, + "Content": "\t\t\"fmt\"\n" + }, + { + "Kind": 2, + "Content": "\t)\n" + }, + { + "Kind": 2, + "Content": "\n" + }, + { + "Kind": 2, + "Content": "\tfunc main() {\n" + }, + { + "Kind": 0, + "Content": "\t\tfmt.Println(\"Hello, World!\")\n" + }, + { + "Kind": 1, + "Content": "\t\tcontent := \"Hello, World!\"\n" + }, + { + "Kind": 1, + "Content": "\t\tfmt.Println(content)\n" + }, + { + "Kind": 2, + "Content": "\t}" + } + ] + } + ] +} diff --git a/internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLinesPlusTwo/Content.golden b/internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLinesPlusTwo/Content.golden new file mode 100644 index 0000000000000000000000000000000000000000..01b92d2512090f1ff2ea624c31fbeb1cae9235b4 --- /dev/null +++ b/internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLinesPlusTwo/Content.golden @@ -0,0 +1,13 @@ +--- main.go ++++ main.go +@@ -3,7 +3,8 @@ + import ( + "fmt" + ) + + func main() { +- fmt.Println("Hello, World!") ++ content := "Hello, World!" ++ fmt.Println(content) + } +\ No newline at end of file diff --git a/internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLinesPlusTwo/JSON.golden b/internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLinesPlusTwo/JSON.golden new file mode 100644 index 0000000000000000000000000000000000000000..2f0df7c1703ffa1ddc929265be0770d29ec2aec3 --- /dev/null +++ b/internal/exp/diff/testdata/TestUdiff/ToUnifiedDiff/DefaultContextLinesPlusTwo/JSON.golden @@ -0,0 +1,48 @@ +{ + "From": "main.go", + "To": "main.go", + "Hunks": [ + { + "FromLine": 3, + "ToLine": 3, + "Lines": [ + { + "Kind": 2, + "Content": "\timport (\n" + }, + { + "Kind": 2, + "Content": "\t\t\"fmt\"\n" + }, + { + "Kind": 2, + "Content": "\t)\n" + }, + { + "Kind": 2, + "Content": "\n" + }, + { + "Kind": 2, + "Content": "\tfunc main() {\n" + }, + { + "Kind": 0, + "Content": "\t\tfmt.Println(\"Hello, World!\")\n" + }, + { + "Kind": 1, + "Content": "\t\tcontent := \"Hello, World!\"\n" + }, + { + "Kind": 1, + "Content": "\t\tfmt.Println(content)\n" + }, + { + "Kind": 2, + "Content": "\t}" + } + ] + } + ] +} diff --git a/internal/exp/diff/testdata/TestUdiff/Unified.golden b/internal/exp/diff/testdata/TestUdiff/Unified.golden new file mode 100644 index 0000000000000000000000000000000000000000..b0d3d504a4dc9e8aabb220d7b03f699e7286e765 --- /dev/null +++ b/internal/exp/diff/testdata/TestUdiff/Unified.golden @@ -0,0 +1,11 @@ +--- main.go ++++ main.go +@@ -5,5 +5,6 @@ + ) + + func main() { +- fmt.Println("Hello, World!") ++ content := "Hello, World!" ++ fmt.Println(content) + } +\ No newline at end of file diff --git a/internal/exp/diff/udiff_test.go b/internal/exp/diff/udiff_test.go new file mode 100644 index 0000000000000000000000000000000000000000..65977ae047aad25551a65957d6ea919ae59da618 --- /dev/null +++ b/internal/exp/diff/udiff_test.go @@ -0,0 +1,92 @@ +package diff_test + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/aymanbagabas/go-udiff" + "github.com/aymanbagabas/go-udiff/myers" + "github.com/charmbracelet/x/exp/golden" +) + +func TestUdiff(t *testing.T) { + before := `package main + + import ( + "fmt" + ) + + func main() { + fmt.Println("Hello, World!") + }` + + after := `package main + + import ( + "fmt" + ) + + func main() { + content := "Hello, World!" + fmt.Println(content) + }` + + t.Run("Unified", func(t *testing.T) { + content := udiff.Unified("main.go", "main.go", before, after) + golden.RequireEqual(t, []byte(content)) + }) + + t.Run("ToUnifiedDiff", func(t *testing.T) { + toUnifiedDiff := func(t *testing.T, before, after string, contextLines int) udiff.UnifiedDiff { + edits := myers.ComputeEdits(before, after) + unifiedDiff, err := udiff.ToUnifiedDiff("main.go", "main.go", before, edits, contextLines) + if err != nil { + t.Fatalf("ToUnifiedDiff failed: %v", err) + } + return unifiedDiff + } + toJSON := func(t *testing.T, unifiedDiff udiff.UnifiedDiff) []byte { + var buff bytes.Buffer + encoder := json.NewEncoder(&buff) + encoder.SetIndent("", " ") + if err := encoder.Encode(unifiedDiff); err != nil { + t.Fatalf("Failed to encode unified diff: %v", err) + } + return buff.Bytes() + } + + t.Run("DefaultContextLines", func(t *testing.T) { + unifiedDiff := toUnifiedDiff(t, before, after, udiff.DefaultContextLines) + + t.Run("Content", func(t *testing.T) { + golden.RequireEqual(t, []byte(unifiedDiff.String())) + }) + t.Run("JSON", func(t *testing.T) { + golden.RequireEqual(t, toJSON(t, unifiedDiff)) + }) + }) + + t.Run("DefaultContextLinesPlusOne", func(t *testing.T) { + unifiedDiff := toUnifiedDiff(t, before, after, udiff.DefaultContextLines+1) + + t.Run("Content", func(t *testing.T) { + golden.RequireEqual(t, []byte(unifiedDiff.String())) + }) + t.Run("JSON", func(t *testing.T) { + golden.RequireEqual(t, toJSON(t, unifiedDiff)) + }) + }) + + t.Run("DefaultContextLinesPlusTwo", func(t *testing.T) { + unifiedDiff := toUnifiedDiff(t, before, after, udiff.DefaultContextLines+2) + + t.Run("Content", func(t *testing.T) { + golden.RequireEqual(t, []byte(unifiedDiff.String())) + }) + t.Run("JSON", func(t *testing.T) { + golden.RequireEqual(t, toJSON(t, unifiedDiff)) + }) + }) + }) +}