@arrai-innovations/reactive-helpers 10.4.2 → 11.0.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/.circleci/config.yml +3 -3
- package/README.md +120 -143
- package/config/listCrud.js +0 -1
- package/docs.md +178 -34
- package/package.json +3 -1
- package/tests/unit/use/listFilter.spec.js +195 -167
- package/tests/unit/use/listSearch.spec.js +505 -0
- package/tests/unit/use/listSort.spec.js +0 -1
- package/tests/unit/use/listSubscription.spec.js +91 -108
- package/tests/unit/use/search.spec.js +217 -36
- package/tests/unit/utils/assignReactiveObject.spec.js +0 -1
- package/tests/unit/{use → utils}/watches.spec.js +27 -3
- package/use/cancellableIntent.js +8 -3
- package/use/index.js +2 -0
- package/use/list.js +41 -14
- package/use/listCalculated.js +22 -19
- package/use/listFilter.js +128 -154
- package/use/listInstance.js +0 -28
- package/use/listKeys.js +94 -0
- package/use/listRelated.js +22 -14
- package/use/listSearch.js +358 -0
- package/use/listSort.js +30 -42
- package/use/listSubscription.js +3 -13
- package/use/search.js +154 -64
- package/utils/assignReactiveObject.js +58 -14
- package/utils/index.js +1 -0
- package/utils/keyDiff.js +13 -7
- package/utils/relatedCalculatedHelpers.js +17 -0
- package/utils/watches.js +14 -11
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { doAwaitNot
|
|
1
|
+
import { doAwaitNot } from "../../../utils/index.js";
|
|
2
2
|
import { CancellableResolvable } from "../crudPromise.js";
|
|
3
3
|
import { poll } from "../poll.js";
|
|
4
4
|
import flushPromises from "flush-promises";
|
|
@@ -15,8 +15,10 @@ describe("use/listSubscription.spec.js", function () {
|
|
|
15
15
|
crudListResolvable = [],
|
|
16
16
|
crudSubscribe,
|
|
17
17
|
crudSubscribeResolvable = [],
|
|
18
|
-
passedSubscriptionEventCallback
|
|
18
|
+
passedSubscriptionEventCallback,
|
|
19
|
+
warnMock;
|
|
19
20
|
beforeEach(async () => {
|
|
21
|
+
warnMock = vi.spyOn(console, "warn").mockImplementation(() => undefined);
|
|
20
22
|
crudListResolvable = [];
|
|
21
23
|
crudSubscribeResolvable = [];
|
|
22
24
|
crudListResolvable.push(new CancellableResolvable());
|
|
@@ -31,11 +33,6 @@ describe("use/listSubscription.spec.js", function () {
|
|
|
31
33
|
crudListResolvable.push(newResolvable);
|
|
32
34
|
return newResolvable.promise;
|
|
33
35
|
});
|
|
34
|
-
listCrudModule.setListCrud({
|
|
35
|
-
list: crudList,
|
|
36
|
-
subscribe: crudSubscribe,
|
|
37
|
-
args: { stream: "test_stream" },
|
|
38
|
-
});
|
|
39
36
|
const listSubscriptionModule = await import("../../../use/listSubscription");
|
|
40
37
|
crudSubscribe = vi
|
|
41
38
|
.fn()
|
|
@@ -51,7 +48,11 @@ describe("use/listSubscription.spec.js", function () {
|
|
|
51
48
|
passedSubscriptionEventCallback = subscriptionEventCallback;
|
|
52
49
|
return newResolvable.promise;
|
|
53
50
|
});
|
|
54
|
-
|
|
51
|
+
listCrudModule.setListCrud({
|
|
52
|
+
list: crudList,
|
|
53
|
+
subscribe: crudSubscribe,
|
|
54
|
+
args: { stream: "test_stream" },
|
|
55
|
+
});
|
|
55
56
|
useListInstance = listInstanceModule.useListInstance;
|
|
56
57
|
useListInstances = listInstanceModule.useListInstances;
|
|
57
58
|
|
|
@@ -63,7 +64,7 @@ describe("use/listSubscription.spec.js", function () {
|
|
|
63
64
|
vi.resetAllMocks();
|
|
64
65
|
});
|
|
65
66
|
const fields = ["id", "__str__", "name"];
|
|
66
|
-
describe
|
|
67
|
+
describe("lifecycle", function () {
|
|
67
68
|
it("success", async function () {
|
|
68
69
|
const listArgs = reactive({
|
|
69
70
|
user: 1,
|
|
@@ -135,14 +136,12 @@ describe("use/listSubscription.spec.js", function () {
|
|
|
135
136
|
const returnValue = await listSubscription.unsubscribe();
|
|
136
137
|
expect(listSubscription.state.intendToSubscribe).toBe(false);
|
|
137
138
|
expect(listSubscription.state.intendToList).toBe(false);
|
|
138
|
-
await poll(() => !listSubscription.listIntent.state.active);
|
|
139
139
|
expect(crudListResolvable[0].promise.cancel).toHaveBeenCalledTimes(0);
|
|
140
|
-
|
|
141
140
|
crudSubscribeResolvable[0].cancel.resolve(true);
|
|
142
|
-
await
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
141
|
+
await doAwaitNot({
|
|
142
|
+
obj: listSubscription.subscribeIntent.state,
|
|
143
|
+
prop: "active",
|
|
144
|
+
});
|
|
146
145
|
expect(crudSubscribeResolvable[0].promise.cancel).toHaveBeenCalledWith();
|
|
147
146
|
expect(crudSubscribeResolvable[0].promise.cancel).toHaveBeenCalledTimes(1);
|
|
148
147
|
expect(returnValue).toBe(true);
|
|
@@ -160,8 +159,8 @@ describe("use/listSubscription.spec.js", function () {
|
|
|
160
159
|
props: { listArgs, retrieveArgs },
|
|
161
160
|
});
|
|
162
161
|
listSubscription.subscribe();
|
|
163
|
-
|
|
164
|
-
await
|
|
162
|
+
crudSubscribeResolvable[0].resolve();
|
|
163
|
+
await poll(() => listSubscription.state.subscribed);
|
|
165
164
|
expect(crudSubscribe).toHaveBeenCalledWith({
|
|
166
165
|
crudArgs: { stream: "test_stream" },
|
|
167
166
|
listArgs: { user: 1 },
|
|
@@ -223,27 +222,15 @@ describe("use/listSubscription.spec.js", function () {
|
|
|
223
222
|
},
|
|
224
223
|
"create"
|
|
225
224
|
);
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
)
|
|
236
|
-
).toThrow(ListSubscriptionError);
|
|
237
|
-
expect(() =>
|
|
238
|
-
passedSubscriptionEventCallback(
|
|
239
|
-
{
|
|
240
|
-
id: 1,
|
|
241
|
-
__str__: "qwer",
|
|
242
|
-
name: "qwer",
|
|
243
|
-
},
|
|
244
|
-
"create"
|
|
245
|
-
)
|
|
246
|
-
).toThrow("addFromSubscription: add for existing id in objects (1).");
|
|
225
|
+
passedSubscriptionEventCallback(
|
|
226
|
+
{
|
|
227
|
+
id: 1,
|
|
228
|
+
__str__: "qwer",
|
|
229
|
+
name: "qwer",
|
|
230
|
+
},
|
|
231
|
+
"create"
|
|
232
|
+
);
|
|
233
|
+
expect(warnMock).toHaveBeenCalledWith("addFromSubscription: add for id already in objects (1).");
|
|
247
234
|
|
|
248
235
|
expect(listSubscription.listInstance.state.objects).toEqual({
|
|
249
236
|
1: {
|
|
@@ -253,26 +240,15 @@ describe("use/listSubscription.spec.js", function () {
|
|
|
253
240
|
},
|
|
254
241
|
});
|
|
255
242
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
).toThrow(ListSubscriptionError);
|
|
266
|
-
expect(() =>
|
|
267
|
-
passedSubscriptionEventCallback(
|
|
268
|
-
{
|
|
269
|
-
id: 2,
|
|
270
|
-
__str__: "qwer",
|
|
271
|
-
name: "qwer",
|
|
272
|
-
},
|
|
273
|
-
"update"
|
|
274
|
-
)
|
|
275
|
-
).toThrow("updateFromSubscription: update for id not in objects (2).");
|
|
243
|
+
passedSubscriptionEventCallback(
|
|
244
|
+
{
|
|
245
|
+
id: 2,
|
|
246
|
+
__str__: "qwer",
|
|
247
|
+
name: "qwer",
|
|
248
|
+
},
|
|
249
|
+
"update"
|
|
250
|
+
);
|
|
251
|
+
expect(warnMock).toHaveBeenCalledWith("updateFromSubscription: update for id not in objects (2).");
|
|
276
252
|
|
|
277
253
|
expect(() =>
|
|
278
254
|
passedSubscriptionEventCallback(
|
|
@@ -293,31 +269,25 @@ describe("use/listSubscription.spec.js", function () {
|
|
|
293
269
|
)
|
|
294
270
|
).toThrow("updateFromSubscription: data missing id.\n{ __str__: 'qwer', name: 'qwer' }");
|
|
295
271
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
expect(() =>
|
|
306
|
-
passedSubscriptionEventCallback(
|
|
307
|
-
{
|
|
308
|
-
__str__: "qwer",
|
|
309
|
-
name: "qwer",
|
|
310
|
-
},
|
|
311
|
-
"delete"
|
|
312
|
-
)
|
|
313
|
-
).toThrow("deleteFromSubscription: delete for id not in objects ({ __str__: 'qwer', name: 'qwer' }).");
|
|
314
|
-
|
|
315
|
-
expect(() => passedSubscriptionEventCallback(2, "delete")).toThrow(ListSubscriptionError);
|
|
316
|
-
expect(() => passedSubscriptionEventCallback(2, "delete")).toThrow(
|
|
317
|
-
"deleteFromSubscription: delete for id not in objects (2)."
|
|
272
|
+
passedSubscriptionEventCallback(
|
|
273
|
+
{
|
|
274
|
+
__str__: "qwer",
|
|
275
|
+
name: "qwer",
|
|
276
|
+
},
|
|
277
|
+
"delete"
|
|
278
|
+
);
|
|
279
|
+
expect(warnMock).toHaveBeenCalledWith(
|
|
280
|
+
"deleteFromSubscription: delete for id not in objects ({ __str__: 'qwer', name: 'qwer' })."
|
|
318
281
|
);
|
|
319
282
|
|
|
320
|
-
|
|
283
|
+
passedSubscriptionEventCallback(2, "delete");
|
|
284
|
+
expect(warnMock).toHaveBeenCalledWith("deleteFromSubscription: delete for id not in objects (2).");
|
|
285
|
+
|
|
286
|
+
await poll(() => listSubscription.state.subscribed);
|
|
287
|
+
const unsubscribe = listSubscription.unsubscribe();
|
|
288
|
+
crudSubscribeResolvable[0].cancel.resolve(true);
|
|
289
|
+
const returnValue = await unsubscribe;
|
|
290
|
+
await poll(() => !listSubscription.state.subscribed);
|
|
321
291
|
expect(crudSubscribeResolvable[0].promise.cancel).toHaveBeenCalledWith();
|
|
322
292
|
expect(crudSubscribeResolvable[0].promise.cancel).toHaveBeenCalledTimes(1);
|
|
323
293
|
expect(returnValue).toBe(true);
|
|
@@ -338,8 +308,8 @@ describe("use/listSubscription.spec.js", function () {
|
|
|
338
308
|
});
|
|
339
309
|
expect(listSubscription.unsubscribe()).toBe(false);
|
|
340
310
|
listSubscription.subscribe();
|
|
341
|
-
|
|
342
|
-
await
|
|
311
|
+
crudSubscribeResolvable[0].resolve();
|
|
312
|
+
await poll(() => listSubscription.state.subscribed);
|
|
343
313
|
expect(crudSubscribe).toHaveBeenCalledWith({
|
|
344
314
|
crudArgs: { stream: "test_stream" },
|
|
345
315
|
listArgs: { user: 1 },
|
|
@@ -348,9 +318,10 @@ describe("use/listSubscription.spec.js", function () {
|
|
|
348
318
|
});
|
|
349
319
|
expect(crudSubscribe).toHaveBeenCalledTimes(1);
|
|
350
320
|
|
|
351
|
-
const
|
|
352
|
-
|
|
353
|
-
await
|
|
321
|
+
const unsubscribePromise = listSubscription.unsubscribe();
|
|
322
|
+
crudSubscribeResolvable[0].cancel.resolve(true);
|
|
323
|
+
const returnValue = await unsubscribePromise;
|
|
324
|
+
await poll(() => !listSubscription.state.subscribed);
|
|
354
325
|
expect(crudSubscribeResolvable[0].promise.cancel).toHaveBeenCalledWith();
|
|
355
326
|
expect(crudSubscribeResolvable[0].promise.cancel).toHaveBeenCalledTimes(1);
|
|
356
327
|
expect(returnValue).toBe(true);
|
|
@@ -365,10 +336,13 @@ describe("use/listSubscription.spec.js", function () {
|
|
|
365
336
|
const retrieveArgs = reactive({
|
|
366
337
|
fields: fields,
|
|
367
338
|
});
|
|
368
|
-
const
|
|
339
|
+
const listSubscriptionProps = reactive({
|
|
369
340
|
listArgs,
|
|
370
341
|
retrieveArgs,
|
|
371
342
|
});
|
|
343
|
+
const listSubscription = useListSubscription({
|
|
344
|
+
props: listSubscriptionProps,
|
|
345
|
+
});
|
|
372
346
|
|
|
373
347
|
const returnValue = await listSubscription.unsubscribe();
|
|
374
348
|
expect(crudSubscribeResolvable[0].promise.cancel).toHaveBeenCalledTimes(0);
|
|
@@ -404,7 +378,10 @@ describe("use/listSubscription.spec.js", function () {
|
|
|
404
378
|
expect(firstReturnValue).toBe(true);
|
|
405
379
|
expect(secondReturnValue).toBe(false);
|
|
406
380
|
|
|
407
|
-
const
|
|
381
|
+
const unsubscribePromise = listSubscription.unsubscribe();
|
|
382
|
+
crudSubscribeResolvable[0].cancel.resolve(true);
|
|
383
|
+
const returnValue = await unsubscribePromise;
|
|
384
|
+
await poll(() => !listSubscription.state.subscribed);
|
|
408
385
|
expect(crudSubscribeResolvable[0].promise.cancel).toHaveBeenCalledWith();
|
|
409
386
|
expect(crudSubscribeResolvable[0].promise.cancel).toHaveBeenCalledTimes(1);
|
|
410
387
|
expect(returnValue).toBe(true);
|
|
@@ -474,7 +451,10 @@ describe("use/listSubscription.spec.js", function () {
|
|
|
474
451
|
|
|
475
452
|
expect(listInstance.state.objects).toEqual({});
|
|
476
453
|
|
|
477
|
-
const
|
|
454
|
+
const unsubscribePromise = listSubscription.unsubscribe();
|
|
455
|
+
crudSubscribeResolvable[0].cancel.resolve(true);
|
|
456
|
+
const returnValue = await unsubscribePromise;
|
|
457
|
+
await poll(() => !listSubscription.state.subscribed);
|
|
478
458
|
expect(crudSubscribeResolvable[0].promise.cancel).toHaveBeenCalledWith();
|
|
479
459
|
expect(crudSubscribeResolvable[0].promise.cancel).toHaveBeenCalledTimes(1);
|
|
480
460
|
expect(returnValue).toBe(true);
|
|
@@ -489,14 +469,13 @@ describe("use/listSubscription.spec.js", function () {
|
|
|
489
469
|
fields: fields,
|
|
490
470
|
});
|
|
491
471
|
const listSubscription = useListSubscription({
|
|
492
|
-
props: {
|
|
472
|
+
props: reactive({
|
|
493
473
|
listArgs,
|
|
494
474
|
retrieveArgs,
|
|
495
|
-
},
|
|
475
|
+
}),
|
|
496
476
|
});
|
|
497
477
|
listSubscription.subscribe();
|
|
498
|
-
await
|
|
499
|
-
await flushPromises();
|
|
478
|
+
await poll(() => listSubscription.state.subscribed);
|
|
500
479
|
expect(crudSubscribe).toHaveBeenCalledWith({
|
|
501
480
|
crudArgs: { stream: "test_stream" },
|
|
502
481
|
listArgs: { user: 1 },
|
|
@@ -505,36 +484,40 @@ describe("use/listSubscription.spec.js", function () {
|
|
|
505
484
|
});
|
|
506
485
|
expect(crudSubscribe).toHaveBeenCalledTimes(1);
|
|
507
486
|
expect(listSubscription.state.subscribed).toBe(true);
|
|
508
|
-
|
|
509
|
-
|
|
487
|
+
expect(listSubscription.state.intendToSubscribe).toBe(true);
|
|
488
|
+
expect(listSubscription.state.intendToList).toBe(true);
|
|
510
489
|
await crudSubscribeResolvable[0].resolve();
|
|
511
490
|
await crudListResolvable[0].resolve();
|
|
512
|
-
await
|
|
513
|
-
await flushPromises();
|
|
491
|
+
await poll(() => listSubscription.state.subscribed);
|
|
514
492
|
listArgs.user = 2;
|
|
515
493
|
retrieveArgs.fields = ["name"];
|
|
516
494
|
await nextTick();
|
|
517
|
-
await crudSubscribeResolvable[
|
|
495
|
+
await poll(() => crudSubscribeResolvable[0].promise.cancel.mock.calls.length === 1);
|
|
496
|
+
await crudSubscribeResolvable[0].cancel.resolve(true);
|
|
497
|
+
await poll(() => crudListResolvable.length === 2);
|
|
518
498
|
await crudListResolvable[1].resolve();
|
|
519
|
-
await
|
|
520
|
-
|
|
521
|
-
prop: "resolving",
|
|
522
|
-
});
|
|
523
|
-
expect(crudSubscribeResolvable[0].promise.cancel).toHaveBeenCalledWith();
|
|
524
|
-
expect(crudSubscribeResolvable[0].promise.cancel).toHaveBeenCalledTimes(1);
|
|
499
|
+
await poll(() => crudSubscribeResolvable.length === 2);
|
|
500
|
+
await crudSubscribeResolvable[1].resolve();
|
|
525
501
|
expect(crudSubscribe).toHaveBeenCalledWith({
|
|
526
502
|
crudArgs: { stream: "test_stream" },
|
|
527
503
|
listArgs: { user: 2 },
|
|
528
504
|
retrieveArgs: { fields: ["name"] },
|
|
529
505
|
subscriptionEventCallback: expect.any(Function),
|
|
530
506
|
});
|
|
507
|
+
expect(crudSubscribeResolvable.length).toBe(2);
|
|
508
|
+
await crudSubscribeResolvable[1].resolve();
|
|
509
|
+
await crudListResolvable[1].resolve();
|
|
510
|
+
await poll(() => listSubscription.state.subscribed);
|
|
511
|
+
expect(crudSubscribeResolvable[0].promise.cancel).toHaveBeenCalledWith();
|
|
512
|
+
expect(crudSubscribeResolvable[0].promise.cancel).toHaveBeenCalledTimes(1);
|
|
513
|
+
|
|
531
514
|
expect(crudSubscribe).toHaveBeenCalledTimes(2);
|
|
532
515
|
|
|
533
|
-
const
|
|
516
|
+
const unsubscribePromise = listSubscription.unsubscribe();
|
|
517
|
+
crudSubscribeResolvable[1].cancel.resolve(true);
|
|
518
|
+
const returnValue = await unsubscribePromise;
|
|
534
519
|
expect(returnValue).toBe(true);
|
|
535
|
-
await
|
|
536
|
-
await flushPromises();
|
|
537
|
-
await doAwaitTimeout(1500);
|
|
520
|
+
await poll(() => !listSubscription.state.subscribed);
|
|
538
521
|
expect(crudSubscribeResolvable[1].promise.cancel).toHaveBeenCalledWith();
|
|
539
522
|
expect(crudSubscribeResolvable[1].promise.cancel).toHaveBeenCalledTimes(1);
|
|
540
523
|
expect(listSubscription.state.subscribed).toBe(false);
|
|
@@ -1,67 +1,248 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { doAwaitNot } from "../../../utils/index.js";
|
|
2
|
+
import { reactive } from "vue";
|
|
2
3
|
|
|
3
4
|
describe("use/search", () => {
|
|
4
|
-
let useSearch
|
|
5
|
+
let useSearch;
|
|
5
6
|
beforeEach(async () => {
|
|
6
7
|
const searchModule = await import("../../../use/search");
|
|
7
8
|
useSearch = searchModule.useSearch;
|
|
8
|
-
setDefaultSearchOptions = searchModule.setDefaultSearchOptions;
|
|
9
|
-
setDefaultSearchOptions({
|
|
10
|
-
throttle: 150,
|
|
11
|
-
});
|
|
12
9
|
});
|
|
13
10
|
it("should allow adding items to the index", async () => {
|
|
14
|
-
const search = useSearch(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
const search = useSearch({
|
|
12
|
+
props: reactive({
|
|
13
|
+
customDocumentOptions: {
|
|
14
|
+
tokenize: "forward",
|
|
15
|
+
document: {
|
|
16
|
+
id: "id",
|
|
17
|
+
index: ["field1", "field2"],
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
}),
|
|
21
|
+
throttle: 50,
|
|
22
|
+
});
|
|
23
|
+
search.addIndex({
|
|
24
|
+
id: 1,
|
|
25
|
+
field1: "test index value field1 one",
|
|
26
|
+
field2: "test index value field2 one",
|
|
27
|
+
});
|
|
28
|
+
search.addIndex({
|
|
29
|
+
id: 2,
|
|
30
|
+
field1: "test index value field1 two",
|
|
31
|
+
field2: "test index value field2 two",
|
|
32
|
+
});
|
|
33
|
+
search.addIndex({
|
|
34
|
+
id: 3,
|
|
35
|
+
field1: "test index value field1 three",
|
|
36
|
+
field2: "test index value field2 three",
|
|
37
|
+
});
|
|
38
|
+
await doAwaitNot({
|
|
39
|
+
obj: search.state,
|
|
40
|
+
prop: "running",
|
|
41
|
+
});
|
|
19
42
|
expect(Object.keys(search.state.results)).toEqual([]);
|
|
20
43
|
search.state.search = "test";
|
|
21
|
-
await
|
|
22
|
-
|
|
44
|
+
await doAwaitNot({
|
|
45
|
+
obj: search.state,
|
|
46
|
+
prop: "running",
|
|
47
|
+
});
|
|
23
48
|
expect(Object.keys(search.state.results)).toEqual(["1", "2", "3"]);
|
|
24
49
|
});
|
|
25
50
|
it("should allow removing items from the index", async () => {
|
|
26
|
-
const search = useSearch(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
51
|
+
const search = useSearch({
|
|
52
|
+
props: reactive({
|
|
53
|
+
customDocumentOptions: {
|
|
54
|
+
tokenize: "forward",
|
|
55
|
+
document: {
|
|
56
|
+
id: "id",
|
|
57
|
+
index: ["field1", "field2"],
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
}),
|
|
61
|
+
throttle: 50,
|
|
62
|
+
});
|
|
63
|
+
search.addIndex({
|
|
64
|
+
id: 1,
|
|
65
|
+
field1: "test index value field1 one",
|
|
66
|
+
field2: "test index value field2 one",
|
|
67
|
+
});
|
|
68
|
+
search.addIndex({
|
|
69
|
+
id: 2,
|
|
70
|
+
field1: "test index value field1 two",
|
|
71
|
+
field2: "test index value field2 two",
|
|
72
|
+
});
|
|
73
|
+
search.addIndex({
|
|
74
|
+
id: 3,
|
|
75
|
+
field1: "test index value field1 three",
|
|
76
|
+
field2: "test index value field2 three",
|
|
77
|
+
});
|
|
30
78
|
search.state.search = "test";
|
|
31
|
-
await
|
|
32
|
-
|
|
79
|
+
await doAwaitNot({
|
|
80
|
+
obj: search.state,
|
|
81
|
+
prop: "running",
|
|
82
|
+
});
|
|
83
|
+
|
|
33
84
|
expect(Object.keys(search.state.results)).toEqual(["1", "2", "3"]);
|
|
34
85
|
search.removeIndex(2);
|
|
35
|
-
await
|
|
86
|
+
await doAwaitNot({
|
|
87
|
+
obj: search.state,
|
|
88
|
+
prop: "running",
|
|
89
|
+
});
|
|
36
90
|
expect(Object.keys(search.state.results)).toEqual(["1", "3"]);
|
|
37
91
|
});
|
|
38
92
|
it("should allow updating items in the index", async () => {
|
|
39
|
-
const search = useSearch(
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
93
|
+
const search = useSearch({
|
|
94
|
+
props: reactive({
|
|
95
|
+
customDocumentOptions: {
|
|
96
|
+
tokenize: "forward",
|
|
97
|
+
document: {
|
|
98
|
+
id: "id",
|
|
99
|
+
index: ["field1", "field2"],
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
}),
|
|
103
|
+
throttle: 50,
|
|
104
|
+
});
|
|
105
|
+
search.addIndex({
|
|
106
|
+
id: 1,
|
|
107
|
+
field1: "test index value field1 one",
|
|
108
|
+
field2: "test index value field2 one",
|
|
109
|
+
});
|
|
110
|
+
search.addIndex({
|
|
111
|
+
id: 2,
|
|
112
|
+
field1: "test index value field1 two",
|
|
113
|
+
field2: "test index value field2 two",
|
|
114
|
+
});
|
|
115
|
+
search.addIndex({
|
|
116
|
+
id: 3,
|
|
117
|
+
field1: "test index value field1 three",
|
|
118
|
+
field2: "test index value field2 three",
|
|
119
|
+
});
|
|
43
120
|
search.state.search = "test";
|
|
44
|
-
await
|
|
45
|
-
|
|
121
|
+
await doAwaitNot({
|
|
122
|
+
obj: search.state,
|
|
123
|
+
prop: "running",
|
|
124
|
+
});
|
|
46
125
|
expect(Object.keys(search.state.results)).toEqual(["1", "2", "3"]);
|
|
47
|
-
search.updateIndex(
|
|
48
|
-
|
|
126
|
+
search.updateIndex({
|
|
127
|
+
id: 2,
|
|
128
|
+
field1: "twest index value field1 two updated",
|
|
129
|
+
field2: "twest index value field2 two updated",
|
|
130
|
+
});
|
|
131
|
+
await doAwaitNot({
|
|
132
|
+
obj: search.state,
|
|
133
|
+
prop: "running",
|
|
134
|
+
});
|
|
49
135
|
expect(Object.keys(search.state.results)).toEqual(["1", "3"]);
|
|
50
136
|
search.state.search = "two";
|
|
51
|
-
await
|
|
137
|
+
await doAwaitNot({
|
|
138
|
+
obj: search.state,
|
|
139
|
+
prop: "running",
|
|
140
|
+
});
|
|
52
141
|
expect(Object.keys(search.state.results)).toEqual(["2"]);
|
|
53
142
|
});
|
|
54
143
|
it("should allow clearing all items from the index", async () => {
|
|
55
|
-
const search = useSearch(
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
144
|
+
const search = useSearch({
|
|
145
|
+
props: reactive({
|
|
146
|
+
customDocumentOptions: {
|
|
147
|
+
tokenize: "forward",
|
|
148
|
+
document: {
|
|
149
|
+
id: "id",
|
|
150
|
+
index: ["field1", "field2"],
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
}),
|
|
154
|
+
throttle: 50,
|
|
155
|
+
});
|
|
156
|
+
search.addIndex({
|
|
157
|
+
id: 1,
|
|
158
|
+
field1: "test index value field1 one",
|
|
159
|
+
field2: "test index value field2 one",
|
|
160
|
+
});
|
|
161
|
+
search.addIndex({
|
|
162
|
+
id: 2,
|
|
163
|
+
field1: "test index value field1 two",
|
|
164
|
+
field2: "test index value field2 two",
|
|
165
|
+
});
|
|
166
|
+
search.addIndex({
|
|
167
|
+
id: 3,
|
|
168
|
+
field1: "test index value field1 three",
|
|
169
|
+
field2: "test index value field2 three",
|
|
170
|
+
});
|
|
59
171
|
search.state.search = "test";
|
|
60
|
-
await
|
|
61
|
-
|
|
172
|
+
await doAwaitNot({
|
|
173
|
+
obj: search.state,
|
|
174
|
+
prop: "running",
|
|
175
|
+
});
|
|
62
176
|
expect(Object.keys(search.state.results)).toEqual(["1", "2", "3"]);
|
|
63
177
|
search.clearIndex();
|
|
64
|
-
await doAwaitTimeout(200);
|
|
65
178
|
expect(Object.keys(search.state.results)).toEqual([]);
|
|
66
179
|
});
|
|
180
|
+
it("should allow changing the index fields", async () => {
|
|
181
|
+
const searchProps = reactive({
|
|
182
|
+
customDocumentOptions: {
|
|
183
|
+
tokenize: "forward",
|
|
184
|
+
document: {
|
|
185
|
+
id: "id",
|
|
186
|
+
index: ["field1", "field2"],
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
});
|
|
190
|
+
const search = useSearch({
|
|
191
|
+
props: searchProps,
|
|
192
|
+
throttle: 50,
|
|
193
|
+
});
|
|
194
|
+
search.addIndex({
|
|
195
|
+
id: 1,
|
|
196
|
+
field1: "test index value field1 one",
|
|
197
|
+
field2: "test index value field2 one",
|
|
198
|
+
});
|
|
199
|
+
search.addIndex({
|
|
200
|
+
id: 2,
|
|
201
|
+
field1: "test index value field1 two",
|
|
202
|
+
field2: "test index value field2 two",
|
|
203
|
+
});
|
|
204
|
+
search.addIndex({
|
|
205
|
+
id: 3,
|
|
206
|
+
field1: "test index value field1 three",
|
|
207
|
+
field2: "test index value field2 three",
|
|
208
|
+
});
|
|
209
|
+
search.state.search = "field2";
|
|
210
|
+
await doAwaitNot({
|
|
211
|
+
obj: search.state,
|
|
212
|
+
prop: "running",
|
|
213
|
+
});
|
|
214
|
+
expect(Object.keys(search.state.results)).toEqual(["1", "2", "3"]);
|
|
215
|
+
// implied clearIndex
|
|
216
|
+
searchProps.customDocumentOptions.document.index = ["field1"];
|
|
217
|
+
// indexes cannot be added until search.events newIndex is fired
|
|
218
|
+
let eventResolve = null;
|
|
219
|
+
const eventPromise = new Promise((resolve) => {
|
|
220
|
+
eventResolve = resolve;
|
|
221
|
+
});
|
|
222
|
+
search.events.addEventListener("newIndex", eventResolve);
|
|
223
|
+
await eventPromise;
|
|
224
|
+
search.addIndex({
|
|
225
|
+
id: 1,
|
|
226
|
+
field1: "test index value field1 one",
|
|
227
|
+
});
|
|
228
|
+
search.addIndex({
|
|
229
|
+
id: 2,
|
|
230
|
+
field1: "test index value field1 two",
|
|
231
|
+
});
|
|
232
|
+
search.addIndex({
|
|
233
|
+
id: 3,
|
|
234
|
+
field1: "test index value field1 three",
|
|
235
|
+
});
|
|
236
|
+
await doAwaitNot({
|
|
237
|
+
obj: search.state,
|
|
238
|
+
prop: "running",
|
|
239
|
+
});
|
|
240
|
+
expect(Object.keys(search.state.results)).toEqual([]);
|
|
241
|
+
search.state.search = "field1";
|
|
242
|
+
await doAwaitNot({
|
|
243
|
+
obj: search.state,
|
|
244
|
+
prop: "running",
|
|
245
|
+
});
|
|
246
|
+
expect(Object.keys(search.state.results)).toEqual(["1", "2", "3"]);
|
|
247
|
+
});
|
|
67
248
|
});
|
|
@@ -6,7 +6,6 @@ import {
|
|
|
6
6
|
import { computed, EffectScope, effectScope, reactive, toRef, unref } from "vue";
|
|
7
7
|
|
|
8
8
|
describe("utils/assignReactiveObject", function () {
|
|
9
|
-
describe.skip("addOrUpdateReactiveObject", function () {});
|
|
10
9
|
describe("assignReactiveObject", function () {
|
|
11
10
|
describe("should update the target", function () {
|
|
12
11
|
it("when both target and source are not reactive", function () {
|
|
@@ -6,10 +6,9 @@ import {
|
|
|
6
6
|
doAwaitTimeout,
|
|
7
7
|
ImmediateStopWatch,
|
|
8
8
|
} from "../../../utils/index.js";
|
|
9
|
-
import {
|
|
10
|
-
import { nextTick, reactive } from "vue";
|
|
9
|
+
import { nextTick, reactive, toRef } from "vue";
|
|
11
10
|
|
|
12
|
-
describe("
|
|
11
|
+
describe("utils/watches", () => {
|
|
13
12
|
let timeout, reactiveObject, awaitNot;
|
|
14
13
|
beforeEach(async () => {
|
|
15
14
|
reactiveObject = reactive({});
|
|
@@ -199,6 +198,31 @@ describe("use/watches", () => {
|
|
|
199
198
|
await expect(awaitNot.promise).rejects.toThrow(AwaitNotError);
|
|
200
199
|
});
|
|
201
200
|
});
|
|
201
|
+
describe("doAwaitNot takes a ref instead of an obj and prop", () => {
|
|
202
|
+
it("resolves", async () => {
|
|
203
|
+
awaitNot = new AwaitNot({
|
|
204
|
+
ref: toRef(reactiveObject, "prop"),
|
|
205
|
+
couldAlreadyBeFalse: false,
|
|
206
|
+
timeout: 500,
|
|
207
|
+
});
|
|
208
|
+
awaitNot.start();
|
|
209
|
+
reactiveObject.prop = true;
|
|
210
|
+
await nextTick();
|
|
211
|
+
reactiveObject.prop = false;
|
|
212
|
+
await expect(awaitNot.promise).resolves.toBeUndefined();
|
|
213
|
+
});
|
|
214
|
+
it("times out", async () => {
|
|
215
|
+
awaitNot = new AwaitNot({
|
|
216
|
+
ref: toRef(reactiveObject, "prop"),
|
|
217
|
+
couldAlreadyBeFalse: false,
|
|
218
|
+
timeout: 500,
|
|
219
|
+
});
|
|
220
|
+
awaitNot.start();
|
|
221
|
+
reactiveObject.prop = true;
|
|
222
|
+
await nextTick();
|
|
223
|
+
await expect(awaitNot.promise).rejects.toThrow(AwaitNotError);
|
|
224
|
+
});
|
|
225
|
+
});
|
|
202
226
|
describe("ImmediateStopWatch", () => {
|
|
203
227
|
it("responds to multiple calls", async () => {
|
|
204
228
|
const immediateStopWatch = new ImmediateStopWatch({});
|