Skip to content

Commit

Permalink
Move listing-related interfaces out to listing.ts, and simplify them
Browse files Browse the repository at this point in the history
  • Loading branch information
kainino0x committed Jul 8, 2019
1 parent 4ffaf6f commit bb0f005
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 45 deletions.
3 changes: 3 additions & 0 deletions src/framework/fixture.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { ParamsAny } from './params/index.js';
import { CaseRecorder } from './logger.js';

// A Fixture is a class used to instantiate each test case at run time.
// A new instance of the Fixture is created for every single test case
// (i.e. every time the test function is run).
export abstract class Fixture {
params: ParamsAny;
protected rec: CaseRecorder;
Expand Down
9 changes: 9 additions & 0 deletions src/framework/listing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// A listing of all specs within a single suite. This is the (awaited) type of
// `groups` in 'src/suites/*/index.ts' and the auto-generated
// 'out/suites/*/index.js' files (see src/tools/gen.ts).
export type TestSuiteListing = Iterable<TestSuiteListingEntry>;

export interface TestSuiteListingEntry {
readonly path: string;
readonly description: string;
}
52 changes: 24 additions & 28 deletions src/framework/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,31 @@ import { GroupRecorder } from './logger.js';
import { ParamsAny, paramsEquals, paramsSupersets } from './params/index.js';
import { RunCaseIterable, TestCaseID, RunCase } from './test_group.js';
import { allowedTestNameCharacters } from './allowed_characters.js';
import { TestSuiteListing } from './listing.js';

export interface TestGroupDesc {
readonly path: string;
readonly description: string;
}

export interface TestSuiteListing {
readonly suite: string;
readonly groups: Iterable<TestGroupDesc>;
}

// One of the following:
// - A shell object describing a directory (from its README.txt).
// - An actual .spec.ts file, as imported.
// - A *filtered* list of cases from a single .spec.ts file.
export interface TestSpecFile {
readonly description: string;
// undefined for README.txt, defined for a test module.
readonly g?: RunCaseIterable;
}

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

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

type TestQueryResults = IterableIterator<TestQueryResult>;

function* concat(lists: TestQueryResult[][]): TestQueryResults {
for (const specs of lists) {
yield* specs;
Expand All @@ -58,7 +53,7 @@ export interface TestFileLoader {

class DefaultTestFileLoader implements TestFileLoader {
async listing(suite: string): Promise<TestSuiteListing> {
return { suite, groups: await (await import(`../suites/${suite}/index.js`)).listing };
return (await import(`../suites/${suite}/index.js`)).listing;
}

import(path: string): Promise<TestSpecFile> {
Expand All @@ -73,17 +68,17 @@ export class TestLoader {
this.fileLoader = fileLoader;
}

async loadTestsFromQuery(query: string): Promise<IterableIterator<TestQueryResult>> {
async loadTestsFromQuery(query: string): Promise<TestQueryResults> {
return this.loadTests(new URLSearchParams(query).getAll('q'));
}

async loadTestsFromCmdLine(filters: string[]): Promise<IterableIterator<TestQueryResult>> {
async loadTestsFromCmdLine(filters: string[]): Promise<TestQueryResults> {
// In actual URL queries (?q=...), + represents a space. But decodeURIComponent doesn't do this,
// so do it manually. (+ is used over %20 for readability.) (See also encodeSelectively.)
return this.loadTests(filters.map(f => decodeURIComponent(f.replace(/\+/g, '%20'))));
}

async loadTests(filters: string[]): Promise<IterableIterator<TestQueryResult>> {
async loadTests(filters: string[]): Promise<TestQueryResults> {
const loads = filters.map(f => this.loadFilter(f));
return concat(await Promise.all(loads));
}
Expand All @@ -103,10 +98,10 @@ export class TestLoader {
// - cts:buffers/
// - cts:buffers/map
const groupPrefix = filter.substring(i1 + 1);
return this.filterByGroup(await this.fileLoader.listing(suite), groupPrefix);
return this.filterByGroup(suite, await this.fileLoader.listing(suite), groupPrefix);
}

const group = filter.substring(i1 + 1, i2);
const path = filter.substring(i1 + 1, i2);
const endOfTestName = new RegExp('[^' + allowedTestNameCharacters + ']');
const i3sub = filter.substring(i2 + 1).search(endOfTestName);
if (i3sub === -1) {
Expand All @@ -116,8 +111,8 @@ export class TestLoader {
return [
{
suite,
path: group,
spec: this.filterByTestMatch(suite, group, testPrefix),
path,
spec: this.filterByTestMatch(suite, path, testPrefix),
},
];
}
Expand All @@ -138,8 +133,8 @@ export class TestLoader {
return [
{
suite,
path: group,
spec: this.filterByParamsMatch(suite, group, test, params),
path,
spec: this.filterByParamsMatch(suite, path, test, params),
},
];
} else if (token === ':') {
Expand All @@ -149,8 +144,8 @@ export class TestLoader {
return [
{
suite,
path: group,
spec: this.filterByParamsExact(suite, group, test, params),
path,
spec: this.filterByParamsExact(suite, path, test, params),
},
];
} else {
Expand All @@ -159,12 +154,13 @@ export class TestLoader {
}

private filterByGroup(
{ suite, groups }: TestSuiteListing,
suite: string,
specs: TestSuiteListing,
groupPrefix: string
): TestQueryResult[] {
const entries: TestQueryResult[] = [];

for (const { path, description } of groups) {
for (const { path, description } of specs) {
if (path.startsWith(groupPrefix)) {
const isReadme = path === '' || path.endsWith('/');
const spec: Promise<TestSpecFile> = isReadme
Expand Down
4 changes: 2 additions & 2 deletions src/suites/cts/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TestGroupDesc } from '../../framework/loader.js';
import { TestSuiteListing } from '../../framework/listing.js';
import { makeListing } from '../../tools/crawl.js';

export const listing: Promise<TestGroupDesc[]> = makeListing(__filename);
export const listing: Promise<TestSuiteListing> = makeListing(__filename);
4 changes: 2 additions & 2 deletions src/suites/unittests/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TestGroupDesc } from '../../framework/loader.js';
import { TestSuiteListing } from '../../framework/listing.js';
import { makeListing } from '../../tools/crawl.js';

export const listing: Promise<TestGroupDesc[]> = makeListing(__filename);
export const listing: Promise<TestSuiteListing> = makeListing(__filename);
13 changes: 4 additions & 9 deletions src/suites/unittests/loading.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,11 @@ import {
TestGroup,
RunCase,
} from '../../framework/index.js';
import {
TestFileLoader,
TestGroupDesc,
TestLoader,
TestSpecFile,
TestSuiteListing,
} from '../../framework/loader.js';
import { TestSpecFile, TestLoader, TestFileLoader } from '../../framework/loader.js';
import { TestSuiteListingEntry, TestSuiteListing } from '../../framework/listing.js';
import { Logger } from '../../framework/logger.js';

const listingData: { [k: string]: TestGroupDesc[] } = {
const listingData: { [k: string]: TestSuiteListingEntry[] } = {
suite1: [
{ path: '', description: 'desc 1a' },
{ path: 'foo', description: 'desc 1b' },
Expand Down Expand Up @@ -79,7 +74,7 @@ const specsData: { [k: string]: TestSpecFile } = {

class FakeTestFileLoader implements TestFileLoader {
async listing(suite: string): Promise<TestSuiteListing> {
return { suite, groups: listingData[suite] };
return listingData[suite];
}

async import(path: string): Promise<TestSpecFile> {
Expand Down
8 changes: 4 additions & 4 deletions src/tools/crawl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import fg from 'fast-glob';
import * as fs from 'fs';
import * as path from 'path';

import { TestGroupDesc } from '../framework/loader.js';
import { TestSuiteListingEntry } from '../framework/listing.js';

const specSuffix = '.spec.ts';

export async function crawl(suite: string): Promise<TestGroupDesc[]> {
export async function crawl(suite: string): Promise<TestSuiteListingEntry[]> {
const specDir = path.normalize(`src/suites/${suite}`);
if (!fs.existsSync(specDir)) {
console.error(`Could not find ${specDir}`);
Expand All @@ -21,7 +21,7 @@ export async function crawl(suite: string): Promise<TestGroupDesc[]> {

const specFiles = await fg(specDir + '/**/{README.txt,*' + specSuffix + '}', { onlyFiles: true });

const groups: TestGroupDesc[] = [];
const groups: TestSuiteListingEntry[] = [];
for (const file of specFiles) {
const f = file.substring((specDir + '/').length);
if (f.endsWith(specSuffix)) {
Expand All @@ -47,7 +47,7 @@ export async function crawl(suite: string): Promise<TestGroupDesc[]> {
return groups;
}

export function makeListing(filename: string): Promise<TestGroupDesc[]> {
export function makeListing(filename: string): Promise<TestSuiteListingEntry[]> {
const suite = path.basename(path.dirname(filename));
return crawl(suite);
}

0 comments on commit bb0f005

Please sign in to comment.