@vitest/expect 0.27.2 → 0.28.0

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,43 +1,21 @@
1
1
  import { use } from 'chai';
2
2
  import { stringify } from '@vitest/utils';
3
+ export { setColors as setupColors } from '@vitest/utils';
3
4
 
4
5
  type Formatter = (input: string | number | null | undefined) => string;
5
6
 
6
- declare const EXPECTED_COLOR: Formatter;
7
- declare const RECEIVED_COLOR: Formatter;
8
- declare const INVERTED_COLOR: Formatter;
9
- declare const BOLD_WEIGHT: Formatter;
10
- declare const DIM_COLOR: Formatter;
11
- declare function matcherHint(matcherName: string, received?: string, expected?: string, options?: MatcherHintOptions): string;
12
- declare const printReceived: (object: unknown) => string;
13
- declare const printExpected: (value: unknown) => string;
7
+ declare function getMatcherUtils(): {
8
+ EXPECTED_COLOR: Formatter;
9
+ RECEIVED_COLOR: Formatter;
10
+ INVERTED_COLOR: Formatter;
11
+ BOLD_WEIGHT: Formatter;
12
+ DIM_COLOR: Formatter;
13
+ matcherHint: (matcherName: string, received?: string, expected?: string, options?: MatcherHintOptions) => string;
14
+ printReceived: (object: unknown) => string;
15
+ printExpected: (value: unknown) => string;
16
+ };
14
17
  declare function diff(a: any, b: any, options?: DiffOptions): string;
15
18
 
16
- declare const jestMatcherUtils_stringify: typeof stringify;
17
- declare const jestMatcherUtils_EXPECTED_COLOR: typeof EXPECTED_COLOR;
18
- declare const jestMatcherUtils_RECEIVED_COLOR: typeof RECEIVED_COLOR;
19
- declare const jestMatcherUtils_INVERTED_COLOR: typeof INVERTED_COLOR;
20
- declare const jestMatcherUtils_BOLD_WEIGHT: typeof BOLD_WEIGHT;
21
- declare const jestMatcherUtils_DIM_COLOR: typeof DIM_COLOR;
22
- declare const jestMatcherUtils_matcherHint: typeof matcherHint;
23
- declare const jestMatcherUtils_printReceived: typeof printReceived;
24
- declare const jestMatcherUtils_printExpected: typeof printExpected;
25
- declare const jestMatcherUtils_diff: typeof diff;
26
- declare namespace jestMatcherUtils {
27
- export {
28
- jestMatcherUtils_stringify as stringify,
29
- jestMatcherUtils_EXPECTED_COLOR as EXPECTED_COLOR,
30
- jestMatcherUtils_RECEIVED_COLOR as RECEIVED_COLOR,
31
- jestMatcherUtils_INVERTED_COLOR as INVERTED_COLOR,
32
- jestMatcherUtils_BOLD_WEIGHT as BOLD_WEIGHT,
33
- jestMatcherUtils_DIM_COLOR as DIM_COLOR,
34
- jestMatcherUtils_matcherHint as matcherHint,
35
- jestMatcherUtils_printReceived as printReceived,
36
- jestMatcherUtils_printExpected as printExpected,
37
- jestMatcherUtils_diff as diff,
38
- };
39
- }
40
-
41
19
  type FirstFunctionArgument<T> = T extends (arg: infer A) => unknown ? A : never;
42
20
  type ChaiPlugin = FirstFunctionArgument<typeof use>;
43
21
  type Tester = (a: any, b: any) => boolean | undefined;
@@ -70,6 +48,7 @@ interface DiffOptions {
70
48
  omitAnnotationLines?: boolean;
71
49
  patchColor?: Formatter;
72
50
  compareKeys?: any;
51
+ showLegend?: boolean;
73
52
  }
74
53
  interface MatcherState {
75
54
  assertionCalls: number;
@@ -86,7 +65,9 @@ interface MatcherState {
86
65
  promise: string;
87
66
  suppressedErrors: Array<Error>;
88
67
  testPath?: string;
89
- utils: typeof jestMatcherUtils & {
68
+ utils: ReturnType<typeof getMatcherUtils> & {
69
+ diff: typeof diff;
70
+ stringify: typeof stringify;
90
71
  iterableEquality: Tester;
91
72
  subsetEquality: Tester;
92
73
  };
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
- import c from 'picocolors';
2
- import { stringify, unifiedDiff, isObject, assertTypes } from '@vitest/utils';
1
+ import { getColors, stringify, isObject, assertTypes } from '@vitest/utils';
2
+ export { setColors as setupColors } from '@vitest/utils';
3
+ import { unifiedDiff } from '@vitest/utils/diff';
3
4
  import { AssertionError, util } from 'chai';
4
5
  import { isMockFunction } from '@vitest/spy';
5
6
 
@@ -29,75 +30,87 @@ const setState = (state, expect) => {
29
30
  map.set(expect, current);
30
31
  };
31
32
 
32
- const EXPECTED_COLOR = c.green;
33
- const RECEIVED_COLOR = c.red;
34
- const INVERTED_COLOR = c.inverse;
35
- const BOLD_WEIGHT = c.bold;
36
- const DIM_COLOR = c.dim;
37
- function matcherHint(matcherName, received = "received", expected = "expected", options = {}) {
38
- const {
39
- comment = "",
40
- isDirectExpectCall = false,
41
- isNot = false,
42
- promise = "",
43
- secondArgument = "",
44
- expectedColor = EXPECTED_COLOR,
45
- receivedColor = RECEIVED_COLOR,
46
- secondArgumentColor = EXPECTED_COLOR
47
- } = options;
48
- let hint = "";
49
- let dimString = "expect";
50
- if (!isDirectExpectCall && received !== "") {
51
- hint += DIM_COLOR(`${dimString}(`) + receivedColor(received);
52
- dimString = ")";
53
- }
54
- if (promise !== "") {
55
- hint += DIM_COLOR(`${dimString}.`) + promise;
56
- dimString = "";
57
- }
58
- if (isNot) {
59
- hint += `${DIM_COLOR(`${dimString}.`)}not`;
60
- dimString = "";
61
- }
62
- if (matcherName.includes(".")) {
63
- dimString += matcherName;
64
- } else {
65
- hint += DIM_COLOR(`${dimString}.`) + matcherName;
66
- dimString = "";
67
- }
68
- if (expected === "") {
69
- dimString += "()";
70
- } else {
71
- hint += DIM_COLOR(`${dimString}(`) + expectedColor(expected);
72
- if (secondArgument)
73
- hint += DIM_COLOR(", ") + secondArgumentColor(secondArgument);
74
- dimString = ")";
33
+ function getMatcherUtils() {
34
+ const c = () => getColors();
35
+ const EXPECTED_COLOR = c().green;
36
+ const RECEIVED_COLOR = c().red;
37
+ const INVERTED_COLOR = c().inverse;
38
+ const BOLD_WEIGHT = c().bold;
39
+ const DIM_COLOR = c().dim;
40
+ function matcherHint(matcherName, received = "received", expected = "expected", options = {}) {
41
+ const {
42
+ comment = "",
43
+ isDirectExpectCall = false,
44
+ isNot = false,
45
+ promise = "",
46
+ secondArgument = "",
47
+ expectedColor = EXPECTED_COLOR,
48
+ receivedColor = RECEIVED_COLOR,
49
+ secondArgumentColor = EXPECTED_COLOR
50
+ } = options;
51
+ let hint = "";
52
+ let dimString = "expect";
53
+ if (!isDirectExpectCall && received !== "") {
54
+ hint += DIM_COLOR(`${dimString}(`) + receivedColor(received);
55
+ dimString = ")";
56
+ }
57
+ if (promise !== "") {
58
+ hint += DIM_COLOR(`${dimString}.`) + promise;
59
+ dimString = "";
60
+ }
61
+ if (isNot) {
62
+ hint += `${DIM_COLOR(`${dimString}.`)}not`;
63
+ dimString = "";
64
+ }
65
+ if (matcherName.includes(".")) {
66
+ dimString += matcherName;
67
+ } else {
68
+ hint += DIM_COLOR(`${dimString}.`) + matcherName;
69
+ dimString = "";
70
+ }
71
+ if (expected === "") {
72
+ dimString += "()";
73
+ } else {
74
+ hint += DIM_COLOR(`${dimString}(`) + expectedColor(expected);
75
+ if (secondArgument)
76
+ hint += DIM_COLOR(", ") + secondArgumentColor(secondArgument);
77
+ dimString = ")";
78
+ }
79
+ if (comment !== "")
80
+ dimString += ` // ${comment}`;
81
+ if (dimString !== "")
82
+ hint += DIM_COLOR(dimString);
83
+ return hint;
75
84
  }
76
- if (comment !== "")
77
- dimString += ` // ${comment}`;
78
- if (dimString !== "")
79
- hint += DIM_COLOR(dimString);
80
- return hint;
85
+ const SPACE_SYMBOL = "\xB7";
86
+ const replaceTrailingSpaces = (text) => text.replace(/\s+$/gm, (spaces) => SPACE_SYMBOL.repeat(spaces.length));
87
+ const printReceived = (object) => RECEIVED_COLOR(replaceTrailingSpaces(stringify(object)));
88
+ const printExpected = (value) => EXPECTED_COLOR(replaceTrailingSpaces(stringify(value)));
89
+ return {
90
+ EXPECTED_COLOR,
91
+ RECEIVED_COLOR,
92
+ INVERTED_COLOR,
93
+ BOLD_WEIGHT,
94
+ DIM_COLOR,
95
+ matcherHint,
96
+ printReceived,
97
+ printExpected
98
+ };
81
99
  }
82
- const SPACE_SYMBOL = "\xB7";
83
- const replaceTrailingSpaces = (text) => text.replace(/\s+$/gm, (spaces) => SPACE_SYMBOL.repeat(spaces.length));
84
- const printReceived = (object) => RECEIVED_COLOR(replaceTrailingSpaces(stringify(object)));
85
- const printExpected = (value) => EXPECTED_COLOR(replaceTrailingSpaces(stringify(value)));
86
100
  function diff(a, b, options) {
87
- return unifiedDiff(stringify(b), stringify(a));
101
+ const c = getColors();
102
+ return unifiedDiff(stringify(b), stringify(a), {
103
+ colorDim: c.dim,
104
+ colorSuccess: c.green,
105
+ colorError: c.red,
106
+ showLegend: options == null ? void 0 : options.showLegend
107
+ });
88
108
  }
89
109
 
90
110
  var matcherUtils = /*#__PURE__*/Object.freeze({
91
111
  __proto__: null,
92
112
  stringify: stringify,
93
- EXPECTED_COLOR: EXPECTED_COLOR,
94
- RECEIVED_COLOR: RECEIVED_COLOR,
95
- INVERTED_COLOR: INVERTED_COLOR,
96
- BOLD_WEIGHT: BOLD_WEIGHT,
97
- DIM_COLOR: DIM_COLOR,
98
- matcherHint: matcherHint,
99
- printReceived: printReceived,
100
- printExpected: printExpected,
113
+ getMatcherUtils: getMatcherUtils,
101
114
  diff: diff
102
115
  });
103
116
 
@@ -609,6 +622,7 @@ const JestAsymmetricMatchers = (chai, utils) => {
609
622
  };
610
623
 
611
624
  const JestChaiExpect = (chai, utils) => {
625
+ const c = () => getColors();
612
626
  function def(name, fn) {
613
627
  const addMethod = (n) => {
614
628
  utils.addMethod(chai.Assertion.prototype, n, fn);
@@ -913,44 +927,44 @@ const JestChaiExpect = (chai, utils) => {
913
927
  return `${i}th`;
914
928
  };
915
929
  const formatCalls = (spy, msg, actualCall) => {
916
- msg += c.gray(`
930
+ msg += c().gray(`
917
931
 
918
932
  Received:
919
933
  ${spy.mock.calls.map((callArg, i) => {
920
- let methodCall = c.bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call:
934
+ let methodCall = c().bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call:
921
935
 
922
936
  `);
923
937
  if (actualCall)
924
- methodCall += unifiedDiff(stringify(callArg), stringify(actualCall), { showLegend: false });
938
+ methodCall += diff(callArg, actualCall, { showLegend: false });
925
939
  else
926
940
  methodCall += stringify(callArg).split("\n").map((line) => ` ${line}`).join("\n");
927
941
  methodCall += "\n";
928
942
  return methodCall;
929
943
  }).join("\n")}`);
930
- msg += c.gray(`
944
+ msg += c().gray(`
931
945
 
932
- Number of calls: ${c.bold(spy.mock.calls.length)}
946
+ Number of calls: ${c().bold(spy.mock.calls.length)}
933
947
  `);
934
948
  return msg;
935
949
  };
936
950
  const formatReturns = (spy, msg, actualReturn) => {
937
- msg += c.gray(`
951
+ msg += c().gray(`
938
952
 
939
953
  Received:
940
954
  ${spy.mock.results.map((callReturn, i) => {
941
- let methodCall = c.bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call return:
955
+ let methodCall = c().bold(` ${ordinalOf(i + 1)} ${spy.getMockName()} call return:
942
956
 
943
957
  `);
944
958
  if (actualReturn)
945
- methodCall += unifiedDiff(stringify(callReturn.value), stringify(actualReturn), { showLegend: false });
959
+ methodCall += diff(callReturn.value, actualReturn, { showLegend: false });
946
960
  else
947
961
  methodCall += stringify(callReturn).split("\n").map((line) => ` ${line}`).join("\n");
948
962
  methodCall += "\n";
949
963
  return methodCall;
950
964
  }).join("\n")}`);
951
- msg += c.gray(`
965
+ msg += c().gray(`
952
966
 
953
- Number of calls: ${c.bold(spy.mock.calls.length)}
967
+ Number of calls: ${c().bold(spy.mock.calls.length)}
954
968
  `);
955
969
  return msg;
956
970
  };
@@ -1236,13 +1250,14 @@ Number of calls: ${c.bold(spy.mock.calls.length)}
1236
1250
  });
1237
1251
  };
1238
1252
 
1239
- const isAsyncFunction = (fn) => typeof fn === "function" && fn[Symbol.toStringTag] === "AsyncFunction";
1240
1253
  const getMatcherState = (assertion, expect) => {
1241
1254
  const obj = assertion._obj;
1242
1255
  const isNot = util.flag(assertion, "negate");
1243
1256
  const promise = util.flag(assertion, "promise") || "";
1244
1257
  const jestUtils = {
1245
- ...matcherUtils,
1258
+ ...getMatcherUtils(),
1259
+ diff,
1260
+ stringify,
1246
1261
  iterableEquality,
1247
1262
  subsetEquality
1248
1263
  };
@@ -1270,21 +1285,21 @@ class JestExtendError extends Error {
1270
1285
  function JestExtendPlugin(expect, matchers) {
1271
1286
  return (c, utils) => {
1272
1287
  Object.entries(matchers).forEach(([expectAssertionName, expectAssertion]) => {
1273
- function expectSyncWrapper(...args) {
1274
- const { state, isNot, obj } = getMatcherState(this, expect);
1275
- const { pass, message, actual, expected } = expectAssertion.call(state, obj, ...args);
1276
- if (pass && isNot || !pass && !isNot)
1277
- throw new JestExtendError(message(), actual, expected);
1278
- }
1279
- async function expectAsyncWrapper(...args) {
1288
+ function expectWrapper(...args) {
1280
1289
  const { state, isNot, obj } = getMatcherState(this, expect);
1281
- const { pass, message, actual, expected } = await expectAssertion.call(state, obj, ...args);
1290
+ const result = expectAssertion.call(state, obj, ...args);
1291
+ if (result && typeof result === "object" && result instanceof Promise) {
1292
+ return result.then(({ pass: pass2, message: message2, actual: actual2, expected: expected2 }) => {
1293
+ if (pass2 && isNot || !pass2 && !isNot)
1294
+ throw new JestExtendError(message2(), actual2, expected2);
1295
+ });
1296
+ }
1297
+ const { pass, message, actual, expected } = result;
1282
1298
  if (pass && isNot || !pass && !isNot)
1283
1299
  throw new JestExtendError(message(), actual, expected);
1284
1300
  }
1285
- const expectAssertionWrapper = isAsyncFunction(expectAssertion) ? expectAsyncWrapper : expectSyncWrapper;
1286
- utils.addMethod(globalThis[JEST_MATCHERS_OBJECT].matchers, expectAssertionName, expectAssertionWrapper);
1287
- utils.addMethod(c.Assertion.prototype, expectAssertionName, expectAssertionWrapper);
1301
+ utils.addMethod(globalThis[JEST_MATCHERS_OBJECT].matchers, expectAssertionName, expectWrapper);
1302
+ utils.addMethod(c.Assertion.prototype, expectAssertionName, expectWrapper);
1288
1303
  class CustomMatcher extends AsymmetricMatcher {
1289
1304
  constructor(inverse = false, ...sample) {
1290
1305
  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.27.2",
4
+ "version": "0.28.0",
5
5
  "description": "Jest's expect matchers as a Chai plugin",
6
6
  "license": "MIT",
7
7
  "repository": {
@@ -25,9 +25,11 @@
25
25
  ],
26
26
  "dependencies": {
27
27
  "chai": "^4.3.7",
28
- "picocolors": "^1.0.0",
29
- "@vitest/utils": "0.27.2",
30
- "@vitest/spy": "0.27.2"
28
+ "@vitest/utils": "0.28.0",
29
+ "@vitest/spy": "0.28.0"
30
+ },
31
+ "devDependencies": {
32
+ "picocolors": "^1.0.0"
31
33
  },
32
34
  "scripts": {
33
35
  "build": "rimraf dist && rollup -c",