@@ -8,10 +8,12 @@ import 'dart:convert';
88import 'package:file/file.dart' ;
99import 'package:file/src/io.dart' as io;
1010
11+ import 'mutable_recording.dart' ;
1112import 'recording_file_system.dart' ;
1213import 'recording_file_system_entity.dart' ;
1314import 'recording_io_sink.dart' ;
1415import 'recording_random_access_file.dart' ;
16+ import 'result_reference.dart' ;
1517
1618/// [File] implementation that records all invocation activity to its file
1719/// system's recording.
@@ -31,14 +33,14 @@ class RecordingFile extends RecordingFileSystemEntity<File, io.File>
3133 #lastModifiedSync: delegate.lastModifiedSync,
3234 #open: _open,
3335 #openSync: _openSync,
34- #openRead: delegate.openRead ,
36+ #openRead: _openRead ,
3537 #openWrite: _openWrite,
36- #readAsBytes: delegate.readAsBytes ,
37- #readAsBytesSync: delegate.readAsBytesSync ,
38- #readAsString: delegate.readAsString ,
39- #readAsStringSync: delegate.readAsStringSync ,
40- #readAsLines: delegate.readAsLines ,
41- #readAsLinesSync: delegate.readAsLinesSync ,
38+ #readAsBytes: _readAsBytes ,
39+ #readAsBytesSync: _readAsBytesSync ,
40+ #readAsString: _readAsString ,
41+ #readAsStringSync: _readAsStringSync ,
42+ #readAsLines: _readAsLines ,
43+ #readAsLinesSync: _readAsLinesSync ,
4244 #writeAsBytes: _writeAsBytes,
4345 #writeAsBytesSync: delegate.writeAsBytesSync,
4446 #writeAsString: _writeAsString,
@@ -65,13 +67,60 @@ class RecordingFile extends RecordingFileSystemEntity<File, io.File>
6567 RandomAccessFile _openSync ({FileMode mode: FileMode .READ }) =>
6668 _wrapRandomAccessFile (delegate.openSync (mode: mode));
6769
70+ StreamReference <List <int >> _openRead ([int start, int end]) =>
71+ new _ByteArrayStreamReference (
72+ recording,
73+ 'openRead' ,
74+ delegate.openRead (start, end),
75+ );
76+
6877 IOSink _openWrite ({FileMode mode: FileMode .WRITE , Encoding encoding: UTF8 }) {
6978 return new RecordingIOSink (
7079 fileSystem,
7180 delegate.openWrite (mode: mode, encoding: encoding),
7281 );
7382 }
7483
84+ FutureReference <List <int >> _readAsBytes () => new _ByteArrayFutureReference (
85+ recording,
86+ 'readAsBytes' ,
87+ delegate.readAsBytes (),
88+ );
89+
90+ ResultReference <List <int >> _readAsBytesSync () => new _ByteArrayReference (
91+ recording,
92+ 'readAsBytesSync' ,
93+ delegate.readAsBytesSync (),
94+ );
95+
96+ FutureReference <String > _readAsString ({Encoding encoding: UTF8 }) =>
97+ new _FileContentFutureReference (
98+ recording,
99+ 'readAsString' ,
100+ delegate.readAsString (encoding: encoding),
101+ );
102+
103+ ResultReference <String > _readAsStringSync ({Encoding encoding: UTF8 }) =>
104+ new _FileContentReference (
105+ recording,
106+ 'readAsStringSync' ,
107+ delegate.readAsStringSync (encoding: encoding),
108+ );
109+
110+ FutureReference <List <String >> _readAsLines ({Encoding encoding: UTF8 }) =>
111+ new _LinesFutureReference (
112+ recording,
113+ 'readAsLines' ,
114+ delegate.readAsLines (encoding: encoding),
115+ );
116+
117+ ResultReference <List <String >> _readAsLinesSync ({Encoding encoding: UTF8 }) =>
118+ new _LinesReference (
119+ recording,
120+ 'readAsLinesSync' ,
121+ delegate.readAsLinesSync (encoding: encoding),
122+ );
123+
75124 Future <File > _writeAsBytes (
76125 List <int > bytes, {
77126 FileMode mode: FileMode .WRITE ,
@@ -89,3 +138,156 @@ class RecordingFile extends RecordingFileSystemEntity<File, io.File>
89138 .writeAsString (contents, mode: mode, encoding: encoding, flush: flush)
90139 .then (wrap);
91140}
141+
142+ class _ByteArrayStreamReference extends StreamReference <List <int >> {
143+ final File file;
144+ IOSink _sink;
145+
146+ _ByteArrayStreamReference (
147+ MutableRecording recording, String name, Stream <List <int >> stream)
148+ : file = recording.newFile (name)..createSync (),
149+ super (stream);
150+
151+ @override
152+ void onData (List <int > event) {
153+ if (_sink == null ) {
154+ _sink = file.openWrite ();
155+ }
156+ _sink.add (event);
157+ }
158+
159+ @override
160+ void onDone () {
161+ if (_sink != null ) {
162+ _sink.close ();
163+ }
164+ }
165+
166+ @override
167+ dynamic get serializedValue => '!${file .basename }' ;
168+
169+ // TODO(tvolkert): remove `.then()` once Dart 1.22 is in stable
170+ @override
171+ Future <Null > get complete =>
172+ Future .wait (< Future <dynamic >> [super .complete, _sink.done]).then ((_) {});
173+ }
174+
175+ class _ByteArrayFutureReference extends FutureReference <List <int >> {
176+ final File file;
177+
178+ _ByteArrayFutureReference (
179+ MutableRecording recording, String name, Future <List <int >> future)
180+ : file = recording.newFile (name),
181+ super (future);
182+
183+ @override
184+ Future <List <int >> get value {
185+ return super .value.then ((List <int > bytes) async {
186+ await file.writeAsBytes (bytes, flush: true );
187+ return bytes;
188+ });
189+ }
190+
191+ @override
192+ dynamic get serializedValue => '!${file .basename }' ;
193+ }
194+
195+ class _ByteArrayReference extends ResultReference <List <int >> {
196+ final File file;
197+ final List <int > bytes;
198+
199+ _ByteArrayReference (MutableRecording recording, String name, this .bytes)
200+ : file = recording.newFile (name);
201+
202+ @override
203+ List <int > get value {
204+ file.writeAsBytesSync (bytes, flush: true );
205+ return bytes;
206+ }
207+
208+ @override
209+ List <int > get recordedValue => bytes;
210+
211+ @override
212+ dynamic get serializedValue => '!${file .basename }' ;
213+ }
214+
215+ class _FileContentFutureReference extends FutureReference <String > {
216+ final File file;
217+
218+ _FileContentFutureReference (
219+ MutableRecording recording, String name, Future <String > future)
220+ : file = recording.newFile (name),
221+ super (future);
222+
223+ @override
224+ Future <String > get value {
225+ return super .value.then ((String content) async {
226+ await file.writeAsString (content, flush: true );
227+ return content;
228+ });
229+ }
230+
231+ @override
232+ dynamic get serializedValue => '!${file .basename }' ;
233+ }
234+
235+ class _FileContentReference extends ResultReference <String > {
236+ final File file;
237+ final String content;
238+
239+ _FileContentReference (MutableRecording recording, String name, this .content)
240+ : file = recording.newFile (name);
241+
242+ @override
243+ String get value {
244+ file.writeAsStringSync (content, flush: true );
245+ return content;
246+ }
247+
248+ @override
249+ String get recordedValue => content;
250+
251+ @override
252+ dynamic get serializedValue => '!${file .basename }' ;
253+ }
254+
255+ class _LinesFutureReference extends FutureReference <List <String >> {
256+ final File file;
257+
258+ _LinesFutureReference (
259+ MutableRecording recording, String name, Future <List <String >> future)
260+ : file = recording.newFile (name),
261+ super (future);
262+
263+ @override
264+ Future <List <String >> get value {
265+ return super .value.then ((List <String > lines) async {
266+ await file.writeAsString (lines.join ('\n ' ), flush: true );
267+ return lines;
268+ });
269+ }
270+
271+ @override
272+ dynamic get serializedValue => '!${file .basename }' ;
273+ }
274+
275+ class _LinesReference extends ResultReference <List <String >> {
276+ final File file;
277+ final List <String > lines;
278+
279+ _LinesReference (MutableRecording recording, String name, this .lines)
280+ : file = recording.newFile (name);
281+
282+ @override
283+ List <String > get value {
284+ file.writeAsStringSync (lines.join ('\n ' ), flush: true );
285+ return lines;
286+ }
287+
288+ @override
289+ List <String > get recordedValue => lines;
290+
291+ @override
292+ dynamic get serializedValue => '!${file .basename }' ;
293+ }
0 commit comments