@@ -205,24 +205,26 @@ fn integers(a: &OsStr, b: &OsStr, op: &OsStr) -> ParseResult<bool> {
205205
206206/// Operations to compare files metadata
207207/// `a` is the left hand side
208- /// `b` is the left hand side
208+ /// `b` is the right hand side
209209/// `op` the operation (ex: -ef, -nt, etc)
210210fn files ( a : & OsStr , b : & OsStr , op : & OsStr ) -> ParseResult < bool > {
211- // Don't manage the error. GNU doesn't show error when doing
212- // test foo -nt bar
213- let ( Ok ( f_a) , Ok ( f_b) ) = ( fs:: metadata ( a) , fs:: metadata ( b) ) else {
214- return Ok ( false ) ;
215- } ;
211+ let f_a = fs:: metadata ( a) ;
212+ let f_b = fs:: metadata ( b) ;
216213
217- Ok ( match op. to_str ( ) {
214+ let result = match ( op. to_str ( ) , f_a , f_b ) {
218215 #[ cfg( unix) ]
219- Some ( "-ef" ) => f_a. ino ( ) == f_b. ino ( ) && f_a. dev ( ) == f_b. dev ( ) ,
216+ ( Some ( "-ef" ) , Ok ( f_a ) , Ok ( f_b ) ) => f_a. ino ( ) == f_b. ino ( ) && f_a. dev ( ) == f_b. dev ( ) ,
220217 #[ cfg( not( unix) ) ]
221- Some ( "-ef" ) => unimplemented ! ( ) ,
222- Some ( "-nt" ) => f_a. modified ( ) . unwrap ( ) > f_b. modified ( ) . unwrap ( ) ,
223- Some ( "-ot" ) => f_a. modified ( ) . unwrap ( ) < f_b. modified ( ) . unwrap ( ) ,
224- _ => return Err ( ParseError :: UnknownOperator ( op. quote ( ) . to_string ( ) ) ) ,
225- } )
218+ ( Some ( "-ef" ) , Ok ( _) , Ok ( _) ) => unimplemented ! ( ) ,
219+ ( Some ( "-nt" ) , Ok ( f_a) , Ok ( f_b) ) => f_a. modified ( ) . unwrap ( ) > f_b. modified ( ) . unwrap ( ) ,
220+ ( Some ( "-nt" ) , Ok ( _) , _) => true ,
221+ ( Some ( "-ot" ) , Ok ( f_a) , Ok ( f_b) ) => f_a. modified ( ) . unwrap ( ) < f_b. modified ( ) . unwrap ( ) ,
222+ ( Some ( "-ot" ) , _, Ok ( _) ) => true ,
223+ ( Some ( "-ef" | "-nt" | "-ot" ) , _, _) => false ,
224+ ( _, _, _) => return Err ( ParseError :: UnknownOperator ( op. quote ( ) . to_string ( ) ) ) ,
225+ } ;
226+
227+ Ok ( result)
226228}
227229
228230fn isatty ( fd : & OsStr ) -> ParseResult < bool > {
@@ -347,8 +349,81 @@ fn path(path: &OsStr, condition: &PathCondition) -> bool {
347349
348350#[ cfg( test) ]
349351mod tests {
350- use super :: integers;
351- use std:: ffi:: OsStr ;
352+ use super :: * ;
353+ use std:: { ffi:: OsStr , time:: UNIX_EPOCH } ;
354+ use tempfile:: NamedTempFile ;
355+
356+ #[ test]
357+ fn test_files_with_unknown_op ( ) {
358+ let a = NamedTempFile :: new ( ) . unwrap ( ) ;
359+ let b = NamedTempFile :: new ( ) . unwrap ( ) ;
360+ let a = OsStr :: new ( a. path ( ) ) ;
361+ let b = OsStr :: new ( b. path ( ) ) ;
362+ let op = OsStr :: new ( "unknown_op" ) ;
363+
364+ assert ! ( files( a, b, op) . is_err( ) ) ;
365+ }
366+
367+ #[ test]
368+ #[ cfg( unix) ]
369+ fn test_files_with_ef_op ( ) {
370+ let a = NamedTempFile :: new ( ) . unwrap ( ) ;
371+ let b = NamedTempFile :: new ( ) . unwrap ( ) ;
372+ let a = OsStr :: new ( a. path ( ) ) ;
373+ let b = OsStr :: new ( b. path ( ) ) ;
374+ let op = OsStr :: new ( "-ef" ) ;
375+
376+ assert ! ( files( a, a, op) . unwrap( ) ) ;
377+ assert ! ( !files( a, b, op) . unwrap( ) ) ;
378+ assert ! ( !files( b, a, op) . unwrap( ) ) ;
379+
380+ let existing_file = a;
381+ let non_existing_file = OsStr :: new ( "non_existing_file" ) ;
382+
383+ assert ! ( !files( existing_file, non_existing_file, op) . unwrap( ) ) ;
384+ assert ! ( !files( non_existing_file, existing_file, op) . unwrap( ) ) ;
385+ assert ! ( !files( non_existing_file, non_existing_file, op) . unwrap( ) ) ;
386+ }
387+
388+ #[ test]
389+ fn test_files_with_nt_op ( ) {
390+ let older_file = NamedTempFile :: new ( ) . unwrap ( ) ;
391+ older_file. as_file ( ) . set_modified ( UNIX_EPOCH ) . unwrap ( ) ;
392+ let older_file = OsStr :: new ( older_file. path ( ) ) ;
393+ let newer_file = NamedTempFile :: new ( ) . unwrap ( ) ;
394+ let newer_file = OsStr :: new ( newer_file. path ( ) ) ;
395+ let op = OsStr :: new ( "-nt" ) ;
396+
397+ assert ! ( files( newer_file, older_file, op) . unwrap( ) ) ;
398+ assert ! ( !files( older_file, newer_file, op) . unwrap( ) ) ;
399+
400+ let existing_file = newer_file;
401+ let non_existing_file = OsStr :: new ( "non_existing_file" ) ;
402+
403+ assert ! ( files( existing_file, non_existing_file, op) . unwrap( ) ) ;
404+ assert ! ( !files( non_existing_file, existing_file, op) . unwrap( ) ) ;
405+ assert ! ( !files( non_existing_file, non_existing_file, op) . unwrap( ) ) ;
406+ }
407+
408+ #[ test]
409+ fn test_files_with_ot_op ( ) {
410+ let older_file = NamedTempFile :: new ( ) . unwrap ( ) ;
411+ older_file. as_file ( ) . set_modified ( UNIX_EPOCH ) . unwrap ( ) ;
412+ let older_file = OsStr :: new ( older_file. path ( ) ) ;
413+ let newer_file = NamedTempFile :: new ( ) . unwrap ( ) ;
414+ let newer_file = OsStr :: new ( newer_file. path ( ) ) ;
415+ let op = OsStr :: new ( "-ot" ) ;
416+
417+ assert ! ( !files( newer_file, older_file, op) . unwrap( ) ) ;
418+ assert ! ( files( older_file, newer_file, op) . unwrap( ) ) ;
419+
420+ let existing_file = newer_file;
421+ let non_existing_file = OsStr :: new ( "non_existing_file" ) ;
422+
423+ assert ! ( !files( existing_file, non_existing_file, op) . unwrap( ) ) ;
424+ assert ! ( files( non_existing_file, existing_file, op) . unwrap( ) ) ;
425+ assert ! ( !files( non_existing_file, non_existing_file, op) . unwrap( ) ) ;
426+ }
352427
353428 #[ test]
354429 fn test_integer_op ( ) {
0 commit comments