Skip to content

Commit 7e948ab

Browse files
Adding test utilities to create Value types
This is a port of firebase/firebase-android-sdk#1158
1 parent 806f0a1 commit 7e948ab

File tree

1 file changed

+109
-0
lines changed

1 file changed

+109
-0
lines changed
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
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 { Timestamp } from '../../src/api/timestamp';
21+
import { GeoPoint } from '../../src/api/geo_point';
22+
import { Blob } from '../../src/api/blob';
23+
import { DocumentKeyReference } from '../../src/api/user_data_converter';
24+
import { fail } from '../../src/util/assert';
25+
import { DatabaseId } from '../../src/core/database_info';
26+
import { DocumentKey } from '../../src/model/document_key';
27+
28+
/** Test helper to create Firestore Value protos from JavaScript types. */
29+
30+
// TODO(mrschmidt): Move into UserDataConverter
31+
export function valueOf(input: unknown, useProto3Json: boolean = false): api.Value {
32+
if (input === null) {
33+
return { nullValue: 'NULL_VALUE' };
34+
} else if (typeof input === 'number') {
35+
if (typeUtils.isSafeInteger(input)) {
36+
return { integerValue: String(input) };
37+
} else {
38+
if (useProto3Json) {
39+
// Proto 3 let's us encode NaN and Infinity as string values as
40+
// expected by the backend. This is currently not checked by our unit
41+
// tests because they rely on protobuf.js.
42+
if (isNaN(doubleValue)) {
43+
return { doubleValue: 'NaN' } as {};
44+
} else if (doubleValue === Infinity) {
45+
return { doubleValue: 'Infinity' } as {};
46+
} else if (doubleValue === -Infinity) {
47+
return { doubleValue: '-Infinity' } as {};
48+
}
49+
}
50+
return { doubleValue: input };
51+
}
52+
} else if (typeof input === 'boolean') {
53+
return { booleanValue: input };
54+
} else if (typeof input === 'string') {
55+
return { stringValue: input };
56+
} else if (input instanceof Timestamp) {
57+
return {
58+
timestampValue: {
59+
seconds: String(input.seconds),
60+
nanos: input.nanoseconds
61+
}
62+
};
63+
} else if (input instanceof GeoPoint) {
64+
return {
65+
geoPointValue: {
66+
latitude: input.latitude,
67+
nanos: input.longitude
68+
}
69+
};
70+
} else if (input instanceof Blob) {
71+
if (useProto3Json) {
72+
return { bytesValue: input._byteString.toBase64() };
73+
} else {
74+
return { bytesValue: input._byteString.toUint8Array() };
75+
}
76+
} else if (input instanceof DocumentKeyReference) {
77+
return {
78+
referenceValue:
79+
'projects/project/databases/(default)/documents/' + input.ref.path
80+
};
81+
} else if (Array.isArray(input)) {
82+
return {
83+
arrayValue: { values: input.map(el => valueOf(el, useProto3Json)) }
84+
};
85+
} else if (typeof input == 'object') {
86+
const result: api.Value = { mapValue: { fields: {} } };
87+
for (const key of input) {
88+
result[key] = valueOf(input[key], useProto3Json);
89+
}
90+
return result;
91+
} else {
92+
fail(`Failed to serialize field: ${input}`);
93+
}
94+
}
95+
96+
/** Creates a MapValue from a list of key/value arguments. */
97+
export function mapOf(...entries: unknown[]): api.Value {
98+
const result: api.Value = { mapValue: { fields: {} } };
99+
for (let i = 0; i < entries.length; i += 2) {
100+
result[entries[i]] = valueOf(entries[i + 1], /* useProto3Json= */ false);
101+
}
102+
return result;
103+
}
104+
105+
export function refValue(dbId: DatabaseId, key: DocumentKey): api.Value {
106+
return {
107+
referenceValue: `projects/${dbId.projectId}/databases/${dbId.databaseId}/documents/${key.path}`
108+
};
109+
}

0 commit comments

Comments
 (0)