| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library test.physical_file_system; | 5 library test.physical_file_system; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:io' as io; | 8 import 'dart:io' as io; |
| 9 | 9 |
| 10 import 'package:analyzer/file_system/file_system.dart'; | 10 import 'package:analyzer/file_system/file_system.dart'; |
| 11 import 'package:analyzer/file_system/physical_file_system.dart'; | 11 import 'package:analyzer/file_system/physical_file_system.dart'; |
| 12 import 'package:analyzer/src/generated/source_io.dart'; | 12 import 'package:analyzer/src/generated/source_io.dart'; |
| 13 import 'package:path/path.dart'; | 13 import 'package:path/path.dart'; |
| 14 import 'package:unittest/unittest.dart'; | 14 import 'package:unittest/unittest.dart'; |
| 15 import 'package:watcher/watcher.dart'; | 15 import 'package:watcher/watcher.dart'; |
| 16 | 16 |
| 17 var _isFile = new isInstanceOf<File>(); | 17 import '../reflective_tests.dart'; |
| 18 var _isFolder = new isInstanceOf<Folder>(); | |
| 19 var _isFileSystemException = new isInstanceOf<FileSystemException>(); | |
| 20 | 18 |
| 21 main() { | 19 main() { |
| 22 groupSep = ' | '; | 20 groupSep = ' | '; |
| 23 | 21 runReflectiveTests(PhysicalResourceProviderTest); |
| 24 group('PhysicalResourceProvider', () { | 22 runReflectiveTests(FileTest); |
| 25 io.Directory tempDirectory; | 23 runReflectiveTests(FolderTest); |
| 26 String tempPath; | 24 } |
| 27 | 25 |
| 28 setUp(() { | 26 var _isFile = new isInstanceOf<File>(); |
| 29 tempDirectory = io.Directory.systemTemp.createTempSync('test_resource'); | 27 var _isFileSystemException = new isInstanceOf<FileSystemException>(); |
| 30 tempPath = tempDirectory.absolute.path; | 28 var _isFolder = new isInstanceOf<Folder>(); |
| 31 }); | 29 |
| 32 | 30 @reflectiveTest |
| 33 tearDown(() { | 31 class FileTest extends _BaseTest { |
| 34 tempDirectory.deleteSync(recursive: true); | 32 String path; |
| 35 }); | 33 File file; |
| 36 | 34 |
| 37 group('Watch', () { | 35 setUp() { |
| 38 Future delayed(computation()) { | 36 super.setUp(); |
| 39 // Give the tests 1 second to detect the changes. While it may only | 37 path = join(tempPath, 'file.txt'); |
| 40 // take up to a few hundred ms, a whole second gives a good margin | 38 file = PhysicalResourceProvider.INSTANCE.getResource(path); |
| 41 // for when running tests. | 39 } |
| 42 return new Future.delayed(new Duration(seconds: 1), computation); | 40 |
| 41 void test_createSource() { |
| 42 new io.File(path).writeAsStringSync('contents'); |
| 43 Source source = file.createSource(); |
| 44 expect(source.uriKind, UriKind.FILE_URI); |
| 45 expect(source.exists(), isTrue); |
| 46 expect(source.contents.data, 'contents'); |
| 47 } |
| 48 |
| 49 void test_equals_differentPaths() { |
| 50 String path2 = join(tempPath, 'file2.txt'); |
| 51 File file2 = PhysicalResourceProvider.INSTANCE.getResource(path2); |
| 52 expect(file == file2, isFalse); |
| 53 } |
| 54 |
| 55 void test_equals_samePath() { |
| 56 new io.File(path).writeAsStringSync('contents'); |
| 57 File file2 = PhysicalResourceProvider.INSTANCE.getResource(path); |
| 58 expect(file == file2, isTrue); |
| 59 } |
| 60 |
| 61 void test_exists_false() { |
| 62 expect(file.exists, isFalse); |
| 63 } |
| 64 |
| 65 void test_exists_true() { |
| 66 new io.File(path).writeAsStringSync('contents'); |
| 67 expect(file.exists, isTrue); |
| 68 } |
| 69 |
| 70 void test_fullName() { |
| 71 expect(file.path, path); |
| 72 } |
| 73 |
| 74 void test_hashCode() { |
| 75 new io.File(path).writeAsStringSync('contents'); |
| 76 File file2 = PhysicalResourceProvider.INSTANCE.getResource(path); |
| 77 expect(file.hashCode, equals(file2.hashCode)); |
| 78 } |
| 79 |
| 80 void test_isOrContains() { |
| 81 File file = PhysicalResourceProvider.INSTANCE.getResource(path); |
| 82 expect(file.isOrContains(path), isTrue); |
| 83 expect(file.isOrContains('foo'), isFalse); |
| 84 } |
| 85 |
| 86 void test_modificationStamp_doesNotExist() { |
| 87 File file = PhysicalResourceProvider.INSTANCE.getResource(path); |
| 88 expect(() { |
| 89 file.modificationStamp; |
| 90 }, throwsA(_isFileSystemException)); |
| 91 } |
| 92 |
| 93 void test_modificationStamp_exists() { |
| 94 new io.File(path).writeAsStringSync('contents'); |
| 95 File file = PhysicalResourceProvider.INSTANCE.getResource(path); |
| 96 expect(file.modificationStamp, isNonNegative); |
| 97 } |
| 98 |
| 99 void test_parent() { |
| 100 Resource parent = file.parent; |
| 101 expect(parent, new isInstanceOf<Folder>()); |
| 102 expect(parent.path, equals(tempPath)); |
| 103 } |
| 104 |
| 105 void test_shortName() { |
| 106 expect(file.shortName, 'file.txt'); |
| 107 } |
| 108 |
| 109 void test_toString() { |
| 110 expect(file.toString(), path); |
| 111 } |
| 112 } |
| 113 |
| 114 @reflectiveTest |
| 115 class FolderTest extends _BaseTest { |
| 116 String path; |
| 117 Folder folder; |
| 118 |
| 119 setUp() { |
| 120 super.setUp(); |
| 121 path = join(tempPath, 'folder'); |
| 122 new io.Directory(path).createSync(); |
| 123 folder = PhysicalResourceProvider.INSTANCE.getResource(path); |
| 124 } |
| 125 |
| 126 void test_canonicalizePath() { |
| 127 String path2 = join(tempPath, 'folder2'); |
| 128 String path3 = join(tempPath, 'folder3'); |
| 129 expect(folder.canonicalizePath('baz'), equals(join(path, 'baz'))); |
| 130 expect(folder.canonicalizePath(path2), equals(path2)); |
| 131 expect(folder.canonicalizePath(join('..', 'folder2')), equals(path2)); |
| 132 expect( |
| 133 folder.canonicalizePath(join(path2, '..', 'folder3')), equals(path3)); |
| 134 expect( |
| 135 folder.canonicalizePath(join('.', 'baz')), equals(join(path, 'baz'))); |
| 136 expect(folder.canonicalizePath(join(path2, '.', 'baz')), |
| 137 equals(join(path2, 'baz'))); |
| 138 } |
| 139 |
| 140 void test_contains() { |
| 141 expect(folder.contains(join(path, 'aaa.txt')), isTrue); |
| 142 expect(folder.contains(join(path, 'aaa', 'bbb.txt')), isTrue); |
| 143 expect(folder.contains(join(tempPath, 'baz.txt')), isFalse); |
| 144 expect(folder.contains(path), isFalse); |
| 145 } |
| 146 |
| 147 void test_equals_differentPaths() { |
| 148 String path2 = join(tempPath, 'folder2'); |
| 149 new io.Directory(path2).createSync(); |
| 150 Folder folder2 = PhysicalResourceProvider.INSTANCE.getResource(path2); |
| 151 expect(folder == folder2, isFalse); |
| 152 } |
| 153 |
| 154 void test_equals_samePath() { |
| 155 Folder folder2 = PhysicalResourceProvider.INSTANCE.getResource(path); |
| 156 expect(folder == folder2, isTrue); |
| 157 } |
| 158 |
| 159 void test_getChild_doesNotExist() { |
| 160 var child = folder.getChild('no-such-resource'); |
| 161 expect(child, isNotNull); |
| 162 expect(child.exists, isFalse); |
| 163 } |
| 164 |
| 165 void test_getChild_file() { |
| 166 new io.File(join(path, 'myFile')).createSync(); |
| 167 var child = folder.getChild('myFile'); |
| 168 expect(child, _isFile); |
| 169 expect(child.exists, isTrue); |
| 170 } |
| 171 |
| 172 void test_getChild_folder() { |
| 173 new io.Directory(join(path, 'myFolder')).createSync(); |
| 174 var child = folder.getChild('myFolder'); |
| 175 expect(child, _isFolder); |
| 176 expect(child.exists, isTrue); |
| 177 } |
| 178 |
| 179 void test_getChildAssumingFolder_doesNotExist() { |
| 180 Folder child = folder.getChildAssumingFolder('no-such-resource'); |
| 181 expect(child, isNotNull); |
| 182 expect(child.exists, isFalse); |
| 183 } |
| 184 |
| 185 void test_getChildAssumingFolder_file() { |
| 186 new io.File(join(path, 'myFile')).createSync(); |
| 187 Folder child = folder.getChildAssumingFolder('myFile'); |
| 188 expect(child, isNotNull); |
| 189 expect(child.exists, isFalse); |
| 190 } |
| 191 |
| 192 void test_getChildAssumingFolder_folder() { |
| 193 new io.Directory(join(path, 'myFolder')).createSync(); |
| 194 Folder child = folder.getChildAssumingFolder('myFolder'); |
| 195 expect(child, isNotNull); |
| 196 expect(child.exists, isTrue); |
| 197 } |
| 198 |
| 199 void test_getChildren_doesNotExist() { |
| 200 folder = folder.getChildAssumingFolder('no-such-folder'); |
| 201 expect(() { |
| 202 folder.getChildren(); |
| 203 }, throwsA(_isFileSystemException)); |
| 204 } |
| 205 |
| 206 void test_getChildren_exists() { |
| 207 // create 2 files and 1 folder |
| 208 new io.File(join(path, 'a.txt')).createSync(); |
| 209 new io.Directory(join(path, 'bFolder')).createSync(); |
| 210 new io.File(join(path, 'c.txt')).createSync(); |
| 211 // prepare 3 children |
| 212 List<Resource> children = folder.getChildren(); |
| 213 expect(children, hasLength(3)); |
| 214 children.sort((a, b) => a.shortName.compareTo(b.shortName)); |
| 215 // check that each child exists |
| 216 children.forEach((child) { |
| 217 expect(child.exists, true); |
| 218 }); |
| 219 // check names |
| 220 expect(children[0].shortName, 'a.txt'); |
| 221 expect(children[1].shortName, 'bFolder'); |
| 222 expect(children[2].shortName, 'c.txt'); |
| 223 // check types |
| 224 expect(children[0], _isFile); |
| 225 expect(children[1], _isFolder); |
| 226 expect(children[2], _isFile); |
| 227 } |
| 228 |
| 229 void test_hashCode() { |
| 230 Folder folder2 = PhysicalResourceProvider.INSTANCE.getResource(path); |
| 231 expect(folder.hashCode, equals(folder2.hashCode)); |
| 232 } |
| 233 |
| 234 void test_isOrContains() { |
| 235 expect(folder.isOrContains(path), isTrue); |
| 236 expect(folder.isOrContains(join(path, 'aaa.txt')), isTrue); |
| 237 expect(folder.isOrContains(join(path, 'aaa', 'bbb.txt')), isTrue); |
| 238 expect(folder.isOrContains(join(tempPath, 'baz.txt')), isFalse); |
| 239 } |
| 240 |
| 241 void test_parent() { |
| 242 Resource parent = folder.parent; |
| 243 expect(parent, new isInstanceOf<Folder>()); |
| 244 expect(parent.path, equals(tempPath)); |
| 245 |
| 246 // Since the OS is in control of where tempPath is, we don't know how |
| 247 // far it should be from the root. So just verify that each call to |
| 248 // parent results in a a folder with a shorter path, and that we |
| 249 // reach the root eventually. |
| 250 while (true) { |
| 251 Resource grandParent = parent.parent; |
| 252 if (grandParent == null) { |
| 253 break; |
| 43 } | 254 } |
| 44 | 255 expect(grandParent, new isInstanceOf<Folder>()); |
| 45 watchingFolder(String path, test(List<WatchEvent> changesReceived)) { | 256 expect(grandParent.path.length, lessThan(parent.path.length)); |
| 46 // Delay before we start watching the folder. This is necessary | 257 parent = grandParent; |
| 47 // because on MacOS, file modifications that occur just before we | 258 } |
| 48 // start watching are sometimes misclassified as happening just after | 259 } |
| 49 // we start watching. | 260 } |
| 50 return delayed(() { | 261 |
| 51 Folder folder = PhysicalResourceProvider.INSTANCE.getResource(path); | 262 @reflectiveTest |
| 52 var changesReceived = <WatchEvent>[]; | 263 class PhysicalResourceProviderTest extends _BaseTest { |
| 53 var subscription = folder.changes.listen(changesReceived.add); | 264 void test_getStateLocation_uniqueness() { |
| 54 // Delay running the rest of the test to allow folder.changes to | 265 PhysicalResourceProvider provider = PhysicalResourceProvider.INSTANCE; |
| 55 // take a snapshot of the current directory state. Otherwise it | 266 String idOne = 'one'; |
| 56 // won't be able to reliably distinguish new files from modified | 267 Folder folderOne = provider.getStateLocation(idOne); |
| 57 // ones. | 268 expect(folderOne, isNotNull); |
| 58 return delayed(() => test(changesReceived)).whenComplete(() { | 269 String idTwo = 'two'; |
| 59 subscription.cancel(); | 270 Folder folderTwo = provider.getStateLocation(idTwo); |
| 60 }); | 271 expect(folderTwo, isNotNull); |
| 61 }); | 272 expect(folderTwo, isNot(equals(folderOne))); |
| 62 } | 273 expect(provider.getStateLocation(idOne), equals(folderOne)); |
| 63 | 274 } |
| 64 test('create file', () => watchingFolder(tempPath, (changesReceived) { | 275 |
| 65 expect(changesReceived, hasLength(0)); | 276 test_watch_createFile() { |
| 66 var path = join(tempPath, 'foo'); | 277 return _watchingFolder(tempPath, (changesReceived) { |
| 67 new io.File(path).writeAsStringSync('contents'); | 278 expect(changesReceived, hasLength(0)); |
| 68 return delayed(() { | 279 var path = join(tempPath, 'foo'); |
| 69 // There should be an "add" event indicating that the file was added. | 280 new io.File(path).writeAsStringSync('contents'); |
| 70 // Depending on how long it took to write the contents, it may be | 281 return _delayed(() { |
| 71 // followed by "modify" events. | 282 // There should be an "add" event indicating that the file was added. |
| 72 expect(changesReceived, isNotEmpty); | 283 // Depending on how long it took to write the contents, it may be |
| 73 expect(changesReceived[0].type, equals(ChangeType.ADD)); | 284 // followed by "modify" events. |
| 74 expect(changesReceived[0].path, equals(path)); | 285 expect(changesReceived, isNotEmpty); |
| 75 for (int i = 1; i < changesReceived.length; i++) { | 286 expect(changesReceived[0].type, equals(ChangeType.ADD)); |
| 76 expect(changesReceived[i].type, equals(ChangeType.MODIFY)); | 287 expect(changesReceived[0].path, equals(path)); |
| 77 expect(changesReceived[i].path, equals(path)); | 288 for (int i = 1; i < changesReceived.length; i++) { |
| 78 } | 289 expect(changesReceived[i].type, equals(ChangeType.MODIFY)); |
| 79 }); | 290 expect(changesReceived[i].path, equals(path)); |
| 80 })); | |
| 81 | |
| 82 test('modify file', () { | |
| 83 var path = join(tempPath, 'foo'); | |
| 84 var file = new io.File(path); | |
| 85 file.writeAsStringSync('contents 1'); | |
| 86 return watchingFolder(tempPath, (changesReceived) { | |
| 87 expect(changesReceived, hasLength(0)); | |
| 88 file.writeAsStringSync('contents 2'); | |
| 89 return delayed(() { | |
| 90 expect(changesReceived, hasLength(1)); | |
| 91 expect(changesReceived[0].type, equals(ChangeType.MODIFY)); | |
| 92 expect(changesReceived[0].path, equals(path)); | |
| 93 }); | |
| 94 }); | |
| 95 }); | |
| 96 | |
| 97 test('modify file in subdir', () { | |
| 98 var subdirPath = join(tempPath, 'foo'); | |
| 99 new io.Directory(subdirPath).createSync(); | |
| 100 var path = join(tempPath, 'bar'); | |
| 101 var file = new io.File(path); | |
| 102 file.writeAsStringSync('contents 1'); | |
| 103 return watchingFolder(tempPath, (changesReceived) { | |
| 104 expect(changesReceived, hasLength(0)); | |
| 105 file.writeAsStringSync('contents 2'); | |
| 106 return delayed(() { | |
| 107 expect(changesReceived, hasLength(1)); | |
| 108 expect(changesReceived[0].type, equals(ChangeType.MODIFY)); | |
| 109 expect(changesReceived[0].path, equals(path)); | |
| 110 }); | |
| 111 }); | |
| 112 }); | |
| 113 | |
| 114 test('delete file', () { | |
| 115 var path = join(tempPath, 'foo'); | |
| 116 var file = new io.File(path); | |
| 117 file.writeAsStringSync('contents 1'); | |
| 118 return watchingFolder(tempPath, (changesReceived) { | |
| 119 expect(changesReceived, hasLength(0)); | |
| 120 file.deleteSync(); | |
| 121 return delayed(() { | |
| 122 expect(changesReceived, hasLength(1)); | |
| 123 expect(changesReceived[0].type, equals(ChangeType.REMOVE)); | |
| 124 expect(changesReceived[0].path, equals(path)); | |
| 125 }); | |
| 126 }); | |
| 127 }); | |
| 128 }); | |
| 129 | |
| 130 group('getStateLocation', () { | |
| 131 test('uniqueness', () { | |
| 132 PhysicalResourceProvider provider = PhysicalResourceProvider.INSTANCE; | |
| 133 String idOne = 'one'; | |
| 134 Folder folderOne = provider.getStateLocation(idOne); | |
| 135 expect(folderOne, isNotNull); | |
| 136 String idTwo = 'two'; | |
| 137 Folder folderTwo = provider.getStateLocation(idTwo); | |
| 138 expect(folderTwo, isNotNull); | |
| 139 expect(folderTwo, isNot(equals(folderOne))); | |
| 140 expect(provider.getStateLocation(idOne), equals(folderOne)); | |
| 141 }); | |
| 142 }); | |
| 143 | |
| 144 group('File', () { | |
| 145 String path; | |
| 146 File file; | |
| 147 | |
| 148 setUp(() { | |
| 149 path = join(tempPath, 'file.txt'); | |
| 150 file = PhysicalResourceProvider.INSTANCE.getResource(path); | |
| 151 }); | |
| 152 | |
| 153 test('createSource', () { | |
| 154 new io.File(path).writeAsStringSync('contents'); | |
| 155 Source source = file.createSource(); | |
| 156 expect(source.uriKind, UriKind.FILE_URI); | |
| 157 expect(source.exists(), isTrue); | |
| 158 expect(source.contents.data, 'contents'); | |
| 159 }); | |
| 160 | |
| 161 group('exists', () { | |
| 162 test('false', () { | |
| 163 expect(file.exists, isFalse); | |
| 164 }); | |
| 165 | |
| 166 test('true', () { | |
| 167 new io.File(path).writeAsStringSync('contents'); | |
| 168 expect(file.exists, isTrue); | |
| 169 }); | |
| 170 }); | |
| 171 | |
| 172 test('fullName', () { | |
| 173 expect(file.path, path); | |
| 174 }); | |
| 175 | |
| 176 test('hashCode', () { | |
| 177 new io.File(path).writeAsStringSync('contents'); | |
| 178 File file2 = PhysicalResourceProvider.INSTANCE.getResource(path); | |
| 179 expect(file.hashCode, equals(file2.hashCode)); | |
| 180 }); | |
| 181 | |
| 182 test('equality: same path', () { | |
| 183 new io.File(path).writeAsStringSync('contents'); | |
| 184 File file2 = PhysicalResourceProvider.INSTANCE.getResource(path); | |
| 185 expect(file == file2, isTrue); | |
| 186 }); | |
| 187 | |
| 188 test('equality: different paths', () { | |
| 189 String path2 = join(tempPath, 'file2.txt'); | |
| 190 File file2 = PhysicalResourceProvider.INSTANCE.getResource(path2); | |
| 191 expect(file == file2, isFalse); | |
| 192 }); | |
| 193 | |
| 194 test('isOrContains', () { | |
| 195 File file = PhysicalResourceProvider.INSTANCE.getResource(path); | |
| 196 expect(file.isOrContains(path), isTrue); | |
| 197 expect(file.isOrContains('foo'), isFalse); | |
| 198 }); | |
| 199 | |
| 200 group('modificationStamp', () { | |
| 201 test('exists', () { | |
| 202 new io.File(path).writeAsStringSync('contents'); | |
| 203 File file = PhysicalResourceProvider.INSTANCE.getResource(path); | |
| 204 expect(file.modificationStamp, isNonNegative); | |
| 205 }); | |
| 206 | |
| 207 test('does not exist', () { | |
| 208 File file = PhysicalResourceProvider.INSTANCE.getResource(path); | |
| 209 expect(() { | |
| 210 file.modificationStamp; | |
| 211 }, throwsA(_isFileSystemException)); | |
| 212 }); | |
| 213 }); | |
| 214 | |
| 215 test('shortName', () { | |
| 216 expect(file.shortName, 'file.txt'); | |
| 217 }); | |
| 218 | |
| 219 test('toString', () { | |
| 220 expect(file.toString(), path); | |
| 221 }); | |
| 222 | |
| 223 test('parent', () { | |
| 224 Resource parent = file.parent; | |
| 225 expect(parent, new isInstanceOf<Folder>()); | |
| 226 expect(parent.path, equals(tempPath)); | |
| 227 }); | |
| 228 }); | |
| 229 | |
| 230 group('Folder', () { | |
| 231 String path; | |
| 232 Folder folder; | |
| 233 | |
| 234 setUp(() { | |
| 235 path = join(tempPath, 'folder'); | |
| 236 new io.Directory(path).createSync(); | |
| 237 folder = PhysicalResourceProvider.INSTANCE.getResource(path); | |
| 238 }); | |
| 239 | |
| 240 test('hashCode', () { | |
| 241 Folder folder2 = PhysicalResourceProvider.INSTANCE.getResource(path); | |
| 242 expect(folder.hashCode, equals(folder2.hashCode)); | |
| 243 }); | |
| 244 | |
| 245 test('equality: same path', () { | |
| 246 Folder folder2 = PhysicalResourceProvider.INSTANCE.getResource(path); | |
| 247 expect(folder == folder2, isTrue); | |
| 248 }); | |
| 249 | |
| 250 test('equality: different paths', () { | |
| 251 String path2 = join(tempPath, 'folder2'); | |
| 252 new io.Directory(path2).createSync(); | |
| 253 Folder folder2 = PhysicalResourceProvider.INSTANCE.getResource(path2); | |
| 254 expect(folder == folder2, isFalse); | |
| 255 }); | |
| 256 | |
| 257 test('contains', () { | |
| 258 expect(folder.contains(join(path, 'aaa.txt')), isTrue); | |
| 259 expect(folder.contains(join(path, 'aaa', 'bbb.txt')), isTrue); | |
| 260 expect(folder.contains(join(tempPath, 'baz.txt')), isFalse); | |
| 261 expect(folder.contains(path), isFalse); | |
| 262 }); | |
| 263 | |
| 264 test('isOrContains', () { | |
| 265 expect(folder.isOrContains(path), isTrue); | |
| 266 expect(folder.isOrContains(join(path, 'aaa.txt')), isTrue); | |
| 267 expect(folder.isOrContains(join(path, 'aaa', 'bbb.txt')), isTrue); | |
| 268 expect(folder.isOrContains(join(tempPath, 'baz.txt')), isFalse); | |
| 269 }); | |
| 270 | |
| 271 group('getChild', () { | |
| 272 test('does not exist', () { | |
| 273 var child = folder.getChild('no-such-resource'); | |
| 274 expect(child, isNotNull); | |
| 275 expect(child.exists, isFalse); | |
| 276 }); | |
| 277 | |
| 278 test('file', () { | |
| 279 new io.File(join(path, 'myFile')).createSync(); | |
| 280 var child = folder.getChild('myFile'); | |
| 281 expect(child, _isFile); | |
| 282 expect(child.exists, isTrue); | |
| 283 }); | |
| 284 | |
| 285 test('folder', () { | |
| 286 new io.Directory(join(path, 'myFolder')).createSync(); | |
| 287 var child = folder.getChild('myFolder'); | |
| 288 expect(child, _isFolder); | |
| 289 expect(child.exists, isTrue); | |
| 290 }); | |
| 291 }); | |
| 292 | |
| 293 group('getChildAssumingFolder', () { | |
| 294 test('does not exist', () { | |
| 295 Folder child = folder.getChildAssumingFolder('no-such-resource'); | |
| 296 expect(child, isNotNull); | |
| 297 expect(child.exists, isFalse); | |
| 298 }); | |
| 299 | |
| 300 test('file', () { | |
| 301 new io.File(join(path, 'myFile')).createSync(); | |
| 302 Folder child = folder.getChildAssumingFolder('myFile'); | |
| 303 expect(child, isNotNull); | |
| 304 expect(child.exists, isFalse); | |
| 305 }); | |
| 306 | |
| 307 test('folder', () { | |
| 308 new io.Directory(join(path, 'myFolder')).createSync(); | |
| 309 Folder child = folder.getChildAssumingFolder('myFolder'); | |
| 310 expect(child, isNotNull); | |
| 311 expect(child.exists, isTrue); | |
| 312 }); | |
| 313 }); | |
| 314 | |
| 315 group('getChildren', () { | |
| 316 test('exists', () { | |
| 317 // create 2 files and 1 folder | |
| 318 new io.File(join(path, 'a.txt')).createSync(); | |
| 319 new io.Directory(join(path, 'bFolder')).createSync(); | |
| 320 new io.File(join(path, 'c.txt')).createSync(); | |
| 321 // prepare 3 children | |
| 322 List<Resource> children = folder.getChildren(); | |
| 323 expect(children, hasLength(3)); | |
| 324 children.sort((a, b) => a.shortName.compareTo(b.shortName)); | |
| 325 // check that each child exists | |
| 326 children.forEach((child) { | |
| 327 expect(child.exists, true); | |
| 328 }); | |
| 329 // check names | |
| 330 expect(children[0].shortName, 'a.txt'); | |
| 331 expect(children[1].shortName, 'bFolder'); | |
| 332 expect(children[2].shortName, 'c.txt'); | |
| 333 // check types | |
| 334 expect(children[0], _isFile); | |
| 335 expect(children[1], _isFolder); | |
| 336 expect(children[2], _isFile); | |
| 337 }); | |
| 338 | |
| 339 test('does not exist', () { | |
| 340 folder = folder.getChildAssumingFolder('no-such-folder'); | |
| 341 expect(() { | |
| 342 folder.getChildren(); | |
| 343 }, throwsA(_isFileSystemException)); | |
| 344 }); | |
| 345 }); | |
| 346 | |
| 347 test('parent', () { | |
| 348 Resource parent = folder.parent; | |
| 349 expect(parent, new isInstanceOf<Folder>()); | |
| 350 expect(parent.path, equals(tempPath)); | |
| 351 | |
| 352 // Since the OS is in control of where tempPath is, we don't know how | |
| 353 // far it should be from the root. So just verify that each call to | |
| 354 // parent results in a a folder with a shorter path, and that we | |
| 355 // reach the root eventually. | |
| 356 while (true) { | |
| 357 Resource grandParent = parent.parent; | |
| 358 if (grandParent == null) { | |
| 359 break; | |
| 360 } | |
| 361 expect(grandParent, new isInstanceOf<Folder>()); | |
| 362 expect(grandParent.path.length, lessThan(parent.path.length)); | |
| 363 parent = grandParent; | |
| 364 } | 291 } |
| 365 }); | 292 }); |
| 366 | 293 }); |
| 367 test('canonicalizePath', () { | 294 } |
| 368 String path2 = join(tempPath, 'folder2'); | 295 |
| 369 String path3 = join(tempPath, 'folder3'); | 296 test_watch_deleteFile() { |
| 370 expect(folder.canonicalizePath('baz'), equals(join(path, 'baz'))); | 297 var path = join(tempPath, 'foo'); |
| 371 expect(folder.canonicalizePath(path2), equals(path2)); | 298 var file = new io.File(path); |
| 372 expect(folder.canonicalizePath(join('..', 'folder2')), equals(path2)); | 299 file.writeAsStringSync('contents 1'); |
| 373 expect(folder.canonicalizePath(join(path2, '..', 'folder3')), | 300 return _watchingFolder(tempPath, (changesReceived) { |
| 374 equals(path3)); | 301 expect(changesReceived, hasLength(0)); |
| 375 expect(folder.canonicalizePath(join('.', 'baz')), | 302 file.deleteSync(); |
| 376 equals(join(path, 'baz'))); | 303 return _delayed(() { |
| 377 expect(folder.canonicalizePath(join(path2, '.', 'baz')), | 304 expect(changesReceived, hasLength(1)); |
| 378 equals(join(path2, 'baz'))); | 305 expect(changesReceived[0].type, equals(ChangeType.REMOVE)); |
| 379 }); | 306 expect(changesReceived[0].path, equals(path)); |
| 380 }); | 307 }); |
| 381 }); | 308 }); |
| 382 } | 309 } |
| 310 |
| 311 test_watch_modifyFile() { |
| 312 var path = join(tempPath, 'foo'); |
| 313 var file = new io.File(path); |
| 314 file.writeAsStringSync('contents 1'); |
| 315 return _watchingFolder(tempPath, (changesReceived) { |
| 316 expect(changesReceived, hasLength(0)); |
| 317 file.writeAsStringSync('contents 2'); |
| 318 return _delayed(() { |
| 319 expect(changesReceived, hasLength(1)); |
| 320 expect(changesReceived[0].type, equals(ChangeType.MODIFY)); |
| 321 expect(changesReceived[0].path, equals(path)); |
| 322 }); |
| 323 }); |
| 324 } |
| 325 |
| 326 test_watch_modifyFile_inSubDir() { |
| 327 var subdirPath = join(tempPath, 'foo'); |
| 328 new io.Directory(subdirPath).createSync(); |
| 329 var path = join(tempPath, 'bar'); |
| 330 var file = new io.File(path); |
| 331 file.writeAsStringSync('contents 1'); |
| 332 return _watchingFolder(tempPath, (changesReceived) { |
| 333 expect(changesReceived, hasLength(0)); |
| 334 file.writeAsStringSync('contents 2'); |
| 335 return _delayed(() { |
| 336 expect(changesReceived, hasLength(1)); |
| 337 expect(changesReceived[0].type, equals(ChangeType.MODIFY)); |
| 338 expect(changesReceived[0].path, equals(path)); |
| 339 }); |
| 340 }); |
| 341 } |
| 342 |
| 343 Future _delayed(computation()) { |
| 344 // Give the tests 1 second to detect the changes. While it may only |
| 345 // take up to a few hundred ms, a whole second gives a good margin |
| 346 // for when running tests. |
| 347 return new Future.delayed(new Duration(seconds: 1), computation); |
| 348 } |
| 349 |
| 350 _watchingFolder(String path, test(List<WatchEvent> changesReceived)) { |
| 351 // Delay before we start watching the folder. This is necessary |
| 352 // because on MacOS, file modifications that occur just before we |
| 353 // start watching are sometimes misclassified as happening just after |
| 354 // we start watching. |
| 355 return _delayed(() { |
| 356 Folder folder = PhysicalResourceProvider.INSTANCE.getResource(path); |
| 357 var changesReceived = <WatchEvent>[]; |
| 358 var subscription = folder.changes.listen(changesReceived.add); |
| 359 // Delay running the rest of the test to allow folder.changes to |
| 360 // take a snapshot of the current directory state. Otherwise it |
| 361 // won't be able to reliably distinguish new files from modified |
| 362 // ones. |
| 363 return _delayed(() => test(changesReceived)).whenComplete(() { |
| 364 subscription.cancel(); |
| 365 }); |
| 366 }); |
| 367 } |
| 368 } |
| 369 |
| 370 class _BaseTest { |
| 371 io.Directory tempDirectory; |
| 372 String tempPath; |
| 373 |
| 374 setUp() { |
| 375 tempDirectory = io.Directory.systemTemp.createTempSync('test_resource'); |
| 376 tempPath = tempDirectory.absolute.path; |
| 377 } |
| 378 |
| 379 tearDown() { |
| 380 tempDirectory.deleteSync(recursive: true); |
| 381 } |
| 382 } |
| OLD | NEW |