1import { parseQuery } from './query/parseQuery.js';
2import { TestQuery } from './query/query.js';
3import { IterableTestGroup } from './test_group.js';
4import { TestSuiteListing } from './test_suite_listing.js';
5import { loadTreeForQuery, TestTree, TestTreeLeaf } from './tree.js';
6
7// A listing file, e.g. either of:
8// - `src/webgpu/listing.ts` (which is dynamically computed, has a Promise<TestSuiteListing>)
9// - `out/webgpu/listing.js` (which is pre-baked, has a TestSuiteListing)
10interface ListingFile {
11  listing: Promise<TestSuiteListing> | TestSuiteListing;
12}
13
14// A .spec.ts file, as imported.
15export interface SpecFile {
16  readonly description: string;
17  readonly g: IterableTestGroup;
18}
19
20// Base class for DefaultTestFileLoader and FakeTestFileLoader.
21export abstract class TestFileLoader {
22  abstract listing(suite: string): Promise<TestSuiteListing>;
23  protected abstract import(path: string): Promise<SpecFile>;
24
25  importSpecFile(suite: string, path: string[]): Promise<SpecFile> {
26    return this.import(`${suite}/${path.join('/')}.spec.js`);
27  }
28
29  async loadTree(query: TestQuery, subqueriesToExpand: string[] = []): Promise<TestTree> {
30    return loadTreeForQuery(
31      this,
32      query,
33      subqueriesToExpand.map(q => parseQuery(q))
34    );
35  }
36
37  async loadCases(query: TestQuery): Promise<IterableIterator<TestTreeLeaf>> {
38    const tree = await this.loadTree(query);
39    return tree.iterateLeaves();
40  }
41}
42
43export class DefaultTestFileLoader extends TestFileLoader {
44  async listing(suite: string): Promise<TestSuiteListing> {
45    return ((await import(`../../${suite}/listing.js`)) as ListingFile).listing;
46  }
47
48  import(path: string): Promise<SpecFile> {
49    return import(`../../${path}`);
50  }
51}
52