import { GraphQLFormattedError, DocumentNode } from 'graphql';
import { Observer, Observable } from 'rxjs';
import { ApolloLink, ErrorLike, ApolloCache } from '@apollo/client';
import { Apollo } from 'apollo-angular';
import * as i0 from '@angular/core';
import { InjectionToken } from '@angular/core';

type Operation = ApolloLink.Operation & {
    clientName: string;
};
declare class TestOperation<T = {
    [key: string]: any;
}> {
    readonly operation: Operation;
    private readonly observer;
    constructor(operation: Operation, observer: Observer<ApolloLink.Result<T>>);
    flush(result: ApolloLink.Result<T> | ErrorLike): void;
    complete(): void;
    flushData(data: T | null): void;
    networkError(error: ErrorLike): void;
    graphqlErrors(errors: GraphQLFormattedError[]): void;
}

type MatchOperationFn = (op: Operation) => boolean;
type MatchOperation = string | DocumentNode | Operation | MatchOperationFn;
/**
 * Controller to be injected into tests, that allows for mocking and flushing
 * of operations.
 *
 *
 */
declare abstract class ApolloTestingController {
    /**
     * Search for operations that match the given parameter, without any expectations.
     */
    abstract match(match: MatchOperation): TestOperation[];
    /**
     * Expect that a single operation has been made which matches the given URL, and return its
     * mock.
     *
     * If no such operation has been made, or more than one such operation has been made, fail with an
     * error message including the given operation description, if any.
     */
    abstract expectOne(operationName: string, description?: string): TestOperation;
    /**
     * Expect that a single operation has been made which matches the given parameters, and return
     * its mock.
     *
     * If no such operation has been made, or more than one such operation has been made, fail with an
     * error message including the given operation description, if any.
     */
    abstract expectOne(op: Operation, description?: string): TestOperation;
    /**
     * Expect that a single operation has been made which matches the given predicate function, and
     * return its mock.
     *
     * If no such operation has been made, or more than one such operation has been made, fail with an
     * error message including the given operation description, if any.
     */
    abstract expectOne(matchFn: MatchOperationFn, description?: string): TestOperation;
    /**
     * Expect that a single operation has been made which matches the given condition, and return
     * its mock.
     *
     * If no such operation has been made, or more than one such operation has been made, fail with an
     * error message including the given operation description, if any.
     */
    abstract expectOne(match: MatchOperation, description?: string): TestOperation;
    /**
     * Expect that no operations have been made which match the given URL.
     *
     * If a matching operation has been made, fail with an error message including the given
     * description, if any.
     */
    abstract expectNone(operationName: string, description?: string): void;
    /**
     * Expect that no operations have been made which match the given parameters.
     *
     * If a matching operation has been made, fail with an error message including the given
     * description, if any.
     */
    abstract expectNone(op: Operation, description?: string): void;
    /**
     * Expect that no operations have been made which match the given predicate function.
     *
     * If a matching operation has been made, fail with an error message including the given
     * description, if any.
     */
    abstract expectNone(matchFn: MatchOperationFn, description?: string): void;
    /**
     * Expect that no operations have been made which match the given condition.
     *
     * If a matching operation has been made, fail with an error message including the given
     * description, if any.
     */
    abstract expectNone(match: MatchOperation, description?: string): void;
    /**
     * Verify that no unmatched operations are outstanding.
     *
     * If any operations are outstanding, fail with an error message indicating which operations were not
     * handled.
     */
    abstract verify(): void;
}

/**
 * A testing backend for `Apollo`.
 *
 * `ApolloTestingBackend` works by keeping a list of all open operations.
 * As operations come in, they're added to the list. Users can assert that specific
 * operations were made and then flush them. In the end, a `verify()` method asserts
 * that no unexpected operations were made.
 */
declare class ApolloTestingBackend implements ApolloTestingController {
    /**
     * List of pending operations which have not yet been expected.
     */
    private open;
    /**
     * Handle an incoming operation by queueing it in the list of open operations.
     */
    handle(op: Operation): Observable<ApolloLink.Result>;
    /**
     * Helper function to search for operations in the list of open operations.
     */
    private _match;
    private matchOp;
    private compare;
    /**
     * Search for operations in the list of open operations, and return all that match
     * without asserting anything about the number of matches.
     */
    match(match: MatchOperation): TestOperation[];
    /**
     * Expect that a single outstanding request matches the given matcher, and return
     * it.
     *
     * operations returned through this API will no longer be in the list of open operations,
     * and thus will not match twice.
     */
    expectOne(match: MatchOperation, description?: string): TestOperation;
    /**
     * Expect that no outstanding operations match the given matcher, and throw an error
     * if any do.
     */
    expectNone(match: MatchOperation, description?: string): void;
    /**
     * Validate that there are no outstanding operations.
     */
    verify(): void;
    private isDocumentNode;
    private descriptionFromMatcher;
    static ɵfac: i0.ɵɵFactoryDeclaration<ApolloTestingBackend, never>;
    static ɵprov: i0.ɵɵInjectableDeclaration<ApolloTestingBackend>;
}

type NamedCaches = Record<string, ApolloCache | undefined | null>;
declare const APOLLO_TESTING_CACHE: InjectionToken<ApolloCache>;
declare const APOLLO_TESTING_NAMED_CACHE: InjectionToken<NamedCaches>;
declare class ApolloTestingModuleCore {
    constructor(apollo: Apollo, backend: ApolloTestingBackend, namedClients?: string[], cache?: ApolloCache, namedCaches?: NamedCaches);
    static ɵfac: i0.ɵɵFactoryDeclaration<ApolloTestingModuleCore, [null, null, { optional: true; }, { optional: true; }, { optional: true; }]>;
    static ɵmod: i0.ɵɵNgModuleDeclaration<ApolloTestingModuleCore, never, never, never>;
    static ɵinj: i0.ɵɵInjectorDeclaration<ApolloTestingModuleCore>;
}
declare class ApolloTestingModule {
    static withClients(names: string[]): {
        ngModule: typeof ApolloTestingModuleCore;
        providers: {
            provide: InjectionToken<string[]>;
            useValue: string[];
        }[];
    };
    static ɵfac: i0.ɵɵFactoryDeclaration<ApolloTestingModule, never>;
    static ɵmod: i0.ɵɵNgModuleDeclaration<ApolloTestingModule, never, [typeof ApolloTestingModuleCore], never>;
    static ɵinj: i0.ɵɵInjectorDeclaration<ApolloTestingModule>;
}

export { APOLLO_TESTING_CACHE, APOLLO_TESTING_NAMED_CACHE, ApolloTestingController, ApolloTestingModule, TestOperation };
export type { NamedCaches, Operation };
