@neocompose/cli 0.26.2 → 0.26.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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.26.3] - 2026-08-10
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- Show a phase-aware loading spinner during interactive `neo test` runs, then
|
|
8
|
+
render files, tests, failures, counts, and durations with Vitest-style
|
|
9
|
+
grouping, alignment, color, and emphasis. JSON reports now expose prepare,
|
|
10
|
+
selection, compilation, registration, execution, and finalization timings.
|
|
11
|
+
- Reuse matcher dispatch metadata, build assertion diagnostics only on failure,
|
|
12
|
+
and compare structured values directly instead of serializing them to JSON.
|
|
13
|
+
This keeps successful `expect`, `toBe`, `toEqual`, `toHaveLength`,
|
|
14
|
+
`toContain`, `toMatchObject`, and mock assertions on a smaller hot path.
|
|
15
|
+
|
|
3
16
|
## [0.26.2] - 2026-08-10
|
|
4
17
|
|
|
5
18
|
### Changed
|
package/dist/neo.mjs
CHANGED
|
@@ -169,6 +169,9 @@ function warn(text) {
|
|
|
169
169
|
function note(text) {
|
|
170
170
|
console.log(color.dim(text));
|
|
171
171
|
}
|
|
172
|
+
function pad(text, width) {
|
|
173
|
+
return text.length >= width ? text : text + " ".repeat(width - text.length);
|
|
174
|
+
}
|
|
172
175
|
function paintChangeKind(kind) {
|
|
173
176
|
const painter = CHANGE_KIND_COLOR[kind];
|
|
174
177
|
return painter === void 0 ? kind : painter(kind);
|
|
@@ -46689,9 +46692,9 @@ ${namedArguments(
|
|
|
46689
46692
|
`;
|
|
46690
46693
|
}
|
|
46691
46694
|
function namedArguments(entries, spaces, raw = /* @__PURE__ */ new Set()) {
|
|
46692
|
-
const
|
|
46695
|
+
const pad2 = " ".repeat(spaces);
|
|
46693
46696
|
return entries.map(
|
|
46694
|
-
([name, value]) => `${
|
|
46697
|
+
([name, value]) => `${pad2}${name}: ${raw.has(name) ? rawValue(value) : jsonValue2(value)},`
|
|
46695
46698
|
).join("\n");
|
|
46696
46699
|
}
|
|
46697
46700
|
function rawValue(value) {
|
|
@@ -57376,6 +57379,13 @@ var init_NeoScriptScope = __esm({
|
|
|
57376
57379
|
setLocal(bindingId, value) {
|
|
57377
57380
|
this.#bindings.set(bindingId, value);
|
|
57378
57381
|
}
|
|
57382
|
+
bindInvocationEntry(bindingId, value) {
|
|
57383
|
+
this.#bindings.set(bindingId, value);
|
|
57384
|
+
}
|
|
57385
|
+
bindInvocationKeyAndEntry(keyBindingId, key, entryBindingId, entry) {
|
|
57386
|
+
this.#bindings.set(keyBindingId, key);
|
|
57387
|
+
this.#bindings.set(entryBindingId, entry);
|
|
57388
|
+
}
|
|
57379
57389
|
resetInvocationLocals(parameterCount) {
|
|
57380
57390
|
if (this.#bindings.size > parameterCount) this.#bindings.clear();
|
|
57381
57391
|
if (this.#readonlyBindingErrors.size > 0) {
|
|
@@ -62423,6 +62433,211 @@ function evalDeclaredListIndex(info, scope, ctx) {
|
|
|
62423
62433
|
}
|
|
62424
62434
|
return Array.isArray(hit) ? [...hit] : [];
|
|
62425
62435
|
}
|
|
62436
|
+
function prepareCollectionCallback(callback, parentScope, ctx, isList, returnContract, onPredicateMatch) {
|
|
62437
|
+
const metrics = ctx.__collectionCallbackPreparationMetrics;
|
|
62438
|
+
if (metrics !== void 0) metrics.bodyValidations += 1;
|
|
62439
|
+
const compilerRevision = callback.compilerRevision ?? 1;
|
|
62440
|
+
if (!Number.isSafeInteger(compilerRevision)) {
|
|
62441
|
+
throw new NSGetterRuntimeError(
|
|
62442
|
+
"Collection callback compiler revision must be a safe integer."
|
|
62443
|
+
);
|
|
62444
|
+
}
|
|
62445
|
+
if (compilerRevision < 1) {
|
|
62446
|
+
throw new NSGetterRuntimeError(
|
|
62447
|
+
"Collection callback compiler revision must be at least 1."
|
|
62448
|
+
);
|
|
62449
|
+
}
|
|
62450
|
+
if (compilerRevision > NEOSCRIPT_COMPILER_REVISION) {
|
|
62451
|
+
throw new NSGetterRuntimeError(
|
|
62452
|
+
`Collection callback compiler revision ${String(compilerRevision)} is newer than supported revision ${String(NEOSCRIPT_COMPILER_REVISION)}.`
|
|
62453
|
+
);
|
|
62454
|
+
}
|
|
62455
|
+
if (!isNSFunctionWithReturnType(callback)) {
|
|
62456
|
+
throw new NSGetterRuntimeError(
|
|
62457
|
+
`Collection callback body metadata is invalid for compiler revision ${String(compilerRevision)}.`
|
|
62458
|
+
);
|
|
62459
|
+
}
|
|
62460
|
+
const parameters = callback.parameters;
|
|
62461
|
+
if (parameters.length < 1) {
|
|
62462
|
+
throw new NSGetterRuntimeError(
|
|
62463
|
+
"Collection callback requires at least one parameter."
|
|
62464
|
+
);
|
|
62465
|
+
}
|
|
62466
|
+
if (parameters.length > 2) {
|
|
62467
|
+
throw new NSGetterRuntimeError(
|
|
62468
|
+
`Collection callback supports at most two parameters, but received ${String(parameters.length)}.`
|
|
62469
|
+
);
|
|
62470
|
+
}
|
|
62471
|
+
if (returnContract === "predicate") {
|
|
62472
|
+
if (callback.typeInfo.type !== 1 /* Bool */) {
|
|
62473
|
+
throw new NSGetterRuntimeError(
|
|
62474
|
+
"Collection predicate callback must declare a Bool return type."
|
|
62475
|
+
);
|
|
62476
|
+
}
|
|
62477
|
+
if (!callback.typeInfo.required) {
|
|
62478
|
+
throw new NSGetterRuntimeError(
|
|
62479
|
+
"Collection predicate callback must declare a required return type."
|
|
62480
|
+
);
|
|
62481
|
+
}
|
|
62482
|
+
}
|
|
62483
|
+
const parameterCount = parameters.length;
|
|
62484
|
+
const callbackScope = ctx.__collectionCallbackStrategy === "fresh" ? null : createChildScope(parentScope);
|
|
62485
|
+
const callbackOptions = evaluationOptions(ctx, false);
|
|
62486
|
+
const instructions = callback.instructions;
|
|
62487
|
+
const returnTypeInfo = callback.typeInfo;
|
|
62488
|
+
const requiresInvocationReset = callbackBodyMayAddInvocationLocals(
|
|
62489
|
+
instructions,
|
|
62490
|
+
new Set(parameters.map((parameter4) => parameter4.id))
|
|
62491
|
+
);
|
|
62492
|
+
let finishBody;
|
|
62493
|
+
if (returnContract === "predicate") {
|
|
62494
|
+
finishBody = (innerScope2) => {
|
|
62495
|
+
const result = evalInstructions(
|
|
62496
|
+
instructions,
|
|
62497
|
+
innerScope2,
|
|
62498
|
+
ctx,
|
|
62499
|
+
callbackOptions
|
|
62500
|
+
);
|
|
62501
|
+
rejectEscapedLoopTransfer(result, "collection callback");
|
|
62502
|
+
if (result.kind !== "return") {
|
|
62503
|
+
throw new NSGetterRuntimeError(
|
|
62504
|
+
"Collection callback ended without returning a value."
|
|
62505
|
+
);
|
|
62506
|
+
}
|
|
62507
|
+
const value = result.value;
|
|
62508
|
+
if (typeof value !== "boolean") {
|
|
62509
|
+
throw new NSGetterRuntimeError(
|
|
62510
|
+
"Collection predicate callback returned a value that does not match its required Bool contract."
|
|
62511
|
+
);
|
|
62512
|
+
}
|
|
62513
|
+
return value;
|
|
62514
|
+
};
|
|
62515
|
+
} else {
|
|
62516
|
+
finishBody = (innerScope2) => {
|
|
62517
|
+
const result = evalInstructions(
|
|
62518
|
+
instructions,
|
|
62519
|
+
innerScope2,
|
|
62520
|
+
ctx,
|
|
62521
|
+
callbackOptions
|
|
62522
|
+
);
|
|
62523
|
+
rejectEscapedLoopTransfer(result, "collection callback");
|
|
62524
|
+
if (result.kind !== "return") {
|
|
62525
|
+
throw new NSGetterRuntimeError(
|
|
62526
|
+
"Collection callback ended without returning a value."
|
|
62527
|
+
);
|
|
62528
|
+
}
|
|
62529
|
+
let value = result.value;
|
|
62530
|
+
if (returnTypeInfo.type === 20 /* Decimal */ && typeof value === "number") {
|
|
62531
|
+
value = coerceDecimalOperand(value, "collection callback return");
|
|
62532
|
+
}
|
|
62533
|
+
if (!runtimeValueMatchesType(value, returnTypeInfo, ctx)) {
|
|
62534
|
+
throw new NSGetterRuntimeError(
|
|
62535
|
+
"Collection projection callback returned a value that does not match its compiled return type."
|
|
62536
|
+
);
|
|
62537
|
+
}
|
|
62538
|
+
return value;
|
|
62539
|
+
};
|
|
62540
|
+
}
|
|
62541
|
+
if (metrics !== void 0) metrics.bindingPlanCreations += 1;
|
|
62542
|
+
if (ctx.__collectionCallbackStrategy === "fresh" || ctx.__collectionCallbackStrategy === "prepared") {
|
|
62543
|
+
return (entry, key, valueId) => {
|
|
62544
|
+
if (onPredicateMatch !== void 0) {
|
|
62545
|
+
consumeBudget(ctx, "workUnits", 1, "work unit");
|
|
62546
|
+
}
|
|
62547
|
+
const innerScope2 = callbackScope ?? createChildScope(parentScope);
|
|
62548
|
+
if (callbackScope !== null) {
|
|
62549
|
+
callbackScope.resetInvocationLocals(parameterCount);
|
|
62550
|
+
}
|
|
62551
|
+
if (parameters.length === 1) {
|
|
62552
|
+
innerScope2.setLocal(parameters[0].id, entry);
|
|
62553
|
+
} else if (parameters.length === 2) {
|
|
62554
|
+
innerScope2.setLocal(
|
|
62555
|
+
parameters[0].id,
|
|
62556
|
+
isList ? Number(key) : String(key)
|
|
62557
|
+
);
|
|
62558
|
+
innerScope2.setLocal(parameters[1].id, entry);
|
|
62559
|
+
}
|
|
62560
|
+
const value = finishBody(innerScope2);
|
|
62561
|
+
if (onPredicateMatch === void 0) return value;
|
|
62562
|
+
return value === true ? onPredicateMatch(entry, key, valueId) : 0 /* Continue */;
|
|
62563
|
+
};
|
|
62564
|
+
}
|
|
62565
|
+
const innerScope = callbackScope ?? createChildScope(parentScope);
|
|
62566
|
+
let bindValues;
|
|
62567
|
+
if (parameterCount === 1) {
|
|
62568
|
+
const entryParameterId = parameters[0].id;
|
|
62569
|
+
bindValues = (entry) => {
|
|
62570
|
+
innerScope.bindInvocationEntry(entryParameterId, entry);
|
|
62571
|
+
};
|
|
62572
|
+
} else {
|
|
62573
|
+
const keyParameterId = parameters[0].id;
|
|
62574
|
+
const entryParameterId = parameters[1].id;
|
|
62575
|
+
bindValues = (entry, key) => {
|
|
62576
|
+
innerScope.bindInvocationKeyAndEntry(
|
|
62577
|
+
keyParameterId,
|
|
62578
|
+
key,
|
|
62579
|
+
entryParameterId,
|
|
62580
|
+
entry
|
|
62581
|
+
);
|
|
62582
|
+
};
|
|
62583
|
+
}
|
|
62584
|
+
if (returnContract === "predicate") {
|
|
62585
|
+
if (onPredicateMatch === void 0) {
|
|
62586
|
+
throw new NSGetterRuntimeError(
|
|
62587
|
+
"Collection predicate preparation requires a match handler."
|
|
62588
|
+
);
|
|
62589
|
+
}
|
|
62590
|
+
if (requiresInvocationReset) {
|
|
62591
|
+
return (entry, key, valueId) => {
|
|
62592
|
+
consumeBudget(ctx, "workUnits", 1, "work unit");
|
|
62593
|
+
innerScope.resetInvocationLocals(parameterCount);
|
|
62594
|
+
bindValues(entry, key);
|
|
62595
|
+
return finishBody(innerScope) === true ? onPredicateMatch(entry, key, valueId) : 0 /* Continue */;
|
|
62596
|
+
};
|
|
62597
|
+
}
|
|
62598
|
+
return (entry, key, valueId) => {
|
|
62599
|
+
consumeBudget(ctx, "workUnits", 1, "work unit");
|
|
62600
|
+
bindValues(entry, key);
|
|
62601
|
+
return finishBody(innerScope) === true ? onPredicateMatch(entry, key, valueId) : 0 /* Continue */;
|
|
62602
|
+
};
|
|
62603
|
+
}
|
|
62604
|
+
if (requiresInvocationReset) {
|
|
62605
|
+
return (entry, key) => {
|
|
62606
|
+
innerScope.resetInvocationLocals(parameterCount);
|
|
62607
|
+
bindValues(entry, key);
|
|
62608
|
+
return finishBody(innerScope);
|
|
62609
|
+
};
|
|
62610
|
+
}
|
|
62611
|
+
return (entry, key) => {
|
|
62612
|
+
bindValues(entry, key);
|
|
62613
|
+
return finishBody(innerScope);
|
|
62614
|
+
};
|
|
62615
|
+
}
|
|
62616
|
+
function callbackBodyMayAddInvocationLocals(instructions, parameterIds) {
|
|
62617
|
+
return instructions.some((instruction) => {
|
|
62618
|
+
switch (instruction.type) {
|
|
62619
|
+
case "variable" /* variable */:
|
|
62620
|
+
return !parameterIds.has(instruction.variable.id);
|
|
62621
|
+
case "assign" /* assign */:
|
|
62622
|
+
return instruction.target.pointer.type === "variable" /* variable */ && !parameterIds.has(instruction.target.pointer.variableId);
|
|
62623
|
+
case "if" /* if */:
|
|
62624
|
+
case "for" /* for */:
|
|
62625
|
+
case "forEach" /* forEach */:
|
|
62626
|
+
case "switch" /* switch */:
|
|
62627
|
+
case "try" /* try */:
|
|
62628
|
+
return true;
|
|
62629
|
+
default:
|
|
62630
|
+
return false;
|
|
62631
|
+
}
|
|
62632
|
+
});
|
|
62633
|
+
}
|
|
62634
|
+
function isListCollection(collection) {
|
|
62635
|
+
if (Array.isArray(collection)) return true;
|
|
62636
|
+
if (typeof collection === "object" && collection !== null) return false;
|
|
62637
|
+
throw new NSGetterRuntimeError(
|
|
62638
|
+
"Collection callback receiver must be a present List or Dictionary value."
|
|
62639
|
+
);
|
|
62640
|
+
}
|
|
62426
62641
|
function evalFunction(fn, scope, ctx) {
|
|
62427
62642
|
switch (fn.type) {
|
|
62428
62643
|
case "classConstructor" /* classConstructor */:
|
|
@@ -62609,34 +62824,15 @@ function evalFunction(fn, scope, ctx) {
|
|
|
62609
62824
|
case "where" /* where */: {
|
|
62610
62825
|
const c = evalPointer(fn.info.collectionPointer, scope, ctx);
|
|
62611
62826
|
const innerFn = fn.info.function;
|
|
62612
|
-
const isList =
|
|
62827
|
+
const isList = isListCollection(c);
|
|
62613
62828
|
const out = isList ? [] : {};
|
|
62614
|
-
const
|
|
62615
|
-
|
|
62616
|
-
|
|
62617
|
-
|
|
62618
|
-
|
|
62619
|
-
|
|
62620
|
-
|
|
62621
|
-
if (callbackScope !== null) {
|
|
62622
|
-
callbackScope.resetInvocationLocals(callbackParameterCount);
|
|
62623
|
-
if (callbackParameterCount === 1) {
|
|
62624
|
-
callbackScope.setLocal(innerFn.parameters[0].id, entry);
|
|
62625
|
-
} else if (callbackParameterCount === 2) {
|
|
62626
|
-
callbackScope.setLocal(
|
|
62627
|
-
innerFn.parameters[0].id,
|
|
62628
|
-
isList ? Number(key) : String(key)
|
|
62629
|
-
);
|
|
62630
|
-
callbackScope.setLocal(innerFn.parameters[1].id, entry);
|
|
62631
|
-
}
|
|
62632
|
-
}
|
|
62633
|
-
const result = evalInstructions(
|
|
62634
|
-
innerFn.instructions,
|
|
62635
|
-
innerScope,
|
|
62636
|
-
ctx,
|
|
62637
|
-
callbackOptions ?? evaluationOptions(ctx, false)
|
|
62638
|
-
);
|
|
62639
|
-
if (result.kind === "return" && result.value === true) {
|
|
62829
|
+
const callback = prepareCollectionCallback(
|
|
62830
|
+
innerFn,
|
|
62831
|
+
scope,
|
|
62832
|
+
ctx,
|
|
62833
|
+
isList,
|
|
62834
|
+
"predicate",
|
|
62835
|
+
(entry, key, valueId) => {
|
|
62640
62836
|
consumeBudget(
|
|
62641
62837
|
ctx,
|
|
62642
62838
|
"producedCollectionEntries",
|
|
@@ -62648,53 +62844,38 @@ function evalFunction(fn, scope, ctx) {
|
|
|
62648
62844
|
} else {
|
|
62649
62845
|
out[String(key)] = valueId ?? entry;
|
|
62650
62846
|
}
|
|
62847
|
+
return 0 /* Continue */;
|
|
62651
62848
|
}
|
|
62652
|
-
|
|
62653
|
-
|
|
62849
|
+
);
|
|
62850
|
+
iterateCollection(c, ctx, callback);
|
|
62654
62851
|
return out;
|
|
62655
62852
|
}
|
|
62656
62853
|
case "first" /* first */:
|
|
62657
62854
|
case "firstOrDefault" /* firstOrDefault */: {
|
|
62658
62855
|
const c = evalPointer(fn.info.collectionPointer, scope, ctx);
|
|
62659
62856
|
const innerFn = fn.info.function ?? null;
|
|
62660
|
-
const isList =
|
|
62857
|
+
const isList = isListCollection(c);
|
|
62661
62858
|
const sentinel = /* @__PURE__ */ Symbol("not-found");
|
|
62662
|
-
const useFreshCallbackScope = ctx.__collectionCallbackStrategy === "fresh";
|
|
62663
|
-
const callbackScope = innerFn === null || useFreshCallbackScope ? null : createChildScope(scope);
|
|
62664
|
-
const callbackOptions = innerFn === null || useFreshCallbackScope ? null : evaluationOptions(ctx, false);
|
|
62665
|
-
const callbackParameterCount = innerFn !== null && (innerFn.parameters.length === 1 || innerFn.parameters.length === 2) ? innerFn.parameters.length : 0;
|
|
62666
62859
|
let found = sentinel;
|
|
62667
|
-
|
|
62668
|
-
|
|
62860
|
+
if (innerFn === null) {
|
|
62861
|
+
iterateCollection(c, ctx, (entry) => {
|
|
62669
62862
|
found = entry;
|
|
62670
62863
|
return 1 /* Break */;
|
|
62671
|
-
}
|
|
62672
|
-
|
|
62673
|
-
const
|
|
62674
|
-
|
|
62675
|
-
|
|
62676
|
-
if (callbackParameterCount === 1) {
|
|
62677
|
-
callbackScope.setLocal(innerFn.parameters[0].id, entry);
|
|
62678
|
-
} else if (callbackParameterCount === 2) {
|
|
62679
|
-
callbackScope.setLocal(
|
|
62680
|
-
innerFn.parameters[0].id,
|
|
62681
|
-
isList ? Number(key) : String(key)
|
|
62682
|
-
);
|
|
62683
|
-
callbackScope.setLocal(innerFn.parameters[1].id, entry);
|
|
62684
|
-
}
|
|
62685
|
-
}
|
|
62686
|
-
const result = evalInstructions(
|
|
62687
|
-
innerFn.instructions,
|
|
62688
|
-
innerScope,
|
|
62864
|
+
});
|
|
62865
|
+
} else {
|
|
62866
|
+
const callback = prepareCollectionCallback(
|
|
62867
|
+
innerFn,
|
|
62868
|
+
scope,
|
|
62689
62869
|
ctx,
|
|
62690
|
-
|
|
62870
|
+
isList,
|
|
62871
|
+
"predicate",
|
|
62872
|
+
(entry) => {
|
|
62873
|
+
found = entry;
|
|
62874
|
+
return 1 /* Break */;
|
|
62875
|
+
}
|
|
62691
62876
|
);
|
|
62692
|
-
|
|
62693
|
-
|
|
62694
|
-
return 1 /* Break */;
|
|
62695
|
-
}
|
|
62696
|
-
return 0 /* Continue */;
|
|
62697
|
-
});
|
|
62877
|
+
iterateCollection(c, ctx, callback);
|
|
62878
|
+
}
|
|
62698
62879
|
if (found !== sentinel) return found;
|
|
62699
62880
|
if (fn.type === "first" /* first */) {
|
|
62700
62881
|
throw new NSGetterRuntimeError(
|
|
@@ -62705,43 +62886,26 @@ function evalFunction(fn, scope, ctx) {
|
|
|
62705
62886
|
}
|
|
62706
62887
|
case "select" /* select */: {
|
|
62707
62888
|
const c = evalPointer(fn.info.collectionPointer, scope, ctx);
|
|
62708
|
-
const useFreshCallbackScope = ctx.__collectionCallbackStrategy === "fresh";
|
|
62709
|
-
const callbackScope = useFreshCallbackScope ? null : createChildScope(scope);
|
|
62710
|
-
const callbackOptions = useFreshCallbackScope ? null : evaluationOptions(ctx, false);
|
|
62711
62889
|
const innerFn = fn.info.function;
|
|
62712
|
-
const
|
|
62713
|
-
const
|
|
62890
|
+
const isList = isListCollection(c);
|
|
62891
|
+
const callback = prepareCollectionCallback(
|
|
62892
|
+
innerFn,
|
|
62893
|
+
scope,
|
|
62894
|
+
ctx,
|
|
62895
|
+
isList,
|
|
62896
|
+
"projection"
|
|
62897
|
+
);
|
|
62714
62898
|
const out = [];
|
|
62715
|
-
iterateCollection(c, ctx, (entry, key) => {
|
|
62899
|
+
iterateCollection(c, ctx, (entry, key, valueId) => {
|
|
62716
62900
|
consumeBudget(ctx, "workUnits", 1, "work unit");
|
|
62717
|
-
const
|
|
62718
|
-
|
|
62719
|
-
callbackScope.resetInvocationLocals(callbackParameterCount);
|
|
62720
|
-
if (callbackParameterCount === 1) {
|
|
62721
|
-
callbackScope.setLocal(innerFn.parameters[0].id, entry);
|
|
62722
|
-
} else if (callbackParameterCount === 2) {
|
|
62723
|
-
callbackScope.setLocal(
|
|
62724
|
-
innerFn.parameters[0].id,
|
|
62725
|
-
isList ? Number(key) : String(key)
|
|
62726
|
-
);
|
|
62727
|
-
callbackScope.setLocal(innerFn.parameters[1].id, entry);
|
|
62728
|
-
}
|
|
62729
|
-
}
|
|
62730
|
-
const result = evalInstructions(
|
|
62731
|
-
innerFn.instructions,
|
|
62732
|
-
innerScope,
|
|
62901
|
+
const value = callback(entry, key, valueId);
|
|
62902
|
+
consumeBudget(
|
|
62733
62903
|
ctx,
|
|
62734
|
-
|
|
62904
|
+
"producedCollectionEntries",
|
|
62905
|
+
1,
|
|
62906
|
+
"produced collection entry"
|
|
62735
62907
|
);
|
|
62736
|
-
|
|
62737
|
-
consumeBudget(
|
|
62738
|
-
ctx,
|
|
62739
|
-
"producedCollectionEntries",
|
|
62740
|
-
1,
|
|
62741
|
-
"produced collection entry"
|
|
62742
|
-
);
|
|
62743
|
-
out.push(result.value);
|
|
62744
|
-
}
|
|
62908
|
+
out.push(value);
|
|
62745
62909
|
return 0 /* Continue */;
|
|
62746
62910
|
});
|
|
62747
62911
|
return out;
|
|
@@ -65294,17 +65458,6 @@ function iterateCollection(c, ctx, callback) {
|
|
|
65294
65458
|
return callback(entry, key, valueId);
|
|
65295
65459
|
});
|
|
65296
65460
|
}
|
|
65297
|
-
function pushParams(parent, parameters, positional, isList) {
|
|
65298
|
-
const child = createChildScope(parent);
|
|
65299
|
-
if (parameters.length === 1) {
|
|
65300
|
-
child.setLocal(parameters[0].id, positional[1]);
|
|
65301
|
-
} else if (parameters.length === 2) {
|
|
65302
|
-
const first = isList ? Number(positional[0]) : String(positional[0]);
|
|
65303
|
-
child.setLocal(parameters[0].id, first);
|
|
65304
|
-
child.setLocal(parameters[1].id, positional[1]);
|
|
65305
|
-
}
|
|
65306
|
-
return child;
|
|
65307
|
-
}
|
|
65308
65461
|
var DELEGATE_LEXICAL_THIS, DELEGATE_LEXICAL_ROOT, NonCatchableNSGetterRuntimeError, NativeFunctionDelegateUnavailableError, CorruptNeoScriptIRError, NeoScriptResourceLimitError, NeoScriptWallClockTimeoutError, DEFAULT_NEO_SCRIPT_EXECUTION_BUDGET_LIMITS, liveListIndexesByProject, evaluatorOwnershipCachesByBase, MAX_CONSTRUCTION_DEPTH, MAX_LOOP_ITERATIONS, resolutionCacheByMembers, NO_SCHEMA_REVISION, LazyValueOverlay, READONLY_FOREACH_BINDING_ERROR, READONLY_CATCH_BINDING_ERROR;
|
|
65309
65462
|
var init_evaluateNSGetter = __esm({
|
|
65310
65463
|
"../src/view-models/neoscript-evaluator/evaluateNSGetter.ts"() {
|
|
@@ -65318,6 +65471,7 @@ var init_evaluateNSGetter = __esm({
|
|
|
65318
65471
|
init_neoscript();
|
|
65319
65472
|
init_NSGetterRuntimeError();
|
|
65320
65473
|
init_value_row_owner_members();
|
|
65474
|
+
init_src();
|
|
65321
65475
|
init_decimal();
|
|
65322
65476
|
init_members();
|
|
65323
65477
|
init_core();
|
|
@@ -102478,7 +102632,7 @@ var init_registry2 = __esm({
|
|
|
102478
102632
|
PROJECT_SCHEMA_CONTRACT = Object.freeze({
|
|
102479
102633
|
formatVersion: 3,
|
|
102480
102634
|
contractVersion: "3.9",
|
|
102481
|
-
cliVersion: "0.26.
|
|
102635
|
+
cliVersion: "0.26.3",
|
|
102482
102636
|
projectFileUploadBatchSize: 32,
|
|
102483
102637
|
documentRecords: {
|
|
102484
102638
|
member: {
|
|
@@ -103792,6 +103946,7 @@ import {
|
|
|
103792
103946
|
resolve as resolve3,
|
|
103793
103947
|
sep as sep5
|
|
103794
103948
|
} from "node:path";
|
|
103949
|
+
import { isDeepStrictEqual } from "node:util";
|
|
103795
103950
|
function isRecord10(value) {
|
|
103796
103951
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
103797
103952
|
}
|
|
@@ -103875,9 +104030,46 @@ function stableTestValue(value) {
|
|
|
103875
104030
|
function display(value) {
|
|
103876
104031
|
return stableTestValue(value);
|
|
103877
104032
|
}
|
|
103878
|
-
function
|
|
103879
|
-
|
|
103880
|
-
|
|
104033
|
+
function matcherFailureMessage(kind, expectationValue, expected, received, details) {
|
|
104034
|
+
const actual = expectationValue.actual;
|
|
104035
|
+
const negation = expectationValue.negated ? "not " : "";
|
|
104036
|
+
switch (kind) {
|
|
104037
|
+
case "toBe":
|
|
104038
|
+
return `Expected ${display(actual)} ${negation}to be ${display(expected)}.`;
|
|
104039
|
+
case "toEqual":
|
|
104040
|
+
return `Expected ${display(actual)} ${negation}to equal ${display(expected)}.`;
|
|
104041
|
+
case "toBeNull":
|
|
104042
|
+
return `Expected ${display(actual)} ${negation}to be null.`;
|
|
104043
|
+
case "boolean":
|
|
104044
|
+
return `Expected ${display(actual)} ${negation}to be ${String(expected)}.`;
|
|
104045
|
+
case "numeric":
|
|
104046
|
+
return `Expected ${display(actual)} ${negation}to satisfy numeric comparison with ${display(expected)}.`;
|
|
104047
|
+
case "toContain":
|
|
104048
|
+
return `Expected ${display(actual)} ${negation}to contain ${display(expected)}.`;
|
|
104049
|
+
case "toHaveLength":
|
|
104050
|
+
return `Expected length ${String(expected)}, received ${String(received)}.`;
|
|
104051
|
+
case "toMatchObject":
|
|
104052
|
+
return `Expected ${display(actual)} ${negation}to match ${display(expected)}.`;
|
|
104053
|
+
case "toThrow":
|
|
104054
|
+
return `Expected callback ${negation}to throw${details === void 0 ? "" : ` a message containing ${display(details)}`}.`;
|
|
104055
|
+
case "mock":
|
|
104056
|
+
return `Expected mock ${negation}to match recorded calls ${display(details)}.`;
|
|
104057
|
+
}
|
|
104058
|
+
}
|
|
104059
|
+
function assertMatcher(condition, expectationValue, messageKind, expected, received = expectationValue.actual, details) {
|
|
104060
|
+
if (condition === expectationValue.negated) {
|
|
104061
|
+
throw new NeoTestAssertionError(
|
|
104062
|
+
matcherFailureMessage(
|
|
104063
|
+
messageKind,
|
|
104064
|
+
expectationValue,
|
|
104065
|
+
expected,
|
|
104066
|
+
received,
|
|
104067
|
+
details
|
|
104068
|
+
),
|
|
104069
|
+
expected,
|
|
104070
|
+
received
|
|
104071
|
+
);
|
|
104072
|
+
}
|
|
103881
104073
|
}
|
|
103882
104074
|
function errorMessage2(error) {
|
|
103883
104075
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -104426,8 +104618,7 @@ function mockResponse(environment, mock, selected2, call) {
|
|
|
104426
104618
|
};
|
|
104427
104619
|
}
|
|
104428
104620
|
function partialObjectMatch(actual, expected) {
|
|
104429
|
-
if (!isRecord10(expected))
|
|
104430
|
-
return stableTestValue(actual) === stableTestValue(expected);
|
|
104621
|
+
if (!isRecord10(expected)) return isDeepStrictEqual(actual, expected);
|
|
104431
104622
|
if (!isRecord10(actual)) return false;
|
|
104432
104623
|
return Object.entries(expected).every(
|
|
104433
104624
|
([key, value]) => partialObjectMatch(actual[key], value)
|
|
@@ -104584,56 +104775,28 @@ function interceptTestCallCore(environment, call) {
|
|
|
104584
104775
|
}
|
|
104585
104776
|
return { handled: true, value: null };
|
|
104586
104777
|
}
|
|
104587
|
-
|
|
104588
|
-
NEO_TEST_IDS.toBe,
|
|
104589
|
-
NEO_TEST_IDS.toEqual,
|
|
104590
|
-
NEO_TEST_IDS.toBeNull,
|
|
104591
|
-
NEO_TEST_IDS.toBeTrue,
|
|
104592
|
-
NEO_TEST_IDS.toBeFalse,
|
|
104593
|
-
NEO_TEST_IDS.toBeGreaterThan,
|
|
104594
|
-
NEO_TEST_IDS.toBeGreaterThanOrEqual,
|
|
104595
|
-
NEO_TEST_IDS.toBeLessThan,
|
|
104596
|
-
NEO_TEST_IDS.toBeLessThanOrEqual,
|
|
104597
|
-
NEO_TEST_IDS.toContain,
|
|
104598
|
-
NEO_TEST_IDS.toHaveLength,
|
|
104599
|
-
NEO_TEST_IDS.toMatchObject,
|
|
104600
|
-
NEO_TEST_IDS.toThrow,
|
|
104601
|
-
NEO_TEST_IDS.toHaveBeenCalled,
|
|
104602
|
-
NEO_TEST_IDS.toHaveBeenCalledTimes,
|
|
104603
|
-
NEO_TEST_IDS.toHaveBeenCalledWith
|
|
104604
|
-
]);
|
|
104605
|
-
if (!matcherIds.has(call.memberId)) return { handled: false };
|
|
104778
|
+
if (!MATCHER_IDS.has(call.memberId)) return { handled: false };
|
|
104606
104779
|
const expectationValue = readExpectation(call.receiver);
|
|
104607
104780
|
const actual = expectationValue.actual;
|
|
104608
104781
|
if (call.memberId === NEO_TEST_IDS.toBe) {
|
|
104609
104782
|
assertMatcher(
|
|
104610
104783
|
Object.is(actual, call.args[0]),
|
|
104611
104784
|
expectationValue,
|
|
104612
|
-
|
|
104785
|
+
"toBe",
|
|
104613
104786
|
call.args[0]
|
|
104614
104787
|
);
|
|
104615
104788
|
} else if (call.memberId === NEO_TEST_IDS.toEqual) {
|
|
104616
104789
|
assertMatcher(
|
|
104617
|
-
|
|
104790
|
+
isDeepStrictEqual(actual, call.args[0]),
|
|
104618
104791
|
expectationValue,
|
|
104619
|
-
|
|
104792
|
+
"toEqual",
|
|
104620
104793
|
call.args[0]
|
|
104621
104794
|
);
|
|
104622
104795
|
} else if (call.memberId === NEO_TEST_IDS.toBeNull) {
|
|
104623
|
-
assertMatcher(
|
|
104624
|
-
actual === null,
|
|
104625
|
-
expectationValue,
|
|
104626
|
-
`Expected ${display(actual)} ${expectationValue.negated ? "not " : ""}to be null.`,
|
|
104627
|
-
null
|
|
104628
|
-
);
|
|
104796
|
+
assertMatcher(actual === null, expectationValue, "toBeNull", null);
|
|
104629
104797
|
} else if (call.memberId === NEO_TEST_IDS.toBeTrue || call.memberId === NEO_TEST_IDS.toBeFalse) {
|
|
104630
104798
|
const expected = call.memberId === NEO_TEST_IDS.toBeTrue;
|
|
104631
|
-
assertMatcher(
|
|
104632
|
-
actual === expected,
|
|
104633
|
-
expectationValue,
|
|
104634
|
-
`Expected ${display(actual)} ${expectationValue.negated ? "not " : ""}to be ${String(expected)}.`,
|
|
104635
|
-
expected
|
|
104636
|
-
);
|
|
104799
|
+
assertMatcher(actual === expected, expectationValue, "boolean", expected);
|
|
104637
104800
|
} else if (call.memberId === NEO_TEST_IDS.toBeGreaterThan || call.memberId === NEO_TEST_IDS.toBeGreaterThanOrEqual || call.memberId === NEO_TEST_IDS.toBeLessThan || call.memberId === NEO_TEST_IDS.toBeLessThanOrEqual) {
|
|
104638
104801
|
const left = Number(actual);
|
|
104639
104802
|
const right = Number(call.args[0]);
|
|
@@ -104641,25 +104804,18 @@ function interceptTestCallCore(environment, call) {
|
|
|
104641
104804
|
assertMatcher(
|
|
104642
104805
|
Number.isFinite(left) && Number.isFinite(right) && matches,
|
|
104643
104806
|
expectationValue,
|
|
104644
|
-
|
|
104807
|
+
"numeric",
|
|
104645
104808
|
call.args[0]
|
|
104646
104809
|
);
|
|
104647
104810
|
} else if (call.memberId === NEO_TEST_IDS.toContain) {
|
|
104648
|
-
const contains2 = typeof actual === "string" ? actual.includes(String(call.args[0])) : Array.isArray(actual) && actual.some(
|
|
104649
|
-
|
|
104650
|
-
);
|
|
104651
|
-
assertMatcher(
|
|
104652
|
-
contains2,
|
|
104653
|
-
expectationValue,
|
|
104654
|
-
`Expected ${display(actual)} ${expectationValue.negated ? "not " : ""}to contain ${display(call.args[0])}.`,
|
|
104655
|
-
call.args[0]
|
|
104656
|
-
);
|
|
104811
|
+
const contains2 = typeof actual === "string" ? actual.includes(String(call.args[0])) : Array.isArray(actual) && actual.some((entry) => isDeepStrictEqual(entry, call.args[0]));
|
|
104812
|
+
assertMatcher(contains2, expectationValue, "toContain", call.args[0]);
|
|
104657
104813
|
} else if (call.memberId === NEO_TEST_IDS.toHaveLength) {
|
|
104658
104814
|
const length = typeof actual === "string" || Array.isArray(actual) ? actual.length : isRecord10(actual) ? Object.keys(actual).length : -1;
|
|
104659
104815
|
assertMatcher(
|
|
104660
104816
|
length === call.args[0],
|
|
104661
104817
|
expectationValue,
|
|
104662
|
-
|
|
104818
|
+
"toHaveLength",
|
|
104663
104819
|
call.args[0],
|
|
104664
104820
|
length
|
|
104665
104821
|
);
|
|
@@ -104667,7 +104823,7 @@ function interceptTestCallCore(environment, call) {
|
|
|
104667
104823
|
assertMatcher(
|
|
104668
104824
|
partialObjectMatch(actual, call.args[0]),
|
|
104669
104825
|
expectationValue,
|
|
104670
|
-
|
|
104826
|
+
"toMatchObject",
|
|
104671
104827
|
call.args[0]
|
|
104672
104828
|
);
|
|
104673
104829
|
} else if (call.memberId === NEO_TEST_IDS.toThrow) {
|
|
@@ -104683,9 +104839,10 @@ function interceptTestCallCore(environment, call) {
|
|
|
104683
104839
|
assertMatcher(
|
|
104684
104840
|
matches,
|
|
104685
104841
|
expectationValue,
|
|
104686
|
-
|
|
104842
|
+
"toThrow",
|
|
104687
104843
|
pattern ?? "a catchable NeoScript error",
|
|
104688
|
-
thrown === void 0 ? "no throw" : errorMessage2(thrown)
|
|
104844
|
+
thrown === void 0 ? "no throw" : errorMessage2(thrown),
|
|
104845
|
+
pattern
|
|
104689
104846
|
);
|
|
104690
104847
|
} else {
|
|
104691
104848
|
const handle = readMockHandle(actual);
|
|
@@ -104695,15 +104852,14 @@ function interceptTestCallCore(environment, call) {
|
|
|
104695
104852
|
"Expected value is not an active mock handle."
|
|
104696
104853
|
);
|
|
104697
104854
|
}
|
|
104698
|
-
const matches = call.memberId === NEO_TEST_IDS.toHaveBeenCalled ? mock.calls.length > 0 : call.memberId === NEO_TEST_IDS.toHaveBeenCalledTimes ? mock.calls.length === call.args[0] : mock.calls.some(
|
|
104699
|
-
(args) => stableTestValue(args) === stableTestValue(call.args)
|
|
104700
|
-
);
|
|
104855
|
+
const matches = call.memberId === NEO_TEST_IDS.toHaveBeenCalled ? mock.calls.length > 0 : call.memberId === NEO_TEST_IDS.toHaveBeenCalledTimes ? mock.calls.length === call.args[0] : mock.calls.some((args) => isDeepStrictEqual(args, call.args));
|
|
104701
104856
|
assertMatcher(
|
|
104702
104857
|
matches,
|
|
104703
104858
|
expectationValue,
|
|
104704
|
-
|
|
104859
|
+
"mock",
|
|
104705
104860
|
call.memberId === NEO_TEST_IDS.toHaveBeenCalled ? "at least one call" : call.memberId === NEO_TEST_IDS.toHaveBeenCalledTimes ? call.args[0] : call.args,
|
|
104706
|
-
call.memberId === NEO_TEST_IDS.toHaveBeenCalledTimes ? mock.calls.length : mock.calls
|
|
104861
|
+
call.memberId === NEO_TEST_IDS.toHaveBeenCalledTimes ? mock.calls.length : mock.calls,
|
|
104862
|
+
mock.calls
|
|
104707
104863
|
);
|
|
104708
104864
|
}
|
|
104709
104865
|
return { handled: true, value: null };
|
|
@@ -104994,8 +105150,24 @@ function maintainNeoTestBuildCache(root, maxBytes = TEST_BUILD_CACHE_LIMIT_BYTES
|
|
|
104994
105150
|
}
|
|
104995
105151
|
}
|
|
104996
105152
|
function formatTestDuration(durationMs) {
|
|
105153
|
+
if (durationMs >= 1e3) {
|
|
105154
|
+
const seconds = durationMs / 1e3;
|
|
105155
|
+
return `${seconds < 10 ? seconds.toFixed(2) : seconds.toFixed(1)}s`;
|
|
105156
|
+
}
|
|
104997
105157
|
return `${durationMs < 10 ? durationMs.toFixed(2) : durationMs.toFixed(1)}ms`;
|
|
104998
105158
|
}
|
|
105159
|
+
function paintTestDuration(durationMs) {
|
|
105160
|
+
const formatted = formatTestDuration(durationMs);
|
|
105161
|
+
return durationMs >= 300 ? color.yellow(formatted) : color.dim(formatted);
|
|
105162
|
+
}
|
|
105163
|
+
function formatStatusCounts(passed, failed, total, skipped = 0) {
|
|
105164
|
+
const parts = [
|
|
105165
|
+
failed > 0 ? color.red(`${failed} failed`) : null,
|
|
105166
|
+
passed > 0 ? color.green(`${passed} passed`) : null,
|
|
105167
|
+
skipped > 0 ? color.yellow(`${skipped} skipped`) : null
|
|
105168
|
+
].filter((part) => part !== null);
|
|
105169
|
+
return `${parts.join(color.dim(" | "))} ${color.dim(`(${total})`)}`;
|
|
105170
|
+
}
|
|
104999
105171
|
async function runTest(workspace, options, dependencies = {}) {
|
|
105000
105172
|
const started = Date.now();
|
|
105001
105173
|
const performanceStarted = performance.now();
|
|
@@ -105025,7 +105197,29 @@ async function runTest(workspace, options, dependencies = {}) {
|
|
|
105025
105197
|
}
|
|
105026
105198
|
};
|
|
105027
105199
|
process.on("SIGINT", handleSigint);
|
|
105200
|
+
const phaseDurations = {
|
|
105201
|
+
prepare: 0,
|
|
105202
|
+
select: 0,
|
|
105203
|
+
compile: 0,
|
|
105204
|
+
register: 0,
|
|
105205
|
+
execute: 0,
|
|
105206
|
+
finalize: 0
|
|
105207
|
+
};
|
|
105028
105208
|
let phase = "prepare";
|
|
105209
|
+
let phaseStarted = performanceStarted;
|
|
105210
|
+
const enterPhase = (next, label) => {
|
|
105211
|
+
const finished = performance.now();
|
|
105212
|
+
phaseDurations[phase] += finished - phaseStarted;
|
|
105213
|
+
phase = next;
|
|
105214
|
+
phaseStarted = finished;
|
|
105215
|
+
dependencies.progress?.update(label);
|
|
105216
|
+
};
|
|
105217
|
+
const finishPhase = () => {
|
|
105218
|
+
const finished = performance.now();
|
|
105219
|
+
phaseDurations[phase] += finished - phaseStarted;
|
|
105220
|
+
phaseStarted = finished;
|
|
105221
|
+
};
|
|
105222
|
+
dependencies.progress?.update("Preparing test project\u2026");
|
|
105029
105223
|
try {
|
|
105030
105224
|
let candidate = dependencies.prepareLocalCandidate === void 0 ? preparedHookCandidate(workspace) : null;
|
|
105031
105225
|
let candidateInputFingerprint = null;
|
|
@@ -105037,7 +105231,11 @@ async function runTest(workspace, options, dependencies = {}) {
|
|
|
105037
105231
|
candidate = cachedTestCandidate(workspace, candidateInputFingerprint);
|
|
105038
105232
|
}
|
|
105039
105233
|
if (candidate === null) {
|
|
105040
|
-
const prepared = dependencies.prepareLocalCandidate === void 0 ? await prepareLocalCandidateV4(workspace
|
|
105234
|
+
const prepared = dependencies.prepareLocalCandidate === void 0 ? await prepareLocalCandidateV4(workspace, {
|
|
105235
|
+
onPhase: (label) => {
|
|
105236
|
+
dependencies.progress?.update(label);
|
|
105237
|
+
}
|
|
105238
|
+
}) : await dependencies.prepareLocalCandidate(workspace);
|
|
105041
105239
|
if (prepared.document === null) {
|
|
105042
105240
|
throw new NeoTestReportWriteError(
|
|
105043
105241
|
"Local test preparation did not produce a project document."
|
|
@@ -105069,7 +105267,7 @@ async function runTest(workspace, options, dependencies = {}) {
|
|
|
105069
105267
|
rawDocument,
|
|
105070
105268
|
candidate.documentSha256
|
|
105071
105269
|
);
|
|
105072
|
-
|
|
105270
|
+
enterPhase("select", "Selecting test files\u2026");
|
|
105073
105271
|
let selectedPaths;
|
|
105074
105272
|
try {
|
|
105075
105273
|
selectedPaths = selectedSpecPaths(workspace, options.selectors);
|
|
@@ -105084,7 +105282,7 @@ async function runTest(workspace, options, dependencies = {}) {
|
|
|
105084
105282
|
"No .spec.neo files matched. Pass --passWithNoTests to treat this as success."
|
|
105085
105283
|
);
|
|
105086
105284
|
}
|
|
105087
|
-
|
|
105285
|
+
enterPhase("compile", "Compiling test files\u2026");
|
|
105088
105286
|
specs = selectedPaths.map(
|
|
105089
105287
|
(path) => compileSpec(workspace, rawDocument, path, compilationHash)
|
|
105090
105288
|
);
|
|
@@ -105098,7 +105296,7 @@ async function runTest(workspace, options, dependencies = {}) {
|
|
|
105098
105296
|
);
|
|
105099
105297
|
}
|
|
105100
105298
|
}
|
|
105101
|
-
|
|
105299
|
+
enterPhase("register", "Registering tests\u2026");
|
|
105102
105300
|
const registered = specs.map((spec) => registerSpec(spec, rawDocument));
|
|
105103
105301
|
const selectedTests = registered.flatMap((entry) => entry.tests).filter((test) => pattern === null || pattern.test(test.fullName));
|
|
105104
105302
|
for (const entry of registered) {
|
|
@@ -105115,7 +105313,7 @@ async function runTest(workspace, options, dependencies = {}) {
|
|
|
105115
105313
|
);
|
|
105116
105314
|
}
|
|
105117
105315
|
const selectedIds = new Set(selectedTests.map((test) => test.id));
|
|
105118
|
-
|
|
105316
|
+
enterPhase("execute", "Running tests\u2026");
|
|
105119
105317
|
const timeoutMs = options.timeoutMs ?? workspace.config.test?.timeoutMs ?? 5e3;
|
|
105120
105318
|
for (const entry of registered) {
|
|
105121
105319
|
const executed = await executeRegisteredSpec(
|
|
@@ -105133,6 +105331,7 @@ async function runTest(workspace, options, dependencies = {}) {
|
|
|
105133
105331
|
if (results.some((result) => result.status === "failed") || [...fileFailuresByPath.values()].some((failures) => failures.length > 0)) {
|
|
105134
105332
|
exitCode = 1;
|
|
105135
105333
|
}
|
|
105334
|
+
enterPhase("finalize", "Finalizing test report\u2026");
|
|
105136
105335
|
const buildManifest = {
|
|
105137
105336
|
version: 1,
|
|
105138
105337
|
cliVersion: PROJECT_SCHEMA_CONTRACT.cliVersion,
|
|
@@ -105168,6 +105367,8 @@ async function runTest(workspace, options, dependencies = {}) {
|
|
|
105168
105367
|
related: []
|
|
105169
105368
|
});
|
|
105170
105369
|
}
|
|
105370
|
+
finishPhase();
|
|
105371
|
+
dependencies.progress?.stop();
|
|
105171
105372
|
process.off("SIGINT", handleSigint);
|
|
105172
105373
|
const failed = results.filter((result) => result.status === "failed").length;
|
|
105173
105374
|
const selectedTestTotal = [...selectedTestCountByFile.values()].reduce(
|
|
@@ -105221,6 +105422,14 @@ async function runTest(workspace, options, dependencies = {}) {
|
|
|
105221
105422
|
sharedStartupDurationMs,
|
|
105222
105423
|
testDurationMs
|
|
105223
105424
|
},
|
|
105425
|
+
timings: {
|
|
105426
|
+
prepareMs: phaseDurations.prepare,
|
|
105427
|
+
selectMs: phaseDurations.select,
|
|
105428
|
+
compileMs: phaseDurations.compile,
|
|
105429
|
+
registerMs: phaseDurations.register,
|
|
105430
|
+
executeMs: phaseDurations.execute,
|
|
105431
|
+
finalizeMs: phaseDurations.finalize
|
|
105432
|
+
},
|
|
105224
105433
|
testFiles,
|
|
105225
105434
|
diagnostics,
|
|
105226
105435
|
startedAt
|
|
@@ -105244,33 +105453,63 @@ async function runTest(workspace, options, dependencies = {}) {
|
|
|
105244
105453
|
if (options.reporter === "json") {
|
|
105245
105454
|
if (options.outputFile === null) process.stdout.write(serialized);
|
|
105246
105455
|
} else {
|
|
105456
|
+
console.log("");
|
|
105457
|
+
console.log(
|
|
105458
|
+
` ${color.bold("RUN")} ${color.dim(`neo ${PROJECT_SCHEMA_CONTRACT.cliVersion} ${workspace.root}`)}`
|
|
105459
|
+
);
|
|
105460
|
+
console.log("");
|
|
105247
105461
|
console.log(
|
|
105248
|
-
|
|
105462
|
+
` ${color.cyan("\u21BB")} ${color.dim("shared startup")} ${paintTestDuration(report.summary.sharedStartupDurationMs)}`
|
|
105249
105463
|
);
|
|
105250
|
-
for (const
|
|
105464
|
+
for (const file of testFiles) {
|
|
105465
|
+
const fileDurationMs = file.tests.reduce(
|
|
105466
|
+
(sum, test) => sum + test.durationMs,
|
|
105467
|
+
0
|
|
105468
|
+
);
|
|
105469
|
+
const fileSymbol = file.status === "passed" ? color.green("\u2713") : file.status === "failed" ? color.red("\xD7") : color.yellow("!");
|
|
105470
|
+
const testLabel = `${file.tests.length} ${file.tests.length === 1 ? "test" : "tests"}`;
|
|
105251
105471
|
console.log(
|
|
105252
|
-
|
|
105472
|
+
` ${fileSymbol} ${color.bold(file.path)} ${color.dim(`(${testLabel})`)} ${paintTestDuration(fileDurationMs)}`
|
|
105253
105473
|
);
|
|
105254
|
-
for (const
|
|
105255
|
-
|
|
105256
|
-
|
|
105257
|
-
|
|
105474
|
+
for (const result of file.tests) {
|
|
105475
|
+
const resultSymbol = result.status === "passed" ? color.green("\u2713") : color.red("\xD7");
|
|
105476
|
+
console.log(
|
|
105477
|
+
` ${resultSymbol} ${result.name} ${color.dim("total")} ${paintTestDuration(result.durationMs)} ${color.dim(`(test ${formatTestDuration(result.testDurationMs)}, startup ${formatTestDuration(result.startupDurationMs)})`)}`
|
|
105478
|
+
);
|
|
105479
|
+
for (const failure of result.failures) {
|
|
105480
|
+
console.log(` ${color.red(failure.message)}`);
|
|
105481
|
+
}
|
|
105482
|
+
}
|
|
105258
105483
|
if (file.status === "interrupted") {
|
|
105259
105484
|
console.log(
|
|
105260
|
-
|
|
105485
|
+
` ${color.yellow("!")} interrupted before all selected tests ran`
|
|
105261
105486
|
);
|
|
105262
105487
|
}
|
|
105263
105488
|
for (const failure of file.failures) {
|
|
105264
105489
|
console.log(
|
|
105265
|
-
|
|
105490
|
+
` ${color.red("\xD7")} ${failure.frames[0]?.member ?? "suite hook"}`
|
|
105266
105491
|
);
|
|
105267
|
-
console.log(`
|
|
105492
|
+
console.log(` ${color.red(failure.message)}`);
|
|
105268
105493
|
}
|
|
105269
105494
|
}
|
|
105270
|
-
for (const diagnostic of diagnostics)
|
|
105271
|
-
console.log(
|
|
105495
|
+
for (const diagnostic of diagnostics) {
|
|
105496
|
+
console.log(` ${color.red("\xD7")} ${diagnostic.message}`);
|
|
105497
|
+
}
|
|
105498
|
+
console.log("");
|
|
105499
|
+
const passedFiles = testFiles.filter(
|
|
105500
|
+
(file) => file.status === "passed"
|
|
105501
|
+
).length;
|
|
105502
|
+
const failedFiles = testFiles.filter(
|
|
105503
|
+
(file) => file.status === "failed"
|
|
105504
|
+
).length;
|
|
105505
|
+
console.log(
|
|
105506
|
+
` ${color.bold(pad("Test Files", 11))} ${formatStatusCounts(passedFiles, failedFiles, report.summary.files)}`
|
|
105507
|
+
);
|
|
105508
|
+
console.log(
|
|
105509
|
+
` ${color.bold(pad("Tests", 11))} ${formatStatusCounts(report.summary.passed, report.summary.failed, report.summary.tests, report.summary.skipped)}`
|
|
105510
|
+
);
|
|
105272
105511
|
console.log(
|
|
105273
|
-
|
|
105512
|
+
` ${color.bold(pad("Duration", 11))} ${color.bold(`total ${formatTestDuration(report.summary.durationMs)}`)} ${color.dim(`(test ${formatTestDuration(report.summary.testDurationMs)}, startup ${formatTestDuration(report.summary.startupDurationMs)})`)}`
|
|
105274
105513
|
);
|
|
105275
105514
|
}
|
|
105276
105515
|
if (!report.success) process.exitCode = exitCode;
|
|
@@ -105317,7 +105556,7 @@ async function inspectNeoTestCompilation(workspace, dependencies = {}) {
|
|
|
105317
105556
|
errors
|
|
105318
105557
|
};
|
|
105319
105558
|
}
|
|
105320
|
-
var TEST_BUILD_CACHE_LIMIT_BYTES, ABANDONED_TEMP_MAX_AGE_MS, TEST_CANDIDATE_CACHE_REVISION, NeoTestUsageError, NeoTestNoTestsError, NeoTestRegistrationError, NeoTestReportWriteError, NeoTestPreparedCandidateError, NeoTestInterruptedError, NeoTestAssertionError, ERROR_SOURCE_POSITIONS, SHARED_EVALUATOR_BASES, REGISTRATION_IDS;
|
|
105559
|
+
var TEST_BUILD_CACHE_LIMIT_BYTES, ABANDONED_TEMP_MAX_AGE_MS, TEST_CANDIDATE_CACHE_REVISION, NeoTestUsageError, NeoTestNoTestsError, NeoTestRegistrationError, NeoTestReportWriteError, NeoTestPreparedCandidateError, NeoTestInterruptedError, NeoTestAssertionError, ERROR_SOURCE_POSITIONS, SHARED_EVALUATOR_BASES, REGISTRATION_IDS, MATCHER_IDS;
|
|
105321
105560
|
var init_test = __esm({
|
|
105322
105561
|
"src/commands/test.ts"() {
|
|
105323
105562
|
"use strict";
|
|
@@ -105330,6 +105569,7 @@ var init_test = __esm({
|
|
|
105330
105569
|
init_push();
|
|
105331
105570
|
init_registry2();
|
|
105332
105571
|
init_push_hook();
|
|
105572
|
+
init_ui();
|
|
105333
105573
|
TEST_BUILD_CACHE_LIMIT_BYTES = 512 * 1024 * 1024;
|
|
105334
105574
|
ABANDONED_TEMP_MAX_AGE_MS = 60 * 60 * 1e3;
|
|
105335
105575
|
TEST_CANDIDATE_CACHE_REVISION = 1;
|
|
@@ -105374,6 +105614,24 @@ var init_test = __esm({
|
|
|
105374
105614
|
NEO_TEST_IDS.beforeEach,
|
|
105375
105615
|
NEO_TEST_IDS.afterEach
|
|
105376
105616
|
]);
|
|
105617
|
+
MATCHER_IDS = /* @__PURE__ */ new Set([
|
|
105618
|
+
NEO_TEST_IDS.toBe,
|
|
105619
|
+
NEO_TEST_IDS.toEqual,
|
|
105620
|
+
NEO_TEST_IDS.toBeNull,
|
|
105621
|
+
NEO_TEST_IDS.toBeTrue,
|
|
105622
|
+
NEO_TEST_IDS.toBeFalse,
|
|
105623
|
+
NEO_TEST_IDS.toBeGreaterThan,
|
|
105624
|
+
NEO_TEST_IDS.toBeGreaterThanOrEqual,
|
|
105625
|
+
NEO_TEST_IDS.toBeLessThan,
|
|
105626
|
+
NEO_TEST_IDS.toBeLessThanOrEqual,
|
|
105627
|
+
NEO_TEST_IDS.toContain,
|
|
105628
|
+
NEO_TEST_IDS.toHaveLength,
|
|
105629
|
+
NEO_TEST_IDS.toMatchObject,
|
|
105630
|
+
NEO_TEST_IDS.toThrow,
|
|
105631
|
+
NEO_TEST_IDS.toHaveBeenCalled,
|
|
105632
|
+
NEO_TEST_IDS.toHaveBeenCalledTimes,
|
|
105633
|
+
NEO_TEST_IDS.toHaveBeenCalledWith
|
|
105634
|
+
]);
|
|
105377
105635
|
}
|
|
105378
105636
|
});
|
|
105379
105637
|
|
|
@@ -108939,7 +109197,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
|
|
|
108939
109197
|
async function main() {
|
|
108940
109198
|
const args = parseArgs(process.argv.slice(2));
|
|
108941
109199
|
if (args.command === "--version") {
|
|
108942
|
-
console.log("0.26.
|
|
109200
|
+
console.log("0.26.3");
|
|
108943
109201
|
return;
|
|
108944
109202
|
}
|
|
108945
109203
|
if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {
|
|
@@ -109223,15 +109481,25 @@ async function main() {
|
|
|
109223
109481
|
"--testTimeout must be a positive number of milliseconds."
|
|
109224
109482
|
);
|
|
109225
109483
|
}
|
|
109226
|
-
const
|
|
109227
|
-
|
|
109228
|
-
|
|
109229
|
-
|
|
109230
|
-
|
|
109231
|
-
|
|
109232
|
-
|
|
109233
|
-
|
|
109234
|
-
|
|
109484
|
+
const progress = reporterValue === "default" && process.stdout.isTTY === true ? spinner("Preparing test project\u2026") : null;
|
|
109485
|
+
try {
|
|
109486
|
+
const { runTest: runTest2 } = await Promise.resolve().then(() => (init_test(), test_exports));
|
|
109487
|
+
await runTest2(
|
|
109488
|
+
workspace,
|
|
109489
|
+
{
|
|
109490
|
+
selectors: args.positional,
|
|
109491
|
+
testNamePattern: stringFlag(args, "testNamePattern"),
|
|
109492
|
+
reporter: reporterValue,
|
|
109493
|
+
outputFile: stringFlag(args, "outputFile") ?? stringFlag(args, "output-file"),
|
|
109494
|
+
passWithNoTests: boolFlag(args, "passWithNoTests"),
|
|
109495
|
+
...timeoutMs === void 0 ? {} : { timeoutMs }
|
|
109496
|
+
},
|
|
109497
|
+
progress === null ? {} : { progress }
|
|
109498
|
+
);
|
|
109499
|
+
} catch (error) {
|
|
109500
|
+
progress?.fail("Test run failed.");
|
|
109501
|
+
throw error;
|
|
109502
|
+
}
|
|
109235
109503
|
return;
|
|
109236
109504
|
}
|
|
109237
109505
|
case "dev": {
|
package/package.json
CHANGED
|
@@ -83,7 +83,7 @@ wrappers.
|
|
|
83
83
|
The marker near the top of `SKILL.md` must exactly match the package version:
|
|
84
84
|
|
|
85
85
|
```html
|
|
86
|
-
<!-- reviewed-through-cli: 0.26.
|
|
86
|
+
<!-- reviewed-through-cli: 0.26.3 -->
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
The quoted version above is checked too, so this instruction cannot go stale
|