filters.test.ts 20.1 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4 5 6 7
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';

import * as assert from 'assert';
8
import { IFilter, or, matchesPrefix, matchesStrictPrefix, matchesCamelCase, matchesSubString, matchesContiguousSubString, matchesWords, fuzzyScore, IMatch, fuzzyScoreGraceful, fuzzyScoreGracefulAggressive, FuzzyScorer } from 'vs/base/common/filters';
E
Erich Gamma 已提交
9 10

function filterOk(filter: IFilter, word: string, wordToMatchAgainst: string, highlights?: { start: number; end: number; }[]) {
11
	let r = filter(word, wordToMatchAgainst);
E
Erich Gamma 已提交
12 13 14 15 16 17
	assert(r);
	if (highlights) {
		assert.deepEqual(r, highlights);
	}
}

18
function filterNotOk(filter: IFilter, word: string, suggestion: string) {
E
Erich Gamma 已提交
19 20 21
	assert(!filter(word, suggestion));
}

22
suite('Filters', () => {
23
	test('or', () => {
24 25 26 27
		let filter: IFilter;
		let counters: number[];
		let newFilter = function (i: number, r: boolean): IFilter {
			return function (): IMatch[] { counters[i]++; return r as any; };
E
Erich Gamma 已提交
28 29
		};

J
Johannes Rieken 已提交
30
		counters = [0, 0];
E
Erich Gamma 已提交
31
		filter = or(newFilter(0, false), newFilter(1, false));
32
		filterNotOk(filter, 'anything', 'anything');
J
Johannes Rieken 已提交
33
		assert.deepEqual(counters, [1, 1]);
E
Erich Gamma 已提交
34

J
Johannes Rieken 已提交
35
		counters = [0, 0];
E
Erich Gamma 已提交
36
		filter = or(newFilter(0, true), newFilter(1, false));
37
		filterOk(filter, 'anything', 'anything');
J
Johannes Rieken 已提交
38
		assert.deepEqual(counters, [1, 0]);
E
Erich Gamma 已提交
39

J
Johannes Rieken 已提交
40
		counters = [0, 0];
E
Erich Gamma 已提交
41
		filter = or(newFilter(0, true), newFilter(1, true));
42
		filterOk(filter, 'anything', 'anything');
J
Johannes Rieken 已提交
43
		assert.deepEqual(counters, [1, 0]);
E
Erich Gamma 已提交
44

J
Johannes Rieken 已提交
45
		counters = [0, 0];
E
Erich Gamma 已提交
46
		filter = or(newFilter(0, false), newFilter(1, true));
47
		filterOk(filter, 'anything', 'anything');
J
Johannes Rieken 已提交
48
		assert.deepEqual(counters, [1, 1]);
E
Erich Gamma 已提交
49 50
	});

51 52 53 54 55 56 57 58 59 60
	test('PrefixFilter - case sensitive', function () {
		filterNotOk(matchesStrictPrefix, '', '');
		filterOk(matchesStrictPrefix, '', 'anything', []);
		filterOk(matchesStrictPrefix, 'alpha', 'alpha', [{ start: 0, end: 5 }]);
		filterOk(matchesStrictPrefix, 'alpha', 'alphasomething', [{ start: 0, end: 5 }]);
		filterNotOk(matchesStrictPrefix, 'alpha', 'alp');
		filterOk(matchesStrictPrefix, 'a', 'alpha', [{ start: 0, end: 1 }]);
		filterNotOk(matchesStrictPrefix, 'x', 'alpha');
		filterNotOk(matchesStrictPrefix, 'A', 'alpha');
		filterNotOk(matchesStrictPrefix, 'AlPh', 'alPHA');
E
Erich Gamma 已提交
61 62
	});

63 64 65 66 67
	test('PrefixFilter - ignore case', function () {
		filterOk(matchesPrefix, 'alpha', 'alpha', [{ start: 0, end: 5 }]);
		filterOk(matchesPrefix, 'alpha', 'alphasomething', [{ start: 0, end: 5 }]);
		filterNotOk(matchesPrefix, 'alpha', 'alp');
		filterOk(matchesPrefix, 'a', 'alpha', [{ start: 0, end: 1 }]);
68
		filterOk(matchesPrefix, 'ä', 'Älpha', [{ start: 0, end: 1 }]);
69 70 71
		filterNotOk(matchesPrefix, 'x', 'alpha');
		filterOk(matchesPrefix, 'A', 'alpha', [{ start: 0, end: 1 }]);
		filterOk(matchesPrefix, 'AlPh', 'alPHA', [{ start: 0, end: 4 }]);
72
		filterNotOk(matchesPrefix, 'T', '4'); // see https://github.com/Microsoft/vscode/issues/22401
E
Erich Gamma 已提交
73 74
	});

75
	test('CamelCaseFilter', () => {
76 77 78 79 80 81
		filterNotOk(matchesCamelCase, '', '');
		filterOk(matchesCamelCase, '', 'anything', []);
		filterOk(matchesCamelCase, 'alpha', 'alpha', [{ start: 0, end: 5 }]);
		filterOk(matchesCamelCase, 'AlPhA', 'alpha', [{ start: 0, end: 5 }]);
		filterOk(matchesCamelCase, 'alpha', 'alphasomething', [{ start: 0, end: 5 }]);
		filterNotOk(matchesCamelCase, 'alpha', 'alp');
E
Erich Gamma 已提交
82

83
		filterOk(matchesCamelCase, 'c', 'CamelCaseRocks', [
E
Erich Gamma 已提交
84 85
			{ start: 0, end: 1 }
		]);
86
		filterOk(matchesCamelCase, 'cc', 'CamelCaseRocks', [
E
Erich Gamma 已提交
87 88 89
			{ start: 0, end: 1 },
			{ start: 5, end: 6 }
		]);
90
		filterOk(matchesCamelCase, 'ccr', 'CamelCaseRocks', [
E
Erich Gamma 已提交
91 92 93 94
			{ start: 0, end: 1 },
			{ start: 5, end: 6 },
			{ start: 9, end: 10 }
		]);
95
		filterOk(matchesCamelCase, 'cacr', 'CamelCaseRocks', [
E
Erich Gamma 已提交
96 97 98 99
			{ start: 0, end: 2 },
			{ start: 5, end: 6 },
			{ start: 9, end: 10 }
		]);
100
		filterOk(matchesCamelCase, 'cacar', 'CamelCaseRocks', [
E
Erich Gamma 已提交
101 102 103 104
			{ start: 0, end: 2 },
			{ start: 5, end: 7 },
			{ start: 9, end: 10 }
		]);
105
		filterOk(matchesCamelCase, 'ccarocks', 'CamelCaseRocks', [
E
Erich Gamma 已提交
106 107 108 109
			{ start: 0, end: 1 },
			{ start: 5, end: 7 },
			{ start: 9, end: 14 }
		]);
110
		filterOk(matchesCamelCase, 'cr', 'CamelCaseRocks', [
E
Erich Gamma 已提交
111 112 113
			{ start: 0, end: 1 },
			{ start: 9, end: 10 }
		]);
114
		filterOk(matchesCamelCase, 'fba', 'FooBarAbe', [
E
Erich Gamma 已提交
115 116 117
			{ start: 0, end: 1 },
			{ start: 3, end: 5 }
		]);
118
		filterOk(matchesCamelCase, 'fbar', 'FooBarAbe', [
E
Erich Gamma 已提交
119 120 121
			{ start: 0, end: 1 },
			{ start: 3, end: 6 }
		]);
122
		filterOk(matchesCamelCase, 'fbara', 'FooBarAbe', [
E
Erich Gamma 已提交
123 124 125
			{ start: 0, end: 1 },
			{ start: 3, end: 7 }
		]);
126
		filterOk(matchesCamelCase, 'fbaa', 'FooBarAbe', [
E
Erich Gamma 已提交
127 128 129 130
			{ start: 0, end: 1 },
			{ start: 3, end: 5 },
			{ start: 6, end: 7 }
		]);
131
		filterOk(matchesCamelCase, 'fbaab', 'FooBarAbe', [
E
Erich Gamma 已提交
132 133 134 135
			{ start: 0, end: 1 },
			{ start: 3, end: 5 },
			{ start: 6, end: 8 }
		]);
136
		filterOk(matchesCamelCase, 'c2d', 'canvasCreation2D', [
E
Erich Gamma 已提交
137 138 139
			{ start: 0, end: 1 },
			{ start: 14, end: 16 }
		]);
140
		filterOk(matchesCamelCase, 'cce', '_canvasCreationEvent', [
E
Erich Gamma 已提交
141 142 143 144 145 146
			{ start: 1, end: 2 },
			{ start: 7, end: 8 },
			{ start: 15, end: 16 }
		]);
	});

147
	test('CamelCaseFilter - #19256', function () {
E
Erich Gamma 已提交
148 149 150 151
		assert(matchesCamelCase('Debug Console', 'Open: Debug Console'));
		assert(matchesCamelCase('Debug console', 'Open: Debug Console'));
		assert(matchesCamelCase('debug console', 'Open: Debug Console'));
	});
B
Benjamin Pasero 已提交
152

153
	test('matchesContiguousSubString', () => {
154
		filterOk(matchesContiguousSubString, 'cela', 'cancelAnimationFrame()', [
B
Benjamin Pasero 已提交
155 156 157 158
			{ start: 3, end: 7 }
		]);
	});

159
	test('matchesSubString', () => {
160
		filterOk(matchesSubString, 'cmm', 'cancelAnimationFrame()', [
B
Benjamin Pasero 已提交
161 162 163 164
			{ start: 0, end: 1 },
			{ start: 9, end: 10 },
			{ start: 18, end: 19 }
		]);
165 166 167 168 169 170 171 172 173 174 175 176
		filterOk(matchesSubString, 'abc', 'abcabc', [
			{ start: 0, end: 3 },
		]);
		filterOk(matchesSubString, 'abc', 'aaabbbccc', [
			{ start: 0, end: 1 },
			{ start: 3, end: 4 },
			{ start: 6, end: 7 },
		]);
	});

	test('matchesSubString performance (#35346)', function () {
		filterNotOk(matchesSubString, 'aaaaaaaaaaaaaaaaaaaax', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa');
B
Benjamin Pasero 已提交
177
	});
178

179
	test('WordFilter', () => {
180 181 182 183 184 185 186 187 188
		filterOk(matchesWords, 'alpha', 'alpha', [{ start: 0, end: 5 }]);
		filterOk(matchesWords, 'alpha', 'alphasomething', [{ start: 0, end: 5 }]);
		filterNotOk(matchesWords, 'alpha', 'alp');
		filterOk(matchesWords, 'a', 'alpha', [{ start: 0, end: 1 }]);
		filterNotOk(matchesWords, 'x', 'alpha');
		filterOk(matchesWords, 'A', 'alpha', [{ start: 0, end: 1 }]);
		filterOk(matchesWords, 'AlPh', 'alPHA', [{ start: 0, end: 4 }]);
		assert(matchesWords('Debug Console', 'Open: Debug Console'));

J
Johannes Rieken 已提交
189 190 191
		filterOk(matchesWords, 'gp', 'Git: Pull', [{ start: 0, end: 1 }, { start: 5, end: 6 }]);
		filterOk(matchesWords, 'g p', 'Git: Pull', [{ start: 0, end: 1 }, { start: 4, end: 6 }]);
		filterOk(matchesWords, 'gipu', 'Git: Pull', [{ start: 0, end: 2 }, { start: 5, end: 7 }]);
192

J
Johannes Rieken 已提交
193 194 195
		filterOk(matchesWords, 'gp', 'Category: Git: Pull', [{ start: 10, end: 11 }, { start: 15, end: 16 }]);
		filterOk(matchesWords, 'g p', 'Category: Git: Pull', [{ start: 10, end: 11 }, { start: 14, end: 16 }]);
		filterOk(matchesWords, 'gipu', 'Category: Git: Pull', [{ start: 10, end: 12 }, { start: 15, end: 17 }]);
196 197 198 199 200

		filterNotOk(matchesWords, 'it', 'Git: Pull');
		filterNotOk(matchesWords, 'll', 'Git: Pull');

		filterOk(matchesWords, 'git: プル', 'git: プル', [{ start: 0, end: 7 }]);
J
Johannes Rieken 已提交
201
		filterOk(matchesWords, 'git プル', 'git: プル', [{ start: 0, end: 3 }, { start: 4, end: 7 }]);
202 203

		filterOk(matchesWords, 'öäk', 'Öhm: Älles Klar', [{ start: 0, end: 1 }, { start: 5, end: 6 }, { start: 11, end: 12 }]);
S
Sandeep Somavarapu 已提交
204 205 206

		assert.ok(matchesWords('gipu', 'Category: Git: Pull', true) === null);
		assert.deepEqual(matchesWords('pu', 'Category: Git: Pull', true), [{ start: 15, end: 17 }]);
207
	});
J
Johannes Rieken 已提交
208

209 210
	function assertMatches(pattern: string, word: string, decoratedWord: string, filter: FuzzyScorer, opts: { patternPos?: number, wordPos?: number, firstMatchCanBeWeak?: boolean } = {}) {
		let r = filter(pattern, pattern.toLowerCase(), opts.patternPos || 0, word, word.toLowerCase(), opts.wordPos || 0, opts.firstMatchCanBeWeak || false);
211
		assert.ok(!decoratedWord === (!r || r[1].length === 0));
212 213 214 215 216 217 218 219
		if (r) {
			const [, matches] = r;
			let pos = 0;
			for (let i = 0; i < matches.length; i++) {
				let actual = matches[i];
				let expected = decoratedWord.indexOf('^', pos) - i;
				assert.equal(actual, expected);
				pos = expected + 1 + i;
J
Johannes Rieken 已提交
220 221
			}
		}
222
	}
J
Johannes Rieken 已提交
223

J
Johannes Rieken 已提交
224 225 226
	test('fuzzyScore, #23215', function () {
		assertMatches('tit', 'win.tit', 'win.^t^i^t', fuzzyScore);
		assertMatches('title', 'win.title', 'win.^t^i^t^l^e', fuzzyScore);
227
		assertMatches('WordCla', 'WordCharacterClassifier', '^W^o^r^dCharacter^C^l^assifier', fuzzyScore);
J
Johannes Rieken 已提交
228 229
		assertMatches('WordCCla', 'WordCharacterClassifier', '^W^o^r^d^Character^C^l^assifier', fuzzyScore);
	});
230

231 232 233
	test('fuzzyScore, #23332', function () {
		assertMatches('dete', '"editor.quickSuggestionsDelay"', undefined, fuzzyScore);
	});
J
Johannes Rieken 已提交
234

235 236 237 238 239
	test('fuzzyScore, #23190', function () {
		assertMatches('c:\\do', '& \'C:\\Documents and Settings\'', '& \'^C^:^\\^D^ocuments and Settings\'', fuzzyScore);
		assertMatches('c:\\do', '& \'c:\\Documents and Settings\'', '& \'^c^:^\\^D^ocuments and Settings\'', fuzzyScore);
	});

240 241 242 243 244 245 246
	test('fuzzyScore, #23581', function () {
		assertMatches('close', 'css.lint.importStatement', '^css.^lint.imp^ort^Stat^ement', fuzzyScore);
		assertMatches('close', 'css.colorDecorators.enable', '^css.co^l^orDecorator^s.^enable', fuzzyScore);
		assertMatches('close', 'workbench.quickOpen.closeOnFocusOut', 'workbench.quickOpen.^c^l^o^s^eOnFocusOut', fuzzyScore);
		assertTopScore(fuzzyScore, 'close', 2, 'css.lint.importStatement', 'css.colorDecorators.enable', 'workbench.quickOpen.closeOnFocusOut');
	});

247 248 249 250 251
	test('fuzzyScore, #23458', function () {
		assertMatches('highlight', 'editorHoverHighlight', 'editorHover^H^i^g^h^l^i^g^h^t', fuzzyScore);
		assertMatches('hhighlight', 'editorHoverHighlight', 'editor^Hover^H^i^g^h^l^i^g^h^t', fuzzyScore);
		assertMatches('dhhighlight', 'editorHoverHighlight', undefined, fuzzyScore);
	});
252 253 254 255 256 257
	test('fuzzyScore, #23746', function () {
		assertMatches('-moz', '-moz-foo', '^-^m^o^z-foo', fuzzyScore);
		assertMatches('moz', '-moz-foo', '-^m^o^z-foo', fuzzyScore);
		assertMatches('moz', '-moz-animation', '-^m^o^z-animation', fuzzyScore);
		assertMatches('moza', '-moz-animation', '-^m^o^z-^animation', fuzzyScore);
	});
258

259
	test('fuzzyScore', () => {
260 261 262 263
		assertMatches('ab', 'abA', '^a^bA', fuzzyScore);
		assertMatches('ccm', 'cacmelCase', '^ca^c^melCase', fuzzyScore);
		assertMatches('bti', 'the_black_knight', undefined, fuzzyScore);
		assertMatches('ccm', 'camelCase', undefined, fuzzyScore);
264
		assertMatches('cmcm', 'camelCase', undefined, fuzzyScore);
265 266
		assertMatches('BK', 'the_black_knight', 'the_^black_^knight', fuzzyScore);
		assertMatches('KeyboardLayout=', 'KeyboardLayout', undefined, fuzzyScore);
267 268
		assertMatches('LLL', 'SVisualLoggerLogsList', 'SVisual^Logger^Logs^List', fuzzyScore);
		assertMatches('LLLL', 'SVilLoLosLi', undefined, fuzzyScore);
269
		assertMatches('LLLL', 'SVisualLoggerLogsList', undefined, fuzzyScore);
270 271
		assertMatches('TEdit', 'TextEdit', '^Text^E^d^i^t', fuzzyScore);
		assertMatches('TEdit', 'TextEditor', '^Text^E^d^i^tor', fuzzyScore);
272
		assertMatches('TEdit', 'Textedit', '^T^exte^d^i^t', fuzzyScore);
273 274 275 276
		assertMatches('TEdit', 'text_edit', '^text_^e^d^i^t', fuzzyScore);
		assertMatches('TEditDit', 'TextEditorDecorationType', '^Text^E^d^i^tor^Decorat^ion^Type', fuzzyScore);
		assertMatches('TEdit', 'TextEditorDecorationType', '^Text^E^d^i^torDecorationType', fuzzyScore);
		assertMatches('Tedit', 'TextEdit', '^Text^E^d^i^t', fuzzyScore);
277 278 279 280 281 282 283 284
		assertMatches('ba', '?AB?', undefined, fuzzyScore);
		assertMatches('bkn', 'the_black_knight', 'the_^black_^k^night', fuzzyScore);
		assertMatches('bt', 'the_black_knight', 'the_^black_knigh^t', fuzzyScore);
		assertMatches('ccm', 'camelCasecm', '^camel^Casec^m', fuzzyScore);
		assertMatches('fdm', 'findModel', '^fin^d^Model', fuzzyScore);
		assertMatches('fob', 'foobar', '^f^oo^bar', fuzzyScore);
		assertMatches('fobz', 'foobar', undefined, fuzzyScore);
		assertMatches('foobar', 'foobar', '^f^o^o^b^a^r', fuzzyScore);
285 286
		assertMatches('form', 'editor.formatOnSave', 'editor.^f^o^r^matOnSave', fuzzyScore);
		assertMatches('g p', 'Git: Pull', '^Git:^ ^Pull', fuzzyScore);
287
		assertMatches('g p', 'Git: Pull', '^Git:^ ^Pull', fuzzyScore);
288
		assertMatches('gip', 'Git: Pull', '^G^it: ^Pull', fuzzyScore);
289 290 291
		assertMatches('gip', 'Git: Pull', '^G^it: ^Pull', fuzzyScore);
		assertMatches('gp', 'Git: Pull', '^Git: ^Pull', fuzzyScore);
		assertMatches('gp', 'Git_Git_Pull', '^Git_Git_^Pull', fuzzyScore);
292
		assertMatches('is', 'ImportStatement', '^Import^Statement', fuzzyScore);
293
		assertMatches('is', 'isValid', '^i^sValid', fuzzyScore);
J
Johannes Rieken 已提交
294
		assertMatches('lowrd', 'lowWord', '^l^o^wWo^r^d', fuzzyScore);
295 296 297 298 299 300
		assertMatches('myvable', 'myvariable', '^m^y^v^aria^b^l^e', fuzzyScore);
		assertMatches('no', '', undefined, fuzzyScore);
		assertMatches('no', 'match', undefined, fuzzyScore);
		assertMatches('ob', 'foobar', undefined, fuzzyScore);
		assertMatches('sl', 'SVisualLoggerLogsList', '^SVisual^LoggerLogsList', fuzzyScore);
		assertMatches('sllll', 'SVisualLoggerLogsList', '^SVisua^l^Logger^Logs^List', fuzzyScore);
301
		assertMatches('Three', 'HTMLHRElement', undefined, fuzzyScore);
J
Johannes Rieken 已提交
302
		assertMatches('Three', 'Three', '^T^h^r^e^e', fuzzyScore);
303 304 305 306 307 308 309
		assertMatches('fo', 'barfoo', undefined, fuzzyScore);
		assertMatches('fo', 'bar_foo', 'bar_^f^oo', fuzzyScore);
		assertMatches('fo', 'bar_Foo', 'bar_^F^oo', fuzzyScore);
		assertMatches('fo', 'bar foo', 'bar ^f^oo', fuzzyScore);
		assertMatches('fo', 'bar.foo', 'bar.^f^oo', fuzzyScore);
		assertMatches('fo', 'bar/foo', 'bar/^f^oo', fuzzyScore);
		assertMatches('fo', 'bar\\foo', 'bar\\^f^oo', fuzzyScore);
310
	});
311

312
	test('fuzzyScore (first match can be weak)', function () {
313 314 315 316 317

		assertMatches('Three', 'HTMLHRElement', 'H^TML^H^R^El^ement', fuzzyScore, { firstMatchCanBeWeak: true });
		assertMatches('tor', 'constructor', 'construc^t^o^r', fuzzyScore, { firstMatchCanBeWeak: true });
		assertMatches('ur', 'constructor', 'constr^ucto^r', fuzzyScore, { firstMatchCanBeWeak: true });
		assertTopScore(fuzzyScore, 'tor', 2, 'constructor', 'Thor', 'cTor');
318 319
	});

320 321 322 323 324 325 326 327 328 329
	test('fuzzyScore, many matches', function () {

		assertMatches(
			'aaaaaa',
			'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
			'^a^a^a^a^a^aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa',
			fuzzyScore
		);
	});

330
	test('fuzzyScore, issue #26423', function () {
331 332 333

		assertMatches('baba', 'abababab', undefined, fuzzyScore);

334 335 336 337 338 339 340 341 342 343 344 345 346 347
		assertMatches(
			'fsfsfs',
			'dsafdsafdsafdsafdsafdsafdsafasdfdsa',
			undefined,
			fuzzyScore
		);
		assertMatches(
			'fsfsfsfsfsfsfsf',
			'dsafdsafdsafdsafdsafdsafdsafasdfdsafdsafdsafdsafdsfdsafdsfdfdfasdnfdsajfndsjnafjndsajlknfdsa',
			undefined,
			fuzzyScore
		);
	});

J
Johannes Rieken 已提交
348 349 350 351 352
	test('Fuzzy IntelliSense matching vs Haxe metadata completion, #26995', function () {
		assertMatches('f', ':Foo', ':^Foo', fuzzyScore);
		assertMatches('f', ':foo', ':^foo', fuzzyScore);
	});

J
Johannes Rieken 已提交
353 354 355
	test('Cannot set property \'1\' of undefined, #26511', function () {
		let word = new Array<void>(123).join('a');
		let pattern = new Array<void>(120).join('a');
356
		fuzzyScore(pattern, pattern.toLowerCase(), 0, word, word.toLowerCase(), 0, false);
J
Johannes Rieken 已提交
357 358 359
		assert.ok(true); // must not explode
	});

360
	test('Vscode 1.12 no longer obeys \'sortText\' in completion items (from language server), #26096', function () {
361 362
		assertMatches('  ', '  group', undefined, fuzzyScore, { patternPos: 2 });
		assertMatches('  g', '  group', '  ^group', fuzzyScore, { patternPos: 2 });
363 364 365
		assertMatches('g', '  group', '  ^group', fuzzyScore);
		assertMatches('g g', '  groupGroup', undefined, fuzzyScore);
		assertMatches('g g', '  group Group', '  ^group^ ^Group', fuzzyScore);
366
		assertMatches(' g g', '  group Group', '  ^group^ ^Group', fuzzyScore, { patternPos: 1 });
367 368 369 370 371
		assertMatches('zz', 'zzGroup', '^z^zGroup', fuzzyScore);
		assertMatches('zzg', 'zzGroup', '^z^z^Group', fuzzyScore);
		assertMatches('g', 'zzGroup', 'zz^Group', fuzzyScore);
	});

J
Johannes Rieken 已提交
372
	function assertTopScore(filter: typeof fuzzyScore, pattern: string, expected: number, ...words: string[]) {
373
		let topScore = -(100 * 10);
J
Johannes Rieken 已提交
374 375 376
		let topIdx = 0;
		for (let i = 0; i < words.length; i++) {
			const word = words[i];
377
			const m = filter(pattern, pattern.toLowerCase(), 0, word, word.toLowerCase(), 0, false);
J
Johannes Rieken 已提交
378 379 380 381 382
			if (m) {
				const [score] = m;
				if (score > topScore) {
					topScore = score;
					topIdx = i;
383 384 385
				}
			}
		}
J
Johannes Rieken 已提交
386 387 388 389 390 391 392
		assert.equal(topIdx, expected, `${pattern} -> actual=${words[topIdx]} <> expected=${words[expected]}`);
	}

	test('topScore - fuzzyScore', function () {

		assertTopScore(fuzzyScore, 'cons', 2, 'ArrayBufferConstructor', 'Console', 'console');
		assertTopScore(fuzzyScore, 'Foo', 1, 'foo', 'Foo', 'foo');
393

394 395
		// #24904
		assertTopScore(fuzzyScore, 'onMess', 1, 'onmessage', 'onMessage', 'onThisMegaEscape');
J
Johannes Rieken 已提交
396

J
Johannes Rieken 已提交
397 398 399 400
		assertTopScore(fuzzyScore, 'CC', 1, 'camelCase', 'CamelCase');
		assertTopScore(fuzzyScore, 'cC', 0, 'camelCase', 'CamelCase');
		// assertTopScore(fuzzyScore, 'cC', 1, 'ccfoo', 'camelCase');
		// assertTopScore(fuzzyScore, 'cC', 1, 'ccfoo', 'camelCase', 'foo-cC-bar');
J
Johannes Rieken 已提交
401

402
		// issue #17836
J
Johannes Rieken 已提交
403
		// assertTopScore(fuzzyScore, 'TEdit', 1, 'TextEditorDecorationType', 'TextEdit', 'TextEditor');
404
		assertTopScore(fuzzyScore, 'p', 4, 'parse', 'posix', 'pafdsa', 'path', 'p');
J
Johannes Rieken 已提交
405
		assertTopScore(fuzzyScore, 'pa', 0, 'parse', 'pafdsa', 'path');
406 407

		// issue #14583
408
		assertTopScore(fuzzyScore, 'log', 3, 'HTMLOptGroupElement', 'ScrollLogicalPosition', 'SVGFEMorphologyElement', 'log', 'logger');
J
Johannes Rieken 已提交
409
		assertTopScore(fuzzyScore, 'e', 2, 'AbstractWorker', 'ActiveXObject', 'else');
410 411

		// issue #14446
J
Johannes Rieken 已提交
412
		assertTopScore(fuzzyScore, 'workbench.sideb', 1, 'workbench.editor.defaultSideBySideLayout', 'workbench.sideBar.location');
413 414

		// issue #11423
J
Johannes Rieken 已提交
415 416 417
		assertTopScore(fuzzyScore, 'editor.r', 2, 'diffEditor.renderSideBySide', 'editor.overviewRulerlanes', 'editor.renderControlCharacter', 'editor.renderWhitespace');
		// assertTopScore(fuzzyScore, 'editor.R', 1, 'diffEditor.renderSideBySide', 'editor.overviewRulerlanes', 'editor.renderControlCharacter', 'editor.renderWhitespace');
		// assertTopScore(fuzzyScore, 'Editor.r', 0, 'diffEditor.renderSideBySide', 'editor.overviewRulerlanes', 'editor.renderControlCharacter', 'editor.renderWhitespace');
418

J
Johannes Rieken 已提交
419
		assertTopScore(fuzzyScore, '-mo', 1, '-ms-ime-mode', '-moz-columns');
420
		// // dupe, issue #14861
J
Johannes Rieken 已提交
421
		assertTopScore(fuzzyScore, 'convertModelPosition', 0, 'convertModelPositionToViewPosition', 'convertViewToModelPosition');
422
		// // dupe, issue #14942
J
Johannes Rieken 已提交
423
		assertTopScore(fuzzyScore, 'is', 0, 'isValidViewletId', 'import statement');
424

425
		assertTopScore(fuzzyScore, 'title', 1, 'files.trimTrailingWhitespace', 'window.title');
426 427

		assertTopScore(fuzzyScore, 'const', 1, 'constructor', 'const', 'cuOnstrul');
428
	});
429

J
Johannes Rieken 已提交
430 431 432 433 434
	test('Unexpected suggestion scoring, #28791', function () {
		assertTopScore(fuzzyScore, '_lines', 1, '_lineStarts', '_lines');
		assertTopScore(fuzzyScore, '_lines', 1, '_lineS', '_lines');
		assertTopScore(fuzzyScore, '_lineS', 0, '_lineS', '_lines');
	});
435

J
Johannes Rieken 已提交
436
	test('HTML closing tag proposal filtered out #38880', function () {
437 438 439
		assertMatches('\t\t<', '\t\t</body>', '^\t^\t^</body>', fuzzyScore, { patternPos: 0 });
		assertMatches('\t\t<', '\t\t</body>', '\t\t^</body>', fuzzyScore, { patternPos: 2 });
		assertMatches('\t<', '\t</body>', '\t^</body>', fuzzyScore, { patternPos: 1 });
J
Johannes Rieken 已提交
440 441
	});

442
	test('fuzzyScoreGraceful', () => {
443 444 445 446 447 448 449 450 451 452

		assertMatches('rlut', 'result', undefined, fuzzyScore);
		assertMatches('rlut', 'result', '^res^u^l^t', fuzzyScoreGraceful);

		assertMatches('cno', 'console', '^co^ns^ole', fuzzyScore);
		assertMatches('cno', 'console', '^co^ns^ole', fuzzyScoreGraceful);
		assertMatches('cno', 'console', '^c^o^nsole', fuzzyScoreGracefulAggressive);
		assertMatches('cno', 'co_new', '^c^o_^new', fuzzyScoreGraceful);
		assertMatches('cno', 'co_new', '^c^o_^new', fuzzyScoreGracefulAggressive);
	});
E
Erich Gamma 已提交
453
});