Use test.py for unit tests too.
This commit is contained in:
parent
cec7a92a99
commit
e18a2c512e
8
Makefile
8
Makefile
@ -83,10 +83,12 @@ bundle: | $(BUILD_DIR)
|
|||||||
|
|
||||||
# make unit-test
|
# make unit-test
|
||||||
#
|
#
|
||||||
# This target runs in-browser unit tests with js-test-driver and jasmine unit
|
# This target runs in-browser unit tests with our test framework and the
|
||||||
# test framework.
|
# jasmine unit test framework.
|
||||||
unit-test:
|
unit-test:
|
||||||
@cd test/unit/ ; make ;
|
cd test; \
|
||||||
|
$(DEFAULT_PYTHON) test.py --unitTest \
|
||||||
|
--browserManifestFile=$(PDF_BROWSERS)
|
||||||
|
|
||||||
# make browser-test
|
# make browser-test
|
||||||
#
|
#
|
||||||
|
676
external/jasmine/jasmine-html.js
vendored
Normal file
676
external/jasmine/jasmine-html.js
vendored
Normal file
@ -0,0 +1,676 @@
|
|||||||
|
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);
|
||||||
|
|
||||||
|
reporterView = new jasmine.HtmlReporter.ReporterView(dom);
|
||||||
|
reporterView.addSpecs(specs, self.specFilter);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.reportRunnerResults = function(runner) {
|
||||||
|
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 = doc.location.search.substring(1).split('&');
|
||||||
|
|
||||||
|
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'}),
|
||||||
|
dom.results = self.createDom('div', {className: 'results'},
|
||||||
|
dom.summary = self.createDom('div', { className: 'summary' }),
|
||||||
|
dom.details = self.createDom('div', { id: 'details' }))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
jasmine.HtmlReporterHelpers.addHelpers(jasmine.HtmlReporter);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.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: "?", 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: "?", 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: "?", 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: '?spec=' + encodeURIComponent(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: '?spec=' + encodeURIComponent(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;
|
||||||
|
};
|
81
external/jasmine/jasmine.css
vendored
Normal file
81
external/jasmine/jasmine.css
vendored
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
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 .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; }
|
BIN
external/jasmine/jasmine_favicon.png
vendored
Normal file
BIN
external/jasmine/jasmine_favicon.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 905 B |
198
external/jasmineAdapter/JasmineAdapter.js
vendored
198
external/jasmineAdapter/JasmineAdapter.js
vendored
@ -1,198 +0,0 @@
|
|||||||
/**
|
|
||||||
* @fileoverview Jasmine JsTestDriver Adapter.
|
|
||||||
* @author misko@hevery.com (Misko Hevery)
|
|
||||||
*/
|
|
||||||
(function(window) {
|
|
||||||
var rootDescribes = new Describes(window);
|
|
||||||
var describePath = [];
|
|
||||||
rootDescribes.collectMode();
|
|
||||||
|
|
||||||
var JASMINE_TYPE = 'jasmine test case';
|
|
||||||
TestCase('Jasmine Adapter Tests', null, JASMINE_TYPE);
|
|
||||||
|
|
||||||
var jasminePlugin = {
|
|
||||||
name:'jasmine',
|
|
||||||
|
|
||||||
getTestRunsConfigurationFor: function(testCaseInfos, expressions, testRunsConfiguration) {
|
|
||||||
for (var i = 0; i < testCaseInfos.length; i++) {
|
|
||||||
if (testCaseInfos[i].getType() == JASMINE_TYPE) {
|
|
||||||
testRunsConfiguration.push(new jstestdriver.TestRunConfiguration(testCaseInfos[i], []));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
|
|
||||||
runTestConfiguration: function(testRunConfiguration, onTestDone, onTestRunConfigurationComplete){
|
|
||||||
if (testRunConfiguration.getTestCaseInfo().getType() != JASMINE_TYPE) return false;
|
|
||||||
|
|
||||||
var jasmineEnv = jasmine.currentEnv_ = new jasmine.Env();
|
|
||||||
rootDescribes.playback();
|
|
||||||
var specLog = jstestdriver.console.log_ = [];
|
|
||||||
var start;
|
|
||||||
jasmineEnv.specFilter = function(spec) {
|
|
||||||
return rootDescribes.isExclusive(spec);
|
|
||||||
};
|
|
||||||
jasmineEnv.reporter = {
|
|
||||||
log: function(str){
|
|
||||||
specLog.push(str);
|
|
||||||
},
|
|
||||||
|
|
||||||
reportRunnerStarting: function(runner) { },
|
|
||||||
|
|
||||||
reportSpecStarting: function(spec) {
|
|
||||||
specLog = jstestdriver.console.log_ = [];
|
|
||||||
start = new Date().getTime();
|
|
||||||
},
|
|
||||||
|
|
||||||
reportSpecResults: function(spec) {
|
|
||||||
var suite = spec.suite;
|
|
||||||
var results = spec.results();
|
|
||||||
if (results.skipped) return;
|
|
||||||
var end = new Date().getTime();
|
|
||||||
var messages = [];
|
|
||||||
var resultItems = results.getItems();
|
|
||||||
var state = 'passed';
|
|
||||||
for ( var i = 0; i < resultItems.length; i++) {
|
|
||||||
if (!resultItems[i].passed()) {
|
|
||||||
state = resultItems[i].message.match(/AssertionError:/) ? 'error' : 'failed';
|
|
||||||
messages.push({
|
|
||||||
message: resultItems[i].toString(),
|
|
||||||
name: resultItems[i].trace.name,
|
|
||||||
stack: formatStack(resultItems[i].trace.stack)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onTestDone(
|
|
||||||
new jstestdriver.TestResult(
|
|
||||||
suite.getFullName(),
|
|
||||||
spec.description,
|
|
||||||
state,
|
|
||||||
jstestdriver.angular.toJson(messages),
|
|
||||||
specLog.join('\n'),
|
|
||||||
end - start));
|
|
||||||
},
|
|
||||||
|
|
||||||
reportSuiteResults: function(suite) {},
|
|
||||||
|
|
||||||
reportRunnerResults: function(runner) {
|
|
||||||
onTestRunConfigurationComplete();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
jasmineEnv.execute();
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
onTestsFinish: function(){
|
|
||||||
jasmine.currentEnv_ = null;
|
|
||||||
rootDescribes.collectMode();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
jstestdriver.pluginRegistrar.register(jasminePlugin);
|
|
||||||
|
|
||||||
function formatStack(stack) {
|
|
||||||
var lines = (stack||'').split(/\r?\n/);
|
|
||||||
var frames = [];
|
|
||||||
for (i = 0; i < lines.length; i++) {
|
|
||||||
if (!lines[i].match(/\/jasmine[\.-]/)) {
|
|
||||||
frames.push(lines[i].replace(/https?:\/\/\w+(:\d+)?\/test\//, '').replace(/^\s*/, ' '));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return frames.join('\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
function noop(){}
|
|
||||||
function Describes(window){
|
|
||||||
var describes = {};
|
|
||||||
var beforeEachs = {};
|
|
||||||
var afterEachs = {};
|
|
||||||
// Here we store:
|
|
||||||
// 0: everyone runs
|
|
||||||
// 1: run everything under ddescribe
|
|
||||||
// 2: run only iits (ignore ddescribe)
|
|
||||||
var exclusive = 0;
|
|
||||||
var collectMode = true;
|
|
||||||
intercept('describe', describes);
|
|
||||||
intercept('xdescribe', describes);
|
|
||||||
intercept('beforeEach', beforeEachs);
|
|
||||||
intercept('afterEach', afterEachs);
|
|
||||||
|
|
||||||
function intercept(functionName, collection){
|
|
||||||
window[functionName] = function(desc, fn){
|
|
||||||
if (collectMode) {
|
|
||||||
collection[desc] = function(){
|
|
||||||
jasmine.getEnv()[functionName](desc, fn);
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
jasmine.getEnv()[functionName](desc, fn);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
window.ddescribe = function(name, fn){
|
|
||||||
if (exclusive < 1) {
|
|
||||||
exclusive = 1; // run ddescribe only
|
|
||||||
}
|
|
||||||
window.describe(name, function(){
|
|
||||||
var oldIt = window.it;
|
|
||||||
window.it = function(name, fn){
|
|
||||||
fn.exclusive = 1; // run anything under ddescribe
|
|
||||||
jasmine.getEnv().it(name, fn);
|
|
||||||
};
|
|
||||||
try {
|
|
||||||
fn.call(this);
|
|
||||||
} finally {
|
|
||||||
window.it = oldIt;
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
window.iit = function(name, fn){
|
|
||||||
exclusive = fn.exclusive = 2; // run only iits
|
|
||||||
jasmine.getEnv().it(name, fn);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
this.collectMode = function() {
|
|
||||||
collectMode = true;
|
|
||||||
exclusive = 0; // run everything
|
|
||||||
};
|
|
||||||
this.playback = function(){
|
|
||||||
collectMode = false;
|
|
||||||
playback(beforeEachs);
|
|
||||||
playback(afterEachs);
|
|
||||||
playback(describes);
|
|
||||||
|
|
||||||
function playback(set) {
|
|
||||||
for ( var name in set) {
|
|
||||||
set[name]();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.isExclusive = function(spec) {
|
|
||||||
if (exclusive) {
|
|
||||||
var blocks = spec.queue.blocks;
|
|
||||||
for ( var i = 0; i < blocks.length; i++) {
|
|
||||||
if (blocks[i].func.exclusive >= exclusive) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
})(window);
|
|
||||||
|
|
||||||
// Patch Jasmine for proper stack traces
|
|
||||||
jasmine.Spec.prototype.fail = function (e) {
|
|
||||||
var expectationResult = new jasmine.ExpectationResult({
|
|
||||||
passed: false,
|
|
||||||
message: e ? jasmine.util.formatException(e) : 'Exception'
|
|
||||||
});
|
|
||||||
// PATCH
|
|
||||||
if (e) {
|
|
||||||
expectationResult.trace = e;
|
|
||||||
}
|
|
||||||
this.results_.addResult(expectationResult);
|
|
||||||
};
|
|
||||||
|
|
23
external/jasmineAdapter/MIT.LICENSE
vendored
23
external/jasmineAdapter/MIT.LICENSE
vendored
@ -1,23 +0,0 @@
|
|||||||
Copyright (c) 2010
|
|
||||||
Misko Hevery <misko@hevery.com>
|
|
||||||
Olmo Maldonado <me@ibolmo.com>
|
|
||||||
Christoph Pojer <christoph.pojer@gmail.com>
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
a copy of this software and associated documentation files (the
|
|
||||||
"Software"), to deal in the Software without restriction, including
|
|
||||||
without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
BIN
external/jsTestDriver/JsTestDriver-1.3.3d.jar
vendored
BIN
external/jsTestDriver/JsTestDriver-1.3.3d.jar
vendored
Binary file not shown.
202
external/jsTestDriver/LICENSE-2.0.txt
vendored
202
external/jsTestDriver/LICENSE-2.0.txt
vendored
@ -1,202 +0,0 @@
|
|||||||
|
|
||||||
Apache License
|
|
||||||
Version 2.0, January 2004
|
|
||||||
http://www.apache.org/licenses/
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
||||||
|
|
||||||
1. Definitions.
|
|
||||||
|
|
||||||
"License" shall mean the terms and conditions for use, reproduction,
|
|
||||||
and distribution as defined by Sections 1 through 9 of this document.
|
|
||||||
|
|
||||||
"Licensor" shall mean the copyright owner or entity authorized by
|
|
||||||
the copyright owner that is granting the License.
|
|
||||||
|
|
||||||
"Legal Entity" shall mean the union of the acting entity and all
|
|
||||||
other entities that control, are controlled by, or are under common
|
|
||||||
control with that entity. For the purposes of this definition,
|
|
||||||
"control" means (i) the power, direct or indirect, to cause the
|
|
||||||
direction or management of such entity, whether by contract or
|
|
||||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
||||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
||||||
|
|
||||||
"You" (or "Your") shall mean an individual or Legal Entity
|
|
||||||
exercising permissions granted by this License.
|
|
||||||
|
|
||||||
"Source" form shall mean the preferred form for making modifications,
|
|
||||||
including but not limited to software source code, documentation
|
|
||||||
source, and configuration files.
|
|
||||||
|
|
||||||
"Object" form shall mean any form resulting from mechanical
|
|
||||||
transformation or translation of a Source form, including but
|
|
||||||
not limited to compiled object code, generated documentation,
|
|
||||||
and conversions to other media types.
|
|
||||||
|
|
||||||
"Work" shall mean the work of authorship, whether in Source or
|
|
||||||
Object form, made available under the License, as indicated by a
|
|
||||||
copyright notice that is included in or attached to the work
|
|
||||||
(an example is provided in the Appendix below).
|
|
||||||
|
|
||||||
"Derivative Works" shall mean any work, whether in Source or Object
|
|
||||||
form, that is based on (or derived from) the Work and for which the
|
|
||||||
editorial revisions, annotations, elaborations, or other modifications
|
|
||||||
represent, as a whole, an original work of authorship. For the purposes
|
|
||||||
of this License, Derivative Works shall not include works that remain
|
|
||||||
separable from, or merely link (or bind by name) to the interfaces of,
|
|
||||||
the Work and Derivative Works thereof.
|
|
||||||
|
|
||||||
"Contribution" shall mean any work of authorship, including
|
|
||||||
the original version of the Work and any modifications or additions
|
|
||||||
to that Work or Derivative Works thereof, that is intentionally
|
|
||||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
||||||
or by an individual or Legal Entity authorized to submit on behalf of
|
|
||||||
the copyright owner. For the purposes of this definition, "submitted"
|
|
||||||
means any form of electronic, verbal, or written communication sent
|
|
||||||
to the Licensor or its representatives, including but not limited to
|
|
||||||
communication on electronic mailing lists, source code control systems,
|
|
||||||
and issue tracking systems that are managed by, or on behalf of, the
|
|
||||||
Licensor for the purpose of discussing and improving the Work, but
|
|
||||||
excluding communication that is conspicuously marked or otherwise
|
|
||||||
designated in writing by the copyright owner as "Not a Contribution."
|
|
||||||
|
|
||||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
||||||
on behalf of whom a Contribution has been received by Licensor and
|
|
||||||
subsequently incorporated within the Work.
|
|
||||||
|
|
||||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
copyright license to reproduce, prepare Derivative Works of,
|
|
||||||
publicly display, publicly perform, sublicense, and distribute the
|
|
||||||
Work and such Derivative Works in Source or Object form.
|
|
||||||
|
|
||||||
3. Grant of Patent License. Subject to the terms and conditions of
|
|
||||||
this License, each Contributor hereby grants to You a perpetual,
|
|
||||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
||||||
(except as stated in this section) patent license to make, have made,
|
|
||||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
||||||
where such license applies only to those patent claims licensable
|
|
||||||
by such Contributor that are necessarily infringed by their
|
|
||||||
Contribution(s) alone or by combination of their Contribution(s)
|
|
||||||
with the Work to which such Contribution(s) was submitted. If You
|
|
||||||
institute patent litigation against any entity (including a
|
|
||||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
||||||
or a Contribution incorporated within the Work constitutes direct
|
|
||||||
or contributory patent infringement, then any patent licenses
|
|
||||||
granted to You under this License for that Work shall terminate
|
|
||||||
as of the date such litigation is filed.
|
|
||||||
|
|
||||||
4. Redistribution. You may reproduce and distribute copies of the
|
|
||||||
Work or Derivative Works thereof in any medium, with or without
|
|
||||||
modifications, and in Source or Object form, provided that You
|
|
||||||
meet the following conditions:
|
|
||||||
|
|
||||||
(a) You must give any other recipients of the Work or
|
|
||||||
Derivative Works a copy of this License; and
|
|
||||||
|
|
||||||
(b) You must cause any modified files to carry prominent notices
|
|
||||||
stating that You changed the files; and
|
|
||||||
|
|
||||||
(c) You must retain, in the Source form of any Derivative Works
|
|
||||||
that You distribute, all copyright, patent, trademark, and
|
|
||||||
attribution notices from the Source form of the Work,
|
|
||||||
excluding those notices that do not pertain to any part of
|
|
||||||
the Derivative Works; and
|
|
||||||
|
|
||||||
(d) If the Work includes a "NOTICE" text file as part of its
|
|
||||||
distribution, then any Derivative Works that You distribute must
|
|
||||||
include a readable copy of the attribution notices contained
|
|
||||||
within such NOTICE file, excluding those notices that do not
|
|
||||||
pertain to any part of the Derivative Works, in at least one
|
|
||||||
of the following places: within a NOTICE text file distributed
|
|
||||||
as part of the Derivative Works; within the Source form or
|
|
||||||
documentation, if provided along with the Derivative Works; or,
|
|
||||||
within a display generated by the Derivative Works, if and
|
|
||||||
wherever such third-party notices normally appear. The contents
|
|
||||||
of the NOTICE file are for informational purposes only and
|
|
||||||
do not modify the License. You may add Your own attribution
|
|
||||||
notices within Derivative Works that You distribute, alongside
|
|
||||||
or as an addendum to the NOTICE text from the Work, provided
|
|
||||||
that such additional attribution notices cannot be construed
|
|
||||||
as modifying the License.
|
|
||||||
|
|
||||||
You may add Your own copyright statement to Your modifications and
|
|
||||||
may provide additional or different license terms and conditions
|
|
||||||
for use, reproduction, or distribution of Your modifications, or
|
|
||||||
for any such Derivative Works as a whole, provided Your use,
|
|
||||||
reproduction, and distribution of the Work otherwise complies with
|
|
||||||
the conditions stated in this License.
|
|
||||||
|
|
||||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
||||||
any Contribution intentionally submitted for inclusion in the Work
|
|
||||||
by You to the Licensor shall be under the terms and conditions of
|
|
||||||
this License, without any additional terms or conditions.
|
|
||||||
Notwithstanding the above, nothing herein shall supersede or modify
|
|
||||||
the terms of any separate license agreement you may have executed
|
|
||||||
with Licensor regarding such Contributions.
|
|
||||||
|
|
||||||
6. Trademarks. This License does not grant permission to use the trade
|
|
||||||
names, trademarks, service marks, or product names of the Licensor,
|
|
||||||
except as required for reasonable and customary use in describing the
|
|
||||||
origin of the Work and reproducing the content of the NOTICE file.
|
|
||||||
|
|
||||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
||||||
agreed to in writing, Licensor provides the Work (and each
|
|
||||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
||||||
implied, including, without limitation, any warranties or conditions
|
|
||||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
||||||
appropriateness of using or redistributing the Work and assume any
|
|
||||||
risks associated with Your exercise of permissions under this License.
|
|
||||||
|
|
||||||
8. Limitation of Liability. In no event and under no legal theory,
|
|
||||||
whether in tort (including negligence), contract, or otherwise,
|
|
||||||
unless required by applicable law (such as deliberate and grossly
|
|
||||||
negligent acts) or agreed to in writing, shall any Contributor be
|
|
||||||
liable to You for damages, including any direct, indirect, special,
|
|
||||||
incidental, or consequential damages of any character arising as a
|
|
||||||
result of this License or out of the use or inability to use the
|
|
||||||
Work (including but not limited to damages for loss of goodwill,
|
|
||||||
work stoppage, computer failure or malfunction, or any and all
|
|
||||||
other commercial damages or losses), even if such Contributor
|
|
||||||
has been advised of the possibility of such damages.
|
|
||||||
|
|
||||||
9. Accepting Warranty or Additional Liability. While redistributing
|
|
||||||
the Work or Derivative Works thereof, You may choose to offer,
|
|
||||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
||||||
or other liability obligations and/or rights consistent with this
|
|
||||||
License. However, in accepting such obligations, You may act only
|
|
||||||
on Your own behalf and on Your sole responsibility, not on behalf
|
|
||||||
of any other Contributor, and only if You agree to indemnify,
|
|
||||||
defend, and hold each Contributor harmless for any liability
|
|
||||||
incurred by, or claims asserted against, such Contributor by reason
|
|
||||||
of your accepting any such warranty or additional liability.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
APPENDIX: How to apply the Apache License to your work.
|
|
||||||
|
|
||||||
To apply the Apache License to your work, attach the following
|
|
||||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
||||||
replaced with your own identifying information. (Don't include
|
|
||||||
the brackets!) The text should be enclosed in the appropriate
|
|
||||||
comment syntax for the file format. We also recommend that a
|
|
||||||
file or class name and description of purpose be included on the
|
|
||||||
same "printed page" as the copyright notice for easier
|
|
||||||
identification within third-party archives.
|
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
|
||||||
|
|
||||||
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.
|
|
29
make.js
29
make.js
@ -358,8 +358,9 @@ target.chrome = function() {
|
|||||||
// make test
|
// make test
|
||||||
//
|
//
|
||||||
target.test = function() {
|
target.test = function() {
|
||||||
target.browsertest();
|
target.unittest({}, function() {
|
||||||
target.unittest();
|
target.browsertest();
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -367,8 +368,10 @@ target.test = function() {
|
|||||||
// (Special tests for the Github bot)
|
// (Special tests for the Github bot)
|
||||||
//
|
//
|
||||||
target.bottest = function() {
|
target.bottest = function() {
|
||||||
target.browsertest({noreftest: true});
|
target.unittest();
|
||||||
// target.unittest();
|
target.browsertest({noreftest: true}, function() {
|
||||||
|
target.browsertest();
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -398,18 +401,22 @@ target.browsertest = function(options) {
|
|||||||
//
|
//
|
||||||
// make unittest
|
// make unittest
|
||||||
//
|
//
|
||||||
target.unittest = function() {
|
target.unittest = function(options, callback) {
|
||||||
cd(ROOT_DIR);
|
cd(ROOT_DIR);
|
||||||
echo();
|
echo();
|
||||||
echo('### Running unit tests');
|
echo('### Running unit tests');
|
||||||
|
|
||||||
if (!which('make')) {
|
var PDF_BROWSERS = env['PDF_BROWSERS'] || 'resources/browser_manifests/browser_manifest.json';
|
||||||
echo('make not found. Skipping unit tests...');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cd('test/unit');
|
if (!test('-f', 'test/' + PDF_BROWSERS)) {
|
||||||
exec('make', {async: true});
|
echo('Browser manifest file test/' + PDF_BROWSERS + ' does not exist.');
|
||||||
|
echo('Try copying one of the examples in test/resources/browser_manifests/');
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
callback = callback || function() {};
|
||||||
|
cd('test');
|
||||||
|
exec(PYTHON_BIN + ' -u test.py --unitTest --browserManifestFile=' + PDF_BROWSERS,
|
||||||
|
{async: true}, callback);
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
//
|
||||||
|
209
test/test.py
209
test/test.py
@ -39,9 +39,13 @@ class TestOptions(OptionParser):
|
|||||||
default=False)
|
default=False)
|
||||||
self.add_option("--port", action="store", dest="port", type="int",
|
self.add_option("--port", action="store", dest="port", type="int",
|
||||||
help="The port the HTTP server should listen on.", default=8080)
|
help="The port the HTTP server should listen on.", default=8080)
|
||||||
|
self.add_option("--unitTest", action="store_true", dest="unitTest",
|
||||||
|
help="Run the unit tests.", default=False)
|
||||||
self.set_usage(USAGE_EXAMPLE)
|
self.set_usage(USAGE_EXAMPLE)
|
||||||
|
|
||||||
def verifyOptions(self, options):
|
def verifyOptions(self, options):
|
||||||
|
if options.reftest and options.unitTest:
|
||||||
|
self.error("--reftest and --unitTest must not be specified at the same time.")
|
||||||
if options.masterMode and options.manifestFile:
|
if options.masterMode and options.manifestFile:
|
||||||
self.error("--masterMode and --manifestFile must not be specified at the same time.")
|
self.error("--masterMode and --manifestFile must not be specified at the same time.")
|
||||||
if not options.manifestFile:
|
if not options.manifestFile:
|
||||||
@ -50,6 +54,7 @@ class TestOptions(OptionParser):
|
|||||||
print "Warning: ignoring browser argument since manifest file was also supplied"
|
print "Warning: ignoring browser argument since manifest file was also supplied"
|
||||||
if not options.browser and not options.browserManifestFile:
|
if not options.browser and not options.browserManifestFile:
|
||||||
print "Starting server on port %s." % options.port
|
print "Starting server on port %s." % options.port
|
||||||
|
|
||||||
return options
|
return options
|
||||||
|
|
||||||
def prompt(question):
|
def prompt(question):
|
||||||
@ -86,6 +91,13 @@ class State:
|
|||||||
eqLog = None
|
eqLog = None
|
||||||
lastPost = { }
|
lastPost = { }
|
||||||
|
|
||||||
|
class UnitTestState:
|
||||||
|
browsers = [ ]
|
||||||
|
browsersRunning = 0
|
||||||
|
lastPost = { }
|
||||||
|
numErrors = 0
|
||||||
|
numRun = 0
|
||||||
|
|
||||||
class Result:
|
class Result:
|
||||||
def __init__(self, snapshot, failure, page):
|
def __init__(self, snapshot, failure, page):
|
||||||
self.snapshot = snapshot
|
self.snapshot = snapshot
|
||||||
@ -95,8 +107,7 @@ class Result:
|
|||||||
class TestServer(SocketServer.TCPServer):
|
class TestServer(SocketServer.TCPServer):
|
||||||
allow_reuse_address = True
|
allow_reuse_address = True
|
||||||
|
|
||||||
class PDFTestHandler(BaseHTTPRequestHandler):
|
class TestHandlerBase(BaseHTTPRequestHandler):
|
||||||
|
|
||||||
# Disable annoying noise by default
|
# Disable annoying noise by default
|
||||||
def log_request(code=0, size=0):
|
def log_request(code=0, size=0):
|
||||||
if VERBOSE:
|
if VERBOSE:
|
||||||
@ -110,34 +121,6 @@ class PDFTestHandler(BaseHTTPRequestHandler):
|
|||||||
with open(path, "rb") as f:
|
with open(path, "rb") as f:
|
||||||
self.wfile.write(f.read())
|
self.wfile.write(f.read())
|
||||||
|
|
||||||
def sendIndex(self, path, query):
|
|
||||||
if not path.endswith("/"):
|
|
||||||
# we need trailing slash
|
|
||||||
self.send_response(301)
|
|
||||||
redirectLocation = path + "/"
|
|
||||||
if query:
|
|
||||||
redirectLocation += "?" + query
|
|
||||||
self.send_header("Location", redirectLocation)
|
|
||||||
self.end_headers()
|
|
||||||
return
|
|
||||||
|
|
||||||
self.send_response(200)
|
|
||||||
self.send_header("Content-Type", "text/html")
|
|
||||||
self.end_headers()
|
|
||||||
if query == "frame":
|
|
||||||
self.wfile.write("<html><frameset cols=*,200><frame name=pdf>" +
|
|
||||||
"<frame src='" + path + "'></frameset></html>")
|
|
||||||
return
|
|
||||||
|
|
||||||
location = os.path.abspath(os.path.realpath(DOC_ROOT + os.sep + path))
|
|
||||||
self.wfile.write("<html><body><h1>PDFs of " + path + "</h1>\n")
|
|
||||||
for filename in os.listdir(location):
|
|
||||||
if filename.lower().endswith('.pdf'):
|
|
||||||
self.wfile.write("<a href='/web/viewer.html?file=" +
|
|
||||||
urllib.quote_plus(path + filename, '/') + "' target=pdf>" +
|
|
||||||
filename + "</a><br>\n")
|
|
||||||
self.wfile.write("</body></html>")
|
|
||||||
|
|
||||||
def do_GET(self):
|
def do_GET(self):
|
||||||
url = urlparse(self.path)
|
url = urlparse(self.path)
|
||||||
# Ignore query string
|
# Ignore query string
|
||||||
@ -168,6 +151,70 @@ class PDFTestHandler(BaseHTTPRequestHandler):
|
|||||||
|
|
||||||
self.sendFile(path, ext)
|
self.sendFile(path, ext)
|
||||||
|
|
||||||
|
class UnitTestHandler(TestHandlerBase):
|
||||||
|
def sendIndex(self, path, query):
|
||||||
|
print "send index"
|
||||||
|
def do_POST(self):
|
||||||
|
numBytes = int(self.headers['Content-Length'])
|
||||||
|
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header('Content-Type', 'text/plain')
|
||||||
|
self.end_headers()
|
||||||
|
|
||||||
|
url = urlparse(self.path)
|
||||||
|
result = json.loads(self.rfile.read(numBytes))
|
||||||
|
browser = result['browser']
|
||||||
|
UnitTestState.lastPost[browser] = int(time.time())
|
||||||
|
if url.path == "/tellMeToQuit":
|
||||||
|
tellAppToQuit(url.path, url.query)
|
||||||
|
UnitTestState.browsersRunning -= 1
|
||||||
|
UnitTestState.lastPost[browser] = None
|
||||||
|
return
|
||||||
|
elif url.path == '/info':
|
||||||
|
print result['message']
|
||||||
|
elif url.path == '/submit_task_results':
|
||||||
|
status, description = result['status'], result['description']
|
||||||
|
UnitTestState.numRun += 1
|
||||||
|
if status == 'TEST-UNEXPECTED-FAIL':
|
||||||
|
UnitTestState.numErrors += 1
|
||||||
|
message = status + ' | ' + description + ' | in ' + browser
|
||||||
|
if 'error' in result:
|
||||||
|
message += ' | ' + result['error']
|
||||||
|
print message
|
||||||
|
else:
|
||||||
|
print 'Error: uknown action' + url.path
|
||||||
|
|
||||||
|
class PDFTestHandler(TestHandlerBase):
|
||||||
|
|
||||||
|
def sendIndex(self, path, query):
|
||||||
|
if not path.endswith("/"):
|
||||||
|
# we need trailing slash
|
||||||
|
self.send_response(301)
|
||||||
|
redirectLocation = path + "/"
|
||||||
|
if query:
|
||||||
|
redirectLocation += "?" + query
|
||||||
|
self.send_header("Location", redirectLocation)
|
||||||
|
self.end_headers()
|
||||||
|
return
|
||||||
|
|
||||||
|
self.send_response(200)
|
||||||
|
self.send_header("Content-Type", "text/html")
|
||||||
|
self.end_headers()
|
||||||
|
if query == "frame":
|
||||||
|
self.wfile.write("<html><frameset cols=*,200><frame name=pdf>" +
|
||||||
|
"<frame src='" + path + "'></frameset></html>")
|
||||||
|
return
|
||||||
|
|
||||||
|
location = os.path.abspath(os.path.realpath(DOC_ROOT + os.sep + path))
|
||||||
|
self.wfile.write("<html><body><h1>PDFs of " + path + "</h1>\n")
|
||||||
|
for filename in os.listdir(location):
|
||||||
|
if filename.lower().endswith('.pdf'):
|
||||||
|
self.wfile.write("<a href='/web/viewer.html?file=" +
|
||||||
|
urllib.quote_plus(path + filename, '/') + "' target=pdf>" +
|
||||||
|
filename + "</a><br>\n")
|
||||||
|
self.wfile.write("</body></html>")
|
||||||
|
|
||||||
|
|
||||||
def do_POST(self):
|
def do_POST(self):
|
||||||
numBytes = int(self.headers['Content-Length'])
|
numBytes = int(self.headers['Content-Length'])
|
||||||
|
|
||||||
@ -354,6 +401,17 @@ def verifyPDFs(manifestList):
|
|||||||
error = True
|
error = True
|
||||||
return not error
|
return not error
|
||||||
|
|
||||||
|
def getTestBrowsers(options):
|
||||||
|
testBrowsers = []
|
||||||
|
if options.browserManifestFile:
|
||||||
|
testBrowsers = makeBrowserCommands(options.browserManifestFile)
|
||||||
|
elif options.browser:
|
||||||
|
testBrowsers = [makeBrowserCommand({"path":options.browser, "name":None})]
|
||||||
|
|
||||||
|
if options.browserManifestFile or options.browser:
|
||||||
|
assert len(testBrowsers) > 0
|
||||||
|
return testBrowsers
|
||||||
|
|
||||||
def setUp(options):
|
def setUp(options):
|
||||||
# Only serve files from a pdf.js clone
|
# Only serve files from a pdf.js clone
|
||||||
assert not GIT_CLONE_CHECK or os.path.isfile('../src/pdf.js') and os.path.isdir('../.git')
|
assert not GIT_CLONE_CHECK or os.path.isfile('../src/pdf.js') and os.path.isdir('../.git')
|
||||||
@ -366,14 +424,7 @@ def setUp(options):
|
|||||||
|
|
||||||
assert not os.path.isdir(TMPDIR)
|
assert not os.path.isdir(TMPDIR)
|
||||||
|
|
||||||
testBrowsers = []
|
testBrowsers = getTestBrowsers(options)
|
||||||
if options.browserManifestFile:
|
|
||||||
testBrowsers = makeBrowserCommands(options.browserManifestFile)
|
|
||||||
elif options.browser:
|
|
||||||
testBrowsers = [makeBrowserCommand({"path":options.browser, "name":None})]
|
|
||||||
|
|
||||||
if options.browserManifestFile or options.browser:
|
|
||||||
assert len(testBrowsers) > 0
|
|
||||||
|
|
||||||
with open(options.manifestFile) as mf:
|
with open(options.manifestFile) as mf:
|
||||||
manifestList = json.load(mf)
|
manifestList = json.load(mf)
|
||||||
@ -398,13 +449,23 @@ def setUp(options):
|
|||||||
|
|
||||||
return testBrowsers
|
return testBrowsers
|
||||||
|
|
||||||
def startBrowsers(browsers, options):
|
def setUpUnitTests(options):
|
||||||
|
# Only serve files from a pdf.js clone
|
||||||
|
assert not GIT_CLONE_CHECK or os.path.isfile('../src/pdf.js') and os.path.isdir('../.git')
|
||||||
|
|
||||||
|
testBrowsers = getTestBrowsers(options)
|
||||||
|
|
||||||
|
UnitTestState.browsersRunning = len(testBrowsers)
|
||||||
|
for b in testBrowsers:
|
||||||
|
UnitTestState.lastPost[b.name] = int(time.time())
|
||||||
|
return testBrowsers
|
||||||
|
|
||||||
|
def startBrowsers(browsers, options, path):
|
||||||
for b in browsers:
|
for b in browsers:
|
||||||
b.setup()
|
b.setup()
|
||||||
print 'Launching', b.name
|
print 'Launching', b.name
|
||||||
host = 'http://%s:%s' % (SERVER_HOST, options.port)
|
host = 'http://%s:%s' % (SERVER_HOST, options.port)
|
||||||
path = '/test/test_slave.html?'
|
qs = '?browser='+ urllib.quote(b.name) +'&manifestFile='+ urllib.quote(options.manifestFile)
|
||||||
qs = 'browser='+ urllib.quote(b.name) +'&manifestFile='+ urllib.quote(options.manifestFile)
|
|
||||||
qs += '&path=' + b.path
|
qs += '&path=' + b.path
|
||||||
b.start(host + path + qs)
|
b.start(host + path + qs)
|
||||||
|
|
||||||
@ -576,7 +637,7 @@ def startReftest(browser, options):
|
|||||||
def runTests(options, browsers):
|
def runTests(options, browsers):
|
||||||
t1 = time.time()
|
t1 = time.time()
|
||||||
try:
|
try:
|
||||||
startBrowsers(browsers, options)
|
startBrowsers(browsers, options, '/test/test_slave.html')
|
||||||
while not State.done:
|
while not State.done:
|
||||||
for b in State.lastPost:
|
for b in State.lastPost:
|
||||||
if State.remaining[b] > 0 and int(time.time()) - State.lastPost[b] > BROWSER_TIMEOUT:
|
if State.remaining[b] > 0 and int(time.time()) - State.lastPost[b] > BROWSER_TIMEOUT:
|
||||||
@ -598,6 +659,30 @@ def runTests(options, browsers):
|
|||||||
print "\nStarting reftest harness to examine %d eq test failures." % State.numEqFailures
|
print "\nStarting reftest harness to examine %d eq test failures." % State.numEqFailures
|
||||||
startReftest(browsers[0], options)
|
startReftest(browsers[0], options)
|
||||||
|
|
||||||
|
def runUnitTests(options, browsers):
|
||||||
|
t1 = time.time()
|
||||||
|
try:
|
||||||
|
startBrowsers(browsers, options, '/test/unit/unit_test.html')
|
||||||
|
while UnitTestState.browsersRunning > 0:
|
||||||
|
for b in UnitTestState.lastPost:
|
||||||
|
if UnitTestState.lastPost[b] != None and int(time.time()) - UnitTestState.lastPost[b] > BROWSER_TIMEOUT:
|
||||||
|
print 'TEST-UNEXPECTED-FAIL | test failed', b, "has not responded in", BROWSER_TIMEOUT, "s"
|
||||||
|
UnitTestState.lastPost[b] = None
|
||||||
|
UnitTestState.browsersRunning -= 1
|
||||||
|
UnitTestState.numErrors += 1
|
||||||
|
time.sleep(1)
|
||||||
|
print ''
|
||||||
|
print 'Ran', UnitTestState.numRun, 'tests'
|
||||||
|
if UnitTestState.numErrors > 0:
|
||||||
|
print 'OHNOES! Some tests failed!'
|
||||||
|
print ' ', UnitTestState.numErrors, 'of', UnitTestState.numRun, 'failed'
|
||||||
|
else:
|
||||||
|
print 'All unit tests passed.'
|
||||||
|
finally:
|
||||||
|
teardownBrowsers(browsers)
|
||||||
|
t2 = time.time()
|
||||||
|
print "Unit test Runtime was", int(t2 - t1), "seconds"
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
optionParser = TestOptions()
|
optionParser = TestOptions()
|
||||||
options, args = optionParser.parse_args()
|
options, args = optionParser.parse_args()
|
||||||
@ -605,23 +690,33 @@ def main():
|
|||||||
if options == None:
|
if options == None:
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
httpd = TestServer((SERVER_HOST, options.port), PDFTestHandler)
|
if options.unitTest:
|
||||||
httpd.masterMode = options.masterMode
|
httpd = TestServer((SERVER_HOST, options.port), UnitTestHandler)
|
||||||
httpd_thread = threading.Thread(target=httpd.serve_forever)
|
httpd_thread = threading.Thread(target=httpd.serve_forever)
|
||||||
httpd_thread.setDaemon(True)
|
httpd_thread.setDaemon(True)
|
||||||
httpd_thread.start()
|
httpd_thread.start()
|
||||||
|
|
||||||
browsers = setUp(options)
|
browsers = setUpUnitTests(options)
|
||||||
if len(browsers) > 0:
|
if len(browsers) > 0:
|
||||||
runTests(options, browsers)
|
runUnitTests(options, browsers)
|
||||||
else:
|
else:
|
||||||
# just run the server
|
httpd = TestServer((SERVER_HOST, options.port), PDFTestHandler)
|
||||||
print "Running HTTP server. Press Ctrl-C to quit."
|
httpd.masterMode = options.masterMode
|
||||||
try:
|
httpd_thread = threading.Thread(target=httpd.serve_forever)
|
||||||
while True:
|
httpd_thread.setDaemon(True)
|
||||||
time.sleep(1)
|
httpd_thread.start()
|
||||||
except (KeyboardInterrupt):
|
|
||||||
print "\nExiting."
|
browsers = setUp(options)
|
||||||
|
if len(browsers) > 0:
|
||||||
|
runTests(options, browsers)
|
||||||
|
else:
|
||||||
|
# just run the server
|
||||||
|
print "Running HTTP server. Press Ctrl-C to quit."
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
time.sleep(1)
|
||||||
|
except (KeyboardInterrupt):
|
||||||
|
print "\nExiting."
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
@ -1,116 +0,0 @@
|
|||||||
# Create temporary profile directory name.
|
|
||||||
TEMP_PROFILE:=$(shell echo `pwd`)/test_reports/temp_profile
|
|
||||||
|
|
||||||
# These are the Firefox command line arguments.
|
|
||||||
FIREFOX_ARGS:=-no-remote -profile $(TEMP_PROFILE)
|
|
||||||
|
|
||||||
# These are the Chrome command line arguments.
|
|
||||||
CHROME_ARGS:=--user-data-dir=$(TEMP_PROFILE) --no-first-run --disable-sync
|
|
||||||
|
|
||||||
# Unit test uses the manifest from ref test to determine which browsers will
|
|
||||||
# be used for running the unit tests.
|
|
||||||
MANIFEST:=../resources/browser_manifests/browser_manifest.json
|
|
||||||
|
|
||||||
# This is a helper command to separate multiple browsers to their own lines
|
|
||||||
# for an easier sed operation.
|
|
||||||
SPLIT_LINES:=sed 's|,|,@|g' | tr '@' '\n'
|
|
||||||
|
|
||||||
# This is a helper command to join multiple lines together.
|
|
||||||
JOIN_LINES:=tr -d '\n'
|
|
||||||
|
|
||||||
# Fetch the paths to browsers that are going to be used in testing.
|
|
||||||
# For OS X the path to the binary needs to be added.
|
|
||||||
# Add the browser arguments for each browser.
|
|
||||||
# Create random profile directory for each browser.
|
|
||||||
BROWSERS_PATHS:=$(shell echo `\
|
|
||||||
sed -n 's|.*"path":\(.*\)|\1,|p' $(MANIFEST) | \
|
|
||||||
$(JOIN_LINES) \
|
|
||||||
`)
|
|
||||||
|
|
||||||
# The browser_manifest.json file has only the app directory for mac browsers.
|
|
||||||
# The absolute path to the browser binary needs to be used.
|
|
||||||
BROWSERS_PATHS_WITH_MAC_CORRECTION:=$(shell echo '$(BROWSERS_PATHS)' | \
|
|
||||||
$(SPLIT_LINES) | \
|
|
||||||
sed 's|\(Aurora\.app\)|\1/Contents/MacOS/firefox-bin|' | \
|
|
||||||
sed 's|\(Firefox.*\.app\)|\1/Contents/MacOS/firefox-bin|' | \
|
|
||||||
sed 's|\(Google Chrome\.app\)|\1/Contents/MacOS/Google Chrome|' | \
|
|
||||||
$(JOIN_LINES) \
|
|
||||||
)
|
|
||||||
|
|
||||||
# Replace " with @@@@ so that echoing do not destroy the quotation marks.
|
|
||||||
QUOTATION_MARK:=\"
|
|
||||||
SUBSTITUTE_FOR_QUOTATION_MARK:=@@@@
|
|
||||||
|
|
||||||
# Each of the browser can have their own separate arguments.
|
|
||||||
BROWSERS_WITH_ARGUMENTS:=$(shell echo '$(BROWSERS_PATHS_WITH_MAC_CORRECTION)' | \
|
|
||||||
$(SPLIT_LINES) | \
|
|
||||||
sed "s|\(irefox.*\)\($(QUOTATION_MARK)\),|\1;$(FIREFOX_ARGS)\2,|" | \
|
|
||||||
sed "s|\(hrome.*\)\($(QUOTATION_MARK)\),|\1;$(CHROME_ARGS)\2,|" | \
|
|
||||||
$(JOIN_LINES) \
|
|
||||||
)
|
|
||||||
|
|
||||||
# A temporary profile directory is needed for each of the browser. In this way
|
|
||||||
# a unit test run will not disturb the main browsing session of the user. The
|
|
||||||
# $RANDOM shell variable is used to generate non-conflicting temporary
|
|
||||||
# directories.
|
|
||||||
BROWSERS_WITH_UKNOWN_RANDOM_PROFILE_PATHS:=$(shell echo '$(BROWSERS_WITH_ARGUMENTS)' | \
|
|
||||||
$(SPLIT_LINES) | \
|
|
||||||
sed 's|\(temp_profile\)|\1_$$RANDOM$$RANDOM|' | \
|
|
||||||
sed "s|$(QUOTATION_MARK)|$(SUBSTITUTE_FOR_QUOTATION_MARK)|g" | \
|
|
||||||
$(JOIN_LINES) \
|
|
||||||
)
|
|
||||||
|
|
||||||
# Echo the variable so that the unknown random directories become known.
|
|
||||||
# Replace @@@@ with " so that jsTestDriver will work properly.
|
|
||||||
BROWSERS:=$(shell echo "$(BROWSERS_WITH_UKNOWN_RANDOM_PROFILE_PATHS)" | \
|
|
||||||
sed "s|$(SUBSTITUTE_FOR_QUOTATION_MARK)|$(QUOTATION_MARK)|g" \
|
|
||||||
)
|
|
||||||
|
|
||||||
# Get the known random directories for browsers. This information will be used
|
|
||||||
# to create the profile directories beforehand. Create also the dummy temp
|
|
||||||
# profile directory so that the mkdir command would not fail for browsers that
|
|
||||||
# do not need it.
|
|
||||||
PROFILES:=$(TEMP_PROFILE) $(shell echo '$(BROWSERS)' | \
|
|
||||||
$(SPLIT_LINES) | \
|
|
||||||
sed -n "s|.*\( $(TEMP_PROFILE)_[0-9]\+\).*|\1|p" | \
|
|
||||||
$(JOIN_LINES) \
|
|
||||||
)
|
|
||||||
|
|
||||||
# This is the command to invoke the unit test.
|
|
||||||
PROG:=java \
|
|
||||||
-Xms512m \
|
|
||||||
-Xmx1024m \
|
|
||||||
-jar ../../external/jsTestDriver/JsTestDriver-1.3.3d.jar \
|
|
||||||
--config ./jsTestDriver.conf \
|
|
||||||
--reset \
|
|
||||||
--port 4224 \
|
|
||||||
--browser $(BROWSERS) \
|
|
||||||
--tests all \
|
|
||||||
--testOutput ./test_reports/
|
|
||||||
|
|
||||||
# This default rule runs the unit tests with the constructed command.
|
|
||||||
test:
|
|
||||||
@mkdir -p $(PROFILES)
|
|
||||||
$(PROG)
|
|
||||||
@rm -rf $(PROFILES)
|
|
||||||
|
|
||||||
# In case this Makefile needs to be debugged then this rule will provide all
|
|
||||||
# the information from intermediate steps.
|
|
||||||
debug:
|
|
||||||
@echo 'Debug browsers paths: $(BROWSERS_PATHS)'
|
|
||||||
@echo
|
|
||||||
@echo 'Debug browsers paths with mac correction: $(BROWSERS_PATHS_WITH_MAC_CORRECTION)'
|
|
||||||
@echo
|
|
||||||
@echo 'Debug browsers with arguments: $(BROWSERS_WITH_ARGUMENTS)'
|
|
||||||
@echo
|
|
||||||
@echo 'Debug browsers random profile paths: $(BROWSERS_WITH_UKNOWN_RANDOM_PROFILE_PATHS)'
|
|
||||||
@echo
|
|
||||||
@echo 'Debug browsers: $(BROWSERS)'
|
|
||||||
@echo
|
|
||||||
@echo 'Debug profiles: $(PROFILES)'
|
|
||||||
@echo
|
|
||||||
@echo 'Command to be run: $(PROG)'
|
|
||||||
@echo
|
|
||||||
|
|
||||||
.phony:: test
|
|
||||||
|
|
@ -6,11 +6,11 @@
|
|||||||
describe('api', function() {
|
describe('api', function() {
|
||||||
// TODO run with worker enabled
|
// TODO run with worker enabled
|
||||||
PDFJS.disableWorker = true;
|
PDFJS.disableWorker = true;
|
||||||
var basicApiUrl = '/basicapi.pdf';
|
var basicApiUrl = '../pdfs/basicapi.pdf';
|
||||||
function waitsForPromise(promise) {
|
function waitsForPromise(promise) {
|
||||||
waitsFor(function() {
|
waitsFor(function() {
|
||||||
return promise.isResolved || promise.isRejected;
|
return promise.isResolved || promise.isRejected;
|
||||||
}, 250);
|
}, 1000);
|
||||||
}
|
}
|
||||||
function expectAfterPromise(promise, successCallback) {
|
function expectAfterPromise(promise, successCallback) {
|
||||||
waitsForPromise(promise);
|
waitsForPromise(promise);
|
||||||
@ -25,8 +25,6 @@ describe('api', function() {
|
|||||||
describe('PDFJS', function() {
|
describe('PDFJS', function() {
|
||||||
describe('getDocument', function() {
|
describe('getDocument', function() {
|
||||||
it('creates pdf doc from URL', function() {
|
it('creates pdf doc from URL', function() {
|
||||||
console.log('what is');
|
|
||||||
debugger;
|
|
||||||
var promise = PDFJS.getDocument(basicApiUrl);
|
var promise = PDFJS.getDocument(basicApiUrl);
|
||||||
expectAfterPromise(promise, function(data) {
|
expectAfterPromise(promise, function(data) {
|
||||||
expect(true).toEqual(true);
|
expect(true).toEqual(true);
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
server: http://localhost:4224
|
|
||||||
|
|
||||||
basepath: ..
|
|
||||||
|
|
||||||
load:
|
|
||||||
- ../external/jasmine/jasmine.js
|
|
||||||
- ../external/jasmineAdapter/JasmineAdapter.js
|
|
||||||
- ../src/obj.js
|
|
||||||
- ../src/core.js
|
|
||||||
- ../src/util.js
|
|
||||||
- ../src/api.js
|
|
||||||
- ../src/canvas.js
|
|
||||||
- ../src/obj.js
|
|
||||||
- ../src/function.js
|
|
||||||
- ../src/charsets.js
|
|
||||||
- ../src/cidmaps.js
|
|
||||||
- ../src/colorspace.js
|
|
||||||
- ../src/crypto.js
|
|
||||||
- ../src/evaluator.js
|
|
||||||
- ../src/fonts.js
|
|
||||||
- ../src/glyphlist.js
|
|
||||||
- ../src/image.js
|
|
||||||
- ../src/metrics.js
|
|
||||||
- ../src/parser.js
|
|
||||||
- ../src/pattern.js
|
|
||||||
- ../src/stream.js
|
|
||||||
- ../src/worker.js
|
|
||||||
- ../src/bidi.js
|
|
||||||
- ../src/metadata.js
|
|
||||||
- ../external/jpgjs/jpg.js
|
|
||||||
- unit/obj_spec.js
|
|
||||||
- unit/font_spec.js
|
|
||||||
- unit/function_spec.js
|
|
||||||
- unit/crypto_spec.js
|
|
||||||
- unit/stream_spec.js
|
|
||||||
- unit/api_spec.js
|
|
||||||
|
|
||||||
gateway:
|
|
||||||
- {matcher: "*.pdf", server: "http://localhost:8888/test/pdfs/"}
|
|
@ -4,7 +4,21 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
describe('stream', function() {
|
describe('stream', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
this.addMatchers({
|
||||||
|
toMatchTypedArray: function(expected) {
|
||||||
|
var actual = this.actual;
|
||||||
|
if (actual.length != expected.length)
|
||||||
|
return false;
|
||||||
|
for (var i = 0, ii = expected.length; i < ii; i++) {
|
||||||
|
var a = actual[i], b = expected[i];
|
||||||
|
if (a !== b)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
describe('PredictorStream', function() {
|
describe('PredictorStream', function() {
|
||||||
it('should decode simple predictor data', function() {
|
it('should decode simple predictor data', function() {
|
||||||
var dict = new Dict();
|
var dict = new Dict();
|
||||||
@ -18,7 +32,7 @@ describe('stream', function() {
|
|||||||
var predictor = new PredictorStream(input, dict);
|
var predictor = new PredictorStream(input, dict);
|
||||||
var result = predictor.getBytes(6);
|
var result = predictor.getBytes(6);
|
||||||
|
|
||||||
expect(result).toEqual(new Uint8Array([100, 3, 101, 2, 102, 1]));
|
expect(result).toMatchTypedArray(new Uint8Array([100, 3, 101, 2, 102, 1]));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
3
test/unit/test_reports/.gitignore
vendored
3
test/unit/test_reports/.gitignore
vendored
@ -1,3 +0,0 @@
|
|||||||
TEST*
|
|
||||||
temp*
|
|
||||||
|
|
71
test/unit/testreporter.js
Normal file
71
test/unit/testreporter.js
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||||
|
|
||||||
|
var TestReporter = function(browser, appPath) {
|
||||||
|
function send(action, json) {
|
||||||
|
var r = new XMLHttpRequest();
|
||||||
|
// (The POST URI is ignored atm.)
|
||||||
|
r.open('POST', action, true);
|
||||||
|
r.setRequestHeader('Content-Type', 'application/json');
|
||||||
|
r.onreadystatechange = function sendTaskResultOnreadystatechange(e) {
|
||||||
|
if (r.readyState == 4) {
|
||||||
|
// Retry until successful
|
||||||
|
if (r.status !== 200)
|
||||||
|
send(action, json);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
json['browser'] = browser;
|
||||||
|
r.send(JSON.stringify(json));
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendInfo(message) {
|
||||||
|
send('/info', {message: message});
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendResult(status, description, error) {
|
||||||
|
var message = {
|
||||||
|
status: status,
|
||||||
|
description: description
|
||||||
|
};
|
||||||
|
if (typeof error !== 'undefined')
|
||||||
|
message['error'] = error;
|
||||||
|
send('/submit_task_results', message);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendQuitRequest() {
|
||||||
|
send('/tellMeToQuit?path=' + escape(appPath), {});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.now = function() {
|
||||||
|
return new Date().getTime();
|
||||||
|
};
|
||||||
|
|
||||||
|
this.reportRunnerStarting = function() {
|
||||||
|
this.runnerStartTime = this.now();
|
||||||
|
sendInfo('Started unit tests for ' + browser + '.');
|
||||||
|
};
|
||||||
|
|
||||||
|
this.reportSpecStarting = function() { };
|
||||||
|
|
||||||
|
this.reportSpecResults = function(spec) {
|
||||||
|
var results = spec.results();
|
||||||
|
if (results.skipped) {
|
||||||
|
sendResult('TEST-SKIPPED', results.description);
|
||||||
|
} else if (results.passed()) {
|
||||||
|
sendResult('TEST-PASSED', results.description);
|
||||||
|
} else {
|
||||||
|
var failedMessages = '';
|
||||||
|
var items = results.getItems();
|
||||||
|
for (var i = 0, ii = items.length; i < ii; i++)
|
||||||
|
if (!items[i].passed())
|
||||||
|
failedMessages += items[i].message + ' ';
|
||||||
|
sendResult('TEST-UNEXPECTED-FAIL', results.description, failedMessages);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.reportSuiteResults = function(suite) { };
|
||||||
|
|
||||||
|
this.reportRunnerResults = function(runner) {
|
||||||
|
sendQuitRequest();
|
||||||
|
};
|
||||||
|
};
|
94
test/unit/unit_test.html
Normal file
94
test/unit/unit_test.html
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>pdf.js unit test</title>
|
||||||
|
|
||||||
|
<link rel="shortcut icon" type="image/png" href="../../external/jasmine/jasmine_favicon.png">
|
||||||
|
<link rel="stylesheet" type="text/css" href="../../external/jasmine/jasmine.css">
|
||||||
|
|
||||||
|
<script type="text/javascript" src="../../external/jasmine/jasmine.js"></script>
|
||||||
|
<script type="text/javascript" src="../../external/jasmine/jasmine-html.js"></script>
|
||||||
|
<script type="text/javascript" src="testreporter.js"></script>
|
||||||
|
|
||||||
|
<!-- include source files here... -->
|
||||||
|
<script type="text/javascript" src="../../src/core.js"></script>
|
||||||
|
<script type="text/javascript" src="../../src/api.js"></script>
|
||||||
|
<script type="text/javascript" src="../../src/util.js"></script>
|
||||||
|
<script type="text/javascript" src="../../src/canvas.js"></script>
|
||||||
|
<script type="text/javascript" src="../../src/obj.js"></script>
|
||||||
|
<script type="text/javascript" src="../../src/function.js"></script>
|
||||||
|
<script type="text/javascript" src="../../src/charsets.js"></script>
|
||||||
|
<script type="text/javascript" src="../../src/cidmaps.js"></script>
|
||||||
|
<script type="text/javascript" src="../../src/colorspace.js"></script>
|
||||||
|
<script type="text/javascript" src="../../src/crypto.js"></script>
|
||||||
|
<script type="text/javascript" src="../../src/evaluator.js"></script>
|
||||||
|
<script type="text/javascript" src="../../src/fonts.js"></script>
|
||||||
|
<script type="text/javascript" src="../../src/glyphlist.js"></script>
|
||||||
|
<script type="text/javascript" src="../../src/image.js"></script>
|
||||||
|
<script type="text/javascript" src="../../src/metrics.js"></script>
|
||||||
|
<script type="text/javascript" src="../../src/parser.js"></script>
|
||||||
|
<script type="text/javascript" src="../../src/pattern.js"></script>
|
||||||
|
<script type="text/javascript" src="../../src/stream.js"></script>
|
||||||
|
<script type="text/javascript" src="../../src/worker.js"></script>
|
||||||
|
<script type="text/javascript" src="../../src/metadata.js"></script>
|
||||||
|
<script type="text/javascript" src="../../external/jpgjs/jpg.js"></script>
|
||||||
|
<script type="text/javascript">PDFJS.workerSrc = '../../src/worker_loader.js';</script>
|
||||||
|
|
||||||
|
<!-- include spec files here... -->
|
||||||
|
<script type="text/javascript" src="obj_spec.js"></script>
|
||||||
|
<script type="text/javascript" src="font_spec.js"></script>
|
||||||
|
<script type="text/javascript" src="function_spec.js"></script>
|
||||||
|
<script type="text/javascript" src="crypto_spec.js"></script>
|
||||||
|
<script type="text/javascript" src="stream_spec.js"></script>
|
||||||
|
<script type="text/javascript" src="api_spec.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
(function pdfJsUnitTest() {
|
||||||
|
function queryParams() {
|
||||||
|
var qs = window.location.search.substring(1);
|
||||||
|
var kvs = qs.split('&');
|
||||||
|
var params = { };
|
||||||
|
for (var i = 0; i < kvs.length; ++i) {
|
||||||
|
var kv = kvs[i].split('=');
|
||||||
|
params[unescape(kv[0])] = unescape(kv[1]);
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
|
||||||
|
var jasmineEnv = jasmine.getEnv();
|
||||||
|
jasmineEnv.updateInterval = 1000;
|
||||||
|
|
||||||
|
var trivialReporter = new jasmine.TrivialReporter();
|
||||||
|
|
||||||
|
jasmineEnv.addReporter(trivialReporter);
|
||||||
|
|
||||||
|
var params = queryParams();
|
||||||
|
if (params['browser']) {
|
||||||
|
var testReporter = new TestReporter(params['browser'], params['path']);
|
||||||
|
jasmineEnv.addReporter(testReporter);
|
||||||
|
}
|
||||||
|
|
||||||
|
jasmineEnv.specFilter = function pdfJsUnitTestSpecFilter(spec) {
|
||||||
|
return trivialReporter.specFilter(spec);
|
||||||
|
};
|
||||||
|
|
||||||
|
var currentWindowOnload = window.onload;
|
||||||
|
|
||||||
|
window.onload = function pdfJsUnitTestOnload() {
|
||||||
|
if (currentWindowOnload) {
|
||||||
|
currentWindowOnload();
|
||||||
|
}
|
||||||
|
execJasmine();
|
||||||
|
};
|
||||||
|
|
||||||
|
function execJasmine() {
|
||||||
|
jasmineEnv.execute();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user