11package jd
22
33import (
4+ "strings"
45 "testing"
56)
67
@@ -23,6 +24,48 @@ func TestDiffRender(t *testing.T) {
2324 `- {"b":1}` ,
2425 `@ ["c"]` ,
2526 `+ {"b":1}` )
27+ // String changes
28+ checkDiffRender (t , `{"a":"bar"}` , `{"a":"baz"}` ,
29+ `@ ["a"]` ,
30+ `- "bar"` ,
31+ `+ "baz"` )
32+ // Array of strings
33+ checkDiffRender (t , `{"qux":["foobar","foobaz"]}` , `{"qux":["fooarrr","foobaz"]}` ,
34+ `@ ["qux",0]` ,
35+ `[` ,
36+ `- "foobar"` ,
37+ `+ "fooarrr"` ,
38+ ` "foobaz"` ,
39+ )
40+ // Addition only
41+ checkDiffRender (t , `{"str":""}` , `{"str":"abc"}` ,
42+ `@ ["str"]` ,
43+ `- ""` ,
44+ `+ "abc"` )
45+ // Removal only
46+ checkDiffRender (t , `{"str":"abc"}` , `{"str":""}` ,
47+ `@ ["str"]` ,
48+ `- "abc"` ,
49+ `+ ""` )
50+ // Nested strings
51+ checkDiffRender (t , `{"a":{"b":"hello"}}` , `{"a":{"b":"world"}}` ,
52+ `@ ["a","b"]` ,
53+ `- "hello"` ,
54+ `+ "world"` )
55+ // Multiple string changes
56+ checkDiffRender (t , `{"a":"foo","b":"bar"}` , `{"a":"baz","b":"qux"}` ,
57+ `@ ["a"]` ,
58+ `- "foo"` ,
59+ `+ "baz"` ,
60+ `@ ["b"]` ,
61+ `- "bar"` ,
62+ `+ "qux"` )
63+ // Key change
64+ checkDiffRender (t , `{"a":"foo"}` , `{"b":"foo"}` ,
65+ `@ ["a"]` ,
66+ `- "foo"` ,
67+ `@ ["b"]` ,
68+ `+ "foo"` )
2669}
2770
2871func checkDiffRender (t * testing.T , a , b string , diffLines ... string ) {
@@ -38,10 +81,85 @@ func checkDiffRender(t *testing.T, a, b string, diffLines ...string) {
3881 if err != nil {
3982 t .Errorf ("%v" , err .Error ())
4083 }
84+
85+ // Test without color
4186 d := aJson .diff (bJson , nil , []Option {}, strictPatchStrategy ).Render ()
4287 if d != diff {
4388 t .Errorf ("%v.diff(%v) = %v. Want %v." , a , b , d , diff )
4489 }
90+
91+ // Test with color
92+ coloredDiff := aJson .diff (bJson , nil , []Option {}, strictPatchStrategy ).Render (COLOR )
93+ strippedDiff := stripAnsiCodes (coloredDiff )
94+ if strippedDiff != diff {
95+ t .Errorf ("%v.diff(%v) with color (stripped) = %v. Want %v." , a , b , strippedDiff , diff )
96+ }
97+
98+ // Verify that uncolored parts in string diffs match between + and - lines
99+ lines := strings .Split (coloredDiff , "\n " )
100+ var minusLine , plusLine string
101+ for i , line := range lines {
102+ if len (line ) == 0 {
103+ continue
104+ }
105+ if line [0 ] == '-' && strings .Contains (line , "\" " ) { // Only check string diffs
106+ minusLine = line
107+ if i + 1 < len (lines ) && len (lines [i + 1 ]) > 0 && lines [i + 1 ][0 ] == '+' {
108+ plusLine = lines [i + 1 ]
109+ minusUncolored := removeColoredParts (minusLine [1 :]) // Skip the "- " prefix
110+ plusUncolored := removeColoredParts (plusLine [1 :]) // Skip the "+ " prefix
111+ if minusUncolored != plusUncolored {
112+ t .Errorf ("Uncolored parts don't match:\n - %s\n + %s" , minusUncolored , plusUncolored )
113+ }
114+ }
115+ }
116+ }
117+ }
118+
119+ // removeColoredParts returns the string with the colored parts (including the text between color codes) removed
120+ func removeColoredParts (s string ) string {
121+ result := ""
122+ inColor := false
123+ for i := 0 ; i < len (s ); i ++ {
124+ // detect a color code (starts coloring)
125+ if ! inColor && i + 1 < len (s ) && s [i ] == '\033' && s [i + 1 ] == '[' {
126+ inColor = true
127+ i ++ // skip '['
128+ continue
129+ }
130+ // if not colored, add the character to the result
131+ if ! inColor {
132+ result += string (s [i ])
133+ }
134+ // detect the reset color code (ends coloring)
135+ if inColor && i + 1 < len (s ) && s [i ] == '[' && s [i + 1 ] == '0' && i + 2 < len (s ) && s [i + 2 ] == 'm' {
136+ inColor = false
137+ i += 2
138+ }
139+ }
140+ return result
141+ }
142+
143+ // stripAnsiCodes removes ANSI color escape sequences from a string
144+ func stripAnsiCodes (s string ) string {
145+ result := ""
146+ inEscape := false
147+
148+ for i := 0 ; i < len (s ); i ++ {
149+ if ! inEscape && i + 1 < len (s ) && s [i ] == '\033' && s [i + 1 ] == '[' {
150+ inEscape = true
151+ i ++ // skip the '['
152+ continue
153+ }
154+ if inEscape {
155+ if s [i ] == 'm' {
156+ inEscape = false
157+ }
158+ continue
159+ }
160+ result += string (s [i ])
161+ }
162+ return result
45163}
46164
47165func TestDiffRenderPatch (t * testing.T ) {
0 commit comments