{"version":3,"file":"index.cjs","names":[],"sources":["../src/executeStep.ts","../src/contextProvider/Context.ts","../src/contextProvider/ContextProvider.ts","../src/contextProvider/index.ts","../src/whenStep/whenStep.ts","../src/thenStep/_hasExpectError.ts","../src/thenStep/thenStep.ts","../src/scenarioTest/_whenThen.ts","../src/scenarioTest/_simple.ts","../src/scenarioTest/_isWhenThenScenarioTest.ts","../src/scenarioTest/scenarioTest.ts","../src/gherkinTest/gherkinTest.ts","../src/gwt.ts"],"sourcesContent":["import type { Step } from \"../types\";\n\nconst executeStep = <T>(context: T, step: Step<T> | undefined) =>\n  Object.values(step ?? {}).reduce(\n    // @ts-ignore\n    (previous, func) => previous.then(() => func.bind(context)()),\n    Promise.resolve(),\n  );\nexport { executeStep };\n","export class Context<T> {\n  public context: Partial<T>;\n\n  constructor(public parent?: Context<T>) {\n    this.context = Object.create(parent?.context || {});\n  }\n\n  getChild(): Context<T> {\n    return new Context<T>(this);\n  }\n}\n","import { Context } from \"./Context\";\n\nexport class ContextProvider<T> {\n  public activeContext?: Context<T>;\n\n  get context(): Partial<T> | undefined {\n    return this.activeContext?.context;\n  }\n\n  public createContext = (): void => {\n    if (!this.activeContext) {\n      this.activeContext = new Context<T>();\n    } else {\n      this.activeContext = this.activeContext.getChild();\n    }\n  };\n\n  public releaseContext = (): void => {\n    this.activeContext = this.activeContext?.parent;\n  };\n}\n","import { ContextProvider } from \"./ContextProvider\";\nexport { ContextProvider } from \"./ContextProvider\";\n\nexport const TestContext: ContextProvider<unknown> = new ContextProvider();\n","import type { Step } from \"../../types\";\nimport { executeStep } from \"../executeStep\";\n\nexport const whenStep = async <T>(\n  context: T,\n  step: Step<T> | undefined,\n): Promise<Error | undefined> => {\n  try {\n    await executeStep(context, step);\n\n    return undefined;\n  } catch (e) {\n    return e as Error;\n  }\n};\n","import type { ThenStep, ThenStepWithExpectError } from \"../../types\";\n\nexport const hasExpectError = <TContext>(\n  step: ThenStep<TContext> | undefined,\n): step is ThenStepWithExpectError<TContext> => !!step && \"expect_error\" in step;\n","import type { ThenStep } from \"../../types\";\nimport { executeStep } from \"../executeStep\";\nimport { hasExpectError } from \"./_hasExpectError\";\n\nexport const thenStep = async <TContext>(\n  context: TContext,\n  step: ThenStep<TContext> | undefined,\n  error: Error | undefined,\n) => {\n  if (hasExpectError(step)) {\n    if (!error) {\n      throw new Error(\"Expected error to be thrown, but no error was thrown\");\n    }\n\n    // @ts-ignore\n    await step.expect_error.bind(context)(error);\n  } else if (error) {\n    throw error;\n  }\n\n  await (hasExpectError(step) ? executeStep(context, step.and) : executeStep(context, step));\n};\n","import type {\n  GivenScenarioWhenThenDefinition,\n  ScenarioStep,\n  ScenarioThenWhenStep,\n  ScenarioWhenStep,\n} from \"../../types\";\nimport { whenStep } from \"../whenStep\";\nimport { thenStep } from \"../thenStep\";\n\nconst recursiveSteps = async <TContext>(\n  context: TContext,\n  steps: ScenarioStep<TContext>,\n  index: number = 0,\n) => {\n  const step = steps[index];\n\n  try {\n    const when =\n      index === 0\n        ? (step as ScenarioWhenStep<TContext>).when\n        : (step as ScenarioThenWhenStep<TContext>).then_when;\n\n    const error = await whenStep(context, when);\n\n    await thenStep(context, step.then, error);\n  } catch (cause: any) {\n    throw new Error(`Error in step \"${step.name ?? index}\": ${cause.message}`, { cause });\n  }\n\n  if (index + 1 < steps.length) {\n    await recursiveSteps(context, steps, index + 1);\n  }\n};\n\nexport const executeWhenThen = async <TContext>(\n  context: TContext,\n  gwt: GivenScenarioWhenThenDefinition<TContext>,\n) => {\n  if (!gwt.scenario) {\n    throw new Error(\"Expected scenario definition\");\n  }\n\n  await recursiveSteps(context, gwt.scenario);\n};\n","import type { GivenScenarioDefinition } from \"../../types\";\nimport { whenStep } from \"../whenStep\";\n\nexport const executeSimple = async <TContext>(\n  context: TContext,\n  gwt: GivenScenarioDefinition<TContext>,\n) => {\n  const error = await whenStep(context, gwt.scenario);\n\n  if (gwt.expect_error) {\n    if (!error) {\n      throw new Error(\"Expected error to be thrown, but no error was thrown\");\n    }\n    // @ts-ignore\n    await gwt.expect_error.bind(context)(error);\n  } else if (error) {\n    throw error;\n  }\n};\n","import type { GivenScenarioTest, GivenScenarioWhenThenDefinition } from \"../../types\";\n\nexport const isWhenThenScenarioTest = <TContext>(\n  gwt: GivenScenarioTest<TContext>,\n): gwt is GivenScenarioWhenThenDefinition<TContext> => Array.isArray(gwt.scenario);\n","import type { GivenScenarioTest, GwtDefinition, TestFunction } from \"../../types\";\nimport { executeStep } from \"../executeStep\";\nimport { TestContext } from \"../contextProvider\";\nimport { executeWhenThen } from \"./_whenThen\";\nimport { executeSimple } from \"./_simple\";\nimport { isWhenThenScenarioTest } from \"./_isWhenThenScenarioTest\";\nimport type { ConfigureTestFunction } from \"../../types/Gwt\";\n\nexport const isScenarioTest = <TContext>(\n  test: GwtDefinition<TContext>,\n): test is GivenScenarioTest<TContext> =>\n  Object.keys(test).every((key) => [\"given\", \"scenario\", \"expect_error\"].includes(key));\n\nexport const scenarioTest = <TContext>(\n  testFunc: TestFunction,\n  configureTestFunction: ConfigureTestFunction<TContext> | undefined,\n  name: string,\n  gwt: GivenScenarioTest<TContext>,\n) =>\n  testFunc(name, async (...args: any[]) => {\n    TestContext.createContext();\n\n    const context = TestContext.context as TContext;\n\n    if (configureTestFunction) {\n      configureTestFunction(context, ...args);\n    }\n\n    await executeStep(context, gwt.given);\n\n    if (isWhenThenScenarioTest(gwt)) {\n      await executeWhenThen(context, gwt);\n    } else {\n      await executeSimple(context, gwt);\n    }\n\n    TestContext.releaseContext();\n  });\n","import type { GherkinDefinition, GwtDefinition } from \"../../types\";\nimport { executeStep } from \"../executeStep\";\nimport { TestContext } from \"../contextProvider\";\nimport { whenStep } from \"../whenStep\";\nimport { thenStep } from \"../thenStep\";\nimport type { ConfigureTestFunction } from \"../../types/Gwt\";\n\nexport const isGherkinTest = <TContext>(\n  test: GwtDefinition<TContext>,\n): test is GherkinDefinition<TContext> =>\n  Object.keys(test).every((key) => [\"given\", \"when\", \"then\"].includes(key));\n\nexport const gherkinTest = <TContext>(\n  testFunc: (name: string, callback: (...args: any[]) => void | Promise<void>) => unknown,\n  configureTestFunc: ConfigureTestFunction<TContext> | undefined,\n  name: string,\n  gwt: GherkinDefinition<TContext>,\n) =>\n  testFunc(name, async (...args) => {\n    TestContext.createContext();\n\n    const context = TestContext.context as TContext;\n\n    if (configureTestFunc) {\n      configureTestFunc(context, ...args);\n    }\n\n    await executeStep(context, gwt.given);\n\n    const error = await whenStep(context, gwt.when);\n\n    await thenStep(context, gwt.then, error);\n\n    TestContext.releaseContext();\n  });\n","import { scenarioTest, isScenarioTest } from \"./scenarioTest\";\nimport { gherkinTest, isGherkinTest } from \"./gherkinTest\";\nimport type { GivenScenarioTest, GwtDefinition, TestFunction } from \"../types\";\nimport type { GherkinTest } from \"../types/gherkin/Gherkin\";\nimport type { ConfigureTestFunction } from \"../types/Gwt\";\n\ntype TestType<T extends GwtDefinition<any> = GwtDefinition<any>> = {\n  test: (def: any) => boolean;\n  runner: (\n    testFunc: TestFunction,\n    configureTestFunc: ConfigureTestFunction<any> | undefined,\n    name: string,\n    gwtDefinition: T,\n  ) => void;\n};\n\nconst testTypes: Array<TestType<any>> = [\n  {\n    test: isGherkinTest,\n    runner: gherkinTest,\n  } as TestType<GherkinTest<any>>,\n  {\n    test: isScenarioTest,\n    runner: scenarioTest,\n  } as TestType<GivenScenarioTest<any>>,\n];\n\nexport const gwtRunner =\n  <TContextBase = never>(\n    testFunc: TestFunction,\n    configureTestFunc?: ConfigureTestFunction<TContextBase>,\n  ) =>\n  <TContext>(name: string, gwtDefinition: GwtDefinition<TContext>): void => {\n    const testType = testTypes.find(({ test }) => test(gwtDefinition));\n\n    if (!testType) {\n      throw new Error(`Invalid GWT definition. Valid keys are [given,when,then] or [given,scenario].\nSupplied keys were [${Object.keys(gwtDefinition).join(\",\")}]`);\n    }\n\n    return testType.runner(testFunc, configureTestFunc, name, gwtDefinition);\n  };\n"],"mappings":"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"}