@vitest/expect 4.0.0-beta.16 → 4.0.0-beta.18

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/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { MockInstance } from '@vitest/spy';
2
2
  import { Constructable } from '@vitest/utils';
3
3
  import { Formatter } from 'tinyrainbow';
4
+ import { StandardSchemaV1 } from '@standard-schema/spec';
4
5
  import { diff, printDiffOrStringify } from '@vitest/utils/diff';
5
6
  export { DiffOptions } from '@vitest/utils/diff';
6
7
  import { stringify } from '@vitest/utils/display';
@@ -72,6 +73,14 @@ declare class StringMatching extends AsymmetricMatcher<RegExp> {
72
73
  toString(): string;
73
74
  getExpectedType(): string;
74
75
  }
76
+ declare class SchemaMatching extends AsymmetricMatcher<StandardSchemaV1<unknown, unknown>> {
77
+ private result;
78
+ constructor(sample: StandardSchemaV1<unknown, unknown>, inverse?: boolean);
79
+ asymmetricMatch(other: unknown): boolean;
80
+ toString(): string;
81
+ getExpectedType(): string;
82
+ toAsymmetricMatcher(): string;
83
+ }
75
84
  declare const JestAsymmetricMatchers: ChaiPlugin;
76
85
 
77
86
  declare function matcherHint(matcherName: string, received?: string, expected?: string, options?: MatcherHintOptions): string;
@@ -230,6 +239,16 @@ interface AsymmetricMatchersContaining extends CustomMatcher {
230
239
  * expect(5.11).toEqual(expect.closeTo(5.12)); // with default precision
231
240
  */
232
241
  closeTo: (expected: number, precision?: number) => any;
242
+ /**
243
+ * Matches if the received value validates against a Standard Schema.
244
+ *
245
+ * @param schema - A Standard Schema V1 compatible schema object
246
+ *
247
+ * @example
248
+ * expect(user).toEqual(expect.schemaMatching(z.object({ name: z.string() })))
249
+ * expect(['hello', 'world']).toEqual([expect.schemaMatching(z.string()), expect.schemaMatching(z.string())])
250
+ */
251
+ schemaMatching: (schema: unknown) => any;
233
252
  }
234
253
  type WithAsymmetricMatcher<T> = T | AsymmetricMatcher<unknown>;
235
254
  type DeeplyAllowMatchers<T> = T extends Array<infer Element> ? WithAsymmetricMatcher<T> | DeeplyAllowMatchers<Element>[] : T extends object ? WithAsymmetricMatcher<T> | { [K in keyof T] : DeeplyAllowMatchers<T[K]> } : WithAsymmetricMatcher<T>;
@@ -773,9 +792,13 @@ declare function getObjectSubset(object: any, subset: any, customTesters: Array<
773
792
  subset: any;
774
793
  stripped: number;
775
794
  };
795
+ /**
796
+ * Detects if an object is a Standard Schema V1 compatible schema
797
+ */
798
+ declare function isStandardSchema(obj: any): obj is StandardSchemaV1;
776
799
 
777
800
  declare function getState<State extends MatcherState = MatcherState>(expect: ExpectStatic): State;
778
801
  declare function setState<State extends MatcherState = MatcherState>(state: Partial<State>, expect: ExpectStatic): void;
779
802
 
780
- export { ASYMMETRIC_MATCHERS_OBJECT, Any, Anything, ArrayContaining, AsymmetricMatcher, GLOBAL_EXPECT, JEST_MATCHERS_OBJECT, JestAsymmetricMatchers, JestChaiExpect, JestExtend, MATCHERS_OBJECT, ObjectContaining, StringContaining, StringMatching, addCustomEqualityTesters, arrayBufferEquality, customMatchers, equals, fnNameFor, generateToBeMessage, getObjectKeys, getObjectSubset, getState, hasAsymmetric, hasProperty, isA, isAsymmetric, isImmutableUnorderedKeyed, isImmutableUnorderedSet, iterableEquality, pluralize, setState, sparseArrayEquality, subsetEquality, typeEquality };
803
+ export { ASYMMETRIC_MATCHERS_OBJECT, Any, Anything, ArrayContaining, AsymmetricMatcher, GLOBAL_EXPECT, JEST_MATCHERS_OBJECT, JestAsymmetricMatchers, JestChaiExpect, JestExtend, MATCHERS_OBJECT, ObjectContaining, SchemaMatching, StringContaining, StringMatching, addCustomEqualityTesters, arrayBufferEquality, customMatchers, equals, fnNameFor, generateToBeMessage, getObjectKeys, getObjectSubset, getState, hasAsymmetric, hasProperty, isA, isAsymmetric, isImmutableUnorderedKeyed, isImmutableUnorderedSet, isStandardSchema, iterableEquality, pluralize, setState, sparseArrayEquality, subsetEquality, typeEquality };
781
804
  export type { Assertion, AsymmetricMatcherInterface, AsymmetricMatchersContaining, AsyncExpectationResult, ChaiPlugin, DeeplyAllowMatchers, ExpectStatic, ExpectationResult, JestAssertion, MatcherHintOptions, MatcherState, Matchers, MatchersObject, PromisifyAssertion, RawMatcherFn, SyncExpectationResult, Tester, TesterContext };
package/dist/index.js CHANGED
@@ -660,6 +660,12 @@ function getObjectSubset(object, subset, customTesters) {
660
660
  stripped
661
661
  };
662
662
  }
663
+ /**
664
+ * Detects if an object is a Standard Schema V1 compatible schema
665
+ */
666
+ function isStandardSchema(obj) {
667
+ return !!obj && typeof obj === "object" && obj["~standard"] && typeof obj["~standard"].validate === "function";
668
+ }
663
669
 
664
670
  if (!Object.hasOwn(globalThis, MATCHERS_OBJECT)) {
665
671
  const globalState = new WeakMap();
@@ -952,6 +958,40 @@ class CloseTo extends AsymmetricMatcher {
952
958
  ].join(" ");
953
959
  }
954
960
  }
961
+ class SchemaMatching extends AsymmetricMatcher {
962
+ result;
963
+ constructor(sample, inverse = false) {
964
+ if (!isStandardSchema(sample)) {
965
+ throw new TypeError("SchemaMatching expected to receive a Standard Schema.");
966
+ }
967
+ super(sample, inverse);
968
+ }
969
+ asymmetricMatch(other) {
970
+ const result = this.sample["~standard"].validate(other);
971
+ // Check if the result is a Promise (async validation)
972
+ if (result instanceof Promise) {
973
+ throw new TypeError("Async schema validation is not supported in asymmetric matchers.");
974
+ }
975
+ this.result = result;
976
+ const pass = !this.result.issues || this.result.issues.length === 0;
977
+ return this.inverse ? !pass : pass;
978
+ }
979
+ toString() {
980
+ return `Schema${this.inverse ? "Not" : ""}Matching`;
981
+ }
982
+ getExpectedType() {
983
+ return "object";
984
+ }
985
+ toAsymmetricMatcher() {
986
+ var _this$result;
987
+ const { utils } = this.getMatcherContext();
988
+ const issues = ((_this$result = this.result) === null || _this$result === void 0 ? void 0 : _this$result.issues) || [];
989
+ if (issues.length > 0) {
990
+ return `${this.toString()} ${utils.stringify(this.result, undefined, { printBasicPrototype: false })}`;
991
+ }
992
+ return this.toString();
993
+ }
994
+ }
955
995
  const JestAsymmetricMatchers = (chai, utils) => {
956
996
  utils.addMethod(chai.expect, "anything", () => new Anything());
957
997
  utils.addMethod(chai.expect, "any", (expected) => new Any(expected));
@@ -960,13 +1000,15 @@ const JestAsymmetricMatchers = (chai, utils) => {
960
1000
  utils.addMethod(chai.expect, "arrayContaining", (expected) => new ArrayContaining(expected));
961
1001
  utils.addMethod(chai.expect, "stringMatching", (expected) => new StringMatching(expected));
962
1002
  utils.addMethod(chai.expect, "closeTo", (expected, precision) => new CloseTo(expected, precision));
1003
+ utils.addMethod(chai.expect, "schemaMatching", (expected) => new SchemaMatching(expected));
963
1004
  // defineProperty does not work
964
1005
  chai.expect.not = {
965
1006
  stringContaining: (expected) => new StringContaining(expected, true),
966
1007
  objectContaining: (expected) => new ObjectContaining(expected, true),
967
1008
  arrayContaining: (expected) => new ArrayContaining(expected, true),
968
1009
  stringMatching: (expected) => new StringMatching(expected, true),
969
- closeTo: (expected, precision) => new CloseTo(expected, precision, true)
1010
+ closeTo: (expected, precision) => new CloseTo(expected, precision, true),
1011
+ schemaMatching: (expected) => new SchemaMatching(expected, true)
970
1012
  };
971
1013
  };
972
1014
 
@@ -1819,4 +1861,4 @@ const JestExtend = (chai, utils) => {
1819
1861
  });
1820
1862
  };
1821
1863
 
1822
- export { ASYMMETRIC_MATCHERS_OBJECT, Any, Anything, ArrayContaining, AsymmetricMatcher, GLOBAL_EXPECT, JEST_MATCHERS_OBJECT, JestAsymmetricMatchers, JestChaiExpect, JestExtend, MATCHERS_OBJECT, ObjectContaining, StringContaining, StringMatching, addCustomEqualityTesters, arrayBufferEquality, customMatchers, equals, fnNameFor, generateToBeMessage, getObjectKeys, getObjectSubset, getState, hasAsymmetric, hasProperty, isA, isAsymmetric, isImmutableUnorderedKeyed, isImmutableUnorderedSet, iterableEquality, pluralize, setState, sparseArrayEquality, subsetEquality, typeEquality };
1864
+ export { ASYMMETRIC_MATCHERS_OBJECT, Any, Anything, ArrayContaining, AsymmetricMatcher, GLOBAL_EXPECT, JEST_MATCHERS_OBJECT, JestAsymmetricMatchers, JestChaiExpect, JestExtend, MATCHERS_OBJECT, ObjectContaining, SchemaMatching, StringContaining, StringMatching, addCustomEqualityTesters, arrayBufferEquality, customMatchers, equals, fnNameFor, generateToBeMessage, getObjectKeys, getObjectSubset, getState, hasAsymmetric, hasProperty, isA, isAsymmetric, isImmutableUnorderedKeyed, isImmutableUnorderedSet, isStandardSchema, iterableEquality, pluralize, setState, sparseArrayEquality, subsetEquality, typeEquality };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vitest/expect",
3
3
  "type": "module",
4
- "version": "4.0.0-beta.16",
4
+ "version": "4.0.0-beta.18",
5
5
  "description": "Jest's expect matchers as a Chai plugin",
6
6
  "license": "MIT",
7
7
  "funding": "https://opencollective.com/vitest",
@@ -29,14 +29,15 @@
29
29
  "dist"
30
30
  ],
31
31
  "dependencies": {
32
+ "@standard-schema/spec": "^1.0.0",
32
33
  "@types/chai": "^5.2.2",
33
34
  "chai": "^6.0.1",
34
35
  "tinyrainbow": "^3.0.3",
35
- "@vitest/spy": "4.0.0-beta.16",
36
- "@vitest/utils": "4.0.0-beta.16"
36
+ "@vitest/utils": "4.0.0-beta.18",
37
+ "@vitest/spy": "4.0.0-beta.18"
37
38
  },
38
39
  "devDependencies": {
39
- "@vitest/runner": "4.0.0-beta.16"
40
+ "@vitest/runner": "4.0.0-beta.18"
40
41
  },
41
42
  "scripts": {
42
43
  "build": "premove dist && rollup -c",