@peerbit/indexer-tests 1.1.2 → 1.1.3-5cf61cb

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/src/tests.ts CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  variant,
8
8
  vec,
9
9
  } from "@dao-xyz/borsh";
10
- import { randomBytes } from "@peerbit/crypto";
10
+ import { randomBytes, sha256Base64Sync } from "@peerbit/crypto";
11
11
  import {
12
12
  And,
13
13
  BoolQuery,
@@ -20,7 +20,6 @@ import {
20
20
  IntegerCompare,
21
21
  IsNull,
22
22
  type IterateOptions,
23
- Nested,
24
23
  Not,
25
24
  Or,
26
25
  Query,
@@ -289,7 +288,7 @@ export const tests = (
289
288
 
290
289
  afterEach(async () => {
291
290
  defaultDocs = [];
292
- await indices?.stop?.();
291
+ await indices?.drop?.();
293
292
  });
294
293
 
295
294
  describe("indexBy", () => {
@@ -848,7 +847,8 @@ export const tests = (
848
847
  });
849
848
  });
850
849
  });
851
- +it("bool", async () => {
850
+
851
+ it("bool", async () => {
852
852
  await setupDefault();
853
853
 
854
854
  const responses = await search(store, {
@@ -911,38 +911,203 @@ export const tests = (
911
911
  @field({ type: vec(Document) })
912
912
  documents: Document[];
913
913
 
914
- constructor(properties?: { documents: Document[] }) {
914
+ constructor(properties?: {
915
+ id?: Uint8Array;
916
+ documents: Document[];
917
+ }) {
915
918
  this.id = randomBytes(32);
916
919
  this.documents = properties?.documents || [];
917
920
  }
918
921
  }
919
922
 
920
- it("can search", async () => {
921
- const out = await setup({ schema: DocumentsVec });
922
- store = out.store;
923
+ describe("search", () => {
924
+ let d1: DocumentsVec;
925
+ let d2: DocumentsVec;
926
+ let d3: DocumentsVec;
923
927
 
924
- const d1 = new DocumentsVec({
925
- documents: [
926
- new Document({ id: uuid(), number: 123n, tags: [] }),
927
- ],
928
- });
929
- await store.put(d1);
930
- await store.put(
931
- new DocumentsVec({
928
+ beforeEach(async () => {
929
+ const out = await setup({ schema: DocumentsVec });
930
+ store = out.store;
931
+
932
+ d1 = new DocumentsVec({
933
+ id: new Uint8Array([0]),
934
+ documents: [
935
+ new Document({ id: uuid(), number: 123n, tags: [] }),
936
+ ],
937
+ });
938
+ await store.put(d1);
939
+
940
+ d2 = new DocumentsVec({
941
+ id: new Uint8Array([1]),
932
942
  documents: [
933
943
  new Document({ id: uuid(), number: 124n, tags: [] }),
934
944
  ],
935
- }),
936
- );
945
+ });
937
946
 
938
- const results = await search(store, {
939
- query: new IntegerCompare({
940
- key: ["documents", "number"],
941
- compare: Compare.Equal,
942
- value: d1.documents[0]!.number,
943
- }),
947
+ await store.put(d2);
948
+
949
+ d3 = new DocumentsVec({
950
+ id: new Uint8Array([2]),
951
+ documents: [
952
+ new Document({ id: uuid(), number: 122n, tags: [] }),
953
+ new Document({ id: uuid(), number: 125n, tags: [] }),
954
+ ],
955
+ });
956
+
957
+ await store.put(d3);
958
+ });
959
+
960
+ it("match", async () => {
961
+ // equality
962
+ const results = await search(store, {
963
+ query: new IntegerCompare({
964
+ key: ["documents", "number"],
965
+ compare: Compare.Equal,
966
+ value: d1.documents[0]!.number,
967
+ }),
968
+ });
969
+ expect(results.map((x) => x.value.id)).to.deep.equal([d1.id]);
970
+ });
971
+
972
+ describe("logical", () => {
973
+ it("and", async () => {
974
+ // can not be equal to two different things at once
975
+ let results = await search(store, {
976
+ query: [
977
+ new And([
978
+ new IntegerCompare({
979
+ key: ["documents", "number"],
980
+ compare: Compare.Equal,
981
+ value: 123n,
982
+ }),
983
+ new IntegerCompare({
984
+ key: ["documents", "number"],
985
+ compare: Compare.Equal,
986
+ value: 124n,
987
+ }),
988
+ ]),
989
+ ],
990
+ });
991
+ expect(results).to.have.length(0);
992
+
993
+ // can not be between two different things at once
994
+ results = await search(store, {
995
+ query: [
996
+ new And([
997
+ new IntegerCompare({
998
+ key: ["documents", "number"],
999
+ compare: Compare.Less,
1000
+ value: 1000n,
1001
+ }),
1002
+ new IntegerCompare({
1003
+ key: ["documents", "number"],
1004
+ compare: Compare.Greater,
1005
+ value: 1000n,
1006
+ }),
1007
+ ]),
1008
+ ],
1009
+ });
1010
+ expect(results).to.have.length(0);
1011
+
1012
+ // between one value matches
1013
+ results = await search(store, {
1014
+ query: [
1015
+ new Or([
1016
+ new IntegerCompare({
1017
+ key: ["documents", "number"],
1018
+ compare: Compare.Less,
1019
+ value: 124n,
1020
+ }),
1021
+ new IntegerCompare({
1022
+ key: ["documents", "number"],
1023
+ compare: Compare.GreaterOrEqual,
1024
+ value: 125n,
1025
+ }),
1026
+ ]),
1027
+ ],
1028
+ });
1029
+
1030
+ // because each query is applied separately
1031
+ expect(
1032
+ results.map((x) => sha256Base64Sync(x.value.id)),
1033
+ ).to.have.members([d1.id, d3.id].map(sha256Base64Sync));
1034
+
1035
+ results = await search(store, {
1036
+ query: [
1037
+ new And([
1038
+ new IntegerCompare({
1039
+ key: ["documents", "number"],
1040
+ compare: Compare.Less,
1041
+ value: 124n,
1042
+ }),
1043
+ new IntegerCompare({
1044
+ key: ["documents", "number"],
1045
+ compare: Compare.GreaterOrEqual,
1046
+ value: 123n,
1047
+ }),
1048
+ ]),
1049
+ ],
1050
+ });
1051
+
1052
+ expect(results.map((x) => x.value.id)).to.deep.eq([d1.id]);
1053
+ });
1054
+
1055
+ it("or", async () => {
1056
+ const results3 = await search(store, {
1057
+ query: [
1058
+ new Or([
1059
+ new IntegerCompare({
1060
+ key: ["documents", "number"],
1061
+ compare: Compare.Equal,
1062
+ value: 123n,
1063
+ }),
1064
+ new IntegerCompare({
1065
+ key: ["documents", "number"],
1066
+ compare: Compare.Equal,
1067
+ value: 124n,
1068
+ }),
1069
+ ]),
1070
+ ],
1071
+ });
1072
+
1073
+ expect(
1074
+ results3.map((x) => sha256Base64Sync(x.value.id)),
1075
+ ).to.have.members([
1076
+ sha256Base64Sync(d1.id),
1077
+ sha256Base64Sync(d2.id),
1078
+ ]);
1079
+ });
1080
+
1081
+ it("or arr, or field", async () => {
1082
+ const results3 = await search(store, {
1083
+ query: [
1084
+ new Or([
1085
+ new IntegerCompare({
1086
+ key: ["documents", "number"],
1087
+ compare: Compare.Equal,
1088
+ value: 123n,
1089
+ }),
1090
+ new IntegerCompare({
1091
+ key: ["documents", "number"],
1092
+ compare: Compare.Equal,
1093
+ value: 124n,
1094
+ }),
1095
+ new ByteMatchQuery({
1096
+ key: "id",
1097
+ value: new Uint8Array([1]),
1098
+ }),
1099
+ ]),
1100
+ ],
1101
+ });
1102
+
1103
+ expect(
1104
+ results3.map((x) => sha256Base64Sync(x.value.id)),
1105
+ ).to.have.members([
1106
+ sha256Base64Sync(d1.id),
1107
+ sha256Base64Sync(d2.id),
1108
+ ]);
1109
+ });
944
1110
  });
945
- expect(results.map((x) => x.value.id)).to.deep.equal([d1.id]);
946
1111
  });
947
1112
 
948
1113
  it("update array", async () => {
@@ -1048,6 +1213,342 @@ export const tests = (
1048
1213
  ).to.equal(0);
1049
1214
  });
1050
1215
  });
1216
+
1217
+ describe("simple value", () => {
1218
+ class ArrayDocument {
1219
+ @field({ type: Uint8Array })
1220
+ id: Uint8Array;
1221
+
1222
+ @field({ type: vec("u32") })
1223
+ array: number[];
1224
+
1225
+ constructor(properties?: { id?: Uint8Array; array: number[] }) {
1226
+ this.id = properties.id || randomBytes(32);
1227
+ this.array = properties?.array || [];
1228
+ }
1229
+ }
1230
+
1231
+ describe("search", () => {
1232
+ let d1: ArrayDocument;
1233
+ let d2: ArrayDocument;
1234
+ let d3: ArrayDocument;
1235
+
1236
+ beforeEach(async () => {
1237
+ const out = await setup({ schema: ArrayDocument });
1238
+ store = out.store;
1239
+
1240
+ d1 = new ArrayDocument({
1241
+ id: new Uint8Array([0]),
1242
+ array: [1],
1243
+ });
1244
+ await store.put(d1);
1245
+
1246
+ d2 = new ArrayDocument({
1247
+ id: new Uint8Array([1]),
1248
+ array: [2],
1249
+ });
1250
+
1251
+ await store.put(d2);
1252
+
1253
+ d3 = new ArrayDocument({
1254
+ id: new Uint8Array([2]),
1255
+ array: [0, 3],
1256
+ });
1257
+
1258
+ await store.put(d3);
1259
+ });
1260
+
1261
+ it("match", async () => {
1262
+ // equality
1263
+ const results = await search(store, {
1264
+ query: new IntegerCompare({
1265
+ key: ["array"],
1266
+ compare: Compare.Equal,
1267
+ value: d1.array[0]!,
1268
+ }),
1269
+ });
1270
+ expect(results.map((x) => x.value.id)).to.deep.equal([d1.id]);
1271
+ });
1272
+
1273
+ describe("logical", () => {
1274
+ it("and", async () => {
1275
+ // can not be equal to two different things at once
1276
+ let results = await search(store, {
1277
+ query: [
1278
+ new And([
1279
+ new IntegerCompare({
1280
+ key: ["array"],
1281
+ compare: Compare.Equal,
1282
+ value: d1.array[0]!,
1283
+ }),
1284
+ new IntegerCompare({
1285
+ key: ["array"],
1286
+ compare: Compare.Equal,
1287
+ value: d2.array[0]!,
1288
+ }),
1289
+ ]),
1290
+ ],
1291
+ });
1292
+ expect(results).to.have.length(0);
1293
+
1294
+ // can not be between two different things at once
1295
+ results = await search(store, {
1296
+ query: [
1297
+ new And([
1298
+ new IntegerCompare({
1299
+ key: ["array"],
1300
+ compare: Compare.Less,
1301
+ value: 1000,
1302
+ }),
1303
+ new IntegerCompare({
1304
+ key: ["array"],
1305
+ compare: Compare.Greater,
1306
+ value: 1000,
1307
+ }),
1308
+ ]),
1309
+ ],
1310
+ });
1311
+ expect(results).to.have.length(0);
1312
+
1313
+ // between one value matches
1314
+ results = await search(store, {
1315
+ query: [
1316
+ new Or([
1317
+ new IntegerCompare({
1318
+ key: ["array"],
1319
+ compare: Compare.Less,
1320
+ value: 2,
1321
+ }),
1322
+ new IntegerCompare({
1323
+ key: ["array"],
1324
+ compare: Compare.GreaterOrEqual,
1325
+ value: 3,
1326
+ }),
1327
+ ]),
1328
+ ],
1329
+ });
1330
+
1331
+ // because each query is applied separately
1332
+ expect(
1333
+ results.map((x) => sha256Base64Sync(x.value.id)),
1334
+ ).to.have.members([d1.id, d3.id].map(sha256Base64Sync));
1335
+
1336
+ results = await search(store, {
1337
+ query: [
1338
+ new And([
1339
+ new IntegerCompare({
1340
+ key: ["array"],
1341
+ compare: Compare.Less,
1342
+ value: 2,
1343
+ }),
1344
+ new IntegerCompare({
1345
+ key: ["array"],
1346
+ compare: Compare.GreaterOrEqual,
1347
+ value: 1,
1348
+ }),
1349
+ ]),
1350
+ ],
1351
+ });
1352
+
1353
+ // using nested path will apply the queries together
1354
+ expect(
1355
+ results.map((x) => sha256Base64Sync(x.value.id)),
1356
+ ).to.have.members([d1.id].map(sha256Base64Sync));
1357
+ });
1358
+
1359
+ it("or", async () => {
1360
+ const results3 = await search(store, {
1361
+ query: [
1362
+ new Or([
1363
+ new IntegerCompare({
1364
+ key: ["array"],
1365
+ compare: Compare.Equal,
1366
+ value: d1.array[0]!,
1367
+ }),
1368
+ new IntegerCompare({
1369
+ key: ["array"],
1370
+ compare: Compare.Equal,
1371
+ value: d3.array[0]!,
1372
+ }),
1373
+ ]),
1374
+ ],
1375
+ });
1376
+
1377
+ expect(
1378
+ results3.map((x) => sha256Base64Sync(x.value.id)),
1379
+ ).to.have.members([
1380
+ sha256Base64Sync(d1.id),
1381
+ sha256Base64Sync(d3.id),
1382
+ ]);
1383
+ });
1384
+
1385
+ it("or array, or field", async () => {
1386
+ const results3 = await search(store, {
1387
+ query: [
1388
+ new Or([
1389
+ new And([
1390
+ new IntegerCompare({
1391
+ key: ["array"],
1392
+ compare: Compare.LessOrEqual,
1393
+ value: 0,
1394
+ }),
1395
+ new IntegerCompare({
1396
+ key: ["array"],
1397
+ compare: Compare.LessOrEqual,
1398
+ value: 1,
1399
+ }),
1400
+ ]),
1401
+ new ByteMatchQuery({
1402
+ key: "id",
1403
+ value: new Uint8Array([0]),
1404
+ }),
1405
+ ]),
1406
+ ],
1407
+ });
1408
+
1409
+ expect(
1410
+ results3.map((x) => sha256Base64Sync(x.value.id)),
1411
+ ).to.have.members([
1412
+ sha256Base64Sync(d1.id),
1413
+ sha256Base64Sync(d3.id),
1414
+ ]);
1415
+ });
1416
+
1417
+ it("or all", async () => {
1418
+ const results = await search(store, {
1419
+ query: [
1420
+ new Or([
1421
+ new Or([
1422
+ new And([
1423
+ new IntegerCompare({
1424
+ key: ["array"],
1425
+ compare: Compare.GreaterOrEqual,
1426
+ value: 0,
1427
+ }),
1428
+ ]),
1429
+ new And([
1430
+ new IntegerCompare({
1431
+ key: ["array"],
1432
+ compare: Compare.GreaterOrEqual,
1433
+ value: 0,
1434
+ }),
1435
+ ]),
1436
+ ]),
1437
+ new IntegerCompare({
1438
+ key: ["array"],
1439
+ compare: Compare.GreaterOrEqual,
1440
+ value: 0,
1441
+ }),
1442
+ ]),
1443
+ ],
1444
+ });
1445
+
1446
+ expect(
1447
+ results.map((x) => sha256Base64Sync(x.value.id)),
1448
+ ).to.have.members([
1449
+ sha256Base64Sync(d1.id),
1450
+ sha256Base64Sync(d2.id),
1451
+ sha256Base64Sync(d3.id),
1452
+ ]);
1453
+ });
1454
+ });
1455
+ });
1456
+
1457
+ it("update array", async () => {
1458
+ const out = await setup({ schema: ArrayDocument });
1459
+ store = out.store;
1460
+
1461
+ const d1 = new ArrayDocument({
1462
+ array: [123],
1463
+ });
1464
+ await store.put(d1);
1465
+
1466
+ d1.array = [124];
1467
+
1468
+ await store.put(d1);
1469
+
1470
+ // should have update results
1471
+ expect(
1472
+ (
1473
+ await search(store, {
1474
+ query: new IntegerCompare({
1475
+ key: ["array"],
1476
+ compare: Compare.Equal,
1477
+ value: 123,
1478
+ }),
1479
+ })
1480
+ ).length,
1481
+ ).to.equal(0);
1482
+
1483
+ expect(
1484
+ (
1485
+ await search(store, {
1486
+ query: new IntegerCompare({
1487
+ key: ["array"],
1488
+ compare: Compare.Equal,
1489
+ value: 124,
1490
+ }),
1491
+ })
1492
+ ).map((x) => x.value.id),
1493
+ ).to.deep.equal([d1.id]);
1494
+ });
1495
+
1496
+ it("put delete put", async () => {
1497
+ const { store } = await setup({ schema: ArrayDocument });
1498
+
1499
+ const d1 = new ArrayDocument({
1500
+ array: [123],
1501
+ });
1502
+
1503
+ await store.put(d1);
1504
+ const [deleted] = await store.del({
1505
+ query: {
1506
+ id: d1.id,
1507
+ },
1508
+ });
1509
+
1510
+ expect(deleted.key).to.deep.equal(d1.id);
1511
+
1512
+ expect(
1513
+ (
1514
+ await search(store, {
1515
+ query: new IntegerCompare({
1516
+ key: ["array"],
1517
+ compare: Compare.Equal,
1518
+ value: 123,
1519
+ }),
1520
+ })
1521
+ ).length,
1522
+ ).to.equal(0);
1523
+
1524
+ d1.array = [124];
1525
+ await store.put(d1);
1526
+
1527
+ expect(
1528
+ (
1529
+ await search(store, {
1530
+ query: new IntegerCompare({
1531
+ key: ["array"],
1532
+ compare: Compare.Equal,
1533
+ value: 124,
1534
+ }),
1535
+ })
1536
+ ).map((x) => x.value.id),
1537
+ ).to.deep.equal([d1.id]);
1538
+
1539
+ expect(
1540
+ (
1541
+ await search(store, {
1542
+ query: new IntegerCompare({
1543
+ key: ["array"],
1544
+ compare: Compare.Equal,
1545
+ value: 123,
1546
+ }),
1547
+ })
1548
+ ).length,
1549
+ ).to.equal(0);
1550
+ });
1551
+ });
1051
1552
  });
1052
1553
 
1053
1554
  describe("logical", () => {
@@ -1132,7 +1633,7 @@ export const tests = (
1132
1633
  new IntegerCompare({
1133
1634
  key: "number",
1134
1635
  compare: Compare.Equal,
1135
- value: 2n,
1636
+ value: 2,
1136
1637
  }),
1137
1638
  ],
1138
1639
  });
@@ -1146,7 +1647,7 @@ export const tests = (
1146
1647
  new IntegerCompare({
1147
1648
  key: "number",
1148
1649
  compare: Compare.Greater,
1149
- value: 2n,
1650
+ value: 2,
1150
1651
  }),
1151
1652
  ],
1152
1653
  });
@@ -1160,7 +1661,7 @@ export const tests = (
1160
1661
  new IntegerCompare({
1161
1662
  key: "number",
1162
1663
  compare: Compare.GreaterOrEqual,
1163
- value: 2n,
1664
+ value: 2,
1164
1665
  }),
1165
1666
  ],
1166
1667
  });
@@ -1178,7 +1679,7 @@ export const tests = (
1178
1679
  new IntegerCompare({
1179
1680
  key: "number",
1180
1681
  compare: Compare.Less,
1181
- value: 2n,
1682
+ value: 2,
1182
1683
  }),
1183
1684
  ],
1184
1685
  });
@@ -1203,6 +1704,20 @@ export const tests = (
1203
1704
  expect(response[0].value.number).to.be.oneOf([1n, 1]);
1204
1705
  expect(response[1].value.number).to.be.oneOf([2n, 2]);
1205
1706
  });
1707
+
1708
+ it("bigint as compare value", async () => {
1709
+ const response = await search(store, {
1710
+ query: [
1711
+ new IntegerCompare({
1712
+ key: "number",
1713
+ compare: Compare.Less,
1714
+ value: 2n,
1715
+ }),
1716
+ ],
1717
+ });
1718
+ expect(response).to.have.length(1);
1719
+ expect(response[0].value.number).to.be.oneOf([1n, 1]);
1720
+ });
1206
1721
  });
1207
1722
 
1208
1723
  describe("bigint", () => {
@@ -1313,6 +1828,19 @@ export const tests = (
1313
1828
  expect(response[0].value.bigint).to.equal(first);
1314
1829
  expect(response[1].value.bigint).to.equal(second);
1315
1830
  });
1831
+
1832
+ it("number as compare value", async () => {
1833
+ const response = await search(store, {
1834
+ query: [
1835
+ new IntegerCompare({
1836
+ key: "bigint",
1837
+ compare: Compare.Greater,
1838
+ value: 1,
1839
+ }),
1840
+ ],
1841
+ });
1842
+ expect(response).to.have.length(3);
1843
+ });
1316
1844
  });
1317
1845
 
1318
1846
  describe("nested", () => {
@@ -1348,6 +1876,31 @@ export const tests = (
1348
1876
  await setup({ schema: DocumentWithNesting });
1349
1877
  });
1350
1878
 
1879
+ it("all", async () => {
1880
+ await store.put(
1881
+ new DocumentWithNesting({
1882
+ id: "1",
1883
+ nested: new Nested({ number: 1n, bool: false }),
1884
+ }),
1885
+ );
1886
+
1887
+ await store.put(
1888
+ new DocumentWithNesting({
1889
+ id: "2",
1890
+ nested: undefined,
1891
+ }),
1892
+ );
1893
+
1894
+ const all = await search(store, {});
1895
+ expect(all).to.have.length(2);
1896
+ expect(all.map((x) => x.id.primitive)).to.have.members([
1897
+ "1",
1898
+ "2",
1899
+ ]);
1900
+ expect(all[0].value.nested).to.be.instanceOf(Nested);
1901
+ expect(all[1].value.nested).to.be.undefined;
1902
+ });
1903
+
1351
1904
  it("number", async () => {
1352
1905
  await store.put(
1353
1906
  new DocumentWithNesting({
@@ -2096,21 +2649,16 @@ export const tests = (
2096
2649
  );
2097
2650
 
2098
2651
  const response = await search(store, {
2099
- query: [
2100
- new Nested({
2101
- path: "array",
2102
- query: new And([
2103
- new StringMatch({
2104
- key: "a",
2105
- value: "hello",
2106
- }),
2107
- new StringMatch({
2108
- key: "b",
2109
- value: "world",
2110
- }),
2111
- ]),
2652
+ query: new And([
2653
+ new StringMatch({
2654
+ key: ["array", "a"],
2655
+ value: "hello",
2112
2656
  }),
2113
- ],
2657
+ new StringMatch({
2658
+ key: ["array", "b"],
2659
+ value: "world",
2660
+ }),
2661
+ ]),
2114
2662
  });
2115
2663
 
2116
2664
  expect(response).to.have.length(1);
@@ -2130,24 +2678,40 @@ export const tests = (
2130
2678
  }),
2131
2679
  ],
2132
2680
  });
2681
+ const doc2 = new NestedMultipleFieldsArrayDocument({
2682
+ id: "2",
2683
+ array: [
2684
+ new NestedMultipleFieldsDocument({
2685
+ a: "hello",
2686
+ b: "värld",
2687
+ }),
2688
+ new NestedMultipleFieldsDocument({
2689
+ a: "hej",
2690
+ b: "world",
2691
+ }),
2692
+ ],
2693
+ });
2694
+
2695
+ const doc3 = new NestedMultipleFieldsArrayDocument({
2696
+ id: "3",
2697
+ array: [
2698
+ new NestedMultipleFieldsDocument({
2699
+ a: "_",
2700
+ b: "_",
2701
+ }),
2702
+ new NestedMultipleFieldsDocument({
2703
+ a: "_",
2704
+ b: "_",
2705
+ }),
2706
+ ],
2707
+ });
2708
+
2133
2709
  await store.put(doc1);
2134
- await store.put(
2135
- new NestedMultipleFieldsArrayDocument({
2136
- id: "2",
2137
- array: [
2138
- new NestedMultipleFieldsDocument({
2139
- a: "hello",
2140
- b: "värld",
2141
- }),
2142
- new NestedMultipleFieldsDocument({
2143
- a: "hej",
2144
- b: "world",
2145
- }),
2146
- ],
2147
- }),
2148
- );
2710
+ await store.put(doc2);
2711
+ await store.put(doc3);
2149
2712
 
2150
- const response = await search(store, {
2713
+ // AND will only yield doc 1 since only doc 1 contains the combination below
2714
+ const responseAnd = await search(store, {
2151
2715
  query: [
2152
2716
  new StringMatch({
2153
2717
  key: ["array", "a"],
@@ -2160,8 +2724,28 @@ export const tests = (
2160
2724
  ],
2161
2725
  });
2162
2726
 
2727
+ expect(responseAnd).to.have.length(1);
2728
+ checkDocument(responseAnd[0].value, doc1);
2729
+
2730
+ // OR will only yield doc 1 and doc 2 since both will fulfill one of two conditions
2731
+ const response = await search(store, {
2732
+ query: [
2733
+ new Or([
2734
+ new StringMatch({
2735
+ key: ["array", "a"],
2736
+ value: "hello",
2737
+ }),
2738
+ new StringMatch({
2739
+ key: ["array", "b"],
2740
+ value: "world",
2741
+ }),
2742
+ ]),
2743
+ ],
2744
+ });
2163
2745
  expect(response).to.have.length(2);
2746
+
2164
2747
  checkDocument(response[0].value, doc1);
2748
+ checkDocument(response[1].value, doc2);
2165
2749
  });
2166
2750
  });
2167
2751
  });
@@ -2693,11 +3277,14 @@ export const tests = (
2693
3277
  });
2694
3278
 
2695
3279
  describe("sort", () => {
2696
- const put = async (id: number, stringId?: string) => {
3280
+ const put = async (
3281
+ id: number,
3282
+ options?: { name?: string; number?: bigint },
3283
+ ) => {
2697
3284
  const doc = new Document({
2698
- id: stringId ?? String(id),
2699
- name: String(id),
2700
- number: BigInt(id),
3285
+ id: String(id),
3286
+ name: options?.name ?? String(id),
3287
+ number: options?.number ?? BigInt(id),
2701
3288
  tags: [],
2702
3289
  });
2703
3290
  const resp = await store.put(doc);
@@ -2866,12 +3453,12 @@ export const tests = (
2866
3453
 
2867
3454
  /* it("no sort is stable", async () => {
2868
3455
  // TODO this test is actually not a good predictor of stability
2869
-
3456
+
2870
3457
  const insertCount = 500;
2871
3458
  for (let i = 0; i < insertCount; i++) {
2872
3459
  await put(i, uuid());
2873
3460
  }
2874
-
3461
+
2875
3462
  const resolvedValues: Set<number> = new Set()
2876
3463
  const batchSize = 123;
2877
3464
  const iterator = store.iterate();
@@ -2897,6 +3484,25 @@ export const tests = (
2897
3484
  await assertIteratorIsDone(iterator);
2898
3485
  });
2899
3486
 
3487
+ it("sort by multiple properties", async () => {
3488
+ await put(0, { name: "a", number: 2n });
3489
+ await put(1, { name: "a", number: 1n });
3490
+
3491
+ await put(2, { name: "b", number: 2n });
3492
+ await put(3, { name: "b", number: 1n });
3493
+
3494
+ const iterator = store.iterate({
3495
+ query: [],
3496
+ sort: [
3497
+ new Sort({ direction: SortDirection.DESC, key: "name" }),
3498
+ new Sort({ direction: SortDirection.ASC, key: "number" }),
3499
+ ],
3500
+ });
3501
+
3502
+ const out = await iterator.all();
3503
+ expect(out.map((x) => x.value.id)).to.deep.equal(["3", "2", "1", "0"]);
3504
+ });
3505
+
2900
3506
  describe("nested", () => {
2901
3507
  it("variants", async () => {
2902
3508
  const doc1 = new Document({
@@ -3395,6 +4001,8 @@ export const tests = (
3395
4001
  });
3396
4002
 
3397
4003
  it("indices", async () => {
4004
+ // TODO make this test more clear and the purpose of each call
4005
+
3398
4006
  let { directory, indices } = await setupDefault();
3399
4007
 
3400
4008
  let subindex = await indices.scope("x");
@@ -3417,7 +4025,11 @@ export const tests = (
3417
4025
 
3418
4026
  await indices.drop();
3419
4027
 
3420
- await store.start();
4028
+ const out = await setup({ schema: Document }, directory);
4029
+ indices = out.indices;
4030
+ await indices.start();
4031
+
4032
+ store = out.store;
3421
4033
 
3422
4034
  expect(await store.getSize()).equal(0);
3423
4035
 
@@ -3426,7 +4038,6 @@ export const tests = (
3426
4038
 
3427
4039
  store = (await setup({ schema: Document }, directory)).store;
3428
4040
 
3429
- await store.start();
3430
4041
  expect(await store.getSize()).equal(0);
3431
4042
  });
3432
4043
  });