Skip to content

Commit

Permalink
chore(internal) add @warp-drive/diagnostic/ember (#9009)
Browse files Browse the repository at this point in the history
* chore(internal) add @warp-drive/diagnostic/ember

* chore(private): add setup to @warp-drive/diagnostic/ember

* stash

* make diagnostic behave like an addon when needed

* maybe can do less
  • Loading branch information
runspired authored Oct 19, 2023
1 parent 79b2e60 commit 65b6752
Show file tree
Hide file tree
Showing 49 changed files with 300 additions and 364 deletions.
32 changes: 32 additions & 0 deletions packages/diagnostic/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ or you can add your own.
- [🔜 Randomization](#randomization)
- [Why Is It Fast?](#why-is-it-fast)
- [Migration From QUnit](#migration-from-qunit)
- [Using with Ember](#using-with-ember)

---

Expand Down Expand Up @@ -433,6 +434,37 @@ module('My Module', function(hooks) {

---

### Using With Ember

1. Add the following peer-deps to your app:

```diff
+ "@ember/test-helpers": ">= 3.2.0",
+ "ember-cli-test-loader": ">= 3.1.0",
+ "@embroider/addon-shim": ">= 1.8.6"
```

2. Configure for ember in `test-helper.js`

```ts
import { configure } from '@warp-drive/diagnostic/ember';

configure();
```

3. Use setup helpers

```ts
import { module, test } from '@warp-drive/diagnostic';
import { setupTest } from '@warp-drive/diagnostic/ember';

module('My Module', function (hooks) {
setupTest(hooks);
});
```

---

### ♥️ Credits

<details>
Expand Down
4 changes: 4 additions & 0 deletions packages/diagnostic/addon-main.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
'use strict';

const { addonV1Shim } = require('@embroider/addon-shim');
module.exports = addonV1Shim(__dirname);
36 changes: 33 additions & 3 deletions packages/diagnostic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"vitest",
"jest",
"mocha",
"chai"
"chai",
"ember-addon"
],
"repository": {
"type": "git",
Expand All @@ -24,6 +25,7 @@
"license": "MIT",
"author": "Chris Thoburn <runspired@users.noreply.github.com>",
"files": [
"addon-main.cjs",
"dist/",
"server/",
"README.md",
Expand All @@ -48,6 +50,10 @@
"bun": "./server/*.js",
"deno": "./server/*.js"
},
"./ember": {
"types": "./dist/ember.d.ts",
"default": "./dist/ember.js"
},
"./*": {
"types": "./dist/*.d.ts",
"default": "./dist/*.js"
Expand All @@ -62,7 +68,22 @@
"prepack": "pnpm build",
"prepare": "pnpm build"
},
"peerDependencies": {},
"peerDependencies": {
"@ember/test-helpers": ">= 3.2.0",
"ember-cli-test-loader": ">= 3.1.0",
"@embroider/addon-shim": ">= 1.8.6"
},
"peerDependenciesMeta": {
"@ember/test-helpers": {
"optional": true
},
"ember-cli-test-loader": {
"optional": true
},
"@embroider/addon-shim": {
"optional": true
}
},
"dependencies": {
"chalk": "^5.3.0",
"debug": "^4.3.4",
Expand All @@ -78,6 +99,7 @@
"@embroider/addon-dev": "^4.1.1",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-node-resolve": "^15.2.3",
"ember-cli-test-loader": "^3.1.0",
"rollup": "^4.1.1",
"tslib": "^2.6.2",
"typescript": "^5.2.2",
Expand All @@ -90,5 +112,13 @@
"volta": {
"extends": "../../package.json"
},
"packageManager": "pnpm@8.9.0"
"packageManager": "pnpm@8.9.0",
"ember-addon": {
"main": "addon-main.cjs",
"type": "addon",
"version": 2
},
"ember": {
"edition": "octane"
}
}
4 changes: 2 additions & 2 deletions packages/diagnostic/rollup.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ export default {
// You can augment this if you need to.
output: addon.output(),

external: [],
external: ["@ember/test-helpers", "ember-cli-test-loader/test-support/index"],

plugins: [
// These are the modules that users should be able to import from your
// addon. Anything not listed here may get optimized away.
addon.publicEntrypoints(['index.js', 'reporters/dom.js', 'reporters/tap.js', 'runners/dom.js']),
addon.publicEntrypoints(['index.js', 'reporters/dom.js', 'reporters/tap.js', 'runners/dom.js', 'ember.js']),

nodeResolve({ extensions: ['.ts'] }),
babel({
Expand Down
52 changes: 27 additions & 25 deletions packages/diagnostic/src/-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,22 @@ export type ParamConfig = {
value: boolean;
}

export type GlobalConfig = {
export type GlobalHooksStorage<TC extends TestContext> = {
onSuiteStart: GlobalCallback[];
onSuiteFinish: GlobalCallback[];
beforeModule: GlobalCallback[];
afterModule: GlobalCallback[];
beforeEach: HooksCallback<TC>[];
afterEach: HooksCallback<TC>[];
}

export type GlobalConfig<TC extends TestContext = TestContext> = {
params: { [key in 'concurrency' | 'tryCatch' | 'instrument' | 'hideReport' | 'memory' | 'groupLogs' | 'debug' | 'container']: ParamConfig };
_current: SuiteReport | null;
useTestem: boolean;
useDiagnostic: boolean;
concurrency: number;
globalHooks: {
beforeEach: HooksCallback[];
afterEach: HooksCallback[];
beforeModule: GlobalCallback[];
afterModule: GlobalCallback[];
onSuiteStart: GlobalCallback[];
onSuiteFinish: GlobalCallback[];
}
globalHooks: GlobalHooksStorage<TC>;
totals: {
tests: number;
primaryModules: number;
Expand Down Expand Up @@ -73,45 +75,45 @@ export interface TestContext {}

export type GlobalCallback = () => void | Promise<void>;

export interface Hooks {
beforeEach: (cb: HooksCallback) => void;
afterEach: (cb: HooksCallback) => void;
export interface Hooks<TC extends TestContext = TestContext> {
beforeEach: (cb: HooksCallback<TC>) => void;
afterEach: (cb: HooksCallback<TC>) => void;
beforeModule: (cb: GlobalCallback) => void;
afterModule: (cb: GlobalCallback) => void;
}
export interface GlobalHooks extends Hooks {
export interface GlobalHooks<TC extends TestContext> extends Hooks<TC> {
onSuiteStart: (cb: GlobalCallback) => void;
onSuiteFinish: (cb: GlobalCallback) => void;
}

export type HooksCallback = (this: TestContext, assert: Diagnostic) => void | Promise<void>;
export type ModuleCallback = ((hooks: Hooks) => void | Promise<void>) | (() => void | Promise<void>);
export type TestCallback = (this: TestContext, assert: Diagnostic) => void | Promise<void>;
export type HooksCallback<TC extends TestContext> = (this: TC, assert: Diagnostic) => void | Promise<void>;
export type ModuleCallback<TC extends TestContext> = ((hooks: Hooks<TC>) => void | Promise<void>) | (() => void | Promise<void>);
export type TestCallback<TC extends TestContext> = (this: TC, assert: Diagnostic) => void | Promise<void>;

export interface TestInfo {
export interface TestInfo<TC extends TestContext> {
id: string;
name: string;
cb: TestCallback;
cb: TestCallback<TC>;
skip: boolean;
todo: boolean;
module: ModuleInfo;
module: ModuleInfo<TC>;
}

export interface OrderedMap<T> {
byName: Map<string, T>;
byOrder: T[];
}

export interface ModuleInfo {
export interface ModuleInfo<TC extends TestContext> {
moduleName: string;
name: string;
cb: ModuleCallback;
cb: ModuleCallback<TC>;
config: {
beforeEach: HooksCallback[];
afterEach: HooksCallback[];
beforeEach: HooksCallback<TC>[];
afterEach: HooksCallback<TC>[];
beforeModule: GlobalCallback[];
afterModule: GlobalCallback[];
},
tests: OrderedMap<TestInfo>;
modules: OrderedMap<ModuleInfo>;
tests: OrderedMap<TestInfo<TC>>;
modules: OrderedMap<ModuleInfo<TC>>;
}
7 changes: 3 additions & 4 deletions packages/diagnostic/src/-utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/* global window, globalThis, global, self */
import type { Config } from "./internals/config";
import { HooksCallback, ModuleInfo } from "./-types";
import { HooksCallback,TestContext, ModuleInfo, GlobalHooksStorage } from "./-types";

export function assert(message: string, test: unknown): asserts test {
if (!test) {
Expand All @@ -15,8 +14,8 @@ export function getGlobal(): Window {
return g as unknown as Window;
}

export function getChain(globalHooks: typeof Config.globalHooks, module: ModuleInfo, parents: ModuleInfo[] | null, prop: 'beforeEach' | 'afterEach'): HooksCallback[] {
const chain: HooksCallback[] = [];
export function getChain<TC extends TestContext>(globalHooks: GlobalHooksStorage<TC>, module: ModuleInfo<TC>, parents: ModuleInfo<TC>[] | null, prop: 'beforeEach' | 'afterEach'): HooksCallback<TC>[] {
const chain: HooksCallback<TC>[] = [];

if (globalHooks[prop].length) {
chain.push(...globalHooks[prop]);
Expand Down
68 changes: 68 additions & 0 deletions packages/diagnostic/src/ember.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { getTestMetadata, setupContext, SetupContextOptions, teardownContext, TestContext } from '@ember/test-helpers';
import AbstractTestLoader from 'ember-cli-test-loader/test-support/index';

import type { Hooks } from './-types';

import { setupGlobalHooks } from './internals/config';

// fix bug with embroider/webpack/auto-import and test-loader
// @ts-expect-error
const CLITestLoader: typeof AbstractTestLoader = AbstractTestLoader.default ? AbstractTestLoader.default : AbstractTestLoader;

export function setupTest(hooks: Hooks<TestContext>, opts?: SetupContextOptions) {
const options = { waitForSettled: false, ...opts };

hooks.beforeEach(async function () {
let testMetadata = getTestMetadata(this);
testMetadata.framework = 'qunit';

await setupContext(this, options);
});

hooks.afterEach(function (this: TestContext) {
return teardownContext(this, options);
});
}

let moduleLoadFailures: Error[] = [];

class TestLoader extends CLITestLoader {
moduleLoadFailure(moduleName: string, error: Error) {
moduleLoadFailures.push(error);
}
}

/**
Load tests following the default patterns:
* The module name ends with `-test`
* The module name ends with `.jshint`
@method loadTests
*/
function loadTests() {
TestLoader.load();
}

export function configure() {
setupGlobalHooks((hooks) => {
hooks.onSuiteFinish(() => {
let length = moduleLoadFailures.length;

try {
if (length === 0) {
// do nothing
} else if (length === 1) {
throw moduleLoadFailures[0];
} else {
throw new Error('\n' + moduleLoadFailures.join('\n'));
}
} finally {
// ensure we release previously captured errors.
moduleLoadFailures = [];
}
});
});

loadTests();
}
Loading

0 comments on commit 65b6752

Please sign in to comment.