OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 watcher.test.utils; | 5 library watcher.test.utils; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:io'; | 8 import 'dart:io'; |
9 | 9 |
10 import 'package:path/path.dart' as p; | 10 import 'package:path/path.dart' as p; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 /// and is polling for changes. If you pass `false` for [waitForReady], it will | 77 /// and is polling for changes. If you pass `false` for [waitForReady], it will |
78 /// not schedule this delay. | 78 /// not schedule this delay. |
79 DirectoryWatcher createWatcher({bool waitForReady}) { | 79 DirectoryWatcher createWatcher({bool waitForReady}) { |
80 // Use a short delay to make the tests run quickly. | 80 // Use a short delay to make the tests run quickly. |
81 _watcher = new DirectoryWatcher(_sandboxDir, | 81 _watcher = new DirectoryWatcher(_sandboxDir, |
82 pollingDelay: new Duration(milliseconds: 100)); | 82 pollingDelay: new Duration(milliseconds: 100)); |
83 | 83 |
84 // Wait until the scan is finished so that we don't miss changes to files | 84 // Wait until the scan is finished so that we don't miss changes to files |
85 // that could occur before the scan completes. | 85 // that could occur before the scan completes. |
86 if (waitForReady != false) { | 86 if (waitForReady != false) { |
87 schedule(() => _watcher.ready); | 87 schedule(() => _watcher.ready, "wait for watcher to be ready"); |
88 } | 88 } |
89 | 89 |
90 currentSchedule.onComplete.schedule(() { | 90 currentSchedule.onComplete.schedule(() { |
91 _nextEvent = 0; | 91 _nextEvent = 0; |
92 _watcher = null; | 92 _watcher = null; |
93 }, "reset watcher"); | 93 }, "reset watcher"); |
94 | 94 |
95 return _watcher; | 95 return _watcher; |
96 } | 96 } |
97 | 97 |
98 void expectEvent(ChangeType type, String path) { | 98 void expectEvent(ChangeType type, String path) { |
99 // Immediately create the future. This ensures we don't register too late and | 99 // Immediately create the future. This ensures we don't register too late and |
100 // drop the event before we receive it. | 100 // drop the event before we receive it. |
101 var future = _watcher.events.elementAt(_nextEvent++).then((event) { | 101 var future = _watcher.events.elementAt(_nextEvent++).then((event) { |
102 expect(event, new _ChangeMatcher(type, path)); | 102 expect(event, new _ChangeMatcher(type, path)); |
103 }); | 103 }); |
104 | 104 |
105 // Make sure the schedule is watching it in case it fails. | 105 // Make sure the schedule is watching it in case it fails. |
106 currentSchedule.wrapFuture(future); | 106 currentSchedule.wrapFuture(future); |
107 | 107 |
108 // Schedule it so that later file modifications don't occur until after this | 108 // Schedule it so that later file modifications don't occur until after this |
109 // event is received. | 109 // event is received. |
110 schedule(() => future); | 110 schedule(() => future, "wait for $type event"); |
111 } | 111 } |
112 | 112 |
113 void expectAddEvent(String path) { | 113 void expectAddEvent(String path) { |
114 expectEvent(ChangeType.ADD, p.join(_sandboxDir, path)); | 114 expectEvent(ChangeType.ADD, p.join(_sandboxDir, path)); |
115 } | 115 } |
116 | 116 |
117 void expectModifyEvent(String path) { | 117 void expectModifyEvent(String path) { |
118 expectEvent(ChangeType.MODIFY, p.join(_sandboxDir, path)); | 118 expectEvent(ChangeType.MODIFY, p.join(_sandboxDir, path)); |
119 } | 119 } |
120 | 120 |
(...skipping 21 matching lines...) Expand all Loading... |
142 new File(fullPath).writeAsStringSync(contents); | 142 new File(fullPath).writeAsStringSync(contents); |
143 | 143 |
144 // Manually update the mock modification time for the file. | 144 // Manually update the mock modification time for the file. |
145 if (updateModified) { | 145 if (updateModified) { |
146 // Make sure we always use the same separator on Windows. | 146 // Make sure we always use the same separator on Windows. |
147 path = p.normalize(path); | 147 path = p.normalize(path); |
148 | 148 |
149 var milliseconds = _mockFileModificationTimes.putIfAbsent(path, () => 0); | 149 var milliseconds = _mockFileModificationTimes.putIfAbsent(path, () => 0); |
150 _mockFileModificationTimes[path]++; | 150 _mockFileModificationTimes[path]++; |
151 } | 151 } |
152 }); | 152 }, "write file $path"); |
153 } | 153 } |
154 | 154 |
155 /// Schedules deleting a file in the sandbox at [path]. | 155 /// Schedules deleting a file in the sandbox at [path]. |
156 void deleteFile(String path) { | 156 void deleteFile(String path) { |
157 schedule(() { | 157 schedule(() { |
158 new File(p.join(_sandboxDir, path)).deleteSync(); | 158 new File(p.join(_sandboxDir, path)).deleteSync(); |
159 }); | 159 }, "delete file $path"); |
160 } | 160 } |
161 | 161 |
162 /// Schedules renaming a file in the sandbox from [from] to [to]. | 162 /// Schedules renaming a file in the sandbox from [from] to [to]. |
163 /// | 163 /// |
164 /// If [contents] is omitted, creates an empty file. | 164 /// If [contents] is omitted, creates an empty file. |
165 void renameFile(String from, String to) { | 165 void renameFile(String from, String to) { |
166 schedule(() { | 166 schedule(() { |
167 new File(p.join(_sandboxDir, from)).renameSync(p.join(_sandboxDir, to)); | 167 new File(p.join(_sandboxDir, from)).renameSync(p.join(_sandboxDir, to)); |
168 | 168 |
169 // Make sure we always use the same separator on Windows. | 169 // Make sure we always use the same separator on Windows. |
170 to = p.normalize(to); | 170 to = p.normalize(to); |
171 | 171 |
172 // Manually update the mock modification time for the file. | 172 // Manually update the mock modification time for the file. |
173 var milliseconds = _mockFileModificationTimes.putIfAbsent(to, () => 0); | 173 var milliseconds = _mockFileModificationTimes.putIfAbsent(to, () => 0); |
174 _mockFileModificationTimes[to]++; | 174 _mockFileModificationTimes[to]++; |
175 }); | 175 }, "rename file $from to $to"); |
176 } | 176 } |
177 | 177 |
178 /// A [Matcher] for [WatchEvent]s. | 178 /// A [Matcher] for [WatchEvent]s. |
179 class _ChangeMatcher extends Matcher { | 179 class _ChangeMatcher extends Matcher { |
180 /// The expected change. | 180 /// The expected change. |
181 final ChangeType type; | 181 final ChangeType type; |
182 | 182 |
183 /// The expected path. | 183 /// The expected path. |
184 final String path; | 184 final String path; |
185 | 185 |
186 _ChangeMatcher(this.type, this.path); | 186 _ChangeMatcher(this.type, this.path); |
187 | 187 |
188 Description describe(Description description) { | 188 Description describe(Description description) { |
189 description.add("$type $path"); | 189 description.add("$type $path"); |
190 } | 190 } |
191 | 191 |
192 bool matches(item, Map matchState) => | 192 bool matches(item, Map matchState) => |
193 item is WatchEvent && | 193 item is WatchEvent && |
194 item.type == type && | 194 item.type == type && |
195 p.normalize(item.path) == p.normalize(path); | 195 p.normalize(item.path) == p.normalize(path); |
196 } | 196 } |
OLD | NEW |