GoPLS Viewer

Home|gopls/internal/diff/lcs/old_test.go
1// Copyright 2022 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package lcs
6
7import (
8    "fmt"
9    "io/ioutil"
10    "log"
11    "math/rand"
12    "strings"
13    "testing"
14)
15
16func TestAlgosOld(t *testing.T) {
17    for ialgo := range []func(*editGraphlcs{forwardbackwardtwosided} {
18        t.Run(strings.Fields("forward backward twosided")[i], func(t *testing.T) {
19            for _tx := range Btests {
20                lim := len(tx.a) + len(tx.b)
21
22                diffslcs := compute(stringSeqs{tx.atx.b}, algolim)
23                check(ttx.alcstx.lcs)
24                checkDiffs(ttx.adiffstx.b)
25
26                diffslcs = compute(stringSeqs{tx.btx.a}, algolim)
27                check(ttx.blcstx.lcs)
28                checkDiffs(ttx.bdiffstx.a)
29            }
30        })
31    }
32}
33
34func TestIntOld(t *testing.T) {
35    // need to avoid any characters in btests
36    lfillrfill := "AAAAAAAAAAAA""BBBBBBBBBBBB"
37    for _tx := range Btests {
38        if len(tx.a) < 2 || len(tx.b) < 2 {
39            continue
40        }
41        left := tx.a + lfill
42        right := tx.b + rfill
43        lim := len(tx.a) + len(tx.b)
44        diffslcs := compute(stringSeqs{leftright}, twosidedlim)
45        check(tleftlcstx.lcs)
46        checkDiffs(tleftdiffsright)
47        diffslcs = compute(stringSeqs{rightleft}, twosidedlim)
48        check(trightlcstx.lcs)
49        checkDiffs(trightdiffsleft)
50
51        left = lfill + tx.a
52        right = rfill + tx.b
53        diffslcs = compute(stringSeqs{leftright}, twosidedlim)
54        check(tleftlcstx.lcs)
55        checkDiffs(tleftdiffsright)
56        diffslcs = compute(stringSeqs{rightleft}, twosidedlim)
57        check(trightlcstx.lcs)
58        checkDiffs(trightdiffsleft)
59    }
60}
61
62func TestSpecialOld(t *testing.T) { // exercises lcs.fix
63    a := "golang.org/x/tools/intern"
64    b := "github.com/google/safehtml/template\"\n\t\"golang.org/x/tools/intern"
65    diffslcs := compute(stringSeqs{ab}, twosided4)
66    if !lcs.valid() {
67        t.Errorf("%d,%v"len(diffs), lcs)
68    }
69}
70
71func TestRegressionOld001(t *testing.T) {
72    a := "// Copyright 2019 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage diff_test\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"golang.org/x/tools/gopls/internal/lsp/diff\"\n\t\"golang.org/x/tools/internal/diff/difftest\"\n\t\"golang.org/x/tools/gopls/internal/span\"\n)\n"
73
74    b := "// Copyright 2019 The Go Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style\n// license that can be found in the LICENSE file.\n\npackage diff_test\n\nimport (\n\t\"fmt\"\n\t\"math/rand\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/google/safehtml/template\"\n\t\"golang.org/x/tools/gopls/internal/lsp/diff\"\n\t\"golang.org/x/tools/internal/diff/difftest\"\n\t\"golang.org/x/tools/gopls/internal/span\"\n)\n"
75    for i := 1i < len(b); i++ {
76        diffslcs := compute(stringSeqs{ab}, twosidedi// 14 from gopls
77        if !lcs.valid() {
78            t.Errorf("%d,%v"len(diffs), lcs)
79        }
80        checkDiffs(tadiffsb)
81    }
82}
83
84func TestRegressionOld002(t *testing.T) {
85    a := "n\"\n)\n"
86    b := "n\"\n\t\"golang.org/x//nnal/stack\"\n)\n"
87    for i := 1i <= len(b); i++ {
88        diffslcs := compute(stringSeqs{ab}, twosidedi)
89        if !lcs.valid() {
90            t.Errorf("%d,%v"len(diffs), lcs)
91        }
92        checkDiffs(tadiffsb)
93    }
94}
95
96func TestRegressionOld003(t *testing.T) {
97    a := "golang.org/x/hello v1.0.0\nrequire golang.org/x/unused v1"
98    b := "golang.org/x/hello v1"
99    for i := 1i <= len(a); i++ {
100        diffslcs := compute(stringSeqs{ab}, twosidedi)
101        if !lcs.valid() {
102            t.Errorf("%d,%v"len(diffs), lcs)
103        }
104        checkDiffs(tadiffsb)
105    }
106}
107
108func TestRandOld(t *testing.T) {
109    rand.Seed(1)
110    for i := 0i < 1000i++ {
111        // TODO(adonovan): use ASCII and bytesSeqs here? The use of
112        // non-ASCII isn't relevant to the property exercised by the test.
113        a := []rune(randstr("abω"16))
114        b := []rune(randstr("abωc"16))
115        seq := runesSeqs{ab}
116
117        const lim = 24 // large enough to get true lcs
118        _forw := compute(seqforwardlim)
119        _back := compute(seqbackwardlim)
120        _two := compute(seqtwosidedlim)
121        if lcslen(two) != lcslen(forw) || lcslen(forw) != lcslen(back) {
122            t.Logf("\n%v\n%v\n%v"forwbacktwo)
123            t.Fatalf("%d forw:%d back:%d two:%d"ilcslen(forw), lcslen(back), lcslen(two))
124        }
125        if !two.valid() || !forw.valid() || !back.valid() {
126            t.Errorf("check failure")
127        }
128    }
129}
130
131// TestDiffAPI tests the public API functions (Diff{Bytes,Strings,Runes})
132// to ensure at least miminal parity of the three representations.
133func TestDiffAPI(t *testing.T) {
134    for _test := range []struct {
135        ab                              string
136        wantStringswantByteswantRunes string
137    }{
138        {"abcXdef""abcxdef""[{3 4 3 4}]""[{3 4 3 4}]""[{3 4 3 4}]"}, // ASCII
139        {"abcωdef""abcΩdef""[{3 5 3 5}]""[{3 5 3 5}]""[{3 4 3 4}]"}, // non-ASCII
140    } {
141
142        gotStrings := fmt.Sprint(DiffStrings(test.atest.b))
143        if gotStrings != test.wantStrings {
144            t.Errorf("DiffStrings(%q, %q) = %v, want %v",
145                test.atest.bgotStringstest.wantStrings)
146        }
147        gotBytes := fmt.Sprint(DiffBytes([]byte(test.a), []byte(test.b)))
148        if gotBytes != test.wantBytes {
149            t.Errorf("DiffBytes(%q, %q) = %v, want %v",
150                test.atest.bgotBytestest.wantBytes)
151        }
152        gotRunes := fmt.Sprint(DiffRunes([]rune(test.a), []rune(test.b)))
153        if gotRunes != test.wantRunes {
154            t.Errorf("DiffRunes(%q, %q) = %v, want %v",
155                test.atest.bgotRunestest.wantRunes)
156        }
157    }
158}
159
160func BenchmarkTwoOld(b *testing.B) {
161    tests := genBench("abc"96)
162    for i := 0i < b.Ni++ {
163        for _tt := range tests {
164            _two := compute(stringSeqs{tt.beforett.after}, twosided100)
165            if !two.valid() {
166                b.Error("check failed")
167            }
168        }
169    }
170}
171
172func BenchmarkForwOld(b *testing.B) {
173    tests := genBench("abc"96)
174    for i := 0i < b.Ni++ {
175        for _tt := range tests {
176            _two := compute(stringSeqs{tt.beforett.after}, forward100)
177            if !two.valid() {
178                b.Error("check failed")
179            }
180        }
181    }
182}
183
184func genBench(set stringn int) []struct{ beforeafter string } {
185    // before and after for benchmarks. 24 strings of length n with
186    // before and after differing at least once, and about 5%
187    rand.Seed(3)
188    var ans []struct{ beforeafter string }
189    for i := 0i < 24i++ {
190        // maybe b should have an approximately known number of diffs
191        a := randstr(setn)
192        cnt := 0
193        bb := make([]rune0n)
194        for _r := range a {
195            if rand.Float64() < .05 {
196                cnt++
197                r = 'N'
198            }
199            bb = append(bbr)
200        }
201        if cnt == 0 {
202            // avoid == shortcut
203            bb[n/2] = 'N'
204        }
205        ans = append(ans, struct{ beforeafter string }{astring(bb)})
206    }
207    return ans
208}
209
210// This benchmark represents a common case for a diff command:
211// large file with a single relatively small diff in the middle.
212// (It's not clear whether this is representative of gopls workloads
213// or whether it is important to gopls diff performance.)
214//
215// TODO(adonovan) opt: it could be much faster.  For example,
216// comparing a file against itself is about 10x faster than with the
217// small deletion in the middle. Strangely, comparing a file against
218// itself minus the last byte is faster still; I don't know why.
219// There is much low-hanging fruit here for further improvement.
220func BenchmarkLargeFileSmallDiff(b *testing.B) {
221    dataerr := ioutil.ReadFile("old.go"// large file
222    if err != nil {
223        log.Fatal(err)
224    }
225
226    n := len(data)
227
228    src := string(data)
229    dst := src[:n*49/100] + src[n*51/100:] // remove 2% from the middle
230    b.Run("string", func(b *testing.B) {
231        for i := 0i < b.Ni++ {
232            compute(stringSeqs{srcdst}, twosidedlen(src)+len(dst))
233        }
234    })
235
236    srcBytes := []byte(src)
237    dstBytes := []byte(dst)
238    b.Run("bytes", func(b *testing.B) {
239        for i := 0i < b.Ni++ {
240            compute(bytesSeqs{srcBytesdstBytes}, twosidedlen(srcBytes)+len(dstBytes))
241        }
242    })
243
244    srcRunes := []rune(src)
245    dstRunes := []rune(dst)
246    b.Run("runes", func(b *testing.B) {
247        for i := 0i < b.Ni++ {
248            compute(runesSeqs{srcRunesdstRunes}, twosidedlen(srcRunes)+len(dstRunes))
249        }
250    })
251}
252
MembersX
TestAlgosOld.RangeStmt_283.algo
TestSpecialOld.a
TestRegressionOld001.b
TestRandOld.BlockStmt.two
BenchmarkForwOld.i
TestAlgosOld.RangeStmt_283.BlockStmt.BlockStmt.RangeStmt_438.tx
TestAlgosOld.RangeStmt_283.BlockStmt.BlockStmt.RangeStmt_438.BlockStmt.lcs
TestRandOld.i
BenchmarkTwoOld
BenchmarkLargeFileSmallDiff.b
TestRegressionOld003.i
TestRandOld.BlockStmt.a
BenchmarkForwOld.tests
BenchmarkForwOld.BlockStmt.RangeStmt_5830.tt
genBench
genBench.BlockStmt.bb
ioutil
TestIntOld.lfill
TestIntOld.rfill
TestRegressionOld002.BlockStmt.lcs
TestRegressionOld003.a
BenchmarkForwOld.b
genBench.set
genBench.n
TestAlgosOld.RangeStmt_283.BlockStmt.BlockStmt.RangeStmt_438.BlockStmt.diffs
TestIntOld.RangeStmt_900.tx
TestIntOld.RangeStmt_900.BlockStmt.diffs
TestRandOld.t
BenchmarkTwoOld.BlockStmt.RangeStmt_5572.BlockStmt._
BenchmarkTwoOld.BlockStmt.RangeStmt_5572.BlockStmt.two
TestSpecialOld
TestRandOld.BlockStmt.back
genBench.i
TestSpecialOld.diffs
TestRegressionOld002.a
TestRegressionOld003.BlockStmt.diffs
BenchmarkLargeFileSmallDiff.n
BenchmarkLargeFileSmallDiff.srcRunes
TestRegressionOld003
TestRandOld
TestDiffAPI.RangeStmt_4580.BlockStmt.gotStrings
TestDiffAPI.RangeStmt_4580.BlockStmt.gotRunes
BenchmarkTwoOld.b
BenchmarkForwOld
TestIntOld.t
genBench.BlockStmt.a
BenchmarkLargeFileSmallDiff.srcBytes
BenchmarkForwOld.BlockStmt.RangeStmt_5830.BlockStmt.two
genBench.BlockStmt.RangeStmt_6391.r
TestAlgosOld.RangeStmt_283.i
TestIntOld
TestSpecialOld.b
TestRegressionOld002
TestRandOld.BlockStmt.seq
TestDiffAPI.RangeStmt_4580.test
BenchmarkLargeFileSmallDiff
BenchmarkLargeFileSmallDiff.err
genBench.BlockStmt.cnt
BenchmarkLargeFileSmallDiff.data
TestAlgosOld.t
TestRegressionOld001.BlockStmt.diffs
TestRandOld.BlockStmt.b
TestRandOld.BlockStmt._
TestDiffAPI.t
BenchmarkTwoOld.tests
BenchmarkLargeFileSmallDiff.dstRunes
BenchmarkLargeFileSmallDiff.BlockStmt.i
TestRegressionOld001.t
TestRegressionOld002.t
TestRegressionOld002.b
TestRegressionOld002.BlockStmt.diffs
TestRandOld.BlockStmt.forw
BenchmarkTwoOld.BlockStmt.RangeStmt_5572.tt
TestRegressionOld002.i
TestRegressionOld003.t
TestAlgosOld
TestSpecialOld.t
TestSpecialOld.lcs
TestRegressionOld001.a
TestRegressionOld001.i
TestRegressionOld001.BlockStmt.lcs
TestRegressionOld003.BlockStmt.lcs
TestRandOld.BlockStmt.lim
BenchmarkTwoOld.i
BenchmarkForwOld.BlockStmt.RangeStmt_5830.BlockStmt._
TestIntOld.RangeStmt_900.BlockStmt.lcs
TestRegressionOld003.b
BenchmarkLargeFileSmallDiff.src
TestDiffAPI.RangeStmt_4580.BlockStmt.gotBytes
BenchmarkLargeFileSmallDiff.dstBytes
TestRegressionOld001
TestDiffAPI
Members
X