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:
parent
fc93dafab1
commit
4c0726db9c
|
@ -24,6 +24,10 @@ import {MockTypescriptHost} from './test_utils';
|
|||
* 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', () => {
|
||||
let mockHost: MockTypescriptHost;
|
||||
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
|
||||
it('should not report diagnostic on iteration of any', () => {
|
||||
const fileName = '/app/test.ng';
|
||||
|
@ -487,7 +547,7 @@ describe('diagnostics', () => {
|
|||
describe('templates', () => {
|
||||
it('should report errors for invalid templateUrls', () => {
|
||||
const fileName = mockHost.addCode(`
|
||||
@Component({
|
||||
@Component({
|
||||
templateUrl: '«notAFile»',
|
||||
})
|
||||
export class MyComponent {}`);
|
||||
|
@ -506,10 +566,10 @@ describe('diagnostics', () => {
|
|||
|
||||
it('should not report errors for valid templateUrls', () => {
|
||||
const fileName = mockHost.addCode(`
|
||||
@Component({
|
||||
@Component({
|
||||
templateUrl: './test.ng',
|
||||
})
|
||||
export class MyComponent {}`);
|
||||
})
|
||||
export class MyComponent {}`);
|
||||
|
||||
const diagnostics = ngLS.getDiagnostics(fileName) !;
|
||||
const urlDiagnostic =
|
||||
|
|
|
@ -14,21 +14,31 @@ import {TypeScriptServiceHost} from '../src/typescript_host';
|
|||
import {MockTypescriptHost} from './test_utils';
|
||||
|
||||
describe('service without angular', () => {
|
||||
let mockHost = new MockTypescriptHost(['/app/main.ts', '/app/parsing-cases.ts']);
|
||||
mockHost.forgetAngular();
|
||||
let service = ts.createLanguageService(mockHost);
|
||||
let ngHost = new TypeScriptServiceHost(mockHost, service);
|
||||
let ngService = createLanguageService(ngHost);
|
||||
const mockHost = new MockTypescriptHost(['/app/main.ts', '/app/parsing-cases.ts']);
|
||||
const service = ts.createLanguageService(mockHost);
|
||||
const ngHost = new TypeScriptServiceHost(mockHost, service);
|
||||
const ngService = createLanguageService(ngHost);
|
||||
const fileName = '/app/test.ng';
|
||||
const position = mockHost.getLocationMarkerFor(fileName, 'h1-content').start;
|
||||
|
||||
beforeEach(() => { mockHost.reset(); });
|
||||
|
||||
it('should not crash a get template references',
|
||||
() => expect(() => ngService.getTemplateReferences()));
|
||||
() => { expect(() => ngService.getTemplateReferences()).not.toThrow(); });
|
||||
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',
|
||||
() => expect(() => ngService.getCompletionsAt(fileName, position)).not.toThrow());
|
||||
() => { expect(() => ngService.getCompletionsAt(fileName, position)).not.toThrow(); });
|
||||
|
||||
it('should not crash a get definition',
|
||||
() => expect(() => ngService.getDefinitionAt(fileName, position)).not.toThrow());
|
||||
it('should not crash a hover', () => expect(() => ngService.getHoverAt(fileName, position)));
|
||||
() => { expect(() => ngService.getDefinitionAt(fileName, position)).not.toThrow(); });
|
||||
|
||||
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();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -139,51 +139,6 @@ describe('plugin', () => {
|
|||
});
|
||||
|
||||
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`, () => {
|
||||
const ngLS = createPlugin(service, mockHost, {angularOnly: true});
|
||||
it('should not report template errors on TOH', () => {
|
||||
|
@ -236,21 +191,6 @@ describe('plugin', () => {
|
|||
locationMarker, plugin.getCompletionsAtPosition(fileName, marker.start, undefined) !,
|
||||
...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 ')}`);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue