1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

test: add -N FILE exists and has been modified since it was last read

Upstream: tests/misc/test-N.sh
This commit is contained in:
Sylvestre Ledru 2022-09-25 03:33:36 +02:00
parent 043c009a41
commit 63203a0a68
3 changed files with 21 additions and 3 deletions

View file

@ -55,8 +55,8 @@ impl Symbol {
"-eq" | "-ge" | "-gt" | "-le" | "-lt" | "-ne" => Self::Op(Operator::Int(s)), "-eq" | "-ge" | "-gt" | "-le" | "-lt" | "-ne" => Self::Op(Operator::Int(s)),
"-ef" | "-nt" | "-ot" => Self::Op(Operator::File(s)), "-ef" | "-nt" | "-ot" => Self::Op(Operator::File(s)),
"-n" | "-z" => Self::UnaryOp(UnaryOperator::StrlenOp(s)), "-n" | "-z" => Self::UnaryOp(UnaryOperator::StrlenOp(s)),
"-b" | "-c" | "-d" | "-e" | "-f" | "-g" | "-G" | "-h" | "-k" | "-L" | "-O" "-b" | "-c" | "-d" | "-e" | "-f" | "-g" | "-G" | "-h" | "-k" | "-L" | "-N"
| "-p" | "-r" | "-s" | "-S" | "-t" | "-u" | "-w" | "-x" => { | "-O" | "-p" | "-r" | "-s" | "-S" | "-t" | "-u" | "-w" | "-x" => {
Self::UnaryOp(UnaryOperator::FiletestOp(s)) Self::UnaryOp(UnaryOperator::FiletestOp(s))
} }
_ => Self::Literal(s), _ => Self::Literal(s),
@ -108,7 +108,7 @@ impl Symbol {
/// INTOP → -eq | -ge | -gt | -le | -lt | -ne /// INTOP → -eq | -ge | -gt | -le | -lt | -ne
/// FILEOP → -ef | -nt | -ot /// FILEOP → -ef | -nt | -ot
/// STRLEN → -n | -z /// STRLEN → -n | -z
/// FILETEST → -b | -c | -d | -e | -f | -g | -G | -h | -k | -L | -O | -p | /// FILETEST → -b | -c | -d | -e | -f | -g | -G | -h | -k | -L | -N | -O | -p |
/// -r | -s | -S | -t | -u | -w | -x /// -r | -s | -S | -t | -u | -w | -x
/// BOOLOP → -a | -o /// BOOLOP → -a | -o
/// ///

View file

@ -205,6 +205,7 @@ fn eval(stack: &mut Vec<Symbol>) -> Result<bool, String> {
"-h" => path(&f, &PathCondition::SymLink), "-h" => path(&f, &PathCondition::SymLink),
"-k" => path(&f, &PathCondition::Sticky), "-k" => path(&f, &PathCondition::Sticky),
"-L" => path(&f, &PathCondition::SymLink), "-L" => path(&f, &PathCondition::SymLink),
"-N" => path(&f, &PathCondition::ExistsModifiedLastRead),
"-O" => path(&f, &PathCondition::UserOwns), "-O" => path(&f, &PathCondition::UserOwns),
"-p" => path(&f, &PathCondition::Fifo), "-p" => path(&f, &PathCondition::Fifo),
"-r" => path(&f, &PathCondition::Readable), "-r" => path(&f, &PathCondition::Readable),
@ -273,6 +274,7 @@ enum PathCondition {
CharacterSpecial, CharacterSpecial,
Directory, Directory,
Exists, Exists,
ExistsModifiedLastRead,
Regular, Regular,
GroupIdFlag, GroupIdFlag,
GroupOwns, GroupOwns,
@ -351,6 +353,9 @@ fn path(path: &OsStr, condition: &PathCondition) -> bool {
PathCondition::CharacterSpecial => file_type.is_char_device(), PathCondition::CharacterSpecial => file_type.is_char_device(),
PathCondition::Directory => file_type.is_dir(), PathCondition::Directory => file_type.is_dir(),
PathCondition::Exists => true, PathCondition::Exists => true,
PathCondition::ExistsModifiedLastRead => {
metadata.accessed().unwrap() < metadata.modified().unwrap()
}
PathCondition::Regular => file_type.is_file(), PathCondition::Regular => file_type.is_file(),
PathCondition::GroupIdFlag => metadata.mode() & S_ISGID != 0, PathCondition::GroupIdFlag => metadata.mode() & S_ISGID != 0,
PathCondition::GroupOwns => metadata.gid() == getegid(), PathCondition::GroupOwns => metadata.gid() == getegid(),

View file

@ -882,3 +882,16 @@ fn test_bracket_syntax_version() {
.succeeds() .succeeds()
.stdout_matches(&r"\[ \d+\.\d+\.\d+".parse().unwrap()); .stdout_matches(&r"\[ \d+\.\d+\.\d+".parse().unwrap());
} }
#[test]
#[allow(non_snake_case)]
fn test_file_N() {
let scene = TestScenario::new(util_name!());
let at = &scene.fixtures;
scene.ucmd().args(&["-N", "regular_file"]).fails();
// The file will have different create/modified data
// so, test -N will return 0
sleep(std::time::Duration::from_millis(1000));
at.touch("regular_file");
scene.ucmd().args(&["-N", "regular_file"]).succeeds();
}