@vitest/expect 0.31.4 → 0.32.1

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,8 @@
1
1
  import { use } from 'chai';
2
2
  import { stringify, Constructable } from '@vitest/utils';
3
3
  export { setupColors } from '@vitest/utils';
4
+ import { diff } from '@vitest/utils/diff';
5
+ export { DiffOptions } from '@vitest/utils/diff';
4
6
 
5
7
  type Formatter = (input: string | number | null | undefined) => string;
6
8
 
@@ -34,11 +36,11 @@ declare function getMatcherUtils(): {
34
36
  printReceived: (object: unknown) => string;
35
37
  printExpected: (value: unknown) => string;
36
38
  };
37
- declare function diff(a: any, b: any, options?: DiffOptions): string;
38
39
 
39
40
  type FirstFunctionArgument<T> = T extends (arg: infer A) => unknown ? A : never;
40
41
  type ChaiPlugin = FirstFunctionArgument<typeof use>;
41
42
  type Tester = (a: any, b: any) => boolean | undefined;
43
+
42
44
  interface MatcherHintOptions {
43
45
  comment?: string;
44
46
  expectedColor?: Formatter;
@@ -49,27 +51,6 @@ interface MatcherHintOptions {
49
51
  secondArgument?: string;
50
52
  secondArgumentColor?: Formatter;
51
53
  }
52
- interface DiffOptions {
53
- aAnnotation?: string;
54
- aColor?: Formatter;
55
- aIndicator?: string;
56
- bAnnotation?: string;
57
- bColor?: Formatter;
58
- bIndicator?: string;
59
- changeColor?: Formatter;
60
- changeLineTrailingSpaceColor?: Formatter;
61
- commonColor?: Formatter;
62
- commonIndicator?: string;
63
- commonLineTrailingSpaceColor?: Formatter;
64
- contextLines?: number;
65
- emptyFirstOrLastLinePlaceholder?: string;
66
- expand?: boolean;
67
- includeChangeCounts?: boolean;
68
- omitAnnotationLines?: boolean;
69
- patchColor?: Formatter;
70
- compareKeys?: any;
71
- showLegend?: boolean;
72
- }
73
54
  interface MatcherState {
74
55
  assertionCalls: number;
75
56
  currentTestName?: string;
@@ -91,6 +72,7 @@ interface MatcherState {
91
72
  iterableEquality: Tester;
92
73
  subsetEquality: Tester;
93
74
  };
75
+ soft?: boolean;
94
76
  }
95
77
  interface SyncExpectationResult {
96
78
  pass: boolean;
@@ -106,6 +88,8 @@ interface RawMatcherFn<T extends MatcherState = MatcherState> {
106
88
  type MatchersObject<T extends MatcherState = MatcherState> = Record<string, RawMatcherFn<T>>;
107
89
  interface ExpectStatic extends Chai.ExpectStatic, AsymmetricMatchersContaining {
108
90
  <T>(actual: T, message?: string): Assertion<T>;
91
+ unreachable(message?: string): never;
92
+ soft<T>(actual: T, message?: string): Assertion<T>;
109
93
  extend(expects: MatchersObject): void;
110
94
  assertions(expected: number): void;
111
95
  hasAssertions(): void;
@@ -270,4 +254,4 @@ declare const JestChaiExpect: ChaiPlugin;
270
254
 
271
255
  declare const JestExtend: ChaiPlugin;
272
256
 
273
- export { Any, Anything, ArrayContaining, Assertion, AsymmetricMatcher, AsymmetricMatcherInterface, AsymmetricMatchersContaining, AsyncExpectationResult, ChaiPlugin, DiffOptions, ExpectStatic, ExpectationResult, FirstFunctionArgument, GLOBAL_EXPECT, JEST_MATCHERS_OBJECT, JestAssertion, JestAsymmetricMatchers, JestChaiExpect, JestExtend, MATCHERS_OBJECT, MatcherHintOptions, MatcherState, MatchersObject, ObjectContaining, RawMatcherFn, StringContaining, StringMatching, SyncExpectationResult, Tester, arrayBufferEquality, equals, fnNameFor, generateToBeMessage, getState, hasAsymmetric, hasProperty, isA, isAsymmetric, isImmutableUnorderedKeyed, isImmutableUnorderedSet, iterableEquality, setState, sparseArrayEquality, subsetEquality, typeEquality };
257
+ export { Any, Anything, ArrayContaining, Assertion, AsymmetricMatcher, AsymmetricMatcherInterface, AsymmetricMatchersContaining, AsyncExpectationResult, ChaiPlugin, ExpectStatic, ExpectationResult, FirstFunctionArgument, GLOBAL_EXPECT, JEST_MATCHERS_OBJECT, JestAssertion, JestAsymmetricMatchers, JestChaiExpect, JestExtend, MATCHERS_OBJECT, MatcherHintOptions, MatcherState, MatchersObject, ObjectContaining, RawMatcherFn, StringContaining, StringMatching, SyncExpectationResult, Tester, arrayBufferEquality, equals, fnNameFor, generateToBeMessage, getState, hasAsymmetric, hasProperty, isA, isAsymmetric, isImmutableUnorderedKeyed, isImmutableUnorderedSet, iterableEquality, setState, sparseArrayEquality, subsetEquality, typeEquality };
package/dist/index.js CHANGED
@@ -1,8 +1,9 @@
1
1
  import { getColors, stringify, isObject, assertTypes } from '@vitest/utils';
2
2
  export { setupColors } from '@vitest/utils';
3
- import { unifiedDiff } from '@vitest/utils/diff';
3
+ import { diff } from '@vitest/utils/diff';
4
4
  import { AssertionError, util } from 'chai';
5
5
  import { isMockFunction } from '@vitest/spy';
6
+ import { processError } from '@vitest/utils/error';
6
7
 
7
8
  const MATCHERS_OBJECT = Symbol.for("matchers-object");
8
9
  const JEST_MATCHERS_OBJECT = Symbol.for("$$jest-matchers-object");
@@ -100,11 +101,6 @@ function getMatcherUtils() {
100
101
  printExpected
101
102
  };
102
103
  }
103
- function diff(a, b, options) {
104
- return unifiedDiff(b, a, {
105
- showLegend: options == null ? void 0 : options.showLegend
106
- });
107
- }
108
104
 
109
105
  function equals(a, b, customTesters, strictCheck) {
110
106
  customTesters = customTesters || [];
@@ -637,13 +633,33 @@ function recordAsyncExpect(test, promise) {
637
633
  }
638
634
  return promise;
639
635
  }
636
+ function wrapSoft(utils, fn) {
637
+ return function(...args) {
638
+ var _a;
639
+ const test = utils.flag(this, "vitest-test");
640
+ const state = (test == null ? void 0 : test.context._local) ? test.context.expect.getState() : getState(globalThis[GLOBAL_EXPECT]);
641
+ if (!state.soft)
642
+ return fn.apply(this, args);
643
+ if (!test)
644
+ throw new Error("expect.soft() can only be used inside a test");
645
+ try {
646
+ return fn.apply(this, args);
647
+ } catch (err) {
648
+ test.result || (test.result = { state: "fail" });
649
+ test.result.state = "fail";
650
+ (_a = test.result).errors || (_a.errors = []);
651
+ test.result.errors.push(processError(err));
652
+ }
653
+ };
654
+ }
640
655
 
641
656
  const JestChaiExpect = (chai, utils) => {
642
657
  const c = () => getColors();
643
658
  function def(name, fn) {
644
659
  const addMethod = (n) => {
645
- utils.addMethod(chai.Assertion.prototype, n, fn);
646
- utils.addMethod(globalThis[JEST_MATCHERS_OBJECT].matchers, n, fn);
660
+ const softWrapper = wrapSoft(utils, fn);
661
+ utils.addMethod(chai.Assertion.prototype, n, softWrapper);
662
+ utils.addMethod(globalThis[JEST_MATCHERS_OBJECT].matchers, n, softWrapper);
647
663
  };
648
664
  if (Array.isArray(name))
649
665
  name.forEach((n) => addMethod(n));
@@ -788,7 +804,8 @@ const JestChaiExpect = (chai, utils) => {
788
804
  Boolean(obj),
789
805
  "expected #{this} to be truthy",
790
806
  "expected #{this} to not be truthy",
791
- obj
807
+ obj,
808
+ false
792
809
  );
793
810
  });
794
811
  def("toBeFalsy", function() {
@@ -797,7 +814,8 @@ const JestChaiExpect = (chai, utils) => {
797
814
  !obj,
798
815
  "expected #{this} to be falsy",
799
816
  "expected #{this} to not be falsy",
800
- obj
817
+ obj,
818
+ false
801
819
  );
802
820
  });
803
821
  def("toBeGreaterThan", function(expected) {
@@ -809,7 +827,8 @@ const JestChaiExpect = (chai, utils) => {
809
827
  `expected ${actual} to be greater than ${expected}`,
810
828
  `expected ${actual} to be not greater than ${expected}`,
811
829
  actual,
812
- expected
830
+ expected,
831
+ false
813
832
  );
814
833
  });
815
834
  def("toBeGreaterThanOrEqual", function(expected) {
@@ -821,7 +840,8 @@ const JestChaiExpect = (chai, utils) => {
821
840
  `expected ${actual} to be greater than or equal to ${expected}`,
822
841
  `expected ${actual} to be not greater than or equal to ${expected}`,
823
842
  actual,
824
- expected
843
+ expected,
844
+ false
825
845
  );
826
846
  });
827
847
  def("toBeLessThan", function(expected) {
@@ -833,7 +853,8 @@ const JestChaiExpect = (chai, utils) => {
833
853
  `expected ${actual} to be less than ${expected}`,
834
854
  `expected ${actual} to be not less than ${expected}`,
835
855
  actual,
836
- expected
856
+ expected,
857
+ false
837
858
  );
838
859
  });
839
860
  def("toBeLessThanOrEqual", function(expected) {
@@ -845,7 +866,8 @@ const JestChaiExpect = (chai, utils) => {
845
866
  `expected ${actual} to be less than or equal to ${expected}`,
846
867
  `expected ${actual} to be not less than or equal to ${expected}`,
847
868
  actual,
848
- expected
869
+ expected,
870
+ false
849
871
  );
850
872
  });
851
873
  def("toBeNaN", function() {
@@ -921,7 +943,8 @@ const JestChaiExpect = (chai, utils) => {
921
943
  `expected #{this} to be close to #{exp}, received difference is ${receivedDiff}, but expected ${expectedDiff}`,
922
944
  `expected #{this} to not be close to #{exp}, received difference is ${receivedDiff}, but expected ${expectedDiff}`,
923
945
  received,
924
- expected
946
+ expected,
947
+ false
925
948
  );
926
949
  });
927
950
  const assertIsMock = (assertion) => {
@@ -948,12 +971,13 @@ const JestChaiExpect = (chai, utils) => {
948
971
  msg += c().gray(`
949
972
 
950
973
  Received:
974
+
951
975
  ${spy.mock.calls.map((callArg, i) => {
952
- let methodCall = c().bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call:
976
+ let methodCall = c().bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call:
953
977
 
954
978
  `);
955
979
  if (actualCall)
956
- methodCall += diff(actualCall, callArg, { showLegend: false });
980
+ methodCall += diff(actualCall, callArg, { omitAnnotationLines: true });
957
981
  else
958
982
  methodCall += stringify(callArg).split("\n").map((line) => ` ${line}`).join("\n");
959
983
  methodCall += "\n";
@@ -970,12 +994,13 @@ Number of calls: ${c().bold(spy.mock.calls.length)}
970
994
  msg += c().gray(`
971
995
 
972
996
  Received:
997
+
973
998
  ${spy.mock.results.map((callReturn, i) => {
974
- let methodCall = c().bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call return:
999
+ let methodCall = c().bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call return:
975
1000
 
976
1001
  `);
977
1002
  if (actualReturn)
978
- methodCall += diff(actualReturn, callReturn.value, { showLegend: false });
1003
+ methodCall += diff(actualReturn, callReturn.value, { omitAnnotationLines: true });
979
1004
  else
980
1005
  methodCall += stringify(callReturn).split("\n").map((line) => ` ${line}`).join("\n");
981
1006
  methodCall += "\n";
@@ -996,7 +1021,8 @@ Number of calls: ${c().bold(spy.mock.calls.length)}
996
1021
  `expected "${spyName}" to be called #{exp} times`,
997
1022
  `expected "${spyName}" to not be called #{exp} times`,
998
1023
  number,
999
- callCount
1024
+ callCount,
1025
+ false
1000
1026
  );
1001
1027
  });
1002
1028
  def("toHaveBeenCalledOnce", function() {
@@ -1008,7 +1034,8 @@ Number of calls: ${c().bold(spy.mock.calls.length)}
1008
1034
  `expected "${spyName}" to be called once`,
1009
1035
  `expected "${spyName}" to not be called once`,
1010
1036
  1,
1011
- callCount
1037
+ callCount,
1038
+ false
1012
1039
  );
1013
1040
  });
1014
1041
  def(["toHaveBeenCalled", "toBeCalled"], function() {
@@ -1112,7 +1139,8 @@ Number of calls: ${c().bold(spy.mock.calls.length)}
1112
1139
  `expected error to be instance of ${name}`,
1113
1140
  `expected error not to be instance of ${name}`,
1114
1141
  expected,
1115
- thrown
1142
+ thrown,
1143
+ false
1116
1144
  );
1117
1145
  }
1118
1146
  if (expected instanceof Error) {
@@ -1131,7 +1159,8 @@ Number of calls: ${c().bold(spy.mock.calls.length)}
1131
1159
  "expected error to match asymmetric matcher",
1132
1160
  "expected error not to match asymmetric matcher",
1133
1161
  matcher.toString(),
1134
- thrown
1162
+ thrown,
1163
+ false
1135
1164
  );
1136
1165
  }
1137
1166
  throw new Error(`"toThrow" expects string, RegExp, function, Error instance or asymmetric matcher, got "${typeof expected}"`);
@@ -1145,7 +1174,8 @@ Number of calls: ${c().bold(spy.mock.calls.length)}
1145
1174
  `expected "${spyName}" to be successfully called at least once`,
1146
1175
  `expected "${spyName}" to not be successfully called`,
1147
1176
  calledAndNotThrew,
1148
- !calledAndNotThrew
1177
+ !calledAndNotThrew,
1178
+ false
1149
1179
  );
1150
1180
  });
1151
1181
  def(["toHaveReturnedTimes", "toReturnTimes"], function(times) {
@@ -1157,7 +1187,8 @@ Number of calls: ${c().bold(spy.mock.calls.length)}
1157
1187
  `expected "${spyName}" to be successfully called ${times} times`,
1158
1188
  `expected "${spyName}" to not be successfully called ${times} times`,
1159
1189
  `expected number of returns: ${times}`,
1160
- `received number of returns: ${successfulReturns}`
1190
+ `received number of returns: ${successfulReturns}`,
1191
+ false
1161
1192
  );
1162
1193
  });
1163
1194
  def(["toHaveReturnedWith", "toReturnWith"], function(value) {
@@ -1322,8 +1353,9 @@ function JestExtendPlugin(expect, matchers) {
1322
1353
  if (pass && isNot || !pass && !isNot)
1323
1354
  throw new JestExtendError(message(), actual, expected);
1324
1355
  }
1325
- utils.addMethod(globalThis[JEST_MATCHERS_OBJECT].matchers, expectAssertionName, expectWrapper);
1326
- utils.addMethod(c.Assertion.prototype, expectAssertionName, expectWrapper);
1356
+ const softWrapper = wrapSoft(utils, expectWrapper);
1357
+ utils.addMethod(globalThis[JEST_MATCHERS_OBJECT].matchers, expectAssertionName, softWrapper);
1358
+ utils.addMethod(c.Assertion.prototype, expectAssertionName, softWrapper);
1327
1359
  class CustomMatcher extends AsymmetricMatcher {
1328
1360
  constructor(inverse = false, ...sample) {
1329
1361
  super(sample, inverse);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vitest/expect",
3
3
  "type": "module",
4
- "version": "0.31.4",
4
+ "version": "0.32.1",
5
5
  "description": "Jest's expect matchers as a Chai plugin",
6
6
  "license": "MIT",
7
7
  "funding": "https://opencollective.com/vitest",
@@ -30,11 +30,12 @@
30
30
  ],
31
31
  "dependencies": {
32
32
  "chai": "^4.3.7",
33
- "@vitest/spy": "0.31.4",
34
- "@vitest/utils": "0.31.4"
33
+ "@vitest/spy": "0.32.1",
34
+ "@vitest/utils": "0.32.1"
35
35
  },
36
36
  "devDependencies": {
37
- "picocolors": "^1.0.0"
37
+ "picocolors": "^1.0.0",
38
+ "@vitest/runner": "0.32.1"
38
39
  },
39
40
  "scripts": {
40
41
  "build": "rimraf dist && rollup -c",