Skip to content

Commit 50418ef

Browse files
committed
Add docs
1 parent 1753549 commit 50418ef

File tree

2 files changed

+54
-37
lines changed

2 files changed

+54
-37
lines changed

packages/firestore/src/util/testing_hooks.ts

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,20 @@
2020
* internal state and events during integration tests. Do not use this class
2121
* except for testing purposes.
2222
*
23-
* There are two ways to retrieve an instance of this class:
23+
* There are two ways to retrieve the global singleton instance of this class:
2424
* 1. The `instance` property, which returns null if the global singleton
25-
* instance has not been created.
25+
* instance has not been created. Use this property if the caller should
26+
* "do nothing" if there are no testing hooks registered, such as when
27+
* delivering an event to notify registered callbacks.
2628
* 2. The `getOrCreateInstance()` method, which creates the global singleton
27-
* instance if it has not been created.
28-
*
29-
* Use the former method if the caller should "do nothing" there are no testing
30-
* hooks registered. Use the latter if the instance is needed to, for example,
31-
* register a testing hook.
29+
* instance if it has not been created. Use this method if the instance is
30+
* needed to, for example, register a callback.
3231
*
3332
* @internal
3433
*/
3534
export class TestingHooks {
36-
private readonly onExistenceFilterMismatchCallbacks: Array<
35+
private readonly onExistenceFilterMismatchCallbacks: Map<
36+
Symbol,
3737
(arg: unknown) => void
3838
> = [];
3939

@@ -61,30 +61,30 @@ export class TestingHooks {
6161
/**
6262
* Registers a callback to be notified when an existence filter mismatch
6363
* occurs in the Watch listen stream.
64-
* @param callback the callback to invoke upon existence filter mismatch.
64+
*
65+
* The relative order in which callbacks are notified is unspecified; do not
66+
* rely on any particular ordering.
67+
*
68+
* @param callback the callback to invoke upon existence filter mismatch. The
69+
* type of the argument to this callback is intentionally declared as
70+
* `unknown`, rather than something more specific, to discourage its use
71+
* unless you really, really know what you are doing. If you know what you are
72+
* doing then you know the type and how to interpret it.
73+
*
6574
* @return a function that, when called, unregisters the given callback; only
6675
* the first invocation of the returned function does anything; all subsequent
6776
* invocations do nothing.
6877
*/
6978
onExistenceFilterMismatch(callback: (arg: unknown) => void): () => void {
70-
this.onExistenceFilterMismatchCallbacks.push(callback);
71-
72-
let removed = false;
73-
return () => {
74-
if (!removed) {
75-
const index = this.onExistenceFilterMismatchCallbacks.indexOf(callback);
76-
this.onExistenceFilterMismatchCallbacks.splice(index, 1);
77-
removed = true;
78-
}
79-
};
79+
const key = Symbol();
80+
this.onExistenceFilterMismatchCallbacks.set(key, callback);
81+
return () => this.onExistenceFilterMismatchCallbacks.delete(key);
8082
}
8183

8284
/**
8385
* Invokes all currently-registered `onExistenceFilterMismatch` callbacks.
84-
* @param arg the argument to specify to the callbacks; the type of this
85-
* argument is intentionally declared as `unknown` to discourage casual use;
86-
* the specific use of this callback in tests knows the structure of the
87-
* given argument and will use it accordingly.
86+
* @param arg the argument to specify to the callbacks; see the documentation
87+
* for `onExistenceFilterMismatch()` for details.
8888
*/
8989
notifyOnExistenceFilterMismatch(arg: unknown): void {
9090
this.onExistenceFilterMismatchCallbacks.forEach(callback => callback(arg));

packages/firestore/test/integration/util/testing_hooks_util.ts

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@
1818
import { _TestingHooks as TestingHooks } from './firebase_export';
1919

2020
/**
21-
* Captures all existence filter mismatches that occur during the execution of
22-
* the given code block.
23-
* @param callback The callback to invoke, during whose invocation the existence
24-
* filter mismatches will be captured.
21+
* Captures all existence filter mismatches in the Watch 'Listen' stream that
22+
* occur during the execution of the given code block.
23+
* @param callback The callback to invoke; during the invocation of this
24+
* callback all existence filter mismatches will be captured.
2525
* @return the captured existence filter mismatches.
2626
*/
2727
export async function captureExistenceFilterMismatches(
@@ -32,20 +32,24 @@ export async function captureExistenceFilterMismatches(
3232
results.push(
3333
existenceFilterMismatchInfoFromRaw(arg as RawExistenceFilterMismatchInfo)
3434
);
35+
3536
const unregister =
3637
TestingHooks.getOrCreateInstance().onExistenceFilterMismatch(
3738
callbackWrapper
3839
);
40+
3941
try {
4042
await callback();
4143
} finally {
4244
unregister();
4345
}
46+
4447
return results;
4548
}
4649

4750
/**
48-
* The shape of the object specified to `onExistenceFilterMismatch` callbacks.
51+
* The shape of the object specified to
52+
* `TestingUtils.onExistenceFilterMismatch()` callbacks.
4953
*/
5054
interface RawExistenceFilterMismatchInfo {
5155
actualCount: number;
@@ -66,38 +70,51 @@ interface RawExistenceFilterMismatchInfo {
6670
}
6771

6872
/**
69-
* Information about an existence filter mismatch.
73+
* Information about an existence filter mismatch, capturing during an
74+
* invocation of `captureExistenceFilterMismatches()`.
7075
*/
7176
export interface ExistenceFilterMismatchInfo {
77+
/** The number of documents that match the query in the local cache. */
7278
actualCount: number;
79+
/** The number of documents that matched the query on the server. */
7380
expectedCount: number;
74-
bloomFilter?: ExistenceFilterBloomFilter;
81+
/** The bloom filter provided by the server, or null if not provided. */
82+
bloomFilter: ExistenceFilterBloomFilter | null;
7583
}
7684

7785
/**
7886
* Information about a bloom filter in an existence filter.
7987
*/
8088
export interface ExistenceFilterBloomFilter {
89+
/** Whether the bloom filter was able to be used to avert a full requery. */
8190
applied: boolean;
91+
/** The number of hash functions used in the bloom filter. */
8292
hashCount: number;
93+
/** The number of bytes in the bloom filter. */
8394
bitmapLength: number;
95+
/** The number of bits of "padding" in the last byte of the bloom filter. */
8496
padding: number;
8597
}
8698

99+
/**
100+
* Creates a `ExistenceFilterMismatchInfo` object from the raw object given
101+
* by `TestingUtils`.
102+
*/
87103
function existenceFilterMismatchInfoFromRaw(
88104
raw: RawExistenceFilterMismatchInfo
89105
): ExistenceFilterMismatchInfo {
90-
const result: ExistenceFilterMismatchInfo = {
106+
return {
91107
actualCount: raw.actualCount,
92-
expectedCount: raw.change.existenceFilter.count
108+
expectedCount: raw.change.existenceFilter.count,
109+
bloomFilter: bloomFilterFromRawExistenceFilterMismatchInfo(raw)
93110
};
94-
const bloomFilter = bloomFilterFromRawExistenceFilterMismatchInfo(raw);
95-
if (bloomFilter) {
96-
result.bloomFilter = bloomFilter;
97-
}
98-
return result;
99111
}
100112

113+
/**
114+
* Creates an `ExistenceFilterBloomFilter` object from the raw object given
115+
* by `TestingUtils`, returning null if the given object does not defined a
116+
* bloom filter.
117+
*/
101118
function bloomFilterFromRawExistenceFilterMismatchInfo(
102119
raw: RawExistenceFilterMismatchInfo
103120
): null | ExistenceFilterBloomFilter {

0 commit comments

Comments
 (0)