@tryghost/jest-snapshot 0.5.16 → 0.5.18

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2013-2023 Ghost Foundation
3
+ Copyright (c) 2013-2025 Ghost Foundation
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -38,4 +38,4 @@ Follow the instructions for the top-level repo.
38
38
 
39
39
  # Copyright & License
40
40
 
41
- Copyright (c) 2013-2023 Ghost Foundation - Released under the [MIT license](LICENSE).
41
+ Copyright (c) 2013-2025 Ghost Foundation - Released under the [MIT license](LICENSE).
@@ -1,38 +1,77 @@
1
- const {SnapshotState, toMatchSnapshot} = require('jest-snapshot');
1
+ const {SnapshotState, toMatchSnapshot, EXTENSION} = require('jest-snapshot');
2
2
  const errors = require('@tryghost/errors');
3
3
  const utils = require('@jest/expect-utils');
4
4
  const assert = require('assert');
5
5
  const path = require('path');
6
6
  const {makeMessageFromMatchMessage} = require('./utils');
7
7
 
8
+ const DOT_EXTENSION = `.${EXTENSION}`;
9
+
10
+ /**
11
+ * Determines whether to update all snapshots or only new ones
12
+ * @returns {string} e.g. 'all' or 'new'
13
+ */
14
+ function willUpdate() {
15
+ const updateSnapshots = (
16
+ process.env.SNAPSHOT_UPDATE
17
+ || process.env.UPDATE_SNAPSHOT
18
+ || process.env.SNAPSHOTS_UPDATE
19
+ || process.env.UPDATE_SNAPSHOTS
20
+ );
21
+
22
+ return updateSnapshots ? 'all' : 'new';
23
+ }
24
+
8
25
  class SnapshotManager {
9
26
  constructor() {
10
27
  this.registry = {};
11
28
  this.currentTest = {};
12
- this.defaultSnapshotPath = '__snapshots__';
29
+ this.defaultSnapshotRoot = '__snapshots__';
30
+
31
+ // Set willUpdate once, as it can't change whilst we are running
32
+ this.willUpdate = willUpdate();
13
33
  }
14
34
 
15
- _getNameForSnapshot(snapshotFilename, snapshotNameTemplate) {
16
- if (!this.registry[snapshotFilename]) {
17
- this.registry[snapshotFilename] = {};
35
+ /**
36
+ * Looks in the registry for a snapshot with the same filename and nameTemplate
37
+ * If needed, increments the counter
38
+ * Returns nametemplate with the counter appended.
39
+ *
40
+ * @param {string} testPath e.g. '/path/to/tests/my-fake.test.js'
41
+ * @param {string} testTitle e.g. 'My fake test title'
42
+ * @returns {string} e.g. 'My fake test title 1'
43
+ */
44
+ _getNameForSnapshot(testPath, testTitle) {
45
+ if (!(testPath in this.registry)) {
46
+ this.registry[testPath] = {};
18
47
  }
19
48
 
20
- const nextCounter = (this.registry[snapshotFilename][snapshotNameTemplate] || 0) + 1;
21
- this.registry[snapshotFilename][snapshotNameTemplate] = nextCounter;
49
+ const nextCounter = (this.registry[testPath][testTitle] || 0) + 1;
50
+ this.registry[testPath][testTitle] = nextCounter;
22
51
 
23
- return `${snapshotNameTemplate} ${nextCounter}`;
52
+ return `${testTitle} ${nextCounter}`;
24
53
  }
25
54
 
26
- _resolveSnapshotFilePath(testFile) {
27
- const parsedPath = path.parse(testFile);
28
-
29
- parsedPath.dir = path.join(parsedPath.dir, this.defaultSnapshotPath);
30
-
31
- return path.format(parsedPath);
55
+ /**
56
+ * Takes the full path to the test file and returns the full path to the snapshot file
57
+ *
58
+ * @param {string} testPath e.g. '/path/to/tests/my-fake.test.js'
59
+ * @returns {string} snapshotFilePath e.g. '/path/to/tests/__snapshots__/my-fake.test.js.snap'
60
+ */
61
+ _resolveSnapshotFilePath(testPath) {
62
+ return path.join(
63
+ path.join(path.dirname(testPath), this.defaultSnapshotRoot),
64
+ path.basename(testPath) + DOT_EXTENSION
65
+ );
32
66
  }
33
67
 
68
+ /**
69
+ * Returns config for the current test
70
+ * Throws an error if the current test is not configured
71
+ * @returns {Object} e.g. {snapshotPath: 'test/__snapshots__/my-fake.test.js.snap', snapshotName: 'My fake test title 1', willUpdate: 'new'}
72
+ */
34
73
  _getConfig() {
35
- if (!this.currentTest.filename || !this.currentTest.nameTemplate) {
74
+ if (!this.currentTest.testPath || !this.currentTest.testTitle) {
36
75
  throw new errors.IncorrectUsageError({
37
76
  message: 'Unable to run snapshot tests, current test was not configured',
38
77
  context: 'Snapshot testing requires current test filename and nameTemplate to be set for each test',
@@ -40,46 +79,60 @@ class SnapshotManager {
40
79
  });
41
80
  }
42
81
 
43
- let testFile = this.currentTest.filename;
44
- const testTitle = this.currentTest.nameTemplate;
45
- const snapshotName = this._getNameForSnapshot(testFile, testTitle);
46
- const updateSnapshots = (
47
- process.env.SNAPSHOT_UPDATE
48
- || process.env.UPDATE_SNAPSHOT
49
- || process.env.SNAPSHOTS_UPDATE
50
- || process.env.UPDATE_SNAPSHOTS
51
- );
52
- const willUpdate = updateSnapshots ? 'all' : 'new';
82
+ const {testPath, testTitle} = this.currentTest;
53
83
 
54
- // Set full path
55
- testFile = this._resolveSnapshotFilePath(testFile);
84
+ const snapshotName = this._getNameForSnapshot(testPath, testTitle);
85
+ const snapshotPath = this._resolveSnapshotFilePath(testPath);
56
86
 
57
- return {testFile, snapshotName, willUpdate};
87
+ return {snapshotPath, snapshotName};
58
88
  }
59
89
 
90
+ /**
91
+ * Resets the registry to an empty object
92
+ */
60
93
  resetRegistry() {
61
94
  this.registry = {};
62
95
  }
63
96
 
97
+ /**
98
+ * Resets the registry for the current test only
99
+ */
64
100
  resetRegistryForCurrentTest() {
65
- const testTitle = this.currentTest.nameTemplate;
66
- if (this.currentTest.filename in this.registry && testTitle in this.registry[this.currentTest.filename]) {
67
- delete this.registry[this.currentTest.filename][testTitle];
101
+ const {testPath, testTitle} = this.currentTest;
102
+ if (testPath in this.registry && testTitle in this.registry[testPath]) {
103
+ delete this.registry[testPath][testTitle];
68
104
  }
69
105
  }
70
106
 
107
+ /**
108
+ * @param {Object} testConfig
109
+ * @param {String} testConfig.testPath full path to the test file
110
+ * @param {String} testConfig.testTitle the full title of the test - all the describe and it names concatenated
111
+ */
71
112
  setCurrentTest(testConfig) {
72
113
  this.currentTest = testConfig;
73
114
  }
74
115
 
75
- getSnapshotState(testFile, willUpdate) {
116
+ /**
117
+ * Gets a SnapshotState instance for the current test
118
+ * @param {string} snapshotPath e.g. 'test/__snapshots__/my-fake.test.js.snap'
119
+ * @returns {SnapshotState}
120
+ */
121
+ getSnapshotState(snapshotPath) {
76
122
  // Initialize the SnapshotState, it’s responsible for actually matching
77
123
  // actual snapshot with expected one and storing results
78
- return new SnapshotState(testFile, {
79
- updateSnapshot: willUpdate
124
+ return new SnapshotState(snapshotPath, {
125
+ updateSnapshot: this.willUpdate
80
126
  });
81
127
  }
82
128
 
129
+ /**
130
+ * Asserts the snapshot values match using the match function
131
+ * Does some formatting of the error message
132
+ *
133
+ * @param {{field: string}} response
134
+ * @param {{properties: Object, field: string, error: Object, hint: string}} assertion
135
+ */
83
136
  assertSnapshot(response, assertion) {
84
137
  const {properties, field, error} = assertion;
85
138
 
@@ -116,10 +169,22 @@ class SnapshotManager {
116
169
  assert.equal(match.pass, true, error);
117
170
  }
118
171
 
172
+ /**
173
+ * Calls Jest's toMatchSnapshot function
174
+ * Binds the snapshotState, currentTestName, utils and equals function to the matcher
175
+ * Executes the matcher
176
+ * Saves the snapshot state
177
+ *
178
+ * @param {Object} received - our actual value
179
+ * @param {Object} [properties] - the properties we want to match against
180
+ * @param {string} [hint] - a hint to help with the match
181
+ * @returns {Object} result of the match
182
+ */
119
183
  match(received, properties = {}, hint) {
120
- const {testFile, snapshotName, willUpdate} = this._getConfig();
184
+ const {snapshotPath, snapshotName} = this._getConfig();
185
+
186
+ const snapshotState = this.getSnapshotState(snapshotPath);
121
187
 
122
- const snapshotState = this.getSnapshotState(testFile, willUpdate);
123
188
  const matcher = toMatchSnapshot.bind({
124
189
  snapshotState,
125
190
  currentTestName: snapshotName,
@@ -12,9 +12,20 @@ function matchSnapshotAssertion(properties) {
12
12
  }
13
13
 
14
14
  const mochaHooks = {
15
+
16
+ /**
17
+ * Runs before all tests
18
+ * Resets the registry so we start with a clean slate
19
+ */
15
20
  beforeAll() {
16
21
  snapshotManager.resetRegistry();
17
22
  },
23
+
24
+ /**
25
+ * Runs before each test
26
+ * Passes the current test config to the snapshot manager
27
+ * If we're running a retry, reset the registry for this test only
28
+ */
18
29
  beforeEach() {
19
30
  const {currentTest} = this;
20
31
 
@@ -24,8 +35,8 @@ const mochaHooks = {
24
35
  }
25
36
 
26
37
  snapshotManager.setCurrentTest({
27
- filename: currentTest.file + '.snap',
28
- nameTemplate: currentTest.fullTitle()
38
+ testPath: currentTest.file,
39
+ testTitle: currentTest.fullTitle()
29
40
  });
30
41
  }
31
42
  };
package/package.json CHANGED
@@ -1,13 +1,17 @@
1
1
  {
2
2
  "name": "@tryghost/jest-snapshot",
3
- "version": "0.5.16",
4
- "repository": "https://github.com/TryGhost/framework/tree/main/packages/jest-snapshot",
3
+ "version": "0.5.18",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/TryGhost/framework.git",
7
+ "directory": "packages/jest-snapshot"
8
+ },
5
9
  "author": "Ghost Foundation",
6
10
  "license": "MIT",
7
11
  "main": "index.js",
8
12
  "scripts": {
9
13
  "dev": "echo \"Implement me!\"",
10
- "test": "NODE_ENV=testing c8 --all --check-coverage --100 --reporter text --reporter cobertura mocha './test/**/*.test.js'",
14
+ "test": "NODE_ENV=testing c8 --all --check-coverage --100 --reporter text --reporter cobertura --reporter html-spa mocha './test/**/*.test.js'",
11
15
  "lint": "eslint . --ext .js --cache",
12
16
  "posttest": "yarn lint"
13
17
  },
@@ -19,16 +23,16 @@
19
23
  "access": "public"
20
24
  },
21
25
  "devDependencies": {
22
- "c8": "10.1.2",
23
- "mocha": "10.7.0",
26
+ "c8": "10.1.3",
27
+ "mocha": "10.7.3",
24
28
  "should": "13.2.3",
25
29
  "sinon": "18.0.0"
26
30
  },
27
31
  "dependencies": {
28
32
  "@jest/expect": "^28.0.1",
29
33
  "@jest/expect-utils": "^28.0.1",
30
- "@tryghost/errors": "^1.3.6",
34
+ "@tryghost/errors": "^1.3.8",
31
35
  "jest-snapshot": "^29.0.0"
32
36
  },
33
- "gitHead": "d86b1d4fb719b9fb3535a31576c06e42ad1d8476"
37
+ "gitHead": "e395f1d79edee4aecc36e572bb402016a8ba9273"
34
38
  }