1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 use super::{ObligationForest, Outcome, Error}
;
15 let mut forest
= ObligationForest
::new();
16 forest
.push_tree("A", "A");
17 forest
.push_tree("B", "B");
18 forest
.push_tree("C", "C");
20 // first round, B errors out, A has subtasks, and C completes, creating this:
24 let Outcome { completed: ok, errors: err, .. }
= forest
.process_obligations(|obligation
,
27 assert_eq
!(obligation
.chars().next(), tree
.chars().next());
29 "A" => Ok(Some(vec
!["A.1", "A.2", "A.3"])),
30 "B" => Err("B is for broken"),
31 "C" => Ok(Some(vec
![])),
35 assert_eq
!(ok
, vec
!["C"]);
38 error
: "B is for broken",
42 // second round: two delays, one success, creating an uneven set of subtasks:
48 forest
.push_tree("D", "D");
49 let Outcome { completed: ok, errors: err, .. }
: Outcome
<&'
static str, ()> =
50 forest
.process_obligations(|obligation
, tree
, _
| {
51 assert_eq
!(obligation
.chars().next(), tree
.chars().next());
55 "A.3" => Ok(Some(vec
!["A.3.i"])),
56 "D" => Ok(Some(vec
!["D.1", "D.2"])),
60 assert_eq
!(ok
, Vec
::<&'
static str>::new());
61 assert_eq
!(err
, Vec
::new());
64 // third round: ok in A.1 but trigger an error in A.2. Check that it
65 // propagates to A.3.i, but not D.1 or D.2.
66 // D |-> D.1 |-> D.1.i
68 let Outcome { completed: ok, errors: err, .. }
= forest
.process_obligations(|obligation
,
71 assert_eq
!(obligation
.chars().next(), tree
.chars().next());
73 "A.1" => Ok(Some(vec
![])),
74 "A.2" => Err("A is for apple"),
75 "D.1" => Ok(Some(vec
!["D.1.i"])),
76 "D.2" => Ok(Some(vec
!["D.2.i"])),
80 assert_eq
!(ok
, vec
!["A.1"]);
83 error
: "A is for apple",
84 backtrace
: vec
!["A.2", "A"],
87 // fourth round: error in D.1.i that should propagate to D.2.i
88 let Outcome { completed: ok, errors: err, .. }
= forest
.process_obligations(|obligation
,
91 assert_eq
!(obligation
.chars().next(), tree
.chars().next());
93 "D.1.i" => Err("D is for dumb"),
94 _
=> panic
!("unexpected obligation {:?}", obligation
),
97 assert_eq
!(ok
, Vec
::<&'
static str>::new());
100 error
: "D is for dumb",
101 backtrace
: vec
!["D.1.i", "D.1", "D"],
105 // Test that if a tree with grandchildren succeeds, everything is
106 // reported as expected:
114 fn success_in_grandchildren() {
115 let mut forest
= ObligationForest
::new();
116 forest
.push_tree("A", "A");
118 let Outcome { completed: ok, errors: err, .. }
=
119 forest
.process_obligations
::<(), _
>(|obligation
, tree
, _
| {
120 assert_eq
!(obligation
.chars().next(), tree
.chars().next());
122 "A" => Ok(Some(vec
!["A.1", "A.2", "A.3"])),
126 assert
!(ok
.is_empty());
127 assert
!(err
.is_empty());
129 let Outcome { completed: ok, errors: err, .. }
=
130 forest
.process_obligations
::<(), _
>(|obligation
, tree
, _
| {
131 assert_eq
!(obligation
.chars().next(), tree
.chars().next());
133 "A.1" => Ok(Some(vec
![])),
134 "A.2" => Ok(Some(vec
!["A.2.i", "A.2.ii"])),
135 "A.3" => Ok(Some(vec
![])),
139 assert_eq
!(ok
, vec
!["A.3", "A.1"]);
140 assert
!(err
.is_empty());
142 let Outcome { completed: ok, errors: err, .. }
=
143 forest
.process_obligations
::<(), _
>(|obligation
, tree
, _
| {
144 assert_eq
!(obligation
.chars().next(), tree
.chars().next());
146 "A.2.i" => Ok(Some(vec
!["A.2.i.a"])),
147 "A.2.ii" => Ok(Some(vec
![])),
151 assert_eq
!(ok
, vec
!["A.2.ii"]);
152 assert
!(err
.is_empty());
154 let Outcome { completed: ok, errors: err, .. }
=
155 forest
.process_obligations
::<(), _
>(|obligation
, tree
, _
| {
156 assert_eq
!(obligation
.chars().next(), tree
.chars().next());
158 "A.2.i.a" => Ok(Some(vec
![])),
162 assert_eq
!(ok
, vec
!["A.2.i.a", "A.2.i", "A.2", "A"]);
163 assert
!(err
.is_empty());
165 let Outcome { completed: ok, errors: err, .. }
= forest
.process_obligations
::<(), _
>(|_
,
170 assert
!(ok
.is_empty());
171 assert
!(err
.is_empty());
175 fn to_errors_no_throw() {
176 // check that converting multiple children with common parent (A)
177 // only yields one of them (and does not panic, in particular).
178 let mut forest
= ObligationForest
::new();
179 forest
.push_tree("A", "A");
180 let Outcome { completed: ok, errors: err, .. }
=
181 forest
.process_obligations
::<(), _
>(|obligation
, tree
, _
| {
182 assert_eq
!(obligation
.chars().next(), tree
.chars().next());
184 "A" => Ok(Some(vec
!["A.1", "A.2", "A.3"])),
188 assert_eq
!(ok
.len(), 0);
189 assert_eq
!(err
.len(), 0);
190 let errors
= forest
.to_errors(());
191 assert_eq
!(errors
.len(), 1);
196 // check that converting multiple children with common parent (A)
197 // only yields one of them (and does not panic, in particular).
198 let mut forest
= ObligationForest
::new();
199 forest
.push_tree("A", "A");
200 let Outcome { completed: ok, errors: err, .. }
=
201 forest
.process_obligations
::<(), _
>(|obligation
, tree
, mut backtrace
| {
202 assert_eq
!(obligation
.chars().next(), tree
.chars().next());
203 assert
!(backtrace
.next().is_none());
205 "A" => Ok(Some(vec
!["A.1"])),
209 assert
!(ok
.is_empty());
210 assert
!(err
.is_empty());
211 let Outcome { completed: ok, errors: err, .. }
=
212 forest
.process_obligations
::<(), _
>(|obligation
, tree
, mut backtrace
| {
213 assert_eq
!(obligation
.chars().next(), tree
.chars().next());
214 assert
!(backtrace
.next().unwrap() == &"A");
215 assert
!(backtrace
.next().is_none());
217 "A.1" => Ok(Some(vec
!["A.1.i"])),
221 assert
!(ok
.is_empty());
222 assert
!(err
.is_empty());
223 let Outcome { completed: ok, errors: err, .. }
=
224 forest
.process_obligations
::<(), _
>(|obligation
, tree
, mut backtrace
| {
225 assert_eq
!(obligation
.chars().next(), tree
.chars().next());
226 assert
!(backtrace
.next().unwrap() == &"A.1");
227 assert
!(backtrace
.next().unwrap() == &"A");
228 assert
!(backtrace
.next().is_none());
234 assert_eq
!(ok
.len(), 0);
235 assert
!(err
.is_empty());