Skip to content

Commit 24f17eb

Browse files
authored
Run common tests for ReplayFileSystem. (#31)
1 parent c9474de commit 24f17eb

File tree

2 files changed

+67
-7
lines changed

2 files changed

+67
-7
lines changed

test/common_tests.dart

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,20 @@ import 'dart:io' as io;
1010
import 'package:file/file.dart';
1111
import 'package:file/testing.dart';
1212
import 'package:test/test.dart';
13-
import 'package:test/test.dart' as testpkg show group, test;
13+
import 'package:test/test.dart' as testpkg show group, test, setUp;
1414

1515
/// Callback used in [runCommonTests] to produce the root folder in which all
1616
/// file system entities will be created.
1717
typedef String RootPathGenerator();
1818

19+
/// Callback used in [runCommonTests] to create the file system under test.
20+
/// It must return either a [FileSystem] or a [Future] that completes with a
21+
/// [FileSystem].
22+
typedef dynamic FileSystemGenerator();
23+
24+
/// A function to run before tests (passed to [setUp]).
25+
typedef dynamic SetUpCallback();
26+
1927
/// Runs a suite of tests common to all file system implementations. All file
2028
/// system implementations should run *at least* these tests to ensure
2129
/// compliance with file system API.
@@ -29,14 +37,24 @@ typedef String RootPathGenerator();
2937
/// not yet fully complete). The format of each entry in the list is:
3038
/// `$group1Description > $group2Description > ... > $testDescription`.
3139
/// Entries may use regular expression syntax.
40+
///
41+
/// If [replay] is specified, each test (and its setup callbacks) will run
42+
/// twice - once as a "setup" pass with the file system returned by
43+
/// [createFileSystem], and again as the "test" pass with the file system
44+
/// returned by [replay]. This is intended for use with `ReplayFileSystem`,
45+
/// where in order for the file system to behave as expected, a recording of
46+
/// the invocation(s) must first be made.
3247
void runCommonTests(
33-
FileSystem createFileSystem(), {
48+
FileSystemGenerator createFileSystem, {
3449
RootPathGenerator root,
3550
List<String> skip: const <String>[],
51+
FileSystemGenerator replay,
3652
}) {
3753
RootPathGenerator rootfn = root;
3854

3955
group('common', () {
56+
FileSystemGenerator createFs;
57+
List<SetUpCallback> setUps;
4058
FileSystem fs;
4159
String root;
4260

@@ -52,11 +70,36 @@ void runCommonTests(
5270
stack.removeLast();
5371
}
5472

73+
testpkg.setUp(() async {
74+
createFs = createFileSystem;
75+
setUps = <SetUpCallback>[];
76+
fs = null;
77+
root = null;
78+
});
79+
80+
void setUp(callback()) {
81+
testpkg.setUp(replay == null ? callback : () => setUps.add(callback));
82+
}
83+
5584
void group(String description, body()) =>
5685
skipIfNecessary(description, () => testpkg.group(description, body));
5786

58-
void test(String description, body()) =>
59-
skipIfNecessary(description, () => testpkg.test(description, body));
87+
void test(String description, body()) => skipIfNecessary(description, () {
88+
if (replay == null) {
89+
testpkg.test(description, body);
90+
} else {
91+
group('rerun', () {
92+
testpkg.setUp(() async {
93+
await Future.forEach(setUps, (SetUpCallback setUp) => setUp());
94+
await body();
95+
createFs = replay;
96+
await Future.forEach(setUps, (SetUpCallback setUp) => setUp());
97+
});
98+
99+
testpkg.test(description, body);
100+
});
101+
}
102+
});
60103

61104
/// Returns [path] prefixed by the [root] namespace.
62105
/// This is only intended for absolute paths.
@@ -68,10 +111,10 @@ void runCommonTests(
68111
return root == '/' ? path : (path == '/' ? root : '$root$path');
69112
}
70113

71-
setUp(() {
114+
setUp(() async {
72115
root = rootfn != null ? rootfn() : '/';
73116
assert(root.startsWith('/') && (root == '/' || !root.endsWith('/')));
74-
fs = createFileSystem();
117+
fs = await createFs();
75118
});
76119

77120
group('FileSystem', () {
@@ -588,7 +631,7 @@ void runCommonTests(
588631
expect(fs.link(ns('/baz')).targetSync(), ns('/foo'));
589632
});
590633

591-
test('succeedsIfDestinationIsLinkToNotFound', () {
634+
test('throwsIfDestinationIsLinkToNotFound', () {
592635
Directory src = fs.directory(ns('/foo'))..createSync();
593636
fs.link(ns('/bar')).createSync(ns('/baz'));
594637
expectFileSystemException('Not a directory', () {

test/replay_test.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import 'package:file/testing.dart';
1111
import 'package:path/path.dart' as path;
1212
import 'package:test/test.dart';
1313

14+
import 'common_tests.dart';
15+
1416
void main() {
1517
group('Replay', () {
1618
RecordingFileSystem recordingFileSystem;
@@ -33,6 +35,21 @@ void main() {
3335
return new ReplayFileSystem(recording: recording.destination);
3436
}
3537

38+
runCommonTests(
39+
() => recordingFileSystem,
40+
replay: replay,
41+
skip: <String>[
42+
// ReplayFileSystem does not yet replay exceptions
43+
'.*(disallows|throws).*',
44+
45+
// TODO(tvolkert): Enable when ReplayFileSystem is complete.
46+
'FileSystem',
47+
'Directory',
48+
'File',
49+
'Link',
50+
],
51+
);
52+
3653
group('ReplayFileSystem', () {
3754
test('directory', () async {
3855
recordingFileSystem.directory('/foo');

0 commit comments

Comments
 (0)