Skip to content

Commit

Permalink
test: run WPT in subdirectories
Browse files Browse the repository at this point in the history
For a directory like this:

- wpt
  - encoding
    - streams
      - backpressure.any.js
    - api-basics.any.js

Previously we only run `api-basics.any.js`, now we also run
`backpressure.any.js` (and any tests in more deeply nested
directories). This enables us to run more of WPT since not
every module put their tests at the top level directory.

PR-URL: #27860
Reviewed-By: Michaël Zasso <[email protected]>
Reviewed-By: Rich Trott <[email protected]>
Reviewed-By: Anna Henningsen <[email protected]>
  • Loading branch information
joyeecheung authored and danbev committed May 28, 2019
1 parent 86ed4ad commit 6abeaac
Showing 1 changed file with 58 additions and 22 deletions.
80 changes: 58 additions & 22 deletions test/common/wpt.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,25 @@ class ResourceLoader {
this.path = path;
}

fetch(url, asPromise = true) {
/**
* Load a resource in test/fixtures/wpt specified with a URL
* @param {string} from the path of the file loading this resource,
* relative to thw WPT folder.
* @param {string} url the url of the resource being loaded.
* @param {boolean} asPromise if true, return the resource in a
* pseudo-Response object.
*/
read(from, url, asFetch = true) {
// We need to patch this to load the WebIDL parser
url = url.replace(
'/resources/WebIDLParser.js',
'/resources/webidl2/lib/webidl2.js'
);
const base = path.dirname(from);
const file = url.startsWith('/') ?
fixtures.path('wpt', url) :
fixtures.path('wpt', this.path, url);
if (asPromise) {
fixtures.path('wpt', base, url);
if (asFetch) {
return fsPromises.readFile(file)
.then((data) => {
return {
Expand Down Expand Up @@ -85,7 +94,7 @@ class StatusRule {
* @returns {RegExp}
*/
transformPattern(pattern) {
const result = pattern.replace(/[-/\\^$+?.()|[\]{}]/g, '\\$&');
const result = path.normalize(pattern).replace(/[-/\\^$+?.()|[\]{}]/g, '\\$&');
return new RegExp(result.replace('*', '.*'));
}
}
Expand Down Expand Up @@ -155,8 +164,12 @@ class WPTTest {
}
}

getRelativePath() {
return path.join(this.module, this.filename);
}

getAbsolutePath() {
return fixtures.path('wpt', this.module, this.filename);
return fixtures.path('wpt', this.getRelativePath());
}

getContent() {
Expand Down Expand Up @@ -217,20 +230,41 @@ class StatusLoader {
this.tests = [];
}

/**
* Grep for all .*.js file recursively in a directory.
* @param {string} dir
*/
grep(dir) {
let result = [];
const list = fs.readdirSync(dir);
for (const file of list) {
const filepath = path.join(dir, file);
const stat = fs.statSync(filepath);
if (stat.isDirectory()) {
const list = this.grep(filepath);
result = result.concat(list);
} else {
if (!(/\.\w+\.js$/.test(filepath))) {
continue;
}
result.push(filepath);
}
}
return result;
}

load() {
const dir = path.join(__dirname, '..', 'wpt');
const statusFile = path.join(dir, 'status', `${this.path}.json`);
const result = JSON.parse(fs.readFileSync(statusFile, 'utf8'));
this.rules.addRules(result);

const list = fs.readdirSync(fixtures.path('wpt', this.path));

const subDir = fixtures.path('wpt', this.path);
const list = this.grep(subDir);
for (const file of list) {
if (!(/\.\w+\.js$/.test(file))) {
continue;
}
const match = this.rules.match(file);
this.tests.push(new WPTTest(this.path, file, match));
const relativePath = path.relative(subDir, file);
const match = this.rules.match(relativePath);
this.tests.push(new WPTTest(this.path, relativePath, match));
}
this.loaded = true;
}
Expand Down Expand Up @@ -309,8 +343,9 @@ class WPTRunner {
const meta = test.title = this.getMeta(content);

const absolutePath = test.getAbsolutePath();
const context = this.generateContext(test.filename);
const code = this.mergeScripts(meta, content);
const context = this.generateContext(test);
const relativePath = test.getRelativePath();
const code = this.mergeScripts(relativePath, meta, content);
try {
vm.runInContext(code, context, {
filename: absolutePath
Expand All @@ -327,14 +362,14 @@ class WPTRunner {
this.tryFinish();
}

mock() {
mock(testfile) {
const resource = this.resource;
const result = {
// This is a mock, because at the moment fetch is not implemented
// in Node.js, but some tests and harness depend on this to pull
// resources.
fetch(file) {
return resource.fetch(file);
return resource.read(testfile, file, true);
},
GLOBAL: {
isWindow() { return false; }
Expand All @@ -346,16 +381,17 @@ class WPTRunner {
}

// Note: this is how our global space for the WPT test should look like
getSandbox() {
const result = this.mock();
getSandbox(filename) {
const result = this.mock(filename);
for (const [name, desc] of this.globals) {
Object.defineProperty(result, name, desc);
}
return result;
}

generateContext(filename) {
const sandbox = this.sandbox = this.getSandbox();
generateContext(test) {
const filename = test.filename;
const sandbox = this.sandbox = this.getSandbox(test.getRelativePath());
const context = this.context = vm.createContext(sandbox);

const harnessPath = fixtures.path('wpt', 'resources', 'testharness.js');
Expand Down Expand Up @@ -509,15 +545,15 @@ class WPTRunner {
}
}

mergeScripts(meta, content) {
mergeScripts(base, meta, content) {
if (!meta.script) {
return content;
}

// only one script
let result = '';
for (const script of meta.script) {
result += this.resource.fetch(script, false);
result += this.resource.read(base, script, false);
}

return result + content;
Expand Down

0 comments on commit 6abeaac

Please sign in to comment.