| 2 | import { Interface, Scenario, intoFullInterface } from './index.js' |
| 3 | |
| 4 | export async function runScenarios( |
| 5 | scenarios: Scenario[], |
| 6 | iface: Interface |
| 7 | ): Promise<void> { |
| 8 | const fullIface = intoFullInterface(iface) |
| 9 | if (scenarios.some((scenario) => scenario.only)) { |
| 10 | scenarios = scenarios.filter((scenario) => scenario.only) |
| 11 | } |
| 12 | scenarios = await fullIface.filterScenarios(scenarios) |
| 13 | let variants = [] |
| 14 | for (const scenario of scenarios) { |
| 15 | let props = [{}] |
| 16 | for (const [key, options] of Object.entries(scenario.config)) { |
| 17 | const newProps = [] |
| 18 | for (const prop of props) { |
| 19 | if (prop === 'scenario' || prop === 'name') |
| 20 | throw new Error("Cannot use 'scenario' or 'name' as a property name") |
| 21 | for (const value of options) { |
| 22 | newProps.push({ |
| 23 | ...prop, |
| 24 | [key]: value, |
| 25 | }) |
| 26 | } |
| 27 | } |
| 28 | props = newProps |
| 29 | } |
| 30 | variants.push( |
| 31 | ...props.map((props) => ({ |
| 32 | scenario, |
| 33 | props, |
| 34 | })) |
| 35 | ) |
| 36 | } |
| 37 | variants = await fullIface.filterScenarioVariants(variants) |
| 38 | |
| 39 | for (const variant of variants) { |
| 40 | try { |
| 41 | const measurements = new Map() |
| 42 | await withCurrent( |
| 43 | { |
| 44 | iface: fullIface, |
| 45 | measurements, |
| 46 | scenario: variant, |
| 47 | }, |
| 48 | async () => { |
| 49 | await fullIface.start(variant.scenario.name, variant.props) |
| 50 | measurements.set('start', { |
| 51 | value: Date.now(), |
| 52 | unit: 'ms', |
| 53 | }) |
| 54 | await variant.scenario.fn(variant.props) |
| 55 | await fullIface.end(variant.scenario.name, variant.props) |
| 56 | } |
| 57 | ) |
| 58 | } catch (e) { |
| 59 | await fullIface.error(variant.scenario.name, variant.props, e) |
| 60 | process.exitCode = 1 |
| 61 | } |