@angular/tsc-wrapped
Version:
Wraps the tsc CLI, allowing extensions.
209 lines • 14.6 kB
JavaScript
"use strict";
/**
* @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
*/
Object.defineProperty(exports, "__esModule", { value: true });
var fs = require("fs");
var path = require("path");
var main_1 = require("../src/main");
var test_support_1 = require("./test_support");
describe('tsc-wrapped', function () {
var basePath;
var write;
beforeEach(function () {
basePath = test_support_1.makeTempDir();
write = function (fileName, content) {
fs.writeFileSync(path.join(basePath, fileName), content, { encoding: 'utf-8' });
};
write('decorators.ts', '/** @Annotation */ export var Component: Function;');
fs.mkdirSync(path.join(basePath, 'dep'));
write('dep/index.ts', "\n export const A = 1;\n export const B = 2;\n ");
write('test.ts', "\n import {Component} from './decorators';\n export * from './dep';\n\n @Component({})\n export class Comp {\n /**\n * Comment that is\n * multiple lines\n */\n method(x: string): void {}\n }\n ");
});
function readOut(ext) {
return fs.readFileSync(path.join(basePath, 'built', "test." + ext), { encoding: 'utf-8' });
}
it('should report error if project not found', function () {
main_1.main('not-exist', null)
.then(function () { return fail('should report error'); })
.catch(function (e) { return expect(e.message).toContain('ENOENT'); });
});
it('should pre-process sources', function (done) {
write('tsconfig.json', "{\n \"compilerOptions\": {\n \"experimentalDecorators\": true,\n \"types\": [],\n \"outDir\": \"built\",\n \"declaration\": true,\n \"moduleResolution\": \"node\",\n \"target\": \"es2015\"\n },\n \"angularCompilerOptions\": {\n \"annotateForClosureCompiler\": true\n },\n \"files\": [\"test.ts\"]\n }");
main_1.main(basePath, { basePath: basePath })
.then(function () {
var out = readOut('js');
// No helpers since decorators were lowered
expect(out).not.toContain('__decorate');
// Expand `export *` and fix index import
expect(out).toContain("export { A, B } from './dep'");
// Annotated for Closure compiler
expect(out).toContain('* {?} x');
// Comments should stay multi-line
expect(out).not.toContain('Comment that is multiple lines');
// Decorator is now an annotation
expect(out).toMatch(/Comp.decorators = \[\s+\{ type: Component/);
var decl = readOut('d.ts');
expect(decl).toContain('declare class Comp');
var metadata = readOut('metadata.json');
expect(metadata).toContain('"Comp":{"__symbolic":"class"');
done();
})
.catch(function (e) { return done.fail(e); });
});
it('should pre-process sources using config from vinyl like object', function (done) {
var config = {
path: basePath + '/tsconfig.json',
contents: new Buffer(JSON.stringify({
compilerOptions: {
experimentalDecorators: true,
types: [],
outDir: 'built',
declaration: true,
moduleResolution: 'node',
target: 'es2015'
},
angularCompilerOptions: { annotateForClosureCompiler: true },
files: ['test.ts']
}))
};
main_1.main(config, { basePath: basePath })
.then(function () {
var out = readOut('js');
// Expand `export *` and fix index import
expect(out).toContain("export { A, B } from './dep'");
// Annotated for Closure compiler
expect(out).toContain('* {?} x');
done();
})
.catch(function (e) { return done.fail(e); });
});
it('should allow all options disabled', function (done) {
write('tsconfig.json', "{\n \"compilerOptions\": {\n \"experimentalDecorators\": true,\n \"types\": [],\n \"outDir\": \"built\",\n \"declaration\": false,\n \"module\": \"es2015\",\n \"moduleResolution\": \"node\"\n },\n \"angularCompilerOptions\": {\n \"annotateForClosureCompiler\": false,\n \"annotationsAs\": \"decorators\",\n \"skipMetadataEmit\": true,\n \"skipTemplateCodegen\": true\n },\n \"files\": [\"test.ts\"]\n }");
main_1.main(basePath, { basePath: basePath })
.then(function () {
var out = readOut('js');
// TypeScript's decorator emit
expect(out).toContain('__decorate');
// Not annotated for Closure compiler
expect(out).not.toContain('* {?} x');
expect(function () { return fs.accessSync(path.join(basePath, 'built', 'test.metadata.json')); }).toThrow();
expect(function () { return fs.accessSync(path.join(basePath, 'built', 'test.d.ts')); }).toThrow();
done();
})
.catch(function (e) { return done.fail(e); });
});
it('should allow all options disabled with metadata emit', function (done) {
write('tsconfig.json', "{\n \"compilerOptions\": {\n \"experimentalDecorators\": true,\n \"types\": [],\n \"outDir\": \"built\",\n \"declaration\": false,\n \"module\": \"es2015\",\n \"moduleResolution\": \"node\"\n },\n \"angularCompilerOptions\": {\n \"annotateForClosureCompiler\": false,\n \"annotationsAs\": \"decorators\",\n \"skipMetadataEmit\": false,\n \"skipTemplateCodegen\": true\n },\n \"files\": [\"test.ts\"]\n }");
main_1.main(basePath, { basePath: basePath })
.then(function () {
var out = readOut('js');
// TypeScript's decorator emit
expect(out).toContain('__decorate');
// Not annotated for Closure compiler
expect(out).not.toContain('* {?} x');
expect(function () { return fs.accessSync(path.join(basePath, 'built', 'test.d.ts')); }).toThrow();
var metadata = readOut('metadata.json');
expect(metadata).toContain('"Comp":{"__symbolic":"class"');
done();
})
.catch(function (e) { return done.fail(e); });
});
it('should allow JSDoc annotations without decorator downleveling', function (done) {
write('tsconfig.json', "{\n \"compilerOptions\": {\n \"experimentalDecorators\": true,\n \"types\": [],\n \"outDir\": \"built\",\n \"declaration\": true\n },\n \"angularCompilerOptions\": {\n \"annotateForClosureCompiler\": true,\n \"annotationsAs\": \"decorators\"\n },\n \"files\": [\"test.ts\"]\n }");
main_1.main(basePath, { basePath: basePath }).then(function () { return done(); }).catch(function (e) { return done.fail(e); });
});
xit('should run quickly (performance baseline)', function (done) {
for (var i = 0; i < 1000; i++) {
write("input" + i + ".ts", "\n import {Component} from './decorators';\n @Component({})\n export class Input" + i + " {\n private __brand: string;\n }\n ");
}
write('tsconfig.json', "{\n \"compilerOptions\": {\n \"experimentalDecorators\": true,\n \"types\": [],\n \"outDir\": \"built\",\n \"declaration\": true,\n \"diagnostics\": true\n },\n \"angularCompilerOptions\": {\n \"annotateForClosureCompiler\": false,\n \"annotationsAs\": \"decorators\",\n \"skipMetadataEmit\": true\n },\n \"include\": [\"input*.ts\"]\n }");
console.time('BASELINE');
main_1.main(basePath, { basePath: basePath })
.then(function () {
console.timeEnd('BASELINE');
done();
})
.catch(function (e) { return done.fail(e); });
});
xit('should run quickly (performance test)', function (done) {
for (var i = 0; i < 1000; i++) {
write("input" + i + ".ts", "\n import {Component} from './decorators';\n @Component({})\n export class Input" + i + " {\n private __brand: string;\n }\n ");
}
write('tsconfig.json', "{\n \"compilerOptions\": {\n \"experimentalDecorators\": true,\n \"types\": [],\n \"outDir\": \"built\",\n \"declaration\": true,\n \"diagnostics\": true,\n \"skipLibCheck\": true\n },\n \"angularCompilerOptions\": {\n \"annotateForClosureCompiler\": true\n },\n \"include\": [\"input*.ts\"]\n }");
console.time('TSICKLE');
main_1.main(basePath, { basePath: basePath })
.then(function () {
console.timeEnd('TSICKLE');
done();
})
.catch(function (e) { return done.fail(e); });
});
it('should produce valid source maps', function (done) {
write('tsconfig.json', "{\n \"compilerOptions\": {\n \"experimentalDecorators\": true,\n \"types\": [],\n \"outDir\": \"built\",\n \"declaration\": true,\n \"moduleResolution\": \"node\",\n \"target\": \"es2015\",\n \"sourceMap\": true\n },\n \"angularCompilerOptions\": {\n \"annotateForClosureCompiler\": true\n },\n \"files\": [\"test.ts\"]\n }");
main_1.main(basePath, { basePath: basePath })
.then(function () {
var out = readOut('js.map');
expect(out).toContain('"sources":["../test.ts"]');
done();
})
.catch(function (e) { return done.fail(e); });
});
it('should accept input source maps', function (done) {
write('tsconfig.json', "{\n \"compilerOptions\": {\n \"experimentalDecorators\": true,\n \"types\": [],\n \"outDir\": \"built\",\n \"declaration\": true,\n \"moduleResolution\": \"node\",\n \"target\": \"es2015\",\n \"sourceMap\": true\n },\n \"angularCompilerOptions\": {\n \"annotateForClosureCompiler\": true\n },\n \"files\": [\"test.ts\"]\n }");
// Provide a file called test.ts that has an inline source map
// which says that it was transpiled from a file other_test.ts
// with exactly the same content.
var inputSourceMap = "{\"version\":3,\"sources\":[\"other_test.ts\"],\"names\":[],\"mappings\":\"AAAA,MAAM,EAAE,EAAE,CAAC\",\"file\":\"../test.ts\",\"sourceRoot\":\"\"}";
var encodedSourceMap = new Buffer(inputSourceMap, 'utf8').toString('base64');
write('test.ts', "const x = 3;\n//# sourceMappingURL=data:application/json;base64," + encodedSourceMap);
main_1.main(basePath, { basePath: basePath })
.then(function () {
var out = readOut('js.map');
expect(out).toContain('"sources":["other_test.ts"]');
done();
})
.catch(function (e) { return done.fail(e); });
});
it("should accept input source maps that don't match the file name", function (done) {
write('tsconfig.json', "{\n \"compilerOptions\": {\n \"experimentalDecorators\": true,\n \"types\": [],\n \"outDir\": \"built\",\n \"declaration\": true,\n \"moduleResolution\": \"node\",\n \"target\": \"es2015\",\n \"sourceMap\": true\n },\n \"angularCompilerOptions\": {\n \"annotateForClosureCompiler\": true\n },\n \"files\": [\"test.ts\"]\n }");
// Provide a file called test.ts that has an inline source map
// which says that it was transpiled from a file other_test.ts
// with exactly the same content.
var inputSourceMap = "{\"version\":3,\"sources\":[\"other_test.ts\"],\"names\":[],\"mappings\":\"AAAA,MAAM,EAAE,EAAE,CAAC\",\"file\":\"test.ts\",\"sourceRoot\":\"\"}";
var encodedSourceMap = new Buffer(inputSourceMap, 'utf8').toString('base64');
write('test.ts', "const x = 3;\n//# sourceMappingURL=data:application/json;base64," + encodedSourceMap);
main_1.main(basePath, { basePath: basePath })
.then(function () {
var out = readOut('js.map');
expect(out).toContain('"sources":["other_test.ts"]');
done();
})
.catch(function (e) { return done.fail(e); });
});
it('should not expand shorthand imports for ES2015 modules', function (done) {
write('tsconfig.json', "{\n \"compilerOptions\": {\n \"experimentalDecorators\": true,\n \"types\": [],\n \"outDir\": \"built\",\n \"declaration\": true,\n \"moduleResolution\": \"node\",\n \"target\": \"es2015\",\n \"module\": \"es2015\"\n },\n \"angularCompilerOptions\": {\n \"annotateForClosureCompiler\": true\n },\n \"files\": [\"test.ts\"]\n }");
main_1.main(basePath, { basePath: basePath })
.then(function () {
var fileOutput = readOut('js');
expect(fileOutput).toContain("export { A, B } from './dep'");
done();
})
.catch(function (e) { return done.fail(e); });
});
it('should not expand shorthand imports for ES5 CommonJS modules', function (done) {
write('tsconfig.json', "{\n \"compilerOptions\": {\n \"experimentalDecorators\": true,\n \"types\": [],\n \"outDir\": \"built\",\n \"declaration\": true,\n \"moduleResolution\": \"node\",\n \"target\": \"es5\",\n \"module\": \"commonjs\"\n },\n \"angularCompilerOptions\": {\n \"annotateForClosureCompiler\": true\n },\n \"files\": [\"test.ts\"]\n }");
main_1.main(basePath, { basePath: basePath })
.then(function () {
var fileOutput = readOut('js');
expect(fileOutput).toContain("var dep_1 = require(\"./dep\");");
done();
})
.catch(function (e) { return done.fail(e); });
});
});
//# sourceMappingURL=main.spec.js.map