/** * In conformance testing mode, all tests will be run. Otherwise, we'll skip * tests for attributes that have an entirely incorrect type.
*/
ReflectionHarness.conformanceTesting = false;
/** * Returns a string representing val. Basically just adds quotes for strings, * and passes through other recognized types literally. * * @public
*/
ReflectionHarness.stringRep = function(val) { if (val === null) { // typeof is object, so the switch isn't useful return"null";
} // In JavaScript, -0 === 0 and String(-0) == "0", so we have to // special-case. if (val === -0 && 1/val === -Infinity) { return"-0";
} switch (typeof val) { case"string": for (var i = 0; i < 32; i++) { var replace = "\\"; switch (i) { case 0: replace += "0"; break; case 1: replace += "x01"; break; case 2: replace += "x02"; break; case 3: replace += "x03"; break; case 4: replace += "x04"; break; case 5: replace += "x05"; break; case 6: replace += "x06"; break; case 7: replace += "x07"; break; case 8: replace += "b"; break; case 9: replace += "t"; break; case 10: replace += "n"; break; case 11: replace += "v"; break; case 12: replace += "f"; break; case 13: replace += "r"; break; case 14: replace += "x0e"; break; case 15: replace += "x0f"; break; case 16: replace += "x10"; break; case 17: replace += "x11"; break; case 18: replace += "x12"; break; case 19: replace += "x13"; break; case 20: replace += "x14"; break; case 21: replace += "x15"; break; case 22: replace += "x16"; break; case 23: replace += "x17"; break; case 24: replace += "x18"; break; case 25: replace += "x19"; break; case 26: replace += "x1a"; break; case 27: replace += "x1b"; break; case 28: replace += "x1c"; break; case 29: replace += "x1d"; break; case 30: replace += "x1e"; break; case 31: replace += "x1f"; break;
}
val = val.replace(String.fromCharCode(i), replace);
} return'"' + val.replace('"', '\\"') + '"'; case"boolean": case"undefined": case"number": return val + ""; default: returntypeof val + ' "' + val + '"';
}
}
/** * An object representing info about the current test, used for printing out * nice messages and so forth.
*/
ReflectionHarness.currentTestInfo = {};
/** * .test() sets this, and it's used by .assertEquals()/.assertThrows(). * Calling .test() recursively is an error.
*/
ReflectionHarness.currentTestDescription = null;
/** * Run a group of one or more assertions. If any exceptions are thrown, catch * them and report a failure.
*/
ReflectionHarness.test = function(fn, description) { if (this.currentTestDescription) { throw"TEST BUG: test() may not be called recursively!";
} this.currentTestDescription = description; try {
fn(); // Not throwing is a success this.success();
} catch(err) { this.failure("Exception thrown during tests with " + description);
} this.currentTestDescription = null;
}
/** * If question === answer, output a success, else report a failure with the * given description. Currently success and failure both increment counters, * and failures output a message to a <ul>. Which <ul> is decided by the type * parameter -- different attribute types are separated for readability. * * @public
*/
ReflectionHarness.assertEquals = function(expected, actual, description) { // Special-case -0 yay! if (expected === 0 && actual === 0 && 1/expected === 1/actual) { this.increment(this.passed);
} elseif (expected === actual) { this.increment(this.passed);
} else { this.increment(this.failed); this.reportFailure(this.currentTestDescription +
(description ? " followed by " + description : "") + ' (expected ' + this.stringRep(actual) + ', got ' + this.stringRep(expected) + ')');
}
}
/** * If calling fn causes a DOMException of the type given by the string * exceptionName (e.g., "IndexSizeError"), output a success. Otherwise, report * a failure. * * @public
*/
ReflectionHarness.assertThrows = function(exceptionName, fn) { try {
fn();
} catch (e) { if (e instanceof DOMException && (e.code == DOMException[exceptionName] ||
e.name == exceptionName)) { this.increment(this.passed); returntrue;
}
} this.increment(this.failed); this.reportFailure(this.currentTestDescription + " must throw " +
exceptionName); returnfalse;
}
/** * Get a description of the current type, e.g., "a.href".
*/
ReflectionHarness.getTypeDescription = function() { var domNode = this.currentTestInfo.domObj.tagName.toLowerCase(); var idlNode = this.currentTestInfo.idlObj.nodeName.toLowerCase(); var domName = this.currentTestInfo.domName; var idlName = this.currentTestInfo.idlName; var comment = this.currentTestInfo.data.comment; var typeDesc = idlNode + "." + idlName; if (!comment && (domNode != idlNode || domName != idlName)) {
comment = "<" + domNode + " " + domName + ">";
} if (comment) {
typeDesc += " (" + comment + ")";
} return typeDesc;
}
/** * Report a failure with the given description, adding context from the * currentTestInfo member. * * @private
*/
ReflectionHarness.reportFailure = function(description) { var typeDesc = this.getTypeDescription(); var idlName = this.currentTestInfo.idlName; var comment = this.currentTestInfo.data.comment;
typeDesc = typeDesc.replace("&", "&").replace("<", "<");
description = description.replace("&", "&").replace("<", "<");
var type = this.currentTestInfo.data.type;
// Special case for undefined attributes, which we don't want getting in // the way of everything else. if (description.search('^typeof IDL attribute \\(expected ".*", got "undefined"\\)$') != -1) {
type = "undefined";
}
var done = false; var ul = document.getElementById("errors-" + type.replace(" ", "-")); if (ul === null) {
ul = document.createElement("ul");
ul.id = "errors-" + type.replace(" ", "-"); var div = document.getElementById("errors");
p = document.createElement("p"); if (type == "undefined") {
div.parentNode.insertBefore(ul, div.nextSibling);
p.innerHTML = "These IDL attributes were of undefined type, presumably representing unimplemented features (cordoned off into a separate section for tidiness):";
} else {
div.appendChild(ul);
p.innerHTML = "Errors for type " + type + ":";
}
ul.parentNode.insertBefore(p, ul);
} elseif (type != "undefined") { var existingErrors = ul.getElementsByClassName("desc"); for (var i = 0; i < existingErrors.length; i++) { if (existingErrors[i].innerHTML == description) { var typeSpan = existingErrors[i].parentNode.getElementsByClassName("type")[0]; // Check if we have lots of the same error for the same // attribute. If so, we want to collapse them -- the exact // elements that exhibit the error aren't going to be important // to report in this case, and it can take a lot of space if // there's an error in a global attribute like dir or id. var types = typeSpan.innerHTML.split(", "); var count = 0; for (var i = 0; i < types.length; i++) { if (types[i].search("^\\([0-9]* elements\\)\\." + idlName + "$") != -1) {
types[i] = "(" + (1 + parseInt(/[0-9]+/.exec(types[i])[0])) + " elements)." + idlName;
typeSpan.innerHTML = types.join(", "); return;
} elseif (types[i].search("\\." + idlName + "$") != -1) {
count++;
}
} if (comment || count < 10) { // Just add the extra error to the end, not many duplicates // (or we have a comment)
typeSpan.innerHTML += ", " + typeDesc;
} else { var filteredTypes = types.filter(function(type) { return type.search("\\." + idlName + "$") == -1; }); if (filteredTypes.length) {
typeSpan.innerHTML = filteredTypes.join(", ") + ", ";
} else {
typeSpan.innerHTML = "";
}
typeSpan.innerHTML += "(" + (types.length - filteredTypes.length) + " elements)." + idlName;
} return;
}
}
}
/** * Shorthand function for when we have a failure outside of * assertEquals()/assertThrows(). Generally used when the failure is an * exception thrown unexpectedly or such, something not equality-based. * * @public
*/
ReflectionHarness.failure = function(message) { this.increment(this.failed); this.reportFailure(message);
}
/** * Shorthand function for when we have a success outside of * assertEquals()/assertThrows(). * * @public
*/
ReflectionHarness.success = function() { this.increment(this.passed);
}
/** * Increment the count in either "passed" or "failed". el should always be one * of those two variables. The implementation of this function amuses me. * * @private
*/
ReflectionHarness.increment = function(el) {
el.innerHTML = parseInt(el.innerHTML) + 1; var percent = document.getElementById("percent"); var passed = document.getElementById("passed"); var failed = document.getElementById("failed");
percent.innerHTML = (parseInt(passed.innerHTML)/(parseInt(passed.innerHTML) + parseInt(failed.innerHTML))*100).toPrecision(3);
}
/** * Hide all displayed errors matching a given regex, so it's easier to filter * out repetitive failures. TODO: Fix this so it works right with the new * "lump many errors in one <li>" thing. * * @private (kind of, only called in the original reflection.html)
*/
ReflectionHarness.maskErrors = function(regex) { var uls = document.getElementsByTagName("ul"); for (var i = 0; i < uls.length; i++) { var lis = uls[i].children; for (var j = 0; j < lis.length; j++) { if (regex !== "" && lis[j].innerHTML.match(regex)) {
lis[j].style.display = "none";
} else {
lis[j].style.display = "list-item";
}
}
}
}
// Now for some stuff that has nothing to do with ReflectionHarness and // everything to do with initialization needed for reflection.js, which seems // pointless to put in an extra file.
var elements = {};
var extraTests = [];
/** * Used for combining a number of small arrays of element data into one big * one.
*/ function mergeElements(src) { for (var key in src) { if (!src.hasOwnProperty(key)) { // This is inherited from a prototype or something. continue;
}
if (key in elements) {
elements[key] = elements[key].concat(src[key]);
} else {
elements[key] = src[key];
}
}
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.1 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.