Line data Source code
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 : import 'dart:async';
6 :
7 : import 'package:matcher/matcher.dart';
8 :
9 : import '../utils.dart';
10 : import 'async_matcher.dart';
11 : import 'expect.dart';
12 :
13 : /// Matches a [Function] that prints text that matches [matcher].
14 : ///
15 : /// [matcher] may be a String or a [Matcher].
16 : ///
17 : /// If the function this runs against returns a [Future], all text printed by
18 : /// the function (using [Zone] scoping) until that Future completes is matched.
19 : ///
20 : /// This only tracks text printed using the [print] function.
21 : ///
22 : /// This returns an [AsyncMatcher], so [expect] won't complete until the matched
23 : /// function does.
24 0 : Matcher prints(matcher) => new _Prints(wrapMatcher(matcher));
25 :
26 : class _Prints extends AsyncMatcher {
27 : final Matcher _matcher;
28 :
29 0 : _Prints(this._matcher);
30 :
31 : // Avoid async/await so we synchronously fail if the function is
32 : // synchronous.
33 : /*FutureOr<String>*/ matchAsync(item) {
34 0 : if (item is! Function) return "was not a Function";
35 :
36 0 : var buffer = new StringBuffer();
37 0 : var result = runZoned(item,
38 0 : zoneSpecification: new ZoneSpecification(print: (_, __, ____, line) {
39 0 : buffer.writeln(line);
40 : }));
41 :
42 0 : return result is Future
43 0 : ? result.then((_) => _check(buffer.toString()))
44 0 : : _check(buffer.toString());
45 : }
46 :
47 : Description describe(Description description) =>
48 0 : description.add('prints ').addDescriptionOf(_matcher);
49 :
50 : /// Verifies that [actual] matches [_matcher] and returns a [String]
51 : /// description of the failure if it doesn't.
52 : String _check(String actual) {
53 0 : var matchState = {};
54 0 : if (_matcher.matches(actual, matchState)) return null;
55 :
56 0 : var result = _matcher
57 0 : .describeMismatch(actual, new StringDescription(), matchState, false)
58 0 : .toString();
59 :
60 0 : var buffer = new StringBuffer();
61 0 : if (actual.isEmpty) {
62 0 : buffer.writeln('printed nothing');
63 : } else {
64 0 : buffer.writeln(indent(prettyPrint(actual), first: 'printed '));
65 : }
66 0 : if (result.isNotEmpty) buffer.writeln(indent(result, first: ' which '));
67 0 : return buffer.toString().trimRight();
68 : }
69 : }
|