completions.test.ts 4.7 KB
Newer Older
M
Martin Aeschlimann 已提交
1 2 3 4 5 6 7 8 9
/*---------------------------------------------------------------------------------------------
 *  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 'mocha';
import * as assert from 'assert';
import * as path from 'path';
10
import Uri from 'vscode-uri';
M
Martin Aeschlimann 已提交
11 12 13
import { TextDocument, CompletionList, CompletionItemKind, } from 'vscode-languageserver-types';
import { getLanguageModes } from '../modes/languageModes';
import { getPathCompletionParticipant } from '../modes/pathCompletion';
14
import { WorkspaceFolder } from 'vscode-languageserver';
M
Martin Aeschlimann 已提交
15 16 17 18 19 20 21 22 23 24

export interface ItemDescription {
	label: string;
	documentation?: string;
	kind?: CompletionItemKind;
	resultText?: string;
	notAvailable?: boolean;
}


25
suite('HTML Completions', () => {
M
Martin Aeschlimann 已提交
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44

	let assertCompletion = function (completions: CompletionList, expected: ItemDescription, document: TextDocument, offset: number) {
		let matches = completions.items.filter(completion => {
			return completion.label === expected.label;
		});
		if (expected.notAvailable) {
			assert.equal(matches.length, 0, `${expected.label} should not existing is results`);
			return;
		}

		assert.equal(matches.length, 1, `${expected.label} should only existing once: Actual: ${completions.items.map(c => c.label).join(', ')}`);
		let match = matches[0];
		if (expected.documentation) {
			assert.equal(match.documentation, expected.documentation);
		}
		if (expected.kind) {
			assert.equal(match.kind, expected.kind);
		}
		if (expected.resultText && match.textEdit) {
45
			assert.equal(TextDocument.applyEdits(document, [match.textEdit]), expected.resultText);
M
Martin Aeschlimann 已提交
46 47 48 49 50
		}
	};

	const testUri = 'test://test/test.html';

51
	function assertCompletions(value: string, expected: { count?: number, items?: ItemDescription[] }, uri = testUri, workspaceFolders?: WorkspaceFolder[]): void {
M
Martin Aeschlimann 已提交
52 53 54 55 56 57 58
		let offset = value.indexOf('|');
		value = value.substr(0, offset) + value.substr(offset + 1);

		let document = TextDocument.create(uri, 'html', 0, value);
		let position = document.positionAt(offset);

		var languageModes = getLanguageModes({ css: true, javascript: true });
59
		var mode = languageModes.getModeAtPosition(document, position)!;
M
Martin Aeschlimann 已提交
60 61 62 63 64 65 66 67 68 69

		if (!workspaceFolders) {
			workspaceFolders = [{ name: 'x', uri: path.dirname(uri) }];
		}

		let participantResult = CompletionList.create([]);
		if (mode.setCompletionParticipants) {
			mode.setCompletionParticipants([getPathCompletionParticipant(document, workspaceFolders, participantResult)]);
		}

70
		let list = mode.doComplete!(document, position)!;
M
Martin Aeschlimann 已提交
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
		list.items = list.items.concat(participantResult.items);

		if (expected.count) {
			assert.equal(list.items, expected.count);
		}
		if (expected.items) {
			for (let item of expected.items) {
				assertCompletion(list, item, document, offset);
			}
		}
	}

	test('HTML Javascript Completions', function (): any {
		assertCompletions('<html><script>window.|</script></html>', {
			items: [
				{ label: 'location', resultText: '<html><script>window.location</script></html>' },
			]
		});
		assertCompletions('<html><script>$.|</script></html>', {
			items: [
				{ label: 'getJSON', resultText: '<html><script>$.getJSON</script></html>' },
			]
		});
	});
95

M
Martin Aeschlimann 已提交
96 97 98 99 100 101 102 103
	test('Path completion', function (): any {
		let testUri = Uri.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/foo.html')).fsPath;

		assertCompletions('<div><a href="about/|">', {
			items: [
				{ label: 'about.html', resultText: '<div><a href="about/about.html">' }
			]
		}, testUri);
104 105 106 107 108 109
		// Unquoted value is not supported in language service yet
		// assertCompletions(`<div><a href=about/|>`, {
		// 	items: [
		// 		{ label: 'about.html', resultText: `<div><a href=about/about.html>` }
		// 	]
		// }, testUri);
M
Martin Aeschlimann 已提交
110 111 112 113
		assertCompletions(`<div><a href='about/|'>`, {
			items: [
				{ label: 'about.html', resultText: `<div><a href='about/about.html'>` }
			]
M
Martin Aeschlimann 已提交
114
		}, testUri);
115 116 117 118 119 120
		// Don't think this is a common use case
		// assertCompletions('<div><a href="about/about|.xml">', {
		// 	items: [
		// 		{ label: 'about.html', resultText: '<div><a href="about/about.html">' }
		// 	]
		// }, testUri);
M
Martin Aeschlimann 已提交
121 122 123 124
		assertCompletions('<div><a href="about/a|">', {
			items: [
				{ label: 'about.html', resultText: '<div><a href="about/about.html">' }
			]
M
Martin Aeschlimann 已提交
125
		}, testUri);
126 127 128 129 130 131 132
		// We should not prompt suggestion before user enters any trigger character
		// assertCompletions('<div><a href="|">', {
		// 	items: [
		// 		{ label: 'index.html', resultText: '<div><a href="index.html">' },
		// 		{ label: 'about', resultText: '<div><a href="about/">' }
		// 	]
		// }, testUri);
M
Martin Aeschlimann 已提交
133 134
	});
});