| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 library test.physical.resource.provider; | |
| 6 | |
| 7 import 'dart:async'; | |
| 8 import 'dart:io' as io; | |
| 9 | |
| 10 import 'package:analysis_server/src/resource.dart'; | |
| 11 import 'package:analyzer/src/generated/source_io.dart'; | |
| 12 import 'package:path/path.dart'; | |
| 13 import 'package:unittest/unittest.dart'; | |
| 14 import 'package:watcher/watcher.dart'; | |
| 15 | |
| 16 main() { | |
| 17 groupSep = ' | '; | |
| 18 | |
| 19 group('PhysicalResourceProvider', () { | |
| 20 io.Directory tempDirectory; | |
| 21 String tempPath; | |
| 22 | |
| 23 setUp(() { | |
| 24 tempDirectory = io.Directory.systemTemp.createTempSync('test_resource'); | |
| 25 tempPath = tempDirectory.absolute.path; | |
| 26 }); | |
| 27 | |
| 28 tearDown(() { | |
| 29 tempDirectory.deleteSync(recursive: true); | |
| 30 }); | |
| 31 | |
| 32 group('Watch', () { | |
| 33 | |
| 34 Future delayed(computation()) { | |
| 35 // Give the tests 1 second to detect the changes. While it may only | |
| 36 // take up to a few hundred ms, a whole second gives a good margin | |
| 37 // for when running tests. | |
| 38 return new Future.delayed( | |
| 39 new Duration(seconds: 1), computation); | |
| 40 } | |
| 41 | |
| 42 watchingFolder(String path, test(List<WatchEvent> changesReceived)) { | |
| 43 // Delay before we start watching the folder. This is necessary | |
| 44 // because on MacOS, file modifications that occur just before we | |
| 45 // start watching are sometimes misclassified as happening just after | |
| 46 // we start watching. | |
| 47 return delayed(() { | |
| 48 Folder folder = PhysicalResourceProvider.INSTANCE.getResource(path); | |
| 49 var changesReceived = <WatchEvent>[]; | |
| 50 var subscription = folder.changes.listen(changesReceived.add); | |
| 51 // Delay running the rest of the test to allow folder.changes to | |
| 52 // take a snapshot of the current directory state. Otherwise it | |
| 53 // won't be able to reliably distinguish new files from modified | |
| 54 // ones. | |
| 55 return delayed(() => test(changesReceived)).whenComplete(() { | |
| 56 subscription.cancel(); | |
| 57 }); | |
| 58 }); | |
| 59 } | |
| 60 | |
| 61 test('create file', () => watchingFolder(tempPath, (changesReceived) { | |
| 62 expect(changesReceived, hasLength(0)); | |
| 63 var path = join(tempPath, 'foo'); | |
| 64 new io.File(path).writeAsStringSync('contents'); | |
| 65 return delayed(() { | |
| 66 expect(changesReceived, hasLength(1)); | |
| 67 expect(changesReceived[0].type, equals(ChangeType.ADD)); | |
| 68 expect(changesReceived[0].path, equals(path)); | |
| 69 }); | |
| 70 })); | |
| 71 | |
| 72 test('modify file', () { | |
| 73 var path = join(tempPath, 'foo'); | |
| 74 var file = new io.File(path); | |
| 75 file.writeAsStringSync('contents 1'); | |
| 76 return watchingFolder(tempPath, (changesReceived) { | |
| 77 expect(changesReceived, hasLength(0)); | |
| 78 file.writeAsStringSync('contents 2'); | |
| 79 return delayed(() { | |
| 80 expect(changesReceived, hasLength(1)); | |
| 81 expect(changesReceived[0].type, equals(ChangeType.MODIFY)); | |
| 82 expect(changesReceived[0].path, equals(path)); | |
| 83 }); | |
| 84 }); | |
| 85 }); | |
| 86 | |
| 87 test('modify file in subdir', () { | |
| 88 var subdirPath = join(tempPath, 'foo'); | |
| 89 new io.Directory(subdirPath).createSync(); | |
| 90 var path = join(tempPath, 'bar'); | |
| 91 var file = new io.File(path); | |
| 92 file.writeAsStringSync('contents 1'); | |
| 93 return watchingFolder(tempPath, (changesReceived) { | |
| 94 expect(changesReceived, hasLength(0)); | |
| 95 file.writeAsStringSync('contents 2'); | |
| 96 return delayed(() { | |
| 97 expect(changesReceived, hasLength(1)); | |
| 98 expect(changesReceived[0].type, equals(ChangeType.MODIFY)); | |
| 99 expect(changesReceived[0].path, equals(path)); | |
| 100 }); | |
| 101 }); | |
| 102 }); | |
| 103 | |
| 104 test('delete file', () { | |
| 105 var path = join(tempPath, 'foo'); | |
| 106 var file = new io.File(path); | |
| 107 file.writeAsStringSync('contents 1'); | |
| 108 return watchingFolder(tempPath, (changesReceived) { | |
| 109 expect(changesReceived, hasLength(0)); | |
| 110 file.deleteSync(); | |
| 111 return delayed(() { | |
| 112 expect(changesReceived, hasLength(1)); | |
| 113 expect(changesReceived[0].type, equals(ChangeType.REMOVE)); | |
| 114 expect(changesReceived[0].path, equals(path)); | |
| 115 }); | |
| 116 }); | |
| 117 }); | |
| 118 }); | |
| 119 | |
| 120 group('File', () { | |
| 121 String path; | |
| 122 File file; | |
| 123 | |
| 124 setUp(() { | |
| 125 path = join(tempPath, 'file.txt'); | |
| 126 file = PhysicalResourceProvider.INSTANCE.getResource(path); | |
| 127 }); | |
| 128 | |
| 129 test('createSource', () { | |
| 130 new io.File(path).writeAsStringSync('contents'); | |
| 131 var source = file.createSource(UriKind.FILE_URI); | |
| 132 expect(source.uriKind, UriKind.FILE_URI); | |
| 133 expect(source.exists(), isTrue); | |
| 134 expect(source.contents.data, 'contents'); | |
| 135 }); | |
| 136 | |
| 137 group('exists', () { | |
| 138 test('false', () { | |
| 139 expect(file.exists, isFalse); | |
| 140 }); | |
| 141 | |
| 142 test('true', () { | |
| 143 new io.File(path).writeAsStringSync('contents'); | |
| 144 expect(file.exists, isTrue); | |
| 145 }); | |
| 146 }); | |
| 147 | |
| 148 test('fullName', () { | |
| 149 expect(file.path, path); | |
| 150 }); | |
| 151 | |
| 152 test('hashCode', () { | |
| 153 new io.File(path).writeAsStringSync('contents'); | |
| 154 File file2 = PhysicalResourceProvider.INSTANCE.getResource(path); | |
| 155 expect(file.hashCode, equals(file2.hashCode)); | |
| 156 }); | |
| 157 | |
| 158 test('equality: same path', () { | |
| 159 new io.File(path).writeAsStringSync('contents'); | |
| 160 File file2 = PhysicalResourceProvider.INSTANCE.getResource(path); | |
| 161 expect(file == file2, isTrue); | |
| 162 }); | |
| 163 | |
| 164 test('equality: different paths', () { | |
| 165 String path2 = join(tempPath, 'file2.txt'); | |
| 166 File file2 = PhysicalResourceProvider.INSTANCE.getResource(path2); | |
| 167 expect(file == file2, isFalse); | |
| 168 }); | |
| 169 | |
| 170 test('shortName', () { | |
| 171 expect(file.shortName, 'file.txt'); | |
| 172 }); | |
| 173 | |
| 174 test('toString', () { | |
| 175 expect(file.toString(), path); | |
| 176 }); | |
| 177 | |
| 178 test('parent', () { | |
| 179 Resource parent = file.parent; | |
| 180 expect(parent, new isInstanceOf<Folder>()); | |
| 181 expect(parent.path, equals(tempPath)); | |
| 182 }); | |
| 183 }); | |
| 184 | |
| 185 group('Folder', () { | |
| 186 String path; | |
| 187 Folder folder; | |
| 188 | |
| 189 setUp(() { | |
| 190 path = join(tempPath, 'folder'); | |
| 191 new io.Directory(path).createSync(); | |
| 192 folder = PhysicalResourceProvider.INSTANCE.getResource(path); | |
| 193 }); | |
| 194 | |
| 195 test('hashCode', () { | |
| 196 Folder folder2 = PhysicalResourceProvider.INSTANCE.getResource(path); | |
| 197 expect(folder.hashCode, equals(folder2.hashCode)); | |
| 198 }); | |
| 199 | |
| 200 test('equality: same path', () { | |
| 201 Folder folder2 = PhysicalResourceProvider.INSTANCE.getResource(path); | |
| 202 expect(folder == folder2, isTrue); | |
| 203 }); | |
| 204 | |
| 205 test('equality: different paths', () { | |
| 206 String path2 = join(tempPath, 'folder2'); | |
| 207 new io.Directory(path2).createSync(); | |
| 208 Folder folder2 = PhysicalResourceProvider.INSTANCE.getResource(path2); | |
| 209 expect(folder == folder2, isFalse); | |
| 210 }); | |
| 211 | |
| 212 group('getChild', () { | |
| 213 test('does not exist', () { | |
| 214 var child = folder.getChild('no-such-resource'); | |
| 215 expect(child, isNotNull); | |
| 216 expect(child.exists, isFalse); | |
| 217 }); | |
| 218 | |
| 219 test('file', () { | |
| 220 new io.File(join(path, 'myFile')).createSync(); | |
| 221 var child = folder.getChild('myFile'); | |
| 222 expect(child, _isFile); | |
| 223 expect(child.exists, isTrue); | |
| 224 }); | |
| 225 | |
| 226 test('folder', () { | |
| 227 new io.Directory(join(path, 'myFolder')).createSync(); | |
| 228 var child = folder.getChild('myFolder'); | |
| 229 expect(child, _isFolder); | |
| 230 expect(child.exists, isTrue); | |
| 231 }); | |
| 232 }); | |
| 233 | |
| 234 test('getChildren', () { | |
| 235 // create 2 files and 1 folder | |
| 236 new io.File(join(path, 'a.txt')).createSync(); | |
| 237 new io.Directory(join(path, 'bFolder')).createSync(); | |
| 238 new io.File(join(path, 'c.txt')).createSync(); | |
| 239 // prepare 3 children | |
| 240 List<Resource> children = folder.getChildren(); | |
| 241 expect(children, hasLength(3)); | |
| 242 children.sort((a, b) => a.shortName.compareTo(b.shortName)); | |
| 243 // check that each child exists | |
| 244 children.forEach((child) { | |
| 245 expect(child.exists, true); | |
| 246 }); | |
| 247 // check names | |
| 248 expect(children[0].shortName, 'a.txt'); | |
| 249 expect(children[1].shortName, 'bFolder'); | |
| 250 expect(children[2].shortName, 'c.txt'); | |
| 251 // check types | |
| 252 expect(children[0], _isFile); | |
| 253 expect(children[1], _isFolder); | |
| 254 expect(children[2], _isFile); | |
| 255 }); | |
| 256 | |
| 257 test('parent', () { | |
| 258 Resource parent = folder.parent; | |
| 259 expect(parent, new isInstanceOf<Folder>()); | |
| 260 expect(parent.path, equals(tempPath)); | |
| 261 | |
| 262 // Since the OS is in control of where tempPath is, we don't know how | |
| 263 // far it should be from the root. So just verify that each call to | |
| 264 // parent results in a a folder with a shorter path, and that we | |
| 265 // reach the root eventually. | |
| 266 while (true) { | |
| 267 Resource grandParent = parent.parent; | |
| 268 if (grandParent == null) { | |
| 269 break; | |
| 270 } | |
| 271 expect(grandParent, new isInstanceOf<Folder>()); | |
| 272 expect(grandParent.path.length, lessThan(parent.path.length)); | |
| 273 parent = grandParent; | |
| 274 } | |
| 275 }); | |
| 276 | |
| 277 test('canonicalizePath', () { | |
| 278 String path2 = join(tempPath, 'folder2'); | |
| 279 String path3 = join(tempPath, 'folder3'); | |
| 280 expect(folder.canonicalizePath('baz'), equals(join(path, 'baz'))); | |
| 281 expect(folder.canonicalizePath(path2), equals(path2)); | |
| 282 expect(folder.canonicalizePath(join('..', 'folder2')), equals(path2)); | |
| 283 expect(folder.canonicalizePath(join(path2, '..', 'folder3')), equals(p
ath3)); | |
| 284 expect(folder.canonicalizePath(join('.', 'baz')), equals(join(path, 'b
az'))); | |
| 285 expect(folder.canonicalizePath(join(path2, '.', 'baz')), equals(join(p
ath2, 'baz'))); | |
| 286 }); | |
| 287 }); | |
| 288 }); | |
| 289 } | |
| 290 | |
| 291 var _isFile = new isInstanceOf<File>(); | |
| 292 var _isFolder = new isInstanceOf<Folder>(); | |
| 293 var _isMemoryResourceException = new isInstanceOf<MemoryResourceException>(); | |
| OLD | NEW |