@firebase/database-compat 0.1.1-2021823172527 → 0.1.2-canary.0b3ca78eb
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -8
- package/dist/database-compat/src/index.d.ts +0 -9
- package/dist/database-compat/src/index.node.d.ts +0 -53
- package/dist/database-compat/src/index.standalone.d.ts +52 -0
- package/dist/index.esm2017.js +5 -6
- package/dist/index.esm2017.js.map +1 -1
- package/dist/index.esm5.js +2 -3
- package/dist/index.esm5.js.map +1 -1
- package/dist/index.js +10 -77
- package/dist/index.js.map +1 -1
- package/dist/index.standalone.js +15150 -0
- package/dist/index.standalone.js.map +1 -0
- package/dist/node-esm/database-compat/src/api/Database.d.ts +72 -0
- package/dist/node-esm/database-compat/src/api/Reference.d.ts +201 -0
- package/{karma.conf.js → dist/node-esm/database-compat/src/api/TransactionResult.d.ts} +26 -34
- package/dist/node-esm/database-compat/src/api/internal.d.ts +39 -0
- package/dist/node-esm/database-compat/src/api/onDisconnect.d.ts +27 -0
- package/dist/node-esm/database-compat/src/index.d.ts +32 -0
- package/dist/node-esm/database-compat/src/index.node.d.ts +14 -0
- package/dist/node-esm/database-compat/src/index.standalone.d.ts +52 -0
- package/{src/util/util.ts → dist/node-esm/database-compat/src/util/util.d.ts} +17 -25
- package/dist/node-esm/database-compat/src/util/validation.d.ts +18 -0
- package/{src/api/TransactionResult.ts → dist/node-esm/database-compat/test/browser/crawler_support.test.d.ts} +17 -34
- package/dist/node-esm/database-compat/test/database.test.d.ts +17 -0
- package/dist/node-esm/database-compat/test/datasnapshot.test.d.ts +17 -0
- package/dist/node-esm/database-compat/test/helpers/events.d.ts +34 -0
- package/dist/node-esm/database-compat/test/helpers/util.d.ts +42 -0
- package/dist/node-esm/database-compat/test/info.test.d.ts +17 -0
- package/dist/node-esm/database-compat/test/order.test.d.ts +17 -0
- package/dist/node-esm/database-compat/test/order_by.test.d.ts +17 -0
- package/dist/node-esm/database-compat/test/promise.test.d.ts +17 -0
- package/dist/node-esm/database-compat/test/query.test.d.ts +17 -0
- package/dist/node-esm/database-compat/test/servervalues.test.d.ts +17 -0
- package/dist/node-esm/database-compat/test/transaction.test.d.ts +17 -0
- package/dist/node-esm/index.js +868 -0
- package/dist/node-esm/index.js.map +1 -0
- package/dist/node-esm/package.json +1 -0
- package/package.json +34 -9
- package/standalone/package.json +7 -0
- package/.eslintrc.js +0 -64
- package/rollup.config.js +0 -125
- package/src/api/Database.ts +0 -123
- package/src/api/Reference.ts +0 -790
- package/src/api/internal.ts +0 -91
- package/src/api/onDisconnect.ts +0 -112
- package/src/index.node.ts +0 -142
- package/src/index.ts +0 -88
- package/src/util/validation.ts +0 -59
- package/test/browser/crawler_support.test.ts +0 -206
- package/test/database.test.ts +0 -306
- package/test/datasnapshot.test.ts +0 -249
- package/test/helpers/events.ts +0 -258
- package/test/helpers/util.ts +0 -177
- package/test/info.test.ts +0 -222
- package/test/order.test.ts +0 -592
- package/test/order_by.test.ts +0 -530
- package/test/promise.test.ts +0 -261
- package/test/query.test.ts +0 -4670
- package/test/servervalues.test.ts +0 -152
- package/test/transaction.test.ts +0 -1534
- package/tsconfig.json +0 -11
package/test/helpers/events.ts
DELETED
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2017 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 { pathParent } from '../../../database/src/core/util/Path';
|
|
19
|
-
import { Reference } from '../../src/api/Reference';
|
|
20
|
-
|
|
21
|
-
import { TEST_PROJECT } from './util';
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* A set of functions to clean up event handlers.
|
|
25
|
-
*/
|
|
26
|
-
export let eventCleanupHandlers = [];
|
|
27
|
-
|
|
28
|
-
/** Clean up outstanding event handlers */
|
|
29
|
-
export function eventCleanup() {
|
|
30
|
-
for (let i = 0; i < eventCleanupHandlers.length; ++i) {
|
|
31
|
-
eventCleanupHandlers[i]();
|
|
32
|
-
}
|
|
33
|
-
eventCleanupHandlers = [];
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* The path component of the firebaseRef url
|
|
38
|
-
*/
|
|
39
|
-
function rawPath(firebaseRef: Reference) {
|
|
40
|
-
return firebaseRef.toString().replace(TEST_PROJECT.databaseURL, '');
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Creates a struct which waits for many events.
|
|
45
|
-
* @param pathAndEvents - an array of tuples of [Firebase, [event type strings]]
|
|
46
|
-
*/
|
|
47
|
-
export function eventTestHelper(pathAndEvents, helperName?) {
|
|
48
|
-
let resolve, reject;
|
|
49
|
-
let promise = new Promise((pResolve, pReject) => {
|
|
50
|
-
resolve = pResolve;
|
|
51
|
-
reject = pReject;
|
|
52
|
-
});
|
|
53
|
-
let resolveInit, rejectInit;
|
|
54
|
-
const initPromise = new Promise((pResolve, pReject) => {
|
|
55
|
-
resolveInit = pResolve;
|
|
56
|
-
rejectInit = pReject;
|
|
57
|
-
});
|
|
58
|
-
const expectedPathAndEvents = [];
|
|
59
|
-
const actualPathAndEvents = [];
|
|
60
|
-
const pathEventListeners = {};
|
|
61
|
-
let initializationEvents = 0;
|
|
62
|
-
|
|
63
|
-
helperName = helperName ? helperName + ': ' : '';
|
|
64
|
-
|
|
65
|
-
// Listen on all of the required paths, with a callback function that just
|
|
66
|
-
// appends to actualPathAndEvents.
|
|
67
|
-
const makeEventCallback = function (type) {
|
|
68
|
-
return function (snap) {
|
|
69
|
-
// Get the ref of where the snapshot came from.
|
|
70
|
-
const ref = type === 'value' ? snap.ref : pathParent(this);
|
|
71
|
-
|
|
72
|
-
actualPathAndEvents.push([rawPath(ref), [type, snap.key]]);
|
|
73
|
-
|
|
74
|
-
if (!pathEventListeners[ref].initialized) {
|
|
75
|
-
initializationEvents++;
|
|
76
|
-
if (type === 'value') {
|
|
77
|
-
pathEventListeners[ref].initialized = true;
|
|
78
|
-
}
|
|
79
|
-
} else {
|
|
80
|
-
// Call waiter here to trigger exceptions when the event is fired, rather than later when the
|
|
81
|
-
// test framework is calling the waiter... makes for easier debugging.
|
|
82
|
-
waiter();
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// We want to trigger the promise resolution if valid, so try to call waiter as events
|
|
86
|
-
// are coming back.
|
|
87
|
-
try {
|
|
88
|
-
if (waiter()) {
|
|
89
|
-
resolve();
|
|
90
|
-
}
|
|
91
|
-
} catch (e) {}
|
|
92
|
-
};
|
|
93
|
-
};
|
|
94
|
-
|
|
95
|
-
// returns a function which indicates whether the events have been received
|
|
96
|
-
// in the correct order. If anything is wrong (too many events or
|
|
97
|
-
// incorrect events, we throw). Else we return false, indicating we should
|
|
98
|
-
// keep waiting.
|
|
99
|
-
const waiter = function () {
|
|
100
|
-
const pathAndEventToString = function (pathAndEvent) {
|
|
101
|
-
return (
|
|
102
|
-
'{path: ' +
|
|
103
|
-
pathAndEvent[0] +
|
|
104
|
-
', event:[' +
|
|
105
|
-
pathAndEvent[1][0] +
|
|
106
|
-
', ' +
|
|
107
|
-
pathAndEvent[1][1] +
|
|
108
|
-
']}'
|
|
109
|
-
);
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
let i = 0;
|
|
113
|
-
while (i < expectedPathAndEvents.length && i < actualPathAndEvents.length) {
|
|
114
|
-
const expected = expectedPathAndEvents[i];
|
|
115
|
-
const actual = actualPathAndEvents[i];
|
|
116
|
-
|
|
117
|
-
if (
|
|
118
|
-
expected[0] !== actual[0] ||
|
|
119
|
-
expected[1][0] !== actual[1][0] ||
|
|
120
|
-
expected[1][1] !== actual[1][1]
|
|
121
|
-
) {
|
|
122
|
-
throw (
|
|
123
|
-
helperName +
|
|
124
|
-
'Event ' +
|
|
125
|
-
i +
|
|
126
|
-
' incorrect. Expected: ' +
|
|
127
|
-
pathAndEventToString(expected) +
|
|
128
|
-
' Actual: ' +
|
|
129
|
-
pathAndEventToString(actual)
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
i++;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
if (expectedPathAndEvents.length < actualPathAndEvents.length) {
|
|
136
|
-
throw (
|
|
137
|
-
helperName +
|
|
138
|
-
"Extra event detected '" +
|
|
139
|
-
pathAndEventToString(actualPathAndEvents[i]) +
|
|
140
|
-
"'."
|
|
141
|
-
);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// If we haven't thrown and both arrays are the same length, then we're
|
|
145
|
-
// done.
|
|
146
|
-
return expectedPathAndEvents.length === actualPathAndEvents.length;
|
|
147
|
-
};
|
|
148
|
-
|
|
149
|
-
const listenOnPath = function (path) {
|
|
150
|
-
const valueCB = makeEventCallback('value');
|
|
151
|
-
const addedCB = makeEventCallback('child_added');
|
|
152
|
-
const removedCB = makeEventCallback('child_removed');
|
|
153
|
-
const movedCB = makeEventCallback('child_moved');
|
|
154
|
-
const changedCB = makeEventCallback('child_changed');
|
|
155
|
-
path.on('child_removed', removedCB);
|
|
156
|
-
path.on('child_added', addedCB);
|
|
157
|
-
path.on('child_moved', movedCB);
|
|
158
|
-
path.on('child_changed', changedCB);
|
|
159
|
-
path.on('value', valueCB);
|
|
160
|
-
return function () {
|
|
161
|
-
path.off('child_removed', removedCB);
|
|
162
|
-
path.off('child_added', addedCB);
|
|
163
|
-
path.off('child_moved', movedCB);
|
|
164
|
-
path.off('child_changed', changedCB);
|
|
165
|
-
path.off('value', valueCB);
|
|
166
|
-
};
|
|
167
|
-
};
|
|
168
|
-
|
|
169
|
-
const addExpectedEvents = function (pathAndEvents) {
|
|
170
|
-
const pathsToListenOn = [];
|
|
171
|
-
for (let i = 0; i < pathAndEvents.length; i++) {
|
|
172
|
-
const pathAndEvent = pathAndEvents[i];
|
|
173
|
-
|
|
174
|
-
const path = pathAndEvent[0];
|
|
175
|
-
//var event = pathAndEvent[1];
|
|
176
|
-
|
|
177
|
-
pathsToListenOn.push(path);
|
|
178
|
-
|
|
179
|
-
pathAndEvent[0] = rawPath(path);
|
|
180
|
-
|
|
181
|
-
if (pathAndEvent[1][0] === 'value') {
|
|
182
|
-
pathAndEvent[1][1] = path.key;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
expectedPathAndEvents.push(pathAndEvent);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// There's some trickiness with event order depending on the order you attach event callbacks:
|
|
189
|
-
//
|
|
190
|
-
// When you listen on a/b/c, a/b, and a, we dedupe that to just listening on a. But if you do it in that
|
|
191
|
-
// order, we'll send "listen a/b/c, listen a/b, unlisten a/b/c, listen a, unlisten a/b" which will result in you
|
|
192
|
-
// getting events something like "a/b/c: value, a/b: child_added c, a: child_added b, a/b: value, a: value"
|
|
193
|
-
//
|
|
194
|
-
// BUT, if all of the listens happen before you are connected to firebase (e.g. this is the first test you're
|
|
195
|
-
// running), the dedupe will have taken affect and we'll just send "listen a", which results in:
|
|
196
|
-
// "a/b/c: value, a/b: child_added c, a/b: value, a: child_added b, a: value"
|
|
197
|
-
// Notice the 3rd and 4th events are swapped.
|
|
198
|
-
// To mitigate this, we re-ordeer your event registrations and do them in order of shortest path to longest.
|
|
199
|
-
|
|
200
|
-
pathsToListenOn.sort((a, b) => {
|
|
201
|
-
return a.toString().length - b.toString().length;
|
|
202
|
-
});
|
|
203
|
-
for (let i = 0; i < pathsToListenOn.length; i++) {
|
|
204
|
-
const path = pathsToListenOn[i];
|
|
205
|
-
if (!pathEventListeners[path.toString()]) {
|
|
206
|
-
pathEventListeners[path.toString()] = {};
|
|
207
|
-
pathEventListeners[path.toString()].initialized = false;
|
|
208
|
-
pathEventListeners[path.toString()].unlisten = listenOnPath(path);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
promise = new Promise((pResolve, pReject) => {
|
|
213
|
-
resolve = pResolve;
|
|
214
|
-
reject = pReject;
|
|
215
|
-
});
|
|
216
|
-
};
|
|
217
|
-
|
|
218
|
-
addExpectedEvents(pathAndEvents);
|
|
219
|
-
|
|
220
|
-
const watchesInitializedWaiter = function () {
|
|
221
|
-
for (const path in pathEventListeners) {
|
|
222
|
-
if (!pathEventListeners[path].initialized) {
|
|
223
|
-
return false;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// Remove any initialization events.
|
|
228
|
-
actualPathAndEvents.splice(
|
|
229
|
-
actualPathAndEvents.length - initializationEvents,
|
|
230
|
-
initializationEvents
|
|
231
|
-
);
|
|
232
|
-
initializationEvents = 0;
|
|
233
|
-
|
|
234
|
-
resolveInit();
|
|
235
|
-
return true;
|
|
236
|
-
};
|
|
237
|
-
|
|
238
|
-
const unregister = function () {
|
|
239
|
-
for (const path in pathEventListeners) {
|
|
240
|
-
if (pathEventListeners.hasOwnProperty(path)) {
|
|
241
|
-
pathEventListeners[path].unlisten();
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
};
|
|
245
|
-
|
|
246
|
-
eventCleanupHandlers.push(unregister);
|
|
247
|
-
return {
|
|
248
|
-
promise,
|
|
249
|
-
initPromise,
|
|
250
|
-
waiter,
|
|
251
|
-
watchesInitializedWaiter,
|
|
252
|
-
unregister,
|
|
253
|
-
|
|
254
|
-
addExpectedEvents(moreEvents) {
|
|
255
|
-
addExpectedEvents(moreEvents);
|
|
256
|
-
}
|
|
257
|
-
};
|
|
258
|
-
}
|
package/test/helpers/util.ts
DELETED
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2017 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
|
-
declare let MozWebSocket: WebSocket;
|
|
19
|
-
|
|
20
|
-
import '../../src/index';
|
|
21
|
-
|
|
22
|
-
import firebase from '@firebase/app-compat';
|
|
23
|
-
import { _FirebaseNamespace } from '@firebase/app-types/private';
|
|
24
|
-
import { Component, ComponentType } from '@firebase/component';
|
|
25
|
-
|
|
26
|
-
import { Path } from '../../../database/src/core/util/Path';
|
|
27
|
-
import { Query, Reference } from '../../src/api/Reference';
|
|
28
|
-
|
|
29
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
30
|
-
export const TEST_PROJECT = require('../../../../config/project.json');
|
|
31
|
-
|
|
32
|
-
const EMULATOR_PORT = process.env.RTDB_EMULATOR_PORT;
|
|
33
|
-
const EMULATOR_NAMESPACE = process.env.RTDB_EMULATOR_NAMESPACE;
|
|
34
|
-
|
|
35
|
-
const USE_EMULATOR = !!EMULATOR_PORT;
|
|
36
|
-
|
|
37
|
-
/*
|
|
38
|
-
* When running against the emulator, the hostname will be "localhost" rather
|
|
39
|
-
* than "<namespace>.firebaseio.com", and so we need to append the namespace
|
|
40
|
-
* as a query param.
|
|
41
|
-
*
|
|
42
|
-
* Some tests look for hostname only while others need full url (with the
|
|
43
|
-
* namespace provided as a query param), hence below declarations.
|
|
44
|
-
*/
|
|
45
|
-
export const DATABASE_ADDRESS = USE_EMULATOR
|
|
46
|
-
? `http://localhost:${EMULATOR_PORT}`
|
|
47
|
-
: TEST_PROJECT.databaseURL;
|
|
48
|
-
|
|
49
|
-
export const DATABASE_URL = USE_EMULATOR
|
|
50
|
-
? `${DATABASE_ADDRESS}?ns=${EMULATOR_NAMESPACE}`
|
|
51
|
-
: TEST_PROJECT.databaseURL;
|
|
52
|
-
|
|
53
|
-
console.log(`USE_EMULATOR: ${USE_EMULATOR}. DATABASE_URL: ${DATABASE_URL}.`);
|
|
54
|
-
|
|
55
|
-
let numDatabases = 0;
|
|
56
|
-
|
|
57
|
-
// mock authentication functions for testing
|
|
58
|
-
(firebase as unknown as _FirebaseNamespace).INTERNAL.registerComponent(
|
|
59
|
-
new Component(
|
|
60
|
-
'auth-internal',
|
|
61
|
-
() => ({
|
|
62
|
-
getToken: async () => null,
|
|
63
|
-
addAuthTokenListener: () => {},
|
|
64
|
-
removeAuthTokenListener: () => {},
|
|
65
|
-
getUid: () => null
|
|
66
|
-
}),
|
|
67
|
-
ComponentType.PRIVATE
|
|
68
|
-
)
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
export function createTestApp() {
|
|
72
|
-
const app = firebase.initializeApp({ databaseURL: DATABASE_URL });
|
|
73
|
-
return app;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Gets or creates a root node to the test namespace. All calls sharing the
|
|
78
|
-
* value of opt_i will share an app context.
|
|
79
|
-
*/
|
|
80
|
-
export function getRootNode(i = 0, ref?: string) {
|
|
81
|
-
if (i + 1 > numDatabases) {
|
|
82
|
-
numDatabases = i + 1;
|
|
83
|
-
}
|
|
84
|
-
let app;
|
|
85
|
-
try {
|
|
86
|
-
app = firebase.app('TEST-' + i);
|
|
87
|
-
} catch (e) {
|
|
88
|
-
app = firebase.initializeApp({ databaseURL: DATABASE_URL }, 'TEST-' + i);
|
|
89
|
-
}
|
|
90
|
-
const db = app.database();
|
|
91
|
-
return db.ref(ref);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Create multiple refs to the same top level
|
|
96
|
-
* push key - each on it's own Firebase.Context.
|
|
97
|
-
*/
|
|
98
|
-
export function getRandomNode(numNodes?): Reference | Reference[] {
|
|
99
|
-
if (numNodes === undefined) {
|
|
100
|
-
return getRandomNode(1)[0] as Reference;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
let child;
|
|
104
|
-
const nodeList = [];
|
|
105
|
-
for (let i = 0; i < numNodes; i++) {
|
|
106
|
-
const ref = getRootNode(i);
|
|
107
|
-
if (child === undefined) {
|
|
108
|
-
child = ref.push().key;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
nodeList[i] = ref.child(child);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return nodeList as Reference[];
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export function getQueryValue(query: Query) {
|
|
118
|
-
return query.once('value').then(snap => snap.val());
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
export function pause(milliseconds: number) {
|
|
122
|
-
return new Promise<void>(resolve => {
|
|
123
|
-
setTimeout(() => resolve(), milliseconds);
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export function getPath(query: Query) {
|
|
128
|
-
return query.toString().replace(DATABASE_ADDRESS, '');
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
export function shuffle(arr, randFn = Math.random) {
|
|
132
|
-
for (let i = arr.length - 1; i > 0; i--) {
|
|
133
|
-
const j = Math.floor(randFn() * (i + 1));
|
|
134
|
-
const tmp = arr[i];
|
|
135
|
-
arr[i] = arr[j];
|
|
136
|
-
arr[j] = tmp;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
let freshRepoId = 1;
|
|
141
|
-
const activeFreshApps = [];
|
|
142
|
-
|
|
143
|
-
export function getFreshRepo(path: Path) {
|
|
144
|
-
const app = firebase.initializeApp(
|
|
145
|
-
{ databaseURL: DATABASE_URL },
|
|
146
|
-
'ISOLATED_REPO_' + freshRepoId++
|
|
147
|
-
);
|
|
148
|
-
activeFreshApps.push(app);
|
|
149
|
-
return (app as any).database().ref(path.toString());
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export function getFreshRepoFromReference(ref) {
|
|
153
|
-
const host = ref.root.toString();
|
|
154
|
-
const path = ref.toString().replace(host, '');
|
|
155
|
-
return getFreshRepo(path);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
// Little helpers to get the currently cached snapshot / value.
|
|
159
|
-
export function getSnap(path) {
|
|
160
|
-
let snap;
|
|
161
|
-
const callback = function (snapshot) {
|
|
162
|
-
snap = snapshot;
|
|
163
|
-
};
|
|
164
|
-
path.once('value', callback);
|
|
165
|
-
return snap;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
export function getVal(path) {
|
|
169
|
-
const snap = getSnap(path);
|
|
170
|
-
return snap ? snap.val() : undefined;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
export function canCreateExtraConnections() {
|
|
174
|
-
return (
|
|
175
|
-
typeof MozWebSocket !== 'undefined' || typeof WebSocket !== 'undefined'
|
|
176
|
-
);
|
|
177
|
-
}
|
package/test/info.test.ts
DELETED
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright 2017 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 { expect } from 'chai';
|
|
19
|
-
|
|
20
|
-
import { EventAccumulator } from '../../database/test/helpers/EventAccumulator';
|
|
21
|
-
import { Reference } from '../src/api/Reference';
|
|
22
|
-
|
|
23
|
-
import {
|
|
24
|
-
getFreshRepo,
|
|
25
|
-
getRootNode,
|
|
26
|
-
getRandomNode,
|
|
27
|
-
getPath
|
|
28
|
-
} from './helpers/util';
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* We have a test that depends on leveraging two properly
|
|
32
|
-
* configured Firebase instances. we are skiping the test
|
|
33
|
-
* but I want to leave the test here for when we can refactor
|
|
34
|
-
* to remove the prod firebase dependency.
|
|
35
|
-
*/
|
|
36
|
-
declare const runs;
|
|
37
|
-
declare const waitsFor;
|
|
38
|
-
declare const TEST_ALT_NAMESPACE;
|
|
39
|
-
declare const TEST_NAMESPACE;
|
|
40
|
-
|
|
41
|
-
describe('.info Tests', function () {
|
|
42
|
-
this.timeout(3000);
|
|
43
|
-
it('Can get a reference to .info nodes.', () => {
|
|
44
|
-
const f = getRootNode() as Reference;
|
|
45
|
-
expect(getPath(f.child('.info'))).to.equal('/.info');
|
|
46
|
-
expect(getPath(f.child('.info/foo'))).to.equal('/.info/foo');
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
it("Can't write to .info", () => {
|
|
50
|
-
const f = (getRootNode() as Reference).child('.info');
|
|
51
|
-
expect(() => {
|
|
52
|
-
f.set('hi');
|
|
53
|
-
}).to.throw;
|
|
54
|
-
expect(() => {
|
|
55
|
-
f.setWithPriority('hi', 5);
|
|
56
|
-
}).to.throw;
|
|
57
|
-
expect(() => {
|
|
58
|
-
f.setPriority('hi');
|
|
59
|
-
}).to.throw;
|
|
60
|
-
expect(() => {
|
|
61
|
-
f.transaction(() => {});
|
|
62
|
-
}).to.throw;
|
|
63
|
-
expect(() => {
|
|
64
|
-
f.push();
|
|
65
|
-
}).to.throw;
|
|
66
|
-
expect(() => {
|
|
67
|
-
f.remove();
|
|
68
|
-
}).to.throw;
|
|
69
|
-
|
|
70
|
-
expect(() => {
|
|
71
|
-
f.child('test').set('hi');
|
|
72
|
-
}).to.throw;
|
|
73
|
-
const f2 = f.child('foo/baz');
|
|
74
|
-
expect(() => {
|
|
75
|
-
f2.set('hi');
|
|
76
|
-
}).to.throw;
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it('Can watch .info/connected.', () => {
|
|
80
|
-
return new Promise<void>(resolve => {
|
|
81
|
-
const f = (getRandomNode() as Reference).root;
|
|
82
|
-
f.child('.info/connected').on('value', snap => {
|
|
83
|
-
if (snap.val() === true) {
|
|
84
|
-
resolve();
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
it('.info/connected correctly goes to false when disconnected.', async () => {
|
|
91
|
-
const f = (getRandomNode() as Reference).root;
|
|
92
|
-
let everConnected = false;
|
|
93
|
-
let connectHistory = '';
|
|
94
|
-
|
|
95
|
-
const ea = new EventAccumulator(() => everConnected);
|
|
96
|
-
f.child('.info/connected').on('value', snap => {
|
|
97
|
-
if (snap.val() === true) {
|
|
98
|
-
everConnected = true;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
if (everConnected) {
|
|
102
|
-
connectHistory += snap.val() + ',';
|
|
103
|
-
}
|
|
104
|
-
ea.addEvent();
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
await ea.promise;
|
|
108
|
-
|
|
109
|
-
ea.reset(() => connectHistory);
|
|
110
|
-
f.database.goOffline();
|
|
111
|
-
f.database.goOnline();
|
|
112
|
-
|
|
113
|
-
return ea.promise;
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
it('.info/serverTimeOffset', async () => {
|
|
117
|
-
const ref = getRootNode() as Reference;
|
|
118
|
-
|
|
119
|
-
// make sure push works
|
|
120
|
-
const child = ref.push();
|
|
121
|
-
|
|
122
|
-
const offsets = [];
|
|
123
|
-
|
|
124
|
-
const ea = new EventAccumulator(() => offsets.length === 1);
|
|
125
|
-
|
|
126
|
-
ref.child('.info/serverTimeOffset').on('value', snap => {
|
|
127
|
-
offsets.push(snap.val());
|
|
128
|
-
ea.addEvent();
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
await ea.promise;
|
|
132
|
-
|
|
133
|
-
expect(typeof offsets[0]).to.equal('number');
|
|
134
|
-
expect(offsets[0]).not.to.be.greaterThan(0);
|
|
135
|
-
|
|
136
|
-
// Make sure push still works
|
|
137
|
-
ref.push();
|
|
138
|
-
ref.child('.info/serverTimeOffset').off();
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
it.skip('database.goOffline() / database.goOnline() connection management', () => {
|
|
142
|
-
// NOTE: getFreshRepo() no longer takes a hostname, so this test needs to be reworked.
|
|
143
|
-
// Need to figure out how to re-enable this test.
|
|
144
|
-
const ref = getFreshRepo(TEST_NAMESPACE);
|
|
145
|
-
const refAlt = getFreshRepo(TEST_ALT_NAMESPACE);
|
|
146
|
-
let ready;
|
|
147
|
-
|
|
148
|
-
// Wait until we're connected to both Firebases
|
|
149
|
-
runs(() => {
|
|
150
|
-
ready = 0;
|
|
151
|
-
const eventHandler = function (snap) {
|
|
152
|
-
if (snap.val() === true) {
|
|
153
|
-
snap.ref.off();
|
|
154
|
-
ready += 1;
|
|
155
|
-
}
|
|
156
|
-
};
|
|
157
|
-
ref.child('.info/connected').on('value', eventHandler);
|
|
158
|
-
refAlt.child('.info/connected').on('value', eventHandler);
|
|
159
|
-
});
|
|
160
|
-
waitsFor(() => {
|
|
161
|
-
return ready === 2;
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
runs(() => {
|
|
165
|
-
ref.database.goOffline();
|
|
166
|
-
refAlt.database.goOffline();
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
// Ensure we're disconnected from both Firebases
|
|
170
|
-
runs(() => {
|
|
171
|
-
ready = 0;
|
|
172
|
-
const eventHandler = function (snap) {
|
|
173
|
-
expect(snap.val() === false);
|
|
174
|
-
ready += 1;
|
|
175
|
-
};
|
|
176
|
-
ref.child('.info/connected').once('value', eventHandler);
|
|
177
|
-
refAlt.child('.info/connected').once('value', eventHandler);
|
|
178
|
-
});
|
|
179
|
-
waitsFor(() => {
|
|
180
|
-
return ready === 2;
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
// Ensure that we don't automatically reconnect upon Reference creation
|
|
184
|
-
runs(() => {
|
|
185
|
-
ready = 0;
|
|
186
|
-
const refDup = ref.database.ref();
|
|
187
|
-
refDup.child('.info/connected').on('value', snap => {
|
|
188
|
-
ready = snap.val() === true || ready;
|
|
189
|
-
});
|
|
190
|
-
setTimeout(() => {
|
|
191
|
-
expect(ready).to.equal(0);
|
|
192
|
-
refDup.child('.info/connected').off();
|
|
193
|
-
ready = -1;
|
|
194
|
-
}, 500);
|
|
195
|
-
});
|
|
196
|
-
waitsFor(() => {
|
|
197
|
-
return ready === -1;
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
runs(() => {
|
|
201
|
-
ref.database.goOnline();
|
|
202
|
-
refAlt.database.goOnline();
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
// Ensure we're connected to both Firebases
|
|
206
|
-
runs(() => {
|
|
207
|
-
ready = 0;
|
|
208
|
-
const eventHandler = function (snap) {
|
|
209
|
-
if (snap.val() === true) {
|
|
210
|
-
snap.ref.off();
|
|
211
|
-
ready += 1;
|
|
212
|
-
}
|
|
213
|
-
};
|
|
214
|
-
ref.child('.info/connected').on('value', eventHandler);
|
|
215
|
-
refAlt.child('.info/connected').on('value', eventHandler);
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
waitsFor(() => {
|
|
219
|
-
return ready === 2;
|
|
220
|
-
});
|
|
221
|
-
});
|
|
222
|
-
});
|