`, '', OTHER_CMP);
- const completions = ngLS.getCompletionsAtPosition(fileName, cursor, /* options */ undefined);
+ const {templateFile} = setup(`
`, '', OTHER_CMP);
+ templateFile.moveCursorToText('
');
+ const completions = templateFile.getCompletionsAtPosition();
expectContain(
completions, unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.COMPONENT),
['other-cmp']);
- const details =
- ngLS.getCompletionEntryDetails(fileName, cursor, 'other-cmp', undefined, undefined)!;
+ const details = templateFile.getCompletionEntryDetails('other-cmp')!;
expect(details).toBeDefined();
expect(ts.displayPartsToString(details.displayParts))
.toEqual('(component) AppModule.OtherCmp');
@@ -333,10 +342,10 @@ describe('completions', () => {
describe('element attribute scope', () => {
describe('dom completions', () => {
it('should return completions for a new element attribute', () => {
- const {ngLS, fileName, cursor} = setup(``, '');
+ const {templateFile} = setup(``, '');
+ templateFile.moveCursorToText('');
- const completions =
- ngLS.getCompletionsAtPosition(fileName, cursor, /* options */ undefined);
+ const completions = templateFile.getCompletionsAtPosition();
expectContain(
completions, unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.ATTRIBUTE),
['value']);
@@ -346,24 +355,24 @@ describe('completions', () => {
});
it('should return completions for a partial attribute', () => {
- const {ngLS, fileName, cursor, text} = setup(``, '');
+ const {templateFile} = setup(``, '');
+ templateFile.moveCursorToText('');
- const completions =
- ngLS.getCompletionsAtPosition(fileName, cursor, /* options */ undefined);
+ const completions = templateFile.getCompletionsAtPosition();
expectContain(
completions, unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.ATTRIBUTE),
['value']);
expectContain(
completions, unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.PROPERTY),
['[value]']);
- expectReplacementText(completions, text, 'val');
+ expectReplacementText(completions, templateFile.contents, 'val');
});
it('should return completions for a partial property binding', () => {
- const {ngLS, fileName, cursor, text} = setup(``, '');
+ const {templateFile} = setup(``, '');
+ templateFile.moveCursorToText('[val¦]');
- const completions =
- ngLS.getCompletionsAtPosition(fileName, cursor, /* options */ undefined);
+ const completions = templateFile.getCompletionsAtPosition();
expectDoesNotContain(
completions, unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.ATTRIBUTE),
['value']);
@@ -373,16 +382,16 @@ describe('completions', () => {
expectContain(
completions, unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.PROPERTY),
['value']);
- expectReplacementText(completions, text, 'val');
+ expectReplacementText(completions, templateFile.contents, 'val');
});
});
describe('directive present', () => {
it('should return directive input completions for a new attribute', () => {
- const {ngLS, fileName, cursor, text} = setup(``, '', DIR_WITH_INPUT);
+ const {templateFile} = setup(``, '', DIR_WITH_INPUT);
+ templateFile.moveCursorToText('dir ¦>');
- const completions =
- ngLS.getCompletionsAtPosition(fileName, cursor, /* options */ undefined);
+ const completions = templateFile.getCompletionsAtPosition();
expectContain(
completions, unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.PROPERTY),
['[myInput]']);
@@ -392,10 +401,10 @@ describe('completions', () => {
});
it('should return directive input completions for a partial attribute', () => {
- const {ngLS, fileName, cursor, text} = setup(``, '', DIR_WITH_INPUT);
+ const {templateFile} = setup(``, '', DIR_WITH_INPUT);
+ templateFile.moveCursorToText('my¦>');
- const completions =
- ngLS.getCompletionsAtPosition(fileName, cursor, /* options */ undefined);
+ const completions = templateFile.getCompletionsAtPosition();
expectContain(
completions, unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.PROPERTY),
['[myInput]']);
@@ -405,10 +414,10 @@ describe('completions', () => {
});
it('should return input completions for a partial property binding', () => {
- const {ngLS, fileName, cursor, text} = setup(``, '', DIR_WITH_INPUT);
+ const {templateFile} = setup(``, '', DIR_WITH_INPUT);
+ templateFile.moveCursorToText('[my¦]');
- const completions =
- ngLS.getCompletionsAtPosition(fileName, cursor, /* options */ undefined);
+ const completions = templateFile.getCompletionsAtPosition();
expectContain(
completions, unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.PROPERTY),
['myInput']);
@@ -417,10 +426,10 @@ describe('completions', () => {
describe('structural directive present', () => {
it('should return structural directive completions for an empty attribute', () => {
- const {ngLS, fileName, cursor, text} = setup(`
`, '', NG_FOR_DIR);
+ const {templateFile} = setup(``, '', NG_FOR_DIR);
+ templateFile.moveCursorToText('');
- const completions =
- ngLS.getCompletionsAtPosition(fileName, cursor, /* options */ undefined);
+ const completions = templateFile.getCompletionsAtPosition();
expectContain(
completions, unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.DIRECTIVE),
['*ngFor']);
@@ -428,49 +437,49 @@ describe('completions', () => {
it('should return structural directive completions for an existing non-structural attribute',
() => {
- const {ngLS, fileName, cursor, text} = setup(``, '', NG_FOR_DIR);
+ const {templateFile} = setup(``, '', NG_FOR_DIR);
+ templateFile.moveCursorToText('');
- const completions =
- ngLS.getCompletionsAtPosition(fileName, cursor, /* options */ undefined);
+ const completions = templateFile.getCompletionsAtPosition();
expectContain(
completions,
unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.DIRECTIVE),
['*ngFor']);
- expectReplacementText(completions, text, 'ng');
+ expectReplacementText(completions, templateFile.contents, 'ng');
});
it('should return structural directive completions for an existing structural attribute',
() => {
- const {ngLS, fileName, cursor, text} = setup(``, '', NG_FOR_DIR);
+ const {templateFile} = setup(``, '', NG_FOR_DIR);
+ templateFile.moveCursorToText('*ng¦>');
- const completions =
- ngLS.getCompletionsAtPosition(fileName, cursor, /* options */ undefined);
+ const completions = templateFile.getCompletionsAtPosition();
expectContain(
completions,
unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.DIRECTIVE),
['ngFor']);
- expectReplacementText(completions, text, 'ng');
+ expectReplacementText(completions, templateFile.contents, 'ng');
});
it('should return structural directive completions for just the structural marker', () => {
- const {ngLS, fileName, cursor, text} = setup(``, '', NG_FOR_DIR);
+ const {templateFile} = setup(``, '', NG_FOR_DIR);
+ templateFile.moveCursorToText('*¦>');
- const completions =
- ngLS.getCompletionsAtPosition(fileName, cursor, /* options */ undefined);
+ const completions = templateFile.getCompletionsAtPosition();
expectContain(
completions, unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.DIRECTIVE),
['ngFor']);
// The completion should not try to overwrite the '*'.
- expectReplacementText(completions, text, '');
+ expectReplacementText(completions, templateFile.contents, '');
});
});
describe('directive not present', () => {
it('should return input completions for a new attribute', () => {
- const {ngLS, fileName, cursor, text} = setup(``, '', DIR_WITH_SELECTED_INPUT);
+ const {templateFile} = setup(``, '', DIR_WITH_SELECTED_INPUT);
+ templateFile.moveCursorToText('¦>');
- const completions =
- ngLS.getCompletionsAtPosition(fileName, cursor, /* options */ undefined);
+ const completions = templateFile.getCompletionsAtPosition();
// This context should generate two completions:
// * `[myInput]` as a property
// * `myInput` as an attribute
@@ -484,10 +493,10 @@ describe('completions', () => {
});
it('should return input completions for a partial attribute', () => {
- const {ngLS, fileName, cursor, text} = setup(``, '', DIR_WITH_SELECTED_INPUT);
+ const {templateFile} = setup(``, '', DIR_WITH_SELECTED_INPUT);
+ templateFile.moveCursorToText('my¦>');
- const completions =
- ngLS.getCompletionsAtPosition(fileName, cursor, /* options */ undefined);
+ const completions = templateFile.getCompletionsAtPosition();
// This context should generate two completions:
// * `[myInput]` as a property
// * `myInput` as an attribute
@@ -497,50 +506,49 @@ describe('completions', () => {
expectContain(
completions, unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.ATTRIBUTE),
['myInput']);
- expectReplacementText(completions, text, 'my');
+ expectReplacementText(completions, templateFile.contents, 'my');
});
it('should return input completions for a partial property binding', () => {
- const {ngLS, fileName, cursor, text} = setup(``, '', DIR_WITH_SELECTED_INPUT);
+ const {templateFile} = setup(``, '', DIR_WITH_SELECTED_INPUT);
+ templateFile.moveCursorToText('[my¦');
- const completions =
- ngLS.getCompletionsAtPosition(fileName, cursor, /* options */ undefined);
+ const completions = templateFile.getCompletionsAtPosition();
// This context should generate two completions:
// * `[myInput]` as a property
// * `myInput` as an attribute
expectContain(
completions, unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.PROPERTY),
['myInput']);
- expectReplacementText(completions, text, 'my');
+ expectReplacementText(completions, templateFile.contents, 'my');
});
it('should return output completions for an empty binding', () => {
- const {ngLS, fileName, cursor, text} = setup(``, '', DIR_WITH_OUTPUT);
+ const {templateFile} = setup(``, '', DIR_WITH_OUTPUT);
+ templateFile.moveCursorToText('¦>');
- const completions =
- ngLS.getCompletionsAtPosition(fileName, cursor, /* options */ undefined);
+ const completions = templateFile.getCompletionsAtPosition();
expectContain(
completions, unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.EVENT),
['(myOutput)']);
});
it('should return output completions for a partial event binding', () => {
- const {ngLS, fileName, cursor, text} = setup(``, '', DIR_WITH_OUTPUT);
+ const {templateFile} = setup(``, '', DIR_WITH_OUTPUT);
+ templateFile.moveCursorToText('(my¦)');
- const completions =
- ngLS.getCompletionsAtPosition(fileName, cursor, /* options */ undefined);
+ const completions = templateFile.getCompletionsAtPosition();
expectContain(
completions, unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.EVENT),
['myOutput']);
- expectReplacementText(completions, text, 'my');
+ expectReplacementText(completions, templateFile.contents, 'my');
});
it('should return completions inside an LHS of a partially complete two-way binding', () => {
- const {ngLS, fileName, cursor, text} =
- setup(``, ``, DIR_WITH_TWO_WAY_BINDING);
- const completions =
- ngLS.getCompletionsAtPosition(fileName, cursor, /* options */ undefined);
- expectReplacementText(completions, text, 'mod');
+ const {templateFile} = setup(``, ``, DIR_WITH_TWO_WAY_BINDING);
+ templateFile.moveCursorToText('[(mod¦)]');
+ const completions = templateFile.getCompletionsAtPosition();
+ expectReplacementText(completions, templateFile.contents, 'mod');
expectContain(completions, ts.ScriptElementKind.memberVariableElement, ['model']);
@@ -560,26 +568,29 @@ describe('completions', () => {
describe('pipe scope', () => {
it('should complete a pipe binding', () => {
- const {ngLS, fileName, cursor, text} = setup(`{{ foo | some¦ }}`, '', SOME_PIPE);
- const completions = ngLS.getCompletionsAtPosition(fileName, cursor, /* options */ undefined);
+ const {templateFile} = setup(`{{ foo | some¦ }}`, '', SOME_PIPE);
+ templateFile.moveCursorToText('some¦');
+ const completions = templateFile.getCompletionsAtPosition();
expectContain(
completions, unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.PIPE),
['somePipe']);
- expectReplacementText(completions, text, 'some');
+ expectReplacementText(completions, templateFile.contents, 'some');
});
it('should complete an empty pipe binding', () => {
- const {ngLS, fileName, cursor, text} = setup(`{{foo | ¦}}`, '', SOME_PIPE);
- const completions = ngLS.getCompletionsAtPosition(fileName, cursor, /* options */ undefined);
+ const {templateFile} = setup(`{{foo | }}`, '', SOME_PIPE);
+ templateFile.moveCursorToText('{{foo | ¦}}');
+ const completions = templateFile.getCompletionsAtPosition();
expectContain(
completions, unsafeCastDisplayInfoKindToScriptElementKind(DisplayInfoKind.PIPE),
['somePipe']);
- expectReplacementText(completions, text, '');
+ expectReplacementText(completions, templateFile.contents, '');
});
it('should not return extraneous completions', () => {
- const {ngLS, fileName, cursor, text} = setup(`{{ foo | some¦ }}`, '');
- const completions = ngLS.getCompletionsAtPosition(fileName, cursor, /* options */ undefined);
+ const {templateFile} = setup(`{{ foo | some }}`, '');
+ templateFile.moveCursorToText('{{ foo | some¦ }}');
+ const completions = templateFile.getCompletionsAtPosition();
expect(completions?.entries.length).toBe(0);
});
});
@@ -632,27 +643,16 @@ function toText(displayParts?: ts.SymbolDisplayPart[]): string {
}
function setup(
- templateWithCursor: string, classContents: string,
- otherDeclarations: {[name: string]: string} = {}): {
- env: LanguageServiceTestEnvironment,
- fileName: AbsoluteFsPath,
- AppCmp: ts.ClassDeclaration,
- ngLS: LanguageService,
- cursor: number,
- text: string,
+ template: string, classContents: string, otherDeclarations: {[name: string]: string} = {}): {
+ templateFile: OpenBuffer,
} {
- const codePath = absoluteFrom('/test.ts');
- const templatePath = absoluteFrom('/test.html');
-
const decls = ['AppCmp', ...Object.keys(otherDeclarations)];
const otherDirectiveClassDecls = Object.values(otherDeclarations).join('\n\n');
- const {cursor, text: templateWithoutCursor} = extractCursorInfo(templateWithCursor);
- const env = LanguageServiceTestEnvironment.setup([
- {
- name: codePath,
- contents: `
+ const env = LanguageServiceTestEnv.setup();
+ const project = env.addProject('test', {
+ 'test.ts': `
import {Component, Directive, NgModule, Pipe, TemplateRef} from '@angular/core';
@Component({
@@ -670,19 +670,7 @@ function setup(
})
export class AppModule {}
`,
- isRoot: true,
- },
- {
- name: templatePath,
- contents: templateWithoutCursor,
- }
- ]);
- return {
- env,
- fileName: templatePath,
- AppCmp: env.getClass(codePath, 'AppCmp'),
- ngLS: env.ngLS,
- text: templateWithoutCursor,
- cursor,
- };
+ 'test.html': template,
+ });
+ return {templateFile: project.openFile('test.html')};
}
diff --git a/packages/language-service/ivy/testing/src/buffer.ts b/packages/language-service/ivy/testing/src/buffer.ts
index 442ee374fcb..48a90c41cf0 100644
--- a/packages/language-service/ivy/testing/src/buffer.ts
+++ b/packages/language-service/ivy/testing/src/buffer.ts
@@ -64,4 +64,16 @@ export class OpenBuffer {
getDefinitionAndBoundSpan(): ts.DefinitionInfoAndBoundSpan|undefined {
return this.ngLS.getDefinitionAndBoundSpan(this.scriptInfo.fileName, this._cursor);
}
+
+ getCompletionsAtPosition(options?: ts.GetCompletionsAtPositionOptions):
+ ts.WithMetadata|undefined {
+ return this.ngLS.getCompletionsAtPosition(this.scriptInfo.fileName, this._cursor, options);
+ }
+
+ getCompletionEntryDetails(
+ entryName: string, formatOptions?: ts.FormatCodeOptions|ts.FormatCodeSettings,
+ preferences?: ts.UserPreferences): ts.CompletionEntryDetails|undefined {
+ return this.ngLS.getCompletionEntryDetails(
+ this.scriptInfo.fileName, this._cursor, entryName, formatOptions, preferences);
+ }
}