mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-18 15:55:59 +01:00
Refactor html path completion test
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
import 'mocha';
|
||||
import * as assert from 'assert';
|
||||
import * as path from 'path';
|
||||
import Uri from 'vscode-uri';
|
||||
// import Uri from 'vscode-uri';
|
||||
import { TextDocument, CompletionList, CompletionItemKind } from 'vscode-languageserver-types';
|
||||
import { getLanguageModes } from '../modes/languageModes';
|
||||
import { getPathCompletionParticipant } from '../modes/pathCompletion';
|
||||
@@ -18,117 +18,224 @@ export interface ItemDescription {
|
||||
documentation?: string;
|
||||
kind?: CompletionItemKind;
|
||||
resultText?: string;
|
||||
command?: { title: string, command: string };
|
||||
notAvailable?: boolean;
|
||||
}
|
||||
|
||||
|
||||
suite('HTML Completions', () => {
|
||||
|
||||
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) {
|
||||
assert.equal(TextDocument.applyEdits(document, [match.textEdit]), expected.resultText);
|
||||
}
|
||||
};
|
||||
|
||||
const testUri = 'test://test/test.html';
|
||||
|
||||
function assertCompletions(value: string, expected: { count?: number, items?: ItemDescription[] }, uri = testUri, workspaceFolders?: WorkspaceFolder[]): void {
|
||||
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 });
|
||||
var mode = languageModes.getModeAtPosition(document, position)!;
|
||||
|
||||
if (!workspaceFolders) {
|
||||
workspaceFolders = [{ name: 'x', uri: path.dirname(uri) }];
|
||||
}
|
||||
|
||||
let participantResult = CompletionList.create([]);
|
||||
if (mode.setCompletionParticipants) {
|
||||
mode.setCompletionParticipants([getPathCompletionParticipant(document, workspaceFolders, participantResult)]);
|
||||
}
|
||||
|
||||
let list = mode.doComplete!(document, position)!;
|
||||
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);
|
||||
}
|
||||
}
|
||||
export function assertCompletion (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) {
|
||||
assert.equal(TextDocument.applyEdits(document, [match.textEdit]), expected.resultText);
|
||||
}
|
||||
if (expected.command) {
|
||||
assert.deepEqual(match.command, expected.command);
|
||||
}
|
||||
}
|
||||
|
||||
const testUri = 'test://test/test.html';
|
||||
|
||||
export function testCompletionFor(
|
||||
value: string,
|
||||
expected: { count?: number, items?: ItemDescription[] },
|
||||
uri = testUri,
|
||||
workspaceFolders?: WorkspaceFolder[]
|
||||
): void {
|
||||
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 });
|
||||
var mode = languageModes.getModeAtPosition(document, position)!;
|
||||
|
||||
if (!workspaceFolders) {
|
||||
workspaceFolders = [{ name: 'x', uri: path.dirname(uri) }];
|
||||
}
|
||||
|
||||
let participantResult = CompletionList.create([]);
|
||||
if (mode.setCompletionParticipants) {
|
||||
mode.setCompletionParticipants([getPathCompletionParticipant(document, workspaceFolders, participantResult)]);
|
||||
}
|
||||
|
||||
let list = mode.doComplete!(document, position)!;
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suite('HTML Completion', () => {
|
||||
test('HTML Javascript Completions', function (): any {
|
||||
assertCompletions('<html><script>window.|</script></html>', {
|
||||
testCompletionFor('<html><script>window.|</script></html>', {
|
||||
items: [
|
||||
{ label: 'location', resultText: '<html><script>window.location</script></html>' },
|
||||
]
|
||||
});
|
||||
assertCompletions('<html><script>$.|</script></html>', {
|
||||
testCompletionFor('<html><script>$.|</script></html>', {
|
||||
items: [
|
||||
{ label: 'getJSON', resultText: '<html><script>$.getJSON</script></html>' },
|
||||
]
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test('Path completion', function (): any {
|
||||
let testUri = Uri.file(path.resolve(__dirname, '../../test/pathCompletionFixtures/foo.html')).fsPath;
|
||||
suite('HTML Path Completion', () => {
|
||||
const triggerSuggestCommand = {
|
||||
title: 'Suggest',
|
||||
command: 'editor.action.triggerSuggest'
|
||||
};
|
||||
|
||||
assertCompletions('<div><a href="about/|">', {
|
||||
const fixtureRoot = path.resolve(__dirname, 'pathcompletionfixtures');
|
||||
const fixtureWorkspace = { name: 'fixture', uri: fixtureRoot };
|
||||
const indexHtmlUri = path.resolve(fixtureRoot, 'index.html');
|
||||
const aboutHtmlUri = path.resolve(fixtureRoot, 'about/about.html');
|
||||
|
||||
test('Basics - Correct label/kind/result/command', () => {
|
||||
testCompletionFor('<script src="./|">', {
|
||||
items: [
|
||||
{ label: 'about.html', resultText: '<div><a href="about/about.html">' }
|
||||
{ label: 'about/', kind: CompletionItemKind.Folder, resultText: '<script src="./about/">', command: triggerSuggestCommand },
|
||||
{ label: 'index.html', kind: CompletionItemKind.File, resultText: '<script src="./index.html">' },
|
||||
{ label: 'src/', kind: CompletionItemKind.Folder, resultText: '<script src="./src/">', command: triggerSuggestCommand }
|
||||
]
|
||||
}, testUri);
|
||||
// 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);
|
||||
assertCompletions(`<div><a href='about/|'>`, {
|
||||
items: [
|
||||
{ label: 'about.html', resultText: `<div><a href='about/about.html'>` }
|
||||
]
|
||||
}, testUri);
|
||||
// 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);
|
||||
assertCompletions('<div><a href="about/a|">', {
|
||||
items: [
|
||||
{ label: 'about.html', resultText: '<div><a href="about/about.html">' }
|
||||
]
|
||||
}, testUri);
|
||||
// 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);
|
||||
}, indexHtmlUri);
|
||||
});
|
||||
});
|
||||
|
||||
test('Basics - Single Quote', () => {
|
||||
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'>` },
|
||||
{ label: 'src/', kind: CompletionItemKind.Folder, resultText: `<script src='./src/'>`, command: triggerSuggestCommand }
|
||||
]
|
||||
}, indexHtmlUri);
|
||||
});
|
||||
|
||||
test('Relative Path', () => {
|
||||
testCompletionFor('<script src="../|">', {
|
||||
items: [
|
||||
{ label: 'about/', resultText: '<script src="../about/">' },
|
||||
{ label: 'index.html', resultText: '<script src="../index.html">' },
|
||||
{ label: 'src/', resultText: '<script src="../src/">' }
|
||||
]
|
||||
}, aboutHtmlUri);
|
||||
|
||||
testCompletionFor('<script src="../src/|">', {
|
||||
items: [
|
||||
{ label: 'feature.js', resultText: '<script src="../src/feature.js">' },
|
||||
{ label: 'test.js', resultText: '<script src="../src/test.js">' },
|
||||
]
|
||||
}, aboutHtmlUri);
|
||||
});
|
||||
|
||||
test('Absolute Path', () => {
|
||||
testCompletionFor('<script src="/|">', {
|
||||
items: [
|
||||
{ label: 'about/', resultText: '<script src="/about/">' },
|
||||
{ label: 'index.html', resultText: '<script src="/index.html">' },
|
||||
{ label: 'src/', resultText: '<script src="/src/">' },
|
||||
]
|
||||
}, indexHtmlUri);
|
||||
|
||||
testCompletionFor('<script src="/src/|">', {
|
||||
items: [
|
||||
{ label: 'feature.js', resultText: '<script src="/src/feature.js">' },
|
||||
{ label: 'test.js', resultText: '<script src="/src/test.js">' },
|
||||
]
|
||||
}, aboutHtmlUri, [fixtureWorkspace]);
|
||||
});
|
||||
|
||||
test('Incomplete Path', () => {
|
||||
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|">', {
|
||||
items: [
|
||||
{ label: 'feature.js', resultText: '<script src="../src/feature.js">' },
|
||||
{ label: 'test.js', resultText: '<script src="../src/test.js">' },
|
||||
]
|
||||
}, aboutHtmlUri, [fixtureWorkspace]);
|
||||
});
|
||||
|
||||
test('No leading dot or slash', () => {
|
||||
testCompletionFor('<script src="s|">', {
|
||||
items: [
|
||||
{ label: 'about/', resultText: '<script src="about/">' },
|
||||
{ label: 'index.html', resultText: '<script src="index.html">' },
|
||||
{ label: 'src/', resultText: '<script src="src/">' },
|
||||
]
|
||||
}, indexHtmlUri, [fixtureWorkspace]);
|
||||
|
||||
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|">', {
|
||||
items: [
|
||||
{ label: 'feature.js', resultText: '<script src="src/feature.js">' },
|
||||
{ label: 'test.js', resultText: '<script src="src/test.js">' },
|
||||
]
|
||||
}, indexHtmlUri, [fixtureWorkspace]);
|
||||
});
|
||||
|
||||
test('Trigger completion in middle of path', () => {
|
||||
/* Trigger Completion In Middle of path
|
||||
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]);
|
||||
*/
|
||||
|
||||
});
|
||||
|
||||
test('Unquoted Path', () => {
|
||||
/* Unquoted value
|
||||
testCompletionFor(`<div><a href=about/|>`, {
|
||||
items: [
|
||||
{ label: 'about.html', resultText: `<div><a href=about/about.html>` }
|
||||
]
|
||||
}, testUri);
|
||||
*/
|
||||
});
|
||||
|
||||
test('Empty Path Value', () => {
|
||||
/*
|
||||
testCompletionFor('<div><a href="|">', {
|
||||
items: [
|
||||
{ label: 'index.html', resultText: '<div><a href="index.html">' },
|
||||
{ label: 'about', resultText: '<div><a href="about/">' }
|
||||
]
|
||||
}, testUri);
|
||||
*/
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,237 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* 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';
|
||||
import * as path from 'path';
|
||||
import { providePathSuggestions } from '../../modes/pathCompletion';
|
||||
import { CompletionItemKind, Range, Position, CompletionItem, TextEdit, Command } from 'vscode-languageserver-types';
|
||||
|
||||
const fixtureRoot = path.resolve(__dirname, '../../../test/pathCompletionFixtures');
|
||||
|
||||
function toRange(line: number, startChar: number, endChar: number) {
|
||||
return Range.create(Position.create(line, startChar), Position.create(line, endChar));
|
||||
}
|
||||
function toTextEdit(line: number, startChar: number, endChar: number, newText: string) {
|
||||
const range = Range.create(Position.create(line, startChar), Position.create(line, endChar));
|
||||
return TextEdit.replace(range, newText);
|
||||
}
|
||||
|
||||
interface PathSuggestion {
|
||||
label?: string;
|
||||
kind?: CompletionItemKind;
|
||||
textEdit?: TextEdit;
|
||||
command?: Command;
|
||||
}
|
||||
|
||||
function assertSuggestions(actual: CompletionItem[], expected: PathSuggestion[]) {
|
||||
assert.equal(actual.length, expected.length, `Suggestions have length ${actual.length} but should have length ${expected.length}`);
|
||||
|
||||
for (let i = 0; i < expected.length; i++) {
|
||||
if (expected[i].label) {
|
||||
assert.equal(
|
||||
actual[i].label,
|
||||
expected[i].label,
|
||||
`Suggestion ${actual[i].label} should have label ${expected[i].label}`
|
||||
);
|
||||
}
|
||||
if (expected[i].kind) {
|
||||
assert.equal(actual[i].kind,
|
||||
expected[i].kind,
|
||||
`Suggestion ${actual[i].label} has kind ${actual[i].kind} but should have ${expected[i].kind}`
|
||||
);
|
||||
}
|
||||
if (expected[i].textEdit) {
|
||||
assert.equal(actual[i].textEdit!.newText, expected[i].textEdit!.newText);
|
||||
assert.deepEqual(actual[i].textEdit!.range, expected[i].textEdit!.range);
|
||||
}
|
||||
if (expected[i].command) {
|
||||
assert.equal(
|
||||
actual[i].command!.title,
|
||||
expected[i].command!.title,
|
||||
`Suggestion ${actual[i].label} has command title ${actual[i].command!.title} but should have command title ${expected[i].command!.title}`
|
||||
);
|
||||
assert.equal(
|
||||
actual[i].command!.command,
|
||||
expected[i].command!.command,
|
||||
`Suggestion ${actual[i].label} has command ${actual[i].command!.command} but should have command ${expected[i].command!.command}`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suite('Path Completion - Relative Path:', () => {
|
||||
const mockRange = toRange(0, 3, 5);
|
||||
|
||||
test('Current Folder', () => {
|
||||
const value = './';
|
||||
const activeFileFsPath = path.resolve(fixtureRoot, 'index.html');
|
||||
const suggestions = providePathSuggestions(value, mockRange, activeFileFsPath);
|
||||
|
||||
assertSuggestions(suggestions, [
|
||||
{ label: 'about/', kind: CompletionItemKind.Folder },
|
||||
{ label: 'index.html', kind: CompletionItemKind.File },
|
||||
{ label: 'src/', kind: CompletionItemKind.Folder }
|
||||
]);
|
||||
});
|
||||
|
||||
test('Parent Folder:', () => {
|
||||
const value = '../';
|
||||
const activeFileFsPath = path.resolve(fixtureRoot, 'about/about.html');
|
||||
const suggestions = providePathSuggestions(value, mockRange, activeFileFsPath);
|
||||
|
||||
assertSuggestions(suggestions, [
|
||||
{ label: 'about/', kind: CompletionItemKind.Folder },
|
||||
{ label: 'index.html', kind: CompletionItemKind.File },
|
||||
{ label: 'src/', kind: CompletionItemKind.Folder }
|
||||
]);
|
||||
});
|
||||
|
||||
test('Adjacent Folder:', () => {
|
||||
const value = '../src/';
|
||||
const activeFileFsPath = path.resolve(fixtureRoot, 'about/about.html');
|
||||
const suggestions = providePathSuggestions(value, mockRange, activeFileFsPath);
|
||||
|
||||
assertSuggestions(suggestions, [
|
||||
{ label: 'feature.js', kind: CompletionItemKind.File },
|
||||
{ label: 'test.js', kind: CompletionItemKind.File }
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Path Completion - Absolute Path:', () => {
|
||||
const mockRange = toRange(0, 3, 5);
|
||||
|
||||
test('Root', () => {
|
||||
const value = '/';
|
||||
const activeFileFsPath1 = path.resolve(fixtureRoot, 'index.html');
|
||||
const activeFileFsPath2 = path.resolve(fixtureRoot, 'about/index.html');
|
||||
|
||||
const suggestions1 = providePathSuggestions(value, mockRange, activeFileFsPath1, fixtureRoot);
|
||||
const suggestions2 = providePathSuggestions(value, mockRange, activeFileFsPath2, fixtureRoot);
|
||||
|
||||
const verify = (suggestions: CompletionItem[]) => {
|
||||
assertSuggestions(suggestions, [
|
||||
{ label: 'about/', kind: CompletionItemKind.Folder },
|
||||
{ label: 'index.html', kind: CompletionItemKind.File },
|
||||
{ label: 'src/', kind: CompletionItemKind.Folder }
|
||||
]);
|
||||
};
|
||||
|
||||
verify(suggestions1);
|
||||
verify(suggestions2);
|
||||
});
|
||||
|
||||
test('Sub Folder', () => {
|
||||
const value = '/src/';
|
||||
const activeFileFsPath = path.resolve(fixtureRoot, 'about/about.html');
|
||||
const suggestions = providePathSuggestions(value, mockRange, activeFileFsPath, fixtureRoot);
|
||||
|
||||
assertSuggestions(suggestions, [
|
||||
{ label: 'feature.js', kind: CompletionItemKind.File },
|
||||
{ label: 'test.js', kind: CompletionItemKind.File }
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Path Completion - Folder Commands:', () => {
|
||||
const mockRange = toRange(0, 3, 5);
|
||||
|
||||
test('Folder should have command `editor.action.triggerSuggest', () => {
|
||||
const value = './';
|
||||
const activeFileFsPath = path.resolve(fixtureRoot, 'index.html');
|
||||
const suggestions = providePathSuggestions(value, mockRange, activeFileFsPath);
|
||||
|
||||
assertSuggestions(suggestions, [
|
||||
{ label: 'about/', command: { title: 'Suggest', command: 'editor.action.triggerSuggest' } },
|
||||
{ label: 'index.html' },
|
||||
{ label: 'src/', command: { title: 'Suggest', command: 'editor.action.triggerSuggest' } },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Path Completion - Incomplete Path at End:', () => {
|
||||
const mockRange = toRange(0, 3, 5);
|
||||
|
||||
test('Incomplete Path that starts with slash', () => {
|
||||
const value = '/src/f';
|
||||
const activeFileFsPath = path.resolve(fixtureRoot, 'about/about.html');
|
||||
const suggestions = providePathSuggestions(value, mockRange, activeFileFsPath, fixtureRoot);
|
||||
|
||||
assertSuggestions(suggestions, [
|
||||
{ label: 'feature.js', kind: CompletionItemKind.File },
|
||||
{ label: 'test.js', kind: CompletionItemKind.File }
|
||||
]);
|
||||
});
|
||||
|
||||
test('Incomplete Path that does not start with slash', () => {
|
||||
const value = '../src/f';
|
||||
const activeFileFsPath = path.resolve(fixtureRoot, 'about/about.html');
|
||||
const suggestions = providePathSuggestions(value, mockRange, activeFileFsPath, fixtureRoot);
|
||||
|
||||
assertSuggestions(suggestions, [
|
||||
{ label: 'feature.js', kind: CompletionItemKind.File },
|
||||
{ label: 'test.js', kind: CompletionItemKind.File }
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Path Completion - No leading dot or slash:', () => {
|
||||
|
||||
test('Top level completion', () => {
|
||||
const value = 's';
|
||||
const activeFileFsPath = path.resolve(fixtureRoot, 'index.html');
|
||||
const range = toRange(0, 3, 5);
|
||||
const suggestions = providePathSuggestions(value, range, activeFileFsPath, fixtureRoot);
|
||||
|
||||
assertSuggestions(suggestions, [
|
||||
{ label: 'about/', kind: CompletionItemKind.Folder, textEdit: toTextEdit(0, 4, 4, 'about/') },
|
||||
{ label: 'index.html', kind: CompletionItemKind.File, textEdit: toTextEdit(0, 4, 4, 'index.html') },
|
||||
{ label: 'src/', kind: CompletionItemKind.Folder, textEdit: toTextEdit(0, 4, 4, 'src/') }
|
||||
]);
|
||||
});
|
||||
|
||||
test('src/', () => {
|
||||
const value = 'src/';
|
||||
const activeFileFsPath = path.resolve(fixtureRoot, 'index.html');
|
||||
const range = toRange(0, 3, 8);
|
||||
const suggestions = providePathSuggestions(value, range, activeFileFsPath, fixtureRoot);
|
||||
|
||||
assertSuggestions(suggestions, [
|
||||
{ label: 'feature.js', kind: CompletionItemKind.File, textEdit: toTextEdit(0, 7, 7, 'feature.js') },
|
||||
{ label: 'test.js', kind: CompletionItemKind.File, textEdit: toTextEdit(0, 7, 7, 'test.js') }
|
||||
]);
|
||||
});
|
||||
|
||||
test('src/f', () => {
|
||||
const value = 'src/f';
|
||||
const activeFileFsPath = path.resolve(fixtureRoot, 'index.html');
|
||||
const range = toRange(0, 3, 9);
|
||||
const suggestions = providePathSuggestions(value, range, activeFileFsPath, fixtureRoot);
|
||||
|
||||
assertSuggestions(suggestions, [
|
||||
{ label: 'feature.js', kind: CompletionItemKind.File, textEdit: toTextEdit(0, 7, 8, 'feature.js') },
|
||||
{ label: 'test.js', kind: CompletionItemKind.File, textEdit: toTextEdit(0, 7, 8, 'test.js') }
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
suite('Path Completion - TextEdit:', () => {
|
||||
|
||||
test('TextEdit has correct replace text and range', () => {
|
||||
const value = './';
|
||||
const activeFileFsPath = path.resolve(fixtureRoot, 'index.html');
|
||||
const range = toRange(0, 3, 5);
|
||||
const expectedReplaceRange = toRange(0, 4, 4);
|
||||
|
||||
const suggestions = providePathSuggestions(value, range, activeFileFsPath);
|
||||
|
||||
assertSuggestions(suggestions, [
|
||||
{ textEdit: TextEdit.replace(expectedReplaceRange, 'about/') },
|
||||
{ textEdit: TextEdit.replace(expectedReplaceRange, 'index.html') },
|
||||
{ textEdit: TextEdit.replace(expectedReplaceRange, 'src/') },
|
||||
]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user