+2
-5
@@ -524,7 +524,7 @@ function launchKarmaWithExternalBrowsers(reporters, browsers, done) {
|
|||||||
|
|
||||||
gulp.task('!test.unit.js/karma-server', function(done) {
|
gulp.task('!test.unit.js/karma-server', function(done) {
|
||||||
var watchStarted = false;
|
var watchStarted = false;
|
||||||
var server = new karma.Server({configFile: __dirname + '/karma-js.conf.js', reporters: 'dots'});
|
var server = new karma.Server({configFile: __dirname + '/karma-js.conf.js'});
|
||||||
server.on('run_complete', function() {
|
server.on('run_complete', function() {
|
||||||
if (!watchStarted) {
|
if (!watchStarted) {
|
||||||
watchStarted = true;
|
watchStarted = true;
|
||||||
@@ -548,10 +548,7 @@ gulp.task('test.unit.router', function(done) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('!test.unit.router/karma-server', function() {
|
gulp.task('!test.unit.router/karma-server', function() {
|
||||||
new karma.Server({
|
new karma.Server({configFile: __dirname + '/modules/angular1_router/karma-router.conf.js'})
|
||||||
configFile: __dirname + '/modules/angular1_router/karma-router.conf.js',
|
|
||||||
reporters: 'dots'
|
|
||||||
})
|
|
||||||
.start();
|
.start();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
var browserProvidersConf = require('./browser-providers.conf.js');
|
var browserProvidersConf = require('./browser-providers.conf.js');
|
||||||
|
var internalAngularReporter = require('./tools/karma/reporter.js');
|
||||||
|
|
||||||
// Karma configuration
|
// Karma configuration
|
||||||
// Generated on Thu Sep 25 2014 11:52:02 GMT-0700 (PDT)
|
// Generated on Thu Sep 25 2014 11:52:02 GMT-0700 (PDT)
|
||||||
@@ -35,6 +36,21 @@ module.exports = function(config) {
|
|||||||
|
|
||||||
customLaunchers: browserProvidersConf.customLaunchers,
|
customLaunchers: browserProvidersConf.customLaunchers,
|
||||||
|
|
||||||
|
plugins: [
|
||||||
|
'karma-jasmine',
|
||||||
|
'karma-browserstack-launcher',
|
||||||
|
'karma-sauce-launcher',
|
||||||
|
'karma-chrome-launcher',
|
||||||
|
'karma-sourcemap-loader',
|
||||||
|
'karma-dart',
|
||||||
|
internalAngularReporter
|
||||||
|
],
|
||||||
|
|
||||||
|
preprocessors: {
|
||||||
|
'**/*.js': ['sourcemap']
|
||||||
|
},
|
||||||
|
|
||||||
|
reporters: ['internal-angular'],
|
||||||
sauceLabs: {
|
sauceLabs: {
|
||||||
testName: 'Angular2',
|
testName: 'Angular2',
|
||||||
startConnect: false,
|
startConnect: false,
|
||||||
|
|||||||
@@ -29,7 +29,13 @@ describe('sourcemaps', function() {
|
|||||||
expect(errorColumn).not.toBeNull();
|
expect(errorColumn).not.toBeNull();
|
||||||
|
|
||||||
|
|
||||||
var sourceMapData = fs.readFileSync('dist/js/prod/es5/playground/src/sourcemap/index.js.map');
|
const content =
|
||||||
|
fs.readFileSync('dist/js/dev/es5/playground/src/sourcemap/index.js').toString("utf8");
|
||||||
|
const marker = "//# sourceMappingURL=data:application/json;base64,";
|
||||||
|
const index = content.indexOf(marker);
|
||||||
|
const sourceMapData =
|
||||||
|
new Buffer(content.substring(index + marker.length), 'base64').toString("utf8");
|
||||||
|
|
||||||
var decoder = new sourceMap.SourceMapConsumer(JSON.parse(sourceMapData));
|
var decoder = new sourceMap.SourceMapConsumer(JSON.parse(sourceMapData));
|
||||||
|
|
||||||
var originalPosition = decoder.originalPositionFor({line: errorLine, column: errorColumn});
|
var originalPosition = decoder.originalPositionFor({line: errorLine, column: errorColumn});
|
||||||
|
|||||||
@@ -12153,6 +12153,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"karma-sourcemap-loader": {
|
||||||
|
"version": "0.3.6"
|
||||||
|
},
|
||||||
"lodash": {
|
"lodash": {
|
||||||
"version": "2.4.2"
|
"version": "2.4.2"
|
||||||
},
|
},
|
||||||
|
|||||||
Generated
+109
-104
File diff suppressed because it is too large
Load Diff
@@ -81,6 +81,7 @@
|
|||||||
"karma-dart": "^0.3.0",
|
"karma-dart": "^0.3.0",
|
||||||
"karma-jasmine": "^0.3.6",
|
"karma-jasmine": "^0.3.6",
|
||||||
"karma-sauce-launcher": "^0.2.14",
|
"karma-sauce-launcher": "^0.2.14",
|
||||||
|
"karma-sourcemap-loader": "^0.3.6",
|
||||||
"lodash": "^2.4.1",
|
"lodash": "^2.4.1",
|
||||||
"madge": "0.5.0",
|
"madge": "0.5.0",
|
||||||
"merge": "^1.2.0",
|
"merge": "^1.2.0",
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ export class AngularBuilder {
|
|||||||
{
|
{
|
||||||
name: 'dev',
|
name: 'dev',
|
||||||
typeAssertions: true,
|
typeAssertions: true,
|
||||||
|
sourceMaps: true,
|
||||||
projects: opts.projects,
|
projects: opts.projects,
|
||||||
noTypeChecks: opts.noTypeChecks,
|
noTypeChecks: opts.noTypeChecks,
|
||||||
generateEs6: opts.generateEs6
|
generateEs6: opts.generateEs6
|
||||||
@@ -84,6 +85,7 @@ export class AngularBuilder {
|
|||||||
{
|
{
|
||||||
name: 'prod',
|
name: 'prod',
|
||||||
typeAssertions: false,
|
typeAssertions: false,
|
||||||
|
sourceMaps: false,
|
||||||
projects: opts.projects,
|
projects: opts.projects,
|
||||||
noTypeChecks: opts.noTypeChecks,
|
noTypeChecks: opts.noTypeChecks,
|
||||||
generateEs6: opts.generateEs6
|
generateEs6: opts.generateEs6
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ class DiffingTSCompiler implements DiffingBroccoliPlugin {
|
|||||||
output.outputFiles.forEach(o => {
|
output.outputFiles.forEach(o => {
|
||||||
let destDirPath = path.dirname(o.name);
|
let destDirPath = path.dirname(o.name);
|
||||||
fse.mkdirsSync(destDirPath);
|
fse.mkdirsSync(destDirPath);
|
||||||
fs.writeFileSync(o.name, o.text, FS_OPTS);
|
fs.writeFileSync(o.name, this.fixSourceMapSources(o.text), FS_OPTS);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -145,9 +145,9 @@ class DiffingTSCompiler implements DiffingBroccoliPlugin {
|
|||||||
|
|
||||||
private doFullBuild() {
|
private doFullBuild() {
|
||||||
let program = this.tsService.getProgram();
|
let program = this.tsService.getProgram();
|
||||||
let emitResult = program.emit(undefined, function(absoluteFilePath, fileContent) {
|
let emitResult = program.emit(undefined, (absoluteFilePath, fileContent) => {
|
||||||
fse.mkdirsSync(path.dirname(absoluteFilePath));
|
fse.mkdirsSync(path.dirname(absoluteFilePath));
|
||||||
fs.writeFileSync(absoluteFilePath, fileContent, FS_OPTS);
|
fs.writeFileSync(absoluteFilePath, this.fixSourceMapSources(fileContent), FS_OPTS);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (emitResult.emitSkipped) {
|
if (emitResult.emitSkipped) {
|
||||||
@@ -176,6 +176,33 @@ class DiffingTSCompiler implements DiffingBroccoliPlugin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* There is a bug in TypeScript 1.6, where the sourceRoot and inlineSourceMap properties
|
||||||
|
* are exclusive. This means that the sources property always contains relative paths
|
||||||
|
* (e.g, ../../../../angular2/src/di/injector.ts).
|
||||||
|
*
|
||||||
|
* Here, we normalize the sources property and remove the ../../../
|
||||||
|
*
|
||||||
|
* This issue is fixed in https://github.com/Microsoft/TypeScript/pull/5620.
|
||||||
|
* Once we switch to TypeScript 1.8, we can remove this method.
|
||||||
|
*/
|
||||||
|
private fixSourceMapSources(content: string): string {
|
||||||
|
try {
|
||||||
|
const marker = "//# sourceMappingURL=data:application/json;base64,";
|
||||||
|
const index = content.indexOf(marker);
|
||||||
|
if (index == -1) return content;
|
||||||
|
|
||||||
|
const base = content.substring(0, index + marker.length);
|
||||||
|
const sourceMapBit =
|
||||||
|
new Buffer(content.substring(index + marker.length), 'base64').toString("utf8");
|
||||||
|
const sourceMaps = JSON.parse(sourceMapBit);
|
||||||
|
const source = sourceMaps.sources[0];
|
||||||
|
sourceMaps.sources = [source.substring(source.lastIndexOf("../") + 3)];
|
||||||
|
return `${base}${new Buffer(JSON.stringify(sourceMaps)).toString('base64')}`;
|
||||||
|
} catch (e) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private removeOutputFor(tsFilePath: string) {
|
private removeOutputFor(tsFilePath: string) {
|
||||||
let absoluteJsFilePath = path.join(this.cachePath, tsFilePath.replace(/\.ts$/, '.js'));
|
let absoluteJsFilePath = path.join(this.cachePath, tsFilePath.replace(/\.ts$/, '.js'));
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ module.exports = function makeBrowserTree(options, destinationPath) {
|
|||||||
const modules = options.projects;
|
const modules = options.projects;
|
||||||
const noTypeChecks = options.noTypeChecks;
|
const noTypeChecks = options.noTypeChecks;
|
||||||
const generateEs6 = options.generateEs6;
|
const generateEs6 = options.generateEs6;
|
||||||
|
const sourceMaps = options.sourceMaps;
|
||||||
|
|
||||||
if (modules.angular2) {
|
if (modules.angular2) {
|
||||||
var angular2Tree = new Funnel('modules/angular2', {
|
var angular2Tree = new Funnel('modules/angular2', {
|
||||||
@@ -147,14 +148,13 @@ module.exports = function makeBrowserTree(options, destinationPath) {
|
|||||||
declaration: false,
|
declaration: false,
|
||||||
emitDecoratorMetadata: true,
|
emitDecoratorMetadata: true,
|
||||||
experimentalDecorators: true,
|
experimentalDecorators: true,
|
||||||
mapRoot: '', // force sourcemaps to use relative path
|
|
||||||
module: 'commonjs',
|
module: 'commonjs',
|
||||||
moduleResolution: 'classic',
|
moduleResolution: 'classic',
|
||||||
noEmitOnError: !noTypeChecks,
|
noEmitOnError: !noTypeChecks,
|
||||||
rootDir: './',
|
rootDir: './',
|
||||||
rootFilePaths: ['angular2/manual_typings/globals.d.ts'],
|
rootFilePaths: ['angular2/manual_typings/globals.d.ts'],
|
||||||
sourceMap: true,
|
inlineSourceMap: sourceMaps,
|
||||||
sourceRoot: '.',
|
inlineSources: sourceMaps,
|
||||||
target: 'es5'
|
target: 'es5'
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -276,12 +276,11 @@ module.exports = function makeBrowserTree(options, destinationPath) {
|
|||||||
declaration: false,
|
declaration: false,
|
||||||
emitDecoratorMetadata: true,
|
emitDecoratorMetadata: true,
|
||||||
experimentalDecorators: true,
|
experimentalDecorators: true,
|
||||||
mapRoot: '', // force sourcemaps to use relative path
|
|
||||||
noEmitOnError: false,
|
noEmitOnError: false,
|
||||||
rootDir: './',
|
rootDir: './',
|
||||||
rootFilePaths: ['angular2/manual_typings/globals-es6.d.ts'],
|
rootFilePaths: ['angular2/manual_typings/globals-es6.d.ts'],
|
||||||
sourceMap: true,
|
inlineSourceMap: sourceMaps,
|
||||||
sourceRoot: '.',
|
inlineSources: sourceMaps,
|
||||||
target: 'es6'
|
target: 'es6'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
var SourceMapConsumer = require('source-map').SourceMapConsumer;
|
||||||
|
var DotsReporter = require('karma/lib/reporters/dots_color');
|
||||||
|
|
||||||
|
var createErrorFormatter = function (basePath, emitter, SourceMapConsumer) {
|
||||||
|
var lastServedFiles = [];
|
||||||
|
emitter.on('file_list_modified', function (files) {
|
||||||
|
lastServedFiles = files.served
|
||||||
|
});
|
||||||
|
function findFile(path) {
|
||||||
|
return lastServedFiles.filter(_ => _.path === path)[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
var URL_REGEXP = new RegExp('(?:https?:\\/\\/[^\\/]*)?\\/?' +
|
||||||
|
'(base|absolute)' + // prefix
|
||||||
|
'((?:[A-z]\\:)?[^\\?\\s\\:]*)' + // path
|
||||||
|
'(\\?\\w*)?' + // sha
|
||||||
|
'(\\:(\\d+))?' + // line
|
||||||
|
'(\\:(\\d+))?' + // column
|
||||||
|
'', 'g')
|
||||||
|
|
||||||
|
return function (msg, indentation) {
|
||||||
|
msg = (msg || '').replace(URL_REGEXP, function (_, prefix, path, __, ___, line, ____, column) {
|
||||||
|
if (prefix === 'base') {
|
||||||
|
path = basePath + path;
|
||||||
|
}
|
||||||
|
line = parseInt(line || '0', 10);
|
||||||
|
column = parseInt(column || '0', 10);
|
||||||
|
|
||||||
|
var file = findFile(path)
|
||||||
|
if (file && file.sourceMap) {
|
||||||
|
try {
|
||||||
|
var original = new SourceMapConsumer(file.sourceMap).originalPositionFor({
|
||||||
|
line: line,
|
||||||
|
column: column
|
||||||
|
});
|
||||||
|
return process.cwd() + "/modules/" + original.source + ":" + original.line + ":" + original.column;
|
||||||
|
} catch (e) {
|
||||||
|
log.warn('SourceMap position not found for trace: %s', msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return path + ':' + line + ':' + column;
|
||||||
|
});
|
||||||
|
|
||||||
|
// indent every line
|
||||||
|
if (indentation) {
|
||||||
|
msg = indentation + msg.replace(/\n/g, '\n' + indentation)
|
||||||
|
}
|
||||||
|
return msg + '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var InternalAngularReporter = function (config, emitter) {
|
||||||
|
var formatter = createErrorFormatter(config.basePath, emitter, SourceMapConsumer);
|
||||||
|
DotsReporter.call(this, formatter, false)
|
||||||
|
}
|
||||||
|
InternalAngularReporter.$inject = ['config', 'emitter']
|
||||||
|
|
||||||
|
module.exports = {'reporter:internal-angular': ['type', InternalAngularReporter]};
|
||||||
Reference in New Issue
Block a user