UNPKG

@zorax/plug

Version:
221 lines (166 loc) 5.28 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var zora = require('zora'); const REPORT_HOOKS = Symbol('@zorax/plug:REPORT_HOOKS'); const noop = () => {}; const getHarnessMutators = pg => [pg.test, pg.harness, pg.init]; const getHarnessDecorators = pg => [ pg.decorate, pg.decorateHarness, pg.decorateInit, ]; const getProxyMutators = pg => [pg.test, pg.harness]; const getProxyDecorators = pg => [pg.decorate, pg.decorateHarness]; const getTestMutators = pg => pg.test; const getTestDecorators = pg => pg.decorate; const getHarnessHooks = plugins => [ ...plugins.flatMap(getHarnessMutators), ...plugins.flatMap(getHarnessDecorators), ].filter(Boolean); const getTestHooks = plugins => [...plugins.map(getTestMutators), ...plugins.map(getTestDecorators)].filter( Boolean ); const getProxyHooks = plugins => [ ...plugins.flatMap(getProxyMutators), ...plugins.flatMap(getProxyDecorators), ].filter(Boolean); const wrapTestMethod = (harness, proxy, withHooks, target) => { const { test } = target; target.test = (desc, run, ...rest) => { // just a friendly sanity check: end of pipeline respects expected signature if ( // undefined title is actually more or less allowed (typeof desc !== 'undefined' && typeof desc !== 'string') || typeof run !== 'function' ) { throw new Error('plugins pipeline in disarray') } const zora_spec_fn = (t, ...rest) => run(withHooks(t), ...rest); return test(desc, zora_spec_fn, ...rest) }; }; // NOTE prop: {} makes it undefined const proxySpecifiers = { report: {}, pass: { writable: true }, // zora.pass wants to rewrite this error: {}, length: {}, count: {}, successCount: {}, skipCount: {}, failureCount: {}, }; const augmentProxy = (harness, target, plugins, getHooks) => { target.plugins = plugins; target.plug = (...newPlugins) => plug(harness, plugins, target, newPlugins); target.run = fn => { fn(target); return target }; const testHooks = getTestHooks(plugins); const withTestHooks = t => { wrapTestMethod(harness, target, withTestHooks, t); testHooks.forEach(hook => hook(t, target, harness)); return t }; wrapTestMethod(harness, target, withTestHooks, target); // NOTE apply hooks _after_ replacing test! const hooks = getHooks(plugins); hooks.forEach(hook => hook(target, harness)); }; const createProxy = t => Object.create(t, proxySpecifiers); const plug = (harness, parentPlugins, target, newPluginsInput) => { const newPlugins = newPluginsInput.flat().filter(Boolean); newPlugins.forEach(pg => { if (pg.init || pg.decorateInit) { throw new Error( 'Init plugin can only be added at harness creation (not plugged): ' + pg.name ) } if (pg.report) { harness[REPORT_HOOKS].push(pg.report); } }); const proxy = createProxy(target); const plugins = [...parentPlugins, ...newPlugins]; augmentProxy(harness, proxy, plugins, getProxyHooks); return proxy }; const parseCreateHarnessFactoryArgs = args => { if (args.length === 0) { return args } let createHarness; let options; let plugins; const [a, b, c] = args; if (typeof a === 'function') { createHarness = a; if (Array.isArray(b)) { plugins = b; } else { options = b; plugins = c; } } else { if (Array.isArray(a)) { plugins = a; } else { options = a; plugins = b; } } return [createHarness, options, plugins] }; // createHarnessFactory(options) // createHarnessFactory(plugins) // createHarnessFactory(options, plugins) // createHarnessFactory(createHarness, options) // createHarnessFactory(createHarness, plugins) // createHarnessFactory(createHarness, options, plugins) const createHarnessFactory = (...args) => { const [ createHarness = zora.createHarness, factoryOptions = {}, factoryPlugins = [], ] = parseCreateHarnessFactoryArgs(args); const createZoraxHarness = ( harnessOptions = {}, harnessPlugins = [], ...args ) => { if (Array.isArray(harnessOptions)) { harnessPlugins = harnessOptions; harnessOptions = {}; } const options = { ...factoryOptions, ...harnessOptions }; const harness = createHarness(options, ...args); harness.options = options; const plugins = [...factoryPlugins, ...harnessPlugins].filter(Boolean); harness[REPORT_HOOKS] = plugins.filter(pg => pg.report).map(pg => pg.report); const { report } = harness; harness.report = async (...args) => { const after = []; for (const reportHook of harness[REPORT_HOOKS]) { const afterHook = await reportHook(harness, args); if (afterHook) after.push(afterHook); } await report.apply(harness, args); for (const afterHook of after) { await afterHook(); } }; augmentProxy(harness, harness, plugins, getHarnessHooks); return harness }; return createZoraxHarness }; const createHarness = createHarnessFactory(zora.createHarness); createHarness.plug = noop; exports.createHarness = createHarness; exports.createHarnessFactory = createHarnessFactory; //# sourceMappingURL=plug.cjs.js.map