@cronn/lib-file-snapshots 0.6.0 → 0.8.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
@@ -34,7 +34,7 @@ interface JsonSerializerOptions {
34
34
  /**
35
35
  * Custom normalizers to apply before serialization
36
36
  */
37
- normalizers?: JsonNormalizer[];
37
+ normalizers?: Array<JsonNormalizer>;
38
38
  }
39
39
  type JsonNormalizer = (value: unknown, context: JsonNormalizerContext) => unknown;
40
40
  interface JsonNormalizerContext {
@@ -44,7 +44,7 @@ declare class JsonSerializer implements SnapshotSerializer {
44
44
  private readonly includeUndefinedObjectProperties;
45
45
  private readonly normalizers;
46
46
  constructor(options?: JsonSerializerOptions);
47
- canSerialize(value: unknown): boolean;
47
+ canSerialize(_value: unknown): boolean;
48
48
  serialize(value: unknown): SnapshotSerializerResult;
49
49
  private normalizeValueRecursive;
50
50
  private normalizeNumber;
@@ -62,7 +62,7 @@ interface TextSerializerOptions {
62
62
  /**
63
63
  * Custom normalizers to apply before serialization
64
64
  */
65
- normalizers?: TextNormalizer[];
65
+ normalizers?: Array<TextNormalizer>;
66
66
  }
67
67
  type TextNormalizer = (value: string) => string;
68
68
  declare class TextSerializer implements SnapshotSerializer {
@@ -99,18 +99,25 @@ interface MatchValidationFileOptions {
99
99
  *
100
100
  * @example ["test A", "when x, then y"]
101
101
  */
102
- titlePath: string[];
102
+ titlePath: Array<string>;
103
103
  /**
104
104
  * Unique name of the file snapshot
105
105
  *
106
106
  * Used to distinguish multiple file snapshots within the same `test`.
107
107
  */
108
108
  name?: string;
109
+ /**
110
+ * The naming strategy to use for storing the file snapshot
111
+ *
112
+ * @default "file"
113
+ */
114
+ namingStrategy?: SnapshotNamingStrategy;
109
115
  /**
110
116
  * The serializer to use for the snapshot
111
117
  */
112
118
  serializer: SnapshotSerializer;
113
119
  }
120
+ type SnapshotNamingStrategy = "file" | "fileSuffix";
114
121
  interface ValidationFileMatcherResult {
115
122
  actual: string;
116
123
  expected: string;
@@ -125,12 +132,13 @@ declare class ValidationFileMatcher {
125
132
  constructor(config?: ValidationFileMatcherConfig);
126
133
  matchFileSnapshot(actual: unknown, options: MatchValidationFileOptions): ValidationFileMatcherResult;
127
134
  private buildValidationFilePath;
135
+ private applyNamingStrategy;
128
136
  private writeFileSnapshots;
129
137
  }
130
138
 
131
139
  declare function isString(value: unknown): value is string;
132
- declare function isArray(value: unknown): value is unknown[];
140
+ declare function isArray(value: unknown): value is Array<unknown>;
133
141
  type PlainObject = Record<PropertyKey, unknown>;
134
142
  declare function isPlainObject(value: unknown): value is PlainObject;
135
143
 
136
- export { type JsonNormalizer, type JsonNormalizerContext, JsonSerializer, type PlainObject, type SnapshotSerializer, type TextNormalizer, TextSerializer, ValidationFileMatcher, isArray, isPlainObject, isString };
144
+ export { type JsonNormalizer, type JsonNormalizerContext, JsonSerializer, type PlainObject, type SnapshotNamingStrategy, type SnapshotSerializer, type TextNormalizer, TextSerializer, ValidationFileMatcher, isArray, isPlainObject, isString };
package/dist/index.js CHANGED
@@ -24,7 +24,7 @@ var JsonSerializer = class {
24
24
  this.includeUndefinedObjectProperties = options.includeUndefinedObjectProperties ?? false;
25
25
  this.normalizers = options.normalizers ?? [];
26
26
  }
27
- canSerialize(value) {
27
+ canSerialize(_value) {
28
28
  return true;
29
29
  }
30
30
  serialize(value) {
@@ -214,7 +214,7 @@ import * as path from "path";
214
214
  import fs from "fs";
215
215
  var NEW_LINE_SEPARATOR = "\n";
216
216
  function normalizeFileName(testName) {
217
- return testName.replaceAll(/\+0/g, "0").replaceAll(/'([\w ]+)'/g, "$1").replaceAll(/[ .:']/g, "_").replaceAll(/,/g, "");
217
+ return testName.replaceAll(/[+*%~<>?!$#'"`|\\/()[\]{}]/g, "").replaceAll(/[\s.:,;]+/g, "_").replaceAll(/_{2,}/g, "_");
218
218
  }
219
219
  function mkdirRecursive(path2) {
220
220
  fs.mkdirSync(path2, { recursive: true });
@@ -245,7 +245,7 @@ var ValidationFileMatcher = class {
245
245
  this.outputDir = config.outputDir ?? "data/test/output";
246
246
  }
247
247
  matchFileSnapshot(actual, options) {
248
- const { testPath, titlePath, name, serializer } = options;
248
+ const { testPath, titlePath, name, namingStrategy, serializer } = options;
249
249
  if (!serializer.canSerialize(actual)) {
250
250
  throw new Error(`Cannot serialize value of type ${typeof actual}`);
251
251
  }
@@ -254,6 +254,7 @@ var ValidationFileMatcher = class {
254
254
  titlePath,
255
255
  testPath,
256
256
  name,
257
+ namingStrategy,
257
258
  fileExtension: serializerResult.fileExtension
258
259
  });
259
260
  return this.writeFileSnapshots(
@@ -262,13 +263,25 @@ var ValidationFileMatcher = class {
262
263
  );
263
264
  }
264
265
  buildValidationFilePath(options) {
265
- const { testPath, titlePath, name, fileExtension } = options;
266
+ const { testPath, titlePath, name, namingStrategy, fileExtension } = options;
266
267
  const normalizedTitlePath = titlePath.map(normalizeFileName);
267
- const normalizedFileName = name !== void 0 ? `_${normalizeFileName(name)}` : "";
268
- const normalizedTestName = normalizedTitlePath.pop();
269
- const validationFilePath = path.join(testPath, ...normalizedTitlePath);
270
- const validationFileName = `${normalizedTestName}${normalizedFileName}.${fileExtension}`;
271
- return path.join(validationFilePath, validationFileName);
268
+ const filePath = path.join(testPath, ...normalizedTitlePath);
269
+ const fullFilePath = this.applyNamingStrategy(
270
+ filePath,
271
+ name,
272
+ namingStrategy
273
+ );
274
+ return `${fullFilePath}.${fileExtension}`;
275
+ }
276
+ applyNamingStrategy(filePath, snapshotName, namingStrategy) {
277
+ if (snapshotName === void 0) {
278
+ return filePath;
279
+ }
280
+ const normalizedSnapshotName = normalizeFileName(snapshotName);
281
+ if (namingStrategy === "fileSuffix") {
282
+ return `${filePath}_${normalizedSnapshotName}`;
283
+ }
284
+ return path.join(filePath, normalizedSnapshotName);
272
285
  }
273
286
  writeFileSnapshots(actual, validationFilePath) {
274
287
  const validationFileDir = path.dirname(validationFilePath);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cronn/lib-file-snapshots",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "The library agnostic core for testing file snapshots",
5
5
  "keywords": [
6
6
  "file snapshots"
@@ -32,21 +32,29 @@
32
32
  "dist"
33
33
  ],
34
34
  "devDependencies": {
35
- "@biomejs/biome": "1.9.4",
35
+ "@trivago/prettier-plugin-sort-imports": "5.2.2",
36
36
  "@types/node": "22.15.30",
37
37
  "@vitest/coverage-istanbul": "3.2.4",
38
+ "eslint": "9.30.1",
39
+ "eslint-config-prettier": "10.1.5",
40
+ "eslint-plugin-unused-imports": "4.1.4",
41
+ "jiti": "2.4.2",
42
+ "prettier": "3.6.2",
38
43
  "tsup": "8.5.0",
39
44
  "typescript": "5.8.3",
45
+ "typescript-eslint": "8.36.0",
40
46
  "vitest": "3.2.4",
41
47
  "@cronn/shared-configs": "0.0.0"
42
48
  },
43
49
  "scripts": {
44
- "check": "biome check .",
45
- "check:fix": "biome check --write .",
50
+ "lint:check": "eslint src/ --max-warnings=0",
51
+ "lint:fix": "eslint src/ --max-warnings=0 --fix",
52
+ "check": "pnpm run compile && pnpm run lint:check",
53
+ "fix": "pnpm run lint:fix",
46
54
  "test": "vitest run",
47
55
  "test:coverage": "vitest run --coverage",
48
56
  "compile": "tsc",
49
57
  "build": "tsup",
50
- "ci": "biome ci . && pnpm run compile && pnpm run test:coverage && pnpm run build"
58
+ "ci": "pnpm run check && pnpm run test:coverage && pnpm run build"
51
59
  }
52
60
  }