angular-cn/packages/language-service/test/references_spec.ts

79 lines
2.7 KiB
TypeScript

/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import * as ts from 'typescript';
import {createLanguageService} from '../src/language_service';
import {TypeScriptServiceHost} from '../src/typescript_host';
import {MockTypescriptHost} from './test_utils';
const APP_COMPONENT = '/app/app.component.ts';
const TEST_TEMPLATE = '/app/test.ng';
describe('references', () => {
const mockHost = new MockTypescriptHost(['/app/main.ts']);
const tsLS = ts.createLanguageService(mockHost);
const ngHost = new TypeScriptServiceHost(mockHost, tsLS);
const ngLS = createLanguageService(ngHost);
beforeEach(() => {
mockHost.reset();
});
for (const templateStrategy of ['inline', 'external'] as const) {
describe(`template: ${templateStrategy}`, () => {
describe('component members', () => {
it('should get TS references for a member in template', () => {
const fileName = overrideTemplate('{{«title»}}');
const marker = mockHost.getReferenceMarkerFor(fileName, 'title');
const references = ngLS.getReferencesAtPosition(fileName, marker.start)!;
expect(references).toBeDefined();
expect(references.length).toBe(2);
for (let i = 0; i < references.length; ++i) {
// The first reference is declared as a class member.
// The second is in `setTitle`.
const ref = references[i];
expect(getSource(ref)).toBe('title');
if (i == 0) {
// The first reference is the member declaration, so it should
// have a context span pointing to the whole declaration.
expect(getSource(ref, 'contextSpan')).toBe('title = \'Tour of Heroes\';');
}
}
});
});
});
// TODO: override parsing-cases#TemplateReference for inline templates.
const overrideTemplate = (template: string): string => {
if (templateStrategy === 'inline') {
mockHost.overrideInlineTemplate(APP_COMPONENT, template);
return APP_COMPONENT;
} else {
mockHost.override(TEST_TEMPLATE, template);
return TEST_TEMPLATE;
}
};
}
/**
* Gets the source code of a reference entry. By default the reference
* `textSpan` is checked, but this can be overridden by specifying `spanKind`.
*/
function getSource(
reference: ts.ReferenceEntry, spanKind: 'textSpan'|'contextSpan' = 'textSpan'): string {
const span = reference[spanKind]!;
const fileName = reference.fileName;
const content = mockHost.readFile(fileName)!;
return content.substring(span.start, span.start + span.length);
}
});