import * as i0 from '@angular/core';
import { Type, Provider, EnvironmentProviders, Binding } from '@angular/core';
import { TestBed, ComponentFixture } from '@angular/core/testing';
import { Queries, queries, BoundFunctions, PrettyDOMOptions } from '@testing-library/dom';
export * from '@testing-library/dom';

type RenderResultQueries<Q extends Queries = typeof queries> = BoundFunctions<Q>;
interface RenderResult<ComponentType, WrapperType = ComponentType> extends RenderResultQueries {
    /**
     * @description
     * The containing DOM node of your rendered Angular Component.
     * This is a regular DOM node, so you can call container.querySelector etc. to inspect the children.
     */
    container: HTMLElement;
    /**
     * @description
     * Prints out the component's DOM with syntax highlighting.
     * Accepts an optional parameter, to print out a specific DOM node.
     *
     * @param
     * element: The to be printed HTML element, if not provided it will log the whole component's DOM
     */
    debug: (element?: Element | Document | (Element | Document)[], maxLength?: number, options?: PrettyDOMOptions) => void;
    /**
     * @description
     * The Angular `ComponentFixture` of the component or the wrapper.
     * If a template is provided, it will be the fixture of the wrapper.
     *
     * For more info see https://angular.io/api/core/testing/ComponentFixture
     */
    fixture: ComponentFixture<WrapperType>;
}
interface RenderOptions<Q extends Queries = typeof queries> {
    /**
     * @description
     * Queries to bind. Overrides the default set from DOM Testing Library unless merged.
     *
     * @default
     * undefined
     *
     * @example
     * import * as customQueries from 'custom-queries'
     * import { queries } from '@testing-library/angular'
     *
     * await render(AppComponent, {
     *  queries: { ...queries, ...customQueries }
     * })
     */
    queries?: Q;
    /**
     * @description
     * Callback to configure the testbed before the compilation.
     *
     * @default
     * () => {}
     *
     * @example
     * await render(AppComponent, {
     *  configureTestBed: (testBed) => { }
     * })
     */
    configureTestBed?: (testbed: TestBed) => void;
    /**
     * @description
     * Determines whether `fixture.detectChanges()` is called after the component is rendered.
     *
     * @default
     * true
     *
     * @example
     * await render(AppComponent, {
     *  skipDetectChanges: false
     * })
     */
    skipDetectChanges?: boolean;
    /**
     * @description
     * Determines whether `fixture.whenStable()` is called after the component is rendered.
     *
     * @default
     * true
     *
     * @example
     * await render(AppComponent, {
     *  waitForStableOnRender: false
     * })
     */
    waitForStableOnRender?: boolean;
    /**
     * @description
     * An array of providers to be added to the testbed.
     */
    providers?: (Provider | EnvironmentProviders)[];
}
interface ImportOverride {
    /** The import to replace (matched by identity) */
    replace: Type<unknown>;
    /** The replacement import to use instead */
    with: Type<unknown> | unknown[];
}
interface RenderComponentOptions<Q extends Queries = typeof queries> extends RenderOptions<Q> {
    /**
     * @description
     * An array of bindings to apply to the component using Angular's native bindings API.
     * This provides a more direct way to bind inputs and outputs compared to the `inputs` and `on` options.
     *
     * @default
     * []
     *
     * @example
     * import { inputBinding, outputBinding, twoWayBinding } from '@angular/core';
     * import { signal } from '@angular/core';
     *
     * await render(AppComponent, {
     *   bindings: [
     *     inputBinding('value', () => 'test value'),
     *     outputBinding('click', (event) => console.log(event)),
     *     twoWayBinding('name', signal('initial value'))
     *   ]
     * })
     */
    bindings?: Binding[];
    /**
     * @description
     * Replace specific imports on a standalone component. This is useful for mocking dependencies of the component under test.
     *
     * @default
     * undefined
     *
     * @example
     * await render(AppComponent, {
     *   importOverrides: [
     *     { replace: RealChildComponent, with: MockChildComponent }
     *   ]
     * })
     */
    importOverrides?: ImportOverride[];
}
interface RenderTemplateOptions<WrapperType, Properties extends object = {}, Q extends Queries = typeof queries> extends RenderOptions<Q> {
    /**
     * @description
     * An Angular component to wrap the component in.
     * The template will be overridden with the `template` option.
     * NOTE: A standalone component cannot be used as a wrapper.
     *
     * @default
     * `WrapperComponent`, a basic empty component.
     *
     * @example
     * await render(`<div spoiler message='SPOILER'></div>`, {
     *  declarations: [SpoilerDirective]
     *  wrapper: CustomWrapperComponent
     * })
     */
    wrapper?: Type<WrapperType>;
    /**
     * @description
     * An object of properties to set on the wrapper component instance.
     * This allows you to set input properties on the wrapper component, which can be useful for testing content projection or other wrapper-related functionality.
     *
     * @default
     * undefined
     *
     * @example
     * await render(`<div>{{ message }}</div>`, {
     *  wrapperProperties: { message: 'Hello World' }
     * })
     */
    wrapperProperties?: Partial<Properties>;
    /**
     * @description
     * An array of modules to be imported into the testbed.
     */
    imports?: any[];
}
declare function render<ComponentType>(component: Type<ComponentType>, renderOptions?: RenderComponentOptions): Promise<RenderResult<ComponentType, ComponentType>>;
declare function render<WrapperType = WrapperComponent>(template: string, renderOptions?: RenderTemplateOptions<WrapperType>): Promise<RenderResult<WrapperType>>;
declare class WrapperComponent {
    static ɵfac: i0.ɵɵFactoryDeclaration<WrapperComponent, never>;
    static ɵcmp: i0.ɵɵComponentDeclaration<WrapperComponent, "atl-wrapper-component", never, {}, {}, never, never, false, never>;
}

export { render };
export type { ImportOverride, RenderComponentOptions, RenderOptions, RenderResult, RenderResultQueries, RenderTemplateOptions };
