diff options
| author | (quasar) nebula <qznebula@protonmail.com> | 2026-03-31 19:53:51 -0300 |
|---|---|---|
| committer | (quasar) nebula <qznebula@protonmail.com> | 2026-03-31 19:53:51 -0300 |
| commit | 90b0f3ebb163e05aa47aec66bf16ddaa03739546 (patch) | |
| tree | 7f271020b791d7ef432d97bbddfba4a736d85291 /test/test-lib.js | |
| parent | 727e1f0b4f6361a38a12489675b8f8c892040d65 (diff) | |
test: move lib functions into one (short!) file
Diffstat (limited to 'test/test-lib.js')
| -rw-r--r-- | test/test-lib.js | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/test/test-lib.js b/test/test-lib.js new file mode 100644 index 00000000..a12974cd --- /dev/null +++ b/test/test-lib.js @@ -0,0 +1,86 @@ +import {compositeFrom} from '#composite'; + +Error.stackTraceLimit = Infinity; + +export function quickCheckCompositeOutputs(t, dependencies) { + return (step, outputDict) => { + t.same( + Object.keys(step.toDescription().outputs), + Object.keys(outputDict)); + + const composite = compositeFrom({ + compose: false, + steps: [ + step, + + { + dependencies: Object.keys(outputDict), + + // Access all dependencies by their expected keys - + // the composition runner actually provides a proxy + // and is checking that *we* access the dependencies + // we've specified. + compute: dependencies => + Object.fromEntries( + Object.keys(outputDict) + .map(key => [key, dependencies[key]])), + }, + ], + }); + + t.same( + composite.expose.compute(dependencies), + outputDict); + }; +} + +export function strictlyThrows(t, fn, pattern) { + const error = catchErrorOrNull(fn); + + t.currentAssert = strictlyThrows; + + if (error === null) { + t.fail(`expected to throw`); + return; + } + + const nameAndMessage = `${pattern.constructor.name} ${pattern.message}`; + t.match( + prepareErrorForMatch(error), + prepareErrorForMatch(pattern), + (pattern instanceof AggregateError + ? `expected to throw: ${nameAndMessage} (${pattern.errors.length} error(s))` + : `expected to throw: ${nameAndMessage}`)); +} + +function prepareErrorForMatch(error) { + if (error instanceof RegExp) { + return { + message: error, + }; + } + + if (!(error instanceof Error)) { + return error; + } + + const matchable = { + name: error.constructor.name, + message: error.message, + }; + + if (error instanceof AggregateError) { + matchable.errors = error.errors.map(prepareErrorForMatch); + } + + return matchable; +} + +function catchErrorOrNull(fn) { + try { + fn(); + return null; + } catch (error) { + return error; + } +} |