@vitest/snapshot 2.2.0-beta.2 → 3.0.0-beta.2

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,5 +1,5 @@
1
- import { S as SnapshotStateOptions, a as SnapshotMatchOptions, b as SnapshotResult, R as RawSnapshotInfo } from './rawSnapshot-CGKRMgF8.js';
2
- export { c as SnapshotData, d as SnapshotSerializer, e as SnapshotSummary, f as SnapshotUpdateState, U as UncheckedSnapshot } from './rawSnapshot-CGKRMgF8.js';
1
+ import { S as SnapshotStateOptions, a as SnapshotMatchOptions, b as SnapshotResult, R as RawSnapshotInfo } from './rawSnapshot-BWAfsPv1.js';
2
+ export { c as SnapshotData, d as SnapshotSerializer, e as SnapshotSummary, f as SnapshotUpdateState, U as UncheckedSnapshot } from './rawSnapshot-BWAfsPv1.js';
3
3
  import { S as SnapshotEnvironment } from './environment-Ddx0EDtY.js';
4
4
  import { Plugin, Plugins } from '@vitest/pretty-format';
5
5
 
@@ -38,35 +38,41 @@ declare class SnapshotState {
38
38
  private _initialData;
39
39
  private _inlineSnapshots;
40
40
  private _inlineSnapshotStacks;
41
+ private _testIdToKeys;
41
42
  private _rawSnapshots;
42
43
  private _uncheckedKeys;
43
44
  private _snapshotFormat;
44
45
  private _environment;
45
46
  private _fileExists;
46
- added: number;
47
+ private added;
48
+ private matched;
49
+ private unmatched;
50
+ private updated;
47
51
  expand: boolean;
48
- matched: number;
49
- unmatched: number;
50
- updated: number;
51
52
  private constructor();
52
53
  static create(testFilePath: string, options: SnapshotStateOptions): Promise<SnapshotState>;
53
54
  get environment(): SnapshotEnvironment;
54
55
  markSnapshotsAsCheckedForTest(testName: string): void;
56
+ clearTest(testId: string): void;
55
57
  protected _inferInlineSnapshotStack(stacks: ParsedStack[]): ParsedStack | null;
56
58
  private _addSnapshot;
57
- clear(): void;
58
59
  save(): Promise<SaveStatus>;
59
60
  getUncheckedCount(): number;
60
61
  getUncheckedKeys(): Array<string>;
61
62
  removeUncheckedKeys(): void;
62
- match({ testName, received, key, inlineSnapshot, isInline, error, rawSnapshot, }: SnapshotMatchOptions): SnapshotReturnOptions;
63
+ match({ testId, testName, received, key, inlineSnapshot, isInline, error, rawSnapshot, }: SnapshotMatchOptions): SnapshotReturnOptions;
63
64
  pack(): Promise<SnapshotResult>;
64
65
  }
65
66
 
66
67
  interface AssertOptions {
67
68
  received: unknown;
68
- filepath?: string;
69
- name?: string;
69
+ filepath: string;
70
+ name: string;
71
+ /**
72
+ * Not required but needed for `SnapshotClient.clearTest` to implement test-retry behavior.
73
+ * @default name
74
+ */
75
+ testId?: string;
70
76
  message?: string;
71
77
  isInline?: boolean;
72
78
  properties?: object;
@@ -80,18 +86,15 @@ interface SnapshotClientOptions {
80
86
  }
81
87
  declare class SnapshotClient {
82
88
  private options;
83
- filepath?: string;
84
- name?: string;
85
- snapshotState: SnapshotState | undefined;
86
89
  snapshotStateMap: Map<string, SnapshotState>;
87
90
  constructor(options?: SnapshotClientOptions);
88
- startCurrentRun(filepath: string, name: string, options: SnapshotStateOptions): Promise<void>;
91
+ setup(filepath: string, options: SnapshotStateOptions): Promise<void>;
92
+ finish(filepath: string): Promise<SnapshotResult>;
93
+ skipTest(filepath: string, testName: string): void;
94
+ clearTest(filepath: string, testId: string): void;
89
95
  getSnapshotState(filepath: string): SnapshotState;
90
- clearTest(): void;
91
- skipTestSnapshots(name: string): void;
92
96
  assert(options: AssertOptions): void;
93
97
  assertRaw(options: AssertOptions): Promise<void>;
94
- finishCurrentRun(): Promise<SnapshotResult | null>;
95
98
  clear(): void;
96
99
  }
97
100
 
package/dist/index.js CHANGED
@@ -1783,6 +1783,33 @@ function deepMergeSnapshot(target, source) {
1783
1783
  }
1784
1784
  return target;
1785
1785
  }
1786
+ class DefaultMap extends Map {
1787
+ constructor(defaultFn, entries) {
1788
+ super(entries);
1789
+ this.defaultFn = defaultFn;
1790
+ }
1791
+ get(key) {
1792
+ if (!this.has(key)) {
1793
+ this.set(key, this.defaultFn(key));
1794
+ }
1795
+ return super.get(key);
1796
+ }
1797
+ }
1798
+ class CounterMap extends DefaultMap {
1799
+ constructor() {
1800
+ super(() => 0);
1801
+ }
1802
+ increment(key) {
1803
+ this.set(key, this.get(key) + 1);
1804
+ }
1805
+ total() {
1806
+ let total = 0;
1807
+ for (const x of this.values()) {
1808
+ total += x;
1809
+ }
1810
+ return total;
1811
+ }
1812
+ }
1786
1813
 
1787
1814
  class SnapshotState {
1788
1815
  constructor(testFilePath, snapshotPath, snapshotContent, options) {
@@ -1790,20 +1817,15 @@ class SnapshotState {
1790
1817
  this.snapshotPath = snapshotPath;
1791
1818
  const { data, dirty } = getSnapshotData(snapshotContent, options);
1792
1819
  this._fileExists = snapshotContent != null;
1793
- this._initialData = data;
1794
- this._snapshotData = data;
1820
+ this._initialData = { ...data };
1821
+ this._snapshotData = { ...data };
1795
1822
  this._dirty = dirty;
1796
1823
  this._inlineSnapshots = [];
1797
1824
  this._inlineSnapshotStacks = [];
1798
1825
  this._rawSnapshots = [];
1799
1826
  this._uncheckedKeys = new Set(Object.keys(this._snapshotData));
1800
- this._counters = /* @__PURE__ */ new Map();
1801
1827
  this.expand = options.expand || false;
1802
- this.added = 0;
1803
- this.matched = 0;
1804
- this.unmatched = 0;
1805
1828
  this._updateSnapshot = options.updateSnapshot;
1806
- this.updated = 0;
1807
1829
  this._snapshotFormat = {
1808
1830
  printBasicPrototype: false,
1809
1831
  escapeString: false,
@@ -1811,23 +1833,24 @@ class SnapshotState {
1811
1833
  };
1812
1834
  this._environment = options.snapshotEnvironment;
1813
1835
  }
1814
- _counters;
1836
+ _counters = new CounterMap();
1815
1837
  _dirty;
1816
1838
  _updateSnapshot;
1817
1839
  _snapshotData;
1818
1840
  _initialData;
1819
1841
  _inlineSnapshots;
1820
1842
  _inlineSnapshotStacks;
1843
+ _testIdToKeys = new DefaultMap(() => []);
1821
1844
  _rawSnapshots;
1822
1845
  _uncheckedKeys;
1823
1846
  _snapshotFormat;
1824
1847
  _environment;
1825
1848
  _fileExists;
1826
- added;
1849
+ added = new CounterMap();
1850
+ matched = new CounterMap();
1851
+ unmatched = new CounterMap();
1852
+ updated = new CounterMap();
1827
1853
  expand;
1828
- matched;
1829
- unmatched;
1830
- updated;
1831
1854
  static async create(testFilePath, options) {
1832
1855
  const snapshotPath = await options.snapshotEnvironment.resolvePath(
1833
1856
  testFilePath
@@ -1847,6 +1870,25 @@ class SnapshotState {
1847
1870
  }
1848
1871
  });
1849
1872
  }
1873
+ clearTest(testId) {
1874
+ this._inlineSnapshots = this._inlineSnapshots.filter((s) => s.testId !== testId);
1875
+ this._inlineSnapshotStacks = this._inlineSnapshotStacks.filter((s) => s.testId !== testId);
1876
+ for (const key of this._testIdToKeys.get(testId)) {
1877
+ const name = keyToTestName(key);
1878
+ const count = this._counters.get(name);
1879
+ if (count > 0) {
1880
+ if (key in this._snapshotData || key in this._initialData) {
1881
+ this._snapshotData[key] = this._initialData[key];
1882
+ }
1883
+ this._counters.set(name, count - 1);
1884
+ }
1885
+ }
1886
+ this._testIdToKeys.delete(testId);
1887
+ this.added.delete(testId);
1888
+ this.updated.delete(testId);
1889
+ this.matched.delete(testId);
1890
+ this.unmatched.delete(testId);
1891
+ }
1850
1892
  _inferInlineSnapshotStack(stacks) {
1851
1893
  const promiseIndex = stacks.findIndex(
1852
1894
  (i) => i.method.match(/__VITEST_(RESOLVES|REJECTS)__/)
@@ -1864,6 +1906,7 @@ class SnapshotState {
1864
1906
  if (options.stack) {
1865
1907
  this._inlineSnapshots.push({
1866
1908
  snapshot: receivedSerialized,
1909
+ testId: options.testId,
1867
1910
  ...options.stack
1868
1911
  });
1869
1912
  } else if (options.rawSnapshot) {
@@ -1875,15 +1918,6 @@ class SnapshotState {
1875
1918
  this._snapshotData[key] = receivedSerialized;
1876
1919
  }
1877
1920
  }
1878
- clear() {
1879
- this._snapshotData = this._initialData;
1880
- this._counters = /* @__PURE__ */ new Map();
1881
- this.added = 0;
1882
- this.matched = 0;
1883
- this.unmatched = 0;
1884
- this.updated = 0;
1885
- this._dirty = false;
1886
- }
1887
1921
  async save() {
1888
1922
  const hasExternalSnapshots = Object.keys(this._snapshotData).length;
1889
1923
  const hasInlineSnapshots = this._inlineSnapshots.length;
@@ -1932,6 +1966,7 @@ class SnapshotState {
1932
1966
  }
1933
1967
  }
1934
1968
  match({
1969
+ testId,
1935
1970
  testName,
1936
1971
  received,
1937
1972
  key,
@@ -1941,11 +1976,12 @@ class SnapshotState {
1941
1976
  rawSnapshot
1942
1977
  }) {
1943
1978
  var _a, _b;
1944
- this._counters.set(testName, (this._counters.get(testName) || 0) + 1);
1945
- const count = Number(this._counters.get(testName));
1979
+ this._counters.increment(testName);
1980
+ const count = this._counters.get(testName);
1946
1981
  if (!key) {
1947
1982
  key = testNameToKey(testName, count);
1948
1983
  }
1984
+ this._testIdToKeys.get(testId).push(key);
1949
1985
  if (!(isInline && this._snapshotData[key] !== void 0)) {
1950
1986
  this._uncheckedKeys.delete(key);
1951
1987
  }
@@ -1987,29 +2023,31 @@ ${JSON.stringify(
1987
2023
  this._inlineSnapshots = this._inlineSnapshots.filter((s) => !(s.file === stack.file && s.line === stack.line && s.column === stack.column));
1988
2024
  throw new Error("toMatchInlineSnapshot cannot be called multiple times at the same location.");
1989
2025
  }
1990
- this._inlineSnapshotStacks.push(stack);
2026
+ this._inlineSnapshotStacks.push({ ...stack, testId });
1991
2027
  }
1992
2028
  if (hasSnapshot && this._updateSnapshot === "all" || (!hasSnapshot || !snapshotIsPersisted) && (this._updateSnapshot === "new" || this._updateSnapshot === "all")) {
1993
2029
  if (this._updateSnapshot === "all") {
1994
2030
  if (!pass) {
1995
2031
  if (hasSnapshot) {
1996
- this.updated++;
2032
+ this.updated.increment(testId);
1997
2033
  } else {
1998
- this.added++;
2034
+ this.added.increment(testId);
1999
2035
  }
2000
2036
  this._addSnapshot(key, receivedSerialized, {
2001
2037
  stack,
2038
+ testId,
2002
2039
  rawSnapshot
2003
2040
  });
2004
2041
  } else {
2005
- this.matched++;
2042
+ this.matched.increment(testId);
2006
2043
  }
2007
2044
  } else {
2008
2045
  this._addSnapshot(key, receivedSerialized, {
2009
2046
  stack,
2047
+ testId,
2010
2048
  rawSnapshot
2011
2049
  });
2012
- this.added++;
2050
+ this.added.increment(testId);
2013
2051
  }
2014
2052
  return {
2015
2053
  actual: "",
@@ -2020,7 +2058,7 @@ ${JSON.stringify(
2020
2058
  };
2021
2059
  } else {
2022
2060
  if (!pass) {
2023
- this.unmatched++;
2061
+ this.unmatched.increment(testId);
2024
2062
  return {
2025
2063
  actual: removeExtraLineBreaks(receivedSerialized),
2026
2064
  count,
@@ -2029,7 +2067,7 @@ ${JSON.stringify(
2029
2067
  pass: false
2030
2068
  };
2031
2069
  } else {
2032
- this.matched++;
2070
+ this.matched.increment(testId);
2033
2071
  return {
2034
2072
  actual: "",
2035
2073
  count,
@@ -2058,10 +2096,10 @@ ${JSON.stringify(
2058
2096
  }
2059
2097
  const status = await this.save();
2060
2098
  snapshot.fileDeleted = status.deleted;
2061
- snapshot.added = this.added;
2062
- snapshot.matched = this.matched;
2063
- snapshot.unmatched = this.unmatched;
2064
- snapshot.updated = this.updated;
2099
+ snapshot.added = this.added.total();
2100
+ snapshot.matched = this.matched.total();
2101
+ snapshot.unmatched = this.unmatched.total();
2102
+ snapshot.updated = this.updated.total();
2065
2103
  snapshot.unchecked = !status.deleted ? uncheckedCount : 0;
2066
2104
  snapshot.uncheckedKeys = Array.from(uncheckedKeys);
2067
2105
  return snapshot;
@@ -2089,41 +2127,45 @@ class SnapshotClient {
2089
2127
  constructor(options = {}) {
2090
2128
  this.options = options;
2091
2129
  }
2092
- filepath;
2093
- name;
2094
- snapshotState;
2095
2130
  snapshotStateMap = /* @__PURE__ */ new Map();
2096
- async startCurrentRun(filepath, name, options) {
2097
- var _a;
2098
- this.filepath = filepath;
2099
- this.name = name;
2100
- if (((_a = this.snapshotState) == null ? void 0 : _a.testFilePath) !== filepath) {
2101
- await this.finishCurrentRun();
2102
- if (!this.getSnapshotState(filepath)) {
2103
- this.snapshotStateMap.set(
2104
- filepath,
2105
- await SnapshotState.create(filepath, options)
2106
- );
2107
- }
2108
- this.snapshotState = this.getSnapshotState(filepath);
2131
+ async setup(filepath, options) {
2132
+ if (this.snapshotStateMap.has(filepath)) {
2133
+ return;
2109
2134
  }
2135
+ this.snapshotStateMap.set(
2136
+ filepath,
2137
+ await SnapshotState.create(filepath, options)
2138
+ );
2110
2139
  }
2111
- getSnapshotState(filepath) {
2112
- return this.snapshotStateMap.get(filepath);
2140
+ async finish(filepath) {
2141
+ const state = this.getSnapshotState(filepath);
2142
+ const result = await state.pack();
2143
+ this.snapshotStateMap.delete(filepath);
2144
+ return result;
2113
2145
  }
2114
- clearTest() {
2115
- this.filepath = void 0;
2116
- this.name = void 0;
2146
+ skipTest(filepath, testName) {
2147
+ const state = this.getSnapshotState(filepath);
2148
+ state.markSnapshotsAsCheckedForTest(testName);
2117
2149
  }
2118
- skipTestSnapshots(name) {
2119
- var _a;
2120
- (_a = this.snapshotState) == null ? void 0 : _a.markSnapshotsAsCheckedForTest(name);
2150
+ clearTest(filepath, testId) {
2151
+ const state = this.getSnapshotState(filepath);
2152
+ state.clearTest(testId);
2153
+ }
2154
+ getSnapshotState(filepath) {
2155
+ const state = this.snapshotStateMap.get(filepath);
2156
+ if (!state) {
2157
+ throw new Error(
2158
+ `The snapshot state for '${filepath}' is not found. Did you call 'SnapshotClient.setup()'?`
2159
+ );
2160
+ }
2161
+ return state;
2121
2162
  }
2122
2163
  assert(options) {
2123
- var _a, _b, _c, _d;
2164
+ var _a, _b;
2124
2165
  const {
2125
- filepath = this.filepath,
2126
- name = this.name,
2166
+ filepath,
2167
+ name,
2168
+ testId = name,
2127
2169
  message,
2128
2170
  isInline = false,
2129
2171
  properties,
@@ -2136,6 +2178,7 @@ class SnapshotClient {
2136
2178
  if (!filepath) {
2137
2179
  throw new Error("Snapshot cannot be used outside of test");
2138
2180
  }
2181
+ const snapshotState = this.getSnapshotState(filepath);
2139
2182
  if (typeof properties === "object") {
2140
2183
  if (typeof received !== "object" || !received) {
2141
2184
  throw new Error(
@@ -2147,7 +2190,7 @@ class SnapshotClient {
2147
2190
  if (!pass2) {
2148
2191
  throw createMismatchError(
2149
2192
  "Snapshot properties mismatched",
2150
- (_c = this.snapshotState) == null ? void 0 : _c.expand,
2193
+ snapshotState.expand,
2151
2194
  received,
2152
2195
  properties
2153
2196
  );
@@ -2160,8 +2203,8 @@ class SnapshotClient {
2160
2203
  }
2161
2204
  }
2162
2205
  const testName = [name, ...message ? [message] : []].join(" > ");
2163
- const snapshotState = this.getSnapshotState(filepath);
2164
2206
  const { actual, expected, key, pass } = snapshotState.match({
2207
+ testId,
2165
2208
  testName,
2166
2209
  received,
2167
2210
  isInline,
@@ -2172,7 +2215,7 @@ class SnapshotClient {
2172
2215
  if (!pass) {
2173
2216
  throw createMismatchError(
2174
2217
  `Snapshot \`${key || "unknown"}\` mismatched`,
2175
- (_d = this.snapshotState) == null ? void 0 : _d.expand,
2218
+ snapshotState.expand,
2176
2219
  actual == null ? void 0 : actual.trim(),
2177
2220
  expected == null ? void 0 : expected.trim()
2178
2221
  );
@@ -2182,7 +2225,7 @@ class SnapshotClient {
2182
2225
  if (!options.rawSnapshot) {
2183
2226
  throw new Error("Raw snapshot is required");
2184
2227
  }
2185
- const { filepath = this.filepath, rawSnapshot } = options;
2228
+ const { filepath, rawSnapshot } = options;
2186
2229
  if (rawSnapshot.content == null) {
2187
2230
  if (!filepath) {
2188
2231
  throw new Error("Snapshot cannot be used outside of test");
@@ -2197,14 +2240,6 @@ class SnapshotClient {
2197
2240
  }
2198
2241
  return this.assert(options);
2199
2242
  }
2200
- async finishCurrentRun() {
2201
- if (!this.snapshotState) {
2202
- return null;
2203
- }
2204
- const result = await this.snapshotState.pack();
2205
- this.snapshotState = void 0;
2206
- return result;
2207
- }
2208
2243
  clear() {
2209
2244
  this.snapshotStateMap.clear();
2210
2245
  }
package/dist/manager.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { S as SnapshotStateOptions, e as SnapshotSummary, b as SnapshotResult } from './rawSnapshot-CGKRMgF8.js';
1
+ import { S as SnapshotStateOptions, e as SnapshotSummary, b as SnapshotResult } from './rawSnapshot-BWAfsPv1.js';
2
2
  import '@vitest/pretty-format';
3
3
  import './environment-Ddx0EDtY.js';
4
4
 
package/dist/manager.js CHANGED
@@ -5,7 +5,7 @@ class SnapshotManager {
5
5
  this.options = options;
6
6
  this.clear();
7
7
  }
8
- summary = void 0;
8
+ summary;
9
9
  extension = ".snap";
10
10
  clear() {
11
11
  this.summary = emptySummary(this.options);
@@ -12,6 +12,7 @@ interface SnapshotStateOptions {
12
12
  resolveSnapshotPath?: (path: string, extension: string, context?: any) => string;
13
13
  }
14
14
  interface SnapshotMatchOptions {
15
+ testId: string;
15
16
  testName: string;
16
17
  received: unknown;
17
18
  key?: string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vitest/snapshot",
3
3
  "type": "module",
4
- "version": "2.2.0-beta.2",
4
+ "version": "3.0.0-beta.2",
5
5
  "description": "Vitest snapshot manager",
6
6
  "license": "MIT",
7
7
  "funding": "https://opencollective.com/vitest",
@@ -38,14 +38,14 @@
38
38
  "dist"
39
39
  ],
40
40
  "dependencies": {
41
- "magic-string": "^0.30.12",
41
+ "magic-string": "^0.30.14",
42
42
  "pathe": "^1.1.2",
43
- "@vitest/pretty-format": "2.2.0-beta.2"
43
+ "@vitest/pretty-format": "3.0.0-beta.2"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/natural-compare": "^1.4.3",
47
47
  "natural-compare": "^1.4.0",
48
- "@vitest/utils": "2.2.0-beta.2"
48
+ "@vitest/utils": "3.0.0-beta.2"
49
49
  },
50
50
  "scripts": {
51
51
  "build": "rimraf dist && rollup -c",