1
+ import dedent from 'dedent'
1
2
import { describe , expect , it } from 'vitest'
2
3
3
- import { bestJaccardMatch , getWords } from './bestJaccardMatch'
4
+ import { bestJaccardMatches , getWordOccurrences } from './bestJaccardMatch'
4
5
5
6
const targetSnippet = `
6
7
import { bestJaccardMatch, getWords } from './context'
@@ -25,30 +26,18 @@ describe('getWords', () => {
25
26
})
26
27
`
27
28
28
- const matchSnippet = `
29
- describe('bestJaccardMatch', () => {
30
- it('should return the best match', () => {
31
- const matchText = [
32
- 'foo',
33
- 'bar',
34
- 'baz',
35
- 'qux',
36
- 'quux',
37
- ].join('\n')
38
- })
39
- })
40
- `
29
+ const MAX_MATCHES = 50
41
30
42
31
describe ( 'getWords' , ( ) => {
43
32
it ( 'works with regular text' , ( ) => {
44
- expect ( getWords ( 'foo bar baz' ) ) . toEqual (
33
+ expect ( getWordOccurrences ( 'foo bar baz' ) ) . toEqual (
45
34
new Map < string , number > ( [
46
35
[ 'foo' , 1 ] ,
47
36
[ 'bar' , 1 ] ,
48
37
[ 'baz' , 1 ] ,
49
38
] )
50
39
)
51
- expect ( getWords ( 'running rocks slipped over' ) ) . toEqual (
40
+ expect ( getWordOccurrences ( 'running rocks slipped over' ) ) . toEqual (
52
41
new Map < string , number > ( [
53
42
[ 'run' , 1 ] ,
54
43
[ 'rock' , 1 ] ,
@@ -58,7 +47,7 @@ describe('getWords', () => {
58
47
} )
59
48
60
49
it ( 'works with code snippets' , ( ) => {
61
- expect ( getWords ( targetSnippet ) ) . toEqual (
50
+ expect ( getWordOccurrences ( targetSnippet ) ) . toEqual (
62
51
new Map < string , number > ( [
63
52
[ 'import' , 1 ] ,
64
53
[ 'bestjaccardmatch' , 1 ] ,
@@ -87,61 +76,158 @@ describe('getWords', () => {
87
76
} )
88
77
89
78
describe ( 'bestJaccardMatch' , ( ) => {
90
- it ( 'should return the best match in 5 line windows ' , ( ) => {
91
- const matchText = [
92
- ' foo' ,
93
- ' bar' ,
94
- ' baz' ,
95
- ' qux' ,
96
- ' quux' ,
97
- ' quuz' ,
98
- ' corge' ,
99
- ' grault' ,
100
- ' garply' ,
101
- ' waldo' ,
102
- ' fred' ,
103
- ' plugh' ,
104
- ' xyzzy' ,
105
- ' thud' ,
106
- ] . join ( '\n' )
107
- expect ( bestJaccardMatch ( 'foo\nbar\nbaz' , matchText , 3 ) ) . toEqual ( {
79
+ it ( 'should return the best match' , ( ) => {
80
+ const matchText = dedent `
81
+ foo
82
+ bar
83
+ baz
84
+ qux
85
+ quux
86
+ quuz
87
+ corge
88
+ grault
89
+ garply
90
+ waldo
91
+ fred
92
+ plugh
93
+ xyzzy
94
+ thud
95
+ `
96
+ expect ( bestJaccardMatches ( 'foo\nbar\nbaz' , matchText , 3 , MAX_MATCHES ) [ 0 ] ) . toEqual ( {
108
97
score : 1 ,
109
98
content : 'foo\nbar\nbaz' ,
110
- startLine : 0 ,
111
99
endLine : 2 ,
100
+ startLine : 0 ,
112
101
} )
113
- expect ( bestJaccardMatch ( 'bar\nquux' , matchText , 4 ) ) . toEqual ( {
102
+ expect ( bestJaccardMatches ( 'bar\nquux' , matchText , 4 , MAX_MATCHES ) [ 0 ] ) . toEqual ( {
114
103
score : 0.5 ,
115
104
content : 'bar\nbaz\nqux\nquux' ,
116
- startLine : 1 ,
117
105
endLine : 4 ,
106
+ startLine : 1 ,
118
107
} )
119
108
expect (
120
- bestJaccardMatch (
109
+ bestJaccardMatches (
121
110
[ 'grault' , 'notexist' , 'garply' , 'notexist' , 'waldo' , 'notexist' , 'notexist' ] . join ( '\n' ) ,
122
111
matchText ,
123
- 6
124
- )
112
+ 6 ,
113
+ MAX_MATCHES
114
+ ) [ 0 ]
125
115
) . toEqual ( {
126
116
score : 0.3 ,
127
- content : [ 'corge' , 'grault' , 'garply' , 'waldo' , 'fred' , 'plugh' ] . join ( '\n' ) ,
128
- startLine : 6 ,
129
- endLine : 11 ,
117
+ startLine : 4 ,
118
+ endLine : 9 ,
119
+ content : [ 'quux' , 'quuz' , 'corge' , 'grault' , 'garply' , 'waldo' ] . join ( '\n' ) ,
130
120
} )
131
121
} )
132
122
123
+ it ( 'returns more than one match' , ( ) => {
124
+ const matchText = dedent `
125
+ foo
126
+ bar
127
+ baz
128
+ qux
129
+ foo
130
+ quuz
131
+ corge
132
+ grault
133
+ garply
134
+ waldo
135
+ fred
136
+ plugh
137
+ xyzzy
138
+ thud`
139
+
140
+ const matches = bestJaccardMatches ( 'foo\nbar\nbaz' , matchText , 3 , MAX_MATCHES )
141
+
142
+ expect ( matches ) . toHaveLength ( 4 )
143
+ expect ( matches . map ( match => match . content . split ( '\n' ) ) ) . toEqual ( [
144
+ [ 'foo' , 'bar' , 'baz' ] ,
145
+ [ 'qux' , 'foo' , 'quuz' ] ,
146
+ [ 'corge' , 'grault' , 'garply' ] ,
147
+ [ 'waldo' , 'fred' , 'plugh' ] ,
148
+ ] )
149
+ } )
150
+
133
151
it ( 'works with code snippets' , ( ) => {
134
- expect ( bestJaccardMatch ( targetSnippet , matchSnippet , 5 ) ) . toMatchInlineSnapshot ( `
152
+ expect (
153
+ bestJaccardMatches (
154
+ targetSnippet ,
155
+ dedent `
156
+ describe('bestJaccardMatch', () => {
157
+ it('should return the best match', () => {
158
+ const matchText = [
159
+ 'foo',
160
+ 'bar',
161
+ 'baz',
162
+ 'qux',
163
+ 'quux',
164
+ ].join('\n')
165
+ })
166
+ })
167
+ ` ,
168
+ 5 ,
169
+ MAX_MATCHES
170
+ ) [ 0 ]
171
+ ) . toMatchInlineSnapshot ( `
135
172
{
136
173
"content": "describe('bestJaccardMatch', () => {
137
174
it('should return the best match', () => {
138
175
const matchText = [
139
176
'foo',
140
177
'bar',",
141
- "endLine": 5 ,
178
+ "endLine": 4 ,
142
179
"score": 0.08695652173913043,
143
- "startLine": 1 ,
180
+ "startLine": 0 ,
144
181
}
145
182
` )
146
183
} )
184
+
185
+ it ( 'works for input texts that are shorter than the window size' , ( ) => {
186
+ expect ( bestJaccardMatches ( 'foo' , 'foo' , 10 , MAX_MATCHES ) [ 0 ] ) . toEqual ( {
187
+ content : 'foo' ,
188
+ endLine : 0 ,
189
+ score : 1 ,
190
+ startLine : 0 ,
191
+ } )
192
+ } )
193
+
194
+ it ( 'skips over windows with empty start lines' , ( ) => {
195
+ const matches = bestJaccardMatches (
196
+ 'foo' ,
197
+ dedent `
198
+ // foo
199
+ // unrelated 1
200
+ // unrelated 2
201
+
202
+
203
+ // foo
204
+ // unrelated 3
205
+ // unrelated 4
206
+ ` ,
207
+ 3 ,
208
+ MAX_MATCHES
209
+ )
210
+
211
+ expect ( matches [ 0 ] . content ) . toBe ( '// foo\n// unrelated 1\n// unrelated 2' )
212
+ expect ( matches [ 1 ] . content ) . toBe ( '// foo\n// unrelated 3\n// unrelated 4' )
213
+ } )
214
+
215
+ it ( "does not skips over windows with empty start lines if we're at the en" , ( ) => {
216
+ const matches = bestJaccardMatches (
217
+ targetSnippet ,
218
+ dedent `
219
+ // foo
220
+ // unrelated
221
+ // unrelated
222
+
223
+
224
+ // foo
225
+ ` ,
226
+ 3 ,
227
+ MAX_MATCHES
228
+ )
229
+
230
+ expect ( matches [ 0 ] . content ) . toBe ( '\n\n// foo' )
231
+ expect ( matches [ 1 ] . content ) . toBe ( '// foo\n// unrelated\n// unrelated' )
232
+ } )
147
233
} )
0 commit comments