@autometa/assertions 1.0.0-rc.4 → 1.0.0-rc.5
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/ensure.d.ts +23 -0
- package/dist/index.cjs +142 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +142 -0
- package/dist/index.js.map +1 -1
- package/dist/matchers/type-of.d.ts +4 -0
- package/package.json +5 -5
package/dist/ensure.d.ts
CHANGED
|
@@ -1,10 +1,32 @@
|
|
|
1
1
|
export interface EnsureOptions {
|
|
2
2
|
readonly label?: string;
|
|
3
3
|
}
|
|
4
|
+
export interface EnsureEachOptions<T> {
|
|
5
|
+
readonly label?: string | ((details: {
|
|
6
|
+
readonly index: number;
|
|
7
|
+
readonly value: T;
|
|
8
|
+
}) => string);
|
|
9
|
+
}
|
|
10
|
+
export interface EnsureTapContext<Negated extends boolean> {
|
|
11
|
+
readonly isNot: Negated;
|
|
12
|
+
readonly label?: string;
|
|
13
|
+
}
|
|
14
|
+
type EnsureTypeOf = "string" | "number" | "boolean" | "bigint" | "symbol" | "undefined" | "object" | "function";
|
|
15
|
+
type TypeOfResult<T extends EnsureTypeOf> = T extends "string" ? string : T extends "number" ? number : T extends "boolean" ? boolean : T extends "bigint" ? bigint : T extends "symbol" ? symbol : T extends "undefined" ? undefined : T extends "function" ? (...args: never[]) => unknown : T extends "object" ? object | null : never;
|
|
16
|
+
type NarrowByTypeOf<T, Expected extends EnsureTypeOf> = [
|
|
17
|
+
Extract<T, TypeOfResult<Expected>>
|
|
18
|
+
] extends [never] ? TypeOfResult<Expected> : Extract<T, TypeOfResult<Expected>>;
|
|
19
|
+
type NarrowToArray<T> = [Extract<T, readonly unknown[]>] extends [never] ? readonly unknown[] : Extract<T, readonly unknown[]>;
|
|
4
20
|
type Toggle<Negated extends boolean> = Negated extends true ? false : true;
|
|
5
21
|
interface EnsureChainInternal<T, Negated extends boolean> {
|
|
6
22
|
readonly value: T;
|
|
7
23
|
readonly not: EnsureChainInternal<T, Toggle<Negated>>;
|
|
24
|
+
tap(fn: (value: T, context: EnsureTapContext<Negated>) => void): EnsureChainInternal<T, Negated>;
|
|
25
|
+
map<U, Arr extends readonly unknown[]>(this: EnsureChainInternal<Arr, Negated>, selector: (value: Arr[number], index: number, array: Arr) => U, options?: EnsureOptions): EnsureChainInternal<U[], Negated>;
|
|
26
|
+
each<Arr extends readonly unknown[]>(this: EnsureChainInternal<Arr, Negated>, fn: (value: EnsureChainInternal<Arr[number], Negated>, index: number) => void, options?: EnsureEachOptions<Arr[number]>): EnsureChainInternal<Arr, Negated>;
|
|
27
|
+
pluck<Arr extends readonly object[], K extends keyof Arr[number]>(this: EnsureChainInternal<Arr, Negated>, key: K, options?: EnsureOptions): EnsureChainInternal<Array<Arr[number][K]>, Negated>;
|
|
28
|
+
prop<Obj extends object, K extends keyof Obj>(this: EnsureChainInternal<Obj, Negated>, key: K, options?: EnsureOptions): EnsureChainInternal<Obj[K], Negated>;
|
|
29
|
+
toBeTypeOf<Expected extends EnsureTypeOf>(expected: Expected): EnsureChainInternal<Negated extends true ? T : NarrowByTypeOf<T, Expected>, Negated>;
|
|
8
30
|
toBe(expected: T): EnsureChainInternal<T, Negated>;
|
|
9
31
|
toEqual(expected: unknown): EnsureChainInternal<T, Negated>;
|
|
10
32
|
toStrictEqual(expected: unknown): EnsureChainInternal<T, Negated>;
|
|
@@ -18,6 +40,7 @@ interface EnsureChainInternal<T, Negated extends boolean> {
|
|
|
18
40
|
toBeLessThan(expected: number): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated>;
|
|
19
41
|
toBeLessThanOrEqual(expected: number): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated>;
|
|
20
42
|
toBeCloseTo(expected: number, precision?: number): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated>;
|
|
43
|
+
toBeInstanceOf(ctor: ArrayConstructor): EnsureChainInternal<Negated extends true ? T : NarrowToArray<T>, Negated>;
|
|
21
44
|
toBeInstanceOf<Ctor extends abstract new (...args: never[]) => unknown>(ctor: Ctor): EnsureChainInternal<Negated extends true ? T : InstanceType<Ctor>, Negated>;
|
|
22
45
|
toBeObjectContaining<Shape extends Record<PropertyKey, unknown>>(shape: Shape): EnsureChainInternal<T, Negated>;
|
|
23
46
|
toBeArrayContaining(expected: readonly unknown[]): EnsureChainInternal<Negated extends true ? T : Extract<T, readonly unknown[]>, Negated>;
|
package/dist/index.cjs
CHANGED
|
@@ -497,6 +497,24 @@ function assertToBeCloseTo(ctx, expected, precision = 2) {
|
|
|
497
497
|
return actual;
|
|
498
498
|
}
|
|
499
499
|
|
|
500
|
+
// src/matchers/type-of.ts
|
|
501
|
+
function assertToBeTypeOf(ctx, expected) {
|
|
502
|
+
const actualType = typeof ctx.value;
|
|
503
|
+
const pass = actualType === expected;
|
|
504
|
+
if (ctx.negated ? pass : !pass) {
|
|
505
|
+
const baseMessage = ctx.negated ? `Expected value not to be of type ${expected}` : `Expected value to be of type ${expected}`;
|
|
506
|
+
ctx.fail("toBeTypeOf", {
|
|
507
|
+
message: buildFailureMessage("toBeTypeOf", baseMessage, {
|
|
508
|
+
expected,
|
|
509
|
+
actual: ctx.value,
|
|
510
|
+
extra: [`Received type: ${actualType}`]
|
|
511
|
+
}),
|
|
512
|
+
expected,
|
|
513
|
+
actual: ctx.value
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
500
518
|
// src/matchers/truthiness.ts
|
|
501
519
|
function assertToBeTruthy(ctx) {
|
|
502
520
|
const pass = Boolean(ctx.value);
|
|
@@ -550,6 +568,115 @@ var EnsureChainImpl = class _EnsureChainImpl {
|
|
|
550
568
|
nextState
|
|
551
569
|
);
|
|
552
570
|
}
|
|
571
|
+
tap(fn) {
|
|
572
|
+
fn(this.state.value, {
|
|
573
|
+
isNot: this.state.negated,
|
|
574
|
+
...this.state.label !== void 0 ? { label: this.state.label } : {}
|
|
575
|
+
});
|
|
576
|
+
return this;
|
|
577
|
+
}
|
|
578
|
+
map(selector, options = {}) {
|
|
579
|
+
const chain = this;
|
|
580
|
+
const current = chain.state.value;
|
|
581
|
+
if (!Array.isArray(current)) {
|
|
582
|
+
chain.fail("map", {
|
|
583
|
+
message: "Expected value to be an array in order to use ensure(...).map(...)",
|
|
584
|
+
actual: chain.state.value,
|
|
585
|
+
expected: "array"
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
const values = current;
|
|
589
|
+
const mapped = values.map(
|
|
590
|
+
(value, index, array) => selector(value, index, array)
|
|
591
|
+
);
|
|
592
|
+
const nextState = {
|
|
593
|
+
value: mapped,
|
|
594
|
+
negated: chain.state.negated,
|
|
595
|
+
...options.label !== void 0 ? { label: options.label } : chain.state.label !== void 0 ? { label: chain.state.label } : {}
|
|
596
|
+
};
|
|
597
|
+
return new _EnsureChainImpl(
|
|
598
|
+
nextState
|
|
599
|
+
);
|
|
600
|
+
}
|
|
601
|
+
each(fn, options = {}) {
|
|
602
|
+
const chain = this;
|
|
603
|
+
const current = chain.state.value;
|
|
604
|
+
if (!Array.isArray(current)) {
|
|
605
|
+
chain.fail("each", {
|
|
606
|
+
message: "Expected value to be an array in order to use ensure(...).each(...)",
|
|
607
|
+
actual: chain.state.value,
|
|
608
|
+
expected: "array"
|
|
609
|
+
});
|
|
610
|
+
}
|
|
611
|
+
const values = current;
|
|
612
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
613
|
+
const element = values[index];
|
|
614
|
+
const elementLabel = chain.buildEachLabel(element, index, options);
|
|
615
|
+
const elementState = {
|
|
616
|
+
value: element,
|
|
617
|
+
negated: chain.state.negated,
|
|
618
|
+
...elementLabel !== void 0 ? { label: elementLabel } : {}
|
|
619
|
+
};
|
|
620
|
+
fn(
|
|
621
|
+
new _EnsureChainImpl(
|
|
622
|
+
elementState
|
|
623
|
+
),
|
|
624
|
+
index
|
|
625
|
+
);
|
|
626
|
+
}
|
|
627
|
+
return this;
|
|
628
|
+
}
|
|
629
|
+
pluck(key, options = {}) {
|
|
630
|
+
const chain = this;
|
|
631
|
+
const current = chain.state.value;
|
|
632
|
+
if (!Array.isArray(current)) {
|
|
633
|
+
chain.fail("pluck", {
|
|
634
|
+
message: "Expected value to be an array in order to use ensure(...).pluck(...)",
|
|
635
|
+
actual: chain.state.value,
|
|
636
|
+
expected: "array"
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
const values = current;
|
|
640
|
+
const mapped = values.map((element, index) => {
|
|
641
|
+
if (typeof element !== "object" && typeof element !== "function" || element === null) {
|
|
642
|
+
chain.fail("pluck", {
|
|
643
|
+
message: `Expected element at index ${index} to be an object in order to pluck "${String(
|
|
644
|
+
key
|
|
645
|
+
)}"`,
|
|
646
|
+
actual: element,
|
|
647
|
+
expected: "object"
|
|
648
|
+
});
|
|
649
|
+
}
|
|
650
|
+
return element[key];
|
|
651
|
+
});
|
|
652
|
+
const nextState = {
|
|
653
|
+
value: mapped,
|
|
654
|
+
negated: chain.state.negated,
|
|
655
|
+
...options.label !== void 0 ? { label: options.label } : chain.state.label !== void 0 ? { label: chain.state.label } : {}
|
|
656
|
+
};
|
|
657
|
+
return new _EnsureChainImpl(
|
|
658
|
+
nextState
|
|
659
|
+
);
|
|
660
|
+
}
|
|
661
|
+
prop(key, options = {}) {
|
|
662
|
+
const chain = this;
|
|
663
|
+
const current = chain.state.value;
|
|
664
|
+
if (typeof current !== "object" && typeof current !== "function" || current === null) {
|
|
665
|
+
chain.fail("prop", {
|
|
666
|
+
message: "Expected value to be an object in order to use ensure(...).prop(...)",
|
|
667
|
+
actual: chain.state.value,
|
|
668
|
+
expected: "object"
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
const nextState = {
|
|
672
|
+
value: current[key],
|
|
673
|
+
negated: chain.state.negated,
|
|
674
|
+
...options.label !== void 0 ? { label: options.label } : chain.state.label !== void 0 ? { label: chain.state.label } : {}
|
|
675
|
+
};
|
|
676
|
+
return new _EnsureChainImpl(
|
|
677
|
+
nextState
|
|
678
|
+
);
|
|
679
|
+
}
|
|
553
680
|
toBe(expected) {
|
|
554
681
|
assertToBe(this.createContext(), expected);
|
|
555
682
|
return this;
|
|
@@ -585,6 +712,11 @@ var EnsureChainImpl = class _EnsureChainImpl {
|
|
|
585
712
|
assertToBeFalsy(this.createContext());
|
|
586
713
|
return this;
|
|
587
714
|
}
|
|
715
|
+
toBeTypeOf(expected) {
|
|
716
|
+
assertToBeTypeOf(this.createContext(), expected);
|
|
717
|
+
const next = this.state.negated ? this : this.rewrap(this.state.value);
|
|
718
|
+
return next;
|
|
719
|
+
}
|
|
588
720
|
toBeGreaterThan(expected) {
|
|
589
721
|
const actual = assertToBeGreaterThan(this.createContext(), expected);
|
|
590
722
|
const next = this.state.negated ? this : this.rewrap(actual);
|
|
@@ -657,6 +789,16 @@ var EnsureChainImpl = class _EnsureChainImpl {
|
|
|
657
789
|
nextState
|
|
658
790
|
);
|
|
659
791
|
}
|
|
792
|
+
buildEachLabel(value, index, options) {
|
|
793
|
+
if (typeof options.label === "function") {
|
|
794
|
+
return options.label({ index, value });
|
|
795
|
+
}
|
|
796
|
+
const baseLabel = options.label ?? this.state.label;
|
|
797
|
+
if (!baseLabel) {
|
|
798
|
+
return void 0;
|
|
799
|
+
}
|
|
800
|
+
return `${baseLabel} (index ${index})`;
|
|
801
|
+
}
|
|
660
802
|
fail(matcher, details) {
|
|
661
803
|
const errorDetails = {
|
|
662
804
|
matcher,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/assertion-error.ts","../src/matchers/collections.ts","../src/core/constants.ts","../src/core/context.ts","../src/core/messages.ts","../src/core/predicates.ts","../src/matchers/equality.ts","../src/matchers/instance.ts","../src/matchers/nullish.ts","../src/matchers/numeric.ts","../src/matchers/truthiness.ts","../src/ensure.ts","../src/plugins.ts","../src/plugins/runtime-assertions-plugin.ts"],"names":["equals","ensure","table"],"mappings":"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","sourcesContent":["import { inspect } from \"node:util\";\n\nexport interface EnsureErrorDetails {\n readonly matcher: string;\n readonly message: string;\n readonly actual?: unknown;\n readonly expected?: unknown;\n readonly receivedLabel?: string;\n}\n\nexport class EnsureError extends Error {\n public readonly matcher: string;\n public readonly actual?: unknown;\n public readonly expected?: unknown;\n\n constructor(details: EnsureErrorDetails) {\n const formattedMessage = buildMessage(details);\n super(formattedMessage);\n this.name = \"EnsureError\";\n this.matcher = details.matcher;\n this.actual = details.actual;\n this.expected = details.expected;\n }\n}\n\nfunction buildMessage({ matcher, message, actual, expected, receivedLabel }: EnsureErrorDetails): string {\n const parts = [message];\n const extras: string[] = [];\n\n if (typeof expected !== \"undefined\" && !containsSection(message, \"Expected:\")) {\n extras.push(`Expected: ${formatValue(expected)}`);\n }\n\n if (typeof actual !== \"undefined\") {\n const label = receivedLabel ? `Received ${receivedLabel}` : \"Received\";\n if (!containsSection(message, `${label}:`)) {\n extras.push(`${label}: ${formatValue(actual)}`);\n }\n }\n\n if (!containsSection(message, \"Matcher:\")) {\n extras.push(`Matcher: ${matcher}`);\n }\n\n if (extras.length > 0) {\n parts.push(\"\", ...extras);\n }\n\n return parts.join(\"\\n\");\n}\n\nfunction formatValue(value: unknown): string {\n return inspect(value, { depth: 4, maxArrayLength: 10, breakLength: 60, sorted: true });\n}\n\nfunction containsSection(message: string, label: string): boolean {\n return message\n .split(\"\\n\")\n .some((line) => line.trimStart().startsWith(label));\n}\n","import { equals } from \"@jest/expect-utils\";\n\nimport { EQUALITY_TESTERS, SUBSET_TESTERS } from \"../core/constants\";\nimport { type MatcherContext, shouldFail } from \"../core/context\";\nimport { buildFailureMessage, formatDiff, formatMissingList } from \"../core/messages\";\nimport { hasLengthProperty, isIterable, isRecord } from \"../core/predicates\";\n\nexport function assertObjectContaining<T>(\n ctx: MatcherContext<T>,\n shape: Record<PropertyKey, unknown>\n): void {\n const isObject = isRecord(ctx.value);\n if (!isObject) {\n if (!ctx.negated) {\n ctx.fail(\"toBeObjectContaining\", {\n message: buildFailureMessage(\"toBeObjectContaining\", \"Expected value to be an object\", {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return;\n }\n\n const pass = equals(ctx.value, shape, SUBSET_TESTERS);\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? \"Expected object not to match the provided subset\"\n : \"Object does not match the provided subset\";\n ctx.fail(\"toBeObjectContaining\", {\n message: buildFailureMessage(\"toBeObjectContaining\", baseMessage, {\n expected: shape,\n actual: ctx.value,\n diff: formatDiff(shape, ctx.value),\n }),\n expected: shape,\n actual: ctx.value,\n });\n }\n}\n\nexport function assertArrayContaining<T>(\n ctx: MatcherContext<T>,\n expected: readonly unknown[]\n): readonly unknown[] {\n if (!Array.isArray(ctx.value)) {\n if (!ctx.negated) {\n ctx.fail(\"toBeArrayContaining\", {\n message: buildFailureMessage(\"toBeArrayContaining\", \"Expected value to be an array\", {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return ctx.value as unknown as readonly unknown[];\n }\n\n const actual = ctx.value as readonly unknown[];\n const missing = expected.filter((item) =>\n !actual.some((entry: unknown) => equals(entry, item, EQUALITY_TESTERS))\n );\n\n const pass = missing.length === 0;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? \"Expected array not to contain the provided elements\"\n : \"Array is missing expected elements\";\n ctx.fail(\"toBeArrayContaining\", {\n message: buildFailureMessage(\"toBeArrayContaining\", baseMessage, {\n expected,\n actual,\n extra: [formatMissingList(\"Missing elements:\", missing)],\n diff: formatDiff(expected, actual),\n }),\n expected,\n actual,\n });\n }\n\n return actual;\n}\n\nexport function assertContainEqual<T>(\n ctx: MatcherContext<T>,\n expected: unknown\n): readonly unknown[] {\n if (!Array.isArray(ctx.value)) {\n if (!ctx.negated) {\n ctx.fail(\"toContainEqual\", {\n message: buildFailureMessage(\"toContainEqual\", \"Expected value to be an array\", {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return ctx.value as unknown as readonly unknown[];\n }\n\n const actual = ctx.value as readonly unknown[];\n const pass = actual.some((entry: unknown) => equals(entry, expected, EQUALITY_TESTERS));\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? \"Expected array not to contain the provided element\"\n : \"Array is missing the expected element\";\n ctx.fail(\"toContainEqual\", {\n message: buildFailureMessage(\"toContainEqual\", baseMessage, {\n expected,\n actual,\n diff: formatDiff(expected, actual),\n }),\n expected,\n actual,\n });\n }\n\n return actual;\n}\n\nexport function assertIterableContaining<T>(\n ctx: MatcherContext<T>,\n expected: readonly unknown[]\n): Iterable<unknown> {\n if (!isIterable(ctx.value)) {\n if (!ctx.negated) {\n ctx.fail(\"toBeIterableContaining\", {\n message: buildFailureMessage(\"toBeIterableContaining\", \"Expected value to be iterable\", {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return ctx.value as unknown as Iterable<unknown>;\n }\n\n const entries = Array.from(ctx.value as Iterable<unknown>);\n const missing = expected.filter((item) =>\n !entries.some((entry) => equals(entry, item, EQUALITY_TESTERS))\n );\n\n const pass = missing.length === 0;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? \"Expected iterable not to contain the provided elements\"\n : \"Iterable is missing expected elements\";\n ctx.fail(\"toBeIterableContaining\", {\n message: buildFailureMessage(\"toBeIterableContaining\", baseMessage, {\n expected,\n actual: entries,\n extra: [formatMissingList(\"Missing elements:\", missing)],\n }),\n expected,\n actual: entries,\n });\n }\n\n return ctx.value as unknown as Iterable<unknown>;\n}\n\nexport function assertHasLength<T>(ctx: MatcherContext<T>, expected: number): number {\n if (!hasLengthProperty(ctx.value)) {\n if (!ctx.negated) {\n ctx.fail(\"toHaveLength\", {\n message: buildFailureMessage(\"toHaveLength\", \"Expected value to have a numeric length property\", {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return NaN;\n }\n\n const actualLength = (ctx.value as { length: number }).length;\n const pass = actualLength === expected;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected length to differ from ${expected}`\n : \"Length does not match expectation\";\n ctx.fail(\"toHaveLength\", {\n message: buildFailureMessage(\"toHaveLength\", baseMessage, {\n expected,\n actual: actualLength,\n diff: formatDiff(expected, actualLength),\n }),\n expected,\n actual: actualLength,\n });\n }\n\n return actualLength;\n}\n","import { iterableEquality, subsetEquality, type Tester } from \"@jest/expect-utils\";\n\nexport const MATCHER_CALL = \"ensure(received)\";\n\nexport const EQUALITY_TESTERS: Tester[] = [iterableEquality];\n\nexport const SUBSET_TESTERS: Tester[] = [iterableEquality, subsetEquality];\n","export interface FailureDetails {\n readonly message: string;\n readonly actual?: unknown;\n readonly expected?: unknown;\n}\n\nexport interface MatcherState<T> {\n readonly value: T;\n readonly label?: string;\n readonly negated: boolean;\n}\n\nexport interface MatcherContext<T> extends MatcherState<T> {\n fail(matcher: string, details: FailureDetails): never;\n}\n\nexport function shouldFail(pass: boolean, negated: boolean): boolean {\n return negated ? pass : !pass;\n}\n","import { diff } from \"jest-diff\";\nimport { printExpected, printReceived } from \"jest-matcher-utils\";\n\nimport { MATCHER_CALL } from \"./constants\";\n\nexport interface FailureMessageOptions {\n readonly expected?: unknown;\n readonly actual?: unknown;\n readonly diff?: string | undefined;\n readonly extra?: readonly (string | undefined)[];\n readonly actualLabel?: string;\n}\n\nexport function buildFailureMessage(\n matcher: string,\n baseMessage: string,\n options: FailureMessageOptions = {}\n): string {\n const sections: string[] = [`${MATCHER_CALL}.${matcher}(expected)`, baseMessage];\n\n if (Object.prototype.hasOwnProperty.call(options, \"expected\")) {\n sections.push(`Expected: ${printExpected(options.expected)}`);\n }\n\n if (Object.prototype.hasOwnProperty.call(options, \"actual\")) {\n const label = options.actualLabel ?? \"Received\";\n sections.push(`${label}: ${printReceived(options.actual)}`);\n }\n\n if (options.extra) {\n for (const extra of options.extra) {\n if (extra && extra.trim().length > 0) {\n sections.push(extra);\n }\n }\n }\n\n if (options.diff && options.diff.trim().length > 0) {\n sections.push(options.diff);\n }\n\n return sections.join(\"\\n\\n\");\n}\n\nexport function formatDiff(expected: unknown, actual: unknown): string | undefined {\n const difference = diff(expected, actual, { expand: false });\n return difference && difference.trim().length > 0 ? difference : undefined;\n}\n\nexport function formatMissingList(title: string, values: readonly unknown[]): string {\n if (values.length === 0) {\n return \"\";\n }\n const items = values.map((value) => ` - ${printExpected(value)}`).join(\"\\n\");\n return `${title}\\n${items}`;\n}\n","export function isRecord(candidate: unknown): candidate is Record<PropertyKey, unknown> {\n return typeof candidate === \"object\" && candidate !== null;\n}\n\nexport function isIterable(candidate: unknown): candidate is Iterable<unknown> {\n return typeof (candidate as { [Symbol.iterator]?: unknown })?.[Symbol.iterator] === \"function\";\n}\n\nexport function hasLengthProperty(candidate: unknown): candidate is { length: number } {\n return typeof (candidate as { length?: unknown })?.length === \"number\";\n}\n","import { equals } from \"@jest/expect-utils\";\n\nimport { EQUALITY_TESTERS } from \"../core/constants\";\nimport { type MatcherContext } from \"../core/context\";\nimport { buildFailureMessage, formatDiff } from \"../core/messages\";\n\nexport function assertToBe<T>(ctx: MatcherContext<T>, expected: T): void {\n const pass = Object.is(ctx.value, expected);\n if (ctx.negated ? pass : !pass) {\n const baseMessage = ctx.negated\n ? \"Expected values not to be strictly equal\"\n : \"Expected values to be strictly equal\";\n ctx.fail(\"toBe\", {\n message: buildFailureMessage(\"toBe\", baseMessage, {\n actual: ctx.value,\n expected,\n diff: formatDiff(expected, ctx.value),\n }),\n actual: ctx.value,\n expected,\n });\n }\n}\n\nexport function assertToEqual<T>(ctx: MatcherContext<T>, expected: unknown): void {\n const pass = equals(ctx.value, expected, EQUALITY_TESTERS);\n if (ctx.negated ? pass : !pass) {\n const baseMessage = ctx.negated\n ? \"Expected values not to be deeply equal\"\n : \"Expected values to be deeply equal\";\n ctx.fail(\"toEqual\", {\n message: buildFailureMessage(\"toEqual\", baseMessage, {\n actual: ctx.value,\n expected,\n diff: formatDiff(expected, ctx.value),\n }),\n actual: ctx.value,\n expected,\n });\n }\n}\n\nexport function assertToStrictEqual<T>(ctx: MatcherContext<T>, expected: unknown): void {\n const pass = equals(ctx.value, expected, EQUALITY_TESTERS, true);\n if (ctx.negated ? pass : !pass) {\n const baseMessage = ctx.negated\n ? \"Expected values not to be strictly equal (including prototypes and property definitions)\"\n : \"Expected values to be strictly equal (including prototypes and property definitions)\";\n ctx.fail(\"toStrictEqual\", {\n message: buildFailureMessage(\"toStrictEqual\", baseMessage, {\n actual: ctx.value,\n expected,\n diff: formatDiff(expected, ctx.value),\n }),\n actual: ctx.value,\n expected,\n });\n }\n}\n","import type { MatcherContext } from \"../core/context\";\nimport { buildFailureMessage } from \"../core/messages\";\n\nexport function assertToBeInstanceOf<\n T,\n Ctor extends abstract new (...args: never[]) => unknown\n>(ctx: MatcherContext<T>, ctor: Ctor): InstanceType<Ctor> {\n if (typeof ctor !== \"function\") {\n ctx.fail(\"toBeInstanceOf\", {\n message: buildFailureMessage(\"toBeInstanceOf\", \"Constructor must be a callable function\", {\n expected: ctor,\n }),\n expected: ctor,\n });\n }\n\n const pass = ctx.value instanceof ctor;\n if (ctx.negated ? pass : !pass) {\n const label = ctor.name || \"<anonymous>\";\n const baseMessage = ctx.negated\n ? `Expected value not to be an instance of ${label}`\n : `Expected value to be an instance of ${label}`;\n ctx.fail(\"toBeInstanceOf\", {\n message: buildFailureMessage(\"toBeInstanceOf\", baseMessage, {\n expected: ctor,\n actual: ctx.value,\n }),\n expected: ctor,\n actual: ctx.value,\n });\n }\n\n return ctx.value as InstanceType<Ctor>;\n}\n","import type { MatcherContext } from \"../core/context\";\nimport { buildFailureMessage } from \"../core/messages\";\n\nconst NIL_MESSAGE = \"Value is null or undefined\";\n\nexport function assertToBeDefined<T>(ctx: MatcherContext<T>): NonNullable<T> {\n const isDefined = ctx.value !== null && typeof ctx.value !== \"undefined\";\n if (ctx.negated ? isDefined : !isDefined) {\n const baseMessage = ctx.negated\n ? \"Expected value to be null or undefined\"\n : NIL_MESSAGE;\n ctx.fail(\"toBeDefined\", {\n message: buildFailureMessage(\"toBeDefined\", baseMessage, {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return ctx.value as NonNullable<T>;\n}\n\nexport function assertToBeUndefined<T>(ctx: MatcherContext<T>): undefined {\n const isUndefined = typeof ctx.value === \"undefined\";\n if (ctx.negated ? isUndefined : !isUndefined) {\n const baseMessage = ctx.negated\n ? \"Expected value not to be undefined\"\n : \"Expected value to be undefined\";\n ctx.fail(\"toBeUndefined\", {\n message: buildFailureMessage(\"toBeUndefined\", baseMessage, {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return undefined;\n}\n\nexport function assertToBeNull<T>(ctx: MatcherContext<T>): null {\n const isNull = ctx.value === null;\n if (ctx.negated ? isNull : !isNull) {\n const baseMessage = ctx.negated\n ? \"Expected value not to be null\"\n : \"Expected value to be null\";\n ctx.fail(\"toBeNull\", {\n message: buildFailureMessage(\"toBeNull\", baseMessage, {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return null;\n}\n","import type { MatcherContext } from \"../core/context\";\nimport { shouldFail } from \"../core/context\";\nimport { buildFailureMessage } from \"../core/messages\";\n\nfunction requireFiniteNumber<T>(\n ctx: MatcherContext<T>,\n matcher: string\n): number {\n const value = ctx.value;\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n ctx.fail(matcher, {\n message: buildFailureMessage(\n matcher,\n \"Expected value to be a finite number\",\n { actual: value }\n ),\n actual: value,\n expected: \"finite number\",\n });\n }\n return value;\n}\n\nfunction requireFiniteExpected(\n ctx: MatcherContext<unknown>,\n matcher: string,\n expected: number,\n name = \"expected\"\n): void {\n if (typeof expected !== \"number\" || !Number.isFinite(expected)) {\n ctx.fail(matcher, {\n message: buildFailureMessage(\n matcher,\n `Expected ${name} to be a finite number`,\n { actual: expected }\n ),\n actual: expected,\n expected: \"finite number\",\n });\n }\n}\n\nexport function assertToBeGreaterThan<T>(\n ctx: MatcherContext<T>,\n expected: number\n): number {\n const actual = requireFiniteNumber(ctx, \"toBeGreaterThan\");\n requireFiniteExpected(ctx as MatcherContext<unknown>, \"toBeGreaterThan\", expected);\n\n const pass = actual > expected;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected value not to be greater than ${expected}`\n : `Expected value to be greater than ${expected}`;\n\n ctx.fail(\"toBeGreaterThan\", {\n message: buildFailureMessage(\"toBeGreaterThan\", baseMessage, {\n expected,\n actual,\n }),\n actual,\n expected,\n });\n }\n\n return actual;\n}\n\nexport function assertToBeGreaterThanOrEqual<T>(\n ctx: MatcherContext<T>,\n expected: number\n): number {\n const actual = requireFiniteNumber(ctx, \"toBeGreaterThanOrEqual\");\n requireFiniteExpected(\n ctx as MatcherContext<unknown>,\n \"toBeGreaterThanOrEqual\",\n expected\n );\n\n const pass = actual >= expected;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected value not to be greater than or equal to ${expected}`\n : `Expected value to be greater than or equal to ${expected}`;\n\n ctx.fail(\"toBeGreaterThanOrEqual\", {\n message: buildFailureMessage(\"toBeGreaterThanOrEqual\", baseMessage, {\n expected,\n actual,\n }),\n actual,\n expected,\n });\n }\n\n return actual;\n}\n\nexport function assertToBeLessThan<T>(\n ctx: MatcherContext<T>,\n expected: number\n): number {\n const actual = requireFiniteNumber(ctx, \"toBeLessThan\");\n requireFiniteExpected(ctx as MatcherContext<unknown>, \"toBeLessThan\", expected);\n\n const pass = actual < expected;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected value not to be less than ${expected}`\n : `Expected value to be less than ${expected}`;\n\n ctx.fail(\"toBeLessThan\", {\n message: buildFailureMessage(\"toBeLessThan\", baseMessage, {\n expected,\n actual,\n }),\n actual,\n expected,\n });\n }\n\n return actual;\n}\n\nexport function assertToBeLessThanOrEqual<T>(\n ctx: MatcherContext<T>,\n expected: number\n): number {\n const actual = requireFiniteNumber(ctx, \"toBeLessThanOrEqual\");\n requireFiniteExpected(\n ctx as MatcherContext<unknown>,\n \"toBeLessThanOrEqual\",\n expected\n );\n\n const pass = actual <= expected;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected value not to be less than or equal to ${expected}`\n : `Expected value to be less than or equal to ${expected}`;\n\n ctx.fail(\"toBeLessThanOrEqual\", {\n message: buildFailureMessage(\"toBeLessThanOrEqual\", baseMessage, {\n expected,\n actual,\n }),\n actual,\n expected,\n });\n }\n\n return actual;\n}\n\nexport function assertToBeCloseTo<T>(\n ctx: MatcherContext<T>,\n expected: number,\n precision = 2\n): number {\n const actual = requireFiniteNumber(ctx, \"toBeCloseTo\");\n requireFiniteExpected(ctx as MatcherContext<unknown>, \"toBeCloseTo\", expected);\n\n if (!Number.isInteger(precision) || precision < 0 || precision > 20) {\n ctx.fail(\"toBeCloseTo\", {\n message: buildFailureMessage(\n \"toBeCloseTo\",\n \"Expected precision to be an integer between 0 and 20\",\n { actual: precision }\n ),\n actual: precision,\n expected: \"integer between 0 and 20\",\n });\n }\n\n const tolerance = Math.pow(10, -precision) / 2;\n const difference = Math.abs(actual - expected);\n // Floating-point operations can produce tiny rounding errors near the boundary.\n // We allow an EPSILON-scaled slack so values that are mathematically on the\n // boundary don't fail due to representation quirks.\n const epsilon = Number.EPSILON * Math.max(1, Math.abs(actual), Math.abs(expected)) * 2;\n const pass = difference <= tolerance + epsilon;\n\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected value not to be close to ${expected} (precision ${precision})`\n : `Expected value to be close to ${expected} (precision ${precision})`;\n\n ctx.fail(\"toBeCloseTo\", {\n message: buildFailureMessage(\"toBeCloseTo\", baseMessage, {\n expected,\n actual,\n extra: [\n `Difference: ${difference}`,\n `Tolerance: ${tolerance}`,\n ],\n }),\n actual,\n expected,\n });\n }\n\n return actual;\n}\n","import type { MatcherContext } from \"../core/context\";\nimport { buildFailureMessage } from \"../core/messages\";\n\nexport function assertToBeTruthy<T>(ctx: MatcherContext<T>): void {\n const pass = Boolean(ctx.value);\n if (ctx.negated ? pass : !pass) {\n const baseMessage = ctx.negated\n ? \"Expected value to be falsy\"\n : \"Expected value to be truthy\";\n ctx.fail(\"toBeTruthy\", {\n message: buildFailureMessage(\"toBeTruthy\", baseMessage, {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n}\n\nexport function assertToBeFalsy<T>(ctx: MatcherContext<T>): void {\n const pass = !ctx.value;\n if (ctx.negated ? pass : !pass) {\n const baseMessage = ctx.negated\n ? \"Expected value to be truthy\"\n : \"Expected value to be falsy\";\n ctx.fail(\"toBeFalsy\", {\n message: buildFailureMessage(\"toBeFalsy\", baseMessage, {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n}\n","import { EnsureError, type EnsureErrorDetails } from \"./assertion-error\";\nimport {\n type FailureDetails,\n type MatcherContext,\n type MatcherState,\n} from \"./core/context\";\nimport {\n assertArrayContaining,\n assertContainEqual,\n assertHasLength,\n assertIterableContaining,\n assertObjectContaining,\n} from \"./matchers/collections\";\nimport { assertToBe, assertToEqual, assertToStrictEqual } from \"./matchers/equality\";\nimport { assertToBeInstanceOf } from \"./matchers/instance\";\nimport {\n assertToBeDefined,\n assertToBeNull,\n assertToBeUndefined,\n} from \"./matchers/nullish\";\nimport {\n assertToBeCloseTo,\n assertToBeGreaterThan,\n assertToBeGreaterThanOrEqual,\n assertToBeLessThan,\n assertToBeLessThanOrEqual,\n} from \"./matchers/numeric\";\nimport { assertToBeFalsy, assertToBeTruthy } from \"./matchers/truthiness\";\n\nexport interface EnsureOptions {\n readonly label?: string;\n}\n\ntype Toggle<Negated extends boolean> = Negated extends true ? false : true;\n\ninterface EnsureChainInternal<T, Negated extends boolean> {\n readonly value: T;\n readonly not: EnsureChainInternal<T, Toggle<Negated>>;\n toBe(expected: T): EnsureChainInternal<T, Negated>;\n toEqual(expected: unknown): EnsureChainInternal<T, Negated>;\n toStrictEqual(expected: unknown): EnsureChainInternal<T, Negated>;\n toBeDefined(): EnsureChainInternal<Negated extends true ? T : NonNullable<T>, Negated>;\n toBeUndefined(): EnsureChainInternal<Negated extends true ? T : undefined, Negated>;\n toBeNull(): EnsureChainInternal<Negated extends true ? T : null, Negated>;\n toBeTruthy(): EnsureChainInternal<T, Negated>;\n toBeFalsy(): EnsureChainInternal<T, Negated>;\n toBeGreaterThan(expected: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n toBeGreaterThanOrEqual(expected: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n toBeLessThan(expected: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n toBeLessThanOrEqual(expected: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n toBeCloseTo(expected: number, precision?: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n toBeInstanceOf<Ctor extends abstract new (...args: never[]) => unknown>(\n ctor: Ctor\n ): EnsureChainInternal<Negated extends true ? T : InstanceType<Ctor>, Negated>;\n toBeObjectContaining<Shape extends Record<PropertyKey, unknown>>(\n shape: Shape\n ): EnsureChainInternal<T, Negated>;\n toBeArrayContaining(expected: readonly unknown[]): EnsureChainInternal<\n Negated extends true ? T : Extract<T, readonly unknown[]>,\n Negated\n >;\n toContainEqual(expected: unknown): EnsureChainInternal<\n Negated extends true ? T : Extract<T, readonly unknown[]>,\n Negated\n >;\n toBeIterableContaining(expected: readonly unknown[]): EnsureChainInternal<\n Negated extends true ? T : Extract<T, Iterable<unknown>>,\n Negated\n >;\n toHaveLength(expected: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, { length: number }> ,\n Negated\n >;\n}\n\nexport type EnsureChain<T> = EnsureChainInternal<T, false>;\nexport type EnsureNegatedChain<T> = EnsureChainInternal<T, true>;\n\nexport function ensure<T>(value: T, options: EnsureOptions = {}): EnsureChain<T> {\n const state = {\n value,\n negated: false as const,\n ...(options.label !== undefined ? { label: options.label } : {}),\n } satisfies MatcherState<T> & { negated: false };\n return new EnsureChainImpl<T, false>(state);\n}\n\nclass EnsureChainImpl<T, Negated extends boolean>\n implements EnsureChainInternal<T, Negated> {\n private readonly state: MatcherState<T> & { negated: Negated };\n\n constructor(state: MatcherState<T> & { negated: Negated }) {\n this.state = state;\n }\n\n public get value(): T {\n return this.state.value;\n }\n\n public get not(): EnsureChainInternal<T, Toggle<Negated>> {\n const toggled = (!this.state.negated) as Toggle<Negated>;\n const nextState = {\n value: this.state.value,\n negated: toggled,\n ...(this.state.label !== undefined ? { label: this.state.label } : {}),\n };\n return new EnsureChainImpl<T, Toggle<Negated>>(\n nextState as MatcherState<T> & { negated: Toggle<Negated> }\n );\n }\n\n public toBe(expected: T): EnsureChainInternal<T, Negated> {\n assertToBe(this.createContext(), expected);\n return this;\n }\n\n public toEqual(expected: unknown): EnsureChainInternal<T, Negated> {\n assertToEqual(this.createContext(), expected);\n return this;\n }\n\n public toStrictEqual(expected: unknown): EnsureChainInternal<T, Negated> {\n assertToStrictEqual(this.createContext(), expected);\n return this;\n }\n\n public toBeDefined(): EnsureChainInternal<Negated extends true ? T : NonNullable<T>, Negated> {\n const defined = assertToBeDefined(this.createContext());\n const next = this.state.negated ? this : this.rewrap(defined);\n return next as EnsureChainInternal<Negated extends true ? T : NonNullable<T>, Negated>;\n }\n\n public toBeUndefined(): EnsureChainInternal<Negated extends true ? T : undefined, Negated> {\n const result = assertToBeUndefined(this.createContext());\n const next = this.state.negated ? this : this.rewrap(result);\n return next as EnsureChainInternal<Negated extends true ? T : undefined, Negated>;\n }\n\n public toBeNull(): EnsureChainInternal<Negated extends true ? T : null, Negated> {\n const result = assertToBeNull(this.createContext());\n const next = this.state.negated ? this : this.rewrap(result);\n return next as EnsureChainInternal<Negated extends true ? T : null, Negated>;\n }\n\n public toBeTruthy(): EnsureChainInternal<T, Negated> {\n assertToBeTruthy(this.createContext());\n return this;\n }\n\n public toBeFalsy(): EnsureChainInternal<T, Negated> {\n assertToBeFalsy(this.createContext());\n return this;\n }\n\n public toBeGreaterThan(\n expected: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated> {\n const actual = assertToBeGreaterThan(this.createContext(), expected);\n const next = this.state.negated ? this : this.rewrap(actual as Extract<T, number>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n }\n\n public toBeGreaterThanOrEqual(\n expected: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated> {\n const actual = assertToBeGreaterThanOrEqual(this.createContext(), expected);\n const next = this.state.negated ? this : this.rewrap(actual as Extract<T, number>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n }\n\n public toBeLessThan(\n expected: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated> {\n const actual = assertToBeLessThan(this.createContext(), expected);\n const next = this.state.negated ? this : this.rewrap(actual as Extract<T, number>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n }\n\n public toBeLessThanOrEqual(\n expected: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated> {\n const actual = assertToBeLessThanOrEqual(this.createContext(), expected);\n const next = this.state.negated ? this : this.rewrap(actual as Extract<T, number>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n }\n\n public toBeCloseTo(\n expected: number,\n precision?: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated> {\n const actual = assertToBeCloseTo(this.createContext(), expected, precision);\n const next = this.state.negated ? this : this.rewrap(actual as Extract<T, number>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n }\n\n public toBeInstanceOf<Ctor extends abstract new (...args: never[]) => unknown>(\n ctor: Ctor\n ): EnsureChainInternal<Negated extends true ? T : InstanceType<Ctor>, Negated> {\n const instance = assertToBeInstanceOf(this.createContext(), ctor);\n const next = this.state.negated ? this : this.rewrap(instance);\n return next as EnsureChainInternal<Negated extends true ? T : InstanceType<Ctor>, Negated>;\n }\n\n public toBeObjectContaining<Shape extends Record<PropertyKey, unknown>>(\n shape: Shape\n ): EnsureChainInternal<T, Negated> {\n assertObjectContaining(this.createContext(), shape);\n return this;\n }\n\n public toBeArrayContaining(\n expected: readonly unknown[]\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, readonly unknown[]>, Negated> {\n const array = assertArrayContaining(this.createContext(), expected);\n const next = this.state.negated\n ? this\n : this.rewrap(array as Extract<T, readonly unknown[]>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, readonly unknown[]>,\n Negated\n >;\n }\n\n public toContainEqual(\n expected: unknown\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, readonly unknown[]>, Negated> {\n const array = assertContainEqual(this.createContext(), expected);\n const next = this.state.negated\n ? this\n : this.rewrap(array as Extract<T, readonly unknown[]>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, readonly unknown[]>,\n Negated\n >;\n }\n\n public toBeIterableContaining(\n expected: readonly unknown[]\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, Iterable<unknown>>, Negated> {\n const iterable = assertIterableContaining(this.createContext(), expected);\n const next = this.state.negated\n ? this\n : this.rewrap(iterable as Extract<T, Iterable<unknown>>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, Iterable<unknown>>,\n Negated\n >;\n }\n\n public toHaveLength(\n expected: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, { length: number }>, Negated> {\n assertHasLength(this.createContext(), expected);\n const next = this.state.negated\n ? this\n : this.rewrap(this.state.value as Extract<T, { length: number }>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, { length: number }> ,\n Negated\n >;\n }\n\n private createContext(): MatcherContext<T> {\n return {\n value: this.state.value,\n negated: this.state.negated,\n fail: (matcher, details) => this.fail(matcher, details),\n ...(this.state.label !== undefined ? { label: this.state.label } : {}),\n } as MatcherContext<T>;\n }\n\n private rewrap<U>(value: U): EnsureChainImpl<U, Negated> {\n const nextState = {\n value,\n negated: this.state.negated,\n ...(this.state.label !== undefined ? { label: this.state.label } : {}),\n };\n return new EnsureChainImpl<U, Negated>(\n nextState as MatcherState<U> & { negated: Negated }\n );\n }\n\n private fail(matcher: string, details: FailureDetails): never {\n const errorDetails: EnsureErrorDetails = {\n matcher,\n message: details.message,\n ...(details.actual !== undefined ? { actual: details.actual } : {}),\n ...(details.expected !== undefined ? { expected: details.expected } : {}),\n ...(this.state.label !== undefined ? { receivedLabel: this.state.label } : {}),\n };\n throw new EnsureError(errorDetails);\n }\n}\n","import type { EnsureChain, EnsureOptions } from \"./ensure\";\nimport { ensure as baseEnsure } from \"./ensure\";\n\nexport type EnsureInvoker = typeof baseEnsure;\n\nexport type EnsureInvoke = <T>(value: T, options?: EnsureOptions) => EnsureChain<T>;\n\n/**\n * An ensure invoker that also exposes a stable, non-negated invoker.\n *\n * This exists to support plugin-level negation (`ensure.not.<plugin>.*`) without\n * forcing plugin authors to manually import the base ensure.\n *\n * Use `ensure.always(...)` for required-value extraction/preconditions that must\n * not be inverted by `.not`.\n */\nexport type EnsureInvokeWithAlways = EnsureInvoke & {\n readonly always: EnsureInvoke;\n};\n\nexport type EnsureFacade<World, Facets extends Record<string, unknown>> = EnsureInvoke &\n Facets & { readonly world: World; readonly not: Facets };\n\nexport type EnsureFactory<World, Facets extends Record<string, unknown>> = (\n world: World\n) => EnsureFacade<World, Facets>;\n\nexport interface AssertionPluginContext {\n readonly ensure: EnsureInvokeWithAlways;\n\n /**\n * True when this plugin facet is being invoked via plugin-level negation\n * (e.g. `ensure.not.<facet>.*`).\n *\n * Mirrors Jest's `this.isNot` matcher context flag.\n */\n readonly isNot: boolean;\n}\n\nexport type AssertionPlugin<World, Facet> = (\n context: AssertionPluginContext\n) => (world: World) => Facet;\n\ntype PluginFacetResult<World, Plugin> = Plugin extends AssertionPlugin<World, infer Facet>\n ? Facet\n : never;\ntype PluginFacets<World, Plugins extends Record<string, AssertionPlugin<World, unknown>>> = {\n readonly [Key in keyof Plugins]: PluginFacetResult<World, Plugins[Key]>;\n};\n\nexport type EnsurePluginFacets<\n World,\n Plugins extends Record<string, AssertionPlugin<World, unknown>>\n> = PluginFacets<World, Plugins>;\n\n/**\n * Assemble a world-aware ensure factory using the provided assertion plugins.\n * Each plugin receives the base ensure function and returns a facet builder that is\n * invoked with the current world instance. The resulting facets are attached to a\n * callable ensure facade, preserving the base ensure invocation signature.\n */\nexport function createEnsureFactory<\n World,\n Plugins extends Record<string, AssertionPlugin<World, unknown>>\n>(\n ensureFn: EnsureInvoke,\n plugins: Plugins\n): EnsureFactory<World, PluginFacets<World, Plugins>> {\n const withAlways = (\n invoker: EnsureInvoke,\n always: EnsureInvoke\n ): EnsureInvokeWithAlways => {\n Object.defineProperty(invoker, \"always\", {\n value: always,\n enumerable: false,\n configurable: false,\n writable: false,\n });\n return invoker as EnsureInvokeWithAlways;\n };\n\n const positiveEnsure = withAlways(ensureFn, ensureFn);\n const pluginEntries = (Object.keys(plugins) as Array<keyof Plugins>).map((key) => {\n const plugin = plugins[key];\n if (!plugin) {\n throw new Error(`Assertion plugin \"${String(key)}\" is not defined.`);\n }\n const factory = plugin({ ensure: positiveEnsure, isNot: false });\n return [key, factory] as const;\n });\n\n const negatedEnsureFn: EnsureInvoke = <T>(value: T, options?: EnsureOptions) => {\n return ensureFn(value, options).not as unknown as EnsureChain<T>;\n };\n\n const negativeEnsure = withAlways(negatedEnsureFn, ensureFn);\n\n const negativePluginEntries = (Object.keys(plugins) as Array<keyof Plugins>).map((key) => {\n const plugin = plugins[key];\n if (!plugin) {\n throw new Error(`Assertion plugin \"${String(key)}\" is not defined.`);\n }\n const factory = plugin({ ensure: negativeEnsure, isNot: true });\n return [key, factory] as const;\n });\n\n return (world) => {\n const facade = ((value: unknown, options?: EnsureOptions) => ensureFn(value, options)) as EnsureFacade<\n World,\n PluginFacets<World, Plugins>\n >;\n\n Object.defineProperty(facade, \"world\", {\n value: world,\n enumerable: false,\n configurable: false,\n writable: false,\n });\n\n for (const [key, buildFacet] of pluginEntries) {\n const facet = buildFacet(world);\n Object.defineProperty(facade, key, {\n value: facet,\n enumerable: true,\n configurable: false,\n writable: false,\n });\n }\n\n const notFacade = {};\n for (const [key, buildFacet] of negativePluginEntries) {\n const facet = buildFacet(world);\n Object.defineProperty(notFacade, key, {\n value: facet,\n enumerable: true,\n configurable: false,\n writable: false,\n });\n }\n\n Object.defineProperty(facade, \"not\", {\n value: notFacade,\n enumerable: true,\n configurable: false,\n writable: false,\n });\n\n return facade;\n };\n}\n\n/**\n * Create a default ensure factory without any plugins. Useful when consumers\n * want a world-aware ensure facade without additional facets.\n */\nexport function createDefaultEnsureFactory<World>(): EnsureFactory<World, Record<string, never>> {\n return createEnsureFactory<World, Record<string, never>>(baseEnsure, {});\n}\n","import type {\n HeaderlessTable,\n HeaderlessTableOptions,\n HorizontalTable,\n HorizontalTableOptions,\n MatrixTable,\n MatrixTableOptions,\n TableShape,\n VerticalTable,\n VerticalTableOptions,\n} from \"@autometa/gherkin\";\nimport type { RawTable, StepRuntimeHelpers, StepRuntimeMetadata } from \"@autometa/executor\";\n\nimport type { AssertionPlugin } from \"../plugins\";\n\n/**\n * Assertion facet attached as `ensure.runtime.*`.\n *\n * This facet is meant for **step-data ergonomics**:\n * - quick preconditions like “a table is present” / “a docstring is present”\n * - extracting required docstrings/tables with consistently-labeled failures\n *\n * It intentionally uses `ensure.always(...)` for required-value extraction so\n * plugin-level negation (`ensure.not.runtime.*`) does **not** invert these\n * preconditions.\n */\nexport interface RuntimeAssertions {\n /**\n * Assert that the current step has an attached data table.\n *\n * Works with plugin-level negation:\n * - `ensure.runtime.hasTable()` asserts table is present\n * - `ensure.not.runtime.hasTable()` asserts table is NOT present\n */\n hasTable(options?: { readonly label?: string }): void;\n\n /**\n * Assert that the current step has an attached docstring.\n *\n * Works with plugin-level negation:\n * - `ensure.runtime.hasDocstring()` asserts docstring is present\n * - `ensure.not.runtime.hasDocstring()` asserts docstring is NOT present\n */\n hasDocstring(options?: { readonly label?: string }): void;\n\n /**\n * Get the current step's docstring without consuming it.\n */\n docstring(): string | undefined;\n\n /**\n * Consume and return the current step's docstring.\n */\n consumeDocstring(): string | undefined;\n\n /**\n * Consume and return the current step's docstring.\n *\n * This is a *required extraction* helper. It is NOT negated under\n * `ensure.not.runtime.*`.\n */\n requireDocstring(options?: { readonly label?: string }): string;\n\n /**\n * Get the current step's data table coerced to the given shape without consuming it.\n */\n table(shape: \"headerless\", options?: HeaderlessTableOptions): HeaderlessTable | undefined;\n /** @inheritdoc */\n table(shape: \"horizontal\", options?: HorizontalTableOptions): HorizontalTable | undefined;\n /** @inheritdoc */\n table(shape: \"vertical\", options?: VerticalTableOptions): VerticalTable | undefined;\n /** @inheritdoc */\n table(shape: \"matrix\", options?: MatrixTableOptions): MatrixTable | undefined;\n /** @inheritdoc */\n table(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined;\n\n /**\n * Consume and return the current step's data table coerced to the given shape.\n */\n consumeTable(shape: \"headerless\", options?: HeaderlessTableOptions): HeaderlessTable | undefined;\n /** @inheritdoc */\n consumeTable(shape: \"horizontal\", options?: HorizontalTableOptions): HorizontalTable | undefined;\n /** @inheritdoc */\n consumeTable(shape: \"vertical\", options?: VerticalTableOptions): VerticalTable | undefined;\n /** @inheritdoc */\n consumeTable(shape: \"matrix\", options?: MatrixTableOptions): MatrixTable | undefined;\n /** @inheritdoc */\n consumeTable(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined;\n\n /**\n * Consume and return the current step's data table coerced to the given shape.\n *\n * This is a *required extraction* helper. It is NOT negated under\n * `ensure.not.runtime.*`.\n */\n requireTable(\n shape: \"headerless\",\n options?: HeaderlessTableOptions & { readonly label?: string }\n ): HeaderlessTable;\n /** @inheritdoc */\n requireTable(\n shape: \"horizontal\",\n options?: HorizontalTableOptions & { readonly label?: string }\n ): HorizontalTable;\n /** @inheritdoc */\n requireTable(\n shape: \"vertical\",\n options?: VerticalTableOptions & { readonly label?: string }\n ): VerticalTable;\n /** @inheritdoc */\n requireTable(\n shape: \"matrix\",\n options?: MatrixTableOptions & { readonly label?: string }\n ): MatrixTable;\n /** @inheritdoc */\n requireTable(\n shape: TableShape,\n options?: (\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ) & { readonly label?: string }\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable;\n\n /**\n * Return the underlying raw data table (array of string arrays) without consuming it.\n *\n * This is useful for custom table parsing or user-defined table semantics.\n */\n rawTable(): RawTable | undefined;\n\n /**\n * Consume the current step's raw data table.\n */\n consumeRawTable(options?: HeaderlessTableOptions): RawTable | undefined;\n\n /**\n * Consume and return the current step's raw data table.\n *\n * This is a *required extraction* helper. It is NOT negated under\n * `ensure.not.runtime.*`.\n */\n requireRawTable(options?: HeaderlessTableOptions & { readonly label?: string }): RawTable;\n\n /**\n * Return runtime metadata about the current feature/scenario/step, if available.\n */\n stepMetadata(): StepRuntimeMetadata | undefined;\n}\n\ntype WorldWithRuntime = {\n readonly runtime: StepRuntimeHelpers;\n};\n\n/**\n * Standard assertion plugin that provides step-runtime helpers as `ensure.runtime.*`.\n *\n * Register via the runner:\n *\n * ```ts\n * const runner = CucumberRunner.builder()\n * .assertionPlugins({ runtime: runtimeAssertionsPlugin<MyWorld>() });\n * ```\n */\nexport const runtimeAssertionsPlugin = <\n World extends WorldWithRuntime,\n>(): AssertionPlugin<World, RuntimeAssertions> =>\n ({ ensure }) =>\n (world) => {\n const defaultTableLabel = \"step data table\";\n const defaultDocstringLabel = \"step docstring\";\n\n function table(\n shape: \"headerless\",\n options?: HeaderlessTableOptions\n ): HeaderlessTable | undefined;\n function table(\n shape: \"horizontal\",\n options?: HorizontalTableOptions\n ): HorizontalTable | undefined;\n function table(\n shape: \"vertical\",\n options?: VerticalTableOptions\n ): VerticalTable | undefined;\n function table(\n shape: \"matrix\",\n options?: MatrixTableOptions\n ): MatrixTable | undefined;\n function table(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined;\n function table(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined {\n return world.runtime.getTable(shape, options as never);\n }\n\n function consumeTable(\n shape: \"headerless\",\n options?: HeaderlessTableOptions\n ): HeaderlessTable | undefined;\n function consumeTable(\n shape: \"horizontal\",\n options?: HorizontalTableOptions\n ): HorizontalTable | undefined;\n function consumeTable(\n shape: \"vertical\",\n options?: VerticalTableOptions\n ): VerticalTable | undefined;\n function consumeTable(\n shape: \"matrix\",\n options?: MatrixTableOptions\n ): MatrixTable | undefined;\n function consumeTable(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined;\n function consumeTable(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined {\n return world.runtime.consumeTable(shape, options as never);\n }\n\n function requireTable(\n shape: \"headerless\",\n options?: HeaderlessTableOptions & { readonly label?: string }\n ): HeaderlessTable;\n function requireTable(\n shape: \"horizontal\",\n options?: HorizontalTableOptions & { readonly label?: string }\n ): HorizontalTable;\n function requireTable(\n shape: \"vertical\",\n options?: VerticalTableOptions & { readonly label?: string }\n ): VerticalTable;\n function requireTable(\n shape: \"matrix\",\n options?: MatrixTableOptions & { readonly label?: string }\n ): MatrixTable;\n function requireTable(\n shape: TableShape,\n options?: (\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ) & { readonly label?: string }\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable;\n function requireTable(\n shape: TableShape,\n options?: (\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ) & { readonly label?: string }\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable {\n const { label, ...tableOptions } = (options ?? {}) as {\n readonly label?: string;\n } & (\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n );\n\n const table = consumeTable(shape, tableOptions);\n return ensure.always(table, {\n label:\n label ??\n `Expected ${shape} ${defaultTableLabel} to be attached to the current step.`,\n })\n .toBeDefined()\n .value as HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable;\n }\n\n function consumeRawTable(options?: HeaderlessTableOptions): RawTable | undefined {\n // `getRawTable()` does not consume; to consume we piggy-back on consuming a\n // headerless table.\n const tableInstance = consumeTable(\"headerless\", options);\n return tableInstance?.raw();\n }\n\n function requireRawTable(\n options?: HeaderlessTableOptions & { readonly label?: string }\n ): RawTable {\n const { label, ...tableOptions } = (options ?? {}) as {\n readonly label?: string;\n } & HeaderlessTableOptions;\n\n const raw = consumeRawTable(tableOptions);\n return ensure.always(raw, {\n label: label ?? `Expected ${defaultTableLabel} to be attached to the current step.`,\n })\n .toBeDefined()\n .value;\n }\n\n return {\n hasTable(options) {\n ensure(world.runtime.hasTable, {\n label: options?.label ?? `${defaultTableLabel} is present`,\n }).toBeTruthy();\n },\n hasDocstring(options) {\n ensure(world.runtime.hasDocstring, {\n label: options?.label ?? `${defaultDocstringLabel} is present`,\n }).toBeTruthy();\n },\n docstring() {\n return world.runtime.getDocstring();\n },\n consumeDocstring() {\n return world.runtime.consumeDocstring();\n },\n requireDocstring(options) {\n const docstring = world.runtime.consumeDocstring();\n return ensure.always(docstring, {\n label:\n options?.label ??\n `Expected ${defaultDocstringLabel} to be attached to the current step.`,\n })\n .toBeDefined()\n .value as string;\n },\n table,\n consumeTable,\n requireTable,\n rawTable() {\n return world.runtime.getRawTable();\n },\n consumeRawTable,\n requireRawTable,\n stepMetadata() {\n return world.runtime.getStepMetadata();\n },\n };\n };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/assertion-error.ts","../src/matchers/collections.ts","../src/core/constants.ts","../src/core/context.ts","../src/core/messages.ts","../src/core/predicates.ts","../src/matchers/equality.ts","../src/matchers/instance.ts","../src/matchers/nullish.ts","../src/matchers/numeric.ts","../src/matchers/type-of.ts","../src/matchers/truthiness.ts","../src/ensure.ts","../src/plugins.ts","../src/plugins/runtime-assertions-plugin.ts"],"names":["equals","ensure","table"],"mappings":";AAAA,SAAS,eAAe;AAUjB,IAAM,cAAN,cAA0B,MAAM;AAAA,EAKrC,YAAY,SAA6B;AACvC,UAAM,mBAAmB,aAAa,OAAO;AAC7C,UAAM,gBAAgB;AACtB,SAAK,OAAO;AACZ,SAAK,UAAU,QAAQ;AACvB,SAAK,SAAS,QAAQ;AACtB,SAAK,WAAW,QAAQ;AAAA,EAC1B;AACF;AAEA,SAAS,aAAa,EAAE,SAAS,SAAS,QAAQ,UAAU,cAAc,GAA+B;AACvG,QAAM,QAAQ,CAAC,OAAO;AACtB,QAAM,SAAmB,CAAC;AAE1B,MAAI,OAAO,aAAa,eAAe,CAAC,gBAAgB,SAAS,WAAW,GAAG;AAC7E,WAAO,KAAK,aAAa,YAAY,QAAQ,CAAC,EAAE;AAAA,EAClD;AAEA,MAAI,OAAO,WAAW,aAAa;AACjC,UAAM,QAAQ,gBAAgB,YAAY,aAAa,KAAK;AAC5D,QAAI,CAAC,gBAAgB,SAAS,GAAG,KAAK,GAAG,GAAG;AAC1C,aAAO,KAAK,GAAG,KAAK,KAAK,YAAY,MAAM,CAAC,EAAE;AAAA,IAChD;AAAA,EACF;AAEA,MAAI,CAAC,gBAAgB,SAAS,UAAU,GAAG;AACzC,WAAO,KAAK,YAAY,OAAO,EAAE;AAAA,EACnC;AAEA,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,KAAK,IAAI,GAAG,MAAM;AAAA,EAC1B;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,YAAY,OAAwB;AAC3C,SAAO,QAAQ,OAAO,EAAE,OAAO,GAAG,gBAAgB,IAAI,aAAa,IAAI,QAAQ,KAAK,CAAC;AACvF;AAEA,SAAS,gBAAgB,SAAiB,OAAwB;AAChE,SAAO,QACJ,MAAM,IAAI,EACV,KAAK,CAAC,SAAS,KAAK,UAAU,EAAE,WAAW,KAAK,CAAC;AACtD;;;AC3DA,SAAS,cAAc;;;ACAvB,SAAS,kBAAkB,sBAAmC;AAEvD,IAAM,eAAe;AAErB,IAAM,mBAA6B,CAAC,gBAAgB;AAEpD,IAAM,iBAA2B,CAAC,kBAAkB,cAAc;;;ACUlE,SAAS,WAAW,MAAe,SAA2B;AACnE,SAAO,UAAU,OAAO,CAAC;AAC3B;;;AClBA,SAAS,YAAY;AACrB,SAAS,eAAe,qBAAqB;AAYtC,SAAS,oBACd,SACA,aACA,UAAiC,CAAC,GAC1B;AACR,QAAM,WAAqB,CAAC,GAAG,YAAY,IAAI,OAAO,cAAc,WAAW;AAE/E,MAAI,OAAO,UAAU,eAAe,KAAK,SAAS,UAAU,GAAG;AAC7D,aAAS,KAAK,aAAa,cAAc,QAAQ,QAAQ,CAAC,EAAE;AAAA,EAC9D;AAEA,MAAI,OAAO,UAAU,eAAe,KAAK,SAAS,QAAQ,GAAG;AAC3D,UAAM,QAAQ,QAAQ,eAAe;AACrC,aAAS,KAAK,GAAG,KAAK,KAAK,cAAc,QAAQ,MAAM,CAAC,EAAE;AAAA,EAC5D;AAEA,MAAI,QAAQ,OAAO;AACjB,eAAW,SAAS,QAAQ,OAAO;AACjC,UAAI,SAAS,MAAM,KAAK,EAAE,SAAS,GAAG;AACpC,iBAAS,KAAK,KAAK;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,QAAQ,QAAQ,KAAK,KAAK,EAAE,SAAS,GAAG;AAClD,aAAS,KAAK,QAAQ,IAAI;AAAA,EAC5B;AAEA,SAAO,SAAS,KAAK,MAAM;AAC7B;AAEO,SAAS,WAAW,UAAmB,QAAqC;AACjF,QAAM,aAAa,KAAK,UAAU,QAAQ,EAAE,QAAQ,MAAM,CAAC;AAC3D,SAAO,cAAc,WAAW,KAAK,EAAE,SAAS,IAAI,aAAa;AACnE;AAEO,SAAS,kBAAkB,OAAe,QAAoC;AACnF,MAAI,OAAO,WAAW,GAAG;AACvB,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,OAAO,IAAI,CAAC,UAAU,OAAO,cAAc,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI;AAC5E,SAAO,GAAG,KAAK;AAAA,EAAK,KAAK;AAC3B;;;ACvDO,SAAS,SAAS,WAA+D;AACtF,SAAO,OAAO,cAAc,YAAY,cAAc;AACxD;AAEO,SAAS,WAAW,WAAoD;AAC7E,SAAO,OAAQ,YAAgD,OAAO,QAAQ,MAAM;AACtF;AAEO,SAAS,kBAAkB,WAAqD;AACrF,SAAO,OAAQ,WAAoC,WAAW;AAChE;;;AJHO,SAAS,uBACd,KACA,OACM;AACN,QAAM,WAAW,SAAS,IAAI,KAAK;AACnC,MAAI,CAAC,UAAU;AACb,QAAI,CAAC,IAAI,SAAS;AAChB,UAAI,KAAK,wBAAwB;AAAA,QAC/B,SAAS,oBAAoB,wBAAwB,kCAAkC;AAAA,UACrF,QAAQ,IAAI;AAAA,QACd,CAAC;AAAA,QACD,QAAQ,IAAI;AAAA,MACd,CAAC;AAAA,IACH;AACA;AAAA,EACF;AAEA,QAAM,OAAO,OAAO,IAAI,OAAO,OAAO,cAAc;AACpD,MAAI,WAAW,MAAM,IAAI,OAAO,GAAG;AACjC,UAAM,cAAc,IAAI,UACpB,qDACA;AACJ,QAAI,KAAK,wBAAwB;AAAA,MAC/B,SAAS,oBAAoB,wBAAwB,aAAa;AAAA,QAChE,UAAU;AAAA,QACV,QAAQ,IAAI;AAAA,QACZ,MAAM,WAAW,OAAO,IAAI,KAAK;AAAA,MACnC,CAAC;AAAA,MACD,UAAU;AAAA,MACV,QAAQ,IAAI;AAAA,IACd,CAAC;AAAA,EACH;AACF;AAEO,SAAS,sBACd,KACA,UACoB;AACpB,MAAI,CAAC,MAAM,QAAQ,IAAI,KAAK,GAAG;AAC7B,QAAI,CAAC,IAAI,SAAS;AAChB,UAAI,KAAK,uBAAuB;AAAA,QAC9B,SAAS,oBAAoB,uBAAuB,iCAAiC;AAAA,UACnF,QAAQ,IAAI;AAAA,QACd,CAAC;AAAA,QACD,QAAQ,IAAI;AAAA,MACd,CAAC;AAAA,IACH;AACA,WAAO,IAAI;AAAA,EACb;AAEA,QAAM,SAAS,IAAI;AACnB,QAAM,UAAU,SAAS;AAAA,IAAO,CAAC,SAC/B,CAAC,OAAO,KAAK,CAAC,UAAmB,OAAO,OAAO,MAAM,gBAAgB,CAAC;AAAA,EACxE;AAEE,QAAM,OAAO,QAAQ,WAAW;AAClC,MAAI,WAAW,MAAM,IAAI,OAAO,GAAG;AACjC,UAAM,cAAc,IAAI,UACpB,wDACA;AACJ,QAAI,KAAK,uBAAuB;AAAA,MAC9B,SAAS,oBAAoB,uBAAuB,aAAa;AAAA,QAC/D;AAAA,QACA;AAAA,QACA,OAAO,CAAC,kBAAkB,qBAAqB,OAAO,CAAC;AAAA,QACvD,MAAM,WAAW,UAAU,MAAM;AAAA,MACnC,CAAC;AAAA,MACD;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEE,SAAO;AACX;AAEO,SAAS,mBACd,KACA,UACoB;AACpB,MAAI,CAAC,MAAM,QAAQ,IAAI,KAAK,GAAG;AAC7B,QAAI,CAAC,IAAI,SAAS;AAChB,UAAI,KAAK,kBAAkB;AAAA,QACzB,SAAS,oBAAoB,kBAAkB,iCAAiC;AAAA,UAC9E,QAAQ,IAAI;AAAA,QACd,CAAC;AAAA,QACD,QAAQ,IAAI;AAAA,MACd,CAAC;AAAA,IACH;AACA,WAAO,IAAI;AAAA,EACb;AAEA,QAAM,SAAS,IAAI;AACnB,QAAM,OAAO,OAAO,KAAK,CAAC,UAAmB,OAAO,OAAO,UAAU,gBAAgB,CAAC;AACtF,MAAI,WAAW,MAAM,IAAI,OAAO,GAAG;AACjC,UAAM,cAAc,IAAI,UACpB,uDACA;AACJ,QAAI,KAAK,kBAAkB;AAAA,MACzB,SAAS,oBAAoB,kBAAkB,aAAa;AAAA,QAC1D;AAAA,QACA;AAAA,QACA,MAAM,WAAW,UAAU,MAAM;AAAA,MACnC,CAAC;AAAA,MACD;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEO,SAAS,yBACd,KACA,UACmB;AACnB,MAAI,CAAC,WAAW,IAAI,KAAK,GAAG;AAC1B,QAAI,CAAC,IAAI,SAAS;AAChB,UAAI,KAAK,0BAA0B;AAAA,QACjC,SAAS,oBAAoB,0BAA0B,iCAAiC;AAAA,UACtF,QAAQ,IAAI;AAAA,QACd,CAAC;AAAA,QACD,QAAQ,IAAI;AAAA,MACd,CAAC;AAAA,IACH;AACA,WAAO,IAAI;AAAA,EACb;AAEA,QAAM,UAAU,MAAM,KAAK,IAAI,KAA0B;AACzD,QAAM,UAAU,SAAS;AAAA,IAAO,CAAC,SAC/B,CAAC,QAAQ,KAAK,CAAC,UAAU,OAAO,OAAO,MAAM,gBAAgB,CAAC;AAAA,EAChE;AAEA,QAAM,OAAO,QAAQ,WAAW;AAChC,MAAI,WAAW,MAAM,IAAI,OAAO,GAAG;AACjC,UAAM,cAAc,IAAI,UACpB,2DACA;AACJ,QAAI,KAAK,0BAA0B;AAAA,MACjC,SAAS,oBAAoB,0BAA0B,aAAa;AAAA,QAClE;AAAA,QACA,QAAQ;AAAA,QACR,OAAO,CAAC,kBAAkB,qBAAqB,OAAO,CAAC;AAAA,MACzD,CAAC;AAAA,MACD;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAEA,SAAO,IAAI;AACb;AAEO,SAAS,gBAAmB,KAAwB,UAA0B;AACnF,MAAI,CAAC,kBAAkB,IAAI,KAAK,GAAG;AACjC,QAAI,CAAC,IAAI,SAAS;AAChB,UAAI,KAAK,gBAAgB;AAAA,QACvB,SAAS,oBAAoB,gBAAgB,oDAAoD;AAAA,UAC/F,QAAQ,IAAI;AAAA,QACd,CAAC;AAAA,QACD,QAAQ,IAAI;AAAA,MACd,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AAEA,QAAM,eAAgB,IAAI,MAA6B;AACvD,QAAM,OAAO,iBAAiB;AAC9B,MAAI,WAAW,MAAM,IAAI,OAAO,GAAG;AACjC,UAAM,cAAc,IAAI,UACpB,kCAAkC,QAAQ,KAC1C;AACJ,QAAI,KAAK,gBAAgB;AAAA,MACvB,SAAS,oBAAoB,gBAAgB,aAAa;AAAA,QACxD;AAAA,QACA,QAAQ;AAAA,QACR,MAAM,WAAW,UAAU,YAAY;AAAA,MACzC,CAAC;AAAA,MACD;AAAA,MACA,QAAQ;AAAA,IACV,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;AK7LA,SAAS,UAAAA,eAAc;AAMhB,SAAS,WAAc,KAAwB,UAAmB;AACvE,QAAM,OAAO,OAAO,GAAG,IAAI,OAAO,QAAQ;AAC1C,MAAI,IAAI,UAAU,OAAO,CAAC,MAAM;AAC9B,UAAM,cAAc,IAAI,UACpB,6CACA;AACJ,QAAI,KAAK,QAAQ;AAAA,MACf,SAAS,oBAAoB,QAAQ,aAAa;AAAA,QAChD,QAAQ,IAAI;AAAA,QACZ;AAAA,QACA,MAAM,WAAW,UAAU,IAAI,KAAK;AAAA,MACtC,CAAC;AAAA,MACD,QAAQ,IAAI;AAAA,MACZ;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEO,SAAS,cAAiB,KAAwB,UAAyB;AAChF,QAAM,OAAOA,QAAO,IAAI,OAAO,UAAU,gBAAgB;AACzD,MAAI,IAAI,UAAU,OAAO,CAAC,MAAM;AAC9B,UAAM,cAAc,IAAI,UACpB,2CACA;AACJ,QAAI,KAAK,WAAW;AAAA,MAClB,SAAS,oBAAoB,WAAW,aAAa;AAAA,QACnD,QAAQ,IAAI;AAAA,QACZ;AAAA,QACA,MAAM,WAAW,UAAU,IAAI,KAAK;AAAA,MACtC,CAAC;AAAA,MACD,QAAQ,IAAI;AAAA,MACZ;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEO,SAAS,oBAAuB,KAAwB,UAAyB;AACtF,QAAM,OAAOA,QAAO,IAAI,OAAO,UAAU,kBAAkB,IAAI;AAC/D,MAAI,IAAI,UAAU,OAAO,CAAC,MAAM;AAC9B,UAAM,cAAc,IAAI,UACpB,6FACA;AACJ,QAAI,KAAK,iBAAiB;AAAA,MACxB,SAAS,oBAAoB,iBAAiB,aAAa;AAAA,QACzD,QAAQ,IAAI;AAAA,QACZ;AAAA,QACA,MAAM,WAAW,UAAU,IAAI,KAAK;AAAA,MACtC,CAAC;AAAA,MACD,QAAQ,IAAI;AAAA,MACZ;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;ACvDO,SAAS,qBAGd,KAAwB,MAAgC;AACxD,MAAI,OAAO,SAAS,YAAY;AAC9B,QAAI,KAAK,kBAAkB;AAAA,MACzB,SAAS,oBAAoB,kBAAkB,2CAA2C;AAAA,QACxF,UAAU;AAAA,MACZ,CAAC;AAAA,MACD,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AAEA,QAAM,OAAO,IAAI,iBAAiB;AAClC,MAAI,IAAI,UAAU,OAAO,CAAC,MAAM;AAC9B,UAAM,QAAQ,KAAK,QAAQ;AAC3B,UAAM,cAAc,IAAI,UACpB,2CAA2C,KAAK,KAChD,uCAAuC,KAAK;AAChD,QAAI,KAAK,kBAAkB;AAAA,MACzB,SAAS,oBAAoB,kBAAkB,aAAa;AAAA,QAC1D,UAAU;AAAA,QACV,QAAQ,IAAI;AAAA,MACd,CAAC;AAAA,MACD,UAAU;AAAA,MACV,QAAQ,IAAI;AAAA,IACd,CAAC;AAAA,EACH;AAEA,SAAO,IAAI;AACb;;;AC9BA,IAAM,cAAc;AAEb,SAAS,kBAAqB,KAAwC;AAC3E,QAAM,YAAY,IAAI,UAAU,QAAQ,OAAO,IAAI,UAAU;AAC7D,MAAI,IAAI,UAAU,YAAY,CAAC,WAAW;AACxC,UAAM,cAAc,IAAI,UACpB,2CACA;AACJ,QAAI,KAAK,eAAe;AAAA,MACtB,SAAS,oBAAoB,eAAe,aAAa;AAAA,QACvD,QAAQ,IAAI;AAAA,MACd,CAAC;AAAA,MACD,QAAQ,IAAI;AAAA,IACd,CAAC;AAAA,EACH;AACA,SAAO,IAAI;AACb;AAEO,SAAS,oBAAuB,KAAmC;AACxE,QAAM,cAAc,OAAO,IAAI,UAAU;AACzC,MAAI,IAAI,UAAU,cAAc,CAAC,aAAa;AAC5C,UAAM,cAAc,IAAI,UACpB,uCACA;AACJ,QAAI,KAAK,iBAAiB;AAAA,MACxB,SAAS,oBAAoB,iBAAiB,aAAa;AAAA,QACzD,QAAQ,IAAI;AAAA,MACd,CAAC;AAAA,MACD,QAAQ,IAAI;AAAA,IACd,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEO,SAAS,eAAkB,KAA8B;AAC9D,QAAM,SAAS,IAAI,UAAU;AAC7B,MAAI,IAAI,UAAU,SAAS,CAAC,QAAQ;AAClC,UAAM,cAAc,IAAI,UACpB,kCACA;AACJ,QAAI,KAAK,YAAY;AAAA,MACnB,SAAS,oBAAoB,YAAY,aAAa;AAAA,QACpD,QAAQ,IAAI;AAAA,MACd,CAAC;AAAA,MACD,QAAQ,IAAI;AAAA,IACd,CAAC;AAAA,EACH;AACA,SAAO;AACT;;;AC/CA,SAAS,oBACP,KACA,SACQ;AACR,QAAM,QAAQ,IAAI;AAClB,MAAI,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GAAG;AACxD,QAAI,KAAK,SAAS;AAAA,MAChB,SAAS;AAAA,QACP;AAAA,QACA;AAAA,QACA,EAAE,QAAQ,MAAM;AAAA,MAClB;AAAA,MACA,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,SAAS,sBACP,KACA,SACA,UACA,OAAO,YACD;AACN,MAAI,OAAO,aAAa,YAAY,CAAC,OAAO,SAAS,QAAQ,GAAG;AAC9D,QAAI,KAAK,SAAS;AAAA,MAChB,SAAS;AAAA,QACP;AAAA,QACA,YAAY,IAAI;AAAA,QAChB,EAAE,QAAQ,SAAS;AAAA,MACrB;AAAA,MACA,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AACF;AAEO,SAAS,sBACd,KACA,UACQ;AACR,QAAM,SAAS,oBAAoB,KAAK,iBAAiB;AACzD,wBAAsB,KAAgC,mBAAmB,QAAQ;AAEjF,QAAM,OAAO,SAAS;AACtB,MAAI,WAAW,MAAM,IAAI,OAAO,GAAG;AACjC,UAAM,cAAc,IAAI,UACpB,yCAAyC,QAAQ,KACjD,qCAAqC,QAAQ;AAEjD,QAAI,KAAK,mBAAmB;AAAA,MAC1B,SAAS,oBAAoB,mBAAmB,aAAa;AAAA,QAC3D;AAAA,QACA;AAAA,MACF,CAAC;AAAA,MACD;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEO,SAAS,6BACd,KACA,UACQ;AACR,QAAM,SAAS,oBAAoB,KAAK,wBAAwB;AAChE;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,OAAO,UAAU;AACvB,MAAI,WAAW,MAAM,IAAI,OAAO,GAAG;AACjC,UAAM,cAAc,IAAI,UACpB,qDAAqD,QAAQ,KAC7D,iDAAiD,QAAQ;AAE7D,QAAI,KAAK,0BAA0B;AAAA,MACjC,SAAS,oBAAoB,0BAA0B,aAAa;AAAA,QAClE;AAAA,QACA;AAAA,MACF,CAAC;AAAA,MACD;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEO,SAAS,mBACd,KACA,UACQ;AACR,QAAM,SAAS,oBAAoB,KAAK,cAAc;AACtD,wBAAsB,KAAgC,gBAAgB,QAAQ;AAE9E,QAAM,OAAO,SAAS;AACtB,MAAI,WAAW,MAAM,IAAI,OAAO,GAAG;AACjC,UAAM,cAAc,IAAI,UACpB,sCAAsC,QAAQ,KAC9C,kCAAkC,QAAQ;AAE9C,QAAI,KAAK,gBAAgB;AAAA,MACvB,SAAS,oBAAoB,gBAAgB,aAAa;AAAA,QACxD;AAAA,QACA;AAAA,MACF,CAAC;AAAA,MACD;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEO,SAAS,0BACd,KACA,UACQ;AACR,QAAM,SAAS,oBAAoB,KAAK,qBAAqB;AAC7D;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,OAAO,UAAU;AACvB,MAAI,WAAW,MAAM,IAAI,OAAO,GAAG;AACjC,UAAM,cAAc,IAAI,UACpB,kDAAkD,QAAQ,KAC1D,8CAA8C,QAAQ;AAE1D,QAAI,KAAK,uBAAuB;AAAA,MAC9B,SAAS,oBAAoB,uBAAuB,aAAa;AAAA,QAC/D;AAAA,QACA;AAAA,MACF,CAAC;AAAA,MACD;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEO,SAAS,kBACd,KACA,UACA,YAAY,GACJ;AACR,QAAM,SAAS,oBAAoB,KAAK,aAAa;AACrD,wBAAsB,KAAgC,eAAe,QAAQ;AAE7E,MAAI,CAAC,OAAO,UAAU,SAAS,KAAK,YAAY,KAAK,YAAY,IAAI;AACnE,QAAI,KAAK,eAAe;AAAA,MACtB,SAAS;AAAA,QACP;AAAA,QACA;AAAA,QACA,EAAE,QAAQ,UAAU;AAAA,MACtB;AAAA,MACA,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ,CAAC;AAAA,EACH;AAEA,QAAM,YAAY,KAAK,IAAI,IAAI,CAAC,SAAS,IAAI;AAC7C,QAAM,aAAa,KAAK,IAAI,SAAS,QAAQ;AAI7C,QAAM,UAAU,OAAO,UAAU,KAAK,IAAI,GAAG,KAAK,IAAI,MAAM,GAAG,KAAK,IAAI,QAAQ,CAAC,IAAI;AACrF,QAAM,OAAO,cAAc,YAAY;AAEvC,MAAI,WAAW,MAAM,IAAI,OAAO,GAAG;AACjC,UAAM,cAAc,IAAI,UACpB,qCAAqC,QAAQ,eAAe,SAAS,MACrE,iCAAiC,QAAQ,eAAe,SAAS;AAErE,QAAI,KAAK,eAAe;AAAA,MACtB,SAAS,oBAAoB,eAAe,aAAa;AAAA,QACvD;AAAA,QACA;AAAA,QACA,OAAO;AAAA,UACL,eAAe,UAAU;AAAA,UACzB,cAAc,SAAS;AAAA,QACzB;AAAA,MACF,CAAC;AAAA,MACD;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;AC7LO,SAAS,iBAAoB,KAAwB,UAA8B;AACxF,QAAM,aAAa,OAAO,IAAI;AAC9B,QAAM,OAAO,eAAe;AAE5B,MAAI,IAAI,UAAU,OAAO,CAAC,MAAM;AAC9B,UAAM,cAAc,IAAI,UACpB,oCAAoC,QAAQ,KAC5C,gCAAgC,QAAQ;AAC5C,QAAI,KAAK,cAAc;AAAA,MACrB,SAAS,oBAAoB,cAAc,aAAa;AAAA,QACtD;AAAA,QACA,QAAQ,IAAI;AAAA,QACZ,OAAO,CAAC,kBAAkB,UAAU,EAAE;AAAA,MACxC,CAAC;AAAA,MACD;AAAA,MACA,QAAQ,IAAI;AAAA,IACd,CAAC;AAAA,EACH;AACF;;;AC5BO,SAAS,iBAAoB,KAA8B;AAChE,QAAM,OAAO,QAAQ,IAAI,KAAK;AAC9B,MAAI,IAAI,UAAU,OAAO,CAAC,MAAM;AAC9B,UAAM,cAAc,IAAI,UACpB,+BACA;AACJ,QAAI,KAAK,cAAc;AAAA,MACrB,SAAS,oBAAoB,cAAc,aAAa;AAAA,QACtD,QAAQ,IAAI;AAAA,MACd,CAAC;AAAA,MACD,QAAQ,IAAI;AAAA,IACd,CAAC;AAAA,EACH;AACF;AAEO,SAAS,gBAAmB,KAA8B;AAC/D,QAAM,OAAO,CAAC,IAAI;AAClB,MAAI,IAAI,UAAU,OAAO,CAAC,MAAM;AAC9B,UAAM,cAAc,IAAI,UACpB,gCACA;AACJ,QAAI,KAAK,aAAa;AAAA,MACpB,SAAS,oBAAoB,aAAa,aAAa;AAAA,QACrD,QAAQ,IAAI;AAAA,MACd,CAAC;AAAA,MACD,QAAQ,IAAI;AAAA,IACd,CAAC;AAAA,EACH;AACF;;;AC2IO,SAAS,OAAU,OAAU,UAAyB,CAAC,GAAmB;AAC/E,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA,SAAS;AAAA,IACT,GAAI,QAAQ,UAAU,SAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,EAChE;AACA,SAAO,IAAI,gBAA0B,KAAK;AAC5C;AAEA,IAAM,kBAAN,MAAM,iBACuC;AAAA,EAG3C,YAAY,OAA+C;AACzD,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,IAAW,QAAW;AACpB,WAAO,KAAK,MAAM;AAAA,EACpB;AAAA,EAEA,IAAW,MAA+C;AACxD,UAAM,UAAW,CAAC,KAAK,MAAM;AAC7B,UAAM,YAAY;AAAA,MAChB,OAAO,KAAK,MAAM;AAAA,MAClB,SAAS;AAAA,MACT,GAAI,KAAK,MAAM,UAAU,SAAY,EAAE,OAAO,KAAK,MAAM,MAAM,IAAI,CAAC;AAAA,IACtE;AACA,WAAO,IAAI;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAAA,EAEO,IACL,IACiC;AACjC,OAAG,KAAK,MAAM,OAAO;AAAA,MACnB,OAAO,KAAK,MAAM;AAAA,MAClB,GAAI,KAAK,MAAM,UAAU,SAAY,EAAE,OAAO,KAAK,MAAM,MAAM,IAAI,CAAC;AAAA,IACtE,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEO,IAEL,UACA,UAAyB,CAAC,GACS;AACnC,UAAM,QAAQ;AACd,UAAM,UAAU,MAAM,MAAM;AAC5B,QAAI,CAAC,MAAM,QAAQ,OAAO,GAAG;AAC3B,YAAM,KAAK,OAAO;AAAA,QAChB,SAAS;AAAA,QACT,QAAQ,MAAM,MAAM;AAAA,QACpB,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAEA,UAAM,SAAS;AACf,UAAM,SAAS,OAAO;AAAA,MAAI,CAAC,OAAO,OAAO,UACvC,SAAS,OAAsB,OAAO,KAAY;AAAA,IACpD;AACA,UAAM,YAAY;AAAA,MAChB,OAAO;AAAA,MACP,SAAS,MAAM,MAAM;AAAA,MACrB,GAAI,QAAQ,UAAU,SAClB,EAAE,OAAO,QAAQ,MAAM,IACvB,MAAM,MAAM,UAAU,SACpB,EAAE,OAAO,MAAM,MAAM,MAAM,IAC3B,CAAC;AAAA,IACT;AACA,WAAO,IAAI;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAAA,EAEO,KAEL,IACA,UAA0C,CAAC,GACR;AACnC,UAAM,QAAQ;AACd,UAAM,UAAU,MAAM,MAAM;AAC5B,QAAI,CAAC,MAAM,QAAQ,OAAO,GAAG;AAC3B,YAAM,KAAK,QAAQ;AAAA,QACjB,SAAS;AAAA,QACT,QAAQ,MAAM,MAAM;AAAA,QACpB,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAEA,UAAM,SAAS;AACf,aAAS,QAAQ,GAAG,QAAQ,OAAO,QAAQ,SAAS,GAAG;AACrD,YAAM,UAAU,OAAO,KAAK;AAC5B,YAAM,eAAe,MAAM,eAAe,SAAS,OAAO,OAAO;AACjE,YAAM,eAAe;AAAA,QACnB,OAAO;AAAA,QACP,SAAS,MAAM,MAAM;AAAA,QACrB,GAAI,iBAAiB,SAAY,EAAE,OAAO,aAAa,IAAI,CAAC;AAAA,MAC9D;AACA;AAAA,QACE,IAAI;AAAA,UACF;AAAA,QACF;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEO,MAEL,KACA,UAAyB,CAAC,GAC2B;AACrD,UAAM,QAAQ;AACd,UAAM,UAAU,MAAM,MAAM;AAC5B,QAAI,CAAC,MAAM,QAAQ,OAAO,GAAG;AAC3B,YAAM,KAAK,SAAS;AAAA,QAClB,SAAS;AAAA,QACT,QAAQ,MAAM,MAAM;AAAA,QACpB,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAEA,UAAM,SAAS;AACf,UAAM,SAAS,OAAO,IAAI,CAAC,SAAS,UAAU;AAC5C,UAAK,OAAO,YAAY,YAAY,OAAO,YAAY,cAAe,YAAY,MAAM;AACtF,cAAM,KAAK,SAAS;AAAA,UAClB,SAAS,6BAA6B,KAAK,uCAAuC;AAAA,YAChF;AAAA,UACF,CAAC;AAAA,UACD,QAAQ;AAAA,UACR,UAAU;AAAA,QACZ,CAAC;AAAA,MACH;AACA,aAAQ,QAAwB,GAAG;AAAA,IACrC,CAAC;AAED,UAAM,YAAY;AAAA,MAChB,OAAO;AAAA,MACP,SAAS,MAAM,MAAM;AAAA,MACrB,GAAI,QAAQ,UAAU,SAClB,EAAE,OAAO,QAAQ,MAAM,IACvB,MAAM,MAAM,UAAU,SACpB,EAAE,OAAO,MAAM,MAAM,MAAM,IAC3B,CAAC;AAAA,IACT;AACA,WAAO,IAAI;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAAA,EAEO,KAEL,KACA,UAAyB,CAAC,GACY;AACtC,UAAM,QAAQ;AACd,UAAM,UAAU,MAAM,MAAM;AAC5B,QAAK,OAAO,YAAY,YAAY,OAAO,YAAY,cAAe,YAAY,MAAM;AACtF,YAAM,KAAK,QAAQ;AAAA,QACjB,SAAS;AAAA,QACT,QAAQ,MAAM,MAAM;AAAA,QACpB,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAEA,UAAM,YAAY;AAAA,MAChB,OAAQ,QAAgB,GAAG;AAAA,MAC3B,SAAS,MAAM,MAAM;AAAA,MACrB,GAAI,QAAQ,UAAU,SAClB,EAAE,OAAO,QAAQ,MAAM,IACvB,MAAM,MAAM,UAAU,SACpB,EAAE,OAAO,MAAM,MAAM,MAAM,IAC3B,CAAC;AAAA,IACT;AACA,WAAO,IAAI;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAAA,EAEO,KAAK,UAA8C;AACxD,eAAW,KAAK,cAAc,GAAG,QAAQ;AACzC,WAAO;AAAA,EACT;AAAA,EAEO,QAAQ,UAAoD;AACjE,kBAAc,KAAK,cAAc,GAAG,QAAQ;AAC5C,WAAO;AAAA,EACT;AAAA,EAEO,cAAc,UAAoD;AACvE,wBAAoB,KAAK,cAAc,GAAG,QAAQ;AAClD,WAAO;AAAA,EACT;AAAA,EAEO,cAAuF;AAC5F,UAAM,UAAU,kBAAkB,KAAK,cAAc,CAAC;AACtD,UAAM,OAAO,KAAK,MAAM,UAAU,OAAO,KAAK,OAAO,OAAO;AAC5D,WAAO;AAAA,EACT;AAAA,EAEO,gBAAoF;AACzF,UAAM,SAAS,oBAAoB,KAAK,cAAc,CAAC;AACvD,UAAM,OAAO,KAAK,MAAM,UAAU,OAAO,KAAK,OAAO,MAAM;AAC3D,WAAO;AAAA,EACT;AAAA,EAEO,WAA0E;AAC/E,UAAM,SAAS,eAAe,KAAK,cAAc,CAAC;AAClD,UAAM,OAAO,KAAK,MAAM,UAAU,OAAO,KAAK,OAAO,MAAM;AAC3D,WAAO;AAAA,EACT;AAAA,EAEO,aAA8C;AACnD,qBAAiB,KAAK,cAAc,CAAC;AACrC,WAAO;AAAA,EACT;AAAA,EAEO,YAA6C;AAClD,oBAAgB,KAAK,cAAc,CAAC;AACpC,WAAO;AAAA,EACT;AAAA,EAEO,WACL,UACsF;AACtF,qBAAiB,KAAK,cAAc,GAAG,QAAQ;AAC/C,UAAM,OAAO,KAAK,MAAM,UACpB,OACA,KAAK,OAAO,KAAK,MAAM,KAA+C;AAC1E,WAAO;AAAA,EAIT;AAAA,EAEO,gBACL,UAC6E;AAC7E,UAAM,SAAS,sBAAsB,KAAK,cAAc,GAAG,QAAQ;AACnE,UAAM,OAAO,KAAK,MAAM,UAAU,OAAO,KAAK,OAAO,MAA4B;AACjF,WAAO;AAAA,EAIT;AAAA,EAEO,uBACL,UAC6E;AAC7E,UAAM,SAAS,6BAA6B,KAAK,cAAc,GAAG,QAAQ;AAC1E,UAAM,OAAO,KAAK,MAAM,UAAU,OAAO,KAAK,OAAO,MAA4B;AACjF,WAAO;AAAA,EAIT;AAAA,EAEO,aACL,UAC6E;AAC7E,UAAM,SAAS,mBAAmB,KAAK,cAAc,GAAG,QAAQ;AAChE,UAAM,OAAO,KAAK,MAAM,UAAU,OAAO,KAAK,OAAO,MAA4B;AACjF,WAAO;AAAA,EAIT;AAAA,EAEO,oBACL,UAC6E;AAC7E,UAAM,SAAS,0BAA0B,KAAK,cAAc,GAAG,QAAQ;AACvE,UAAM,OAAO,KAAK,MAAM,UAAU,OAAO,KAAK,OAAO,MAA4B;AACjF,WAAO;AAAA,EAIT;AAAA,EAEO,YACL,UACA,WAC6E;AAC7E,UAAM,SAAS,kBAAkB,KAAK,cAAc,GAAG,UAAU,SAAS;AAC1E,UAAM,OAAO,KAAK,MAAM,UAAU,OAAO,KAAK,OAAO,MAA4B;AACjF,WAAO;AAAA,EAIT;AAAA,EAQO,eACL,MAQA;AACA,UAAM,WAAW,qBAAqB,KAAK,cAAc,GAAG,IAAI;AAChE,UAAM,OAAO,KAAK,MAAM,UAAU,OAAO,KAAK,OAAO,QAAQ;AAC7D,WAAO;AAAA,EAQT;AAAA,EAEO,qBACL,OACiC;AACjC,2BAAuB,KAAK,cAAc,GAAG,KAAK;AAClD,WAAO;AAAA,EACT;AAAA,EAEO,oBACL,UACyF;AACzF,UAAM,QAAQ,sBAAsB,KAAK,cAAc,GAAG,QAAQ;AAClE,UAAM,OAAO,KAAK,MAAM,UACpB,OACA,KAAK,OAAO,KAAuC;AACvD,WAAO;AAAA,EAIT;AAAA,EAEO,eACL,UACyF;AACzF,UAAM,QAAQ,mBAAmB,KAAK,cAAc,GAAG,QAAQ;AAC/D,UAAM,OAAO,KAAK,MAAM,UACpB,OACA,KAAK,OAAO,KAAuC;AACvD,WAAO;AAAA,EAIT;AAAA,EAEO,uBACL,UACwF;AACxF,UAAM,WAAW,yBAAyB,KAAK,cAAc,GAAG,QAAQ;AACxE,UAAM,OAAO,KAAK,MAAM,UACpB,OACA,KAAK,OAAO,QAAyC;AACzD,WAAO;AAAA,EAIT;AAAA,EAEO,aACL,UACyF;AACzF,oBAAgB,KAAK,cAAc,GAAG,QAAQ;AAC9C,UAAM,OAAO,KAAK,MAAM,UACpB,OACA,KAAK,OAAO,KAAK,MAAM,KAAuC;AAClE,WAAO;AAAA,EAIT;AAAA,EAEQ,gBAAmC;AACzC,WAAO;AAAA,MACL,OAAO,KAAK,MAAM;AAAA,MAClB,SAAS,KAAK,MAAM;AAAA,MACpB,MAAM,CAAC,SAAS,YAAY,KAAK,KAAK,SAAS,OAAO;AAAA,MACtD,GAAI,KAAK,MAAM,UAAU,SAAY,EAAE,OAAO,KAAK,MAAM,MAAM,IAAI,CAAC;AAAA,IACtE;AAAA,EACF;AAAA,EAEQ,OAAU,OAAuC;AACvD,UAAM,YAAY;AAAA,MAChB;AAAA,MACA,SAAS,KAAK,MAAM;AAAA,MACpB,GAAI,KAAK,MAAM,UAAU,SAAY,EAAE,OAAO,KAAK,MAAM,MAAM,IAAI,CAAC;AAAA,IACtE;AACA,WAAO,IAAI;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,eACN,OACA,OACA,SACoB;AACpB,QAAI,OAAO,QAAQ,UAAU,YAAY;AACvC,aAAO,QAAQ,MAAM,EAAE,OAAO,MAAM,CAAC;AAAA,IACvC;AACA,UAAM,YAAY,QAAQ,SAAS,KAAK,MAAM;AAC9C,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AACA,WAAO,GAAG,SAAS,WAAW,KAAK;AAAA,EACrC;AAAA,EAEQ,KAAK,SAAiB,SAAgC;AAC5D,UAAM,eAAmC;AAAA,MACvC;AAAA,MACA,SAAS,QAAQ;AAAA,MACjB,GAAI,QAAQ,WAAW,SAAY,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MACjE,GAAI,QAAQ,aAAa,SAAY,EAAE,UAAU,QAAQ,SAAS,IAAI,CAAC;AAAA,MACvE,GAAI,KAAK,MAAM,UAAU,SAAY,EAAE,eAAe,KAAK,MAAM,MAAM,IAAI,CAAC;AAAA,IAC9E;AACA,UAAM,IAAI,YAAY,YAAY;AAAA,EACpC;AACF;;;ACxhBO,SAAS,oBAId,UACA,SACoD;AACpD,QAAM,aAAa,CACjB,SACA,WAC2B;AAC3B,WAAO,eAAe,SAAS,UAAU;AAAA,MACvC,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,UAAU;AAAA,IACZ,CAAC;AACD,WAAO;AAAA,EACT;AAEA,QAAM,iBAAiB,WAAW,UAAU,QAAQ;AACpD,QAAM,gBAAiB,OAAO,KAAK,OAAO,EAA2B,IAAI,CAAC,QAAQ;AAChF,UAAM,SAAS,QAAQ,GAAG;AAC1B,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,qBAAqB,OAAO,GAAG,CAAC,mBAAmB;AAAA,IACrE;AACA,UAAM,UAAU,OAAO,EAAE,QAAQ,gBAAgB,OAAO,MAAM,CAAC;AAC/D,WAAO,CAAC,KAAK,OAAO;AAAA,EACtB,CAAC;AAED,QAAM,kBAAgC,CAAI,OAAU,YAA4B;AAC9E,WAAO,SAAS,OAAO,OAAO,EAAE;AAAA,EAClC;AAEA,QAAM,iBAAiB,WAAW,iBAAiB,QAAQ;AAE3D,QAAM,wBAAyB,OAAO,KAAK,OAAO,EAA2B,IAAI,CAAC,QAAQ;AACxF,UAAM,SAAS,QAAQ,GAAG;AAC1B,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,qBAAqB,OAAO,GAAG,CAAC,mBAAmB;AAAA,IACrE;AACA,UAAM,UAAU,OAAO,EAAE,QAAQ,gBAAgB,OAAO,KAAK,CAAC;AAC9D,WAAO,CAAC,KAAK,OAAO;AAAA,EACtB,CAAC;AAED,SAAO,CAAC,UAAU;AAChB,UAAM,SAAU,CAAC,OAAgB,YAA4B,SAAS,OAAO,OAAO;AAKpF,WAAO,eAAe,QAAQ,SAAS;AAAA,MACrC,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,UAAU;AAAA,IACZ,CAAC;AAED,eAAW,CAAC,KAAK,UAAU,KAAK,eAAe;AAC7C,YAAM,QAAQ,WAAW,KAAK;AAC9B,aAAO,eAAe,QAAQ,KAAK;AAAA,QACjC,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,cAAc;AAAA,QACd,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAEA,UAAM,YAAY,CAAC;AACnB,eAAW,CAAC,KAAK,UAAU,KAAK,uBAAuB;AACrD,YAAM,QAAQ,WAAW,KAAK;AAC9B,aAAO,eAAe,WAAW,KAAK;AAAA,QACpC,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,cAAc;AAAA,QACd,UAAU;AAAA,MACZ,CAAC;AAAA,IACH;AAEA,WAAO,eAAe,QAAQ,OAAO;AAAA,MACnC,OAAO;AAAA,MACP,YAAY;AAAA,MACZ,cAAc;AAAA,MACd,UAAU;AAAA,IACZ,CAAC;AAED,WAAO;AAAA,EACT;AACF;AAMO,SAAS,6BAAiF;AAC/F,SAAO,oBAAkD,QAAY,CAAC,CAAC;AACzE;;;ACsBO,IAAM,0BAA0B,MAGrC,CAAC,EAAE,QAAAC,QAAO,MACV,CAAC,UAAU;AACT,QAAM,oBAAoB;AAC1B,QAAM,wBAAwB;AA0B9B,WAAS,MACP,OACA,SAK6E;AAC7E,WAAO,MAAM,QAAQ,SAAS,OAAO,OAAgB;AAAA,EACvD;AA0BA,WAAS,aACP,OACA,SAK6E;AAC7E,WAAO,MAAM,QAAQ,aAAa,OAAO,OAAgB;AAAA,EAC3D;AA2BA,WAAS,aACP,OACA,SAMiE;AACjE,UAAM,EAAE,OAAO,GAAG,aAAa,IAAK,WAAW,CAAC;AAShD,UAAMC,SAAQ,aAAa,OAAO,YAAY;AAC9C,WAAOD,QAAO,OAAOC,QAAO;AAAA,MAC1B,OACE,SACA,YAAY,KAAK,IAAI,iBAAiB;AAAA,IAC1C,CAAC,EACE,YAAY,EACZ;AAAA,EACL;AAEA,WAAS,gBAAgB,SAAwD;AAG/E,UAAM,gBAAgB,aAAa,cAAc,OAAO;AACxD,WAAO,eAAe,IAAI;AAAA,EAC5B;AAEA,WAAS,gBACP,SACU;AACV,UAAM,EAAE,OAAO,GAAG,aAAa,IAAK,WAAW,CAAC;AAIhD,UAAM,MAAM,gBAAgB,YAAY;AACxC,WAAOD,QAAO,OAAO,KAAK;AAAA,MACxB,OAAO,SAAS,YAAY,iBAAiB;AAAA,IAC/C,CAAC,EACE,YAAY,EACZ;AAAA,EACL;AAEA,SAAO;AAAA,IACL,SAAS,SAAS;AAChB,MAAAA,QAAO,MAAM,QAAQ,UAAU;AAAA,QAC7B,OAAO,SAAS,SAAS,GAAG,iBAAiB;AAAA,MAC/C,CAAC,EAAE,WAAW;AAAA,IAChB;AAAA,IACA,aAAa,SAAS;AACpB,MAAAA,QAAO,MAAM,QAAQ,cAAc;AAAA,QACjC,OAAO,SAAS,SAAS,GAAG,qBAAqB;AAAA,MACnD,CAAC,EAAE,WAAW;AAAA,IAChB;AAAA,IACA,YAAY;AACV,aAAO,MAAM,QAAQ,aAAa;AAAA,IACpC;AAAA,IACA,mBAAmB;AACjB,aAAO,MAAM,QAAQ,iBAAiB;AAAA,IACxC;AAAA,IACA,iBAAiB,SAAS;AACxB,YAAM,YAAY,MAAM,QAAQ,iBAAiB;AACjD,aAAOA,QAAO,OAAO,WAAW;AAAA,QAC9B,OACE,SAAS,SACT,YAAY,qBAAqB;AAAA,MACrC,CAAC,EACE,YAAY,EACZ;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AACT,aAAO,MAAM,QAAQ,YAAY;AAAA,IACnC;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe;AACb,aAAO,MAAM,QAAQ,gBAAgB;AAAA,IACvC;AAAA,EACF;AACF","sourcesContent":["import { inspect } from \"node:util\";\n\nexport interface EnsureErrorDetails {\n readonly matcher: string;\n readonly message: string;\n readonly actual?: unknown;\n readonly expected?: unknown;\n readonly receivedLabel?: string;\n}\n\nexport class EnsureError extends Error {\n public readonly matcher: string;\n public readonly actual?: unknown;\n public readonly expected?: unknown;\n\n constructor(details: EnsureErrorDetails) {\n const formattedMessage = buildMessage(details);\n super(formattedMessage);\n this.name = \"EnsureError\";\n this.matcher = details.matcher;\n this.actual = details.actual;\n this.expected = details.expected;\n }\n}\n\nfunction buildMessage({ matcher, message, actual, expected, receivedLabel }: EnsureErrorDetails): string {\n const parts = [message];\n const extras: string[] = [];\n\n if (typeof expected !== \"undefined\" && !containsSection(message, \"Expected:\")) {\n extras.push(`Expected: ${formatValue(expected)}`);\n }\n\n if (typeof actual !== \"undefined\") {\n const label = receivedLabel ? `Received ${receivedLabel}` : \"Received\";\n if (!containsSection(message, `${label}:`)) {\n extras.push(`${label}: ${formatValue(actual)}`);\n }\n }\n\n if (!containsSection(message, \"Matcher:\")) {\n extras.push(`Matcher: ${matcher}`);\n }\n\n if (extras.length > 0) {\n parts.push(\"\", ...extras);\n }\n\n return parts.join(\"\\n\");\n}\n\nfunction formatValue(value: unknown): string {\n return inspect(value, { depth: 4, maxArrayLength: 10, breakLength: 60, sorted: true });\n}\n\nfunction containsSection(message: string, label: string): boolean {\n return message\n .split(\"\\n\")\n .some((line) => line.trimStart().startsWith(label));\n}\n","import { equals } from \"@jest/expect-utils\";\n\nimport { EQUALITY_TESTERS, SUBSET_TESTERS } from \"../core/constants\";\nimport { type MatcherContext, shouldFail } from \"../core/context\";\nimport { buildFailureMessage, formatDiff, formatMissingList } from \"../core/messages\";\nimport { hasLengthProperty, isIterable, isRecord } from \"../core/predicates\";\n\nexport function assertObjectContaining<T>(\n ctx: MatcherContext<T>,\n shape: Record<PropertyKey, unknown>\n): void {\n const isObject = isRecord(ctx.value);\n if (!isObject) {\n if (!ctx.negated) {\n ctx.fail(\"toBeObjectContaining\", {\n message: buildFailureMessage(\"toBeObjectContaining\", \"Expected value to be an object\", {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return;\n }\n\n const pass = equals(ctx.value, shape, SUBSET_TESTERS);\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? \"Expected object not to match the provided subset\"\n : \"Object does not match the provided subset\";\n ctx.fail(\"toBeObjectContaining\", {\n message: buildFailureMessage(\"toBeObjectContaining\", baseMessage, {\n expected: shape,\n actual: ctx.value,\n diff: formatDiff(shape, ctx.value),\n }),\n expected: shape,\n actual: ctx.value,\n });\n }\n}\n\nexport function assertArrayContaining<T>(\n ctx: MatcherContext<T>,\n expected: readonly unknown[]\n): readonly unknown[] {\n if (!Array.isArray(ctx.value)) {\n if (!ctx.negated) {\n ctx.fail(\"toBeArrayContaining\", {\n message: buildFailureMessage(\"toBeArrayContaining\", \"Expected value to be an array\", {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return ctx.value as unknown as readonly unknown[];\n }\n\n const actual = ctx.value as readonly unknown[];\n const missing = expected.filter((item) =>\n !actual.some((entry: unknown) => equals(entry, item, EQUALITY_TESTERS))\n );\n\n const pass = missing.length === 0;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? \"Expected array not to contain the provided elements\"\n : \"Array is missing expected elements\";\n ctx.fail(\"toBeArrayContaining\", {\n message: buildFailureMessage(\"toBeArrayContaining\", baseMessage, {\n expected,\n actual,\n extra: [formatMissingList(\"Missing elements:\", missing)],\n diff: formatDiff(expected, actual),\n }),\n expected,\n actual,\n });\n }\n\n return actual;\n}\n\nexport function assertContainEqual<T>(\n ctx: MatcherContext<T>,\n expected: unknown\n): readonly unknown[] {\n if (!Array.isArray(ctx.value)) {\n if (!ctx.negated) {\n ctx.fail(\"toContainEqual\", {\n message: buildFailureMessage(\"toContainEqual\", \"Expected value to be an array\", {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return ctx.value as unknown as readonly unknown[];\n }\n\n const actual = ctx.value as readonly unknown[];\n const pass = actual.some((entry: unknown) => equals(entry, expected, EQUALITY_TESTERS));\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? \"Expected array not to contain the provided element\"\n : \"Array is missing the expected element\";\n ctx.fail(\"toContainEqual\", {\n message: buildFailureMessage(\"toContainEqual\", baseMessage, {\n expected,\n actual,\n diff: formatDiff(expected, actual),\n }),\n expected,\n actual,\n });\n }\n\n return actual;\n}\n\nexport function assertIterableContaining<T>(\n ctx: MatcherContext<T>,\n expected: readonly unknown[]\n): Iterable<unknown> {\n if (!isIterable(ctx.value)) {\n if (!ctx.negated) {\n ctx.fail(\"toBeIterableContaining\", {\n message: buildFailureMessage(\"toBeIterableContaining\", \"Expected value to be iterable\", {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return ctx.value as unknown as Iterable<unknown>;\n }\n\n const entries = Array.from(ctx.value as Iterable<unknown>);\n const missing = expected.filter((item) =>\n !entries.some((entry) => equals(entry, item, EQUALITY_TESTERS))\n );\n\n const pass = missing.length === 0;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? \"Expected iterable not to contain the provided elements\"\n : \"Iterable is missing expected elements\";\n ctx.fail(\"toBeIterableContaining\", {\n message: buildFailureMessage(\"toBeIterableContaining\", baseMessage, {\n expected,\n actual: entries,\n extra: [formatMissingList(\"Missing elements:\", missing)],\n }),\n expected,\n actual: entries,\n });\n }\n\n return ctx.value as unknown as Iterable<unknown>;\n}\n\nexport function assertHasLength<T>(ctx: MatcherContext<T>, expected: number): number {\n if (!hasLengthProperty(ctx.value)) {\n if (!ctx.negated) {\n ctx.fail(\"toHaveLength\", {\n message: buildFailureMessage(\"toHaveLength\", \"Expected value to have a numeric length property\", {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return NaN;\n }\n\n const actualLength = (ctx.value as { length: number }).length;\n const pass = actualLength === expected;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected length to differ from ${expected}`\n : \"Length does not match expectation\";\n ctx.fail(\"toHaveLength\", {\n message: buildFailureMessage(\"toHaveLength\", baseMessage, {\n expected,\n actual: actualLength,\n diff: formatDiff(expected, actualLength),\n }),\n expected,\n actual: actualLength,\n });\n }\n\n return actualLength;\n}\n","import { iterableEquality, subsetEquality, type Tester } from \"@jest/expect-utils\";\n\nexport const MATCHER_CALL = \"ensure(received)\";\n\nexport const EQUALITY_TESTERS: Tester[] = [iterableEquality];\n\nexport const SUBSET_TESTERS: Tester[] = [iterableEquality, subsetEquality];\n","export interface FailureDetails {\n readonly message: string;\n readonly actual?: unknown;\n readonly expected?: unknown;\n}\n\nexport interface MatcherState<T> {\n readonly value: T;\n readonly label?: string;\n readonly negated: boolean;\n}\n\nexport interface MatcherContext<T> extends MatcherState<T> {\n fail(matcher: string, details: FailureDetails): never;\n}\n\nexport function shouldFail(pass: boolean, negated: boolean): boolean {\n return negated ? pass : !pass;\n}\n","import { diff } from \"jest-diff\";\nimport { printExpected, printReceived } from \"jest-matcher-utils\";\n\nimport { MATCHER_CALL } from \"./constants\";\n\nexport interface FailureMessageOptions {\n readonly expected?: unknown;\n readonly actual?: unknown;\n readonly diff?: string | undefined;\n readonly extra?: readonly (string | undefined)[];\n readonly actualLabel?: string;\n}\n\nexport function buildFailureMessage(\n matcher: string,\n baseMessage: string,\n options: FailureMessageOptions = {}\n): string {\n const sections: string[] = [`${MATCHER_CALL}.${matcher}(expected)`, baseMessage];\n\n if (Object.prototype.hasOwnProperty.call(options, \"expected\")) {\n sections.push(`Expected: ${printExpected(options.expected)}`);\n }\n\n if (Object.prototype.hasOwnProperty.call(options, \"actual\")) {\n const label = options.actualLabel ?? \"Received\";\n sections.push(`${label}: ${printReceived(options.actual)}`);\n }\n\n if (options.extra) {\n for (const extra of options.extra) {\n if (extra && extra.trim().length > 0) {\n sections.push(extra);\n }\n }\n }\n\n if (options.diff && options.diff.trim().length > 0) {\n sections.push(options.diff);\n }\n\n return sections.join(\"\\n\\n\");\n}\n\nexport function formatDiff(expected: unknown, actual: unknown): string | undefined {\n const difference = diff(expected, actual, { expand: false });\n return difference && difference.trim().length > 0 ? difference : undefined;\n}\n\nexport function formatMissingList(title: string, values: readonly unknown[]): string {\n if (values.length === 0) {\n return \"\";\n }\n const items = values.map((value) => ` - ${printExpected(value)}`).join(\"\\n\");\n return `${title}\\n${items}`;\n}\n","export function isRecord(candidate: unknown): candidate is Record<PropertyKey, unknown> {\n return typeof candidate === \"object\" && candidate !== null;\n}\n\nexport function isIterable(candidate: unknown): candidate is Iterable<unknown> {\n return typeof (candidate as { [Symbol.iterator]?: unknown })?.[Symbol.iterator] === \"function\";\n}\n\nexport function hasLengthProperty(candidate: unknown): candidate is { length: number } {\n return typeof (candidate as { length?: unknown })?.length === \"number\";\n}\n","import { equals } from \"@jest/expect-utils\";\n\nimport { EQUALITY_TESTERS } from \"../core/constants\";\nimport { type MatcherContext } from \"../core/context\";\nimport { buildFailureMessage, formatDiff } from \"../core/messages\";\n\nexport function assertToBe<T>(ctx: MatcherContext<T>, expected: T): void {\n const pass = Object.is(ctx.value, expected);\n if (ctx.negated ? pass : !pass) {\n const baseMessage = ctx.negated\n ? \"Expected values not to be strictly equal\"\n : \"Expected values to be strictly equal\";\n ctx.fail(\"toBe\", {\n message: buildFailureMessage(\"toBe\", baseMessage, {\n actual: ctx.value,\n expected,\n diff: formatDiff(expected, ctx.value),\n }),\n actual: ctx.value,\n expected,\n });\n }\n}\n\nexport function assertToEqual<T>(ctx: MatcherContext<T>, expected: unknown): void {\n const pass = equals(ctx.value, expected, EQUALITY_TESTERS);\n if (ctx.negated ? pass : !pass) {\n const baseMessage = ctx.negated\n ? \"Expected values not to be deeply equal\"\n : \"Expected values to be deeply equal\";\n ctx.fail(\"toEqual\", {\n message: buildFailureMessage(\"toEqual\", baseMessage, {\n actual: ctx.value,\n expected,\n diff: formatDiff(expected, ctx.value),\n }),\n actual: ctx.value,\n expected,\n });\n }\n}\n\nexport function assertToStrictEqual<T>(ctx: MatcherContext<T>, expected: unknown): void {\n const pass = equals(ctx.value, expected, EQUALITY_TESTERS, true);\n if (ctx.negated ? pass : !pass) {\n const baseMessage = ctx.negated\n ? \"Expected values not to be strictly equal (including prototypes and property definitions)\"\n : \"Expected values to be strictly equal (including prototypes and property definitions)\";\n ctx.fail(\"toStrictEqual\", {\n message: buildFailureMessage(\"toStrictEqual\", baseMessage, {\n actual: ctx.value,\n expected,\n diff: formatDiff(expected, ctx.value),\n }),\n actual: ctx.value,\n expected,\n });\n }\n}\n","import type { MatcherContext } from \"../core/context\";\nimport { buildFailureMessage } from \"../core/messages\";\n\nexport function assertToBeInstanceOf<\n T,\n Ctor extends abstract new (...args: never[]) => unknown\n>(ctx: MatcherContext<T>, ctor: Ctor): InstanceType<Ctor> {\n if (typeof ctor !== \"function\") {\n ctx.fail(\"toBeInstanceOf\", {\n message: buildFailureMessage(\"toBeInstanceOf\", \"Constructor must be a callable function\", {\n expected: ctor,\n }),\n expected: ctor,\n });\n }\n\n const pass = ctx.value instanceof ctor;\n if (ctx.negated ? pass : !pass) {\n const label = ctor.name || \"<anonymous>\";\n const baseMessage = ctx.negated\n ? `Expected value not to be an instance of ${label}`\n : `Expected value to be an instance of ${label}`;\n ctx.fail(\"toBeInstanceOf\", {\n message: buildFailureMessage(\"toBeInstanceOf\", baseMessage, {\n expected: ctor,\n actual: ctx.value,\n }),\n expected: ctor,\n actual: ctx.value,\n });\n }\n\n return ctx.value as InstanceType<Ctor>;\n}\n","import type { MatcherContext } from \"../core/context\";\nimport { buildFailureMessage } from \"../core/messages\";\n\nconst NIL_MESSAGE = \"Value is null or undefined\";\n\nexport function assertToBeDefined<T>(ctx: MatcherContext<T>): NonNullable<T> {\n const isDefined = ctx.value !== null && typeof ctx.value !== \"undefined\";\n if (ctx.negated ? isDefined : !isDefined) {\n const baseMessage = ctx.negated\n ? \"Expected value to be null or undefined\"\n : NIL_MESSAGE;\n ctx.fail(\"toBeDefined\", {\n message: buildFailureMessage(\"toBeDefined\", baseMessage, {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return ctx.value as NonNullable<T>;\n}\n\nexport function assertToBeUndefined<T>(ctx: MatcherContext<T>): undefined {\n const isUndefined = typeof ctx.value === \"undefined\";\n if (ctx.negated ? isUndefined : !isUndefined) {\n const baseMessage = ctx.negated\n ? \"Expected value not to be undefined\"\n : \"Expected value to be undefined\";\n ctx.fail(\"toBeUndefined\", {\n message: buildFailureMessage(\"toBeUndefined\", baseMessage, {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return undefined;\n}\n\nexport function assertToBeNull<T>(ctx: MatcherContext<T>): null {\n const isNull = ctx.value === null;\n if (ctx.negated ? isNull : !isNull) {\n const baseMessage = ctx.negated\n ? \"Expected value not to be null\"\n : \"Expected value to be null\";\n ctx.fail(\"toBeNull\", {\n message: buildFailureMessage(\"toBeNull\", baseMessage, {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return null;\n}\n","import type { MatcherContext } from \"../core/context\";\nimport { shouldFail } from \"../core/context\";\nimport { buildFailureMessage } from \"../core/messages\";\n\nfunction requireFiniteNumber<T>(\n ctx: MatcherContext<T>,\n matcher: string\n): number {\n const value = ctx.value;\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n ctx.fail(matcher, {\n message: buildFailureMessage(\n matcher,\n \"Expected value to be a finite number\",\n { actual: value }\n ),\n actual: value,\n expected: \"finite number\",\n });\n }\n return value;\n}\n\nfunction requireFiniteExpected(\n ctx: MatcherContext<unknown>,\n matcher: string,\n expected: number,\n name = \"expected\"\n): void {\n if (typeof expected !== \"number\" || !Number.isFinite(expected)) {\n ctx.fail(matcher, {\n message: buildFailureMessage(\n matcher,\n `Expected ${name} to be a finite number`,\n { actual: expected }\n ),\n actual: expected,\n expected: \"finite number\",\n });\n }\n}\n\nexport function assertToBeGreaterThan<T>(\n ctx: MatcherContext<T>,\n expected: number\n): number {\n const actual = requireFiniteNumber(ctx, \"toBeGreaterThan\");\n requireFiniteExpected(ctx as MatcherContext<unknown>, \"toBeGreaterThan\", expected);\n\n const pass = actual > expected;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected value not to be greater than ${expected}`\n : `Expected value to be greater than ${expected}`;\n\n ctx.fail(\"toBeGreaterThan\", {\n message: buildFailureMessage(\"toBeGreaterThan\", baseMessage, {\n expected,\n actual,\n }),\n actual,\n expected,\n });\n }\n\n return actual;\n}\n\nexport function assertToBeGreaterThanOrEqual<T>(\n ctx: MatcherContext<T>,\n expected: number\n): number {\n const actual = requireFiniteNumber(ctx, \"toBeGreaterThanOrEqual\");\n requireFiniteExpected(\n ctx as MatcherContext<unknown>,\n \"toBeGreaterThanOrEqual\",\n expected\n );\n\n const pass = actual >= expected;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected value not to be greater than or equal to ${expected}`\n : `Expected value to be greater than or equal to ${expected}`;\n\n ctx.fail(\"toBeGreaterThanOrEqual\", {\n message: buildFailureMessage(\"toBeGreaterThanOrEqual\", baseMessage, {\n expected,\n actual,\n }),\n actual,\n expected,\n });\n }\n\n return actual;\n}\n\nexport function assertToBeLessThan<T>(\n ctx: MatcherContext<T>,\n expected: number\n): number {\n const actual = requireFiniteNumber(ctx, \"toBeLessThan\");\n requireFiniteExpected(ctx as MatcherContext<unknown>, \"toBeLessThan\", expected);\n\n const pass = actual < expected;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected value not to be less than ${expected}`\n : `Expected value to be less than ${expected}`;\n\n ctx.fail(\"toBeLessThan\", {\n message: buildFailureMessage(\"toBeLessThan\", baseMessage, {\n expected,\n actual,\n }),\n actual,\n expected,\n });\n }\n\n return actual;\n}\n\nexport function assertToBeLessThanOrEqual<T>(\n ctx: MatcherContext<T>,\n expected: number\n): number {\n const actual = requireFiniteNumber(ctx, \"toBeLessThanOrEqual\");\n requireFiniteExpected(\n ctx as MatcherContext<unknown>,\n \"toBeLessThanOrEqual\",\n expected\n );\n\n const pass = actual <= expected;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected value not to be less than or equal to ${expected}`\n : `Expected value to be less than or equal to ${expected}`;\n\n ctx.fail(\"toBeLessThanOrEqual\", {\n message: buildFailureMessage(\"toBeLessThanOrEqual\", baseMessage, {\n expected,\n actual,\n }),\n actual,\n expected,\n });\n }\n\n return actual;\n}\n\nexport function assertToBeCloseTo<T>(\n ctx: MatcherContext<T>,\n expected: number,\n precision = 2\n): number {\n const actual = requireFiniteNumber(ctx, \"toBeCloseTo\");\n requireFiniteExpected(ctx as MatcherContext<unknown>, \"toBeCloseTo\", expected);\n\n if (!Number.isInteger(precision) || precision < 0 || precision > 20) {\n ctx.fail(\"toBeCloseTo\", {\n message: buildFailureMessage(\n \"toBeCloseTo\",\n \"Expected precision to be an integer between 0 and 20\",\n { actual: precision }\n ),\n actual: precision,\n expected: \"integer between 0 and 20\",\n });\n }\n\n const tolerance = Math.pow(10, -precision) / 2;\n const difference = Math.abs(actual - expected);\n // Floating-point operations can produce tiny rounding errors near the boundary.\n // We allow an EPSILON-scaled slack so values that are mathematically on the\n // boundary don't fail due to representation quirks.\n const epsilon = Number.EPSILON * Math.max(1, Math.abs(actual), Math.abs(expected)) * 2;\n const pass = difference <= tolerance + epsilon;\n\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected value not to be close to ${expected} (precision ${precision})`\n : `Expected value to be close to ${expected} (precision ${precision})`;\n\n ctx.fail(\"toBeCloseTo\", {\n message: buildFailureMessage(\"toBeCloseTo\", baseMessage, {\n expected,\n actual,\n extra: [\n `Difference: ${difference}`,\n `Tolerance: ${tolerance}`,\n ],\n }),\n actual,\n expected,\n });\n }\n\n return actual;\n}\n","import type { MatcherContext } from \"../core/context\";\nimport { buildFailureMessage } from \"../core/messages\";\n\ntype EnsureTypeOf =\n | \"string\"\n | \"number\"\n | \"boolean\"\n | \"bigint\"\n | \"symbol\"\n | \"undefined\"\n | \"object\"\n | \"function\";\n\nexport function assertToBeTypeOf<T>(ctx: MatcherContext<T>, expected: EnsureTypeOf): void {\n const actualType = typeof ctx.value;\n const pass = actualType === expected;\n\n if (ctx.negated ? pass : !pass) {\n const baseMessage = ctx.negated\n ? `Expected value not to be of type ${expected}`\n : `Expected value to be of type ${expected}`;\n ctx.fail(\"toBeTypeOf\", {\n message: buildFailureMessage(\"toBeTypeOf\", baseMessage, {\n expected,\n actual: ctx.value,\n extra: [`Received type: ${actualType}`],\n }),\n expected,\n actual: ctx.value,\n });\n }\n}\n\n","import type { MatcherContext } from \"../core/context\";\nimport { buildFailureMessage } from \"../core/messages\";\n\nexport function assertToBeTruthy<T>(ctx: MatcherContext<T>): void {\n const pass = Boolean(ctx.value);\n if (ctx.negated ? pass : !pass) {\n const baseMessage = ctx.negated\n ? \"Expected value to be falsy\"\n : \"Expected value to be truthy\";\n ctx.fail(\"toBeTruthy\", {\n message: buildFailureMessage(\"toBeTruthy\", baseMessage, {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n}\n\nexport function assertToBeFalsy<T>(ctx: MatcherContext<T>): void {\n const pass = !ctx.value;\n if (ctx.negated ? pass : !pass) {\n const baseMessage = ctx.negated\n ? \"Expected value to be truthy\"\n : \"Expected value to be falsy\";\n ctx.fail(\"toBeFalsy\", {\n message: buildFailureMessage(\"toBeFalsy\", baseMessage, {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n}\n","import { EnsureError, type EnsureErrorDetails } from \"./assertion-error\";\nimport {\n type FailureDetails,\n type MatcherContext,\n type MatcherState,\n} from \"./core/context\";\nimport {\n assertArrayContaining,\n assertContainEqual,\n assertHasLength,\n assertIterableContaining,\n assertObjectContaining,\n} from \"./matchers/collections\";\nimport { assertToBe, assertToEqual, assertToStrictEqual } from \"./matchers/equality\";\nimport { assertToBeInstanceOf } from \"./matchers/instance\";\nimport {\n assertToBeDefined,\n assertToBeNull,\n assertToBeUndefined,\n} from \"./matchers/nullish\";\nimport {\n assertToBeCloseTo,\n assertToBeGreaterThan,\n assertToBeGreaterThanOrEqual,\n assertToBeLessThan,\n assertToBeLessThanOrEqual,\n} from \"./matchers/numeric\";\nimport { assertToBeTypeOf } from \"./matchers/type-of\";\nimport { assertToBeFalsy, assertToBeTruthy } from \"./matchers/truthiness\";\n\nexport interface EnsureOptions {\n readonly label?: string;\n}\n\nexport interface EnsureEachOptions<T> {\n readonly label?: string | ((details: { readonly index: number; readonly value: T }) => string);\n}\n\nexport interface EnsureTapContext<Negated extends boolean> {\n readonly isNot: Negated;\n readonly label?: string;\n}\n\ntype EnsureTypeOf =\n | \"string\"\n | \"number\"\n | \"boolean\"\n | \"bigint\"\n | \"symbol\"\n | \"undefined\"\n | \"object\"\n | \"function\";\n\ntype TypeOfResult<T extends EnsureTypeOf> = T extends \"string\"\n ? string\n : T extends \"number\"\n ? number\n : T extends \"boolean\"\n ? boolean\n : T extends \"bigint\"\n ? bigint\n : T extends \"symbol\"\n ? symbol\n : T extends \"undefined\"\n ? undefined\n : T extends \"function\"\n ? (...args: never[]) => unknown\n : T extends \"object\"\n ? object | null\n : never;\n\ntype NarrowByTypeOf<T, Expected extends EnsureTypeOf> = [\n Extract<T, TypeOfResult<Expected>>,\n] extends [never]\n ? TypeOfResult<Expected>\n : Extract<T, TypeOfResult<Expected>>;\n\ntype NarrowToArray<T> = [Extract<T, readonly unknown[]>] extends [never]\n ? readonly unknown[]\n : Extract<T, readonly unknown[]>;\n\ntype Toggle<Negated extends boolean> = Negated extends true ? false : true;\n\ninterface EnsureChainInternal<T, Negated extends boolean> {\n readonly value: T;\n readonly not: EnsureChainInternal<T, Toggle<Negated>>;\n tap(\n fn: (value: T, context: EnsureTapContext<Negated>) => void\n ): EnsureChainInternal<T, Negated>;\n map<U, Arr extends readonly unknown[]>(\n this: EnsureChainInternal<Arr, Negated>,\n selector: (value: Arr[number], index: number, array: Arr) => U,\n options?: EnsureOptions\n ): EnsureChainInternal<U[], Negated>;\n each<Arr extends readonly unknown[]>(\n this: EnsureChainInternal<Arr, Negated>,\n fn: (value: EnsureChainInternal<Arr[number], Negated>, index: number) => void,\n options?: EnsureEachOptions<Arr[number]>\n ): EnsureChainInternal<Arr, Negated>;\n pluck<Arr extends readonly object[], K extends keyof Arr[number]>(\n this: EnsureChainInternal<Arr, Negated>,\n key: K,\n options?: EnsureOptions\n ): EnsureChainInternal<Array<Arr[number][K]>, Negated>;\n prop<Obj extends object, K extends keyof Obj>(\n this: EnsureChainInternal<Obj, Negated>,\n key: K,\n options?: EnsureOptions\n ): EnsureChainInternal<Obj[K], Negated>;\n toBeTypeOf<Expected extends EnsureTypeOf>(\n expected: Expected\n ): EnsureChainInternal<Negated extends true ? T : NarrowByTypeOf<T, Expected>, Negated>;\n toBe(expected: T): EnsureChainInternal<T, Negated>;\n toEqual(expected: unknown): EnsureChainInternal<T, Negated>;\n toStrictEqual(expected: unknown): EnsureChainInternal<T, Negated>;\n toBeDefined(): EnsureChainInternal<Negated extends true ? T : NonNullable<T>, Negated>;\n toBeUndefined(): EnsureChainInternal<Negated extends true ? T : undefined, Negated>;\n toBeNull(): EnsureChainInternal<Negated extends true ? T : null, Negated>;\n toBeTruthy(): EnsureChainInternal<T, Negated>;\n toBeFalsy(): EnsureChainInternal<T, Negated>;\n toBeGreaterThan(expected: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n toBeGreaterThanOrEqual(expected: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n toBeLessThan(expected: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n toBeLessThanOrEqual(expected: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n toBeCloseTo(expected: number, precision?: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n toBeInstanceOf(\n ctor: ArrayConstructor\n ): EnsureChainInternal<Negated extends true ? T : NarrowToArray<T>, Negated>;\n toBeInstanceOf<Ctor extends abstract new (...args: never[]) => unknown>(\n ctor: Ctor\n ): EnsureChainInternal<Negated extends true ? T : InstanceType<Ctor>, Negated>;\n toBeObjectContaining<Shape extends Record<PropertyKey, unknown>>(\n shape: Shape\n ): EnsureChainInternal<T, Negated>;\n toBeArrayContaining(expected: readonly unknown[]): EnsureChainInternal<\n Negated extends true ? T : Extract<T, readonly unknown[]>,\n Negated\n >;\n toContainEqual(expected: unknown): EnsureChainInternal<\n Negated extends true ? T : Extract<T, readonly unknown[]>,\n Negated\n >;\n toBeIterableContaining(expected: readonly unknown[]): EnsureChainInternal<\n Negated extends true ? T : Extract<T, Iterable<unknown>>,\n Negated\n >;\n toHaveLength(expected: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, { length: number }> ,\n Negated\n >;\n}\n\nexport type EnsureChain<T> = EnsureChainInternal<T, false>;\nexport type EnsureNegatedChain<T> = EnsureChainInternal<T, true>;\n\nexport function ensure<T>(value: T, options: EnsureOptions = {}): EnsureChain<T> {\n const state = {\n value,\n negated: false as const,\n ...(options.label !== undefined ? { label: options.label } : {}),\n } satisfies MatcherState<T> & { negated: false };\n return new EnsureChainImpl<T, false>(state);\n}\n\nclass EnsureChainImpl<T, Negated extends boolean>\n implements EnsureChainInternal<T, Negated> {\n private readonly state: MatcherState<T> & { negated: Negated };\n\n constructor(state: MatcherState<T> & { negated: Negated }) {\n this.state = state;\n }\n\n public get value(): T {\n return this.state.value;\n }\n\n public get not(): EnsureChainInternal<T, Toggle<Negated>> {\n const toggled = (!this.state.negated) as Toggle<Negated>;\n const nextState = {\n value: this.state.value,\n negated: toggled,\n ...(this.state.label !== undefined ? { label: this.state.label } : {}),\n };\n return new EnsureChainImpl<T, Toggle<Negated>>(\n nextState as MatcherState<T> & { negated: Toggle<Negated> }\n );\n }\n\n public tap(\n fn: (value: T, context: EnsureTapContext<Negated>) => void\n ): EnsureChainInternal<T, Negated> {\n fn(this.state.value, {\n isNot: this.state.negated,\n ...(this.state.label !== undefined ? { label: this.state.label } : {}),\n });\n return this;\n }\n\n public map<U, Arr extends readonly unknown[]>(\n this: EnsureChainInternal<Arr, Negated>,\n selector: (value: Arr[number], index: number, array: Arr) => U,\n options: EnsureOptions = {}\n ): EnsureChainInternal<U[], Negated> {\n const chain = this as unknown as EnsureChainImpl<Arr, Negated>;\n const current = chain.state.value as unknown;\n if (!Array.isArray(current)) {\n chain.fail(\"map\", {\n message: \"Expected value to be an array in order to use ensure(...).map(...)\",\n actual: chain.state.value,\n expected: \"array\",\n });\n }\n\n const values = current as unknown as Arr;\n const mapped = values.map((value, index, array) =>\n selector(value as Arr[number], index, array as Arr)\n );\n const nextState = {\n value: mapped,\n negated: chain.state.negated,\n ...(options.label !== undefined\n ? { label: options.label }\n : chain.state.label !== undefined\n ? { label: chain.state.label }\n : {}),\n };\n return new EnsureChainImpl<U[], Negated>(\n nextState as MatcherState<U[]> & { negated: Negated }\n );\n }\n\n public each<Arr extends readonly unknown[]>(\n this: EnsureChainInternal<Arr, Negated>,\n fn: (value: EnsureChainInternal<Arr[number], Negated>, index: number) => void,\n options: EnsureEachOptions<Arr[number]> = {}\n ): EnsureChainInternal<Arr, Negated> {\n const chain = this as unknown as EnsureChainImpl<Arr, Negated>;\n const current = chain.state.value as unknown;\n if (!Array.isArray(current)) {\n chain.fail(\"each\", {\n message: \"Expected value to be an array in order to use ensure(...).each(...)\",\n actual: chain.state.value,\n expected: \"array\",\n });\n }\n\n const values = current as unknown as Arr;\n for (let index = 0; index < values.length; index += 1) {\n const element = values[index] as Arr[number];\n const elementLabel = chain.buildEachLabel(element, index, options);\n const elementState = {\n value: element,\n negated: chain.state.negated,\n ...(elementLabel !== undefined ? { label: elementLabel } : {}),\n };\n fn(\n new EnsureChainImpl<Arr[number], Negated>(\n elementState as MatcherState<Arr[number]> & { negated: Negated }\n ),\n index\n );\n }\n\n return this;\n }\n\n public pluck<Arr extends readonly object[], K extends keyof Arr[number]>(\n this: EnsureChainInternal<Arr, Negated>,\n key: K,\n options: EnsureOptions = {}\n ): EnsureChainInternal<Array<Arr[number][K]>, Negated> {\n const chain = this as unknown as EnsureChainImpl<Arr, Negated>;\n const current = chain.state.value as unknown;\n if (!Array.isArray(current)) {\n chain.fail(\"pluck\", {\n message: \"Expected value to be an array in order to use ensure(...).pluck(...)\",\n actual: chain.state.value,\n expected: \"array\",\n });\n }\n\n const values = current as unknown as Arr;\n const mapped = values.map((element, index) => {\n if ((typeof element !== \"object\" && typeof element !== \"function\") || element === null) {\n chain.fail(\"pluck\", {\n message: `Expected element at index ${index} to be an object in order to pluck \"${String(\n key\n )}\"`,\n actual: element,\n expected: \"object\",\n });\n }\n return (element as Arr[number])[key] as Arr[number][K];\n });\n\n const nextState = {\n value: mapped,\n negated: chain.state.negated,\n ...(options.label !== undefined\n ? { label: options.label }\n : chain.state.label !== undefined\n ? { label: chain.state.label }\n : {}),\n };\n return new EnsureChainImpl<Array<Arr[number][K]>, Negated>(\n nextState as MatcherState<Array<Arr[number][K]>> & { negated: Negated }\n );\n }\n\n public prop<Obj extends object, K extends keyof Obj>(\n this: EnsureChainInternal<Obj, Negated>,\n key: K,\n options: EnsureOptions = {}\n ): EnsureChainInternal<Obj[K], Negated> {\n const chain = this as unknown as EnsureChainImpl<Obj, Negated>;\n const current = chain.state.value as unknown;\n if ((typeof current !== \"object\" && typeof current !== \"function\") || current === null) {\n chain.fail(\"prop\", {\n message: \"Expected value to be an object in order to use ensure(...).prop(...)\",\n actual: chain.state.value,\n expected: \"object\",\n });\n }\n\n const nextState = {\n value: (current as Obj)[key],\n negated: chain.state.negated,\n ...(options.label !== undefined\n ? { label: options.label }\n : chain.state.label !== undefined\n ? { label: chain.state.label }\n : {}),\n };\n return new EnsureChainImpl<Obj[K], Negated>(\n nextState as MatcherState<Obj[K]> & { negated: Negated }\n );\n }\n\n public toBe(expected: T): EnsureChainInternal<T, Negated> {\n assertToBe(this.createContext(), expected);\n return this;\n }\n\n public toEqual(expected: unknown): EnsureChainInternal<T, Negated> {\n assertToEqual(this.createContext(), expected);\n return this;\n }\n\n public toStrictEqual(expected: unknown): EnsureChainInternal<T, Negated> {\n assertToStrictEqual(this.createContext(), expected);\n return this;\n }\n\n public toBeDefined(): EnsureChainInternal<Negated extends true ? T : NonNullable<T>, Negated> {\n const defined = assertToBeDefined(this.createContext());\n const next = this.state.negated ? this : this.rewrap(defined);\n return next as EnsureChainInternal<Negated extends true ? T : NonNullable<T>, Negated>;\n }\n\n public toBeUndefined(): EnsureChainInternal<Negated extends true ? T : undefined, Negated> {\n const result = assertToBeUndefined(this.createContext());\n const next = this.state.negated ? this : this.rewrap(result);\n return next as EnsureChainInternal<Negated extends true ? T : undefined, Negated>;\n }\n\n public toBeNull(): EnsureChainInternal<Negated extends true ? T : null, Negated> {\n const result = assertToBeNull(this.createContext());\n const next = this.state.negated ? this : this.rewrap(result);\n return next as EnsureChainInternal<Negated extends true ? T : null, Negated>;\n }\n\n public toBeTruthy(): EnsureChainInternal<T, Negated> {\n assertToBeTruthy(this.createContext());\n return this;\n }\n\n public toBeFalsy(): EnsureChainInternal<T, Negated> {\n assertToBeFalsy(this.createContext());\n return this;\n }\n\n public toBeTypeOf<Expected extends EnsureTypeOf>(\n expected: Expected\n ): EnsureChainInternal<Negated extends true ? T : NarrowByTypeOf<T, Expected>, Negated> {\n assertToBeTypeOf(this.createContext(), expected);\n const next = this.state.negated\n ? this\n : this.rewrap(this.state.value as unknown as NarrowByTypeOf<T, Expected>);\n return next as EnsureChainInternal<\n Negated extends true ? T : NarrowByTypeOf<T, Expected>,\n Negated\n >;\n }\n\n public toBeGreaterThan(\n expected: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated> {\n const actual = assertToBeGreaterThan(this.createContext(), expected);\n const next = this.state.negated ? this : this.rewrap(actual as Extract<T, number>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n }\n\n public toBeGreaterThanOrEqual(\n expected: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated> {\n const actual = assertToBeGreaterThanOrEqual(this.createContext(), expected);\n const next = this.state.negated ? this : this.rewrap(actual as Extract<T, number>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n }\n\n public toBeLessThan(\n expected: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated> {\n const actual = assertToBeLessThan(this.createContext(), expected);\n const next = this.state.negated ? this : this.rewrap(actual as Extract<T, number>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n }\n\n public toBeLessThanOrEqual(\n expected: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated> {\n const actual = assertToBeLessThanOrEqual(this.createContext(), expected);\n const next = this.state.negated ? this : this.rewrap(actual as Extract<T, number>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n }\n\n public toBeCloseTo(\n expected: number,\n precision?: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated> {\n const actual = assertToBeCloseTo(this.createContext(), expected, precision);\n const next = this.state.negated ? this : this.rewrap(actual as Extract<T, number>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n }\n\n public toBeInstanceOf(\n ctor: ArrayConstructor\n ): EnsureChainInternal<Negated extends true ? T : NarrowToArray<T>, Negated>;\n public toBeInstanceOf<Ctor extends abstract new (...args: never[]) => unknown>(\n ctor: Ctor\n ): EnsureChainInternal<Negated extends true ? T : InstanceType<Ctor>, Negated>;\n public toBeInstanceOf<Ctor extends abstract new (...args: never[]) => unknown>(\n ctor: Ctor\n ): EnsureChainInternal<\n Negated extends true\n ? T\n : Ctor extends ArrayConstructor\n ? NarrowToArray<T>\n : InstanceType<Ctor>,\n Negated\n > {\n const instance = assertToBeInstanceOf(this.createContext(), ctor);\n const next = this.state.negated ? this : this.rewrap(instance);\n return next as EnsureChainInternal<\n Negated extends true\n ? T\n : Ctor extends ArrayConstructor\n ? NarrowToArray<T>\n : InstanceType<Ctor>,\n Negated\n >;\n }\n\n public toBeObjectContaining<Shape extends Record<PropertyKey, unknown>>(\n shape: Shape\n ): EnsureChainInternal<T, Negated> {\n assertObjectContaining(this.createContext(), shape);\n return this;\n }\n\n public toBeArrayContaining(\n expected: readonly unknown[]\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, readonly unknown[]>, Negated> {\n const array = assertArrayContaining(this.createContext(), expected);\n const next = this.state.negated\n ? this\n : this.rewrap(array as Extract<T, readonly unknown[]>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, readonly unknown[]>,\n Negated\n >;\n }\n\n public toContainEqual(\n expected: unknown\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, readonly unknown[]>, Negated> {\n const array = assertContainEqual(this.createContext(), expected);\n const next = this.state.negated\n ? this\n : this.rewrap(array as Extract<T, readonly unknown[]>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, readonly unknown[]>,\n Negated\n >;\n }\n\n public toBeIterableContaining(\n expected: readonly unknown[]\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, Iterable<unknown>>, Negated> {\n const iterable = assertIterableContaining(this.createContext(), expected);\n const next = this.state.negated\n ? this\n : this.rewrap(iterable as Extract<T, Iterable<unknown>>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, Iterable<unknown>>,\n Negated\n >;\n }\n\n public toHaveLength(\n expected: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, { length: number }>, Negated> {\n assertHasLength(this.createContext(), expected);\n const next = this.state.negated\n ? this\n : this.rewrap(this.state.value as Extract<T, { length: number }>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, { length: number }> ,\n Negated\n >;\n }\n\n private createContext(): MatcherContext<T> {\n return {\n value: this.state.value,\n negated: this.state.negated,\n fail: (matcher, details) => this.fail(matcher, details),\n ...(this.state.label !== undefined ? { label: this.state.label } : {}),\n } as MatcherContext<T>;\n }\n\n private rewrap<U>(value: U): EnsureChainImpl<U, Negated> {\n const nextState = {\n value,\n negated: this.state.negated,\n ...(this.state.label !== undefined ? { label: this.state.label } : {}),\n };\n return new EnsureChainImpl<U, Negated>(\n nextState as MatcherState<U> & { negated: Negated }\n );\n }\n\n private buildEachLabel<E>(\n value: E,\n index: number,\n options: EnsureEachOptions<E>\n ): string | undefined {\n if (typeof options.label === \"function\") {\n return options.label({ index, value });\n }\n const baseLabel = options.label ?? this.state.label;\n if (!baseLabel) {\n return undefined;\n }\n return `${baseLabel} (index ${index})`;\n }\n\n private fail(matcher: string, details: FailureDetails): never {\n const errorDetails: EnsureErrorDetails = {\n matcher,\n message: details.message,\n ...(details.actual !== undefined ? { actual: details.actual } : {}),\n ...(details.expected !== undefined ? { expected: details.expected } : {}),\n ...(this.state.label !== undefined ? { receivedLabel: this.state.label } : {}),\n };\n throw new EnsureError(errorDetails);\n }\n}\n","import type { EnsureChain, EnsureOptions } from \"./ensure\";\nimport { ensure as baseEnsure } from \"./ensure\";\n\nexport type EnsureInvoker = typeof baseEnsure;\n\nexport type EnsureInvoke = <T>(value: T, options?: EnsureOptions) => EnsureChain<T>;\n\n/**\n * An ensure invoker that also exposes a stable, non-negated invoker.\n *\n * This exists to support plugin-level negation (`ensure.not.<plugin>.*`) without\n * forcing plugin authors to manually import the base ensure.\n *\n * Use `ensure.always(...)` for required-value extraction/preconditions that must\n * not be inverted by `.not`.\n */\nexport type EnsureInvokeWithAlways = EnsureInvoke & {\n readonly always: EnsureInvoke;\n};\n\nexport type EnsureFacade<World, Facets extends Record<string, unknown>> = EnsureInvoke &\n Facets & { readonly world: World; readonly not: Facets };\n\nexport type EnsureFactory<World, Facets extends Record<string, unknown>> = (\n world: World\n) => EnsureFacade<World, Facets>;\n\nexport interface AssertionPluginContext {\n readonly ensure: EnsureInvokeWithAlways;\n\n /**\n * True when this plugin facet is being invoked via plugin-level negation\n * (e.g. `ensure.not.<facet>.*`).\n *\n * Mirrors Jest's `this.isNot` matcher context flag.\n */\n readonly isNot: boolean;\n}\n\nexport type AssertionPlugin<World, Facet> = (\n context: AssertionPluginContext\n) => (world: World) => Facet;\n\ntype PluginFacetResult<World, Plugin> = Plugin extends AssertionPlugin<World, infer Facet>\n ? Facet\n : never;\ntype PluginFacets<World, Plugins extends Record<string, AssertionPlugin<World, unknown>>> = {\n readonly [Key in keyof Plugins]: PluginFacetResult<World, Plugins[Key]>;\n};\n\nexport type EnsurePluginFacets<\n World,\n Plugins extends Record<string, AssertionPlugin<World, unknown>>\n> = PluginFacets<World, Plugins>;\n\n/**\n * Assemble a world-aware ensure factory using the provided assertion plugins.\n * Each plugin receives the base ensure function and returns a facet builder that is\n * invoked with the current world instance. The resulting facets are attached to a\n * callable ensure facade, preserving the base ensure invocation signature.\n */\nexport function createEnsureFactory<\n World,\n Plugins extends Record<string, AssertionPlugin<World, unknown>>\n>(\n ensureFn: EnsureInvoke,\n plugins: Plugins\n): EnsureFactory<World, PluginFacets<World, Plugins>> {\n const withAlways = (\n invoker: EnsureInvoke,\n always: EnsureInvoke\n ): EnsureInvokeWithAlways => {\n Object.defineProperty(invoker, \"always\", {\n value: always,\n enumerable: false,\n configurable: false,\n writable: false,\n });\n return invoker as EnsureInvokeWithAlways;\n };\n\n const positiveEnsure = withAlways(ensureFn, ensureFn);\n const pluginEntries = (Object.keys(plugins) as Array<keyof Plugins>).map((key) => {\n const plugin = plugins[key];\n if (!plugin) {\n throw new Error(`Assertion plugin \"${String(key)}\" is not defined.`);\n }\n const factory = plugin({ ensure: positiveEnsure, isNot: false });\n return [key, factory] as const;\n });\n\n const negatedEnsureFn: EnsureInvoke = <T>(value: T, options?: EnsureOptions) => {\n return ensureFn(value, options).not as unknown as EnsureChain<T>;\n };\n\n const negativeEnsure = withAlways(negatedEnsureFn, ensureFn);\n\n const negativePluginEntries = (Object.keys(plugins) as Array<keyof Plugins>).map((key) => {\n const plugin = plugins[key];\n if (!plugin) {\n throw new Error(`Assertion plugin \"${String(key)}\" is not defined.`);\n }\n const factory = plugin({ ensure: negativeEnsure, isNot: true });\n return [key, factory] as const;\n });\n\n return (world) => {\n const facade = ((value: unknown, options?: EnsureOptions) => ensureFn(value, options)) as EnsureFacade<\n World,\n PluginFacets<World, Plugins>\n >;\n\n Object.defineProperty(facade, \"world\", {\n value: world,\n enumerable: false,\n configurable: false,\n writable: false,\n });\n\n for (const [key, buildFacet] of pluginEntries) {\n const facet = buildFacet(world);\n Object.defineProperty(facade, key, {\n value: facet,\n enumerable: true,\n configurable: false,\n writable: false,\n });\n }\n\n const notFacade = {};\n for (const [key, buildFacet] of negativePluginEntries) {\n const facet = buildFacet(world);\n Object.defineProperty(notFacade, key, {\n value: facet,\n enumerable: true,\n configurable: false,\n writable: false,\n });\n }\n\n Object.defineProperty(facade, \"not\", {\n value: notFacade,\n enumerable: true,\n configurable: false,\n writable: false,\n });\n\n return facade;\n };\n}\n\n/**\n * Create a default ensure factory without any plugins. Useful when consumers\n * want a world-aware ensure facade without additional facets.\n */\nexport function createDefaultEnsureFactory<World>(): EnsureFactory<World, Record<string, never>> {\n return createEnsureFactory<World, Record<string, never>>(baseEnsure, {});\n}\n","import type {\n HeaderlessTable,\n HeaderlessTableOptions,\n HorizontalTable,\n HorizontalTableOptions,\n MatrixTable,\n MatrixTableOptions,\n TableShape,\n VerticalTable,\n VerticalTableOptions,\n} from \"@autometa/gherkin\";\nimport type { RawTable, StepRuntimeHelpers, StepRuntimeMetadata } from \"@autometa/executor\";\n\nimport type { AssertionPlugin } from \"../plugins\";\n\n/**\n * Assertion facet attached as `ensure.runtime.*`.\n *\n * This facet is meant for **step-data ergonomics**:\n * - quick preconditions like “a table is present” / “a docstring is present”\n * - extracting required docstrings/tables with consistently-labeled failures\n *\n * It intentionally uses `ensure.always(...)` for required-value extraction so\n * plugin-level negation (`ensure.not.runtime.*`) does **not** invert these\n * preconditions.\n */\nexport interface RuntimeAssertions {\n /**\n * Assert that the current step has an attached data table.\n *\n * Works with plugin-level negation:\n * - `ensure.runtime.hasTable()` asserts table is present\n * - `ensure.not.runtime.hasTable()` asserts table is NOT present\n */\n hasTable(options?: { readonly label?: string }): void;\n\n /**\n * Assert that the current step has an attached docstring.\n *\n * Works with plugin-level negation:\n * - `ensure.runtime.hasDocstring()` asserts docstring is present\n * - `ensure.not.runtime.hasDocstring()` asserts docstring is NOT present\n */\n hasDocstring(options?: { readonly label?: string }): void;\n\n /**\n * Get the current step's docstring without consuming it.\n */\n docstring(): string | undefined;\n\n /**\n * Consume and return the current step's docstring.\n */\n consumeDocstring(): string | undefined;\n\n /**\n * Consume and return the current step's docstring.\n *\n * This is a *required extraction* helper. It is NOT negated under\n * `ensure.not.runtime.*`.\n */\n requireDocstring(options?: { readonly label?: string }): string;\n\n /**\n * Get the current step's data table coerced to the given shape without consuming it.\n */\n table(shape: \"headerless\", options?: HeaderlessTableOptions): HeaderlessTable | undefined;\n /** @inheritdoc */\n table(shape: \"horizontal\", options?: HorizontalTableOptions): HorizontalTable | undefined;\n /** @inheritdoc */\n table(shape: \"vertical\", options?: VerticalTableOptions): VerticalTable | undefined;\n /** @inheritdoc */\n table(shape: \"matrix\", options?: MatrixTableOptions): MatrixTable | undefined;\n /** @inheritdoc */\n table(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined;\n\n /**\n * Consume and return the current step's data table coerced to the given shape.\n */\n consumeTable(shape: \"headerless\", options?: HeaderlessTableOptions): HeaderlessTable | undefined;\n /** @inheritdoc */\n consumeTable(shape: \"horizontal\", options?: HorizontalTableOptions): HorizontalTable | undefined;\n /** @inheritdoc */\n consumeTable(shape: \"vertical\", options?: VerticalTableOptions): VerticalTable | undefined;\n /** @inheritdoc */\n consumeTable(shape: \"matrix\", options?: MatrixTableOptions): MatrixTable | undefined;\n /** @inheritdoc */\n consumeTable(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined;\n\n /**\n * Consume and return the current step's data table coerced to the given shape.\n *\n * This is a *required extraction* helper. It is NOT negated under\n * `ensure.not.runtime.*`.\n */\n requireTable(\n shape: \"headerless\",\n options?: HeaderlessTableOptions & { readonly label?: string }\n ): HeaderlessTable;\n /** @inheritdoc */\n requireTable(\n shape: \"horizontal\",\n options?: HorizontalTableOptions & { readonly label?: string }\n ): HorizontalTable;\n /** @inheritdoc */\n requireTable(\n shape: \"vertical\",\n options?: VerticalTableOptions & { readonly label?: string }\n ): VerticalTable;\n /** @inheritdoc */\n requireTable(\n shape: \"matrix\",\n options?: MatrixTableOptions & { readonly label?: string }\n ): MatrixTable;\n /** @inheritdoc */\n requireTable(\n shape: TableShape,\n options?: (\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ) & { readonly label?: string }\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable;\n\n /**\n * Return the underlying raw data table (array of string arrays) without consuming it.\n *\n * This is useful for custom table parsing or user-defined table semantics.\n */\n rawTable(): RawTable | undefined;\n\n /**\n * Consume the current step's raw data table.\n */\n consumeRawTable(options?: HeaderlessTableOptions): RawTable | undefined;\n\n /**\n * Consume and return the current step's raw data table.\n *\n * This is a *required extraction* helper. It is NOT negated under\n * `ensure.not.runtime.*`.\n */\n requireRawTable(options?: HeaderlessTableOptions & { readonly label?: string }): RawTable;\n\n /**\n * Return runtime metadata about the current feature/scenario/step, if available.\n */\n stepMetadata(): StepRuntimeMetadata | undefined;\n}\n\ntype WorldWithRuntime = {\n readonly runtime: StepRuntimeHelpers;\n};\n\n/**\n * Standard assertion plugin that provides step-runtime helpers as `ensure.runtime.*`.\n *\n * Register via the runner:\n *\n * ```ts\n * const runner = CucumberRunner.builder()\n * .assertionPlugins({ runtime: runtimeAssertionsPlugin<MyWorld>() });\n * ```\n */\nexport const runtimeAssertionsPlugin = <\n World extends WorldWithRuntime,\n>(): AssertionPlugin<World, RuntimeAssertions> =>\n ({ ensure }) =>\n (world) => {\n const defaultTableLabel = \"step data table\";\n const defaultDocstringLabel = \"step docstring\";\n\n function table(\n shape: \"headerless\",\n options?: HeaderlessTableOptions\n ): HeaderlessTable | undefined;\n function table(\n shape: \"horizontal\",\n options?: HorizontalTableOptions\n ): HorizontalTable | undefined;\n function table(\n shape: \"vertical\",\n options?: VerticalTableOptions\n ): VerticalTable | undefined;\n function table(\n shape: \"matrix\",\n options?: MatrixTableOptions\n ): MatrixTable | undefined;\n function table(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined;\n function table(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined {\n return world.runtime.getTable(shape, options as never);\n }\n\n function consumeTable(\n shape: \"headerless\",\n options?: HeaderlessTableOptions\n ): HeaderlessTable | undefined;\n function consumeTable(\n shape: \"horizontal\",\n options?: HorizontalTableOptions\n ): HorizontalTable | undefined;\n function consumeTable(\n shape: \"vertical\",\n options?: VerticalTableOptions\n ): VerticalTable | undefined;\n function consumeTable(\n shape: \"matrix\",\n options?: MatrixTableOptions\n ): MatrixTable | undefined;\n function consumeTable(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined;\n function consumeTable(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined {\n return world.runtime.consumeTable(shape, options as never);\n }\n\n function requireTable(\n shape: \"headerless\",\n options?: HeaderlessTableOptions & { readonly label?: string }\n ): HeaderlessTable;\n function requireTable(\n shape: \"horizontal\",\n options?: HorizontalTableOptions & { readonly label?: string }\n ): HorizontalTable;\n function requireTable(\n shape: \"vertical\",\n options?: VerticalTableOptions & { readonly label?: string }\n ): VerticalTable;\n function requireTable(\n shape: \"matrix\",\n options?: MatrixTableOptions & { readonly label?: string }\n ): MatrixTable;\n function requireTable(\n shape: TableShape,\n options?: (\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ) & { readonly label?: string }\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable;\n function requireTable(\n shape: TableShape,\n options?: (\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ) & { readonly label?: string }\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable {\n const { label, ...tableOptions } = (options ?? {}) as {\n readonly label?: string;\n } & (\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n );\n\n const table = consumeTable(shape, tableOptions);\n return ensure.always(table, {\n label:\n label ??\n `Expected ${shape} ${defaultTableLabel} to be attached to the current step.`,\n })\n .toBeDefined()\n .value as HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable;\n }\n\n function consumeRawTable(options?: HeaderlessTableOptions): RawTable | undefined {\n // `getRawTable()` does not consume; to consume we piggy-back on consuming a\n // headerless table.\n const tableInstance = consumeTable(\"headerless\", options);\n return tableInstance?.raw();\n }\n\n function requireRawTable(\n options?: HeaderlessTableOptions & { readonly label?: string }\n ): RawTable {\n const { label, ...tableOptions } = (options ?? {}) as {\n readonly label?: string;\n } & HeaderlessTableOptions;\n\n const raw = consumeRawTable(tableOptions);\n return ensure.always(raw, {\n label: label ?? `Expected ${defaultTableLabel} to be attached to the current step.`,\n })\n .toBeDefined()\n .value;\n }\n\n return {\n hasTable(options) {\n ensure(world.runtime.hasTable, {\n label: options?.label ?? `${defaultTableLabel} is present`,\n }).toBeTruthy();\n },\n hasDocstring(options) {\n ensure(world.runtime.hasDocstring, {\n label: options?.label ?? `${defaultDocstringLabel} is present`,\n }).toBeTruthy();\n },\n docstring() {\n return world.runtime.getDocstring();\n },\n consumeDocstring() {\n return world.runtime.consumeDocstring();\n },\n requireDocstring(options) {\n const docstring = world.runtime.consumeDocstring();\n return ensure.always(docstring, {\n label:\n options?.label ??\n `Expected ${defaultDocstringLabel} to be attached to the current step.`,\n })\n .toBeDefined()\n .value as string;\n },\n table,\n consumeTable,\n requireTable,\n rawTable() {\n return world.runtime.getRawTable();\n },\n consumeRawTable,\n requireRawTable,\n stepMetadata() {\n return world.runtime.getStepMetadata();\n },\n };\n };\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { EnsureError } from "./assertion-error";
|
|
2
|
-
export { ensure, type EnsureChain, type EnsureOptions } from "./ensure";
|
|
2
|
+
export { ensure, type EnsureChain, type EnsureEachOptions, type EnsureOptions, type EnsureTapContext, } from "./ensure";
|
|
3
3
|
export { createDefaultEnsureFactory, createEnsureFactory, type EnsurePluginFacets, type AssertionPlugin, type AssertionPluginContext, type EnsureFacade, type EnsureFactory, type EnsureInvoke, type EnsureInvokeWithAlways, type EnsureInvoker, } from "./plugins";
|
|
4
4
|
export { runtimeAssertionsPlugin, type RuntimeAssertions, } from "./plugins/runtime-assertions-plugin";
|
package/dist/index.js
CHANGED
|
@@ -495,6 +495,24 @@ function assertToBeCloseTo(ctx, expected, precision = 2) {
|
|
|
495
495
|
return actual;
|
|
496
496
|
}
|
|
497
497
|
|
|
498
|
+
// src/matchers/type-of.ts
|
|
499
|
+
function assertToBeTypeOf(ctx, expected) {
|
|
500
|
+
const actualType = typeof ctx.value;
|
|
501
|
+
const pass = actualType === expected;
|
|
502
|
+
if (ctx.negated ? pass : !pass) {
|
|
503
|
+
const baseMessage = ctx.negated ? `Expected value not to be of type ${expected}` : `Expected value to be of type ${expected}`;
|
|
504
|
+
ctx.fail("toBeTypeOf", {
|
|
505
|
+
message: buildFailureMessage("toBeTypeOf", baseMessage, {
|
|
506
|
+
expected,
|
|
507
|
+
actual: ctx.value,
|
|
508
|
+
extra: [`Received type: ${actualType}`]
|
|
509
|
+
}),
|
|
510
|
+
expected,
|
|
511
|
+
actual: ctx.value
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
498
516
|
// src/matchers/truthiness.ts
|
|
499
517
|
function assertToBeTruthy(ctx) {
|
|
500
518
|
const pass = Boolean(ctx.value);
|
|
@@ -548,6 +566,115 @@ var EnsureChainImpl = class _EnsureChainImpl {
|
|
|
548
566
|
nextState
|
|
549
567
|
);
|
|
550
568
|
}
|
|
569
|
+
tap(fn) {
|
|
570
|
+
fn(this.state.value, {
|
|
571
|
+
isNot: this.state.negated,
|
|
572
|
+
...this.state.label !== void 0 ? { label: this.state.label } : {}
|
|
573
|
+
});
|
|
574
|
+
return this;
|
|
575
|
+
}
|
|
576
|
+
map(selector, options = {}) {
|
|
577
|
+
const chain = this;
|
|
578
|
+
const current = chain.state.value;
|
|
579
|
+
if (!Array.isArray(current)) {
|
|
580
|
+
chain.fail("map", {
|
|
581
|
+
message: "Expected value to be an array in order to use ensure(...).map(...)",
|
|
582
|
+
actual: chain.state.value,
|
|
583
|
+
expected: "array"
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
const values = current;
|
|
587
|
+
const mapped = values.map(
|
|
588
|
+
(value, index, array) => selector(value, index, array)
|
|
589
|
+
);
|
|
590
|
+
const nextState = {
|
|
591
|
+
value: mapped,
|
|
592
|
+
negated: chain.state.negated,
|
|
593
|
+
...options.label !== void 0 ? { label: options.label } : chain.state.label !== void 0 ? { label: chain.state.label } : {}
|
|
594
|
+
};
|
|
595
|
+
return new _EnsureChainImpl(
|
|
596
|
+
nextState
|
|
597
|
+
);
|
|
598
|
+
}
|
|
599
|
+
each(fn, options = {}) {
|
|
600
|
+
const chain = this;
|
|
601
|
+
const current = chain.state.value;
|
|
602
|
+
if (!Array.isArray(current)) {
|
|
603
|
+
chain.fail("each", {
|
|
604
|
+
message: "Expected value to be an array in order to use ensure(...).each(...)",
|
|
605
|
+
actual: chain.state.value,
|
|
606
|
+
expected: "array"
|
|
607
|
+
});
|
|
608
|
+
}
|
|
609
|
+
const values = current;
|
|
610
|
+
for (let index = 0; index < values.length; index += 1) {
|
|
611
|
+
const element = values[index];
|
|
612
|
+
const elementLabel = chain.buildEachLabel(element, index, options);
|
|
613
|
+
const elementState = {
|
|
614
|
+
value: element,
|
|
615
|
+
negated: chain.state.negated,
|
|
616
|
+
...elementLabel !== void 0 ? { label: elementLabel } : {}
|
|
617
|
+
};
|
|
618
|
+
fn(
|
|
619
|
+
new _EnsureChainImpl(
|
|
620
|
+
elementState
|
|
621
|
+
),
|
|
622
|
+
index
|
|
623
|
+
);
|
|
624
|
+
}
|
|
625
|
+
return this;
|
|
626
|
+
}
|
|
627
|
+
pluck(key, options = {}) {
|
|
628
|
+
const chain = this;
|
|
629
|
+
const current = chain.state.value;
|
|
630
|
+
if (!Array.isArray(current)) {
|
|
631
|
+
chain.fail("pluck", {
|
|
632
|
+
message: "Expected value to be an array in order to use ensure(...).pluck(...)",
|
|
633
|
+
actual: chain.state.value,
|
|
634
|
+
expected: "array"
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
const values = current;
|
|
638
|
+
const mapped = values.map((element, index) => {
|
|
639
|
+
if (typeof element !== "object" && typeof element !== "function" || element === null) {
|
|
640
|
+
chain.fail("pluck", {
|
|
641
|
+
message: `Expected element at index ${index} to be an object in order to pluck "${String(
|
|
642
|
+
key
|
|
643
|
+
)}"`,
|
|
644
|
+
actual: element,
|
|
645
|
+
expected: "object"
|
|
646
|
+
});
|
|
647
|
+
}
|
|
648
|
+
return element[key];
|
|
649
|
+
});
|
|
650
|
+
const nextState = {
|
|
651
|
+
value: mapped,
|
|
652
|
+
negated: chain.state.negated,
|
|
653
|
+
...options.label !== void 0 ? { label: options.label } : chain.state.label !== void 0 ? { label: chain.state.label } : {}
|
|
654
|
+
};
|
|
655
|
+
return new _EnsureChainImpl(
|
|
656
|
+
nextState
|
|
657
|
+
);
|
|
658
|
+
}
|
|
659
|
+
prop(key, options = {}) {
|
|
660
|
+
const chain = this;
|
|
661
|
+
const current = chain.state.value;
|
|
662
|
+
if (typeof current !== "object" && typeof current !== "function" || current === null) {
|
|
663
|
+
chain.fail("prop", {
|
|
664
|
+
message: "Expected value to be an object in order to use ensure(...).prop(...)",
|
|
665
|
+
actual: chain.state.value,
|
|
666
|
+
expected: "object"
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
const nextState = {
|
|
670
|
+
value: current[key],
|
|
671
|
+
negated: chain.state.negated,
|
|
672
|
+
...options.label !== void 0 ? { label: options.label } : chain.state.label !== void 0 ? { label: chain.state.label } : {}
|
|
673
|
+
};
|
|
674
|
+
return new _EnsureChainImpl(
|
|
675
|
+
nextState
|
|
676
|
+
);
|
|
677
|
+
}
|
|
551
678
|
toBe(expected) {
|
|
552
679
|
assertToBe(this.createContext(), expected);
|
|
553
680
|
return this;
|
|
@@ -583,6 +710,11 @@ var EnsureChainImpl = class _EnsureChainImpl {
|
|
|
583
710
|
assertToBeFalsy(this.createContext());
|
|
584
711
|
return this;
|
|
585
712
|
}
|
|
713
|
+
toBeTypeOf(expected) {
|
|
714
|
+
assertToBeTypeOf(this.createContext(), expected);
|
|
715
|
+
const next = this.state.negated ? this : this.rewrap(this.state.value);
|
|
716
|
+
return next;
|
|
717
|
+
}
|
|
586
718
|
toBeGreaterThan(expected) {
|
|
587
719
|
const actual = assertToBeGreaterThan(this.createContext(), expected);
|
|
588
720
|
const next = this.state.negated ? this : this.rewrap(actual);
|
|
@@ -655,6 +787,16 @@ var EnsureChainImpl = class _EnsureChainImpl {
|
|
|
655
787
|
nextState
|
|
656
788
|
);
|
|
657
789
|
}
|
|
790
|
+
buildEachLabel(value, index, options) {
|
|
791
|
+
if (typeof options.label === "function") {
|
|
792
|
+
return options.label({ index, value });
|
|
793
|
+
}
|
|
794
|
+
const baseLabel = options.label ?? this.state.label;
|
|
795
|
+
if (!baseLabel) {
|
|
796
|
+
return void 0;
|
|
797
|
+
}
|
|
798
|
+
return `${baseLabel} (index ${index})`;
|
|
799
|
+
}
|
|
658
800
|
fail(matcher, details) {
|
|
659
801
|
const errorDetails = {
|
|
660
802
|
matcher,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/assertion-error.ts","../src/matchers/collections.ts","../src/core/constants.ts","../src/core/context.ts","../src/core/messages.ts","../src/core/predicates.ts","../src/matchers/equality.ts","../src/matchers/instance.ts","../src/matchers/nullish.ts","../src/matchers/numeric.ts","../src/matchers/truthiness.ts","../src/ensure.ts","../src/plugins.ts","../src/plugins/runtime-assertions-plugin.ts"],"names":["equals","ensure","table"],"mappings":"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","sourcesContent":["import { inspect } from \"node:util\";\n\nexport interface EnsureErrorDetails {\n readonly matcher: string;\n readonly message: string;\n readonly actual?: unknown;\n readonly expected?: unknown;\n readonly receivedLabel?: string;\n}\n\nexport class EnsureError extends Error {\n public readonly matcher: string;\n public readonly actual?: unknown;\n public readonly expected?: unknown;\n\n constructor(details: EnsureErrorDetails) {\n const formattedMessage = buildMessage(details);\n super(formattedMessage);\n this.name = \"EnsureError\";\n this.matcher = details.matcher;\n this.actual = details.actual;\n this.expected = details.expected;\n }\n}\n\nfunction buildMessage({ matcher, message, actual, expected, receivedLabel }: EnsureErrorDetails): string {\n const parts = [message];\n const extras: string[] = [];\n\n if (typeof expected !== \"undefined\" && !containsSection(message, \"Expected:\")) {\n extras.push(`Expected: ${formatValue(expected)}`);\n }\n\n if (typeof actual !== \"undefined\") {\n const label = receivedLabel ? `Received ${receivedLabel}` : \"Received\";\n if (!containsSection(message, `${label}:`)) {\n extras.push(`${label}: ${formatValue(actual)}`);\n }\n }\n\n if (!containsSection(message, \"Matcher:\")) {\n extras.push(`Matcher: ${matcher}`);\n }\n\n if (extras.length > 0) {\n parts.push(\"\", ...extras);\n }\n\n return parts.join(\"\\n\");\n}\n\nfunction formatValue(value: unknown): string {\n return inspect(value, { depth: 4, maxArrayLength: 10, breakLength: 60, sorted: true });\n}\n\nfunction containsSection(message: string, label: string): boolean {\n return message\n .split(\"\\n\")\n .some((line) => line.trimStart().startsWith(label));\n}\n","import { equals } from \"@jest/expect-utils\";\n\nimport { EQUALITY_TESTERS, SUBSET_TESTERS } from \"../core/constants\";\nimport { type MatcherContext, shouldFail } from \"../core/context\";\nimport { buildFailureMessage, formatDiff, formatMissingList } from \"../core/messages\";\nimport { hasLengthProperty, isIterable, isRecord } from \"../core/predicates\";\n\nexport function assertObjectContaining<T>(\n ctx: MatcherContext<T>,\n shape: Record<PropertyKey, unknown>\n): void {\n const isObject = isRecord(ctx.value);\n if (!isObject) {\n if (!ctx.negated) {\n ctx.fail(\"toBeObjectContaining\", {\n message: buildFailureMessage(\"toBeObjectContaining\", \"Expected value to be an object\", {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return;\n }\n\n const pass = equals(ctx.value, shape, SUBSET_TESTERS);\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? \"Expected object not to match the provided subset\"\n : \"Object does not match the provided subset\";\n ctx.fail(\"toBeObjectContaining\", {\n message: buildFailureMessage(\"toBeObjectContaining\", baseMessage, {\n expected: shape,\n actual: ctx.value,\n diff: formatDiff(shape, ctx.value),\n }),\n expected: shape,\n actual: ctx.value,\n });\n }\n}\n\nexport function assertArrayContaining<T>(\n ctx: MatcherContext<T>,\n expected: readonly unknown[]\n): readonly unknown[] {\n if (!Array.isArray(ctx.value)) {\n if (!ctx.negated) {\n ctx.fail(\"toBeArrayContaining\", {\n message: buildFailureMessage(\"toBeArrayContaining\", \"Expected value to be an array\", {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return ctx.value as unknown as readonly unknown[];\n }\n\n const actual = ctx.value as readonly unknown[];\n const missing = expected.filter((item) =>\n !actual.some((entry: unknown) => equals(entry, item, EQUALITY_TESTERS))\n );\n\n const pass = missing.length === 0;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? \"Expected array not to contain the provided elements\"\n : \"Array is missing expected elements\";\n ctx.fail(\"toBeArrayContaining\", {\n message: buildFailureMessage(\"toBeArrayContaining\", baseMessage, {\n expected,\n actual,\n extra: [formatMissingList(\"Missing elements:\", missing)],\n diff: formatDiff(expected, actual),\n }),\n expected,\n actual,\n });\n }\n\n return actual;\n}\n\nexport function assertContainEqual<T>(\n ctx: MatcherContext<T>,\n expected: unknown\n): readonly unknown[] {\n if (!Array.isArray(ctx.value)) {\n if (!ctx.negated) {\n ctx.fail(\"toContainEqual\", {\n message: buildFailureMessage(\"toContainEqual\", \"Expected value to be an array\", {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return ctx.value as unknown as readonly unknown[];\n }\n\n const actual = ctx.value as readonly unknown[];\n const pass = actual.some((entry: unknown) => equals(entry, expected, EQUALITY_TESTERS));\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? \"Expected array not to contain the provided element\"\n : \"Array is missing the expected element\";\n ctx.fail(\"toContainEqual\", {\n message: buildFailureMessage(\"toContainEqual\", baseMessage, {\n expected,\n actual,\n diff: formatDiff(expected, actual),\n }),\n expected,\n actual,\n });\n }\n\n return actual;\n}\n\nexport function assertIterableContaining<T>(\n ctx: MatcherContext<T>,\n expected: readonly unknown[]\n): Iterable<unknown> {\n if (!isIterable(ctx.value)) {\n if (!ctx.negated) {\n ctx.fail(\"toBeIterableContaining\", {\n message: buildFailureMessage(\"toBeIterableContaining\", \"Expected value to be iterable\", {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return ctx.value as unknown as Iterable<unknown>;\n }\n\n const entries = Array.from(ctx.value as Iterable<unknown>);\n const missing = expected.filter((item) =>\n !entries.some((entry) => equals(entry, item, EQUALITY_TESTERS))\n );\n\n const pass = missing.length === 0;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? \"Expected iterable not to contain the provided elements\"\n : \"Iterable is missing expected elements\";\n ctx.fail(\"toBeIterableContaining\", {\n message: buildFailureMessage(\"toBeIterableContaining\", baseMessage, {\n expected,\n actual: entries,\n extra: [formatMissingList(\"Missing elements:\", missing)],\n }),\n expected,\n actual: entries,\n });\n }\n\n return ctx.value as unknown as Iterable<unknown>;\n}\n\nexport function assertHasLength<T>(ctx: MatcherContext<T>, expected: number): number {\n if (!hasLengthProperty(ctx.value)) {\n if (!ctx.negated) {\n ctx.fail(\"toHaveLength\", {\n message: buildFailureMessage(\"toHaveLength\", \"Expected value to have a numeric length property\", {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return NaN;\n }\n\n const actualLength = (ctx.value as { length: number }).length;\n const pass = actualLength === expected;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected length to differ from ${expected}`\n : \"Length does not match expectation\";\n ctx.fail(\"toHaveLength\", {\n message: buildFailureMessage(\"toHaveLength\", baseMessage, {\n expected,\n actual: actualLength,\n diff: formatDiff(expected, actualLength),\n }),\n expected,\n actual: actualLength,\n });\n }\n\n return actualLength;\n}\n","import { iterableEquality, subsetEquality, type Tester } from \"@jest/expect-utils\";\n\nexport const MATCHER_CALL = \"ensure(received)\";\n\nexport const EQUALITY_TESTERS: Tester[] = [iterableEquality];\n\nexport const SUBSET_TESTERS: Tester[] = [iterableEquality, subsetEquality];\n","export interface FailureDetails {\n readonly message: string;\n readonly actual?: unknown;\n readonly expected?: unknown;\n}\n\nexport interface MatcherState<T> {\n readonly value: T;\n readonly label?: string;\n readonly negated: boolean;\n}\n\nexport interface MatcherContext<T> extends MatcherState<T> {\n fail(matcher: string, details: FailureDetails): never;\n}\n\nexport function shouldFail(pass: boolean, negated: boolean): boolean {\n return negated ? pass : !pass;\n}\n","import { diff } from \"jest-diff\";\nimport { printExpected, printReceived } from \"jest-matcher-utils\";\n\nimport { MATCHER_CALL } from \"./constants\";\n\nexport interface FailureMessageOptions {\n readonly expected?: unknown;\n readonly actual?: unknown;\n readonly diff?: string | undefined;\n readonly extra?: readonly (string | undefined)[];\n readonly actualLabel?: string;\n}\n\nexport function buildFailureMessage(\n matcher: string,\n baseMessage: string,\n options: FailureMessageOptions = {}\n): string {\n const sections: string[] = [`${MATCHER_CALL}.${matcher}(expected)`, baseMessage];\n\n if (Object.prototype.hasOwnProperty.call(options, \"expected\")) {\n sections.push(`Expected: ${printExpected(options.expected)}`);\n }\n\n if (Object.prototype.hasOwnProperty.call(options, \"actual\")) {\n const label = options.actualLabel ?? \"Received\";\n sections.push(`${label}: ${printReceived(options.actual)}`);\n }\n\n if (options.extra) {\n for (const extra of options.extra) {\n if (extra && extra.trim().length > 0) {\n sections.push(extra);\n }\n }\n }\n\n if (options.diff && options.diff.trim().length > 0) {\n sections.push(options.diff);\n }\n\n return sections.join(\"\\n\\n\");\n}\n\nexport function formatDiff(expected: unknown, actual: unknown): string | undefined {\n const difference = diff(expected, actual, { expand: false });\n return difference && difference.trim().length > 0 ? difference : undefined;\n}\n\nexport function formatMissingList(title: string, values: readonly unknown[]): string {\n if (values.length === 0) {\n return \"\";\n }\n const items = values.map((value) => ` - ${printExpected(value)}`).join(\"\\n\");\n return `${title}\\n${items}`;\n}\n","export function isRecord(candidate: unknown): candidate is Record<PropertyKey, unknown> {\n return typeof candidate === \"object\" && candidate !== null;\n}\n\nexport function isIterable(candidate: unknown): candidate is Iterable<unknown> {\n return typeof (candidate as { [Symbol.iterator]?: unknown })?.[Symbol.iterator] === \"function\";\n}\n\nexport function hasLengthProperty(candidate: unknown): candidate is { length: number } {\n return typeof (candidate as { length?: unknown })?.length === \"number\";\n}\n","import { equals } from \"@jest/expect-utils\";\n\nimport { EQUALITY_TESTERS } from \"../core/constants\";\nimport { type MatcherContext } from \"../core/context\";\nimport { buildFailureMessage, formatDiff } from \"../core/messages\";\n\nexport function assertToBe<T>(ctx: MatcherContext<T>, expected: T): void {\n const pass = Object.is(ctx.value, expected);\n if (ctx.negated ? pass : !pass) {\n const baseMessage = ctx.negated\n ? \"Expected values not to be strictly equal\"\n : \"Expected values to be strictly equal\";\n ctx.fail(\"toBe\", {\n message: buildFailureMessage(\"toBe\", baseMessage, {\n actual: ctx.value,\n expected,\n diff: formatDiff(expected, ctx.value),\n }),\n actual: ctx.value,\n expected,\n });\n }\n}\n\nexport function assertToEqual<T>(ctx: MatcherContext<T>, expected: unknown): void {\n const pass = equals(ctx.value, expected, EQUALITY_TESTERS);\n if (ctx.negated ? pass : !pass) {\n const baseMessage = ctx.negated\n ? \"Expected values not to be deeply equal\"\n : \"Expected values to be deeply equal\";\n ctx.fail(\"toEqual\", {\n message: buildFailureMessage(\"toEqual\", baseMessage, {\n actual: ctx.value,\n expected,\n diff: formatDiff(expected, ctx.value),\n }),\n actual: ctx.value,\n expected,\n });\n }\n}\n\nexport function assertToStrictEqual<T>(ctx: MatcherContext<T>, expected: unknown): void {\n const pass = equals(ctx.value, expected, EQUALITY_TESTERS, true);\n if (ctx.negated ? pass : !pass) {\n const baseMessage = ctx.negated\n ? \"Expected values not to be strictly equal (including prototypes and property definitions)\"\n : \"Expected values to be strictly equal (including prototypes and property definitions)\";\n ctx.fail(\"toStrictEqual\", {\n message: buildFailureMessage(\"toStrictEqual\", baseMessage, {\n actual: ctx.value,\n expected,\n diff: formatDiff(expected, ctx.value),\n }),\n actual: ctx.value,\n expected,\n });\n }\n}\n","import type { MatcherContext } from \"../core/context\";\nimport { buildFailureMessage } from \"../core/messages\";\n\nexport function assertToBeInstanceOf<\n T,\n Ctor extends abstract new (...args: never[]) => unknown\n>(ctx: MatcherContext<T>, ctor: Ctor): InstanceType<Ctor> {\n if (typeof ctor !== \"function\") {\n ctx.fail(\"toBeInstanceOf\", {\n message: buildFailureMessage(\"toBeInstanceOf\", \"Constructor must be a callable function\", {\n expected: ctor,\n }),\n expected: ctor,\n });\n }\n\n const pass = ctx.value instanceof ctor;\n if (ctx.negated ? pass : !pass) {\n const label = ctor.name || \"<anonymous>\";\n const baseMessage = ctx.negated\n ? `Expected value not to be an instance of ${label}`\n : `Expected value to be an instance of ${label}`;\n ctx.fail(\"toBeInstanceOf\", {\n message: buildFailureMessage(\"toBeInstanceOf\", baseMessage, {\n expected: ctor,\n actual: ctx.value,\n }),\n expected: ctor,\n actual: ctx.value,\n });\n }\n\n return ctx.value as InstanceType<Ctor>;\n}\n","import type { MatcherContext } from \"../core/context\";\nimport { buildFailureMessage } from \"../core/messages\";\n\nconst NIL_MESSAGE = \"Value is null or undefined\";\n\nexport function assertToBeDefined<T>(ctx: MatcherContext<T>): NonNullable<T> {\n const isDefined = ctx.value !== null && typeof ctx.value !== \"undefined\";\n if (ctx.negated ? isDefined : !isDefined) {\n const baseMessage = ctx.negated\n ? \"Expected value to be null or undefined\"\n : NIL_MESSAGE;\n ctx.fail(\"toBeDefined\", {\n message: buildFailureMessage(\"toBeDefined\", baseMessage, {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return ctx.value as NonNullable<T>;\n}\n\nexport function assertToBeUndefined<T>(ctx: MatcherContext<T>): undefined {\n const isUndefined = typeof ctx.value === \"undefined\";\n if (ctx.negated ? isUndefined : !isUndefined) {\n const baseMessage = ctx.negated\n ? \"Expected value not to be undefined\"\n : \"Expected value to be undefined\";\n ctx.fail(\"toBeUndefined\", {\n message: buildFailureMessage(\"toBeUndefined\", baseMessage, {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return undefined;\n}\n\nexport function assertToBeNull<T>(ctx: MatcherContext<T>): null {\n const isNull = ctx.value === null;\n if (ctx.negated ? isNull : !isNull) {\n const baseMessage = ctx.negated\n ? \"Expected value not to be null\"\n : \"Expected value to be null\";\n ctx.fail(\"toBeNull\", {\n message: buildFailureMessage(\"toBeNull\", baseMessage, {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return null;\n}\n","import type { MatcherContext } from \"../core/context\";\nimport { shouldFail } from \"../core/context\";\nimport { buildFailureMessage } from \"../core/messages\";\n\nfunction requireFiniteNumber<T>(\n ctx: MatcherContext<T>,\n matcher: string\n): number {\n const value = ctx.value;\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n ctx.fail(matcher, {\n message: buildFailureMessage(\n matcher,\n \"Expected value to be a finite number\",\n { actual: value }\n ),\n actual: value,\n expected: \"finite number\",\n });\n }\n return value;\n}\n\nfunction requireFiniteExpected(\n ctx: MatcherContext<unknown>,\n matcher: string,\n expected: number,\n name = \"expected\"\n): void {\n if (typeof expected !== \"number\" || !Number.isFinite(expected)) {\n ctx.fail(matcher, {\n message: buildFailureMessage(\n matcher,\n `Expected ${name} to be a finite number`,\n { actual: expected }\n ),\n actual: expected,\n expected: \"finite number\",\n });\n }\n}\n\nexport function assertToBeGreaterThan<T>(\n ctx: MatcherContext<T>,\n expected: number\n): number {\n const actual = requireFiniteNumber(ctx, \"toBeGreaterThan\");\n requireFiniteExpected(ctx as MatcherContext<unknown>, \"toBeGreaterThan\", expected);\n\n const pass = actual > expected;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected value not to be greater than ${expected}`\n : `Expected value to be greater than ${expected}`;\n\n ctx.fail(\"toBeGreaterThan\", {\n message: buildFailureMessage(\"toBeGreaterThan\", baseMessage, {\n expected,\n actual,\n }),\n actual,\n expected,\n });\n }\n\n return actual;\n}\n\nexport function assertToBeGreaterThanOrEqual<T>(\n ctx: MatcherContext<T>,\n expected: number\n): number {\n const actual = requireFiniteNumber(ctx, \"toBeGreaterThanOrEqual\");\n requireFiniteExpected(\n ctx as MatcherContext<unknown>,\n \"toBeGreaterThanOrEqual\",\n expected\n );\n\n const pass = actual >= expected;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected value not to be greater than or equal to ${expected}`\n : `Expected value to be greater than or equal to ${expected}`;\n\n ctx.fail(\"toBeGreaterThanOrEqual\", {\n message: buildFailureMessage(\"toBeGreaterThanOrEqual\", baseMessage, {\n expected,\n actual,\n }),\n actual,\n expected,\n });\n }\n\n return actual;\n}\n\nexport function assertToBeLessThan<T>(\n ctx: MatcherContext<T>,\n expected: number\n): number {\n const actual = requireFiniteNumber(ctx, \"toBeLessThan\");\n requireFiniteExpected(ctx as MatcherContext<unknown>, \"toBeLessThan\", expected);\n\n const pass = actual < expected;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected value not to be less than ${expected}`\n : `Expected value to be less than ${expected}`;\n\n ctx.fail(\"toBeLessThan\", {\n message: buildFailureMessage(\"toBeLessThan\", baseMessage, {\n expected,\n actual,\n }),\n actual,\n expected,\n });\n }\n\n return actual;\n}\n\nexport function assertToBeLessThanOrEqual<T>(\n ctx: MatcherContext<T>,\n expected: number\n): number {\n const actual = requireFiniteNumber(ctx, \"toBeLessThanOrEqual\");\n requireFiniteExpected(\n ctx as MatcherContext<unknown>,\n \"toBeLessThanOrEqual\",\n expected\n );\n\n const pass = actual <= expected;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected value not to be less than or equal to ${expected}`\n : `Expected value to be less than or equal to ${expected}`;\n\n ctx.fail(\"toBeLessThanOrEqual\", {\n message: buildFailureMessage(\"toBeLessThanOrEqual\", baseMessage, {\n expected,\n actual,\n }),\n actual,\n expected,\n });\n }\n\n return actual;\n}\n\nexport function assertToBeCloseTo<T>(\n ctx: MatcherContext<T>,\n expected: number,\n precision = 2\n): number {\n const actual = requireFiniteNumber(ctx, \"toBeCloseTo\");\n requireFiniteExpected(ctx as MatcherContext<unknown>, \"toBeCloseTo\", expected);\n\n if (!Number.isInteger(precision) || precision < 0 || precision > 20) {\n ctx.fail(\"toBeCloseTo\", {\n message: buildFailureMessage(\n \"toBeCloseTo\",\n \"Expected precision to be an integer between 0 and 20\",\n { actual: precision }\n ),\n actual: precision,\n expected: \"integer between 0 and 20\",\n });\n }\n\n const tolerance = Math.pow(10, -precision) / 2;\n const difference = Math.abs(actual - expected);\n // Floating-point operations can produce tiny rounding errors near the boundary.\n // We allow an EPSILON-scaled slack so values that are mathematically on the\n // boundary don't fail due to representation quirks.\n const epsilon = Number.EPSILON * Math.max(1, Math.abs(actual), Math.abs(expected)) * 2;\n const pass = difference <= tolerance + epsilon;\n\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected value not to be close to ${expected} (precision ${precision})`\n : `Expected value to be close to ${expected} (precision ${precision})`;\n\n ctx.fail(\"toBeCloseTo\", {\n message: buildFailureMessage(\"toBeCloseTo\", baseMessage, {\n expected,\n actual,\n extra: [\n `Difference: ${difference}`,\n `Tolerance: ${tolerance}`,\n ],\n }),\n actual,\n expected,\n });\n }\n\n return actual;\n}\n","import type { MatcherContext } from \"../core/context\";\nimport { buildFailureMessage } from \"../core/messages\";\n\nexport function assertToBeTruthy<T>(ctx: MatcherContext<T>): void {\n const pass = Boolean(ctx.value);\n if (ctx.negated ? pass : !pass) {\n const baseMessage = ctx.negated\n ? \"Expected value to be falsy\"\n : \"Expected value to be truthy\";\n ctx.fail(\"toBeTruthy\", {\n message: buildFailureMessage(\"toBeTruthy\", baseMessage, {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n}\n\nexport function assertToBeFalsy<T>(ctx: MatcherContext<T>): void {\n const pass = !ctx.value;\n if (ctx.negated ? pass : !pass) {\n const baseMessage = ctx.negated\n ? \"Expected value to be truthy\"\n : \"Expected value to be falsy\";\n ctx.fail(\"toBeFalsy\", {\n message: buildFailureMessage(\"toBeFalsy\", baseMessage, {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n}\n","import { EnsureError, type EnsureErrorDetails } from \"./assertion-error\";\nimport {\n type FailureDetails,\n type MatcherContext,\n type MatcherState,\n} from \"./core/context\";\nimport {\n assertArrayContaining,\n assertContainEqual,\n assertHasLength,\n assertIterableContaining,\n assertObjectContaining,\n} from \"./matchers/collections\";\nimport { assertToBe, assertToEqual, assertToStrictEqual } from \"./matchers/equality\";\nimport { assertToBeInstanceOf } from \"./matchers/instance\";\nimport {\n assertToBeDefined,\n assertToBeNull,\n assertToBeUndefined,\n} from \"./matchers/nullish\";\nimport {\n assertToBeCloseTo,\n assertToBeGreaterThan,\n assertToBeGreaterThanOrEqual,\n assertToBeLessThan,\n assertToBeLessThanOrEqual,\n} from \"./matchers/numeric\";\nimport { assertToBeFalsy, assertToBeTruthy } from \"./matchers/truthiness\";\n\nexport interface EnsureOptions {\n readonly label?: string;\n}\n\ntype Toggle<Negated extends boolean> = Negated extends true ? false : true;\n\ninterface EnsureChainInternal<T, Negated extends boolean> {\n readonly value: T;\n readonly not: EnsureChainInternal<T, Toggle<Negated>>;\n toBe(expected: T): EnsureChainInternal<T, Negated>;\n toEqual(expected: unknown): EnsureChainInternal<T, Negated>;\n toStrictEqual(expected: unknown): EnsureChainInternal<T, Negated>;\n toBeDefined(): EnsureChainInternal<Negated extends true ? T : NonNullable<T>, Negated>;\n toBeUndefined(): EnsureChainInternal<Negated extends true ? T : undefined, Negated>;\n toBeNull(): EnsureChainInternal<Negated extends true ? T : null, Negated>;\n toBeTruthy(): EnsureChainInternal<T, Negated>;\n toBeFalsy(): EnsureChainInternal<T, Negated>;\n toBeGreaterThan(expected: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n toBeGreaterThanOrEqual(expected: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n toBeLessThan(expected: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n toBeLessThanOrEqual(expected: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n toBeCloseTo(expected: number, precision?: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n toBeInstanceOf<Ctor extends abstract new (...args: never[]) => unknown>(\n ctor: Ctor\n ): EnsureChainInternal<Negated extends true ? T : InstanceType<Ctor>, Negated>;\n toBeObjectContaining<Shape extends Record<PropertyKey, unknown>>(\n shape: Shape\n ): EnsureChainInternal<T, Negated>;\n toBeArrayContaining(expected: readonly unknown[]): EnsureChainInternal<\n Negated extends true ? T : Extract<T, readonly unknown[]>,\n Negated\n >;\n toContainEqual(expected: unknown): EnsureChainInternal<\n Negated extends true ? T : Extract<T, readonly unknown[]>,\n Negated\n >;\n toBeIterableContaining(expected: readonly unknown[]): EnsureChainInternal<\n Negated extends true ? T : Extract<T, Iterable<unknown>>,\n Negated\n >;\n toHaveLength(expected: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, { length: number }> ,\n Negated\n >;\n}\n\nexport type EnsureChain<T> = EnsureChainInternal<T, false>;\nexport type EnsureNegatedChain<T> = EnsureChainInternal<T, true>;\n\nexport function ensure<T>(value: T, options: EnsureOptions = {}): EnsureChain<T> {\n const state = {\n value,\n negated: false as const,\n ...(options.label !== undefined ? { label: options.label } : {}),\n } satisfies MatcherState<T> & { negated: false };\n return new EnsureChainImpl<T, false>(state);\n}\n\nclass EnsureChainImpl<T, Negated extends boolean>\n implements EnsureChainInternal<T, Negated> {\n private readonly state: MatcherState<T> & { negated: Negated };\n\n constructor(state: MatcherState<T> & { negated: Negated }) {\n this.state = state;\n }\n\n public get value(): T {\n return this.state.value;\n }\n\n public get not(): EnsureChainInternal<T, Toggle<Negated>> {\n const toggled = (!this.state.negated) as Toggle<Negated>;\n const nextState = {\n value: this.state.value,\n negated: toggled,\n ...(this.state.label !== undefined ? { label: this.state.label } : {}),\n };\n return new EnsureChainImpl<T, Toggle<Negated>>(\n nextState as MatcherState<T> & { negated: Toggle<Negated> }\n );\n }\n\n public toBe(expected: T): EnsureChainInternal<T, Negated> {\n assertToBe(this.createContext(), expected);\n return this;\n }\n\n public toEqual(expected: unknown): EnsureChainInternal<T, Negated> {\n assertToEqual(this.createContext(), expected);\n return this;\n }\n\n public toStrictEqual(expected: unknown): EnsureChainInternal<T, Negated> {\n assertToStrictEqual(this.createContext(), expected);\n return this;\n }\n\n public toBeDefined(): EnsureChainInternal<Negated extends true ? T : NonNullable<T>, Negated> {\n const defined = assertToBeDefined(this.createContext());\n const next = this.state.negated ? this : this.rewrap(defined);\n return next as EnsureChainInternal<Negated extends true ? T : NonNullable<T>, Negated>;\n }\n\n public toBeUndefined(): EnsureChainInternal<Negated extends true ? T : undefined, Negated> {\n const result = assertToBeUndefined(this.createContext());\n const next = this.state.negated ? this : this.rewrap(result);\n return next as EnsureChainInternal<Negated extends true ? T : undefined, Negated>;\n }\n\n public toBeNull(): EnsureChainInternal<Negated extends true ? T : null, Negated> {\n const result = assertToBeNull(this.createContext());\n const next = this.state.negated ? this : this.rewrap(result);\n return next as EnsureChainInternal<Negated extends true ? T : null, Negated>;\n }\n\n public toBeTruthy(): EnsureChainInternal<T, Negated> {\n assertToBeTruthy(this.createContext());\n return this;\n }\n\n public toBeFalsy(): EnsureChainInternal<T, Negated> {\n assertToBeFalsy(this.createContext());\n return this;\n }\n\n public toBeGreaterThan(\n expected: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated> {\n const actual = assertToBeGreaterThan(this.createContext(), expected);\n const next = this.state.negated ? this : this.rewrap(actual as Extract<T, number>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n }\n\n public toBeGreaterThanOrEqual(\n expected: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated> {\n const actual = assertToBeGreaterThanOrEqual(this.createContext(), expected);\n const next = this.state.negated ? this : this.rewrap(actual as Extract<T, number>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n }\n\n public toBeLessThan(\n expected: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated> {\n const actual = assertToBeLessThan(this.createContext(), expected);\n const next = this.state.negated ? this : this.rewrap(actual as Extract<T, number>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n }\n\n public toBeLessThanOrEqual(\n expected: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated> {\n const actual = assertToBeLessThanOrEqual(this.createContext(), expected);\n const next = this.state.negated ? this : this.rewrap(actual as Extract<T, number>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n }\n\n public toBeCloseTo(\n expected: number,\n precision?: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated> {\n const actual = assertToBeCloseTo(this.createContext(), expected, precision);\n const next = this.state.negated ? this : this.rewrap(actual as Extract<T, number>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n }\n\n public toBeInstanceOf<Ctor extends abstract new (...args: never[]) => unknown>(\n ctor: Ctor\n ): EnsureChainInternal<Negated extends true ? T : InstanceType<Ctor>, Negated> {\n const instance = assertToBeInstanceOf(this.createContext(), ctor);\n const next = this.state.negated ? this : this.rewrap(instance);\n return next as EnsureChainInternal<Negated extends true ? T : InstanceType<Ctor>, Negated>;\n }\n\n public toBeObjectContaining<Shape extends Record<PropertyKey, unknown>>(\n shape: Shape\n ): EnsureChainInternal<T, Negated> {\n assertObjectContaining(this.createContext(), shape);\n return this;\n }\n\n public toBeArrayContaining(\n expected: readonly unknown[]\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, readonly unknown[]>, Negated> {\n const array = assertArrayContaining(this.createContext(), expected);\n const next = this.state.negated\n ? this\n : this.rewrap(array as Extract<T, readonly unknown[]>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, readonly unknown[]>,\n Negated\n >;\n }\n\n public toContainEqual(\n expected: unknown\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, readonly unknown[]>, Negated> {\n const array = assertContainEqual(this.createContext(), expected);\n const next = this.state.negated\n ? this\n : this.rewrap(array as Extract<T, readonly unknown[]>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, readonly unknown[]>,\n Negated\n >;\n }\n\n public toBeIterableContaining(\n expected: readonly unknown[]\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, Iterable<unknown>>, Negated> {\n const iterable = assertIterableContaining(this.createContext(), expected);\n const next = this.state.negated\n ? this\n : this.rewrap(iterable as Extract<T, Iterable<unknown>>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, Iterable<unknown>>,\n Negated\n >;\n }\n\n public toHaveLength(\n expected: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, { length: number }>, Negated> {\n assertHasLength(this.createContext(), expected);\n const next = this.state.negated\n ? this\n : this.rewrap(this.state.value as Extract<T, { length: number }>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, { length: number }> ,\n Negated\n >;\n }\n\n private createContext(): MatcherContext<T> {\n return {\n value: this.state.value,\n negated: this.state.negated,\n fail: (matcher, details) => this.fail(matcher, details),\n ...(this.state.label !== undefined ? { label: this.state.label } : {}),\n } as MatcherContext<T>;\n }\n\n private rewrap<U>(value: U): EnsureChainImpl<U, Negated> {\n const nextState = {\n value,\n negated: this.state.negated,\n ...(this.state.label !== undefined ? { label: this.state.label } : {}),\n };\n return new EnsureChainImpl<U, Negated>(\n nextState as MatcherState<U> & { negated: Negated }\n );\n }\n\n private fail(matcher: string, details: FailureDetails): never {\n const errorDetails: EnsureErrorDetails = {\n matcher,\n message: details.message,\n ...(details.actual !== undefined ? { actual: details.actual } : {}),\n ...(details.expected !== undefined ? { expected: details.expected } : {}),\n ...(this.state.label !== undefined ? { receivedLabel: this.state.label } : {}),\n };\n throw new EnsureError(errorDetails);\n }\n}\n","import type { EnsureChain, EnsureOptions } from \"./ensure\";\nimport { ensure as baseEnsure } from \"./ensure\";\n\nexport type EnsureInvoker = typeof baseEnsure;\n\nexport type EnsureInvoke = <T>(value: T, options?: EnsureOptions) => EnsureChain<T>;\n\n/**\n * An ensure invoker that also exposes a stable, non-negated invoker.\n *\n * This exists to support plugin-level negation (`ensure.not.<plugin>.*`) without\n * forcing plugin authors to manually import the base ensure.\n *\n * Use `ensure.always(...)` for required-value extraction/preconditions that must\n * not be inverted by `.not`.\n */\nexport type EnsureInvokeWithAlways = EnsureInvoke & {\n readonly always: EnsureInvoke;\n};\n\nexport type EnsureFacade<World, Facets extends Record<string, unknown>> = EnsureInvoke &\n Facets & { readonly world: World; readonly not: Facets };\n\nexport type EnsureFactory<World, Facets extends Record<string, unknown>> = (\n world: World\n) => EnsureFacade<World, Facets>;\n\nexport interface AssertionPluginContext {\n readonly ensure: EnsureInvokeWithAlways;\n\n /**\n * True when this plugin facet is being invoked via plugin-level negation\n * (e.g. `ensure.not.<facet>.*`).\n *\n * Mirrors Jest's `this.isNot` matcher context flag.\n */\n readonly isNot: boolean;\n}\n\nexport type AssertionPlugin<World, Facet> = (\n context: AssertionPluginContext\n) => (world: World) => Facet;\n\ntype PluginFacetResult<World, Plugin> = Plugin extends AssertionPlugin<World, infer Facet>\n ? Facet\n : never;\ntype PluginFacets<World, Plugins extends Record<string, AssertionPlugin<World, unknown>>> = {\n readonly [Key in keyof Plugins]: PluginFacetResult<World, Plugins[Key]>;\n};\n\nexport type EnsurePluginFacets<\n World,\n Plugins extends Record<string, AssertionPlugin<World, unknown>>\n> = PluginFacets<World, Plugins>;\n\n/**\n * Assemble a world-aware ensure factory using the provided assertion plugins.\n * Each plugin receives the base ensure function and returns a facet builder that is\n * invoked with the current world instance. The resulting facets are attached to a\n * callable ensure facade, preserving the base ensure invocation signature.\n */\nexport function createEnsureFactory<\n World,\n Plugins extends Record<string, AssertionPlugin<World, unknown>>\n>(\n ensureFn: EnsureInvoke,\n plugins: Plugins\n): EnsureFactory<World, PluginFacets<World, Plugins>> {\n const withAlways = (\n invoker: EnsureInvoke,\n always: EnsureInvoke\n ): EnsureInvokeWithAlways => {\n Object.defineProperty(invoker, \"always\", {\n value: always,\n enumerable: false,\n configurable: false,\n writable: false,\n });\n return invoker as EnsureInvokeWithAlways;\n };\n\n const positiveEnsure = withAlways(ensureFn, ensureFn);\n const pluginEntries = (Object.keys(plugins) as Array<keyof Plugins>).map((key) => {\n const plugin = plugins[key];\n if (!plugin) {\n throw new Error(`Assertion plugin \"${String(key)}\" is not defined.`);\n }\n const factory = plugin({ ensure: positiveEnsure, isNot: false });\n return [key, factory] as const;\n });\n\n const negatedEnsureFn: EnsureInvoke = <T>(value: T, options?: EnsureOptions) => {\n return ensureFn(value, options).not as unknown as EnsureChain<T>;\n };\n\n const negativeEnsure = withAlways(negatedEnsureFn, ensureFn);\n\n const negativePluginEntries = (Object.keys(plugins) as Array<keyof Plugins>).map((key) => {\n const plugin = plugins[key];\n if (!plugin) {\n throw new Error(`Assertion plugin \"${String(key)}\" is not defined.`);\n }\n const factory = plugin({ ensure: negativeEnsure, isNot: true });\n return [key, factory] as const;\n });\n\n return (world) => {\n const facade = ((value: unknown, options?: EnsureOptions) => ensureFn(value, options)) as EnsureFacade<\n World,\n PluginFacets<World, Plugins>\n >;\n\n Object.defineProperty(facade, \"world\", {\n value: world,\n enumerable: false,\n configurable: false,\n writable: false,\n });\n\n for (const [key, buildFacet] of pluginEntries) {\n const facet = buildFacet(world);\n Object.defineProperty(facade, key, {\n value: facet,\n enumerable: true,\n configurable: false,\n writable: false,\n });\n }\n\n const notFacade = {};\n for (const [key, buildFacet] of negativePluginEntries) {\n const facet = buildFacet(world);\n Object.defineProperty(notFacade, key, {\n value: facet,\n enumerable: true,\n configurable: false,\n writable: false,\n });\n }\n\n Object.defineProperty(facade, \"not\", {\n value: notFacade,\n enumerable: true,\n configurable: false,\n writable: false,\n });\n\n return facade;\n };\n}\n\n/**\n * Create a default ensure factory without any plugins. Useful when consumers\n * want a world-aware ensure facade without additional facets.\n */\nexport function createDefaultEnsureFactory<World>(): EnsureFactory<World, Record<string, never>> {\n return createEnsureFactory<World, Record<string, never>>(baseEnsure, {});\n}\n","import type {\n HeaderlessTable,\n HeaderlessTableOptions,\n HorizontalTable,\n HorizontalTableOptions,\n MatrixTable,\n MatrixTableOptions,\n TableShape,\n VerticalTable,\n VerticalTableOptions,\n} from \"@autometa/gherkin\";\nimport type { RawTable, StepRuntimeHelpers, StepRuntimeMetadata } from \"@autometa/executor\";\n\nimport type { AssertionPlugin } from \"../plugins\";\n\n/**\n * Assertion facet attached as `ensure.runtime.*`.\n *\n * This facet is meant for **step-data ergonomics**:\n * - quick preconditions like “a table is present” / “a docstring is present”\n * - extracting required docstrings/tables with consistently-labeled failures\n *\n * It intentionally uses `ensure.always(...)` for required-value extraction so\n * plugin-level negation (`ensure.not.runtime.*`) does **not** invert these\n * preconditions.\n */\nexport interface RuntimeAssertions {\n /**\n * Assert that the current step has an attached data table.\n *\n * Works with plugin-level negation:\n * - `ensure.runtime.hasTable()` asserts table is present\n * - `ensure.not.runtime.hasTable()` asserts table is NOT present\n */\n hasTable(options?: { readonly label?: string }): void;\n\n /**\n * Assert that the current step has an attached docstring.\n *\n * Works with plugin-level negation:\n * - `ensure.runtime.hasDocstring()` asserts docstring is present\n * - `ensure.not.runtime.hasDocstring()` asserts docstring is NOT present\n */\n hasDocstring(options?: { readonly label?: string }): void;\n\n /**\n * Get the current step's docstring without consuming it.\n */\n docstring(): string | undefined;\n\n /**\n * Consume and return the current step's docstring.\n */\n consumeDocstring(): string | undefined;\n\n /**\n * Consume and return the current step's docstring.\n *\n * This is a *required extraction* helper. It is NOT negated under\n * `ensure.not.runtime.*`.\n */\n requireDocstring(options?: { readonly label?: string }): string;\n\n /**\n * Get the current step's data table coerced to the given shape without consuming it.\n */\n table(shape: \"headerless\", options?: HeaderlessTableOptions): HeaderlessTable | undefined;\n /** @inheritdoc */\n table(shape: \"horizontal\", options?: HorizontalTableOptions): HorizontalTable | undefined;\n /** @inheritdoc */\n table(shape: \"vertical\", options?: VerticalTableOptions): VerticalTable | undefined;\n /** @inheritdoc */\n table(shape: \"matrix\", options?: MatrixTableOptions): MatrixTable | undefined;\n /** @inheritdoc */\n table(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined;\n\n /**\n * Consume and return the current step's data table coerced to the given shape.\n */\n consumeTable(shape: \"headerless\", options?: HeaderlessTableOptions): HeaderlessTable | undefined;\n /** @inheritdoc */\n consumeTable(shape: \"horizontal\", options?: HorizontalTableOptions): HorizontalTable | undefined;\n /** @inheritdoc */\n consumeTable(shape: \"vertical\", options?: VerticalTableOptions): VerticalTable | undefined;\n /** @inheritdoc */\n consumeTable(shape: \"matrix\", options?: MatrixTableOptions): MatrixTable | undefined;\n /** @inheritdoc */\n consumeTable(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined;\n\n /**\n * Consume and return the current step's data table coerced to the given shape.\n *\n * This is a *required extraction* helper. It is NOT negated under\n * `ensure.not.runtime.*`.\n */\n requireTable(\n shape: \"headerless\",\n options?: HeaderlessTableOptions & { readonly label?: string }\n ): HeaderlessTable;\n /** @inheritdoc */\n requireTable(\n shape: \"horizontal\",\n options?: HorizontalTableOptions & { readonly label?: string }\n ): HorizontalTable;\n /** @inheritdoc */\n requireTable(\n shape: \"vertical\",\n options?: VerticalTableOptions & { readonly label?: string }\n ): VerticalTable;\n /** @inheritdoc */\n requireTable(\n shape: \"matrix\",\n options?: MatrixTableOptions & { readonly label?: string }\n ): MatrixTable;\n /** @inheritdoc */\n requireTable(\n shape: TableShape,\n options?: (\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ) & { readonly label?: string }\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable;\n\n /**\n * Return the underlying raw data table (array of string arrays) without consuming it.\n *\n * This is useful for custom table parsing or user-defined table semantics.\n */\n rawTable(): RawTable | undefined;\n\n /**\n * Consume the current step's raw data table.\n */\n consumeRawTable(options?: HeaderlessTableOptions): RawTable | undefined;\n\n /**\n * Consume and return the current step's raw data table.\n *\n * This is a *required extraction* helper. It is NOT negated under\n * `ensure.not.runtime.*`.\n */\n requireRawTable(options?: HeaderlessTableOptions & { readonly label?: string }): RawTable;\n\n /**\n * Return runtime metadata about the current feature/scenario/step, if available.\n */\n stepMetadata(): StepRuntimeMetadata | undefined;\n}\n\ntype WorldWithRuntime = {\n readonly runtime: StepRuntimeHelpers;\n};\n\n/**\n * Standard assertion plugin that provides step-runtime helpers as `ensure.runtime.*`.\n *\n * Register via the runner:\n *\n * ```ts\n * const runner = CucumberRunner.builder()\n * .assertionPlugins({ runtime: runtimeAssertionsPlugin<MyWorld>() });\n * ```\n */\nexport const runtimeAssertionsPlugin = <\n World extends WorldWithRuntime,\n>(): AssertionPlugin<World, RuntimeAssertions> =>\n ({ ensure }) =>\n (world) => {\n const defaultTableLabel = \"step data table\";\n const defaultDocstringLabel = \"step docstring\";\n\n function table(\n shape: \"headerless\",\n options?: HeaderlessTableOptions\n ): HeaderlessTable | undefined;\n function table(\n shape: \"horizontal\",\n options?: HorizontalTableOptions\n ): HorizontalTable | undefined;\n function table(\n shape: \"vertical\",\n options?: VerticalTableOptions\n ): VerticalTable | undefined;\n function table(\n shape: \"matrix\",\n options?: MatrixTableOptions\n ): MatrixTable | undefined;\n function table(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined;\n function table(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined {\n return world.runtime.getTable(shape, options as never);\n }\n\n function consumeTable(\n shape: \"headerless\",\n options?: HeaderlessTableOptions\n ): HeaderlessTable | undefined;\n function consumeTable(\n shape: \"horizontal\",\n options?: HorizontalTableOptions\n ): HorizontalTable | undefined;\n function consumeTable(\n shape: \"vertical\",\n options?: VerticalTableOptions\n ): VerticalTable | undefined;\n function consumeTable(\n shape: \"matrix\",\n options?: MatrixTableOptions\n ): MatrixTable | undefined;\n function consumeTable(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined;\n function consumeTable(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined {\n return world.runtime.consumeTable(shape, options as never);\n }\n\n function requireTable(\n shape: \"headerless\",\n options?: HeaderlessTableOptions & { readonly label?: string }\n ): HeaderlessTable;\n function requireTable(\n shape: \"horizontal\",\n options?: HorizontalTableOptions & { readonly label?: string }\n ): HorizontalTable;\n function requireTable(\n shape: \"vertical\",\n options?: VerticalTableOptions & { readonly label?: string }\n ): VerticalTable;\n function requireTable(\n shape: \"matrix\",\n options?: MatrixTableOptions & { readonly label?: string }\n ): MatrixTable;\n function requireTable(\n shape: TableShape,\n options?: (\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ) & { readonly label?: string }\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable;\n function requireTable(\n shape: TableShape,\n options?: (\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ) & { readonly label?: string }\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable {\n const { label, ...tableOptions } = (options ?? {}) as {\n readonly label?: string;\n } & (\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n );\n\n const table = consumeTable(shape, tableOptions);\n return ensure.always(table, {\n label:\n label ??\n `Expected ${shape} ${defaultTableLabel} to be attached to the current step.`,\n })\n .toBeDefined()\n .value as HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable;\n }\n\n function consumeRawTable(options?: HeaderlessTableOptions): RawTable | undefined {\n // `getRawTable()` does not consume; to consume we piggy-back on consuming a\n // headerless table.\n const tableInstance = consumeTable(\"headerless\", options);\n return tableInstance?.raw();\n }\n\n function requireRawTable(\n options?: HeaderlessTableOptions & { readonly label?: string }\n ): RawTable {\n const { label, ...tableOptions } = (options ?? {}) as {\n readonly label?: string;\n } & HeaderlessTableOptions;\n\n const raw = consumeRawTable(tableOptions);\n return ensure.always(raw, {\n label: label ?? `Expected ${defaultTableLabel} to be attached to the current step.`,\n })\n .toBeDefined()\n .value;\n }\n\n return {\n hasTable(options) {\n ensure(world.runtime.hasTable, {\n label: options?.label ?? `${defaultTableLabel} is present`,\n }).toBeTruthy();\n },\n hasDocstring(options) {\n ensure(world.runtime.hasDocstring, {\n label: options?.label ?? `${defaultDocstringLabel} is present`,\n }).toBeTruthy();\n },\n docstring() {\n return world.runtime.getDocstring();\n },\n consumeDocstring() {\n return world.runtime.consumeDocstring();\n },\n requireDocstring(options) {\n const docstring = world.runtime.consumeDocstring();\n return ensure.always(docstring, {\n label:\n options?.label ??\n `Expected ${defaultDocstringLabel} to be attached to the current step.`,\n })\n .toBeDefined()\n .value as string;\n },\n table,\n consumeTable,\n requireTable,\n rawTable() {\n return world.runtime.getRawTable();\n },\n consumeRawTable,\n requireRawTable,\n stepMetadata() {\n return world.runtime.getStepMetadata();\n },\n };\n };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/assertion-error.ts","../src/matchers/collections.ts","../src/core/constants.ts","../src/core/context.ts","../src/core/messages.ts","../src/core/predicates.ts","../src/matchers/equality.ts","../src/matchers/instance.ts","../src/matchers/nullish.ts","../src/matchers/numeric.ts","../src/matchers/type-of.ts","../src/matchers/truthiness.ts","../src/ensure.ts","../src/plugins.ts","../src/plugins/runtime-assertions-plugin.ts"],"names":["equals","ensure","table"],"mappings":"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","sourcesContent":["import { inspect } from \"node:util\";\n\nexport interface EnsureErrorDetails {\n readonly matcher: string;\n readonly message: string;\n readonly actual?: unknown;\n readonly expected?: unknown;\n readonly receivedLabel?: string;\n}\n\nexport class EnsureError extends Error {\n public readonly matcher: string;\n public readonly actual?: unknown;\n public readonly expected?: unknown;\n\n constructor(details: EnsureErrorDetails) {\n const formattedMessage = buildMessage(details);\n super(formattedMessage);\n this.name = \"EnsureError\";\n this.matcher = details.matcher;\n this.actual = details.actual;\n this.expected = details.expected;\n }\n}\n\nfunction buildMessage({ matcher, message, actual, expected, receivedLabel }: EnsureErrorDetails): string {\n const parts = [message];\n const extras: string[] = [];\n\n if (typeof expected !== \"undefined\" && !containsSection(message, \"Expected:\")) {\n extras.push(`Expected: ${formatValue(expected)}`);\n }\n\n if (typeof actual !== \"undefined\") {\n const label = receivedLabel ? `Received ${receivedLabel}` : \"Received\";\n if (!containsSection(message, `${label}:`)) {\n extras.push(`${label}: ${formatValue(actual)}`);\n }\n }\n\n if (!containsSection(message, \"Matcher:\")) {\n extras.push(`Matcher: ${matcher}`);\n }\n\n if (extras.length > 0) {\n parts.push(\"\", ...extras);\n }\n\n return parts.join(\"\\n\");\n}\n\nfunction formatValue(value: unknown): string {\n return inspect(value, { depth: 4, maxArrayLength: 10, breakLength: 60, sorted: true });\n}\n\nfunction containsSection(message: string, label: string): boolean {\n return message\n .split(\"\\n\")\n .some((line) => line.trimStart().startsWith(label));\n}\n","import { equals } from \"@jest/expect-utils\";\n\nimport { EQUALITY_TESTERS, SUBSET_TESTERS } from \"../core/constants\";\nimport { type MatcherContext, shouldFail } from \"../core/context\";\nimport { buildFailureMessage, formatDiff, formatMissingList } from \"../core/messages\";\nimport { hasLengthProperty, isIterable, isRecord } from \"../core/predicates\";\n\nexport function assertObjectContaining<T>(\n ctx: MatcherContext<T>,\n shape: Record<PropertyKey, unknown>\n): void {\n const isObject = isRecord(ctx.value);\n if (!isObject) {\n if (!ctx.negated) {\n ctx.fail(\"toBeObjectContaining\", {\n message: buildFailureMessage(\"toBeObjectContaining\", \"Expected value to be an object\", {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return;\n }\n\n const pass = equals(ctx.value, shape, SUBSET_TESTERS);\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? \"Expected object not to match the provided subset\"\n : \"Object does not match the provided subset\";\n ctx.fail(\"toBeObjectContaining\", {\n message: buildFailureMessage(\"toBeObjectContaining\", baseMessage, {\n expected: shape,\n actual: ctx.value,\n diff: formatDiff(shape, ctx.value),\n }),\n expected: shape,\n actual: ctx.value,\n });\n }\n}\n\nexport function assertArrayContaining<T>(\n ctx: MatcherContext<T>,\n expected: readonly unknown[]\n): readonly unknown[] {\n if (!Array.isArray(ctx.value)) {\n if (!ctx.negated) {\n ctx.fail(\"toBeArrayContaining\", {\n message: buildFailureMessage(\"toBeArrayContaining\", \"Expected value to be an array\", {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return ctx.value as unknown as readonly unknown[];\n }\n\n const actual = ctx.value as readonly unknown[];\n const missing = expected.filter((item) =>\n !actual.some((entry: unknown) => equals(entry, item, EQUALITY_TESTERS))\n );\n\n const pass = missing.length === 0;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? \"Expected array not to contain the provided elements\"\n : \"Array is missing expected elements\";\n ctx.fail(\"toBeArrayContaining\", {\n message: buildFailureMessage(\"toBeArrayContaining\", baseMessage, {\n expected,\n actual,\n extra: [formatMissingList(\"Missing elements:\", missing)],\n diff: formatDiff(expected, actual),\n }),\n expected,\n actual,\n });\n }\n\n return actual;\n}\n\nexport function assertContainEqual<T>(\n ctx: MatcherContext<T>,\n expected: unknown\n): readonly unknown[] {\n if (!Array.isArray(ctx.value)) {\n if (!ctx.negated) {\n ctx.fail(\"toContainEqual\", {\n message: buildFailureMessage(\"toContainEqual\", \"Expected value to be an array\", {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return ctx.value as unknown as readonly unknown[];\n }\n\n const actual = ctx.value as readonly unknown[];\n const pass = actual.some((entry: unknown) => equals(entry, expected, EQUALITY_TESTERS));\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? \"Expected array not to contain the provided element\"\n : \"Array is missing the expected element\";\n ctx.fail(\"toContainEqual\", {\n message: buildFailureMessage(\"toContainEqual\", baseMessage, {\n expected,\n actual,\n diff: formatDiff(expected, actual),\n }),\n expected,\n actual,\n });\n }\n\n return actual;\n}\n\nexport function assertIterableContaining<T>(\n ctx: MatcherContext<T>,\n expected: readonly unknown[]\n): Iterable<unknown> {\n if (!isIterable(ctx.value)) {\n if (!ctx.negated) {\n ctx.fail(\"toBeIterableContaining\", {\n message: buildFailureMessage(\"toBeIterableContaining\", \"Expected value to be iterable\", {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return ctx.value as unknown as Iterable<unknown>;\n }\n\n const entries = Array.from(ctx.value as Iterable<unknown>);\n const missing = expected.filter((item) =>\n !entries.some((entry) => equals(entry, item, EQUALITY_TESTERS))\n );\n\n const pass = missing.length === 0;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? \"Expected iterable not to contain the provided elements\"\n : \"Iterable is missing expected elements\";\n ctx.fail(\"toBeIterableContaining\", {\n message: buildFailureMessage(\"toBeIterableContaining\", baseMessage, {\n expected,\n actual: entries,\n extra: [formatMissingList(\"Missing elements:\", missing)],\n }),\n expected,\n actual: entries,\n });\n }\n\n return ctx.value as unknown as Iterable<unknown>;\n}\n\nexport function assertHasLength<T>(ctx: MatcherContext<T>, expected: number): number {\n if (!hasLengthProperty(ctx.value)) {\n if (!ctx.negated) {\n ctx.fail(\"toHaveLength\", {\n message: buildFailureMessage(\"toHaveLength\", \"Expected value to have a numeric length property\", {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return NaN;\n }\n\n const actualLength = (ctx.value as { length: number }).length;\n const pass = actualLength === expected;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected length to differ from ${expected}`\n : \"Length does not match expectation\";\n ctx.fail(\"toHaveLength\", {\n message: buildFailureMessage(\"toHaveLength\", baseMessage, {\n expected,\n actual: actualLength,\n diff: formatDiff(expected, actualLength),\n }),\n expected,\n actual: actualLength,\n });\n }\n\n return actualLength;\n}\n","import { iterableEquality, subsetEquality, type Tester } from \"@jest/expect-utils\";\n\nexport const MATCHER_CALL = \"ensure(received)\";\n\nexport const EQUALITY_TESTERS: Tester[] = [iterableEquality];\n\nexport const SUBSET_TESTERS: Tester[] = [iterableEquality, subsetEquality];\n","export interface FailureDetails {\n readonly message: string;\n readonly actual?: unknown;\n readonly expected?: unknown;\n}\n\nexport interface MatcherState<T> {\n readonly value: T;\n readonly label?: string;\n readonly negated: boolean;\n}\n\nexport interface MatcherContext<T> extends MatcherState<T> {\n fail(matcher: string, details: FailureDetails): never;\n}\n\nexport function shouldFail(pass: boolean, negated: boolean): boolean {\n return negated ? pass : !pass;\n}\n","import { diff } from \"jest-diff\";\nimport { printExpected, printReceived } from \"jest-matcher-utils\";\n\nimport { MATCHER_CALL } from \"./constants\";\n\nexport interface FailureMessageOptions {\n readonly expected?: unknown;\n readonly actual?: unknown;\n readonly diff?: string | undefined;\n readonly extra?: readonly (string | undefined)[];\n readonly actualLabel?: string;\n}\n\nexport function buildFailureMessage(\n matcher: string,\n baseMessage: string,\n options: FailureMessageOptions = {}\n): string {\n const sections: string[] = [`${MATCHER_CALL}.${matcher}(expected)`, baseMessage];\n\n if (Object.prototype.hasOwnProperty.call(options, \"expected\")) {\n sections.push(`Expected: ${printExpected(options.expected)}`);\n }\n\n if (Object.prototype.hasOwnProperty.call(options, \"actual\")) {\n const label = options.actualLabel ?? \"Received\";\n sections.push(`${label}: ${printReceived(options.actual)}`);\n }\n\n if (options.extra) {\n for (const extra of options.extra) {\n if (extra && extra.trim().length > 0) {\n sections.push(extra);\n }\n }\n }\n\n if (options.diff && options.diff.trim().length > 0) {\n sections.push(options.diff);\n }\n\n return sections.join(\"\\n\\n\");\n}\n\nexport function formatDiff(expected: unknown, actual: unknown): string | undefined {\n const difference = diff(expected, actual, { expand: false });\n return difference && difference.trim().length > 0 ? difference : undefined;\n}\n\nexport function formatMissingList(title: string, values: readonly unknown[]): string {\n if (values.length === 0) {\n return \"\";\n }\n const items = values.map((value) => ` - ${printExpected(value)}`).join(\"\\n\");\n return `${title}\\n${items}`;\n}\n","export function isRecord(candidate: unknown): candidate is Record<PropertyKey, unknown> {\n return typeof candidate === \"object\" && candidate !== null;\n}\n\nexport function isIterable(candidate: unknown): candidate is Iterable<unknown> {\n return typeof (candidate as { [Symbol.iterator]?: unknown })?.[Symbol.iterator] === \"function\";\n}\n\nexport function hasLengthProperty(candidate: unknown): candidate is { length: number } {\n return typeof (candidate as { length?: unknown })?.length === \"number\";\n}\n","import { equals } from \"@jest/expect-utils\";\n\nimport { EQUALITY_TESTERS } from \"../core/constants\";\nimport { type MatcherContext } from \"../core/context\";\nimport { buildFailureMessage, formatDiff } from \"../core/messages\";\n\nexport function assertToBe<T>(ctx: MatcherContext<T>, expected: T): void {\n const pass = Object.is(ctx.value, expected);\n if (ctx.negated ? pass : !pass) {\n const baseMessage = ctx.negated\n ? \"Expected values not to be strictly equal\"\n : \"Expected values to be strictly equal\";\n ctx.fail(\"toBe\", {\n message: buildFailureMessage(\"toBe\", baseMessage, {\n actual: ctx.value,\n expected,\n diff: formatDiff(expected, ctx.value),\n }),\n actual: ctx.value,\n expected,\n });\n }\n}\n\nexport function assertToEqual<T>(ctx: MatcherContext<T>, expected: unknown): void {\n const pass = equals(ctx.value, expected, EQUALITY_TESTERS);\n if (ctx.negated ? pass : !pass) {\n const baseMessage = ctx.negated\n ? \"Expected values not to be deeply equal\"\n : \"Expected values to be deeply equal\";\n ctx.fail(\"toEqual\", {\n message: buildFailureMessage(\"toEqual\", baseMessage, {\n actual: ctx.value,\n expected,\n diff: formatDiff(expected, ctx.value),\n }),\n actual: ctx.value,\n expected,\n });\n }\n}\n\nexport function assertToStrictEqual<T>(ctx: MatcherContext<T>, expected: unknown): void {\n const pass = equals(ctx.value, expected, EQUALITY_TESTERS, true);\n if (ctx.negated ? pass : !pass) {\n const baseMessage = ctx.negated\n ? \"Expected values not to be strictly equal (including prototypes and property definitions)\"\n : \"Expected values to be strictly equal (including prototypes and property definitions)\";\n ctx.fail(\"toStrictEqual\", {\n message: buildFailureMessage(\"toStrictEqual\", baseMessage, {\n actual: ctx.value,\n expected,\n diff: formatDiff(expected, ctx.value),\n }),\n actual: ctx.value,\n expected,\n });\n }\n}\n","import type { MatcherContext } from \"../core/context\";\nimport { buildFailureMessage } from \"../core/messages\";\n\nexport function assertToBeInstanceOf<\n T,\n Ctor extends abstract new (...args: never[]) => unknown\n>(ctx: MatcherContext<T>, ctor: Ctor): InstanceType<Ctor> {\n if (typeof ctor !== \"function\") {\n ctx.fail(\"toBeInstanceOf\", {\n message: buildFailureMessage(\"toBeInstanceOf\", \"Constructor must be a callable function\", {\n expected: ctor,\n }),\n expected: ctor,\n });\n }\n\n const pass = ctx.value instanceof ctor;\n if (ctx.negated ? pass : !pass) {\n const label = ctor.name || \"<anonymous>\";\n const baseMessage = ctx.negated\n ? `Expected value not to be an instance of ${label}`\n : `Expected value to be an instance of ${label}`;\n ctx.fail(\"toBeInstanceOf\", {\n message: buildFailureMessage(\"toBeInstanceOf\", baseMessage, {\n expected: ctor,\n actual: ctx.value,\n }),\n expected: ctor,\n actual: ctx.value,\n });\n }\n\n return ctx.value as InstanceType<Ctor>;\n}\n","import type { MatcherContext } from \"../core/context\";\nimport { buildFailureMessage } from \"../core/messages\";\n\nconst NIL_MESSAGE = \"Value is null or undefined\";\n\nexport function assertToBeDefined<T>(ctx: MatcherContext<T>): NonNullable<T> {\n const isDefined = ctx.value !== null && typeof ctx.value !== \"undefined\";\n if (ctx.negated ? isDefined : !isDefined) {\n const baseMessage = ctx.negated\n ? \"Expected value to be null or undefined\"\n : NIL_MESSAGE;\n ctx.fail(\"toBeDefined\", {\n message: buildFailureMessage(\"toBeDefined\", baseMessage, {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return ctx.value as NonNullable<T>;\n}\n\nexport function assertToBeUndefined<T>(ctx: MatcherContext<T>): undefined {\n const isUndefined = typeof ctx.value === \"undefined\";\n if (ctx.negated ? isUndefined : !isUndefined) {\n const baseMessage = ctx.negated\n ? \"Expected value not to be undefined\"\n : \"Expected value to be undefined\";\n ctx.fail(\"toBeUndefined\", {\n message: buildFailureMessage(\"toBeUndefined\", baseMessage, {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return undefined;\n}\n\nexport function assertToBeNull<T>(ctx: MatcherContext<T>): null {\n const isNull = ctx.value === null;\n if (ctx.negated ? isNull : !isNull) {\n const baseMessage = ctx.negated\n ? \"Expected value not to be null\"\n : \"Expected value to be null\";\n ctx.fail(\"toBeNull\", {\n message: buildFailureMessage(\"toBeNull\", baseMessage, {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n return null;\n}\n","import type { MatcherContext } from \"../core/context\";\nimport { shouldFail } from \"../core/context\";\nimport { buildFailureMessage } from \"../core/messages\";\n\nfunction requireFiniteNumber<T>(\n ctx: MatcherContext<T>,\n matcher: string\n): number {\n const value = ctx.value;\n if (typeof value !== \"number\" || !Number.isFinite(value)) {\n ctx.fail(matcher, {\n message: buildFailureMessage(\n matcher,\n \"Expected value to be a finite number\",\n { actual: value }\n ),\n actual: value,\n expected: \"finite number\",\n });\n }\n return value;\n}\n\nfunction requireFiniteExpected(\n ctx: MatcherContext<unknown>,\n matcher: string,\n expected: number,\n name = \"expected\"\n): void {\n if (typeof expected !== \"number\" || !Number.isFinite(expected)) {\n ctx.fail(matcher, {\n message: buildFailureMessage(\n matcher,\n `Expected ${name} to be a finite number`,\n { actual: expected }\n ),\n actual: expected,\n expected: \"finite number\",\n });\n }\n}\n\nexport function assertToBeGreaterThan<T>(\n ctx: MatcherContext<T>,\n expected: number\n): number {\n const actual = requireFiniteNumber(ctx, \"toBeGreaterThan\");\n requireFiniteExpected(ctx as MatcherContext<unknown>, \"toBeGreaterThan\", expected);\n\n const pass = actual > expected;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected value not to be greater than ${expected}`\n : `Expected value to be greater than ${expected}`;\n\n ctx.fail(\"toBeGreaterThan\", {\n message: buildFailureMessage(\"toBeGreaterThan\", baseMessage, {\n expected,\n actual,\n }),\n actual,\n expected,\n });\n }\n\n return actual;\n}\n\nexport function assertToBeGreaterThanOrEqual<T>(\n ctx: MatcherContext<T>,\n expected: number\n): number {\n const actual = requireFiniteNumber(ctx, \"toBeGreaterThanOrEqual\");\n requireFiniteExpected(\n ctx as MatcherContext<unknown>,\n \"toBeGreaterThanOrEqual\",\n expected\n );\n\n const pass = actual >= expected;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected value not to be greater than or equal to ${expected}`\n : `Expected value to be greater than or equal to ${expected}`;\n\n ctx.fail(\"toBeGreaterThanOrEqual\", {\n message: buildFailureMessage(\"toBeGreaterThanOrEqual\", baseMessage, {\n expected,\n actual,\n }),\n actual,\n expected,\n });\n }\n\n return actual;\n}\n\nexport function assertToBeLessThan<T>(\n ctx: MatcherContext<T>,\n expected: number\n): number {\n const actual = requireFiniteNumber(ctx, \"toBeLessThan\");\n requireFiniteExpected(ctx as MatcherContext<unknown>, \"toBeLessThan\", expected);\n\n const pass = actual < expected;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected value not to be less than ${expected}`\n : `Expected value to be less than ${expected}`;\n\n ctx.fail(\"toBeLessThan\", {\n message: buildFailureMessage(\"toBeLessThan\", baseMessage, {\n expected,\n actual,\n }),\n actual,\n expected,\n });\n }\n\n return actual;\n}\n\nexport function assertToBeLessThanOrEqual<T>(\n ctx: MatcherContext<T>,\n expected: number\n): number {\n const actual = requireFiniteNumber(ctx, \"toBeLessThanOrEqual\");\n requireFiniteExpected(\n ctx as MatcherContext<unknown>,\n \"toBeLessThanOrEqual\",\n expected\n );\n\n const pass = actual <= expected;\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected value not to be less than or equal to ${expected}`\n : `Expected value to be less than or equal to ${expected}`;\n\n ctx.fail(\"toBeLessThanOrEqual\", {\n message: buildFailureMessage(\"toBeLessThanOrEqual\", baseMessage, {\n expected,\n actual,\n }),\n actual,\n expected,\n });\n }\n\n return actual;\n}\n\nexport function assertToBeCloseTo<T>(\n ctx: MatcherContext<T>,\n expected: number,\n precision = 2\n): number {\n const actual = requireFiniteNumber(ctx, \"toBeCloseTo\");\n requireFiniteExpected(ctx as MatcherContext<unknown>, \"toBeCloseTo\", expected);\n\n if (!Number.isInteger(precision) || precision < 0 || precision > 20) {\n ctx.fail(\"toBeCloseTo\", {\n message: buildFailureMessage(\n \"toBeCloseTo\",\n \"Expected precision to be an integer between 0 and 20\",\n { actual: precision }\n ),\n actual: precision,\n expected: \"integer between 0 and 20\",\n });\n }\n\n const tolerance = Math.pow(10, -precision) / 2;\n const difference = Math.abs(actual - expected);\n // Floating-point operations can produce tiny rounding errors near the boundary.\n // We allow an EPSILON-scaled slack so values that are mathematically on the\n // boundary don't fail due to representation quirks.\n const epsilon = Number.EPSILON * Math.max(1, Math.abs(actual), Math.abs(expected)) * 2;\n const pass = difference <= tolerance + epsilon;\n\n if (shouldFail(pass, ctx.negated)) {\n const baseMessage = ctx.negated\n ? `Expected value not to be close to ${expected} (precision ${precision})`\n : `Expected value to be close to ${expected} (precision ${precision})`;\n\n ctx.fail(\"toBeCloseTo\", {\n message: buildFailureMessage(\"toBeCloseTo\", baseMessage, {\n expected,\n actual,\n extra: [\n `Difference: ${difference}`,\n `Tolerance: ${tolerance}`,\n ],\n }),\n actual,\n expected,\n });\n }\n\n return actual;\n}\n","import type { MatcherContext } from \"../core/context\";\nimport { buildFailureMessage } from \"../core/messages\";\n\ntype EnsureTypeOf =\n | \"string\"\n | \"number\"\n | \"boolean\"\n | \"bigint\"\n | \"symbol\"\n | \"undefined\"\n | \"object\"\n | \"function\";\n\nexport function assertToBeTypeOf<T>(ctx: MatcherContext<T>, expected: EnsureTypeOf): void {\n const actualType = typeof ctx.value;\n const pass = actualType === expected;\n\n if (ctx.negated ? pass : !pass) {\n const baseMessage = ctx.negated\n ? `Expected value not to be of type ${expected}`\n : `Expected value to be of type ${expected}`;\n ctx.fail(\"toBeTypeOf\", {\n message: buildFailureMessage(\"toBeTypeOf\", baseMessage, {\n expected,\n actual: ctx.value,\n extra: [`Received type: ${actualType}`],\n }),\n expected,\n actual: ctx.value,\n });\n }\n}\n\n","import type { MatcherContext } from \"../core/context\";\nimport { buildFailureMessage } from \"../core/messages\";\n\nexport function assertToBeTruthy<T>(ctx: MatcherContext<T>): void {\n const pass = Boolean(ctx.value);\n if (ctx.negated ? pass : !pass) {\n const baseMessage = ctx.negated\n ? \"Expected value to be falsy\"\n : \"Expected value to be truthy\";\n ctx.fail(\"toBeTruthy\", {\n message: buildFailureMessage(\"toBeTruthy\", baseMessage, {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n}\n\nexport function assertToBeFalsy<T>(ctx: MatcherContext<T>): void {\n const pass = !ctx.value;\n if (ctx.negated ? pass : !pass) {\n const baseMessage = ctx.negated\n ? \"Expected value to be truthy\"\n : \"Expected value to be falsy\";\n ctx.fail(\"toBeFalsy\", {\n message: buildFailureMessage(\"toBeFalsy\", baseMessage, {\n actual: ctx.value,\n }),\n actual: ctx.value,\n });\n }\n}\n","import { EnsureError, type EnsureErrorDetails } from \"./assertion-error\";\nimport {\n type FailureDetails,\n type MatcherContext,\n type MatcherState,\n} from \"./core/context\";\nimport {\n assertArrayContaining,\n assertContainEqual,\n assertHasLength,\n assertIterableContaining,\n assertObjectContaining,\n} from \"./matchers/collections\";\nimport { assertToBe, assertToEqual, assertToStrictEqual } from \"./matchers/equality\";\nimport { assertToBeInstanceOf } from \"./matchers/instance\";\nimport {\n assertToBeDefined,\n assertToBeNull,\n assertToBeUndefined,\n} from \"./matchers/nullish\";\nimport {\n assertToBeCloseTo,\n assertToBeGreaterThan,\n assertToBeGreaterThanOrEqual,\n assertToBeLessThan,\n assertToBeLessThanOrEqual,\n} from \"./matchers/numeric\";\nimport { assertToBeTypeOf } from \"./matchers/type-of\";\nimport { assertToBeFalsy, assertToBeTruthy } from \"./matchers/truthiness\";\n\nexport interface EnsureOptions {\n readonly label?: string;\n}\n\nexport interface EnsureEachOptions<T> {\n readonly label?: string | ((details: { readonly index: number; readonly value: T }) => string);\n}\n\nexport interface EnsureTapContext<Negated extends boolean> {\n readonly isNot: Negated;\n readonly label?: string;\n}\n\ntype EnsureTypeOf =\n | \"string\"\n | \"number\"\n | \"boolean\"\n | \"bigint\"\n | \"symbol\"\n | \"undefined\"\n | \"object\"\n | \"function\";\n\ntype TypeOfResult<T extends EnsureTypeOf> = T extends \"string\"\n ? string\n : T extends \"number\"\n ? number\n : T extends \"boolean\"\n ? boolean\n : T extends \"bigint\"\n ? bigint\n : T extends \"symbol\"\n ? symbol\n : T extends \"undefined\"\n ? undefined\n : T extends \"function\"\n ? (...args: never[]) => unknown\n : T extends \"object\"\n ? object | null\n : never;\n\ntype NarrowByTypeOf<T, Expected extends EnsureTypeOf> = [\n Extract<T, TypeOfResult<Expected>>,\n] extends [never]\n ? TypeOfResult<Expected>\n : Extract<T, TypeOfResult<Expected>>;\n\ntype NarrowToArray<T> = [Extract<T, readonly unknown[]>] extends [never]\n ? readonly unknown[]\n : Extract<T, readonly unknown[]>;\n\ntype Toggle<Negated extends boolean> = Negated extends true ? false : true;\n\ninterface EnsureChainInternal<T, Negated extends boolean> {\n readonly value: T;\n readonly not: EnsureChainInternal<T, Toggle<Negated>>;\n tap(\n fn: (value: T, context: EnsureTapContext<Negated>) => void\n ): EnsureChainInternal<T, Negated>;\n map<U, Arr extends readonly unknown[]>(\n this: EnsureChainInternal<Arr, Negated>,\n selector: (value: Arr[number], index: number, array: Arr) => U,\n options?: EnsureOptions\n ): EnsureChainInternal<U[], Negated>;\n each<Arr extends readonly unknown[]>(\n this: EnsureChainInternal<Arr, Negated>,\n fn: (value: EnsureChainInternal<Arr[number], Negated>, index: number) => void,\n options?: EnsureEachOptions<Arr[number]>\n ): EnsureChainInternal<Arr, Negated>;\n pluck<Arr extends readonly object[], K extends keyof Arr[number]>(\n this: EnsureChainInternal<Arr, Negated>,\n key: K,\n options?: EnsureOptions\n ): EnsureChainInternal<Array<Arr[number][K]>, Negated>;\n prop<Obj extends object, K extends keyof Obj>(\n this: EnsureChainInternal<Obj, Negated>,\n key: K,\n options?: EnsureOptions\n ): EnsureChainInternal<Obj[K], Negated>;\n toBeTypeOf<Expected extends EnsureTypeOf>(\n expected: Expected\n ): EnsureChainInternal<Negated extends true ? T : NarrowByTypeOf<T, Expected>, Negated>;\n toBe(expected: T): EnsureChainInternal<T, Negated>;\n toEqual(expected: unknown): EnsureChainInternal<T, Negated>;\n toStrictEqual(expected: unknown): EnsureChainInternal<T, Negated>;\n toBeDefined(): EnsureChainInternal<Negated extends true ? T : NonNullable<T>, Negated>;\n toBeUndefined(): EnsureChainInternal<Negated extends true ? T : undefined, Negated>;\n toBeNull(): EnsureChainInternal<Negated extends true ? T : null, Negated>;\n toBeTruthy(): EnsureChainInternal<T, Negated>;\n toBeFalsy(): EnsureChainInternal<T, Negated>;\n toBeGreaterThan(expected: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n toBeGreaterThanOrEqual(expected: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n toBeLessThan(expected: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n toBeLessThanOrEqual(expected: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n toBeCloseTo(expected: number, precision?: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n toBeInstanceOf(\n ctor: ArrayConstructor\n ): EnsureChainInternal<Negated extends true ? T : NarrowToArray<T>, Negated>;\n toBeInstanceOf<Ctor extends abstract new (...args: never[]) => unknown>(\n ctor: Ctor\n ): EnsureChainInternal<Negated extends true ? T : InstanceType<Ctor>, Negated>;\n toBeObjectContaining<Shape extends Record<PropertyKey, unknown>>(\n shape: Shape\n ): EnsureChainInternal<T, Negated>;\n toBeArrayContaining(expected: readonly unknown[]): EnsureChainInternal<\n Negated extends true ? T : Extract<T, readonly unknown[]>,\n Negated\n >;\n toContainEqual(expected: unknown): EnsureChainInternal<\n Negated extends true ? T : Extract<T, readonly unknown[]>,\n Negated\n >;\n toBeIterableContaining(expected: readonly unknown[]): EnsureChainInternal<\n Negated extends true ? T : Extract<T, Iterable<unknown>>,\n Negated\n >;\n toHaveLength(expected: number): EnsureChainInternal<\n Negated extends true ? T : Extract<T, { length: number }> ,\n Negated\n >;\n}\n\nexport type EnsureChain<T> = EnsureChainInternal<T, false>;\nexport type EnsureNegatedChain<T> = EnsureChainInternal<T, true>;\n\nexport function ensure<T>(value: T, options: EnsureOptions = {}): EnsureChain<T> {\n const state = {\n value,\n negated: false as const,\n ...(options.label !== undefined ? { label: options.label } : {}),\n } satisfies MatcherState<T> & { negated: false };\n return new EnsureChainImpl<T, false>(state);\n}\n\nclass EnsureChainImpl<T, Negated extends boolean>\n implements EnsureChainInternal<T, Negated> {\n private readonly state: MatcherState<T> & { negated: Negated };\n\n constructor(state: MatcherState<T> & { negated: Negated }) {\n this.state = state;\n }\n\n public get value(): T {\n return this.state.value;\n }\n\n public get not(): EnsureChainInternal<T, Toggle<Negated>> {\n const toggled = (!this.state.negated) as Toggle<Negated>;\n const nextState = {\n value: this.state.value,\n negated: toggled,\n ...(this.state.label !== undefined ? { label: this.state.label } : {}),\n };\n return new EnsureChainImpl<T, Toggle<Negated>>(\n nextState as MatcherState<T> & { negated: Toggle<Negated> }\n );\n }\n\n public tap(\n fn: (value: T, context: EnsureTapContext<Negated>) => void\n ): EnsureChainInternal<T, Negated> {\n fn(this.state.value, {\n isNot: this.state.negated,\n ...(this.state.label !== undefined ? { label: this.state.label } : {}),\n });\n return this;\n }\n\n public map<U, Arr extends readonly unknown[]>(\n this: EnsureChainInternal<Arr, Negated>,\n selector: (value: Arr[number], index: number, array: Arr) => U,\n options: EnsureOptions = {}\n ): EnsureChainInternal<U[], Negated> {\n const chain = this as unknown as EnsureChainImpl<Arr, Negated>;\n const current = chain.state.value as unknown;\n if (!Array.isArray(current)) {\n chain.fail(\"map\", {\n message: \"Expected value to be an array in order to use ensure(...).map(...)\",\n actual: chain.state.value,\n expected: \"array\",\n });\n }\n\n const values = current as unknown as Arr;\n const mapped = values.map((value, index, array) =>\n selector(value as Arr[number], index, array as Arr)\n );\n const nextState = {\n value: mapped,\n negated: chain.state.negated,\n ...(options.label !== undefined\n ? { label: options.label }\n : chain.state.label !== undefined\n ? { label: chain.state.label }\n : {}),\n };\n return new EnsureChainImpl<U[], Negated>(\n nextState as MatcherState<U[]> & { negated: Negated }\n );\n }\n\n public each<Arr extends readonly unknown[]>(\n this: EnsureChainInternal<Arr, Negated>,\n fn: (value: EnsureChainInternal<Arr[number], Negated>, index: number) => void,\n options: EnsureEachOptions<Arr[number]> = {}\n ): EnsureChainInternal<Arr, Negated> {\n const chain = this as unknown as EnsureChainImpl<Arr, Negated>;\n const current = chain.state.value as unknown;\n if (!Array.isArray(current)) {\n chain.fail(\"each\", {\n message: \"Expected value to be an array in order to use ensure(...).each(...)\",\n actual: chain.state.value,\n expected: \"array\",\n });\n }\n\n const values = current as unknown as Arr;\n for (let index = 0; index < values.length; index += 1) {\n const element = values[index] as Arr[number];\n const elementLabel = chain.buildEachLabel(element, index, options);\n const elementState = {\n value: element,\n negated: chain.state.negated,\n ...(elementLabel !== undefined ? { label: elementLabel } : {}),\n };\n fn(\n new EnsureChainImpl<Arr[number], Negated>(\n elementState as MatcherState<Arr[number]> & { negated: Negated }\n ),\n index\n );\n }\n\n return this;\n }\n\n public pluck<Arr extends readonly object[], K extends keyof Arr[number]>(\n this: EnsureChainInternal<Arr, Negated>,\n key: K,\n options: EnsureOptions = {}\n ): EnsureChainInternal<Array<Arr[number][K]>, Negated> {\n const chain = this as unknown as EnsureChainImpl<Arr, Negated>;\n const current = chain.state.value as unknown;\n if (!Array.isArray(current)) {\n chain.fail(\"pluck\", {\n message: \"Expected value to be an array in order to use ensure(...).pluck(...)\",\n actual: chain.state.value,\n expected: \"array\",\n });\n }\n\n const values = current as unknown as Arr;\n const mapped = values.map((element, index) => {\n if ((typeof element !== \"object\" && typeof element !== \"function\") || element === null) {\n chain.fail(\"pluck\", {\n message: `Expected element at index ${index} to be an object in order to pluck \"${String(\n key\n )}\"`,\n actual: element,\n expected: \"object\",\n });\n }\n return (element as Arr[number])[key] as Arr[number][K];\n });\n\n const nextState = {\n value: mapped,\n negated: chain.state.negated,\n ...(options.label !== undefined\n ? { label: options.label }\n : chain.state.label !== undefined\n ? { label: chain.state.label }\n : {}),\n };\n return new EnsureChainImpl<Array<Arr[number][K]>, Negated>(\n nextState as MatcherState<Array<Arr[number][K]>> & { negated: Negated }\n );\n }\n\n public prop<Obj extends object, K extends keyof Obj>(\n this: EnsureChainInternal<Obj, Negated>,\n key: K,\n options: EnsureOptions = {}\n ): EnsureChainInternal<Obj[K], Negated> {\n const chain = this as unknown as EnsureChainImpl<Obj, Negated>;\n const current = chain.state.value as unknown;\n if ((typeof current !== \"object\" && typeof current !== \"function\") || current === null) {\n chain.fail(\"prop\", {\n message: \"Expected value to be an object in order to use ensure(...).prop(...)\",\n actual: chain.state.value,\n expected: \"object\",\n });\n }\n\n const nextState = {\n value: (current as Obj)[key],\n negated: chain.state.negated,\n ...(options.label !== undefined\n ? { label: options.label }\n : chain.state.label !== undefined\n ? { label: chain.state.label }\n : {}),\n };\n return new EnsureChainImpl<Obj[K], Negated>(\n nextState as MatcherState<Obj[K]> & { negated: Negated }\n );\n }\n\n public toBe(expected: T): EnsureChainInternal<T, Negated> {\n assertToBe(this.createContext(), expected);\n return this;\n }\n\n public toEqual(expected: unknown): EnsureChainInternal<T, Negated> {\n assertToEqual(this.createContext(), expected);\n return this;\n }\n\n public toStrictEqual(expected: unknown): EnsureChainInternal<T, Negated> {\n assertToStrictEqual(this.createContext(), expected);\n return this;\n }\n\n public toBeDefined(): EnsureChainInternal<Negated extends true ? T : NonNullable<T>, Negated> {\n const defined = assertToBeDefined(this.createContext());\n const next = this.state.negated ? this : this.rewrap(defined);\n return next as EnsureChainInternal<Negated extends true ? T : NonNullable<T>, Negated>;\n }\n\n public toBeUndefined(): EnsureChainInternal<Negated extends true ? T : undefined, Negated> {\n const result = assertToBeUndefined(this.createContext());\n const next = this.state.negated ? this : this.rewrap(result);\n return next as EnsureChainInternal<Negated extends true ? T : undefined, Negated>;\n }\n\n public toBeNull(): EnsureChainInternal<Negated extends true ? T : null, Negated> {\n const result = assertToBeNull(this.createContext());\n const next = this.state.negated ? this : this.rewrap(result);\n return next as EnsureChainInternal<Negated extends true ? T : null, Negated>;\n }\n\n public toBeTruthy(): EnsureChainInternal<T, Negated> {\n assertToBeTruthy(this.createContext());\n return this;\n }\n\n public toBeFalsy(): EnsureChainInternal<T, Negated> {\n assertToBeFalsy(this.createContext());\n return this;\n }\n\n public toBeTypeOf<Expected extends EnsureTypeOf>(\n expected: Expected\n ): EnsureChainInternal<Negated extends true ? T : NarrowByTypeOf<T, Expected>, Negated> {\n assertToBeTypeOf(this.createContext(), expected);\n const next = this.state.negated\n ? this\n : this.rewrap(this.state.value as unknown as NarrowByTypeOf<T, Expected>);\n return next as EnsureChainInternal<\n Negated extends true ? T : NarrowByTypeOf<T, Expected>,\n Negated\n >;\n }\n\n public toBeGreaterThan(\n expected: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated> {\n const actual = assertToBeGreaterThan(this.createContext(), expected);\n const next = this.state.negated ? this : this.rewrap(actual as Extract<T, number>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n }\n\n public toBeGreaterThanOrEqual(\n expected: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated> {\n const actual = assertToBeGreaterThanOrEqual(this.createContext(), expected);\n const next = this.state.negated ? this : this.rewrap(actual as Extract<T, number>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n }\n\n public toBeLessThan(\n expected: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated> {\n const actual = assertToBeLessThan(this.createContext(), expected);\n const next = this.state.negated ? this : this.rewrap(actual as Extract<T, number>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n }\n\n public toBeLessThanOrEqual(\n expected: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated> {\n const actual = assertToBeLessThanOrEqual(this.createContext(), expected);\n const next = this.state.negated ? this : this.rewrap(actual as Extract<T, number>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n }\n\n public toBeCloseTo(\n expected: number,\n precision?: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, number>, Negated> {\n const actual = assertToBeCloseTo(this.createContext(), expected, precision);\n const next = this.state.negated ? this : this.rewrap(actual as Extract<T, number>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, number>,\n Negated\n >;\n }\n\n public toBeInstanceOf(\n ctor: ArrayConstructor\n ): EnsureChainInternal<Negated extends true ? T : NarrowToArray<T>, Negated>;\n public toBeInstanceOf<Ctor extends abstract new (...args: never[]) => unknown>(\n ctor: Ctor\n ): EnsureChainInternal<Negated extends true ? T : InstanceType<Ctor>, Negated>;\n public toBeInstanceOf<Ctor extends abstract new (...args: never[]) => unknown>(\n ctor: Ctor\n ): EnsureChainInternal<\n Negated extends true\n ? T\n : Ctor extends ArrayConstructor\n ? NarrowToArray<T>\n : InstanceType<Ctor>,\n Negated\n > {\n const instance = assertToBeInstanceOf(this.createContext(), ctor);\n const next = this.state.negated ? this : this.rewrap(instance);\n return next as EnsureChainInternal<\n Negated extends true\n ? T\n : Ctor extends ArrayConstructor\n ? NarrowToArray<T>\n : InstanceType<Ctor>,\n Negated\n >;\n }\n\n public toBeObjectContaining<Shape extends Record<PropertyKey, unknown>>(\n shape: Shape\n ): EnsureChainInternal<T, Negated> {\n assertObjectContaining(this.createContext(), shape);\n return this;\n }\n\n public toBeArrayContaining(\n expected: readonly unknown[]\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, readonly unknown[]>, Negated> {\n const array = assertArrayContaining(this.createContext(), expected);\n const next = this.state.negated\n ? this\n : this.rewrap(array as Extract<T, readonly unknown[]>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, readonly unknown[]>,\n Negated\n >;\n }\n\n public toContainEqual(\n expected: unknown\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, readonly unknown[]>, Negated> {\n const array = assertContainEqual(this.createContext(), expected);\n const next = this.state.negated\n ? this\n : this.rewrap(array as Extract<T, readonly unknown[]>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, readonly unknown[]>,\n Negated\n >;\n }\n\n public toBeIterableContaining(\n expected: readonly unknown[]\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, Iterable<unknown>>, Negated> {\n const iterable = assertIterableContaining(this.createContext(), expected);\n const next = this.state.negated\n ? this\n : this.rewrap(iterable as Extract<T, Iterable<unknown>>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, Iterable<unknown>>,\n Negated\n >;\n }\n\n public toHaveLength(\n expected: number\n ): EnsureChainInternal<Negated extends true ? T : Extract<T, { length: number }>, Negated> {\n assertHasLength(this.createContext(), expected);\n const next = this.state.negated\n ? this\n : this.rewrap(this.state.value as Extract<T, { length: number }>);\n return next as EnsureChainInternal<\n Negated extends true ? T : Extract<T, { length: number }> ,\n Negated\n >;\n }\n\n private createContext(): MatcherContext<T> {\n return {\n value: this.state.value,\n negated: this.state.negated,\n fail: (matcher, details) => this.fail(matcher, details),\n ...(this.state.label !== undefined ? { label: this.state.label } : {}),\n } as MatcherContext<T>;\n }\n\n private rewrap<U>(value: U): EnsureChainImpl<U, Negated> {\n const nextState = {\n value,\n negated: this.state.negated,\n ...(this.state.label !== undefined ? { label: this.state.label } : {}),\n };\n return new EnsureChainImpl<U, Negated>(\n nextState as MatcherState<U> & { negated: Negated }\n );\n }\n\n private buildEachLabel<E>(\n value: E,\n index: number,\n options: EnsureEachOptions<E>\n ): string | undefined {\n if (typeof options.label === \"function\") {\n return options.label({ index, value });\n }\n const baseLabel = options.label ?? this.state.label;\n if (!baseLabel) {\n return undefined;\n }\n return `${baseLabel} (index ${index})`;\n }\n\n private fail(matcher: string, details: FailureDetails): never {\n const errorDetails: EnsureErrorDetails = {\n matcher,\n message: details.message,\n ...(details.actual !== undefined ? { actual: details.actual } : {}),\n ...(details.expected !== undefined ? { expected: details.expected } : {}),\n ...(this.state.label !== undefined ? { receivedLabel: this.state.label } : {}),\n };\n throw new EnsureError(errorDetails);\n }\n}\n","import type { EnsureChain, EnsureOptions } from \"./ensure\";\nimport { ensure as baseEnsure } from \"./ensure\";\n\nexport type EnsureInvoker = typeof baseEnsure;\n\nexport type EnsureInvoke = <T>(value: T, options?: EnsureOptions) => EnsureChain<T>;\n\n/**\n * An ensure invoker that also exposes a stable, non-negated invoker.\n *\n * This exists to support plugin-level negation (`ensure.not.<plugin>.*`) without\n * forcing plugin authors to manually import the base ensure.\n *\n * Use `ensure.always(...)` for required-value extraction/preconditions that must\n * not be inverted by `.not`.\n */\nexport type EnsureInvokeWithAlways = EnsureInvoke & {\n readonly always: EnsureInvoke;\n};\n\nexport type EnsureFacade<World, Facets extends Record<string, unknown>> = EnsureInvoke &\n Facets & { readonly world: World; readonly not: Facets };\n\nexport type EnsureFactory<World, Facets extends Record<string, unknown>> = (\n world: World\n) => EnsureFacade<World, Facets>;\n\nexport interface AssertionPluginContext {\n readonly ensure: EnsureInvokeWithAlways;\n\n /**\n * True when this plugin facet is being invoked via plugin-level negation\n * (e.g. `ensure.not.<facet>.*`).\n *\n * Mirrors Jest's `this.isNot` matcher context flag.\n */\n readonly isNot: boolean;\n}\n\nexport type AssertionPlugin<World, Facet> = (\n context: AssertionPluginContext\n) => (world: World) => Facet;\n\ntype PluginFacetResult<World, Plugin> = Plugin extends AssertionPlugin<World, infer Facet>\n ? Facet\n : never;\ntype PluginFacets<World, Plugins extends Record<string, AssertionPlugin<World, unknown>>> = {\n readonly [Key in keyof Plugins]: PluginFacetResult<World, Plugins[Key]>;\n};\n\nexport type EnsurePluginFacets<\n World,\n Plugins extends Record<string, AssertionPlugin<World, unknown>>\n> = PluginFacets<World, Plugins>;\n\n/**\n * Assemble a world-aware ensure factory using the provided assertion plugins.\n * Each plugin receives the base ensure function and returns a facet builder that is\n * invoked with the current world instance. The resulting facets are attached to a\n * callable ensure facade, preserving the base ensure invocation signature.\n */\nexport function createEnsureFactory<\n World,\n Plugins extends Record<string, AssertionPlugin<World, unknown>>\n>(\n ensureFn: EnsureInvoke,\n plugins: Plugins\n): EnsureFactory<World, PluginFacets<World, Plugins>> {\n const withAlways = (\n invoker: EnsureInvoke,\n always: EnsureInvoke\n ): EnsureInvokeWithAlways => {\n Object.defineProperty(invoker, \"always\", {\n value: always,\n enumerable: false,\n configurable: false,\n writable: false,\n });\n return invoker as EnsureInvokeWithAlways;\n };\n\n const positiveEnsure = withAlways(ensureFn, ensureFn);\n const pluginEntries = (Object.keys(plugins) as Array<keyof Plugins>).map((key) => {\n const plugin = plugins[key];\n if (!plugin) {\n throw new Error(`Assertion plugin \"${String(key)}\" is not defined.`);\n }\n const factory = plugin({ ensure: positiveEnsure, isNot: false });\n return [key, factory] as const;\n });\n\n const negatedEnsureFn: EnsureInvoke = <T>(value: T, options?: EnsureOptions) => {\n return ensureFn(value, options).not as unknown as EnsureChain<T>;\n };\n\n const negativeEnsure = withAlways(negatedEnsureFn, ensureFn);\n\n const negativePluginEntries = (Object.keys(plugins) as Array<keyof Plugins>).map((key) => {\n const plugin = plugins[key];\n if (!plugin) {\n throw new Error(`Assertion plugin \"${String(key)}\" is not defined.`);\n }\n const factory = plugin({ ensure: negativeEnsure, isNot: true });\n return [key, factory] as const;\n });\n\n return (world) => {\n const facade = ((value: unknown, options?: EnsureOptions) => ensureFn(value, options)) as EnsureFacade<\n World,\n PluginFacets<World, Plugins>\n >;\n\n Object.defineProperty(facade, \"world\", {\n value: world,\n enumerable: false,\n configurable: false,\n writable: false,\n });\n\n for (const [key, buildFacet] of pluginEntries) {\n const facet = buildFacet(world);\n Object.defineProperty(facade, key, {\n value: facet,\n enumerable: true,\n configurable: false,\n writable: false,\n });\n }\n\n const notFacade = {};\n for (const [key, buildFacet] of negativePluginEntries) {\n const facet = buildFacet(world);\n Object.defineProperty(notFacade, key, {\n value: facet,\n enumerable: true,\n configurable: false,\n writable: false,\n });\n }\n\n Object.defineProperty(facade, \"not\", {\n value: notFacade,\n enumerable: true,\n configurable: false,\n writable: false,\n });\n\n return facade;\n };\n}\n\n/**\n * Create a default ensure factory without any plugins. Useful when consumers\n * want a world-aware ensure facade without additional facets.\n */\nexport function createDefaultEnsureFactory<World>(): EnsureFactory<World, Record<string, never>> {\n return createEnsureFactory<World, Record<string, never>>(baseEnsure, {});\n}\n","import type {\n HeaderlessTable,\n HeaderlessTableOptions,\n HorizontalTable,\n HorizontalTableOptions,\n MatrixTable,\n MatrixTableOptions,\n TableShape,\n VerticalTable,\n VerticalTableOptions,\n} from \"@autometa/gherkin\";\nimport type { RawTable, StepRuntimeHelpers, StepRuntimeMetadata } from \"@autometa/executor\";\n\nimport type { AssertionPlugin } from \"../plugins\";\n\n/**\n * Assertion facet attached as `ensure.runtime.*`.\n *\n * This facet is meant for **step-data ergonomics**:\n * - quick preconditions like “a table is present” / “a docstring is present”\n * - extracting required docstrings/tables with consistently-labeled failures\n *\n * It intentionally uses `ensure.always(...)` for required-value extraction so\n * plugin-level negation (`ensure.not.runtime.*`) does **not** invert these\n * preconditions.\n */\nexport interface RuntimeAssertions {\n /**\n * Assert that the current step has an attached data table.\n *\n * Works with plugin-level negation:\n * - `ensure.runtime.hasTable()` asserts table is present\n * - `ensure.not.runtime.hasTable()` asserts table is NOT present\n */\n hasTable(options?: { readonly label?: string }): void;\n\n /**\n * Assert that the current step has an attached docstring.\n *\n * Works with plugin-level negation:\n * - `ensure.runtime.hasDocstring()` asserts docstring is present\n * - `ensure.not.runtime.hasDocstring()` asserts docstring is NOT present\n */\n hasDocstring(options?: { readonly label?: string }): void;\n\n /**\n * Get the current step's docstring without consuming it.\n */\n docstring(): string | undefined;\n\n /**\n * Consume and return the current step's docstring.\n */\n consumeDocstring(): string | undefined;\n\n /**\n * Consume and return the current step's docstring.\n *\n * This is a *required extraction* helper. It is NOT negated under\n * `ensure.not.runtime.*`.\n */\n requireDocstring(options?: { readonly label?: string }): string;\n\n /**\n * Get the current step's data table coerced to the given shape without consuming it.\n */\n table(shape: \"headerless\", options?: HeaderlessTableOptions): HeaderlessTable | undefined;\n /** @inheritdoc */\n table(shape: \"horizontal\", options?: HorizontalTableOptions): HorizontalTable | undefined;\n /** @inheritdoc */\n table(shape: \"vertical\", options?: VerticalTableOptions): VerticalTable | undefined;\n /** @inheritdoc */\n table(shape: \"matrix\", options?: MatrixTableOptions): MatrixTable | undefined;\n /** @inheritdoc */\n table(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined;\n\n /**\n * Consume and return the current step's data table coerced to the given shape.\n */\n consumeTable(shape: \"headerless\", options?: HeaderlessTableOptions): HeaderlessTable | undefined;\n /** @inheritdoc */\n consumeTable(shape: \"horizontal\", options?: HorizontalTableOptions): HorizontalTable | undefined;\n /** @inheritdoc */\n consumeTable(shape: \"vertical\", options?: VerticalTableOptions): VerticalTable | undefined;\n /** @inheritdoc */\n consumeTable(shape: \"matrix\", options?: MatrixTableOptions): MatrixTable | undefined;\n /** @inheritdoc */\n consumeTable(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined;\n\n /**\n * Consume and return the current step's data table coerced to the given shape.\n *\n * This is a *required extraction* helper. It is NOT negated under\n * `ensure.not.runtime.*`.\n */\n requireTable(\n shape: \"headerless\",\n options?: HeaderlessTableOptions & { readonly label?: string }\n ): HeaderlessTable;\n /** @inheritdoc */\n requireTable(\n shape: \"horizontal\",\n options?: HorizontalTableOptions & { readonly label?: string }\n ): HorizontalTable;\n /** @inheritdoc */\n requireTable(\n shape: \"vertical\",\n options?: VerticalTableOptions & { readonly label?: string }\n ): VerticalTable;\n /** @inheritdoc */\n requireTable(\n shape: \"matrix\",\n options?: MatrixTableOptions & { readonly label?: string }\n ): MatrixTable;\n /** @inheritdoc */\n requireTable(\n shape: TableShape,\n options?: (\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ) & { readonly label?: string }\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable;\n\n /**\n * Return the underlying raw data table (array of string arrays) without consuming it.\n *\n * This is useful for custom table parsing or user-defined table semantics.\n */\n rawTable(): RawTable | undefined;\n\n /**\n * Consume the current step's raw data table.\n */\n consumeRawTable(options?: HeaderlessTableOptions): RawTable | undefined;\n\n /**\n * Consume and return the current step's raw data table.\n *\n * This is a *required extraction* helper. It is NOT negated under\n * `ensure.not.runtime.*`.\n */\n requireRawTable(options?: HeaderlessTableOptions & { readonly label?: string }): RawTable;\n\n /**\n * Return runtime metadata about the current feature/scenario/step, if available.\n */\n stepMetadata(): StepRuntimeMetadata | undefined;\n}\n\ntype WorldWithRuntime = {\n readonly runtime: StepRuntimeHelpers;\n};\n\n/**\n * Standard assertion plugin that provides step-runtime helpers as `ensure.runtime.*`.\n *\n * Register via the runner:\n *\n * ```ts\n * const runner = CucumberRunner.builder()\n * .assertionPlugins({ runtime: runtimeAssertionsPlugin<MyWorld>() });\n * ```\n */\nexport const runtimeAssertionsPlugin = <\n World extends WorldWithRuntime,\n>(): AssertionPlugin<World, RuntimeAssertions> =>\n ({ ensure }) =>\n (world) => {\n const defaultTableLabel = \"step data table\";\n const defaultDocstringLabel = \"step docstring\";\n\n function table(\n shape: \"headerless\",\n options?: HeaderlessTableOptions\n ): HeaderlessTable | undefined;\n function table(\n shape: \"horizontal\",\n options?: HorizontalTableOptions\n ): HorizontalTable | undefined;\n function table(\n shape: \"vertical\",\n options?: VerticalTableOptions\n ): VerticalTable | undefined;\n function table(\n shape: \"matrix\",\n options?: MatrixTableOptions\n ): MatrixTable | undefined;\n function table(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined;\n function table(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined {\n return world.runtime.getTable(shape, options as never);\n }\n\n function consumeTable(\n shape: \"headerless\",\n options?: HeaderlessTableOptions\n ): HeaderlessTable | undefined;\n function consumeTable(\n shape: \"horizontal\",\n options?: HorizontalTableOptions\n ): HorizontalTable | undefined;\n function consumeTable(\n shape: \"vertical\",\n options?: VerticalTableOptions\n ): VerticalTable | undefined;\n function consumeTable(\n shape: \"matrix\",\n options?: MatrixTableOptions\n ): MatrixTable | undefined;\n function consumeTable(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined;\n function consumeTable(\n shape: TableShape,\n options?:\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable | undefined {\n return world.runtime.consumeTable(shape, options as never);\n }\n\n function requireTable(\n shape: \"headerless\",\n options?: HeaderlessTableOptions & { readonly label?: string }\n ): HeaderlessTable;\n function requireTable(\n shape: \"horizontal\",\n options?: HorizontalTableOptions & { readonly label?: string }\n ): HorizontalTable;\n function requireTable(\n shape: \"vertical\",\n options?: VerticalTableOptions & { readonly label?: string }\n ): VerticalTable;\n function requireTable(\n shape: \"matrix\",\n options?: MatrixTableOptions & { readonly label?: string }\n ): MatrixTable;\n function requireTable(\n shape: TableShape,\n options?: (\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ) & { readonly label?: string }\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable;\n function requireTable(\n shape: TableShape,\n options?: (\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n ) & { readonly label?: string }\n ): HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable {\n const { label, ...tableOptions } = (options ?? {}) as {\n readonly label?: string;\n } & (\n | HeaderlessTableOptions\n | HorizontalTableOptions\n | VerticalTableOptions\n | MatrixTableOptions\n );\n\n const table = consumeTable(shape, tableOptions);\n return ensure.always(table, {\n label:\n label ??\n `Expected ${shape} ${defaultTableLabel} to be attached to the current step.`,\n })\n .toBeDefined()\n .value as HeaderlessTable | HorizontalTable | VerticalTable | MatrixTable;\n }\n\n function consumeRawTable(options?: HeaderlessTableOptions): RawTable | undefined {\n // `getRawTable()` does not consume; to consume we piggy-back on consuming a\n // headerless table.\n const tableInstance = consumeTable(\"headerless\", options);\n return tableInstance?.raw();\n }\n\n function requireRawTable(\n options?: HeaderlessTableOptions & { readonly label?: string }\n ): RawTable {\n const { label, ...tableOptions } = (options ?? {}) as {\n readonly label?: string;\n } & HeaderlessTableOptions;\n\n const raw = consumeRawTable(tableOptions);\n return ensure.always(raw, {\n label: label ?? `Expected ${defaultTableLabel} to be attached to the current step.`,\n })\n .toBeDefined()\n .value;\n }\n\n return {\n hasTable(options) {\n ensure(world.runtime.hasTable, {\n label: options?.label ?? `${defaultTableLabel} is present`,\n }).toBeTruthy();\n },\n hasDocstring(options) {\n ensure(world.runtime.hasDocstring, {\n label: options?.label ?? `${defaultDocstringLabel} is present`,\n }).toBeTruthy();\n },\n docstring() {\n return world.runtime.getDocstring();\n },\n consumeDocstring() {\n return world.runtime.consumeDocstring();\n },\n requireDocstring(options) {\n const docstring = world.runtime.consumeDocstring();\n return ensure.always(docstring, {\n label:\n options?.label ??\n `Expected ${defaultDocstringLabel} to be attached to the current step.`,\n })\n .toBeDefined()\n .value as string;\n },\n table,\n consumeTable,\n requireTable,\n rawTable() {\n return world.runtime.getRawTable();\n },\n consumeRawTable,\n requireRawTable,\n stepMetadata() {\n return world.runtime.getStepMetadata();\n },\n };\n };\n"]}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { MatcherContext } from "../core/context";
|
|
2
|
+
type EnsureTypeOf = "string" | "number" | "boolean" | "bigint" | "symbol" | "undefined" | "object" | "function";
|
|
3
|
+
export declare function assertToBeTypeOf<T>(ctx: MatcherContext<T>, expected: EnsureTypeOf): void;
|
|
4
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autometa/assertions",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.5",
|
|
4
4
|
"description": "Runner-agnostic assertion helpers powered by ensure(value) matcher chains.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -22,11 +22,11 @@
|
|
|
22
22
|
"jest-diff": "^29.7.0",
|
|
23
23
|
"jest-matcher-utils": "^29.7.0",
|
|
24
24
|
"tslib": "^2.6.2",
|
|
25
|
+
"@autometa/cucumber-expressions": "1.0.0-rc.2",
|
|
25
26
|
"@autometa/gherkin": "1.0.0-rc.2",
|
|
27
|
+
"@autometa/injection": "1.0.0-rc.2",
|
|
26
28
|
"@autometa/executor": "1.0.0-rc.4",
|
|
27
|
-
"@autometa/scopes": "1.0.0-rc.1"
|
|
28
|
-
"@autometa/cucumber-expressions": "1.0.0-rc.2",
|
|
29
|
-
"@autometa/injection": "1.0.0-rc.2"
|
|
29
|
+
"@autometa/scopes": "1.0.0-rc.1"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@types/node": "^18.11.18",
|
|
@@ -38,8 +38,8 @@
|
|
|
38
38
|
"tsup": "^7.2.0",
|
|
39
39
|
"typescript": "^4.9.5",
|
|
40
40
|
"vitest": "1.4.0",
|
|
41
|
-
"eslint-config-custom": "0.6.0",
|
|
42
41
|
"tsup-config": "0.1.0",
|
|
42
|
+
"eslint-config-custom": "0.6.0",
|
|
43
43
|
"tsconfig": "0.7.0"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|