diff --git a/packages/language-service/test/completions_spec.ts b/packages/language-service/test/completions_spec.ts
index 6795b97a50..b6ec2ac2a7 100644
--- a/packages/language-service/test/completions_spec.ts
+++ b/packages/language-service/test/completions_spec.ts
@@ -9,7 +9,7 @@
import * as ts from 'typescript';
import {createLanguageService} from '../src/language_service';
-import {CompletionKind, LanguageService} from '../src/types';
+import {CompletionKind} from '../src/types';
import {TypeScriptServiceHost} from '../src/typescript_host';
import {MockTypescriptHost} from './test_utils';
@@ -25,6 +25,8 @@ describe('completions', () => {
const ngHost = new TypeScriptServiceHost(mockHost, tsLS);
const ngLS = createLanguageService(ngHost);
+ beforeEach(() => { mockHost.reset(); });
+
it('should be able to get entity completions', () => {
const marker = mockHost.getLocationMarkerFor(APP_COMPONENT, 'entity-amp');
const completions = ngLS.getCompletionsAt(APP_COMPONENT, marker.start);
@@ -370,192 +372,182 @@ describe('completions', () => {
// expectContain(completions, CompletionKind.PROPERTY, ['innerText']);
// });
});
-});
-describe('replace completions correctly', () => {
- const mockHost = new MockTypescriptHost(['/app/main.ts']);
- let ngLS: LanguageService;
+ describe('replacement span', () => {
+ it('should not generate replacement entries for zero-length replacements', () => {
+ const fileName = mockHost.addCode(`
+ @Component({
+ selector: 'foo-component',
+ template: \`
+
{{obj.~{key}}}
+ \`,
+ })
+ export class FooComponent {
+ obj: {key: 'value'};
+ }
+ `);
+ const location = mockHost.getLocationMarkerFor(fileName, 'key');
+ const completions = ngLS.getCompletionsAt(fileName, location.start) !;
+ expect(completions).toBeDefined();
+ const completion = completions.entries.find(entry => entry.name === 'key') !;
+ expect(completion).toBeDefined();
+ expect(completion.kind).toBe('property');
+ expect(completion.replacementSpan).toBeUndefined();
+ });
- beforeEach(() => {
- mockHost.reset();
- const tsLS = ts.createLanguageService(mockHost);
- const ngHost = new TypeScriptServiceHost(mockHost, tsLS);
- ngLS = createLanguageService(ngHost);
- });
+ it('should work for start of template', () => {
+ const fileName = mockHost.addCode(`
+ @Component({
+ selector: 'foo-component',
+ template: \`~{start}abc\`,
+ })
+ export class FooComponent {}
+ `);
+ const location = mockHost.getLocationMarkerFor(fileName, 'start');
+ const completions = ngLS.getCompletionsAt(fileName, location.start) !;
+ expect(completions).toBeDefined();
+ const completion = completions.entries.find(entry => entry.name === 'acronym') !;
+ expect(completion).toBeDefined();
+ expect(completion.kind).toBe('html element');
+ expect(completion.replacementSpan).toEqual({start: location.start, length: 3});
+ });
- it('should not generate replacement entries for zero-length replacements', () => {
- const fileName = mockHost.addCode(`
- @Component({
- selector: 'foo-component',
- template: \`
- {{obj.~{key}}}
- \`,
- })
- export class FooComponent {
- obj: {key: 'value'};
- }
- `);
- const location = mockHost.getLocationMarkerFor(fileName, 'key');
- const completions = ngLS.getCompletionsAt(fileName, location.start) !;
- expect(completions).toBeDefined();
- const completion = completions.entries.find(entry => entry.name === 'key') !;
- expect(completion).toBeDefined();
- expect(completion.kind).toBe('property');
- expect(completion.replacementSpan).toBeUndefined();
- });
+ it('should work for end of template', () => {
+ const fileName = mockHost.addCode(`
+ @Component({
+ selector: 'foo-component',
+ template: \`acro~{end}\`,
+ })
+ export class FooComponent {}
+ `);
+ const location = mockHost.getLocationMarkerFor(fileName, 'end');
+ const completions = ngLS.getCompletionsAt(fileName, location.start) !;
+ expect(completions).toBeDefined();
+ const completion = completions.entries.find(entry => entry.name === 'acronym') !;
+ expect(completion).toBeDefined();
+ expect(completion.kind).toBe('html element');
+ expect(completion.replacementSpan).toEqual({start: location.start - 4, length: 4});
+ });
- it('should work for start of template', () => {
- const fileName = mockHost.addCode(`
- @Component({
- selector: 'foo-component',
- template: \`~{start}abc\`,
- })
- export class FooComponent {}
- `);
- const location = mockHost.getLocationMarkerFor(fileName, 'start');
- const completions = ngLS.getCompletionsAt(fileName, location.start) !;
- expect(completions).toBeDefined();
- const completion = completions.entries.find(entry => entry.name === 'acronym') !;
- expect(completion).toBeDefined();
- expect(completion.kind).toBe('html element');
- expect(completion.replacementSpan).toEqual({start: location.start, length: 3});
- });
+ it('should work for middle-word replacements', () => {
+ const fileName = mockHost.addCode(`
+ @Component({
+ selector: 'foo-component',
+ template: \`
+ {{obj.ke~{key}key}}
+ \`,
+ })
+ export class FooComponent {
+ obj: {key: 'value'};
+ }
+ `);
+ const location = mockHost.getLocationMarkerFor(fileName, 'key');
+ const completions = ngLS.getCompletionsAt(fileName, location.start) !;
+ expect(completions).toBeDefined();
+ const completion = completions.entries.find(entry => entry.name === 'key') !;
+ expect(completion).toBeDefined();
+ expect(completion.kind).toBe('property');
+ expect(completion.replacementSpan).toEqual({start: location.start - 2, length: 5});
+ });
- it('should work for end of template', () => {
- const fileName = mockHost.addCode(`
- @Component({
- selector: 'foo-component',
- template: \`acro~{end}\`,
- })
- export class FooComponent {}
- `);
- const location = mockHost.getLocationMarkerFor(fileName, 'end');
- const completions = ngLS.getCompletionsAt(fileName, location.start) !;
- expect(completions).toBeDefined();
- const completion = completions.entries.find(entry => entry.name === 'acronym') !;
- expect(completion).toBeDefined();
- expect(completion.kind).toBe('html element');
- expect(completion.replacementSpan).toEqual({start: location.start - 4, length: 4});
- });
+ it('should work for all kinds of identifier characters', () => {
+ const fileName = mockHost.addCode(`
+ @Component({
+ selector: 'foo-component',
+ template: \`
+ {{~{field}$title_1}}
+ \`,
+ })
+ export class FooComponent {
+ $title_1: string;
+ }
+ `);
+ const location = mockHost.getLocationMarkerFor(fileName, 'field');
+ const completions = ngLS.getCompletionsAt(fileName, location.start) !;
+ expect(completions).toBeDefined();
+ const completion = completions.entries.find(entry => entry.name === '$title_1') !;
+ expect(completion).toBeDefined();
+ expect(completion.kind).toBe('property');
+ expect(completion.replacementSpan).toEqual({start: location.start, length: 8});
+ });
- it('should work for middle-word replacements', () => {
- const fileName = mockHost.addCode(`
- @Component({
- selector: 'foo-component',
- template: \`
- {{obj.ke~{key}key}}
- \`,
- })
- export class FooComponent {
- obj: {key: 'value'};
- }
- `);
- const location = mockHost.getLocationMarkerFor(fileName, 'key');
- const completions = ngLS.getCompletionsAt(fileName, location.start) !;
- expect(completions).toBeDefined();
- const completion = completions.entries.find(entry => entry.name === 'key') !;
- expect(completion).toBeDefined();
- expect(completion.kind).toBe('property');
- expect(completion.replacementSpan).toEqual({start: location.start - 2, length: 5});
- });
+ it('should work for attributes', () => {
+ const fileName = mockHost.addCode(`
+ @Component({
+ selector: 'foo-component',
+ template: \`
+
+ \`,
+ })
+ export class FooComponent {}
+ `);
+ const location = mockHost.getLocationMarkerFor(fileName, 'click');
+ const completions = ngLS.getCompletionsAt(fileName, location.start) !;
+ expect(completions).toBeDefined();
+ const completion = completions.entries.find(entry => entry.name === '(click)') !;
+ expect(completion).toBeDefined();
+ expect(completion.kind).toBe('attribute');
+ expect(completion.replacementSpan).toEqual({start: location.start - 2, length: 2});
+ });
- it('should work for all kinds of identifier characters', () => {
- const fileName = mockHost.addCode(`
- @Component({
- selector: 'foo-component',
- template: \`
- {{~{field}$title_1}}
- \`,
- })
- export class FooComponent {
- $title_1: string;
- }
- `);
- const location = mockHost.getLocationMarkerFor(fileName, 'field');
- const completions = ngLS.getCompletionsAt(fileName, location.start) !;
- expect(completions).toBeDefined();
- const completion = completions.entries.find(entry => entry.name === '$title_1') !;
- expect(completion).toBeDefined();
- expect(completion.kind).toBe('property');
- expect(completion.replacementSpan).toEqual({start: location.start, length: 8});
- });
+ it('should work for events', () => {
+ const fileName = mockHost.addCode(`
+ @Component({
+ selector: 'foo-component',
+ template: \`
+
+ \`,
+ })
+ export class FooComponent {
+ handleClick() {}
+ }
+ `);
+ const location = mockHost.getLocationMarkerFor(fileName, 'handleClick');
+ const completions = ngLS.getCompletionsAt(fileName, location.start) !;
+ expect(completions).toBeDefined();
+ const completion = completions.entries.find(entry => entry.name === 'handleClick') !;
+ expect(completion).toBeDefined();
+ expect(completion.kind).toBe('method');
+ expect(completion.replacementSpan).toEqual({start: location.start - 3, length: 3});
+ });
- it('should work for attributes', () => {
- const fileName = mockHost.addCode(`
- @Component({
- selector: 'foo-component',
- template: \`
-
- \`,
- })
- export class FooComponent {}
- `);
- const location = mockHost.getLocationMarkerFor(fileName, 'click');
- const completions = ngLS.getCompletionsAt(fileName, location.start) !;
- expect(completions).toBeDefined();
- const completion = completions.entries.find(entry => entry.name === '(click)') !;
- expect(completion).toBeDefined();
- expect(completion.kind).toBe('attribute');
- expect(completion.replacementSpan).toEqual({start: location.start - 2, length: 2});
- });
+ it('should work for element names', () => {
+ const fileName = mockHost.addCode(`
+ @Component({
+ selector: 'foo-component',
+ template: \`
+
+ \`,
+ })
+ export class FooComponent {}
+ `);
+ const location = mockHost.getLocationMarkerFor(fileName, 'div');
+ const completions = ngLS.getCompletionsAt(fileName, location.start) !;
+ expect(completions).toBeDefined();
+ const completion = completions.entries.find(entry => entry.name === 'div') !;
+ expect(completion).toBeDefined();
+ expect(completion.kind).toBe('html element');
+ expect(completion.replacementSpan).toEqual({start: location.start - 2, length: 2});
+ });
- it('should work for events', () => {
- const fileName = mockHost.addCode(`
- @Component({
- selector: 'foo-component',
- template: \`
-
- \`,
- })
- export class FooComponent {
- handleClick() {}
- }
- `);
- const location = mockHost.getLocationMarkerFor(fileName, 'handleClick');
- const completions = ngLS.getCompletionsAt(fileName, location.start) !;
- expect(completions).toBeDefined();
- const completion = completions.entries.find(entry => entry.name === 'handleClick') !;
- expect(completion).toBeDefined();
- expect(completion.kind).toBe('method');
- expect(completion.replacementSpan).toEqual({start: location.start - 3, length: 3});
- });
-
- it('should work for element names', () => {
- const fileName = mockHost.addCode(`
- @Component({
- selector: 'foo-component',
- template: \`
-
- \`,
- })
- export class FooComponent {}
- `);
- const location = mockHost.getLocationMarkerFor(fileName, 'div');
- const completions = ngLS.getCompletionsAt(fileName, location.start) !;
- expect(completions).toBeDefined();
- const completion = completions.entries.find(entry => entry.name === 'div') !;
- expect(completion).toBeDefined();
- expect(completion.kind).toBe('html element');
- expect(completion.replacementSpan).toEqual({start: location.start - 2, length: 2});
- });
-
- it('should work for bindings', () => {
- const fileName = mockHost.addCode(`
- @Component({
- selector: 'foo-component',
- template: \`
+ it('should work for bindings', () => {
+ const fileName = mockHost.addCode(`
+ @Component({
+ selector: 'foo-component',
+ template: \`
- \`,
- })
- export class FooComponent {}
- `);
- const location = mockHost.getLocationMarkerFor(fileName, 'model');
- const completions = ngLS.getCompletionsAt(fileName, location.start) !;
- expect(completions).toBeDefined();
- const completion = completions.entries.find(entry => entry.name === '[(ngModel)]') !;
- expect(completion).toBeDefined();
- expect(completion.kind).toBe('attribute');
- expect(completion.replacementSpan).toEqual({start: location.start - 5, length: 5});
+ \`,
+ })
+ export class FooComponent {}
+ `);
+ const location = mockHost.getLocationMarkerFor(fileName, 'model');
+ const completions = ngLS.getCompletionsAt(fileName, location.start) !;
+ expect(completions).toBeDefined();
+ const completion = completions.entries.find(entry => entry.name === '[(ngModel)]') !;
+ expect(completion).toBeDefined();
+ expect(completion.kind).toBe('attribute');
+ expect(completion.replacementSpan).toEqual({start: location.start - 5, length: 5});
+ });
});
});