refactor(ivy): run the compiler compliance tests against ngtsc (#24862)

This commit moves the compiler compliance tests into compiler-cli,
and uses ngtsc to run them instead of the custom compilation
pipeline used before. Testing against ngtsc allows for validation
of the real compiler output.

This commit also fixes a few small issues that prevented the tests
from passing.

PR Close #24862
This commit is contained in:
Alex Rickabaugh 2018-07-12 15:10:55 -07:00 committed by Victor Berchet
parent b7bbc82e3e
commit 9fd70c9715
17 changed files with 529 additions and 652 deletions

View File

@ -73,6 +73,7 @@ module.exports = function(config) {
'dist/all/@angular/benchpress/**', 'dist/all/@angular/benchpress/**',
'dist/all/@angular/compiler-cli/**', 'dist/all/@angular/compiler-cli/**',
'dist/all/@angular/compiler-cli/src/ngtsc/**', 'dist/all/@angular/compiler-cli/src/ngtsc/**',
'dist/all/@angular/compiler-cli/test/compliance/**',
'dist/all/@angular/compiler-cli/test/ngtsc/**', 'dist/all/@angular/compiler-cli/test/ngtsc/**',
'dist/all/@angular/compiler/test/aot/**', 'dist/all/@angular/compiler/test/aot/**',
'dist/all/@angular/compiler/test/render3/**', 'dist/all/@angular/compiler/test/render3/**',

View File

@ -0,0 +1,35 @@
load("//tools:defaults.bzl", "ts_library")
load("@build_bazel_rules_nodejs//:defs.bzl", "jasmine_node_test")
ts_library(
name = "test_lib",
testonly = 1,
srcs = glob(
["**/*.ts"],
),
deps = [
"//packages:types",
"//packages/compiler",
"//packages/compiler-cli",
"//packages/compiler/test:test_utils",
"//packages/compiler/testing",
"//packages/core",
],
)
jasmine_node_test(
name = "compliance",
bootstrap = ["angular/tools/testing/init_node_spec.js"],
data = [
"//packages/common:npm_package",
"//packages/core:npm_package",
],
tags = [
"ivy-local",
"ivy-only",
],
deps = [
":test_lib",
"//tools/testing:node",
],
)

View File

@ -0,0 +1 @@
Tests in this directory are excluded from running in the browser and only run in node.

View File

@ -0,0 +1,178 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {AotCompilerOptions} from '@angular/compiler';
import {escapeRegExp} from '@angular/compiler/src/util';
import {MockCompilerHost, MockData, MockDirectory, arrayToMockDir, settings, toMockFileArray} from '@angular/compiler/test/aot/test_util';
import * as ts from 'typescript';
import {NgtscProgram} from '../../src/ngtsc/program';
const IDENTIFIER = /[A-Za-z_$ɵ][A-Za-z0-9_$]*/;
const OPERATOR =
/!|%|\*|\/|\^|&&?|\|\|?|\(|\)|\{|\}|\[|\]|:|;|<=?|>=?|={1,3}|!==?|=>|\+\+?|--?|@|,|\.|\.\.\./;
const STRING = /'[^']*'|"[^"]*"|`[\s\S]*?`/;
const NUMBER = /\d+/;
const ELLIPSIS = '…';
const TOKEN = new RegExp(
`\\s*((${IDENTIFIER.source})|(${OPERATOR.source})|(${STRING.source})|${NUMBER.source}|${ELLIPSIS})`,
'y');
type Piece = string | RegExp;
const SKIP = /(?:.|\n|\r)*/;
const ERROR_CONTEXT_WIDTH = 30;
// Transform the expected output to set of tokens
function tokenize(text: string): Piece[] {
TOKEN.lastIndex = 0;
let match: RegExpMatchArray|null;
const pieces: Piece[] = [];
while ((match = TOKEN.exec(text)) !== null) {
const token = match[1];
if (token === 'IDENT') {
pieces.push(IDENTIFIER);
} else if (token === ELLIPSIS) {
pieces.push(SKIP);
} else {
pieces.push(token);
}
}
if (pieces.length === 0 || TOKEN.lastIndex !== 0) {
const from = TOKEN.lastIndex;
const to = from + ERROR_CONTEXT_WIDTH;
throw Error(`Invalid test, no token found for '${text.substr(from, to)}...'`);
}
return pieces;
}
export function expectEmit(
source: string, expected: string, description: string,
assertIdentifiers?: {[name: string]: RegExp}) {
// turns `// ...` into `…`
// remove `// TODO` comment lines
expected = expected.replace(/\/\/\s*\.\.\./g, ELLIPSIS).replace(/\/\/\s*TODO.*?\n/g, '');
const pieces = tokenize(expected);
const {regexp, groups} = buildMatcher(pieces);
const matches = source.match(regexp);
if (matches === null) {
let last: number = 0;
for (let i = 1; i < pieces.length; i++) {
const {regexp} = buildMatcher(pieces.slice(0, i));
const m = source.match(regexp);
const expectedPiece = pieces[i - 1] == IDENTIFIER ? '<IDENT>' : pieces[i - 1];
if (!m) {
fail(
`${description}: Expected to find ${expectedPiece} '${source.substr(0,last)}[<---HERE expected "${expectedPiece}"]${source.substr(last)}'`);
return;
} else {
last = (m.index || 0) + m[0].length;
}
}
fail(
`Test helper failure: Expected expression failed but the reporting logic could not find where it failed in: ${source}`);
} else {
if (assertIdentifiers) {
// It might be possible to add the constraints in the original regexp (see `buildMatcher`)
// by transforming the assertion regexps when using anchoring, grouping, back references,
// flags, ...
//
// Checking identifiers after they have matched allows for a simple and flexible
// implementation.
// The overall performance are not impacted when `assertIdentifiers` is empty.
const ids = Object.keys(assertIdentifiers);
for (let i = 0; i < ids.length; i++) {
const id = ids[i];
if (groups.has(id)) {
const name = matches[groups.get(id) as number];
const regexp = assertIdentifiers[id];
if (!regexp.test(name)) {
throw Error(
`${description}: The matching identifier "${id}" is "${name}" which doesn't match ${regexp}`);
}
}
}
}
}
}
const IDENT_LIKE = /^[a-z][A-Z]/;
const MATCHING_IDENT = /^\$.*\$$/;
/*
* Builds a regexp that matches the given `pieces`
*
* It returns:
* - the `regexp` to be used to match the generated code,
* - the `groups` which maps `$...$` identifier to their position in the regexp matches.
*/
function buildMatcher(pieces: (string | RegExp)[]): {regexp: RegExp, groups: Map<string, number>} {
const results: string[] = [];
let first = true;
let group = 0;
const groups = new Map<string, number>();
for (const piece of pieces) {
if (!first)
results.push(`\\s${typeof piece === 'string' && IDENT_LIKE.test(piece) ? '+' : '*'}`);
first = false;
if (typeof piece === 'string') {
if (MATCHING_IDENT.test(piece)) {
const matchGroup = groups.get(piece);
if (!matchGroup) {
results.push('(' + IDENTIFIER.source + ')');
const newGroup = ++group;
groups.set(piece, newGroup);
} else {
results.push(`\\${matchGroup}`);
}
} else {
results.push(escapeRegExp(piece));
}
} else {
results.push('(?:' + piece.source + ')');
}
}
return {
regexp: new RegExp(results.join('')),
groups,
};
}
export function compile(
data: MockDirectory, angularFiles: MockData, options: AotCompilerOptions = {},
errorCollector: (error: any, fileName?: string) => void = error => { throw error;}): {
source: string,
} {
const testFiles = toMockFileArray(data);
const scripts = testFiles.map(entry => entry.fileName);
const angularFilesArray = toMockFileArray(angularFiles);
const files = arrayToMockDir([...testFiles, ...angularFilesArray]);
const mockCompilerHost = new MockCompilerHost(scripts, files);
const program = new NgtscProgram(
scripts, {
target: ts.ScriptTarget.ES2015,
module: ts.ModuleKind.ES2015,
moduleResolution: ts.ModuleResolutionKind.NodeJs, ...options,
},
mockCompilerHost);
program.emit();
const source =
scripts.map(script => mockCompilerHost.readFile(script.replace(/\.ts$/, '.js'))).join('\n');
return {source};
}

View File

@ -7,7 +7,7 @@
*/ */
import {MockDirectory, setup} from '../aot/test_util'; import {MockDirectory, setup} from '@angular/compiler/test/aot/test_util';
import {compile, expectEmit} from './mock_compile'; import {compile, expectEmit} from './mock_compile';
describe('mock_compiler', () => { describe('mock_compiler', () => {
@ -47,9 +47,6 @@ describe('mock_compiler', () => {
// result.source contains just the emitted factory declarations regardless of the original // result.source contains just the emitted factory declarations regardless of the original
// module. // module.
expect(result.source).toContain('Hello'); expect(result.source).toContain('Hello');
// The output context is also returned if the actual output ast is needed.
expect(result.outputContext.statements.length).toBeGreaterThan(0);
}); });
}); });
@ -143,7 +140,7 @@ describe('mock_compiler', () => {
expectEmit( expectEmit(
result.source, ` result.source, `
// TODO: this comment should not be taken into account // TODO: this comment should not be taken into account
$r3$.ɵT(0, 'Hello!'); $r3$.ɵT(0, "Hello!");
// TODO: this comment should not be taken into account // TODO: this comment should not be taken into account
`, `,
'todo comments should be ignored'); 'todo comments should be ignored');

View File

@ -6,9 +6,8 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {InitialStylingFlags} from '../../src/core'; import {InitialStylingFlags} from '@angular/compiler/src/core';
import {MockDirectory, setup} from '../aot/test_util'; import {MockDirectory, setup} from '@angular/compiler/test/aot/test_util';
import {compile, expectEmit} from './mock_compile'; import {compile, expectEmit} from './mock_compile';
@ -47,21 +46,21 @@ describe('compiler compliance', () => {
// The template should look like this (where IDENT is a wild card for an identifier): // The template should look like this (where IDENT is a wild card for an identifier):
const template = ` const template = `
const $c1$ = ['title', 'Hello']; const $c1$ = ["title", "Hello"];
const $c2$ = ['my-app', ${InitialStylingFlags.VALUES_MODE}, 'my-app', true]; const $c2$ = ["my-app", ${InitialStylingFlags.VALUES_MODE}, "my-app", true];
const $c3$ = ['cx', '20', 'cy', '30', 'r', '50']; const $c3$ = ["cx", "20", "cy", "30", "r", "50"];
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { template: function MyComponent_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'div', $c1$); $r3$.ɵE(0, "div", $c1$);
$r3$.ɵs((null as any), $c2$); $r3$.ɵs(null, $c2$);
$r3$.ɵNS(); $r3$.ɵNS();
$r3$.ɵE(1, 'svg'); $r3$.ɵE(1, "svg");
$r3$.ɵEe(2, 'circle', $c3$); $r3$.ɵEe(2, "circle", $c3$);
$r3$.ɵe(); $r3$.ɵe();
$r3$.ɵNH(); $r3$.ɵNH();
$r3$.ɵE(3, 'p'); $r3$.ɵE(3, "p");
$r3$.ɵT(4, 'test'); $r3$.ɵT(4, "test");
$r3$.ɵe(); $r3$.ɵe();
$r3$.ɵe(); $r3$.ɵe();
} }
@ -98,20 +97,20 @@ describe('compiler compliance', () => {
// The template should look like this (where IDENT is a wild card for an identifier): // The template should look like this (where IDENT is a wild card for an identifier):
const template = ` const template = `
const $c1$ = ['title', 'Hello']; const $c1$ = ["title", "Hello"];
const $c2$ = ['my-app', ${InitialStylingFlags.VALUES_MODE}, 'my-app', true]; const $c2$ = ["my-app", ${InitialStylingFlags.VALUES_MODE}, "my-app", true];
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { template: function MyComponent_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'div', $c1$); $r3$.ɵE(0, "div", $c1$);
$r3$.ɵs((null as any), $c2$); $r3$.ɵs(null, $c2$);
$r3$.ɵNM(); $r3$.ɵNM();
$r3$.ɵE(1, 'math'); $r3$.ɵE(1, "math");
$r3$.ɵEe(2, 'infinity'); $r3$.ɵEe(2, "infinity");
$r3$.ɵe(); $r3$.ɵe();
$r3$.ɵNH(); $r3$.ɵNH();
$r3$.ɵE(3, 'p'); $r3$.ɵE(3, "p");
$r3$.ɵT(4, 'test'); $r3$.ɵT(4, "test");
$r3$.ɵe(); $r3$.ɵe();
$r3$.ɵe(); $r3$.ɵe();
} }
@ -148,18 +147,18 @@ describe('compiler compliance', () => {
// The template should look like this (where IDENT is a wild card for an identifier): // The template should look like this (where IDENT is a wild card for an identifier):
const template = ` const template = `
const $c1$ = ['title', 'Hello']; const $c1$ = ["title", "Hello"];
const $c2$ = ['my-app', ${InitialStylingFlags.VALUES_MODE}, 'my-app', true]; const $c2$ = ["my-app", ${InitialStylingFlags.VALUES_MODE}, "my-app", true];
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { template: function MyComponent_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'div', $c1$); $r3$.ɵE(0, "div", $c1$);
$r3$.ɵs((null as any), $c2$); $r3$.ɵs(null, $c2$);
$r3$.ɵT(1, 'Hello '); $r3$.ɵT(1, "Hello ");
$r3$.ɵE(2, 'b'); $r3$.ɵE(2, "b");
$r3$.ɵT(3, 'World'); $r3$.ɵT(3, "World");
$r3$.ɵe(); $r3$.ɵe();
$r3$.ɵT(4, '!'); $r3$.ɵT(4, "!");
$r3$.ɵe(); $r3$.ɵe();
} }
} }
@ -197,16 +196,16 @@ describe('compiler compliance', () => {
// The template should look like this (where IDENT is a wild card for an identifier): // The template should look like this (where IDENT is a wild card for an identifier):
const template = ` const template = `
const $c1$ = ['class', 'my-app', 0, 'http://someuri/foo', 'foo:bar', 'baz', 'title', 'Hello', 0, 'http://someuri/foo', 'foo:qux', 'quacks']; const $c1$ = ["class", "my-app", 0, "http://someuri/foo", "foo:bar", "baz", "title", "Hello", 0, "http://someuri/foo", "foo:qux", "quacks"];
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { template: function MyComponent_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'div', $e0_attrs$); $r3$.ɵE(0, "div", $e0_attrs$);
$r3$.ɵT(1, 'Hello '); $r3$.ɵT(1, "Hello ");
$r3$.ɵE(2, 'b'); $r3$.ɵE(2, "b");
$r3$.ɵT(3, 'World'); $r3$.ɵT(3, "World");
$r3$.ɵe(); $r3$.ɵe();
$r3$.ɵT(4, '!'); $r3$.ɵT(4, "!");
$r3$.ɵe(); $r3$.ɵe();
} }
} }
@ -241,12 +240,12 @@ describe('compiler compliance', () => {
const factory = 'factory: function MyComponent_Factory() { return new MyComponent(); }'; const factory = 'factory: function MyComponent_Factory() { return new MyComponent(); }';
const template = ` const template = `
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { template: function MyComponent_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵEe(0, 'div'); $r3$.ɵEe(0, "div");
} }
if (rf & 2) { if (rf & 2) {
$r3$.ɵp(0, 'id', $r3$.ɵb(ctx.id)); $r3$.ɵp(0, "id", $r3$.ɵb(ctx.id));
} }
} }
`; `;
@ -285,17 +284,17 @@ describe('compiler compliance', () => {
const factory = 'factory: function MyComponent_Factory() { return new MyComponent(); }'; const factory = 'factory: function MyComponent_Factory() { return new MyComponent(); }';
const template = ` const template = `
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { template: function MyComponent_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵEe(0, 'div'); $r3$.ɵEe(0, "div");
$r3$.ɵPp(1,'pipe'); $r3$.ɵPp(1,"pipe");
$r3$.ɵrS(10); $r3$.ɵrS(10);
} }
if (rf & 2) { if (rf & 2) {
$r3$.ɵp(0, 'ternary', $r3$.ɵb((ctx.cond ? $r3$.ɵf1(2, _c0, ctx.a): _c1))); $r3$.ɵp(0, "ternary", $r3$.ɵb((ctx.cond ? $r3$.ɵf1(2, _c0, ctx.a): _c1)));
$r3$.ɵp(0, 'pipe', $r3$.ɵb($r3$.ɵpb3(6, 1, ctx.value, 1, 2))); $r3$.ɵp(0, "pipe", $r3$.ɵb($r3$.ɵpb3(6, 1, ctx.value, 1, 2)));
$r3$.ɵp(0, 'and', $r3$.ɵb((ctx.cond && $r3$.ɵf1(4, _c0, ctx.b)))); $r3$.ɵp(0, "and", $r3$.ɵb((ctx.cond && $r3$.ɵf1(4, _c0, ctx.b))));
$r3$.ɵp(0, 'or', $r3$.ɵb((ctx.cond || $r3$.ɵf1(6, _c0, ctx.c)))); $r3$.ɵp(0, "or", $r3$.ɵb((ctx.cond || $r3$.ɵf1(6, _c0, ctx.c))));
} }
} }
`; `;
@ -330,15 +329,15 @@ describe('compiler compliance', () => {
const factory = 'factory: function MyComponent_Factory() { return new MyComponent(); }'; const factory = 'factory: function MyComponent_Factory() { return new MyComponent(); }';
const template = ` const template = `
const _c0 = ['background-color']; const _c0 = ["background-color"];
const _c1 = ['error']; const _c1 = ["error"];
class MyComponent {
static ngComponentDef = i0.ɵdefineComponent({type:MyComponent,selectors:[['my-component']], MyComponent.ngComponentDef = i0.ɵdefineComponent({type:MyComponent,selectors:[["my-component"]],
factory:function MyComponent_Factory(){ factory:function MyComponent_Factory(){
return new MyComponent(); return new MyComponent();
},template:function MyComponent_Template(rf:number,ctx:any){ },template:function MyComponent_Template(rf,ctx){
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'div'); $r3$.ɵE(0, "div");
$r3$.ɵs(_c0, _c1); $r3$.ɵs(_c0, _c1);
$r3$.ɵe(); $r3$.ɵe();
} }
@ -348,6 +347,7 @@ describe('compiler compliance', () => {
$r3$.ɵsa(0); $r3$.ɵsa(0);
} }
} }
});
`; `;
@ -383,38 +383,38 @@ describe('compiler compliance', () => {
// ChildComponent definition should be: // ChildComponent definition should be:
const ChildComponentDefinition = ` const ChildComponentDefinition = `
static ngComponentDef = $r3$.ɵdefineComponent({ ChildComponent.ngComponentDef = $r3$.ɵdefineComponent({
type: ChildComponent, type: ChildComponent,
selectors: [['child']], selectors: [["child"]],
factory: function ChildComponent_Factory() { return new ChildComponent(); }, factory: function ChildComponent_Factory() { return new ChildComponent(); },
template: function ChildComponent_Template(rf: IDENT, ctx: IDENT) { template: function ChildComponent_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵT(0, 'child-view'); $r3$.ɵT(0, "child-view");
} }
} }
});`; });`;
// SomeDirective definition should be: // SomeDirective definition should be:
const SomeDirectiveDefinition = ` const SomeDirectiveDefinition = `
static ngDirectiveDef = $r3$.ɵdefineDirective({ SomeDirective.ngDirectiveDef = $r3$.ɵdefineDirective({
type: SomeDirective, type: SomeDirective,
selectors: [['', 'some-directive', '']], selectors: [["", "some-directive", ""]],
factory: function SomeDirective_Factory() {return new SomeDirective(); } factory: function SomeDirective_Factory() {return new SomeDirective(); }
}); });
`; `;
// MyComponent definition should be: // MyComponent definition should be:
const MyComponentDefinition = ` const MyComponentDefinition = `
const $c1$ = ['some-directive', '']; const $c1$ = ["some-directive", ""];
static ngComponentDef = $r3$.ɵdefineComponent({ MyComponent.ngComponentDef = $r3$.ɵdefineComponent({
type: MyComponent, type: MyComponent,
selectors: [['my-component']], selectors: [["my-component"]],
factory: function MyComponent_Factory() { return new MyComponent(); }, factory: function MyComponent_Factory() { return new MyComponent(); },
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { template: function MyComponent_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵEe(0, 'child', $c1$); $r3$.ɵEe(0, "child", $c1$);
$r3$.ɵT(1, '!'); $r3$.ɵT(1, "!");
} }
}, },
directives: [ChildComponent, SomeDirective] directives: [ChildComponent, SomeDirective]
@ -450,18 +450,18 @@ describe('compiler compliance', () => {
// SomeDirective definition should be: // SomeDirective definition should be:
const SomeDirectiveDefinition = ` const SomeDirectiveDefinition = `
static ngDirectiveDef = $r3$.ɵdefineDirective({ SomeDirective.ngDirectiveDef = $r3$.ɵdefineDirective({
type: SomeDirective, type: SomeDirective,
selectors: [['div', 'some-directive', '', 8, 'foo', 3, 'title', '', 9, 'baz']], selectors: [["div", "some-directive", "", 8, "foo", 3, "title", "", 9, "baz"]],
factory: function SomeDirective_Factory() {return new SomeDirective(); } factory: function SomeDirective_Factory() {return new SomeDirective(); }
}); });
`; `;
// OtherDirective definition should be: // OtherDirective definition should be:
const OtherDirectiveDefinition = ` const OtherDirectiveDefinition = `
static ngDirectiveDef = $r3$.ɵdefineDirective({ OtherDirective.ngDirectiveDef = $r3$.ɵdefineDirective({
type: OtherDirective, type: OtherDirective,
selectors: [['', 5, 'span', 'title', '', 9, 'baz']], selectors: [["", 5, "span", "title", "", 9, "baz"]],
factory: function OtherDirective_Factory() {return new OtherDirective(); } factory: function OtherDirective_Factory() {return new OtherDirective(); }
}); });
`; `;
@ -491,13 +491,12 @@ describe('compiler compliance', () => {
}; };
const HostBindingDirDeclaration = ` const HostBindingDirDeclaration = `
static ngDirectiveDef = $r3$.ɵdefineDirective({ HostBindingDir.ngDirectiveDef = $r3$.ɵdefineDirective({
type: HostBindingDir, type: HostBindingDir,
selectors: [['', 'hostBindingDir', '']], selectors: [["", "hostBindingDir", ""]],
factory: function HostBindingDir_Factory() { return new HostBindingDir(); }, factory: function HostBindingDir_Factory() { return new HostBindingDir(); },
hostBindings: function HostBindingDir_HostBindings( hostBindings: function HostBindingDir_HostBindings(dirIndex, elIndex) {
dirIndex: $number$, elIndex: $number$) { $r3$.ɵp(elIndex, "id", $r3$.ɵb($r3$.ɵd(dirIndex).dirId));
$r3$.ɵp(elIndex, 'id', $r3$.ɵb($r3$.ɵd(dirIndex).dirId));
} }
}); });
`; `;
@ -534,34 +533,34 @@ describe('compiler compliance', () => {
}; };
const IfDirectiveDefinition = ` const IfDirectiveDefinition = `
static ngDirectiveDef = $r3$.ɵdefineDirective({ IfDirective.ngDirectiveDef = $r3$.ɵdefineDirective({
type: IfDirective, type: IfDirective,
selectors: [['', 'if', '']], selectors: [["", "if", ""]],
factory: function IfDirective_Factory() { return new IfDirective($r3$.ɵinjectTemplateRef()); } factory: function IfDirective_Factory() { return new IfDirective($r3$.ɵinjectTemplateRef()); }
});`; });`;
const MyComponentDefinition = ` const MyComponentDefinition = `
const $c1$ = ['foo', '']; const $c1$ = ["foo", ""];
const $c2$ = ['if', '']; const $c2$ = ["if", ""];
static ngComponentDef = $r3$.ɵdefineComponent({ MyComponent.ngComponentDef = $r3$.ɵdefineComponent({
type: MyComponent, type: MyComponent,
selectors: [['my-component']], selectors: [["my-component"]],
factory: function MyComponent_Factory() { return new MyComponent(); }, factory: function MyComponent_Factory() { return new MyComponent(); },
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { template: function MyComponent_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'ul', null, $c1$); $r3$.ɵE(0, "ul", null, $c1$);
$r3$.ɵC(2, MyComponent_li_Template_2, null, $c2$); $r3$.ɵC(2, MyComponent_li_Template_2, null, $c2$);
$r3$.ɵe(); $r3$.ɵe();
} }
const $foo$ = $r3$.ɵld(1); const $foo$ = $r3$.ɵld(1);
function MyComponent_li_Template_2(rf: IDENT, ctx0: IDENT) { function MyComponent_li_Template_2(rf, ctx0) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'li'); $r3$.ɵE(0, "li");
$r3$.ɵT(1); $r3$.ɵT(1);
$r3$.ɵe(); $r3$.ɵe();
} }
if (rf & 2) { if (rf & 2) {
$r3$.ɵt(1, $r3$.ɵi2('', ctx.salutation, ' ', $foo$, '')); $r3$.ɵt(1, $r3$.ɵi2("", ctx.salutation, " ", $foo$, ""));
} }
} }
}, },
@ -611,19 +610,19 @@ describe('compiler compliance', () => {
}; };
const MyAppDeclaration = ` const MyAppDeclaration = `
const $e0_ff$ = ($v$: any) => { return ['Nancy', $v$]; }; const $e0_ff$ = function ($v$) { return ["Nancy", $v$]; };
static ngComponentDef = $r3$.ɵdefineComponent({ MyApp.ngComponentDef = $r3$.ɵdefineComponent({
type: MyApp, type: MyApp,
selectors: [['my-app']], selectors: [["my-app"]],
factory: function MyApp_Factory() { return new MyApp(); }, factory: function MyApp_Factory() { return new MyApp(); },
template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { template: function MyApp_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵEe(0, 'my-comp'); $r3$.ɵEe(0, "my-comp");
$r3$.ɵrS(2); $r3$.ɵrS(2);
} }
if (rf & 2) { if (rf & 2) {
$r3$.ɵp(0, 'names', $r3$.ɵb($r3$.ɵf1(2, $e0_ff$, ctx.customName))); $r3$.ɵp(0, "names", $r3$.ɵb($r3$.ɵf1(2, $e0_ff$, ctx.customName)));
} }
}, },
directives: [MyComp] directives: [MyComp]
@ -688,22 +687,22 @@ describe('compiler compliance', () => {
}; };
const MyAppDefinition = ` const MyAppDefinition = `
const $e0_ff$ = ($v0$: $any$, $v1$: $any$, $v2$: $any$, $v3$: $any$, $v4$: $any$, $v5$: $any$, $v6$: $any$, $v7$: $any$, $v8$: $any$) => { const $e0_ff$ = function ($v0$, $v1$, $v2$, $v3$, $v4$, $v5$, $v6$, $v7$, $v8$) {
return ['start-', $v0$, $v1$, $v2$, $v3$, $v4$, '-middle-', $v5$, $v6$, $v7$, $v8$, '-end']; return ["start-", $v0$, $v1$, $v2$, $v3$, $v4$, "-middle-", $v5$, $v6$, $v7$, $v8$, "-end"];
} }
static ngComponentDef = $r3$.ɵdefineComponent({ MyApp.ngComponentDef = $r3$.ɵdefineComponent({
type: MyApp, type: MyApp,
selectors: [['my-app']], selectors: [["my-app"]],
factory: function MyApp_Factory() { return new MyApp(); }, factory: function MyApp_Factory() { return new MyApp(); },
template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { template: function MyApp_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵEe(0, 'my-comp'); $r3$.ɵEe(0, "my-comp");
$r3$.ɵrS(10); $r3$.ɵrS(10);
} }
if (rf & 2) { if (rf & 2) {
$r3$.ɵp( $r3$.ɵp(
0, 'names', 0, "names",
$r3$.ɵb($r3$.ɵfV(10, $e0_ff$, [ctx.n0, ctx.n1, ctx.n2, ctx.n3, ctx.n4, ctx.n5, ctx.n6, ctx.n7, ctx.n8]))); $r3$.ɵb($r3$.ɵfV(10, $e0_ff$, [ctx.n0, ctx.n1, ctx.n2, ctx.n3, ctx.n4, ctx.n5, ctx.n6, ctx.n7, ctx.n8])));
} }
}, },
@ -751,19 +750,19 @@ describe('compiler compliance', () => {
}; };
const MyAppDefinition = ` const MyAppDefinition = `
const $e0_ff$ = ($v$: any) => { return {'duration': 500, animation: $v$}; }; const $e0_ff$ = function ($v$) { return {"duration": 500, animation: $v$}; };
static ngComponentDef = $r3$.ɵdefineComponent({ MyApp.ngComponentDef = $r3$.ɵdefineComponent({
type: MyApp, type: MyApp,
selectors: [['my-app']], selectors: [["my-app"]],
factory: function MyApp_Factory() { return new MyApp(); }, factory: function MyApp_Factory() { return new MyApp(); },
template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { template: function MyApp_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵEe(0, 'object-comp'); $r3$.ɵEe(0, "object-comp");
$r3$.ɵrS(2); $r3$.ɵrS(2);
} }
if (rf & 2) { if (rf & 2) {
$r3$.ɵp(0, 'config', $r3$.ɵb($r3$.ɵf1(2, $e0_ff$, ctx.name))); $r3$.ɵp(0, "config", $r3$.ɵb($r3$.ɵf1(2, $e0_ff$, ctx.name)));
} }
}, },
directives: [ObjectComp] directives: [ObjectComp]
@ -814,22 +813,22 @@ describe('compiler compliance', () => {
const MyAppDefinition = ` const MyAppDefinition = `
const $c0$ = {opacity: 0, duration: 0}; const $c0$ = {opacity: 0, duration: 0};
const $e0_ff$ = ($v$: any) => { return {opacity: 1, duration: $v$}; }; const $e0_ff$ = function ($v$) { return {opacity: 1, duration: $v$}; };
const $e0_ff_1$ = ($v$: any) => { return [$c0$, $v$]; }; const $e0_ff_1$ = function ($v$) { return [$c0$, $v$]; };
const $e0_ff_2$ = ($v1$: any, $v2$: any) => { return {animation: $v1$, actions: $v2$}; }; const $e0_ff_2$ = function ($v1$, $v2$) { return {animation: $v1$, actions: $v2$}; };
static ngComponentDef = $r3$.ɵdefineComponent({ MyApp.ngComponentDef = $r3$.ɵdefineComponent({
type: MyApp, type: MyApp,
selectors: [['my-app']], selectors: [["my-app"]],
factory: function MyApp_Factory() { return new MyApp(); }, factory: function MyApp_Factory() { return new MyApp(); },
template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) { template: function MyApp_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵEe(0, 'nested-comp'); $r3$.ɵEe(0, "nested-comp");
$r3$.ɵrS(7); $r3$.ɵrS(7);
} }
if (rf & 2) { if (rf & 2) {
$r3$.ɵp( $r3$.ɵp(
0, 'config', 0, "config",
$r3$.ɵb($r3$.ɵf2(7, $e0_ff_2$, ctx.name, $r3$.ɵf1(4, $e0_ff_1$, $r3$.ɵf1(2, $e0_ff$, ctx.duration))))); $r3$.ɵb($r3$.ɵf2(7, $e0_ff_2$, ctx.name, $r3$.ɵf1(4, $e0_ff_1$, $r3$.ɵf1(2, $e0_ff$, ctx.duration)))));
} }
}, },
@ -875,14 +874,14 @@ describe('compiler compliance', () => {
}; };
const SimpleComponentDefinition = ` const SimpleComponentDefinition = `
static ngComponentDef = $r3$.ɵdefineComponent({ SimpleComponent.ngComponentDef = $r3$.ɵdefineComponent({
type: SimpleComponent, type: SimpleComponent,
selectors: [['simple']], selectors: [["simple"]],
factory: function SimpleComponent_Factory() { return new SimpleComponent(); }, factory: function SimpleComponent_Factory() { return new SimpleComponent(); },
template: function SimpleComponent_Template(rf: IDENT, ctx: IDENT) { template: function SimpleComponent_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵpD(); $r3$.ɵpD();
$r3$.ɵE(0, 'div'); $r3$.ɵE(0, "div");
$r3$.ɵP(1); $r3$.ɵP(1);
$r3$.ɵe(); $r3$.ɵe();
} }
@ -890,22 +889,22 @@ describe('compiler compliance', () => {
});`; });`;
const ComplexComponentDefinition = ` const ComplexComponentDefinition = `
const $c1$ = [[['span', 'title', 'tofirst']], [['span', 'title', 'tosecond']]]; const $c1$ = [[["span", "title", "tofirst"]], [["span", "title", "tosecond"]]];
const $c2$ = ['span[title=toFirst]', 'span[title=toSecond]']; const $c2$ = ["span[title=toFirst]", "span[title=toSecond]"];
const $c3$ = ['id','first']; const $c3$ = ["id","first"];
const $c4$ = ['id','second']; const $c4$ = ["id","second"];
static ngComponentDef = $r3$.ɵdefineComponent({ ComplexComponent.ngComponentDef = $r3$.ɵdefineComponent({
type: ComplexComponent, type: ComplexComponent,
selectors: [['complex']], selectors: [["complex"]],
factory: function ComplexComponent_Factory() { return new ComplexComponent(); }, factory: function ComplexComponent_Factory() { return new ComplexComponent(); },
template: function ComplexComponent_Template(rf: IDENT, ctx: IDENT) { template: function ComplexComponent_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵpD($c1$, $c2$); $r3$.ɵpD($c1$, $c2$);
$r3$.ɵE(0, 'div', $c3$); $r3$.ɵE(0, "div", $c3$);
$r3$.ɵP(1, 1); $r3$.ɵP(1, 1);
$r3$.ɵe(); $r3$.ɵe();
$r3$.ɵE(2, 'div', $c4$); $r3$.ɵE(2, "div", $c4$);
$r3$.ɵP(3, 2); $r3$.ɵP(3, 2);
$r3$.ɵe(); $r3$.ɵe();
} }
@ -958,17 +957,17 @@ describe('compiler compliance', () => {
}; };
const ViewQueryComponentDefinition = ` const ViewQueryComponentDefinition = `
const $e0_attrs$ = ['someDir','']; const $e0_attrs$ = ["someDir",""];
static ngComponentDef = $r3$.ɵdefineComponent({ ViewQueryComponent.ngComponentDef = $r3$.ɵdefineComponent({
type: ViewQueryComponent, type: ViewQueryComponent,
selectors: [['view-query-component']], selectors: [["view-query-component"]],
factory: function ViewQueryComponent_Factory() { return new ViewQueryComponent(); }, factory: function ViewQueryComponent_Factory() { return new ViewQueryComponent(); },
template: function ViewQueryComponent_Template(rf: $RenderFlags$, ctx: $ViewQueryComponent$) { template: function ViewQueryComponent_Template(rf, ctx) {
var $tmp$: $any$; var $tmp$;
if (rf & 1) { if (rf & 1) {
$r3$.ɵQ(0, SomeDirective, true); $r3$.ɵQ(0, SomeDirective, true);
$r3$.ɵEe(1, 'div', $e0_attrs$); $r3$.ɵEe(1, "div", $e0_attrs$);
} }
if (rf & 2) { if (rf & 2) {
($r3$.ɵqR(($tmp$ = $r3$.ɵld(0))) && (ctx.someDir = $tmp$.first)); ($r3$.ɵqR(($tmp$ = $r3$.ɵld(0))) && (ctx.someDir = $tmp$.first));
@ -1018,22 +1017,20 @@ describe('compiler compliance', () => {
}; };
const ContentQueryComponentDefinition = ` const ContentQueryComponentDefinition = `
static ngComponentDef = $r3$.ɵdefineComponent({ ContentQueryComponent.ngComponentDef = $r3$.ɵdefineComponent({
type: ContentQueryComponent, type: ContentQueryComponent,
selectors: [['content-query-component']], selectors: [["content-query-component"]],
factory: function ContentQueryComponent_Factory() { factory: function ContentQueryComponent_Factory() {
return [new ContentQueryComponent(), $r3$.ɵQ(null, SomeDirective, true)]; return [new ContentQueryComponent(), $r3$.ɵQ(null, SomeDirective, true)];
}, },
hostBindings: function ContentQueryComponent_HostBindings( hostBindings: function ContentQueryComponent_HostBindings(dirIndex, elIndex) {
dirIndex: $number$, elIndex: $number$) { var $tmp$;
var $tmp$: $any$;
($r3$.ɵqR(($tmp$ = $r3$.ɵd(dirIndex)[1])) && ($r3$.ɵd(dirIndex)[0].someDir = $tmp$.first)); ($r3$.ɵqR(($tmp$ = $r3$.ɵd(dirIndex)[1])) && ($r3$.ɵd(dirIndex)[0].someDir = $tmp$.first));
}, },
template: function ContentQueryComponent_Template( template: function ContentQueryComponent_Template(rf, ctx) {
rf: $RenderFlags$, ctx: $ContentQueryComponent$) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵpD(); $r3$.ɵpD();
$r3$.ɵE(0, 'div'); $r3$.ɵE(0, "div");
$r3$.ɵP(1); $r3$.ɵP(1);
$r3$.ɵe(); $r3$.ɵe();
} }
@ -1089,41 +1086,41 @@ describe('compiler compliance', () => {
it('should render pipes', () => { it('should render pipes', () => {
const MyPipeDefinition = ` const MyPipeDefinition = `
static ngPipeDef = $r3$.ɵdefinePipe( MyPipe.ngPipeDef = $r3$.ɵdefinePipe(
{name: 'myPipe', type: MyPipe, factory: function MyPipe_Factory() { return new MyPipe(); }, pure: false}); {name: "myPipe", type: MyPipe, factory: function MyPipe_Factory() { return new MyPipe(); }, pure: false});
`; `;
const MyPurePipeDefinition = ` const MyPurePipeDefinition = `
static ngPipeDef = $r3$.ɵdefinePipe({ MyPurePipe.ngPipeDef = $r3$.ɵdefinePipe({
name: 'myPurePipe', name: "myPurePipe",
type: MyPurePipe, type: MyPurePipe,
factory: function MyPurePipe_Factory() { return new MyPurePipe(); }, factory: function MyPurePipe_Factory() { return new MyPurePipe(); },
pure: true pure: true
});`; });`;
const MyAppDefinition = ` const MyAppDefinition = `
const $c0$ = ($a0$: any) => { const $c0$ = function ($a0$) {
return [$a0$, 1, 2, 3, 4, 5]; return [$a0$, 1, 2, 3, 4, 5];
}; };
// ... // ...
static ngComponentDef = $r3$.ɵdefineComponent({ MyApp.ngComponentDef = $r3$.ɵdefineComponent({
type: MyApp, type: MyApp,
selectors: [['my-app']], selectors: [["my-app"]],
factory: function MyApp_Factory() { return new MyApp(); }, factory: function MyApp_Factory() { return new MyApp(); },
template: function MyApp_Template(rf: IDENT, ctx: IDENT) { template: function MyApp_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵT(0); $r3$.ɵT(0);
$r3$.ɵPp(1, 'myPurePipe'); $r3$.ɵPp(1, "myPurePipe");
$r3$.ɵPp(2, 'myPipe'); $r3$.ɵPp(2, "myPipe");
$r3$.ɵE(3, 'p'); $r3$.ɵE(3, "p");
$r3$.ɵT(4); $r3$.ɵT(4);
$r3$.ɵPp(5, 'myPipe'); $r3$.ɵPp(5, "myPipe");
$r3$.ɵe(); $r3$.ɵe();
$r3$.ɵrS(15); $r3$.ɵrS(15);
} }
if (rf & 2) { if (rf & 2) {
$r3$.ɵt(0, $r3$.ɵi1('', $r3$.ɵpb2(1, 3, $r3$.ɵpb2(2, 6, ctx.name, ctx.size), ctx.size), '')); $r3$.ɵt(0, $r3$.ɵi1("", $r3$.ɵpb2(1, 3, $r3$.ɵpb2(2, 6, ctx.name, ctx.size), ctx.size), ""));
$r3$.ɵt(4, $r3$.ɵi1('', $r3$.ɵpbV(5, 13 , $r3$.ɵf1(15, $c0$, ctx.name)), '')); $r3$.ɵt(4, $r3$.ɵi1("", $r3$.ɵpbV(5, 13 , $r3$.ɵf1(15, $c0$, ctx.name)), ""));
} }
}, },
pipes: [MyPurePipe, MyPipe] pipes: [MyPurePipe, MyPipe]
@ -1154,20 +1151,20 @@ describe('compiler compliance', () => {
}; };
const MyComponentDefinition = ` const MyComponentDefinition = `
const $c1$ = ['user', '']; const $c1$ = ["user", ""];
static ngComponentDef = $r3$.ɵdefineComponent({ MyComponent.ngComponentDef = $r3$.ɵdefineComponent({
type: MyComponent, type: MyComponent,
selectors: [['my-component']], selectors: [["my-component"]],
factory: function MyComponent_Factory() { return new MyComponent(); }, factory: function MyComponent_Factory() { return new MyComponent(); },
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { template: function MyComponent_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵEe(0, 'input', null, $c1$); $r3$.ɵEe(0, "input", null, $c1$);
$r3$.ɵT(2); $r3$.ɵT(2);
} }
const $user$ = $r3$.ɵld(1); const $user$ = $r3$.ɵld(1);
if (rf & 2) { if (rf & 2) {
$r3$.ɵt(2, $r3$.ɵi1('Hello ', $user$.value, '!')); $r3$.ɵt(2, $r3$.ɵi1("Hello ", $user$.value, "!"));
} }
} }
}); });
@ -1225,28 +1222,28 @@ describe('compiler compliance', () => {
it('should gen hooks with a few simple components', () => { it('should gen hooks with a few simple components', () => {
const LifecycleCompDefinition = ` const LifecycleCompDefinition = `
static ngComponentDef = $r3$.ɵdefineComponent({ LifecycleComp.ngComponentDef = $r3$.ɵdefineComponent({
type: LifecycleComp, type: LifecycleComp,
selectors: [['lifecycle-comp']], selectors: [["lifecycle-comp"]],
factory: function LifecycleComp_Factory() { return new LifecycleComp(); }, factory: function LifecycleComp_Factory() { return new LifecycleComp(); },
inputs: {nameMin: 'name'}, inputs: {nameMin: "name"},
features: [$r3$.ɵNgOnChangesFeature], features: [$r3$.ɵNgOnChangesFeature],
template: function LifecycleComp_Template(rf: IDENT, ctx: IDENT) {} template: function LifecycleComp_Template(rf, ctx) {}
});`; });`;
const SimpleLayoutDefinition = ` const SimpleLayoutDefinition = `
static ngComponentDef = $r3$.ɵdefineComponent({ SimpleLayout.ngComponentDef = $r3$.ɵdefineComponent({
type: SimpleLayout, type: SimpleLayout,
selectors: [['simple-layout']], selectors: [["simple-layout"]],
factory: function SimpleLayout_Factory() { return new SimpleLayout(); }, factory: function SimpleLayout_Factory() { return new SimpleLayout(); },
template: function SimpleLayout_Template(rf: IDENT, ctx: IDENT) { template: function SimpleLayout_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵEe(0, 'lifecycle-comp'); $r3$.ɵEe(0, "lifecycle-comp");
$r3$.ɵEe(1, 'lifecycle-comp'); $r3$.ɵEe(1, "lifecycle-comp");
} }
if (rf & 2) { if (rf & 2) {
$r3$.ɵp(0, 'name', $r3$.ɵb(ctx.name1)); $r3$.ɵp(0, "name", $r3$.ɵb(ctx.name1));
$r3$.ɵp(1, 'name', $r3$.ɵb(ctx.name2)); $r3$.ɵp(1, "name", $r3$.ɵb(ctx.name2));
} }
}, },
directives: [LifecycleComp] directives: [LifecycleComp]
@ -1340,37 +1337,37 @@ describe('compiler compliance', () => {
// TODO(benlesh): Enforce this when the directives are specified // TODO(benlesh): Enforce this when the directives are specified
const ForDirectiveDefinition = ` const ForDirectiveDefinition = `
static ngDirectiveDef = $r3$.ɵdefineDirective({ ForOfDirective.ngDirectiveDef = $r3$.ɵdefineDirective({
type: ForOfDirective, type: ForOfDirective,
selectors: [['', 'forOf', '']], selectors: [["", "forOf", ""]],
factory: function ForOfDirective_Factory() { factory: function ForOfDirective_Factory() {
return new ForOfDirective($r3$.ɵinjectViewContainerRef(), $r3$.ɵinjectTemplateRef()); return new ForOfDirective($r3$.ɵinjectViewContainerRef(), $r3$.ɵinjectTemplateRef());
}, },
features: [$r3$.ɵNgOnChangesFeature], features: [$r3$.ɵNgOnChangesFeature],
inputs: {forOf: 'forOf'} inputs: {forOf: "forOf"}
}); });
`; `;
const MyComponentDefinition = ` const MyComponentDefinition = `
const $_c0$ = ['for','','forOf','']; const $_c0$ = ["for","","forOf",""];
static ngComponentDef = $r3$.ɵdefineComponent({ MyComponent.ngComponentDef = $r3$.ɵdefineComponent({
type: MyComponent, type: MyComponent,
selectors: [['my-component']], selectors: [["my-component"]],
factory: function MyComponent_Factory() { return new MyComponent(); }, factory: function MyComponent_Factory() { return new MyComponent(); },
template: function MyComponent_Template(rf:IDENT,ctx:IDENT){ template: function MyComponent_Template(rf, ctx){
if (rf & 1) { if (rf & 1) {
$r3$.ɵNS(); $r3$.ɵNS();
$r3$.ɵE(0,'svg'); $r3$.ɵE(0,"svg");
$r3$.ɵC(1,MyComponent__svg_g_Template_1,null,$_c0$); $r3$.ɵC(1,MyComponent__svg_g_Template_1,null,$_c0$);
$r3$.ɵe(); $r3$.ɵe();
} }
if (rf & 2) { $r3$.ɵp(1,'forOf',$r3$.ɵb(ctx.items)); } if (rf & 2) { $r3$.ɵp(1,"forOf",$r3$.ɵb(ctx.items)); }
function MyComponent__svg_g_Template_1(rf:IDENT,ctx0:IDENT) { function MyComponent__svg_g_Template_1(rf, ctx0) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵNS(); $r3$.ɵNS();
$r3$.ɵE(0,'g'); $r3$.ɵE(0,"g");
$r3$.ɵEe(1,'circle'); $r3$.ɵEe(1,"circle");
$r3$.ɵe(); $r3$.ɵe();
} }
} }
@ -1413,43 +1410,43 @@ describe('compiler compliance', () => {
// TODO(chuckj): Enforce this when the directives are specified // TODO(chuckj): Enforce this when the directives are specified
const ForDirectiveDefinition = ` const ForDirectiveDefinition = `
static ngDirectiveDef = $r3$.ɵdefineDirective({ ForOfDirective.ngDirectiveDef = $r3$.ɵdefineDirective({
type: ForOfDirective, type: ForOfDirective,
selectors: [['', 'forOf', '']], selectors: [["", "forOf", ""]],
factory: function ForOfDirective_Factory() { factory: function ForOfDirective_Factory() {
return new ForOfDirective($r3$.ɵinjectViewContainerRef(), $r3$.ɵinjectTemplateRef()); return new ForOfDirective($r3$.ɵinjectViewContainerRef(), $r3$.ɵinjectTemplateRef());
}, },
features: [$r3$.ɵNgOnChangesFeature], features: [$r3$.ɵNgOnChangesFeature],
inputs: {forOf: 'forOf'} inputs: {forOf: "forOf"}
}); });
`; `;
const MyComponentDefinition = ` const MyComponentDefinition = `
const $_c0$ = ['for','','forOf','']; const $_c0$ = ["for","","forOf",""];
static ngComponentDef = $r3$.ɵdefineComponent({ MyComponent.ngComponentDef = $r3$.ɵdefineComponent({
type: MyComponent, type: MyComponent,
selectors: [['my-component']], selectors: [["my-component"]],
factory: function MyComponent_Factory() { return new MyComponent(); }, factory: function MyComponent_Factory() { return new MyComponent(); },
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { template: function MyComponent_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'ul'); $r3$.ɵE(0, "ul");
$r3$.ɵC(1, MyComponent_li_Template_1, null, $_c0$); $r3$.ɵC(1, MyComponent_li_Template_1, null, $_c0$);
$r3$.ɵe(); $r3$.ɵe();
} }
if (rf & 2) { if (rf & 2) {
$r3$.ɵp(1, 'forOf', $r3$.ɵb(ctx.items)); $r3$.ɵp(1, "forOf", $r3$.ɵb(ctx.items));
} }
function MyComponent_li_Template_1(rf: IDENT, ctx0: IDENT) { function MyComponent_li_Template_1(rf, ctx0) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'li'); $r3$.ɵE(0, "li");
$r3$.ɵT(1); $r3$.ɵT(1);
$r3$.ɵe(); $r3$.ɵe();
} }
if (rf & 2) { if (rf & 2) {
const $item$ = ctx0.$implicit; const $item$ = ctx0.$implicit;
$r3$.ɵt(1, $r3$.ɵi1('', $item$.name, '')); $r3$.ɵt(1, $r3$.ɵi1("", $item$.name, ""));
} }
} }
}, },
@ -1503,49 +1500,49 @@ describe('compiler compliance', () => {
}; };
const MyComponentDefinition = ` const MyComponentDefinition = `
const $c1$ = ['for', '', 'forOf', '']; const $c1$ = ["for", "", "forOf", ""];
static ngComponentDef = $r3$.ɵdefineComponent({ MyComponent.ngComponentDef = $r3$.ɵdefineComponent({
type: MyComponent, type: MyComponent,
selectors: [['my-component']], selectors: [["my-component"]],
factory: function MyComponent_Factory() { return new MyComponent(); }, factory: function MyComponent_Factory() { return new MyComponent(); },
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { template: function MyComponent_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'ul'); $r3$.ɵE(0, "ul");
$r3$.ɵC(1, MyComponent_li_Template_1, null, $c1$); $r3$.ɵC(1, MyComponent_li_Template_1, null, $c1$);
$r3$.ɵe(); $r3$.ɵe();
} }
if (rf & 2) { if (rf & 2) {
$r3$.ɵp(1, 'forOf', $r3$.ɵb(ctx.items)); $r3$.ɵp(1, "forOf", $r3$.ɵb(ctx.items));
} }
function MyComponent_li_Template_1(rf: IDENT, ctx0: IDENT) { function MyComponent_li_Template_1(rf, ctx0) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'li'); $r3$.ɵE(0, "li");
$r3$.ɵE(1, 'div'); $r3$.ɵE(1, "div");
$r3$.ɵT(2); $r3$.ɵT(2);
$r3$.ɵe(); $r3$.ɵe();
$r3$.ɵE(3, 'ul'); $r3$.ɵE(3, "ul");
$r3$.ɵC(4, MyComponent_li_li_Template_4, null, $c1$); $r3$.ɵC(4, MyComponent_li_li_Template_4, null, $c1$);
$r3$.ɵe(); $r3$.ɵe();
$r3$.ɵe(); $r3$.ɵe();
} }
if (rf & 2) { if (rf & 2) {
const $item$ = ctx0.$implicit; const $item$ = ctx0.$implicit;
$r3$.ɵt(2, $r3$.ɵi1('', IDENT.name, '')); $r3$.ɵt(2, $r3$.ɵi1("", IDENT.name, ""));
$r3$.ɵp(4, 'forOf', $r3$.ɵb(IDENT.infos)); $r3$.ɵp(4, "forOf", $r3$.ɵb(IDENT.infos));
} }
function MyComponent_li_li_Template_4(rf: IDENT, ctx1: IDENT) { function MyComponent_li_li_Template_4(rf, ctx1) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'li'); $r3$.ɵE(0, "li");
$r3$.ɵT(1); $r3$.ɵT(1);
$r3$.ɵe(); $r3$.ɵe();
} }
if (rf & 2) { if (rf & 2) {
const $item$ = ctx0.$implicit; const $item$ = ctx0.$implicit;
const $info$ = ctx1.$implicit; const $info$ = ctx1.$implicit;
$r3$.ɵt(1, $r3$.ɵi2(' ', $item$.name, ': ', $info$.description, ' ')); $r3$.ɵt(1, $r3$.ɵi2(" ", $item$.name, ": ", $info$.description, " "));
} }
} }
} }

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {MockDirectory, setup} from '../aot/test_util'; import {MockDirectory, setup} from '@angular/compiler/test/aot/test_util';
import {compile, expectEmit} from './mock_compile'; import {compile, expectEmit} from './mock_compile';
describe('compiler compliance: bindings', () => { describe('compiler compliance: bindings', () => {
@ -37,14 +37,14 @@ describe('compiler compliance: bindings', () => {
}; };
const template = ` const template = `
template:function MyComponent_Template(rf: IDENT, $ctx$: IDENT){ template:function MyComponent_Template(rf, $ctx$){
if (rf & 1) { if (rf & 1) {
$i0$.ɵE(0, 'div'); $i0$.ɵE(0, "div");
$i0$.ɵT(1); $i0$.ɵT(1);
$i0$.ɵe(); $i0$.ɵe();
} }
if (rf & 2) { if (rf & 2) {
$i0$.ɵt(1, $i0$.ɵi1('Hello ', $ctx$.name, '')); $i0$.ɵt(1, $i0$.ɵi1("Hello ", $ctx$.name, ""));
} }
}`; }`;
const result = compile(files, angularFiles); const result = compile(files, angularFiles);
@ -73,12 +73,12 @@ describe('compiler compliance: bindings', () => {
}; };
const template = ` const template = `
template:function MyComponent_Template(rf: IDENT, $ctx$: IDENT){ template:function MyComponent_Template(rf, $ctx$){
if (rf & 1) { if (rf & 1) {
$i0$.ɵEe(0, 'a'); $i0$.ɵEe(0, "a");
} }
if (rf & 2) { if (rf & 2) {
$i0$.ɵp(0, 'title', $i0$.ɵb($ctx$.title)); $i0$.ɵp(0, "title", $i0$.ɵb($ctx$.title));
} }
}`; }`;
const result = compile(files, angularFiles); const result = compile(files, angularFiles);
@ -105,12 +105,12 @@ describe('compiler compliance: bindings', () => {
}; };
const template = ` const template = `
template:function MyComponent_Template(rf: IDENT, $ctx$: IDENT){ template:function MyComponent_Template(rf, $ctx$){
if (rf & 1) { if (rf & 1) {
$i0$.ɵEe(0, 'a'); $i0$.ɵEe(0, "a");
} }
if (rf & 2) { if (rf & 2) {
$i0$.ɵp(0, 'title', $i0$.ɵi1('Hello ', $ctx$.name, '')); $i0$.ɵp(0, "title", $i0$.ɵi1("Hello ", $ctx$.name, ""));
} }
}`; }`;
const result = compile(files, angularFiles); const result = compile(files, angularFiles);

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {MockDirectory, setup} from '../aot/test_util'; import {MockDirectory, setup} from '@angular/compiler/test/aot/test_util';
import {compile, expectEmit} from './mock_compile'; import {compile, expectEmit} from './mock_compile';
describe('compiler compliance: dependency injection', () => { describe('compiler compliance: dependency injection', () => {

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {setup} from '../aot/test_util'; import {MockDirectory, setup} from '@angular/compiler/test/aot/test_util';
import {compile, expectEmit} from './mock_compile'; import {compile, expectEmit} from './mock_compile';
const TRANSLATION_NAME_REGEXP = /^MSG_[A-Z0-9]+/; const TRANSLATION_NAME_REGEXP = /^MSG_[A-Z0-9]+/;
@ -43,15 +43,15 @@ describe('i18n support in the view compiler', () => {
}; };
const template = ` const template = `
const $msg_1$ = goog.getMsg('Hello world'); const $msg_1$ = goog.getMsg("Hello world");
const $msg_2$ = goog.getMsg('farewell'); const $msg_2$ = goog.getMsg("farewell");
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { template: function MyComponent_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵT(1, $msg_1$); $r3$.ɵT(1, $msg_1$);
$r3$.ɵT(3,'&'); $r3$.ɵT(3,"&");
$r3$.ɵT(5, $msg_2$); $r3$.ɵT(5, $msg_2$);
@ -92,18 +92,18 @@ describe('i18n support in the view compiler', () => {
/** /**
* @desc desc * @desc desc
*/ */
const $msg_1$ = goog.getMsg('introduction'); const $msg_1$ = goog.getMsg("introduction");
const $c1$ = ['title', $msg_1$]; const $c1$ = ["title", $msg_1$];
/** /**
* @desc desc * @desc desc
* @meaning meaning * @meaning meaning
*/ */
const $msg_2$ = goog.getMsg('Hello world'); const $msg_2$ = goog.getMsg("Hello world");
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { template: function MyComponent_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'div', $c1$); $r3$.ɵE(0, "div", $c1$);
$r3$.ɵT(1, $msg_2$); $r3$.ɵT(1, $msg_2$);
$r3$.ɵe(); $r3$.ɵe();
} }
@ -143,12 +143,12 @@ describe('i18n support in the view compiler', () => {
* @desc d * @desc d
* @meaning m * @meaning m
*/ */
const $msg_1$ = goog.getMsg('introduction'); const $msg_1$ = goog.getMsg("introduction");
const $c1$ = ['id', 'static', 'title', $msg_1$]; const $c1$ = ["id", "static", "title", $msg_1$];
template: function MyComponent_Template(rf: IDENT, ctx: IDENT) { template: function MyComponent_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵEe(0, 'div', $c1$); $r3$.ɵEe(0, "div", $c1$);
} }
} }
`; `;
@ -186,8 +186,8 @@ describe('i18n support in the view compiler', () => {
}; };
const template = ` const template = `
const $r1$ = {'b':[2], 'i':[4, 6]}; const $r1$ = {"b":[2], "i":[4, 6]};
const $r2$ = {'i':[13]}; const $r2$ = {"i":[13]};
`; `;
const result = compile(files, angularFiles); const result = compile(files, angularFiles);

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {MockDirectory, setup} from '../aot/test_util'; import {MockDirectory, setup} from '@angular/compiler/test/aot/test_util';
import {compile, expectEmit} from './mock_compile'; import {compile, expectEmit} from './mock_compile';
describe('compiler compliance: listen()', () => { describe('compiler compliance: listen()', () => {
@ -52,29 +52,29 @@ describe('compiler compliance: listen()', () => {
}; };
const componentDef = ` const componentDef = `
static ngComponentDef = IDENT.ɵdefineComponent({ MyComponent.ngComponentDef = IDENT.ɵdefineComponent({
inputs:{ inputs:{
componentInput: 'componentInput', componentInput: "componentInput",
originalComponentInput: 'renamedComponentInput' originalComponentInput: "renamedComponentInput"
}, },
outputs: { outputs: {
componentOutput: 'componentOutput', componentOutput: "componentOutput",
originalComponentOutput: 'renamedComponentOutput' originalComponentOutput: "renamedComponentOutput"
} }
});`; });`;
const directiveDef = ` const directiveDef = `
static ngDirectiveDef = IDENT.ɵdefineDirective({ MyDirective.ngDirectiveDef = IDENT.ɵdefineDirective({
inputs:{ inputs:{
directiveInput: 'directiveInput', directiveInput: "directiveInput",
originalDirectiveInput: 'renamedDirectiveInput' originalDirectiveInput: "renamedDirectiveInput"
}, },
outputs: { outputs: {
directiveOutput: 'directiveOutput', directiveOutput: "directiveOutput",
originalDirectiveOutput: 'renamedDirectiveOutput' originalDirectiveOutput: "renamedDirectiveOutput"
} }
});`; });`;

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {MockDirectory, setup} from '../aot/test_util'; import {MockDirectory, setup} from '@angular/compiler/test/aot/test_util';
import {compile, expectEmit} from './mock_compile'; import {compile, expectEmit} from './mock_compile';
/* These tests are codified version of the tests in compiler_canonical_spec.ts. Every /* These tests are codified version of the tests in compiler_canonical_spec.ts. Every
@ -41,10 +41,10 @@ describe('compiler compliance: listen()', () => {
// The template should look like this (where IDENT is a wild card for an identifier): // The template should look like this (where IDENT is a wild card for an identifier):
const template = ` const template = `
template: function MyComponent_Template(rf: $RenderFlags$, ctx: $MyComponent$) { template: function MyComponent_Template(rf, ctx) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'div'); $r3$.ɵE(0, "div");
$r3$.ɵL('click', function MyComponent_Template_div_click_listener($event: $any$) { $r3$.ɵL("click", function MyComponent_Template_div_click_listener($event) {
ctx.onClick($event); ctx.onClick($event);
return (1 == 2); return (1 == 2);
}); });

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {MockDirectory, setup} from '../aot/test_util'; import {MockDirectory, setup} from '@angular/compiler/test/aot/test_util';
import {compile, expectEmit} from './mock_compile'; import {compile, expectEmit} from './mock_compile';
describe('r3_view_compiler', () => { describe('r3_view_compiler', () => {
@ -114,9 +114,9 @@ describe('r3_view_compiler', () => {
} }
}; };
const bV_call = `$r3$.ɵiV([' ',ctx.list[0],' ',ctx.list[1],' ',ctx.list[2],' ',ctx.list[3], const bV_call = `$r3$.ɵiV([" ",ctx.list[0]," ",ctx.list[1]," ",ctx.list[2]," ",ctx.list[3],
' ',ctx.list[4],' ',ctx.list[5],' ',ctx.list[6],' ',ctx.list[7],' ',ctx.list[8], " ",ctx.list[4]," ",ctx.list[5]," ",ctx.list[6]," ",ctx.list[7]," ",ctx.list[8],
' '])`; " "])`;
const result = compile(files, angularFiles); const result = compile(files, angularFiles);
expectEmit(result.source, bV_call, 'Incorrect bV call'); expectEmit(result.source, bV_call, 'Incorrect bV call');
}); });

View File

@ -6,8 +6,8 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {InitialStylingFlags} from '../../src/core'; import {InitialStylingFlags} from '@angular/compiler/src/core';
import {MockDirectory, setup} from '../aot/test_util'; import {MockDirectory, setup} from '@angular/compiler/test/aot/test_util';
import {compile, expectEmit} from './mock_compile'; import {compile, expectEmit} from './mock_compile';
@ -40,9 +40,9 @@ describe('compiler compliance: styling', () => {
}; };
const template = ` const template = `
template: function MyComponent_Template(rf: $RenderFlags$, $ctx$: $MyComponent$) { template: function MyComponent_Template(rf, $ctx$) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'div'); $r3$.ɵE(0, "div");
$r3$.ɵs(); $r3$.ɵs();
$r3$.ɵe(); $r3$.ɵe();
} }
@ -85,17 +85,17 @@ describe('compiler compliance: styling', () => {
}; };
const template = ` const template = `
const _c0 = ['opacity','width','height',${InitialStylingFlags.VALUES_MODE},'opacity','1']; const _c0 = ["opacity","width","height",${InitialStylingFlags.VALUES_MODE},"opacity","1"];
class MyComponent {
static ngComponentDef = i0.ɵdefineComponent({ MyComponent.ngComponentDef = i0.ɵdefineComponent({
type: MyComponent, type: MyComponent,
selectors:[['my-component']], selectors:[["my-component"]],
factory:function MyComponent_Factory(){ factory:function MyComponent_Factory(){
return new MyComponent(); return new MyComponent();
}, },
template: function MyComponent_Template(rf: $RenderFlags$, $ctx$: $MyComponent$) { template: function MyComponent_Template(rf, $ctx$) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'div'); $r3$.ɵE(0, "div");
$r3$.ɵs(_c0); $r3$.ɵs(_c0);
$r3$.ɵe(); $r3$.ɵe();
} }
@ -104,7 +104,7 @@ describe('compiler compliance: styling', () => {
$r3$.ɵsp(0, 1, $ctx$.myWidth); $r3$.ɵsp(0, 1, $ctx$.myWidth);
$r3$.ɵsp(0, 2, $ctx$.myHeight); $r3$.ɵsp(0, 2, $ctx$.myHeight);
$r3$.ɵsa(0); $r3$.ɵsa(0);
$r3$.ɵa(0, 'style', $r3$.ɵb('border-width: 10px')); $r3$.ɵa(0, "style", $r3$.ɵb("border-width: 10px"));
} }
} }
}); });
@ -137,14 +137,14 @@ describe('compiler compliance: styling', () => {
}; };
const template = ` const template = `
template: function MyComponent_Template(rf: $RenderFlags$, $ctx$: $MyComponent$) { template: function MyComponent_Template(rf, $ctx$) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'div'); $r3$.ɵE(0, "div");
$r3$.ɵs(); $r3$.ɵs();
$r3$.ɵe(); $r3$.ɵe();
} }
if (rf & 2) { if (rf & 2) {
$r3$.ɵsm(0,(null as any),$ctx$.myClassExp); $r3$.ɵsm(0,null,$ctx$.myClassExp);
$r3$.ɵsa(0); $r3$.ɵsa(0);
} }
} }
@ -182,26 +182,26 @@ describe('compiler compliance: styling', () => {
}; };
const template = ` const template = `
const _c0 = ['grape','apple','orange',${InitialStylingFlags.VALUES_MODE},'grape',true]; const _c0 = ["grape","apple","orange",${InitialStylingFlags.VALUES_MODE},"grape",true];
class MyComponent {
static ngComponentDef = i0.ɵdefineComponent({ MyComponent.ngComponentDef = i0.ɵdefineComponent({
type: MyComponent, type: MyComponent,
selectors:[['my-component']], selectors:[["my-component"]],
factory:function MyComponent_Factory(){ factory:function MyComponent_Factory(){
return new MyComponent(); return new MyComponent();
}, },
template: function MyComponent_Template(rf: $RenderFlags$, $ctx$: $MyComponent$) { template: function MyComponent_Template(rf, $ctx$) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'div'); $r3$.ɵE(0, "div");
$r3$.ɵs((null as any), _c0); $r3$.ɵs(null, _c0);
$r3$.ɵe(); $r3$.ɵe();
} }
if (rf & 2) { if (rf & 2) {
$r3$.ɵsm(0, (null as any), $ctx$.myClassExp); $r3$.ɵsm(0, null, $ctx$.myClassExp);
$r3$.ɵcp(0, 1, $ctx$.yesToApple); $r3$.ɵcp(0, 1, $ctx$.yesToApple);
$r3$.ɵcp(0, 2, $ctx$.yesToOrange); $r3$.ɵcp(0, 2, $ctx$.yesToOrange);
$r3$.ɵsa(0); $r3$.ɵsa(0);
$r3$.ɵa(0, 'class', $r3$.ɵb('banana')); $r3$.ɵa(0, "class", $r3$.ɵb("banana"));
} }
} }
}); });
@ -234,24 +234,24 @@ describe('compiler compliance: styling', () => {
}; };
const template = ` const template = `
const _c0 = ['width',${InitialStylingFlags.VALUES_MODE},'width','100px']; const _c0 = ["width",${InitialStylingFlags.VALUES_MODE},"width","100px"];
const _c1 = ['foo',${InitialStylingFlags.VALUES_MODE},'foo',true]; const _c1 = ["foo",${InitialStylingFlags.VALUES_MODE},"foo",true];
class MyComponent {
static ngComponentDef = i0.ɵdefineComponent({ MyComponent.ngComponentDef = i0.ɵdefineComponent({
type: MyComponent, type: MyComponent,
selectors:[['my-component']], selectors:[["my-component"]],
factory:function MyComponent_Factory(){ factory:function MyComponent_Factory(){
return new MyComponent(); return new MyComponent();
}, },
template: function MyComponent_Template(rf: $RenderFlags$, $ctx$: $MyComponent$) { template: function MyComponent_Template(rf, $ctx$) {
if (rf & 1) { if (rf & 1) {
$r3$.ɵE(0, 'div'); $r3$.ɵE(0, "div");
$r3$.ɵs(_c0, _c1); $r3$.ɵs(_c0, _c1);
$r3$.ɵe(); $r3$.ɵe();
} }
if (rf & 2) { if (rf & 2) {
$r3$.ɵa(0, 'class', $r3$.ɵb('round')); $r3$.ɵa(0, "class", $r3$.ɵb("round"));
$r3$.ɵa(0, 'style', $r3$.ɵb('height:100px')); $r3$.ɵa(0, "style", $r3$.ɵb("height:100px"));
} }
} }
}); });

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {MockDirectory, setup} from '../aot/test_util'; import {MockDirectory, setup} from '@angular/compiler/test/aot/test_util';
import {compile, expectEmit} from './mock_compile'; import {compile, expectEmit} from './mock_compile';
describe('compiler compliance: template', () => { describe('compiler compliance: template', () => {
@ -51,39 +51,39 @@ describe('compiler compliance: template', () => {
// The template should look like this (where IDENT is a wild card for an identifier): // The template should look like this (where IDENT is a wild card for an identifier):
const template = ` const template = `
const $c0$ = ['ngFor','','ngForOf','']; const $c0$ = ["ngFor","","ngForOf",""];
// ... // ...
template:function MyComponent_Template(rf: IDENT, $ctx$: IDENT){ template:function MyComponent_Template(rf, $ctx$){
if (rf & 1) { if (rf & 1) {
$i0$.ɵC(0, MyComponent_ul_Template_0, null, _c0); $i0$.ɵC(0, MyComponent_ul_Template_0, null, _c0);
} }
if (rf & 2) { if (rf & 2) {
$i0$.ɵp(0, 'ngForOf', $i0$.ɵb($ctx$.items)); $i0$.ɵp(0, "ngForOf", $i0$.ɵb($ctx$.items));
} }
function MyComponent_ul_Template_0(rf: IDENT, $ctx0$: IDENT) { function MyComponent_ul_Template_0(rf, $ctx0$) {
if (rf & 1) { if (rf & 1) {
$i0$.ɵE(0, 'ul'); $i0$.ɵE(0, "ul");
$i0$.ɵC(1, MyComponent_ul_li_Template_1, null, _c0); $i0$.ɵC(1, MyComponent_ul_li_Template_1, null, _c0);
$i0$.ɵe(); $i0$.ɵe();
} }
if (rf & 2) { if (rf & 2) {
const $outer$ = $ctx0$.$implicit; const $outer$ = $ctx0$.$implicit;
$i0$.ɵp(1, 'ngForOf', $i0$.ɵb($outer$.items)); $i0$.ɵp(1, "ngForOf", $i0$.ɵb($outer$.items));
} }
function MyComponent_ul_li_Template_1(rf: IDENT, $ctx1$: IDENT) { function MyComponent_ul_li_Template_1(rf, $ctx1$) {
if (rf & 1) { if (rf & 1) {
$i0$.ɵE(0, 'li'); $i0$.ɵE(0, "li");
$i0$.ɵC(1, MyComponent_ul_li_div_Template_1, null, _c0); $i0$.ɵC(1, MyComponent_ul_li_div_Template_1, null, _c0);
$i0$.ɵe(); $i0$.ɵe();
} }
if (rf & 2) { if (rf & 2) {
$i0$.ɵp(1, 'ngForOf', $i0$.ɵb($ctx$.items)); $i0$.ɵp(1, "ngForOf", $i0$.ɵb($ctx$.items));
} }
function MyComponent_ul_li_div_Template_1(rf: IDENT, $ctx2$: IDENT) { function MyComponent_ul_li_div_Template_1(rf, $ctx2$) {
if (rf & 1) { if (rf & 1) {
$i0$.ɵE(0, 'div'); $i0$.ɵE(0, "div");
$i0$.ɵL('click', function MyComponent_ul_li_div_Template_1_div_click_listener($event:any){ $i0$.ɵL("click", function MyComponent_ul_li_div_Template_1_div_click_listener($event){
const $outer$ = $ctx0$.$implicit; const $outer$ = $ctx0$.$implicit;
const $middle$ = $ctx1$.$implicit; const $middle$ = $ctx1$.$implicit;
const $inner$ = $ctx2$.$implicit; const $inner$ = $ctx2$.$implicit;
@ -96,8 +96,8 @@ describe('compiler compliance: template', () => {
const $outer$ = $ctx0$.$implicit; const $outer$ = $ctx0$.$implicit;
const $middle$ = $ctx1$.$implicit; const $middle$ = $ctx1$.$implicit;
const $inner$ = $ctx2$.$implicit; const $inner$ = $ctx2$.$implicit;
$i0$.ɵp(0, 'title', $i0$.ɵb(ctx.format($outer$, $middle$, $inner$, $ctx$.component))); $i0$.ɵp(0, "title", $i0$.ɵb(ctx.format($outer$, $middle$, $inner$, $ctx$.component)));
$i0$.ɵt(1, $i0$.ɵi1(' ', ctx.format($outer$, $middle$, $inner$, $ctx$.component), ' ')); $i0$.ɵt(1, $i0$.ɵi1(" ", ctx.format($outer$, $middle$, $inner$, $ctx$.component), " "));
} }
} }
} }

View File

@ -20,10 +20,6 @@ ts_library(
jasmine_node_test( jasmine_node_test(
name = "test", name = "test",
bootstrap = ["angular/tools/testing/init_node_spec.js"], bootstrap = ["angular/tools/testing/init_node_spec.js"],
data = [
"//packages/common:npm_package",
"//packages/core:npm_package",
],
deps = [ deps = [
":test_lib", ":test_lib",
"//tools/testing:node", "//tools/testing:node",

View File

@ -1,329 +0,0 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {AotCompilerOptions, AotSummaryResolver, CompileMetadataResolver, CompilerConfig, DEFAULT_INTERPOLATION_CONFIG, DirectiveNormalizer, DirectiveResolver, DomElementSchemaRegistry, HtmlParser, Lexer, NgModuleResolver, ParseError, Parser, PipeResolver, StaticReflector, StaticSymbol, StaticSymbolCache, StaticSymbolResolver, TemplateParser, TypeScriptEmitter, analyzeNgModules, createAotUrlResolver} from '@angular/compiler';
import {ViewEncapsulation} from '@angular/core';
import * as ts from 'typescript';
import {NgAnalyzedModules} from '../../src/aot/compiler';
import {ConstantPool} from '../../src/constant_pool';
import * as html from '../../src/ml_parser/ast';
import {removeWhitespaces} from '../../src/ml_parser/html_whitespaces';
import * as o from '../../src/output/output_ast';
import {compilePipeFromRender2} from '../../src/render3/r3_pipe_compiler';
import {htmlAstToRender3Ast} from '../../src/render3/r3_template_transform';
import {compileComponentFromRender2, compileDirectiveFromRender2} from '../../src/render3/view/compiler';
import {BindingParser} from '../../src/template_parser/binding_parser';
import {OutputContext, escapeRegExp} from '../../src/util';
import {MockAotCompilerHost, MockCompilerHost, MockData, MockDirectory, arrayToMockDir, expectNoDiagnostics, settings, toMockFileArray} from '../aot/test_util';
const IDENTIFIER = /[A-Za-z_$ɵ][A-Za-z0-9_$]*/;
const OPERATOR =
/!|%|\*|\/|\^|&&?|\|\|?|\(|\)|\{|\}|\[|\]|:|;|<=?|>=?|={1,3}|!==?|=>|\+\+?|--?|@|,|\.|\.\.\./;
const STRING = /'[^']*'|"[^"]*"|`[\s\S]*?`/;
const NUMBER = /\d+/;
const ELLIPSIS = '…';
const TOKEN = new RegExp(
`\\s*((${IDENTIFIER.source})|(${OPERATOR.source})|(${STRING.source})|${NUMBER.source}|${ELLIPSIS})`,
'y');
type Piece = string | RegExp;
const SKIP = /(?:.|\n|\r)*/;
const ERROR_CONTEXT_WIDTH = 30;
// Transform the expected output to set of tokens
function tokenize(text: string): Piece[] {
TOKEN.lastIndex = 0;
let match: RegExpMatchArray|null;
const pieces: Piece[] = [];
while ((match = TOKEN.exec(text)) !== null) {
const token = match[1];
if (token === 'IDENT') {
pieces.push(IDENTIFIER);
} else if (token === ELLIPSIS) {
pieces.push(SKIP);
} else {
pieces.push(token);
}
}
if (pieces.length === 0 || TOKEN.lastIndex !== 0) {
const from = TOKEN.lastIndex;
const to = from + ERROR_CONTEXT_WIDTH;
throw Error(`Invalid test, no token found for '${text.substr(from, to)}...'`);
}
return pieces;
}
export function expectEmit(
source: string, expected: string, description: string,
assertIdentifiers?: {[name: string]: RegExp}) {
// turns `// ...` into `…`
// remove `// TODO` comment lines
expected = expected.replace(/\/\/\s*\.\.\./g, ELLIPSIS).replace(/\/\/\s*TODO.*?\n/g, '');
const pieces = tokenize(expected);
const {regexp, groups} = buildMatcher(pieces);
const matches = source.match(regexp);
if (matches === null) {
let last: number = 0;
for (let i = 1; i < pieces.length; i++) {
const {regexp} = buildMatcher(pieces.slice(0, i));
const m = source.match(regexp);
const expectedPiece = pieces[i - 1] == IDENTIFIER ? '<IDENT>' : pieces[i - 1];
if (!m) {
fail(
`${description}: Expected to find ${expectedPiece} '${source.substr(0,last)}[<---HERE expected "${expectedPiece}"]${source.substr(last)}'`);
return;
} else {
last = (m.index || 0) + m[0].length;
}
}
fail(
`Test helper failure: Expected expression failed but the reporting logic could not find where it failed in: ${source}`);
} else {
if (assertIdentifiers) {
// It might be possible to add the constraints in the original regexp (see `buildMatcher`)
// by transforming the assertion regexps when using anchoring, grouping, back references,
// flags, ...
//
// Checking identifiers after they have matched allows for a simple and flexible
// implementation.
// The overall performance are not impacted when `assertIdentifiers` is empty.
const ids = Object.keys(assertIdentifiers);
for (let i = 0; i < ids.length; i++) {
const id = ids[i];
if (groups.has(id)) {
const name = matches[groups.get(id) as number];
const regexp = assertIdentifiers[id];
if (!regexp.test(name)) {
throw Error(
`${description}: The matching identifier "${id}" is "${name}" which doesn't match ${regexp}`);
}
}
}
}
}
}
const IDENT_LIKE = /^[a-z][A-Z]/;
const MATCHING_IDENT = /^\$.*\$$/;
/*
* Builds a regexp that matches the given `pieces`
*
* It returns:
* - the `regexp` to be used to match the generated code,
* - the `groups` which maps `$...$` identifier to their position in the regexp matches.
*/
function buildMatcher(pieces: (string | RegExp)[]): {regexp: RegExp, groups: Map<string, number>} {
const results: string[] = [];
let first = true;
let group = 0;
const groups = new Map<string, number>();
for (const piece of pieces) {
if (!first)
results.push(`\\s${typeof piece === 'string' && IDENT_LIKE.test(piece) ? '+' : '*'}`);
first = false;
if (typeof piece === 'string') {
if (MATCHING_IDENT.test(piece)) {
const matchGroup = groups.get(piece);
if (!matchGroup) {
results.push('(' + IDENTIFIER.source + ')');
const newGroup = ++group;
groups.set(piece, newGroup);
} else {
results.push(`\\${matchGroup}`);
}
} else {
results.push(escapeRegExp(piece));
}
} else {
results.push('(?:' + piece.source + ')');
}
}
return {
regexp: new RegExp(results.join('')),
groups,
};
}
function doCompile(
data: MockDirectory, angularFiles: MockData, options: AotCompilerOptions = {},
errorCollector: (error: any, fileName?: string) => void = error => { throw error; },
compileAction: (
outputCtx: OutputContext, analyzedModules: NgAnalyzedModules,
resolver: CompileMetadataResolver, htmlParser: HtmlParser, templateParser: TemplateParser,
hostBindingParser: BindingParser, reflector: StaticReflector) => void) {
const testFiles = toMockFileArray(data);
const scripts = testFiles.map(entry => entry.fileName);
const angularFilesArray = toMockFileArray(angularFiles);
const files = arrayToMockDir([...testFiles, ...angularFilesArray]);
const mockCompilerHost = new MockCompilerHost(scripts, files);
const compilerHost = new MockAotCompilerHost(mockCompilerHost);
const program = ts.createProgram(scripts, {...settings}, mockCompilerHost);
expectNoDiagnostics(program);
// TODO(chuckj): Replace with a variant of createAotCompiler() when the r3_view_compiler is
// integrated
const urlResolver = createAotUrlResolver(compilerHost);
const symbolCache = new StaticSymbolCache();
const summaryResolver = new AotSummaryResolver(compilerHost, symbolCache);
const symbolResolver = new StaticSymbolResolver(compilerHost, symbolCache, summaryResolver);
const staticReflector =
new StaticReflector(summaryResolver, symbolResolver, [], [], errorCollector);
const htmlParser = new HtmlParser();
const config = new CompilerConfig({
defaultEncapsulation: ViewEncapsulation.Emulated,
useJit: false,
missingTranslation: options.missingTranslation,
preserveWhitespaces: options.preserveWhitespaces,
strictInjectionParameters: options.strictInjectionParameters,
});
const normalizer = new DirectiveNormalizer(
{get: (url: string) => compilerHost.loadResource(url)}, urlResolver, htmlParser, config);
const expressionParser = new Parser(new Lexer());
const elementSchemaRegistry = new DomElementSchemaRegistry();
const templateParser = new TemplateParser(
config, staticReflector, expressionParser, elementSchemaRegistry, htmlParser, console, []);
const resolver = new CompileMetadataResolver(
config, htmlParser, new NgModuleResolver(staticReflector),
new DirectiveResolver(staticReflector), new PipeResolver(staticReflector), summaryResolver,
elementSchemaRegistry, normalizer, console, symbolCache, staticReflector, errorCollector);
// Create the TypeScript program
const sourceFiles = program.getSourceFiles().map(sf => sf.fileName);
// Analyze the modules
// TODO(chuckj): Eventually this should not be necessary as the ts.SourceFile should be sufficient
// to generate a template definition.
const analyzedModules = analyzeNgModules(sourceFiles, compilerHost, symbolResolver, resolver);
const pipesOrDirectives = Array.from(analyzedModules.ngModuleByPipeOrDirective.keys());
const fakeOutputContext: OutputContext = {
genFilePath: 'fakeFactory.ts',
statements: [],
importExpr(symbol: StaticSymbol, typeParams: o.Type[]) {
if (!(symbol instanceof StaticSymbol)) {
if (!symbol) {
throw new Error('Invalid: undefined passed to as a symbol');
}
throw new Error(`Invalid: ${(symbol as any).constructor.name} is not a symbol`);
}
return (symbol.members || [])
.reduce(
(expr, member) => expr.prop(member),
<o.Expression>o.importExpr(new o.ExternalReference(symbol.filePath, symbol.name)));
},
constantPool: new ConstantPool()
};
const errors: ParseError[] = [];
const hostBindingParser = new BindingParser(
expressionParser, DEFAULT_INTERPOLATION_CONFIG, elementSchemaRegistry, null, errors);
// Load all directives and pipes
for (const pipeOrDirective of pipesOrDirectives) {
const module = analyzedModules.ngModuleByPipeOrDirective.get(pipeOrDirective) !;
resolver.loadNgModuleDirectiveAndPipeMetadata(module.type.reference, true);
}
compileAction(
fakeOutputContext, analyzedModules, resolver, htmlParser, templateParser, hostBindingParser,
staticReflector);
fakeOutputContext.statements.unshift(...fakeOutputContext.constantPool.statements);
const emitter = new TypeScriptEmitter();
const result = emitter.emitStatementsAndContext(
fakeOutputContext.genFilePath, fakeOutputContext.statements, '', false,
/* referenceFilter */ undefined,
/* importFilter */ e => e.moduleName != null && e.moduleName.startsWith('/app'));
if (errors.length) {
throw new Error('Unexpected errors:' + errors.map(e => e.toString()).join(', '));
}
return {source: result.sourceText, outputContext: fakeOutputContext};
}
export function compile(
data: MockDirectory, angularFiles: MockData, options: AotCompilerOptions = {},
errorCollector: (error: any, fileName?: string) => void = error => { throw error;}) {
return doCompile(
data, angularFiles, options, errorCollector,
(outputCtx: OutputContext, analyzedModules: NgAnalyzedModules,
resolver: CompileMetadataResolver, htmlParser: HtmlParser, templateParser: TemplateParser,
hostBindingParser: BindingParser, reflector: StaticReflector) => {
const pipesOrDirectives = Array.from(analyzedModules.ngModuleByPipeOrDirective.keys());
for (const pipeOrDirective of pipesOrDirectives) {
const module = analyzedModules.ngModuleByPipeOrDirective.get(pipeOrDirective);
if (!module || !module.type.reference.filePath.startsWith('/app')) {
continue;
}
if (resolver.isDirective(pipeOrDirective)) {
const directive = resolver.getDirectiveMetadata(pipeOrDirective);
if (directive.isComponent) {
const fakeUrl = 'ng://fake-template-url.html';
let htmlAst = htmlParser.parse(directive.template !.template !, fakeUrl);
// Map of StaticType by directive selectors
const directiveTypeBySel = new Map<string, any>();
const directives = module.transitiveModule.directives.map(
dir => resolver.getDirectiveSummary(dir.reference));
directives.forEach(directive => {
if (directive.selector) {
directiveTypeBySel.set(directive.selector, directive.type.reference);
}
});
// Map of StaticType by pipe names
const pipeTypeByName = new Map<string, any>();
const pipes = module.transitiveModule.pipes.map(
pipe => resolver.getPipeSummary(pipe.reference));
pipes.forEach(pipe => { pipeTypeByName.set(pipe.name, pipe.type.reference); });
const preserveWhitespaces = directive.template !.preserveWhitespaces;
if (!preserveWhitespaces) {
htmlAst = removeWhitespaces(htmlAst);
}
const render3Ast = htmlAstToRender3Ast(htmlAst.rootNodes, hostBindingParser);
compileComponentFromRender2(
outputCtx, directive, render3Ast, reflector, hostBindingParser,
directiveTypeBySel, pipeTypeByName);
} else {
compileDirectiveFromRender2(outputCtx, directive, reflector, hostBindingParser);
}
} else if (resolver.isPipe(pipeOrDirective)) {
const metadata = resolver.getPipeMetadata(pipeOrDirective);
if (metadata) {
compilePipeFromRender2(outputCtx, metadata, reflector);
}
}
}
});
}

View File

@ -58,6 +58,7 @@ const specFiles =
'@angular/_testing_init/**', '@angular/_testing_init/**',
'@angular/compiler/test/aot/**', '@angular/compiler/test/aot/**',
'@angular/compiler/test/render3/**', '@angular/compiler/test/render3/**',
'@angular/compiler-cli/test/compliance/**',
'@angular/core/test/bundling/**', '@angular/core/test/bundling/**',
'@angular/core/test/fake_async_spec.*', '@angular/core/test/fake_async_spec.*',
'@angular/core/test/render3/**', '@angular/core/test/render3/**',