// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. // ignore-windows TempDir may cause IoError on windows: #10462 #![cfg_attr(test, deny(warnings))] extern crate capturing_glob as glob; extern crate tempdir; use glob::glob; use std::env; use std::path::PathBuf; use std::fs; use tempdir::TempDir; #[test] fn main() { fn mk_file(path: &str, directory: bool) { if directory { fs::create_dir(path).unwrap(); } else { fs::File::create(path).unwrap(); } } fn glob_vec(pattern: &str) -> Vec { glob(pattern).unwrap().map(|r| r.unwrap().into()).collect() } let root = TempDir::new("glob-tests"); let root = root.ok().expect("Should have created a temp directory"); assert!(env::set_current_dir(root.path()).is_ok()); mk_file("aaa", true); mk_file("aaa/apple", true); mk_file("aaa/orange", true); mk_file("aaa/tomato", true); mk_file("aaa/tomato/tomato.txt", false); mk_file("aaa/tomato/tomoto.txt", false); mk_file("bbb", true); mk_file("bbb/specials", true); mk_file("bbb/specials/!", false); // windows does not allow `*` or `?` characters to exist in filenames if env::consts::FAMILY != "windows" { mk_file("bbb/specials/*", false); mk_file("bbb/specials/?", false); } mk_file("bbb/specials/[", false); mk_file("bbb/specials/]", false); mk_file("ccc", true); mk_file("xyz", true); mk_file("xyz/x", false); mk_file("xyz/y", false); mk_file("xyz/z", false); mk_file("r", true); mk_file("r/current_dir.md", false); mk_file("r/one", true); mk_file("r/one/a.md", false); mk_file("r/one/another", true); mk_file("r/one/another/a.md", false); mk_file("r/one/another/deep", true); mk_file("r/one/another/deep/spelunking.md", false); mk_file("r/another", true); mk_file("r/another/a.md", false); mk_file("r/two", true); mk_file("r/two/b.md", false); mk_file("r/three", true); mk_file("r/three/c.md", false); // all recursive entities assert_eq!(glob_vec("r/**"), vec!( PathBuf::from("r/another"), PathBuf::from("r/one"), PathBuf::from("r/one/another"), PathBuf::from("r/one/another/deep"), PathBuf::from("r/three"), PathBuf::from("r/two"))); // collapse consecutive recursive patterns assert_eq!(glob_vec("r/**/**"), vec!( PathBuf::from("r/another"), PathBuf::from("r/one"), PathBuf::from("r/one/another"), PathBuf::from("r/one/another/deep"), PathBuf::from("r/three"), PathBuf::from("r/two"))); assert_eq!(glob_vec("r/**/*"), vec!( PathBuf::from("r/another"), PathBuf::from("r/another/a.md"), PathBuf::from("r/current_dir.md"), PathBuf::from("r/one"), PathBuf::from("r/one/a.md"), PathBuf::from("r/one/another"), PathBuf::from("r/one/another/a.md"), PathBuf::from("r/one/another/deep"), PathBuf::from("r/one/another/deep/spelunking.md"), PathBuf::from("r/three"), PathBuf::from("r/three/c.md"), PathBuf::from("r/two"), PathBuf::from("r/two/b.md"))); // followed by a wildcard assert_eq!(glob_vec("r/**/*.md"), vec!( PathBuf::from("r/another/a.md"), PathBuf::from("r/current_dir.md"), PathBuf::from("r/one/a.md"), PathBuf::from("r/one/another/a.md"), PathBuf::from("r/one/another/deep/spelunking.md"), PathBuf::from("r/three/c.md"), PathBuf::from("r/two/b.md"))); // followed by a precise pattern assert_eq!(glob_vec("r/one/**/a.md"), vec!( PathBuf::from("r/one/a.md"), PathBuf::from("r/one/another/a.md"))); // followed by another recursive pattern // collapses consecutive recursives into one assert_eq!(glob_vec("r/one/**/**/a.md"), vec!( PathBuf::from("r/one/a.md"), PathBuf::from("r/one/another/a.md"))); // followed by two precise patterns assert_eq!(glob_vec("r/**/another/a.md"), vec!( PathBuf::from("r/another/a.md"), PathBuf::from("r/one/another/a.md"))); assert_eq!(glob_vec(""), Vec::::new()); assert_eq!(glob_vec("."), vec!(PathBuf::from("."))); assert_eq!(glob_vec(".."), vec!(PathBuf::from(".."))); assert_eq!(glob_vec("aaa"), vec!(PathBuf::from("aaa"))); assert_eq!(glob_vec("aaa/"), vec!(PathBuf::from("aaa"))); assert_eq!(glob_vec("a"), Vec::::new()); assert_eq!(glob_vec("aa"), Vec::::new()); assert_eq!(glob_vec("aaaa"), Vec::::new()); assert_eq!(glob_vec("aaa/apple"), vec!(PathBuf::from("aaa/apple"))); assert_eq!(glob_vec("aaa/apple/nope"), Vec::::new()); // windows should support both / and \ as directory separators if env::consts::FAMILY == "windows" { assert_eq!(glob_vec("aaa\\apple"), vec!(PathBuf::from("aaa/apple"))); } assert_eq!(glob_vec("???/"), vec!( PathBuf::from("aaa"), PathBuf::from("bbb"), PathBuf::from("ccc"), PathBuf::from("xyz"))); assert_eq!(glob_vec("aaa/tomato/tom?to.txt"), vec!( PathBuf::from("aaa/tomato/tomato.txt"), PathBuf::from("aaa/tomato/tomoto.txt"))); assert_eq!(glob_vec("xyz/?"), vec!( PathBuf::from("xyz/x"), PathBuf::from("xyz/y"), PathBuf::from("xyz/z"))); assert_eq!(glob_vec("a*"), vec!(PathBuf::from("aaa"))); assert_eq!(glob_vec("*a*"), vec!(PathBuf::from("aaa"))); assert_eq!(glob_vec("a*a"), vec!(PathBuf::from("aaa"))); assert_eq!(glob_vec("aaa*"), vec!(PathBuf::from("aaa"))); assert_eq!(glob_vec("*aaa"), vec!(PathBuf::from("aaa"))); assert_eq!(glob_vec("*aaa*"), vec!(PathBuf::from("aaa"))); assert_eq!(glob_vec("*a*a*a*"), vec!(PathBuf::from("aaa"))); assert_eq!(glob_vec("aaa*/"), vec!(PathBuf::from("aaa"))); assert_eq!(glob_vec("aaa/*"), vec!( PathBuf::from("aaa/apple"), PathBuf::from("aaa/orange"), PathBuf::from("aaa/tomato"))); assert_eq!(glob_vec("aaa/*a*"), vec!( PathBuf::from("aaa/apple"), PathBuf::from("aaa/orange"), PathBuf::from("aaa/tomato"))); assert_eq!(glob_vec("*/*/*.txt"), vec!( PathBuf::from("aaa/tomato/tomato.txt"), PathBuf::from("aaa/tomato/tomoto.txt"))); assert_eq!(glob_vec("*/*/t[aob]m?to[.]t[!y]t"), vec!( PathBuf::from("aaa/tomato/tomato.txt"), PathBuf::from("aaa/tomato/tomoto.txt"))); assert_eq!(glob_vec("./aaa"), vec!(PathBuf::from("aaa"))); assert_eq!(glob_vec("./*"), glob_vec("*")); assert_eq!(glob_vec("*/..").pop().unwrap(), PathBuf::from("xyz/..")); assert_eq!(glob_vec("aaa/../bbb"), vec!(PathBuf::from("aaa/../bbb"))); assert_eq!(glob_vec("nonexistent/../bbb"), Vec::::new()); assert_eq!(glob_vec("aaa/tomato/tomato.txt/.."), Vec::::new()); assert_eq!(glob_vec("aaa/tomato/tomato.txt/"), Vec::::new()); assert_eq!(glob_vec("aa[a]"), vec!(PathBuf::from("aaa"))); assert_eq!(glob_vec("aa[abc]"), vec!(PathBuf::from("aaa"))); assert_eq!(glob_vec("a[bca]a"), vec!(PathBuf::from("aaa"))); assert_eq!(glob_vec("aa[b]"), Vec::::new()); assert_eq!(glob_vec("aa[xyz]"), Vec::::new()); assert_eq!(glob_vec("aa[]]"), Vec::::new()); assert_eq!(glob_vec("aa[!b]"), vec!(PathBuf::from("aaa"))); assert_eq!(glob_vec("aa[!bcd]"), vec!(PathBuf::from("aaa"))); assert_eq!(glob_vec("a[!bcd]a"), vec!(PathBuf::from("aaa"))); assert_eq!(glob_vec("aa[!a]"), Vec::::new()); assert_eq!(glob_vec("aa[!abc]"), Vec::::new()); assert_eq!(glob_vec("bbb/specials/[[]"), vec!(PathBuf::from("bbb/specials/["))); assert_eq!(glob_vec("bbb/specials/!"), vec!(PathBuf::from("bbb/specials/!"))); assert_eq!(glob_vec("bbb/specials/[]]"), vec!(PathBuf::from("bbb/specials/]"))); if env::consts::FAMILY != "windows" { assert_eq!(glob_vec("bbb/specials/[*]"), vec!(PathBuf::from("bbb/specials/*"))); assert_eq!(glob_vec("bbb/specials/[?]"), vec!(PathBuf::from("bbb/specials/?"))); } if env::consts::FAMILY == "windows" { assert_eq!(glob_vec("bbb/specials/[![]"), vec!( PathBuf::from("bbb/specials/!"), PathBuf::from("bbb/specials/]"))); assert_eq!(glob_vec("bbb/specials/[!]]"), vec!( PathBuf::from("bbb/specials/!"), PathBuf::from("bbb/specials/["))); assert_eq!(glob_vec("bbb/specials/[!!]"), vec!( PathBuf::from("bbb/specials/["), PathBuf::from("bbb/specials/]"))); } else { assert_eq!(glob_vec("bbb/specials/[![]"), vec!( PathBuf::from("bbb/specials/!"), PathBuf::from("bbb/specials/*"), PathBuf::from("bbb/specials/?"), PathBuf::from("bbb/specials/]"))); assert_eq!(glob_vec("bbb/specials/[!]]"), vec!( PathBuf::from("bbb/specials/!"), PathBuf::from("bbb/specials/*"), PathBuf::from("bbb/specials/?"), PathBuf::from("bbb/specials/["))); assert_eq!(glob_vec("bbb/specials/[!!]"), vec!( PathBuf::from("bbb/specials/*"), PathBuf::from("bbb/specials/?"), PathBuf::from("bbb/specials/["), PathBuf::from("bbb/specials/]"))); assert_eq!(glob_vec("bbb/specials/[!*]"), vec!( PathBuf::from("bbb/specials/!"), PathBuf::from("bbb/specials/?"), PathBuf::from("bbb/specials/["), PathBuf::from("bbb/specials/]"))); assert_eq!(glob_vec("bbb/specials/[!?]"), vec!( PathBuf::from("bbb/specials/!"), PathBuf::from("bbb/specials/*"), PathBuf::from("bbb/specials/["), PathBuf::from("bbb/specials/]"))); } }