@@ -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 ;
@@ -162,12 +123,7 @@ class SnapshotManager {
162
123
}
163
124
}
164
125
165
- writeSnapshotFile ( ) {
166
- if ( ! this . updateSnapshots ) {
167
- debug ( 'skipping write of snapshot file' ) ;
168
- return ;
169
- }
170
-
126
+ writeFile ( ) {
171
127
try {
172
128
const keys = ArrayPrototypeSort ( ObjectKeys ( this . snapshots ) ) ;
173
129
const snapshotStrings = ArrayPrototypeMap ( keys , ( key ) => {
@@ -184,34 +140,87 @@ class SnapshotManager {
184
140
throw error ;
185
141
}
186
142
}
143
+ }
144
+
145
+ class SnapshotManager {
146
+ constructor ( updateSnapshots ) {
147
+ // A manager instance will only read or write snapshot files based on the
148
+ // updateSnapshots argument.
149
+ this . updateSnapshots = updateSnapshots ;
150
+ this . cache = new SafeMap ( ) ;
151
+ }
152
+
153
+ resolveSnapshotFile ( entryFile ) {
154
+ let snapshotFile = this . cache . get ( entryFile ) ;
155
+
156
+ if ( snapshotFile === undefined ) {
157
+ const resolved = resolveSnapshotPathFn ( entryFile ) ;
158
+
159
+ if ( typeof resolved !== 'string' ) {
160
+ const err = new ERR_INVALID_STATE ( 'Invalid snapshot filename.' ) ;
161
+ err . filename = resolved ;
162
+ throw err ;
163
+ }
164
+
165
+ snapshotFile = new SnapshotFile ( resolved ) ;
166
+ snapshotFile . loaded = this . updateSnapshots ;
167
+ this . cache . set ( entryFile , snapshotFile ) ;
168
+ }
169
+
170
+ return snapshotFile ;
171
+ }
172
+
173
+ serialize ( input , serializers = serializerFns ) {
174
+ try {
175
+ let value = input ;
176
+
177
+ for ( let i = 0 ; i < serializers . length ; ++ i ) {
178
+ const fn = serializers [ i ] ;
179
+ value = fn ( value ) ;
180
+ }
181
+
182
+ return `\n${ templateEscape ( value ) } \n` ;
183
+ } catch ( err ) {
184
+ const error = new ERR_INVALID_STATE (
185
+ 'The provided serializers did not generate a string.' ,
186
+ ) ;
187
+ error . input = input ;
188
+ error . cause = err ;
189
+ throw error ;
190
+ }
191
+ }
192
+
193
+ writeSnapshotFiles ( ) {
194
+ if ( ! this . updateSnapshots ) {
195
+ debug ( 'skipping write of snapshot files' ) ;
196
+ return ;
197
+ }
198
+
199
+ this . cache . forEach ( ( snapshotFile ) => {
200
+ snapshotFile . writeFile ( ) ;
201
+ } ) ;
202
+ }
187
203
188
204
createAssert ( ) {
189
205
const manager = this ;
190
206
191
207
return function snapshotAssertion ( actual , options = kEmptyObject ) {
192
208
emitExperimentalWarning ( kExperimentalWarning ) ;
193
- // Resolve the snapshot file here so that any resolution errors are
194
- // surfaced as early as possible.
195
- manager . resolveSnapshotFile ( ) ;
196
-
197
- const { fullName } = this ;
198
- const id = manager . nextId ( fullName ) ;
199
-
200
209
validateObject ( options , 'options' ) ;
201
-
202
210
const {
203
211
serializers = serializerFns ,
204
212
} = options ;
205
-
206
213
validateFunctionArray ( serializers , 'options.serializers' ) ;
207
-
214
+ const { filePath, fullName } = this ;
215
+ const snapshotFile = manager . resolveSnapshotFile ( filePath ) ;
208
216
const value = manager . serialize ( actual , serializers ) ;
217
+ const id = snapshotFile . nextId ( fullName ) ;
209
218
210
219
if ( manager . updateSnapshots ) {
211
- manager . setSnapshot ( id , value ) ;
220
+ snapshotFile . setSnapshot ( id , value ) ;
212
221
} else {
213
- manager . readSnapshotFile ( ) ;
214
- strictEqual ( value , manager . getSnapshot ( id ) ) ;
222
+ snapshotFile . readFile ( ) ;
223
+ strictEqual ( value , snapshotFile . getSnapshot ( id ) ) ;
215
224
}
216
225
} ;
217
226
}
0 commit comments