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[]) {
let location = mockHost.getMarkerLocations(fileName) ![locationMarker];
if (location == null) {
throw new Error(`No marker ${locationMarker} found.`);
}
expectEntries(locationMarker, ngService.getCompletionsAt(fileName, location), ...names);
const marker = mockHost.getLocationMarkerFor(fileName, locationMarker);
expectEntries(locationMarker, ngService.getCompletionsAt(fileName, marker.start), ...names);
}
});

View File

@ -20,7 +20,7 @@ describe('service without angular', () => {
let ngHost = new TypeScriptServiceHost(mockHost, service);
let ngService = createLanguageService(ngHost);
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',
() => expect(() => ngService.getTemplateReferences()));

View File

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

View File

@ -15,7 +15,7 @@ export interface Person {
@Component({
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>
</div>`,
})
@ -24,7 +24,7 @@ export class UnknownPeople {
@Component({
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>
</div>`,
})
@ -34,7 +34,7 @@ export class UnknownEven {
@Component({
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>
</div>`,
})

View File

@ -10,7 +10,7 @@ import {Component} from '@angular/core';
@Component({
template: `
<div ~{implicit}*ngIf="show; let l=unknown"~{implicit-end}>
<div ~{start-implicit}*ngIf="show; let l=unknown"~{end-implicit}>
Showing now!
</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.
*/
@ -279,62 +265,95 @@ 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.
* @param fileName name of the file
* @param selector name of the marker
*/
getDefinitionMarkerFor(fileName: string, selector: string): ts.TextSpan {
const markers = this.getReferenceMarkers(fileName);
expect(markers).toBeDefined();
expect(Object.keys(markers !.definitions)).toContain(selector);
expect(markers !.definitions[selector].length).toBe(1);
const marker = markers !.definitions[selector][0];
expect(marker.start).toBeLessThanOrEqual(marker.end);
const content = this.getRawFileContent(fileName);
if (!content) {
throw new Error(`File does not exist: ${fileName}`);
}
const markers = getReferenceMarkers(content);
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 {
start: marker.start,
length: marker.end - marker.start,
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.
* @param fileName name of the file
* @param selector name of the marker
*/
getReferenceMarkerFor(fileName: string, selector: string): ts.TextSpan {
const markers = this.getReferenceMarkers(fileName);
expect(markers).toBeDefined();
expect(Object.keys(markers !.references)).toContain(selector);
expect(markers !.references[selector].length).toBe(1);
const marker = markers !.references[selector][0];
expect(marker.start).toBeLessThanOrEqual(marker.end);
const content = this.getRawFileContent(fileName);
if (!content) {
throw new Error(`File does not exist: ${fileName}`);
}
const markers = getReferenceMarkers(content);
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 {
start: marker.start,
length: marker.end - marker.start,
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.
* @param fileName name of the file
* @param selector name of the marker
*/
getLocationMarkerFor(fileName: string, selector: string): ts.TextSpan {
const markers = this.getMarkerLocations(fileName);
expect(markers).toBeDefined();
const start = markers ![`start-${selector}`];
expect(start).toBeDefined();
const end = markers ![`end-${selector}`];
expect(end).toBeDefined();
expect(start).toBeLessThanOrEqual(end);
const content = this.getRawFileContent(fileName);
if (!content) {
throw new Error(`File does not exist: ${fileName}`);
}
const markers = getLocationMarkers(content);
// Look for just the selector itself
const position = markers[selector];
if (position !== undefined) {
return {
start: 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}`);
}
}
const locationMarker = /\~\{(\w+(-\w+)*)\}/g;

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');
});
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', () => {
expectError(
@ -180,7 +180,7 @@ describe('plugin', () => {
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\'');
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', () => {
const fileName = '/app/app.component.ts';
const marker = 'entity-amp';
const position = getMarkerLocation(fileName, marker);
const results = ngLS.getCompletionsAtPosition(fileName, position, {} /* options */);
const marker = mockHost.getLocationMarkerFor(fileName, 'entity-amp');
const results = ngLS.getCompletionsAtPosition(fileName, marker.start, {} /* options */);
expect(results).toBeTruthy();
expectEntries(marker, results !, ...['&amp;', '&gt;', '&lt;', '&iota;']);
expectEntries('entity-amp', results !, ...['&amp;', '&gt;', '&lt;', '&iota;']);
});
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[]) {
const location = getMarkerLocation(fileName, locationMarker);
const marker = mockHost.getLocationMarkerFor(fileName, locationMarker);
expectEntries(
locationMarker, plugin.getCompletionsAtPosition(fileName, location, undefined) !, ...names);
locationMarker, plugin.getCompletionsAtPosition(fileName, marker.start, undefined) !,
...names);
}
function expectSemanticError(fileName: string, locationMarker: string, message: string) {
const start = getMarkerLocation(fileName, locationMarker);
const end = getMarkerLocation(fileName, locationMarker + '-end');
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(start);
expect(error.length).toEqual(end - start);
expect(error.start).toEqual(marker.start);
expect(error.length).toEqual(marker.length);
return;
}
}