Skip to content

Commit

Permalink
Implement tests for Directory (flutter#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
tvolkert authored Dec 15, 2016
1 parent 4b48927 commit 4531665
Show file tree
Hide file tree
Showing 6 changed files with 656 additions and 247 deletions.
25 changes: 16 additions & 9 deletions lib/src/backends/memory/memory_directory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class _MemoryDirectory extends _MemoryFileSystemEntity implements Directory {
}
return null;
},
resolveTailLink: true,
);
if (node.type != expectedType) {
// There was an existing non-directory node at this object's path
Expand All @@ -42,8 +43,8 @@ class _MemoryDirectory extends _MemoryFileSystemEntity implements Directory {

@override
Directory createTempSync([String prefix]) {
prefix ??= '';
String fullPath = '$path$_separator$prefix';
prefix = (prefix ?? '') + 'rand';
String fullPath = fileSystem._context.join(path, prefix);
String dirname = fileSystem._context.dirname(fullPath);
String basename = fileSystem._context.basename(fullPath);
_DirectoryNode node = fileSystem._findNode(dirname);
Expand All @@ -55,7 +56,8 @@ class _MemoryDirectory extends _MemoryFileSystemEntity implements Directory {
}
_DirectoryNode tempDir = new _DirectoryNode(node);
node.children[name()] = tempDir;
return new _MemoryDirectory(fileSystem, '$dirname$_separator${name()}');
return new _MemoryDirectory(
fileSystem, fileSystem._context.join(dirname, name()));
}

@override
Expand Down Expand Up @@ -95,24 +97,28 @@ class _MemoryDirectory extends _MemoryFileSystemEntity implements Directory {
}) {
_DirectoryNode node = backing;
List<FileSystemEntity> listing = <FileSystemEntity>[];
Set<_LinkNode> visitedLinks = new Set<_LinkNode>();
List<_PendingListTask> tasks = <_PendingListTask>[
new _PendingListTask(
node,
path.endsWith(_separator) ? path.substring(0, path.length - 1) : path,
new Set<_LinkNode>(),
),
];
while (tasks.isNotEmpty) {
_PendingListTask task = tasks.removeLast();
task.dir.children.forEach((String name, _Node child) {
String childPath = '${task.path}$_separator$name';
if (followLinks && _isLink(child) && visitedLinks.add(child)) {
child = (child as _LinkNode).referent;
Set<_LinkNode> breadcrumbs = new Set<_LinkNode>.from(task.breadcrumbs);
String childPath = fileSystem._context.join(task.path, name);
while (followLinks && _isLink(child) && breadcrumbs.add(child)) {
_Node referent = (child as _LinkNode).referentOrNull;
if (referent != null) {
child = referent;
}
}
if (_isDirectory(child)) {
listing.add(new _MemoryDirectory(fileSystem, childPath));
if (recursive) {
tasks.add(new _PendingListTask(child, childPath));
tasks.add(new _PendingListTask(child, childPath, breadcrumbs));
}
} else if (_isLink(child)) {
listing.add(new _MemoryLink(fileSystem, childPath));
Expand All @@ -131,5 +137,6 @@ class _MemoryDirectory extends _MemoryFileSystemEntity implements Directory {
class _PendingListTask {
final _DirectoryNode dir;
final String path;
_PendingListTask(this.dir, this.path);
final Set<_LinkNode> breadcrumbs;
_PendingListTask(this.dir, this.path, this.breadcrumbs);
}
9 changes: 5 additions & 4 deletions lib/src/backends/memory/memory_file_system.dart
Original file line number Diff line number Diff line change
Expand Up @@ -209,19 +209,20 @@ class MemoryFileSystem extends FileSystem {
if (i < finalSegment) {
_PathGenerator subpath = _subpath(parts, 0, i);
_checkExists(child, subpath);
if (pathWithSymlinks != null) {
pathWithSymlinks.add(basename);
}
if (_isLink(child)) {
child = _resolveLinks(child, subpath, ledger: pathWithSymlinks);
} else if (pathWithSymlinks != null) {
pathWithSymlinks..add(_separator)..add(basename);
}
_checkIsDir(child, subpath);
directory = child;
} else if (pathWithSymlinks != null) {
pathWithSymlinks..add(_separator)..add(basename);
pathWithSymlinks.add(basename);
}
}
if (_isLink(child) && resolveTailLink) {
child = _resolveLinks(child, () => path);
child = _resolveLinks(child, () => path, ledger: pathWithSymlinks);
}
return child;
}
Expand Down
20 changes: 14 additions & 6 deletions lib/src/backends/memory/memory_file_system_entity.dart
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ abstract class _MemoryFileSystemEntity implements FileSystemEntity {
pathWithSymlinks: ledger, resolveTailLink: true);
_checkExists(node, () => path);
String resolved = ledger.join(_separator);
if (!isAbsolute) {
resolved = fileSystem._cwd + resolved;
if (!_isAbsolute(resolved)) {
resolved = fileSystem._cwd + _separator + resolved;
}
return fileSystem._context.normalize(resolved);
}
Expand All @@ -88,7 +88,7 @@ abstract class _MemoryFileSystemEntity implements FileSystemEntity {
if (node is _DirectoryNode && node.children.isNotEmpty) {
throw new io.FileSystemException('Directory not empty', path);
}
if (node.type != expectedType) {
if (node.stat.type != expectedType) {
throw new io.FileSystemException(
'Not a ${expectedType.toString().toLowerCase()}', path);
}
Expand All @@ -113,7 +113,7 @@ abstract class _MemoryFileSystemEntity implements FileSystemEntity {
FileSystemEntity get absolute {
String absolutePath = path;
if (!_isAbsolute(absolutePath)) {
absolutePath = '${fileSystem._cwd}$_separator$absolutePath';
absolutePath = fileSystem._context.join(fileSystem._cwd, absolutePath);
}
return _clone(absolutePath);
}
Expand All @@ -136,11 +136,16 @@ abstract class _MemoryFileSystemEntity implements FileSystemEntity {
/// If an entity already existed at this path, [createChild] will not be
/// invoked at all, and this method will return with the backing node for the
/// existing entity (whose type may differ from this entity's type).
///
/// If [resolveTailLink] is true and the result node is a link, this will
/// resolve it to its target prior to returning it.
_Node _createSync(
_Node createChild(_DirectoryNode parent, bool isFinalSegment),
) {
_Node createChild(_DirectoryNode parent, bool isFinalSegment), {
bool resolveTailLink: false,
}) {
return fileSystem._findNode(
path,
resolveTailLink: resolveTailLink,
segmentVisitor: (
_DirectoryNode parent,
String childName,
Expand Down Expand Up @@ -183,6 +188,9 @@ abstract class _MemoryFileSystemEntity implements FileSystemEntity {
_RenameOverwriteValidator<dynamic> validateOverwriteExistingEntity,
}) {
_Node node = backing;
if (node.stat.type != expectedType) {
throw new io.FileSystemException('No such file or directory', path);
}
fileSystem._findNode(
newPath,
segmentVisitor: (
Expand Down
19 changes: 17 additions & 2 deletions lib/src/backends/memory/node.dart
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,24 @@ class _LinkNode extends _Node {
assert(target != null && target.isNotEmpty);
}

/// Gets the node backing for this link's target. Throws a
/// [io.FileSystemException] if this link references a non-existent file
/// system entity.
_Node get referent {
_Node node = fs._findNode(target, reference: this);
_checkExists(node, () => target);
return node;
}

/// Gets the node backing for this link's target, or null if this link
/// references a non-existent file system entity.
_Node get referent => fs._findNode(target, reference: this);
_Node get referentOrNull {
try {
return referent;
} on io.FileSystemException {
return null;
}
}

@override
io.FileSystemEntityType get type => io.FileSystemEntityType.LINK;
Expand All @@ -164,7 +179,7 @@ class _LinkNode extends _Node {
}
reentrant = true;
try {
_Node node = referent;
_Node node = referentOrNull;
return node == null ? _MemoryFileStat._notFound : node.stat;
} finally {
reentrant = false;
Expand Down
3 changes: 2 additions & 1 deletion lib/src/backends/memory/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ _Node _resolveLinks(
while (_isLink(node)) {
link = node;
if (!breadcrumbs.add(node)) {
throw new io.FileSystemException('Loop found in link chain', path());
throw new io.FileSystemException(
'Too many levels of symbolic links', path());
}
if (ledger != null) {
if (_isAbsolute(link.target)) {
Expand Down
Loading

0 comments on commit 4531665

Please sign in to comment.