Enable Windows testing of LocalFileSystem (#54)

We currently skip any tests that are already failing.

Fixes #51 
diff --git a/appveyor.yml b/appveyor.yml
index 1e45697..1259c77 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -10,9 +10,4 @@
 build: off
 
 test_script:
-  # TODO(tvolkert): Enable testing of LocalFileSystem
-  - pub run test test\chroot_test.dart
-  - pub run test test\memory_test.dart
-  - pub run test test\recording_test.dart
-  - pub run test test\replay_test.dart
-  - pub run test test\utils_test.dart
+  - pub run test
diff --git a/test/local_test.dart b/test/local_test.dart
index 028b4e5..2b39b66 100644
--- a/test/local_test.dart
+++ b/test/local_test.dart
@@ -29,6 +29,158 @@
       tmp.deleteSync(recursive: true);
     });
 
+    Map<String, List<String>> skipOnPlatform = <String, List<String>>{
+      'windows': <String>[
+        'FileSystem > currentDirectory > throwsIfHasNonExistentPathInComplexChain',
+        'FileSystem > currentDirectory > staysAtRootIfSetToParentOfRoot',
+        'FileSystem > currentDirectory > throwsIfSetToFilePathSegmentAtTail',
+        'FileSystem > currentDirectory > throwsIfSetToFilePathSegmentViaTraversal',
+        'FileSystem > currentDirectory > resolvesLinksIfEncountered',
+        'FileSystem > currentDirectory > succeedsIfSetToDirectoryLinkAtTail',
+        'FileSystem > currentDirectory > throwsIfSetToLinkLoop',
+        'FileSystem > stat > isFileForLinkToFile',
+        'FileSystem > type > isFileForLinkToFileAndFollowLinksTrue',
+        'FileSystem > type > isNotFoundForLinkWithCircularReferenceAndFollowLinksTrue',
+        'Directory > uri',
+        'Directory > exists > falseIfExistsAsLinkToFile',
+        'Directory > exists > falseIfNotFoundSegmentExistsThenIsBackedOut',
+        'Directory > create > throwsIfAlreadyExistsAsFile',
+        'Directory > create > throwsIfAlreadyExistsAsLinkToFile',
+        'Directory > create > throwsIfAlreadyExistsAsLinkToNotFoundViaTraversal',
+        'Directory > create > throwsIfAncestorDoesntExistRecursiveFalse',
+        'Directory > rename > throwsIfDestinationIsFile',
+        'Directory > rename > throwsIfDestinationParentFolderDoesntExist',
+        'Directory > rename > throwsIfDestinationIsNonEmptyDirectory',
+        'Directory > rename > throwsIfSourceIsFile',
+        'Directory > rename > throwsIfDestinationIsLinkToNotFound',
+        'Directory > rename > throwsIfDestinationIsLinkToEmptyDirectory',
+        'Directory > delete > throwsIfNonEmptyDirectoryExistsAndRecursiveFalse',
+        'Directory > delete > throwsIfPathReferencesFileAndRecursiveFalse',
+        'Directory > delete > throwsIfPathReferencesLinkToFileAndRecursiveFalse',
+        'Directory > delete > throwsIfPathReferencesLinkToNotFoundAndRecursiveFalse',
+        'Directory > resolveSymbolicLinks > throwsIfLoopInLinkChain',
+        'Directory > resolveSymbolicLinks > throwsIfPathNotFoundInTraversal',
+        'Directory > resolveSymbolicLinks > throwsIfPathNotFoundInMiddleThenBackedOut',
+        'Directory > createTemp > throwsIfDirectoryDoesntExist',
+        'Directory > createTemp > succeedsWithNestedPathPrefixThatExists',
+        'Directory > createTemp > throwsWithNestedPathPrefixThatDoesntExist',
+        'Directory > list > throwsIfDirectoryDoesntExist',
+        'Directory > list > followsLinksIfFollowLinksTrue',
+        'Directory > list > returnsLinkObjectsForRecursiveLinkIfFollowLinksTrue',
+        'File > uri',
+        'File > create > throwsIfAncestorDoesntExistRecursiveFalse',
+        'File > create > succeedsIfAlreadyExistsAsLinkToFile',
+        'File > create > succeedsIfAlreadyExistsAsLinkToNotFoundAtTail',
+        'File > create > throwsIfAlreadyExistsAsLinkToNotFoundViaTraversal',
+        'File > create > succeedsIfAlreadyExistsAsLinkToNotFoundInDifferentDirectory',
+        'File > rename > throwsIfDestinationDoesntExistViaTraversal',
+        'File > rename > throwsIfDestinationExistsAsDirectory',
+        'File > rename > succeedsIfDestinationExistsAsLinkToFile',
+        'File > rename > succeedsIfDestinationExistsAsLinkToNotFound',
+        'File > rename > throwsIfSourceExistsAsDirectory',
+        'File > rename > succeedsIfSourceExistsAsLinkToFile',
+        'File > rename > throwsIfSourceExistsAsLinkToDirectory',
+        'File > copy > throwsIfDestinationDoesntExistViaTraversal',
+        'File > copy > throwsIfDestinationExistsAsDirectory',
+        'File > copy > succeedsIfDestinationExistsAsLinkToFile',
+        'File > copy > throwsIfDestinationExistsAsLinkToDirectory',
+        'File > copy > throwsIfSourceExistsAsDirectory',
+        'File > copy > succeedsIfSourceExistsAsLinkToFile',
+        'File > copy > succeedsIfSourceIsLinkToFileInDifferentDirectory',
+        'File > copy > succeedsIfDestinationIsLinkToFileInDifferentDirectory',
+        'File > open > READ > throwsIfDoesntExistViaTraversal',
+        'File > open > READ > RandomAccessFile > throwsIfWriteByte',
+        'File > open > READ > RandomAccessFile > throwsIfWriteFrom',
+        'File > open > READ > RandomAccessFile > throwsIfWriteString',
+        'File > open > READ > RandomAccessFile > position > throwsIfSetToNegativeNumber',
+        'File > open > READ > RandomAccessFile > throwsIfTruncate',
+        'File > open > WRITE > throwsIfDoesntExistViaTraversal',
+        'File > open > WRITE > RandomAccessFile > position > throwsIfSetToNegativeNumber',
+        'File > open > APPEND > throwsIfDoesntExistViaTraversal',
+        'File > open > APPEND > RandomAccessFile > position > throwsIfSetToNegativeNumber',
+        'File > open > WRITE_ONLY > throwsIfDoesntExistViaTraversal',
+        'File > open > WRITE_ONLY > RandomAccessFile > throwsIfReadByte',
+        'File > open > WRITE_ONLY > RandomAccessFile > throwsIfRead',
+        'File > open > WRITE_ONLY > RandomAccessFile > throwsIfReadInto',
+        'File > open > WRITE_ONLY > RandomAccessFile > position > throwsIfSetToNegativeNumber',
+        'File > open > WRITE_ONLY_APPEND > throwsIfDoesntExistViaTraversal',
+        'File > open > WRITE_ONLY_APPEND > RandomAccessFile > throwsIfReadByte',
+        'File > open > WRITE_ONLY_APPEND > RandomAccessFile > throwsIfRead',
+        'File > open > WRITE_ONLY_APPEND > RandomAccessFile > throwsIfReadInto',
+        'File > open > WRITE_ONLY_APPEND > RandomAccessFile > position > throwsIfSetToNegativeNumber',
+        'File > openRead > throwsIfExistsAsDirectory',
+        'File > openRead > succeedsIfExistsAsLinkToFile',
+        'File > openWrite > throwsIfExistsAsDirectory',
+        'File > openWrite > throwsIfExistsAsLinkToDirectory',
+        'File > openWrite > succeedsIfExistsAsLinkToFile',
+        'File > openWrite > ioSink > throwsIfEncodingIsNullAndWriteObject',
+        'File > openWrite > ioSink > allowsChangingEncoding',
+        'File > openWrite > ioSink > succeedsIfAddRawData',
+        'File > openWrite > ioSink > succeedsIfWrite',
+        'File > openWrite > ioSink > succeedsIfWriteAll',
+        'File > openWrite > ioSink > succeedsIfWriteCharCode',
+        'File > openWrite > ioSink > succeedsIfWriteln',
+        'File > openWrite > ioSink > addStream > succeedsIfStreamProducesData',
+        'File > openWrite > ioSink > addStream > blocksCallToAddWhileStreamIsActive',
+        'File > openWrite > ioSink > addStream > blocksCallToWriteWhileStreamIsActive',
+        'File > openWrite > ioSink > addStream > blocksCallToWriteAllWhileStreamIsActive',
+        'File > openWrite > ioSink > addStream > blocksCallToWriteCharCodeWhileStreamIsActive',
+        'File > openWrite > ioSink > addStream > blocksCallToWritelnWhileStreamIsActive',
+        'File > openWrite > ioSink > addStream > blocksCallToFlushWhileStreamIsActive',
+        'File > readAsBytes > throwsIfExistsAsDirectory',
+        'File > readAsBytes > throwsIfExistsAsLinkToDirectory',
+        'File > readAsBytes > succeedsIfExistsAsLinkToFile',
+        'File > readAsString > throwsIfExistsAsDirectory',
+        'File > readAsString > throwsIfExistsAsLinkToDirectory',
+        'File > readAsString > succeedsIfExistsAsLinkToFile',
+        'File > readAsLines > throwsIfExistsAsDirectory',
+        'File > readAsLines > throwsIfExistsAsLinkToDirectory',
+        'File > writeAsBytes > throwsIfExistsAsDirectory',
+        'File > writeAsBytes > throwsIfExistsAsLinkToDirectory',
+        'File > writeAsBytes > succeedsIfExistsAsLinkToFile',
+        'File > writeAsBytes > throwsIfFileModeRead',
+        'File > writeAsString > throwsIfExistsAsDirectory',
+        'File > writeAsString > throwsIfExistsAsLinkToDirectory',
+        'File > writeAsString > succeedsIfExistsAsLinkToFile',
+        'File > writeAsString > throwsIfFileModeRead',
+        'File > stat > isFileIfExistsAsLinkToFile',
+        'File > delete > throwsIfExistsAsDirectoryAndRecursiveFalse',
+        'File > delete > succeedsIfExistsAsLinkToFileAndRecursiveFalse',
+        'File > delete > throwsIfExistsAsLinkToDirectoryAndRecursiveFalse',
+        'Link > uri > whenTargetIsDirectory',
+        'Link > uri > whenTargetIsFile',
+        'Link > uri > whenLinkDoesntExist',
+        'Link > stat > isFileIfTargetIsFile',
+        'Link > stat > isDirectoryIfTargetIsDirectory',
+        'Link > delete > throwsIfPathReferencesFileAndRecursiveFalse',
+        'Link > delete > throwsIfPathReferencesDirectoryAndRecursiveFalse',
+        'Link > create > throwsIfLinkDoesntExistViaTraversalAndRecursiveFalse',
+        'Link > create > succeedsIfLinkDoesntExistViaTraversalAndRecursiveTrue',
+        'Link > create > throwsIfAlreadyExistsAsFile',
+        'Link > create > throwsIfAlreadyExistsAsDirectory',
+        'Link > create > throwsIfAlreadyExistsWithSameTarget',
+        'Link > create > throwsIfAlreadyExistsWithDifferentTarget',
+        'Link > update > throwsIfPathReferencesFile',
+        'Link > update > throwsIfPathReferencesDirectory',
+        'Link > target > throwsIfLinkDoesntExistViaTraversal',
+        'Link > target > throwsIfPathReferencesFile',
+        'Link > target > throwsIfPathReferencesDirectory',
+        'Link > rename > returnsCovariantType',
+        'Link > rename > throwsIfSourceIsFile',
+        'Link > rename > throwsIfSourceIsDirectory',
+        'Link > rename > throwsIfDestinationDoesntExistViaTraversal',
+        'Link > rename > succeedsIfDestinationExistsAsLinkToFile',
+        'Link > rename > throwsIfDestinationExistsAsLinkToDirectory',
+        'Link > rename > succeedsIfDestinationExistsAsLinkToNotFound',
+
+        // Fixed in SDK 1.23 (https://github.com/dart-lang/sdk/issues/28852)
+        'File > open > WRITE > RandomAccessFile > truncate > throwsIfSetToNegativeNumber',
+        'File > open > APPEND > RandomAccessFile > truncate > throwsIfSetToNegativeNumber',
+        'File > open > WRITE_ONLY > RandomAccessFile > truncate > throwsIfSetToNegativeNumber',
+        'File > open > WRITE_ONLY_APPEND > RandomAccessFile > truncate > throwsIfSetToNegativeNumber',
+      ],
+    };
+
     runCommonTests(
       () => fs,
       root: () => tmp.path,
@@ -70,7 +222,7 @@
 
         // https://github.com/dart-lang/sdk/issues/28277
         'Link > rename > throwsIfDestinationExistsAsFile',
-      ],
+      ]..addAll(skipOnPlatform[io.Platform.operatingSystem] ?? <String>[]),
     );
 
     group('toString', () {