{"version":3,"file":"testing-library-angular-zoneless.mjs","sources":["../../../../projects/testing-library/zoneless/src/public_api.ts","../../../../projects/testing-library/zoneless/src/testing-library-angular-zoneless.ts"],"sourcesContent":["import { Component, type Type, type Binding, type Provider, type EnvironmentProviders } from '@angular/core';\nimport { ComponentFixture, TestBed } from '@angular/core/testing';\nimport {\n  getQueriesForElement,\n  prettyDOM,\n  type BoundFunctions,\n  type PrettyDOMOptions,\n  type queries,\n  type Queries,\n} from '@testing-library/dom';\n\nexport type RenderResultQueries<Q extends Queries = typeof queries> = BoundFunctions<Q>;\n\nexport interface RenderResult<ComponentType, WrapperType = ComponentType> extends RenderResultQueries {\n  /**\n   * @description\n   * The containing DOM node of your rendered Angular Component.\n   * This is a regular DOM node, so you can call container.querySelector etc. to inspect the children.\n   */\n  container: HTMLElement;\n\n  /**\n   * @description\n   * Prints out the component's DOM with syntax highlighting.\n   * Accepts an optional parameter, to print out a specific DOM node.\n   *\n   * @param\n   * element: The to be printed HTML element, if not provided it will log the whole component's DOM\n   */\n  debug: (\n    element?: Element | Document | (Element | Document)[],\n    maxLength?: number,\n    options?: PrettyDOMOptions,\n  ) => void;\n\n  /**\n   * @description\n   * The Angular `ComponentFixture` of the component or the wrapper.\n   * If a template is provided, it will be the fixture of the wrapper.\n   *\n   * For more info see https://angular.io/api/core/testing/ComponentFixture\n   */\n  fixture: ComponentFixture<WrapperType>;\n}\n\nexport interface RenderOptions<Q extends Queries = typeof queries> {\n  /**\n   * @description\n   * Queries to bind. Overrides the default set from DOM Testing Library unless merged.\n   *\n   * @default\n   * undefined\n   *\n   * @example\n   * import * as customQueries from 'custom-queries'\n   * import { queries } from '@testing-library/angular'\n   *\n   * await render(AppComponent, {\n   *  queries: { ...queries, ...customQueries }\n   * })\n   */\n  queries?: Q;\n\n  /**\n   * @description\n   * Callback to configure the testbed before the compilation.\n   *\n   * @default\n   * () => {}\n   *\n   * @example\n   * await render(AppComponent, {\n   *  configureTestBed: (testBed) => { }\n   * })\n   */\n  configureTestBed?: (testbed: TestBed) => void;\n\n  /**\n   * @description\n   * Determines whether `fixture.detectChanges()` is called after the component is rendered.\n   *\n   * @default\n   * true\n   *\n   * @example\n   * await render(AppComponent, {\n   *  skipDetectChanges: false\n   * })\n   */\n  skipDetectChanges?: boolean;\n\n  /**\n   * @description\n   * Determines whether `fixture.whenStable()` is called after the component is rendered.\n   *\n   * @default\n   * true\n   *\n   * @example\n   * await render(AppComponent, {\n   *  waitForStableOnRender: false\n   * })\n   */\n  waitForStableOnRender?: boolean;\n\n  /**\n   * @description\n   * An array of providers to be added to the testbed.\n   */\n  providers?: (Provider | EnvironmentProviders)[];\n}\n\nexport interface RenderComponentOptions<Q extends Queries = typeof queries> extends RenderOptions<Q> {\n  /**\n   * @description\n   * An array of bindings to apply to the component using Angular's native bindings API.\n   * This provides a more direct way to bind inputs and outputs compared to the `inputs` and `on` options.\n   *\n   * @default\n   * []\n   *\n   * @example\n   * import { inputBinding, outputBinding, twoWayBinding } from '@angular/core';\n   * import { signal } from '@angular/core';\n   *\n   * await render(AppComponent, {\n   *   bindings: [\n   *     inputBinding('value', () => 'test value'),\n   *     outputBinding('click', (event) => console.log(event)),\n   *     twoWayBinding('name', signal('initial value'))\n   *   ]\n   * })\n   */\n  bindings?: Binding[];\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface RenderTemplateOptions<WrapperType, Properties extends object = {}, Q extends Queries = typeof queries>\n  extends RenderOptions<Q> {\n  /**\n   * @description\n   * An Angular component to wrap the component in.\n   * The template will be overridden with the `template` option.\n   * NOTE: A standalone component cannot be used as a wrapper.\n   *\n   * @default\n   * `WrapperComponent`, a basic empty component.\n   *\n   * @example\n   * await render(`<div spoiler message='SPOILER'></div>`, {\n   *  declarations: [SpoilerDirective]\n   *  wrapper: CustomWrapperComponent\n   * })\n   */\n  wrapper?: Type<WrapperType>;\n\n  /**\n   * @description\n   * An object of properties to set on the wrapper component instance.\n   * This allows you to set input properties on the wrapper component, which can be useful for testing content projection or other wrapper-related functionality.\n   *\n   * @default\n   * undefined\n   *\n   * @example\n   * await render(`<div>{{ message }}</div>`, {\n   *  wrapperProperties: { message: 'Hello World' }\n   * })\n   */\n  wrapperProperties?: Partial<Properties>;\n\n  /**\n   * @description\n   * An array of modules to be imported into the testbed.\n   */\n  imports?: any[];\n}\n\nexport async function render<ComponentType>(\n  component: Type<ComponentType>,\n  renderOptions?: RenderComponentOptions,\n): Promise<RenderResult<ComponentType, ComponentType>>;\nexport async function render<WrapperType = WrapperComponent>(\n  template: string,\n  renderOptions?: RenderTemplateOptions<WrapperType>,\n): Promise<RenderResult<WrapperType>>;\nexport async function render<ComponentType, WrapperType = ComponentType>(\n  componentOrTemplate: Type<ComponentType> | string,\n  renderOptions: RenderComponentOptions | RenderTemplateOptions<WrapperType> = {},\n): Promise<RenderResult<ComponentType, ComponentType | WrapperType>> {\n  TestBed.configureTestingModule({\n    declarations: [WrapperComponent],\n    imports: 'imports' in renderOptions ? renderOptions.imports : [],\n    providers: renderOptions.providers ?? [],\n  });\n\n  renderOptions.configureTestBed?.(TestBed);\n  await TestBed.compileComponents();\n\n  const fixture =\n    typeof componentOrTemplate === 'string'\n      ? await createWrapperFixture(componentOrTemplate, (renderOptions ?? {}) as RenderTemplateOptions<WrapperType>)\n      : await createComponentFixture(componentOrTemplate, (renderOptions ?? {}) as RenderComponentOptions);\n\n  if (renderOptions.skipDetectChanges !== true) {\n    fixture.detectChanges();\n  }\n\n  if (renderOptions.waitForStableOnRender === true) {\n    await fixture.whenStable();\n  }\n\n  return {\n    fixture,\n    container: fixture.nativeElement,\n    debug: (element = fixture.nativeElement, maxLength?: number, options?: PrettyDOMOptions) => {\n      if (Array.isArray(element)) {\n        for (const e of element) {\n          console.log(prettyDOM(e, maxLength, options));\n        }\n      } else {\n        console.log(prettyDOM(element, maxLength, options));\n      }\n    },\n    ...getQueriesForElement(fixture.nativeElement, renderOptions?.queries),\n  };\n}\n\nasync function createComponentFixture<SutType>(\n  sut: Type<SutType>,\n  options: RenderComponentOptions,\n): Promise<ComponentFixture<SutType>> {\n  return TestBed.createComponent(sut, { bindings: options.bindings || [] });\n}\n\nasync function createWrapperFixture<WrapperType>(\n  sut: string,\n  options: RenderTemplateOptions<WrapperType>,\n): Promise<ComponentFixture<WrapperType>> {\n  const wrapper = options.wrapper ?? (WrapperComponent as Type<WrapperType>);\n  TestBed.overrideTemplate(wrapper, sut);\n  const fixture = TestBed.createComponent(wrapper);\n  setWrapperProperties(fixture, options.wrapperProperties);\n  return fixture;\n}\n\nfunction setWrapperProperties<SutType>(\n  fixture: ComponentFixture<SutType>,\n  wrapperProperties: RenderTemplateOptions<SutType, any>['wrapperProperties'] = {},\n) {\n  for (const key of Object.keys(wrapperProperties)) {\n    const descriptor = Object.getOwnPropertyDescriptor((fixture.componentInstance as any).constructor.prototype, key);\n    let _value = wrapperProperties[key];\n    const defaultGetter = () => _value;\n    const extendedSetter = (value: any) => {\n      _value = value;\n      descriptor?.set?.call(fixture.componentInstance, _value);\n      fixture.changeDetectorRef.detectChanges();\n    };\n\n    Object.defineProperty(fixture.componentInstance, key, {\n      get: descriptor?.get || defaultGetter,\n      set: extendedSetter,\n      // Allow the property to be defined again later.\n      // This happens when the component properties are updated after initial render.\n      // For Jest this is `true` by default, for Karma and a real browser the default is `false`\n      configurable: true,\n    });\n\n    descriptor?.set?.call(fixture.componentInstance, _value);\n  }\n  return fixture;\n}\n\n@Component({ selector: 'atl-wrapper-component', template: '', standalone: false })\nclass WrapperComponent {}\n\nexport * from '@testing-library/dom';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public_api';\n"],"names":[],"mappings":"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"}