blob: 963cdc0a95502e2013e5db34d81abc7904196b62 (
plain)
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
use std::io;
use std::io::BufRead;
pub fn read_single_char_from_stdin() -> io::Result<char> {
let stdin = io::stdin();
let stdinlock = stdin.lock();
read_single_char(stdinlock)
}
pub fn read_single_char(mut source: impl BufRead) -> io::Result<char> {
let mut buf = String::new();
source.read_line(&mut buf)?;
buf.chars().next().ok_or_else(|| io::Error::new(io::ErrorKind::Other, "calendar has no path"))
}
#[cfg(not(test))]
pub use self::production::*;
#[cfg(test)]
pub use self::test::*;
#[cfg(test)]
pub use self::fixtures::*;
#[cfg(not(test))]
mod production {
use super::*;
pub fn read_lines_from_stdin() -> io::Result<Vec<String>> {
let stdin = io::stdin();
let lines = stdin.lock().lines();
lines.collect()
}
pub fn is_stdin_tty() -> bool {
atty::is(atty::Stream::Stdin)
}
pub fn is_stdout_tty() -> bool {
atty::is(atty::Stream::Stdout)
}
}
#[cfg(test)]
mod test {
use super::*;
pub fn read_lines_from_stdin() -> io::Result<Vec<String>> {
let lines = fixtures::test_stdin_clear();
Ok(lines)
}
pub fn is_stdin_tty() -> bool {
fixtures::test_stdin_is_tty()
}
pub fn is_stdout_tty() -> bool {
fixtures::test_stdout_is_tty()
}
}
#[cfg(test)]
pub mod fixtures {
use std::cell::RefCell;
thread_local! {
pub static STDOUT_BUF: RefCell<String> = RefCell::new(String::new());
pub static STDIN_BUF: RefCell<String> = RefCell::new(String::new());
pub static STDIN_TTY: RefCell<bool> = RefCell::new(true);
pub static STDOUT_TTY: RefCell<bool> = RefCell::new(true);
}
pub fn test_stdout_write(line: &str) {
STDOUT_BUF.with(|cell| cell.borrow_mut().push_str(&line));
}
pub fn test_stdout_clear() -> String {
STDOUT_BUF.with(|cell| {
let result = cell.borrow().clone();
*cell.borrow_mut() = String::new();
result
})
}
pub fn test_stdout_set_tty(istty: bool) {
STDOUT_TTY.with(|cell| { *cell.borrow_mut() = istty } );
}
pub fn test_stdout_is_tty() -> bool {
STDOUT_TTY.with(|cell| { *cell.borrow() } )
}
pub fn test_stdin_write(text: &str) {
test_stdin_set_tty(false);
STDIN_BUF.with(|cell| cell.borrow_mut().push_str(&text));
}
pub fn test_stdin_clear() -> Vec<String> {
STDIN_BUF.with(|cell| {
let result = cell.borrow().lines().map(|line| line.to_owned()).collect();
*cell.borrow_mut() = String::new();
result
})
}
pub fn test_stdin_set_tty(istty: bool) {
STDIN_TTY.with(|cell| { *cell.borrow_mut() = istty } );
}
pub fn test_stdin_is_tty() -> bool {
STDIN_TTY.with(|cell| { *cell.borrow() } )
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn read_single_char_test() {
let source = "ab".as_bytes();
let read_char = read_single_char(source).unwrap();
assert_eq!('a', read_char);
}
}
|