@@ -95,6 +95,8 @@ module Playback {
9595
9696 export interface PlaybackIO extends Harness . IO , PlaybackControl { }
9797
98+ export interface PlaybackSystem extends ts . System , PlaybackControl { }
99+
98100 function createEmptyLog ( ) : IOLog {
99101 return {
100102 timestamp : ( new Date ( ) ) . toString ( ) ,
@@ -114,8 +116,10 @@ module Playback {
114116 } ;
115117 }
116118
117- function initWrapper < T > ( wrapper : PlaybackControl , underlying : T ) {
118- Object . keys ( underlying ) . forEach ( prop => {
119+ function initWrapper ( wrapper : PlaybackSystem , underlying : ts . System ) : void ;
120+ function initWrapper ( wrapper : PlaybackIO , underlying : Harness . IO ) : void ;
121+ function initWrapper ( wrapper : PlaybackSystem | PlaybackIO , underlying : ts . System | Harness . IO ) : void {
122+ ts . forEach ( Object . keys ( underlying ) , prop => {
119123 ( < any > wrapper ) [ prop ] = ( < any > underlying ) [ prop ] ;
120124 } ) ;
121125
@@ -135,6 +139,79 @@ module Playback {
135139 wrapper . startRecord = ( fileNameBase ) => {
136140 recordLogFileNameBase = fileNameBase ;
137141 recordLog = createEmptyLog ( ) ;
142+
143+ if ( underlying . args !== undefined && typeof underlying . args !== "function" ) {
144+ recordLog . arguments = < string [ ] > underlying . args ;
145+ }
146+ } ;
147+
148+ wrapper . startReplayFromFile = logFn => {
149+ wrapper . startReplayFromString ( underlying . readFile ( logFn ) ) ;
150+ } ;
151+ wrapper . endRecord = ( ) => {
152+ if ( recordLog !== undefined ) {
153+ let i = 0 ;
154+ let fn = ( ) => recordLogFileNameBase + i + ".json" ;
155+ while ( underlying . fileExists ( fn ( ) ) ) i ++ ;
156+ underlying . writeFile ( fn ( ) , JSON . stringify ( recordLog ) ) ;
157+ recordLog = undefined ;
158+ }
159+ } ;
160+
161+ wrapper . fileExists = recordReplay ( wrapper . fileExists , underlying ) (
162+ ( path ) => callAndRecord ( underlying . fileExists ( path ) , recordLog . fileExists , { path : path } ) ,
163+ memoize ( ( path ) => {
164+ // If we read from the file, it must exist
165+ if ( findResultByPath ( wrapper , replayLog . filesRead , path , null ) !== null ) {
166+ return true ;
167+ } else {
168+ return findResultByFields ( replayLog . fileExists , { path : path } , false ) ;
169+ }
170+ } )
171+ ) ;
172+
173+ wrapper . getExecutingFilePath = ( ) => {
174+ if ( replayLog !== undefined ) {
175+ return replayLog . executingPath ;
176+ } else if ( recordLog !== undefined ) {
177+ return recordLog . executingPath = underlying . getExecutingFilePath ( ) ;
178+ } else {
179+ return underlying . getExecutingFilePath ( ) ;
180+ }
181+ } ;
182+
183+ wrapper . getCurrentDirectory = ( ) => {
184+ if ( replayLog !== undefined ) {
185+ return replayLog . currentDirectory || "" ;
186+ } else if ( recordLog !== undefined ) {
187+ return recordLog . currentDirectory = underlying . getCurrentDirectory ( ) ;
188+ } else {
189+ return underlying . getCurrentDirectory ( ) ;
190+ }
191+ } ;
192+
193+ wrapper . resolvePath = recordReplay ( wrapper . resolvePath , underlying ) (
194+ ( path ) => callAndRecord ( underlying . resolvePath ( path ) , recordLog . pathsResolved , { path : path } ) ,
195+ memoize ( ( path ) => findResultByFields ( replayLog . pathsResolved , { path : path } , ! ts . isRootedDiskPath ( ts . normalizeSlashes ( path ) ) && replayLog . currentDirectory ? replayLog . currentDirectory + "/" + path : ts . normalizeSlashes ( path ) ) ) ) ;
196+
197+ wrapper . readFile = recordReplay ( wrapper . readFile , underlying ) (
198+ ( path ) => {
199+ let result = underlying . readFile ( path ) ;
200+ let logEntry = { path : path , codepage : 0 , result : { contents : result , codepage : 0 } } ;
201+ recordLog . filesRead . push ( logEntry ) ;
202+ return result ;
203+ } ,
204+ memoize ( ( path ) => findResultByPath ( wrapper , replayLog . filesRead , path ) . contents ) ) ;
205+
206+ wrapper . writeFile = recordReplay ( wrapper . writeFile , underlying ) (
207+ ( path , contents ) => callAndRecord ( underlying . writeFile ( path , contents ) , recordLog . filesWritten , { path : path , contents : contents , bom : false } ) ,
208+ ( path , contents ) => noOpReplay ( "writeFile" ) ) ;
209+
210+ wrapper . exit = ( exitCode ) => {
211+ if ( recordLog !== undefined ) {
212+ wrapper . endRecord ( ) ;
213+ }
214+ underlying . exit ( exitCode ) ;
138215 } ;
139216 }
140217
@@ -227,93 +304,18 @@ module Playback {
227304 let wrapper : PlaybackIO = < any > { } ;
228305 initWrapper ( wrapper , underlying ) ;
229306
230- wrapper . startReplayFromFile = logFn => {
231- wrapper . startReplayFromString ( underlying . readFile ( logFn ) ) ;
232- } ;
233- wrapper . endRecord = ( ) => {
234- if ( recordLog !== undefined ) {
235- let i = 0 ;
236- let fn = ( ) => recordLogFileNameBase + i + ".json" ;
237- while ( underlying . fileExists ( fn ( ) ) ) i ++ ;
238- underlying . writeFile ( fn ( ) , JSON . stringify ( recordLog ) ) ;
239- recordLog = undefined ;
240- }
241- } ;
242-
243- wrapper . args = ( ) => {
244- if ( replayLog !== undefined ) {
245- return replayLog . arguments ;
246- } else if ( recordLog !== undefined ) {
247- recordLog . arguments = underlying . args ( ) ;
248- }
249- return underlying . args ( ) ;
250- }
251-
252- wrapper . newLine = ( ) => underlying . newLine ( ) ;
253- wrapper . useCaseSensitiveFileNames = ( ) => underlying . useCaseSensitiveFileNames ( ) ;
254307 wrapper . directoryName = ( path ) : string => { throw new Error ( "NotSupported" ) ; } ;
255- wrapper . createDirectory = path => { throw new Error ( "NotSupported" ) ; } ;
308+ wrapper . createDirectory = ( path ) : void => { throw new Error ( "NotSupported" ) ; } ;
256309 wrapper . directoryExists = ( path ) : boolean => { throw new Error ( "NotSupported" ) ; } ;
257- wrapper . deleteFile = path => { throw new Error ( "NotSupported" ) ; } ;
310+ wrapper . deleteFile = ( path ) : void => { throw new Error ( "NotSupported" ) ; } ;
258311 wrapper . listFiles = ( path , filter , options ) : string [ ] => { throw new Error ( "NotSupported" ) ; } ;
259- wrapper . log = text => underlying . log ( text ) ;
260-
261- wrapper . fileExists = recordReplay ( wrapper . fileExists , underlying ) (
262- ( path ) => callAndRecord ( underlying . fileExists ( path ) , recordLog . fileExists , { path : path } ) ,
263- memoize ( ( path ) => {
264- // If we read from the file, it must exist
265- if ( findResultByPath ( wrapper , replayLog . filesRead , path , null ) !== null ) {
266- return true ;
267- } else {
268- return findResultByFields ( replayLog . fileExists , { path : path } , false ) ;
269- }
270- } )
271- ) ;
272-
273- wrapper . getExecutingFilePath = ( ) => {
274- if ( replayLog !== undefined ) {
275- return replayLog . executingPath ;
276- } else if ( recordLog !== undefined ) {
277- return recordLog . executingPath = underlying . getExecutingFilePath ( ) ;
278- } else {
279- return underlying . getExecutingFilePath ( ) ;
280- }
281- } ;
282312
283- wrapper . getCurrentDirectory = ( ) => {
284- if ( replayLog !== undefined ) {
285- return replayLog . currentDirectory || "" ;
286- } else if ( recordLog !== undefined ) {
287- return recordLog . currentDirectory = underlying . getCurrentDirectory ( ) ;
288- } else {
289- return underlying . getCurrentDirectory ( ) ;
290- }
291- } ;
292-
293- wrapper . resolvePath = recordReplay ( wrapper . resolvePath , underlying ) (
294- ( path ) => callAndRecord ( underlying . resolvePath ( path ) , recordLog . pathsResolved , { path : path } ) ,
295- memoize ( ( path ) => findResultByFields ( replayLog . pathsResolved , { path : path } , ! ts . isRootedDiskPath ( ts . normalizeSlashes ( path ) ) && replayLog . currentDirectory ? replayLog . currentDirectory + "/" + path : ts . normalizeSlashes ( path ) ) ) ) ;
296-
297- wrapper . readFile = recordReplay ( wrapper . readFile , underlying ) (
298- ( path ) => {
299- let result = underlying . readFile ( path ) ;
300- let logEntry = { path : path , codepage : 0 , result : { contents : result , codepage : 0 } } ;
301- recordLog . filesRead . push ( logEntry ) ;
302- return result ;
303- } ,
304- memoize ( ( path ) => findResultByPath ( wrapper , replayLog . filesRead , path ) . contents ) ) ;
305-
306- wrapper . writeFile = recordReplay ( wrapper . writeFile , underlying ) (
307- ( path , contents ) => callAndRecord ( underlying . writeFile ( path , contents ) , recordLog . filesWritten , { path : path , contents : contents , bom : false } ) ,
308- ( path , contents ) => noOpReplay ( "writeFile" ) ) ;
309-
310- wrapper . exit = ( exitCode ) => {
311- if ( recordLog !== undefined ) {
312- wrapper . endRecord ( ) ;
313- }
314- underlying . exit ( exitCode ) ;
315- } ;
313+ return wrapper ;
314+ }
316315
316+ export function wrapSystem ( underlying : ts . System ) : PlaybackSystem {
317+ let wrapper : PlaybackSystem = < any > { } ;
318+ initWrapper ( wrapper , underlying ) ;
317319 return wrapper ;
318320 }
319321}
0 commit comments