@firebase/firestore
Version:
The Cloud Firestore component of the Firebase JS SDK.
324 lines (323 loc) • 11.9 kB
TypeScript
/**
* @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 {};