make test runner more robust

pull/468/merge
nightwing 2017-11-05 05:00:07 +00:00
rodzic 6693bd0080
commit 1b9799d093
3 zmienionych plików z 95 dodań i 235 usunięć

Wyświetl plik

@ -93,17 +93,18 @@ var addToLoadQueue = function(missing, deps, callback, errback) {
var processLoadQueue = function(err, id) {
var changed = false;
if (err) {
define.errors[err.id] = err;
if (!id) id = err.id;
define.errors[id] = err;
define.queue.forEach(function(r) {
if (r.map[err.id]) {
if (r.map[id]) {
r.toLoad = -1;
if (r.errback) r.errback(err);
}
});
if (define.lastModule == err.id)
if (define.lastModule == id)
define.lastModule = null;
define.pending = define.pending.filter(function(p) {
return p != err.id;
return p != id;
});
changed = true;
} else if (id && !defQueue.length && !define.loaded[id]) {
@ -285,10 +286,10 @@ var config = require.config = function(cfg) {
config.paths[p] = cfg.paths[p];
});
if (cfg.useCache && global.caches) {
if (cfg.useCache && global.caches && location.protocol == "https:") {
config.useCache = true;
checkCache();
}
}
if (cfg.baseUrlLoadBalancers)
config.baseUrlLoadBalancers = cfg.baseUrlLoadBalancers;
@ -457,12 +458,7 @@ var loadCached = function(path, cb) {
return loadText(path, cb);
function loadNew() {
loadText(path, function(e, val, xhr) {
try {
var m = cb(e, val);
} catch(err) {
ideCache.delete(path);
throw err;
}
var m = cb(e, val);
if (!e) {
var ETAG = xhr.getResponseHeader("ETAG");
if (!ETAG) return;

Wyświetl plik

@ -20,11 +20,6 @@
<script src="/configs/require_config.js"></script>
<script src="lib/mocha/mocha.js"></script>
<script>
/*global mocha*/
mocha.setup('bdd');
mocha.bail(false);
mocha.ignoreLeaks(true);
mocha.fullTrace && mocha.fullTrace();
window.onerror=function(msg){ var el=document.getElementById('jserror'); el.innerHTML+="<div class='jserr'>"+msg+"</div>";};
/* wrap setTimeout to prevent any plugins leaking timeouts to the next test*/
@ -57,7 +52,6 @@
return id;
};
}();
function Storage(_items) {
this.getItem = function(n) {
return _items[n];
@ -95,75 +89,98 @@
};
Storage.create(window, "localStorage");
Storage.create(window, "sessionStorage");
/*global Mocha, mocha*/
mocha.reporter(function(runner) {
function extend(target, BaseFn, arg) {
var base = BaseFn.prototype;
for (var i in base) if (!target[i]) target[i] = base[i];
BaseFn.call(target, arg);
}
extend(this, Mocha.reporters.Base, runner);
extend(this, Mocha.reporters.HTML, runner);
var tests = [];
var stats = this.stats;
mocha.lastReport = null;
mocha.report = { stats: stats, tests: tests };
mocha.getReport = function() {
return {
stats: JSON.parse(JSON.stringify(stats)),
tests: tests.map(clean)
};
var XMLHttpRequest_orig = XMLHttpRequest;
var currentTest;
/*global Mocha*/
function setupMocha(test) {
currentTest = test;
window.XMLHttpRequest = function() {
var req = new XMLHttpRequest_orig();
if (currentTest != test) {
req.open = function() {
console.error(test + " tried to open xhr after end");
};
req.setRequestHeader = req.send = function() {};
}
return req;
};
var mocha = window.mocha = new Mocha({ reporter: 'html' });
mocha.reporter(function(runner) {
function extend(target, BaseFn, arg) {
var base = BaseFn.prototype;
for (var i in base) if (!target[i]) target[i] = base[i];
BaseFn.call(target, arg);
}
extend(this, Mocha.reporters.Base, runner);
extend(this, Mocha.reporters.HTML, runner);
var tests = [];
var stats = this.stats;
mocha.lastReport = null;
mocha.report = { stats: stats, tests: tests };
mocha.getReport = function() {
return {
stats: JSON.parse(JSON.stringify(stats)),
tests: tests.map(clean)
};
};
runner.on('test end', function(test) {
stats.percent = stats.tests / runner.total * 100 | 0;
tests.push(test);
if (mocha._onSubTest)
mocha._onSubTest(test);
});
runner.on('end', function() {
// tests might generate errors after they finished running
// e.g. using on instead of once can call done second time during app unload
// so we save the report at the time when test runner ended.
mocha.lastReport = mocha.getReport();
});
function parseError(err) {
var str = err.stack || err.toString();
runner.on('test end', function(test) {
stats.percent = stats.tests / runner.total * 100 | 0;
tests.push(test);
if (mocha._onSubTest)
mocha._onSubTest(test);
});
runner.on('end', function() {
// tests might generate errors after they finished running
// e.g. using on instead of once can call done second time during app unload
// so we save the report at the time when test runner ended.
mocha.lastReport = mocha.getReport();
// FF / Opera do not add the message
if (!~str.indexOf(err.message)) {
str = err.message + '\n' + str;
}
// <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
// check for the result of the stringifying.
if ('[object Error]' == str) str = err.message;
// Safari doesn't give you a stack. Let's at least provide a source line.
if (!err.stack && err.sourceURL && err.line !== undefined) {
str += "\n(" + err.sourceURL + ":" + err.line + ")";
}
return str;
}
function clean(test) {
return {
title: test.title,
duration: test.duration,
error: test.err && parseError(test.err),
speed: test.speed,
state: test.state
};
}
});
function parseError(err) {
var str = err.stack || err.toString();
// FF / Opera do not add the message
if (!~str.indexOf(err.message)) {
str = err.message + '\n' + str;
}
// <=IE7 stringifies to [Object Error]. Since it can be overloaded, we
// check for the result of the stringifying.
if ('[object Error]' == str) str = err.message;
// Safari doesn't give you a stack. Let's at least provide a source line.
if (!err.stack && err.sourceURL && err.line !== undefined) {
str += "\n(" + err.sourceURL + ":" + err.line + ")";
}
return str;
}
function clean(test) {
return {
title: test.title,
duration: test.duration,
error: test.err && parseError(test.err),
speed: test.speed,
state: test.state
};
}
});
require.config({ useCache: true });
mocha.bail(false);
mocha.ignoreLeaks(true);
mocha.fullTrace && mocha.fullTrace();
mocha.timeout(10000);
mocha.ui();
mocha.suite.emit('pre-require', window, null, mocha);
}
</script>
<script>//<!--
/*global mocha afterEach after*/
var inIFrame = window.parent !== window;
function defineEmpty(path) {
define(path, [], {});
require([path]);
@ -252,18 +269,6 @@
};
onload.remain = options.remain == "1";
mocha.timeout(10000);
if (inIFrame) {
// we're in an iframe, postMessage the results to the parent.
after(function(done) {
console.log('test completed');
var payload = getReport();
window.parent.postMessage(payload, '*');
done();
});
}
function getReport() {
return mocha.lastReport || { failures: "didn't complete" };
}
@ -306,7 +311,8 @@
}
c9Test.last = test;
mocha.suite.suites.length = 0;
setupMocha(test);
function unloadApp() {
var app = window.app;
window.app = null;

Wyświetl plik

@ -1,142 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Test Runner</title>
<link rel="stylesheet" href="lib/mocha/mocha.css" />
<style>
HTML {
overflow: auto !important
}
IFRAME {
width: 70%;
height: 100%;
display: block;
position: absolute;
left: 30%;
right: 0;
bottom: 0;
}
.stats {
font-size: 0.6em;
font-weight: normal;
font-style: italic;
}
#mocha-stats {
left: 41px;
right: initial;
}
</style>
</head>
<body>
<div id="mocha">
<ul id="mocha-stats">
<li class="passes">
<a href="#">passes:</a><em>0</em>
</li>
<li class="failures">
<a href="#">failures:</a><em>0</em>
</li>
<li class="duration">
duration: <em>0</em>s
</li>
<li class="progress">
<em>0</em>
</li>
</ul>
<ul id="mocha-report"></ul>
</div>
<script src="require.js"></script>
<script src="/configs/require_config.js"></script>
<div id='jserror' width='100%' height='20px' style='font: 10px \"courier new\"; color: red; display: none;'></div>
<script>
window.onerror = function(msg) {
var el = document.getElementById('jserror');
el.innerHTML += "<div class='jserr'>" + msg + "</div>";
};
</script>
<script>
//<!--
/*global mocha afterEach*/
define("amd-loader", [], {});
require(["amd-loader"]);
// require.config({paths: {chai: "lib/chai/chai"}});
require(["text!/test/all.json"], function(tests) {
tests = JSON.parse(tests);
var allFiles = tests.list.slice();
var files = allFiles;
var iframe;
var file;
window.addEventListener('message', function(e) {
var ul = document.createElement('ul');
ul.innerHTML = e.data.report;
var h1 = ul.querySelector('h1');
h1.innerHTML = [
"<span class='stats'>",
" <span style='color:", e.data.failures ? "red" : "green", "'>",
e.data.passes, "/", e.data.passes + e.data.failures,
"</span>",
" <span style='color:", e.data.duration > 2 ? "red" : "gray", "'>",
e.data.duration + "s",
"</span>",
" <span style='color:", e.data.failures ? "red" : "gray", "'>",
file,
"</span>",
"</span>",
" <a href='", 'test.html?' + file, "'>\u21D7</a>"
].join("");
if (h1.nextElementSibling)
h1.nextElementSibling.style.display = "none";
var h2s = ul.querySelectorAll('h1, h2');
for (var i = 0, ii = h2s.length; i < ii; ++i) {
h2s[i].addEventListener('click', toggle, false);
}
while (ul.firstChild) {
document.getElementById('mocha-report').appendChild(ul.firstChild);
}
var _stats = document.getElementById('mocha-stats');
function addStats(opt, prec) {
if (!(opt in e.data)) return;
var em = _stats.querySelector('.' + opt + ' > em');
var value = Number(em.textContent) + e.data[opt];
if (prec) value = value.toFixed(prec);
em.textContent = value;
}
addStats('passes');
addStats('failures');
addStats('duration', 1);
iframe.remove();
loadNext();
}, false);
function toggle(e) {
var pre = e.currentTarget.nextElementSibling;
pre.style.display = pre.style.display !== 'none' ? 'none' : 'block';
}
function loadNext() {
file = files.shift();
if (!file) {
return;
}
console.warn(file);
iframe = document.createElement('iframe');
iframe.src = 'test.html?' + file;
document.body.appendChild(iframe);
}
loadNext();
});
//-->
</script>
</body>
</html>