| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 scheduled_test.stream_matcher; | 5 library scheduled_test.stream_matcher; |
| 6 | 6 |
| 7 import 'dart:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection'; | 8 import 'dart:collection'; |
| 9 | 9 |
| 10 import '../scheduled_stream.dart'; | 10 import '../scheduled_stream.dart'; |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 return stream.hasNext.then((hasNext) { | 133 return stream.hasNext.then((hasNext) { |
| 134 if (!hasNext) return new StringDescription('unexpected end of stream'); | 134 if (!hasNext) return new StringDescription('unexpected end of stream'); |
| 135 | 135 |
| 136 return stream.next().then((value) { | 136 return stream.next().then((value) { |
| 137 collectedValues.add(value); | 137 collectedValues.add(value); |
| 138 return collectValues(count - 1); | 138 return collectValues(count - 1); |
| 139 }); | 139 }); |
| 140 }); | 140 }); |
| 141 } | 141 } |
| 142 | 142 |
| 143 return collectValues(_n).then((description) { | 143 return collectValues(_n).then((failure) { |
| 144 if (description != null) return description; | 144 if (failure != null) return failure; |
| 145 var matchState = {}; | 145 var matchState = {}; |
| 146 if (_matcher.matches(collectedValues, matchState)) return null; | 146 if (_matcher.matches(collectedValues, matchState)) return null; |
| 147 return _matcher.describeMismatch(collectedValues, new StringDescription(), | 147 return _matcher.describeMismatch(collectedValues, new StringDescription(), |
| 148 matchState, false); | 148 matchState, false); |
| 149 }); | 149 }); |
| 150 } | 150 } |
| 151 | 151 |
| 152 String toString() { | 152 String toString() { |
| 153 return new StringDescription('$_n values that ') | 153 return new StringDescription('$_n values that ') |
| 154 .addDescriptionOf(_matcher) | 154 .addDescriptionOf(_matcher) |
| 155 .toString(); | 155 .toString(); |
| 156 } | 156 } |
| 157 } | 157 } |
| 158 | 158 |
| 159 /// See [inOrder]. | 159 /// See [inOrder]. |
| 160 class _InOrderMatcher implements StreamMatcher { | 160 class _InOrderMatcher implements StreamMatcher { |
| 161 final List<StreamMatcher> _matchers; | 161 final List<StreamMatcher> _matchers; |
| 162 | 162 |
| 163 _InOrderMatcher(Iterable streamMatchers) | 163 _InOrderMatcher(Iterable streamMatchers) |
| 164 : _matchers = streamMatchers.map((matcher) => | 164 : _matchers = streamMatchers.map((matcher) => |
| 165 new StreamMatcher.wrap(matcher)).toList(); | 165 new StreamMatcher.wrap(matcher)).toList(); |
| 166 | 166 |
| 167 Future<Description> tryMatch(ScheduledStream stream) { | 167 Future<Description> tryMatch(ScheduledStream stream) { |
| 168 var matchers = new Queue.from(_matchers); | 168 var matchers = new Queue.from(_matchers); |
| 169 | 169 |
| 170 matchNext() { | 170 matchNext() { |
| 171 if (matchers.isEmpty) return new Future.value(); | 171 if (matchers.isEmpty) return new Future.value(); |
| 172 var matcher = matchers.removeFirst(); | 172 var matcher = matchers.removeFirst(); |
| 173 return matcher.tryMatch(stream).then((description) { | 173 return matcher.tryMatch(stream).then((failure) { |
| 174 if (description == null) return matchNext(); | 174 if (failure == null) return matchNext(); |
| 175 var newDescription = new StringDescription( | 175 var newFailure = new StringDescription( |
| 176 'matcher #${_matchers.length - matchers.length} failed'); | 176 'matcher #${_matchers.length - matchers.length} failed'); |
| 177 if (description.length != 0) newDescription.add(':\n$description'); | 177 if (failure.length != 0) newFailure.add(':\n$failure'); |
| 178 return newDescription; | 178 return newFailure; |
| 179 }); | 179 }); |
| 180 } | 180 } |
| 181 | 181 |
| 182 return matchNext(); | 182 return matchNext(); |
| 183 } | 183 } |
| 184 | 184 |
| 185 String toString() => _matchers | 185 String toString() => _matchers |
| 186 .map((matcher) => prefixLines(matcher.toString(), firstPrefix: '* ')) | 186 .map((matcher) => prefixLines(matcher.toString(), firstPrefix: '* ')) |
| 187 .join('\n'); | 187 .join('\n'); |
| 188 } | 188 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 : _matcher1 = new StreamMatcher.wrap(streamMatcher1), | 224 : _matcher1 = new StreamMatcher.wrap(streamMatcher1), |
| 225 _matcher2 = new StreamMatcher.wrap(streamMatcher2); | 225 _matcher2 = new StreamMatcher.wrap(streamMatcher2); |
| 226 | 226 |
| 227 Future<Description> tryMatch(ScheduledStream stream) { | 227 Future<Description> tryMatch(ScheduledStream stream) { |
| 228 var stream1 = stream.fork(); | 228 var stream1 = stream.fork(); |
| 229 var stream2 = stream.fork(); | 229 var stream2 = stream.fork(); |
| 230 | 230 |
| 231 return Future.wait([ | 231 return Future.wait([ |
| 232 _matcher1.tryMatch(stream1).whenComplete(stream1.close), | 232 _matcher1.tryMatch(stream1).whenComplete(stream1.close), |
| 233 _matcher2.tryMatch(stream2).whenComplete(stream2.close) | 233 _matcher2.tryMatch(stream2).whenComplete(stream2.close) |
| 234 ]).then((descriptions) { | 234 ]).then((failures) { |
| 235 var description1 = descriptions.first; | 235 var failure1 = failures.first; |
| 236 var description2 = descriptions.last; | 236 var failure2 = failures.last; |
| 237 | 237 |
| 238 // If both matchers matched, use the one that consumed more of the stream. | 238 // If both matchers matched, use the one that consumed more of the stream. |
| 239 if (description1 == null && description2 == null) { | 239 if (failure1 == null && failure2 == null) { |
| 240 if (stream1.emittedValues.length >= stream2.emittedValues.length) { | 240 if (stream1.emittedValues.length >= stream2.emittedValues.length) { |
| 241 return _matcher1.tryMatch(stream); | 241 return _matcher1.tryMatch(stream); |
| 242 } else { | 242 } else { |
| 243 return _matcher2.tryMatch(stream); | 243 return _matcher2.tryMatch(stream); |
| 244 } | 244 } |
| 245 } else if (description1 == null) { | 245 } else if (failure1 == null) { |
| 246 return _matcher1.tryMatch(stream); | 246 return _matcher1.tryMatch(stream); |
| 247 } else if (description2 == null) { | 247 } else if (failure2 == null) { |
| 248 return _matcher2.tryMatch(stream); | 248 return _matcher2.tryMatch(stream); |
| 249 } else { | 249 } else { |
| 250 return new StringDescription('both\n') | 250 return new StringDescription('both\n') |
| 251 .add(prefixLines(description1.toString(), prefix: ' ')) | 251 .add(prefixLines(failure1.toString(), prefix: ' ')) |
| 252 .add('\nand\n') | 252 .add('\nand\n') |
| 253 .add(prefixLines(description2.toString(), prefix: ' ')) | 253 .add(prefixLines(failure2.toString(), prefix: ' ')) |
| 254 .toString(); | 254 .toString(); |
| 255 } | 255 } |
| 256 }); | 256 }); |
| 257 } | 257 } |
| 258 | 258 |
| 259 String toString() { | 259 String toString() { |
| 260 return new StringDescription('either\n') | 260 return new StringDescription('either\n') |
| 261 .add(prefixLines(_matcher1.toString(), prefix: ' ')) | 261 .add(prefixLines(_matcher1.toString(), prefix: ' ')) |
| 262 .add('\nor\n') | 262 .add('\nor\n') |
| 263 .add(prefixLines(_matcher2.toString(), prefix: ' ')) | 263 .add(prefixLines(_matcher2.toString(), prefix: ' ')) |
| 264 .toString(); | 264 .toString(); |
| 265 } | 265 } |
| 266 } | 266 } |
| 267 | 267 |
| 268 /// See [allow]. | 268 /// See [allow]. |
| 269 class _AllowMatcher implements StreamMatcher { | 269 class _AllowMatcher implements StreamMatcher { |
| 270 final StreamMatcher _matcher; | 270 final StreamMatcher _matcher; |
| 271 | 271 |
| 272 _AllowMatcher(streamMatcher) | 272 _AllowMatcher(streamMatcher) |
| 273 : _matcher = new StreamMatcher.wrap(streamMatcher); | 273 : _matcher = new StreamMatcher.wrap(streamMatcher); |
| 274 | 274 |
| 275 Future<Description> tryMatch(ScheduledStream stream) { | 275 Future<Description> tryMatch(ScheduledStream stream) { |
| 276 var fork = stream.fork(); | 276 var fork = stream.fork(); |
| 277 return _matcher.tryMatch(fork).whenComplete(fork.close).then((description) { | 277 return _matcher.tryMatch(fork).whenComplete(fork.close).then((failure) { |
| 278 if (description != null) return null; | 278 if (failure != null) return null; |
| 279 return _matcher.tryMatch(stream); | 279 return _matcher.tryMatch(stream); |
| 280 }); | 280 }); |
| 281 } | 281 } |
| 282 | 282 |
| 283 String toString() { | 283 String toString() { |
| 284 return new StringDescription('allow\n') | 284 return new StringDescription('allow\n') |
| 285 .add(prefixLines(_matcher.toString())) | 285 .add(prefixLines(_matcher.toString())) |
| 286 .toString(); | 286 .toString(); |
| 287 } | 287 } |
| 288 } | 288 } |
| 289 | 289 |
| 290 /// See [never]. | 290 /// See [never]. |
| 291 class _NeverMatcher implements StreamMatcher { | 291 class _NeverMatcher implements StreamMatcher { |
| 292 final StreamMatcher _matcher; | 292 final StreamMatcher _matcher; |
| 293 | 293 |
| 294 _NeverMatcher(streamMatcher) | 294 _NeverMatcher(streamMatcher) |
| 295 : _matcher = new StreamMatcher.wrap(streamMatcher); | 295 : _matcher = new StreamMatcher.wrap(streamMatcher); |
| 296 | 296 |
| 297 Future<Description> tryMatch(ScheduledStream stream) { | 297 Future<Description> tryMatch(ScheduledStream stream) { |
| 298 consumeNext() { | 298 consumeNext() { |
| 299 return stream.hasNext.then((hasNext) { | 299 return stream.hasNext.then((hasNext) { |
| 300 if (!hasNext) return new Future.value(); | 300 if (!hasNext) return new Future.value(); |
| 301 | 301 |
| 302 var fork = stream.fork(); | 302 var fork = stream.fork(); |
| 303 return _matcher.tryMatch(fork).whenComplete(fork.close) | 303 return _matcher.tryMatch(fork).whenComplete(fork.close) |
| 304 .then((description) { | 304 .then((failure) { |
| 305 if (description != null) { | 305 if (failure != null) { |
| 306 return stream.next().then((_) => consumeNext()); | 306 return stream.next().then((_) => consumeNext()); |
| 307 } | 307 } |
| 308 | 308 |
| 309 return new StringDescription("matched\n") | 309 return new StringDescription("matched\n") |
| 310 .add(prefixLines(_matcher.toString(), prefix: ' ')); | 310 .add(prefixLines(_matcher.toString(), prefix: ' ')); |
| 311 }); | 311 }); |
| 312 }); | 312 }); |
| 313 } | 313 } |
| 314 | 314 |
| 315 return consumeNext(); | 315 return consumeNext(); |
| 316 } | 316 } |
| 317 | 317 |
| 318 String toString() => | 318 String toString() => |
| 319 'never\n${prefixLines(_matcher.toString(), prefix: ' ')}'; | 319 'never\n${prefixLines(_matcher.toString(), prefix: ' ')}'; |
| 320 } | 320 } |
| 321 | 321 |
| 322 /// See [isDone]. | 322 /// See [isDone]. |
| 323 class _IsDoneMatcher implements StreamMatcher { | 323 class _IsDoneMatcher implements StreamMatcher { |
| 324 _IsDoneMatcher(); | 324 _IsDoneMatcher(); |
| 325 | 325 |
| 326 Future<Description> tryMatch(ScheduledStream stream) { | 326 Future<Description> tryMatch(ScheduledStream stream) { |
| 327 return stream.hasNext.then((hasNext) { | 327 return stream.hasNext.then((hasNext) { |
| 328 if (!hasNext) return null; | 328 if (!hasNext) return null; |
| 329 return new StringDescription("stream wasn't finished"); | 329 return new StringDescription("stream wasn't finished"); |
| 330 }); | 330 }); |
| 331 } | 331 } |
| 332 | 332 |
| 333 String toString() => 'is done'; | 333 String toString() => 'is done'; |
| 334 } | 334 } |
| OLD | NEW |