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_root("A");
17 forest.push_root("B");
18 forest.push_root("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, _| {
26 "A" => Ok(Some(vec!["A.1", "A.2", "A.3"])),
27 "B" => Err("B is for broken"),
28 "C" => Ok(Some(vec![])),
32 assert_eq!(ok, vec!["C"]);
33 assert_eq!(err, vec![Error {error: "B is for broken",
34 backtrace: vec!["B"]}]);
36 // second round: two delays, one success, creating an uneven set of subtasks:
42 forest.push_root("D");
43 let Outcome { completed: ok, errors: err, .. }: Outcome<&'static str, ()> =
44 forest.process_obligations(|obligation, _| {
48 "A.3" => Ok(Some(vec!["A.3.i"])),
49 "D" => Ok(Some(vec!["D.1", "D.2"])),
53 assert_eq!(ok, Vec::<&'static str>::new());
54 assert_eq!(err, Vec::new());
57 // third round: ok in A.1 but trigger an error in A.2. Check that it
58 // propagates to A.3.i, but not D.1 or D.2.
59 // D |-> D.1 |-> D.1.i
61 let Outcome { completed: ok, errors: err, .. } = forest.process_obligations(|obligation, _| {
63 "A.1" => Ok(Some(vec![])),
64 "A.2" => Err("A is for apple"),
65 "D.1" => Ok(Some(vec!["D.1.i"])),
66 "D.2" => Ok(Some(vec!["D.2.i"])),
70 assert_eq!(ok, vec!["A.1"]);
71 assert_eq!(err, vec![Error { error: "A is for apple",
72 backtrace: vec!["A.2", "A"] }]);
74 // fourth round: error in D.1.i that should propagate to D.2.i
75 let Outcome { completed: ok, errors: err, .. } = forest.process_obligations(|obligation, _| {
77 "D.1.i" => Err("D is for dumb"),
78 _ => panic!("unexpected obligation {:?}", obligation),
81 assert_eq!(ok, Vec::<&'static str>::new());
82 assert_eq!(err, vec![Error { error: "D is for dumb",
83 backtrace: vec!["D.1.i", "D.1", "D"] }]);
86 // Test that if a tree with grandchildren succeeds, everything is
87 // reported as expected:
95 fn success_in_grandchildren() {
96 let mut forest = ObligationForest::new();
97 forest.push_root("A");
99 let Outcome { completed: ok, errors: err, .. } =
100 forest.process_obligations::<(),_>(|obligation, _| {
102 "A" => Ok(Some(vec!["A.1", "A.2", "A.3"])),
106 assert!(ok.is_empty());
107 assert!(err.is_empty());
109 let Outcome { completed: ok, errors: err, .. } =
110 forest.process_obligations::<(),_>(|obligation, _| {
112 "A.1" => Ok(Some(vec![])),
113 "A.2" => Ok(Some(vec!["A.2.i", "A.2.ii"])),
114 "A.3" => Ok(Some(vec![])),
118 assert_eq!(ok, vec!["A.3", "A.1"]);
119 assert!(err.is_empty());
121 let Outcome { completed: ok, errors: err, .. } =
122 forest.process_obligations::<(),_>(|obligation, _| {
124 "A.2.i" => Ok(Some(vec!["A.2.i.a"])),
125 "A.2.ii" => Ok(Some(vec![])),
129 assert_eq!(ok, vec!["A.2.ii"]);
130 assert!(err.is_empty());
132 let Outcome { completed: ok, errors: err, .. } =
133 forest.process_obligations::<(),_>(|obligation, _| {
135 "A.2.i.a" => Ok(Some(vec![])),
139 assert_eq!(ok, vec!["A.2.i.a", "A.2.i", "A.2", "A"]);
140 assert!(err.is_empty());
142 let Outcome { completed: ok, errors: err, .. } =
143 forest.process_obligations::<(),_>(|_, _| unreachable!());
144 assert!(ok.is_empty());
145 assert!(err.is_empty());
149 fn to_errors_no_throw() {
150 // check that converting multiple children with common parent (A)
151 // only yields one of them (and does not panic, in particular).
152 let mut forest = ObligationForest::new();
153 forest.push_root("A");
154 let Outcome { completed: ok, errors: err, .. } =
155 forest.process_obligations::<(),_>(|obligation, _| {
157 "A" => Ok(Some(vec!["A.1", "A.2", "A.3"])),
161 assert_eq!(ok.len(), 0);
162 assert_eq!(err.len(), 0);
163 let errors = forest.to_errors(());
164 assert_eq!(errors.len(), 1);
169 // check that converting multiple children with common parent (A)
170 // only yields one of them (and does not panic, in particular).
171 let mut forest: ObligationForest<&'static str> = ObligationForest::new();
172 forest.push_root("A");
173 let Outcome { completed: ok, errors: err, .. } =
174 forest.process_obligations::<(),_>(|obligation, mut backtrace| {
175 assert!(backtrace.next().is_none());
177 "A" => Ok(Some(vec!["A.1"])),
181 assert!(ok.is_empty());
182 assert!(err.is_empty());
183 let Outcome { completed: ok, errors: err, .. } =
184 forest.process_obligations::<(),_>(|obligation, mut backtrace| {
185 assert!(backtrace.next().unwrap() == &"A");
186 assert!(backtrace.next().is_none());
188 "A.1" => Ok(Some(vec!["A.1.i"])),
192 assert!(ok.is_empty());
193 assert!(err.is_empty());
194 let Outcome { completed: ok, errors: err, .. } =
195 forest.process_obligations::<(),_>(|obligation, mut backtrace| {
196 assert!(backtrace.next().unwrap() == &"A.1");
197 assert!(backtrace.next().unwrap() == &"A");
198 assert!(backtrace.next().is_none());
204 assert_eq!(ok.len(), 0);
205 assert!(err.is_empty());