mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Use bin/jsx and browserify to build a jasmine bundle.
This commit is contained in:
@@ -1,166 +0,0 @@
|
||||
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);
|
||||
@@ -1,127 +0,0 @@
|
||||
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("test/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 || '');
|
||||
};
|
||||
@@ -1,164 +0,0 @@
|
||||
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);
|
||||
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
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);
|
||||
@@ -1,22 +0,0 @@
|
||||
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);
|
||||
|
||||
@@ -2,17 +2,8 @@
|
||||
// modules in src/test and to specify an ordering on those modules, since
|
||||
// some still have implicit dependencies on others.
|
||||
|
||||
require("./phantom");
|
||||
require("./console");
|
||||
require("ReactTestUtils");
|
||||
require("reactComponentExpect");
|
||||
require("./diff");
|
||||
require("./PrintReporter");
|
||||
require("./HtmlReporter");
|
||||
require("./ReporterView");
|
||||
require("./SpecView");
|
||||
require("./SuiteView");
|
||||
require("./jasmine-support");
|
||||
require("mocks");
|
||||
require("mock-modules");
|
||||
require("./mock-timers");
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
/**
|
||||
* Copyright 2013 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* 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.
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -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, "&");
|
||||
n = n.replace(/</g, "<");
|
||||
n = n.replace(/>/g, ">");
|
||||
n = n.replace(/"/g, """);
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
var global = Function("return this")();
|
||||
var jasmine = global.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('toBeCalled() 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('toBeCalled() 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.bind(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.bind(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);
|
||||
};
|
||||
}
|
||||
|
||||
var HtmlReporter = require("./HtmlReporter").HtmlReporter;
|
||||
var PrintReporter = require("./PrintReporter").PrintReporter;
|
||||
|
||||
jasmine.getEnv().addReporter(new HtmlReporter);
|
||||
jasmine.getEnv().addReporter(new PrintReporter);
|
||||
@@ -1,64 +0,0 @@
|
||||
/**
|
||||
* Copyright 2013 Facebook, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* 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")();
|
||||
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);
|
||||
return args.length > 0 ? function() {
|
||||
return func.apply(
|
||||
context || this,
|
||||
args.concat(slice.call(arguments))
|
||||
);
|
||||
} : function() {
|
||||
return func.apply(context || this, arguments);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
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() {};
|
||||
}
|
||||
Reference in New Issue
Block a user