Skip to content

Commit

Permalink
Finish implementation of ReplayFileSystem (#33)
Browse files Browse the repository at this point in the history
Fixes #11
  • Loading branch information
tvolkert committed Feb 11, 2017
1 parent da342e3 commit 9369e91
Show file tree
Hide file tree
Showing 13 changed files with 378 additions and 321 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
@@ -1,4 +1,4 @@
#### 1.0.2
#### 2.0.0

* Improved `toString` implementations in file system entity classes
* Added `ForwardingFileSystem` and associated forwarding classes to the
Expand Down
353 changes: 179 additions & 174 deletions lib/src/backends/record_replay/codecs.dart

Large diffs are not rendered by default.

32 changes: 19 additions & 13 deletions lib/src/backends/record_replay/replay_directory.dart
Expand Up @@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:async';
import 'dart:convert';

import 'package:file/file.dart';
Expand All @@ -16,24 +17,29 @@ class ReplayDirectory extends ReplayFileSystemEntity implements Directory {
/// Creates a new `ReplayDirectory`.
ReplayDirectory(ReplayFileSystemImpl fileSystem, String identifier)
: super(fileSystem, identifier) {
Converter<dynamic, dynamic> convertThis = directoryReviver(fileSystem);
Converter<dynamic, dynamic> convertFutureThis =
convertThis.fuse(kFutureReviver);
Converter<String, Directory> reviveDirectory =
new ReviveDirectory(fileSystem);
Converter<String, Future<Directory>> reviveFutureDirectory =
reviveDirectory.fuse(const ToFuture<Directory>());
Converter<String, FileSystemEntity> reviveEntity =
new ReviveFileSystemEntity(fileSystem);
Converter<List<String>, List<FileSystemEntity>> reviveEntities =
new ConvertElements<String, FileSystemEntity>(reviveEntity);

methods.addAll(<Symbol, Converter<dynamic, dynamic>>{
#rename: convertFutureThis,
#renameSync: convertThis,
#delete: convertFutureThis,
#create: convertFutureThis,
#createSync: kPassthrough,
#createTemp: convertFutureThis,
#createTempSync: convertThis,
#list: listReviver(entityReviver(fileSystem)).fuse(kStreamReviver),
#listSync: listReviver(entityReviver(fileSystem)),
#rename: reviveFutureDirectory,
#renameSync: reviveDirectory,
#delete: reviveFutureDirectory,
#create: reviveFutureDirectory,
#createSync: const Passthrough<Null>(),
#createTemp: reviveFutureDirectory,
#createTempSync: reviveDirectory,
#list: reviveEntities.fuse(const ToStream<FileSystemEntity>()),
#listSync: reviveEntities,
});

properties.addAll(<Symbol, Converter<dynamic, dynamic>>{
#absolute: convertThis,
#absolute: reviveDirectory,
});
}
}
71 changes: 42 additions & 29 deletions lib/src/backends/record_replay/replay_file.dart
Expand Up @@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:async';
import 'dart:convert';

import 'package:file/file.dart';
Expand All @@ -16,40 +17,52 @@ class ReplayFile extends ReplayFileSystemEntity implements File {
/// Creates a new `ReplayFile`.
ReplayFile(ReplayFileSystemImpl fileSystem, String identifier)
: super(fileSystem, identifier) {
Converter<dynamic, dynamic> convertThis = fileReviver(fileSystem);
Converter<dynamic, dynamic> convertFutureThis =
convertThis.fuse(kFutureReviver);
Converter<String, File> reviveFile = new ReviveFile(fileSystem);
Converter<String, Future<File>> reviveFileAsFuture =
reviveFile.fuse(const ToFuture<File>());
Converter<String, List<int>> blobToBytes = new BlobToBytes(fileSystem);
Converter<String, String> blobToString = blobToBytes.fuse(UTF8.decoder);
Converter<String, RandomAccessFile> reviveRandomAccessFile =
new ReviveRandomAccessFile(fileSystem);
// TODO(tvolkert) remove `as`: https://github.com/dart-lang/sdk/issues/28748
Converter<String, List<String>> lineSplitter =
const LineSplitter() as Converter<String, List<String>>;
Converter<String, List<String>> blobToLines =
blobToString.fuse(lineSplitter);
Converter<String, Stream<List<int>>> blobToByteStream = blobToBytes
.fuse(const Listify<List<int>>())
.fuse(const ToStream<List<int>>());

methods.addAll(<Symbol, Converter<dynamic, dynamic>>{
#rename: convertFutureThis,
#renameSync: convertThis,
#delete: convertFutureThis,
#create: convertFutureThis,
#createSync: kPassthrough,
#copy: convertFutureThis,
#copySync: convertThis,
#length: kFutureReviver,
#lengthSync: kPassthrough,
#lastModified: kDateTimeReviver.fuse(kFutureReviver),
#lastModifiedSync: kDateTimeReviver,
#open: randomAccessFileReviver(fileSystem).fuse(kFutureReviver),
#openSync: randomAccessFileReviver(fileSystem),
#openRead: kStreamReviver,
#openWrite: ioSinkReviver(fileSystem),
#readAsBytes: blobReviver(fileSystem).fuse(kFutureReviver),
#readAsBytesSync: blobReviver(fileSystem),
#readAsString: kFutureReviver,
#readAsStringSync: kPassthrough,
#readAsLines: kFutureReviver,
#readAsLinesSync: kPassthrough,
#writeAsBytes: convertFutureThis,
#writeAsBytesSync: kPassthrough,
#writeAsString: convertFutureThis,
#writeAsStringSync: kPassthrough,
#rename: reviveFileAsFuture,
#renameSync: reviveFile,
#delete: reviveFileAsFuture,
#create: reviveFileAsFuture,
#createSync: const Passthrough<Null>(),
#copy: reviveFileAsFuture,
#copySync: reviveFile,
#length: const ToFuture<int>(),
#lengthSync: const Passthrough<int>(),
#lastModified: DateTimeCodec.deserialize.fuse(const ToFuture<DateTime>()),
#lastModifiedSync: DateTimeCodec.deserialize,
#open: reviveRandomAccessFile.fuse(const ToFuture<RandomAccessFile>()),
#openSync: reviveRandomAccessFile,
#openRead: blobToByteStream,
#openWrite: new ReviveIOSink(fileSystem),
#readAsBytes: blobToBytes.fuse(const ToFuture<List<int>>()),
#readAsBytesSync: blobToBytes,
#readAsString: blobToString.fuse(const ToFuture<String>()),
#readAsStringSync: blobToString,
#readAsLines: blobToLines.fuse(const ToFuture<List<String>>()),
#readAsLinesSync: blobToLines,
#writeAsBytes: reviveFileAsFuture,
#writeAsBytesSync: const Passthrough<Null>(),
#writeAsString: reviveFileAsFuture,
#writeAsStringSync: const Passthrough<Null>(),
});

properties.addAll(<Symbol, Converter<dynamic, dynamic>>{
#absolute: convertThis,
#absolute: reviveFile,
});
}
}
9 changes: 5 additions & 4 deletions lib/src/backends/record_replay/replay_file_stat.dart
Expand Up @@ -16,16 +16,17 @@ class ReplayFileStat implements FileStat {
ReplayFileStat(Map<String, dynamic> data) : _data = data;

@override
DateTime get changed => kDateTimeReviver.convert(_data['changed']);
DateTime get changed => DateTimeCodec.deserialize.convert(_data['changed']);

@override
DateTime get modified => kDateTimeReviver.convert(_data['modified']);
DateTime get modified => DateTimeCodec.deserialize.convert(_data['modified']);

@override
DateTime get accessed => kDateTimeReviver.convert(_data['accessed']);
DateTime get accessed => DateTimeCodec.deserialize.convert(_data['accessed']);

@override
FileSystemEntityType get type => kEntityTypeReviver.convert(_data['type']);
FileSystemEntityType get type =>
EntityTypeCodec.deserialize.convert(_data['type']);

@override
int get mode => _data['mode'];
Expand Down
32 changes: 18 additions & 14 deletions lib/src/backends/record_replay/replay_file_system.dart
Expand Up @@ -70,24 +70,28 @@ class ReplayFileSystemImpl extends FileSystem
implements ReplayFileSystem, ReplayAware {
/// Creates a new `ReplayFileSystemImpl`.
ReplayFileSystemImpl(this.recording, this.manifest) {
Converter<String, Directory> reviveDirectory = new ReviveDirectory(this);
ToFuture<FileSystemEntityType> toFutureType =
const ToFuture<FileSystemEntityType>();

methods.addAll(<Symbol, Converter<dynamic, dynamic>>{
#directory: directoryReviver(this),
#file: fileReviver(this),
#link: linkReviver(this),
#stat: kFileStatReviver.fuse(kFutureReviver),
#statSync: kFileStatReviver,
#identical: kPassthrough.fuse(kFutureReviver),
#identicalSync: kPassthrough,
#type: kEntityTypeReviver.fuse(kFutureReviver),
#typeSync: kEntityTypeReviver,
#directory: reviveDirectory,
#file: new ReviveFile(this),
#link: new ReviveLink(this),
#stat: FileStatCodec.deserialize.fuse(const ToFuture<FileStat>()),
#statSync: FileStatCodec.deserialize,
#identical: const Passthrough<bool>().fuse(const ToFuture<bool>()),
#identicalSync: const Passthrough<bool>(),
#type: EntityTypeCodec.deserialize.fuse(toFutureType),
#typeSync: EntityTypeCodec.deserialize,
});

properties.addAll(<Symbol, Converter<dynamic, dynamic>>{
#path: kPathContextReviver,
#systemTempDirectory: directoryReviver(this),
#currentDirectory: directoryReviver(this),
const Symbol('currentDirectory='): kPassthrough,
#isWatchSupported: kPassthrough,
#path: PathContextCodec.deserialize,
#systemTempDirectory: reviveDirectory,
#currentDirectory: reviveDirectory,
const Symbol('currentDirectory='): const Passthrough<Null>(),
#isWatchSupported: const Passthrough<bool>(),
});
}

Expand Down
35 changes: 21 additions & 14 deletions lib/src/backends/record_replay/replay_file_system_entity.dart
Expand Up @@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:async';
import 'dart:convert';

import 'package:file/file.dart';
Expand All @@ -17,24 +18,30 @@ abstract class ReplayFileSystemEntity extends Object
implements FileSystemEntity {
/// Creates a new `ReplayFileSystemEntity`.
ReplayFileSystemEntity(this.fileSystem, this.identifier) {
Converter<List<Map<String, Object>>, List<FileSystemEvent>> toEvents =
const ConvertElements<Map<String, Object>, FileSystemEvent>(
FileSystemEventCodec.deserialize);
Converter<List<Map<String, Object>>, Stream<FileSystemEvent>>
toEventStream = toEvents.fuse(const ToStream<FileSystemEvent>());

methods.addAll(<Symbol, Converter<dynamic, dynamic>>{
#exists: kPassthrough.fuse(kFutureReviver),
#existsSync: kPassthrough,
#resolveSymbolicLinks: kPassthrough.fuse(kFutureReviver),
#resolveSymbolicLinksSync: kPassthrough,
#stat: kFileStatReviver.fuse(kFutureReviver),
#statSync: kFileStatReviver,
#deleteSync: kPassthrough,
#watch: listReviver(kFileSystemEventReviver).fuse(kStreamReviver),
#exists: const ToFuture<bool>(),
#existsSync: const Passthrough<bool>(),
#resolveSymbolicLinks: const ToFuture<String>(),
#resolveSymbolicLinksSync: const Passthrough<String>(),
#stat: FileStatCodec.deserialize.fuse(const ToFuture<FileStat>()),
#statSync: FileStatCodec.deserialize,
#deleteSync: const Passthrough<Null>(),
#watch: toEventStream,
});

properties.addAll(<Symbol, Converter<dynamic, dynamic>>{
#path: kPassthrough,
#uri: kUriReviver,
#isAbsolute: kPassthrough,
#parent: directoryReviver(fileSystem),
#basename: kPassthrough,
#dirname: kPassthrough,
#path: const Passthrough<String>(),
#uri: UriCodec.deserialize,
#isAbsolute: const Passthrough<bool>(),
#parent: new ReviveDirectory(fileSystem),
#basename: const Passthrough<String>(),
#dirname: const Passthrough<String>(),
});
}

Expand Down
26 changes: 13 additions & 13 deletions lib/src/backends/record_replay/replay_io_sink.dart
Expand Up @@ -15,24 +15,24 @@ import 'replay_proxy_mixin.dart';
class ReplayIOSink extends Object with ReplayProxyMixin implements IOSink {
final ReplayFileSystemImpl _fileSystem;

/// Creates a new `ReplayIOSink`.
/// Creates a new [ReplayIOSink].
ReplayIOSink(this._fileSystem, this.identifier) {
methods.addAll(<Symbol, Converter<dynamic, dynamic>>{
#add: kPassthrough,
#write: kPassthrough,
#writeAll: kPassthrough,
#writeln: kPassthrough,
#writeCharCode: kPassthrough,
#addError: kPassthrough,
#addStream: kFutureReviver,
#flush: kFutureReviver,
#close: kFutureReviver,
#add: const Passthrough<Null>(),
#write: const Passthrough<Null>(),
#writeAll: const Passthrough<Null>(),
#writeln: const Passthrough<Null>(),
#writeCharCode: const Passthrough<Null>(),
#addError: const Passthrough<Null>(),
#addStream: const ToFuture<dynamic>(),
#flush: const ToFuture<dynamic>(),
#close: const ToFuture<dynamic>(),
});

properties.addAll(<Symbol, Converter<dynamic, dynamic>>{
#encoding: kEncodingReviver,
const Symbol('encoding='): kPassthrough,
#done: kPassthrough.fuse(kFutureReviver),
#encoding: EncodingCodec.deserialize,
const Symbol('encoding='): const Passthrough<Null>(),
#done: const Passthrough<dynamic>().fuse(const ToFuture<dynamic>()),
});
}

Expand Down
25 changes: 15 additions & 10 deletions lib/src/backends/record_replay/replay_link.dart
Expand Up @@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:async';
import 'dart:convert';

import 'package:file/file.dart';
Expand All @@ -16,20 +17,24 @@ class ReplayLink extends ReplayFileSystemEntity implements Link {
/// Creates a new `ReplayLink`.
ReplayLink(ReplayFileSystemImpl fileSystem, String identifier)
: super(fileSystem, identifier) {
Converter<String, Link> reviveLink = new ReviveLink(fileSystem);
Converter<String, Future<Link>> reviveLinkAsFuture =
reviveLink.fuse(const ToFuture<Link>());

methods.addAll(<Symbol, Converter<dynamic, dynamic>>{
#rename: linkReviver(fileSystem).fuse(kFutureReviver),
#renameSync: linkReviver(fileSystem),
#delete: linkReviver(fileSystem).fuse(kFutureReviver),
#create: linkReviver(fileSystem).fuse(kFutureReviver),
#createSync: kPassthrough,
#update: linkReviver(fileSystem).fuse(kFutureReviver),
#updateSync: kPassthrough,
#target: kPassthrough.fuse(kFutureReviver),
#targetSync: kPassthrough,
#rename: reviveLinkAsFuture,
#renameSync: reviveLink,
#delete: reviveLinkAsFuture,
#create: reviveLinkAsFuture,
#createSync: const Passthrough<Null>(),
#update: reviveLinkAsFuture,
#updateSync: const Passthrough<Null>(),
#target: const Passthrough<String>().fuse(const ToFuture<String>()),
#targetSync: const Passthrough<String>(),
});

properties.addAll(<Symbol, Converter<dynamic, dynamic>>{
#absolute: linkReviver(fileSystem),
#absolute: reviveLink,
});
}
}

0 comments on commit 9369e91

Please sign in to comment.