Skip to content

Commit a9d2f38

Browse files
committed
dbg_macro: output tests.
1 parent 6d08821 commit a9d2f38

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
// run-pass
2+
3+
// Tests ensuring that `dbg!(expr)` has the expected run-time behavior.
4+
// as well as some compile time properties we expect.
5+
6+
#![feature(dbg_macro)]
7+
8+
#[derive(Copy, Clone, Debug)]
9+
struct Unit;
10+
11+
#[derive(Copy, Clone, Debug, PartialEq)]
12+
struct Point<T> {
13+
x: T,
14+
y: T,
15+
}
16+
17+
#[derive(Debug, PartialEq)]
18+
struct NoCopy(usize);
19+
20+
fn test() {
21+
let a: Unit = dbg!(Unit);
22+
let _: Unit = dbg!(a);
23+
// We can move `a` because it's Copy.
24+
drop(a);
25+
26+
// `Point<T>` will be faithfully formatted according to `{:#?}`.
27+
let a = Point { x: 42, y: 24 };
28+
let b: Point<u8> = dbg!(Point { x: 42, y: 24 }); // test stringify!(..)
29+
let c: Point<u8> = dbg!(b);
30+
// Identity conversion:
31+
assert_eq!(a, b);
32+
assert_eq!(a, c);
33+
// We can move `b` because it's Copy.
34+
drop(b);
35+
36+
// Test that we can borrow and that successive applications is still identity.
37+
let a = NoCopy(1337);
38+
let b: &NoCopy = dbg!(dbg!(&a));
39+
assert_eq!(&a, b);
40+
41+
// Test involving lifetimes of temporaries:
42+
fn f<'a>(x: &'a u8) -> &'a u8 { x }
43+
let a: &u8 = dbg!(f(&42));
44+
assert_eq!(a, &42);
45+
46+
// Test side effects:
47+
let mut foo = 41;
48+
assert_eq!(7331, dbg!({
49+
foo += 1;
50+
eprintln!("before");
51+
7331
52+
}));
53+
assert_eq!(foo, 42);
54+
}
55+
56+
fn validate_stderr(stderr: Vec<String>) {
57+
assert_eq!(stderr, &[
58+
":21] Unit = Unit",
59+
60+
":22] a = Unit",
61+
62+
":28] Point{x: 42, y: 24,} = Point {",
63+
" x: 42,",
64+
" y: 24",
65+
"}",
66+
67+
":29] b = Point {",
68+
" x: 42,",
69+
" y: 24",
70+
"}",
71+
72+
":38] &a = NoCopy(",
73+
" 1337",
74+
")",
75+
76+
":38] dbg!(& a) = NoCopy(",
77+
" 1337",
78+
")",
79+
":43] f(&42) = 42",
80+
81+
"before",
82+
":48] { foo += 1; eprintln!(\"before\"); 7331 } = 7331",
83+
]);
84+
}
85+
86+
fn main() {
87+
// The following is a hack to deal with compiletest's inability
88+
// to check the output (to stdout) of run-pass tests.
89+
use std::env;
90+
use std::process::Command;
91+
92+
let mut args = env::args();
93+
let prog = args.next().unwrap();
94+
let child = args.next();
95+
if let Some("child") = child.as_ref().map(|s| &**s) {
96+
// Only run the test if we've been spawned as 'child'
97+
test()
98+
} else {
99+
// This essentially spawns as 'child' to run the tests
100+
// and then it collects output of stderr and checks the output
101+
// against what we expect.
102+
let out = Command::new(&prog).arg("child").output().unwrap();
103+
assert!(out.status.success());
104+
assert!(out.stdout.is_empty());
105+
106+
let stderr = String::from_utf8(out.stderr).unwrap();
107+
let stderr = stderr.lines().map(|mut s| {
108+
if s.starts_with("[") {
109+
// Strip `[` and file path:
110+
s = s.trim_start_matches("[");
111+
assert!(s.starts_with(file!()));
112+
s = s.trim_start_matches(file!());
113+
}
114+
s.to_owned()
115+
}).collect();
116+
117+
validate_stderr(stderr);
118+
}
119+
}

0 commit comments

Comments
 (0)