DuyTa's picture
Upload folder using huggingface_hub
bc20498 verified
'use strict';
var fs = require('fs');
var Path = require('path');
var domino = require('../lib');
var Window = require('../lib/Window');
var BLOCKLIST_PATH = Path.resolve(__dirname, 'web-platform-blocklist.json');
// Set to true and delete the existing blocklist file to regenerate the
// blocklist from currently-failing tests.
var WRITE_BLOCKLIST = false;
// These are the tests we currently fail.
// Some of these failures are bugs we ought to fix.
var blocklist = {};
try {
blocklist = require(BLOCKLIST_PATH);
} catch(e) {
// We expect that you deleted the old blocklist before using WRITE_BLOCKLIST
if (!WRITE_BLOCKLIST) { throw e; }
}
var escapeRegExp = function(s) {
// Note that JSON is not a subset of JavaScript: it allows \u2028 and \u2029
// to be embedded as literals. Escape them in the regexp to prevent this
// from causing a syntax error when we eval() this regexp.
return s.replace(/[\^\\$*+?.()|{}\[\]\/]/g, '\\$&')
.replace(/[\u2028\u2029]/, function(c) {
var cp = c.codePointAt(0).toString(16);
while (cp.length < 4) { cp = '0' + cp; }
return '\\u' + cp;
});
};
var onblocklist = function(shortFile) {
if (WRITE_BLOCKLIST) { return null; }
if (!Array.isArray(blocklist[shortFile])) { return null; }
// convert strings to huge regexp
return new RegExp('^(' + blocklist[shortFile].map(escapeRegExp).join('|') + ')$');
};
// Test suite requires Array.includes(); polyfill from
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes
/* jshint bitwise: false */
if (!Array.prototype.includes) {
Object.defineProperty(Array.prototype, 'includes', {
value: function(searchElement, fromIndex) {
if (this === null || this === undefined) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
var len = o.length >>> 0;
if (len === 0) {
return false;
}
var n = fromIndex | 0;
var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
function sameValueZero(x, y) {
return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
}
while (k < len) {
if (sameValueZero(o[k], searchElement)) {
return true;
}
k++;
}
return false;
}
});
}
// Test suite requires Array.values() as well
if (global.Symbol && global.Symbol.iterator && !Array.prototype.values) {
Object.defineProperty(
Array.prototype, 'values',
Object.getOwnPropertyDescriptor(Array.prototype, global.Symbol.iterator)
);
}
function read(file) {
return fs.readFileSync(Path.resolve(__dirname, '..', file), 'utf8');
}
var testharness = require(__dirname + '/web-platform-tests/resources/testharness.js');
function list(base, dir, fn) {
var result = {};
var fulldir = Path.resolve(__dirname, '..', base, dir);
fs.readdirSync(fulldir).forEach(function(file) {
var path = Path.join(dir, file);
var stat = fs.statSync(Path.join(fulldir, file));
if (stat.isDirectory()) {
result[file] = list(base, path, fn);
}
else if (file.match(/\.x?html$/)) {
var test = fn(path, Path.join(fulldir, file));
if (test) result[file] = test;
}
});
return result;
}
var badTestFiles = new RegExp('(' + [
'/html/dom/interfaces.https.html', // Uses ES6, missing .../WebIDLParser.js
'/dom/nodes/Document-characterSet-normalization.html',
'/dom/nodes/Document-contentType/contentType/contenttype_datauri_02.html',
'/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess.html',
'/dom/nodes/ParentNode-querySelector-All.html',
'/dom/nodes/query-target-in-load-event.html',
].map(escapeRegExp).join('|') + ')$');
var forceSyncTestFiles = new RegExp('(' + [
'/dom/nodes/Node-parentNode.html',
'/html/dom/documents/dom-tree-accessors/Document.currentScript.html',
'/html/dom/self-origin.sub.html',
'/dom/nodes/Node-isEqualNode-xhtml.xhtml',
].map(escapeRegExp).join('|') + ')$');
var harness = function() {
var paths = Array.from(arguments);
var harnessResult = {
// Could add 'before' or 'after' hooks here.
};
paths.forEach(function(path) {
var shortName = path.replace(/^.*?\/web-platform-tests\//, '');
harnessResult[shortName] = list(path, '', function(name, file) {
var shortFile = file.replace(/^.*?\/web-platform-tests\//, '');
if (/\/html\/dom\/reflection-original.html$/.test(file)) {
// This is a compilation file & not a test suite.
return; // skip
}
if (badTestFiles.test(file)) {
// Misc problems w/ test file, usually resulting in async done() method
// never getting invoked and a time-wasting timeout.
return; // skip
}
var html = read(file);
var document = domino.createDocument(html);
document.address = 'http://example.com/';
var window = new Window(document);
Array.from(window.document.getElementsByTagName('iframe')).forEach(function(iframe) {
if (iframe.src === 'http://example.com/common/dummy.xml') {
var dummyXmlDoc = domino.createDOMImplementation().createDocument(
'http://www.w3.org/1999/xhtml', 'html', null
);
dummyXmlDoc._contentType = 'application/xml';
iframe._contentWindow = new Window(dummyXmlDoc);
var foo = dummyXmlDoc.createElement('foo');
foo.textContent = 'Dummy XML document';
dummyXmlDoc.documentElement.appendChild(foo);
}
if (iframe.src === 'http://example.com/common/dummy.xhtml') {
var dummyXhtml = read('test/web-platform-tests/common/dummy.xhtml');
var dummyXhtmlAsHtml = domino.createDocument(dummyXhtml);
// Tweak this a tiny bit, since we actually used an HTML parser not
// an XML parser.
dummyXhtmlAsHtml.body.textContent = '';
// Create a proper XML document, and copy the HTML contents into it
var dummyXhtmlDoc = domino.createDOMImplementation().createDocument(
'http://www.w3.org/1999/xhtml', 'html', null
);
dummyXhtmlDoc._contentType = 'application/xhtml+xml';
dummyXhtmlDoc.insertBefore(
dummyXhtmlDoc.adoptNode(dummyXhtmlAsHtml.doctype),
dummyXhtmlDoc.documentElement
);
dummyXhtmlDoc.documentElement.appendChild(
dummyXhtmlDoc.adoptNode(dummyXhtmlAsHtml.head)
);
dummyXhtmlDoc.documentElement.appendChild(
dummyXhtmlDoc.adoptNode(dummyXhtmlAsHtml.body)
);
iframe._contentWindow = new Window(dummyXhtmlDoc);
}
});
testharness(window);
window.setup({explicit_timeout:true});
if (forceSyncTestFiles.test(file)) {
window.async_test = function(){
return {
step: function() {},
step_func_done: function() {},
done: function() {},
}
};
}
var scripts = window.document.getElementsByTagName('script');
scripts = Array.from(scripts);
var sawTestHarness = false;
var concatenatedScripts = scripts.map(function(script) {
if (/\/resources\/testharness(report)?\.js$/.test(script.getAttribute('src')||'')) {
// We've already included the test harnesses.
sawTestHarness = true;
return '';
}
if (/\/webrtc\/RTCPeerConnection-helper.js$/.test(script.getAttribute('src')||'')) {
// Bad script: we don't support webrtc and furthermore it contains
// ES6 syntax which causes older versions of node to choke.
return '';
}
if (/^text\/plain$/.test(script.getAttribute('type')||'')) {
return '';
}
if (/^(\w+|..|\/)/.test(script.getAttribute('src')||'')) {
var f = script.getAttribute('src');
if (/^\//.test(f)) {
f = Path.resolve(__dirname, 'web-platform-tests' + f);
} else {
//console.log('??', {path:path, name:name, file:file});
f = Path.resolve(Path.dirname(file), f);
}
if (fs.existsSync(f)) {
return read(f);
} else {
// console.warn('SKIPPING SCRIPT', script.outerHTML);
}
}
var textContent = script.textContent;
if (/\.xhtml$/.test(file)) {
// hacky way to expand entities
var txt = window.document.createElementNS('http://www.w3.org/1999/xhtml', 'textarea');
txt.innerHTML = textContent;
textContent = txt.textContent;
}
return textContent + '\n';
}).join("\n");
concatenatedScripts =
concatenatedScripts.replace(/\.attributes\[(\w+)\]/g,
'.attributes.item($1)');
// Some tests use [...foo] syntax for `Array.from(foo)`
concatenatedScripts =
concatenatedScripts.replace(/\[\.\.\.(\w+)\]/g,
'Array.from($1)');
// usvstring-reflection.html uses () => { ... } syntax (unnecessarily)
concatenatedScripts =
concatenatedScripts.replace(/(\b\w+|\(\w*\))\s*=>\s*\{/g, function(_,a){
if (a.slice(0,1)!=='(') { a = '(' + a + ')'; }
return 'function '+a+' {';
});
// It also contains `([channel1, channel2]) => {` in a test case which is
// bound to fail anyway (it exercises WebRTC)
concatenatedScripts =
concatenatedScripts.replace(
/\(\[channel1, channel2\]\) => \{/,
'function(channel1, channel2){' // not right, but not a syntax error
);
// Workaround for https://github.com/w3c/web-platform-tests/pull/3984
concatenatedScripts =
'"use strict";\n' +
'var ReflectionTests, x, attr;\n' +
// Hack in globals on window object
'"String|Boolean|Number".split("|").forEach(function(x){' +
'window[x] = global[x];})\n' +
// Hack in frames on window object
'Array.from(document.getElementsByTagName("iframe")).forEach(' +
'function(f,i){window[i]=f.contentWindow;});\n' +
concatenatedScripts;
// Fire load events
var closeDocument =
'document.close();\n' +
'Array.from(document.getElementsByTagName("iframe")).forEach(' +
'function(f){f.dispatchEvent(new Event("load"));});';
var expectedFailures = onblocklist(shortFile);
return function(done) {
var haveTests = false, isComplete = false, sawError = [];
var calledOnce = false;
var withResults = function(results) {
if (calledOnce) {
console.warn('DONE CALLED TWICE', name, (new Error()).stack);
return;
}
else { calledOnce = true; }
if (!WRITE_BLOCKLIST) {
var str = results.map(function(item) {
var s = item.name;
if (item.message) s += ': ' + item.message;
if (item.status) s += ' ['+item.status+']';
return s;
});
sawError.forEach(function(err) {
if (!(expectedFailures && expectedFailures.test('Uncaught: '+err.message))) {
str.push('Uncaught: '+err.message);
}
});
if (sawError.length === 1 && str.length === 1) {
done(sawError[0]); // for nicer stack trace
} else {
done(str.length ? new Error(str.join('\n\n')) : null);
}
} else {
var bl = {};
try {
bl = JSON.parse(fs.readFileSync(blocklist_PATH, 'utf-8'));
} catch (e) { /* ignore */ }
bl[shortFile] = results.map(function(item) { return item.name; });
sawError.forEach(function(err) {
bl[shortFile].push('Uncaught: ' + err.message);
});
if (!bl[shortFile].length) { bl[shortFile] = undefined; }
fs.writeFileSync(
blocklist_PATH, JSON.stringify(bl, null, 2), 'utf-8'
);
done();
}
};
window.add_start_callback(function() {
haveTests = true;
});
window.add_completion_callback(function(tests, status) {
isComplete = true;
var failed = tests.filter(function(t) {
if (t.status === t.TIMEOUT) { return true; /* never ok */ }
var expectFail =
expectedFailures ? expectedFailures.test(t.name) : false;
var actualFail = (t.status === t.FAIL);
return expectFail !== actualFail;
});
var report = failed.map(function(t) {
var item = { name: t.name, message: t.message };
if (t.status===t.TIMEOUT) { item.status = 'TIMEOUT'; }
else if (t.status!==t.FAIL) { item.status = 'EXPECT FAIL'; }
return item;
});
withResults(report);
});
// TODO(jessicajaniuk): window._run was removed to enable ESM support
// try {
// window._run(concatenatedScripts);
// } catch (e) {
// sawError.push(e);
// }
// try {
// window._run(closeDocument);
// } catch (e) {
// sawError.push(e);
// }
if (!sawTestHarness) { withResults([]); }
else if (sawError.length && !haveTests) { withResults([]); }
};
});
});
return harnessResult;
};
// module.exports = harness(__dirname + '/web-platform-tests/html/dom',
// __dirname + '/web-platform-tests/dom/nodes',
// __dirname + '/web-platform-tests/dom/traversal',
// __dirname + '/web-platform-tests/domparsing');