test(language-service): Add method to override inline template (#36890)
This commit adds a method `overrideInlineTemplate` to the `MockTypescriptHost`. This allows us to override an inline template in a Component without changing the TypeScript parts. This methods works in a similar way as `MockTypescriptHost.override()`, which is used for overriding external template. PR Close #36890
This commit is contained in:
parent
e037840b88
commit
b3713a112f
|
@ -136,34 +136,43 @@ describe('completions', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to return attribute names with an incomplete attribute', () => {
|
it('should be able to return attribute names with an incomplete attribute', () => {
|
||||||
const marker = mockHost.getLocationMarkerFor(PARSING_CASES, 'no-value-attribute');
|
mockHost.overrideInlineTemplate(APP_COMPONENT, '<h1 h~{no-value-attribute}></h1>');
|
||||||
const completions = ngLS.getCompletionsAtPosition(PARSING_CASES, marker.start);
|
const marker = mockHost.getLocationMarkerFor(APP_COMPONENT, 'no-value-attribute');
|
||||||
|
const completions = ngLS.getCompletionsAtPosition(APP_COMPONENT, marker.start);
|
||||||
expectContain(completions, CompletionKind.HTML_ATTRIBUTE, ['id', 'class', 'dir', 'lang']);
|
expectContain(completions, CompletionKind.HTML_ATTRIBUTE, ['id', 'class', 'dir', 'lang']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to return attributes of an incomplete element', () => {
|
it('should be able to return attributes of an incomplete element', () => {
|
||||||
const m1 = mockHost.getLocationMarkerFor(PARSING_CASES, 'incomplete-open-lt');
|
mockHost.overrideInlineTemplate(APP_COMPONENT, `
|
||||||
const c1 = ngLS.getCompletionsAtPosition(PARSING_CASES, m1.start);
|
<h1>
|
||||||
|
Some <~{incomplete-open-lt}a~{incomplete-open-a} ~{incomplete-open-attr} text
|
||||||
|
</h1>`);
|
||||||
|
|
||||||
|
const m1 = mockHost.getLocationMarkerFor(APP_COMPONENT, 'incomplete-open-lt');
|
||||||
|
const c1 = ngLS.getCompletionsAtPosition(APP_COMPONENT, m1.start);
|
||||||
expectContain(c1, CompletionKind.HTML_ELEMENT, ['a', 'div', 'p', 'span']);
|
expectContain(c1, CompletionKind.HTML_ELEMENT, ['a', 'div', 'p', 'span']);
|
||||||
|
|
||||||
const m2 = mockHost.getLocationMarkerFor(PARSING_CASES, 'incomplete-open-a');
|
const m2 = mockHost.getLocationMarkerFor(APP_COMPONENT, 'incomplete-open-a');
|
||||||
const c2 = ngLS.getCompletionsAtPosition(PARSING_CASES, m2.start);
|
const c2 = ngLS.getCompletionsAtPosition(APP_COMPONENT, m2.start);
|
||||||
expectContain(c2, CompletionKind.HTML_ELEMENT, ['a', 'div', 'p', 'span']);
|
expectContain(c2, CompletionKind.HTML_ELEMENT, ['a', 'div', 'p', 'span']);
|
||||||
|
|
||||||
const m3 = mockHost.getLocationMarkerFor(PARSING_CASES, 'incomplete-open-attr');
|
const m3 = mockHost.getLocationMarkerFor(APP_COMPONENT, 'incomplete-open-attr');
|
||||||
const c3 = ngLS.getCompletionsAtPosition(PARSING_CASES, m3.start);
|
const c3 = ngLS.getCompletionsAtPosition(APP_COMPONENT, m3.start);
|
||||||
expectContain(c3, CompletionKind.HTML_ATTRIBUTE, ['id', 'class', 'href', 'name']);
|
expectContain(c3, CompletionKind.HTML_ATTRIBUTE, ['id', 'class', 'href', 'name']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to return completions with a missing closing tag', () => {
|
it('should be able to return completions with a missing closing tag', () => {
|
||||||
const marker = mockHost.getLocationMarkerFor(PARSING_CASES, 'missing-closing');
|
mockHost.overrideInlineTemplate(APP_COMPONENT, '<h1>Some <a> ~{missing-closing} text</h1>');
|
||||||
const completions = ngLS.getCompletionsAtPosition(PARSING_CASES, marker.start);
|
const marker = mockHost.getLocationMarkerFor(APP_COMPONENT, 'missing-closing');
|
||||||
|
const completions = ngLS.getCompletionsAtPosition(APP_COMPONENT, marker.start);
|
||||||
expectContain(completions, CompletionKind.HTML_ELEMENT, ['a', 'div', 'p', 'span', 'h1', 'h2']);
|
expectContain(completions, CompletionKind.HTML_ELEMENT, ['a', 'div', 'p', 'span', 'h1', 'h2']);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to return common attributes of an unknown tag', () => {
|
it('should be able to return common attributes of an unknown tag', () => {
|
||||||
const marker = mockHost.getLocationMarkerFor(PARSING_CASES, 'unknown-element');
|
mockHost.overrideInlineTemplate(
|
||||||
const completions = ngLS.getCompletionsAtPosition(PARSING_CASES, marker.start);
|
APP_COMPONENT, '<h1>Some <unknown ~{unknown-element}> text</h1>');
|
||||||
|
const marker = mockHost.getLocationMarkerFor(APP_COMPONENT, 'unknown-element');
|
||||||
|
const completions = ngLS.getCompletionsAtPosition(APP_COMPONENT, marker.start);
|
||||||
expectContain(completions, CompletionKind.HTML_ATTRIBUTE, ['id', 'dir', 'lang']);
|
expectContain(completions, CompletionKind.HTML_ATTRIBUTE, ['id', 'dir', 'lang']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -16,12 +16,8 @@ import * as ParsingCases from './parsing-cases';
|
||||||
imports: [CommonModule, FormsModule],
|
imports: [CommonModule, FormsModule],
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
ParsingCases.CaseIncompleteOpen,
|
|
||||||
ParsingCases.CaseMissingClosing,
|
|
||||||
ParsingCases.CaseUnknown,
|
|
||||||
ParsingCases.CounterDirective,
|
ParsingCases.CounterDirective,
|
||||||
ParsingCases.HintModel,
|
ParsingCases.HintModel,
|
||||||
ParsingCases.NoValueAttribute,
|
|
||||||
ParsingCases.NumberModel,
|
ParsingCases.NumberModel,
|
||||||
ParsingCases.StringModel,
|
ParsingCases.StringModel,
|
||||||
ParsingCases.TemplateReference,
|
ParsingCases.TemplateReference,
|
||||||
|
|
|
@ -10,33 +10,6 @@ import {Component, Directive, EventEmitter, Input, OnChanges, Output, SimpleChan
|
||||||
|
|
||||||
import {Hero} from './app.component';
|
import {Hero} from './app.component';
|
||||||
|
|
||||||
@Component({
|
|
||||||
template: `
|
|
||||||
<h1>
|
|
||||||
Some <~{incomplete-open-lt}a~{incomplete-open-a} ~{incomplete-open-attr} text
|
|
||||||
</h1>`,
|
|
||||||
})
|
|
||||||
export class CaseIncompleteOpen {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
template: '<h1>Some <a> ~{missing-closing} text</h1>',
|
|
||||||
})
|
|
||||||
export class CaseMissingClosing {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
template: '<h1>Some <unknown ~{unknown-element}> text</h1>',
|
|
||||||
})
|
|
||||||
export class CaseUnknown {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
template: '<h1 h~{no-value-attribute}></h1>',
|
|
||||||
})
|
|
||||||
export class NoValueAttribute {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Directive({
|
@Directive({
|
||||||
selector: '[string-model]',
|
selector: '[string-model]',
|
||||||
})
|
})
|
||||||
|
|
|
@ -124,6 +124,19 @@ export class MockTypescriptHost implements ts.LanguageServiceHost {
|
||||||
return content;
|
return content;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override the inline template in `fileName`.
|
||||||
|
* @param fileName path to component that has inline template
|
||||||
|
* @param content new template
|
||||||
|
*
|
||||||
|
* @return the new content of the file
|
||||||
|
*/
|
||||||
|
overrideInlineTemplate(fileName: string, content: string): string {
|
||||||
|
const originalContent = this.getRawFileContent(fileName)!;
|
||||||
|
const newContent = originalContent.replace(/template: `([\s\S]+)`/, `template: \`${content}\``);
|
||||||
|
return this.override(fileName, newContent);
|
||||||
|
}
|
||||||
|
|
||||||
addScript(fileName: string, content: string) {
|
addScript(fileName: string, content: string) {
|
||||||
if (this.scriptVersion.has(fileName)) {
|
if (this.scriptVersion.has(fileName)) {
|
||||||
throw new Error(`${fileName} is already in the root files.`);
|
throw new Error(`${fileName} is already in the root files.`);
|
||||||
|
|
|
@ -94,7 +94,7 @@ describe('TypeScriptServiceHost', () => {
|
||||||
const tsLS = ts.createLanguageService(tsLSHost);
|
const tsLS = ts.createLanguageService(tsLSHost);
|
||||||
const ngLSHost = new TypeScriptServiceHost(tsLSHost, tsLS);
|
const ngLSHost = new TypeScriptServiceHost(tsLSHost, tsLS);
|
||||||
const templates = ngLSHost.getTemplates('/app/parsing-cases.ts');
|
const templates = ngLSHost.getTemplates('/app/parsing-cases.ts');
|
||||||
expect(templates.length).toBe(5);
|
expect(templates.length).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should be able to find external template', () => {
|
it('should be able to find external template', () => {
|
||||||
|
|
Loading…
Reference in New Issue