@cronn/lib-file-snapshots 0.16.0 → 0.18.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
@@ -103,7 +103,14 @@ interface ValidationFileMatcherConfig {
103
103
  * The serializer to use for the snapshot
104
104
  */
105
105
  serializer: SnapshotSerializer;
106
+ /**
107
+ * Whether to update golden masters with the actual result.
108
+ *
109
+ * @default "missing"
110
+ */
111
+ updateSnapshots?: UpdateSnapshotsType;
106
112
  }
113
+ type UpdateSnapshotsType = "all" | "missing" | "none";
107
114
  interface ValidationFileMatcherResult {
108
115
  actual: string;
109
116
  expected: string;
@@ -120,16 +127,19 @@ interface FilePathResolverParams {
120
127
  }
121
128
 
122
129
  declare class ValidationFileMatcher {
130
+ private readonly updateSnapshots;
123
131
  private readonly serializer;
124
132
  private readonly filePaths;
125
- private readonly validationFile;
133
+ private validationFile;
126
134
  constructor(config: ValidationFileMatcherConfig);
127
135
  get isValidationFileMissing(): boolean;
136
+ get isUpdate(): boolean;
128
137
  matchFileSnapshot(actual: unknown): ValidationFileMatcherResult;
129
138
  private buildFilePaths;
130
139
  private readValidationFile;
131
140
  private createMatcherResult;
132
141
  private writeFileSnapshots;
142
+ private resolveExpected;
133
143
  }
134
144
 
135
145
  declare function resolveNameAsFile(params: FilePathResolverParams): string;
@@ -142,4 +152,4 @@ declare function isArray(value: unknown): value is Array<unknown>;
142
152
  type PlainObject = Record<PropertyKey, unknown>;
143
153
  declare function isPlainObject(value: unknown): value is PlainObject;
144
154
 
145
- export { type FilePathResolver, type FilePathResolverParams, type JsonNormalizer, type JsonNormalizerContext, JsonSerializer, type PlainObject, type SnapshotSerializer, type TextNormalizer, TextSerializer, ValidationFileMatcher, type ValidationFileMatcherResult, isArray, isPlainObject, isString, normalizeFileName, resolveNameAsFile, resolveNameAsFileSuffix };
155
+ export { type FilePathResolver, type FilePathResolverParams, type JsonNormalizer, type JsonNormalizerContext, JsonSerializer, type PlainObject, type SnapshotSerializer, type TextNormalizer, TextSerializer, type UpdateSnapshotsType, ValidationFileMatcher, type ValidationFileMatcherResult, isArray, isPlainObject, isString, normalizeFileName, resolveNameAsFile, resolveNameAsFileSuffix };
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  // src/utils/file.ts
2
2
  import fs from "fs";
3
+ import os from "os";
3
4
  import path from "path";
4
5
  var NEW_LINE_SEPARATOR = "\n";
5
6
  var EMOJI_REGEXP = /(?!(\*|#|\d))[\p{Extended_Pictographic}\p{Emoji_Component}]|[\u0030-\u0039]\ufe0f?[\u20e3]|[\u002A\u0023]?\ufe0f?[\u20e3]/gu;
@@ -7,7 +8,11 @@ function normalizeFileName(testName) {
7
8
  return testName.replaceAll(EMOJI_REGEXP, "").replaceAll(/[+*%~<>?!$#'"`|\\/()[\]{}]/g, "").replaceAll(/[\s.:,;]+/g, "_").replaceAll(/_{2,}/g, "_");
8
9
  }
9
10
  function readSnapshotFile(path4) {
10
- return fs.readFileSync(path4, { encoding: "utf8" });
11
+ const contents = fs.readFileSync(path4, { encoding: "utf8" });
12
+ if (os.EOL === NEW_LINE_SEPARATOR) {
13
+ return contents;
14
+ }
15
+ return contents.replace(new RegExp(os.EOL, "g"), NEW_LINE_SEPARATOR);
11
16
  }
12
17
  function writeSnapshotFile(file, data) {
13
18
  mkdirRecursive(path.dirname(file));
@@ -245,10 +250,12 @@ var TextSerializer = class {
245
250
  import * as fs2 from "fs";
246
251
  import * as path2 from "path";
247
252
  var ValidationFileMatcher = class {
253
+ updateSnapshots;
248
254
  serializer;
249
255
  filePaths;
250
256
  validationFile;
251
257
  constructor(config) {
258
+ this.updateSnapshots = config.updateSnapshots ?? "missing";
252
259
  this.serializer = config.serializer;
253
260
  this.filePaths = this.buildFilePaths(config);
254
261
  this.validationFile = this.readValidationFile();
@@ -256,20 +263,18 @@ var ValidationFileMatcher = class {
256
263
  get isValidationFileMissing() {
257
264
  return this.validationFile === void 0;
258
265
  }
266
+ get isUpdate() {
267
+ return this.updateSnapshots === "all" || this.isValidationFileMissing && this.updateSnapshots === "missing";
268
+ }
259
269
  matchFileSnapshot(actual) {
260
270
  if (!this.serializer.canSerialize(actual)) {
261
271
  throw new Error(`Cannot serialize value of type ${typeof actual}`);
262
272
  }
263
273
  const serializedActual = this.serializer.serialize(actual);
264
- if (this.validationFile === void 0) {
265
- return this.createMatcherResult({
266
- actual: serializedActual,
267
- expected: addMissingFileMarker(serializedActual)
268
- });
269
- }
274
+ const expected = this.resolveExpected(serializedActual);
270
275
  return this.createMatcherResult({
271
276
  actual: serializedActual,
272
- expected: this.validationFile
277
+ expected
273
278
  });
274
279
  }
275
280
  buildFilePaths(config) {
@@ -304,9 +309,17 @@ does not match validation file '${validationFilePath}'`,
304
309
  const { actual, expected } = matcherResult;
305
310
  const { outputFilePath, validationFilePath } = this.filePaths;
306
311
  writeSnapshotFile(outputFilePath, actual);
307
- if (this.isValidationFileMissing) {
308
- writeSnapshotFile(validationFilePath, expected);
312
+ if (this.isUpdate) {
313
+ const validationFileData = this.isValidationFileMissing ? expected : actual;
314
+ writeSnapshotFile(validationFilePath, validationFileData);
315
+ this.validationFile = validationFileData;
316
+ }
317
+ }
318
+ resolveExpected(actual) {
319
+ if (this.validationFile === void 0) {
320
+ return addMissingFileMarker(actual);
309
321
  }
322
+ return this.validationFile;
310
323
  }
311
324
  };
312
325
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cronn/lib-file-snapshots",
3
- "version": "0.16.0",
3
+ "version": "0.18.0",
4
4
  "description": "The library agnostic core for testing file snapshots",
5
5
  "keywords": [
6
6
  "file snapshots"
@@ -17,8 +17,19 @@
17
17
  },
18
18
  "homepage": "https://github.com/cronn/file-snapshots",
19
19
  "engines": {
20
- "node": ">=22.18",
21
- "pnpm": ">=10"
20
+ "node": "^20 || ^22 || >=24"
21
+ },
22
+ "devEngines": {
23
+ "runtime": {
24
+ "name": "node",
25
+ "version": ">=24.11 <25",
26
+ "onFail": "error"
27
+ },
28
+ "packageManager": {
29
+ "name": "pnpm",
30
+ "version": ">=10.27 <11",
31
+ "onFail": "error"
32
+ }
22
33
  },
23
34
  "type": "module",
24
35
  "exports": {
@@ -32,17 +43,17 @@
32
43
  "dist"
33
44
  ],
34
45
  "devDependencies": {
35
- "@trivago/prettier-plugin-sort-imports": "5.2.2",
36
- "@types/node": "22.18.6",
37
- "@vitest/coverage-istanbul": "3.2.4",
38
- "eslint": "9.36.0",
46
+ "@trivago/prettier-plugin-sort-imports": "6.0.2",
47
+ "@types/node": "24.10.7",
48
+ "@vitest/coverage-v8": "4.0.17",
49
+ "eslint": "9.39.2",
39
50
  "eslint-config-prettier": "10.1.8",
40
- "eslint-plugin-unused-imports": "4.2.0",
41
- "prettier": "3.6.2",
42
- "tsup": "8.5.0",
43
- "typescript": "5.9.2",
44
- "typescript-eslint": "8.44.0",
45
- "vitest": "3.2.4",
51
+ "eslint-plugin-unused-imports": "4.3.0",
52
+ "prettier": "3.7.4",
53
+ "tsup": "8.5.1",
54
+ "typescript": "5.9.3",
55
+ "typescript-eslint": "8.53.0",
56
+ "vitest": "4.0.17",
46
57
  "@cronn/shared-configs": "0.0.0"
47
58
  },
48
59
  "scripts": {