refactor: move angular source to /packages rather than modules/@angular
This commit is contained in:
16
packages/compiler-cli/integrationtest/test/all_spec.ts
Normal file
16
packages/compiler-cli/integrationtest/test/all_spec.ts
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* @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 './init';
|
||||
import './animate_spec';
|
||||
import './basic_spec';
|
||||
import './entry_components_spec';
|
||||
import './i18n_spec';
|
||||
import './ng_module_spec';
|
||||
import './projection_spec';
|
||||
import './query_spec';
|
72
packages/compiler-cli/integrationtest/test/animate_spec.ts
Normal file
72
packages/compiler-cli/integrationtest/test/animate_spec.ts
Normal file
@ -0,0 +1,72 @@
|
||||
/**
|
||||
* @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 './init';
|
||||
import {DebugElement} from '@angular/core';
|
||||
import {AnimateCmp} from '../src/animate';
|
||||
import {createComponent} from './util';
|
||||
|
||||
// TODO(matsko): make this green again...
|
||||
xdescribe('template codegen output', () => {
|
||||
function findTargetElement(elm: DebugElement): DebugElement {
|
||||
// the open-close-container is a child of the main container
|
||||
// if the template changes then please update the location below
|
||||
return elm.children[4];
|
||||
}
|
||||
|
||||
it('should apply the animate states to the element', (done) => {
|
||||
const compFixture = createComponent(AnimateCmp);
|
||||
const debugElement = compFixture.debugElement;
|
||||
|
||||
const targetDebugElement = findTargetElement(<DebugElement>debugElement);
|
||||
|
||||
compFixture.componentInstance.setAsOpen();
|
||||
compFixture.detectChanges();
|
||||
|
||||
setTimeout(() => {
|
||||
expect(targetDebugElement.styles['height']).toEqual(null);
|
||||
expect(targetDebugElement.styles['borderColor']).toEqual('green');
|
||||
expect(targetDebugElement.styles['color']).toEqual('green');
|
||||
|
||||
compFixture.componentInstance.setAsClosed();
|
||||
compFixture.detectChanges();
|
||||
|
||||
setTimeout(() => {
|
||||
expect(targetDebugElement.styles['height']).toEqual('0px');
|
||||
expect(targetDebugElement.styles['borderColor']).toEqual('maroon');
|
||||
expect(targetDebugElement.styles['color']).toEqual('maroon');
|
||||
done();
|
||||
}, 0);
|
||||
}, 0);
|
||||
});
|
||||
|
||||
it('should apply the default animate state to the element', (done) => {
|
||||
const compFixture = createComponent(AnimateCmp);
|
||||
const debugElement = compFixture.debugElement;
|
||||
|
||||
const targetDebugElement = findTargetElement(<DebugElement>debugElement);
|
||||
|
||||
compFixture.componentInstance.setAsSomethingElse();
|
||||
compFixture.detectChanges();
|
||||
|
||||
setTimeout(() => {
|
||||
expect(targetDebugElement.styles['height']).toEqual(null);
|
||||
expect(targetDebugElement.styles['borderColor']).toEqual('black');
|
||||
expect(targetDebugElement.styles['color']).toEqual('black');
|
||||
|
||||
compFixture.componentInstance.setAsClosed();
|
||||
compFixture.detectChanges();
|
||||
|
||||
setTimeout(() => {
|
||||
expect(targetDebugElement.styles['height']).not.toEqual(null);
|
||||
expect(targetDebugElement.styles['borderColor']).not.toEqual('grey');
|
||||
expect(targetDebugElement.styles['color']).not.toEqual('grey');
|
||||
done();
|
||||
}, 0);
|
||||
}, 0);
|
||||
});
|
||||
});
|
92
packages/compiler-cli/integrationtest/test/basic_spec.ts
Normal file
92
packages/compiler-cli/integrationtest/test/basic_spec.ts
Normal file
@ -0,0 +1,92 @@
|
||||
/**
|
||||
* @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 './init';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
import {MultipleComponentsMyComp} from '../src/a/multiple_components';
|
||||
import {BasicComp} from '../src/basic';
|
||||
import {createComponent} from './util';
|
||||
|
||||
describe('template codegen output', () => {
|
||||
const outDir = 'src';
|
||||
|
||||
it('should lower Decorators without reflect-metadata', () => {
|
||||
const jsOutput = path.join(outDir, 'basic.js');
|
||||
expect(fs.existsSync(jsOutput)).toBeTruthy();
|
||||
expect(fs.readFileSync(jsOutput, {encoding: 'utf-8'})).not.toContain('Reflect.decorate');
|
||||
});
|
||||
|
||||
it('should produce metadata.json outputs', () => {
|
||||
const metadataOutput = path.join(outDir, 'basic.metadata.json');
|
||||
expect(fs.existsSync(metadataOutput)).toBeTruthy();
|
||||
const output = fs.readFileSync(metadataOutput, {encoding: 'utf-8'});
|
||||
expect(output).toContain('"decorators":');
|
||||
expect(output).toContain('"module":"@angular/core","name":"Component"');
|
||||
});
|
||||
|
||||
it('should write .d.ts files', () => {
|
||||
const dtsOutput = path.join(outDir, 'basic.d.ts');
|
||||
expect(fs.existsSync(dtsOutput)).toBeTruthy();
|
||||
expect(fs.readFileSync(dtsOutput, {encoding: 'utf-8'})).toContain('Basic');
|
||||
});
|
||||
|
||||
it('should write .ngfactory.ts for .d.ts inputs', () => {
|
||||
const factoryOutput =
|
||||
path.join('node_modules', '@angular2-material', 'button', 'button.ngfactory.ts');
|
||||
expect(fs.existsSync(factoryOutput)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should be able to create the basic component', () => {
|
||||
const compFixture = createComponent(BasicComp);
|
||||
expect(compFixture.componentInstance).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should support ngIf', () => {
|
||||
const compFixture = createComponent(BasicComp);
|
||||
const debugElement = compFixture.debugElement;
|
||||
expect(debugElement.children.length).toBe(3);
|
||||
|
||||
compFixture.componentInstance.ctxBool = true;
|
||||
compFixture.detectChanges();
|
||||
expect(debugElement.children.length).toBe(4);
|
||||
expect(debugElement.children[2].injector.get(MultipleComponentsMyComp)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should support ngFor', () => {
|
||||
const compFixture = createComponent(BasicComp);
|
||||
const debugElement = compFixture.debugElement;
|
||||
expect(debugElement.children.length).toBe(3);
|
||||
|
||||
// test NgFor
|
||||
compFixture.componentInstance.ctxArr = [1, 2];
|
||||
compFixture.detectChanges();
|
||||
expect(debugElement.children.length).toBe(5);
|
||||
expect(debugElement.children[2].attributes['value']).toBe('1');
|
||||
expect(debugElement.children[3].attributes['value']).toBe('2');
|
||||
});
|
||||
|
||||
describe('i18n', () => {
|
||||
it('should inject the locale into the component', () => {
|
||||
const compFixture = createComponent(BasicComp);
|
||||
expect(compFixture.componentInstance.localeId).toEqual('fi');
|
||||
});
|
||||
|
||||
it('should inject the translations format into the component', () => {
|
||||
const compFixture = createComponent(BasicComp);
|
||||
expect(compFixture.componentInstance.translationsFormat).toEqual('xlf');
|
||||
});
|
||||
|
||||
it('should support i18n for content tags', () => {
|
||||
const containerElement = createComponent(BasicComp).nativeElement;
|
||||
const pElement = containerElement.children.find((c: any) => c.name == 'p');
|
||||
const pText = pElement.children.map((c: any) => c.data).join('').trim();
|
||||
expect(pText).toBe('tervetuloa');
|
||||
});
|
||||
});
|
||||
});
|
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* @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 './init';
|
||||
|
||||
import {BasicComp} from '../src/basic';
|
||||
import {CompWithAnalyzeEntryComponentsProvider, CompWithEntryComponents} from '../src/entry_components';
|
||||
|
||||
import {createComponent} from './util';
|
||||
|
||||
describe('content projection', () => {
|
||||
it('should support entryComponents in components', () => {
|
||||
const compFixture = createComponent(CompWithEntryComponents);
|
||||
const cf = compFixture.componentInstance.cfr.resolveComponentFactory(BasicComp);
|
||||
expect(cf.componentType).toBe(BasicComp);
|
||||
});
|
||||
|
||||
it('should support entryComponents via the ANALYZE_FOR_ENTRY_COMPONENTS provider and function providers in components',
|
||||
() => {
|
||||
const compFixture = createComponent(CompWithAnalyzeEntryComponentsProvider);
|
||||
const cf = compFixture.componentInstance.cfr.resolveComponentFactory(BasicComp);
|
||||
expect(cf.componentType).toBe(BasicComp);
|
||||
// check that the function call that created the provider for ANALYZE_FOR_ENTRY_COMPONENTS
|
||||
// worked.
|
||||
expect(compFixture.componentInstance.providedValue).toEqual([
|
||||
{a: 'b', component: BasicComp}
|
||||
]);
|
||||
});
|
||||
});
|
88
packages/compiler-cli/integrationtest/test/i18n_spec.ts
Normal file
88
packages/compiler-cli/integrationtest/test/i18n_spec.ts
Normal file
@ -0,0 +1,88 @@
|
||||
/**
|
||||
* @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 './init';
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
const EXPECTED_XMB = `<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE messagebundle [
|
||||
<!ELEMENT messagebundle (msg)*>
|
||||
<!ATTLIST messagebundle class CDATA #IMPLIED>
|
||||
|
||||
<!ELEMENT msg (#PCDATA|ph|source)*>
|
||||
<!ATTLIST msg id CDATA #IMPLIED>
|
||||
<!ATTLIST msg seq CDATA #IMPLIED>
|
||||
<!ATTLIST msg name CDATA #IMPLIED>
|
||||
<!ATTLIST msg desc CDATA #IMPLIED>
|
||||
<!ATTLIST msg meaning CDATA #IMPLIED>
|
||||
<!ATTLIST msg obsolete (obsolete) #IMPLIED>
|
||||
<!ATTLIST msg xml:space (default|preserve) "default">
|
||||
<!ATTLIST msg is_hidden CDATA #IMPLIED>
|
||||
|
||||
<!ELEMENT source (#PCDATA)>
|
||||
|
||||
<!ELEMENT ph (#PCDATA|ex)*>
|
||||
<!ATTLIST ph name CDATA #REQUIRED>
|
||||
|
||||
<!ELEMENT ex (#PCDATA)>
|
||||
]>
|
||||
<messagebundle>
|
||||
<msg id="8136548302122759730" desc="desc" meaning="meaning">translate me</msg>
|
||||
<msg id="3492007542396725315">Welcome</msg>
|
||||
<msg id="3772663375917578720">other-3rdP-component</msg>
|
||||
</messagebundle>
|
||||
`;
|
||||
|
||||
const EXPECTED_XLIFF = `<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<xliff version="1.2" xmlns="urn:oasis:names:tc:xliff:document:1.2">
|
||||
<file source-language="fr" datatype="plaintext" original="ng2.template">
|
||||
<body>
|
||||
<trans-unit id="76e1eccb1b772fa9f294ef9c146ea6d0efa8a2d4" datatype="html">
|
||||
<source>translate me</source>
|
||||
<target/>
|
||||
<note priority="1" from="description">desc</note>
|
||||
<note priority="1" from="meaning">meaning</note>
|
||||
</trans-unit>
|
||||
<trans-unit id="65cc4ab3b4c438e07c89be2b677d08369fb62da2" datatype="html">
|
||||
<source>Welcome</source>
|
||||
<target/>
|
||||
</trans-unit>
|
||||
<trans-unit id="63a85808f03b8181e36a952e0fa38202c2304862" datatype="html">
|
||||
<source>other-3rdP-component</source>
|
||||
<target/>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
`;
|
||||
|
||||
describe('template i18n extraction output', () => {
|
||||
const outDir = '';
|
||||
const genDir = 'out';
|
||||
|
||||
it('should extract i18n messages as xmb', () => {
|
||||
const xmbOutput = path.join(outDir, 'custom_file.xmb');
|
||||
expect(fs.existsSync(xmbOutput)).toBeTruthy();
|
||||
const xmb = fs.readFileSync(xmbOutput, {encoding: 'utf-8'});
|
||||
expect(xmb).toEqual(EXPECTED_XMB);
|
||||
});
|
||||
|
||||
it('should extract i18n messages as xliff', () => {
|
||||
const xlfOutput = path.join(outDir, 'messages.xlf');
|
||||
expect(fs.existsSync(xlfOutput)).toBeTruthy();
|
||||
const xlf = fs.readFileSync(xlfOutput, {encoding: 'utf-8'});
|
||||
expect(xlf).toEqual(EXPECTED_XLIFF);
|
||||
});
|
||||
|
||||
it('should not emit js', () => {
|
||||
const genOutput = path.join(genDir, '');
|
||||
expect(fs.existsSync(genOutput)).toBeFalsy();
|
||||
});
|
||||
});
|
17
packages/compiler-cli/integrationtest/test/init.ts
Normal file
17
packages/compiler-cli/integrationtest/test/init.ts
Normal file
@ -0,0 +1,17 @@
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
|
||||
// Only needed to satisfy the check in core/src/util/decorators.ts
|
||||
// TODO(alexeagle): maybe remove that check?
|
||||
require('reflect-metadata');
|
||||
|
||||
require('zone.js/dist/zone-node.js');
|
||||
require('zone.js/dist/long-stack-trace-zone.js');
|
||||
require('zone.js/dist/sync-test.js');
|
||||
require('zone.js/dist/proxy.js');
|
||||
require('zone.js/dist/jasmine-patch.js');
|
83
packages/compiler-cli/integrationtest/test/ng_module_spec.ts
Normal file
83
packages/compiler-cli/integrationtest/test/ng_module_spec.ts
Normal file
@ -0,0 +1,83 @@
|
||||
/**
|
||||
* @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 './init';
|
||||
|
||||
import {ComponentUsingThirdParty} from '../src/comp_using_3rdp';
|
||||
import {MainModule} from '../src/module';
|
||||
import {CompUsingLibModuleDirectiveAndPipe, CompUsingRootModuleDirectiveAndPipe, SOME_TOKEN, ServiceUsingLibModule, SomeLibModule, SomeService} from '../src/module_fixtures';
|
||||
|
||||
import {createComponent, createModule} from './util';
|
||||
|
||||
describe('NgModule', () => {
|
||||
it('should support providers', () => {
|
||||
const moduleRef = createModule();
|
||||
expect(moduleRef.instance instanceof MainModule).toEqual(true);
|
||||
expect(moduleRef.injector.get(MainModule) instanceof MainModule).toEqual(true);
|
||||
expect(moduleRef.injector.get(SomeService) instanceof SomeService).toEqual(true);
|
||||
});
|
||||
|
||||
it('should support entryComponents components', () => {
|
||||
const moduleRef = createModule();
|
||||
const cf = moduleRef.componentFactoryResolver.resolveComponentFactory(
|
||||
CompUsingRootModuleDirectiveAndPipe);
|
||||
expect(cf.componentType).toBe(CompUsingRootModuleDirectiveAndPipe);
|
||||
const compRef = cf.create(moduleRef.injector);
|
||||
expect(compRef.instance instanceof CompUsingRootModuleDirectiveAndPipe).toEqual(true);
|
||||
});
|
||||
|
||||
it('should support entryComponents via the ANALYZE_FOR_ENTRY_COMPONENTS provider and function providers in components',
|
||||
() => {
|
||||
const moduleRef = createModule();
|
||||
const cf = moduleRef.componentFactoryResolver.resolveComponentFactory(
|
||||
CompUsingRootModuleDirectiveAndPipe);
|
||||
expect(cf.componentType).toBe(CompUsingRootModuleDirectiveAndPipe);
|
||||
// check that the function call that created the provider for ANALYZE_FOR_ENTRY_COMPONENTS
|
||||
// worked.
|
||||
expect(moduleRef.injector.get(SOME_TOKEN)).toEqual([
|
||||
{a: 'b', component: CompUsingLibModuleDirectiveAndPipe}
|
||||
]);
|
||||
});
|
||||
|
||||
describe('third-party modules', () => {
|
||||
// https://github.com/angular/angular/issues/11889
|
||||
it('should support third party entryComponents components', () => {
|
||||
const fixture = createComponent(ComponentUsingThirdParty);
|
||||
const thirdPComps = fixture.nativeElement.children;
|
||||
expect(thirdPComps[0].children[0].children[0].data).toEqual('3rdP-component');
|
||||
expect(thirdPComps[1].children[0].children[0].data).toEqual('other-3rdP-component');
|
||||
});
|
||||
|
||||
// https://github.com/angular/angular/issues/12428
|
||||
it('should support third party directives', () => {
|
||||
const fixture = createComponent(ComponentUsingThirdParty);
|
||||
const debugElement = fixture.debugElement;
|
||||
fixture.detectChanges();
|
||||
expect(debugElement.children[0].properties['title']).toEqual('from 3rd party');
|
||||
});
|
||||
});
|
||||
|
||||
it('should support module directives and pipes', () => {
|
||||
const compFixture = createComponent(CompUsingRootModuleDirectiveAndPipe);
|
||||
compFixture.detectChanges();
|
||||
|
||||
const debugElement = compFixture.debugElement;
|
||||
expect(debugElement.children[0].properties['title']).toEqual('transformed someValue');
|
||||
});
|
||||
|
||||
it('should support module directives and pipes on lib modules', () => {
|
||||
const compFixture = createComponent(CompUsingLibModuleDirectiveAndPipe);
|
||||
compFixture.detectChanges();
|
||||
|
||||
const debugElement = compFixture.debugElement;
|
||||
expect(debugElement.children[0].properties['title']).toEqual('transformed someValue');
|
||||
|
||||
expect(debugElement.injector.get(SomeLibModule) instanceof SomeLibModule).toEqual(true);
|
||||
expect(debugElement.injector.get(ServiceUsingLibModule) instanceof ServiceUsingLibModule)
|
||||
.toEqual(true);
|
||||
});
|
||||
});
|
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* @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 './init';
|
||||
import {By} from '@angular/platform-browser';
|
||||
import {CompWithNgContent, ProjectingComp} from '../src/projection';
|
||||
import {createComponent} from './util';
|
||||
|
||||
describe('content projection', () => {
|
||||
it('should support basic content projection', () => {
|
||||
const mainCompFixture = createComponent(ProjectingComp);
|
||||
|
||||
const debugElement = mainCompFixture.debugElement;
|
||||
const compWithProjection = debugElement.query(By.directive(CompWithNgContent));
|
||||
expect(compWithProjection.children.length).toBe(1);
|
||||
expect(compWithProjection.children[0].attributes['greeting']).toEqual('Hello world!');
|
||||
});
|
||||
});
|
35
packages/compiler-cli/integrationtest/test/query_spec.ts
Normal file
35
packages/compiler-cli/integrationtest/test/query_spec.ts
Normal file
@ -0,0 +1,35 @@
|
||||
/**
|
||||
* @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 './init';
|
||||
import {DebugElement, QueryList} from '@angular/core';
|
||||
import {By} from '@angular/platform-browser';
|
||||
import {CompForChildQuery, CompWithChildQuery} from '../src/queries';
|
||||
import {createComponent} from './util';
|
||||
|
||||
describe('child queries', () => {
|
||||
it('should support compiling child queries', () => {
|
||||
const childQueryCompFixture = createComponent(CompWithChildQuery);
|
||||
const debugElement = childQueryCompFixture.debugElement;
|
||||
const compWithChildren = debugElement.query(By.directive(CompWithChildQuery));
|
||||
expect(childQueryCompFixture.componentInstance.child).toBeDefined();
|
||||
expect(childQueryCompFixture.componentInstance.child instanceof CompForChildQuery).toBe(true);
|
||||
|
||||
});
|
||||
|
||||
it('should support compiling children queries', () => {
|
||||
const childQueryCompFixture = createComponent(CompWithChildQuery);
|
||||
const debugElement = childQueryCompFixture.debugElement;
|
||||
const compWithChildren = debugElement.query(By.directive(CompWithChildQuery));
|
||||
|
||||
childQueryCompFixture.detectChanges();
|
||||
|
||||
expect(childQueryCompFixture.componentInstance.children).toBeDefined();
|
||||
expect(childQueryCompFixture.componentInstance.children instanceof QueryList).toBe(true);
|
||||
});
|
||||
});
|
219
packages/compiler-cli/integrationtest/test/test_ngtools_api.ts
Normal file
219
packages/compiler-cli/integrationtest/test/test_ngtools_api.ts
Normal file
@ -0,0 +1,219 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
/* tslint:disable:no-console */
|
||||
|
||||
// Must be imported first, because angular2 decorators throws on load.
|
||||
import 'reflect-metadata';
|
||||
|
||||
import * as path from 'path';
|
||||
import * as ts from 'typescript';
|
||||
import * as assert from 'assert';
|
||||
import {tsc} from '@angular/tsc-wrapped/src/tsc';
|
||||
import {AngularCompilerOptions, CodeGenerator, CompilerHostContext, NodeCompilerHostContext, __NGTOOLS_PRIVATE_API_2} from '@angular/compiler-cli';
|
||||
|
||||
const glob = require('glob');
|
||||
|
||||
/**
|
||||
* Main method.
|
||||
* Standalone program that executes codegen using the ngtools API and tests that files were
|
||||
* properly read and wrote.
|
||||
*/
|
||||
function main() {
|
||||
console.log(`testing ngtools API...`);
|
||||
|
||||
Promise.resolve()
|
||||
.then(() => codeGenTest())
|
||||
.then(() => i18nTest())
|
||||
.then(() => lazyRoutesTest())
|
||||
.then(() => {
|
||||
console.log('All done!');
|
||||
process.exit(0);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err.stack);
|
||||
console.error('Test failed');
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
function codeGenTest() {
|
||||
const basePath = path.join(__dirname, '../ngtools_src');
|
||||
const project = path.join(basePath, 'tsconfig-build.json');
|
||||
const readResources: string[] = [];
|
||||
const wroteFiles: string[] = [];
|
||||
|
||||
const config = tsc.readConfiguration(project, basePath);
|
||||
const hostContext = new NodeCompilerHostContext();
|
||||
const delegateHost = ts.createCompilerHost(config.parsed.options, true);
|
||||
const host: ts.CompilerHost = Object.assign(
|
||||
{}, delegateHost,
|
||||
{writeFile: (fileName: string, ...rest: any[]) => { wroteFiles.push(fileName); }});
|
||||
const program = ts.createProgram(config.parsed.fileNames, config.parsed.options, host);
|
||||
|
||||
config.ngOptions.basePath = basePath;
|
||||
|
||||
console.log(`>>> running codegen for ${project}`);
|
||||
return __NGTOOLS_PRIVATE_API_2
|
||||
.codeGen({
|
||||
basePath,
|
||||
compilerOptions: config.parsed.options, program, host,
|
||||
|
||||
angularCompilerOptions: config.ngOptions,
|
||||
|
||||
// i18n options.
|
||||
i18nFormat: null,
|
||||
i18nFile: null,
|
||||
locale: null,
|
||||
|
||||
readResource: (fileName: string) => {
|
||||
readResources.push(fileName);
|
||||
return hostContext.readResource(fileName);
|
||||
}
|
||||
})
|
||||
.then(() => {
|
||||
console.log(`>>> codegen done, asserting read and wrote files`);
|
||||
|
||||
// Assert for each file that it has been read and each `ts` has a written file associated.
|
||||
const allFiles = glob.sync(path.join(basePath, '**/*'), {nodir: true});
|
||||
|
||||
allFiles.forEach((fileName: string) => {
|
||||
// Skip tsconfig.
|
||||
if (fileName.match(/tsconfig-build.json$/)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Assert that file was read.
|
||||
if (fileName.match(/\.module\.ts$/)) {
|
||||
const factory = fileName.replace(/\.module\.ts$/, '.module.ngfactory.ts');
|
||||
assert(wroteFiles.indexOf(factory) != -1, `Expected file "${factory}" to be written.`);
|
||||
} else if (fileName.match(/\.css$/) || fileName.match(/\.html$/)) {
|
||||
assert(
|
||||
readResources.indexOf(fileName) != -1,
|
||||
`Expected resource "${fileName}" to be read.`);
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`done, no errors.`);
|
||||
})
|
||||
.catch((e: any) => {
|
||||
console.error(e.stack);
|
||||
console.error('Compilation failed');
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
|
||||
function i18nTest() {
|
||||
const basePath = path.join(__dirname, '../ngtools_src');
|
||||
const project = path.join(basePath, 'tsconfig-build.json');
|
||||
const readResources: string[] = [];
|
||||
const wroteFiles: string[] = [];
|
||||
|
||||
const config = tsc.readConfiguration(project, basePath);
|
||||
const hostContext = new NodeCompilerHostContext();
|
||||
const delegateHost = ts.createCompilerHost(config.parsed.options, true);
|
||||
const host: ts.CompilerHost = Object.assign(
|
||||
{}, delegateHost,
|
||||
{writeFile: (fileName: string, ...rest: any[]) => { wroteFiles.push(fileName); }});
|
||||
const program = ts.createProgram(config.parsed.fileNames, config.parsed.options, host);
|
||||
|
||||
config.ngOptions.basePath = basePath;
|
||||
|
||||
console.log(`>>> running i18n extraction for ${project}`);
|
||||
return __NGTOOLS_PRIVATE_API_2
|
||||
.extractI18n({
|
||||
basePath,
|
||||
compilerOptions: config.parsed.options, program, host,
|
||||
angularCompilerOptions: config.ngOptions,
|
||||
i18nFormat: 'xlf',
|
||||
locale: null,
|
||||
outFile: null,
|
||||
readResource: (fileName: string) => {
|
||||
readResources.push(fileName);
|
||||
return hostContext.readResource(fileName);
|
||||
},
|
||||
})
|
||||
.then(() => {
|
||||
console.log(`>>> i18n extraction done, asserting read and wrote files`);
|
||||
|
||||
const allFiles = glob.sync(path.join(basePath, '**/*'), {nodir: true});
|
||||
|
||||
assert(wroteFiles.length == 1, `Expected a single message bundle file.`);
|
||||
|
||||
assert(
|
||||
wroteFiles[0].endsWith('/ngtools_src/messages.xlf'),
|
||||
`Expected the bundle file to be "message.xlf".`);
|
||||
|
||||
allFiles.forEach((fileName: string) => {
|
||||
// Skip tsconfig.
|
||||
if (fileName.match(/tsconfig-build.json$/)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Assert that file was read.
|
||||
if (fileName.match(/\.css$/) || fileName.match(/\.html$/)) {
|
||||
assert(
|
||||
readResources.indexOf(fileName) != -1,
|
||||
`Expected resource "${fileName}" to be read.`);
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`done, no errors.`);
|
||||
})
|
||||
.catch((e: any) => {
|
||||
console.error(e.stack);
|
||||
console.error('Extraction failed');
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
|
||||
function lazyRoutesTest() {
|
||||
const basePath = path.join(__dirname, '../ngtools_src');
|
||||
const project = path.join(basePath, 'tsconfig-build.json');
|
||||
|
||||
const config = tsc.readConfiguration(project, basePath);
|
||||
const host = ts.createCompilerHost(config.parsed.options, true);
|
||||
const program = ts.createProgram(config.parsed.fileNames, config.parsed.options, host);
|
||||
|
||||
config.ngOptions.basePath = basePath;
|
||||
|
||||
const lazyRoutes = __NGTOOLS_PRIVATE_API_2.listLazyRoutes({
|
||||
program,
|
||||
host,
|
||||
angularCompilerOptions: config.ngOptions,
|
||||
entryModule: 'app.module#AppModule'
|
||||
});
|
||||
|
||||
const expectations: {[route: string]: string} = {
|
||||
'./lazy.module#LazyModule': 'lazy.module.ts',
|
||||
'./feature/feature.module#FeatureModule': 'feature/feature.module.ts',
|
||||
'./feature/lazy-feature.module#LazyFeatureModule': 'feature/lazy-feature.module.ts',
|
||||
'./feature.module#FeatureModule': 'feature/feature.module.ts',
|
||||
'./lazy-feature-nested.module#LazyFeatureNestedModule': 'feature/lazy-feature-nested.module.ts',
|
||||
'feature2/feature2.module#Feature2Module': 'feature2/feature2.module.ts',
|
||||
'./default.module': 'feature2/default.module.ts',
|
||||
'feature/feature.module#FeatureModule': 'feature/feature.module.ts'
|
||||
};
|
||||
|
||||
Object.keys(lazyRoutes).forEach((route: string) => {
|
||||
assert(route in expectations, `Found a route that was not expected: "${route}".`);
|
||||
assert(
|
||||
lazyRoutes[route] == path.join(basePath, expectations[route]),
|
||||
`Route "${route}" does not point to the expected absolute path ` +
|
||||
`"${path.join(basePath, expectations[route])}". It points to "${lazyRoutes[route]}"`);
|
||||
});
|
||||
|
||||
// Verify that all expectations were met.
|
||||
assert.deepEqual(
|
||||
Object.keys(lazyRoutes), Object.keys(expectations), `Expected routes listed to be: \n` +
|
||||
` ${JSON.stringify(Object.keys(expectations))}\n` +
|
||||
`Actual:\n` +
|
||||
` ${JSON.stringify(Object.keys(lazyRoutes))}\n`);
|
||||
}
|
||||
|
||||
main();
|
126
packages/compiler-cli/integrationtest/test/test_summaries.ts
Normal file
126
packages/compiler-cli/integrationtest/test/test_summaries.ts
Normal file
@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* @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
|
||||
*/
|
||||
/* tslint:disable:no-console */
|
||||
|
||||
// Must be imported first, because angular2 decorators throws on load.
|
||||
import 'reflect-metadata';
|
||||
|
||||
import * as path from 'path';
|
||||
import * as ts from 'typescript';
|
||||
import * as assert from 'assert';
|
||||
import {tsc} from '@angular/tsc-wrapped/src/tsc';
|
||||
import {AngularCompilerOptions, CodeGenerator, CompilerHostContext, NodeCompilerHostContext} from '@angular/compiler-cli';
|
||||
|
||||
/**
|
||||
* Main method.
|
||||
* Standalone program that executes the real codegen and tests that
|
||||
* ngsummary.json files are used for libraries.
|
||||
*/
|
||||
function main() {
|
||||
console.log(`testing usage of ngsummary.json files in libraries...`);
|
||||
const basePath = path.resolve(__dirname, '..');
|
||||
const project = path.resolve(basePath, 'tsconfig-build.json');
|
||||
const readFiles: string[] = [];
|
||||
const writtenFiles: {fileName: string, content: string}[] = [];
|
||||
|
||||
class AssertingHostContext extends NodeCompilerHostContext {
|
||||
readFile(fileName: string): string {
|
||||
if (/.*\/node_modules\/.*/.test(fileName) && !/.*ngsummary\.json$/.test(fileName) &&
|
||||
!/package\.json$/.test(fileName)) {
|
||||
// Only allow to read summaries and package.json files from node_modules
|
||||
return null;
|
||||
}
|
||||
readFiles.push(path.relative(basePath, fileName));
|
||||
return super.readFile(fileName);
|
||||
}
|
||||
readResource(s: string): Promise<string> {
|
||||
readFiles.push(path.relative(basePath, s));
|
||||
return super.readResource(s);
|
||||
}
|
||||
}
|
||||
|
||||
const config = tsc.readConfiguration(project, basePath);
|
||||
config.ngOptions.basePath = basePath;
|
||||
// This flag tells ngc do not recompile libraries.
|
||||
config.ngOptions.generateCodeForLibraries = false;
|
||||
|
||||
console.log(`>>> running codegen for ${project}`);
|
||||
codegen(
|
||||
config,
|
||||
(host) => {
|
||||
host.writeFile = (fileName: string, content: string) => {
|
||||
fileName = path.relative(basePath, fileName);
|
||||
writtenFiles.push({fileName, content});
|
||||
};
|
||||
return new AssertingHostContext();
|
||||
})
|
||||
.then((exitCode: any) => {
|
||||
console.log(`>>> codegen done, asserting read files`);
|
||||
assertSomeFileMatch(readFiles, /^node_modules\/.*\.ngsummary\.json$/);
|
||||
assertNoFileMatch(readFiles, /^node_modules\/.*\.metadata.json$/);
|
||||
assertNoFileMatch(readFiles, /^node_modules\/.*\.html$/);
|
||||
assertNoFileMatch(readFiles, /^node_modules\/.*\.css$/);
|
||||
|
||||
assertNoFileMatch(readFiles, /^src\/.*\.ngsummary\.json$/);
|
||||
assertSomeFileMatch(readFiles, /^src\/.*\.html$/);
|
||||
assertSomeFileMatch(readFiles, /^src\/.*\.css$/);
|
||||
|
||||
console.log(`>>> asserting written files`);
|
||||
assertWrittenFile(writtenFiles, /^src\/module\.ngfactory\.ts$/, /class MainModuleInjector/);
|
||||
|
||||
console.log(`done, no errors.`);
|
||||
process.exit(exitCode);
|
||||
})
|
||||
.catch((e: any) => {
|
||||
console.error(e.stack);
|
||||
console.error('Compilation failed');
|
||||
process.exit(1);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple adaption of tsc-wrapped main to just run codegen with a CompilerHostContext
|
||||
*/
|
||||
function codegen(
|
||||
config: {parsed: ts.ParsedCommandLine, ngOptions: AngularCompilerOptions},
|
||||
hostContextFactory: (host: ts.CompilerHost) => CompilerHostContext) {
|
||||
const host = ts.createCompilerHost(config.parsed.options, true);
|
||||
|
||||
// HACK: patch the realpath to solve symlink issue here:
|
||||
// https://github.com/Microsoft/TypeScript/issues/9552
|
||||
// todo(misko): remove once facade symlinks are removed
|
||||
host.realpath = (path) => path;
|
||||
|
||||
const program = ts.createProgram(config.parsed.fileNames, config.parsed.options, host);
|
||||
|
||||
return CodeGenerator.create(config.ngOptions, {
|
||||
} as any, program, host, hostContextFactory(host)).codegen();
|
||||
}
|
||||
|
||||
function assertSomeFileMatch(fileNames: string[], pattern: RegExp) {
|
||||
assert(
|
||||
fileNames.some(fileName => pattern.test(fileName)),
|
||||
`Expected some read files match ${pattern}`);
|
||||
}
|
||||
|
||||
function assertNoFileMatch(fileNames: string[], pattern: RegExp) {
|
||||
const matches = fileNames.filter(fileName => pattern.test(fileName));
|
||||
assert(
|
||||
matches.length === 0,
|
||||
`Expected no read files match ${pattern}, but found: \n${matches.join('\n')}`);
|
||||
}
|
||||
|
||||
function assertWrittenFile(
|
||||
files: {fileName: string, content: string}[], filePattern: RegExp, contentPattern: RegExp) {
|
||||
assert(
|
||||
files.some(file => filePattern.test(file.fileName) && contentPattern.test(file.content)),
|
||||
`Expected some written files for ${filePattern} and content ${contentPattern}`);
|
||||
}
|
||||
|
||||
main();
|
33
packages/compiler-cli/integrationtest/test/util.ts
Normal file
33
packages/compiler-cli/integrationtest/test/util.ts
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* @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 {NgModuleFactory, NgModuleRef} from '@angular/core';
|
||||
import {ComponentFixture} from '@angular/core/testing';
|
||||
import {platformServer} from '@angular/platform-server';
|
||||
|
||||
import {MainModule} from '../src/module';
|
||||
import {MainModuleNgFactory} from '../src/module.ngfactory';
|
||||
|
||||
let mainModuleRef: NgModuleRef<MainModule> = null;
|
||||
beforeEach((done) => {
|
||||
platformServer().bootstrapModuleFactory(MainModuleNgFactory).then((moduleRef: any) => {
|
||||
mainModuleRef = moduleRef;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
export function createModule(): NgModuleRef<MainModule> {
|
||||
return mainModuleRef;
|
||||
}
|
||||
|
||||
export function createComponent<C>(comp: {new (...args: any[]): C}): ComponentFixture<C> {
|
||||
const moduleRef = createModule();
|
||||
const compRef =
|
||||
moduleRef.componentFactoryResolver.resolveComponentFactory(comp).create(moduleRef.injector);
|
||||
return new ComponentFixture(compRef, null, null);
|
||||
}
|
Reference in New Issue
Block a user