summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/actions/agenda.rs3
-rw-r--r--src/actions/cursor.rs8
-rw-r--r--src/actions/edit.rs4
-rw-r--r--src/actions/get.rs3
-rw-r--r--src/actions/seq.rs59
-rw-r--r--src/actions/show.rs1
-rw-r--r--src/cursorfile.rs2
-rw-r--r--src/input.rs11
-rw-r--r--src/macros.rs12
-rw-r--r--src/seqfile.rs18
-rw-r--r--src/testutils.rs32
-rw-r--r--src/utils/fileutil.rs34
-rw-r--r--src/utils/mod.rs2
-rw-r--r--src/utils/stdioutils.rs124
14 files changed, 198 insertions, 115 deletions
diff --git a/src/actions/agenda.rs b/src/actions/agenda.rs
index 41c0d9d..8750b1f 100644
--- a/src/actions/agenda.rs
+++ b/src/actions/agenda.rs
@@ -177,6 +177,7 @@ mod tests {
use super::*;
use testdata;
use testutils::*;
+ use utils::stdioutils;
use config::Config;
use chrono::{Local, TimeZone};
@@ -272,7 +273,7 @@ mod tests {
show_events(&Config::read_config(), &[]).unwrap();
- let stdout = test_stdout_clear();
+ let stdout = stdioutils::test_stdout_clear();
let expected = indoc!("
2018-12-13, Thursday
0 22:30- shows up on two days
diff --git a/src/actions/cursor.rs b/src/actions/cursor.rs
index 8b052a2..864fc52 100644
--- a/src/actions/cursor.rs
+++ b/src/actions/cursor.rs
@@ -1,17 +1,17 @@
extern crate atty;
use cursorfile;
-use utils::fileutil;
+use utils::stdioutils;
use KhResult;
pub fn do_cursor(_args: &[&str]) -> KhResult<()> {
- if atty::isnt(atty::Stream::Stdin) {
+ if !stdioutils::is_stdin_tty() {
write_stdin_to_cursorfile();
} else {
//println!("stdin is tty")
}
- if atty::isnt(atty::Stream::Stdout) || atty::is(atty::Stream::Stdin) {
+ if !stdioutils::is_stdout_tty() || stdioutils::is_stdin_tty() {
write_cursorfile_to_stdout();
}
@@ -19,7 +19,7 @@ pub fn do_cursor(_args: &[&str]) -> KhResult<()> {
}
fn write_stdin_to_cursorfile() {
- let lines = match fileutil::read_lines_from_stdin() {
+ let lines = match stdioutils::read_lines_from_stdin() {
Ok(input) => input,
Err(error) => {
error!("Error reading from stdin: {}", error);
diff --git a/src/actions/edit.rs b/src/actions/edit.rs
index d0b1251..1a9843c 100644
--- a/src/actions/edit.rs
+++ b/src/actions/edit.rs
@@ -7,7 +7,7 @@ use tempfile::NamedTempFile;
use backup::backup;
use input;
use khline::KhLine;
-use utils::fileutil;
+use utils::{fileutil,stdioutils};
use KhResult;
pub fn do_edit(_args: &[&str]) -> KhResult<()> {
@@ -54,7 +54,7 @@ fn ask_continue_editing(error: &[String]) -> bool {
println!("Calendar contains errors:\n{}", error.join("\n"));
println!("Continue editing? y/n:");
- match fileutil::read_single_char_from_stdin().unwrap() {
+ match stdioutils::read_single_char_from_stdin().unwrap() {
'y' => true,
_ => false
}
diff --git a/src/actions/get.rs b/src/actions/get.rs
index 7c09470..f059ea0 100644
--- a/src/actions/get.rs
+++ b/src/actions/get.rs
@@ -24,6 +24,7 @@ mod tests {
use super::*;
use testutils;
+ use utils::stdioutils;
#[test]
fn test_get_calendars() {
@@ -31,6 +32,6 @@ mod tests {
action_get(&["calendars"]).unwrap();
- assert_eq!("first\nsecond\nsecond/second_sub\n", testutils::test_stdout_clear());
+ assert_eq!("first\nsecond\nsecond/second_sub\n", stdioutils::test_stdout_clear());
}
}
diff --git a/src/actions/seq.rs b/src/actions/seq.rs
index 8426bfd..bd71e34 100644
--- a/src/actions/seq.rs
+++ b/src/actions/seq.rs
@@ -1,41 +1,66 @@
-extern crate atty;
-
use seqfile;
-use utils::fileutil;
+use utils::stdioutils;
use KhResult;
pub fn do_seq(_args: &[&str]) -> KhResult<()> {
- if atty::isnt(atty::Stream::Stdin) {
- write_stdin_to_seqfile();
+ if !stdioutils::is_stdin_tty() {
+ write_stdin_to_seqfile()?;
} else {
//println!("stdin is tty")
}
- if atty::isnt(atty::Stream::Stdout) || atty::is(atty::Stream::Stdin) {
+ if !stdioutils::is_stdout_tty() || stdioutils::is_stdin_tty() {
write_seqfile_to_stdout();
}
Ok(())
}
-fn write_stdin_to_seqfile() {
- let mut lines;
- match fileutil::read_lines_from_stdin() {
- Ok(input) => lines = input.join("\n"),
- Err(error) => {
- error!("Error reading from stdin: {}", error);
- return
- }
- }
+fn write_stdin_to_seqfile() -> KhResult<()> {
+ let mut lines = stdioutils::read_lines_from_stdin()?.join("\n");
lines.push_str("\n");
- seqfile::write_to_seqfile(&lines);
+ seqfile::write_to_seqfile(&lines)?;
+
+ Ok(())
}
fn write_seqfile_to_stdout() {
if let Ok(sequence) = seqfile::read_seqfile() {
for line in sequence {
- println!("{}", line);
+ khprintln!("{}", line);
}
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ use assert_fs::prelude::*;
+ use predicates::prelude::*;
+ use testutils;
+ use utils::stdioutils;
+
+ #[test]
+ fn test_write_stdin_to_seqfile() {
+ let testdir = testutils::prepare_testdir_empty();
+ stdioutils::test_stdin_write("hi\nthere");
+
+ write_stdin_to_seqfile().unwrap();
+
+ testdir.child(".khaleesi/seq").assert("hi\nthere\n");
+ }
+
+ #[test]
+ fn test_read_seqfile_to_stdout() {
+ let testdir = testutils::prepare_testdir("testdir_with_seq");
+
+ write_seqfile_to_stdout();
+ let out = stdioutils::test_stdout_clear();
+
+ let predicate = predicate::str::similar(out);
+ testdir.child(".khaleesi/seq").assert(predicate);
+ }
+}
+
diff --git a/src/actions/show.rs b/src/actions/show.rs
index f5ead26..00f4626 100644
--- a/src/actions/show.rs
+++ b/src/actions/show.rs
@@ -19,6 +19,7 @@ mod tests {
use super::*;
use testutils::*;
+ use utils::stdioutils::*;
#[test]
fn test_() {
diff --git a/src/cursorfile.rs b/src/cursorfile.rs
index a06b80e..cd95286 100644
--- a/src/cursorfile.rs
+++ b/src/cursorfile.rs
@@ -1,5 +1,3 @@
-extern crate atty;
-
use std::fs::rename;
use std::io;
diff --git a/src/input.rs b/src/input.rs
index 7dace16..860db05 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -1,15 +1,14 @@
-use atty;
use std::io;
use seqfile;
use cursorfile;
use khline::KhLine;
-use utils::fileutil;
+use utils::stdioutils;
pub fn default_input_khlines() -> Result<Box<dyn Iterator<Item = KhLine>>, String> {
- if atty::isnt(atty::Stream::Stdin) {
+ if !stdioutils::is_stdin_tty() {
debug!("Taking input from Stdin");
- let lines = fileutil::read_lines_from_stdin().unwrap().into_iter();
+ let lines = stdioutils::read_lines_from_stdin().unwrap().into_iter();
let khlines = lines.map(|line| line.parse::<KhLine>()).flatten();
Ok(Box::new(khlines))
} else {
@@ -20,10 +19,10 @@ pub fn default_input_khlines() -> Result<Box<dyn Iterator<Item = KhLine>>, Strin
}
pub fn default_input_khline() -> io::Result<KhLine> {
- if atty::isnt(atty::Stream::Stdin) {
+ if !stdioutils::is_stdin_tty() {
debug!("Taking input from Stdin");
- let lines = fileutil::read_lines_from_stdin()?;
+ let lines = stdioutils::read_lines_from_stdin()?;
if lines.len() > 1 {
Err(io::Error::new(io::ErrorKind::Other, "too many lines in cursorfile"))
} else {
diff --git a/src/macros.rs b/src/macros.rs
index a393399..2dc64da 100644
--- a/src/macros.rs
+++ b/src/macros.rs
@@ -4,7 +4,7 @@ macro_rules! khprint {
($($arg:tt)*) => ({
let line = format!($($arg)*);
#[cfg(test)] {
- use testutils;
+ use utils::stdioutils;
testutils::test_stdout_write(&line);
}
print!("{}", line);
@@ -15,17 +15,17 @@ macro_rules! khprint {
macro_rules! khprintln {
() => ({
#[cfg(test)] {
- use testutils;
- testutils::test_stdout_write("\n");
+ use utils::stdioutils;
+ stdioutils::test_stdout_write("\n");
}
println!();
});
($($arg:tt)*) => ({
let line = format!($($arg)*);
#[cfg(test)] {
- use testutils;
- testutils::test_stdout_write(&line);
- testutils::test_stdout_write("\n");
+ use utils::stdioutils;
+ stdioutils::test_stdout_write(&line);
+ stdioutils::test_stdout_write("\n");
}
println!("{}", line);
})
diff --git a/src/seqfile.rs b/src/seqfile.rs
index adb1c93..66caed3 100644
--- a/src/seqfile.rs
+++ b/src/seqfile.rs
@@ -1,23 +1,18 @@
-extern crate atty;
-
use std::fs::rename;
use std::io;
use defaults::*;
use utils::fileutil;
-pub fn write_to_seqfile(lines: &str) {
+pub fn write_to_seqfile(lines: &str) -> io::Result<()> {
let tmpfilename = get_datafile("tmpseq");
- if let Err(error) = fileutil::write_file(&tmpfilename, lines) {
- error!("Could not write seqfile: {}", error);
- return
- }
+ fileutil::write_file(&tmpfilename, lines)?;
let seqfile = get_seqfile();
- if let Err(error) = rename(tmpfilename, seqfile) {
- error!("{}", error)
- }
+ rename(tmpfilename, seqfile)?;
+
+ Ok(())
}
pub fn read_seqfile() -> io::Result<impl Iterator<Item = String>> {
@@ -50,7 +45,8 @@ mod tests {
let testdir = prepare_testdir("testdir");
let teststr = "Teststr äöüß\n";
- write_to_seqfile(teststr);
+ write_to_seqfile(teststr).unwrap();
+
testdir.child(".khaleesi/seq").assert(teststr);
}
}
diff --git a/src/testutils.rs b/src/testutils.rs
index 7593f98..42fa765 100644
--- a/src/testutils.rs
+++ b/src/testutils.rs
@@ -1,12 +1,7 @@
use assert_fs::prelude::*;
use assert_fs::TempDir;
use std::path::PathBuf;
-
-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());
-}
+use std::fs;
use defaults;
@@ -16,6 +11,7 @@ pub fn path_to(artifact: &str) -> PathBuf {
pub fn prepare_testdir_empty() -> TempDir {
let testdir = TempDir::new().unwrap();
+ fs::create_dir(testdir.child(".khaleesi").path()).unwrap();
defaults::set_khaleesi_dir(testdir.path());
testdir
}
@@ -25,27 +21,3 @@ pub fn prepare_testdir(template: &str) -> TempDir {
testdir.child(".khaleesi/").copy_from(path_to(template), &["*"]).unwrap();
testdir
}
-
-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_stdin_write(text: &str) {
- 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
- })
-}
diff --git a/src/utils/fileutil.rs b/src/utils/fileutil.rs
index fca810e..ab90a55 100644
--- a/src/utils/fileutil.rs
+++ b/src/utils/fileutil.rs
@@ -53,33 +53,6 @@ pub fn read_lines_from_file(filepath: &Path) -> io::Result<impl Iterator<Item =
lines.map(|result| result.into_iter())
}
-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"))
-}
-
-pub fn read_single_char_from_stdin() -> io::Result<char> {
- let stdin = std::io::stdin();
- let stdinlock = stdin.lock();
- read_single_char(stdinlock)
-}
-
-#[cfg(not(test))]
-pub fn read_lines_from_stdin() -> io::Result<Vec<String>> {
- let stdin = io::stdin();
- let lines = stdin.lock().lines();
- lines.collect()
-}
-
-#[cfg(test)]
-pub fn read_lines_from_stdin() -> io::Result<Vec<String>> {
- use testutils;
- let lines = testutils::test_stdin_clear();
- Ok(lines)
-}
-
pub fn read_file_to_string(path: &Path) -> io::Result<String> {
let mut file = fs::File::open(&path)?;
let mut contents = String::new();
@@ -117,11 +90,4 @@ mod tests {
write_file(file.path(), "z\n").unwrap();
file.assert("z\n");
}
-
- #[test]
- fn read_single_char_test() {
- let source = "ab".as_bytes();
- let read_char = read_single_char(source).unwrap();
- assert_eq!('a', read_char);
- }
}
diff --git a/src/utils/mod.rs b/src/utils/mod.rs
index 8244c95..b4b17e2 100644
--- a/src/utils/mod.rs
+++ b/src/utils/mod.rs
@@ -2,4 +2,4 @@ pub mod dateutil;
pub mod lock;
pub mod fileutil;
pub mod misc;
-
+pub mod stdioutils;
diff --git a/src/utils/stdioutils.rs b/src/utils/stdioutils.rs
new file mode 100644
index 0000000..963cdc0
--- /dev/null
+++ b/src/utils/stdioutils.rs
@@ -0,0 +1,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);
+ }
+}