UNPKG

@firebase/firestore

Version:

The Cloud Firestore component of the Firebase JS SDK.

324 lines (323 loc) • 11.9 kB
/** * @license * Copyright 2017 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import { IndexConfiguration } from '../../../src/api/index_configuration'; import { ListenOptions } from '../../../src/core/event_manager'; import { Query } from '../../../src/core/query'; import { TargetId } from '../../../src/core/types'; import { FieldIndex } from '../../../src/model/field_index'; import { JsonObject } from '../../../src/model/object_value'; import * as api from '../../../src/protos/firestore_proto_api'; import { TestSnapshotVersion } from '../../util/helpers'; import { ActiveTargetMap } from './spec_builder'; interface DocumentOptions { hasLocalMutations?: boolean; hasCommittedMutations?: boolean; } export declare function parseQuery(querySpec: string | SpecQuery): Query; /** * Runs a spec test case. * * The spec consists of an array of individual steps to run in sequence. */ export declare function runSpec(name: string, tags: string[], usePersistence: boolean, config: SpecConfig, steps: SpecStep[]): Promise<void>; /** Specifies initial configuration information for the test. */ export interface SpecConfig { /** A boolean to enable / disable eager GC for memory persistence. */ useEagerGCForMemory: boolean; /** The number of active clients for this test run. */ numClients: number; /** * The maximum number of concurrently-active listens for limbo resolutions. * This value must be strictly greater than zero, or undefined to use the * default value. */ maxConcurrentLimboResolutions?: number; } /** * The cumulative list of actions run against Persistence. This is used by the * Spec tests to fail specific types of actions. */ export type PersistenceAction = 'Get next mutation batch' | 'read document' | 'Allocate target' | 'Release target' | 'Execute query' | 'Handle user change' | 'Locally write mutations' | 'Acknowledge batch' | 'Reject batch' | 'Get highest unacknowledged batch id' | 'Get last stream token' | 'Set last stream token' | 'Get last remote snapshot version' | 'Set last remote snapshot version' | 'Apply remote event' | 'notifyLocalViewChanges' | 'Remote document keys' | 'Collect garbage' | 'maybeGarbageCollectMultiClientState' | 'Lookup mutation documents' | 'Get target data' | 'Get new document changes' | 'Synchronize last document change read time' | 'updateClientMetadataAndTryBecomePrimary' | 'getHighestListenSequenceNumber'; /** * Union type for each step. The step consists of exactly one `field` * set and optionally expected events in the `expect` field. */ export interface SpecStep { /** The index of the local client for multi-client spec tests. */ clientIndex?: number; /** Listen to a new query (must be unique) */ userListen?: SpecUserListen; /** Unlisten from a query (must be listened to) */ userUnlisten?: SpecUserUnlisten; /** Perform a user initiated set */ userSet?: SpecUserSet; /** Perform a user initiated patch */ userPatch?: SpecUserPatch; /** Perform a user initiated delete */ userDelete?: SpecUserDelete; /** Listens to a SnapshotsInSync event. */ addSnapshotsInSyncListener?: true; /** Unlistens from a SnapshotsInSync event. */ removeSnapshotsInSyncListener?: true; /** Loads a bundle from a string. */ loadBundle?: string; /** Ack for a query in the watch stream */ watchAck?: SpecWatchAck; /** Marks the query results as current */ watchCurrent?: SpecWatchCurrent; /** Reset the results of a query */ watchReset?: SpecWatchReset; /** Ack for remove or rejection of a query in the watch stream */ watchRemove?: SpecWatchRemove; /** Document update in the watch stream */ watchEntity?: SpecWatchEntity; /** Existence filter in the watch stream */ watchFilter?: SpecWatchFilter; /** Snapshot ("NO_CHANGE") event in the watch stream. */ watchSnapshot?: SpecWatchSnapshot; /** A step that the watch stream restarts. */ watchStreamClose?: SpecWatchStreamClose; /** Ack the last write */ writeAck?: SpecWriteAck; /** Fail a write */ failWrite?: SpecWriteFailure; /** Add a new `waitForPendingWrites` listener. */ waitForPendingWrites?: true; /** Fails the listed database actions. */ failDatabase?: false | PersistenceAction[]; /** * Set Index Configuration */ setIndexConfiguration?: string | IndexConfiguration; /** * Run a queued timer task (without waiting for the delay to expire). See * TimerId enum definition for possible values). */ runTimer?: string; /** * Process all events currently enqueued in the AsyncQueue. */ drainQueue?: true; /** Enable or disable RemoteStore's network connection. */ enableNetwork?: boolean; /** Clears the persistent storage in IndexedDB. */ clearPersistence?: true; /** Changes the metadata state of a client instance. */ applyClientState?: SpecClientState; /** Change to a new active user (specified by uid or null for anonymous). */ changeUser?: string | null; /** Trigger a GC event with given cache threshold in bytes. */ triggerLruGC?: number; /** * Restarts the SyncEngine from scratch, except re-uses persistence and auth * components. This allows you to queue writes, get documents into cache, * etc. and then simulate an app restart. */ restart?: true; /** Shut down the client and close it network connection. */ shutdown?: true; /** * Optional list of expected events. * If not provided, the test will fail if the step causes events to be raised. */ expectedSnapshotEvents?: SnapshotEvent[]; /** * Optional dictionary of expected states. */ expectedState?: StateExpectation; /** * Optional expected number of onSnapshotsInSync callbacks to be called. * If not provided, the test will fail if the step causes events to be raised. */ expectedSnapshotsInSyncEvents?: number; /** * Optional expected number of waitForPendingWrite callbacks to be called. * If not provided, the test will fail if the step causes events to be raised. */ expectedWaitForPendingWritesEvents?: number; } export interface SpecUserListen { targetId: TargetId; query: string | SpecQuery; options?: ListenOptions; } /** [<target-id>, <query-path>] */ export type SpecUserUnlisten = [TargetId, string | SpecQuery]; /** [<key>, <value>] */ export type SpecUserSet = [string, JsonObject<unknown>]; /** [<key>, <patches>] */ export type SpecUserPatch = [string, JsonObject<unknown>]; /** key */ export type SpecUserDelete = string; /** [<target-id>, ...] */ export type SpecWatchAck = TargetId[]; /** [[<target-id>, ...], <resume-token>] */ export type SpecWatchCurrent = [TargetId[], string]; /** [<target-id>, ...] */ export type SpecWatchReset = TargetId[]; export interface SpecError { code: number; message: string; } export interface SpecWatchRemove { targetIds: TargetId[]; cause?: SpecError; } export interface SpecWatchSnapshot { version: TestSnapshotVersion; targetIds: TargetId[]; resumeToken?: string; } export interface SpecWatchStreamClose { error: SpecError; runBackoffTimer: boolean; } export interface SpecWriteAck { /** The version the backend uses to ack the write. */ version: TestSnapshotVersion; /** * Whether we should keep the write in our internal queue. This should only * be set to 'true' if the client ignores the write (e.g. a secondary client * which ignores write acknowledgments). * * Defaults to false. */ keepInQueue?: boolean; } export interface SpecWriteFailure { /** The error the backend uses to fail the write. */ error: SpecError; /** * Whether we should keep the write in our internal queue. This should be set * to 'true' for transient errors or if the client ignores the failure * (e.g. a secondary client which ignores write rejections). * * Defaults to false. */ keepInQueue?: boolean; } export interface SpecWatchEntity { key?: string; /** [<key>, <version>, <value>] */ doc?: SpecDocument; /** [<key>, <version>, <value>][] */ docs?: SpecDocument[]; /** [<target-id>, ...] */ targets?: TargetId[]; /** [<target-id>, ...] */ removedTargets?: TargetId[]; } export interface SpecClientState { /** The visibility state of the browser tab running the client. */ visibility?: DocumentVisibilityState; /** Whether this tab should try to forcefully become primary. */ primary?: true; } /** * The filter is based of a list of keys to match in the existence filter */ export interface SpecWatchFilter { targetIds: TargetId[]; keys: string[]; bloomFilter?: api.BloomFilter; } export type SpecLimitType = 'LimitToFirst' | 'LimitToLast'; /** * [field, op, value] * Op must be the `name` of an `Operator`. */ export type SpecQueryFilter = [string, string, unknown]; /** * [field, direction] * Direction can be 'asc' or 'desc'. */ export type SpecQueryOrderBy = [string, string]; /** * A representation of a query. */ export interface SpecQuery { path: string; collectionGroup?: string; limit?: number; limitType?: SpecLimitType; filters?: SpecQueryFilter[]; orderBys?: SpecQueryOrderBy[]; } /** * [<key>, <version>, <value>, <doc-options> (optional), ...] * Represents a document. <value> is null for deleted documents. * Doc options are: * 'local': document has local modifications */ export interface SpecDocument { key: string; version: TestSnapshotVersion; createTime: TestSnapshotVersion; value: JsonObject<unknown> | null; options?: DocumentOptions; } export interface SnapshotEvent { query: SpecQuery; errorCode?: number; fromCache?: boolean; hasPendingWrites?: boolean; added?: SpecDocument[]; removed?: SpecDocument[]; modified?: SpecDocument[]; metadata?: SpecDocument[]; } export interface StateExpectation { /** Number of outstanding writes in the datastore queue. */ numOutstandingWrites?: number; /** Number of clients currently marked active. Used in multi-client tests. */ numActiveClients?: number; /** Number of requests sent to the write stream. */ writeStreamRequestCount?: number; /** Number of requests sent to the watch stream. */ watchStreamRequestCount?: number; /** * Current documents in limbo that have an active target. * Verified in each step until overwritten. */ activeLimboDocs?: string[]; /** * Current documents in limbo that are enqueued and therefore do not have an * active target. * Verified in each step until overwritten. */ enqueuedLimboDocs?: string[]; /** * Whether the instance holds the primary lease. Used in multi-client tests. */ isPrimary?: boolean; /** Whether the client is shutdown. */ isShutdown?: boolean; /** * Current expected active targets. Verified in each step until overwritten. */ activeTargets?: ActiveTargetMap; /** * Expected set of callbacks for previously written docs. */ userCallbacks?: { acknowledgedDocs: string[]; rejectedDocs: string[]; }; /** Indexes */ indexes?: FieldIndex[]; } export {};