tutuca 0.9.73 → 0.9.76
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/tutuca-cli.js +36 -3
- package/dist/tutuca-dev.ext.js +119 -4
- package/dist/tutuca-dev.js +118 -3
- package/dist/tutuca-dev.min.js +2 -2
- package/dist/tutuca-extra.ext.js +36 -3
- package/dist/tutuca-extra.js +36 -3
- package/dist/tutuca-extra.min.js +2 -2
- package/dist/tutuca.ext.js +36 -3
- package/dist/tutuca.js +36 -3
- package/dist/tutuca.min.js +2 -2
- package/package.json +1 -1
- package/skill/tutuca-source/tutuca.ext.js +36 -3
package/dist/tutuca-cli.js
CHANGED
|
@@ -4247,6 +4247,9 @@ class Step {
|
|
|
4247
4247
|
toAbstractPathStep() {
|
|
4248
4248
|
return this;
|
|
4249
4249
|
}
|
|
4250
|
+
pinKey(_v) {
|
|
4251
|
+
return this;
|
|
4252
|
+
}
|
|
4250
4253
|
}
|
|
4251
4254
|
function warnRawDynStep(op, step) {
|
|
4252
4255
|
console.warn(`Path.${op} reached a DynStep: call toTransactionPath() first`, step);
|
|
@@ -4297,6 +4300,20 @@ class Path {
|
|
|
4297
4300
|
}
|
|
4298
4301
|
return new Path(out);
|
|
4299
4302
|
}
|
|
4303
|
+
pinKeys(root) {
|
|
4304
|
+
let curVal = root;
|
|
4305
|
+
let out = null;
|
|
4306
|
+
for (let i = 0;i < this.steps.length; i++) {
|
|
4307
|
+
const step = this.steps[i];
|
|
4308
|
+
const pinned = step.pinKey(curVal);
|
|
4309
|
+
if (pinned !== step)
|
|
4310
|
+
(out ??= this.steps.slice())[i] = pinned;
|
|
4311
|
+
curVal = step.lookup(curVal, NONE);
|
|
4312
|
+
if (curVal === NONE)
|
|
4313
|
+
break;
|
|
4314
|
+
}
|
|
4315
|
+
return out ? new Path(out) : this;
|
|
4316
|
+
}
|
|
4300
4317
|
lookup(v, dval = null) {
|
|
4301
4318
|
let curVal = v;
|
|
4302
4319
|
for (const step of this.steps) {
|
|
@@ -4582,6 +4599,10 @@ var init_path = __esm(() => {
|
|
|
4582
4599
|
const key = root?.get(this.keyField, NONE);
|
|
4583
4600
|
return seq === NONE || key === NONE ? root : root.set(this.seqField, seq.set(key, v));
|
|
4584
4601
|
}
|
|
4602
|
+
pinKey(v) {
|
|
4603
|
+
const key = v?.get(this.keyField, NONE);
|
|
4604
|
+
return key === NONE ? this : new SeqStep(this.seqField, key);
|
|
4605
|
+
}
|
|
4585
4606
|
};
|
|
4586
4607
|
EachBindStep = class EachBindStep extends Step {
|
|
4587
4608
|
constructor(seqVal, key) {
|
|
@@ -13744,12 +13765,14 @@ class Transactor {
|
|
|
13744
13765
|
}
|
|
13745
13766
|
async pushRequest(path, name, args = [], opts = {}, parent = null) {
|
|
13746
13767
|
const curRoot = this.state.val;
|
|
13747
|
-
const
|
|
13768
|
+
const txnPath = path.toTransactionPath();
|
|
13769
|
+
const curLeaf = txnPath.lookup(curRoot);
|
|
13748
13770
|
const handler = this.comps.getRequestFor(curLeaf, name) ?? mkReq404(name);
|
|
13749
13771
|
const resHandlerName = opts?.onResName ?? name;
|
|
13772
|
+
const resPath = opts?.livePath ? null : txnPath.pinKeys(curRoot);
|
|
13750
13773
|
const push = (specificName, baseName, singleArg, result, error) => {
|
|
13751
13774
|
const resArgs = specificName ? [singleArg] : [result, error];
|
|
13752
|
-
const t = new ResponseEvent(path, this, specificName ?? baseName, resArgs, parent);
|
|
13775
|
+
const t = new ResponseEvent(path, this, specificName ?? baseName, resArgs, parent, resPath);
|
|
13753
13776
|
this.pushTransaction(t);
|
|
13754
13777
|
};
|
|
13755
13778
|
try {
|
|
@@ -13824,8 +13847,11 @@ class Transaction {
|
|
|
13824
13847
|
getHandlerAndArgs(_root, _instance, _comps) {
|
|
13825
13848
|
return null;
|
|
13826
13849
|
}
|
|
13850
|
+
getTransactionPath() {
|
|
13851
|
+
return this.path.toTransactionPath();
|
|
13852
|
+
}
|
|
13827
13853
|
updateRootValue(curRoot, comps) {
|
|
13828
|
-
const txnPath = this.
|
|
13854
|
+
const txnPath = this.getTransactionPath();
|
|
13829
13855
|
const curLeaf = txnPath.lookup(curRoot);
|
|
13830
13856
|
const newLeaf = this.callHandler(curRoot, curLeaf, comps);
|
|
13831
13857
|
this._task?.complete?.({ value: newLeaf, old: curLeaf });
|
|
@@ -13990,6 +14016,13 @@ var init_transactor = __esm(() => {
|
|
|
13990
14016
|
};
|
|
13991
14017
|
ResponseEvent = class ResponseEvent extends NameArgsTransaction {
|
|
13992
14018
|
handlerProp = "response";
|
|
14019
|
+
constructor(path, transactor, name, args, parent, txnPath = null) {
|
|
14020
|
+
super(path, transactor, name, args, parent);
|
|
14021
|
+
this._txnPath = txnPath;
|
|
14022
|
+
}
|
|
14023
|
+
getTransactionPath() {
|
|
14024
|
+
return this._txnPath ?? super.getTransactionPath();
|
|
14025
|
+
}
|
|
13993
14026
|
};
|
|
13994
14027
|
SendEvent = class SendEvent extends NameArgsTransaction {
|
|
13995
14028
|
handlerProp = "receive";
|
package/dist/tutuca-dev.ext.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// dev.js
|
|
2
|
-
import { expect } from "chai";
|
|
2
|
+
import { expect, use } from "chai";
|
|
3
3
|
|
|
4
4
|
// src/value.js
|
|
5
5
|
import { is } from "immutable";
|
|
@@ -20,6 +20,9 @@ class Step {
|
|
|
20
20
|
toAbstractPathStep() {
|
|
21
21
|
return this;
|
|
22
22
|
}
|
|
23
|
+
pinKey(_v) {
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
23
26
|
}
|
|
24
27
|
|
|
25
28
|
class BindStep extends Step {
|
|
@@ -101,6 +104,10 @@ class SeqAccessStep extends Step {
|
|
|
101
104
|
const key = root?.get(this.keyField, NONE);
|
|
102
105
|
return seq === NONE || key === NONE ? root : root.set(this.seqField, seq.set(key, v));
|
|
103
106
|
}
|
|
107
|
+
pinKey(v) {
|
|
108
|
+
const key = v?.get(this.keyField, NONE);
|
|
109
|
+
return key === NONE ? this : new SeqStep(this.seqField, key);
|
|
110
|
+
}
|
|
104
111
|
}
|
|
105
112
|
|
|
106
113
|
class EachBindStep extends Step {
|
|
@@ -223,6 +230,20 @@ class Path {
|
|
|
223
230
|
}
|
|
224
231
|
return new Path(out);
|
|
225
232
|
}
|
|
233
|
+
pinKeys(root) {
|
|
234
|
+
let curVal = root;
|
|
235
|
+
let out = null;
|
|
236
|
+
for (let i = 0;i < this.steps.length; i++) {
|
|
237
|
+
const step = this.steps[i];
|
|
238
|
+
const pinned = step.pinKey(curVal);
|
|
239
|
+
if (pinned !== step)
|
|
240
|
+
(out ??= this.steps.slice())[i] = pinned;
|
|
241
|
+
curVal = step.lookup(curVal, NONE);
|
|
242
|
+
if (curVal === NONE)
|
|
243
|
+
break;
|
|
244
|
+
}
|
|
245
|
+
return out ? new Path(out) : this;
|
|
246
|
+
}
|
|
226
247
|
lookup(v, dval = null) {
|
|
227
248
|
let curVal = v;
|
|
228
249
|
for (const step of this.steps) {
|
|
@@ -2301,6 +2322,87 @@ function compileModifiers(eventName, names) {
|
|
|
2301
2322
|
};
|
|
2302
2323
|
}
|
|
2303
2324
|
|
|
2325
|
+
// src/chai-jest.js
|
|
2326
|
+
function jestMatchers(chai, utils) {
|
|
2327
|
+
const A = chai.Assertion;
|
|
2328
|
+
const m = (name, fn) => A.addMethod(name, fn);
|
|
2329
|
+
m("toBe", function(expected) {
|
|
2330
|
+
this.assert(Object.is(this._obj, expected), "expected #{this} to be #{exp}", "expected #{this} not to be #{exp}", expected, this._obj);
|
|
2331
|
+
});
|
|
2332
|
+
m("toEqual", function(expected) {
|
|
2333
|
+
this.assert(utils.eql(this._obj, expected), "expected #{this} to deeply equal #{exp}", "expected #{this} not to deeply equal #{exp}", expected, this._obj, true);
|
|
2334
|
+
});
|
|
2335
|
+
m("toBeTruthy", function() {
|
|
2336
|
+
this.assert(Boolean(this._obj), "expected #{this} to be truthy", "expected #{this} not to be truthy");
|
|
2337
|
+
});
|
|
2338
|
+
m("toBeFalsy", function() {
|
|
2339
|
+
this.assert(!this._obj, "expected #{this} to be falsy", "expected #{this} not to be falsy");
|
|
2340
|
+
});
|
|
2341
|
+
m("toBeNull", function() {
|
|
2342
|
+
this.assert(this._obj === null, "expected #{this} to be null", "expected #{this} not to be null");
|
|
2343
|
+
});
|
|
2344
|
+
m("toBeUndefined", function() {
|
|
2345
|
+
this.assert(this._obj === undefined, "expected #{this} to be undefined", "expected #{this} not to be undefined");
|
|
2346
|
+
});
|
|
2347
|
+
m("toBeDefined", function() {
|
|
2348
|
+
this.assert(this._obj !== undefined, "expected #{this} to be defined", "expected #{this} to be undefined");
|
|
2349
|
+
});
|
|
2350
|
+
m("toBeNaN", function() {
|
|
2351
|
+
this.assert(Number.isNaN(this._obj), "expected #{this} to be NaN", "expected #{this} not to be NaN");
|
|
2352
|
+
});
|
|
2353
|
+
const compare = (name, op, word) => m(name, function(expected) {
|
|
2354
|
+
this.assert(op(this._obj, expected), `expected #{this} to be ${word} #{exp}`, `expected #{this} not to be ${word} #{exp}`, expected);
|
|
2355
|
+
});
|
|
2356
|
+
compare("toBeGreaterThan", (a, b) => a > b, "greater than");
|
|
2357
|
+
compare("toBeGreaterThanOrEqual", (a, b) => a >= b, "greater than or equal to");
|
|
2358
|
+
compare("toBeLessThan", (a, b) => a < b, "less than");
|
|
2359
|
+
compare("toBeLessThanOrEqual", (a, b) => a <= b, "less than or equal to");
|
|
2360
|
+
m("toBeCloseTo", function(expected, numDigits = 2) {
|
|
2361
|
+
const pass = Math.abs(expected - this._obj) < 10 ** -numDigits / 2;
|
|
2362
|
+
this.assert(pass, `expected #{this} to be close to #{exp} (${numDigits} digits)`, `expected #{this} not to be close to #{exp} (${numDigits} digits)`, expected);
|
|
2363
|
+
});
|
|
2364
|
+
m("toContain", function(item) {
|
|
2365
|
+
const obj = this._obj;
|
|
2366
|
+
const ok = typeof obj === "string" ? obj.includes(item) : Array.from(obj).includes(item);
|
|
2367
|
+
this.assert(ok, "expected #{this} to contain #{exp}", "expected #{this} not to contain #{exp}", item);
|
|
2368
|
+
});
|
|
2369
|
+
m("toHaveLength", function(length) {
|
|
2370
|
+
const actual = this._obj == null ? undefined : this._obj.length;
|
|
2371
|
+
this.assert(actual === length, "expected #{this} to have length #{exp}", "expected #{this} not to have length #{exp}", length, actual);
|
|
2372
|
+
});
|
|
2373
|
+
m("toMatch", function(expected) {
|
|
2374
|
+
const obj = this._obj;
|
|
2375
|
+
const ok = expected instanceof RegExp ? expected.test(obj) : String(obj).includes(expected);
|
|
2376
|
+
this.assert(ok, "expected #{this} to match #{exp}", "expected #{this} not to match #{exp}", expected);
|
|
2377
|
+
});
|
|
2378
|
+
m("toHaveProperty", function(path, ...rest) {
|
|
2379
|
+
const keys = Array.isArray(path) ? path : String(path).split(".");
|
|
2380
|
+
let cur = this._obj;
|
|
2381
|
+
let found = true;
|
|
2382
|
+
for (const k of keys) {
|
|
2383
|
+
if (cur != null && k in Object(cur))
|
|
2384
|
+
cur = cur[k];
|
|
2385
|
+
else {
|
|
2386
|
+
found = false;
|
|
2387
|
+
break;
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
2390
|
+
const pass = found && (rest.length === 0 || utils.eql(cur, rest[0]));
|
|
2391
|
+
this.assert(pass, "expected #{this} to have property #{exp}", "expected #{this} not to have property #{exp}", path);
|
|
2392
|
+
});
|
|
2393
|
+
m("toBeInstanceOf", function(ctor) {
|
|
2394
|
+
this.assert(this._obj instanceof ctor, "expected #{this} to be an instance of #{exp}", "expected #{this} not to be an instance of #{exp}", ctor.name ?? ctor);
|
|
2395
|
+
});
|
|
2396
|
+
m("toThrow", function(expected) {
|
|
2397
|
+
const a = new chai.Assertion(this._obj);
|
|
2398
|
+
if (utils.flag(this, "negate")) {
|
|
2399
|
+
expected === undefined ? a.to.not.throw() : a.to.not.throw(expected);
|
|
2400
|
+
} else {
|
|
2401
|
+
expected === undefined ? a.to.throw() : a.to.throw(expected);
|
|
2402
|
+
}
|
|
2403
|
+
});
|
|
2404
|
+
}
|
|
2405
|
+
|
|
2304
2406
|
// src/util/parsectx.js
|
|
2305
2407
|
class ParseCtxClassSetCollector extends ParseContext {
|
|
2306
2408
|
constructor(...args) {
|
|
@@ -6329,12 +6431,14 @@ class Transactor {
|
|
|
6329
6431
|
}
|
|
6330
6432
|
async pushRequest(path, name, args = [], opts = {}, parent = null) {
|
|
6331
6433
|
const curRoot = this.state.val;
|
|
6332
|
-
const
|
|
6434
|
+
const txnPath = path.toTransactionPath();
|
|
6435
|
+
const curLeaf = txnPath.lookup(curRoot);
|
|
6333
6436
|
const handler = this.comps.getRequestFor(curLeaf, name) ?? mkReq404(name);
|
|
6334
6437
|
const resHandlerName = opts?.onResName ?? name;
|
|
6438
|
+
const resPath = opts?.livePath ? null : txnPath.pinKeys(curRoot);
|
|
6335
6439
|
const push = (specificName, baseName, singleArg, result, error) => {
|
|
6336
6440
|
const resArgs = specificName ? [singleArg] : [result, error];
|
|
6337
|
-
const t = new ResponseEvent(path, this, specificName ?? baseName, resArgs, parent);
|
|
6441
|
+
const t = new ResponseEvent(path, this, specificName ?? baseName, resArgs, parent, resPath);
|
|
6338
6442
|
this.pushTransaction(t);
|
|
6339
6443
|
};
|
|
6340
6444
|
try {
|
|
@@ -6409,8 +6513,11 @@ class Transaction {
|
|
|
6409
6513
|
getHandlerAndArgs(_root, _instance, _comps) {
|
|
6410
6514
|
return null;
|
|
6411
6515
|
}
|
|
6516
|
+
getTransactionPath() {
|
|
6517
|
+
return this.path.toTransactionPath();
|
|
6518
|
+
}
|
|
6412
6519
|
updateRootValue(curRoot, comps) {
|
|
6413
|
-
const txnPath = this.
|
|
6520
|
+
const txnPath = this.getTransactionPath();
|
|
6414
6521
|
const curLeaf = txnPath.lookup(curRoot);
|
|
6415
6522
|
const newLeaf = this.callHandler(curRoot, curLeaf, comps);
|
|
6416
6523
|
this._task?.complete?.({ value: newLeaf, old: curLeaf });
|
|
@@ -6519,6 +6626,13 @@ class NameArgsTransaction extends Transaction {
|
|
|
6519
6626
|
|
|
6520
6627
|
class ResponseEvent extends NameArgsTransaction {
|
|
6521
6628
|
handlerProp = "response";
|
|
6629
|
+
constructor(path, transactor, name, args, parent, txnPath = null) {
|
|
6630
|
+
super(path, transactor, name, args, parent);
|
|
6631
|
+
this._txnPath = txnPath;
|
|
6632
|
+
}
|
|
6633
|
+
getTransactionPath() {
|
|
6634
|
+
return this._txnPath ?? super.getTransactionPath();
|
|
6635
|
+
}
|
|
6522
6636
|
}
|
|
6523
6637
|
|
|
6524
6638
|
class SendEvent extends NameArgsTransaction {
|
|
@@ -7905,6 +8019,7 @@ function collectIterBindings(Comp, compInstance, seq, opts = {}) {
|
|
|
7905
8019
|
}
|
|
7906
8020
|
|
|
7907
8021
|
// dev.js
|
|
8022
|
+
use(jestMatchers);
|
|
7908
8023
|
async function test2(opts = {}) {
|
|
7909
8024
|
const report = await runTests({ expect, ...opts });
|
|
7910
8025
|
reportTestReportToConsole(report);
|
package/dist/tutuca-dev.js
CHANGED
|
@@ -7685,6 +7685,9 @@ class Step {
|
|
|
7685
7685
|
toAbstractPathStep() {
|
|
7686
7686
|
return this;
|
|
7687
7687
|
}
|
|
7688
|
+
pinKey(_v) {
|
|
7689
|
+
return this;
|
|
7690
|
+
}
|
|
7688
7691
|
}
|
|
7689
7692
|
|
|
7690
7693
|
class BindStep extends Step {
|
|
@@ -7766,6 +7769,10 @@ class SeqAccessStep extends Step {
|
|
|
7766
7769
|
const key = root?.get(this.keyField, NONE);
|
|
7767
7770
|
return seq === NONE || key === NONE ? root : root.set(this.seqField, seq.set(key, v));
|
|
7768
7771
|
}
|
|
7772
|
+
pinKey(v) {
|
|
7773
|
+
const key = v?.get(this.keyField, NONE);
|
|
7774
|
+
return key === NONE ? this : new SeqStep(this.seqField, key);
|
|
7775
|
+
}
|
|
7769
7776
|
}
|
|
7770
7777
|
|
|
7771
7778
|
class EachBindStep extends Step {
|
|
@@ -7888,6 +7895,20 @@ class Path {
|
|
|
7888
7895
|
}
|
|
7889
7896
|
return new Path(out);
|
|
7890
7897
|
}
|
|
7898
|
+
pinKeys(root) {
|
|
7899
|
+
let curVal = root;
|
|
7900
|
+
let out = null;
|
|
7901
|
+
for (let i = 0;i < this.steps.length; i++) {
|
|
7902
|
+
const step = this.steps[i];
|
|
7903
|
+
const pinned = step.pinKey(curVal);
|
|
7904
|
+
if (pinned !== step)
|
|
7905
|
+
(out ??= this.steps.slice())[i] = pinned;
|
|
7906
|
+
curVal = step.lookup(curVal, NONE);
|
|
7907
|
+
if (curVal === NONE)
|
|
7908
|
+
break;
|
|
7909
|
+
}
|
|
7910
|
+
return out ? new Path(out) : this;
|
|
7911
|
+
}
|
|
7891
7912
|
lookup(v, dval = null) {
|
|
7892
7913
|
let curVal = v;
|
|
7893
7914
|
for (const step of this.steps) {
|
|
@@ -9966,6 +9987,87 @@ function compileModifiers(eventName, names) {
|
|
|
9966
9987
|
};
|
|
9967
9988
|
}
|
|
9968
9989
|
|
|
9990
|
+
// src/chai-jest.js
|
|
9991
|
+
function jestMatchers(chai, utils) {
|
|
9992
|
+
const A = chai.Assertion;
|
|
9993
|
+
const m = (name, fn) => A.addMethod(name, fn);
|
|
9994
|
+
m("toBe", function(expected) {
|
|
9995
|
+
this.assert(Object.is(this._obj, expected), "expected #{this} to be #{exp}", "expected #{this} not to be #{exp}", expected, this._obj);
|
|
9996
|
+
});
|
|
9997
|
+
m("toEqual", function(expected) {
|
|
9998
|
+
this.assert(utils.eql(this._obj, expected), "expected #{this} to deeply equal #{exp}", "expected #{this} not to deeply equal #{exp}", expected, this._obj, true);
|
|
9999
|
+
});
|
|
10000
|
+
m("toBeTruthy", function() {
|
|
10001
|
+
this.assert(Boolean(this._obj), "expected #{this} to be truthy", "expected #{this} not to be truthy");
|
|
10002
|
+
});
|
|
10003
|
+
m("toBeFalsy", function() {
|
|
10004
|
+
this.assert(!this._obj, "expected #{this} to be falsy", "expected #{this} not to be falsy");
|
|
10005
|
+
});
|
|
10006
|
+
m("toBeNull", function() {
|
|
10007
|
+
this.assert(this._obj === null, "expected #{this} to be null", "expected #{this} not to be null");
|
|
10008
|
+
});
|
|
10009
|
+
m("toBeUndefined", function() {
|
|
10010
|
+
this.assert(this._obj === undefined, "expected #{this} to be undefined", "expected #{this} not to be undefined");
|
|
10011
|
+
});
|
|
10012
|
+
m("toBeDefined", function() {
|
|
10013
|
+
this.assert(this._obj !== undefined, "expected #{this} to be defined", "expected #{this} to be undefined");
|
|
10014
|
+
});
|
|
10015
|
+
m("toBeNaN", function() {
|
|
10016
|
+
this.assert(Number.isNaN(this._obj), "expected #{this} to be NaN", "expected #{this} not to be NaN");
|
|
10017
|
+
});
|
|
10018
|
+
const compare = (name, op, word) => m(name, function(expected) {
|
|
10019
|
+
this.assert(op(this._obj, expected), `expected #{this} to be ${word} #{exp}`, `expected #{this} not to be ${word} #{exp}`, expected);
|
|
10020
|
+
});
|
|
10021
|
+
compare("toBeGreaterThan", (a, b) => a > b, "greater than");
|
|
10022
|
+
compare("toBeGreaterThanOrEqual", (a, b) => a >= b, "greater than or equal to");
|
|
10023
|
+
compare("toBeLessThan", (a, b) => a < b, "less than");
|
|
10024
|
+
compare("toBeLessThanOrEqual", (a, b) => a <= b, "less than or equal to");
|
|
10025
|
+
m("toBeCloseTo", function(expected, numDigits = 2) {
|
|
10026
|
+
const pass = Math.abs(expected - this._obj) < 10 ** -numDigits / 2;
|
|
10027
|
+
this.assert(pass, `expected #{this} to be close to #{exp} (${numDigits} digits)`, `expected #{this} not to be close to #{exp} (${numDigits} digits)`, expected);
|
|
10028
|
+
});
|
|
10029
|
+
m("toContain", function(item) {
|
|
10030
|
+
const obj = this._obj;
|
|
10031
|
+
const ok = typeof obj === "string" ? obj.includes(item) : Array.from(obj).includes(item);
|
|
10032
|
+
this.assert(ok, "expected #{this} to contain #{exp}", "expected #{this} not to contain #{exp}", item);
|
|
10033
|
+
});
|
|
10034
|
+
m("toHaveLength", function(length) {
|
|
10035
|
+
const actual = this._obj == null ? undefined : this._obj.length;
|
|
10036
|
+
this.assert(actual === length, "expected #{this} to have length #{exp}", "expected #{this} not to have length #{exp}", length, actual);
|
|
10037
|
+
});
|
|
10038
|
+
m("toMatch", function(expected) {
|
|
10039
|
+
const obj = this._obj;
|
|
10040
|
+
const ok = expected instanceof RegExp ? expected.test(obj) : String(obj).includes(expected);
|
|
10041
|
+
this.assert(ok, "expected #{this} to match #{exp}", "expected #{this} not to match #{exp}", expected);
|
|
10042
|
+
});
|
|
10043
|
+
m("toHaveProperty", function(path, ...rest) {
|
|
10044
|
+
const keys = Array.isArray(path) ? path : String(path).split(".");
|
|
10045
|
+
let cur = this._obj;
|
|
10046
|
+
let found = true;
|
|
10047
|
+
for (const k of keys) {
|
|
10048
|
+
if (cur != null && k in Object(cur))
|
|
10049
|
+
cur = cur[k];
|
|
10050
|
+
else {
|
|
10051
|
+
found = false;
|
|
10052
|
+
break;
|
|
10053
|
+
}
|
|
10054
|
+
}
|
|
10055
|
+
const pass = found && (rest.length === 0 || utils.eql(cur, rest[0]));
|
|
10056
|
+
this.assert(pass, "expected #{this} to have property #{exp}", "expected #{this} not to have property #{exp}", path);
|
|
10057
|
+
});
|
|
10058
|
+
m("toBeInstanceOf", function(ctor) {
|
|
10059
|
+
this.assert(this._obj instanceof ctor, "expected #{this} to be an instance of #{exp}", "expected #{this} not to be an instance of #{exp}", ctor.name ?? ctor);
|
|
10060
|
+
});
|
|
10061
|
+
m("toThrow", function(expected) {
|
|
10062
|
+
const a = new chai.Assertion(this._obj);
|
|
10063
|
+
if (utils.flag(this, "negate")) {
|
|
10064
|
+
expected === undefined ? a.to.not.throw() : a.to.not.throw(expected);
|
|
10065
|
+
} else {
|
|
10066
|
+
expected === undefined ? a.to.throw() : a.to.throw(expected);
|
|
10067
|
+
}
|
|
10068
|
+
});
|
|
10069
|
+
}
|
|
10070
|
+
|
|
9969
10071
|
// src/util/parsectx.js
|
|
9970
10072
|
class ParseCtxClassSetCollector extends ParseContext {
|
|
9971
10073
|
constructor(...args) {
|
|
@@ -13994,12 +14096,14 @@ class Transactor {
|
|
|
13994
14096
|
}
|
|
13995
14097
|
async pushRequest(path, name, args = [], opts = {}, parent = null) {
|
|
13996
14098
|
const curRoot = this.state.val;
|
|
13997
|
-
const
|
|
14099
|
+
const txnPath = path.toTransactionPath();
|
|
14100
|
+
const curLeaf = txnPath.lookup(curRoot);
|
|
13998
14101
|
const handler = this.comps.getRequestFor(curLeaf, name) ?? mkReq404(name);
|
|
13999
14102
|
const resHandlerName = opts?.onResName ?? name;
|
|
14103
|
+
const resPath = opts?.livePath ? null : txnPath.pinKeys(curRoot);
|
|
14000
14104
|
const push = (specificName, baseName, singleArg, result, error) => {
|
|
14001
14105
|
const resArgs = specificName ? [singleArg] : [result, error];
|
|
14002
|
-
const t = new ResponseEvent(path, this, specificName ?? baseName, resArgs, parent);
|
|
14106
|
+
const t = new ResponseEvent(path, this, specificName ?? baseName, resArgs, parent, resPath);
|
|
14003
14107
|
this.pushTransaction(t);
|
|
14004
14108
|
};
|
|
14005
14109
|
try {
|
|
@@ -14074,8 +14178,11 @@ class Transaction {
|
|
|
14074
14178
|
getHandlerAndArgs(_root, _instance, _comps) {
|
|
14075
14179
|
return null;
|
|
14076
14180
|
}
|
|
14181
|
+
getTransactionPath() {
|
|
14182
|
+
return this.path.toTransactionPath();
|
|
14183
|
+
}
|
|
14077
14184
|
updateRootValue(curRoot, comps) {
|
|
14078
|
-
const txnPath = this.
|
|
14185
|
+
const txnPath = this.getTransactionPath();
|
|
14079
14186
|
const curLeaf = txnPath.lookup(curRoot);
|
|
14080
14187
|
const newLeaf = this.callHandler(curRoot, curLeaf, comps);
|
|
14081
14188
|
this._task?.complete?.({ value: newLeaf, old: curLeaf });
|
|
@@ -14184,6 +14291,13 @@ class NameArgsTransaction extends Transaction {
|
|
|
14184
14291
|
|
|
14185
14292
|
class ResponseEvent extends NameArgsTransaction {
|
|
14186
14293
|
handlerProp = "response";
|
|
14294
|
+
constructor(path, transactor, name, args, parent, txnPath = null) {
|
|
14295
|
+
super(path, transactor, name, args, parent);
|
|
14296
|
+
this._txnPath = txnPath;
|
|
14297
|
+
}
|
|
14298
|
+
getTransactionPath() {
|
|
14299
|
+
return this._txnPath ?? super.getTransactionPath();
|
|
14300
|
+
}
|
|
14187
14301
|
}
|
|
14188
14302
|
|
|
14189
14303
|
class SendEvent extends NameArgsTransaction {
|
|
@@ -15510,6 +15624,7 @@ function collectIterBindings(Comp, compInstance, seq, opts = {}) {
|
|
|
15510
15624
|
}
|
|
15511
15625
|
|
|
15512
15626
|
// dev.js
|
|
15627
|
+
use(jestMatchers);
|
|
15513
15628
|
async function test3(opts = {}) {
|
|
15514
15629
|
const report = await runTests({ expect, ...opts });
|
|
15515
15630
|
reportTestReportToConsole(report);
|