mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-01 05:51:32 +01:00
html headless
This commit is contained in:
@@ -6,7 +6,9 @@ import 'mocha';
|
||||
import * as assert from 'assert';
|
||||
import * as path from 'path';
|
||||
import { URI } from 'vscode-uri';
|
||||
import { getLanguageModes, WorkspaceFolder, TextDocument, CompletionList, CompletionItemKind, ClientCapabilities} from '../modes/languageModes';
|
||||
import { getLanguageModes, WorkspaceFolder, TextDocument, CompletionList, CompletionItemKind, ClientCapabilities, TextEdit } from '../modes/languageModes';
|
||||
import { getNodeFSRequestService } from '../node/nodeFs';
|
||||
import { getDocumentContext } from '../utils/documentContext';
|
||||
export interface ItemDescription {
|
||||
label: string;
|
||||
documentation?: string;
|
||||
@@ -34,7 +36,8 @@ export function assertCompletion(completions: CompletionList, expected: ItemDesc
|
||||
assert.equal(match.kind, expected.kind);
|
||||
}
|
||||
if (expected.resultText && match.textEdit) {
|
||||
assert.equal(TextDocument.applyEdits(document, [match.textEdit]), expected.resultText);
|
||||
const edit = TextEdit.is(match.textEdit) ? match.textEdit : TextEdit.replace(match.textEdit.replace, match.textEdit.newText);
|
||||
assert.equal(TextDocument.applyEdits(document, [edit]), expected.resultText);
|
||||
}
|
||||
if (expected.command) {
|
||||
assert.deepEqual(match.command, expected.command);
|
||||
@@ -43,7 +46,7 @@ export function assertCompletion(completions: CompletionList, expected: ItemDesc
|
||||
|
||||
const testUri = 'test://test/test.html';
|
||||
|
||||
export function testCompletionFor(value: string, expected: { count?: number, items?: ItemDescription[] }, uri = testUri, workspaceFolders?: WorkspaceFolder[]): void {
|
||||
export async function testCompletionFor(value: string, expected: { count?: number, items?: ItemDescription[] }, uri = testUri, workspaceFolders?: WorkspaceFolder[]): Promise<void> {
|
||||
let offset = value.indexOf('|');
|
||||
value = value.substr(0, offset) + value.substr(offset + 1);
|
||||
|
||||
@@ -54,11 +57,12 @@ export function testCompletionFor(value: string, expected: { count?: number, ite
|
||||
|
||||
let document = TextDocument.create(uri, 'html', 0, value);
|
||||
let position = document.positionAt(offset);
|
||||
const context = getDocumentContext(uri, workspace.folders)
|
||||
|
||||
const languageModes = getLanguageModes({ css: true, javascript: true }, workspace, ClientCapabilities.LATEST);
|
||||
const languageModes = getLanguageModes({ css: true, javascript: true }, workspace, ClientCapabilities.LATEST, getNodeFSRequestService());
|
||||
const mode = languageModes.getModeAtPosition(document, position)!;
|
||||
|
||||
let list = mode.doComplete!(document, position);
|
||||
let list = await mode.doComplete!(document, position, context);
|
||||
|
||||
if (expected.count) {
|
||||
assert.equal(list.items.length, expected.count);
|
||||
@@ -71,13 +75,13 @@ export function testCompletionFor(value: string, expected: { count?: number, ite
|
||||
}
|
||||
|
||||
suite('HTML Completion', () => {
|
||||
test('HTML JavaScript Completions', function (): any {
|
||||
testCompletionFor('<html><script>window.|</script></html>', {
|
||||
test('HTML JavaScript Completions', async () => {
|
||||
await testCompletionFor('<html><script>window.|</script></html>', {
|
||||
items: [
|
||||
{ label: 'location', resultText: '<html><script>window.location</script></html>' },
|
||||
]
|
||||
});
|
||||
testCompletionFor('<html><script>$.|</script></html>', {
|
||||
await testCompletionFor('<html><script>$.|</script></html>', {
|
||||
items: [
|
||||
{ label: 'getJSON', resultText: '<html><script>$.getJSON</script></html>' },
|
||||
]
|
||||
@@ -96,8 +100,8 @@ suite('HTML Path Completion', () => {
|
||||
const indexHtmlUri = URI.file(path.resolve(fixtureRoot, 'index.html')).toString();
|
||||
const aboutHtmlUri = URI.file(path.resolve(fixtureRoot, 'about/about.html')).toString();
|
||||
|
||||
test('Basics - Correct label/kind/result/command', () => {
|
||||
testCompletionFor('<script src="./|">', {
|
||||
test('Basics - Correct label/kind/result/command', async () => {
|
||||
await testCompletionFor('<script src="./|">', {
|
||||
items: [
|
||||
{ label: 'about/', kind: CompletionItemKind.Folder, resultText: '<script src="./about/">', command: triggerSuggestCommand },
|
||||
{ label: 'index.html', kind: CompletionItemKind.File, resultText: '<script src="./index.html">' },
|
||||
@@ -106,8 +110,8 @@ suite('HTML Path Completion', () => {
|
||||
}, indexHtmlUri);
|
||||
});
|
||||
|
||||
test('Basics - Single Quote', () => {
|
||||
testCompletionFor(`<script src='./|'>`, {
|
||||
test('Basics - Single Quote', async () => {
|
||||
await testCompletionFor(`<script src='./|'>`, {
|
||||
items: [
|
||||
{ label: 'about/', kind: CompletionItemKind.Folder, resultText: `<script src='./about/'>`, command: triggerSuggestCommand },
|
||||
{ label: 'index.html', kind: CompletionItemKind.File, resultText: `<script src='./index.html'>` },
|
||||
@@ -116,18 +120,18 @@ suite('HTML Path Completion', () => {
|
||||
}, indexHtmlUri);
|
||||
});
|
||||
|
||||
test('No completion for remote paths', () => {
|
||||
testCompletionFor('<script src="http:">', { items: [] });
|
||||
testCompletionFor('<script src="http:/|">', { items: [] });
|
||||
testCompletionFor('<script src="http://|">', { items: [] });
|
||||
testCompletionFor('<script src="https:|">', { items: [] });
|
||||
testCompletionFor('<script src="https:/|">', { items: [] });
|
||||
testCompletionFor('<script src="https://|">', { items: [] });
|
||||
testCompletionFor('<script src="//|">', { items: [] });
|
||||
test('No completion for remote paths', async () => {
|
||||
await testCompletionFor('<script src="http:">', { items: [] });
|
||||
await testCompletionFor('<script src="http:/|">', { items: [] });
|
||||
await testCompletionFor('<script src="http://|">', { items: [] });
|
||||
await testCompletionFor('<script src="https:|">', { items: [] });
|
||||
await testCompletionFor('<script src="https:/|">', { items: [] });
|
||||
await testCompletionFor('<script src="https://|">', { items: [] });
|
||||
await testCompletionFor('<script src="//|">', { items: [] });
|
||||
});
|
||||
|
||||
test('Relative Path', () => {
|
||||
testCompletionFor('<script src="../|">', {
|
||||
test('Relative Path', async () => {
|
||||
await testCompletionFor('<script src="../|">', {
|
||||
items: [
|
||||
{ label: 'about/', resultText: '<script src="../about/">' },
|
||||
{ label: 'index.html', resultText: '<script src="../index.html">' },
|
||||
@@ -135,7 +139,7 @@ suite('HTML Path Completion', () => {
|
||||
]
|
||||
}, aboutHtmlUri);
|
||||
|
||||
testCompletionFor('<script src="../src/|">', {
|
||||
await testCompletionFor('<script src="../src/|">', {
|
||||
items: [
|
||||
{ label: 'feature.js', resultText: '<script src="../src/feature.js">' },
|
||||
{ label: 'test.js', resultText: '<script src="../src/test.js">' },
|
||||
@@ -143,8 +147,8 @@ suite('HTML Path Completion', () => {
|
||||
}, aboutHtmlUri);
|
||||
});
|
||||
|
||||
test('Absolute Path', () => {
|
||||
testCompletionFor('<script src="/|">', {
|
||||
test('Absolute Path', async () => {
|
||||
await testCompletionFor('<script src="/|">', {
|
||||
items: [
|
||||
{ label: 'about/', resultText: '<script src="/about/">' },
|
||||
{ label: 'index.html', resultText: '<script src="/index.html">' },
|
||||
@@ -152,7 +156,7 @@ suite('HTML Path Completion', () => {
|
||||
]
|
||||
}, indexHtmlUri);
|
||||
|
||||
testCompletionFor('<script src="/src/|">', {
|
||||
await testCompletionFor('<script src="/src/|">', {
|
||||
items: [
|
||||
{ label: 'feature.js', resultText: '<script src="/src/feature.js">' },
|
||||
{ label: 'test.js', resultText: '<script src="/src/test.js">' },
|
||||
@@ -160,9 +164,9 @@ suite('HTML Path Completion', () => {
|
||||
}, aboutHtmlUri, [fixtureWorkspace]);
|
||||
});
|
||||
|
||||
test('Empty Path Value', () => {
|
||||
test('Empty Path Value', async () => {
|
||||
// document: index.html
|
||||
testCompletionFor('<script src="|">', {
|
||||
await testCompletionFor('<script src="|">', {
|
||||
items: [
|
||||
{ label: 'about/', resultText: '<script src="about/">' },
|
||||
{ label: 'index.html', resultText: '<script src="index.html">' },
|
||||
@@ -170,7 +174,7 @@ suite('HTML Path Completion', () => {
|
||||
]
|
||||
}, indexHtmlUri);
|
||||
// document: about.html
|
||||
testCompletionFor('<script src="|">', {
|
||||
await testCompletionFor('<script src="|">', {
|
||||
items: [
|
||||
{ label: 'about.css', resultText: '<script src="about.css">' },
|
||||
{ label: 'about.html', resultText: '<script src="about.html">' },
|
||||
@@ -178,15 +182,15 @@ suite('HTML Path Completion', () => {
|
||||
]
|
||||
}, aboutHtmlUri);
|
||||
});
|
||||
test('Incomplete Path', () => {
|
||||
testCompletionFor('<script src="/src/f|">', {
|
||||
test('Incomplete Path', async () => {
|
||||
await testCompletionFor('<script src="/src/f|">', {
|
||||
items: [
|
||||
{ label: 'feature.js', resultText: '<script src="/src/feature.js">' },
|
||||
{ label: 'test.js', resultText: '<script src="/src/test.js">' },
|
||||
]
|
||||
}, aboutHtmlUri, [fixtureWorkspace]);
|
||||
|
||||
testCompletionFor('<script src="../src/f|">', {
|
||||
await testCompletionFor('<script src="../src/f|">', {
|
||||
items: [
|
||||
{ label: 'feature.js', resultText: '<script src="../src/feature.js">' },
|
||||
{ label: 'test.js', resultText: '<script src="../src/test.js">' },
|
||||
@@ -194,9 +198,9 @@ suite('HTML Path Completion', () => {
|
||||
}, aboutHtmlUri, [fixtureWorkspace]);
|
||||
});
|
||||
|
||||
test('No leading dot or slash', () => {
|
||||
test('No leading dot or slash', async () => {
|
||||
// document: index.html
|
||||
testCompletionFor('<script src="s|">', {
|
||||
await testCompletionFor('<script src="s|">', {
|
||||
items: [
|
||||
{ label: 'about/', resultText: '<script src="about/">' },
|
||||
{ label: 'index.html', resultText: '<script src="index.html">' },
|
||||
@@ -204,14 +208,14 @@ suite('HTML Path Completion', () => {
|
||||
]
|
||||
}, indexHtmlUri, [fixtureWorkspace]);
|
||||
|
||||
testCompletionFor('<script src="src/|">', {
|
||||
await testCompletionFor('<script src="src/|">', {
|
||||
items: [
|
||||
{ label: 'feature.js', resultText: '<script src="src/feature.js">' },
|
||||
{ label: 'test.js', resultText: '<script src="src/test.js">' },
|
||||
]
|
||||
}, indexHtmlUri, [fixtureWorkspace]);
|
||||
|
||||
testCompletionFor('<script src="src/f|">', {
|
||||
await testCompletionFor('<script src="src/f|">', {
|
||||
items: [
|
||||
{ label: 'feature.js', resultText: '<script src="src/feature.js">' },
|
||||
{ label: 'test.js', resultText: '<script src="src/test.js">' },
|
||||
@@ -219,7 +223,7 @@ suite('HTML Path Completion', () => {
|
||||
}, indexHtmlUri, [fixtureWorkspace]);
|
||||
|
||||
// document: about.html
|
||||
testCompletionFor('<script src="s|">', {
|
||||
await testCompletionFor('<script src="s|">', {
|
||||
items: [
|
||||
{ label: 'about.css', resultText: '<script src="about.css">' },
|
||||
{ label: 'about.html', resultText: '<script src="about.html">' },
|
||||
@@ -227,29 +231,29 @@ suite('HTML Path Completion', () => {
|
||||
]
|
||||
}, aboutHtmlUri, [fixtureWorkspace]);
|
||||
|
||||
testCompletionFor('<script src="media/|">', {
|
||||
await testCompletionFor('<script src="media/|">', {
|
||||
items: [
|
||||
{ label: 'icon.pic', resultText: '<script src="media/icon.pic">' }
|
||||
]
|
||||
}, aboutHtmlUri, [fixtureWorkspace]);
|
||||
|
||||
testCompletionFor('<script src="media/f|">', {
|
||||
await testCompletionFor('<script src="media/f|">', {
|
||||
items: [
|
||||
{ label: 'icon.pic', resultText: '<script src="media/icon.pic">' }
|
||||
]
|
||||
}, aboutHtmlUri, [fixtureWorkspace]);
|
||||
});
|
||||
|
||||
test('Trigger completion in middle of path', () => {
|
||||
test('Trigger completion in middle of path', async () => {
|
||||
// document: index.html
|
||||
testCompletionFor('<script src="src/f|eature.js">', {
|
||||
await testCompletionFor('<script src="src/f|eature.js">', {
|
||||
items: [
|
||||
{ label: 'feature.js', resultText: '<script src="src/feature.js">' },
|
||||
{ label: 'test.js', resultText: '<script src="src/test.js">' },
|
||||
]
|
||||
}, indexHtmlUri, [fixtureWorkspace]);
|
||||
|
||||
testCompletionFor('<script src="s|rc/feature.js">', {
|
||||
await testCompletionFor('<script src="s|rc/feature.js">', {
|
||||
items: [
|
||||
{ label: 'about/', resultText: '<script src="about/">' },
|
||||
{ label: 'index.html', resultText: '<script src="index.html">' },
|
||||
@@ -258,13 +262,13 @@ suite('HTML Path Completion', () => {
|
||||
}, indexHtmlUri, [fixtureWorkspace]);
|
||||
|
||||
// document: about.html
|
||||
testCompletionFor('<script src="media/f|eature.js">', {
|
||||
await testCompletionFor('<script src="media/f|eature.js">', {
|
||||
items: [
|
||||
{ label: 'icon.pic', resultText: '<script src="media/icon.pic">' }
|
||||
]
|
||||
}, aboutHtmlUri, [fixtureWorkspace]);
|
||||
|
||||
testCompletionFor('<script src="m|edia/feature.js">', {
|
||||
await testCompletionFor('<script src="m|edia/feature.js">', {
|
||||
items: [
|
||||
{ label: 'about.css', resultText: '<script src="about.css">' },
|
||||
{ label: 'about.html', resultText: '<script src="about.html">' },
|
||||
@@ -274,8 +278,8 @@ suite('HTML Path Completion', () => {
|
||||
});
|
||||
|
||||
|
||||
test('Trigger completion in middle of path and with whitespaces', () => {
|
||||
testCompletionFor('<script src="./| about/about.html>', {
|
||||
test('Trigger completion in middle of path and with whitespaces', async () => {
|
||||
await testCompletionFor('<script src="./| about/about.html>', {
|
||||
items: [
|
||||
{ label: 'about/', resultText: '<script src="./about/ about/about.html>' },
|
||||
{ label: 'index.html', resultText: '<script src="./index.html about/about.html>' },
|
||||
@@ -283,7 +287,7 @@ suite('HTML Path Completion', () => {
|
||||
]
|
||||
}, indexHtmlUri, [fixtureWorkspace]);
|
||||
|
||||
testCompletionFor('<script src="./a|bout /about.html>', {
|
||||
await testCompletionFor('<script src="./a|bout /about.html>', {
|
||||
items: [
|
||||
{ label: 'about/', resultText: '<script src="./about/ /about.html>' },
|
||||
{ label: 'index.html', resultText: '<script src="./index.html /about.html>' },
|
||||
@@ -292,13 +296,13 @@ suite('HTML Path Completion', () => {
|
||||
}, indexHtmlUri, [fixtureWorkspace]);
|
||||
});
|
||||
|
||||
test('Completion should ignore files/folders starting with dot', () => {
|
||||
testCompletionFor('<script src="./|"', {
|
||||
test('Completion should ignore files/folders starting with dot', async () => {
|
||||
await testCompletionFor('<script src="./|"', {
|
||||
count: 3
|
||||
}, indexHtmlUri, [fixtureWorkspace]);
|
||||
});
|
||||
|
||||
test('Unquoted Path', () => {
|
||||
test('Unquoted Path', async () => {
|
||||
/* Unquoted value is not supported in html language service yet
|
||||
testCompletionFor(`<div><a href=about/|>`, {
|
||||
items: [
|
||||
|
||||
Reference in New Issue
Block a user