test(language-service): Move diagnostics tests to diagnostics_spec.ts (#33158)

This commit moves diagnostic specs in `ts_plugin_spec.ts` to
`diagnostics_spec.ts`.

PR Close #33158
This commit is contained in:
Keen Yee Liau 2019-10-14 15:24:04 -07:00 committed by Miško Hevery
parent fc93dafab1
commit 4c0726db9c
3 changed files with 84 additions and 74 deletions

View File

@ -24,6 +24,10 @@ import {MockTypescriptHost} from './test_utils';
* as well. * as well.
*/ */
const EXPRESSION_CASES = '/app/expression-cases.ts';
const NG_FOR_CASES = '/app/ng-for-cases.ts';
const NG_IF_CASES = '/app/ng-if-cases.ts';
describe('diagnostics', () => { describe('diagnostics', () => {
let mockHost: MockTypescriptHost; let mockHost: MockTypescriptHost;
let ngHost: TypeScriptServiceHost; let ngHost: TypeScriptServiceHost;
@ -57,6 +61,62 @@ describe('diagnostics', () => {
} }
}); });
describe('in expression-cases.ts', () => {
it('should report access to an unknown field', () => {
const diags = ngLS.getDiagnostics(EXPRESSION_CASES).map(d => d.messageText);
expect(diags).toContain(
`Identifier 'foo' is not defined. ` +
`The component declaration, template variable declarations, ` +
`and element references do not contain such a member`);
});
it('should report access to an unknown sub-field', () => {
const diags = ngLS.getDiagnostics(EXPRESSION_CASES).map(d => d.messageText);
expect(diags).toContain(
`Identifier 'nam' is not defined. 'Person' does not contain such a member`);
});
it('should report access to a private member', () => {
const diags = ngLS.getDiagnostics(EXPRESSION_CASES).map(d => d.messageText);
expect(diags).toContain(`Identifier 'myField' refers to a private member of the component`);
});
it('should report numeric operator errors', () => {
const diags = ngLS.getDiagnostics(EXPRESSION_CASES).map(d => d.messageText);
expect(diags).toContain('Expected a numeric type');
});
});
describe('in ng-for-cases.ts', () => {
it('should report an unknown field', () => {
const diags = ngLS.getDiagnostics(NG_FOR_CASES).map(d => d.messageText);
expect(diags).toContain(
`Identifier 'people_1' is not defined. ` +
`The component declaration, template variable declarations, ` +
`and element references do not contain such a member`);
});
it('should report an unknown context reference', () => {
const diags = ngLS.getDiagnostics(NG_FOR_CASES).map(d => d.messageText);
expect(diags).toContain(`The template context does not define a member called 'even_1'`);
});
it('should report an unknown value in a key expression', () => {
const diags = ngLS.getDiagnostics(NG_FOR_CASES).map(d => d.messageText);
expect(diags).toContain(
`Identifier 'trackBy_1' is not defined. ` +
`The component declaration, template variable declarations, ` +
`and element references do not contain such a member`);
});
});
describe('in ng-if-cases.ts', () => {
it('should report an implicit context reference', () => {
const diags = ngLS.getDiagnostics(NG_IF_CASES).map(d => d.messageText);
expect(diags).toContain(`The template context does not define a member called 'unknown'`);
});
});
// #17611 // #17611
it('should not report diagnostic on iteration of any', () => { it('should not report diagnostic on iteration of any', () => {
const fileName = '/app/test.ng'; const fileName = '/app/test.ng';

View File

@ -14,21 +14,31 @@ import {TypeScriptServiceHost} from '../src/typescript_host';
import {MockTypescriptHost} from './test_utils'; import {MockTypescriptHost} from './test_utils';
describe('service without angular', () => { describe('service without angular', () => {
let mockHost = new MockTypescriptHost(['/app/main.ts', '/app/parsing-cases.ts']); const mockHost = new MockTypescriptHost(['/app/main.ts', '/app/parsing-cases.ts']);
mockHost.forgetAngular(); const service = ts.createLanguageService(mockHost);
let service = ts.createLanguageService(mockHost); const ngHost = new TypeScriptServiceHost(mockHost, service);
let ngHost = new TypeScriptServiceHost(mockHost, service); const ngService = createLanguageService(ngHost);
let ngService = createLanguageService(ngHost);
const fileName = '/app/test.ng'; const fileName = '/app/test.ng';
const position = mockHost.getLocationMarkerFor(fileName, 'h1-content').start; const position = mockHost.getLocationMarkerFor(fileName, 'h1-content').start;
beforeEach(() => { mockHost.reset(); });
it('should not crash a get template references', it('should not crash a get template references',
() => expect(() => ngService.getTemplateReferences())); () => { expect(() => ngService.getTemplateReferences()).not.toThrow(); });
it('should not crash a get diagnostics', it('should not crash a get diagnostics',
() => expect(() => ngService.getDiagnostics(fileName)).not.toThrow()); () => { expect(() => ngService.getDiagnostics(fileName)).not.toThrow(); });
it('should not crash a completion', it('should not crash a completion',
() => expect(() => ngService.getCompletionsAt(fileName, position)).not.toThrow()); () => { expect(() => ngService.getCompletionsAt(fileName, position)).not.toThrow(); });
it('should not crash a get definition', it('should not crash a get definition',
() => expect(() => ngService.getDefinitionAt(fileName, position)).not.toThrow()); () => { expect(() => ngService.getDefinitionAt(fileName, position)).not.toThrow(); });
it('should not crash a hover', () => expect(() => ngService.getHoverAt(fileName, position)));
it('should not crash a hover',
() => { expect(() => ngService.getHoverAt(fileName, position)).not.toThrow(); });
it('should not crash with an incomplete class', () => {
mockHost.addCode('\nexport class');
expect(() => ngHost.getAnalyzedModules()).not.toThrow();
});
}); });

View File

@ -139,51 +139,6 @@ describe('plugin', () => {
}); });
describe('for semantic errors', () => { describe('for semantic errors', () => {
it('should report access to an unknown field', () => {
expectSemanticError(
'/app/expression-cases.ts', 'foo',
'Identifier \'foo\' is not defined. The component declaration, template variable declarations, and element references do not contain such a member');
});
it('should report access to an unknown sub-field', () => {
expectSemanticError(
'/app/expression-cases.ts', 'nam',
'Identifier \'nam\' is not defined. \'Person\' does not contain such a member');
});
it('should report access to a private member', () => {
expectSemanticError(
'/app/expression-cases.ts', 'myField',
'Identifier \'myField\' refers to a private member of the component');
});
it('should report numeric operator errors', () => {
expectSemanticError('/app/expression-cases.ts', 'mod', 'Expected a numeric type');
});
describe('in ngFor', () => {
function expectError(locationMarker: string, message: string) {
expectSemanticError('/app/ng-for-cases.ts', locationMarker, message);
}
it('should report an unknown field', () => {
expectError(
'people_1',
'Identifier \'people_1\' is not defined. The component declaration, template variable declarations, and element references do not contain such a member');
});
it('should report an unknown context reference', () => {
expectError('even_1', `The template context does not define a member called 'even_1'`);
});
it('should report an unknown value in a key expression', () => {
expectError(
'trackBy_1',
'Identifier \'trackBy_1\' is not defined. The component declaration, template variable declarations, and element references do not contain such a member');
});
});
describe('in ngIf', () => {
function expectError(locationMarker: string, message: string) {
expectSemanticError('/app/ng-if-cases.ts', locationMarker, message);
}
it('should report an implicit context reference', () => {
expectError('implicit', `The template context does not define a member called 'unknown'`);
});
});
describe(`with config 'angularOnly = true`, () => { describe(`with config 'angularOnly = true`, () => {
const ngLS = createPlugin(service, mockHost, {angularOnly: true}); const ngLS = createPlugin(service, mockHost, {angularOnly: true});
it('should not report template errors on TOH', () => { it('should not report template errors on TOH', () => {
@ -236,21 +191,6 @@ describe('plugin', () => {
locationMarker, plugin.getCompletionsAtPosition(fileName, marker.start, undefined) !, locationMarker, plugin.getCompletionsAtPosition(fileName, marker.start, undefined) !,
...names); ...names);
} }
function expectSemanticError(fileName: string, locationMarker: string, message: string) {
const marker = mockHost.getLocationMarkerFor(fileName, locationMarker);
const errors = plugin.getSemanticDiagnostics(fileName);
for (const error of errors) {
if (error.messageText.toString().indexOf(message) >= 0) {
expect(error.start).toEqual(marker.start);
expect(error.length).toEqual(marker.length);
return;
}
}
throw new Error(`Expected error messages to contain ${message}, in messages:\n ${errors
.map(e => e.messageText.toString())
.join(',\n ')}`);
}
}); });