]>
Commit | Line | Data |
---|---|---|
a7813a04 XL |
1 | // Copyright 2012-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. | |
4 | // | |
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. | |
10 | ||
11 | //! Code for checking whether the output of the compiler matches what is | |
12 | //! expected. | |
13 | ||
14 | pub fn diff_lines(actual: &str, expected: &str) -> Vec<String> { | |
15 | // mega simplistic diff algorithm that just prints the things added/removed | |
5bcae85e SL |
16 | zip_all(actual.lines(), expected.lines()) |
17 | .enumerate() | |
18 | .filter_map(|(i, (a, e))| { | |
19 | match (a, e) { | |
20 | (Some(a), Some(e)) => { | |
21 | if lines_match(e, a) { | |
22 | None | |
23 | } else { | |
24 | Some(format!("{:3} - |{}|\n + |{}|\n", i, e, a)) | |
25 | } | |
a7813a04 | 26 | } |
5bcae85e SL |
27 | (Some(a), None) => Some(format!("{:3} -\n + |{}|\n", i, a)), |
28 | (None, Some(e)) => Some(format!("{:3} - |{}|\n +\n", i, e)), | |
29 | (None, None) => panic!("Cannot get here"), | |
30 | } | |
31 | }) | |
32 | .collect() | |
a7813a04 XL |
33 | } |
34 | ||
35 | fn lines_match(expected: &str, mut actual: &str) -> bool { | |
36 | for (i, part) in expected.split("[..]").enumerate() { | |
37 | match actual.find(part) { | |
38 | Some(j) => { | |
39 | if i == 0 && j != 0 { | |
5bcae85e | 40 | return false; |
a7813a04 XL |
41 | } |
42 | actual = &actual[j + part.len()..]; | |
43 | } | |
5bcae85e | 44 | None => return false, |
a7813a04 XL |
45 | } |
46 | } | |
47 | actual.is_empty() || expected.ends_with("[..]") | |
48 | } | |
49 | ||
50 | struct ZipAll<I1: Iterator, I2: Iterator> { | |
51 | first: I1, | |
52 | second: I2, | |
53 | } | |
54 | ||
5bcae85e | 55 | impl<T, I1: Iterator<Item = T>, I2: Iterator<Item = T>> Iterator for ZipAll<I1, I2> { |
a7813a04 XL |
56 | type Item = (Option<T>, Option<T>); |
57 | fn next(&mut self) -> Option<(Option<T>, Option<T>)> { | |
58 | let first = self.first.next(); | |
59 | let second = self.second.next(); | |
60 | ||
61 | match (first, second) { | |
62 | (None, None) => None, | |
5bcae85e | 63 | (a, b) => Some((a, b)), |
a7813a04 XL |
64 | } |
65 | } | |
66 | } | |
67 | ||
5bcae85e | 68 | fn zip_all<T, I1: Iterator<Item = T>, I2: Iterator<Item = T>>(a: I1, b: I2) -> ZipAll<I1, I2> { |
a7813a04 XL |
69 | ZipAll { |
70 | first: a, | |
71 | second: b, | |
72 | } | |
73 | } |