@@ -58,50 +58,12 @@ function setDefaultSnapshotSerializers(serializers) {
5858 serializerFns = ArrayPrototypeSlice ( serializers ) ;
5959}
6060
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 ;
6564 this . snapshots = { __proto__ : null } ;
6665 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 ;
10567 }
10668
10769 getSnapshot ( id ) {
@@ -122,12 +84,11 @@ class SnapshotManager {
12284
12385 nextId ( name ) {
12486 const count = this . nameCounts . get ( name ) ?? 1 ;
125-
12687 this . nameCounts . set ( name , count + 1 ) ;
12788 return `${ name } ${ count } ` ;
12889 }
12990
130- readSnapshotFile ( ) {
91+ readFile ( ) {
13192 if ( this . loaded ) {
13293 debug ( 'skipping read of snapshot file' ) ;
13394 return ;
@@ -164,12 +125,7 @@ class SnapshotManager {
164125 }
165126 }
166127
167- writeSnapshotFile ( ) {
168- if ( ! this . updateSnapshots ) {
169- debug ( 'skipping write of snapshot file' ) ;
170- return ;
171- }
172-
128+ writeFile ( ) {
173129 try {
174130 const keys = ArrayPrototypeSort ( ObjectKeys ( this . snapshots ) ) ;
175131 const snapshotStrings = ArrayPrototypeMap ( keys , ( key ) => {
@@ -186,34 +142,87 @@ class SnapshotManager {
186142 throw error ;
187143 }
188144 }
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+ }
189205
190206 createAssert ( ) {
191207 const manager = this ;
192208
193209 return function snapshotAssertion ( actual , options = kEmptyObject ) {
194210 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-
202211 validateObject ( options , 'options' ) ;
203-
204212 const {
205213 serializers = serializerFns ,
206214 } = options ;
207-
208215 validateFunctionArray ( serializers , 'options.serializers' ) ;
209-
216+ const { filePath, fullName } = this ;
217+ const snapshotFile = manager . resolveSnapshotFile ( filePath ) ;
210218 const value = manager . serialize ( actual , serializers ) ;
219+ const id = snapshotFile . nextId ( fullName ) ;
211220
212221 if ( manager . updateSnapshots ) {
213- manager . setSnapshot ( id , value ) ;
222+ snapshotFile . setSnapshot ( id , value ) ;
214223 } else {
215- manager . readSnapshotFile ( ) ;
216- strictEqual ( value , manager . getSnapshot ( id ) ) ;
224+ snapshotFile . readFile ( ) ;
225+ strictEqual ( value , snapshotFile . getSnapshot ( id ) ) ;
217226 }
218227 } ;
219228 }
0 commit comments