{"version":3,"file":"signalstory-testing.mjs","sources":["../../../packages/signalstory/testing/src/helper.ts","../../../packages/signalstory/testing/src/public_api.ts","../../../packages/signalstory/testing/src/signalstory-testing.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * Following methods are intendet to simplify testing with stores. You can achieve everything the regular way.\n * The philosophy is, that setup logic (arrange) can be completely done by each test case independently and that\n * the setup is as readable and easy to follow as possible. Note, that you could still share setup logic using those methods.\n *\n * As every store can have its own injector (store.config.injector) you can create a separate injection context\n * for every test case. This is especially handy if you are testing effect or query objects as you don't necessarily\n * need to use Testbed or jest.mock (or any other mocking lib) to setup a mocked DI Context + mocked dependencies.\n * But you could also use this for independent services, register them in the stores injector and using the method getFromStoreInjector to get an instance\n */\nimport { Injector, ProviderToken, StaticProvider } from '@angular/core';\nimport { Store } from 'signalstory';\n\n/**\n * Interface for specifying providers in the mocked Dependency Injection (DI) context.\n */\nexport interface InjectionContextConfiguration {\n  /**\n   * Returns  array of {@link StaticProvider} objects representing the providers\n   * included in the mocked DI context.\n   */\n  collectProviders(): StaticProvider[];\n\n  /**\n   * Adds a provider to the configuration.\n   * This would represent a provider instance inside `TestBed.configureTestingModule({providers})`\n   * @param provider - The provider to be added to the configuration.\n   * @returns The current {@link InjectionContextConfiguration} instance for method chaining.\n   */\n  add(provider: StaticProvider): InjectionContextConfiguration;\n\n  /**\n   * Adds a regular provider to the configuration based on the provided class type.\n   * This Corresponds to `<StaticProvider>{ provide: MyService }` without specifying further dependencies or factories\n   * @param classType - The class type for the provider.\n   * @returns The current {@link InjectionContextConfiguration} instance for method chaining.\n   */\n  addRegular<T>(classType: ProviderToken<T>): InjectionContextConfiguration;\n\n  /**\n   * Adds an existing instance as a provided value to the di providers based on the provided class type.\n   * Injecting the provided classType in this context would always return the provided instance.\n   * NOTE: This is not the same as useExisting in the angular di provide configuration\n   * @param classType - The class type for the provider.\n   * @param instance - The existing instance to be used as the provider.\n   * @returns The current {@link InjectionContextConfiguration} instance for method chaining.\n   *\n   * @example\n   * ```typescript\n   * const myInstance = new MyService();\n   * myInjectionContextConfiguration.addExisting(MyService, myInstance);\n   * ```\n   */\n  addExisting<T>(\n    classType: ProviderToken<T>,\n    instance: T\n  ): InjectionContextConfiguration;\n\n  /**\n   * Adds a mocked provider to the configuration based on the provided class type.\n   * This technique is intendet to mock specific methods or properties of a given service, not the whole functionality.\n   * Injection will bypass the constructor and using the configureInstance mocks for properties and methods can be applied\n   *\n   * @param classType - The class type for the provider.\n   * @param configureInstance - A function to configure the mocked instance.\n   * @returns The current {@link InjectionContextConfiguration} instance for method chaining.\n   */\n  addMocked<T>(\n    classType: ProviderToken<T>,\n    configureInstance: (obj: T) => void\n  ): InjectionContextConfiguration;\n}\n\n/**\n * Configures a mocked Dependency Injection (DI) context for a specific store, allowing\n * the injection of mocked dependencies during testing. This has no sideefffects for other injection contexts (e.g. root)\n * Only the injection context for the given store is created and configured using this method\n *\n * @param store - The SignalStory store for which the injection context is being configured.\n * @param configure - A callback function that receives an {@link InjectionContextConfiguration} object\n *   for specifying providers in the injection context.\n *\n * @example\n * ```typescript\n * configureInjectionContext(myStore, (config) => {\n *   config.addRegular(MyService);\n *   config.addMocked(OtherService, (instance) => {\n *     instance.methodToMock = jest.fn(() => 'mocked result');\n *   });\n * });\n * ```\n */\nexport function configureInjectionContext(\n  store: Store<any>,\n  configure: (options: InjectionContextConfiguration) => void\n): void {\n  const options = new DefaultInjectionContextConfiguration();\n  configure(options);\n  (store.config.injector as any) = Injector.create({\n    providers: options.collectProviders(),\n  });\n}\n\n/**\n * Retrieves an instance of a specified type from the store's injector.\n *\n * @param store - The SignalStory store from which to retrieve the instance.\n * @param classType - The class type for the instance to be retrieved.\n * @returns The instance of the specified type if found; otherwise, `undefined`.\n */\nexport function getFromStoreInjector<T>(\n  store: Store<any>,\n  classType: ProviderToken<T>\n): T | undefined {\n  return store.config.injector?.get(classType);\n}\n\n/**\n * Default implementation of the {@link InjectionContextConfiguration} interface.\n *\n * @public\n */\nexport class DefaultInjectionContextConfiguration\n  implements InjectionContextConfiguration\n{\n  private providers: StaticProvider[] = [];\n\n  collectProviders(): StaticProvider[] {\n    return this.providers;\n  }\n\n  add(provider: StaticProvider): InjectionContextConfiguration {\n    this.providers.push(provider);\n    return this;\n  }\n\n  addRegular<T>(classType: ProviderToken<T>): InjectionContextConfiguration {\n    this.providers.push(<StaticProvider>{ provide: classType });\n    return this;\n  }\n\n  addExisting<T>(\n    classType: ProviderToken<T>,\n    instance: T\n  ): InjectionContextConfiguration {\n    this.providers.push({\n      provide: classType,\n      useFactory: () => instance,\n    });\n    return this;\n  }\n\n  addMocked<T>(\n    classType: ProviderToken<T>,\n    configureInstance: (obj: T) => void\n  ): InjectionContextConfiguration {\n    this.providers.push({\n      provide: classType,\n      useFactory: () => {\n        const instance = Object.create(classType);\n        configureInstance(instance);\n        return instance;\n      },\n    });\n    return this;\n  }\n}\n","/*\n * Public API Surface of signalstory/testing\n */\n\nexport { configureInjectionContext, getFromStoreInjector } from './helper';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":";;AAAA;AACA;;;;;;;;;AASG;AAgEH;;;;;;;;;;;;;;;;;;AAkBG;AACG,SAAU,yBAAyB,CACvC,KAAiB,EACjB,SAA2D,EAAA;AAE3D,IAAA,MAAM,OAAO,GAAG,IAAI,oCAAoC,EAAE;IAC1D,SAAS,CAAC,OAAO,CAAC;IACjB,KAAK,CAAC,MAAM,CAAC,QAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC;AAC/C,QAAA,SAAS,EAAE,OAAO,CAAC,gBAAgB,EAAE;AACtC,KAAA,CAAC;AACJ;AAEA;;;;;;AAMG;AACG,SAAU,oBAAoB,CAClC,KAAiB,EACjB,SAA2B,EAAA;IAE3B,OAAO,KAAK,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,SAAS,CAAC;AAC9C;AAEA;;;;AAIG;MACU,oCAAoC,CAAA;AAAjD,IAAA,WAAA,GAAA;QAGU,IAAA,CAAA,SAAS,GAAqB,EAAE;IAyC1C;IAvCE,gBAAgB,GAAA;QACd,OAAO,IAAI,CAAC,SAAS;IACvB;AAEA,IAAA,GAAG,CAAC,QAAwB,EAAA;AAC1B,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC;AAC7B,QAAA,OAAO,IAAI;IACb;AAEA,IAAA,UAAU,CAAI,SAA2B,EAAA;QACvC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAiB,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;AAC3D,QAAA,OAAO,IAAI;IACb;IAEA,WAAW,CACT,SAA2B,EAC3B,QAAW,EAAA;AAEX,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;AAClB,YAAA,OAAO,EAAE,SAAS;AAClB,YAAA,UAAU,EAAE,MAAM,QAAQ;AAC3B,SAAA,CAAC;AACF,QAAA,OAAO,IAAI;IACb;IAEA,SAAS,CACP,SAA2B,EAC3B,iBAAmC,EAAA;AAEnC,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;AAClB,YAAA,OAAO,EAAE,SAAS;YAClB,UAAU,EAAE,MAAK;gBACf,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC;gBACzC,iBAAiB,CAAC,QAAQ,CAAC;AAC3B,gBAAA,OAAO,QAAQ;YACjB,CAAC;AACF,SAAA,CAAC;AACF,QAAA,OAAO,IAAI;IACb;AACD;;ACvKD;;AAEG;;ACFH;;AAEG;;;;"}