@@ -457,15 +457,19 @@ impl Drop for KqueueWatcher {
457457 }
458458}
459459
460+ #[ cfg( test) ]
460461mod tests {
461- use super :: { Config , KqueueWatcher , RecursiveMode } ;
462- use crate :: Watcher ;
463- use std:: error:: Error ;
464- use std:: path:: PathBuf ;
465- use std:: result:: Result ;
462+ use std:: time:: Duration ;
463+
464+ use super :: * ;
465+ use crate :: test:: { self , * } ;
466+
467+ fn watcher ( ) -> ( TestWatcher < KqueueWatcher > , test:: Receiver ) {
468+ channel ( )
469+ }
466470
467471 #[ test]
468- fn test_remove_recursive ( ) -> Result < ( ) , Box < dyn Error > > {
472+ fn test_remove_recursive ( ) -> std :: result :: Result < ( ) , Box < dyn std :: error :: Error > > {
469473 let path = PathBuf :: from ( "src" ) ;
470474
471475 let mut watcher = KqueueWatcher :: new ( |event| println ! ( "{:?}" , event) , Config :: default ( ) ) ?;
@@ -478,4 +482,358 @@ mod tests {
478482 ) ;
479483 Ok ( ( ) )
480484 }
485+
486+ #[ test]
487+ fn create_file ( ) {
488+ let tmpdir = testdir ( ) ;
489+ let ( mut watcher, mut rx) = watcher ( ) ;
490+ watcher. watch_recursively ( & tmpdir) ;
491+
492+ let path = tmpdir. path ( ) . join ( "entry" ) ;
493+ std:: fs:: File :: create_new ( & path) . expect ( "create" ) ;
494+
495+ rx. wait_unordered ( [ expected ( path) . create_file ( ) ] ) ;
496+ }
497+
498+ #[ test]
499+ fn write_file ( ) {
500+ let tmpdir = testdir ( ) ;
501+
502+ let path = tmpdir. path ( ) . join ( "entry" ) ;
503+ std:: fs:: File :: create_new ( & path) . expect ( "create" ) ;
504+
505+ let ( mut watcher, mut rx) = watcher ( ) ;
506+
507+ watcher. watch_recursively ( & tmpdir) ;
508+
509+ std:: fs:: write ( & path, b"123" ) . expect ( "write" ) ;
510+
511+ rx. wait_unordered ( [ expected ( & path) . modify_data_any ( ) ] ) ;
512+ }
513+
514+ #[ test]
515+ fn chmod_file ( ) {
516+ let tmpdir = testdir ( ) ;
517+ let ( mut watcher, mut rx) = watcher ( ) ;
518+
519+ let path = tmpdir. path ( ) . join ( "entry" ) ;
520+ let file = std:: fs:: File :: create_new ( & path) . expect ( "create" ) ;
521+ let mut permissions = file. metadata ( ) . expect ( "metadata" ) . permissions ( ) ;
522+ permissions. set_readonly ( true ) ;
523+
524+ watcher. watch_recursively ( & tmpdir) ;
525+ file. set_permissions ( permissions) . expect ( "set_permissions" ) ;
526+
527+ rx. wait_unordered ( [ expected ( & path) . modify_meta_any ( ) ] ) ;
528+ }
529+
530+ #[ test]
531+ fn rename_file ( ) {
532+ let tmpdir = testdir ( ) ;
533+ let ( mut watcher, mut rx) = watcher ( ) ;
534+
535+ let path = tmpdir. path ( ) . join ( "entry" ) ;
536+ std:: fs:: File :: create_new ( & path) . expect ( "create" ) ;
537+
538+ watcher. watch_recursively ( & tmpdir) ;
539+ let new_path = tmpdir. path ( ) . join ( "renamed" ) ;
540+
541+ std:: fs:: rename ( & path, & new_path) . expect ( "rename" ) ;
542+
543+ rx. wait_unordered ( [ expected ( path) . rename_any ( ) , expected ( new_path) . create ( ) ] ) ;
544+ }
545+
546+ #[ test]
547+ fn delete_file ( ) {
548+ let tmpdir = testdir ( ) ;
549+ let ( mut watcher, mut rx) = watcher ( ) ;
550+ let file = tmpdir. path ( ) . join ( "file" ) ;
551+ std:: fs:: write ( & file, "" ) . expect ( "write" ) ;
552+
553+ watcher. watch_nonrecursively ( & tmpdir) ;
554+
555+ std:: fs:: remove_file ( & file) . expect ( "remove" ) ;
556+
557+ // kqueue reports a write event on the directory when a file is deleted
558+ rx. wait_unordered ( [ expected ( tmpdir. path ( ) ) . modify_data_any ( ) ] ) ;
559+ }
560+
561+ #[ test]
562+ fn delete_self_file ( ) {
563+ let tmpdir = testdir ( ) ;
564+ let ( mut watcher, mut rx) = watcher ( ) ;
565+ let file = tmpdir. path ( ) . join ( "file" ) ;
566+ std:: fs:: write ( & file, "" ) . expect ( "write" ) ;
567+
568+ watcher. watch_nonrecursively ( & file) ;
569+
570+ std:: fs:: remove_file ( & file) . expect ( "remove" ) ;
571+
572+ rx. wait_unordered ( [ expected ( file) . remove_any ( ) ] ) ;
573+ }
574+
575+ #[ test]
576+ #[ ignore = "FIXME" ]
577+ fn create_write_overwrite ( ) {
578+ let tmpdir = testdir ( ) ;
579+ let ( mut watcher, mut rx) = watcher ( ) ;
580+ let overwritten_file = tmpdir. path ( ) . join ( "overwritten_file" ) ;
581+ let overwriting_file = tmpdir. path ( ) . join ( "overwriting_file" ) ;
582+ std:: fs:: write ( & overwritten_file, "123" ) . expect ( "write1" ) ;
583+
584+ watcher. watch_nonrecursively ( & tmpdir) ;
585+
586+ std:: fs:: File :: create ( & overwriting_file) . expect ( "create" ) ;
587+ std:: fs:: write ( & overwriting_file, "321" ) . expect ( "write2" ) ;
588+ std:: fs:: rename ( & overwriting_file, & overwritten_file) . expect ( "rename" ) ;
589+
590+ rx. wait_unordered ( [
591+ expected ( & overwriting_file) . create_file ( ) ,
592+ expected ( & overwriting_file) . modify_data_any ( ) . multiple ( ) ,
593+ expected ( & overwriting_file) . rename_any ( ) ,
594+ expected ( & overwritten_file) . rename_any ( ) ,
595+ ] )
596+ . ensure_no_tail ( ) ;
597+ }
598+
599+ #[ test]
600+ fn create_dir ( ) {
601+ let tmpdir = testdir ( ) ;
602+ let ( mut watcher, mut rx) = watcher ( ) ;
603+ watcher. watch_recursively ( & tmpdir) ;
604+
605+ let path = tmpdir. path ( ) . join ( "entry" ) ;
606+ std:: fs:: create_dir ( & path) . expect ( "create" ) ;
607+
608+ rx. wait_unordered ( [ expected ( & path) . create_folder ( ) ] ) ;
609+ }
610+
611+ #[ test]
612+ fn chmod_dir ( ) {
613+ let tmpdir = testdir ( ) ;
614+ let ( mut watcher, mut rx) = watcher ( ) ;
615+
616+ let path = tmpdir. path ( ) . join ( "entry" ) ;
617+ std:: fs:: create_dir ( & path) . expect ( "create_dir" ) ;
618+ let mut permissions = std:: fs:: metadata ( & path) . expect ( "metadata" ) . permissions ( ) ;
619+ permissions. set_readonly ( true ) ;
620+
621+ watcher. watch_recursively ( & tmpdir) ;
622+ std:: fs:: set_permissions ( & path, permissions) . expect ( "set_permissions" ) ;
623+
624+ rx. wait_unordered ( [ expected ( & path) . modify_meta_any ( ) ] ) ;
625+ }
626+
627+ #[ test]
628+ fn rename_dir ( ) {
629+ let tmpdir = testdir ( ) ;
630+ let ( mut watcher, mut rx) = watcher ( ) ;
631+
632+ let path = tmpdir. path ( ) . join ( "entry" ) ;
633+ let new_path = tmpdir. path ( ) . join ( "new_path" ) ;
634+ std:: fs:: create_dir ( & path) . expect ( "create_dir" ) ;
635+
636+ watcher. watch_recursively ( & tmpdir) ;
637+ std:: fs:: rename ( & path, & new_path) . expect ( "rename" ) ;
638+
639+ rx. wait_ordered ( [
640+ expected ( & new_path) . create_folder ( ) ,
641+ expected ( & path) . rename_any ( ) ,
642+ ] ) ;
643+ }
644+
645+ #[ test]
646+ fn delete_dir ( ) {
647+ let tmpdir = testdir ( ) ;
648+ let ( mut watcher, mut rx) = watcher ( ) ;
649+
650+ let path = tmpdir. path ( ) . join ( "entry" ) ;
651+ std:: fs:: create_dir ( & path) . expect ( "create_dir" ) ;
652+
653+ watcher. watch_recursively ( & tmpdir) ;
654+ std:: fs:: remove_dir ( & path) . expect ( "remove" ) ;
655+
656+ rx. wait_unordered ( [ expected ( path) . remove_any ( ) ] ) ;
657+ }
658+
659+ #[ test]
660+ #[ ignore = "FIXME" ]
661+ fn rename_dir_twice ( ) {
662+ let tmpdir = testdir ( ) ;
663+ let ( mut watcher, mut rx) = watcher ( ) ;
664+
665+ let path = tmpdir. path ( ) . join ( "entry" ) ;
666+ let new_path = tmpdir. path ( ) . join ( "new_path" ) ;
667+ let new_path2 = tmpdir. path ( ) . join ( "new_path2" ) ;
668+ std:: fs:: create_dir ( & path) . expect ( "create_dir" ) ;
669+
670+ watcher. watch_recursively ( & tmpdir) ;
671+ std:: fs:: rename ( & path, & new_path) . expect ( "rename" ) ;
672+ std:: fs:: rename ( & new_path, & new_path2) . expect ( "rename2" ) ;
673+
674+ rx. wait_unordered ( [
675+ expected ( & path) . rename_any ( ) ,
676+ expected ( & new_path) . create_folder ( ) ,
677+ expected ( & new_path) . rename_any ( ) ,
678+ expected ( & new_path2) . create_folder ( ) ,
679+ ] ) ;
680+ }
681+
682+ #[ test]
683+ fn move_out_of_watched_dir ( ) {
684+ let tmpdir = testdir ( ) ;
685+ let subdir = tmpdir. path ( ) . join ( "subdir" ) ;
686+ let ( mut watcher, mut rx) = watcher ( ) ;
687+
688+ let path = subdir. join ( "entry" ) ;
689+ std:: fs:: create_dir_all ( & subdir) . expect ( "create_dir_all" ) ;
690+ std:: fs:: File :: create_new ( & path) . expect ( "create" ) ;
691+
692+ watcher. watch_recursively ( & subdir) ;
693+ let new_path = tmpdir. path ( ) . join ( "entry" ) ;
694+
695+ std:: fs:: rename ( & path, & new_path) . expect ( "rename" ) ;
696+
697+ rx. wait_unordered ( [ expected ( path) . rename_any ( ) ] ) ;
698+ }
699+
700+ #[ test]
701+ #[ ignore = "FIXME" ]
702+ fn create_write_write_rename_write_remove ( ) {
703+ let tmpdir = testdir ( ) ;
704+ let ( mut watcher, mut rx) = watcher ( ) ;
705+
706+ let file1 = tmpdir. path ( ) . join ( "entry" ) ;
707+ let file2 = tmpdir. path ( ) . join ( "entry2" ) ;
708+ std:: fs:: File :: create_new ( & file2) . expect ( "create file2" ) ;
709+ let new_path = tmpdir. path ( ) . join ( "renamed" ) ;
710+
711+ watcher. watch_recursively ( & tmpdir) ;
712+ std:: fs:: write ( & file1, "123" ) . expect ( "write 1" ) ;
713+ std:: fs:: write ( & file2, "321" ) . expect ( "write 2" ) ;
714+ std:: fs:: rename ( & file1, & new_path) . expect ( "rename" ) ;
715+ std:: fs:: write ( & new_path, b"1" ) . expect ( "write 3" ) ;
716+ std:: fs:: remove_file ( & new_path) . expect ( "remove" ) ;
717+
718+ rx. wait_ordered ( [
719+ expected ( & file1) . create_file ( ) ,
720+ expected ( & file1) . modify_data_content ( ) ,
721+ expected ( & file2) . modify_data_content ( ) ,
722+ expected ( & file1) . rename_any ( ) ,
723+ expected ( & new_path) . rename_any ( ) ,
724+ expected ( & new_path) . modify_data_content ( ) ,
725+ expected ( & new_path) . remove_file ( ) ,
726+ ] ) ;
727+ }
728+
729+ #[ test]
730+ #[ ignore = "FIXME" ]
731+ fn rename_twice ( ) {
732+ let tmpdir = testdir ( ) ;
733+ let ( mut watcher, mut rx) = watcher ( ) ;
734+
735+ let path = tmpdir. path ( ) . join ( "entry" ) ;
736+ std:: fs:: File :: create_new ( & path) . expect ( "create" ) ;
737+
738+ watcher. watch_recursively ( & tmpdir) ;
739+ let new_path1 = tmpdir. path ( ) . join ( "renamed1" ) ;
740+ let new_path2 = tmpdir. path ( ) . join ( "renamed2" ) ;
741+
742+ std:: fs:: rename ( & path, & new_path1) . expect ( "rename1" ) ;
743+ std:: fs:: rename ( & new_path1, & new_path2) . expect ( "rename2" ) ;
744+
745+ rx. wait_unordered ( [
746+ expected ( & path) . rename_any ( ) ,
747+ expected ( & new_path1) . rename_any ( ) ,
748+ expected ( & new_path2) . create ( ) ,
749+ ] ) ;
750+ }
751+
752+ #[ test]
753+ fn set_file_mtime ( ) {
754+ let tmpdir = testdir ( ) ;
755+ let ( mut watcher, mut rx) = watcher ( ) ;
756+
757+ let path = tmpdir. path ( ) . join ( "entry" ) ;
758+ let file = std:: fs:: File :: create_new ( & path) . expect ( "create" ) ;
759+
760+ watcher. watch_recursively ( & tmpdir) ;
761+
762+ file. set_modified (
763+ std:: time:: SystemTime :: now ( )
764+ . checked_sub ( Duration :: from_secs ( 60 * 60 ) )
765+ . expect ( "time" ) ,
766+ )
767+ . expect ( "set_time" ) ;
768+
769+ rx. wait_unordered ( [ expected ( & path) . modify_meta_any ( ) ] ) ;
770+ }
771+
772+ #[ test]
773+ fn write_file_non_recursive_watch ( ) {
774+ let tmpdir = testdir ( ) ;
775+ let ( mut watcher, mut rx) = watcher ( ) ;
776+
777+ let path = tmpdir. path ( ) . join ( "entry" ) ;
778+ std:: fs:: File :: create_new ( & path) . expect ( "create" ) ;
779+
780+ watcher. watch_nonrecursively ( & path) ;
781+
782+ std:: fs:: write ( & path, b"123" ) . expect ( "write" ) ;
783+
784+ rx. wait_unordered ( [ expected ( path) . modify_data_any ( ) ] ) ;
785+ }
786+
787+ #[ test]
788+ fn write_to_a_hardlink_pointed_to_the_watched_file_triggers_an_event ( ) {
789+ let tmpdir = testdir ( ) ;
790+ let ( mut watcher, mut rx) = watcher ( ) ;
791+
792+ let subdir = tmpdir. path ( ) . join ( "subdir" ) ;
793+ let file = subdir. join ( "file" ) ;
794+ let hardlink = tmpdir. path ( ) . join ( "hardlink" ) ;
795+
796+ std:: fs:: create_dir ( & subdir) . expect ( "create" ) ;
797+ std:: fs:: write ( & file, "" ) . expect ( "file" ) ;
798+ std:: fs:: hard_link ( & file, & hardlink) . expect ( "hardlink" ) ;
799+
800+ watcher. watch_nonrecursively ( & file) ;
801+
802+ std:: fs:: write ( & hardlink, "123123" ) . expect ( "write to the hard link" ) ;
803+
804+ rx. wait_unordered ( [ expected ( file) . modify_data_any ( ) ] ) ;
805+ }
806+
807+ #[ test]
808+ #[ ignore = "FIXME" ]
809+ fn recursive_creation ( ) {
810+ let tmpdir = testdir ( ) ;
811+ let nested1 = tmpdir. path ( ) . join ( "1" ) ;
812+ let nested2 = tmpdir. path ( ) . join ( "1/2" ) ;
813+ let nested3 = tmpdir. path ( ) . join ( "1/2/3" ) ;
814+ let nested4 = tmpdir. path ( ) . join ( "1/2/3/4" ) ;
815+ let nested5 = tmpdir. path ( ) . join ( "1/2/3/4/5" ) ;
816+ let nested6 = tmpdir. path ( ) . join ( "1/2/3/4/5/6" ) ;
817+ let nested7 = tmpdir. path ( ) . join ( "1/2/3/4/5/6/7" ) ;
818+ let nested8 = tmpdir. path ( ) . join ( "1/2/3/4/5/6/7/8" ) ;
819+ let nested9 = tmpdir. path ( ) . join ( "1/2/3/4/5/6/7/8/9" ) ;
820+
821+ let ( mut watcher, mut rx) = watcher ( ) ;
822+
823+ watcher. watch_recursively ( & tmpdir) ;
824+
825+ std:: fs:: create_dir_all ( & nested9) . expect ( "create_dir_all" ) ;
826+
827+ rx. wait_unordered ( [
828+ expected ( & nested1) . create_folder ( ) ,
829+ expected ( & nested2) . create_folder ( ) ,
830+ expected ( & nested3) . create_folder ( ) ,
831+ expected ( & nested4) . create_folder ( ) ,
832+ expected ( & nested5) . create_folder ( ) ,
833+ expected ( & nested6) . create_folder ( ) ,
834+ expected ( & nested7) . create_folder ( ) ,
835+ expected ( & nested8) . create_folder ( ) ,
836+ expected ( & nested9) . create_folder ( ) ,
837+ ] ) ;
838+ }
481839}
0 commit comments