refactor(compiler-cli): don't use FakeEnvironment for tcb tests (#41043)
For the tests in //packages/compiler-cli/src/ngtsc/typecheck, this commits uses a `TypeCheckFile` for the environment, rather than a `FakeEnvironment`. Using a real environment gives us more flexibility with testing. PR Close #41043
This commit is contained in:
parent
02e8901d9e
commit
c267c680d8
|
@ -385,7 +385,8 @@ export class TypeCheckContextImpl implements TypeCheckContext {
|
||||||
path: pendingShimData.file.fileName,
|
path: pendingShimData.file.fileName,
|
||||||
templates: pendingShimData.templates,
|
templates: pendingShimData.templates,
|
||||||
});
|
});
|
||||||
updates.set(pendingShimData.file.fileName, pendingShimData.file.render());
|
updates.set(
|
||||||
|
pendingShimData.file.fileName, pendingShimData.file.render(false /* removeComments */));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,12 +49,12 @@ export class TypeCheckFile extends Environment {
|
||||||
this.tcbStatements.push(fn);
|
this.tcbStatements.push(fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
render(): string {
|
render(removeComments: boolean): string {
|
||||||
let source: string = this.importManager.getAllImports(this.contextFile.fileName)
|
let source: string = this.importManager.getAllImports(this.contextFile.fileName)
|
||||||
.map(i => `import * as ${i.qualifier.text} from '${i.specifier}';`)
|
.map(i => `import * as ${i.qualifier.text} from '${i.specifier}';`)
|
||||||
.join('\n') +
|
.join('\n') +
|
||||||
'\n\n';
|
'\n\n';
|
||||||
const printer = ts.createPrinter();
|
const printer = ts.createPrinter({removeComments});
|
||||||
source += '\n';
|
source += '\n';
|
||||||
for (const stmt of this.pipeInstStatements) {
|
for (const stmt of this.pipeInstStatements) {
|
||||||
source += printer.printNode(ts.EmitHint.Unspecified, stmt, this.contextFile) + '\n';
|
source += printer.printNode(ts.EmitHint.Unspecified, stmt, this.contextFile) + '\n';
|
||||||
|
|
|
@ -6,9 +6,12 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {initMockFileSystem} from '../../file_system/testing';
|
||||||
import {tcb, TestDeclaration} from './test_utils';
|
import {tcb, TestDeclaration} from './test_utils';
|
||||||
|
|
||||||
describe('type check blocks diagnostics', () => {
|
describe('type check blocks diagnostics', () => {
|
||||||
|
beforeEach(() => initMockFileSystem('Native'));
|
||||||
|
|
||||||
describe('parse spans', () => {
|
describe('parse spans', () => {
|
||||||
it('should annotate unary ops', () => {
|
it('should annotate unary ops', () => {
|
||||||
expect(tcbWithSpans('{{ -a }}')).toContain('(-((ctx).a /*4,5*/) /*4,5*/) /*3,5*/');
|
expect(tcbWithSpans('{{ -a }}')).toContain('(-((ctx).a /*4,5*/) /*4,5*/) /*3,5*/');
|
||||||
|
@ -146,8 +149,9 @@ describe('type check blocks diagnostics', () => {
|
||||||
pipeName: 'test',
|
pipeName: 'test',
|
||||||
}];
|
}];
|
||||||
const block = tcbWithSpans(TEMPLATE, PIPES);
|
const block = tcbWithSpans(TEMPLATE, PIPES);
|
||||||
|
expect(block).toContain('var _pipe1: i0.TestPipe = null!');
|
||||||
expect(block).toContain(
|
expect(block).toContain(
|
||||||
'((null as TestPipe).transform /*7,11*/(((ctx).a /*3,4*/) /*3,4*/, ((ctx).b /*12,13*/) /*12,13*/) /*3,13*/);');
|
'(_pipe1.transform /*7,11*/(((ctx).a /*3,4*/) /*3,4*/, ((ctx).b /*12,13*/) /*12,13*/) /*3,13*/);');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('attaching multiple comments for multiple references', () => {
|
describe('attaching multiple comments for multiple references', () => {
|
||||||
|
|
|
@ -11,7 +11,7 @@ import * as ts from 'typescript';
|
||||||
|
|
||||||
import {absoluteFrom, AbsoluteFsPath, getSourceFileOrError, LogicalFileSystem} from '../../file_system';
|
import {absoluteFrom, AbsoluteFsPath, getSourceFileOrError, LogicalFileSystem} from '../../file_system';
|
||||||
import {TestFile} from '../../file_system/testing';
|
import {TestFile} from '../../file_system/testing';
|
||||||
import {AbsoluteModuleStrategy, LocalIdentifierStrategy, LogicalProjectStrategy, ModuleResolver, Reexport, Reference, ReferenceEmitter} from '../../imports';
|
import {AbsoluteModuleStrategy, LocalIdentifierStrategy, LogicalProjectStrategy, ModuleResolver, Reexport, Reference, ReferenceEmitter, RelativePathStrategy} from '../../imports';
|
||||||
import {NOOP_INCREMENTAL_BUILD} from '../../incremental';
|
import {NOOP_INCREMENTAL_BUILD} from '../../incremental';
|
||||||
import {ClassPropertyMapping, CompoundMetadataReader} from '../../metadata';
|
import {ClassPropertyMapping, CompoundMetadataReader} from '../../metadata';
|
||||||
import {ClassDeclaration, isNamedClassDeclaration, TypeScriptReflectionHost} from '../../reflection';
|
import {ClassDeclaration, isNamedClassDeclaration, TypeScriptReflectionHost} from '../../reflection';
|
||||||
|
@ -28,6 +28,7 @@ import {Environment} from '../src/environment';
|
||||||
import {OutOfBandDiagnosticRecorder} from '../src/oob';
|
import {OutOfBandDiagnosticRecorder} from '../src/oob';
|
||||||
import {TypeCheckShimGenerator} from '../src/shim';
|
import {TypeCheckShimGenerator} from '../src/shim';
|
||||||
import {generateTypeCheckBlock} from '../src/type_check_block';
|
import {generateTypeCheckBlock} from '../src/type_check_block';
|
||||||
|
import {TypeCheckFile} from '../src/type_check_file';
|
||||||
|
|
||||||
export function typescriptLibDts(): TestFile {
|
export function typescriptLibDts(): TestFile {
|
||||||
return {
|
return {
|
||||||
|
@ -201,6 +202,7 @@ export type TestDirective = Partial<Pick<
|
||||||
coercedInputFields?: string[], restrictedInputFields?: string[],
|
coercedInputFields?: string[], restrictedInputFields?: string[],
|
||||||
stringLiteralInputFields?: string[], undeclaredInputFields?: string[], isGeneric?: boolean;
|
stringLiteralInputFields?: string[], undeclaredInputFields?: string[], isGeneric?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TestPipe = {
|
export type TestPipe = {
|
||||||
name: string,
|
name: string,
|
||||||
file?: AbsoluteFsPath, pipeName: string, type: 'pipe',
|
file?: AbsoluteFsPath, pipeName: string, type: 'pipe',
|
||||||
|
@ -212,9 +214,14 @@ export function tcb(
|
||||||
template: string, declarations: TestDeclaration[] = [], config?: TypeCheckingConfig,
|
template: string, declarations: TestDeclaration[] = [], config?: TypeCheckingConfig,
|
||||||
options?: {emitSpans?: boolean}): string {
|
options?: {emitSpans?: boolean}): string {
|
||||||
const classes = ['Test', ...declarations.map(decl => decl.name)];
|
const classes = ['Test', ...declarations.map(decl => decl.name)];
|
||||||
const code = classes.map(name => `class ${name}<T extends string> {}`).join('\n');
|
const code = classes.map(name => `export class ${name}<T extends string> {}`).join('\n');
|
||||||
|
|
||||||
const sf = ts.createSourceFile('synthetic.ts', code, ts.ScriptTarget.Latest, true);
|
const rootFilePath = absoluteFrom('/synthetic.ts');
|
||||||
|
const {program, host} = makeProgram([
|
||||||
|
{name: rootFilePath, contents: code, isRoot: true},
|
||||||
|
]);
|
||||||
|
|
||||||
|
const sf = getSourceFileOrError(program, rootFilePath);
|
||||||
const clazz = getClass(sf, 'Test');
|
const clazz = getClass(sf, 'Test');
|
||||||
const templateUrl = 'synthetic.html';
|
const templateUrl = 'synthetic.html';
|
||||||
const {nodes} = parseTemplate(template, templateUrl);
|
const {nodes} = parseTemplate(template, templateUrl);
|
||||||
|
@ -251,13 +258,25 @@ export function tcb(
|
||||||
emitSpans: false,
|
emitSpans: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const tcb = generateTypeCheckBlock(
|
const fileName = absoluteFrom('/type-check-file.ts');
|
||||||
FakeEnvironment.newFake(config), new Reference(clazz), ts.createIdentifier('Test_TCB'), meta,
|
|
||||||
new NoopSchemaChecker(), new NoopOobRecorder());
|
|
||||||
|
|
||||||
const removeComments = !options.emitSpans;
|
const reflectionHost = new TypeScriptReflectionHost(program.getTypeChecker());
|
||||||
const res = ts.createPrinter({removeComments}).printNode(ts.EmitHint.Unspecified, tcb, sf);
|
|
||||||
return res.replace(/\s+/g, ' ');
|
const refEmmiter: ReferenceEmitter = new ReferenceEmitter(
|
||||||
|
[new LocalIdentifierStrategy(), new RelativePathStrategy(reflectionHost)]);
|
||||||
|
|
||||||
|
const env = new TypeCheckFile(fileName, config, refEmmiter, reflectionHost, host);
|
||||||
|
|
||||||
|
const ref = new Reference(clazz);
|
||||||
|
|
||||||
|
const tcb = generateTypeCheckBlock(
|
||||||
|
env, ref, ts.createIdentifier('Test_TCB'), meta, new NoopSchemaChecker(),
|
||||||
|
new NoopOobRecorder());
|
||||||
|
|
||||||
|
env.addTypeCheckBlock(ref, meta, new NoopSchemaChecker(), new NoopOobRecorder());
|
||||||
|
|
||||||
|
const rendered = env.render(!options.emitSpans /* removeComments */);
|
||||||
|
return rendered.replace(/\s+/g, ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -6,12 +6,15 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import {initMockFileSystem} from '../../file_system/testing';
|
||||||
import {TypeCheckingConfig} from '../api';
|
import {TypeCheckingConfig} from '../api';
|
||||||
|
|
||||||
import {ALL_ENABLED_CONFIG, tcb, TestDeclaration, TestDirective} from './test_utils';
|
import {ALL_ENABLED_CONFIG, tcb, TestDeclaration, TestDirective} from './test_utils';
|
||||||
|
|
||||||
|
|
||||||
describe('type check blocks', () => {
|
describe('type check blocks', () => {
|
||||||
|
beforeEach(() => initMockFileSystem('Native'));
|
||||||
|
|
||||||
it('should generate a basic block for a binding', () => {
|
it('should generate a basic block for a binding', () => {
|
||||||
expect(tcb('{{hello}} {{world}}')).toContain('"" + (((ctx).hello)) + (((ctx).world));');
|
expect(tcb('{{hello}} {{world}}')).toContain('"" + (((ctx).hello)) + (((ctx).world));');
|
||||||
});
|
});
|
||||||
|
@ -60,7 +63,7 @@ describe('type check blocks', () => {
|
||||||
selector: '[dir]',
|
selector: '[dir]',
|
||||||
inputs: {inputA: 'inputA'},
|
inputs: {inputA: 'inputA'},
|
||||||
}];
|
}];
|
||||||
expect(tcb(TEMPLATE, DIRECTIVES)).toContain('_t1: DirA = null!; _t1.inputA = ("value");');
|
expect(tcb(TEMPLATE, DIRECTIVES)).toContain('_t1: i0.DirA = null!; _t1.inputA = ("value");');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle multiple bindings to the same property', () => {
|
it('should handle multiple bindings to the same property', () => {
|
||||||
|
@ -133,9 +136,11 @@ describe('type check blocks', () => {
|
||||||
},
|
},
|
||||||
isGeneric: true,
|
isGeneric: true,
|
||||||
}];
|
}];
|
||||||
expect(tcb(TEMPLATE, DIRECTIVES))
|
const actual = tcb(TEMPLATE, DIRECTIVES);
|
||||||
.toContain(
|
expect(actual).toContain(
|
||||||
'var _t1 = Dir.ngTypeCtor({ "fieldA": (((ctx).foo)), "fieldB": null as any });');
|
'const _ctor1: <T extends string = any>(init: Pick<i0.Dir<T>, "fieldA" | "fieldB">) => i0.Dir<T> = null!;');
|
||||||
|
expect(actual).toContain(
|
||||||
|
'var _t1 = _ctor1({ "fieldA": (((ctx).foo)), "fieldB": null as any });');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle multiple bindings to the same property', () => {
|
it('should handle multiple bindings to the same property', () => {
|
||||||
|
@ -183,11 +188,14 @@ describe('type check blocks', () => {
|
||||||
inputs: {input: 'input'},
|
inputs: {input: 'input'},
|
||||||
isGeneric: true,
|
isGeneric: true,
|
||||||
}];
|
}];
|
||||||
expect(tcb(TEMPLATE, DIRECTIVES))
|
|
||||||
.toContain(
|
const actual = tcb(TEMPLATE, DIRECTIVES);
|
||||||
'var _t2 = Dir.ngTypeCtor({ "input": (null!) }); ' +
|
expect(actual).toContain(
|
||||||
'var _t1 = _t2; ' +
|
'const _ctor1: <T extends string = any>(init: Pick<i0.Dir<T>, "input">) => i0.Dir<T> = null!;');
|
||||||
'_t2.input = (_t1);');
|
expect(actual).toContain(
|
||||||
|
'var _t2 = _ctor1({ "input": (null!) }); ' +
|
||||||
|
'var _t1 = _t2; ' +
|
||||||
|
'_t2.input = (_t1);');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should generate circular references between two directives correctly', () => {
|
it('should generate circular references between two directives correctly', () => {
|
||||||
|
@ -213,14 +221,16 @@ describe('type check blocks', () => {
|
||||||
isGeneric: true,
|
isGeneric: true,
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
expect(tcb(TEMPLATE, DIRECTIVES))
|
const actual = tcb(TEMPLATE, DIRECTIVES);
|
||||||
.toContain(
|
expect(actual).toContain(
|
||||||
'var _t4 = DirA.ngTypeCtor({ "inputA": (null!) }); ' +
|
'const _ctor1: <T extends string = any>(init: Pick<i0.DirA<T>, "inputA">) => i0.DirA<T> = null!; const _ctor2: <T extends string = any>(init: Pick<i0.DirB<T>, "inputB">) => i0.DirB<T> = null!;');
|
||||||
'var _t3 = _t4; ' +
|
expect(actual).toContain(
|
||||||
'var _t2 = DirB.ngTypeCtor({ "inputB": (_t3) }); ' +
|
'var _t4 = _ctor1({ "inputA": (null!) }); ' +
|
||||||
'var _t1 = _t2; ' +
|
'var _t3 = _t4; ' +
|
||||||
'_t4.inputA = (_t1); ' +
|
'var _t2 = _ctor2({ "inputB": (_t3) }); ' +
|
||||||
'_t2.inputB = (_t3);');
|
'var _t1 = _t2; ' +
|
||||||
|
'_t4.inputA = (_t1); ' +
|
||||||
|
'_t2.inputB = (_t3);');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle empty bindings', () => {
|
it('should handle empty bindings', () => {
|
||||||
|
@ -261,7 +271,7 @@ describe('type check blocks', () => {
|
||||||
}];
|
}];
|
||||||
expect(tcb(TEMPLATE, DIRECTIVES))
|
expect(tcb(TEMPLATE, DIRECTIVES))
|
||||||
.toContain(
|
.toContain(
|
||||||
'var _t1: typeof Dir.ngAcceptInputType_fieldA = null!; ' +
|
'var _t1: typeof i0.Dir.ngAcceptInputType_fieldA = null!; ' +
|
||||||
'_t1 = (((ctx).foo));');
|
'_t1 = (((ctx).foo));');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -321,11 +331,11 @@ describe('type check blocks', () => {
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const block = tcb(TEMPLATE, DIRECTIVES);
|
const block = tcb(TEMPLATE, DIRECTIVES);
|
||||||
expect(block).toContain('var _t1: HasInput = null!');
|
expect(block).toContain('var _t1: i0.HasInput = null!');
|
||||||
expect(block).toContain('_t1.input = (((ctx).value));');
|
expect(block).toContain('_t1.input = (((ctx).value));');
|
||||||
expect(block).toContain('var _t2: HasOutput = null!');
|
expect(block).toContain('var _t2: i0.HasOutput = null!');
|
||||||
expect(block).toContain('_t2["output"]');
|
expect(block).toContain('_t2["output"]');
|
||||||
expect(block).toContain('var _t4: HasReference = null!');
|
expect(block).toContain('var _t4: i0.HasReference = null!');
|
||||||
expect(block).toContain('var _t3 = _t4;');
|
expect(block).toContain('var _t3 = _t4;');
|
||||||
expect(block).toContain('(_t3).a');
|
expect(block).toContain('(_t3).a');
|
||||||
expect(block).not.toContain('NoBindings');
|
expect(block).not.toContain('NoBindings');
|
||||||
|
@ -355,7 +365,7 @@ describe('type check blocks', () => {
|
||||||
}];
|
}];
|
||||||
expect(tcb(TEMPLATE, DIRECTIVES))
|
expect(tcb(TEMPLATE, DIRECTIVES))
|
||||||
.toContain(
|
.toContain(
|
||||||
'var _t2: Dir = null!; ' +
|
'var _t2: i0.Dir = null!; ' +
|
||||||
'var _t1 = _t2; ' +
|
'var _t1 = _t2; ' +
|
||||||
'"" + (((_t1).value));');
|
'"" + (((_t1).value));');
|
||||||
});
|
});
|
||||||
|
@ -403,7 +413,7 @@ describe('type check blocks', () => {
|
||||||
}];
|
}];
|
||||||
expect(tcb(TEMPLATE, DIRECTIVES))
|
expect(tcb(TEMPLATE, DIRECTIVES))
|
||||||
.toContain(
|
.toContain(
|
||||||
'var _t2: Dir = null!; ' +
|
'var _t2: i0.Dir = null!; ' +
|
||||||
'var _t1 = _t2; ' +
|
'var _t1 = _t2; ' +
|
||||||
'_t2.input = (_t1);');
|
'_t2.input = (_t1);');
|
||||||
});
|
});
|
||||||
|
@ -431,9 +441,9 @@ describe('type check blocks', () => {
|
||||||
];
|
];
|
||||||
expect(tcb(TEMPLATE, DIRECTIVES))
|
expect(tcb(TEMPLATE, DIRECTIVES))
|
||||||
.toContain(
|
.toContain(
|
||||||
'var _t2: DirB = null!; ' +
|
'var _t2: i0.DirB = null!; ' +
|
||||||
'var _t1 = _t2; ' +
|
'var _t1 = _t2; ' +
|
||||||
'var _t3: DirA = null!; ' +
|
'var _t3: i0.DirA = null!; ' +
|
||||||
'_t3.inputA = (_t1); ' +
|
'_t3.inputA = (_t1); ' +
|
||||||
'var _t4 = _t3; ' +
|
'var _t4 = _t3; ' +
|
||||||
'_t2.inputA = (_t4);');
|
'_t2.inputA = (_t4);');
|
||||||
|
@ -468,7 +478,7 @@ describe('type check blocks', () => {
|
||||||
}];
|
}];
|
||||||
expect(tcb(TEMPLATE, DIRECTIVES))
|
expect(tcb(TEMPLATE, DIRECTIVES))
|
||||||
.toContain(
|
.toContain(
|
||||||
'var _t1: Dir = null!; ' +
|
'var _t1: i0.Dir = null!; ' +
|
||||||
'var _t2: typeof _t1["fieldA"] = null!; ' +
|
'var _t2: typeof _t1["fieldA"] = null!; ' +
|
||||||
'_t2 = (((ctx).foo)); ');
|
'_t2 = (((ctx).foo)); ');
|
||||||
});
|
});
|
||||||
|
@ -487,7 +497,7 @@ describe('type check blocks', () => {
|
||||||
}];
|
}];
|
||||||
const block = tcb(TEMPLATE, DIRECTIVES);
|
const block = tcb(TEMPLATE, DIRECTIVES);
|
||||||
expect(block).toContain(
|
expect(block).toContain(
|
||||||
'var _t1: Dir = null!; ' +
|
'var _t1: i0.Dir = null!; ' +
|
||||||
'_t1["some-input.xs"] = (((ctx).foo)); ');
|
'_t1["some-input.xs"] = (((ctx).foo)); ');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -504,7 +514,7 @@ describe('type check blocks', () => {
|
||||||
}];
|
}];
|
||||||
expect(tcb(TEMPLATE, DIRECTIVES))
|
expect(tcb(TEMPLATE, DIRECTIVES))
|
||||||
.toContain(
|
.toContain(
|
||||||
'var _t1: Dir = null!; ' +
|
'var _t1: i0.Dir = null!; ' +
|
||||||
'_t1.field2 = _t1.field1 = (((ctx).foo));');
|
'_t1.field2 = _t1.field1 = (((ctx).foo));');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -523,8 +533,8 @@ describe('type check blocks', () => {
|
||||||
}];
|
}];
|
||||||
expect(tcb(TEMPLATE, DIRECTIVES))
|
expect(tcb(TEMPLATE, DIRECTIVES))
|
||||||
.toContain(
|
.toContain(
|
||||||
'var _t1: typeof Dir.ngAcceptInputType_field1 = null!; ' +
|
'var _t1: typeof i0.Dir.ngAcceptInputType_field1 = null!; ' +
|
||||||
'var _t2: Dir = null!; ' +
|
'var _t2: i0.Dir = null!; ' +
|
||||||
'_t2.field2 = _t1 = (((ctx).foo));');
|
'_t2.field2 = _t1 = (((ctx).foo));');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -543,7 +553,7 @@ describe('type check blocks', () => {
|
||||||
}];
|
}];
|
||||||
expect(tcb(TEMPLATE, DIRECTIVES))
|
expect(tcb(TEMPLATE, DIRECTIVES))
|
||||||
.toContain(
|
.toContain(
|
||||||
'var _t1: Dir = null!; ' +
|
'var _t1: i0.Dir = null!; ' +
|
||||||
'_t1.field2 = (((ctx).foo));');
|
'_t1.field2 = (((ctx).foo));');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -561,7 +571,7 @@ describe('type check blocks', () => {
|
||||||
const block = tcb(TEMPLATE, DIRECTIVES);
|
const block = tcb(TEMPLATE, DIRECTIVES);
|
||||||
expect(block).not.toContain('var _t1: Dir = null!;');
|
expect(block).not.toContain('var _t1: Dir = null!;');
|
||||||
expect(block).toContain(
|
expect(block).toContain(
|
||||||
'var _t1: typeof Dir.ngAcceptInputType_fieldA = null!; ' +
|
'var _t1: typeof i0.Dir.ngAcceptInputType_fieldA = null!; ' +
|
||||||
'_t1 = (((ctx).foo));');
|
'_t1 = (((ctx).foo));');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -580,7 +590,7 @@ describe('type check blocks', () => {
|
||||||
const block = tcb(TEMPLATE, DIRECTIVES);
|
const block = tcb(TEMPLATE, DIRECTIVES);
|
||||||
expect(block).not.toContain('var _t1: Dir = null!;');
|
expect(block).not.toContain('var _t1: Dir = null!;');
|
||||||
expect(block).toContain(
|
expect(block).toContain(
|
||||||
'var _t1: typeof Dir.ngAcceptInputType_fieldA = null!; ' +
|
'var _t1: typeof i0.Dir.ngAcceptInputType_fieldA = null!; ' +
|
||||||
'_t1 = (((ctx).foo));');
|
'_t1 = (((ctx).foo));');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -619,7 +629,7 @@ describe('type check blocks', () => {
|
||||||
}];
|
}];
|
||||||
const TEMPLATE = `<div *ngIf="person">{{person.name}}</div>`;
|
const TEMPLATE = `<div *ngIf="person">{{person.name}}</div>`;
|
||||||
const block = tcb(TEMPLATE, DIRECTIVES);
|
const block = tcb(TEMPLATE, DIRECTIVES);
|
||||||
expect(block).toContain('if (NgIf.ngTemplateGuard_ngIf(_t1, ((ctx).person)))');
|
expect(block).toContain('if (i0.NgIf.ngTemplateGuard_ngIf(_t1, ((ctx).person)))');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should emit binding guards', () => {
|
it('should emit binding guards', () => {
|
||||||
|
@ -672,8 +682,7 @@ describe('type check blocks', () => {
|
||||||
it('should emit a listener function with AnimationEvent for animation events', () => {
|
it('should emit a listener function with AnimationEvent for animation events', () => {
|
||||||
const TEMPLATE = `<div (@animation.done)="foo($event)"></div>`;
|
const TEMPLATE = `<div (@animation.done)="foo($event)"></div>`;
|
||||||
const block = tcb(TEMPLATE);
|
const block = tcb(TEMPLATE);
|
||||||
expect(block).toContain(
|
expect(block).toContain('function ($event: i1.AnimationEvent): any { (ctx).foo($event); }');
|
||||||
'function ($event: animations.AnimationEvent): any { (ctx).foo($event); }');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should emit addEventListener calls for unclaimed outputs', () => {
|
it('should emit addEventListener calls for unclaimed outputs', () => {
|
||||||
|
@ -740,7 +749,7 @@ describe('type check blocks', () => {
|
||||||
|
|
||||||
describe('config.applyTemplateContextGuards', () => {
|
describe('config.applyTemplateContextGuards', () => {
|
||||||
const TEMPLATE = `<div *dir>{{ value }}</div>`;
|
const TEMPLATE = `<div *dir>{{ value }}</div>`;
|
||||||
const GUARD_APPLIED = 'if (Dir.ngTemplateContextGuard(';
|
const GUARD_APPLIED = 'if (i0.Dir.ngTemplateContextGuard(';
|
||||||
|
|
||||||
it('should apply template context guards when enabled', () => {
|
it('should apply template context guards when enabled', () => {
|
||||||
const block = tcb(TEMPLATE, DIRECTIVES);
|
const block = tcb(TEMPLATE, DIRECTIVES);
|
||||||
|
@ -769,13 +778,13 @@ describe('type check blocks', () => {
|
||||||
|
|
||||||
it('generates a references var when enabled', () => {
|
it('generates a references var when enabled', () => {
|
||||||
const block = tcb(TEMPLATE, DIRECTIVES);
|
const block = tcb(TEMPLATE, DIRECTIVES);
|
||||||
expect(block).toContain('var _t1 = (_t2 as any as core.TemplateRef<any>);');
|
expect(block).toContain('var _t1 = (_t2 as any as i1.TemplateRef<any>);');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('generates a reference var when disabled', () => {
|
it('generates a reference var when disabled', () => {
|
||||||
const DISABLED_CONFIG: TypeCheckingConfig = {...BASE_CONFIG, checkTemplateBodies: false};
|
const DISABLED_CONFIG: TypeCheckingConfig = {...BASE_CONFIG, checkTemplateBodies: false};
|
||||||
const block = tcb(TEMPLATE, DIRECTIVES, DISABLED_CONFIG);
|
const block = tcb(TEMPLATE, DIRECTIVES, DISABLED_CONFIG);
|
||||||
expect(block).toContain('var _t1 = (_t2 as any as core.TemplateRef<any>);');
|
expect(block).toContain('var _t1 = (_t2 as any as i1.TemplateRef<any>);');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -848,8 +857,7 @@ describe('type check blocks', () => {
|
||||||
|
|
||||||
it('should check types of animation events when enabled', () => {
|
it('should check types of animation events when enabled', () => {
|
||||||
const block = tcb(TEMPLATE, DIRECTIVES);
|
const block = tcb(TEMPLATE, DIRECTIVES);
|
||||||
expect(block).toContain(
|
expect(block).toContain('function ($event: i1.AnimationEvent): any { (ctx).foo($event); }');
|
||||||
'function ($event: animations.AnimationEvent): any { (ctx).foo($event); }');
|
|
||||||
});
|
});
|
||||||
it('should not check types of animation events when disabled', () => {
|
it('should not check types of animation events when disabled', () => {
|
||||||
const DISABLED_CONFIG:
|
const DISABLED_CONFIG:
|
||||||
|
@ -919,7 +927,7 @@ describe('type check blocks', () => {
|
||||||
it('should trace references to an <ng-template> when enabled', () => {
|
it('should trace references to an <ng-template> when enabled', () => {
|
||||||
const block = tcb(TEMPLATE, DIRECTIVES);
|
const block = tcb(TEMPLATE, DIRECTIVES);
|
||||||
expect(block).toContain(
|
expect(block).toContain(
|
||||||
'var _t3 = (_t4 as any as core.TemplateRef<any>); ' +
|
'var _t3 = (_t4 as any as i1.TemplateRef<any>); ' +
|
||||||
'"" + (((_t3).value2));');
|
'"" + (((_t3).value2));');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -968,13 +976,14 @@ describe('type check blocks', () => {
|
||||||
|
|
||||||
it('should check types of pipes when enabled', () => {
|
it('should check types of pipes when enabled', () => {
|
||||||
const block = tcb(TEMPLATE, PIPES);
|
const block = tcb(TEMPLATE, PIPES);
|
||||||
expect(block).toContain('(null as TestPipe).transform(((ctx).a), ((ctx).b), ((ctx).c))');
|
expect(block).toContain('var _pipe1: i0.TestPipe = null!;');
|
||||||
|
expect(block).toContain('(_pipe1.transform(((ctx).a), ((ctx).b), ((ctx).c)));');
|
||||||
});
|
});
|
||||||
it('should not check types of pipes when disabled', () => {
|
it('should not check types of pipes when disabled', () => {
|
||||||
const DISABLED_CONFIG: TypeCheckingConfig = {...BASE_CONFIG, checkTypeOfPipes: false};
|
const DISABLED_CONFIG: TypeCheckingConfig = {...BASE_CONFIG, checkTypeOfPipes: false};
|
||||||
const block = tcb(TEMPLATE, PIPES, DISABLED_CONFIG);
|
const block = tcb(TEMPLATE, PIPES, DISABLED_CONFIG);
|
||||||
expect(block).toContain(
|
expect(block).toContain('var _pipe1: i0.TestPipe = null!;');
|
||||||
'((null as TestPipe) as any).transform(((ctx).a), ((ctx).b), ((ctx).c))');
|
expect(block).toContain('((_pipe1 as any).transform(((ctx).a), ((ctx).b), ((ctx).c)));');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1016,13 +1025,13 @@ describe('type check blocks', () => {
|
||||||
|
|
||||||
it('should use the generic type of the context when enabled', () => {
|
it('should use the generic type of the context when enabled', () => {
|
||||||
const block = tcb(TEMPLATE);
|
const block = tcb(TEMPLATE);
|
||||||
expect(block).toContain('function Test_TCB<T extends string>(ctx: Test<T>)');
|
expect(block).toContain('function _tcb1<T extends string>(ctx: i0.Test<T>)');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should use any for the context generic type when disabled', () => {
|
it('should use any for the context generic type when disabled', () => {
|
||||||
const DISABLED_CONFIG: TypeCheckingConfig = {...BASE_CONFIG, useContextGenericType: false};
|
const DISABLED_CONFIG: TypeCheckingConfig = {...BASE_CONFIG, useContextGenericType: false};
|
||||||
const block = tcb(TEMPLATE, undefined, DISABLED_CONFIG);
|
const block = tcb(TEMPLATE, undefined, DISABLED_CONFIG);
|
||||||
expect(block).toContain('function Test_TCB(ctx: Test<any>)');
|
expect(block).toContain('function _tcb1(ctx: i0.Test<any>)');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1045,7 +1054,7 @@ describe('type check blocks', () => {
|
||||||
TypeCheckingConfig = {...BASE_CONFIG, honorAccessModifiersForInputBindings: true};
|
TypeCheckingConfig = {...BASE_CONFIG, honorAccessModifiersForInputBindings: true};
|
||||||
const block = tcb(TEMPLATE, DIRECTIVES, enableChecks);
|
const block = tcb(TEMPLATE, DIRECTIVES, enableChecks);
|
||||||
expect(block).toContain(
|
expect(block).toContain(
|
||||||
'var _t1: Dir = null!; ' +
|
'var _t1: i0.Dir = null!; ' +
|
||||||
'_t1["some-input.xs"] = (((ctx).foo)); ');
|
'_t1["some-input.xs"] = (((ctx).foo)); ');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1063,7 +1072,7 @@ describe('type check blocks', () => {
|
||||||
TypeCheckingConfig = {...BASE_CONFIG, honorAccessModifiersForInputBindings: true};
|
TypeCheckingConfig = {...BASE_CONFIG, honorAccessModifiersForInputBindings: true};
|
||||||
const block = tcb(TEMPLATE, DIRECTIVES, enableChecks);
|
const block = tcb(TEMPLATE, DIRECTIVES, enableChecks);
|
||||||
expect(block).toContain(
|
expect(block).toContain(
|
||||||
'var _t1: Dir = null!; ' +
|
'var _t1: i0.Dir = null!; ' +
|
||||||
'_t1.fieldA = (((ctx).foo)); ');
|
'_t1.fieldA = (((ctx).foo)); ');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -43,7 +43,7 @@ runInEachFileSystem(() => {
|
||||||
const file = new TypeCheckFile(
|
const file = new TypeCheckFile(
|
||||||
_('/_typecheck_.ts'), ALL_ENABLED_CONFIG, new ReferenceEmitter([]),
|
_('/_typecheck_.ts'), ALL_ENABLED_CONFIG, new ReferenceEmitter([]),
|
||||||
/* reflector */ null!, host);
|
/* reflector */ null!, host);
|
||||||
const sf = file.render();
|
const sf = file.render(false /* removeComments */);
|
||||||
expect(sf).toContain('export const IS_A_MODULE = true;');
|
expect(sf).toContain('export const IS_A_MODULE = true;');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue