2017-08-12 09:09:33 +00:00
|
|
|
|
//! Parsing the options for `FileFilter`.
|
|
|
|
|
|
2017-06-27 00:13:50 +00:00
|
|
|
|
use fs::DotFilter;
|
2017-07-24 07:34:50 +00:00
|
|
|
|
use fs::filter::{FileFilter, SortField, SortCase, IgnorePatterns};
|
2017-07-26 16:48:18 +00:00
|
|
|
|
|
|
|
|
|
use options::{flags, Misfire};
|
2017-08-05 18:11:00 +00:00
|
|
|
|
use options::parser::MatchedFlags;
|
2016-04-17 19:38:37 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl FileFilter {
|
|
|
|
|
|
2017-08-12 09:09:33 +00:00
|
|
|
|
/// Determines which of all the file filter options to use.
|
2017-08-05 18:11:00 +00:00
|
|
|
|
pub fn deduce(matches: &MatchedFlags) -> Result<FileFilter, Misfire> {
|
2016-04-17 19:38:37 +00:00
|
|
|
|
Ok(FileFilter {
|
Be stricter in strict mode
Now the code actually starts to use the Strictness flag that was added in the earlier commit! Well, the *code* doesn’t, but the tests do: the macros that create the test cases now have a parameter for which tests they should run. It’s usually ‘Both’ for both strict mode and default mode, but can be specified to only run in one, for when the results differ (usually when options override one another)
The downside to strict mode is that, now, *any* call to `matches.has` or `matches.get` could fail, because an option could have been specified twice, and this is the place where those are checked for. This makes the code a little less ergonomic in places, but that’s what the ? operator is for. The only place this has really had an effect is in `Classify::deduce`, which used to just return a boolean but can now fail.
In order to more thoroughly test the mode, some of the older parts of the code can now act more strict. For example, `TerminalColours::deduce` will now use the last-given option rather than searching for “colours” before “colors”.
Help and Version continue doing their own thing.
2017-08-09 08:21:29 +00:00
|
|
|
|
list_dirs_first: matches.has(&flags::DIRS_FIRST)?,
|
|
|
|
|
reverse: matches.has(&flags::REVERSE)?,
|
2017-03-26 16:35:50 +00:00
|
|
|
|
sort_field: SortField::deduce(matches)?,
|
2017-06-29 11:07:46 +00:00
|
|
|
|
dot_filter: DotFilter::deduce(matches)?,
|
2017-03-26 16:35:50 +00:00
|
|
|
|
ignore_patterns: IgnorePatterns::deduce(matches)?,
|
2016-04-17 19:38:37 +00:00
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-07-26 19:45:01 +00:00
|
|
|
|
const SORTS: &[&str] = &[ "name", "Name", "size", "extension",
|
|
|
|
|
"Extension", "modified", "accessed",
|
|
|
|
|
"created", "inode", "type", "none" ];
|
|
|
|
|
|
2016-04-17 19:38:37 +00:00
|
|
|
|
impl SortField {
|
|
|
|
|
|
2017-08-12 09:09:33 +00:00
|
|
|
|
/// Determines which sort field to use based on the `--sort` argument.
|
|
|
|
|
/// This argument’s value can be one of several flags, listed above.
|
|
|
|
|
/// Returns the default sort field if none is given, or `Err` if the
|
|
|
|
|
/// value doesn’t correspond to a sort field we know about.
|
2017-08-05 18:11:00 +00:00
|
|
|
|
fn deduce(matches: &MatchedFlags) -> Result<SortField, Misfire> {
|
Be stricter in strict mode
Now the code actually starts to use the Strictness flag that was added in the earlier commit! Well, the *code* doesn’t, but the tests do: the macros that create the test cases now have a parameter for which tests they should run. It’s usually ‘Both’ for both strict mode and default mode, but can be specified to only run in one, for when the results differ (usually when options override one another)
The downside to strict mode is that, now, *any* call to `matches.has` or `matches.get` could fail, because an option could have been specified twice, and this is the place where those are checked for. This makes the code a little less ergonomic in places, but that’s what the ? operator is for. The only place this has really had an effect is in `Classify::deduce`, which used to just return a boolean but can now fail.
In order to more thoroughly test the mode, some of the older parts of the code can now act more strict. For example, `TerminalColours::deduce` will now use the last-given option rather than searching for “colours” before “colors”.
Help and Version continue doing their own thing.
2017-08-09 08:21:29 +00:00
|
|
|
|
let word = match matches.get(&flags::SORT)? {
|
2017-07-26 16:48:18 +00:00
|
|
|
|
Some(w) => w,
|
|
|
|
|
None => return Ok(SortField::default()),
|
|
|
|
|
};
|
|
|
|
|
|
2017-08-12 09:09:33 +00:00
|
|
|
|
// The field is an OsStr, so can’t be matched.
|
2017-07-26 16:48:18 +00:00
|
|
|
|
if word == "name" || word == "filename" {
|
2017-08-20 16:33:39 +00:00
|
|
|
|
Ok(SortField::Name(SortCase::AaBbCc))
|
2017-07-26 16:48:18 +00:00
|
|
|
|
}
|
|
|
|
|
else if word == "Name" || word == "Filename" {
|
2017-08-20 16:33:39 +00:00
|
|
|
|
Ok(SortField::Name(SortCase::ABCabc))
|
2017-07-26 16:48:18 +00:00
|
|
|
|
}
|
|
|
|
|
else if word == "size" || word == "filesize" {
|
|
|
|
|
Ok(SortField::Size)
|
|
|
|
|
}
|
|
|
|
|
else if word == "ext" || word == "extension" {
|
2017-08-20 16:33:39 +00:00
|
|
|
|
Ok(SortField::Extension(SortCase::AaBbCc))
|
2017-07-26 16:48:18 +00:00
|
|
|
|
}
|
|
|
|
|
else if word == "Ext" || word == "Extension" {
|
2017-08-20 16:33:39 +00:00
|
|
|
|
Ok(SortField::Extension(SortCase::ABCabc))
|
2017-07-26 16:48:18 +00:00
|
|
|
|
}
|
|
|
|
|
else if word == "mod" || word == "modified" {
|
|
|
|
|
Ok(SortField::ModifiedDate)
|
|
|
|
|
}
|
|
|
|
|
else if word == "acc" || word == "accessed" {
|
|
|
|
|
Ok(SortField::AccessedDate)
|
|
|
|
|
}
|
|
|
|
|
else if word == "cr" || word == "created" {
|
|
|
|
|
Ok(SortField::CreatedDate)
|
|
|
|
|
}
|
|
|
|
|
else if word == "inode" {
|
|
|
|
|
Ok(SortField::FileInode)
|
|
|
|
|
}
|
|
|
|
|
else if word == "type" {
|
|
|
|
|
Ok(SortField::FileType)
|
|
|
|
|
}
|
|
|
|
|
else if word == "none" {
|
|
|
|
|
Ok(SortField::Unsorted)
|
2016-04-17 19:38:37 +00:00
|
|
|
|
}
|
|
|
|
|
else {
|
2017-07-26 16:48:18 +00:00
|
|
|
|
Err(Misfire::bad_argument(&flags::SORT, word, SORTS))
|
2016-04-17 19:38:37 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-10-30 14:43:33 +00:00
|
|
|
|
|
2017-08-20 16:33:39 +00:00
|
|
|
|
// I’ve gone back and forth between whether to sort case-sensitively or
|
|
|
|
|
// insensitively by default. The default string sort in most programming
|
|
|
|
|
// languages takes each character’s ASCII value into account, sorting
|
|
|
|
|
// “Documents” before “apps”, but there’s usually an option to ignore
|
|
|
|
|
// characters’ case, putting “apps” before “Documents”.
|
|
|
|
|
//
|
|
|
|
|
// The argument for following case is that it’s easy to forget whether an item
|
|
|
|
|
// begins with an uppercase or lowercase letter and end up having to scan both
|
|
|
|
|
// the uppercase and lowercase sub-lists to find the item you want. If you
|
|
|
|
|
// happen to pick the sublist it’s not in, it looks like it’s missing, which
|
|
|
|
|
// is worse than if you just take longer to find it.
|
|
|
|
|
// (https://ux.stackexchange.com/a/79266)
|
|
|
|
|
//
|
|
|
|
|
// The argument for ignoring case is that it makes exa sort files differently
|
|
|
|
|
// from shells. A user would expect a directory’s files to be in the same
|
|
|
|
|
// order if they used “exa ~/directory” or “exa ~/directory/*”, but exa sorts
|
|
|
|
|
// them in the first case, and the shell in the second case, so they wouldn’t
|
|
|
|
|
// be exactly the same if exa does something non-conventional.
|
|
|
|
|
//
|
|
|
|
|
// However, exa already sorts files differently: it uses natural sorting from
|
|
|
|
|
// the natord crate, sorting the string “2” before “10” because the number’s
|
|
|
|
|
// smaller, because that’s usually what the user expects to happen. Users will
|
|
|
|
|
// name their files with numbers expecting them to be treated like numbers,
|
|
|
|
|
// rather than lists of numeric characters.
|
|
|
|
|
//
|
|
|
|
|
// In the same way, users will name their files with letters expecting the
|
|
|
|
|
// order of the letters to matter, rather than each letter’s character’s ASCII
|
|
|
|
|
// value. So exa breaks from tradition and ignores case while sorting:
|
|
|
|
|
// “apps” first, then “Documents”.
|
|
|
|
|
//
|
|
|
|
|
// You can get the old behaviour back by sorting with `--sort=Name`.
|
|
|
|
|
|
2017-08-12 09:09:33 +00:00
|
|
|
|
impl Default for SortField {
|
|
|
|
|
fn default() -> SortField {
|
2017-08-20 16:33:39 +00:00
|
|
|
|
SortField::Name(SortCase::AaBbCc)
|
2017-08-12 09:09:33 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-30 14:43:33 +00:00
|
|
|
|
|
2017-06-26 22:28:10 +00:00
|
|
|
|
impl DotFilter {
|
2017-08-12 09:09:33 +00:00
|
|
|
|
|
|
|
|
|
/// Determines the dot filter based on how many `--all` options were
|
|
|
|
|
/// given: one will show dotfiles, but two will show `.` and `..` too.
|
|
|
|
|
///
|
|
|
|
|
/// It also checks for the `--tree` option in strict mode, because of a
|
2017-08-20 16:33:39 +00:00
|
|
|
|
/// special case where `--tree --all --all` won’t work: listing the
|
2017-08-12 09:09:33 +00:00
|
|
|
|
/// parent directory in tree mode would loop onto itself!
|
2017-08-05 18:11:00 +00:00
|
|
|
|
pub fn deduce(matches: &MatchedFlags) -> Result<DotFilter, Misfire> {
|
Be stricter in strict mode
Now the code actually starts to use the Strictness flag that was added in the earlier commit! Well, the *code* doesn’t, but the tests do: the macros that create the test cases now have a parameter for which tests they should run. It’s usually ‘Both’ for both strict mode and default mode, but can be specified to only run in one, for when the results differ (usually when options override one another)
The downside to strict mode is that, now, *any* call to `matches.has` or `matches.get` could fail, because an option could have been specified twice, and this is the place where those are checked for. This makes the code a little less ergonomic in places, but that’s what the ? operator is for. The only place this has really had an effect is in `Classify::deduce`, which used to just return a boolean but can now fail.
In order to more thoroughly test the mode, some of the older parts of the code can now act more strict. For example, `TerminalColours::deduce` will now use the last-given option rather than searching for “colours” before “colors”.
Help and Version continue doing their own thing.
2017-08-09 08:21:29 +00:00
|
|
|
|
let count = matches.count(&flags::ALL);
|
|
|
|
|
|
|
|
|
|
if count == 0 {
|
|
|
|
|
Ok(DotFilter::JustFiles)
|
|
|
|
|
}
|
|
|
|
|
else if count == 1 {
|
|
|
|
|
Ok(DotFilter::Dotfiles)
|
|
|
|
|
}
|
|
|
|
|
else if matches.count(&flags::TREE) > 0 {
|
|
|
|
|
Err(Misfire::TreeAllAll)
|
|
|
|
|
}
|
|
|
|
|
else if count >= 3 && matches.is_strict() {
|
|
|
|
|
Err(Misfire::Conflict(&flags::ALL, &flags::ALL))
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
Ok(DotFilter::DotfilesAndDots)
|
2017-06-26 22:48:55 +00:00
|
|
|
|
}
|
2017-06-26 22:28:10 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2016-10-30 14:43:33 +00:00
|
|
|
|
impl IgnorePatterns {
|
2017-07-24 07:34:50 +00:00
|
|
|
|
|
2017-08-12 09:09:33 +00:00
|
|
|
|
/// Determines the set of glob patterns to use based on the
|
|
|
|
|
/// `--ignore-patterns` argument’s value. This is a list of strings
|
|
|
|
|
/// separated by pipe (`|`) characters, given in any order.
|
2017-08-05 18:11:00 +00:00
|
|
|
|
pub fn deduce(matches: &MatchedFlags) -> Result<IgnorePatterns, Misfire> {
|
2016-10-30 14:43:33 +00:00
|
|
|
|
|
2017-08-12 09:09:33 +00:00
|
|
|
|
// If there are no inputs, we return a set of patterns that doesn’t
|
|
|
|
|
// match anything, rather than, say, `None`.
|
Be stricter in strict mode
Now the code actually starts to use the Strictness flag that was added in the earlier commit! Well, the *code* doesn’t, but the tests do: the macros that create the test cases now have a parameter for which tests they should run. It’s usually ‘Both’ for both strict mode and default mode, but can be specified to only run in one, for when the results differ (usually when options override one another)
The downside to strict mode is that, now, *any* call to `matches.has` or `matches.get` could fail, because an option could have been specified twice, and this is the place where those are checked for. This makes the code a little less ergonomic in places, but that’s what the ? operator is for. The only place this has really had an effect is in `Classify::deduce`, which used to just return a boolean but can now fail.
In order to more thoroughly test the mode, some of the older parts of the code can now act more strict. For example, `TerminalColours::deduce` will now use the last-given option rather than searching for “colours” before “colors”.
Help and Version continue doing their own thing.
2017-08-09 08:21:29 +00:00
|
|
|
|
let inputs = match matches.get(&flags::IGNORE_GLOB)? {
|
2017-08-07 08:16:56 +00:00
|
|
|
|
None => return Ok(IgnorePatterns::empty()),
|
|
|
|
|
Some(is) => is,
|
|
|
|
|
};
|
|
|
|
|
|
2017-08-12 09:09:33 +00:00
|
|
|
|
// Awkwardly, though, a glob pattern can be invalid, and we need to
|
|
|
|
|
// deal with invalid patterns somehow.
|
2017-08-07 08:16:56 +00:00
|
|
|
|
let (patterns, mut errors) = IgnorePatterns::parse_from_iter(inputs.to_string_lossy().split('|'));
|
2017-07-26 16:48:18 +00:00
|
|
|
|
|
2017-08-07 08:16:56 +00:00
|
|
|
|
// It can actually return more than one glob error,
|
2017-08-12 09:09:33 +00:00
|
|
|
|
// but we only use one. (TODO)
|
|
|
|
|
match errors.pop() {
|
|
|
|
|
Some(e) => Err(e.into()),
|
|
|
|
|
None => Ok(patterns),
|
2017-08-07 08:16:56 +00:00
|
|
|
|
}
|
2016-10-30 14:43:33 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2017-07-26 19:45:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod test {
|
|
|
|
|
use super::*;
|
|
|
|
|
use std::ffi::OsString;
|
|
|
|
|
use options::flags;
|
Be stricter in strict mode
Now the code actually starts to use the Strictness flag that was added in the earlier commit! Well, the *code* doesn’t, but the tests do: the macros that create the test cases now have a parameter for which tests they should run. It’s usually ‘Both’ for both strict mode and default mode, but can be specified to only run in one, for when the results differ (usually when options override one another)
The downside to strict mode is that, now, *any* call to `matches.has` or `matches.get` could fail, because an option could have been specified twice, and this is the place where those are checked for. This makes the code a little less ergonomic in places, but that’s what the ? operator is for. The only place this has really had an effect is in `Classify::deduce`, which used to just return a boolean but can now fail.
In order to more thoroughly test the mode, some of the older parts of the code can now act more strict. For example, `TerminalColours::deduce` will now use the last-given option rather than searching for “colours” before “colors”.
Help and Version continue doing their own thing.
2017-08-09 08:21:29 +00:00
|
|
|
|
use options::parser::Flag;
|
2017-07-26 19:45:01 +00:00
|
|
|
|
|
|
|
|
|
pub fn os(input: &'static str) -> OsString {
|
|
|
|
|
let mut os = OsString::new();
|
|
|
|
|
os.push(input);
|
|
|
|
|
os
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
macro_rules! test {
|
Be stricter in strict mode
Now the code actually starts to use the Strictness flag that was added in the earlier commit! Well, the *code* doesn’t, but the tests do: the macros that create the test cases now have a parameter for which tests they should run. It’s usually ‘Both’ for both strict mode and default mode, but can be specified to only run in one, for when the results differ (usually when options override one another)
The downside to strict mode is that, now, *any* call to `matches.has` or `matches.get` could fail, because an option could have been specified twice, and this is the place where those are checked for. This makes the code a little less ergonomic in places, but that’s what the ? operator is for. The only place this has really had an effect is in `Classify::deduce`, which used to just return a boolean but can now fail.
In order to more thoroughly test the mode, some of the older parts of the code can now act more strict. For example, `TerminalColours::deduce` will now use the last-given option rather than searching for “colours” before “colors”.
Help and Version continue doing their own thing.
2017-08-09 08:21:29 +00:00
|
|
|
|
($name:ident: $type:ident <- $inputs:expr; $stricts:expr => $result:expr) => {
|
2017-07-26 19:45:01 +00:00
|
|
|
|
#[test]
|
|
|
|
|
fn $name() {
|
2017-08-08 08:18:17 +00:00
|
|
|
|
use options::parser::Arg;
|
2017-08-09 12:36:06 +00:00
|
|
|
|
use options::test::parse_for_test;
|
2017-08-08 08:18:17 +00:00
|
|
|
|
use options::test::Strictnesses::*;
|
2017-07-26 19:45:01 +00:00
|
|
|
|
|
2017-07-26 20:29:49 +00:00
|
|
|
|
static TEST_ARGS: &[&Arg] = &[ &flags::SORT, &flags::ALL, &flags::TREE, &flags::IGNORE_GLOB ];
|
2017-08-09 12:36:06 +00:00
|
|
|
|
for result in parse_for_test($inputs.as_ref(), TEST_ARGS, $stricts, |mf| $type::deduce(mf)) {
|
|
|
|
|
assert_eq!(result, $result);
|
|
|
|
|
}
|
2017-07-26 19:45:01 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mod sort_fields {
|
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
|
|
// Default behaviour
|
Be stricter in strict mode
Now the code actually starts to use the Strictness flag that was added in the earlier commit! Well, the *code* doesn’t, but the tests do: the macros that create the test cases now have a parameter for which tests they should run. It’s usually ‘Both’ for both strict mode and default mode, but can be specified to only run in one, for when the results differ (usually when options override one another)
The downside to strict mode is that, now, *any* call to `matches.has` or `matches.get` could fail, because an option could have been specified twice, and this is the place where those are checked for. This makes the code a little less ergonomic in places, but that’s what the ? operator is for. The only place this has really had an effect is in `Classify::deduce`, which used to just return a boolean but can now fail.
In order to more thoroughly test the mode, some of the older parts of the code can now act more strict. For example, `TerminalColours::deduce` will now use the last-given option rather than searching for “colours” before “colors”.
Help and Version continue doing their own thing.
2017-08-09 08:21:29 +00:00
|
|
|
|
test!(empty: SortField <- []; Both => Ok(SortField::default()));
|
2017-07-26 19:45:01 +00:00
|
|
|
|
|
|
|
|
|
// Sort field arguments
|
Be stricter in strict mode
Now the code actually starts to use the Strictness flag that was added in the earlier commit! Well, the *code* doesn’t, but the tests do: the macros that create the test cases now have a parameter for which tests they should run. It’s usually ‘Both’ for both strict mode and default mode, but can be specified to only run in one, for when the results differ (usually when options override one another)
The downside to strict mode is that, now, *any* call to `matches.has` or `matches.get` could fail, because an option could have been specified twice, and this is the place where those are checked for. This makes the code a little less ergonomic in places, but that’s what the ? operator is for. The only place this has really had an effect is in `Classify::deduce`, which used to just return a boolean but can now fail.
In order to more thoroughly test the mode, some of the older parts of the code can now act more strict. For example, `TerminalColours::deduce` will now use the last-given option rather than searching for “colours” before “colors”.
Help and Version continue doing their own thing.
2017-08-09 08:21:29 +00:00
|
|
|
|
test!(one_arg: SortField <- ["--sort=cr"]; Both => Ok(SortField::CreatedDate));
|
|
|
|
|
test!(one_long: SortField <- ["--sort=size"]; Both => Ok(SortField::Size));
|
|
|
|
|
test!(one_short: SortField <- ["-saccessed"]; Both => Ok(SortField::AccessedDate));
|
2017-08-20 16:33:39 +00:00
|
|
|
|
test!(lowercase: SortField <- ["--sort", "name"]; Both => Ok(SortField::Name(SortCase::AaBbCc)));
|
|
|
|
|
test!(uppercase: SortField <- ["--sort", "Name"]; Both => Ok(SortField::Name(SortCase::ABCabc)));
|
2017-07-26 19:45:01 +00:00
|
|
|
|
|
|
|
|
|
// Errors
|
Be stricter in strict mode
Now the code actually starts to use the Strictness flag that was added in the earlier commit! Well, the *code* doesn’t, but the tests do: the macros that create the test cases now have a parameter for which tests they should run. It’s usually ‘Both’ for both strict mode and default mode, but can be specified to only run in one, for when the results differ (usually when options override one another)
The downside to strict mode is that, now, *any* call to `matches.has` or `matches.get` could fail, because an option could have been specified twice, and this is the place where those are checked for. This makes the code a little less ergonomic in places, but that’s what the ? operator is for. The only place this has really had an effect is in `Classify::deduce`, which used to just return a boolean but can now fail.
In order to more thoroughly test the mode, some of the older parts of the code can now act more strict. For example, `TerminalColours::deduce` will now use the last-given option rather than searching for “colours” before “colors”.
Help and Version continue doing their own thing.
2017-08-09 08:21:29 +00:00
|
|
|
|
test!(error: SortField <- ["--sort=colour"]; Both => Err(Misfire::bad_argument(&flags::SORT, &os("colour"), super::SORTS)));
|
2017-07-26 19:45:01 +00:00
|
|
|
|
|
|
|
|
|
// Overriding
|
Be stricter in strict mode
Now the code actually starts to use the Strictness flag that was added in the earlier commit! Well, the *code* doesn’t, but the tests do: the macros that create the test cases now have a parameter for which tests they should run. It’s usually ‘Both’ for both strict mode and default mode, but can be specified to only run in one, for when the results differ (usually when options override one another)
The downside to strict mode is that, now, *any* call to `matches.has` or `matches.get` could fail, because an option could have been specified twice, and this is the place where those are checked for. This makes the code a little less ergonomic in places, but that’s what the ? operator is for. The only place this has really had an effect is in `Classify::deduce`, which used to just return a boolean but can now fail.
In order to more thoroughly test the mode, some of the older parts of the code can now act more strict. For example, `TerminalColours::deduce` will now use the last-given option rather than searching for “colours” before “colors”.
Help and Version continue doing their own thing.
2017-08-09 08:21:29 +00:00
|
|
|
|
test!(overridden: SortField <- ["--sort=cr", "--sort", "mod"]; Last => Ok(SortField::ModifiedDate));
|
2017-08-20 16:33:39 +00:00
|
|
|
|
test!(overridden_2: SortField <- ["--sort", "none", "--sort=Extension"]; Last => Ok(SortField::Extension(SortCase::ABCabc)));
|
Be stricter in strict mode
Now the code actually starts to use the Strictness flag that was added in the earlier commit! Well, the *code* doesn’t, but the tests do: the macros that create the test cases now have a parameter for which tests they should run. It’s usually ‘Both’ for both strict mode and default mode, but can be specified to only run in one, for when the results differ (usually when options override one another)
The downside to strict mode is that, now, *any* call to `matches.has` or `matches.get` could fail, because an option could have been specified twice, and this is the place where those are checked for. This makes the code a little less ergonomic in places, but that’s what the ? operator is for. The only place this has really had an effect is in `Classify::deduce`, which used to just return a boolean but can now fail.
In order to more thoroughly test the mode, some of the older parts of the code can now act more strict. For example, `TerminalColours::deduce` will now use the last-given option rather than searching for “colours” before “colors”.
Help and Version continue doing their own thing.
2017-08-09 08:21:29 +00:00
|
|
|
|
test!(overridden_3: SortField <- ["--sort=cr", "--sort", "mod"]; Complain => Err(Misfire::Duplicate(Flag::Long("sort"), Flag::Long("sort"))));
|
|
|
|
|
test!(overridden_4: SortField <- ["--sort", "none", "--sort=Extension"]; Complain => Err(Misfire::Duplicate(Flag::Long("sort"), Flag::Long("sort"))));
|
2017-07-26 19:45:01 +00:00
|
|
|
|
}
|
2017-07-26 20:01:22 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mod dot_filters {
|
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
|
|
// Default behaviour
|
Be stricter in strict mode
Now the code actually starts to use the Strictness flag that was added in the earlier commit! Well, the *code* doesn’t, but the tests do: the macros that create the test cases now have a parameter for which tests they should run. It’s usually ‘Both’ for both strict mode and default mode, but can be specified to only run in one, for when the results differ (usually when options override one another)
The downside to strict mode is that, now, *any* call to `matches.has` or `matches.get` could fail, because an option could have been specified twice, and this is the place where those are checked for. This makes the code a little less ergonomic in places, but that’s what the ? operator is for. The only place this has really had an effect is in `Classify::deduce`, which used to just return a boolean but can now fail.
In order to more thoroughly test the mode, some of the older parts of the code can now act more strict. For example, `TerminalColours::deduce` will now use the last-given option rather than searching for “colours” before “colors”.
Help and Version continue doing their own thing.
2017-08-09 08:21:29 +00:00
|
|
|
|
test!(empty: DotFilter <- []; Both => Ok(DotFilter::JustFiles));
|
2017-07-26 20:01:22 +00:00
|
|
|
|
|
|
|
|
|
// --all
|
Be stricter in strict mode
Now the code actually starts to use the Strictness flag that was added in the earlier commit! Well, the *code* doesn’t, but the tests do: the macros that create the test cases now have a parameter for which tests they should run. It’s usually ‘Both’ for both strict mode and default mode, but can be specified to only run in one, for when the results differ (usually when options override one another)
The downside to strict mode is that, now, *any* call to `matches.has` or `matches.get` could fail, because an option could have been specified twice, and this is the place where those are checked for. This makes the code a little less ergonomic in places, but that’s what the ? operator is for. The only place this has really had an effect is in `Classify::deduce`, which used to just return a boolean but can now fail.
In order to more thoroughly test the mode, some of the older parts of the code can now act more strict. For example, `TerminalColours::deduce` will now use the last-given option rather than searching for “colours” before “colors”.
Help and Version continue doing their own thing.
2017-08-09 08:21:29 +00:00
|
|
|
|
test!(all: DotFilter <- ["--all"]; Both => Ok(DotFilter::Dotfiles));
|
|
|
|
|
test!(all_all: DotFilter <- ["--all", "-a"]; Both => Ok(DotFilter::DotfilesAndDots));
|
|
|
|
|
test!(all_all_2: DotFilter <- ["-aa"]; Both => Ok(DotFilter::DotfilesAndDots));
|
|
|
|
|
|
|
|
|
|
test!(all_all_3: DotFilter <- ["-aaa"]; Last => Ok(DotFilter::DotfilesAndDots));
|
|
|
|
|
test!(all_all_4: DotFilter <- ["-aaa"]; Complain => Err(Misfire::Conflict(&flags::ALL, &flags::ALL)));
|
2017-07-26 20:01:22 +00:00
|
|
|
|
|
|
|
|
|
// --all and --tree
|
Be stricter in strict mode
Now the code actually starts to use the Strictness flag that was added in the earlier commit! Well, the *code* doesn’t, but the tests do: the macros that create the test cases now have a parameter for which tests they should run. It’s usually ‘Both’ for both strict mode and default mode, but can be specified to only run in one, for when the results differ (usually when options override one another)
The downside to strict mode is that, now, *any* call to `matches.has` or `matches.get` could fail, because an option could have been specified twice, and this is the place where those are checked for. This makes the code a little less ergonomic in places, but that’s what the ? operator is for. The only place this has really had an effect is in `Classify::deduce`, which used to just return a boolean but can now fail.
In order to more thoroughly test the mode, some of the older parts of the code can now act more strict. For example, `TerminalColours::deduce` will now use the last-given option rather than searching for “colours” before “colors”.
Help and Version continue doing their own thing.
2017-08-09 08:21:29 +00:00
|
|
|
|
test!(tree_a: DotFilter <- ["-Ta"]; Both => Ok(DotFilter::Dotfiles));
|
|
|
|
|
test!(tree_aa: DotFilter <- ["-Taa"]; Both => Err(Misfire::TreeAllAll));
|
|
|
|
|
test!(tree_aaa: DotFilter <- ["-Taaa"]; Both => Err(Misfire::TreeAllAll));
|
2017-07-26 20:01:22 +00:00
|
|
|
|
}
|
2017-07-26 20:29:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mod ignore_patternses {
|
|
|
|
|
use super::*;
|
2017-08-07 08:16:56 +00:00
|
|
|
|
use std::iter::FromIterator;
|
2017-07-26 20:29:49 +00:00
|
|
|
|
use glob;
|
|
|
|
|
|
|
|
|
|
fn pat(string: &'static str) -> glob::Pattern {
|
|
|
|
|
glob::Pattern::new(string).unwrap()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Various numbers of globs
|
Be stricter in strict mode
Now the code actually starts to use the Strictness flag that was added in the earlier commit! Well, the *code* doesn’t, but the tests do: the macros that create the test cases now have a parameter for which tests they should run. It’s usually ‘Both’ for both strict mode and default mode, but can be specified to only run in one, for when the results differ (usually when options override one another)
The downside to strict mode is that, now, *any* call to `matches.has` or `matches.get` could fail, because an option could have been specified twice, and this is the place where those are checked for. This makes the code a little less ergonomic in places, but that’s what the ? operator is for. The only place this has really had an effect is in `Classify::deduce`, which used to just return a boolean but can now fail.
In order to more thoroughly test the mode, some of the older parts of the code can now act more strict. For example, `TerminalColours::deduce` will now use the last-given option rather than searching for “colours” before “colors”.
Help and Version continue doing their own thing.
2017-08-09 08:21:29 +00:00
|
|
|
|
test!(none: IgnorePatterns <- []; Both => Ok(IgnorePatterns::empty()));
|
|
|
|
|
test!(one: IgnorePatterns <- ["--ignore-glob", "*.ogg"]; Both => Ok(IgnorePatterns::from_iter(vec![ pat("*.ogg") ])));
|
|
|
|
|
test!(two: IgnorePatterns <- ["--ignore-glob=*.ogg|*.MP3"]; Both => Ok(IgnorePatterns::from_iter(vec![ pat("*.ogg"), pat("*.MP3") ])));
|
|
|
|
|
test!(loads: IgnorePatterns <- ["-I*|?|.|*"]; Both => Ok(IgnorePatterns::from_iter(vec![ pat("*"), pat("?"), pat("."), pat("*") ])));
|
|
|
|
|
|
|
|
|
|
// Overriding
|
|
|
|
|
test!(overridden: IgnorePatterns <- ["-I=*.ogg", "-I", "*.mp3"]; Last => Ok(IgnorePatterns::from_iter(vec![ pat("*.mp3") ])));
|
|
|
|
|
test!(overridden_2: IgnorePatterns <- ["-I", "*.OGG", "-I*.MP3"]; Last => Ok(IgnorePatterns::from_iter(vec![ pat("*.MP3") ])));
|
|
|
|
|
test!(overridden_3: IgnorePatterns <- ["-I=*.ogg", "-I", "*.mp3"]; Complain => Err(Misfire::Duplicate(Flag::Short(b'I'), Flag::Short(b'I'))));
|
|
|
|
|
test!(overridden_4: IgnorePatterns <- ["-I", "*.OGG", "-I*.MP3"]; Complain => Err(Misfire::Duplicate(Flag::Short(b'I'), Flag::Short(b'I'))));
|
2017-07-26 20:29:49 +00:00
|
|
|
|
}
|
2017-07-26 19:45:01 +00:00
|
|
|
|
}
|