@@ -10,12 +10,20 @@ import 'dart:io' as io;
1010import 'package:file/file.dart' ;
1111import 'package:file/testing.dart' ;
1212import '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.
1717typedef 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.
3247void 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' , () {
0 commit comments