Skip to content

Commit dc6bade

Browse files
committed
add support for filtering, add more tests
1 parent 15ef3f3 commit dc6bade

File tree

2 files changed

+348
-88
lines changed

2 files changed

+348
-88
lines changed
Lines changed: 269 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,293 @@
11
import Autocompleter from './index';
22
import { expect } from 'chai';
33

4-
const FOO_TS = `
4+
const CODE_TS = `
55
6-
export type Foo = {
7-
a: string,
8-
bb: (p1: number) => void
6+
export type MyObject = {
7+
stringProp: string,
8+
functionProp: (p1: number) => void
99
};
1010
11-
export type Params = { param1: string, param2: string };
11+
export type MyFunctionParams = { param1: string, param2: string };
1212
1313
declare global {
14-
declare var foo: Foo;
15-
export function bar(params: Params): void {};
14+
declare var myGlobalObject: MyObject;
15+
export function myGlobalFunction(params: MyFunctionParams): void {};
1616
}
1717
`;
1818

19+
function filterStartingWith({
20+
name,
21+
trigger,
22+
}: {
23+
name: string;
24+
trigger: string;
25+
}): boolean {
26+
name = name.toLocaleLowerCase();
27+
trigger = trigger.toLocaleLowerCase();
28+
29+
return name !== trigger && name.startsWith(trigger);
30+
}
31+
1932
describe('Autocompleter', function () {
20-
let autoCompleter: Autocompleter;
33+
describe('without filter', function () {
34+
let autoCompleter: Autocompleter;
2135

22-
beforeEach(function () {
23-
autoCompleter = new Autocompleter();
24-
});
36+
beforeEach(function () {
37+
autoCompleter = new Autocompleter();
38+
});
2539

26-
it('returns nothing when it has no code', function () {
27-
expect(autoCompleter.autocomplete('foo')).to.deep.equal([]);
28-
expect(autoCompleter.autocomplete('foo', 0)).to.deep.equal([]);
29-
expect(autoCompleter.autocomplete('foo', 1)).to.deep.equal([]);
30-
expect(autoCompleter.autocomplete('foo.')).to.deep.equal([]);
31-
});
40+
it('returns the global scope for a global variable that does not exist', function () {
41+
autoCompleter.updateCode({
42+
'/code.d.ts': CODE_TS,
43+
});
44+
45+
const completions = autoCompleter.autocomplete('doesNotExist');
46+
expect(completions.length).to.be.gt(100);
47+
});
48+
49+
it('returns completions for global variables', function () {
50+
autoCompleter.updateCode({
51+
'/code.d.ts': CODE_TS,
52+
});
53+
54+
// this is just the entire global scope
55+
const completions = autoCompleter.autocomplete('myGlobalFunct');
56+
57+
expect(completions.length).to.be.gt(100);
58+
59+
// one of them is the myGlobalFunction() function
60+
expect(completions).to.deep.include({
61+
kind: 'function',
62+
name: 'myGlobalFunction',
63+
type: 'myGlobalFunction',
64+
});
65+
});
66+
67+
it('returns nothing for a member of a variable that does not exist', function () {
68+
autoCompleter.updateCode({
69+
'/code.d.ts': CODE_TS,
70+
});
71+
72+
expect(
73+
autoCompleter.autocomplete('doesNotExist.somethingElse')
74+
).to.deep.equal([]);
75+
});
76+
77+
it('returns matches for a member of a variable that exists', function () {
78+
autoCompleter.updateCode({
79+
'/code.d.ts': CODE_TS,
80+
});
81+
82+
expect(autoCompleter.autocomplete('myGlobalObject.')).to.deep.equal([
83+
{
84+
kind: 'property',
85+
name: 'functionProp',
86+
type: '(p1: number) => void',
87+
},
88+
{ kind: 'property', name: 'stringProp', type: 'string' },
89+
]);
90+
});
91+
92+
it('returns matches for part of a member of a variable that exists', function () {
93+
autoCompleter.updateCode({
94+
'/code.d.ts': CODE_TS,
95+
});
96+
97+
expect(autoCompleter.autocomplete('myGlobalObject.str')).to.deep.equal([
98+
{
99+
kind: 'property',
100+
name: 'functionProp',
101+
type: '(p1: number) => void',
102+
},
103+
{ kind: 'property', name: 'stringProp', type: 'string' },
104+
]);
105+
});
106+
107+
it('returns matches for an unknown member of a variable that exists', function () {
108+
autoCompleter.updateCode({
109+
'/code.d.ts': CODE_TS,
110+
});
111+
112+
expect(
113+
autoCompleter.autocomplete('myGlobalObject.doesNotExist')
114+
).to.deep.equal([
115+
{
116+
kind: 'property',
117+
name: 'functionProp',
118+
type: '(p1: number) => void',
119+
},
120+
{ kind: 'property', name: 'stringProp', type: 'string' },
121+
]);
122+
});
32123

33-
it('returns completions for members of global variables', function () {
34-
autoCompleter.updateCode({
35-
'/foo.d.ts': FOO_TS,
124+
it('returns the global scope for object parameters of a function that does not exist', function () {
125+
autoCompleter.updateCode({
126+
'/code.d.ts': CODE_TS,
127+
});
128+
129+
const completions = autoCompleter.autocomplete('doesNotExist({');
130+
131+
expect(completions.length).to.be.gt(100);
36132
});
37133

38-
expect(autoCompleter.autocomplete('foo')).to.deep.equal([]);
39-
expect(autoCompleter.autocomplete('foo.')).to.deep.equal([
40-
{ kind: 'property', name: 'a', type: 'string' },
41-
{ kind: 'property', name: 'bb', type: '(p1: number) => void' },
42-
]);
134+
it('returns matches for object parameters of a function that exists', function () {
135+
autoCompleter.updateCode({
136+
'/code.d.ts': CODE_TS,
137+
});
43138

44-
expect(autoCompleter.autocomplete('foo.', 0)).to.deep.equal([]);
45-
expect(autoCompleter.autocomplete('foo.', 1)).to.deep.equal([]);
46-
expect(autoCompleter.autocomplete('foo.', 2)).to.deep.equal([]);
47-
expect(autoCompleter.autocomplete('foo.', 3)).to.deep.equal([]);
139+
const completions = autoCompleter.autocomplete('myGlobalFunction({ p');
140+
141+
expect(completions).to.deep.equal([
142+
{
143+
kind: 'property',
144+
name: 'param1',
145+
type: 'string',
146+
},
147+
{
148+
kind: 'property',
149+
name: 'param2',
150+
type: 'string',
151+
},
152+
]);
153+
});
48154

49-
expect(autoCompleter.autocomplete('foo.b')).to.deep.equal([
50-
{ kind: 'property', name: 'a', type: 'string' },
51-
{ kind: 'property', name: 'bb', type: '(p1: number) => void' },
52-
]);
155+
it('returns matches for part of an object parameter of a function that exists', function () {
156+
autoCompleter.updateCode({
157+
'/code.d.ts': CODE_TS,
158+
});
159+
160+
const completions = autoCompleter.autocomplete('myGlobalFunction({ p');
161+
162+
expect(completions).to.deep.equal([
163+
{
164+
kind: 'property',
165+
name: 'param1',
166+
type: 'string',
167+
},
168+
{
169+
kind: 'property',
170+
name: 'param2',
171+
type: 'string',
172+
},
173+
]);
174+
});
53175

54-
expect(autoCompleter.autocomplete('foo.bar', 4)).to.deep.equal([
55-
{ kind: 'property', name: 'a', type: 'string' },
56-
{ kind: 'property', name: 'bb', type: '(p1: number) => void' },
57-
]);
176+
it('returns matches for an unknown object parameter of a function that exists', function () {
177+
autoCompleter.updateCode({
178+
'/code.d.ts': CODE_TS,
179+
});
180+
181+
const completions = autoCompleter.autocomplete(
182+
'myGlobalFunction({ doesNotExist'
183+
);
184+
expect(completions).to.deep.equal([
185+
{
186+
kind: 'property',
187+
name: 'param1',
188+
type: 'string',
189+
},
190+
{
191+
kind: 'property',
192+
name: 'param2',
193+
type: 'string',
194+
},
195+
]);
196+
});
58197
});
59198

60-
it('returns completions for the fields of object function parameters', function () {
61-
autoCompleter.updateCode({
62-
'/foo.d.ts': FOO_TS,
63-
});
64-
65-
expect(autoCompleter.autocomplete('bar({ par')).to.deep.equal([
66-
{
67-
kind: 'property',
68-
name: 'param1',
69-
type: 'string',
70-
},
71-
{
72-
kind: 'property',
73-
name: 'param2',
74-
type: 'string',
75-
},
76-
]);
199+
describe('with filter', function () {
200+
let autoCompleter: Autocompleter;
201+
202+
beforeEach(function () {
203+
autoCompleter = new Autocompleter({ filter: filterStartingWith });
204+
});
205+
206+
it('returns nothing when it has no code', function () {
207+
expect(autoCompleter.autocomplete('myGlobalOb')).to.deep.equal([]);
208+
expect(autoCompleter.autocomplete('myGlobalObject')).to.deep.equal([]);
209+
expect(autoCompleter.autocomplete('myGlobalObject', 0)).to.deep.equal([]);
210+
expect(autoCompleter.autocomplete('myGlobalObject', 1)).to.deep.equal([]);
211+
expect(autoCompleter.autocomplete('myGlobalObject.')).to.deep.equal([]);
212+
});
213+
214+
it('returns completions for global variables', function () {
215+
autoCompleter.updateCode({
216+
'/code.d.ts': CODE_TS,
217+
});
218+
219+
// it finds the entire global scope and then filters it
220+
expect(autoCompleter.autocomplete('myGlobalFunct')).to.deep.equal([
221+
{
222+
kind: 'function',
223+
name: 'myGlobalFunction',
224+
type: 'myGlobalFunction',
225+
},
226+
]);
227+
});
228+
229+
it('returns completions for members of global variables', function () {
230+
autoCompleter.updateCode({
231+
'/code.d.ts': CODE_TS,
232+
});
233+
234+
expect(autoCompleter.autocomplete('myGlobalObject')).to.deep.equal([]);
235+
expect(autoCompleter.autocomplete('myGlobalObject.')).to.deep.equal([
236+
{
237+
kind: 'property',
238+
name: 'functionProp',
239+
type: '(p1: number) => void',
240+
},
241+
{ kind: 'property', name: 'stringProp', type: 'string' },
242+
]);
243+
244+
expect(autoCompleter.autocomplete('myGlobalObject.', 0)).to.deep.equal(
245+
[]
246+
);
247+
expect(autoCompleter.autocomplete('myGlobalObject.', 1)).to.deep.equal(
248+
[]
249+
);
250+
expect(autoCompleter.autocomplete('myGlobalObject.', 2)).to.deep.equal(
251+
[]
252+
);
253+
expect(autoCompleter.autocomplete('myGlobalObject.', 3)).to.deep.equal(
254+
[]
255+
);
256+
257+
expect(
258+
autoCompleter.autocomplete('myGlobalObject.functionPr')
259+
).to.deep.equal([
260+
{
261+
kind: 'property',
262+
name: 'functionProp',
263+
type: '(p1: number) => void',
264+
},
265+
]);
266+
267+
expect(
268+
autoCompleter.autocomplete('myGlobalObject.typo', 4)
269+
).to.deep.equal([]);
270+
});
271+
272+
it('returns completions for the fields of object function parameters', function () {
273+
autoCompleter.updateCode({
274+
'/code.d.ts': CODE_TS,
275+
});
276+
277+
expect(
278+
autoCompleter.autocomplete('myGlobalFunction({ par')
279+
).to.deep.equal([
280+
{
281+
kind: 'property',
282+
name: 'param1',
283+
type: 'string',
284+
},
285+
{
286+
kind: 'property',
287+
name: 'param2',
288+
type: 'string',
289+
},
290+
]);
291+
});
77292
});
78293
});

0 commit comments

Comments
 (0)