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 '../frontend/test_chain.dart';
12 :
13 : /// This function is deprecated.
14 : ///
15 : /// Use [throwsA] instead. We strongly recommend that you add assertions about
16 : /// at least the type of the error, but you can write `throwsA(anything)` to
17 : /// mimic the behavior of this matcher.
18 : @Deprecated("Will be removed in 0.13.0")
19 : const Matcher throws = const Throws();
20 :
21 : /// This can be used to match three kinds of objects:
22 : ///
23 : /// * A [Function] that throws an exception when called. The function cannot
24 : /// take any arguments. If you want to test that a function expecting
25 : /// arguments throws, wrap it in another zero-argument function that calls
26 : /// the one you want to test.
27 : ///
28 : /// * A [Future] that completes with an exception. Note that this creates an
29 : /// asynchronous expectation. The call to `expect()` that includes this will
30 : /// return immediately and execution will continue. Later, when the future
31 : /// completes, the actual expectation will run.
32 : ///
33 : /// * A [Function] that returns a [Future] that completes with an exception.
34 : ///
35 : /// In all three cases, when an exception is thrown, this will test that the
36 : /// exception object matches [matcher]. If [matcher] is not an instance of
37 : /// [Matcher], it will implicitly be treated as `equals(matcher)`.
38 2 : Matcher throwsA(matcher) => new Throws(wrapMatcher(matcher));
39 :
40 : /// Use the [throwsA] function instead.
41 : @Deprecated("Will be removed in 0.13.0")
42 : class Throws extends AsyncMatcher {
43 : final Matcher _matcher;
44 :
45 1 : const Throws([Matcher matcher]) : this._matcher = matcher;
46 :
47 : // Avoid async/await so we synchronously fail if we match a synchronous
48 : // function.
49 : /*FutureOr<String>*/ matchAsync(item) {
50 1 : if (item is! Function && item is! Future) {
51 : return "was not a Function or Future";
52 : }
53 :
54 1 : if (item is Future) {
55 0 : return item.then((value) => indent(prettyPrint(value), first: 'emitted '),
56 0 : onError: _check);
57 : }
58 :
59 : try {
60 1 : var value = item();
61 0 : if (value is Future) {
62 0 : return value.then(
63 0 : (value) => indent(prettyPrint(value),
64 : first: 'returned a Future that emitted '),
65 0 : onError: _check);
66 : }
67 :
68 0 : return indent(prettyPrint(value), first: 'returned ');
69 : } catch (error, trace) {
70 1 : return _check(error, trace);
71 : }
72 : }
73 :
74 : Description describe(Description description) {
75 0 : if (_matcher == null) {
76 0 : return description.add("throws");
77 : } else {
78 0 : return description.add('throws ').addDescriptionOf(_matcher);
79 : }
80 : }
81 :
82 : /// Verifies that [error] matches [_matcher] and returns a [String]
83 : /// description of the failure if it doesn't.
84 : String _check(error, StackTrace trace) {
85 1 : if (_matcher == null) return null;
86 :
87 1 : var matchState = {};
88 2 : if (_matcher.matches(error, matchState)) return null;
89 :
90 0 : var result = _matcher
91 0 : .describeMismatch(error, new StringDescription(), matchState, false)
92 0 : .toString();
93 :
94 0 : var buffer = new StringBuffer();
95 0 : buffer.writeln(indent(prettyPrint(error), first: 'threw '));
96 : if (trace != null) {
97 0 : buffer.writeln(indent(testChain(trace).toString(), first: 'stack '));
98 : }
99 0 : if (result.isNotEmpty) buffer.writeln(indent(result, first: 'which '));
100 0 : return buffer.toString().trimRight();
101 : }
102 : }
|