test(language-service): Remove redundant marker methods in MockHost (#33115)

Remove the following methods from MockHost:

1. `getMarkerLocations`: Replaced with `getLocationMarkerFor()`
2. `getReferenceMarkers`: Replaced with `getReferenceMarkerFor()`

PR Close #33115
This commit is contained in:
Keen Yee Liau 2019-10-11 13:56:33 -07:00 committed by Miško Hevery
parent 1a67d70bf8
commit 84ba1f012e
7 changed files with 85 additions and 77 deletions

View File

@ -196,11 +196,8 @@ describe('completions', () => {
}); });
function expectContains(fileName: string, locationMarker: string, ...names: string[]) { function expectContains(fileName: string, locationMarker: string, ...names: string[]) {
let location = mockHost.getMarkerLocations(fileName) ![locationMarker]; const marker = mockHost.getLocationMarkerFor(fileName, locationMarker);
if (location == null) { expectEntries(locationMarker, ngService.getCompletionsAt(fileName, marker.start), ...names);
throw new Error(`No marker ${locationMarker} found.`);
}
expectEntries(locationMarker, ngService.getCompletionsAt(fileName, location), ...names);
} }
}); });

View File

@ -20,7 +20,7 @@ describe('service without angular', () => {
let ngHost = new TypeScriptServiceHost(mockHost, service); let ngHost = new TypeScriptServiceHost(mockHost, service);
let ngService = createLanguageService(ngHost); let ngService = createLanguageService(ngHost);
const fileName = '/app/test.ng'; const fileName = '/app/test.ng';
let position = mockHost.getMarkerLocations(fileName) !['h1-content']; const position = mockHost.getLocationMarkerFor(fileName, 'h1-content').start;
it('should not crash a get template references', it('should not crash a get template references',
() => expect(() => ngService.getTemplateReferences())); () => expect(() => ngService.getTemplateReferences()));

View File

@ -14,28 +14,28 @@ export interface Person {
} }
@Component({ @Component({
template: '{{~{foo}foo~{foo-end}}}', template: '{{~{start-foo}foo~{end-foo}}}',
}) })
export class WrongFieldReference { export class WrongFieldReference {
bar = 'bar'; bar = 'bar';
} }
@Component({ @Component({
template: '{{~{nam}person.nam~{nam-end}}}', template: '{{~{start-nam}person.nam~{end-nam}}}',
}) })
export class WrongSubFieldReference { export class WrongSubFieldReference {
person: Person = {name: 'Bob', age: 23}; person: Person = {name: 'Bob', age: 23};
} }
@Component({ @Component({
template: '{{~{myField}myField~{myField-end}}}', template: '{{~{start-myField}myField~{end-myField}}}',
}) })
export class PrivateReference { export class PrivateReference {
private myField = 'My Field'; private myField = 'My Field';
} }
@Component({ @Component({
template: '{{~{mod}"a" ~{mod-end}% 2}}', template: '{{~{start-mod}"a" ~{end-mod}% 2}}',
}) })
export class ExpectNumericType { export class ExpectNumericType {
} }

View File

@ -15,7 +15,7 @@ export interface Person {
@Component({ @Component({
template: ` template: `
<div *ngFor="let person of ~{people_1}people_1~{people_1-end}"> <div *ngFor="let person of ~{start-people_1}people_1~{end-people_1}">
<span>{{person.name}}</span> <span>{{person.name}}</span>
</div>`, </div>`,
}) })
@ -24,7 +24,7 @@ export class UnknownPeople {
@Component({ @Component({
template: ` template: `
<div ~{even_1}*ngFor="let person of people; let e = even_1"~{even_1-end}> <div ~{start-even_1}*ngFor="let person of people; let e = even_1"~{end-even_1}>
<span>{{person.name}}</span> <span>{{person.name}}</span>
</div>`, </div>`,
}) })
@ -34,7 +34,7 @@ export class UnknownEven {
@Component({ @Component({
template: ` template: `
<div *ngFor="let person of people; trackBy ~{trackBy_1}trackBy_1~{trackBy_1-end}"> <div *ngFor="let person of people; trackBy ~{start-trackBy_1}trackBy_1~{end-trackBy_1}">
<span>{{person.name}}</span> <span>{{person.name}}</span>
</div>`, </div>`,
}) })

View File

@ -10,7 +10,7 @@ import {Component} from '@angular/core';
@Component({ @Component({
template: ` template: `
<div ~{implicit}*ngIf="show; let l=unknown"~{implicit-end}> <div ~{start-implicit}*ngIf="show; let l=unknown"~{end-implicit}>
Showing now! Showing now!
</div>`, </div>`,
}) })

View File

@ -181,20 +181,6 @@ export class MockTypescriptHost implements ts.LanguageServiceHost {
} }
} }
getMarkerLocations(fileName: string): {[name: string]: number}|undefined {
let content = this.getRawFileContent(fileName);
if (content) {
return getLocationMarkers(content);
}
}
getReferenceMarkers(fileName: string): ReferenceResult|undefined {
let content = this.getRawFileContent(fileName);
if (content) {
return getReferenceMarkers(content);
}
}
/** /**
* Reset the project to its original state, effectively removing all overrides. * Reset the project to its original state, effectively removing all overrides.
*/ */
@ -279,61 +265,94 @@ export class MockTypescriptHost implements ts.LanguageServiceHost {
} }
/** /**
* Returns the definition marker selectorᐱ for the specified 'selector'. * Returns the definition marker `ᐱselectorᐱ` for the specified 'selector'.
* Asserts that marker exists. * Asserts that marker exists.
* @param fileName name of the file * @param fileName name of the file
* @param selector name of the marker * @param selector name of the marker
*/ */
getDefinitionMarkerFor(fileName: string, selector: string): ts.TextSpan { getDefinitionMarkerFor(fileName: string, selector: string): ts.TextSpan {
const markers = this.getReferenceMarkers(fileName); const content = this.getRawFileContent(fileName);
expect(markers).toBeDefined(); if (!content) {
expect(Object.keys(markers !.definitions)).toContain(selector); throw new Error(`File does not exist: ${fileName}`);
expect(markers !.definitions[selector].length).toBe(1); }
const marker = markers !.definitions[selector][0]; const markers = getReferenceMarkers(content);
expect(marker.start).toBeLessThanOrEqual(marker.end); const definitions = markers.definitions[selector];
if (!definitions || !definitions.length) {
throw new Error(`Failed to find marker '${selector}' in ${fileName}`);
}
if (definitions.length > 1) {
throw new Error(`Multiple positions found for '${selector}' in ${fileName}`);
}
const {start, end} = definitions[0];
if (start > end) {
throw new Error(`Marker '${selector}' in ${fileName} is invalid: ${start} > ${end}`);
}
return { return {
start: marker.start, start,
length: marker.end - marker.start, length: end - start,
}; };
} }
/** /**
* Returns the reference marker «selector» for the specified 'selector'. * Returns the reference marker `«selector»` for the specified 'selector'.
* Asserts that marker exists. * Asserts that marker exists.
* @param fileName name of the file * @param fileName name of the file
* @param selector name of the marker * @param selector name of the marker
*/ */
getReferenceMarkerFor(fileName: string, selector: string): ts.TextSpan { getReferenceMarkerFor(fileName: string, selector: string): ts.TextSpan {
const markers = this.getReferenceMarkers(fileName); const content = this.getRawFileContent(fileName);
expect(markers).toBeDefined(); if (!content) {
expect(Object.keys(markers !.references)).toContain(selector); throw new Error(`File does not exist: ${fileName}`);
expect(markers !.references[selector].length).toBe(1); }
const marker = markers !.references[selector][0]; const markers = getReferenceMarkers(content);
expect(marker.start).toBeLessThanOrEqual(marker.end); const references = markers.references[selector];
if (!references || !references.length) {
throw new Error(`Failed to find marker '${selector}' in ${fileName}`);
}
if (references.length > 1) {
throw new Error(`Multiple positions found for '${selector}' in ${fileName}`);
}
const {start, end} = references[0];
if (start > end) {
throw new Error(`Marker '${selector}' in ${fileName} is invalid: ${start} > ${end}`);
}
return { return {
start: marker.start, start,
length: marker.end - marker.start, length: end - start,
}; };
} }
/** /**
* Returns the location marker ~{selector} for the specified 'selector'. * Returns the location marker `~{selector}` or the marker pair
* `~{start-selector}` and `~{end-selector}` for the specified 'selector'.
* Asserts that marker exists. * Asserts that marker exists.
* @param fileName name of the file * @param fileName name of the file
* @param selector name of the marker * @param selector name of the marker
*/ */
getLocationMarkerFor(fileName: string, selector: string): ts.TextSpan { getLocationMarkerFor(fileName: string, selector: string): ts.TextSpan {
const markers = this.getMarkerLocations(fileName); const content = this.getRawFileContent(fileName);
expect(markers).toBeDefined(); if (!content) {
const start = markers ![`start-${selector}`]; throw new Error(`File does not exist: ${fileName}`);
expect(start).toBeDefined(); }
const end = markers ![`end-${selector}`]; const markers = getLocationMarkers(content);
expect(end).toBeDefined(); // Look for just the selector itself
expect(start).toBeLessThanOrEqual(end); const position = markers[selector];
return { if (position !== undefined) {
start: start, return {
length: end - start, start: position,
}; length: 0,
};
}
// Look for start and end markers for the selector
const start = markers[`start-${selector}`];
const end = markers[`end-${selector}`];
if (start !== undefined && end !== undefined) {
return {
start,
length: end - start,
};
}
throw new Error(`Failed to find marker '${selector}' in ${fileName}`);
} }
} }

View File

@ -167,7 +167,7 @@ describe('plugin', () => {
'Identifier \'people_1\' is not defined. The component declaration, template variable declarations, and element references do not contain such a member'); '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', () => { it('should report an unknown context reference', () => {
expectError('even_1', 'The template context does not define a member called \'even_1\''); expectError('even_1', `The template context does not define a member called 'even_1'`);
}); });
it('should report an unknown value in a key expression', () => { it('should report an unknown value in a key expression', () => {
expectError( expectError(
@ -180,7 +180,7 @@ describe('plugin', () => {
expectSemanticError('/app/ng-if-cases.ts', locationMarker, message); expectSemanticError('/app/ng-if-cases.ts', locationMarker, message);
} }
it('should report an implicit context reference', () => { it('should report an implicit context reference', () => {
expectError('implicit', 'The template context does not define a member called \'unknown\''); expectError('implicit', `The template context does not define a member called 'unknown'`);
}); });
}); });
@ -199,11 +199,10 @@ describe('plugin', () => {
it('should be able to get entity completions', () => { it('should be able to get entity completions', () => {
const fileName = '/app/app.component.ts'; const fileName = '/app/app.component.ts';
const marker = 'entity-amp'; const marker = mockHost.getLocationMarkerFor(fileName, 'entity-amp');
const position = getMarkerLocation(fileName, marker); const results = ngLS.getCompletionsAtPosition(fileName, marker.start, {} /* options */);
const results = ngLS.getCompletionsAtPosition(fileName, position, {} /* options */);
expect(results).toBeTruthy(); expect(results).toBeTruthy();
expectEntries(marker, results !, ...['&amp;', '&gt;', '&lt;', '&iota;']); expectEntries('entity-amp', results !, ...['&amp;', '&gt;', '&lt;', '&iota;']);
}); });
it('should report template diagnostics', () => { it('should report template diagnostics', () => {
@ -231,27 +230,20 @@ describe('plugin', () => {
}); });
} }
function getMarkerLocation(fileName: string, locationMarker: string): number {
const location = mockHost.getMarkerLocations(fileName) ![locationMarker];
if (location == null) {
throw new Error(`No marker ${locationMarker} found.`);
}
return location;
}
function contains(fileName: string, locationMarker: string, ...names: string[]) { function contains(fileName: string, locationMarker: string, ...names: string[]) {
const location = getMarkerLocation(fileName, locationMarker); const marker = mockHost.getLocationMarkerFor(fileName, locationMarker);
expectEntries( expectEntries(
locationMarker, plugin.getCompletionsAtPosition(fileName, location, undefined) !, ...names); locationMarker, plugin.getCompletionsAtPosition(fileName, marker.start, undefined) !,
...names);
} }
function expectSemanticError(fileName: string, locationMarker: string, message: string) { function expectSemanticError(fileName: string, locationMarker: string, message: string) {
const start = getMarkerLocation(fileName, locationMarker); const marker = mockHost.getLocationMarkerFor(fileName, locationMarker);
const end = getMarkerLocation(fileName, locationMarker + '-end');
const errors = plugin.getSemanticDiagnostics(fileName); const errors = plugin.getSemanticDiagnostics(fileName);
for (const error of errors) { for (const error of errors) {
if (error.messageText.toString().indexOf(message) >= 0) { if (error.messageText.toString().indexOf(message) >= 0) {
expect(error.start).toEqual(start); expect(error.start).toEqual(marker.start);
expect(error.length).toEqual(end - start); expect(error.length).toEqual(marker.length);
return; return;
} }
} }