@fluid-internal/presence-runtime 2.101.1 → 2.103.0
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/dist/packageVersion.d.ts +1 -1
- package/dist/packageVersion.js +1 -1
- package/dist/packageVersion.js.map +1 -1
- package/dist/runtime/extension/containerPresence.d.ts +1 -1
- package/dist/runtime/presenceDatastoreManager.d.ts +2 -2
- package/dist/runtime/presenceDatastoreManager.d.ts.map +1 -1
- package/dist/runtime/presenceDatastoreManager.js.map +1 -1
- package/dist/runtime/presenceManager.js.map +1 -1
- package/lib/packageVersion.d.ts +1 -1
- package/lib/packageVersion.js +1 -1
- package/lib/packageVersion.js.map +1 -1
- package/lib/runtime/extension/containerPresence.d.ts +1 -1
- package/lib/runtime/presenceDatastoreManager.d.ts +2 -2
- package/lib/runtime/presenceDatastoreManager.d.ts.map +1 -1
- package/lib/runtime/presenceDatastoreManager.js.map +1 -1
- package/lib/runtime/presenceManager.js.map +1 -1
- package/package.json +14 -14
- package/dist/runtime/test/presenceDatastoreManager.spec.js +0 -618
- package/dist/runtime/test/presenceDatastoreManager.spec.js.map +0 -1
- package/dist/runtime/test/presenceManager.spec.js +0 -651
- package/dist/runtime/test/presenceManager.spec.js.map +0 -1
- package/dist/states/test/batching.spec.js +0 -843
- package/dist/states/test/batching.spec.js.map +0 -1
- package/dist/states/test/broadcastControlsTests.js +0 -60
- package/dist/states/test/broadcastControlsTests.js.map +0 -1
- package/dist/states/test/eventing.spec.js +0 -576
- package/dist/states/test/eventing.spec.js.map +0 -1
- package/dist/states/test/latestMapValueManager.spec.js +0 -210
- package/dist/states/test/latestMapValueManager.spec.js.map +0 -1
- package/dist/states/test/latestValueManager.spec.js +0 -193
- package/dist/states/test/latestValueManager.spec.js.map +0 -1
- package/dist/states/test/mockEphemeralRuntime.js +0 -11
- package/dist/states/test/mockEphemeralRuntime.js.map +0 -1
- package/dist/states/test/notificationsManager.spec.js +0 -460
- package/dist/states/test/notificationsManager.spec.js.map +0 -1
- package/dist/states/test/presenceStates.spec.js +0 -73
- package/dist/states/test/presenceStates.spec.js.map +0 -1
- package/dist/states/test/schemaValidation/protocol.spec.js +0 -246
- package/dist/states/test/schemaValidation/protocol.spec.js.map +0 -1
- package/dist/states/test/schemaValidation/valueManagers.spec.js +0 -784
- package/dist/states/test/schemaValidation/valueManagers.spec.js.map +0 -1
- package/dist/states/test/testUtils.js +0 -21
- package/dist/states/test/testUtils.js.map +0 -1
- package/dist/test/mockEphemeralRuntime.js +0 -175
- package/dist/test/mockEphemeralRuntime.js.map +0 -1
- package/dist/test/testUtils.js +0 -262
- package/dist/test/testUtils.js.map +0 -1
- package/dist/test/utils/index.js +0 -27
- package/dist/test/utils/index.js.map +0 -1
- package/dist/utils/test/timerManager.spec.js +0 -93
- package/dist/utils/test/timerManager.spec.js.map +0 -1
- package/lib/runtime/test/presenceDatastoreManager.spec.js +0 -616
- package/lib/runtime/test/presenceDatastoreManager.spec.js.map +0 -1
- package/lib/runtime/test/presenceManager.spec.js +0 -649
- package/lib/runtime/test/presenceManager.spec.js.map +0 -1
- package/lib/states/test/batching.spec.js +0 -841
- package/lib/states/test/batching.spec.js.map +0 -1
- package/lib/states/test/broadcastControlsTests.js +0 -56
- package/lib/states/test/broadcastControlsTests.js.map +0 -1
- package/lib/states/test/eventing.spec.js +0 -574
- package/lib/states/test/eventing.spec.js.map +0 -1
- package/lib/states/test/latestMapValueManager.spec.js +0 -206
- package/lib/states/test/latestMapValueManager.spec.js.map +0 -1
- package/lib/states/test/latestValueManager.spec.js +0 -189
- package/lib/states/test/latestValueManager.spec.js.map +0 -1
- package/lib/states/test/mockEphemeralRuntime.js +0 -6
- package/lib/states/test/mockEphemeralRuntime.js.map +0 -1
- package/lib/states/test/notificationsManager.spec.js +0 -456
- package/lib/states/test/notificationsManager.spec.js.map +0 -1
- package/lib/states/test/presenceStates.spec.js +0 -69
- package/lib/states/test/presenceStates.spec.js.map +0 -1
- package/lib/states/test/schemaValidation/protocol.spec.js +0 -244
- package/lib/states/test/schemaValidation/protocol.spec.js.map +0 -1
- package/lib/states/test/schemaValidation/valueManagers.spec.js +0 -782
- package/lib/states/test/schemaValidation/valueManagers.spec.js.map +0 -1
- package/lib/states/test/testUtils.js +0 -6
- package/lib/states/test/testUtils.js.map +0 -1
- package/lib/test/mockEphemeralRuntime.js +0 -171
- package/lib/test/mockEphemeralRuntime.js.map +0 -1
- package/lib/test/testUtils.js +0 -251
- package/lib/test/testUtils.js.map +0 -1
- package/lib/test/utils/index.js +0 -8
- package/lib/test/utils/index.js.map +0 -1
- package/lib/utils/test/timerManager.spec.js +0 -91
- package/lib/utils/test/timerManager.spec.js.map +0 -1
|
@@ -1,784 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*!
|
|
3
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
4
|
-
* Licensed under the MIT License.
|
|
5
|
-
*/
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
const node_assert_1 = require("node:assert");
|
|
8
|
-
const internal_1 = require("@fluidframework/test-utils/internal");
|
|
9
|
-
const mocha_1 = require("mocha");
|
|
10
|
-
const sinon_1 = require("sinon");
|
|
11
|
-
const states_1 = require("@fluid-internal/presence-runtime/states");
|
|
12
|
-
const utils_1 = require("@fluid-internal/presence-runtime/utils");
|
|
13
|
-
const mockEphemeralRuntime_js_1 = require("../mockEphemeralRuntime.js");
|
|
14
|
-
const testUtils_js_1 = require("../testUtils.js");
|
|
15
|
-
const attendeeUpdate = {
|
|
16
|
-
"clientToSessionId": {
|
|
17
|
-
[testUtils_js_1.connectionId1]: {
|
|
18
|
-
"rev": 0,
|
|
19
|
-
"timestamp": 0,
|
|
20
|
-
"value": testUtils_js_1.attendeeId1,
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
};
|
|
24
|
-
const latestUpdate = {
|
|
25
|
-
"latest": {
|
|
26
|
-
[testUtils_js_1.attendeeId1]: {
|
|
27
|
-
"rev": 1,
|
|
28
|
-
"timestamp": 0,
|
|
29
|
-
"value": (0, utils_1.toOpaqueJson)({ x: 1, y: 1, z: 1 }),
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
};
|
|
33
|
-
const latestMapUpdate = {
|
|
34
|
-
"latestMap": {
|
|
35
|
-
[testUtils_js_1.attendeeId1]: {
|
|
36
|
-
"rev": 1,
|
|
37
|
-
"items": {
|
|
38
|
-
"key1": {
|
|
39
|
-
"rev": 1,
|
|
40
|
-
"timestamp": 0,
|
|
41
|
-
"value": (0, utils_1.toOpaqueJson)({ x: 1, y: 1, z: 1 }),
|
|
42
|
-
},
|
|
43
|
-
"key2": {
|
|
44
|
-
"rev": 1,
|
|
45
|
-
"timestamp": 0,
|
|
46
|
-
"value": (0, utils_1.toOpaqueJson)({ x: 2, y: 2, z: 2 }),
|
|
47
|
-
},
|
|
48
|
-
"invalidKey": {
|
|
49
|
-
"rev": 1,
|
|
50
|
-
"timestamp": 0,
|
|
51
|
-
"value": (0, utils_1.toOpaqueJson)({ x: -1, y: -1, z: -1 }),
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
},
|
|
56
|
-
};
|
|
57
|
-
function datastoreUpdateSignal(sendTimestamp, valueObjectName, metadata) {
|
|
58
|
-
return {
|
|
59
|
-
type: "Pres:DatastoreUpdate",
|
|
60
|
-
content: {
|
|
61
|
-
sendTimestamp,
|
|
62
|
-
avgLatency: 20,
|
|
63
|
-
data: {
|
|
64
|
-
"system:presence": attendeeUpdate,
|
|
65
|
-
"s:name:testWorkspace": {
|
|
66
|
-
[valueObjectName]: {
|
|
67
|
-
[testUtils_js_1.attendeeId1]: metadata,
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
},
|
|
71
|
-
},
|
|
72
|
-
clientId: testUtils_js_1.connectionId1,
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Runs a test against a validator by getting the value and matching the resulting data and validator call counts
|
|
77
|
-
* against expectations.
|
|
78
|
-
*/
|
|
79
|
-
function runValidatorTest(params) {
|
|
80
|
-
const initialValue = params.getRemoteValue();
|
|
81
|
-
node_assert_1.strict.equal(params.validatorFunction.callCount, params.expectedCallCount);
|
|
82
|
-
node_assert_1.strict.deepEqual(initialValue, params.expectedValue);
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Runs a test against a validator by getting the value multiple times and verifying that the validator is not called
|
|
86
|
-
* multiple times.
|
|
87
|
-
*/
|
|
88
|
-
function runMultipleCallsTest(params) {
|
|
89
|
-
// First call should invoke validator
|
|
90
|
-
const firstValue = params.getRemoteValue();
|
|
91
|
-
node_assert_1.strict.equal(params.validatorFunction.callCount, 1);
|
|
92
|
-
node_assert_1.strict.deepEqual(firstValue, params.expectedValue);
|
|
93
|
-
// Subsequent calls should not invoke validator when data is unchanged
|
|
94
|
-
const secondValue = params.getRemoteValue();
|
|
95
|
-
node_assert_1.strict.equal(params.validatorFunction.callCount, 1);
|
|
96
|
-
const thirdValue = params.getRemoteValue();
|
|
97
|
-
node_assert_1.strict.equal(params.validatorFunction.callCount, 1);
|
|
98
|
-
node_assert_1.strict.deepEqual(secondValue, params.expectedValue);
|
|
99
|
-
node_assert_1.strict.deepEqual(thirdValue, params.expectedValue);
|
|
100
|
-
}
|
|
101
|
-
(0, mocha_1.describe)("Presence/States", () => {
|
|
102
|
-
(0, mocha_1.describe)("Runtime schema validation", () => {
|
|
103
|
-
const afterCleanUp = [];
|
|
104
|
-
const initialTime = 1000;
|
|
105
|
-
function processUpdates(valueManagerUpdates) {
|
|
106
|
-
const updates = { "system:presence": attendeeUpdate, ...valueManagerUpdates };
|
|
107
|
-
processSignal([], {
|
|
108
|
-
type: "Pres:DatastoreUpdate",
|
|
109
|
-
content: {
|
|
110
|
-
sendTimestamp: clock.now - 10,
|
|
111
|
-
avgLatency: 20,
|
|
112
|
-
data: updates,
|
|
113
|
-
},
|
|
114
|
-
clientId: "client1",
|
|
115
|
-
}, false);
|
|
116
|
-
}
|
|
117
|
-
let clock;
|
|
118
|
-
let logger;
|
|
119
|
-
let presence;
|
|
120
|
-
let processSignal;
|
|
121
|
-
let runtime;
|
|
122
|
-
let remoteAttendee;
|
|
123
|
-
let validatorCallExpected;
|
|
124
|
-
let point3DValidatorFunction;
|
|
125
|
-
(0, mocha_1.before)(async () => {
|
|
126
|
-
clock = (0, sinon_1.useFakeTimers)();
|
|
127
|
-
});
|
|
128
|
-
/**
|
|
129
|
-
* This beforeEach sets up the runtime and presence objects. The `presence` object is owned by attendee2, while
|
|
130
|
-
* attendee1 acts as a remote attendee for the purposes of the tests.
|
|
131
|
-
*/
|
|
132
|
-
(0, mocha_1.beforeEach)(() => {
|
|
133
|
-
logger = new internal_1.EventAndErrorTrackingLogger();
|
|
134
|
-
runtime = new mockEphemeralRuntime_js_1.MockEphemeralRuntime(logger);
|
|
135
|
-
clock.setSystemTime(initialTime);
|
|
136
|
-
validatorCallExpected = true;
|
|
137
|
-
point3DValidatorFunction = (0, testUtils_js_1.createSpiedValidator)((d) => {
|
|
138
|
-
if (validatorCallExpected === "once") {
|
|
139
|
-
validatorCallExpected = false;
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
(0, node_assert_1.strict)(validatorCallExpected, "point3DValidatorFunction should not be called at this time");
|
|
143
|
-
}
|
|
144
|
-
return typeof d === "object" ? d : undefined;
|
|
145
|
-
});
|
|
146
|
-
// Create Presence joining session as attendeeId-2. Tests will act as attendee2
|
|
147
|
-
({ presence, processSignal } = (0, testUtils_js_1.prepareConnectedPresence)(runtime, testUtils_js_1.localAttendeeId, testUtils_js_1.initialLocalClientConnectionId, clock, logger));
|
|
148
|
-
// Pass a little time (to mimic reality)
|
|
149
|
-
clock.tick(10);
|
|
150
|
-
// Process remote client update signal (attendeeId-1 is then part of local client's known session).
|
|
151
|
-
processUpdates({
|
|
152
|
-
"s:name:testWorkspace": { ...latestUpdate, ...latestMapUpdate },
|
|
153
|
-
});
|
|
154
|
-
// Pass a little time (to mimic reality)
|
|
155
|
-
clock.tick(10);
|
|
156
|
-
// Get attendee references
|
|
157
|
-
remoteAttendee = presence.attendees.getAttendee(testUtils_js_1.attendeeId1);
|
|
158
|
-
});
|
|
159
|
-
(0, mocha_1.afterEach)(function (done) {
|
|
160
|
-
clock.reset();
|
|
161
|
-
point3DValidatorFunction.resetHistory();
|
|
162
|
-
// If the test passed so far, check final expectations.
|
|
163
|
-
if (this.currentTest?.state === "passed") {
|
|
164
|
-
(0, testUtils_js_1.assertFinalExpectations)(runtime, logger);
|
|
165
|
-
}
|
|
166
|
-
for (const cleanUp of afterCleanUp) {
|
|
167
|
-
cleanUp();
|
|
168
|
-
}
|
|
169
|
-
afterCleanUp.length = 0;
|
|
170
|
-
done();
|
|
171
|
-
});
|
|
172
|
-
(0, mocha_1.after)(() => {
|
|
173
|
-
clock.restore();
|
|
174
|
-
});
|
|
175
|
-
(0, mocha_1.describe)("Latest validator", () => {
|
|
176
|
-
let latest;
|
|
177
|
-
/**
|
|
178
|
-
* This beforeEach sets up the presence workspace itself and gets a reference to it. It then sets some new data as
|
|
179
|
-
* attendee1 by processing a datastore update signal.
|
|
180
|
-
*/
|
|
181
|
-
(0, mocha_1.beforeEach)(() => {
|
|
182
|
-
// Setup workspace initialization signal
|
|
183
|
-
runtime.signalsExpected.push([
|
|
184
|
-
{
|
|
185
|
-
type: "Pres:DatastoreUpdate",
|
|
186
|
-
content: {
|
|
187
|
-
sendTimestamp: clock.now,
|
|
188
|
-
avgLatency: 10,
|
|
189
|
-
data: {
|
|
190
|
-
"system:presence": {
|
|
191
|
-
"clientToSessionId": {
|
|
192
|
-
[testUtils_js_1.initialLocalClientConnectionId]: {
|
|
193
|
-
"rev": 0,
|
|
194
|
-
"timestamp": initialTime,
|
|
195
|
-
"value": testUtils_js_1.localAttendeeId,
|
|
196
|
-
},
|
|
197
|
-
},
|
|
198
|
-
},
|
|
199
|
-
"s:name:testWorkspace": {
|
|
200
|
-
"latest": {
|
|
201
|
-
[testUtils_js_1.localAttendeeId]: {
|
|
202
|
-
"rev": 0,
|
|
203
|
-
"timestamp": clock.now,
|
|
204
|
-
"value": (0, utils_1.toOpaqueJson)({ x: 0, y: 0, z: 0 }),
|
|
205
|
-
},
|
|
206
|
-
},
|
|
207
|
-
},
|
|
208
|
-
},
|
|
209
|
-
},
|
|
210
|
-
},
|
|
211
|
-
]);
|
|
212
|
-
const stateWorkspace = presence.states.getWorkspace("name:testWorkspace", {
|
|
213
|
-
latest: states_1.StateFactory.latest({
|
|
214
|
-
local: { x: 0, y: 0, z: 0 },
|
|
215
|
-
validator: point3DValidatorFunction,
|
|
216
|
-
settings: { allowableUpdateLatencyMs: 0 },
|
|
217
|
-
}),
|
|
218
|
-
});
|
|
219
|
-
latest = stateWorkspace.states.latest;
|
|
220
|
-
// Process a valid update signal with Point3D data
|
|
221
|
-
processSignal([], {
|
|
222
|
-
type: "Pres:DatastoreUpdate",
|
|
223
|
-
content: {
|
|
224
|
-
sendTimestamp: clock.now - 10,
|
|
225
|
-
avgLatency: 20,
|
|
226
|
-
data: {
|
|
227
|
-
"system:presence": attendeeUpdate,
|
|
228
|
-
"s:name:testWorkspace": {
|
|
229
|
-
"latest": {
|
|
230
|
-
[testUtils_js_1.attendeeId1]: {
|
|
231
|
-
"rev": 2,
|
|
232
|
-
"timestamp": clock.now - 10,
|
|
233
|
-
"value": (0, utils_1.toOpaqueJson)({ x: 10, y: 20, z: 30 }),
|
|
234
|
-
},
|
|
235
|
-
},
|
|
236
|
-
},
|
|
237
|
-
},
|
|
238
|
-
},
|
|
239
|
-
clientId: "client1",
|
|
240
|
-
}, false);
|
|
241
|
-
});
|
|
242
|
-
(0, mocha_1.describe)("is not called", () => {
|
|
243
|
-
(0, mocha_1.it)("by .getRemote()", () => {
|
|
244
|
-
// Calling getRemote should not invoke the validator (only a value read will).
|
|
245
|
-
latest.getRemote(remoteAttendee);
|
|
246
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 0);
|
|
247
|
-
});
|
|
248
|
-
(0, mocha_1.it)("by .getRemotes()", () => {
|
|
249
|
-
for (const _ of latest.getRemotes()) {
|
|
250
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 0);
|
|
251
|
-
}
|
|
252
|
-
});
|
|
253
|
-
(0, mocha_1.it)("when accessing .local", () => {
|
|
254
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 0, "initial call count is wrong");
|
|
255
|
-
node_assert_1.strict.deepEqual(latest.local, { x: 0, y: 0, z: 0 });
|
|
256
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 0, "validator was called on local data");
|
|
257
|
-
});
|
|
258
|
-
(0, mocha_1.it)("when remote data is updated", () => {
|
|
259
|
-
const remoteData = latest.getRemote(remoteAttendee);
|
|
260
|
-
// Should call validator
|
|
261
|
-
runValidatorTest({
|
|
262
|
-
getRemoteValue: () => remoteData.value(),
|
|
263
|
-
expectedCallCount: 1,
|
|
264
|
-
expectedValue: { x: 10, y: 20, z: 30 },
|
|
265
|
-
validatorFunction: point3DValidatorFunction,
|
|
266
|
-
});
|
|
267
|
-
// Send updated data from remote client
|
|
268
|
-
const timestamp = clock.now - 15;
|
|
269
|
-
processSignal([], datastoreUpdateSignal(timestamp, "latest", {
|
|
270
|
-
"rev": 3,
|
|
271
|
-
timestamp,
|
|
272
|
-
"value": (0, utils_1.toOpaqueJson)({ x: 50, y: 60, z: 70 }),
|
|
273
|
-
}), false);
|
|
274
|
-
// Validator is not called by remote update
|
|
275
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 1);
|
|
276
|
-
});
|
|
277
|
-
});
|
|
278
|
-
(0, mocha_1.describe)("is called", () => {
|
|
279
|
-
(0, mocha_1.it)("on first .value() call", () => {
|
|
280
|
-
const remoteData = latest.getRemote(remoteAttendee);
|
|
281
|
-
runValidatorTest({
|
|
282
|
-
getRemoteValue: () => remoteData.value(),
|
|
283
|
-
expectedCallCount: 1,
|
|
284
|
-
expectedValue: { x: 10, y: 20, z: 30 },
|
|
285
|
-
validatorFunction: point3DValidatorFunction,
|
|
286
|
-
});
|
|
287
|
-
});
|
|
288
|
-
(0, mocha_1.it)("only once for multiple .value() calls in series and .value() always returns same value", () => {
|
|
289
|
-
const remoteData = latest.getRemote(remoteAttendee);
|
|
290
|
-
runMultipleCallsTest({
|
|
291
|
-
getRemoteValue: () => remoteData.value(),
|
|
292
|
-
expectedValue: { x: 10, y: 20, z: 30 },
|
|
293
|
-
validatorFunction: point3DValidatorFunction,
|
|
294
|
-
});
|
|
295
|
-
});
|
|
296
|
-
(0, mocha_1.it)("on .value() call after remote data has changed", () => {
|
|
297
|
-
// Get the remote data and read it, verify that the validator is called once.
|
|
298
|
-
const remoteData = latest.getRemote(remoteAttendee);
|
|
299
|
-
node_assert_1.strict.deepEqual(remoteData.value(), { x: 10, y: 20, z: 30 });
|
|
300
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 1, "first call count is wrong");
|
|
301
|
-
// Send updated data from remote client
|
|
302
|
-
const timestamp = clock.now - 15;
|
|
303
|
-
processSignal([], datastoreUpdateSignal(timestamp, "latest", {
|
|
304
|
-
"rev": 3,
|
|
305
|
-
timestamp,
|
|
306
|
-
"value": (0, utils_1.toOpaqueJson)({ x: 50, y: 60, z: 70 }),
|
|
307
|
-
}), false);
|
|
308
|
-
// Reading the remote value should cause the validator to be called a second time since the data has been changed.
|
|
309
|
-
const data2 = latest.getRemote(remoteAttendee);
|
|
310
|
-
node_assert_1.strict.deepEqual(data2.value(), { x: 50, y: 60, z: 70 }, "updated remote value is wrong");
|
|
311
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 2, "validator should be called twice");
|
|
312
|
-
});
|
|
313
|
-
(0, mocha_1.it)("on .value() call when remote data changes from valid to invalid", () => {
|
|
314
|
-
// Get the remote data and read it, verify that the validator is called once.
|
|
315
|
-
const remoteData = latest.getRemote(remoteAttendee);
|
|
316
|
-
node_assert_1.strict.deepEqual(remoteData.value(), { x: 10, y: 20, z: 30 });
|
|
317
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 1, "first call count is wrong");
|
|
318
|
-
// Send invalid data from remote client
|
|
319
|
-
const timestamp = clock.now - 15;
|
|
320
|
-
processSignal([], datastoreUpdateSignal(timestamp, "latest", {
|
|
321
|
-
"rev": 3,
|
|
322
|
-
timestamp,
|
|
323
|
-
"value": (0, utils_1.toOpaqueJson)("invalid"),
|
|
324
|
-
}), false);
|
|
325
|
-
// Reading the remote value should cause the validator to be called a second time and return undefined
|
|
326
|
-
const data2 = latest.getRemote(remoteAttendee);
|
|
327
|
-
node_assert_1.strict.equal(data2.value(), undefined, "invalid data should return undefined");
|
|
328
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 2, "validator should be called twice");
|
|
329
|
-
});
|
|
330
|
-
(0, mocha_1.it)("on .value() call when remote data changes from invalid to valid", () => {
|
|
331
|
-
// First send invalid data
|
|
332
|
-
let timestamp = clock.now - 15;
|
|
333
|
-
processSignal([], datastoreUpdateSignal(timestamp, "latest", {
|
|
334
|
-
"rev": 3,
|
|
335
|
-
timestamp,
|
|
336
|
-
"value": (0, utils_1.toOpaqueJson)("invalid"),
|
|
337
|
-
}), false);
|
|
338
|
-
// Get the remote data and read it, verify that the validator is called once and returns undefined
|
|
339
|
-
const remoteData = latest.getRemote(remoteAttendee);
|
|
340
|
-
node_assert_1.strict.equal(remoteData.value(), undefined);
|
|
341
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 1, "first call count is wrong");
|
|
342
|
-
// Send valid data from remote client
|
|
343
|
-
timestamp += 10;
|
|
344
|
-
processSignal([], datastoreUpdateSignal(timestamp, "latest", {
|
|
345
|
-
"rev": 4,
|
|
346
|
-
timestamp,
|
|
347
|
-
"value": (0, utils_1.toOpaqueJson)({ x: 100, y: 200, z: 300 }),
|
|
348
|
-
}), false);
|
|
349
|
-
// Reading the remote value should cause the validator to be called a second time and return valid data
|
|
350
|
-
const data2 = latest.getRemote(remoteAttendee);
|
|
351
|
-
node_assert_1.strict.deepEqual(data2.value(), { x: 100, y: 200, z: 300 }, "valid data should be returned");
|
|
352
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 2, "validator should be called twice");
|
|
353
|
-
});
|
|
354
|
-
(0, mocha_1.it)("on .value() call when remote data changes from invalid to invalid", () => {
|
|
355
|
-
// First send invalid data
|
|
356
|
-
let timestamp = clock.now - 15;
|
|
357
|
-
processSignal([], datastoreUpdateSignal(timestamp, "latest", {
|
|
358
|
-
"rev": 3,
|
|
359
|
-
timestamp,
|
|
360
|
-
"value": (0, utils_1.toOpaqueJson)("invalid"),
|
|
361
|
-
}), false);
|
|
362
|
-
// Get the remote data and read it, verify that the validator is called once and returns undefined
|
|
363
|
-
const remoteData = latest.getRemote(remoteAttendee);
|
|
364
|
-
node_assert_1.strict.equal(remoteData.value(), undefined);
|
|
365
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 1, "first call count is wrong");
|
|
366
|
-
// Send different invalid data from remote client
|
|
367
|
-
timestamp += 10;
|
|
368
|
-
processSignal([], datastoreUpdateSignal(timestamp, "latest", {
|
|
369
|
-
"rev": 4,
|
|
370
|
-
timestamp,
|
|
371
|
-
"value": (0, utils_1.toOpaqueJson)("also-invalid"),
|
|
372
|
-
}), false);
|
|
373
|
-
// Reading the remote value should cause the validator to be called a second time and still return undefined
|
|
374
|
-
const data2 = latest.getRemote(remoteAttendee);
|
|
375
|
-
node_assert_1.strict.equal(data2.value(), undefined, "invalid data should return undefined");
|
|
376
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 2, "validator should be called twice");
|
|
377
|
-
});
|
|
378
|
-
});
|
|
379
|
-
});
|
|
380
|
-
(0, mocha_1.describe)("LatestMap with validation", () => {
|
|
381
|
-
let latestMap;
|
|
382
|
-
let keyValidatorCallExpectedCount;
|
|
383
|
-
function keyValidatorFunction(key) {
|
|
384
|
-
(0, node_assert_1.strict)(keyValidatorCallExpectedCount > 0, "keyValidatorFunction should not be called at this time");
|
|
385
|
-
keyValidatorCallExpectedCount--;
|
|
386
|
-
return key.startsWith("key");
|
|
387
|
-
}
|
|
388
|
-
/**
|
|
389
|
-
* This beforeEach sets up the presence workspace itself and gets a
|
|
390
|
-
* reference to it.
|
|
391
|
-
*/
|
|
392
|
-
(0, mocha_1.beforeEach)(() => {
|
|
393
|
-
keyValidatorCallExpectedCount = 0;
|
|
394
|
-
// workspace setup's initialization signal
|
|
395
|
-
runtime.signalsExpected.push([
|
|
396
|
-
{
|
|
397
|
-
"type": "Pres:DatastoreUpdate",
|
|
398
|
-
"content": {
|
|
399
|
-
"sendTimestamp": clock.now,
|
|
400
|
-
"avgLatency": 10,
|
|
401
|
-
"data": {
|
|
402
|
-
"system:presence": {
|
|
403
|
-
"clientToSessionId": {
|
|
404
|
-
[testUtils_js_1.initialLocalClientConnectionId]: {
|
|
405
|
-
"rev": 0,
|
|
406
|
-
"timestamp": initialTime,
|
|
407
|
-
"value": testUtils_js_1.localAttendeeId,
|
|
408
|
-
},
|
|
409
|
-
},
|
|
410
|
-
},
|
|
411
|
-
"s:name:testWorkspace": {
|
|
412
|
-
"latestMap": {
|
|
413
|
-
[testUtils_js_1.localAttendeeId]: {
|
|
414
|
-
"rev": 0,
|
|
415
|
-
"items": {
|
|
416
|
-
"key1": {
|
|
417
|
-
"rev": 0,
|
|
418
|
-
"timestamp": clock.now,
|
|
419
|
-
"value": (0, utils_1.toOpaqueJson)({ "x": 0, "y": 0, "z": 0 }),
|
|
420
|
-
},
|
|
421
|
-
"key2": {
|
|
422
|
-
"rev": 0,
|
|
423
|
-
"timestamp": clock.now,
|
|
424
|
-
"value": (0, utils_1.toOpaqueJson)({ "x": 0, "y": 0, "z": 0 }),
|
|
425
|
-
},
|
|
426
|
-
},
|
|
427
|
-
},
|
|
428
|
-
},
|
|
429
|
-
},
|
|
430
|
-
},
|
|
431
|
-
},
|
|
432
|
-
},
|
|
433
|
-
]);
|
|
434
|
-
const stateWorkspace = presence.states.getWorkspace("name:testWorkspace", {
|
|
435
|
-
latestMap: states_1.StateFactory.latestMap({
|
|
436
|
-
local: { "key1": { x: 0, y: 0, z: 0 }, "key2": { x: 0, y: 0, z: 0 } },
|
|
437
|
-
validator: point3DValidatorFunction,
|
|
438
|
-
keyValidator: keyValidatorFunction,
|
|
439
|
-
settings: { allowableUpdateLatencyMs: 0 },
|
|
440
|
-
}),
|
|
441
|
-
});
|
|
442
|
-
latestMap = stateWorkspace.states.latestMap;
|
|
443
|
-
});
|
|
444
|
-
function sendInvalidData(key = "key1") {
|
|
445
|
-
keyValidatorCallExpectedCount = 1;
|
|
446
|
-
const timestamp = clock.now - 15;
|
|
447
|
-
processSignal([], datastoreUpdateSignal(timestamp, "latestMap", {
|
|
448
|
-
"rev": 2,
|
|
449
|
-
"items": {
|
|
450
|
-
[key]: {
|
|
451
|
-
"rev": 2,
|
|
452
|
-
timestamp,
|
|
453
|
-
"value": (0, utils_1.toOpaqueJson)("invalid"),
|
|
454
|
-
},
|
|
455
|
-
},
|
|
456
|
-
}), false);
|
|
457
|
-
node_assert_1.strict.equal(keyValidatorCallExpectedCount, 0);
|
|
458
|
-
}
|
|
459
|
-
(0, mocha_1.describe)("no validator is called", () => {
|
|
460
|
-
(0, mocha_1.beforeEach)(() => {
|
|
461
|
-
validatorCallExpected = false;
|
|
462
|
-
});
|
|
463
|
-
(0, mocha_1.it)("when reading local key value", () => {
|
|
464
|
-
// Act
|
|
465
|
-
const localData = latestMap.local.get("key1");
|
|
466
|
-
// Verify
|
|
467
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 0);
|
|
468
|
-
// double check local data
|
|
469
|
-
node_assert_1.strict.deepEqual(localData, { x: 0, y: 0, z: 0 });
|
|
470
|
-
});
|
|
471
|
-
(0, mocha_1.it)("when writing local key value", () => {
|
|
472
|
-
// Setup
|
|
473
|
-
runtime.signalsExpected.push([
|
|
474
|
-
{
|
|
475
|
-
"type": "Pres:DatastoreUpdate",
|
|
476
|
-
"content": {
|
|
477
|
-
"sendTimestamp": clock.now,
|
|
478
|
-
"avgLatency": 10,
|
|
479
|
-
"data": {
|
|
480
|
-
"system:presence": {
|
|
481
|
-
"clientToSessionId": {
|
|
482
|
-
[testUtils_js_1.initialLocalClientConnectionId]: {
|
|
483
|
-
"rev": 0,
|
|
484
|
-
"timestamp": initialTime,
|
|
485
|
-
"value": testUtils_js_1.localAttendeeId,
|
|
486
|
-
},
|
|
487
|
-
},
|
|
488
|
-
},
|
|
489
|
-
"s:name:testWorkspace": {
|
|
490
|
-
"latestMap": {
|
|
491
|
-
[testUtils_js_1.localAttendeeId]: {
|
|
492
|
-
"rev": 1,
|
|
493
|
-
"items": {
|
|
494
|
-
"key1": {
|
|
495
|
-
"rev": 1,
|
|
496
|
-
"timestamp": clock.now,
|
|
497
|
-
"value": (0, utils_1.toOpaqueJson)({ "x": 0, "y": 1, "z": 2 }),
|
|
498
|
-
},
|
|
499
|
-
},
|
|
500
|
-
},
|
|
501
|
-
},
|
|
502
|
-
},
|
|
503
|
-
},
|
|
504
|
-
},
|
|
505
|
-
},
|
|
506
|
-
]);
|
|
507
|
-
// Act
|
|
508
|
-
latestMap.local.set("key1", { x: 0, y: 1, z: 2 });
|
|
509
|
-
// Verify
|
|
510
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 0);
|
|
511
|
-
});
|
|
512
|
-
});
|
|
513
|
-
(0, mocha_1.it)("update with invalid key invokes key validator per key and does not raise events", () => {
|
|
514
|
-
// Setup
|
|
515
|
-
for (const event of [
|
|
516
|
-
"remoteUpdated",
|
|
517
|
-
"remoteItemUpdated",
|
|
518
|
-
"remoteItemRemoved",
|
|
519
|
-
]) {
|
|
520
|
-
afterCleanUp.push(latestMap.events.on(event, () => {
|
|
521
|
-
node_assert_1.strict.fail(`${event} event should not be raised for invalid key`);
|
|
522
|
-
}));
|
|
523
|
-
}
|
|
524
|
-
keyValidatorCallExpectedCount = 1;
|
|
525
|
-
// Act
|
|
526
|
-
sendInvalidData("invalidKey");
|
|
527
|
-
// Verify
|
|
528
|
-
node_assert_1.strict.equal(keyValidatorCallExpectedCount, 0); // all expected calls were made
|
|
529
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 0);
|
|
530
|
-
});
|
|
531
|
-
/**
|
|
532
|
-
* Sets validator call expectations and gets remote value data.
|
|
533
|
-
* @returns `latestMap.getRemote(remoteAttendee)`
|
|
534
|
-
* @remarks
|
|
535
|
-
* `validatorCallExpected` will be `false` and `keyValidatorCallExpectedCount`
|
|
536
|
-
* will be `0` after the call.
|
|
537
|
-
*/
|
|
538
|
-
function getRemoteValue() {
|
|
539
|
-
validatorCallExpected = false;
|
|
540
|
-
keyValidatorCallExpectedCount = 3;
|
|
541
|
-
const remoteData = latestMap.getRemote(remoteAttendee);
|
|
542
|
-
node_assert_1.strict.equal(keyValidatorCallExpectedCount, 0);
|
|
543
|
-
return remoteData;
|
|
544
|
-
}
|
|
545
|
-
(0, mocha_1.it)(".getRemote call invokes key validator per key but not value validator", () => {
|
|
546
|
-
// Setup and Act
|
|
547
|
-
getRemoteValue();
|
|
548
|
-
// Verify
|
|
549
|
-
node_assert_1.strict.equal(keyValidatorCallExpectedCount, 0); // all expected calls were made
|
|
550
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 0);
|
|
551
|
-
});
|
|
552
|
-
(0, mocha_1.describe)("remote value map", () => {
|
|
553
|
-
(0, mocha_1.it)(".get() does not call any validator", () => {
|
|
554
|
-
// Setup
|
|
555
|
-
const remoteData = getRemoteValue();
|
|
556
|
-
// Act
|
|
557
|
-
remoteData.get("key1");
|
|
558
|
-
// Verify
|
|
559
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 0);
|
|
560
|
-
});
|
|
561
|
-
(0, mocha_1.it)(".forEach() iteration does not call any validator", () => {
|
|
562
|
-
// Setup
|
|
563
|
-
const remoteData = getRemoteValue();
|
|
564
|
-
let counter = 0;
|
|
565
|
-
const expectedValues = [
|
|
566
|
-
["key1", { x: 1, y: 1, z: 1 }],
|
|
567
|
-
["key2", { x: 2, y: 2, z: 2 }],
|
|
568
|
-
];
|
|
569
|
-
// Act
|
|
570
|
-
// eslint-disable-next-line unicorn/no-array-for-each -- forEach is being tested here
|
|
571
|
-
remoteData.forEach((_value, key) => {
|
|
572
|
-
// Verify
|
|
573
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 0, "call count is wrong");
|
|
574
|
-
node_assert_1.strict.equal(key, expectedValues[counter][0]);
|
|
575
|
-
counter++;
|
|
576
|
-
});
|
|
577
|
-
// Make sure forEach iterated through all keys
|
|
578
|
-
node_assert_1.strict.equal(counter, expectedValues.length, "counter should match expected values length");
|
|
579
|
-
});
|
|
580
|
-
(0, mocha_1.describe)("value validator is called", () => {
|
|
581
|
-
for (const { desc, setup, expectedValue } of [
|
|
582
|
-
{
|
|
583
|
-
desc: "for valid value",
|
|
584
|
-
setup: () => { },
|
|
585
|
-
expectedValue: { x: 1, y: 1, z: 1 },
|
|
586
|
-
},
|
|
587
|
-
{
|
|
588
|
-
desc: "for invalid value",
|
|
589
|
-
setup: sendInvalidData,
|
|
590
|
-
expectedValue: undefined,
|
|
591
|
-
},
|
|
592
|
-
]) {
|
|
593
|
-
(0, mocha_1.it)(`once when key.value() is called ${desc}`, () => {
|
|
594
|
-
// Setup
|
|
595
|
-
setup();
|
|
596
|
-
const remoteData = getRemoteValue();
|
|
597
|
-
validatorCallExpected = "once";
|
|
598
|
-
// Act
|
|
599
|
-
runValidatorTest({
|
|
600
|
-
getRemoteValue: () => remoteData.get("key1")?.value(),
|
|
601
|
-
expectedCallCount: 1,
|
|
602
|
-
expectedValue,
|
|
603
|
-
validatorFunction: point3DValidatorFunction,
|
|
604
|
-
});
|
|
605
|
-
});
|
|
606
|
-
(0, mocha_1.it)(`only once for multiple key.value() calls in series and .value() always returned same result ${desc}`, () => {
|
|
607
|
-
// Setup
|
|
608
|
-
setup();
|
|
609
|
-
const remoteData = getRemoteValue();
|
|
610
|
-
validatorCallExpected = "once";
|
|
611
|
-
// Act
|
|
612
|
-
runMultipleCallsTest({
|
|
613
|
-
getRemoteValue: () => remoteData.get("key1")?.value(),
|
|
614
|
-
expectedValue,
|
|
615
|
-
validatorFunction: point3DValidatorFunction,
|
|
616
|
-
});
|
|
617
|
-
});
|
|
618
|
-
(0, mocha_1.it)(`exactly once for each value's .value() calls in .forEach() and .value() always returns same result ${desc}`, () => {
|
|
619
|
-
// Setup
|
|
620
|
-
setup();
|
|
621
|
-
const remoteData = getRemoteValue();
|
|
622
|
-
let counter = 0;
|
|
623
|
-
const expectedValues = [
|
|
624
|
-
// only key1 value might be altered by the setup function
|
|
625
|
-
["key1", expectedValue],
|
|
626
|
-
// key2 value will always be the valid
|
|
627
|
-
["key2", { x: 2, y: 2, z: 2 }],
|
|
628
|
-
];
|
|
629
|
-
// Act
|
|
630
|
-
// eslint-disable-next-line unicorn/no-array-for-each -- forEach is being tested here
|
|
631
|
-
remoteData.forEach((value, key) => {
|
|
632
|
-
node_assert_1.strict.equal(key, expectedValues[counter][0]);
|
|
633
|
-
// reset call expectations/count for each iteration
|
|
634
|
-
validatorCallExpected = "once";
|
|
635
|
-
point3DValidatorFunction.callCount = 0;
|
|
636
|
-
// Act - first call
|
|
637
|
-
const valueData = value?.value();
|
|
638
|
-
// Verify
|
|
639
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 1, "validator was not called");
|
|
640
|
-
// double check value
|
|
641
|
-
node_assert_1.strict.deepEqual(valueData, expectedValues[counter][1], `value at key "${key}" is wrong`);
|
|
642
|
-
// Act - second call
|
|
643
|
-
// Access value a second time; should not affect validator call count
|
|
644
|
-
const valueDataRedux = value?.value();
|
|
645
|
-
// Verify
|
|
646
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 1, "validator was called a second time");
|
|
647
|
-
node_assert_1.strict.strictEqual(valueDataRedux, valueData, `value at key "${key}" is wrong`);
|
|
648
|
-
counter++;
|
|
649
|
-
});
|
|
650
|
-
// Make sure forEach iterated through all keys
|
|
651
|
-
node_assert_1.strict.equal(counter, expectedValues.length, "counter should match expected values length");
|
|
652
|
-
});
|
|
653
|
-
}
|
|
654
|
-
for (const { desc, setup, expectedInitialValue, newData, expectedValue } of [
|
|
655
|
-
{
|
|
656
|
-
desc: "from valid to different valid value",
|
|
657
|
-
setup: () => { },
|
|
658
|
-
expectedInitialValue: { x: 1, y: 1, z: 1 },
|
|
659
|
-
newData: { x: 4, y: 4, z: 4 },
|
|
660
|
-
expectedValue: { x: 4, y: 4, z: 4 },
|
|
661
|
-
},
|
|
662
|
-
{
|
|
663
|
-
desc: "from valid to same valid value",
|
|
664
|
-
setup: () => { },
|
|
665
|
-
expectedInitialValue: { x: 1, y: 1, z: 1 },
|
|
666
|
-
newData: { x: 1, y: 1, z: 1 },
|
|
667
|
-
expectedValue: { x: 1, y: 1, z: 1 },
|
|
668
|
-
},
|
|
669
|
-
{
|
|
670
|
-
desc: "from valid to invalid value",
|
|
671
|
-
setup: () => { },
|
|
672
|
-
expectedInitialValue: { x: 1, y: 1, z: 1 },
|
|
673
|
-
newData: "invalid",
|
|
674
|
-
expectedValue: undefined,
|
|
675
|
-
},
|
|
676
|
-
{
|
|
677
|
-
desc: "from invalid to valid value",
|
|
678
|
-
setup: sendInvalidData,
|
|
679
|
-
expectedInitialValue: undefined,
|
|
680
|
-
newData: { x: 4, y: 4, z: 4 },
|
|
681
|
-
expectedValue: { x: 4, y: 4, z: 4 },
|
|
682
|
-
},
|
|
683
|
-
{
|
|
684
|
-
desc: "from invalid to invalid value",
|
|
685
|
-
setup: sendInvalidData,
|
|
686
|
-
expectedInitialValue: undefined,
|
|
687
|
-
newData: "invalid",
|
|
688
|
-
expectedValue: undefined,
|
|
689
|
-
},
|
|
690
|
-
]) {
|
|
691
|
-
(0, mocha_1.it)(`during .value() call after remote key data has changed ${desc}`, () => {
|
|
692
|
-
// Setup
|
|
693
|
-
setup();
|
|
694
|
-
const originalMap = getRemoteValue();
|
|
695
|
-
validatorCallExpected = "once";
|
|
696
|
-
// Get the remote data and read it, expect that the validator is called once.
|
|
697
|
-
const key1Value = originalMap.get("key1")?.value();
|
|
698
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 1, "first call count is wrong");
|
|
699
|
-
node_assert_1.strict.deepEqual(key1Value, expectedInitialValue);
|
|
700
|
-
// Reset call count for next verification
|
|
701
|
-
point3DValidatorFunction.callCount = 0;
|
|
702
|
-
// Process updated key data from remote client
|
|
703
|
-
keyValidatorCallExpectedCount = 1;
|
|
704
|
-
const timestamp = clock.now - 15;
|
|
705
|
-
processSignal([], datastoreUpdateSignal(timestamp, "latestMap", {
|
|
706
|
-
"rev": 3,
|
|
707
|
-
"items": {
|
|
708
|
-
"key1": {
|
|
709
|
-
"rev": 3,
|
|
710
|
-
timestamp,
|
|
711
|
-
"value": (0, utils_1.toOpaqueJson)(newData),
|
|
712
|
-
},
|
|
713
|
-
},
|
|
714
|
-
}), false);
|
|
715
|
-
node_assert_1.strict.equal(keyValidatorCallExpectedCount, 0);
|
|
716
|
-
// Verify no call yet
|
|
717
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 0, "call count after update is wrong");
|
|
718
|
-
// Reading the remote value should cause the validator to be
|
|
719
|
-
// called since the data has been changed.
|
|
720
|
-
const updatedMap = getRemoteValue();
|
|
721
|
-
validatorCallExpected = "once";
|
|
722
|
-
// Act - read updated key value
|
|
723
|
-
const updatedKey1Value = updatedMap.get("key1")?.value();
|
|
724
|
-
// Verify
|
|
725
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 1, "validator should be called twice");
|
|
726
|
-
node_assert_1.strict.deepEqual(updatedKey1Value, expectedValue, "updated remote key value is wrong");
|
|
727
|
-
});
|
|
728
|
-
}
|
|
729
|
-
});
|
|
730
|
-
});
|
|
731
|
-
// Note this block is after "value validator is called" as it is only valid when those tests are passing.
|
|
732
|
-
(0, mocha_1.describe)("no validator is called", () => {
|
|
733
|
-
(0, mocha_1.it)("during .value() call for unchanged keys", () => {
|
|
734
|
-
// Setup
|
|
735
|
-
keyValidatorCallExpectedCount = 3;
|
|
736
|
-
const originalMap = latestMap.getRemote(remoteAttendee);
|
|
737
|
-
node_assert_1.strict.equal(keyValidatorCallExpectedCount, 0);
|
|
738
|
-
validatorCallExpected = "once";
|
|
739
|
-
// Read key1 value - should call validator once
|
|
740
|
-
const key1Value = originalMap.get("key1")?.value();
|
|
741
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 1, "validator should be called once for key1");
|
|
742
|
-
node_assert_1.strict.deepEqual(key1Value, { x: 1, y: 1, z: 1 });
|
|
743
|
-
// Update key2 (different key) with new data, keeping key1 unchanged
|
|
744
|
-
keyValidatorCallExpectedCount = 1;
|
|
745
|
-
const timestamp = clock.now - 15;
|
|
746
|
-
processSignal([], datastoreUpdateSignal(timestamp, "latestMap", {
|
|
747
|
-
"rev": 2,
|
|
748
|
-
"items": {
|
|
749
|
-
"key2": {
|
|
750
|
-
"rev": 2,
|
|
751
|
-
timestamp,
|
|
752
|
-
"value": (0, utils_1.toOpaqueJson)({ "x": 4, "y": 4, "z": 4 }),
|
|
753
|
-
},
|
|
754
|
-
},
|
|
755
|
-
}), false);
|
|
756
|
-
node_assert_1.strict.equal(keyValidatorCallExpectedCount, 0);
|
|
757
|
-
const updatedMap = getRemoteValue();
|
|
758
|
-
const key1Redux = updatedMap.get("key1");
|
|
759
|
-
node_assert_1.strict.ok(key1Redux);
|
|
760
|
-
node_assert_1.strict.equal(keyValidatorCallExpectedCount, 0);
|
|
761
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 1);
|
|
762
|
-
// Act & Verify
|
|
763
|
-
// Read key1 value (again) but from updated map - should NOT call validator again since key1 data hasn't changed
|
|
764
|
-
const key1ValueRedux = key1Redux.value();
|
|
765
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 1, "validator should still be called only once for key1");
|
|
766
|
-
node_assert_1.strict.strictEqual(key1ValueRedux, key1Value, "key1 value should remain unchanged");
|
|
767
|
-
// Test verification
|
|
768
|
-
validatorCallExpected = true;
|
|
769
|
-
point3DValidatorFunction.callCount = 0;
|
|
770
|
-
// key2 should have been updated; so, reading key2 value from
|
|
771
|
-
// original map and updated map should both result in call
|
|
772
|
-
// count increases. Also check for updated value.
|
|
773
|
-
let key2Value = originalMap.get("key2")?.value();
|
|
774
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 1, "validator should be called once for original key2 value read");
|
|
775
|
-
node_assert_1.strict.deepEqual(key2Value, { "x": 2, "y": 2, "z": 2 }, "key2 value from original map should be unchanged");
|
|
776
|
-
key2Value = updatedMap.get("key2")?.value();
|
|
777
|
-
node_assert_1.strict.equal(point3DValidatorFunction.callCount, 2, "validator should be called second time for updated key2 value read");
|
|
778
|
-
node_assert_1.strict.deepEqual(key2Value, { "x": 4, "y": 4, "z": 4 }, "key2 should have updated value");
|
|
779
|
-
});
|
|
780
|
-
});
|
|
781
|
-
});
|
|
782
|
-
});
|
|
783
|
-
});
|
|
784
|
-
//# sourceMappingURL=valueManagers.spec.js.map
|