UNPKG

@japa/runner

Version:

A simple yet powerful testing framework for Node.js

235 lines (231 loc) 6.16 kB
import { CliParser, ConfigManager, GlobalHooks, Planner, createTest, createTestGroup } from "../chunk-Y57JXJ7G.js"; import "../chunk-U3BSXCEH.js"; import { Emitter, Runner, Suite } from "../chunk-PCBL2VZP.js"; import "../chunk-2KG3PWR4.js"; // factories/runner.ts import { fileURLToPath } from "url"; var RunnerFactory = class { #emitter = new Emitter(); #config; #cliArgs; #file = fileURLToPath(import.meta.url); #bail = false; get #refiner() { return this.#config.refiner; } /** * Registers plugins */ async #registerPlugins(runner2) { for (let plugin of this.#config.plugins) { await plugin({ config: this.#config, runner: runner2, emitter: this.#emitter, cliArgs: this.#cliArgs }); } } /** * Configure runner */ configure(config, argv) { this.#cliArgs = new CliParser().parse(argv || []); this.#config = new ConfigManager(config, this.#cliArgs).hydrate(); return this; } /** * Define a custom emitter instance to use */ useEmitter(emitter) { this.#emitter = emitter; return this; } /** * Run a test using the runner */ async runTest(title, callback) { return this.runSuites((emitter, refiner, file) => { const defaultSuite = new Suite("default", emitter, refiner); createTest(title, emitter, refiner, { suite: defaultSuite, file }).run(callback); return [defaultSuite]; }); } /** * Enable/disable the bail mode */ bail(toggle = true) { this.#bail = toggle; return this; } /** * Run dummy tests. You might use */ async runSuites(suites) { const runner2 = new Runner(this.#emitter); runner2.bail(this.#bail); await this.#registerPlugins(runner2); const { config, reporters, refinerFilters } = await new Planner(this.#config).plan(); const globalHooks = new GlobalHooks(); globalHooks.apply(config); reporters.forEach((reporter) => { runner2.registerReporter(reporter); }); refinerFilters.forEach((filter) => { config.refiner.add(filter.layer, filter.filters); }); suites(this.#emitter, this.#refiner, this.#file).forEach((suite) => runner2.add(suite)); await globalHooks.setup(runner2); await runner2.start(); await runner2.exec(); await runner2.end(); await globalHooks.teardown(null, runner2); return runner2.getSummary(); } }; // factories/create_dummy_tests.ts import assert from "assert"; function createUnitTestsSuite(emitter, refiner, file) { const suite = new Suite("unit", emitter, refiner); const group = createTestGroup("Maths#add", emitter, refiner, { suite, file }); createTest("A top level test inside a suite", emitter, refiner, { suite, file }).run(() => { }); createTest("add two numbers", emitter, refiner, { group, file }).run(() => { assert.equal(2 + 2, 4); }); createTest("add three numbers", emitter, refiner, { group, file }).run(() => { assert.equal(2 + 2 + 2, 6); }); createTest("add group of numbers", emitter, refiner, { group, file }); createTest("use math.js lib", emitter, refiner, { group, file }).skip( true, "Library work pending" ); createTest("add multiple numbers", emitter, refiner, { file, group }).run(() => { assert.equal(2 + 2 + 2 + 2, 6); }); createTest("add floating numbers", emitter, refiner, { group, file }).run(() => { assert.equal(2 + 2.2 + 2.1, 6); }).fails("Have to add support for floating numbers"); createTest("regression test that is passing", emitter, refiner, { group, file }).run(() => { assert.equal(2 + 2.2 + 2.1, 2 + 2.2 + 2.1); }).fails("Have to add support for floating numbers"); createTest("A test with an error that is not an AssertionError", emitter, refiner, { group, file }).run(() => { throw new Error("This is an error"); }); return suite; } function createFunctionalTestsSuite(emitter, refiner, file) { const suite = new Suite("functional", emitter, refiner); const group = createTestGroup("Users/store", emitter, refiner, { suite, file }); createTest("Validate user data", emitter, refiner, { group, file }).run(() => { }); createTest("Disallow duplicate emails", emitter, refiner, { group, file }).run(() => { }); createTest("Disallow duplicate emails across tenants", emitter, refiner, { group, file }).run(() => { const users = ["", ""]; assert.equal(users.length, 1); }); createTest("Normalize email before persisting it", emitter, refiner, { group, file }).skip(true, "Have to build a normalizer"); createTest("Send email verification mail", emitter, refiner, { group, file }); createTest("Test that times out", emitter, refiner, { group, file }).run(() => { return new Promise((resolve) => { setTimeout(resolve, 2100); }); }); const usersListGroup = createTestGroup("Users/list", emitter, refiner, { suite, file }); usersListGroup.setup(() => { throw new Error("Unable to cleanup database"); }); createTest("A test that will never run because the group hooks fails", emitter, refiner, { group: usersListGroup }); createTest("A top level test inside functional suite", emitter, refiner, { suite, file }).run(() => { }); return suite; } function createDummyTests(emitter, refiner, file) { return [ createUnitTestsSuite(emitter, refiner, file), createFunctionalTestsSuite(emitter, refiner, file) ]; } // factories/main.ts var runner = () => new RunnerFactory(); var syncReporter = { name: "sync", handler(r, emitter) { emitter.on("runner:end", function() { const summary = r.getSummary(); if (summary.hasError) { if (summary.failureTree[0].errors.length) { throw summary.failureTree[0].errors[0].error; } if (summary.failureTree[0].children[0].errors.length) { throw summary.failureTree[0].children[0].errors[0].error; } } }); } }; export { createDummyTests, runner, syncReporter };