<commit_before>use std::path::{Path, PathBuf};

use ignore::Match;
use ignore::gitignore::{Gitignore, GitignoreBuilder};
use walkdir::{WalkDir, DirEntry, WalkDirIterator};

use error::Result;

pub struct FilesBuilder {
    root_dir: PathBuf,
    ignore: GitignoreBuilder,
}

impl FilesBuilder {
    pub fn new(root_dir: &Path) -> Result<FilesBuilder> {
        let mut ignore = GitignoreBuilder::new(root_dir);
        ignore.add_line(None, "**/.*")?;
        ignore.add_line(None, "**/.*/**")?;
        ignore.add_line(None, "**/_*")?;
        ignore.add_line(None, "**/_*/**")?;
        let builder = FilesBuilder {
            root_dir: root_dir.to_path_buf(),
            ignore: ignore,
        };

        Ok(builder)
    }

    pub fn add_ignore(&mut self, line: &str) -> Result<&mut FilesBuilder> {
        debug!("{:?}: adding '{}' ignore pattern", self.root_dir, line);
        self.ignore.add_line(None, line)?;
        Ok(self)
    }

    pub fn build(&self) -> Result<Files> {
        let files = Files::new(self.root_dir.as_path(), self.ignore.build()?);
        Ok(files)
    }
}

pub struct FilesIterator<'a> {
    inner: Box<Iterator<Item = PathBuf> + 'a>,
}

impl<'a> FilesIterator<'a> {
    fn new(files: &'a Files) -> FilesIterator<'a> {
        let walker = WalkDir::new(files.root_dir.as_path())
            .min_depth(1)
            .follow_links(false)
            .into_iter()
            .filter_entry(move |e| files.includes_entry(e))
            .filter_map(|e| e.ok())
            .filter(|e| e.file_type().is_file())
            .filter_map(move |e| {
                            e.path()
                                .strip_prefix(files.root_dir.as_path())
                                .ok()
                                .map(|p| p.to_path_buf())
                        });
        FilesIterator { inner: Box::new(walker) }
    }
}

impl<'a> Iterator for FilesIterator<'a> {
    type Item = PathBuf;

    fn next(&mut self) -> Option<PathBuf> {
        self.inner.next()
    }
}

pub struct Files {
    root_dir: PathBuf,
    ignore: Gitignore,
}

impl Files {
    fn new(root_dir: &Path, ignore: Gitignore) -> Files {
        Files {
            root_dir: root_dir.to_path_buf(),
            ignore: ignore,
        }
    }

    #[cfg(test)]
    pub fn includes_file(&self, file: &Path) -> bool {
        let is_dir = false;
        self.includes_path(file, is_dir)
    }

    #[cfg(test)]
    pub fn includes_dir(&self, dir: &Path) -> bool {
        let is_dir = true;
        self.includes_path(dir, is_dir)
    }

    pub fn files(&self) -> FilesIterator {
        FilesIterator::new(self)
    }

    fn includes_entry(&self, entry: &DirEntry) -> bool {
        self.includes_path(entry.path(), entry.file_type().is_dir())
    }

    fn includes_path(&self, path: &Path, is_dir: bool) -> bool {
        match self.ignore.matched(path, is_dir) {
            Match::None => true,
            Match::Ignore(glob) => {
                debug!("{:?}: ignored {:?}", path, glob.original());
                false
            }
            Match::Whitelist(glob) => {
                debug!("{:?}: allowed {:?}", path, glob.original());
                true
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn files_includes_root_dir() {
        let files = FilesBuilder::new(Path::new("/user/cobalt/site"))
            .unwrap()
            .build()
            .unwrap();
        assert!(files.includes_dir(Path::new("/usr/cobalt/site")));
    }

    #[test]
    fn files_includes_child_dir() {
        let files = FilesBuilder::new(Path::new("/user/cobalt/site"))
            .unwrap()
            .build()
            .unwrap();
        assert!(files.includes_dir(Path::new("/usr/cobalt/site/child")));
    }

    #[test]
    fn files_excludes_hidden_dir() {
        let files = FilesBuilder::new(Path::new("/user/cobalt/site"))
            .unwrap()
            .build()
            .unwrap();
        assert!(!files.includes_dir(Path::new("/usr/cobalt/site/_child")));

        let files = FilesBuilder::new(Path::new("/user/cobalt/site"))
            .unwrap()
            .build()
            .unwrap();
        assert!(!files.includes_dir(Path::new("/usr/cobalt/site/child/_child")));

        let files = FilesBuilder::new(Path::new("/user/cobalt/site"))
            .unwrap()
            .build()
            .unwrap();
        assert!(!files.includes_dir(Path::new("/usr/cobalt/site/_child/child")));
    }

    #[test]
    fn files_excludes_dot_dir() {
        let files = FilesBuilder::new(Path::new("/user/cobalt/site"))
            .unwrap()
            .build()
            .unwrap();
        assert!(!files.includes_dir(Path::new("/usr/cobalt/site/.child")));

        let files = FilesBuilder::new(Path::new("/user/cobalt/site"))
            .unwrap()
            .build()
            .unwrap();
        assert!(!files.includes_dir(Path::new("/usr/cobalt/site/.child/child")));
    }

    #[test]
    fn files_includes_file() {
        let files = FilesBuilder::new(Path::new("/user/cobalt/site"))
            .unwrap()
            .build()
            .unwrap();
        assert!(files.includes_file(Path::new("/usr/cobalt/site/child.txt")));
    }

    #[test]
    fn files_includes_child_dir_file() {
        let files = FilesBuilder::new(Path::new("/user/cobalt/site"))
            .unwrap()
            .build()
            .unwrap();
        assert!(files.includes_file(Path::new("/usr/cobalt/site/child/child.txt")));
    }

    #[test]
    fn files_excludes_hidden_file() {
        let files = FilesBuilder::new(Path::new("/user/cobalt/site"))
            .unwrap()
            .build()
            .unwrap();
        assert!(!files.includes_file(Path::new("/usr/cobalt/site/_child.txt")));

        let files = FilesBuilder::new(Path::new("/user/cobalt/site"))
            .unwrap()
            .build()
            .unwrap();
        assert!(!files.includes_file(Path::new("/usr/cobalt/site/child/_child.txt")));
    }

    #[test]
    fn files_excludes_hidden_dir_file() {
        let files = FilesBuilder::new(Path::new("/user/cobalt/site"))
            .unwrap()
            .build()
            .unwrap();
        assert!(!files.includes_file(Path::new("/usr/cobalt/site/_child/child.txt")));

        let files = FilesBuilder::new(Path::new("/user/cobalt/site"))
            .unwrap()
            .build()
            .unwrap();
        assert!(!files.includes_file(Path::new("/usr/cobalt/site/child/_child/child.txt")));
    }

    #[test]
    fn files_excludes_dot_file() {
        let files = FilesBuilder::new(Path::new("/user/cobalt/site"))
            .unwrap()
            .build()
            .unwrap();
        assert!(!files.includes_file(Path::new("/usr/cobalt/site/.child.txt")));

        let files = FilesBuilder::new(Path::new("/user/cobalt/site"))
            .unwrap()
            .build()
            .unwrap();
        assert!(!files.includes_file(Path::new("/usr/cobalt/site/child/.child.txt")));
    }

    #[test]
    fn files_excludes_dot_dir_file() {
        let files = FilesBuilder::new(Path::new("/user/cobalt/site"))
            .unwrap()
            .build()
            .unwrap();
        assert!(!files.includes_file(Path::new("/usr/cobalt/site/.child/child.txt")));

        let files = FilesBuilder::new(Path::new("/user/cobalt/site"))
            .unwrap()
            .build()
            .unwrap();
        assert!(!files.includes_file(Path::new("/usr/cobalt/site/child/.child/child.txt")));
    }

    #[test]
    fn files_excludes_ignored_file() {
        let files = FilesBuilder::new(Path::new("/user/cobalt/site"))
            .unwrap()
            .add_ignore("README")
            .unwrap()
            .add_ignore("**/*.scss")
            .unwrap()
            .build()
            .unwrap();

        assert!(!files.includes_file(Path::new("/usr/cobalt/site/README")));
        assert!(!files.includes_file(Path::new("/usr/cobalt/site/child/README")));

        assert!(!files.includes_file(Path::new("/usr/cobalt/site/blog.scss")));
        assert!(!files.includes_file(Path::new("/usr/cobalt/site/child/blog.scss")));
    }

    #[test]
    fn files_includes_overriden_file() {
        let files = FilesBuilder::new(Path::new("/user/cobalt/site"))
            .unwrap()
            .add_ignore("!.htaccess")
            .unwrap()
            .build()
            .unwrap();

        assert!(files.includes_file(Path::new("/usr/cobalt/site/.htaccess")));
        assert!(files.includes_file(Path::new("/usr/cobalt/site/child/.htaccess")));
    }

    #[test]
    fn files_includes_overriden_dir() {
        let files = FilesBuilder::new(Path::new("/user/cobalt/site"))
            .unwrap()
            .add_ignore("!_posts")
            .unwrap()
            .add_ignore("!_posts/**")
            .unwrap()
            .add_ignore("_posts/**/_*")
            .unwrap()
            .add_ignore("_posts/**/_*/**")
            .unwrap()
            .build()
            .unwrap();

        assert!(files.includes_dir(Path::new("/usr/cobalt/site/_posts")));
        assert!(files.includes_dir(Path::new("/usr/cobalt/site/_posts/child")));

        // TODO These two cases should instead fail
        assert!(files.includes_dir(Path::new("/usr/cobalt/site/child/_posts")));
        assert!(files.includes_dir(Path::new("/usr/cobalt/site/child/_posts/child")));

        assert!(!files.includes_dir(Path::new("/usr/cobalt/site/_posts/child/_child")));
        assert!(!files.includes_dir(Path::new("/usr/cobalt/site/_posts/child/_child/child")));

        let files = FilesBuilder::new(Path::new("./"))
            .unwrap()
            .add_ignore("!_posts")
            .unwrap()
            .add_ignore("!_posts/**")
            .unwrap()
            .add_ignore("_posts/**/_*")
            .unwrap()
            .add_ignore("_posts/**/_*/**")
            .unwrap()
            .build()
            .unwrap();

        assert!(files.includes_dir(Path::new("./_posts")));
        assert!(files.includes_dir(Path::new("./_posts/child")));
    }

    #[test]
    fn files_includes_overriden_dir_file() {
        let files = FilesBuilder::new(Path::new("/user/cobalt/site"))
            .unwrap()
            .add_ignore("!_posts")
            .unwrap()
            .add_ignore("!_posts/**")
            .unwrap()
            .add_ignore("_posts/**/_*")
            .unwrap()
            .add_ignore("_posts/**/_*/**")
            .unwrap()
            .build()
            .unwrap();

        assert!(files.includes_file(Path::new("/usr/cobalt/site/_posts/child.txt")));
        assert!(files.includes_file(Path::new("/usr/cobalt/site/_posts/child/child.txt")));

        // TODO These two cases should instead fail
        assert!(files.includes_file(Path::new("/usr/cobalt/site/child/_posts/child.txt")));
        assert!(files.includes_file(Path::new("/usr/cobalt/site/child/_posts/child/child.txt")));

        assert!(!files.includes_file(Path::new("/usr/cobalt/site/_posts/child/_child.txt")));
        assert!(!files.includes_file(Path::new("/usr/cobalt/site/_posts/child/_child/child.txt")));
    }

    #[test]
    fn files_iter_matches_include() {
        let root_dir = Path::new("tests/fixtures/hidden_files");
        let files = FilesBuilder::new(root_dir).unwrap().build().unwrap();
        let mut actual: Vec<_> = files.files().collect();
        actual.sort();

        let expected = vec![Path::new("child/child.txt").to_path_buf(),
                            Path::new("child.txt").to_path_buf()];

        assert_eq!(expected, actual);
    }
}
<commit_msg>feat(tests): Make it easier to add new tests<commit_after>use std::path::{Path, PathBuf};

use ignore::Match;
use ignore::gitignore::{Gitignore, GitignoreBuilder};
use walkdir::{WalkDir, DirEntry, WalkDirIterator};

use error::Result;

pub struct FilesBuilder {
    root_dir: PathBuf,
    ignore: GitignoreBuilder,
}

impl FilesBuilder {
    pub fn new(root_dir: &Path) -> Result<FilesBuilder> {
        let mut ignore = GitignoreBuilder::new(root_dir);
        ignore.add_line(None, "**/.*")?;
        ignore.add_line(None, "**/.*/**")?;
        ignore.add_line(None, "**/_*")?;
        ignore.add_line(None, "**/_*/**")?;
        let builder = FilesBuilder {
            root_dir: root_dir.to_path_buf(),
            ignore: ignore,
        };

        Ok(builder)
    }

    pub fn add_ignore(&mut self, line: &str) -> Result<&mut FilesBuilder> {
        debug!("{:?}: adding '{}' ignore pattern", self.root_dir, line);
        self.ignore.add_line(None, line)?;
        Ok(self)
    }

    pub fn build(&self) -> Result<Files> {
        let files = Files::new(self.root_dir.as_path(), self.ignore.build()?);
        Ok(files)
    }
}

pub struct FilesIterator<'a> {
    inner: Box<Iterator<Item = PathBuf> + 'a>,
}

impl<'a> FilesIterator<'a> {
    fn new(files: &'a Files) -> FilesIterator<'a> {
        let walker = WalkDir::new(files.root_dir.as_path())
            .min_depth(1)
            .follow_links(false)
            .into_iter()
            .filter_entry(move |e| files.includes_entry(e))
            .filter_map(|e| e.ok())
            .filter(|e| e.file_type().is_file())
            .filter_map(move |e| {
                            e.path()
                                .strip_prefix(files.root_dir.as_path())
                                .ok()
                                .map(|p| p.to_path_buf())
                        });
        FilesIterator { inner: Box::new(walker) }
    }
}

impl<'a> Iterator for FilesIterator<'a> {
    type Item = PathBuf;

    fn next(&mut self) -> Option<PathBuf> {
        self.inner.next()
    }
}

pub struct Files {
    root_dir: PathBuf,
    ignore: Gitignore,
}

impl Files {
    fn new(root_dir: &Path, ignore: Gitignore) -> Files {
        Files {
            root_dir: root_dir.to_path_buf(),
            ignore: ignore,
        }
    }

    #[cfg(test)]
    pub fn includes_file(&self, file: &Path) -> bool {
        let is_dir = false;
        self.includes_path(file, is_dir)
    }

    #[cfg(test)]
    pub fn includes_dir(&self, dir: &Path) -> bool {
        let is_dir = true;
        self.includes_path(dir, is_dir)
    }

    pub fn files(&self) -> FilesIterator {
        FilesIterator::new(self)
    }

    fn includes_entry(&self, entry: &DirEntry) -> bool {
        self.includes_path(entry.path(), entry.file_type().is_dir())
    }

    fn includes_path(&self, path: &Path, is_dir: bool) -> bool {
        match self.ignore.matched(path, is_dir) {
            Match::None => true,
            Match::Ignore(glob) => {
                debug!("{:?}: ignored {:?}", path, glob.original());
                false
            }
            Match::Whitelist(glob) => {
                debug!("{:?}: allowed {:?}", path, glob.original());
                true
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    macro_rules! assert_includes_dir {
        ($root: expr, $ignores: expr, $test: expr, $included: expr) => {
            let mut files = FilesBuilder::new(Path::new($root)).unwrap();
            let ignores: &[&str] = $ignores;
            for ignore in ignores {
                files.add_ignore(ignore).unwrap();
            }
            let files = files.build().unwrap();
            assert_eq!(files.includes_dir(Path::new($test)), $included);
        }
    }
    macro_rules! assert_includes_file {
        ($root: expr, $ignores: expr, $test: expr, $included: expr) => {
            let mut files = FilesBuilder::new(Path::new($root)).unwrap();
            let ignores: &[&str] = $ignores;
            for ignore in ignores {
                files.add_ignore(ignore).unwrap();
            }
            let files = files.build().unwrap();
            assert_eq!(files.includes_file(Path::new($test)), $included);
        }
    }

    #[test]
    fn files_includes_root_dir() {
        assert_includes_dir!("/usr/cobalt/site", &[], "/usr/cobalt/site", true);
    }

    #[test]
    fn files_includes_child_dir() {
        assert_includes_dir!("/usr/cobalt/site", &[], "/usr/cobalt/site/child", true);
    }

    #[test]
    fn files_excludes_hidden_dir() {
        assert_includes_dir!("/usr/cobalt/site", &[], "/usr/cobalt/site/_child", false);
        assert_includes_dir!("/usr/cobalt/site",
                             &[],
                             "/usr/cobalt/site/child/_child",
                             false);
        assert_includes_dir!("/usr/cobalt/site",
                             &[],
                             "/usr/cobalt/site/_child/child",
                             false);
    }

    #[test]
    fn files_excludes_dot_dir() {
        assert_includes_dir!("/usr/cobalt/site", &[], "/usr/cobalt/site/.child", false);
        assert_includes_dir!("/usr/cobalt/site",
                             &[],
                             "/usr/cobalt/site/child/.child",
                             false);
        assert_includes_dir!("/usr/cobalt/site",
                             &[],
                             "/usr/cobalt/site/.child/child",
                             false);
    }

    #[test]
    fn files_includes_file() {
        assert_includes_file!("/usr/cobalt/site", &[], "/usr/cobalt/site/child.txt", true);
    }

    #[test]
    fn files_includes_child_dir_file() {
        assert_includes_file!("/usr/cobalt/site",
                              &[],
                              "/usr/cobalt/site/child/child.txt",
                              true);
    }

    #[test]
    fn files_excludes_hidden_file() {
        assert_includes_file!("/usr/cobalt/site",
                              &[],
                              "/usr/cobalt/site/_child.txt",
                              false);
        assert_includes_file!("/usr/cobalt/site",
                              &[],
                              "/usr/cobalt/site/child/_child.txt",
                              false);
    }

    #[test]
    fn files_excludes_hidden_dir_file() {
        assert_includes_file!("/usr/cobalt/site",
                              &[],
                              "/usr/cobalt/site/_child/child.txt",
                              false);
        assert_includes_file!("/usr/cobalt/site",
                              &[],
                              "/usr/cobalt/site/child/_child/child.txt",
                              false);
    }

    #[test]
    fn files_excludes_dot_file() {
        assert_includes_file!("/usr/cobalt/site",
                              &[],
                              "/usr/cobalt/site/.child.txt",
                              false);
        assert_includes_file!("/usr/cobalt/site",
                              &[],
                              "/usr/cobalt/site/child/.child.txt",
                              false);
    }

    #[test]
    fn files_excludes_dot_dir_file() {
        assert_includes_file!("/usr/cobalt/site",
                              &[],
                              "/usr/cobalt/site/.child/child.txt",
                              false);
        assert_includes_file!("/usr/cobalt/site",
                              &[],
                              "/usr/cobalt/site/child/.child/child.txt",
                              false);
    }

    #[test]
    fn files_excludes_ignored_file() {
        let ignores = &["README", "**/*.scss"];

        assert_includes_file!("/usr/cobalt/site",
                              ignores,
                              "/usr/cobalt/site/README",
                              false);
        assert_includes_file!("/usr/cobalt/site",
                              ignores,
                              "/usr/cobalt/site/child/README",
                              false);
        assert_includes_file!("/usr/cobalt/site",
                              ignores,
                              "/usr/cobalt/site/blog.scss",
                              false);
        assert_includes_file!("/usr/cobalt/site",
                              ignores,
                              "/usr/cobalt/site/child/blog.scss",
                              false);
    }

    #[test]
    fn files_includes_overriden_file() {
        let ignores = &["!.htaccess"];

        assert_includes_file!("/usr/cobalt/site",
                              ignores,
                              "/usr/cobalt/site/.htaccess",
                              true);
        assert_includes_file!("/usr/cobalt/site",
                              ignores,
                              "/usr/cobalt/site/child/.htaccess",
                              true);
    }

    #[test]
    fn files_includes_overriden_dir() {
        let ignores = &["!_posts", "!_posts/**", "_posts/**/_*", "_posts/**/_*/**"];

        assert_includes_dir!("/usr/cobalt/site", ignores, "/usr/cobalt/site/_posts", true);
        assert_includes_dir!("/usr/cobalt/site",
                             ignores,
                             "/usr/cobalt/site/_posts/child",
                             true);

        // TODO These two cases should instead fail
        assert_includes_dir!("/usr/cobalt/site",
                             ignores,
                             "/usr/cobalt/site/child/_posts",
                             true);
        assert_includes_dir!("/usr/cobalt/site",
                             ignores,
                             "/usr/cobalt/site/child/_posts/child",
                             true);

        assert_includes_dir!("/usr/cobalt/site",
                             ignores,
                             "/usr/cobalt/site/_posts/child/_child",
                             false);
        assert_includes_dir!("/usr/cobalt/site",
                             ignores,
                             "/usr/cobalt/site/_posts/child/_child/child",
                             false);
    }

    #[test]
    fn files_includes_overriden_dir_file() {
        let ignores = &["!_posts", "!_posts/**", "_posts/**/_*", "_posts/**/_*/**"];

        assert_includes_file!("/usr/cobalt/site",
                              ignores,
                              "/usr/cobalt/site/_posts/child.txt",
                              true);
        assert_includes_file!("/usr/cobalt/site",
                              ignores,
                              "/usr/cobalt/site/_posts/child/child.txt",
                              true);

        // TODO These two cases should instead fail
        assert_includes_file!("/usr/cobalt/site",
                              ignores,
                              "/usr/cobalt/site/child/_posts/child.txt",
                              true);
        assert_includes_file!("/usr/cobalt/site",
                              ignores,
                              "/usr/cobalt/site/child/_posts/child/child.txt",
                              true);

        assert_includes_file!("/usr/cobalt/site",
                              ignores,
                              "/usr/cobalt/site/_posts/child/_child.txt",
                              false);
        assert_includes_file!("/usr/cobalt/site",
                              ignores,
                              "/usr/cobalt/site/_posts/child/_child/child.txt",
                              false);
    }

    #[test]
    fn files_iter_matches_include() {
        let root_dir = Path::new("tests/fixtures/hidden_files");
        let files = FilesBuilder::new(root_dir).unwrap().build().unwrap();
        let mut actual: Vec<_> = files.files().collect();
        actual.sort();

        let expected = vec![Path::new("child/child.txt").to_path_buf(),
                            Path::new("child.txt").to_path_buf()];

        assert_eq!(expected, actual);
    }
}
<|endoftext|>


<commit_before>extern crate assert_cli;
#[macro_use]
extern crate lazy_static;
extern crate tempdir;

use std::env;
use std::str;
use std::path::{Path, PathBuf};

use tempdir::TempDir;

lazy_static! {
    static ref _CWD: PathBuf = env::current_dir().unwrap();
    static ref CWD: &'static Path = _CWD.as_path();
    // TODO test on release
    static ref _BIN: PathBuf = CWD.join("target/debug/cobalt");
    static ref BIN: &'static str = _BIN.to_str().unwrap();
}

#[test]
pub fn invalid_calls() {
    println!("Binary: {:?}", BIN.to_owned());
    assert_cli::Assert::command(&[&BIN])
        .fails()
        .stderr()
        .contains("requires a subcommand")
        .unwrap();

    assert_cli::Assert::command(&[&BIN, "--nonexistent-argument"])
        .fails_with(1)
        .stderr()
        .contains(r"Found argument '--nonexistent-argument' which wasn't expected")
        .unwrap();
}

#[test]
pub fn log_levels_trace() {
    let destdir = TempDir::new("trace").expect("Tempdir not created");
    let dest_param = destdir
        .path()
        .to_str()
        .expect("Can't convert destdir to str")
        .to_owned();

    assert_cli::Assert::command(&[&BIN, "build", "-L", "trace", "-d", &dest_param])
        .current_dir(CWD.join("tests/fixtures/example"))
        .stderr()
        .contains("[trace]")
        .stderr()
        .contains("[debug]")
        .stderr()
        .contains("[info]")
        .unwrap();

    destdir.close().unwrap();
}

#[test]
pub fn log_levels_trace_alias() {
    let destdir = TempDir::new("trace").expect("Tempdir not created");
    let dest_param = destdir
        .path()
        .to_str()
        .expect("Can't convert destdir to str")
        .to_owned();

    assert_cli::Assert::command(&[&BIN, "build", "--trace", "-d", &dest_param])
        .current_dir(CWD.join("tests/fixtures/example"))
        .stderr()
        .contains("[trace]")
        .stderr()
        .contains("[debug]")
        .stderr()
        .contains("[info]")
        .unwrap();

    destdir.close().unwrap();
}

#[test]
pub fn log_levels_debug() {
    let destdir = TempDir::new("debug").expect("Tempdir not created");
    let dest_param = destdir
        .path()
        .to_str()
        .expect("Can't convert destdir to str")
        .to_owned();

    assert_cli::Assert::command(&[&BIN, "build", "-L", "debug", "-d", &dest_param])
        .current_dir(CWD.join("tests/fixtures/example"))
        .stderr()
        .doesnt_contain("[trace]")
        .stderr()
        .contains("[debug]")
        .stderr()
        .contains("[info]")
        .unwrap();

    destdir.close().unwrap();
}

#[test]
pub fn log_levels_info() {
    let destdir = TempDir::new("info").expect("Tempdir not created");
    let dest_param = destdir
        .path()
        .to_str()
        .expect("Can't convert destdir to str")
        .to_owned();

    assert_cli::Assert::command(&[&BIN, "build", "-L", "info", "-d", &dest_param])
        .current_dir(CWD.join("tests/fixtures/example"))
        .stderr()
        .doesnt_contain("[trace]")
        .stderr()
        .doesnt_contain("[debug]")
        .stderr()
        .contains("[info]")
        .unwrap();

    destdir.close().unwrap();
}

#[test]
pub fn log_levels_silent() {
    let destdir = TempDir::new("silent").expect("Tempdir not created");
    let dest_param = destdir
        .path()
        .to_str()
        .expect("Can't convert destdir to str")
        .to_owned();

    assert_cli::Assert::command(&[&BIN, "build", "--silent", "-d", &dest_param])
        .current_dir(CWD.join("tests/fixtures/example"))
        .stderr()
        .is("")
        .stdout()
        .is("")
        .unwrap();

    destdir.close().unwrap();
}

#[test]
pub fn clean() {
    let destdir = TempDir::new("clean").expect("Tempdir not created");
    let dest_param = destdir
        .path()
        .to_str()
        .expect("Can't convert destdir to str")
        .to_owned();

    assert_cli::Assert::command(&[&BIN, "build", "--trace", "-d", &dest_param])
        .current_dir(CWD.join("tests/fixtures/example"))
        .unwrap();
    assert_eq!(destdir.path().is_dir(), true);

    assert_cli::Assert::command(&[&BIN, "clean", "--trace", "-d", &dest_param])
        .current_dir(CWD.join("tests/fixtures/example"))
        .unwrap();
    assert_eq!(destdir.path().is_dir(), false);
}

#[cfg(not(windows))]
#[test]
pub fn clean_warning() {
    assert_cli::Assert::command(&[&BIN, "clean"])
        .current_dir(CWD.join("tests/fixtures/example"))
        .fails_with(1)
        .stderr()
        .contains("Destination directory is same as current directory. Cancelling the \
              operation")
        .unwrap();
}
<commit_msg>tests: Test cobalt init<commit_after>extern crate assert_cli;
#[macro_use]
extern crate lazy_static;
extern crate tempdir;

use std::env;
use std::str;
use std::path::{Path, PathBuf};

use tempdir::TempDir;

lazy_static! {
    static ref _CWD: PathBuf = env::current_dir().unwrap();
    static ref CWD: &'static Path = _CWD.as_path();
    // TODO test on release
    static ref _BIN: PathBuf = CWD.join("target/debug/cobalt");
    static ref BIN: &'static str = _BIN.to_str().unwrap();
}

#[test]
pub fn invalid_calls() {
    println!("Binary: {:?}", BIN.to_owned());
    assert_cli::Assert::command(&[&BIN])
        .fails()
        .stderr()
        .contains("requires a subcommand")
        .unwrap();

    assert_cli::Assert::command(&[&BIN, "--nonexistent-argument"])
        .fails_with(1)
        .stderr()
        .contains(r"Found argument '--nonexistent-argument' which wasn't expected")
        .unwrap();
}

#[test]
pub fn log_levels_trace() {
    let destdir = TempDir::new("trace").expect("Tempdir not created");
    let dest_param = destdir
        .path()
        .to_str()
        .expect("Can't convert destdir to str")
        .to_owned();

    assert_cli::Assert::command(&[&BIN, "build", "-L", "trace", "-d", &dest_param])
        .current_dir(CWD.join("tests/fixtures/example"))
        .stderr()
        .contains("[trace]")
        .stderr()
        .contains("[debug]")
        .stderr()
        .contains("[info]")
        .unwrap();

    destdir.close().unwrap();
}

#[test]
pub fn log_levels_trace_alias() {
    let destdir = TempDir::new("trace").expect("Tempdir not created");
    let dest_param = destdir
        .path()
        .to_str()
        .expect("Can't convert destdir to str")
        .to_owned();

    assert_cli::Assert::command(&[&BIN, "build", "--trace", "-d", &dest_param])
        .current_dir(CWD.join("tests/fixtures/example"))
        .stderr()
        .contains("[trace]")
        .stderr()
        .contains("[debug]")
        .stderr()
        .contains("[info]")
        .unwrap();

    destdir.close().unwrap();
}

#[test]
pub fn log_levels_debug() {
    let destdir = TempDir::new("debug").expect("Tempdir not created");
    let dest_param = destdir
        .path()
        .to_str()
        .expect("Can't convert destdir to str")
        .to_owned();

    assert_cli::Assert::command(&[&BIN, "build", "-L", "debug", "-d", &dest_param])
        .current_dir(CWD.join("tests/fixtures/example"))
        .stderr()
        .doesnt_contain("[trace]")
        .stderr()
        .contains("[debug]")
        .stderr()
        .contains("[info]")
        .unwrap();

    destdir.close().unwrap();
}

#[test]
pub fn log_levels_info() {
    let destdir = TempDir::new("info").expect("Tempdir not created");
    let dest_param = destdir
        .path()
        .to_str()
        .expect("Can't convert destdir to str")
        .to_owned();

    assert_cli::Assert::command(&[&BIN, "build", "-L", "info", "-d", &dest_param])
        .current_dir(CWD.join("tests/fixtures/example"))
        .stderr()
        .doesnt_contain("[trace]")
        .stderr()
        .doesnt_contain("[debug]")
        .stderr()
        .contains("[info]")
        .unwrap();

    destdir.close().unwrap();
}

#[test]
pub fn log_levels_silent() {
    let destdir = TempDir::new("silent").expect("Tempdir not created");
    let dest_param = destdir
        .path()
        .to_str()
        .expect("Can't convert destdir to str")
        .to_owned();

    assert_cli::Assert::command(&[&BIN, "build", "--silent", "-d", &dest_param])
        .current_dir(CWD.join("tests/fixtures/example"))
        .stderr()
        .is("")
        .stdout()
        .is("")
        .unwrap();

    destdir.close().unwrap();
}

#[test]
pub fn clean() {
    let destdir = TempDir::new("clean").expect("Tempdir not created");
    let dest_param = destdir
        .path()
        .to_str()
        .expect("Can't convert destdir to str")
        .to_owned();

    assert_cli::Assert::command(&[&BIN, "build", "--trace", "-d", &dest_param])
        .current_dir(CWD.join("tests/fixtures/example"))
        .unwrap();
    assert_eq!(destdir.path().is_dir(), true);

    assert_cli::Assert::command(&[&BIN, "clean", "--trace", "-d", &dest_param])
        .current_dir(CWD.join("tests/fixtures/example"))
        .unwrap();
    assert_eq!(destdir.path().is_dir(), false);
}

#[cfg(not(windows))]
#[test]
pub fn clean_warning() {
    assert_cli::Assert::command(&[&BIN, "clean"])
        .current_dir(CWD.join("tests/fixtures/example"))
        .fails_with(1)
        .stderr()
        .contains("Destination directory is same as current directory. Cancelling the \
              operation")
        .unwrap();
}

#[test]
pub fn init_project_can_build() {
    let initdir = TempDir::new("init").expect("Tempdir not created");

    let destdir = TempDir::new("dest").expect("Tempdir not created");
    let dest_param = destdir
        .path()
        .to_str()
        .expect("Can't convert destdir to str")
        .to_owned();

    assert_cli::Assert::command(&[&BIN, "init", "--trace"])
        .current_dir(initdir.path())
        .unwrap();
    assert_cli::Assert::command(&[&BIN, "build", "--trace", "-d", &dest_param])
        .current_dir(initdir.path())
        .unwrap();

    destdir.close().unwrap();
    initdir.close().unwrap();
}
<|endoftext|>


<commit_before>extern crate clap;

use std::env;
use std::ffi::OsStr;

use clap::{App, Arg};

#[test]
fn env() {
    env::set_var("CLP_TEST_ENV", "env");

    let r = App::new("df")
        .arg(Arg::from("[arg] 'some opt'").env("CLP_TEST_ENV"))
        .get_matches_from_safe(vec![""]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 0);
    assert_eq!(m.value_of("arg").unwrap(), "env");
}

#[test]
fn env_os() {
    env::set_var("CLP_TEST_ENV", "env");

    let r = App::new("df")
        .arg(Arg::from("[arg] 'some opt'").env_os(OsStr::new("CLP_TEST_ENV")))
        .get_matches_from_safe(vec![""]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 0);
    assert_eq!(m.value_of("arg").unwrap(), "env");
}

#[test]
fn no_env() {
    // All the other tests use the presence of the Environment variable...
    // we need another variable just in case one of the others is running at the same time...
    env::remove_var("CLP_TEST_ENV_NONE");

    let r = App::new("df")
        .arg(Arg::from("[arg] 'some opt'").env("CLP_TEST_ENV_NONE"))
        .get_matches_from_safe(vec![""]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(!m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 0);
    assert_eq!(m.value_of("arg"), None);
}

#[test]
fn with_default() {
    env::set_var("CLP_TEST_ENV", "env");

    let r = App::new("df")
        .arg(
            Arg::from("[arg] 'some opt'")
                .env("CLP_TEST_ENV")
                .default_value("default"),
        )
        .get_matches_from_safe(vec![""]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 0);
    assert_eq!(m.value_of("arg").unwrap(), "env");
}

#[test]
fn opt_user_override() {
    env::set_var("CLP_TEST_ENV", "env");

    let r = App::new("df")
        .arg(Arg::from("--arg [FILE] 'some arg'").env("CLP_TEST_ENV"))
        .get_matches_from_safe(vec!["", "--arg", "opt"]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 1);
    assert_eq!(m.value_of("arg").unwrap(), "opt");
}

#[test]
fn positionals() {
    env::set_var("CLP_TEST_ENV", "env");

    let r = App::new("df")
        .arg(Arg::from("[arg] 'some opt'").env("CLP_TEST_ENV"))
        .get_matches_from_safe(vec![""]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 0);
    assert_eq!(m.value_of("arg").unwrap(), "env");
}

#[test]
fn positionals_user_override() {
    env::set_var("CLP_TEST_ENV", "env");

    let r = App::new("df")
        .arg(Arg::from("[arg] 'some opt'").env("CLP_TEST_ENV"))
        .get_matches_from_safe(vec!["", "opt"]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 1);
    assert_eq!(m.value_of("arg").unwrap(), "opt");
}

#[test]
fn multiple_one() {
    env::set_var("CLP_TEST_ENV", "env");

    let r = App::new("df")
        .arg(
            Arg::from("[arg] 'some opt'")
                .env("CLP_TEST_ENV")
                .use_delimiter(true)
                .multiple(true),
        )
        .get_matches_from_safe(vec![""]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 0);
    assert_eq!(m.values_of("arg").unwrap().collect::<Vec<_>>(), vec!["env"]);
}

#[test]
fn multiple_three() {
    env::set_var("CLP_TEST_ENV_MULTI1", "env1,env2,env3");

    let r = App::new("df")
        .arg(
            Arg::from("[arg] 'some opt'")
                .env("CLP_TEST_ENV_MULTI1")
                .use_delimiter(true)
                .multiple(true),
        )
        .get_matches_from_safe(vec![""]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 0);
    assert_eq!(
        m.values_of("arg").unwrap().collect::<Vec<_>>(),
        vec!["env1", "env2", "env3"]
    );
}

#[test]
fn multiple_no_delimiter() {
    env::set_var("CLP_TEST_ENV_MULTI2", "env1 env2 env3");

    let r = App::new("df")
        .arg(
            Arg::from("[arg] 'some opt'")
                .env("CLP_TEST_ENV_MULTI2")
                .multiple(true),
        )
        .get_matches_from_safe(vec![""]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 0);
    assert_eq!(
        m.values_of("arg").unwrap().collect::<Vec<_>>(),
        vec!["env1 env2 env3"]
    );
}

#[test]
fn possible_value() {
    env::set_var("CLP_TEST_ENV", "env");

    let r = App::new("df")
        .arg(
            Arg::from("[arg] 'some opt'")
                .env("CLP_TEST_ENV")
                .possible_value("env"),
        )
        .get_matches_from_safe(vec![""]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 0);
    assert_eq!(m.value_of("arg").unwrap(), "env");
}

#[test]
fn not_possible_value() {
    env::set_var("CLP_TEST_ENV", "env");

    let r = App::new("df")
        .arg(
            Arg::from("[arg] 'some opt'")
                .env("CLP_TEST_ENV")
                .possible_value("never"),
        )
        .get_matches_from_safe(vec![""]);

    assert!(r.is_err());
}

#[test]
fn validator() {
    env::set_var("CLP_TEST_ENV", "env");

    let r = App::new("df")
        .arg(
            Arg::from("[arg] 'some opt'")
                .env("CLP_TEST_ENV")
                .validator(|s| {
                    if s == "env" {
                        Ok(())
                    } else {
                        Err("not equal".to_string())
                    }
                }),
        )
        .get_matches_from_safe(vec![""]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 0);
    assert_eq!(m.value_of("arg").unwrap(), "env");
}

#[test]
fn validator_output() {
    env::set_var("CLP_TEST_ENV", "42");

    let m = App::new("df")
        .arg(
            Arg::from("[arg] 'some opt'")
                .env("CLP_TEST_ENV")
                .validator(|s| s.parse::<i32>()),
        )
        .get_matches_from(vec![""]);

    assert_eq!(m.value_of("arg").unwrap().parse(), Ok(42));
}

#[test]
fn validator_invalid() {
    env::set_var("CLP_TEST_ENV", "env");

    let r = App::new("df")
        .arg(
            Arg::from("[arg] 'some opt'")
                .env("CLP_TEST_ENV")
                .validator(|s| {
                    if s != "env" {
                        Ok(())
                    } else {
                        Err("is equal".to_string())
                    }
                }),
        )
        .get_matches_from_safe(vec![""]);

    assert!(r.is_err());
}
<commit_msg>tests: fixes intermitent failures using env vars<commit_after>extern crate clap;

use std::env;
use std::ffi::OsStr;

use clap::{App, Arg};

#[test]
fn env() {
    env::set_var("CLP_TEST_ENV", "env");

    let r = App::new("df")
        .arg(Arg::from("[arg] 'some opt'").env("CLP_TEST_ENV"))
        .get_matches_from_safe(vec![""]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 0);
    assert_eq!(m.value_of("arg").unwrap(), "env");
}

#[test]
fn env_os() {
    env::set_var("CLP_TEST_ENV_OS", "env");

    let r = App::new("df")
        .arg(Arg::from("[arg] 'some opt'").env_os(OsStr::new("CLP_TEST_ENV_OS")))
        .get_matches_from_safe(vec![""]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 0);
    assert_eq!(m.value_of("arg").unwrap(), "env");
}

#[test]
fn no_env() {
    // All the other tests use the presence of the Environment variable...
    // we need another variable just in case one of the others is running at the same time...
    env::remove_var("CLP_TEST_ENV_NONE");

    let r = App::new("df")
        .arg(Arg::from("[arg] 'some opt'").env("CLP_TEST_ENV_NONE"))
        .get_matches_from_safe(vec![""]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(!m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 0);
    assert_eq!(m.value_of("arg"), None);
}

#[test]
fn with_default() {
    env::set_var("CLP_TEST_ENV_WITH_DEFAULT", "env");

    let r = App::new("df")
        .arg(
            Arg::from("[arg] 'some opt'")
                .env("CLP_TEST_ENV_WITH_DEFAULT")
                .default_value("default"),
        ).get_matches_from_safe(vec![""]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 0);
    assert_eq!(m.value_of("arg").unwrap(), "env");
}

#[test]
fn opt_user_override() {
    env::set_var("CLP_TEST_ENV_OVERRIDE", "env");

    let r = App::new("df")
        .arg(Arg::from("--arg [FILE] 'some arg'").env("CLP_TEST_ENV_OVERRIDE"))
        .get_matches_from_safe(vec!["", "--arg", "opt"]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 1);
    assert_eq!(m.value_of("arg").unwrap(), "opt");
}

#[test]
fn positionals() {
    env::set_var("CLP_TEST_ENV_POS", "env");

    let r = App::new("df")
        .arg(Arg::from("[arg] 'some opt'").env("CLP_TEST_ENV_POS"))
        .get_matches_from_safe(vec![""]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 0);
    assert_eq!(m.value_of("arg").unwrap(), "env");
}

#[test]
fn positionals_user_override() {
    env::set_var("CLP_TEST_ENV_USER_OR", "env");

    let r = App::new("df")
        .arg(Arg::from("[arg] 'some opt'").env("CLP_TEST_ENV_USER_OR"))
        .get_matches_from_safe(vec!["", "opt"]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 1);
    assert_eq!(m.value_of("arg").unwrap(), "opt");
}

#[test]
fn multiple_one() {
    env::set_var("CLP_TEST_ENV_MULT1", "env");

    let r = App::new("df")
        .arg(
            Arg::from("[arg] 'some opt'")
                .env("CLP_TEST_ENV_MULT1")
                .use_delimiter(true)
                .multiple(true),
        ).get_matches_from_safe(vec![""]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 0);
    assert_eq!(m.values_of("arg").unwrap().collect::<Vec<_>>(), vec!["env"]);
}

#[test]
fn multiple_three() {
    env::set_var("CLP_TEST_ENV_MULTI1", "env1,env2,env3");

    let r = App::new("df")
        .arg(
            Arg::from("[arg] 'some opt'")
                .env("CLP_TEST_ENV_MULTI1")
                .use_delimiter(true)
                .multiple(true),
        ).get_matches_from_safe(vec![""]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 0);
    assert_eq!(
        m.values_of("arg").unwrap().collect::<Vec<_>>(),
        vec!["env1", "env2", "env3"]
    );
}

#[test]
fn multiple_no_delimiter() {
    env::set_var("CLP_TEST_ENV_MULTI2", "env1 env2 env3");

    let r = App::new("df")
        .arg(
            Arg::from("[arg] 'some opt'")
                .env("CLP_TEST_ENV_MULTI2")
                .multiple(true),
        ).get_matches_from_safe(vec![""]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 0);
    assert_eq!(
        m.values_of("arg").unwrap().collect::<Vec<_>>(),
        vec!["env1 env2 env3"]
    );
}

#[test]
fn possible_value() {
    env::set_var("CLP_TEST_ENV_POS_VAL", "env");

    let r = App::new("df")
        .arg(
            Arg::from("[arg] 'some opt'")
                .env("CLP_TEST_ENV_POS_VAL")
                .possible_value("env"),
        ).get_matches_from_safe(vec![""]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 0);
    assert_eq!(m.value_of("arg").unwrap(), "env");
}

#[test]
fn not_possible_value() {
    env::set_var("CLP_TEST_ENV_NOT_POS_VAL", "env");

    let r = App::new("df")
        .arg(
            Arg::from("[arg] 'some opt'")
                .env("CLP_TEST_ENV_NOT_POS_VAL")
                .possible_value("never"),
        ).get_matches_from_safe(vec![""]);

    assert!(r.is_err());
}

#[test]
fn validator() {
    env::set_var("CLP_TEST_ENV_VAL", "env");

    let r = App::new("df")
        .arg(
            Arg::from("[arg] 'some opt'")
                .env("CLP_TEST_ENV_VAL")
                .validator(|s| {
                    if s == "env" {
                        Ok(())
                    } else {
                        Err("not equal".to_string())
                    }
                }),
        ).get_matches_from_safe(vec![""]);

    assert!(r.is_ok());
    let m = r.unwrap();
    assert!(m.is_present("arg"));
    assert_eq!(m.occurrences_of("arg"), 0);
    assert_eq!(m.value_of("arg").unwrap(), "env");
}

#[test]
fn validator_output() {
    env::set_var("CLP_TEST_ENV_VAL_OUT", "42");

    let m = App::new("df")
        .arg(
            Arg::from("[arg] 'some opt'")
                .env("CLP_TEST_ENV_VAL_OUT")
                .validator(|s| s.parse::<i32>()),
        ).get_matches_from(vec![""]);

    assert_eq!(m.value_of("arg").unwrap().parse(), Ok(42));
}

#[test]
fn validator_invalid() {
    env::set_var("CLP_TEST_ENV_INVAL", "env");

    let r = App::new("df")
        .arg(
            Arg::from("[arg] 'some opt'")
                .env("CLP_TEST_ENV_INVAL")
                .validator(|s| {
                    if s != "env" {
                        Ok(())
                    } else {
                        Err("is equal".to_string())
                    }
                }),
        ).get_matches_from_safe(vec![""]);

    assert!(r.is_err());
}
<|endoftext|>


<commit_before>
#[macro_use]
extern crate nom;

use nom::{IResult,Needed,not_line_ending, space, alphanumeric, multispace};
use nom::IResult::*;

use std::str;
use std::str::from_utf8;
use std::collections::HashMap;

named!(category     <&[u8], &str>,
  chain!(
          tag!("[")       ~
    name: map_res!(
      take_until!("]"),
      from_utf8)          ~
          tag!("]")       ~
          multispace?     ,
    ||{ name }
  )
);

named!(key_value    <&[u8],(&str,&str)>,
  chain!(
    key: map_res!(alphanumeric, from_utf8) ~
         space?                            ~
         tag!("=")                         ~
         space?                            ~
    val: map_res!(
           take_until_either!("\n;"),
           from_utf8
         )                                 ~
         space?                            ~
         chain!(
           tag!(";")        ~
           not_line_ending  ,
           ||{}
         ) ?                               ~
         multispace?                       ,
    ||{(key, val)}
  )
);

named!(keys_and_values_aggregator<&[u8], Vec<(&str,&str)> >, many0!(key_value));

fn keys_and_values(input:&[u8]) -> IResult<&[u8], HashMap<&str, &str> > {
  let mut h: HashMap<&str, &str> = HashMap::new();

  match keys_and_values_aggregator(input) {
    IResult::Done(i,tuple_vec) => {
      for &(k,v) in tuple_vec.iter() {
        h.insert(k, v);
      }
      IResult::Done(i, h)
    },
    IResult::Incomplete(a)     => IResult::Incomplete(a),
    IResult::Error(a)          => IResult::Error(a)
  }
}

named!(category_and_keys<&[u8],(&str,HashMap<&str,&str>)>,
  chain!(
    category: category    ~
    keys: keys_and_values ,
    move ||{(category, keys)}
  )
);

named!(categories_aggregator<&[u8], Vec<(&str, HashMap<&str,&str>)> >, many0!(category_and_keys));

fn categories(input: &[u8]) -> IResult<&[u8], HashMap<&str, HashMap<&str, &str> > > {
  let mut h: HashMap<&str, HashMap<&str, &str>> = HashMap::new();

  match categories_aggregator(input) {
    IResult::Done(i,tuple_vec) => {
      for &(k,ref v) in tuple_vec.iter() {
        h.insert(k, v.clone());
      }
      IResult::Done(i, h)
    },
    IResult::Incomplete(a)     => IResult::Incomplete(a),
    IResult::Error(a)          => IResult::Error(a)
  }
}

#[test]
fn parse_category_test() {
  let ini_file = &b"[category]

parameter=value
key = value2"[..];

  let ini_without_category = &b"parameter=value
key = value2"[..];

  let res = category(ini_file);
  println!("{:?}", res);
  match res {
    IResult::Done(i, o) => println!("i: {:?} | o: {:?}", str::from_utf8(i), o),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_category, "category"));
}

#[test]
fn parse_key_value_test() {
  let ini_file = &b"parameter=value
key = value2"[..];

  let ini_without_key_value = &b"key = value2"[..];

  let res = key_value(ini_file);
  println!("{:?}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {:?} | o: ({:?},{:?})", str::from_utf8(i), o1, o2),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value, ("parameter", "value")));
}

#[test]
fn parse_key_value_with_space_test() {
  let ini_file = &b"parameter = value
key = value2"[..];

  let ini_without_key_value = &b"key = value2"[..];

  let res = key_value(ini_file);
  println!("{:?}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {:?} | o: ({:?},{:?})", str::from_utf8(i), o1, o2),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value, ("parameter", "value")));
}

#[test]
fn parse_key_value_with_comment_test() {
  let ini_file = &b"parameter=value;abc
key = value2"[..];

  let ini_without_key_value = &b"key = value2"[..];

  let res = key_value(ini_file);
  println!("{:?}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {:?} | o: ({:?},{:?})", str::from_utf8(i), o1, o2),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value, ("parameter", "value")));
}

#[test]
fn parse_multiple_keys_and_values_test() {
  let ini_file = &b"parameter=value;abc

key = value2

[category]"[..];

  let ini_without_key_value = &b"[category]"[..];

  let res = keys_and_values(ini_file);
  println!("{:?}", res);
  match res {
    IResult::Done(i, ref o) => println!("i: {:?} | o: {:?}", str::from_utf8(i), o),
    _ => println!("error")
  }

  let mut expected: HashMap<&str, &str> = HashMap::new();
  expected.insert("parameter", "value");
  expected.insert("key", "value2");
  assert_eq!(res, Done(ini_without_key_value, expected));
}

#[test]
fn parse_category_then_multiple_keys_and_values_test() {
  //FIXME: there can be an empty line or a comment line after a category
  let ini_file = &b"[abcd]
parameter=value;abc

key = value2

[category]"[..];

  let ini_after_parser = &b"[category]"[..];

  let res = category_and_keys(ini_file);
  println!("{:?}", res);
  match res {
    IResult::Done(i, ref o) => println!("i: {:?} | o: {:?}", str::from_utf8(i), o),
    _ => println!("error")
  }

  let mut expected_h: HashMap<&str, &str> = HashMap::new();
  expected_h.insert("parameter", "value");
  expected_h.insert("key", "value2");
  assert_eq!(res, Done(ini_after_parser, ("abcd", expected_h)));
}

#[test]
fn parse_multiple_categories_test() {
  let ini_file = &b"[abcd]

parameter=value;abc

key = value2

[category]
parameter3=value3
key4 = value4
"[..];

  let ini_after_parser = &b""[..];

  let res = categories(ini_file);
  println!("{:?}", res);
  match res {
    IResult::Done(i, ref o) => println!("i: {:?} | o: {:?}", str::from_utf8(i), o),
    _ => println!("error")
  }

  let mut expected_1: HashMap<&str, &str> = HashMap::new();
  expected_1.insert("parameter", "value");
  expected_1.insert("key", "value2");
  let mut expected_2: HashMap<&str, &str> = HashMap::new();
  expected_2.insert("parameter3", "value3");
  expected_2.insert("key4", "value4");
  let mut expected_h: HashMap<&str, HashMap<&str, &str>> = HashMap::new();
  expected_h.insert("abcd",     expected_1);
  expected_h.insert("category", expected_2);
  assert_eq!(res, Done(ini_after_parser, expected_h));
}

<commit_msg>remove a log message<commit_after>
#[macro_use]
extern crate nom;

use nom::{IResult,Needed,not_line_ending, space, alphanumeric, multispace};
use nom::IResult::*;

use std::str;
use std::str::from_utf8;
use std::collections::HashMap;

named!(category     <&[u8], &str>,
  chain!(
          tag!("[")       ~
    name: map_res!(
      take_until!("]"),
      from_utf8)          ~
          tag!("]")       ~
          multispace?     ,
    ||{ name }
  )
);

named!(key_value    <&[u8],(&str,&str)>,
  chain!(
    key: map_res!(alphanumeric, from_utf8) ~
         space?                            ~
         tag!("=")                         ~
         space?                            ~
    val: map_res!(
           take_until_either!("\n;"),
           from_utf8
         )                                 ~
         space?                            ~
         chain!(
           tag!(";")        ~
           not_line_ending  ,
           ||{}
         ) ?                               ~
         multispace?                       ,
    ||{(key, val)}
  )
);

named!(keys_and_values_aggregator<&[u8], Vec<(&str,&str)> >, many0!(key_value));

fn keys_and_values(input:&[u8]) -> IResult<&[u8], HashMap<&str, &str> > {
  let mut h: HashMap<&str, &str> = HashMap::new();

  match keys_and_values_aggregator(input) {
    IResult::Done(i,tuple_vec) => {
      for &(k,v) in tuple_vec.iter() {
        h.insert(k, v);
      }
      IResult::Done(i, h)
    },
    IResult::Incomplete(a)     => IResult::Incomplete(a),
    IResult::Error(a)          => IResult::Error(a)
  }
}

named!(category_and_keys<&[u8],(&str,HashMap<&str,&str>)>,
  chain!(
    category: category    ~
    keys: keys_and_values ,
    move ||{(category, keys)}
  )
);

named!(categories_aggregator<&[u8], Vec<(&str, HashMap<&str,&str>)> >, many0!(category_and_keys));

fn categories(input: &[u8]) -> IResult<&[u8], HashMap<&str, HashMap<&str, &str> > > {
  let mut h: HashMap<&str, HashMap<&str, &str>> = HashMap::new();

  match categories_aggregator(input) {
    IResult::Done(i,tuple_vec) => {
      for &(k,ref v) in tuple_vec.iter() {
        h.insert(k, v.clone());
      }
      IResult::Done(i, h)
    },
    IResult::Incomplete(a)     => IResult::Incomplete(a),
    IResult::Error(a)          => IResult::Error(a)
  }
}

#[test]
fn parse_category_test() {
  let ini_file = &b"[category]

parameter=value
key = value2"[..];

  let ini_without_category = &b"parameter=value
key = value2"[..];

  let res = category(ini_file);
  println!("{:?}", res);
  match res {
    IResult::Done(i, o) => println!("i: {:?} | o: {:?}", str::from_utf8(i), o),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_category, "category"));
}

#[test]
fn parse_key_value_test() {
  let ini_file = &b"parameter=value
key = value2"[..];

  let ini_without_key_value = &b"key = value2"[..];

  let res = key_value(ini_file);
  println!("{:?}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {:?} | o: ({:?},{:?})", str::from_utf8(i), o1, o2),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value, ("parameter", "value")));
}

#[test]
fn parse_key_value_with_space_test() {
  let ini_file = &b"parameter = value
key = value2"[..];

  let ini_without_key_value = &b"key = value2"[..];

  let res = key_value(ini_file);
  println!("{:?}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {:?} | o: ({:?},{:?})", str::from_utf8(i), o1, o2),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value, ("parameter", "value")));
}

#[test]
fn parse_key_value_with_comment_test() {
  let ini_file = &b"parameter=value;abc
key = value2"[..];

  let ini_without_key_value = &b"key = value2"[..];

  let res = key_value(ini_file);
  println!("{:?}", res);
  match res {
    IResult::Done(i, (o1, o2)) => println!("i: {:?} | o: ({:?},{:?})", str::from_utf8(i), o1, o2),
    _ => println!("error")
  }

  assert_eq!(res, Done(ini_without_key_value, ("parameter", "value")));
}

#[test]
fn parse_multiple_keys_and_values_test() {
  let ini_file = &b"parameter=value;abc

key = value2

[category]"[..];

  let ini_without_key_value = &b"[category]"[..];

  let res = keys_and_values(ini_file);
  println!("{:?}", res);
  match res {
    IResult::Done(i, ref o) => println!("i: {:?} | o: {:?}", str::from_utf8(i), o),
    _ => println!("error")
  }

  let mut expected: HashMap<&str, &str> = HashMap::new();
  expected.insert("parameter", "value");
  expected.insert("key", "value2");
  assert_eq!(res, Done(ini_without_key_value, expected));
}

#[test]
fn parse_category_then_multiple_keys_and_values_test() {
  //FIXME: there can be an empty line or a comment line after a category
  let ini_file = &b"[abcd]
parameter=value;abc

key = value2

[category]"[..];

  let ini_after_parser = &b"[category]"[..];

  let res = category_and_keys(ini_file);
  println!("{:?}", res);
  match res {
    IResult::Done(i, ref o) => println!("i: {:?} | o: {:?}", str::from_utf8(i), o),
    _ => println!("error")
  }

  let mut expected_h: HashMap<&str, &str> = HashMap::new();
  expected_h.insert("parameter", "value");
  expected_h.insert("key", "value2");
  assert_eq!(res, Done(ini_after_parser, ("abcd", expected_h)));
}

#[test]
fn parse_multiple_categories_test() {
  let ini_file = &b"[abcd]

parameter=value;abc

key = value2

[category]
parameter3=value3
key4 = value4
"[..];

  let ini_after_parser = &b""[..];

  let res = categories(ini_file);
  //println!("{:?}", res);
  match res {
    IResult::Done(i, ref o) => println!("i: {:?} | o: {:?}", str::from_utf8(i), o),
    _ => println!("error")
  }

  let mut expected_1: HashMap<&str, &str> = HashMap::new();
  expected_1.insert("parameter", "value");
  expected_1.insert("key", "value2");
  let mut expected_2: HashMap<&str, &str> = HashMap::new();
  expected_2.insert("parameter3", "value3");
  expected_2.insert("key4", "value4");
  let mut expected_h: HashMap<&str, HashMap<&str, &str>> = HashMap::new();
  expected_h.insert("abcd",     expected_1);
  expected_h.insert("category", expected_2);
  assert_eq!(res, Done(ini_after_parser, expected_h));
}

<|endoftext|>


<commit_before>extern crate rig;

mod format_test {

    use std::collections::HashMap;
    use rig::format::{format, Placeholder};

    const W: &'static str = "Fabulous Is Rust";

    #[test]
    fn lower_case() {
        assert_eq!(format(W, "lower".into()), "fabulous is rust");
    }

    #[test]
    fn upper_case() {
        assert_eq!(format(W, "upper".into()), "FABULOUS IS RUST");
    }

    #[test]
    fn capitalize() {
        assert_eq!(format(&W.to_lowercase(), "cap".into()), "Fabulous is rust");
    }

    #[test]
    fn decapitalize() {
        assert_eq!(format(W, "decap".into()), "fabulous Is Rust");
    }

    #[test]
    fn start_case() {
        assert_eq!(format(&W.to_lowercase(), "start".into()), W);
    }

    #[test]
    fn word_only() {
        let includes_ctrls = "_!$what'is-this@charac#ters??";
        assert_eq!(format(includes_ctrls, "word".into()),
                   "_whatisthischaracters");
    }

    #[test]
    fn hyphenate() {
        assert_eq!(format(W, "hyphen".into()), "Fabulous-Is-Rust");
    }

    #[test]
    fn upper_camel() {
        assert_eq!(format(W, "Camel".into()), "FabulousIsRust");
    }

    #[test]
    fn lower_camel() {
        assert_eq!(format(W, "camel".into()), "fabulousIsRust");
    }

    #[test]
    fn normalize() {
        assert_eq!(format(W, "norm".into()), "fabulous-is-rust");
    }

    #[test]
    fn snake_case() {
        assert_eq!(format(W, "snake".into()), "Fabulous_Is_Rust");
    }

    #[test]
    fn directory_path() {
        let p = "path.to.my.directory";
        assert_eq!(format(p, "packaged".into()), "path/to/my/directory");
    }

    #[test]
    fn placeholder_giter8() {
        let ph = Placeholder::parse_g8(r#"project_name;format="upper,hyphen""#).unwrap();
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("project_name".to_owned(), "A simple proj".to_owned());

        assert_eq!(ph.format_with(&params), "A-SIMPLE-PROJ".to_owned());
    }

    #[test]
    fn placeholder_simple() {
        let ph = Placeholder::parse_simple("project_name;norm").unwrap();
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("project_name".to_owned(),
                      "A si\nmPLe         p\trOj".to_owned());

        assert_eq!(ph.format_with(&params), "a-si-mple-p-roj".to_owned());
    }

    #[test]
    fn placeholder_dirname() {
        let ph = Placeholder::parse_dirname("twitter_id__word_cap").unwrap();
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("twitter_id".to_owned(), "bar3s%Ye".to_owned());

        assert_eq!(ph.format_with(&params), "Bar3sye".to_owned());
    }
}

mod template_test {

    use std::collections::HashMap;
    use std::str;
    use rig::format::Style;
    use rig::template::{Params, Template};

    #[test]
    fn compile_inline() {
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("name".to_owned(), "Rust".to_owned());

        let mut out = Vec::new();

        Template::compile_inline(&mut out, Style::Simple, "Hello, $name$!", &params).unwrap();
        assert_eq!(str::from_utf8(&out).unwrap(), "Hello, Rust!");
    }

    #[test]
    fn format_template() {
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("DOCUMENT_NAME".to_owned(),
                      "RUST PROGRAMMING LANGUAGE".to_owned());

        let mut out = Vec::new();

        Template::compile_inline(&mut out,
                                 Style::Simple,
                                 "It's a $DOCUMENT_NAME;camel$",
                                 &params)
            .unwrap();
        assert_eq!(str::from_utf8(&out).unwrap(),
                   "It's a rustProgrammingLanguage".to_owned());
    }

    #[test]
    fn escape_character() {
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("DOCUMENT_NAME".to_owned(),
                      "RUST PROGRAMMING LANGUAGE".to_owned());

        let mut out = Vec::new();

        Template::compile_inline(&mut out,
                                 Style::Simple,
                                 "It's a \\$DOCUMENT_NAME;camel$",
                                 &params)
            .unwrap();
        assert_eq!(str::from_utf8(&out).unwrap(),
                   "It's a \\$DOCUMENT_NAME;camel$".to_owned());
    }

    #[test]
    fn giter8_template() {
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("name".to_owned(),
                      "awesome distributed interface".to_owned());

        let mut out = Vec::new();

        let mut tpl =
            Template::new_g8(r#"trait $name;format="Camel"$[-A] extends js.Dictionary[A]"#);
        tpl.write(&mut out, &params).unwrap();

        assert_eq!(str::from_utf8(&out).unwrap(),
                   "trait AwesomeDistributedInterface[-A] extends js.Dictionary[A]".to_owned());
    }
}

mod project_test {

    extern crate tempdir;
    use std::fs;
    use std::path::{Path, PathBuf};

    use rig::fsutils;
    use rig::project::Project;

    const G8_PROPS: &'static str = r#"
        name = value1
        bar = baz!
        package = com.example.me
    "#;

    const TOML: &'static str = r#"
        name = "My Project"
        package = "deep.pkg.path"
        will_be_ignored = [4, 5, 6, 7]
        module_name = "quux"
    "#;

    #[test]
    fn giter8_project() {

        let g8_dirs = vec![
            "src/main/g8",
            "src/main/g8/project",
            "src/main/g8/src/main/scala/$package$"
        ];

        let src = tempdir::TempDir::new("rig-g8-test").unwrap();
        let src = src.path();
        for dir in &g8_dirs {
            let dir = src.join(dir);
            fs::create_dir_all(dir).unwrap();
        }

        let props = src.join("src/main/g8/default.properties");
        fsutils::write_file(&props, G8_PROPS).unwrap();
        assert!(fsutils::exists(&props));

        let dest = tempdir::TempDir::new("generated-proj").unwrap();
        let dest = dest.path();

        let project = Project::new_g8(Some("src/main/g8"));

        let params = project.default_params(&src).unwrap();
        assert_eq!(params.get("name"), Some(&"value1".to_owned()));

        project.generate(&params, &src, &dest, false).unwrap();

        let expected = vec![
            "project",
            "src/main/scala/com",
            "src/main/scala/com/example",
            "src/main/scala/com/example/me",
        ];

        for goal in &expected {
            let goal = &dest.join(goal);
            assert!(fsutils::exists(&goal));
        }
    }
}
<commit_msg>tests: testing simple project<commit_after>extern crate rig;

mod format_test {

    use std::collections::HashMap;
    use rig::format::{format, Placeholder};

    const W: &'static str = "Fabulous Is Rust";

    #[test]
    fn lower_case() {
        assert_eq!(format(W, "lower".into()), "fabulous is rust");
    }

    #[test]
    fn upper_case() {
        assert_eq!(format(W, "upper".into()), "FABULOUS IS RUST");
    }

    #[test]
    fn capitalize() {
        assert_eq!(format(&W.to_lowercase(), "cap".into()), "Fabulous is rust");
    }

    #[test]
    fn decapitalize() {
        assert_eq!(format(W, "decap".into()), "fabulous Is Rust");
    }

    #[test]
    fn start_case() {
        assert_eq!(format(&W.to_lowercase(), "start".into()), W);
    }

    #[test]
    fn word_only() {
        let includes_ctrls = "_!$what'is-this@charac#ters??";
        assert_eq!(format(includes_ctrls, "word".into()),
                   "_whatisthischaracters");
    }

    #[test]
    fn hyphenate() {
        assert_eq!(format(W, "hyphen".into()), "Fabulous-Is-Rust");
    }

    #[test]
    fn upper_camel() {
        assert_eq!(format(W, "Camel".into()), "FabulousIsRust");
    }

    #[test]
    fn lower_camel() {
        assert_eq!(format(W, "camel".into()), "fabulousIsRust");
    }

    #[test]
    fn normalize() {
        assert_eq!(format(W, "norm".into()), "fabulous-is-rust");
    }

    #[test]
    fn snake_case() {
        assert_eq!(format(W, "snake".into()), "Fabulous_Is_Rust");
    }

    #[test]
    fn directory_path() {
        let p = "path.to.my.directory";
        assert_eq!(format(p, "packaged".into()), "path/to/my/directory");
    }

    #[test]
    fn placeholder_giter8() {
        let ph = Placeholder::parse_g8(r#"project_name;format="upper,hyphen""#).unwrap();
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("project_name".to_owned(), "A simple proj".to_owned());

        assert_eq!(ph.format_with(&params), "A-SIMPLE-PROJ".to_owned());
    }

    #[test]
    fn placeholder_simple() {
        let ph = Placeholder::parse_simple("project_name;norm").unwrap();
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("project_name".to_owned(),
                      "A si\nmPLe         p\trOj".to_owned());

        assert_eq!(ph.format_with(&params), "a-si-mple-p-roj".to_owned());
    }

    #[test]
    fn placeholder_dirname() {
        let ph = Placeholder::parse_dirname("twitter_id__word_cap").unwrap();
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("twitter_id".to_owned(), "bar3s%Ye".to_owned());

        assert_eq!(ph.format_with(&params), "Bar3sye".to_owned());
    }
}

mod template_test {

    use std::collections::HashMap;
    use std::str;
    use rig::format::Style;
    use rig::template::Template;

    #[test]
    fn compile_inline() {
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("name".to_owned(), "Rust".to_owned());

        let mut out = Vec::new();

        Template::compile_inline(&mut out, Style::Simple, "Hello, $name$!", &params).unwrap();
        assert_eq!(str::from_utf8(&out).unwrap(), "Hello, Rust!");
    }

    #[test]
    fn format_template() {
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("DOCUMENT_NAME".to_owned(),
                      "RUST PROGRAMMING LANGUAGE".to_owned());

        let mut out = Vec::new();

        Template::compile_inline(&mut out,
                                 Style::Simple,
                                 "It's a $DOCUMENT_NAME;camel$",
                                 &params)
            .unwrap();
        assert_eq!(str::from_utf8(&out).unwrap(),
                   "It's a rustProgrammingLanguage".to_owned());
    }

    #[test]
    fn escape_character() {
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("DOCUMENT_NAME".to_owned(),
                      "RUST PROGRAMMING LANGUAGE".to_owned());

        let mut out = Vec::new();

        Template::compile_inline(&mut out,
                                 Style::Simple,
                                 "It's a \\$DOCUMENT_NAME;camel$",
                                 &params)
            .unwrap();
        assert_eq!(str::from_utf8(&out).unwrap(),
                   "It's a \\$DOCUMENT_NAME;camel$".to_owned());
    }

    #[test]
    fn giter8_template() {
        let mut params: HashMap<String, String> = HashMap::new();
        params.insert("name".to_owned(),
                      "awesome distributed interface".to_owned());

        let mut out = Vec::new();

        let mut tpl =
            Template::new_g8(r#"trait $name;format="Camel"$[-A] extends js.Dictionary[A]"#);
        tpl.write(&mut out, &params).unwrap();

        assert_eq!(str::from_utf8(&out).unwrap(),
                   "trait AwesomeDistributedInterface[-A] extends js.Dictionary[A]".to_owned());
    }
}

mod project_test {

    extern crate tempdir;
    use std::fs;

    use rig::fsutils;
    use rig::project::{ConfigFormat, Project};

    const G8_PROPS: &'static str = r#"
        name = value1
        bar = baz!
        package = com.example.me
    "#;

    const TOML: &'static str = r#"
        name = "My Project"
        package = "deep.pkg.path"
        will_be_ignored = [4, 5, 6, 7]
        module_name = "quux"
    "#;

    #[test]
    fn simple_project() {

        let rust_dirs = vec![
            "src/sample",
            "src/sample/$package$",
            "ci"
        ];

        let src = tempdir::TempDir::new("rig-simple-test").unwrap();
        let src = src.path();
        for dir in &rust_dirs {
            let dir = src.join(dir);
            fs::create_dir_all(dir).unwrap();
        }

        let toml = src.join("_rig.toml");
        fsutils::write_file(&toml, TOML).unwrap();
        assert!(fsutils::exists(&toml));

        let dest = tempdir::TempDir::new("generated-proj").unwrap();
        let dest = dest.path();

        let project = Project::new(None as Option<&str>, ConfigFormat::Toml, false);
        let params = project.default_params(&src).unwrap();
        assert_eq!(params.get("name"), Some(&"My Project".to_owned()));
        assert_eq!(params.get("module_name"), Some(&"quux".to_owned()));
        assert!(params.get("will_be_ignored").is_none());

        project.generate(&params, &src, &dest, false).unwrap();

        let expected = vec![
            "ci",
            "src/sample",
            "src/sample/deep.pkg.path"
        ];

        for goal in &expected {
            let goal = &dest.join(goal);
            assert!(fsutils::exists(&goal));
        }
    }

    #[test]
    fn giter8_project() {

        let g8_dirs = vec![
            "src/main/g8",
            "src/main/g8/project",
            "src/main/g8/src/main/scala/$package$"
        ];

        let src = tempdir::TempDir::new("rig-g8-test").unwrap();
        let src = src.path();
        for dir in &g8_dirs {
            let dir = src.join(dir);
            fs::create_dir_all(dir).unwrap();
        }

        let props = src.join("src/main/g8/default.properties");
        fsutils::write_file(&props, G8_PROPS).unwrap();
        assert!(fsutils::exists(&props));

        let dest = tempdir::TempDir::new("generated-proj").unwrap();
        let dest = dest.path();

        let project = Project::new_g8(Some("src/main/g8"));

        let params = project.default_params(&src).unwrap();
        assert_eq!(params.get("name"), Some(&"value1".to_owned()));

        project.generate(&params, &src, &dest, false).unwrap();

        let expected = vec![
            "project",
            "src/main/scala/com",
            "src/main/scala/com/example",
            "src/main/scala/com/example/me",
        ];

        for goal in &expected {
            let goal = &dest.join(goal);
            assert!(fsutils::exists(&goal));
        }
    }
}
<|endoftext|>


<commit_before>extern crate compression;

#[test]
/// Simple first test
fn should_decompress_xxxxxyyyyy() {
	use std::io::{ Cursor, Read };
	use compression::gzip::Decompressor;
	use compression::bitreader::BitReader;

	let gzip_stream = BitReader::new(Cursor::new(vec![0x1fu8, 0x8bu8, 0x08u8, 0x08u8, 0x9fu8, 0x30u8, 0x04u8, 0x56u8, 0x00u8, 0x03u8, 0x78u8, 0x78u8, 0x78u8, 0x78u8, 0x78u8, 0x79u8, 0x79u8, 0x79u8, 0x79u8, 0x79u8, 0x2eu8, 0x74u8, 0x78u8, 0x74u8, 0x00u8, 0xabu8, 0xa8u8, 0x00u8, 0x82u8, 0x4au8, 0x10u8, 0x00u8, 0x00u8, 0x42u8, 0x62u8, 0xddu8, 0x64u8, 0x0au8, 0x00u8, 0x00u8, 0x00u8]));
	let mut decompressed = &mut String::new();

	let _ = Decompressor::new(gzip_stream).read_to_string(&mut decompressed);

	assert_eq!("xxxxxyyyyy", decompressed);
}

#[test]
/// Tests distance codes being read correctly, and output bytes being appened in the right order to output buffer
fn should_decompress_abc() {
	use std::io::{ Cursor, Read };
	use compression::gzip::Decompressor;
	use compression::bitreader::BitReader;

	let gzip_stream = BitReader::new(Cursor::new(vec![0x1fu8, 0x8bu8, 0x08u8, 0x08u8, 0x31u8, 0x51u8, 0x10u8, 0x56u8, 0x00u8, 0x03u8, 0x61u8, 0x62u8, 0x63u8, 0x2eu8, 0x74u8, 0x78u8, 0x74u8, 0x00u8, 0x4bu8, 0x4cu8, 0x4au8, 0x4eu8, 0x49u8, 0x4du8, 0x4bu8, 0xcfu8, 0xc8u8, 0xccu8, 0xcau8, 0xceu8, 0xc9u8, 0xcdu8, 0xcbu8, 0x2fu8, 0x28u8, 0x2cu8, 0x2au8, 0x2eu8, 0x29u8, 0x2du8, 0x2bu8, 0xafu8, 0xa8u8, 0xacu8, 0x4au8, 0xa4u8, 0xaau8, 0x0cu8, 0x00u8, 0x20u8, 0x2du8, 0x2au8, 0x6au8, 0x68u8, 0x00u8, 0x00u8, 0x00u8]));
	let mut decompressed = &mut String::new();

	let _ = Decompressor::new(gzip_stream).read_to_string(&mut decompressed);

	assert_eq!("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", decompressed);
}

#[test]
/// Tests file with dynamic huffman codes
fn should_decompress_abccba() {
	use std::io::{ Cursor, Read };
	use compression::gzip::Decompressor;
	use compression::bitreader::BitReader;

	let gzip_stream = BitReader::new(Cursor::new(vec![
		0x1f, 0x8b, 0x08, 0x08, 0xbf, 0x72, 0x10, 0x56, 0x00, 0x03, 0x61, 0x62, 0x63, 0x63, 0x62, 0x61,
		0x2e, 0x74, 0x78, 0x74, 0x00, 0x9d, 0xcb, 0xb7, 0x01, 0x00, 0x20, 0x08, 0x00, 0xb0, 0x5b, 0xb1,
		0x63, 0x45, 0xec, 0x5e, 0xef, 0x0f, 0x66, 0x0f, 0x08, 0xa9, 0xb4, 0xb1, 0x0e, 0x7d, 0x88, 0x29,
		0x17, 0xaa, 0xdc, 0xfa, 0x98, 0x6b, 0x9f, 0x7b, 0xcf, 0x5e, 0x73, 0xf4, 0xc6, 0x95, 0x4a, 0x4e,
		0x31, 0x78, 0x74, 0xd6, 0x68, 0x25, 0x05, 0xc0, 0xc7, 0x79, 0x72, 0xf1, 0x8d, 0xd6, 0x68, 0x00,
		0x00, 0x00
	]));
	let mut decompressed = &mut String::new();

	let _ = Decompressor::new(gzip_stream).read_to_string(&mut decompressed);

	assert_eq!("abcdefghijklmnopqrstuvwxyzzyxwvutsrqponmlkjihgfedcbaabcdefghijklmnopqrstuvwxyzzyxwvutsrqponmlkjihgfedcba", decompressed);
}

#[test]
/// Brotli: Empty file
fn should_decompress_to_empty_string() {
	use std::io::{ Cursor, Read };
	use compression::brotli::Decompressor;
	use compression::bitreader::BitReader;

	let brotli_stream = BitReader::new(Cursor::new(vec![
		0x06
	]));

	let mut decompressed = &mut String::new();
	let _ = Decompressor::new(brotli_stream).read_to_string(&mut decompressed);

	assert_eq!("", decompressed);
}

#[test]
/// Brotli: Empty file #01
fn should_decompress_to_empty_string_01() {
	use std::io::{ Cursor, Read };
	use compression::brotli::Decompressor;
	use compression::bitreader::BitReader;

	let brotli_stream = BitReader::new(Cursor::new(vec![
		0x81, 0x01
	]));

	let mut decompressed = &mut String::new();
	let _ = Decompressor::new(brotli_stream).read_to_string(&mut decompressed);

	assert_eq!("", decompressed);
}

#[test]
#[should_panic]
fn should_reject_invalid_stream_with_trailing_non_zero_bits() {
	use std::io::{ Cursor, Read };
	use compression::brotli::Decompressor;
	use compression::bitreader::BitReader;

	let brotli_stream = BitReader::new(Cursor::new(vec![
		0xa1, 0x03,
	]));

	let mut decompressed = &mut String::new();
	let _ = Decompressor::new(brotli_stream).read_to_string(&mut decompressed);
}

#[test]
/// Brotli: Empty file #15
fn should_decompress_to_empty_string_15() {
	use std::io::{ Cursor, Read };
	use compression::brotli::Decompressor;
	use compression::bitreader::BitReader;

	let brotli_stream = BitReader::new(Cursor::new(vec![
		0x1a,
	]));

	let mut decompressed = &mut String::new();
	let _ = Decompressor::new(brotli_stream).read_to_string(&mut decompressed);

	assert_eq!("", decompressed);
}

#[test]
/// Brotli: Empty file #16
fn should_decompress_to_empty_string_16() {
	use std::io::{ Cursor, Read };
	use compression::brotli::Decompressor;
	use compression::bitreader::BitReader;

	let brotli_stream = BitReader::new(Cursor::new(vec![
		0x81, 0x16, 0x00, 0x58
	]));

	let mut decompressed = &mut String::new();
	let _ = Decompressor::new(brotli_stream).read_to_string(&mut decompressed);

	assert_eq!("", decompressed);
}

#[test]
/// Brotli: Empty file
#[should_panic(expected="Expected end-of-stream, but stream did not end")]
fn should_reject_invalid_stream_with_trailing_bytes() {
	use std::io::{ Cursor, Read };
	use compression::brotli::Decompressor;
	use compression::bitreader::BitReader;

	let brotli_stream = BitReader::new(Cursor::new(vec![
		0x1a, 0xff
	]));

	let mut decompressed = &mut String::new();
	let _ = Decompressor::new(brotli_stream).read_to_string(&mut decompressed);

	assert_eq!("", decompressed);
}

#[test]
/// Brotli: Empty file #17
fn should_decompress_to_empty_string_17() {
	use std::fs::{ File };
	use std::io::{ Read };
	use compression::brotli::Decompressor;
	use compression::bitreader::BitReader;

	let brotli_stream = BitReader::new(File::open("data/empty.compressed.17").unwrap());

	let mut decompressed = &mut String::new();
	let _ = Decompressor::new(brotli_stream).read_to_string(&mut decompressed);

	assert_eq!("", decompressed);
}

#[test]
/// Brotli: X file
fn should_decompress_to_X() {
	use std::io::{ Cursor, Read };
	use compression::brotli::Decompressor;
	use compression::bitreader::BitReader;

	let brotli_stream = BitReader::new(Cursor::new(vec![
		0x0b, 0x00, 0x80, 0x58, 0x03,
	]));

	let mut decompressed = &mut String::new();
	let _ = Decompressor::new(brotli_stream).read_to_string(&mut decompressed);

	assert_eq!("X", decompressed);
}
<commit_msg>FIX: snake-case lint<commit_after>extern crate compression;

#[test]
/// Simple first test
fn should_decompress_xxxxxyyyyy() {
	use std::io::{ Cursor, Read };
	use compression::gzip::Decompressor;
	use compression::bitreader::BitReader;

	let gzip_stream = BitReader::new(Cursor::new(vec![0x1fu8, 0x8bu8, 0x08u8, 0x08u8, 0x9fu8, 0x30u8, 0x04u8, 0x56u8, 0x00u8, 0x03u8, 0x78u8, 0x78u8, 0x78u8, 0x78u8, 0x78u8, 0x79u8, 0x79u8, 0x79u8, 0x79u8, 0x79u8, 0x2eu8, 0x74u8, 0x78u8, 0x74u8, 0x00u8, 0xabu8, 0xa8u8, 0x00u8, 0x82u8, 0x4au8, 0x10u8, 0x00u8, 0x00u8, 0x42u8, 0x62u8, 0xddu8, 0x64u8, 0x0au8, 0x00u8, 0x00u8, 0x00u8]));
	let mut decompressed = &mut String::new();

	let _ = Decompressor::new(gzip_stream).read_to_string(&mut decompressed);

	assert_eq!("xxxxxyyyyy", decompressed);
}

#[test]
/// Tests distance codes being read correctly, and output bytes being appened in the right order to output buffer
fn should_decompress_abc() {
	use std::io::{ Cursor, Read };
	use compression::gzip::Decompressor;
	use compression::bitreader::BitReader;

	let gzip_stream = BitReader::new(Cursor::new(vec![0x1fu8, 0x8bu8, 0x08u8, 0x08u8, 0x31u8, 0x51u8, 0x10u8, 0x56u8, 0x00u8, 0x03u8, 0x61u8, 0x62u8, 0x63u8, 0x2eu8, 0x74u8, 0x78u8, 0x74u8, 0x00u8, 0x4bu8, 0x4cu8, 0x4au8, 0x4eu8, 0x49u8, 0x4du8, 0x4bu8, 0xcfu8, 0xc8u8, 0xccu8, 0xcau8, 0xceu8, 0xc9u8, 0xcdu8, 0xcbu8, 0x2fu8, 0x28u8, 0x2cu8, 0x2au8, 0x2eu8, 0x29u8, 0x2du8, 0x2bu8, 0xafu8, 0xa8u8, 0xacu8, 0x4au8, 0xa4u8, 0xaau8, 0x0cu8, 0x00u8, 0x20u8, 0x2du8, 0x2au8, 0x6au8, 0x68u8, 0x00u8, 0x00u8, 0x00u8]));
	let mut decompressed = &mut String::new();

	let _ = Decompressor::new(gzip_stream).read_to_string(&mut decompressed);

	assert_eq!("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz", decompressed);
}

#[test]
/// Tests file with dynamic huffman codes
fn should_decompress_abccba() {
	use std::io::{ Cursor, Read };
	use compression::gzip::Decompressor;
	use compression::bitreader::BitReader;

	let gzip_stream = BitReader::new(Cursor::new(vec![
		0x1f, 0x8b, 0x08, 0x08, 0xbf, 0x72, 0x10, 0x56, 0x00, 0x03, 0x61, 0x62, 0x63, 0x63, 0x62, 0x61,
		0x2e, 0x74, 0x78, 0x74, 0x00, 0x9d, 0xcb, 0xb7, 0x01, 0x00, 0x20, 0x08, 0x00, 0xb0, 0x5b, 0xb1,
		0x63, 0x45, 0xec, 0x5e, 0xef, 0x0f, 0x66, 0x0f, 0x08, 0xa9, 0xb4, 0xb1, 0x0e, 0x7d, 0x88, 0x29,
		0x17, 0xaa, 0xdc, 0xfa, 0x98, 0x6b, 0x9f, 0x7b, 0xcf, 0x5e, 0x73, 0xf4, 0xc6, 0x95, 0x4a, 0x4e,
		0x31, 0x78, 0x74, 0xd6, 0x68, 0x25, 0x05, 0xc0, 0xc7, 0x79, 0x72, 0xf1, 0x8d, 0xd6, 0x68, 0x00,
		0x00, 0x00
	]));
	let mut decompressed = &mut String::new();

	let _ = Decompressor::new(gzip_stream).read_to_string(&mut decompressed);

	assert_eq!("abcdefghijklmnopqrstuvwxyzzyxwvutsrqponmlkjihgfedcbaabcdefghijklmnopqrstuvwxyzzyxwvutsrqponmlkjihgfedcba", decompressed);
}

#[test]
/// Brotli: Empty file
fn should_decompress_to_empty_string() {
	use std::io::{ Cursor, Read };
	use compression::brotli::Decompressor;
	use compression::bitreader::BitReader;

	let brotli_stream = BitReader::new(Cursor::new(vec![
		0x06
	]));

	let mut decompressed = &mut String::new();
	let _ = Decompressor::new(brotli_stream).read_to_string(&mut decompressed);

	assert_eq!("", decompressed);
}

#[test]
/// Brotli: Empty file #01
fn should_decompress_to_empty_string_01() {
	use std::io::{ Cursor, Read };
	use compression::brotli::Decompressor;
	use compression::bitreader::BitReader;

	let brotli_stream = BitReader::new(Cursor::new(vec![
		0x81, 0x01
	]));

	let mut decompressed = &mut String::new();
	let _ = Decompressor::new(brotli_stream).read_to_string(&mut decompressed);

	assert_eq!("", decompressed);
}

#[test]
#[should_panic]
fn should_reject_invalid_stream_with_trailing_non_zero_bits() {
	use std::io::{ Cursor, Read };
	use compression::brotli::Decompressor;
	use compression::bitreader::BitReader;

	let brotli_stream = BitReader::new(Cursor::new(vec![
		0xa1, 0x03,
	]));

	let mut decompressed = &mut String::new();
	let _ = Decompressor::new(brotli_stream).read_to_string(&mut decompressed);
}

#[test]
/// Brotli: Empty file #15
fn should_decompress_to_empty_string_15() {
	use std::io::{ Cursor, Read };
	use compression::brotli::Decompressor;
	use compression::bitreader::BitReader;

	let brotli_stream = BitReader::new(Cursor::new(vec![
		0x1a,
	]));

	let mut decompressed = &mut String::new();
	let _ = Decompressor::new(brotli_stream).read_to_string(&mut decompressed);

	assert_eq!("", decompressed);
}

#[test]
/// Brotli: Empty file #16
fn should_decompress_to_empty_string_16() {
	use std::io::{ Cursor, Read };
	use compression::brotli::Decompressor;
	use compression::bitreader::BitReader;

	let brotli_stream = BitReader::new(Cursor::new(vec![
		0x81, 0x16, 0x00, 0x58
	]));

	let mut decompressed = &mut String::new();
	let _ = Decompressor::new(brotli_stream).read_to_string(&mut decompressed);

	assert_eq!("", decompressed);
}

#[test]
/// Brotli: Empty file
#[should_panic(expected="Expected end-of-stream, but stream did not end")]
fn should_reject_invalid_stream_with_trailing_bytes() {
	use std::io::{ Cursor, Read };
	use compression::brotli::Decompressor;
	use compression::bitreader::BitReader;

	let brotli_stream = BitReader::new(Cursor::new(vec![
		0x1a, 0xff
	]));

	let mut decompressed = &mut String::new();
	let _ = Decompressor::new(brotli_stream).read_to_string(&mut decompressed);

	assert_eq!("", decompressed);
}

#[test]
/// Brotli: Empty file #17
fn should_decompress_to_empty_string_17() {
	use std::fs::{ File };
	use std::io::{ Read };
	use compression::brotli::Decompressor;
	use compression::bitreader::BitReader;

	let brotli_stream = BitReader::new(File::open("data/empty.compressed.17").unwrap());

	let mut decompressed = &mut String::new();
	let _ = Decompressor::new(brotli_stream).read_to_string(&mut decompressed);

	assert_eq!("", decompressed);
}

#[test]
/// Brotli: X file
fn should_decompress_to_x() {
	use std::io::{ Cursor, Read };
	use compression::brotli::Decompressor;
	use compression::bitreader::BitReader;

	let brotli_stream = BitReader::new(Cursor::new(vec![
		0x0b, 0x00, 0x80, 0x58, 0x03,
	]));

	let mut decompressed = &mut String::new();
	let _ = Decompressor::new(brotli_stream).read_to_string(&mut decompressed);

	assert_eq!("X", decompressed);
}
<|endoftext|>


<commit_before>use std::io;

use tokio_core::io::Io;

use flushed::{Flushed, flushed};
use {Buf};

/// A wrapper for full-duplex stream
pub struct IoBuf<S: Io> {
    pub in_buf: Buf,
    pub out_buf: Buf,
    socket: S,
    done: bool,
}

/// Main trait of a stream (meaning socket) with input and output buffers
///
/// This is ought to be similar to `tokio_core::Io` but with buffers
impl<S: Io> IoBuf<S> {
    /// Create a new IoBuf object with empty buffers
    pub fn new(sock: S) -> IoBuf<S> {
        IoBuf {
            in_buf: Buf::new(),
            out_buf: Buf::new(),
            socket: sock,
            done: false,
        }
    }
    /// Read a chunk of data into a buffer
    ///
    /// The data just read can then be found in `self.in_buf`.
    ///
    /// This method does just one read. Because you are ought to try parse
    /// request after every read rather than reading a lot of the data in
    /// memory.
    ///
    /// This method returns `0` when no bytes are read, both when WouldBlock
    /// occurred and when connection has been closed. You may then use
    /// `self.done()` to distinguish from these conditions.
    pub fn read(&mut self) -> Result<usize, io::Error> {
        match self.in_buf.read_from(&mut self.socket) {
            Ok(0) => {
                self.done = true;
                Ok(0)
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => Ok(0),
            result => result,
        }
    }

    /// Write data in the output buffer to actual stream
    ///
    /// You should put the data to be sent into `self.out_buf` before flush
    pub fn flush(&mut self) -> Result<(), io::Error> {
        loop {
            if self.out_buf.len() == 0 {
                break;
            }
            match self.out_buf.write_to(&mut self.socket) {
                Ok(0) => break,
                Ok(_) => continue,
                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                    break;
                }
                Err(e) => {
                    return Err(e);
                },
            }
        }
        // This probably aways does nothing, but we have to support the full
        // Io protocol
        match self.socket.flush() {
            Ok(()) => Ok(()),
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => Ok(()),
            Err(e) => Err(e),
        }
    }

    /// Returns true when connection is closed by peer
    pub fn done(&self) -> bool {
        return self.done;
    }

    /// Returns a future which resolves to this stream when output buffer is
    /// flushed
    pub fn flushed(self) -> Flushed<S> {
        flushed(self)
    }
}
<commit_msg>Suppresses `ConnectionReset` and `BrokenPipe` errors<commit_after>use std::io;

use tokio_core::io::Io;

use flushed::{Flushed, flushed};
use {Buf};

/// A wrapper for full-duplex stream
pub struct IoBuf<S: Io> {
    pub in_buf: Buf,
    pub out_buf: Buf,
    socket: S,
    done: bool,
}

/// Main trait of a stream (meaning socket) with input and output buffers
///
/// This is ought to be similar to `tokio_core::Io` but with buffers
impl<S: Io> IoBuf<S> {
    /// Create a new IoBuf object with empty buffers
    pub fn new(sock: S) -> IoBuf<S> {
        IoBuf {
            in_buf: Buf::new(),
            out_buf: Buf::new(),
            socket: sock,
            done: false,
        }
    }
    /// Read a chunk of data into a buffer
    ///
    /// The data just read can then be found in `self.in_buf`.
    ///
    /// This method does just one read. Because you are ought to try parse
    /// request after every read rather than reading a lot of the data in
    /// memory.
    ///
    /// This method returns `0` when no bytes are read, both when WouldBlock
    /// occurred and when connection has been closed. You may then use
    /// `self.done()` to distinguish from these conditions.
    pub fn read(&mut self) -> Result<usize, io::Error> {
        match self.in_buf.read_from(&mut self.socket) {
            Ok(0) => {
                self.done = true;
                Ok(0)
            }
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => Ok(0),
            Err(ref e)
                if e.kind() == io::ErrorKind::BrokenPipe ||
                   e.kind() == io::ErrorKind::ConnectionReset
            => {
                self.done = true;
                Ok(0)
            }
            result => result,
        }
    }

    /// Write data in the output buffer to actual stream
    ///
    /// You should put the data to be sent into `self.out_buf` before flush
    pub fn flush(&mut self) -> Result<(), io::Error> {
        loop {
            if self.out_buf.len() == 0 {
                break;
            }
            match self.out_buf.write_to(&mut self.socket) {
                Ok(0) => break,
                Ok(_) => continue,
                Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
                    break;
                }
                Err(ref e)
                    if e.kind() == io::ErrorKind::BrokenPipe ||
                       e.kind() == io::ErrorKind::ConnectionReset
                => {
                    self.done = true;
                    break;
                }
                Err(e) => {
                    return Err(e);
                },
            }
        }
        // This probably aways does nothing, but we have to support the full
        // Io protocol
        match self.socket.flush() {
            Ok(()) => Ok(()),
            Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => Ok(()),
            Err(ref e) if e.kind() == io::ErrorKind::BrokenPipe => {
                self.done = true;
                Ok(())
            }
            Err(e) => Err(e),
        }
    }

    /// Returns true when connection is closed by peer
    pub fn done(&self) -> bool {
        return self.done;
    }

    /// Returns a future which resolves to this stream when output buffer is
    /// flushed
    pub fn flushed(self) -> Flushed<S> {
        flushed(self)
    }
}
<|endoftext|>