blob: 8faa8956abe65a7d42107ec2e467c392f0f651e9 [file] [log] [blame]
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library matcher.prints_matcher;
import 'dart:async';
import 'description.dart';
import 'expect.dart';
import 'interfaces.dart';
import 'future_matchers.dart';
import 'util.dart';
/// Matches a [Function] that prints text that matches [matcher].
///
/// [matcher] may be a String or a [Matcher].
///
/// If the function this runs against returns a [Future], all text printed by
/// the function (using [Zone] scoping) until that Future completes is matched.
///
/// This only tracks text printed using the [print] function.
Matcher prints(matcher) => new _Prints(wrapMatcher(matcher));
class _Prints extends Matcher {
final Matcher _matcher;
_Prints(this._matcher);
bool matches(item, Map matchState) {
if (item is! Function) return false;
var buffer = new StringBuffer();
var result = runZoned(item, zoneSpecification:
new ZoneSpecification(print: (_, __, ____, line) {
buffer.writeln(line);
}));
if (result is! Future) {
var actual = buffer.toString();
matchState['prints.actual'] = actual;
return _matcher.matches(actual, matchState);
}
return completes.matches(result.then(wrapAsync((_) {
expect(buffer.toString(), _matcher);
}, 'prints')), matchState);
}
Description describe(Description description) =>
description.add('prints ').addDescriptionOf(_matcher);
Description describeMismatch(item, Description description, Map matchState,
bool verbose) {
var actual = matchState.remove('prints.actual');
if (actual == null) return description;
if (actual.isEmpty) return description.add("printed nothing.");
description.add('printed ').addDescriptionOf(actual);
// Create a new description for the matcher because at least
// [_StringEqualsMatcher] replaces the previous contents of the description.
var innerMismatch = _matcher.describeMismatch(
actual, new StringDescription(), matchState, verbose).toString();
if (innerMismatch.isNotEmpty) {
description.add('\n Which: ').add(innerMismatch.toString());
}
return description;
}
}