@@ -58,50 +58,12 @@ function setDefaultSnapshotSerializers(serializers) {
58
58
serializerFns = ArrayPrototypeSlice ( serializers ) ;
59
59
}
60
60
61
- class SnapshotManager {
62
- constructor ( entryFile , updateSnapshots ) {
63
- this . entryFile = entryFile ;
64
- this . snapshotFile = undefined ;
61
+ class SnapshotFile {
62
+ constructor ( snapshotFile ) {
63
+ this . snapshotFile = snapshotFile ;
65
64
this . snapshots = { __proto__ : null } ;
66
65
this . nameCounts = new SafeMap ( ) ;
67
- // A manager instance will only read or write snapshot files based on the
68
- // updateSnapshots argument.
69
- this . loaded = updateSnapshots ;
70
- this . updateSnapshots = updateSnapshots ;
71
- }
72
-
73
- resolveSnapshotFile ( ) {
74
- if ( this . snapshotFile === undefined ) {
75
- const resolved = resolveSnapshotPathFn ( this . entryFile ) ;
76
-
77
- if ( typeof resolved !== 'string' ) {
78
- const err = new ERR_INVALID_STATE ( 'Invalid snapshot filename.' ) ;
79
- err . filename = resolved ;
80
- throw err ;
81
- }
82
-
83
- this . snapshotFile = resolved ;
84
- }
85
- }
86
-
87
- serialize ( input , serializers = serializerFns ) {
88
- try {
89
- let value = input ;
90
-
91
- for ( let i = 0 ; i < serializers . length ; ++ i ) {
92
- const fn = serializers [ i ] ;
93
- value = fn ( value ) ;
94
- }
95
-
96
- return `\n${ templateEscape ( value ) } \n` ;
97
- } catch ( err ) {
98
- const error = new ERR_INVALID_STATE (
99
- 'The provided serializers did not generate a string.' ,
100
- ) ;
101
- error . input = input ;
102
- error . cause = err ;
103
- throw error ;
104
- }
66
+ this . loaded = false ;
105
67
}
106
68
107
69
getSnapshot ( id ) {
@@ -122,12 +84,11 @@ class SnapshotManager {
122
84
123
85
nextId ( name ) {
124
86
const count = this . nameCounts . get ( name ) ?? 1 ;
125
-
126
87
this . nameCounts . set ( name , count + 1 ) ;
127
88
return `${ name } ${ count } ` ;
128
89
}
129
90
130
- readSnapshotFile ( ) {
91
+ readFile ( ) {
131
92
if ( this . loaded ) {
132
93
debug ( 'skipping read of snapshot file' ) ;
133
94
return ;
@@ -164,12 +125,7 @@ class SnapshotManager {
164
125
}
165
126
}
166
127
167
- writeSnapshotFile ( ) {
168
- if ( ! this . updateSnapshots ) {
169
- debug ( 'skipping write of snapshot file' ) ;
170
- return ;
171
- }
172
-
128
+ writeFile ( ) {
173
129
try {
174
130
const keys = ArrayPrototypeSort ( ObjectKeys ( this . snapshots ) ) ;
175
131
const snapshotStrings = ArrayPrototypeMap ( keys , ( key ) => {
@@ -186,34 +142,87 @@ class SnapshotManager {
186
142
throw error ;
187
143
}
188
144
}
145
+ }
146
+
147
+ class SnapshotManager {
148
+ constructor ( updateSnapshots ) {
149
+ // A manager instance will only read or write snapshot files based on the
150
+ // updateSnapshots argument.
151
+ this . updateSnapshots = updateSnapshots ;
152
+ this . cache = new SafeMap ( ) ;
153
+ }
154
+
155
+ resolveSnapshotFile ( entryFile ) {
156
+ let snapshotFile = this . cache . get ( entryFile ) ;
157
+
158
+ if ( snapshotFile === undefined ) {
159
+ const resolved = resolveSnapshotPathFn ( entryFile ) ;
160
+
161
+ if ( typeof resolved !== 'string' ) {
162
+ const err = new ERR_INVALID_STATE ( 'Invalid snapshot filename.' ) ;
163
+ err . filename = resolved ;
164
+ throw err ;
165
+ }
166
+
167
+ snapshotFile = new SnapshotFile ( resolved ) ;
168
+ snapshotFile . loaded = this . updateSnapshots ;
169
+ this . cache . set ( entryFile , snapshotFile ) ;
170
+ }
171
+
172
+ return snapshotFile ;
173
+ }
174
+
175
+ serialize ( input , serializers = serializerFns ) {
176
+ try {
177
+ let value = input ;
178
+
179
+ for ( let i = 0 ; i < serializers . length ; ++ i ) {
180
+ const fn = serializers [ i ] ;
181
+ value = fn ( value ) ;
182
+ }
183
+
184
+ return `\n${ templateEscape ( value ) } \n` ;
185
+ } catch ( err ) {
186
+ const error = new ERR_INVALID_STATE (
187
+ 'The provided serializers did not generate a string.' ,
188
+ ) ;
189
+ error . input = input ;
190
+ error . cause = err ;
191
+ throw error ;
192
+ }
193
+ }
194
+
195
+ writeSnapshotFiles ( ) {
196
+ if ( ! this . updateSnapshots ) {
197
+ debug ( 'skipping write of snapshot files' ) ;
198
+ return ;
199
+ }
200
+
201
+ this . cache . forEach ( ( snapshotFile ) => {
202
+ snapshotFile . writeFile ( ) ;
203
+ } ) ;
204
+ }
189
205
190
206
createAssert ( ) {
191
207
const manager = this ;
192
208
193
209
return function snapshotAssertion ( actual , options = kEmptyObject ) {
194
210
emitExperimentalWarning ( kExperimentalWarning ) ;
195
- // Resolve the snapshot file here so that any resolution errors are
196
- // surfaced as early as possible.
197
- manager . resolveSnapshotFile ( ) ;
198
-
199
- const { fullName } = this ;
200
- const id = manager . nextId ( fullName ) ;
201
-
202
211
validateObject ( options , 'options' ) ;
203
-
204
212
const {
205
213
serializers = serializerFns ,
206
214
} = options ;
207
-
208
215
validateFunctionArray ( serializers , 'options.serializers' ) ;
209
-
216
+ const { filePath, fullName } = this ;
217
+ const snapshotFile = manager . resolveSnapshotFile ( filePath ) ;
210
218
const value = manager . serialize ( actual , serializers ) ;
219
+ const id = snapshotFile . nextId ( fullName ) ;
211
220
212
221
if ( manager . updateSnapshots ) {
213
- manager . setSnapshot ( id , value ) ;
222
+ snapshotFile . setSnapshot ( id , value ) ;
214
223
} else {
215
- manager . readSnapshotFile ( ) ;
216
- strictEqual ( value , manager . getSnapshot ( id ) ) ;
224
+ snapshotFile . readFile ( ) ;
225
+ strictEqual ( value , snapshotFile . getSnapshot ( id ) ) ;
217
226
}
218
227
} ;
219
228
}
0 commit comments