searchService.test.ts 7.1 KB
Newer Older
C
chrmarti 已提交
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';

C
Christof Marti 已提交
8 9
import * as assert from 'assert';
import {normalize} from 'path';
C
chrmarti 已提交
10

11 12
import {IProgress, IUncachedSearchStats} from 'vs/platform/search/common/search';
import {ISearchEngine, IRawSearch, IRawFileMatch, ISerializedFileMatch, ISerializedSearchComplete} from 'vs/workbench/services/search/node/search';
C
chrmarti 已提交
13 14 15 16
import {SearchService as RawSearchService} from 'vs/workbench/services/search/node/rawSearchService';
import {DiskSearch} from 'vs/workbench/services/search/node/searchService';


17 18 19
const stats: IUncachedSearchStats = {
	fromCache: false,
	resultCount: 4,
C
Christof Marti 已提交
20 21
	traversal: 'node',
	errors: [],
22 23 24 25 26
	fileWalkStartTime: 0,
	fileWalkResultTime: 1,
	directoriesWalked: 2,
	filesWalked: 3
};
C
chrmarti 已提交
27

28 29 30 31 32 33 34 35
class TestSearchEngine implements ISearchEngine<IRawFileMatch> {

	public static last: TestSearchEngine;

	private isCanceled = false;

	constructor(private result: () => IRawFileMatch, public config?: IRawSearch) {
		TestSearchEngine.last = this;
C
chrmarti 已提交
36 37
	}

38
	public search(onResult: (match: IRawFileMatch) => void, onProgress: (progress: IProgress) => void, done: (error: Error, complete: ISerializedSearchComplete) => void): void {
C
chrmarti 已提交
39 40 41
		const self = this;
		(function next() {
			process.nextTick(() => {
42 43 44 45 46 47 48
				if (self.isCanceled) {
					done(null, {
						limitHit: false,
						stats: stats
					});
					return;
				}
C
chrmarti 已提交
49 50
				const result = self.result();
				if (!result) {
C
chrmarti 已提交
51 52
					done(null, {
						limitHit: false,
53
						stats: stats
C
chrmarti 已提交
54
					});
C
chrmarti 已提交
55 56 57 58 59 60 61 62 63
				} else {
					onResult(result);
					next();
				}
			});
		})();
	}

	public cancel(): void {
64
		this.isCanceled = true;
C
chrmarti 已提交
65 66 67 68 69
	}
}

suite('SearchService', () => {

70
	const rawSearch: IRawSearch = {
C
Christof Marti 已提交
71
		rootFolders: [normalize('/some/where')],
72 73 74 75
		filePattern: 'a'
	};

	const rawMatch: IRawFileMatch = {
C
Christof Marti 已提交
76 77
		base: normalize('/some'),
		path: 'where',
78 79 80 81
		size: 123
	};

	const match: ISerializedFileMatch = {
C
Christof Marti 已提交
82
		path: normalize('/some/where')
83 84
	};

C
chrmarti 已提交
85 86
	test('Individual results', function () {
		let i = 5;
87
		const Engine = TestSearchEngine.bind(null, () => i-- && rawMatch);
C
chrmarti 已提交
88 89 90
		const service = new RawSearchService();

		let results = 0;
91
		return service.doFileSearch(Engine, rawSearch)
C
chrmarti 已提交
92 93 94 95
		.then(() => {
			assert.strictEqual(results, 5);
		}, null, value => {
			if (!Array.isArray(value)) {
96
				assert.deepStrictEqual(value, match);
C
chrmarti 已提交
97 98 99 100 101 102 103 104 105
				results++;
			} else {
				assert.fail(value);
			}
		});
	});

	test('Batch results', function () {
		let i = 25;
106
		const Engine = TestSearchEngine.bind(null, () => i-- && rawMatch);
C
chrmarti 已提交
107 108 109
		const service = new RawSearchService();

		const results = [];
110
		return service.doFileSearch(Engine, rawSearch, 10)
C
chrmarti 已提交
111 112 113 114
		.then(() => {
			assert.deepStrictEqual(results, [10, 10, 5]);
		}, null, value => {
			if (Array.isArray(value)) {
115 116
				value.forEach(m => {
					assert.deepStrictEqual(m, match);
C
chrmarti 已提交
117 118 119 120 121 122 123 124 125
				});
				results.push(value.length);
			} else {
				assert.fail(value);
			}
		});
	});

	test('Collect batched results', function () {
C
Christof Marti 已提交
126
		const uriPath = '/some/where';
C
chrmarti 已提交
127
		let i = 25;
128
		const Engine = TestSearchEngine.bind(null, () => i-- && rawMatch);
C
chrmarti 已提交
129 130 131 132
		const service = new RawSearchService();
		const diskSearch = new DiskSearch(false);

		const progressResults = [];
133
		return DiskSearch.collectResults(service.doFileSearch(Engine, rawSearch, 10))
C
chrmarti 已提交
134 135 136 137
		.then(result => {
			assert.strictEqual(result.results.length, 25, 'Result');
			assert.strictEqual(progressResults.length, 25, 'Progress');
		}, null, match => {
C
Christof Marti 已提交
138
			assert.strictEqual(match.resource.path, uriPath);
C
chrmarti 已提交
139 140 141
			progressResults.push(match);
		});
	});
142 143 144

	test('Sorted results', function () {
		const paths = ['bab', 'bbc', 'abb'];
C
Christof Marti 已提交
145 146 147
		const matches: IRawFileMatch[] = paths.map(path => ({
			base: normalize('/some/where'),
			path,
148 149 150 151 152 153 154 155
			size: 3
		}));
		let i = 0;
		const Engine = TestSearchEngine.bind(null, () => matches.shift());
		const service = new RawSearchService();

		const results = [];
		return service.doFileSearch(Engine, {
C
Christof Marti 已提交
156
			rootFolders: [normalize('/some/where')],
157 158 159 160 161
			filePattern: 'bb',
			sortByScore: true,
			maxResults: 2
		}, 1).then(() => {
			assert.notStrictEqual(typeof TestSearchEngine.last.config.maxResults, 'number');
C
Christof Marti 已提交
162
			assert.deepStrictEqual(results, [normalize('/some/where/bbc'), normalize('/some/where/bab')]);
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178
		}, null, value => {
			if (Array.isArray(value)) {
				results.push(...value.map(v => v.path));
			} else {
				assert.fail(value);
			}
		});
	});

	test('Sorted result batches', function () {
		let i = 25;
		const Engine = TestSearchEngine.bind(null, () => i-- && rawMatch);
		const service = new RawSearchService();

		const results = [];
		return service.doFileSearch(Engine, {
C
Christof Marti 已提交
179
			rootFolders: [normalize('/some/where')],
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
			filePattern: 'a',
			sortByScore: true,
			maxResults: 23
		}, 10)
		.then(() => {
			assert.deepStrictEqual(results, [10, 10, 3]);
		}, null, value => {
			if (Array.isArray(value)) {
				value.forEach(m => {
					assert.deepStrictEqual(m, match);
				});
				results.push(value.length);
			} else {
				assert.fail(value);
			}
		});
	});

	test('Cached results', function () {
		const paths = ['bcb', 'bbc', 'aab'];
C
Christof Marti 已提交
200 201 202
		const matches: IRawFileMatch[] = paths.map(path => ({
			base: normalize('/some/where'),
			path,
203 204 205 206 207 208 209 210
			size: 3
		}));
		let i = 0;
		const Engine = TestSearchEngine.bind(null, () => matches.shift());
		const service = new RawSearchService();

		const results = [];
		return service.doFileSearch(Engine, {
C
Christof Marti 已提交
211
			rootFolders: [normalize('/some/where')],
212 213 214 215 216
			filePattern: 'b',
			sortByScore: true,
			cacheKey: 'x'
		}, -1).then(complete => {
			assert.strictEqual(complete.stats.fromCache, false);
C
Christof Marti 已提交
217
			assert.deepStrictEqual(results, [normalize('/some/where/bcb'), normalize('/some/where/bbc'), normalize('/some/where/aab')]);
218 219 220 221 222 223 224 225 226
		}, null, value => {
			if (Array.isArray(value)) {
				results.push(...value.map(v => v.path));
			} else {
				assert.fail(value);
			}
		}).then(() => {
			const results = [];
			return service.doFileSearch(Engine, {
C
Christof Marti 已提交
227
				rootFolders: [normalize('/some/where')],
228 229 230 231 232
				filePattern: 'bc',
				sortByScore: true,
				cacheKey: 'x'
			}, -1).then(complete => {
				assert.ok(complete.stats.fromCache);
C
Christof Marti 已提交
233
				assert.deepStrictEqual(results, [normalize('/some/where/bcb'), normalize('/some/where/bbc')]);
234 235 236 237 238 239 240 241 242 243 244
			}, null, value => {
				if (Array.isArray(value)) {
					results.push(...value.map(v => v.path));
				} else {
					assert.fail(value);
				}
			});
		}).then(() => {
			return service.clearCache('x');
		}).then(() => {
			matches.push({
C
Christof Marti 已提交
245 246
				base: normalize('/some/where'),
				path: 'bc',
247 248 249 250
				size: 3
			});
			const results = [];
			return service.doFileSearch(Engine, {
C
Christof Marti 已提交
251
				rootFolders: [normalize('/some/where')],
252 253 254 255 256
				filePattern: 'bc',
				sortByScore: true,
				cacheKey: 'x'
			}, -1).then(complete => {
				assert.strictEqual(complete.stats.fromCache, false);
C
Christof Marti 已提交
257
				assert.deepStrictEqual(results, [normalize('/some/where/bc')]);
258 259 260 261 262 263 264 265 266
			}, null, value => {
				if (Array.isArray(value)) {
					results.push(...value.map(v => v.path));
				} else {
					assert.fail(value);
				}
			});
		});
	});
C
chrmarti 已提交
267
});