22// Use of this source code is governed by a BSD-style
33// license that can be found in the LICENSE file.
44
5- package diff
5+ package diff_test
66
77import (
8+ "github.com/mb0/diff"
89 "testing"
910)
1011
1112type testcase struct {
1213 name string
1314 a , b []int
14- res []Change
15+ res []diff. Change
1516}
1617
1718var tests = []testcase {
1819 {"shift" ,
1920 []int {1 , 2 , 3 },
2021 []int {0 , 1 , 2 , 3 },
21- []Change {{0 , 0 , 0 , 1 }},
22+ []diff. Change {{0 , 0 , 0 , 1 }},
2223 },
2324 {"push" ,
2425 []int {1 , 2 , 3 },
2526 []int {1 , 2 , 3 , 4 },
26- []Change {{3 , 3 , 0 , 1 }},
27+ []diff. Change {{3 , 3 , 0 , 1 }},
2728 },
2829 {"unshift" ,
2930 []int {0 , 1 , 2 , 3 },
3031 []int {1 , 2 , 3 },
31- []Change {{0 , 0 , 1 , 0 }},
32+ []diff. Change {{0 , 0 , 1 , 0 }},
3233 },
3334 {"pop" ,
3435 []int {1 , 2 , 3 , 4 },
3536 []int {1 , 2 , 3 },
36- []Change {{3 , 3 , 1 , 0 }},
37+ []diff. Change {{3 , 3 , 1 , 0 }},
3738 },
3839 {"all changed" ,
3940 []int {0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 },
4041 []int {10 , 11 , 12 , 13 , 14 },
41- []Change {
42+ []diff. Change {
4243 {0 , 0 , 10 , 5 },
4344 },
4445 },
4546 {"all same" ,
4647 []int {0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 },
4748 []int {0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 },
48- []Change {},
49+ []diff. Change {},
4950 },
5051 {"wrap" ,
5152 []int {1 },
5253 []int {0 , 1 , 2 , 3 },
53- []Change {
54+ []diff. Change {
5455 {0 , 0 , 0 , 1 },
5556 {1 , 2 , 0 , 2 },
5657 },
5758 },
5859 {"snake" ,
5960 []int {0 , 1 , 2 , 3 , 4 , 5 },
6061 []int {1 , 2 , 3 , 4 , 5 , 6 },
61- []Change {
62+ []diff. Change {
6263 {0 , 0 , 1 , 0 },
6364 {6 , 5 , 0 , 1 },
6465 },
@@ -69,7 +70,7 @@ var tests = []testcase{
6970 {"paper fig. 1" ,
7071 []int {1 , 2 , 3 , 1 , 2 , 2 , 1 },
7172 []int {3 , 2 , 1 , 2 , 1 , 3 },
72- []Change {
73+ []diff. Change {
7374 {0 , 0 , 1 , 1 },
7475 {2 , 2 , 1 , 0 },
7576 {5 , 4 , 1 , 0 },
@@ -80,7 +81,7 @@ var tests = []testcase{
8081
8182func TestDiffAB (t * testing.T ) {
8283 for _ , test := range tests {
83- res := Ints (test .a , test .b )
84+ res := diff . Ints (test .a , test .b )
8485 if len (res ) != len (test .res ) {
8586 t .Error (test .name , "expected length" , len (test .res ), "for" , res )
8687 continue
@@ -95,36 +96,87 @@ func TestDiffAB(t *testing.T) {
9596
9697func TestDiffBA (t * testing.T ) {
9798 // interesting: fig.1 Diff(b, a) results in the same path as `diff -d a b`
98- tests [len (tests )- 1 ].res = []Change {
99+ tests [len (tests )- 1 ].res = []diff. Change {
99100 {0 , 0 , 2 , 0 },
100101 {3 , 1 , 1 , 0 },
101102 {5 , 2 , 0 , 1 },
102103 {7 , 5 , 0 , 1 },
103104 }
104105 for _ , test := range tests {
105- res := Ints (test .b , test .a )
106+ res := diff . Ints (test .b , test .a )
106107 if len (res ) != len (test .res ) {
107108 t .Error (test .name , "expected length" , len (test .res ), "for" , res )
108109 continue
109110 }
110111 for i , c := range test .res {
111112 // flip change data also
112- rc := Change {c .B , c .A , c .Ins , c .Del }
113+ rc := diff. Change {c .B , c .A , c .Ins , c .Del }
113114 if rc != res [i ] {
114115 t .Error (test .name , "expected " , rc , "got" , res [i ])
115116 }
116117 }
117118 }
118119}
119120
121+ func diffsEqual (a , b []diff.Change ) bool {
122+ if len (a ) != len (b ) {
123+ return false
124+ }
125+ for i := 0 ; i < len (a ); i ++ {
126+ if a [i ] != b [i ] {
127+ return false
128+ }
129+ }
130+ return true
131+ }
132+
133+ func TestGranularStrings (t * testing.T ) {
134+ a := "abcdefghijklmnopqrstuvwxyza"
135+ b := "AbCdeFghiJklmnOpqrstUvwxyzab"
136+ // each iteration of i increases granularity and will absorb one more lower-letter-followed-by-upper-letters sequence
137+ changesI := [][]diff.Change {
138+ {{0 , 0 , 1 , 1 }, {2 , 2 , 1 , 1 }, {5 , 5 , 1 , 1 }, {9 , 9 , 1 , 1 }, {14 , 14 , 1 , 1 }, {20 , 20 , 1 , 1 }, {27 , 27 , 0 , 1 }},
139+ {{0 , 0 , 3 , 3 }, {5 , 5 , 1 , 1 }, {9 , 9 , 1 , 1 }, {14 , 14 , 1 , 1 }, {20 , 20 , 1 , 1 }, {27 , 27 , 0 , 1 }},
140+ {{0 , 0 , 6 , 6 }, {9 , 9 , 1 , 1 }, {14 , 14 , 1 , 1 }, {20 , 20 , 1 , 1 }, {27 , 27 , 0 , 1 }},
141+ {{0 , 0 , 10 , 10 }, {14 , 14 , 1 , 1 }, {20 , 20 , 1 , 1 }, {27 , 27 , 0 , 1 }},
142+ {{0 , 0 , 15 , 15 }, {20 , 20 , 1 , 1 }, {27 , 27 , 0 , 1 }},
143+ {{0 , 0 , 21 , 21 }, {27 , 27 , 0 , 1 }},
144+ {{0 , 0 , 27 , 28 }},
145+ }
146+ for i := 0 ; i < len (changesI ); i ++ {
147+ diffs := diff .Granular (i , diff .ByteStrings (a , b ))
148+ if ! diffsEqual (diffs , changesI [i ]) {
149+ t .Errorf ("expected %v, got %v" , diffs , changesI [i ])
150+ }
151+ }
152+ }
153+
120154func TestDiffRunes (t * testing.T ) {
121- d := & runes {
122- []rune ("brown fox jumps over the lazy dog" ),
123- []rune ("brwn faax junps ovver the lay dago" ),
155+ a := []rune ("brown fox jumps over the lazy dog" )
156+ b := []rune ("brwn faax junps ovver the lay dago" )
157+ res := diff .Runes (a , b )
158+ echange := []diff.Change {
159+ {2 , 2 , 1 , 0 },
160+ {7 , 6 , 1 , 2 },
161+ {12 , 12 , 1 , 1 },
162+ {18 , 18 , 0 , 1 },
163+ {27 , 28 , 1 , 0 },
164+ {31 , 31 , 0 , 2 },
165+ {32 , 34 , 1 , 0 },
124166 }
125- n , m := len (d .a ), len (d .b )
126- res := Diff (n , m , d )
127- echange := []Change {
167+ for i , c := range res {
168+ t .Log (c )
169+ if c != echange [i ] {
170+ t .Error ("expected" , echange [i ], "got" , c )
171+ }
172+ }
173+ }
174+
175+ func TestDiffByteStrings (t * testing.T ) {
176+ a := "brown fox jumps over the lazy dog"
177+ b := "brwn faax junps ovver the lay dago"
178+ res := diff .ByteStrings (a , b )
179+ echange := []diff.Change {
128180 {2 , 2 , 1 , 0 },
129181 {7 , 6 , 1 , 2 },
130182 {12 , 12 , 1 , 1 },
@@ -141,19 +193,47 @@ func TestDiffRunes(t *testing.T) {
141193 }
142194}
143195
196+ type ints struct { a , b []int }
197+
198+ func (d * ints ) Equal (i , j int ) bool { return d .a [i ] == d .b [j ] }
144199func BenchmarkDiff (b * testing.B ) {
145200 t := tests [len (tests )- 1 ]
146201 d := & ints {t .a , t .b }
147202 n , m := len (d .a ), len (d .b )
148203 for i := 0 ; i < b .N ; i ++ {
149- Diff (n , m , d )
204+ diff .Diff (n , m , d )
205+ }
206+ }
207+
208+ func BenchmarkInts (b * testing.B ) {
209+ t := tests [len (tests )- 1 ]
210+ d1 := t .a
211+ d2 := t .b
212+ for i := 0 ; i < b .N ; i ++ {
213+ diff .Ints (d1 , d2 )
150214 }
151215}
152216
153217func BenchmarkDiffRunes (b * testing.B ) {
154- d := & runes {[]rune ("1231221" ), []rune ("321213" )}
155- n , m := len (d .a ), len (d .b )
218+ d1 := []rune ("1231221" )
219+ d2 := []rune ("321213" )
220+ for i := 0 ; i < b .N ; i ++ {
221+ diff .Runes (d1 , d2 )
222+ }
223+ }
224+
225+ func BenchmarkDiffBytes (b * testing.B ) {
226+ d1 := []byte ("lorem ipsum dolor sit amet consectetur" )
227+ d2 := []byte ("lorem lovesum daenerys targaryen ami consecteture" )
228+ for i := 0 ; i < b .N ; i ++ {
229+ diff .Bytes (d1 , d2 )
230+ }
231+ }
232+
233+ func BenchmarkDiffByteStrings (b * testing.B ) {
234+ d1 := "lorem ipsum dolor sit amet consectetur"
235+ d2 := "lorem lovesum daenerys targaryen ami consecteture"
156236 for i := 0 ; i < b .N ; i ++ {
157- Diff ( n , m , d )
237+ diff . ByteStrings ( d1 , d2 )
158238 }
159239}
0 commit comments