1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
use pretty_assertions::assert_eq;
use super::*;
/// Covers: a chatty child cannot grow the stderr capture without bound, and the
/// kept slice is the tail, marked as elided.
/// Owner: the stderr capture, which is the only bound on that memory.
#[test]
fn stderr_capture_keeps_a_bounded_tail() {
let mut tail = StderrTail::default();
for _ in 0..64 {
tail.push(&[b'a'; MAX_STDERR_BYTES]);
assert!(
tail.bytes.len() <= MAX_STDERR_BYTES,
"capture grew past its budget"
);
}
tail.push(b"last line\n");
let text = tail.finish();
assert!(text.starts_with(rho_sdk::ELLIPSIS), "elision is not marked");
assert!(
text.ends_with("last line"),
"kept the head instead of the tail"
);
}
/// Covers: cutting the head mid-character never opens the tail on a replacement
/// character.
/// Owner: the byte-level boundary walk, which `String::from_utf8_lossy` cannot
/// recover from once the cut has happened.
#[test]
fn stderr_capture_cuts_on_a_character_boundary() {
let mut tail = StderrTail::default();
// Three-byte characters make every cut land inside one unless it is walked
// forward: the budget is not a multiple of three.
tail.push("★".repeat(MAX_STDERR_BYTES).as_bytes());
let text = tail.finish();
assert_eq!(text.matches('\u{FFFD}').count(), 0);
}
/// Covers: stderr short enough to keep whole is reported without an elision
/// marker.
/// Owner: the same capture, whose no-elision path feeds one-shot failure text.
#[test]
fn stderr_capture_keeps_short_output_whole() {
let mut tail = StderrTail::default();
tail.push(b" boom\n");
assert_eq!(tail.finish(), "boom");
}