build: make `internal-angular` karma reporter compatible with latest karma (#24803)

Due to changes in karma@1.0.0, `internal-angular` karma reporter stopped
showing browser logs (such as `console.log()` etc.).
Related to d571a5173.

PR Close #24803
This commit is contained in:
George Kalpakas 2018-07-09 14:04:45 +03:00 committed by Miško Hevery
parent 3d20c50156
commit 89203c96ad
3 changed files with 64 additions and 38 deletions

View File

@ -6,62 +6,90 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
var SourceMapConsumer = require('source-map').SourceMapConsumer; 'use strict';
var DotsReporter = require('karma/lib/reporters/dots_color');
var createErrorFormatter = function(basePath, emitter, SourceMapConsumer) { const DotsColorReporter = require('karma/lib/reporters/dots_color');
var lastServedFiles = []; const {SourceMapConsumer} = require('source-map');
emitter.on('file_list_modified', function(files) { lastServedFiles = files.served; }); const {resolve} = require('url');
function findFile(path) { return lastServedFiles.filter(_ => _.path === path)[0]; }
var URL_REGEXP = new RegExp( // Based on `karma/lib/reporter.js` (v2.0.4):
'(?:https?:\\/\\/[^\\/]*)?\\/?' + // https://github.com/karma-runner/karma/blob/v2.0.4/lib/reporter.js
'(base|absolute)' + // prefix function createErrorFormatter(config, emitter, SourceMapConsumer) {
const basePath = config.basePath;
const urlRoot = (config.urlRoot === '/') ? '' : (config.urlRoot || '');
const urlRegexp = new RegExp(
'(?:https?:\\/\\/' + config.hostname + '(?:\\:' + config.port + ')?' +
')?\\/?' + urlRoot + '\\/?' +
'(base/|absolute)' + // prefix, including slash for base/ to create relative paths.
'((?:[A-z]\\:)?[^\\?\\s\\:]*)' + // path '((?:[A-z]\\:)?[^\\?\\s\\:]*)' + // path
'(\\?\\w*)?' + // sha '(\\?\\w*)?' + // sha
'(\\:(\\d+))?' + // line '(\\:(\\d+))?' + // line
'(\\:(\\d+))?' + // column '(\\:(\\d+))?' + // column
'', '',
'g'); 'g');
const sourceMapConsumerCache = new WeakMap();
let lastServedFiles = [];
return function(msg, indentation) { // Helpers
msg = (msg || '').replace(URL_REGEXP, function(_, prefix, path, __, ___, line, ____, column) { const findFile = path => lastServedFiles.find(f => f.path === path);
if (prefix === 'base') { const formatPathMapping = (path, line, column) =>
path = basePath + path; path + (line ? `:${line}` : '') + (column ? `:${column}` : '');
} const isString = input => typeof input === 'string';
line = parseInt(line || '0', 10); const getSourceMapConsumer = sourceMap => {
column = parseInt(column || '0', 10); if (!sourceMapConsumerCache.has(sourceMap)) {
sourceMapConsumerCache.set(sourceMap, new SourceMapConsumer(sourceMap));
}
return sourceMapConsumerCache.get(sourceMap);
};
emitter.on('file_list_modified', files => lastServedFiles = files.served);
return (input, indentation) => {
if (!isString(indentation)) indentation = '';
if (!input) input = '';
if (isString(input.message)) input = input.message;
if (!isString(input)) input = JSON.stringify(input, null, indentation);
let msg = input.replace(urlRegexp, (_, prefix, path, __, ___, line, ____, column) => {
const normalizedPath = (prefix === 'base/') ? `${basePath}/${path}` : path;
const file = findFile(normalizedPath);
if (file && file.sourceMap && line) {
line = +line;
column = +column || 0;
const bias =
column ? SourceMapConsumer.GREATEST_LOWER_BOUND : SourceMapConsumer.LEAST_UPPER_BOUND;
var file = findFile(path);
if (file && file.sourceMap) {
try { try {
var original = new SourceMapConsumer(file.sourceMap) const original =
.originalPositionFor({line: line, column: column}); getSourceMapConsumer(file.sourceMap).originalPositionFor({line, column, bias});
return process.cwd() + '/modules/' + original.source + ':' + original.line + ':' + return formatPathMapping(
original.column; `${resolve(path, original.source)}`, original.line, original.column);
} catch (e) { } catch (e) {
console.warn('SourceMap position not found for trace: %s', msg); console.warn(`SourceMap position not found for trace: ${input}`);
} }
} }
return path + ':' + line + ':' + column;
return formatPathMapping(path, line, column) || prefix;
}); });
// indent every line // Indent every line.
if (indentation) { if (indentation) {
msg = indentation + msg.replace(/\n/g, '\n' + indentation); msg = indentation + msg.replace(/\n/g, `\n${indentation}`);
} }
return msg + '\n';
return config.formatError ? config.formatError(msg) : `${msg}\n`;
}; };
}; }
var InternalAngularReporter = function(config, emitter) {
var formatter = createErrorFormatter(config.basePath, emitter, SourceMapConsumer);
DotsReporter.call(this, formatter, false, config.colors);
};
InternalAngularReporter.$inject = ['config', 'emitter']; InternalAngularReporter.$inject = ['config', 'emitter'];
function InternalAngularReporter(config, emitter) {
var formatter = createErrorFormatter(config, emitter, SourceMapConsumer);
DotsColorReporter.call(this, formatter, false, config.colors, config.browserConsoleLogOptions);
}
module.exports = { module.exports = {
'reporter:internal-angular': ['type', InternalAngularReporter] 'reporter:internal-angular': ['type', InternalAngularReporter],
}; };

View File

@ -7,10 +7,9 @@
*/ */
/* tslint:disable:no-console */ /* tslint:disable:no-console */
import {spawn} from 'child_process'; import {existsSync, mkdirSync} from 'fs';
import {existsSync, mkdirSync, writeFileSync} from 'fs';
import {TSC, TscWatch, reportError} from './tsc_watch'; import {TscWatch} from './tsc_watch';
export * from './tsc_watch'; export * from './tsc_watch';
import 'reflect-metadata'; import 'reflect-metadata';

View File

@ -10,7 +10,6 @@
import {spawn} from 'child_process'; import {spawn} from 'child_process';
import {platform} from 'os'; import {platform} from 'os';
import {normalize} from 'path'; import {normalize} from 'path';
import {resolve} from 'url';
enum State { enum State {
idle, idle,