Remove in-browser unit testing

Rely on jest for now until we get a better and less hacky solution to running tests in the browser, probably a totally different test suite with different behavior/goals.
This commit is contained in:
Paul O’Shannessy 2015-07-15 18:58:51 -07:00
parent 44ed6010d3
commit 5da408297f
42 changed files with 2 additions and 6534 deletions

View File

@ -2,11 +2,6 @@
src/shared/vendor src/shared/vendor
# This should be enabled but that folder has too much in it that doesn't belong # This should be enabled but that folder has too much in it that doesn't belong
src/test src/test
test/the-files-to-test.generated.js
# This is synced with a different file internally, don't want to lint it yet
vendor/fbtransform/syntax.js
vendor/jasmine/
vendor/jasmine-jsreporter/
# But not in docs/_js/examples/* # But not in docs/_js/examples/*
docs/_js/*.js docs/_js/*.js
docs/js/ docs/js/

View File

@ -66,12 +66,10 @@ script:
fi fi
env: env:
matrix: matrix:
- TEST_TYPE=test
- TEST_TYPE=build - TEST_TYPE=build
- TEST_TYPE=jest - TEST_TYPE=jest
- TEST_TYPE=lint - TEST_TYPE=lint
- TEST_TYPE=build_website - TEST_TYPE=build_website
- TEST_TYPE=test:webdriver:saucelabs:modern
global: global:
# SERVER # SERVER
- secure: qPvsJ46XzGrdIuPA70b55xQNGF8jcK7N1LN5CCQYYocXLa+fBrl+fTE77QvehOPhqwJXcj6kOxI+sY0KrVwV7gmq2XY2HZGWUSCxTN0SZlNIzqPA80Y7G/yOjA4PUt8LKgP+8tptyhTAY56qf+hgW8BoLiKOdztYF2p+3zXOLuA= - secure: qPvsJ46XzGrdIuPA70b55xQNGF8jcK7N1LN5CCQYYocXLa+fBrl+fTE77QvehOPhqwJXcj6kOxI+sY0KrVwV7gmq2XY2HZGWUSCxTN0SZlNIzqPA80Y7G/yOjA4PUt8LKgP+8tptyhTAY56qf+hgW8BoLiKOdztYF2p+3zXOLuA=
@ -81,15 +79,6 @@ env:
- secure: EHCyCSKMwKlLHNtcj9nmkRzmiiPE3aDGlPcnEyrDJeRI0SeN/iCXHXfFivR0vFq3vr+9naMBczAR2AEidtps5KbJrKqdZnjPFRbmfVtzWr/LlvVCub3u13Pub6TdKIVBTny1PuZ5X8GvdxMNVig89jGjvzhhWuQRaz3VhJnTra4= - secure: EHCyCSKMwKlLHNtcj9nmkRzmiiPE3aDGlPcnEyrDJeRI0SeN/iCXHXfFivR0vFq3vr+9naMBczAR2AEidtps5KbJrKqdZnjPFRbmfVtzWr/LlvVCub3u13Pub6TdKIVBTny1PuZ5X8GvdxMNVig89jGjvzhhWuQRaz3VhJnTra4=
matrix: matrix:
fast_finish: true fast_finish: true
allow_failures:
- env: TEST_TYPE=test:coverage
- env: TEST_TYPE=test:webdriver:saucelabs:modern
- env: TEST_TYPE=test:webdriver:saucelabs BROWSER_NAME=ie11
- env: TEST_TYPE=test:webdriver:saucelabs BROWSER_NAME=ie10
- env: TEST_TYPE=test:webdriver:saucelabs BROWSER_NAME=ie9
- env: TEST_TYPE=test:webdriver:saucelabs BROWSER_NAME=ie8
- env: TEST_TYPE=test:webdriver:saucelabs:ios
- env: TEST_TYPE=test:webdriver:saucelabs BROWSER_NAME=safari
notifications: notifications:
irc: irc:
use_notice: true use_notice: true

View File

@ -6,9 +6,6 @@ module.exports = function(grunt) {
pkg: grunt.file.readJSON('package.json'), pkg: grunt.file.readJSON('package.json'),
jsx: require('./grunt/config/jsx'), jsx: require('./grunt/config/jsx'),
browserify: require('./grunt/config/browserify'), browserify: require('./grunt/config/browserify'),
populist: require('./grunt/config/populist')(grunt),
connect: require('./grunt/config/server')(grunt),
'webdriver-jasmine': require('./grunt/config/webdriver-jasmine'),
npm: require('./grunt/config/npm'), npm: require('./grunt/config/npm'),
clean: [ clean: [
'./build', './build',
@ -39,11 +36,6 @@ module.exports = function(grunt) {
grunt.registerTask('lint', ['eslint']); grunt.registerTask('lint', ['eslint']);
grunt.registerTask(
'download-previous-version',
require('./grunt/tasks/download-previous-version.js')
);
grunt.registerTask('delete-build-modules', function() { grunt.registerTask('delete-build-modules', function() {
if (grunt.file.exists('build/modules')) { if (grunt.file.exists('build/modules')) {
grunt.file.delete('build/modules'); grunt.file.delete('build/modules');
@ -56,12 +48,6 @@ module.exports = function(grunt) {
// Our own browserify-based tasks to build a single JS file build. // Our own browserify-based tasks to build a single JS file build.
grunt.registerMultiTask('browserify', require('./grunt/tasks/browserify')); grunt.registerMultiTask('browserify', require('./grunt/tasks/browserify'));
grunt.registerMultiTask('populist', require('./grunt/tasks/populist'));
grunt.registerTask('sauce-tunnel', require('./grunt/tasks/sauce-tunnel'));
grunt.registerMultiTask('webdriver-jasmine', require('./grunt/tasks/webdriver-jasmine'));
grunt.registerMultiTask('npm', require('./grunt/tasks/npm')); grunt.registerMultiTask('npm', require('./grunt/tasks/npm'));
var npmReactTasks = require('./grunt/tasks/npm-react'); var npmReactTasks = require('./grunt/tasks/npm-react');
@ -107,17 +93,6 @@ module.exports = function(grunt) {
'jsx:normal', 'jsx:normal',
'browserify:addonsMin', 'browserify:addonsMin',
]); ]);
grunt.registerTask('build:withCodeCoverageLogging', [
'jsx:normal',
'version-check',
'browserify:withCodeCoverageLogging',
]);
grunt.registerTask('build:test', [
'delete-build-modules',
'jsx:test',
'version-check',
'populist:test',
]);
grunt.registerTask('build:npm-react', [ grunt.registerTask('build:npm-react', [
'version-check', 'version-check',
'jsx:normal', 'jsx:normal',
@ -128,89 +103,10 @@ module.exports = function(grunt) {
'gem-react-source:release', 'gem-react-source:release',
]); ]);
grunt.registerTask('webdriver-phantomjs', require('./grunt/tasks/webdriver-phantomjs'));
grunt.registerTask('coverage:parse', require('./grunt/tasks/coverage-parse'));
grunt.registerTask('test:webdriver:phantomjs', [
'connect',
'webdriver-phantomjs',
'webdriver-jasmine:local',
]);
grunt.registerTask('test:full', [
'build:test',
'build:basic',
'connect',
'webdriver-phantomjs',
'webdriver-jasmine:local',
'sauce-tunnel',
'webdriver-jasmine:saucelabs_android',
'webdriver-jasmine:saucelabs_firefox',
'webdriver-jasmine:saucelabs_chrome',
]);
grunt.registerTask('test:webdriver:saucelabs', [
'build:test',
'build:basic',
'connect',
'sauce-tunnel',
'webdriver-jasmine:saucelabs_' + (process.env.BROWSER_NAME || 'ie8'),
]);
grunt.registerTask('test:webdriver:saucelabs:modern', [
'build:test',
'build:basic',
'connect',
'sauce-tunnel',
'webdriver-jasmine:saucelabs_android',
'webdriver-jasmine:saucelabs_firefox',
'webdriver-jasmine:saucelabs_chrome',
'webdriver-jasmine:saucelabs_ie11',
]);
grunt.registerTask('test:webdriver:saucelabs:ie', [
'build:test',
'build:basic',
'connect',
'sauce-tunnel',
'webdriver-jasmine:saucelabs_ie8',
'webdriver-jasmine:saucelabs_ie9',
'webdriver-jasmine:saucelabs_ie10',
'webdriver-jasmine:saucelabs_ie11',
]);
grunt.registerTask('test:webdriver:saucelabs:ios', [
'build:test',
'build:basic',
'connect',
'sauce-tunnel',
'webdriver-jasmine:saucelabs_ios6_1',
'webdriver-jasmine:saucelabs_ios5_1',
'webdriver-jasmine:saucelabs_ios4',
]);
grunt.registerTask('test:coverage', [
'build:withCodeCoverageLogging',
'test:webdriver:phantomjs',
'coverage:parse',
]);
grunt.registerTask('fasttest', function() { grunt.registerTask('fasttest', function() {
grunt.task.run('test'); grunt.task.run('test');
}); });
grunt.registerTask('test', function() { grunt.registerTask('test', ['jest']);
if (grunt.option('debug')) {
grunt.task.run('build:test', 'connect:server:keepalive');
} else {
grunt.task.run('build:test', 'test:webdriver:phantomjs');
}
});
grunt.registerTask('npm:test', ['build', 'npm:pack']); grunt.registerTask('npm:test', ['build', 'npm:pack']);
// Optimized build task that does all of our builds. The subtasks will be run // Optimized build task that does all of our builds. The subtasks will be run

View File

@ -43,22 +43,5 @@ require("commoner").version(
}).code; }).code;
} }
if (context.config.mocking) {
// Make sure there is exactly one newline at the end of the module.
source = source.replace(/\s+$/m, "\n");
return context.getProvidedP().then(function(idToPath) {
if (id !== "mock-modules" &&
id !== "mocks" &&
id !== "test/all" &&
idToPath.hasOwnProperty("mock-modules")) {
return source + '\nrequire("mock-modules").register(' +
JSON.stringify(id) + ', module);\n';
}
return source;
});
}
return source; return source;
}); });

View File

@ -121,25 +121,10 @@ var addonsMin = {
after: [/*derequire,*/ minify, bannerify], after: [/*derequire,*/ minify, bannerify],
}; };
var withCodeCoverageLogging = {
entries: [
'./build/modules/React.js',
],
outfile: './build/react.js',
debug: true,
standalone: 'React',
transforms: [
envify({NODE_ENV: process.env.NODE_ENV || 'development'}),
require('coverify'),
],
plugins: [collapser],
};
module.exports = { module.exports = {
basic: basic, basic: basic,
min: min, min: min,
transformer: transformer, transformer: transformer,
addons: addons, addons: addons,
addonsMin: addonsMin, addonsMin: addonsMin,
withCodeCoverageLogging: withCodeCoverageLogging,
}; };

View File

@ -1,6 +1,5 @@
'use strict'; 'use strict';
var assign = require('../../src/shared/stubs/Object.assign');
var grunt = require('grunt'); var grunt = require('grunt');
var rootIDs = [ var rootIDs = [
@ -21,23 +20,6 @@ var normal = {
outputDir: 'build/modules', outputDir: 'build/modules',
}; };
var test = {
rootIDs: rootIDs.concat([
'test/all.js',
'**/__tests__/*.js',
]),
getConfig: function() {
return assign({}, normal.getConfig(), {
mocking: true,
});
},
sourceDir: 'src',
outputDir: 'build/modules',
};
module.exports = { module.exports = {
normal: normal, normal: normal,
test: test,
}; };

View File

@ -1,32 +0,0 @@
'use strict';
module.exports = function(grunt) {
var jasmine = {
rootDirectory: 'build/jasmine',
// This syntax means to require and expose the 'jasmine' module
// (build/jasmine/jasmine.js) as global.jasmine, and to require the
// 'all' module (build/jasmine/all.js) but not expose it globally.
args: ['jasmine:jasmine', 'all:'],
outfile: './build/jasmine.js',
};
var filterExpr = grunt.option('filter');
if (filterExpr) {
filterExpr = '**/__tests__/' + filterExpr + '-test.js';
} else {
filterExpr = '**/__tests__/*-test.js';
}
var test = {
rootDirectory: 'build/modules',
args: ['test/all:harness'],
requires: [filterExpr],
outfile: './build/react-test.js',
};
return {
jasmine: jasmine,
test: test,
};
};

View File

@ -1,112 +0,0 @@
'use strict';
var fs = require('fs');
var path = require('path');
module.exports = function(grunt) {
var coverageWriteStream;
grunt.task.registerTask('finalize-coverage-stream', function() {
if (!coverageWriteStream) {
return;
}
var done = this.async();
coverageWriteStream.once('close', done);
coverageWriteStream.end();
coverageWriteStream = null;
});
function consoleLoggerMiddleware(req, res, next) {
if (!(req.method === 'POST' && req._parsedUrl.pathname.replace(/\//g, '') === 'console' && Array.isArray(req.body))) {
return next();
}
res.write('<!doctype html><meta charset=utf-8>');
res.end('Got it, thanks!');
req.body.forEach(function(log) {
if (log.message.indexOf('not ok ') === 0) {
log.type = 'error';
} else if (log.message.indexOf('ok ') === 0) {
log.type = 'ok';
} else if (log.message.indexOf('COVER') === 0) {
log.type = 'coverage';
} else if (log.message.indexOf('DONE\t') === 0) {
log.type = 'coverage done';
}
if (log.type === 'error') {
grunt.log.error(log.message);
} else if (log.type === 'ok') {
grunt.log.ok(log.message);
} else if (log.type === 'log') {
grunt.log.writeln(log.message);
} else if (log.type === 'coverage') {
if (!coverageWriteStream) {
coverageWriteStream = fs.createWriteStream(path.join(__dirname, '/../../coverage.log'));
}
coverageWriteStream.write(log.message + '\n');
} else if (log.type === 'coverage done') {
grunt.task.run('finalize-coverage-stream');
} else if (log.type === 'perf') {
grunt.event.emit('perf results', log.message);
} else {
grunt.verbose.writeln(log);
}
});
}
function testResultLoggerMiddleware(req, res, next) {
if (!(req.method === 'POST' && req._parsedUrl.pathname.indexOf('/reportTestResults') === 0)) {
return next();
}
res.write('<!doctype html><meta charset=utf-8>');
res.end('Got it, thanks!');
var logType = 'writeln';
var message = req.body;
if (req.body.type && req.body.message) {
if (req.body.type === 'error') {
logType = 'error';
} else if (req.body.message.indexOf('ok') === 0) {
logType = 'ok';
} else if (req.body.message.indexOf('not ok') === 0) {
logType = 'error';
}
message = req.body.message;
}
if (typeof message !== 'string') {
message = JSON.stringify(message, null, 2);
}
grunt.log[logType]('[%s][%s]', req.headers['user-agent'], Date.now(), message);
}
return {
server: {
options: {
base: '.',
hostname: '*',
port: 9999,
middleware: function(connect, options) {
connect.logger.token('user-agent', function(req, res) {
return req.headers['user-agent'];
});
connect.logger.token('timestamp', function(req, res) {
return Date.now();
});
return [
connect.json(),
consoleLoggerMiddleware,
testResultLoggerMiddleware,
connect.logger({format:'[:user-agent][:timestamp] :method :url', stream:grunt.verbose}),
connect.static(options.base),
connect.directory(options.base),
];
},
},
},
};
};

View File

@ -1,115 +0,0 @@
'use strict';
var grunt = require('grunt');
module.exports = function(props) {
if (typeof props.url !== 'string') {
throw TypeError('expected url string');
}
if ('isDoneTimeout' in props && typeof props.isDoneTimeout !== 'number') {
throw TypeError('expected isDoneTimeout to be a number');
}
if ('onStart' in props && typeof props.onStart !== 'function') {
throw TypeError('expected onStart to be a function');
}
if ('onComplete' in props && typeof props.onComplete !== 'function') {
throw TypeError('expected onComplete to be a function');
}
if ('onError' in props && typeof props.onError !== 'function') {
throw TypeError('expected onError to be a function');
}
var exports = {};
exports.local = {
webdriver: {
remote: {protocol: 'http:', hostname: '127.0.0.1', port: 9515, path: '/'},
},
url: props.url,
onStart: props.onStart,
onComplete: props.onComplete,
onError: props.onError,
isDoneTimeout: props.isDoneTimeout,
};
if (grunt.option('debug')) {
exports.local.url += (exports.local.url.indexOf('?') === -1 ? '?' : '&') + 'debug=' + grunt.option('debug');
}
exports.saucelabs = {
webdriver: {
remote: {
/* https://github.com/admc/wd/blob/master/README.md#named-parameters */
user: process.env.SAUCE_USERNAME || 'React',
pwd: process.env.SAUCE_ACCESS_KEY || '339d32ca-d594-4570-a3c2-94c50a91919b',
protocol: 'http:',
hostname: 'ondemand.saucelabs.com',
port: '80',
path: '/wd/hub',
},
},
desiredCapabilities: {
'build': process.env.TRAVIS_BUILD_NUMBER || 'dev' + Date.now(),
'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER || 'my awesome tunnel',
'browserName': 'chrome',
},
url: exports.local.url,
onStart: function(browser) {
grunt.log.writeln('Starting WebDriver Test. Watch results here: http://saucelabs.com/tests/' + browser.sessionID);
if (props.onStart) {
return props.onStart(browser);
}
},
onComplete: exports.local.onComplete,
onError: exports.local.onError,
isDoneTimeout: exports.local.isDoneTimeout,
};
/*eslint-disable camelcase*/
/* https://saucelabs.com/platforms */
exports.saucelabs_ios =
exports.saucelabs_ios7 = sauceItUp({browserName: 'iphone', version: '7', platform:'OS X 10.9'});
exports.saucelabs_ios6_1 = sauceItUp({browserName: 'iphone', version: '6.1', platform:'OS X 10.8'});
exports.saucelabs_ios6 = sauceItUp({browserName: 'iphone', version: '6', platform:'OS X 10.8'});
exports.saucelabs_ios5_1 = sauceItUp({browserName: 'iphone', version: '5.1', platform:'OS X 10.8'});
exports.saucelabs_ios5 = sauceItUp({browserName: 'iphone', version: '5', platform:'OS X 10.6'});
exports.saucelabs_ios4 = sauceItUp({browserName: 'iphone', version: '4', platform:'OS X 10.6'});
exports.saucelabs_ipad =
exports.saucelabs_ipad7 = sauceItUp({browserName: 'ipad', version: '7', platform:'OS X 10.9'});
exports.saucelabs_ipad6_1 = sauceItUp({browserName: 'ipad', version: '6.1', platform:'OS X 10.8'});
exports.saucelabs_ipad6 = sauceItUp({browserName: 'ipad', version: '6', platform:'OS X 10.8'});
exports.saucelabs_ipad5_1 = sauceItUp({browserName: 'ipad', version: '5.1', platform:'OS X 10.8'});
exports.saucelabs_ipad5 = sauceItUp({browserName: 'ipad', version: '5', platform:'OS X 10.6'});
exports.saucelabs_ipad4 = sauceItUp({browserName: 'ipad', version: '4', platform:'OS X 10.6'});
exports.saucelabs_android = sauceItUp({browserName: 'android', version: '4.0', platform:'Linux'});
exports.saucelabs_android_tablet = sauceItUp({browserName: 'android', version: '4.0', platform:'Linux', 'device-type':'tablet'});
exports.saucelabs_safari = sauceItUp({browserName: 'safari'});
exports.saucelabs_chrome = sauceItUp({browserName: 'chrome'});
exports.saucelabs_firefox = sauceItUp({browserName: 'firefox'});
exports.saucelabs_ie =
exports.saucelabs_ie8 = sauceItUp({browserName: 'internet explorer', version: 8});
exports.saucelabs_ie9 = sauceItUp({browserName: 'internet explorer', version: 9});
exports.saucelabs_ie10 = sauceItUp({browserName: 'internet explorer', version: 10});
exports.saucelabs_ie11 = sauceItUp({browserName: 'internet explorer', version: 11, platform:'Windows 8.1'});
/*eslint-enable camelcase*/
function sauceItUp(desiredCapabilities) {
desiredCapabilities.build = exports.saucelabs.desiredCapabilities.build;
desiredCapabilities['tunnel-identifier'] = exports.saucelabs.desiredCapabilities['tunnel-identifier'];
return {
webdriver: exports.saucelabs.webdriver,
url: exports.saucelabs.url,
onStart: exports.saucelabs.onStart,
onComplete: exports.saucelabs.onComplete,
onError: exports.saucelabs.onError,
isDoneTimeout: exports.saucelabs.isDoneTimeout,
desiredCapabilities: desiredCapabilities,
};
}
return exports;
};

View File

@ -1,15 +0,0 @@
'use strict';
var grunt = require('grunt');
module.exports = require('./webdriver-all')({
url: 'http://127.0.0.1:9999/test/index.html',
onComplete: function(passed) {
if (!passed) {
grunt.fatal('tests failed');
}
},
onError: function(error) {
grunt.fatal(error);
},
});

View File

@ -1,54 +0,0 @@
'use strict';
var grunt = require('grunt');
var path = require('path');
var fs = require('fs');
module.exports = function() {
var ROOT = path.join(__dirname, '/../..');
var done = this.async();
var uncoveredExpressionCount = 0;
var uncoveredLineCount = 0;
fs.createReadStream(ROOT + '/coverage.log')
.pipe(require('coverify/parse')(function(error, results) {
if (error) {
grunt.fatal(error);
}
Object.keys(results)
.sort(function(a, b) {
return results[a].length - results[b].length;
})
.reverse()
.forEach(function(concretePath) {
if (results[concretePath].length === 0) {
return;
}
var relativePath = concretePath.replace(ROOT, '');
uncoveredExpressionCount += results[concretePath].length;
grunt.log.error(results[concretePath].length + ' expressions not covered ' + relativePath);
results[concretePath].forEach(function(c) {
uncoveredLineCount += c.code.split('\n').length;
console.log('txmt://open?url=' + encodeURIComponent('file://' + concretePath) + '&line=' + (c.lineNum + 1) + '&column=' + (c.column[0] + 2));
});
console.log('');
});
Object.keys(results).sort().forEach(function(concretePath) {
if (results[concretePath].length > 0) {
return;
}
var relativePath = concretePath.replace(ROOT, '');
grunt.log.ok('100% coverage ' + relativePath);
});
if (uncoveredExpressionCount > 0) {
grunt.log.error(uncoveredExpressionCount + ' expressions not covered');
}
if (uncoveredLineCount > 0) {
grunt.log.error(uncoveredLineCount + ' lines not covered');
}
done();
}));
};

View File

@ -1,47 +0,0 @@
'use strict';
var grunt = require('grunt');
var http = require('http');
var fs = require('fs');
var path = require('path');
function get(url, targetFilePath, completedSuccessfully) {
grunt.verbose.writeln('getting url \'' + url + '\'');
http.get(url, function(response) {
grunt.verbose.writeln('Received status code ' + response.statusCode + ' for \'' + url + '\'');
if (response.statusCode !== 200) {
if (response.headers.location) {
get(response.headers.location, targetFilePath);
return;
} else {
grunt.fatal('Nothing else to do.');
completedSuccessfully(false);
return;
}
}
grunt.verbose.writeln('Writing url to \'' + targetFilePath + '\'');
response.pipe(fs.createWriteStream(targetFilePath))
.on('close', function() {
completedSuccessfully(true);
});
});
}
module.exports = function() {
var completedSuccessfully = this.async();
get(
'http://react.zpao.com/builds/master/latest/react.min.js',
path.join(__dirname, '/../../build/react-previous.min.js'),
function(success) {
if (!success) {
return completedSuccessfully(success);
}
get(
'http://react.zpao.com/builds/master/latest/JSXTransformer.js',
path.join(__dirname, '/../../build/JSXTransformer-previous.js'),
completedSuccessfully
);
}
);
};

View File

@ -1,40 +0,0 @@
'use strict';
var grunt = require('grunt');
var fs = require('fs');
var path = require('path');
module.exports = function() {
var config = this.data;
var done = this.async();
var theFilesToTestScript = fs.createWriteStream(path.join(__dirname, '/../../test/the-files-to-test.generated.js'));
theFilesToTestScript.write('// Generated by ');
theFilesToTestScript.write(JSON.stringify(__filename.split(/(?=grunt)/)[1]));
theFilesToTestScript.write(' at ');
theFilesToTestScript.write(JSON.stringify(new Date()));
theFilesToTestScript.write('\n\n');
// create the bundle we'll work with
var args = config.args;
// Make sure the things that need to be exposed are.
var requires = config.requires || [];
grunt.file.expand({
nonull: true, // Keep IDs that don't expand to anything.
cwd: config.rootDirectory,
}, requires).forEach(function(name) {
name = name.replace(/\.js$/i, '');
args.push(name);
theFilesToTestScript.write('harness.enableTest(' + JSON.stringify(name) + ');\n');
});
require('populist').buildP({
rootDirectory: config.rootDirectory,
args: args,
}).then(function(output) {
grunt.file.write(config.outfile, 'process = {env: {}};' + output);
theFilesToTestScript.end();
theFilesToTestScript.once('close', done);
});
};

View File

@ -1,43 +0,0 @@
'use strict';
var grunt = require('grunt');
var SauceTunnel = require('sauce-tunnel');
module.exports = function() {
var task = this;
var shouldStayAliveForever = task.flags.keepalive;
var SAUCE_ACCESS_KEY = process.env.SAUCE_ACCESS_KEY || '339d32ca-d594-4570-a3c2-94c50a91919b';
if (!SAUCE_ACCESS_KEY) {
grunt.fatal('Requires the environment variable SAUCE_ACCESS_KEY to be set');
}
var SAUCE_USERNAME = process.env.SAUCE_USERNAME || 'React';
if (!SAUCE_USERNAME) {
grunt.fatal('Requires the environment variable SAUCE_USERNAME to be set');
}
var IDENTIFIER = process.env.TRAVIS_JOB_NUMBER || 'my awesome tunnel';
var taskCompletedSuccessfully = task.async();
var stunnel = new SauceTunnel(SAUCE_USERNAME, SAUCE_ACCESS_KEY, IDENTIFIER, /*tunneled*/true, /*tunnelTimeout*/5);
process.on('exit', stunnel.stop.bind(stunnel, function() {}));
stunnel.on('log:error', grunt.log.error.bind(grunt.log));
stunnel.on('log:writeln', grunt.log.writeln.bind(grunt.log));
stunnel.on('verbose:ok', grunt.verbose.ok.bind(grunt.verbose));
stunnel.on('verbose:error', grunt.verbose.error.bind(grunt.verbose));
stunnel.on('verbose:debug', grunt.verbose.debug.bind(grunt.verbose));
stunnel.on('verbose:writeln', grunt.verbose.writeln.bind(grunt.verbose));
stunnel.openTunnel(function(isOpen) {
if (shouldStayAliveForever && isOpen) {
grunt.verbose.writeln('Keeping the sauce-tunnel open forever because you used the keepalive flag `' + task.nameArgs + '`');
return;
}
grunt.verbose.writeln('To keep the sauce-tunnel open forever, use the grunt task `' + task.nameArgs + ':keepalive`');
taskCompletedSuccessfully(isOpen);
});
};

View File

@ -1,77 +0,0 @@
/*eslint-disable consistent-return*/
'use strict';
var grunt = require('grunt');
var wd = require('wd');
module.exports = function task(getJSReport) {
var config = this.data;
var taskSucceeded = this.async();
getJSReport = getJSReport.bind(this, config, wd);
var desiredCapabilities = {};
if (config.desiredCapabilities) {
Object.keys(config.desiredCapabilities).forEach(function(key) {
if (config.desiredCapabilities[key] === undefined) {
return;
}
desiredCapabilities[key] = config.desiredCapabilities[key];
});
}
grunt.verbose.writeln('desiredCapabilities', JSON.stringify(desiredCapabilities));
var browser = wd.promiseChainRemote(config.webdriver.remote);
browser.on('status', function(info) {
grunt.verbose.writeln(info);
});
browser.on('command', function(meth, path, data) {
grunt.verbose.writeln(' > ' + meth, path, data || '');
});
var results = null;
// browser._debugPromise();
browser
.init(desiredCapabilities)
.then(config.onStart && config.onStart.bind(config, browser))
.get(config.url)
.then(function() {
return browser;
})
.then(getJSReport)
.then(function(data) {
results = data;
})
.fail(function(error) {
grunt.log.error(error);
return browser
.eval('document.documentElement.innerText || document.documentElement.textContent')
.then(grunt.verbose.writeln.bind(grunt.verbose))
.then(function() {
throw error;
});
})
.finally(function() {
if (grunt.option('webdriver-keep-open')) {
return;
}
grunt.verbose.writeln('Closing the browser window. To keep it open, pass the --webdriver-keep-open flag to grunt.');
return browser.quit();
})
.done(
function() {
if (config.onComplete) {
config.onComplete(results);
}
taskSucceeded(true);
},
function(error) {
if (config.onError) {
config.onError(error);
}
taskSucceeded(false);
}
);
};

View File

@ -1,14 +0,0 @@
'use strict';
module.exports = function() {
return require('./webdriver-all').call(this, function(config, wd, browser) {
return browser
.waitFor(wd.asserters.jsCondition('typeof window.jasmine != \'undefined\''), 5e3, 50)
.fail(function(error) {
throw Error('The test page didn\'t load properly. ' + error);
})
.waitFor(wd.asserters.jsCondition('typeof window.jasmine.getJSReport != \'undefined\''), 60e3, 100)
.waitFor(wd.asserters.jsCondition('window.postDataToURL.running <= 0'), 30e3, 500)
.eval('jasmine.getJSReport().passed');
});
};

View File

@ -1,41 +0,0 @@
'use strict';
var grunt = require('grunt');
module.exports = function() {
var onReadyCallback = this.async();
var phantomjs = require('phantomjs').path;
var childProcess = require('child_process');
var config = this.data || {};
var args = ['--webdriver=' + (config.port || 9515)];
grunt.verbose.writeln('phantomjs START path:%s args:%s', phantomjs, args);
var child = childProcess.spawn(phantomjs, args);
process.on('exit', function() {
child.kill();
});
child.on('error', function(error) {
grunt.verbose.writeln('phantomjs ERROR');
grunt.fatal(error);
});
child.on('exit', function(code) {
grunt.verbose.writeln('phantomjs END');
if (code) {
grunt.fatal('phantomjs FAIL');
}
});
function verboseWrite(chunk) {
if (onReadyCallback && chunk.toString().indexOf('running on port') !== -1) {
grunt.verbose.writeln('phantomjs STARTED');
onReadyCallback();
onReadyCallback = null;
}
grunt.verbose.write(chunk);
}
child.stdout.on('data', verboseWrite);
child.stderr.on('data', verboseWrite);
};

View File

@ -35,10 +35,8 @@
"browserify": "^9.0.3", "browserify": "^9.0.3",
"bundle-collapser": "^1.1.1", "bundle-collapser": "^1.1.1",
"coffee-script": "^1.8.0", "coffee-script": "^1.8.0",
"coverify": "^1.3.3",
"derequire": "^2.0.0", "derequire": "^2.0.0",
"envify": "^3.0.0", "envify": "^3.0.0",
"es5-shim": "^4.0.0",
"eslint": "^0.22.1", "eslint": "^0.22.1",
"eslint-plugin-react": "^2.5.0", "eslint-plugin-react": "^2.5.0",
"eslint-plugin-react-internal": "file:eslint-rules", "eslint-plugin-react-internal": "file:eslint-rules",
@ -48,22 +46,16 @@
"grunt-compare-size": "^0.4.0", "grunt-compare-size": "^0.4.0",
"grunt-contrib-clean": "^0.6.0", "grunt-contrib-clean": "^0.6.0",
"grunt-contrib-compress": "^0.13.0", "grunt-contrib-compress": "^0.13.0",
"grunt-contrib-connect": "~0.6.0",
"grunt-jest": "^0.1.3", "grunt-jest": "^0.1.3",
"gzip-js": "~0.3.2", "gzip-js": "~0.3.2",
"jasmine-tapreporter": "~0.2.2",
"jest-cli": "^0.4.13", "jest-cli": "^0.4.13",
"object-assign": "^3.0.0", "object-assign": "^3.0.0",
"optimist": "^0.6.1", "optimist": "^0.6.1",
"phantomjs": "^1.9.17",
"platform": "^1.1.0", "platform": "^1.1.0",
"populist": "~0.1.6",
"sauce-tunnel": "~1.1.0",
"tmp": "~0.0.18", "tmp": "~0.0.18",
"typescript": "^1.4.0", "typescript": "^1.4.0",
"uglify-js": "^2.4.23", "uglify-js": "^2.4.23",
"uglifyify": "^3.0.1", "uglifyify": "^3.0.1"
"wd": "~0.2.6"
}, },
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"

View File

@ -1,31 +0,0 @@
// This file exists both to give a single entry point for all the utility
// modules in src/test and to specify an ordering on those modules, since
// some still have implicit dependencies on others.
require("./phantomjs-shims");
require("ReactTestUtils");
require("reactComponentExpect");
require("mocks");
require("mock-modules");
require("./mock-timers");
exports.enableTest = function(testID) {
describe(testID, function() {
beforeEach(function() {
require("mock-modules").setMockMap(mockMap);
});
require("mock-modules").clearMockMap();
require("../" + testID);
var mockMap = require("mock-modules").getMockMap();
});
};
exports.removeNextSiblings = function(node) {
var parent = node && node.parentNode;
if (parent) {
while (node.nextSibling) {
parent.removeChild(node.nextSibling);
}
}
};

View File

@ -1,125 +0,0 @@
/**
* Copyright 2013-2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule mock-modules
*/
var mocks = require("mocks");
var exportsRegistry = {};
var hasOwn = exportsRegistry.hasOwnProperty;
var explicitMockMap = {};
function getMock(exports) {
try {
return mocks.generateFromMetadata(mocks.getMetadata(exports));
} catch (err) {
console.warn(err);
return exports;
}
}
// This function should be called at the bottom of any module that might
// need to be mocked, after the final value of module.exports is known.
exports.register = function(id, module) {
exportsRegistry[id] = {
module: module,
actual: module.exports,
mocked: null // Filled in lazily later.
};
// If doMock or doNotMock was called earlier, before the module was
// registered, then the choice should have been recorded in
// explicitMockMap. Now that the module is registered, we can finally
// fulfill the request.
if (hasOwn.call(explicitMockMap, id)) {
if (explicitMockMap[id]) {
doMock(id);
} else {
doNotMock(id);
}
}
return exports;
};
function resetEntry(id) {
if (hasOwn.call(exportsRegistry, id)) {
delete exportsRegistry[id].module.exports;
delete exportsRegistry[id];
}
}
exports.dumpCache = function() {
require("mocks").clear();
// Deleting module.exports will cause the module to be lazily
// reevaluated the next time it is required.
for (var id in exportsRegistry) {
resetEntry(id);
}
return exports;
};
exports.getMockMap = function() {
return explicitMockMap;
};
exports.clearMockMap = function() {
explicitMockMap = {};
};
exports.setMockMap = function(mockMap) {
exports.dumpCache();
exports.clearMockMap();
for (var id in mockMap) {
if (mockMap[id]) {
doMock(id);
} else {
doNotMock(id);
}
}
return exports;
};
// Call this function to ensure that require(id) returns the actual
// exports object created by the module.
function doNotMock(id) {
explicitMockMap[id] = false;
var entry = exportsRegistry[id];
if (entry && entry.module && entry.actual) {
entry.module.exports = entry.actual;
}
return exports;
}
// Call this function to ensure that require(id) returns a mock exports
// object based on the actual exports object created by the module.
function doMock(id) {
explicitMockMap[id] = true;
var entry = exportsRegistry[id];
if (entry && entry.module && entry.actual) {
// Because mocking can be expensive, create the mock exports object on
// demand, the first time doMock is called.
entry.mocked || (entry.mocked = getMock(entry.actual));
entry.module.exports = entry.mocked;
}
return exports;
}
var global = Function("return this")();
require('test/mock-timers').installMockTimers(global);
// Exported names are different for backwards compatibility.
exports.dontMock = doNotMock;
exports.mock = doMock;

View File

@ -1,219 +0,0 @@
var mocks = require('mocks');
var timers = {};
// Keep a fake timestamp
// move on the time when runTimersToTime() is called
var now = 0;
// add a timer of type either 'timeout' or 'interval'
function _setTimer(type, callback, delay) {
var token = null;
do {
token = Math.floor(Math.random() * 4294967296) + 1;
} while (timers[token]);
timers[token] = {
type: type,
callback: callback,
// Add some random msecs to the delay to mimic code execution time.
time: now + delay + Math.floor(Math.random() * 5),
interval: (type == 'interval' ? delay : 0)
};
return token;
}
// clear a timer of type either 'timeout' or 'interval'
function _clearTimer(type, token) {
if (timers[token] && timers[token].type == type) {
delete timers[token];
}
}
function _setTimeout(callback, delay) {
return _setTimer('timeout', callback, delay);
}
function _setInterval(callback, delay) {
return _setTimer('interval', callback, delay);
}
function _clearTimeout(token) {
_clearTimer('timeout', token);
}
function _clearInterval(token) {
_clearTimer('interval', token);
}
// Run timer of given token
function _runTimer(token) {
// Skip non-existing token
if (timers[token]) {
if (timers[token].type == 'timeout') {
// for 'timeout', run callback and delete the timer
var callback = timers[token].callback;
delete timers[token];
callback();
} else if (timers[token].type == 'interval') {
// for 'interval', run callback and set the next invoke time
// Add some random msecs to the delay to mimic code execution time.
timers[token].time =
now + timers[token].interval + Math.floor(Math.random() * 5);
timers[token].callback();
}
}
}
function _runTimersOnce() {
// Invoke all timers once regardsless of the delay
for (var token in timers) {
_runTimer(token);
}
}
function _runTimersToTime(delay) {
var toRunToken = _getNextTimerToken();
if (!toRunToken) {
return;
}
var minTime = timers[toRunToken].time;
if (now + delay < minTime) {
// Termination when there's no more timers to invoke
now += delay;
} else {
// Recursively invoke the next to-run timer
delay -= (minTime - now);
now = minTime;
_runTimer(toRunToken);
_runTimersToTime(delay);
}
}
function _runTimersRepeatedly() {
// Only run a generous 1000 timers and then bail, since we may have entered
// a loop if we have more than that.
var max_timers = 1000;
var token;
for (var ii = 0; ii < max_timers; ii++) {
token = _getNextTimerToken();
if (!token) {
break;
}
_runTimer(token);
}
if (ii === max_timers) {
throw new Error("More timers still exist after " + max_timers + " timers!");
}
}
function _clearTimers() {
for (var token in timers) {
delete timers[token];
}
}
function _getNextTimerToken() {
var nextTimerToken = null;
var minTime = 31536000000; // One year
// Find the next to invoke timer
for (var token in timers) {
if (timers[token].time < minTime) {
nextTimerToken = token;
minTime = timers[token].time;
}
}
return nextTimerToken;
}
var mockTimers = {
setTimeout: _setTimeout,
clearTimeout: _clearTimeout,
setInterval: _setInterval,
clearInterval: _clearInterval,
/**
* Copyright 2013-2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* Iteratively run callbacks in time order during the time from now to
* now + delay.
* If one callback register another timer which should be run during now to
* now + delay, the new timer will also be run in the right order.
*
* @param delay
*/
runTimersToTime: _runTimersToTime,
/**
* Run all registered timer once. Newly registered timers will not be run.
*/
runTimersOnce: _runTimersOnce,
/**
* Iteratively run callbacks until there are no timers left to call. Will
* stop after a maximum number of iterations to avoid infinite loop.
*
* @param maximum iterations (optional)
*/
runTimersRepeatedly: _runTimersRepeatedly,
/**
* Clear all timers
*/
clearTimers: _clearTimers,
/**
* Get the number of remaining timers
*/
getTimersCount: function() {
return Object.keys(timers).length;
}
};
module.exports.installMockTimers = function(window) {
window._originalTimeouts = {
setTimeout: window.setTimeout,
clearTimeout: window.clearTimeout,
setInterval: window.setInterval,
clearInterval: window.clearInterval
};
window.setTimeout =
mocks.getMockFunction().mockImplementation(mockTimers.setTimeout);
window.clearTimeout =
mocks.getMockFunction().mockImplementation(mockTimers.clearTimeout);
window.setInterval =
mocks.getMockFunction().mockImplementation(mockTimers.setInterval);
window.clearInterval =
mocks.getMockFunction().mockImplementation(mockTimers.clearInterval);
window.mockRunTimersOnce =
mocks.getMockFunction().mockImplementation(mockTimers.runTimersOnce);
window.mockRunTimersToTime =
mocks.getMockFunction().mockImplementation(mockTimers.runTimersToTime);
window.mockRunTimersRepeatedly =
mocks.getMockFunction().mockImplementation(mockTimers.runTimersRepeatedly);
window.mockClearTimers =
mocks.getMockFunction().mockImplementation(mockTimers.clearTimers);
window.mockGetTimersCount =
mocks.getMockFunction().mockImplementation(mockTimers.getTimersCount);
};
module.exports.uninstallMockTimers = function(window) {
window.setTimeout = window._originalTimeouts.setTimeout;
window.clearTimeout = window._originalTimeouts.clearTimeout;
window.setInterval = window._originalTimeouts.setInterval;
window.clearInterval = window._originalTimeouts.clearInterval;
window._originalTimeouts = undefined;
window.mockRunTimersOnce = undefined;
window.mockRunTimersToTime = undefined;
window.mockRunTimersRepeatedly = undefined;
window.mockClearTimers = undefined;
window.mockGetTimersCount = undefined;
};

View File

@ -1,425 +0,0 @@
/**
* Copyright 2013-2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule mocks
*/
function isA(typeName, value) {
return Object.prototype.toString.apply(value) === '[object ' + typeName + ']';
}
function getType(ref) {
if (isA('RegExp', ref)) {
return 'regexp';
}
if (isA('Array', ref)) {
return 'array';
}
if (isA('Function', ref)) {
return 'function';
}
if (isA('Object', ref)) {
return 'object';
}
// consider number and string fields to be constants that we want to
// pick up as they are
if (isA('Number', ref) || isA('String', ref)) {
return 'constant';
}
return null;
}
function makeComponent(metadata) {
switch (metadata.type) {
case 'object':
return {};
case 'array':
return [];
case 'regexp':
return new RegExp();
case 'constant':
return metadata.value;
case 'function':
var defaultReturnValue;
var specificReturnValues = [];
var mockImpl;
var isReturnValueLastSet = false;
var calls = [];
var instances = [];
var prototype =
(metadata.members && metadata.members.prototype &&
metadata.members.prototype.members) || {};
var f = function() {
global.dirtyMocks.push(f);
instances.push(this);
calls.push(Array.prototype.slice.call(arguments));
if (this instanceof f) {
// This is probably being called as a constructor
for (var slot in prototype) {
// Copy prototype methods to the instance to make
// it easier to interact with mock instance call and
// return values
if (prototype[slot].type == 'function') {
var protoImpl = this[slot];
this[slot] = generateFromMetadata(prototype[slot]);
this[slot]._protoImpl = protoImpl;
}
}
// Run the mock constructor implementation
mockImpl && mockImpl.apply(this, arguments);
return;
}
var returnValue;
// If return value is last set, either specific or default, i.e.
// mockReturnValueOnce()/mockReturnValue() is called and no
// mockImplementation() is called after that.
// use the set return value.
if (isReturnValueLastSet) {
returnValue = specificReturnValues.shift();
if (returnValue === undefined) {
returnValue = defaultReturnValue;
}
}
// If mockImplementation() is last set, or specific return values
// are used up, use the mock implementation.
if (mockImpl && returnValue === undefined) {
return mockImpl.apply(this, arguments);
}
// Otherwise use prototype implementation
if (returnValue === undefined && f._protoImpl) {
return f._protoImpl.apply(this, arguments);
}
return returnValue;
};
f._isMockFunction = true;
f.mock = {
calls: calls,
instances: instances
};
f.mockClear = function() {
calls.length = 0;
instances.length = 0;
};
f.mockReturnValueOnce = function(value) {
// next function call will return this value or default return value
isReturnValueLastSet = true;
specificReturnValues.push(value);
return f;
};
f.mockReturnValue = function(value) {
// next function call will return specified return value or this one
isReturnValueLastSet = true;
defaultReturnValue = value;
return f;
};
f.mockImplementation = function(fn) {
// next function call will use mock implementation return value
isReturnValueLastSet = false;
mockImpl = fn;
return f;
};
f.mockReturnThis = function() {
return f.mockImplementation(function() {
return this;
});
};
f._getMockImplementation = function() {
return mockImpl;
};
if (metadata.mockImpl) {
f.mockImplementation(metadata.mockImpl);
}
return f;
}
throw new Error('Unrecognized type ' + metadata.type);
}
function generateFromMetadata(_metadata) {
var callbacks = [];
var refs = {};
function generateMock(metadata) {
var mock = makeComponent(metadata);
if (metadata.ref_id != null) {
refs[metadata.ref_id] = mock;
}
function getRefCallback(slot, ref) {
return function() {
mock[slot] = refs[ref];
};
}
for (var slot in metadata.members) {
var slotMetadata = metadata.members[slot];
if (slotMetadata.ref != null) {
callbacks.push(getRefCallback(slot, slotMetadata.ref));
} else {
mock[slot] = generateMock(slotMetadata);
}
}
return mock;
}
var mock = generateMock(_metadata);
callbacks.forEach(function(setter) {
setter();
});
return mock;
}
function _getMetadata(component, _refs) {
var refs = _refs || [];
// This is a potential performance drain, since the whole list is scanned
// for every component
var ref = refs.indexOf(component);
if (ref > -1) {
return {ref: ref};
}
var type = getType(component);
if (!type) {
return null;
}
var metadata = {type: type};
if (type == 'constant') {
metadata.value = component;
return metadata;
} else if (type == 'function') {
if (component._isMockFunction) {
metadata.mockImpl = component._getMockImplementation();
}
}
metadata.ref_id = refs.length;
refs.push(component);
var members = null;
function addMember(slot, data) {
if (!data) {
return;
}
if (!members) {
members = {};
}
members[slot] = data;
}
// Leave arrays alone
if (type != 'array') {
for (var slot in component) {
if (slot.charAt(0) == '_' ||
(type == 'function' && component._isMockFunction &&
slot.match(/^mock/))) {
continue;
}
if (component.hasOwnProperty(slot) ||
(type == 'object' && component[slot] != Object.prototype[slot])) {
addMember(slot, _getMetadata(component[slot], refs));
}
}
// If component is native code function, prototype might be undefined
if (type == 'function' && component.prototype) {
var prototype = _getMetadata(component.prototype, refs);
if (prototype && prototype.members) {
addMember('prototype', prototype);
}
}
}
if (members) {
metadata.members = members;
}
return metadata;
}
function removeUnusedRefs(metadata) {
function visit(md, f) {
f(md);
if (md.members) {
for (var slot in md.members) {
visit(md.members[slot], f);
}
}
}
var usedRefs = {};
visit(metadata, function(md) {
if (md.ref != null) {
usedRefs[md.ref] = true;
}
});
visit(metadata, function(md) {
if (!usedRefs[md.ref_id]) {
delete md.ref_id;
}
});
}
var global = Function("return this")();
global.dirtyMocks = global.dirtyMocks || [];
module.exports = {
/**
* Invokes the .mockClear method of all function mocks that have been
* called since the last time clear was called.
*/
clear: function() {
var old = global.dirtyMocks;
global.dirtyMocks = [];
old.forEach(function(mock) {
mock.mockClear();
});
},
/**
* Generates a mock based on the given metadata. Mocks treat functions
* specially, and all mock functions have additional members, described in the
* documentation for getMockFunction in this module.
*
* One important note: function prototoypes are handled specially by this
* mocking framework. For functions with prototypes, when called as a
* constructor, the mock will install mocked function members on the instance.
* This allows different instances of the same constructor to have different
* values for its mocks member and its return values.
*
* @param metadata Metadata for the mock in the schema returned by the
* getMetadata method of this module.
*
*/
generateFromMetadata: generateFromMetadata,
/**
* Inspects the argument and returns its schema in the following recursive
* format:
* {
* type: ...
* members : {}
* }
*
* Where type is one of 'array', 'object', 'function', or 'ref', and members
* is an optional dictionary where the keys are member names and the values
* are metadata objects. Function prototypes are defined simply by defining
* metadata for the member.prototype of the function. The type of a function
* prototype should always be "object". For instance, a simple class might be
* defined like this:
*
* {
* type: 'function',
* members: {
* staticMethod: {type: 'function'},
* prototype: {
* type: 'object',
* members: {
* instanceMethod: {type: 'function'}
* }
* }
* }
* }
*
* Metadata may also contain references to other objects defined within the
* same metadata object. The metadata for the referent must be marked with
* 'ref_id' key and an arbitrary value. The referer must be marked with a
* 'ref' key that has the same value as object with ref_id that it refers to.
* For instance, this metadata blob:
* {
* type: 'object',
* ref_id: 1,
* members: {
* self: {ref: 1}
* }
* }
*
* defines an object with a slot named 'self' that refers back to the object.
*
* @param {*} component The component for which to retrieve metadata.
*/
getMetadata: function(component) {
var metadata = _getMetadata(component);
// to make it easier to work with mock metadata, only preserve references
// that are actually used
removeUnusedRefs(metadata);
return metadata;
},
/**
* Generates a stand-alone function with members that help drive unit tests or
* confirm expectations. Specifically, functions returned by this method have
* the following members:
*
* .mock:
* An object with two members, "calls", and "instances", which are both
* lists. The items in the "calls" list are the arguments with which the
* function was called. The "instances" list stores the value of 'this' for
* each call to the function. This is useful for retrieving instances from a
* constructor.
*
* .mockReturnValueOnce(value)
* Pushes the given value onto a FIFO queue of return values for the
* function.
*
* .mockReturnValue(value)
* Sets the default return value for the function.
*
* .mockImplementation(function)
* Sets a mock implementation for the function.
*
* .mockReturnThis()
* Syntactic sugar for .mockImplementation(function() {return this;})
*
* In case both mockImplementation() and
* mockReturnValueOnce()/mockReturnValue() are called. The priority of
* which to use is based on what is the last call:
* - if the last call is mockReturnValueOnce() or mockReturnValue(),
* use the specific return specific return value or default return value.
* If specific return values are used up or no default return value is set,
* fall back to try mockImplementation();
* - if the last call is mockImplementation(), run the given implementation
* and return the result.
*/
getMockFunction: function() {
return makeComponent({type: 'function'});
}
};

View File

@ -1,35 +0,0 @@
(function() {
var Ap = Array.prototype;
var slice = Ap.slice;
var Fp = Function.prototype;
if (!Fp.bind) {
// PhantomJS doesn't support Function.prototype.bind natively, so
// polyfill it whenever this module is required.
Fp.bind = function(context) {
var func = this;
var args = slice.call(arguments, 1);
function bound() {
var invokedAsConstructor = func.prototype && (this instanceof func);
return func.apply(
// Ignore the context parameter when invoking the bound function
// as a constructor. Note that this includes not only constructor
// invocations using the new keyword but also calls to base class
// constructors such as BaseClass.call(this, ...) or super(...).
!invokedAsConstructor && context || this,
args.concat(slice.call(arguments))
);
}
// The bound function must share the .prototype of the unbound
// function so that any object created by one constructor will count
// as an instance of both constructors.
bound.prototype = func.prototype;
return bound;
};
}
})();

View File

@ -1,8 +0,0 @@
globals:
harness: true
rules:
strict: false
no-undef: false
no-unused-vars: false
block-scoped-var: false

View File

@ -1,38 +0,0 @@
<!doctype html>
<meta charset=utf-8>
<body>
<script>
;(function(){
var urls = [
'../src/shared/vendor/third_party/webcomponents.js',
'../vendor/jasmine/jasmine.js',
'../vendor/jasmine/jasmine-support.js',
'../vendor/jasmine/jasmine-html.js',
'../node_modules/jasmine-tapreporter/src/tapreporter.js',
'../vendor/jasmine-jsreporter/jasmine-jsreporter.js',
'lib/postDataToURL.browser.js',
'lib/reportTestResults.browser.js',
'lib/jasmine-execute.js',
'../build/react.js',
'../build/react-test.js',
'the-files-to-test.generated.js'
];
if (typeof Function.prototype.bind == 'undefined') {
urls.unshift('../node_modules/es5-shim/es5-sham.js');
urls.unshift('../node_modules/es5-shim/es5-shim.js');
}
var cacheBust = '?_=' + (+new Date).toString(36);
for (var urls_index = -1, urls_length = urls.length; ++urls_index < urls_length;) {
document.write('<script src="' + urls[urls_index] + cacheBust + '"><\/script>');
}
var base = location.protocol + '//' + location.hostname + ':' + location.port + location.pathname.replace(/^\/?/,'/').split('/').reverse().slice(1).reverse().join('/');
}());
</script>

View File

@ -1,47 +0,0 @@
document.write('<style> @import \'../vendor/jasmine/jasmine.css?_=' + (+new Date()).toString(36) + '\'; </style>');
(function(env) {
var htmlReporter = new jasmine.HtmlReporter();
env.addReporter(htmlReporter);
env.specFilter = function(spec) {
return htmlReporter.specFilter(spec);
};
// Clean up any nodes the previous test might have added.
env.afterEach(function() {
harness.removeNextSiblings(document.body);
harness.removeNextSiblings(document.getElementById('HTMLReporter'));
});
window.onload = function() {
env.execute();
};
var oldError = console.error;
var newError = function() {
oldError.apply(this, arguments);
var spec = env.currentSpec;
if (spec) {
var expectationResult = new jasmine.ExpectationResult({
passed: false,
message:
'Expected test not to warn. If the warning is expected, mock it ' +
'out using spyOn(console, \'error\'); and test that the warning ' +
'occurs.',
});
spec.addMatcherResult(expectationResult);
}
};
console.error = newError;
// Make sure console.error is set back at the end of each test, or else the
// above logic won't work
env.afterEach(function() {
if (console.error !== newError && !console.error.isSpy) {
var expectationResult = new jasmine.ExpectationResult({
passed: false,
message: 'Test did not tear down console.error mock properly.',
});
env.currentSpec.addMatcherResult(expectationResult);
}
});
})(jasmine.getEnv());

View File

@ -1,48 +0,0 @@
/*eslint-disable brace-style*/
function createXMLHttpRequest() {
try {
return new XMLHttpRequest();
}
catch(e) {}
try {
return new ActiveXObject('Msxml2.XMLHTTP');
}
catch (e) {}
try {
return new ActiveXObject('Microsoft.XMLHTTP');
}
catch (e) {}
}
/*eslint-enable brace-style*/
function getURLSync(url) {
var request = createXMLHttpRequest();
request.open('GET', url, /*asynchronous?*/false);
return request.responseText;
}
function postDataToURL(data, url, callback) {
if (!callback) {
callback = postDataToURL.defaultCallback;
}
var request = createXMLHttpRequest();
if (!request) {
return callback(Error('XMLHttpRequest is unsupported'));
}
postDataToURL.running = (postDataToURL.running || 0) + 1;
request.onreadystatechange = function() {
if (request.readyState !== 4) {
return;
}
request.onreadystatechange = null;
postDataToURL.running = (postDataToURL.running || 0) - 1;
callback(request.status === 200 ? null : request.status, request.responseText);
};
request.open('POST', url);
request.setRequestHeader('Content-Type', 'application/json');
request.send(JSON.stringify(data));
}
postDataToURL.defaultCallback = function(error) {
// console.log('postDataToURL.defaultCallback', arguments)
};

View File

@ -1,60 +0,0 @@
var __DEBUG__ = location.search.substring(1).indexOf('debug') !== -1;
if (typeof console === 'undefined') {
console = {
log: function() {},
warn: function() {},
error: function() {},
};
}
var __consoleReport__ = [];
console._log = console.log;
console.log = function(message) {
console._log(message);
if (__DEBUG__) {
postDataToURL({type:'log', message:message}, '/reportTestResults');
} else {
__consoleReport__.push({type:'log', message:message});
}
};
console._error = console.error;
console.error = function(message) {
console._error(message);
if (__DEBUG__) {
postDataToURL({type:'error', message:message}, '/reportTestResults');
} else {
__consoleReport__.push({type:'error', message:message});
}
};
console._flush = function() {
postDataToURL(__consoleReport__, '/console');
__consoleReport__.length = 0;
};
(function(env) {
env.addReporter(new jasmine.JSReporter());
env.addReporter(new TAPReporter(console.log.bind(console)));
function report() {
if (typeof jasmine.getJSReport !== 'function') {
return setTimeout(report, 100);
}
if (!__DEBUG__) {
console.log('DONE\t' + navigator.userAgent);
console._flush();
}
}
var oldCallback = env.currentRunner().finishCallback;
env.currentRunner().finishCallback = function() {
if (oldCallback) {
oldCallback.apply(this, arguments);
}
report();
};
}(window.jasmine.getEnv()));

View File

@ -1,162 +0,0 @@
/*
This file is part of the Jasmine JSReporter project from Ivan De Marino.
Copyright (C) 2011 Ivan De Marino (aka detro, aka detronizator), http://blog.ivandemarino.me, ivan.de.marino@gmail.com
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL IVAN DE MARINO BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
(function () {
// Ensure that Jasmine library is loaded first
if (typeof jasmine === "undefined") {
throw new Error("[Jasmine JSReporter] 'Jasmine' library not found");
}
/**
* Calculate elapsed time, in Seconds.
* @param startMs Start time in Milliseconds
* @param finishMs Finish time in Milliseconds
* @return Elapsed time in Seconds */
function elapsedSec (startMs, finishMs) {
return (finishMs - startMs) / 1000;
}
/**
* Round an amount to the given number of Digits.
* If no number of digits is given, than '2' is assumed.
* @param amount Amount to round
* @param numOfDecDigits Number of Digits to round to. Default value is '2'.
* @return Rounded amount */
function round (amount, numOfDecDigits) {
numOfDecDigits = numOfDecDigits || 2;
return Math.round(amount * Math.pow(10, numOfDecDigits)) / Math.pow(10, numOfDecDigits);
}
/**
* Collect information about a Suite, recursively, and return a JSON result.
* @param suite The Jasmine Suite to get data from
*/
function getSuiteData (suite) {
var suiteData = {
description : suite.description,
durationSec : 0,
specs: [],
suites: [],
passed: true
},
specs = suite.specs(),
suites = suite.suites(),
i, ilen;
// Loop over all the Suite's Specs
for (i = 0, ilen = specs.length; i < ilen; ++i) {
suiteData.specs[i] = {
description : specs[i].description,
durationSec : specs[i].durationSec,
passed : specs[i].results().passedCount === specs[i].results().totalCount,
skipped : specs[i].results().skipped,
passedCount : specs[i].results().passedCount,
failedCount : specs[i].results().failedCount,
totalCount : specs[i].results().totalCount
};
suiteData.passed = !suiteData.specs[i].passed ? false : suiteData.passed;
suiteData.durationSec += suiteData.specs[i].durationSec;
}
// Loop over all the Suite's sub-Suites
for (i = 0, ilen = suites.length; i < ilen; ++i) {
suiteData.suites[i] = getSuiteData(suites[i]); //< recursive population
suiteData.passed = !suiteData.suites[i].passed ? false : suiteData.passed;
suiteData.durationSec += suiteData.suites[i].durationSec;
}
// Rounding duration numbers to 3 decimal digits
suiteData.durationSec = round(suiteData.durationSec, 4);
return suiteData;
}
var JSReporter = function () {
};
JSReporter.prototype = {
reportRunnerStarting: function (runner) {
// Nothing to do
},
reportSpecStarting: function (spec) {
// Start timing this spec
spec.startedAt = new Date();
},
reportSpecResults: function (spec) {
// Finish timing this spec and calculate duration/delta (in sec)
spec.finishedAt = new Date();
// If the spec was skipped, reportSpecStarting is never called and spec.startedAt is undefined
spec.durationSec = spec.startedAt ? elapsedSec(spec.startedAt.getTime(), spec.finishedAt.getTime()) : 0;
},
reportSuiteResults: function (suite) {
// Nothing to do
},
reportRunnerResults: function (runner) {
var suites = runner.suites(),
i, ilen;
// Attach results to the "jasmine" object to make those results easy to scrap/find
jasmine.runnerResults = {
suites: [],
durationSec : 0,
passed : true
};
// Loop over all the Suites
for (i = 0, ilen = suites.length; i < ilen; ++i) {
if (suites[i].parentSuite === null) {
jasmine.runnerResults.suites[i] = getSuiteData(suites[i]);
// If 1 suite fails, the whole runner fails
jasmine.runnerResults.passed = !jasmine.runnerResults.suites[i].passed ? false : jasmine.runnerResults.passed;
// Add up all the durations
jasmine.runnerResults.durationSec += jasmine.runnerResults.suites[i].durationSec;
}
}
// Decorate the 'jasmine' object with getters
jasmine.getJSReport = function () {
if (jasmine.runnerResults) {
return jasmine.runnerResults;
}
return null;
};
jasmine.getJSReportAsString = function () {
return JSON.stringify(jasmine.getJSReport());
};
}
};
// export public
jasmine.JSReporter = JSReporter;
})();

View File

@ -1,168 +0,0 @@
var jasmine = require("./jasmine");
exports.HtmlReporter =
jasmine.HtmlReporter = function(_doc) {
var self = this;
var doc = _doc || window.document;
var reporterView;
var dom = {};
// Jasmine Reporter Public Interface
self.logRunningSpecs = false;
self.reportRunnerStarting = function(runner) {
var specs = runner.specs() || [];
if (specs.length == 0) {
return;
}
createReporterDom(runner.env.versionString());
doc.body.appendChild(dom.reporter);
setExceptionHandling();
reporterView = new jasmine.HtmlReporter.ReporterView(dom);
reporterView.addSpecs(specs, self.specFilter);
};
self.reportRunnerResults = function(runner) {
reporterView && reporterView.complete();
};
self.reportSuiteResults = function(suite) {
reporterView.suiteComplete(suite);
};
self.reportSpecStarting = function(spec) {
if (self.logRunningSpecs) {
self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
}
};
self.reportSpecResults = function(spec) {
reporterView.specComplete(spec);
};
self.log = function() {
var console = jasmine.getGlobal().console;
if (console && console.log) {
if (console.log.apply) {
console.log.apply(console, arguments);
} else {
console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
}
}
};
self.specFilter = function(spec) {
if (!focusedSpecName()) {
return true;
}
return spec.getFullName().indexOf(focusedSpecName()) === 0;
};
return self;
function focusedSpecName() {
var specName;
(function memoizeFocusedSpec() {
if (specName) {
return;
}
var paramMap = [];
var params = jasmine.HtmlReporter.parameters(doc);
for (var i = 0; i < params.length; i++) {
var p = params[i].split('=');
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
}
specName = paramMap.spec;
})();
return specName;
}
function createReporterDom(version) {
dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' },
dom.banner = self.createDom('div', { className: 'banner' },
self.createDom('span', { className: 'title' }, "Jasmine "),
self.createDom('span', { className: 'version' }, version)),
dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),
dom.alert = self.createDom('div', {className: 'alert'},
self.createDom('span', { className: 'exceptions' },
self.createDom('label', { className: 'label', 'for': 'no_try_catch' }, 'No try/catch'),
self.createDom('input', { id: 'no_try_catch', type: 'checkbox' }))),
dom.results = self.createDom('div', {className: 'results'},
dom.summary = self.createDom('div', { className: 'summary' }),
dom.details = self.createDom('div', { id: 'details' }))
);
}
function noTryCatch() {
return window.location.search.match(/catch=false/);
}
function searchWithCatch() {
var params = jasmine.HtmlReporter.parameters(window.document);
var removed = false;
var i = 0;
while (!removed && i < params.length) {
if (params[i].match(/catch=/)) {
params.splice(i, 1);
removed = true;
}
i++;
}
if (jasmine.CATCH_EXCEPTIONS) {
params.push("catch=false");
}
return params.join("&");
}
function setExceptionHandling() {
var chxCatch = document.getElementById('no_try_catch');
if (noTryCatch()) {
chxCatch.setAttribute('checked', true);
jasmine.CATCH_EXCEPTIONS = false;
}
chxCatch.onclick = function() {
window.location.search = searchWithCatch();
};
}
};
jasmine.HtmlReporter.parameters = function(doc) {
var paramStr = doc.location.search.substring(1);
var params = [];
if (paramStr.length > 0) {
params = paramStr.split('&');
}
return params;
}
jasmine.HtmlReporter.sectionLink = function(sectionName) {
var link = '?';
var params = [];
if (sectionName) {
params.push('spec=' + encodeURIComponent(sectionName));
}
if (!jasmine.CATCH_EXCEPTIONS) {
params.push("catch=false");
}
if (params.length > 0) {
link += params.join("&");
}
return link;
};
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);

View File

@ -1,128 +0,0 @@
var jasmine = require("./jasmine");
var diff = require('./diff');
var red = '\u001b[1;41m';
var reset = '\u001b[0m';
function highlightDifferences(a, b) {
var changes = diff.diffChars(a, b);
var ret = {a: '', b: ''};
var change;
for (var i = 0, il = changes.length; i < il; i++) {
change = changes[i];
if (change.added) {
ret.b += red + change.value + reset;
} else if (change.removed) {
ret.a += red + change.value + reset;
} else {
ret.a += change.value;
ret.b += change.value;
}
}
return ret;
}
function PrintReporter(name, root_directory) {
this.skipCount = 0;
this.failCount = 0;
this.expectCount = 0;
this.specCount = 0;
this.name = name;
this.rootDirectory = root_directory;
}
exports.PrintReporter =
jasmine.PrintReporter = PrintReporter;
PrintReporter.prototype = new jasmine.Reporter();
// Set verbose=true on the test instance to enable additional logging
PrintReporter.prototype.verbose = false;
PrintReporter.prototype._didSpecName = false;
PrintReporter.prototype.reportSpecStarting = function(spec) {
this._didSpecName = false;
this._spec = spec;
};
PrintReporter.prototype.reportRunnerResults = function(runner) {
// Don't print out the spec name at the end
this._didSpecName = true;
this.log([
this.specCount + " spec",
this.expectCount + " expect",
this.skipCount + " skip",
this.failCount + " fail"
].join(" "));
require("./phantom").exit(this.failCount);
};
PrintReporter.prototype.reportSuiteResults = function(suite) {
var results = suite.results();
if (this.verbose) {
this.log('Suite "' + suite.description + '": ' +
results.passedCount + '/' + results.totalCount + ' passed.');
}
// If suite is nested, only count the root suite
if (!suite.parentSuite) {
this.failCount += results.totalCount - results.passedCount;
this.expectCount += results.totalCount;
}
};
PrintReporter.prototype.reportSpecResults = function(spec) {
if (this.verbose) {
this.log('it... ' +
spec.description + ': ' + (spec.results().passed() ? 'pass' : 'fail'));
}
var self = this;
var results = spec.results();
this.specCount += 1;
if (results.skipped)
this.skipCount += 1;
results.getItems().forEach(function(result) {
if (result.type == 'log') {
self.log(result.toString());
} else if (result.type == 'expect' && result.passed && !result.passed()) {
var ppActual = jasmine.pp(result.actual);
var ppExpected = jasmine.pp(result.expected);
var colorDiff = highlightDifferences(ppActual, ppExpected);
var message = result.message;
message = message.replace(ppActual, colorDiff.a);
message = message.replace(ppExpected, colorDiff.b);
self.log(message);
if (result.trace.stack) {
self.log();
result.trace.stack.split('\n').forEach(function(stackFrame) {
if (stackFrame.indexOf('/jasmine/lib/jasmine-core') > -1) {
return;
}
if (this.rootDirectory) {
stackFrame = stackFrame.replace(this.rootDirectory + '/', '');
}
self.log(' ' + stackFrame);
}.bind(this));
}
}
});
};
PrintReporter.prototype.log = function(str) {
if (!this._didSpecName) {
console.log('');
console.log(
this._spec.suite.description + ': it ' + this._spec.description);
this._didSpecName = true;
}
console.log(str || '');
};

View File

@ -1,166 +0,0 @@
var jasmine = require("jasmine");
jasmine.HtmlReporter.ReporterView = function(dom) {
this.startedAt = new Date();
this.runningSpecCount = 0;
this.completeSpecCount = 0;
this.passedCount = 0;
this.failedCount = 0;
this.skippedCount = 0;
this.createResultsMenu = function() {
this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'},
this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: "#"}, '0 specs'),
' | ',
this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: "#"}, '0 failing'));
this.summaryMenuItem.onclick = function() {
dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, '');
};
this.detailsMenuItem.onclick = function() {
showDetails();
};
};
this.addSpecs = function(specs, specFilter) {
this.totalSpecCount = specs.length;
this.views = {
specs: {},
suites: {}
};
for (var i = 0; i < specs.length; i++) {
var spec = specs[i];
this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views);
if (specFilter(spec)) {
this.runningSpecCount++;
}
}
};
this.specComplete = function(spec) {
this.completeSpecCount++;
if (isUndefined(this.views.specs[spec.id])) {
this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom);
}
var specView = this.views.specs[spec.id];
switch (specView.status()) {
case 'passed':
this.passedCount++;
break;
case 'failed':
this.failedCount++;
break;
case 'skipped':
this.skippedCount++;
break;
}
specView.refresh();
this.refresh();
};
this.suiteComplete = function(suite) {
var suiteView = this.views.suites[suite.id];
if (isUndefined(suiteView)) {
return;
}
suiteView.refresh();
};
this.refresh = function() {
if (isUndefined(this.resultsMenu)) {
this.createResultsMenu();
}
// currently running UI
if (isUndefined(this.runningAlert)) {
this.runningAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "runningAlert bar" });
dom.alert.appendChild(this.runningAlert);
}
this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount);
// skipped specs UI
if (isUndefined(this.skippedAlert)) {
this.skippedAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "skippedAlert bar" });
}
this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
if (this.skippedCount === 1 && isDefined(dom.alert)) {
dom.alert.appendChild(this.skippedAlert);
}
// passing specs UI
if (isUndefined(this.passedAlert)) {
this.passedAlert = this.createDom('span', { href: jasmine.HtmlReporter.sectionLink(), className: "passingAlert bar" });
}
this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount);
// failing specs UI
if (isUndefined(this.failedAlert)) {
this.failedAlert = this.createDom('span', {href: "?", className: "failingAlert bar"});
}
this.failedAlert.innerHTML = "Failing " + specPluralizedFor(this.failedCount);
if (this.failedCount === 1 && isDefined(dom.alert)) {
dom.alert.appendChild(this.failedAlert);
dom.alert.appendChild(this.resultsMenu);
}
// summary info
this.summaryMenuItem.innerHTML = "" + specPluralizedFor(this.runningSpecCount);
this.detailsMenuItem.innerHTML = "" + this.failedCount + " failing";
};
this.complete = function() {
dom.alert.removeChild(this.runningAlert);
this.skippedAlert.innerHTML = "Ran " + this.runningSpecCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
if (this.failedCount === 0) {
dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, "Passing " + specPluralizedFor(this.passedCount)));
} else {
showDetails();
}
dom.banner.appendChild(this.createDom('span', {className: 'duration'}, "finished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"));
};
return this;
function showDetails() {
if (dom.reporter.className.search(/showDetails/) === -1) {
dom.reporter.className += " showDetails";
}
}
function isUndefined(obj) {
return typeof obj === 'undefined';
}
function isDefined(obj) {
return !isUndefined(obj);
}
function specPluralizedFor(count) {
var str = count + " spec";
if (count > 1) {
str += "s"
}
return str;
}
};
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView);

View File

@ -1,81 +0,0 @@
var jasmine = require("./jasmine");
jasmine.HtmlReporter.SpecView = function(spec, dom, views) {
this.spec = spec;
this.dom = dom;
this.views = views;
this.symbol = this.createDom('li', { className: 'pending' });
this.dom.symbolSummary.appendChild(this.symbol);
this.summary = this.createDom('div', { className: 'specSummary' },
this.createDom('a', {
className: 'description',
href: jasmine.HtmlReporter.sectionLink(this.spec.getFullName()),
title: this.spec.getFullName()
}, this.spec.description)
);
this.detail = this.createDom('div', { className: 'specDetail' },
this.createDom('a', {
className: 'description',
href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
title: this.spec.getFullName()
}, this.spec.getFullName())
);
};
jasmine.HtmlReporter.SpecView.prototype.status = function() {
return this.getSpecStatus(this.spec);
};
jasmine.HtmlReporter.SpecView.prototype.refresh = function() {
this.symbol.className = this.status();
switch (this.status()) {
case 'skipped':
break;
case 'passed':
this.appendSummaryToSuiteDiv();
break;
case 'failed':
this.appendSummaryToSuiteDiv();
this.appendFailureDetail();
break;
}
};
jasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() {
this.summary.className += ' ' + this.status();
this.appendToSummary(this.spec, this.summary);
};
jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {
this.detail.className += ' ' + this.status();
var resultItems = this.spec.results().getItems();
var messagesDiv = this.createDom('div', { className: 'messages' });
for (var i = 0; i < resultItems.length; i++) {
var result = resultItems[i];
if (result.type == 'log') {
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
} else if (result.type == 'expect' && result.passed && !result.passed()) {
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
if (result.trace.stack) {
messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
}
}
}
if (messagesDiv.childNodes.length > 0) {
this.detail.appendChild(messagesDiv);
this.dom.details.appendChild(this.detail);
}
};
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);

View File

@ -1,24 +0,0 @@
var jasmine = require("./jasmine");
jasmine.HtmlReporter.SuiteView = function(suite, dom, views) {
this.suite = suite;
this.dom = dom;
this.views = views;
this.element = this.createDom('div', { className: 'suite' },
this.createDom('a', { className: 'description', href: jasmine.HtmlReporter.sectionLink(this.suite.getFullName()) }, this.suite.description)
);
this.appendToSummary(this.suite, this.element);
};
jasmine.HtmlReporter.SuiteView.prototype.status = function() {
return this.getSpecStatus(this.suite);
};
jasmine.HtmlReporter.SuiteView.prototype.refresh = function() {
this.element.className += " " + this.status();
};
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView);

38
vendor/jasmine/all.js vendored
View File

@ -1,38 +0,0 @@
require("./phantom");
require("./console");
// TODO Also bundle jasmine.css here.
var jasmine = require("./jasmine");
require("./jasmine-html");
require("./jasmine-support");
require("./HtmlReporter");
require("./PrintReporter");
require("./ReporterView");
require("./SpecView");
require("./SuiteView");
var env = jasmine.getEnv();
env.addReporter(new jasmine.HtmlReporter);
env.addReporter(new jasmine.PrintReporter);
function exposeFrom(obj) {
obj.spyOn = jasmine.spyOn;
obj.it = jasmine.it;
obj.xit = jasmine.xit;
obj.expect = jasmine.expect;
obj.runs = jasmine.runs;
obj.waits = jasmine.waits;
obj.waitsFor = jasmine.waitsFor;
obj.beforeEach = jasmine.beforeEach;
obj.afterEach = jasmine.afterEach;
obj.describe = jasmine.describe;
obj.xdescribe = jasmine.xdescribe;
obj.jasmine = jasmine;
return obj;
}
jasmine.exposeFrom = exposeFrom;
var global = Function("return this")();
exposeFrom(global);
module.exports = jasmine;

View File

@ -1,85 +0,0 @@
/**
* Copyright 2013-2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* This module allows interception of console.* method calls, so that
* listeners other than the native console object can consume logged
* messages.
*/
var global = Function("return this")();
var Ap = Array.prototype;
var slice = Ap.slice;
var nativeConsole;
if ("console" in global) {
var gc = global.console;
try { delete global.console } catch (ignored) {}
nativeConsole = global.console || gc;
global.console = gc;
}
// Provide a reliable console interface in all browsers.
global.console = exports;
function makeLogger(method) {
var logger = exports[method] = function() {
var args = slice.call(arguments);
listeners.forEach(function(listener) {
listener(method, args, logger);
});
};
}
makeLogger("info");
makeLogger("log");
makeLogger("debug");
makeLogger("warn");
makeLogger("error");
makeLogger("dir");
makeLogger("dirxml");
makeLogger("trace");
makeLogger("assert");
makeLogger("count");
makeLogger("markTimeline");
makeLogger("profile");
makeLogger("profileEnd");
makeLogger("time");
makeLogger("timeEnd");
makeLogger("timeStamp");
makeLogger("group");
makeLogger("groupCollapsed");
makeLogger("groupEnd");
makeLogger("clear");
var listeners = [];
function addListener(listener) {
listeners.push(listener);
}
exports.addListener = addListener
function clean(arg) {
if (typeof arg === "string") {
// Remove any xterm-color escape sequences.
// TODO Display colors in console if possible.
arg = arg.replace(/\033\[\d+m/g, "");
}
return arg;
}
if (nativeConsole) {
// If present, the native console object becomes a listener just like
// any other.
addListener(function(method, args) {
var method = nativeConsole[method];
if (method) {
method.apply(nativeConsole, args.map(clean));
} else {
// Ignore this call.
}
});
}

349
vendor/jasmine/diff.js vendored
View File

@ -1,349 +0,0 @@
/* See LICENSE file for terms of use */
/*
* Text diff implementation.
*
* This library supports the following APIS:
* JsDiff.diffChars: Character by character diff
* JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace
* JsDiff.diffLines: Line based diff
*
* JsDiff.diffCss: Diff targeted at CSS content
*
* These methods are based on the implementation proposed in
* "An O(ND) Difference Algorithm and its Variations" (Myers, 1986).
* http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927
*/
var JsDiff = (function() {
function clonePath(path) {
return { newPos: path.newPos, components: path.components.slice(0) };
}
function removeEmpty(array) {
var ret = [];
for (var i = 0; i < array.length; i++) {
if (array[i]) {
ret.push(array[i]);
}
}
return ret;
}
function escapeHTML(s) {
var n = s;
n = n.replace(/&/g, "&amp;");
n = n.replace(/</g, "&lt;");
n = n.replace(/>/g, "&gt;");
n = n.replace(/"/g, "&quot;");
return n;
}
var fbDiff = function(ignoreWhitespace) {
this.ignoreWhitespace = ignoreWhitespace;
};
fbDiff.prototype = {
diff: function(oldString, newString) {
// Handle the identity case (this is due to unrolling editLength == 0
if (newString == oldString) {
return [{ value: newString }];
}
if (!newString) {
return [{ value: oldString, removed: true }];
}
if (!oldString) {
return [{ value: newString, added: true }];
}
newString = this.tokenize(newString);
oldString = this.tokenize(oldString);
var newLen = newString.length, oldLen = oldString.length;
var maxEditLength = newLen + oldLen;
var bestPath = [{ newPos: -1, components: [] }];
// Seed editLength = 0
var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);
if (bestPath[0].newPos+1 >= newLen && oldPos+1 >= oldLen) {
return bestPath[0].components;
}
for (var editLength = 1; editLength <= maxEditLength; editLength++) {
for (var diagonalPath = -1*editLength; diagonalPath <= editLength; diagonalPath+=2) {
var basePath;
var addPath = bestPath[diagonalPath-1],
removePath = bestPath[diagonalPath+1];
oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;
if (addPath) {
// No one else is going to attempt to use this value, clear it
bestPath[diagonalPath-1] = undefined;
}
var canAdd = addPath && addPath.newPos+1 < newLen;
var canRemove = removePath && 0 <= oldPos && oldPos < oldLen;
if (!canAdd && !canRemove) {
bestPath[diagonalPath] = undefined;
continue;
}
// Select the diagonal that we want to branch from. We select the prior
// path whose position in the new string is the farthest from the origin
// and does not pass the bounds of the diff graph
if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {
basePath = clonePath(removePath);
this.pushComponent(basePath.components, oldString[oldPos], undefined, true);
} else {
basePath = clonePath(addPath);
basePath.newPos++;
this.pushComponent(basePath.components, newString[basePath.newPos], true, undefined);
}
var oldPos = this.extractCommon(basePath, newString, oldString, diagonalPath);
if (basePath.newPos+1 >= newLen && oldPos+1 >= oldLen) {
return basePath.components;
} else {
bestPath[diagonalPath] = basePath;
}
}
}
},
pushComponent: function(components, value, added, removed) {
var last = components[components.length-1];
if (last && last.added === added && last.removed === removed) {
// We need to clone here as the component clone operation is just
// as shallow array clone
components[components.length-1] =
{value: this.join(last.value, value), added: added, removed: removed };
} else {
components.push({value: value, added: added, removed: removed });
}
},
extractCommon: function(basePath, newString, oldString, diagonalPath) {
var newLen = newString.length,
oldLen = oldString.length,
newPos = basePath.newPos,
oldPos = newPos - diagonalPath;
while (newPos+1 < newLen && oldPos+1 < oldLen && this.equals(newString[newPos+1], oldString[oldPos+1])) {
newPos++;
oldPos++;
this.pushComponent(basePath.components, newString[newPos], undefined, undefined);
}
basePath.newPos = newPos;
return oldPos;
},
equals: function(left, right) {
var reWhitespace = /\S/;
if (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)) {
return true;
} else {
return left == right;
}
},
join: function(left, right) {
return left + right;
},
tokenize: function(value) {
return value;
}
};
var CharDiff = new fbDiff();
var WordDiff = new fbDiff(true);
WordDiff.tokenize = function(value) {
return removeEmpty(value.split(/(\s+|\b)/));
};
var CssDiff = new fbDiff(true);
CssDiff.tokenize = function(value) {
return removeEmpty(value.split(/([{}:;,]|\s+)/));
};
var LineDiff = new fbDiff();
LineDiff.tokenize = function(value) {
return value.split(/^/m);
};
return {
diffChars: function(oldStr, newStr) { return CharDiff.diff(oldStr, newStr); },
diffWords: function(oldStr, newStr) { return WordDiff.diff(oldStr, newStr); },
diffLines: function(oldStr, newStr) { return LineDiff.diff(oldStr, newStr); },
diffCss: function(oldStr, newStr) { return CssDiff.diff(oldStr, newStr); },
createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {
var ret = [];
ret.push("Index: " + fileName);
ret.push("===================================================================");
ret.push("--- " + fileName + (typeof oldHeader === "undefined" ? "" : "\t" + oldHeader));
ret.push("+++ " + fileName + (typeof newHeader === "undefined" ? "" : "\t" + newHeader));
var diff = LineDiff.diff(oldStr, newStr);
if (!diff[diff.length-1].value) {
diff.pop(); // Remove trailing newline add
}
diff.push({value: "", lines: []}); // Append an empty value to make cleanup easier
function contextLines(lines) {
return lines.map(function(entry) { return ' ' + entry; });
}
function eofNL(curRange, i, current) {
var last = diff[diff.length-2],
isLast = i === diff.length-2,
isLastOfType = i === diff.length-3 && (current.added !== last.added || current.removed !== last.removed);
// Figure out if this is the last line for the given file and missing NL
if (!/\n$/.test(current.value) && (isLast || isLastOfType)) {
curRange.push('\\ No newline at end of file');
}
}
var oldRangeStart = 0, newRangeStart = 0, curRange = [],
oldLine = 1, newLine = 1;
for (var i = 0; i < diff.length; i++) {
var current = diff[i],
lines = current.lines || current.value.replace(/\n$/, "").split("\n");
current.lines = lines;
if (current.added || current.removed) {
if (!oldRangeStart) {
var prev = diff[i-1];
oldRangeStart = oldLine;
newRangeStart = newLine;
if (prev) {
curRange = contextLines(prev.lines.slice(-4));
oldRangeStart -= curRange.length;
newRangeStart -= curRange.length;
}
}
curRange.push.apply(curRange, lines.map(function(entry) { return (current.added?"+":"-") + entry; }));
eofNL(curRange, i, current);
if (current.added) {
newLine += lines.length;
} else {
oldLine += lines.length;
}
} else {
if (oldRangeStart) {
// Close out any changes that have been output (or join overlapping)
if (lines.length <= 8 && i < diff.length-2) {
// Overlapping
curRange.push.apply(curRange, contextLines(lines));
} else {
// end the range and output
var contextSize = Math.min(lines.length, 4);
ret.push(
"@@ -" + oldRangeStart + "," + (oldLine-oldRangeStart+contextSize)
+ " +" + newRangeStart + "," + (newLine-newRangeStart+contextSize)
+ " @@");
ret.push.apply(ret, curRange);
ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));
if (lines.length <= 4) {
eofNL(ret, i, current);
}
oldRangeStart = 0; newRangeStart = 0; curRange = [];
}
}
oldLine += lines.length;
newLine += lines.length;
}
}
return ret.join('\n') + '\n';
},
applyPatch: function(oldStr, uniDiff) {
var diffstr = uniDiff.split("\n");
var diff = [];
var remEOFNL = false,
addEOFNL = false;
for (var i = (diffstr[0][0]=="I"?4:0); i < diffstr.length; i++) {
if(diffstr[i][0] == "@") {
var meh = diffstr[i].split(/@@ -(\d+),(\d+) \+(\d+),(\d+) @@/);
diff.unshift({
start:meh[3],
oldlength:meh[2],
oldlines:[],
newlength:meh[4],
newlines:[]
});
} else if(diffstr[i][0] == '+') {
diff[0].newlines.push(diffstr[i].substr(1));
} else if(diffstr[i][0] == '-') {
diff[0].oldlines.push(diffstr[i].substr(1));
} else if(diffstr[i][0] == ' ') {
diff[0].newlines.push(diffstr[i].substr(1));
diff[0].oldlines.push(diffstr[i].substr(1));
} else if(diffstr[i][0] == '\\') {
if (diffstr[i-1][0] == '+') {
remEOFNL = true;
} else if(diffstr[i-1][0] == '-') {
addEOFNL = true;
}
}
}
var str = oldStr.split("\n");
for (var i = diff.length - 1; i >= 0; i--) {
var d = diff[i];
for (var j = 0; j < d.oldlength; j++) {
if(str[d.start-1+j] != d.oldlines[j]) {
return false;
}
}
Array.prototype.splice.apply(str,[d.start-1,+d.oldlength].concat(d.newlines));
}
if (remEOFNL) {
while (!str[str.length-1]) {
str.pop();
}
} else if (addEOFNL) {
str.push('');
}
return str.join('\n');
},
convertChangesToXML: function(changes){
var ret = [];
for ( var i = 0; i < changes.length; i++) {
var change = changes[i];
if (change.added) {
ret.push("<ins>");
} else if (change.removed) {
ret.push("<del>");
}
ret.push(escapeHTML(change.value));
if (change.added) {
ret.push("</ins>");
} else if (change.removed) {
ret.push("</del>");
}
}
return ret.join("");
},
// See: http://code.google.com/p/google-diff-match-patch/wiki/API
convertChangesToDMP: function(changes){
var ret = [], change;
for ( var i = 0; i < changes.length; i++) {
change = changes[i];
ret.push([(change.added ? 1 : change.removed ? -1 : 0), change.value]);
}
return ret;
}
};
})();
if (typeof module !== "undefined") {
module.exports = JsDiff;
}

View File

@ -1,681 +0,0 @@
jasmine.HtmlReporterHelpers = {};
jasmine.HtmlReporterHelpers.createDom = function(type, attrs, childrenVarArgs) {
var el = document.createElement(type);
for (var i = 2; i < arguments.length; i++) {
var child = arguments[i];
if (typeof child === 'string') {
el.appendChild(document.createTextNode(child));
} else {
if (child) {
el.appendChild(child);
}
}
}
for (var attr in attrs) {
if (attr == "className") {
el[attr] = attrs[attr];
} else {
el.setAttribute(attr, attrs[attr]);
}
}
return el;
};
jasmine.HtmlReporterHelpers.getSpecStatus = function(child) {
var results = child.results();
var status = results.passed() ? 'passed' : 'failed';
if (results.skipped) {
status = 'skipped';
}
return status;
};
jasmine.HtmlReporterHelpers.appendToSummary = function(child, childElement) {
var parentDiv = this.dom.summary;
var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite';
var parent = child[parentSuite];
if (parent) {
if (typeof this.views.suites[parent.id] == 'undefined') {
this.views.suites[parent.id] = new jasmine.HtmlReporter.SuiteView(parent, this.dom, this.views);
}
parentDiv = this.views.suites[parent.id].element;
}
parentDiv.appendChild(childElement);
};
jasmine.HtmlReporterHelpers.addHelpers = function(ctor) {
for(var fn in jasmine.HtmlReporterHelpers) {
ctor.prototype[fn] = jasmine.HtmlReporterHelpers[fn];
}
};
jasmine.HtmlReporter = function(_doc) {
var self = this;
var doc = _doc || window.document;
var reporterView;
var dom = {};
// Jasmine Reporter Public Interface
self.logRunningSpecs = false;
self.reportRunnerStarting = function(runner) {
var specs = runner.specs() || [];
if (specs.length == 0) {
return;
}
createReporterDom(runner.env.versionString());
doc.body.appendChild(dom.reporter);
setExceptionHandling();
reporterView = new jasmine.HtmlReporter.ReporterView(dom);
reporterView.addSpecs(specs, self.specFilter);
};
self.reportRunnerResults = function(runner) {
reporterView && reporterView.complete();
};
self.reportSuiteResults = function(suite) {
reporterView.suiteComplete(suite);
};
self.reportSpecStarting = function(spec) {
if (self.logRunningSpecs) {
self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
}
};
self.reportSpecResults = function(spec) {
reporterView.specComplete(spec);
};
self.log = function() {
var console = jasmine.getGlobal().console;
if (console && console.log) {
if (console.log.apply) {
console.log.apply(console, arguments);
} else {
console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
}
}
};
self.specFilter = function(spec) {
if (!focusedSpecName()) {
return true;
}
return spec.getFullName().indexOf(focusedSpecName()) === 0;
};
return self;
function focusedSpecName() {
var specName;
(function memoizeFocusedSpec() {
if (specName) {
return;
}
var paramMap = [];
var params = jasmine.HtmlReporter.parameters(doc);
for (var i = 0; i < params.length; i++) {
var p = params[i].split('=');
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
}
specName = paramMap.spec;
})();
return specName;
}
function createReporterDom(version) {
dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' },
dom.banner = self.createDom('div', { className: 'banner' },
self.createDom('span', { className: 'title' }, "Jasmine "),
self.createDom('span', { className: 'version' }, version)),
dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),
dom.alert = self.createDom('div', {className: 'alert'},
self.createDom('span', { className: 'exceptions' },
self.createDom('label', { className: 'label', 'for': 'no_try_catch' }, 'No try/catch'),
self.createDom('input', { id: 'no_try_catch', type: 'checkbox' }))),
dom.results = self.createDom('div', {className: 'results'},
dom.summary = self.createDom('div', { className: 'summary' }),
dom.details = self.createDom('div', { id: 'details' }))
);
}
function noTryCatch() {
return window.location.search.match(/catch=false/);
}
function searchWithCatch() {
var params = jasmine.HtmlReporter.parameters(window.document);
var removed = false;
var i = 0;
while (!removed && i < params.length) {
if (params[i].match(/catch=/)) {
params.splice(i, 1);
removed = true;
}
i++;
}
if (jasmine.CATCH_EXCEPTIONS) {
params.push("catch=false");
}
return params.join("&");
}
function setExceptionHandling() {
var chxCatch = document.getElementById('no_try_catch');
if (noTryCatch()) {
chxCatch.setAttribute('checked', true);
jasmine.CATCH_EXCEPTIONS = false;
}
chxCatch.onclick = function() {
window.location.search = searchWithCatch();
};
}
};
jasmine.HtmlReporter.parameters = function(doc) {
var paramStr = doc.location.search.substring(1);
var params = [];
if (paramStr.length > 0) {
params = paramStr.split('&');
}
return params;
}
jasmine.HtmlReporter.sectionLink = function(sectionName) {
var link = '?';
var params = [];
if (sectionName) {
params.push('spec=' + encodeURIComponent(sectionName));
}
if (!jasmine.CATCH_EXCEPTIONS) {
params.push("catch=false");
}
if (params.length > 0) {
link += params.join("&");
}
return link;
};
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);
jasmine.HtmlReporter.ReporterView = function(dom) {
this.startedAt = new Date();
this.runningSpecCount = 0;
this.completeSpecCount = 0;
this.passedCount = 0;
this.failedCount = 0;
this.skippedCount = 0;
this.createResultsMenu = function() {
this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'},
this.summaryMenuItem = this.createDom('a', {className: 'summaryMenuItem', href: "#"}, '0 specs'),
' | ',
this.detailsMenuItem = this.createDom('a', {className: 'detailsMenuItem', href: "#"}, '0 failing'));
this.summaryMenuItem.onclick = function() {
dom.reporter.className = dom.reporter.className.replace(/ showDetails/g, '');
};
this.detailsMenuItem.onclick = function() {
showDetails();
};
};
this.addSpecs = function(specs, specFilter) {
this.totalSpecCount = specs.length;
this.views = {
specs: {},
suites: {}
};
for (var i = 0; i < specs.length; i++) {
var spec = specs[i];
this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom, this.views);
if (specFilter(spec)) {
this.runningSpecCount++;
}
}
};
this.specComplete = function(spec) {
this.completeSpecCount++;
if (isUndefined(this.views.specs[spec.id])) {
this.views.specs[spec.id] = new jasmine.HtmlReporter.SpecView(spec, dom);
}
var specView = this.views.specs[spec.id];
switch (specView.status()) {
case 'passed':
this.passedCount++;
break;
case 'failed':
this.failedCount++;
break;
case 'skipped':
this.skippedCount++;
break;
}
specView.refresh();
this.refresh();
};
this.suiteComplete = function(suite) {
var suiteView = this.views.suites[suite.id];
if (isUndefined(suiteView)) {
return;
}
suiteView.refresh();
};
this.refresh = function() {
if (isUndefined(this.resultsMenu)) {
this.createResultsMenu();
}
// currently running UI
if (isUndefined(this.runningAlert)) {
this.runningAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "runningAlert bar" });
dom.alert.appendChild(this.runningAlert);
}
this.runningAlert.innerHTML = "Running " + this.completeSpecCount + " of " + specPluralizedFor(this.totalSpecCount);
// skipped specs UI
if (isUndefined(this.skippedAlert)) {
this.skippedAlert = this.createDom('a', { href: jasmine.HtmlReporter.sectionLink(), className: "skippedAlert bar" });
}
this.skippedAlert.innerHTML = "Skipping " + this.skippedCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
if (this.skippedCount === 1 && isDefined(dom.alert)) {
dom.alert.appendChild(this.skippedAlert);
}
// passing specs UI
if (isUndefined(this.passedAlert)) {
this.passedAlert = this.createDom('span', { href: jasmine.HtmlReporter.sectionLink(), className: "passingAlert bar" });
}
this.passedAlert.innerHTML = "Passing " + specPluralizedFor(this.passedCount);
// failing specs UI
if (isUndefined(this.failedAlert)) {
this.failedAlert = this.createDom('span', {href: "?", className: "failingAlert bar"});
}
this.failedAlert.innerHTML = "Failing " + specPluralizedFor(this.failedCount);
if (this.failedCount === 1 && isDefined(dom.alert)) {
dom.alert.appendChild(this.failedAlert);
dom.alert.appendChild(this.resultsMenu);
}
// summary info
this.summaryMenuItem.innerHTML = "" + specPluralizedFor(this.runningSpecCount);
this.detailsMenuItem.innerHTML = "" + this.failedCount + " failing";
};
this.complete = function() {
dom.alert.removeChild(this.runningAlert);
this.skippedAlert.innerHTML = "Ran " + this.runningSpecCount + " of " + specPluralizedFor(this.totalSpecCount) + " - run all";
if (this.failedCount === 0) {
dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, "Passing " + specPluralizedFor(this.passedCount)));
} else {
showDetails();
}
dom.banner.appendChild(this.createDom('span', {className: 'duration'}, "finished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"));
};
return this;
function showDetails() {
if (dom.reporter.className.search(/showDetails/) === -1) {
dom.reporter.className += " showDetails";
}
}
function isUndefined(obj) {
return typeof obj === 'undefined';
}
function isDefined(obj) {
return !isUndefined(obj);
}
function specPluralizedFor(count) {
var str = count + " spec";
if (count > 1) {
str += "s"
}
return str;
}
};
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.ReporterView);
jasmine.HtmlReporter.SpecView = function(spec, dom, views) {
this.spec = spec;
this.dom = dom;
this.views = views;
this.symbol = this.createDom('li', { className: 'pending' });
this.dom.symbolSummary.appendChild(this.symbol);
this.summary = this.createDom('div', { className: 'specSummary' },
this.createDom('a', {
className: 'description',
href: jasmine.HtmlReporter.sectionLink(this.spec.getFullName()),
title: this.spec.getFullName()
}, this.spec.description)
);
this.detail = this.createDom('div', { className: 'specDetail' },
this.createDom('a', {
className: 'description',
href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
title: this.spec.getFullName()
}, this.spec.getFullName())
);
};
jasmine.HtmlReporter.SpecView.prototype.status = function() {
return this.getSpecStatus(this.spec);
};
jasmine.HtmlReporter.SpecView.prototype.refresh = function() {
this.symbol.className = this.status();
switch (this.status()) {
case 'skipped':
break;
case 'passed':
this.appendSummaryToSuiteDiv();
break;
case 'failed':
this.appendSummaryToSuiteDiv();
this.appendFailureDetail();
break;
}
};
jasmine.HtmlReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() {
this.summary.className += ' ' + this.status();
this.appendToSummary(this.spec, this.summary);
};
jasmine.HtmlReporter.SpecView.prototype.appendFailureDetail = function() {
this.detail.className += ' ' + this.status();
var resultItems = this.spec.results().getItems();
var messagesDiv = this.createDom('div', { className: 'messages' });
for (var i = 0; i < resultItems.length; i++) {
var result = resultItems[i];
if (result.type == 'log') {
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
} else if (result.type == 'expect' && result.passed && !result.passed()) {
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
if (result.trace.stack) {
messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
}
}
}
if (messagesDiv.childNodes.length > 0) {
this.detail.appendChild(messagesDiv);
this.dom.details.appendChild(this.detail);
}
};
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SpecView);jasmine.HtmlReporter.SuiteView = function(suite, dom, views) {
this.suite = suite;
this.dom = dom;
this.views = views;
this.element = this.createDom('div', { className: 'suite' },
this.createDom('a', { className: 'description', href: jasmine.HtmlReporter.sectionLink(this.suite.getFullName()) }, this.suite.description)
);
this.appendToSummary(this.suite, this.element);
};
jasmine.HtmlReporter.SuiteView.prototype.status = function() {
return this.getSpecStatus(this.suite);
};
jasmine.HtmlReporter.SuiteView.prototype.refresh = function() {
this.element.className += " " + this.status();
};
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter.SuiteView);
/* @deprecated Use jasmine.HtmlReporter instead
*/
jasmine.TrivialReporter = function(doc) {
this.document = doc || document;
this.suiteDivs = {};
this.logRunningSpecs = false;
};
jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
var el = document.createElement(type);
for (var i = 2; i < arguments.length; i++) {
var child = arguments[i];
if (typeof child === 'string') {
el.appendChild(document.createTextNode(child));
} else {
if (child) { el.appendChild(child); }
}
}
for (var attr in attrs) {
if (attr == "className") {
el[attr] = attrs[attr];
} else {
el.setAttribute(attr, attrs[attr]);
}
}
return el;
};
jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) {
var showPassed, showSkipped;
this.outerDiv = this.createDom('div', { id: 'TrivialReporter', className: 'jasmine_reporter' },
this.createDom('div', { className: 'banner' },
this.createDom('div', { className: 'logo' },
this.createDom('span', { className: 'title' }, "Jasmine"),
this.createDom('span', { className: 'version' }, runner.env.versionString())),
this.createDom('div', { className: 'options' },
"Show ",
showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }),
this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "),
showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }),
this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped")
)
),
this.runnerDiv = this.createDom('div', { className: 'runner running' },
this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
);
this.document.body.appendChild(this.outerDiv);
var suites = runner.suites();
for (var i = 0; i < suites.length; i++) {
var suite = suites[i];
var suiteDiv = this.createDom('div', { className: 'suite' },
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
this.suiteDivs[suite.id] = suiteDiv;
var parentDiv = this.outerDiv;
if (suite.parentSuite) {
parentDiv = this.suiteDivs[suite.parentSuite.id];
}
parentDiv.appendChild(suiteDiv);
}
this.startedAt = new Date();
var self = this;
showPassed.onclick = function(evt) {
if (showPassed.checked) {
self.outerDiv.className += ' show-passed';
} else {
self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
}
};
showSkipped.onclick = function(evt) {
if (showSkipped.checked) {
self.outerDiv.className += ' show-skipped';
} else {
self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
}
};
};
jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) {
var results = runner.results();
var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
this.runnerDiv.setAttribute("class", className);
//do it twice for IE
this.runnerDiv.setAttribute("className", className);
var specs = runner.specs();
var specCount = 0;
for (var i = 0; i < specs.length; i++) {
if (this.specFilter(specs[i])) {
specCount++;
}
}
var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
};
jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) {
var results = suite.results();
var status = results.passed() ? 'passed' : 'failed';
if (results.totalCount === 0) { // todo: change this to check results.skipped
status = 'skipped';
}
this.suiteDivs[suite.id].className += " " + status;
};
jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) {
if (this.logRunningSpecs) {
this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
}
};
jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) {
var results = spec.results();
var status = results.passed() ? 'passed' : 'failed';
if (results.skipped) {
status = 'skipped';
}
var specDiv = this.createDom('div', { className: 'spec ' + status },
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
this.createDom('a', {
className: 'description',
href: '?spec=' + encodeURIComponent(spec.getFullName()),
title: spec.getFullName()
}, spec.description));
var resultItems = results.getItems();
var messagesDiv = this.createDom('div', { className: 'messages' });
for (var i = 0; i < resultItems.length; i++) {
var result = resultItems[i];
if (result.type == 'log') {
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString()));
} else if (result.type == 'expect' && result.passed && !result.passed()) {
messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message));
if (result.trace.stack) {
messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack));
}
}
}
if (messagesDiv.childNodes.length > 0) {
specDiv.appendChild(messagesDiv);
}
this.suiteDivs[spec.suite.id].appendChild(specDiv);
};
jasmine.TrivialReporter.prototype.log = function() {
var console = jasmine.getGlobal().console;
if (console && console.log) {
if (console.log.apply) {
console.log.apply(console, arguments);
} else {
console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
}
}
};
jasmine.TrivialReporter.prototype.getLocation = function() {
return this.document.location;
};
jasmine.TrivialReporter.prototype.specFilter = function(spec) {
var paramMap = {};
var params = this.getLocation().search.substring(1).split('&');
for (var i = 0; i < params.length; i++) {
var p = params[i].split('=');
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
}
if (!paramMap.spec) {
return true;
}
return spec.getFullName().indexOf(paramMap.spec) === 0;
};

View File

@ -1,127 +0,0 @@
if (typeof jasmine == 'undefined') jasmine = require("./jasmine");
var spec = false; // TODO
// Add some matcher for mock functions
jasmine.getEnv().beforeEach(function() {
this.addMatchers({
toBeCalled: function() {
if (this.actual.mock === undefined) {
throw Error('toBeCalled() should be used on a mock function');
}
return this.actual.mock.calls.length !== 0;
},
lastCalledWith: function() {
if (this.actual.mock === undefined) {
throw Error('lastCalledWith() should be used on a mock function');
}
var calls = this.actual.mock.calls;
var args = Array.prototype.slice.call(arguments);
return this.env.equals_(calls[calls.length - 1], args);
},
toBeCalledWith: function() {
if (this.actual.mock === undefined) {
throw Error('toBeCalledWith() should be used on a mock function');
}
var args = Array.prototype.slice.call(arguments);
return this.actual.mock.calls.some(function(call) {
return this.env.equals_(call, args);
}.bind(this));
}
});
});
var _it = jasmine.Env.prototype.it;
var _xit = jasmine.Env.prototype.xit;
jasmine.Env.prototype.it = function(desc, func) {
// If spec is provided, only run matching specs
if (!spec || desc.match(new RegExp(spec, 'i'))) {
return _it.call(this, desc, func);
} else {
return this.xit(desc, func);
}
};
jasmine.Env.prototype.xit = function(desc, func) {
if (typeof func == 'function') {
var matches = func.toString().match(/.*\W?expect\(/g);
if (matches) {
this.reporter.subReporters_[0].skipCount += matches.length;
this.reporter.subReporters_[0].totalCount += matches.length;
}
}
return _xit.call(this, desc, func);
}
// Mainline Jasmine sets __Jasmine_been_here_before__ on each object to detect
// cycles, but that doesn't work on frozen objects so we use a WeakMap instead.
// We can only do this if if WeakMap is available, but if WeakMap is
// unavailable, then objects probably can't be frozen anyway.
if (typeof WeakMap !== "undefined") {
var _comparedObjects = new WeakMap;
jasmine.Env.prototype.compareObjects_ =
function(a, b, mismatchKeys, mismatchValues) {
if (_comparedObjects.get(a) === b && _comparedObjects.get(b) === a) {
return true;
}
var areArrays = jasmine.isArray_(a) && jasmine.isArray_(b);
_comparedObjects.set(a, b);
_comparedObjects.set(b, a);
var hasKey = function(obj, keyName) {
return obj != null && obj[keyName] !== jasmine.undefined;
};
for (var property in b) {
if (areArrays && typeof b[property] == 'function') {
continue;
}
if (!hasKey(a, property) && hasKey(b, property)) {
mismatchKeys.push(
"expected has key '" + property + "', but missing from actual."
);
}
}
for (property in a) {
if (areArrays && typeof a[property] == 'function') {
continue;
}
if (!hasKey(b, property) && hasKey(a, property)) {
mismatchKeys.push(
"expected missing key '" + property + "', but present in actual."
);
}
}
for (property in b) {
// The only different implementation from the original jasmine
if (areArrays &&
(typeof a[property] == 'function' ||
typeof b[property] == 'function')) {
continue;
}
if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues))
{
mismatchValues.push(
"'" + property + "' was '" + (b[property] ?
jasmine.util.htmlEscape(b[property].toString()) :
b[property]) +
"' in expected, but was '" + (a[property] ?
jasmine.util.htmlEscape(a[property].toString()) :
a[property]) + "' in actual."
);
}
}
if (areArrays &&
a.length != b.length) {
mismatchValues.push("arrays were not the same length");
}
_comparedObjects["delete"](a);
_comparedObjects["delete"](b);
return (mismatchKeys.length == 0 && mismatchValues.length == 0);
};
}

View File

@ -1,82 +0,0 @@
body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
#HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
#HTMLReporter a { text-decoration: none; }
#HTMLReporter a:hover { text-decoration: underline; }
#HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; }
#HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; }
#HTMLReporter #jasmine_content { position: fixed; right: 100%; }
#HTMLReporter .version { color: #aaaaaa; }
#HTMLReporter .banner { margin-top: 14px; }
#HTMLReporter .duration { color: #aaaaaa; float: right; }
#HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; }
#HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
#HTMLReporter .symbolSummary li.passed { font-size: 14px; }
#HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; }
#HTMLReporter .symbolSummary li.failed { line-height: 9px; }
#HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
#HTMLReporter .symbolSummary li.skipped { font-size: 14px; }
#HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; }
#HTMLReporter .symbolSummary li.pending { line-height: 11px; }
#HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; }
#HTMLReporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; }
#HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
#HTMLReporter .runningAlert { background-color: #666666; }
#HTMLReporter .skippedAlert { background-color: #aaaaaa; }
#HTMLReporter .skippedAlert:first-child { background-color: #333333; }
#HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; }
#HTMLReporter .passingAlert { background-color: #a6b779; }
#HTMLReporter .passingAlert:first-child { background-color: #5e7d00; }
#HTMLReporter .failingAlert { background-color: #cf867e; }
#HTMLReporter .failingAlert:first-child { background-color: #b03911; }
#HTMLReporter .results { margin-top: 14px; }
#HTMLReporter #details { display: none; }
#HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; }
#HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
#HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
#HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
#HTMLReporter.showDetails .summary { display: none; }
#HTMLReporter.showDetails #details { display: block; }
#HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
#HTMLReporter .summary { margin-top: 14px; }
#HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; }
#HTMLReporter .summary .specSummary.passed a { color: #5e7d00; }
#HTMLReporter .summary .specSummary.failed a { color: #b03911; }
#HTMLReporter .description + .suite { margin-top: 0; }
#HTMLReporter .suite { margin-top: 14px; }
#HTMLReporter .suite a { color: #333333; }
#HTMLReporter #details .specDetail { margin-bottom: 28px; }
#HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; }
#HTMLReporter .resultMessage { padding-top: 14px; color: #333333; }
#HTMLReporter .resultMessage span.result { display: block; }
#HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }
#TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ }
#TrivialReporter a:visited, #TrivialReporter a { color: #303; }
#TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }
#TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }
#TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }
#TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }
#TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }
#TrivialReporter .runner.running { background-color: yellow; }
#TrivialReporter .options { text-align: right; font-size: .8em; }
#TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }
#TrivialReporter .suite .suite { margin: 5px; }
#TrivialReporter .suite.passed { background-color: #dfd; }
#TrivialReporter .suite.failed { background-color: #fdd; }
#TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }
#TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }
#TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }
#TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }
#TrivialReporter .spec.skipped { background-color: #bbb; }
#TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }
#TrivialReporter .passed { background-color: #cfc; display: none; }
#TrivialReporter .failed { background-color: #fbb; }
#TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }
#TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }
#TrivialReporter .resultMessage .mismatch { color: black; }
#TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }
#TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }
#TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }
#TrivialReporter #jasmine_content { position: fixed; right: 100%; }
#TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }

File diff suppressed because it is too large Load Diff

View File

@ -1,37 +0,0 @@
/**
* Copyright 2013-2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* This module provides a bridge from content-land to phantom-land via the
* window.callPhantom interface.
*/
var console = require("./console");
var global = Function("return this")();
if (global.callPhantom) {
// Phantom's onConsoleMessage support is lacking (only one argument
// supported, and it must be a string), so we use callPhantom to
// forward console messages instead.
console.addListener(function(method, args) {
global.callPhantom({
type: "console",
method: method,
args: args
});
});
exports.exit = function(code) {
global.callPhantom({
type: "exit",
code: code
});
};
} else {
exports.exit = function() {};
}