Skip to content

Commit

Permalink
refactor TestSpecPath into TestSpecID
Browse files Browse the repository at this point in the history
  • Loading branch information
kainino0x committed Jul 8, 2019
1 parent bb0f005 commit c66c7d1
Show file tree
Hide file tree
Showing 11 changed files with 86 additions and 84 deletions.
2 changes: 2 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
".tscache": true,
".vscode": true,
"node_modules": true,
"out": true,
"prettier.config.js": true,
"third_party": true,
"tsconfig.json": true,
"tsconfig.web.json": true,
"tslint.json": true,
Expand Down
15 changes: 15 additions & 0 deletions src/framework/id.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ParamsSpec } from './params/index.js';

// Identifies a test spec file.
export interface TestSpecID {
// The spec's suite, e.g. 'cts'.
readonly suite: string;
// The spec's path within the suite, e.g. 'command_buffer/compute/basic'.
readonly path: string;
}

// Identifies a test case (a specific parameterization of a test), within its spec file.
export interface TestCaseID {
readonly name: string;
readonly params: ParamsSpec | null;
}
27 changes: 10 additions & 17 deletions src/framework/loader.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { GroupRecorder } from './logger.js';
import { ParamsAny, paramsEquals, paramsSupersets } from './params/index.js';
import { RunCaseIterable, TestCaseID, RunCase } from './test_group.js';
import { RunCaseIterable, RunCase } from './test_group.js';
import { allowedTestNameCharacters } from './allowed_characters.js';
import { TestSuiteListing } from './listing.js';
import { TestSpecID, TestCaseID } from './id.js';

// One of the following:
// - A shell object describing a directory (from its README.txt).
Expand All @@ -14,18 +15,13 @@ export interface TestSpecFile {
readonly g?: RunCaseIterable;
}

// Identifies a test spec (a .spec.ts file).
export interface TestSpecPath {
// The spec's suite, e.g. 'cts'.
readonly suite: string;
// The spec's path within the suite, e.g. 'command_buffer/compute/basic'.
readonly path: string;
// A pending loaded spec (.spec.ts) file, plus identifying information.
export interface TestQueryResult {
readonly id: TestSpecID;
readonly spec: Promise<TestSpecFile>;
}

type TestQueryResults = IterableIterator<TestQueryResult>;
export interface TestQueryResult extends TestSpecPath {
readonly spec: Promise<TestSpecFile>;
}

function* concat(lists: TestQueryResult[][]): TestQueryResults {
for (const specs of lists) {
Expand Down Expand Up @@ -110,8 +106,7 @@ export class TestLoader {
const testPrefix = filter.substring(i2 + 1);
return [
{
suite,
path,
id: { suite, path },
spec: this.filterByTestMatch(suite, path, testPrefix),
},
];
Expand All @@ -132,8 +127,7 @@ export class TestLoader {
// - cts:buffers/mapWriteAsync:basic~{filter:"params"}
return [
{
suite,
path,
id: { suite, path },
spec: this.filterByParamsMatch(suite, path, test, params),
},
];
Expand All @@ -143,8 +137,7 @@ export class TestLoader {
// - cts:buffers/mapWriteAsync:basic:{exact:"params"}
return [
{
suite,
path,
id: { suite, path },
spec: this.filterByParamsExact(suite, path, test, params),
},
];
Expand All @@ -166,7 +159,7 @@ export class TestLoader {
const spec: Promise<TestSpecFile> = isReadme
? Promise.resolve({ description })
: this.fileLoader.import(`${suite}/${path}.spec.js`);
entries.push({ suite, path, spec });
entries.push({ id: { suite, path }, spec });
}
}

Expand Down
8 changes: 2 additions & 6 deletions src/framework/test_group.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import { CaseRecorder, GroupRecorder, TestCaseLiveResult } from './logger.js';
import { ParamsAny, ParamsSpec, ParamSpecIterable, paramsEquals } from './params/index.js';
import { ParamsAny, ParamSpecIterable, paramsEquals } from './params/index.js';
import { Fixture } from './fixture.js';
import { allowedTestNameCharacters } from './allowed_characters.js';

export interface TestCaseID {
readonly name: string;
readonly params: ParamsSpec | null;
}
import { TestCaseID } from './id.js';

export interface RunCase {
readonly id: TestCaseID;
Expand Down
17 changes: 9 additions & 8 deletions src/framework/url_query.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { TestSpecPath } from './loader.js';
import { TestCaseID } from './test_group.js';
import { TestCaseID, TestSpecID } from './id.js';

export function encodeSelectively(s: string) {
let ret = encodeURIComponent(s);
Expand All @@ -13,12 +12,14 @@ export function encodeSelectively(s: string) {
return ret;
}

export function makeQueryString(entry: TestSpecPath, testcase: TestCaseID): string {
let s = entry.suite + ':';
s += entry.path + ':';
s += testcase.name + ':';
if (testcase.params) {
s += JSON.stringify(testcase.params);
export function makeQueryString(spec: TestSpecID, testcase?: TestCaseID): string {
let s = spec.suite + ':';
s += spec.path + ':';
if (testcase !== undefined) {
s += testcase.name + ':';
if (testcase.params) {
s += JSON.stringify(testcase.params);
}
}
return encodeSelectively(s);
}
35 changes: 17 additions & 18 deletions src/tools/run.ts → src/runtime/cmdline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import * as process from 'process';

import { TestSpecFile, TestLoader } from '../framework/loader.js';
import { Logger, TestCaseLiveResult } from '../framework/logger.js';
import { TestSpecID } from '../framework/id.js';
import { makeQueryString } from '../framework/url_query.js';

function usage(rc: number) {
console.log('Usage:');
Expand All @@ -17,7 +19,7 @@ if (process.argv.length <= 2) {
usage(0);
}

if (!fs.existsSync('src/tools/run.ts')) {
if (!fs.existsSync('src/runtime/cmdline.ts')) {
console.log('Must be run from repository root');
usage(1);
}
Expand All @@ -42,33 +44,30 @@ for (const a of process.argv.slice(2)) {
const listing = await loader.loadTestsFromCmdLine(filterArgs);

const log = new Logger();
const entries = await Promise.all(
Array.from(listing, ({ suite, path, spec }) =>
spec.then((s: TestSpecFile) => ({ suite, path, g: s.g }))
)
const queryResults = await Promise.all(
Array.from(listing, ({ id, spec }) => spec.then((s: TestSpecFile) => ({ id, spec: s })))
);

const failed: Array<[string, string, TestCaseLiveResult]> = [];
const warned: Array<[string, string, TestCaseLiveResult]> = [];
const failed: Array<[TestSpecID, TestCaseLiveResult]> = [];
const warned: Array<[TestSpecID, TestCaseLiveResult]> = [];

// TODO: don't run all tests all at once
const running = [];
for (const entry of entries) {
const { suite, path, g } = entry;
if (!g) {
for (const qr of queryResults) {
if (!qr.spec.g) {
continue;
}

const [rec] = log.record(path);
for (const t of g.iterate(rec)) {
const [rec] = log.record(qr.id.path);
for (const t of qr.spec.g.iterate(rec)) {
running.push(
(async () => {
const res = await t.run();
if (res.status === 'fail') {
failed.push([suite, path, res]);
failed.push([qr.id, res]);
}
if (res.status === 'warn') {
warned.push([suite, path, res]);
warned.push([qr.id, res]);
}
})()
);
Expand All @@ -89,17 +88,17 @@ for (const a of process.argv.slice(2)) {
if (warned.length) {
console.log('');
console.log('** Warnings **');
for (const [suite, path, r] of warned) {
for (const [id, r] of warned) {
// TODO: actually print query here
console.log(suite + ':' + path, r);
console.log(makeQueryString(id), r);
}
}
if (failed.length) {
console.log('');
console.log('** Failures **');
for (const [suite, path, r] of failed) {
for (const [id, r] of failed) {
// TODO: actually print query here
console.log(suite + ':' + path, r);
console.log(makeQueryString(id), r);
}
}

Expand Down
26 changes: 15 additions & 11 deletions src/runtime/standalone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { TestLoader } from '../framework/loader.js';
import { Logger } from '../framework/logger.js';
import { makeQueryString } from '../framework/url_query.js';
import { RunCase } from '../framework/index.js';
import { TestSpecID } from '../framework/id.js';

const log = new Logger();

Expand All @@ -12,7 +13,7 @@ const runButtonCallbacks = new Map<HTMLElement, runButtonCallback>();

const resultsJSON = document.getElementById('resultsJSON') as HTMLElement;
const resultsVis = document.getElementById('resultsVis') as HTMLElement;
function makeTest(path: string, description: string): HTMLElement {
function makeTest(spec: TestSpecID, description: string): HTMLElement {
const test = $('<div>')
.addClass('test')
.appendTo(resultsVis);
Expand All @@ -24,7 +25,7 @@ function makeTest(path: string, description: string): HTMLElement {

$('<div>')
.addClass('testname')
.text(path)
.text(makeQueryString(spec))
.appendTo(test);

$('<div>')
Expand Down Expand Up @@ -102,23 +103,26 @@ function mkCase(testcasesVis: HTMLElement, query: string, t: RunCase) {

const loader = new TestLoader();
const listing = await loader.loadTestsFromQuery(window.location.search);
const entries = await Promise.all(
Array.from(listing, ({ suite, path, spec }) => spec.then(s => ({ suite, path, spec: s })))

// TODO: everything after this point is very similar across the three runtimes.

// TODO: start populating page before waiting for everything to load?
const queryResults = await Promise.all(
Array.from(listing, ({ id, spec }) => spec.then(s => ({ id, spec: s })))
);
// TODO: convert listing to tree so it can be displayed as a tree?

const runCaseList = [];
for (const entry of entries) {
const { path, spec } = entry;
const testcasesVis = makeTest(path, spec.description);
for (const qr of queryResults) {
const testcasesVis = makeTest(qr.id, qr.spec.description);

if (!spec.g) {
if (!qr.spec.g) {
continue;
}

const [tRec] = log.record(path);
for (const t of spec.g.iterate(tRec)) {
const query = makeQueryString(entry, t.id);
const [tRec] = log.record(qr.id.path);
for (const t of qr.spec.g.iterate(tRec)) {
const query = makeQueryString(qr.id, t.id);
const runCase = mkCase(testcasesVis, query, t);
runCaseList.push(runCase);
}
Expand Down
15 changes: 7 additions & 8 deletions src/runtime/wpt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,18 @@ declare function async_test(f: (this: WptTestObject) => Promise<void>, name: str

const log = new Logger();
const running = [];
const entries = await Promise.all(
Array.from(listing, ({ suite, path, spec }) => spec.then(s => ({ suite, path, spec: s })))
const queryResults = await Promise.all(
Array.from(listing, ({ id, spec }) => spec.then(s => ({ id, spec: s })))
);

for (const entry of entries) {
const { path, spec } = entry;
if (!spec.g) {
for (const qr of queryResults) {
if (!qr.spec.g) {
continue;
}

const [rec] = log.record(path);
const [rec] = log.record(qr.id.path);
// TODO: don't run all tests all at once
for (const t of spec.g.iterate(rec)) {
for (const t of qr.spec.g.iterate(rec)) {
const run = t.run();
running.push(run);
// Note: apparently, async_tests must ALL be added within the same task.
Expand All @@ -40,7 +39,7 @@ declare function async_test(f: (this: WptTestObject) => Promise<void>, name: str
}
});
this.done();
}, makeQueryString(entry, t.id));
}, makeQueryString(qr.id, t.id));
}
}

Expand Down
14 changes: 6 additions & 8 deletions src/suites/unittests/loading.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,7 @@ class LoadingTest extends DefaultFixture {
async load(filters: string[]) {
const listing = await this.loader.loadTests(filters);
const entries = Promise.all(
Array.from(listing, ({ suite, path, spec }) =>
spec.then((s: TestSpecFile) => ({ suite, path, spec: s }))
)
Array.from(listing, ({ id, spec }) => spec.then((s: TestSpecFile) => ({ id, spec: s })))
);
return entries;
}
Expand Down Expand Up @@ -139,8 +137,8 @@ g.test('whole group', async t => {

{
const foo = (await t.load(['suite1:foo:']))[0];
t.expect(foo.suite === 'suite1');
t.expect(foo.path === 'foo');
t.expect(foo.id.suite === 'suite1');
t.expect(foo.id.path === 'foo');
if (foo.spec.g === undefined) {
throw new Error('foo group');
}
Expand Down Expand Up @@ -181,16 +179,16 @@ g.test('end2end', async t => {
throw new Error('listing length');
}

t.expect(l[0].suite === 'suite2');
t.expect(l[0].path === 'foof');
t.expect(l[0].id.suite === 'suite2');
t.expect(l[0].id.path === 'foof');
t.expect(l[0].spec.description === 'desc 2b');
if (l[0].spec.g === undefined) {
throw new Error();
}
t.expect(l[0].spec.g.iterate instanceof Function);

const log = new Logger();
const [rec, res] = log.record(l[0].path);
const [rec, res] = log.record(l[0].id.path);
const rcs = Array.from(l[0].spec.g.iterate(rec));
if (rcs.length !== 2) {
throw new Error('iterate length');
Expand Down
9 changes: 2 additions & 7 deletions src/suites/unittests/test_group_test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import {
DefaultFixture,
TestGroup,
Fixture,
paramsEquals,
TestCaseID,
} from '../../framework/index.js';
import { DefaultFixture, TestGroup, Fixture, paramsEquals } from '../../framework/index.js';
import { Logger } from '../../framework/logger.js';
import { TestCaseID } from '../../framework/id.js';

export class TestGroupTest extends DefaultFixture {
async run<F extends Fixture>(g: TestGroup<F>): Promise<void> {
Expand Down
2 changes: 1 addition & 1 deletion tools/run
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
// Run test suites under node.

require('../src/tools/setup-ts-in-node.js');
require('../src/tools/run.ts');
require('../src/runtime/cmdline.ts');

0 comments on commit c66c7d1

Please sign in to comment.