Skip to content

Commit 251a980

Browse files
Adding test utilities to create Value types (#2680)
1 parent 799bc96 commit 251a980

File tree

1 file changed

+116
-0
lines changed

1 file changed

+116
-0
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/**
2+
* @license
3+
* Copyright 2020 Google LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
import * as api from '../../src/protos/firestore_proto_api';
19+
import * as typeUtils from '../../src/util/types';
20+
import { Blob } from '../../src/api/blob';
21+
import { Timestamp } from '../../src/api/timestamp';
22+
import { GeoPoint } from '../../src/api/geo_point';
23+
import { DocumentKeyReference } from '../../src/api/user_data_converter';
24+
import { DatabaseId } from '../../src/core/database_info';
25+
import { DocumentKey } from '../../src/model/document_key';
26+
import { fail } from '../../src/util/assert';
27+
import { Dict, forEach } from '../../src/util/obj';
28+
29+
/** Test helper to create Firestore Value protos from JavaScript types. */
30+
31+
// TODO(mrschmidt): Move into UserDataConverter
32+
export function valueOf(
33+
input: unknown,
34+
useProto3Json: boolean = false
35+
): api.Value {
36+
if (input === null) {
37+
return { nullValue: 'NULL_VALUE' };
38+
} else if (typeof input === 'number') {
39+
if (typeUtils.isSafeInteger(input)) {
40+
return { integerValue: String(input) };
41+
} else {
42+
if (useProto3Json) {
43+
// Proto 3 let's us encode NaN and Infinity as string values as
44+
// expected by the backend. This is currently not checked by our unit
45+
// tests because they rely on protobuf.js.
46+
if (isNaN(input)) {
47+
return { doubleValue: 'NaN' } as {};
48+
} else if (input === Infinity) {
49+
return { doubleValue: 'Infinity' } as {};
50+
} else if (input === -Infinity) {
51+
return { doubleValue: '-Infinity' } as {};
52+
}
53+
}
54+
return { doubleValue: input };
55+
}
56+
} else if (typeof input === 'boolean') {
57+
return { booleanValue: input };
58+
} else if (typeof input === 'string') {
59+
return { stringValue: input };
60+
} else if (input instanceof Timestamp) {
61+
return {
62+
timestampValue: {
63+
seconds: String(input.seconds),
64+
nanos: input.nanoseconds
65+
}
66+
};
67+
} else if (input instanceof GeoPoint) {
68+
return {
69+
geoPointValue: {
70+
latitude: input.latitude,
71+
longitude: input.longitude
72+
}
73+
};
74+
} else if (input instanceof Blob) {
75+
if (useProto3Json) {
76+
return { bytesValue: input._byteString.toBase64() };
77+
} else {
78+
return { bytesValue: input._byteString.toUint8Array() };
79+
}
80+
} else if (input instanceof DocumentKeyReference) {
81+
return {
82+
referenceValue:
83+
'projects/project/databases/(default)/documents/' + input.key.path
84+
};
85+
} else if (Array.isArray(input)) {
86+
return {
87+
arrayValue: { values: input.map(el => valueOf(el, useProto3Json)) }
88+
};
89+
} else if (typeof input === 'object') {
90+
const result: api.Value = { mapValue: { fields: {} } };
91+
forEach(input as Dict<unknown>, (key: string, val: unknown) => {
92+
result.mapValue!.fields![key] = valueOf(val, useProto3Json);
93+
});
94+
return result;
95+
} else {
96+
fail(`Failed to serialize field: ${input}`);
97+
}
98+
}
99+
100+
/** Creates a MapValue from a list of key/value arguments. */
101+
export function mapOf(...entries: unknown[]): api.Value {
102+
const result: api.Value = { mapValue: { fields: {} } };
103+
for (let i = 0; i < entries.length; i += 2) {
104+
result.mapValue!.fields![entries[i] as string] = valueOf(
105+
entries[i + 1],
106+
/* useProto3Json= */ false
107+
);
108+
}
109+
return result;
110+
}
111+
112+
export function refValue(dbId: DatabaseId, key: DocumentKey): api.Value {
113+
return {
114+
referenceValue: `projects/${dbId.projectId}/databases/${dbId.database}/documents/${key.path}`
115+
};
116+
}

0 commit comments

Comments
 (0)