@rotorsoft/act-tck 1.19.2 → 1.19.3
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/.tsbuildinfo +1 -1
- package/dist/@types/store-tck.d.ts +4 -0
- package/dist/@types/store-tck.d.ts.map +1 -1
- package/dist/index.cjs +88 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +90 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -798,7 +798,8 @@ import {
|
|
|
798
798
|
ConcurrencyError,
|
|
799
799
|
InMemoryCache,
|
|
800
800
|
SNAP_EVENT as SNAP_EVENT2,
|
|
801
|
-
TOMBSTONE_EVENT
|
|
801
|
+
TOMBSTONE_EVENT,
|
|
802
|
+
ValidationError
|
|
802
803
|
} from "@rotorsoft/act";
|
|
803
804
|
import { afterAll as afterAll4, beforeAll as beforeAll4, describe as describe8, expect as expect8, it as it7 } from "vitest";
|
|
804
805
|
var runStoreTck = (options) => {
|
|
@@ -1155,6 +1156,94 @@ var runStoreTck = (options) => {
|
|
|
1155
1156
|
expect8(got.map((e) => e.stream).sort()).toEqual([a, b].sort());
|
|
1156
1157
|
});
|
|
1157
1158
|
});
|
|
1159
|
+
describe8("stream filter grammar", () => {
|
|
1160
|
+
const seed_streams = async (streams) => {
|
|
1161
|
+
for (const s of streams)
|
|
1162
|
+
await store.commit(
|
|
1163
|
+
s,
|
|
1164
|
+
[inc(1)],
|
|
1165
|
+
make_meta({ stream: s })
|
|
1166
|
+
);
|
|
1167
|
+
};
|
|
1168
|
+
const streams_matching = async (pattern) => (await collect(store, { stream: pattern })).map((e) => e.stream).sort();
|
|
1169
|
+
const match_exactly_or_throw = async (pattern, expected) => {
|
|
1170
|
+
let matched;
|
|
1171
|
+
let error;
|
|
1172
|
+
try {
|
|
1173
|
+
matched = await streams_matching(pattern);
|
|
1174
|
+
} catch (e) {
|
|
1175
|
+
error = e;
|
|
1176
|
+
}
|
|
1177
|
+
if (error !== void 0) expect8(error).toBeInstanceOf(ValidationError);
|
|
1178
|
+
else expect8(matched).toEqual(expected.sort());
|
|
1179
|
+
};
|
|
1180
|
+
it7("portable subset: anchors, `.`, and `.*` match identically", async () => {
|
|
1181
|
+
const tag = uid();
|
|
1182
|
+
const plain = `g-${tag}-plain`;
|
|
1183
|
+
const dotted = `g-${tag}.dot`;
|
|
1184
|
+
const scored = `g-${tag}_us`;
|
|
1185
|
+
const pct = `g-${tag}%pc`;
|
|
1186
|
+
await seed_streams([plain, dotted, scored, pct]);
|
|
1187
|
+
expect8(await streams_matching(`^g-${tag}`)).toEqual(
|
|
1188
|
+
[plain, dotted, scored, pct].sort()
|
|
1189
|
+
);
|
|
1190
|
+
expect8(await streams_matching(`${tag}-plain$`)).toEqual([plain]);
|
|
1191
|
+
expect8(await streams_matching(`^g-${tag}-plain$`)).toEqual([plain]);
|
|
1192
|
+
expect8(await streams_matching(`^g-${tag}.dot$`)).toEqual([dotted]);
|
|
1193
|
+
expect8(await streams_matching(`^g-${tag}.plain$`)).toEqual([plain]);
|
|
1194
|
+
expect8(await streams_matching(`^g-${tag}.*dot$`)).toEqual([dotted]);
|
|
1195
|
+
});
|
|
1196
|
+
it7("literal `_` and `%` in patterns are not wildcards", async () => {
|
|
1197
|
+
const tag = uid();
|
|
1198
|
+
const scored = `u-${tag}_x`;
|
|
1199
|
+
const scored_decoy = `u-${tag}Zx`;
|
|
1200
|
+
const pct = `p-${tag}%y`;
|
|
1201
|
+
const pct_decoy = `p-${tag}ZZy`;
|
|
1202
|
+
await seed_streams([scored, scored_decoy, pct, pct_decoy]);
|
|
1203
|
+
expect8(await streams_matching(`^u-${tag}_x$`)).toEqual([scored]);
|
|
1204
|
+
expect8(await streams_matching(`^p-${tag}%y$`)).toEqual([pct]);
|
|
1205
|
+
});
|
|
1206
|
+
it7("portable subset applies to stream-position filters", async () => {
|
|
1207
|
+
const tag = uid();
|
|
1208
|
+
const scored = `sf-${tag}_a`;
|
|
1209
|
+
const decoy = `sf-${tag}Za`;
|
|
1210
|
+
await store.subscribe([{ stream: scored }, { stream: decoy }]);
|
|
1211
|
+
const got = [];
|
|
1212
|
+
await store.query_streams((p) => got.push(p.stream), {
|
|
1213
|
+
stream: `^sf-${tag}_a$`
|
|
1214
|
+
});
|
|
1215
|
+
expect8(got).toEqual([scored]);
|
|
1216
|
+
});
|
|
1217
|
+
it7("non-portable patterns match with full regex semantics or throw", async () => {
|
|
1218
|
+
const tag = uid();
|
|
1219
|
+
const a = `np-${tag}-a`;
|
|
1220
|
+
const b = `np-${tag}-b`;
|
|
1221
|
+
const c = `np-${tag}-c`;
|
|
1222
|
+
const one = `np-${tag}-1`;
|
|
1223
|
+
const aaa = `np-${tag}-aaa`;
|
|
1224
|
+
const dot = `e-${tag}.d`;
|
|
1225
|
+
const dot_decoy = `e-${tag}xd`;
|
|
1226
|
+
await seed_streams([a, b, c, one, aaa, dot, dot_decoy]);
|
|
1227
|
+
await match_exactly_or_throw(`^np-${tag}-(a|b)$`, [a, b]);
|
|
1228
|
+
await match_exactly_or_throw(`^np-${tag}-[0-9]$`, [one]);
|
|
1229
|
+
await match_exactly_or_throw(`^np-${tag}-a+$`, [a, aaa]);
|
|
1230
|
+
await match_exactly_or_throw(`^e-${tag}\\.d$`, [dot]);
|
|
1231
|
+
});
|
|
1232
|
+
it7("bulk stream ops reject non-portable filters instead of mis-matching", async () => {
|
|
1233
|
+
const tag = uid();
|
|
1234
|
+
const s = `bo-${tag}-a`;
|
|
1235
|
+
await store.subscribe([{ stream: s }]);
|
|
1236
|
+
let count;
|
|
1237
|
+
let error;
|
|
1238
|
+
try {
|
|
1239
|
+
count = await store.reset({ stream: `^bo-${tag}-(a|b)$` });
|
|
1240
|
+
} catch (e) {
|
|
1241
|
+
error = e;
|
|
1242
|
+
}
|
|
1243
|
+
if (error !== void 0) expect8(error).toBeInstanceOf(ValidationError);
|
|
1244
|
+
else expect8(count).toBe(1);
|
|
1245
|
+
});
|
|
1246
|
+
});
|
|
1158
1247
|
describe8("subscribe + claim + ack", () => {
|
|
1159
1248
|
it7("subscribes new streams and is idempotent on repeat", async () => {
|
|
1160
1249
|
const s = `sub-${uid()}`;
|