fun_with_files 0.0.15 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/CHANGELOG.markdown +15 -3
- data/Gemfile +17 -7
- data/{README.rdoc → README.markdown} +11 -10
- data/VERSION +1 -1
- data/lib/fun_with/files/bootstrapper.rb +87 -0
- data/lib/fun_with/files/digest_methods.rb +30 -16
- data/lib/fun_with/files/directory_builder.rb +4 -0
- data/lib/fun_with/files/downloader.rb +3 -19
- data/lib/fun_with/files/errors.rb +9 -1
- data/lib/fun_with/files/file_manipulation_methods.rb +25 -15
- data/lib/fun_with/files/file_path.rb +147 -150
- data/lib/fun_with/files/file_path_class_methods.rb +23 -2
- data/lib/fun_with/files/file_permission_methods.rb +18 -7
- data/lib/fun_with/files/file_requirements.rb +63 -7
- data/lib/fun_with/files/requirements/manager.rb +104 -0
- data/lib/fun_with/files/root_path.rb +3 -3
- data/lib/fun_with/files/stat_methods.rb +33 -0
- data/lib/fun_with/files/string_behavior.rb +6 -2
- data/lib/fun_with/files/utils/byte_size.rb +143 -0
- data/lib/fun_with/files/utils/opts.rb +26 -0
- data/lib/fun_with/files/utils/succession.rb +47 -0
- data/lib/fun_with/files/utils/timestamp.rb +47 -0
- data/lib/fun_with/files/utils/timestamp_format.rb +31 -0
- data/lib/fun_with/files/watcher.rb +157 -0
- data/lib/fun_with/files/watchers/directory_watcher.rb +67 -0
- data/lib/fun_with/files/watchers/file_watcher.rb +45 -0
- data/lib/fun_with/files/watchers/missing_watcher.rb +23 -0
- data/lib/fun_with/files/watchers/node_watcher.rb +44 -0
- data/lib/fun_with/testing/assertions/fun_with_files.rb +91 -0
- data/lib/fun_with/testing/test_case_extensions.rb +12 -0
- data/lib/fun_with_files.rb +5 -75
- data/test/helper.rb +13 -5
- data/test/test_core_extensions.rb +5 -0
- data/test/test_directory_builder.rb +29 -10
- data/test/test_extension_methods.rb +62 -0
- data/test/test_file_manipulation.rb +2 -2
- data/test/test_file_path.rb +18 -39
- data/test/test_file_requirements.rb +36 -0
- data/test/test_fun_with_files.rb +1 -1
- data/test/test_fwf_assertions.rb +62 -0
- data/test/test_moving_files.rb +111 -0
- data/test/test_permission_methods.rb +22 -0
- data/test/test_root_path.rb +9 -0
- data/test/test_stat_methods.rb +17 -0
- data/test/test_timestamping.rb +74 -0
- data/test/test_utils_bytesize.rb +71 -0
- data/test/test_utils_succession.rb +30 -0
- data/test/test_watchers.rb +196 -0
- metadata +54 -16
| @@ -0,0 +1,62 @@ | |
| 1 | 
            +
            module FunWith
         | 
| 2 | 
            +
              module Testing
         | 
| 3 | 
            +
                class TestFwfAssertions < FunWith::Testing::AssertionsTestCase
         | 
| 4 | 
            +
                  context "testing assertions" do
         | 
| 5 | 
            +
                    setup do
         | 
| 6 | 
            +
                      extended_test_case  # sets @case, which is used to access to assertions
         | 
| 7 | 
            +
                      @case_class.install_fun_with_files_assertions
         | 
| 8 | 
            +
                    end
         | 
| 9 | 
            +
                    
         | 
| 10 | 
            +
                    context "testing :assert_fwf_filepath()" do
         | 
| 11 | 
            +
                      should "pass all tests" do
         | 
| 12 | 
            +
                        testing_method :assert_fwf_filepath do
         | 
| 13 | 
            +
                          nope __FILE__
         | 
| 14 | 
            +
                          yep  __FILE__.fwf_filepath
         | 
| 15 | 
            +
                          
         | 
| 16 | 
            +
                          nope nil
         | 
| 17 | 
            +
                          nope :five
         | 
| 18 | 
            +
                          nope 5
         | 
| 19 | 
            +
                          nope [5]
         | 
| 20 | 
            +
                          nope "five"
         | 
| 21 | 
            +
                        end
         | 
| 22 | 
            +
                      end
         | 
| 23 | 
            +
                    end
         | 
| 24 | 
            +
                      
         | 
| 25 | 
            +
                    context "testing :assert_file()" do
         | 
| 26 | 
            +
                      should "pass all tests" do
         | 
| 27 | 
            +
                        testing_method :assert_file do
         | 
| 28 | 
            +
                          yep  __FILE__.fwf_filepath
         | 
| 29 | 
            +
                          
         | 
| 30 | 
            +
                          nope __FILE__
         | 
| 31 | 
            +
                          nope nil
         | 
| 32 | 
            +
                          nope :five
         | 
| 33 | 
            +
                          nope 5
         | 
| 34 | 
            +
                          nope [5]
         | 
| 35 | 
            +
                          nope "five"
         | 
| 36 | 
            +
                        end
         | 
| 37 | 
            +
                      end
         | 
| 38 | 
            +
                    end
         | 
| 39 | 
            +
                    
         | 
| 40 | 
            +
                    context "testing :assert_directory()" do
         | 
| 41 | 
            +
                      should "pass all tests" do
         | 
| 42 | 
            +
                        testing_method :assert_directory do
         | 
| 43 | 
            +
                          nope __FILE__
         | 
| 44 | 
            +
                          nope __FILE__.fwf_filepath
         | 
| 45 | 
            +
                          
         | 
| 46 | 
            +
                          yep  __FILE__.fwf_filepath.dirname
         | 
| 47 | 
            +
                          yep  __FILE__.fwf_filepath.up
         | 
| 48 | 
            +
                          yep  FunWith::Files.root
         | 
| 49 | 
            +
                          
         | 
| 50 | 
            +
                          nope nil
         | 
| 51 | 
            +
                          nope :five
         | 
| 52 | 
            +
                          nope 5
         | 
| 53 | 
            +
                          nope [5]
         | 
| 54 | 
            +
                          nope "five"
         | 
| 55 | 
            +
                        end
         | 
| 56 | 
            +
                      end
         | 
| 57 | 
            +
                    end
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
                end
         | 
| 60 | 
            +
              end
         | 
| 61 | 
            +
            end
         | 
| 62 | 
            +
             | 
| @@ -0,0 +1,111 @@ | |
| 1 | 
            +
            require 'helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class TestMovingFiles < FunWith::Files::TestCase
         | 
| 4 | 
            +
              context "inside a tmpdir" do
         | 
| 5 | 
            +
                setup do
         | 
| 6 | 
            +
                  @src_dir = FilePath.tmpdir
         | 
| 7 | 
            +
                  @dst_dir = FilePath.tmpdir
         | 
| 8 | 
            +
                  
         | 
| 9 | 
            +
                  assert_directory @src_dir
         | 
| 10 | 
            +
                  assert_directory @dst_dir
         | 
| 11 | 
            +
                  
         | 
| 12 | 
            +
                  assert_empty_directory @src_dir
         | 
| 13 | 
            +
                  assert_empty_directory @dst_dir
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
                
         | 
| 16 | 
            +
                teardown do
         | 
| 17 | 
            +
                  @src_dir.rm
         | 
| 18 | 
            +
                  @dst_dir.rm
         | 
| 19 | 
            +
                  assert_not_directory @src_dir
         | 
| 20 | 
            +
                  assert_not_directory @dst_dir
         | 
| 21 | 
            +
                end
         | 
| 22 | 
            +
                
         | 
| 23 | 
            +
                context "with a source file" do
         | 
| 24 | 
            +
                  setup do
         | 
| 25 | 
            +
                    @src_file = @src_dir / "file.txt"
         | 
| 26 | 
            +
                    @src_file.write( "Hello world" )
         | 
| 27 | 
            +
                    
         | 
| 28 | 
            +
                    assert_file_not_empty( @src_file )
         | 
| 29 | 
            +
                  end
         | 
| 30 | 
            +
                  
         | 
| 31 | 
            +
                  
         | 
| 32 | 
            +
                  should "successfully move a file into a directory" do
         | 
| 33 | 
            +
                    dest = @dst_dir / "file.txt"
         | 
| 34 | 
            +
                    
         | 
| 35 | 
            +
                    assert_no_file dest
         | 
| 36 | 
            +
                    
         | 
| 37 | 
            +
                    @src_file.move @dst_dir
         | 
| 38 | 
            +
                    
         | 
| 39 | 
            +
                    assert_file dest 
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
                  
         | 
| 42 | 
            +
                  
         | 
| 43 | 
            +
                  
         | 
| 44 | 
            +
                  # Seems dangerous to not have a concrete idea of what should happen when a move
         | 
| 45 | 
            +
                  # remove / create request takes place.  Ideas:
         | 
| 46 | 
            +
                  # be able to mark a destination as a directory, so that it knows the file move 
         | 
| 47 | 
            +
                  # is saying to
         | 
| 48 | 
            +
                  #
         | 
| 49 | 
            +
                  #  a directory should be created
         | 
| 50 | 
            +
                  #  a directory must exist for the move to occur
         | 
| 51 | 
            +
                  #  nothing exists at the destination, so the file is given the name of <thing_what_didnt_exist>
         | 
| 52 | 
            +
                  #  
         | 
| 53 | 
            +
                  should "fail to move a file to a non-existent directory" do
         | 
| 54 | 
            +
                    flunk "this actually moves the file (the file getting the name of the 'missing' directory, and I'm not sure that's wrong)"
         | 
| 55 | 
            +
                    not_a_dir = @dst_dir / "humblebrag"
         | 
| 56 | 
            +
                    
         | 
| 57 | 
            +
                    assert_raises( Errno::ENOENT ) do
         | 
| 58 | 
            +
                      @src_file.move( not_a_dir )
         | 
| 59 | 
            +
                    end
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
                  
         | 
| 62 | 
            +
                  should "fail to move a file owing to lack of privileges" do
         | 
| 63 | 
            +
                    write_protected_dir = @dst_dir / "write_protected_dir"
         | 
| 64 | 
            +
                    write_protected_dir.touch_dir
         | 
| 65 | 
            +
                    
         | 
| 66 | 
            +
                    temporarily_write_protect( write_protected_dir ) do
         | 
| 67 | 
            +
                      assert_raises( Errno::EACCES ) do
         | 
| 68 | 
            +
                        @src_file.move( write_protected_dir )
         | 
| 69 | 
            +
                      end
         | 
| 70 | 
            +
                    end
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
                
         | 
| 74 | 
            +
                  
         | 
| 75 | 
            +
                
         | 
| 76 | 
            +
                should "fail to move a non-existent file" do
         | 
| 77 | 
            +
                  f = @src_dir.join( "file.txt" )
         | 
| 78 | 
            +
                  
         | 
| 79 | 
            +
                  assert_no_file( f )
         | 
| 80 | 
            +
                  
         | 
| 81 | 
            +
                  assert_raises( Errno::ENOENT ) do
         | 
| 82 | 
            +
                    f.move( @dst_dir )
         | 
| 83 | 
            +
                  end
         | 
| 84 | 
            +
                end
         | 
| 85 | 
            +
              end
         | 
| 86 | 
            +
                
         | 
| 87 | 
            +
              #
         | 
| 88 | 
            +
              #   should "successfully move a directory" do
         | 
| 89 | 
            +
              #     flunk "write test"
         | 
| 90 | 
            +
              #   end
         | 
| 91 | 
            +
              #
         | 
| 92 | 
            +
              #   should "fail to move a non-existent directory" do
         | 
| 93 | 
            +
              #     flunk "write test"
         | 
| 94 | 
            +
              #   end
         | 
| 95 | 
            +
              #
         | 
| 96 | 
            +
              #   should "fail to move a directory to a non-existent directory" do
         | 
| 97 | 
            +
              #     flunk "write test"
         | 
| 98 | 
            +
              #   end
         | 
| 99 | 
            +
              #
         | 
| 100 | 
            +
              #   should "fail to move a directory owing to lack of privileges" do
         | 
| 101 | 
            +
              #
         | 
| 102 | 
            +
              #     flunk "write test"
         | 
| 103 | 
            +
              #   end
         | 
| 104 | 
            +
              # end
         | 
| 105 | 
            +
              
         | 
| 106 | 
            +
              def temporarily_write_protect( f, &block )
         | 
| 107 | 
            +
                f.chmod( "a-w" )
         | 
| 108 | 
            +
                yield
         | 
| 109 | 
            +
                f.chmod( "a+w" )
         | 
| 110 | 
            +
              end
         | 
| 111 | 
            +
            end
         | 
| @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            require 'helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class TestPermissionMethods < FunWith::Files::TestCase
         | 
| 4 | 
            +
              context "checking for availability of permission methods" do
         | 
| 5 | 
            +
                setup do
         | 
| 6 | 
            +
                  @filepath = FunWith::Files::FilePath.new("/")
         | 
| 7 | 
            +
                end
         | 
| 8 | 
            +
                
         | 
| 9 | 
            +
                should "have permission methods" do
         | 
| 10 | 
            +
                  assert_respond_to @filepath, :readable?
         | 
| 11 | 
            +
                  assert_respond_to @filepath, :writable?
         | 
| 12 | 
            +
                  assert_respond_to @filepath, :executable?
         | 
| 13 | 
            +
                  assert_respond_to @filepath, :chown
         | 
| 14 | 
            +
                  assert_respond_to @filepath, :chmod
         | 
| 15 | 
            +
                  assert_respond_to @filepath, :owner
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
                
         | 
| 18 | 
            +
                should "have a root owner" do
         | 
| 19 | 
            +
                  assert_equal "root", @filepath.owner
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
            end
         | 
    
        data/test/test_root_path.rb
    CHANGED
    
    | @@ -13,6 +13,15 @@ class TestRootPath < FunWith::Files::TestCase | |
| 13 13 | 
             
                rootify_and_test( obj, path )
         | 
| 14 14 | 
             
              end
         | 
| 15 15 |  | 
| 16 | 
            +
              context "FunWith::Files.root" do
         | 
| 17 | 
            +
                should "be a directory" do
         | 
| 18 | 
            +
                  assert_directory( FunWith::Files.root )
         | 
| 19 | 
            +
                  assert_empty_directory( FunWith::Files.root( :test, :tmp ) )
         | 
| 20 | 
            +
                  assert_empty_directory( FunWith::Files.root / :test / :tmp )
         | 
| 21 | 
            +
                  assert_empty_directory( FunWith::Files.root / "test" / "tmp" )
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
              end
         | 
| 24 | 
            +
              
         | 
| 16 25 | 
             
              def rootify_and_test( obj, path )
         | 
| 17 26 | 
             
                RootPath.rootify( obj, path )
         | 
| 18 27 | 
             
                assert obj.respond_to?(:root)
         | 
| @@ -0,0 +1,17 @@ | |
| 1 | 
            +
            require 'helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class TestStatMethods < FunWith::Files::TestCase
         | 
| 4 | 
            +
              
         | 
| 5 | 
            +
              context "checking for availability of stat-enabling methods" do
         | 
| 6 | 
            +
                setup do
         | 
| 7 | 
            +
                  @filepath = FunWith::Files::FilePath.new("/")
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
                
         | 
| 10 | 
            +
                should "have stat methods" do
         | 
| 11 | 
            +
                  assert_respond_to @filepath, :stat
         | 
| 12 | 
            +
                  assert_respond_to @filepath, :inode
         | 
| 13 | 
            +
                  assert_respond_to @filepath, :birthtime  # this (and many others) come from Pathname
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
                
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
            end
         | 
| @@ -0,0 +1,74 @@ | |
| 1 | 
            +
            require 'helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class TestTimestamping < FunWith::Files::TestCase
         | 
| 4 | 
            +
              context "testing timestamping" do
         | 
| 5 | 
            +
                setup do
         | 
| 6 | 
            +
                  @tmp_dir = FunWith::Files.root( 'test', 'tmp' )
         | 
| 7 | 
            +
                  @logfile = @tmp_dir / "apache.log"
         | 
| 8 | 
            +
                  @stamp_time = Time.new( 2000, 10, 13, 23, 59, 59 )
         | 
| 9 | 
            +
                end
         | 
| 10 | 
            +
              
         | 
| 11 | 
            +
                teardown do
         | 
| 12 | 
            +
                  `rm -rf #{@tmp_dir.join('*')}`
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
                
         | 
| 15 | 
            +
                should "sequence files with datestamps" do
         | 
| 16 | 
            +
                  dates = %w(2012-11-30 1900-12-01 2727-06-14)
         | 
| 17 | 
            +
                  
         | 
| 18 | 
            +
                  for date in dates
         | 
| 19 | 
            +
                    d = Date.new( * date.split("-").map(&:to_i) )
         | 
| 20 | 
            +
                    
         | 
| 21 | 
            +
                    f = @logfile.timestamp( format: :ymd, time: d )
         | 
| 22 | 
            +
                    f.write( date )
         | 
| 23 | 
            +
                    
         | 
| 24 | 
            +
                    fy = @logfile.timestamp( format: :y, time: d )
         | 
| 25 | 
            +
                    fy.write date[0..3]
         | 
| 26 | 
            +
                  end
         | 
| 27 | 
            +
                  
         | 
| 28 | 
            +
                  for str in dates + %w(2012 1900 2727)
         | 
| 29 | 
            +
                    file = @tmp_dir / "apache.#{str}.log"
         | 
| 30 | 
            +
                    assert_file file
         | 
| 31 | 
            +
                    assert_file_contents file, str
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
                end
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                should "timestamp files using the timestamp() method" do
         | 
| 36 | 
            +
                  timestampable_file = @tmp_dir / "timestamped.dat"
         | 
| 37 | 
            +
                  
         | 
| 38 | 
            +
                  timestamped_file1  = timestampable_file.timestamp
         | 
| 39 | 
            +
                  timestamped_file2  = timestampable_file.timestamp( format: :y )
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  assert timestamped_file1 =~ /timestamped.\d{17}.dat$/
         | 
| 42 | 
            +
                  assert timestamped_file2 =~ /timestamped.\d{4}.dat$/
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
                
         | 
| 45 | 
            +
                should "raise an error when invalid format requested" do
         | 
| 46 | 
            +
                  f = @tmp_dir / "apache.log"
         | 
| 47 | 
            +
                  
         | 
| 48 | 
            +
                  stamped = f.timestamp
         | 
| 49 | 
            +
                  
         | 
| 50 | 
            +
                  assert_raises Errors::TimestampFormatUnrecognized do
         | 
| 51 | 
            +
                    f.timestamp( format: :zztop )
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
                  
         | 
| 54 | 
            +
                  # Symbols only!
         | 
| 55 | 
            +
                  assert_raises Errors::TimestampFormatUnrecognized do
         | 
| 56 | 
            +
                    f.timestamp( format: "ymd" )
         | 
| 57 | 
            +
                  end
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
                
         | 
| 60 | 
            +
                should "update the timestamp of a file that already has one" do
         | 
| 61 | 
            +
                  f = "apache.19931020235959000.tgz".fwf_filepath
         | 
| 62 | 
            +
                  timestamped_file = f.timestamp( time: @stamp_time )
         | 
| 63 | 
            +
                  
         | 
| 64 | 
            +
                  assert_equal "apache.20001013235959000.tgz", timestamped_file.path
         | 
| 65 | 
            +
                end
         | 
| 66 | 
            +
                
         | 
| 67 | 
            +
                should "be able to give the timestamp method a custom format" do
         | 
| 68 | 
            +
                  fmt = Utils::TimestampFormat.new.recognizer( /^\d{2}_\d{2}_\d{2}$/ ).strftime( "%m_%d_%y" )
         | 
| 69 | 
            +
                  
         | 
| 70 | 
            +
                  timestamped_file = @logfile.timestamp( format: fmt, time: @stamp_time )
         | 
| 71 | 
            +
                  assert_equal "apache.10_13_00.log", timestamped_file.basename.path
         | 
| 72 | 
            +
                end
         | 
| 73 | 
            +
              end
         | 
| 74 | 
            +
            end
         | 
| @@ -0,0 +1,71 @@ | |
| 1 | 
            +
            require 'helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class TestUtilsByteSize < FunWith::Files::TestCase
         | 
| 4 | 
            +
              context "testing the thing" do
         | 
| 5 | 
            +
                setup do
         | 
| 6 | 
            +
                  @bytie = Object.new
         | 
| 7 | 
            +
                  @bytie.extend FunWith::Files::Utils::ByteSize
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
                
         | 
| 10 | 
            +
                should "respond to :to_bytes" do
         | 
| 11 | 
            +
                  assert_respond_to @bytie, :to_bytes
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
                
         | 
| 14 | 
            +
                should "accurately convert strings to bytes" do
         | 
| 15 | 
            +
                  assert_bytes 1_000, "1000b"
         | 
| 16 | 
            +
                  assert_bytes 1_000, "1 kb"
         | 
| 17 | 
            +
                  assert_bytes 1_000, "0.001 MB"
         | 
| 18 | 
            +
                  assert_bytes 1_000, "0.000001 GB"
         | 
| 19 | 
            +
                  
         | 
| 20 | 
            +
                  assert_bytes 1_234, "1234"
         | 
| 21 | 
            +
                  assert_bytes 1_234, "  1.234  kb  "
         | 
| 22 | 
            +
                  assert_bytes 9_001, "9.001k"                    # it's over 9000!
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
                
         | 
| 25 | 
            +
                context "converting expressions between units" do
         | 
| 26 | 
            +
                  should "handle simple cases" do
         | 
| 27 | 
            +
                    assert_converts "1KB", "B",  "1000B"
         | 
| 28 | 
            +
                    assert_converts "2MB", "KB", "2000KB"
         | 
| 29 | 
            +
                    assert_converts "3GB", "MB", "3000MB"
         | 
| 30 | 
            +
                    assert_converts "4TB", "GB", "4000GB"
         | 
| 31 | 
            +
                    assert_converts "5PB", "TB", "5000TB"
         | 
| 32 | 
            +
                  end
         | 
| 33 | 
            +
                
         | 
| 34 | 
            +
                  should "be case insensitive" do
         | 
| 35 | 
            +
                    assert_converts "1kb", "B", "1000B"
         | 
| 36 | 
            +
                    assert_converts "1000k", "mb", "1mb"
         | 
| 37 | 
            +
                    assert_converts "1000m", "GB", "1GB"
         | 
| 38 | 
            +
                    assert_converts "2000 PB", " EB", "2 EB"
         | 
| 39 | 
            +
                  end
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                  should "sometimes put space between number and unit" do
         | 
| 42 | 
            +
                    assert_converts "2000 PB", " EB", "2 EB"
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
                  
         | 
| 45 | 
            +
                  should "reflect the unit styling that the caller sends" do
         | 
| 46 | 
            +
                    assert_converts "1kb", "b", "1000b"     # uses the unit capitalization that the caller sends
         | 
| 47 | 
            +
                  end
         | 
| 48 | 
            +
                  
         | 
| 49 | 
            +
                  should "sometimes use decimal points" do
         | 
| 50 | 
            +
                    assert_converts "900kb", "MB", "0.9MB"
         | 
| 51 | 
            +
                    assert_converts "930kb", "mb", "0.9mb"
         | 
| 52 | 
            +
                  
         | 
| 53 | 
            +
                    assert_converts "99500b", "kb", "99.5kb"
         | 
| 54 | 
            +
                    assert_converts "1200MB", "gb", "1.2gb"
         | 
| 55 | 
            +
                  end
         | 
| 56 | 
            +
                  
         | 
| 57 | 
            +
                  should "sometimes not use decimal points" do
         | 
| 58 | 
            +
                    assert_converts "100372b", "k", "100k"
         | 
| 59 | 
            +
                    assert_converts "1b", "GB", "0GB"
         | 
| 60 | 
            +
                  end
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
              end
         | 
| 63 | 
            +
              
         | 
| 64 | 
            +
              def assert_bytes( n, expr )
         | 
| 65 | 
            +
                assert_equal n, @bytie.to_bytes( expr ), "to_bytes( #{expr} ) should resolve to #{n}"
         | 
| 66 | 
            +
              end
         | 
| 67 | 
            +
              
         | 
| 68 | 
            +
              def assert_converts( old_expr, new_units, new_expr )
         | 
| 69 | 
            +
                assert_equal new_expr, @bytie.convert( old_expr, new_units )
         | 
| 70 | 
            +
              end
         | 
| 71 | 
            +
            end
         | 
| @@ -0,0 +1,30 @@ | |
| 1 | 
            +
            require 'helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class TestUtilsSuccession < FunWith::Files::TestCase
         | 
| 4 | 
            +
              USucc = FunWith::Files::Utils::Succession
         | 
| 5 | 
            +
              
         | 
| 6 | 
            +
              context "testing Succession.get_successor_name()" do
         | 
| 7 | 
            +
                should "succeed" do
         | 
| 8 | 
            +
                  with_digit_count( 4 ) do
         | 
| 9 | 
            +
                    assert_succession "file.0001.txt", "file.0002.txt" 
         | 
| 10 | 
            +
                    assert_succession "file.txt", "file.0000.txt" 
         | 
| 11 | 
            +
                    assert_succession "", "0000"
         | 
| 12 | 
            +
                  end
         | 
| 13 | 
            +
                end
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
              
         | 
| 16 | 
            +
              def with_digit_count( i, &block )
         | 
| 17 | 
            +
                @digit_count = i
         | 
| 18 | 
            +
                yield 
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
              
         | 
| 21 | 
            +
              def assert_succession( input, expected )
         | 
| 22 | 
            +
                if defined?( @digit_count )
         | 
| 23 | 
            +
                  actual = USucc.get_successor_name( input, @digit_count )
         | 
| 24 | 
            +
                else
         | 
| 25 | 
            +
                  actual = USucc.get_successor_name( input )
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
                
         | 
| 28 | 
            +
                assert_equal( expected, actual, "Utils::Succession.get_successor_name() failed:\n\tinput: #{input}(#{input.class})\n\texpected: #{expected}(#{expected.class})\n\tactual: #{actual}(#{actual.class})")
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
            end
         | 
| @@ -0,0 +1,196 @@ | |
| 1 | 
            +
            require 'helper'
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            class TestWatchers < FunWith::Files::TestCase
         | 
| 4 | 
            +
              context "testing Watcher as it benevolently watches over the files placed under its care" do
         | 
| 5 | 
            +
                setup do
         | 
| 6 | 
            +
                  tmpdir     # assigns @tmpdir a freshly created temp directory
         | 
| 7 | 
            +
                  self.watch @tmpdir
         | 
| 8 | 
            +
                end
         | 
| 9 | 
            +
                
         | 
| 10 | 
            +
                teardown do
         | 
| 11 | 
            +
                  @tmpdir.rm
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
                
         | 
| 14 | 
            +
                should "watch an empty directory as a subdirectory and a file are added" do
         | 
| 15 | 
            +
                  @tmpdir.touch_dir :lethe do |d|
         | 
| 16 | 
            +
                    file = d.join( "forgotten_file.txt" )
         | 
| 17 | 
            +
                    file.write( "someone help me remember this" )
         | 
| 18 | 
            +
                    
         | 
| 19 | 
            +
                    get_changes do
         | 
| 20 | 
            +
                      assert_changes :created, d, file
         | 
| 21 | 
            +
                    end
         | 
| 22 | 
            +
                    
         | 
| 23 | 
            +
                    file.append( "\nbecause I don't trust my brain to keep track of things" )
         | 
| 24 | 
            +
                    
         | 
| 25 | 
            +
                    get_changes(1) do
         | 
| 26 | 
            +
                      assert_changes :modified, file
         | 
| 27 | 
            +
                    end
         | 
| 28 | 
            +
                    
         | 
| 29 | 
            +
                    d.rm
         | 
| 30 | 
            +
                  
         | 
| 31 | 
            +
                    get_changes do
         | 
| 32 | 
            +
                      assert_changes :deleted, d, file
         | 
| 33 | 
            +
                    end
         | 
| 34 | 
            +
                  end  
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
                
         | 
| 37 | 
            +
                should "watch an empty directory as a bunch of changes happen" do
         | 
| 38 | 
            +
                  @tmpdir.touch_dir( :battles ) do |d0|
         | 
| 39 | 
            +
                    @tmpdir.touch_dir( :bunker_hill ) do |d1|
         | 
| 40 | 
            +
                      file0 = d1.join( "troop_movements.csv" )
         | 
| 41 | 
            +
                      file0.write( "My dearest Sarah,\n\tI fear this may be the last time I write to you.  Our forces are outnumbered." )
         | 
| 42 | 
            +
                      
         | 
| 43 | 
            +
                      get_changes do
         | 
| 44 | 
            +
                        assert_changes :created, d0, d1, file0
         | 
| 45 | 
            +
                      end  
         | 
| 46 | 
            +
                      
         | 
| 47 | 
            +
                      file0.append "Supplies are scarce and the horses have lost their patience with us."
         | 
| 48 | 
            +
                      
         | 
| 49 | 
            +
                      get_changes(1) do
         | 
| 50 | 
            +
                        assert_changes :modified, file0
         | 
| 51 | 
            +
                      end
         | 
| 52 | 
            +
                      
         | 
| 53 | 
            +
                      d1.rm
         | 
| 54 | 
            +
                      
         | 
| 55 | 
            +
                      get_changes(2) do
         | 
| 56 | 
            +
                        assert_changes :deleted, d1, file0
         | 
| 57 | 
            +
                      end
         | 
| 58 | 
            +
                    end
         | 
| 59 | 
            +
                    
         | 
| 60 | 
            +
                    d0.rm
         | 
| 61 | 
            +
                    
         | 
| 62 | 
            +
                    get_changes(1) do
         | 
| 63 | 
            +
                      assert_changes :deleted, d0
         | 
| 64 | 
            +
                    end
         | 
| 65 | 
            +
                  end
         | 
| 66 | 
            +
                end
         | 
| 67 | 
            +
                
         | 
| 68 | 
            +
                should "watch for a file that doesn't exist yet" do
         | 
| 69 | 
            +
                  @tmpdir.touch_dir( "web_app" ) do |d|
         | 
| 70 | 
            +
                    watch( d.join( "restart.txt" ) )
         | 
| 71 | 
            +
                    
         | 
| 72 | 
            +
                    get_changes(0)
         | 
| 73 | 
            +
                    
         | 
| 74 | 
            +
                    restart_file = d.touch( "restart.txt" )
         | 
| 75 | 
            +
                    
         | 
| 76 | 
            +
                    get_changes(1) do
         | 
| 77 | 
            +
                      assert_changes :created, restart_file
         | 
| 78 | 
            +
                    end
         | 
| 79 | 
            +
                    
         | 
| 80 | 
            +
                    restart_file.rm
         | 
| 81 | 
            +
                    
         | 
| 82 | 
            +
                    get_changes(1) do
         | 
| 83 | 
            +
                      assert_changes :deleted, restart_file
         | 
| 84 | 
            +
                    end
         | 
| 85 | 
            +
                    
         | 
| 86 | 
            +
                    get_changes(0)
         | 
| 87 | 
            +
                  end
         | 
| 88 | 
            +
                end
         | 
| 89 | 
            +
                
         | 
| 90 | 
            +
                should "build out a filesystem using DirectoryBuilder" do
         | 
| 91 | 
            +
                  @tmpdir.touch_dir( :ebook ) do |ebook|
         | 
| 92 | 
            +
                    watch ebook
         | 
| 93 | 
            +
                    
         | 
| 94 | 
            +
                    DirectoryBuilder.create( ebook ) do |builder|
         | 
| 95 | 
            +
                      builder.dir( :html ) do
         | 
| 96 | 
            +
                        builder.file "title_page.xhtml", "Make sure we get some neato art to go here."
         | 
| 97 | 
            +
                        builder.file "chapter1.xhtml", "Besta times, worsta times, y'know?"
         | 
| 98 | 
            +
                        builder.file "chapter2.xhtml", "I see a magpie perched on the roof."
         | 
| 99 | 
            +
                      end
         | 
| 100 | 
            +
                      
         | 
| 101 | 
            +
                      builder.dir( :css ) do
         | 
| 102 | 
            +
                        builder.file "main.css", "p{ background-color: painfully-pink}"
         | 
| 103 | 
            +
                        builder.file "title_page.css", "body{ width: 80% }"
         | 
| 104 | 
            +
                      end
         | 
| 105 | 
            +
                      
         | 
| 106 | 
            +
                      builder.dir( :images ) do
         | 
| 107 | 
            +
                        builder.file "cover.png", "We shoulda hired a graphic designer"
         | 
| 108 | 
            +
                      end
         | 
| 109 | 
            +
                    end
         | 
| 110 | 
            +
                    
         | 
| 111 | 
            +
                    html_dir = ebook / :html
         | 
| 112 | 
            +
                    
         | 
| 113 | 
            +
                    images_dir = ebook / :images
         | 
| 114 | 
            +
                    cover_file = images_dir / "cover.png"        
         | 
| 115 | 
            +
                    
         | 
| 116 | 
            +
                    get_changes(9) do 
         | 
| 117 | 
            +
                      assert_changes :created, 
         | 
| 118 | 
            +
                                     #  ebook,      # already existed when the watcher started
         | 
| 119 | 
            +
                                     html_dir, 
         | 
| 120 | 
            +
                                     html_dir / "title_page.xhtml",
         | 
| 121 | 
            +
                                     ebook / :css, 
         | 
| 122 | 
            +
                                     ebook / :css / "main.css",
         | 
| 123 | 
            +
                                     images_dir,
         | 
| 124 | 
            +
                                     cover_file
         | 
| 125 | 
            +
                    end
         | 
| 126 | 
            +
                    
         | 
| 127 | 
            +
                    cover_file.append ", Trevor worked out okay last time, can we use him again?"
         | 
| 128 | 
            +
                    
         | 
| 129 | 
            +
                    # debugger
         | 
| 130 | 
            +
                    
         | 
| 131 | 
            +
                    get_changes(2) do
         | 
| 132 | 
            +
                      assert_changes :modified, cover_file, images_dir, html_dir
         | 
| 133 | 
            +
                    end
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                    images_dir.rm
         | 
| 136 | 
            +
                    
         | 
| 137 | 
            +
                    get_changes(2) do
         | 
| 138 | 
            +
                      assert_changes :deleted, images_dir, cover_file, html_dir
         | 
| 139 | 
            +
                    end
         | 
| 140 | 
            +
                  end
         | 
| 141 | 
            +
                end
         | 
| 142 | 
            +
                
         | 
| 143 | 
            +
                should "only notice changes that aren't excluded by filters" do
         | 
| 144 | 
            +
                  
         | 
| 145 | 
            +
                  @tmpdir.touch_dir( :application_code ) do |code|
         | 
| 146 | 
            +
                    watch( code )
         | 
| 147 | 
            +
                    
         | 
| 148 | 
            +
                    @watcher.filter( notice: /\.cpp$/, ignore: /main.cpp$/ )
         | 
| 149 | 
            +
             | 
| 150 | 
            +
                    f0 = code.touch( "main.cpp" )
         | 
| 151 | 
            +
                    f1 = code.touch( "counter.cpp" )
         | 
| 152 | 
            +
                    
         | 
| 153 | 
            +
                    get_changes( count: 1 ) do
         | 
| 154 | 
            +
                      assert_changes :added, f1
         | 
| 155 | 
            +
                    end
         | 
| 156 | 
            +
                  end
         | 
| 157 | 
            +
                end
         | 
| 158 | 
            +
              end
         | 
| 159 | 
            +
              
         | 
| 160 | 
            +
              def watch( *paths )
         | 
| 161 | 
            +
                @watcher = Watcher.watch( *paths ).sleep_interval( 0.01 )
         | 
| 162 | 
            +
              end
         | 
| 163 | 
            +
              
         | 
| 164 | 
            +
              def get_changes( count: nil, expected: nil, &block )
         | 
| 165 | 
            +
                @changes = @watcher.update
         | 
| 166 | 
            +
                yield if block_given?
         | 
| 167 | 
            +
                assert_change_count( count ) unless count.nil?
         | 
| 168 | 
            +
                assert_change_set( expected ) unless expected.nil?
         | 
| 169 | 
            +
              end
         | 
| 170 | 
            +
              
         | 
| 171 | 
            +
              def assert_changes( status, *paths )
         | 
| 172 | 
            +
                assert_kind_of Hash, @changes
         | 
| 173 | 
            +
                
         | 
| 174 | 
            +
                oopsies = {}
         | 
| 175 | 
            +
                
         | 
| 176 | 
            +
                for path in paths
         | 
| 177 | 
            +
                  path_to_report = path.relative_path_from(@tmpdir).to_s
         | 
| 178 | 
            +
                  
         | 
| 179 | 
            +
                  if @changes.has_key?( path )
         | 
| 180 | 
            +
                    oopsies[path_to_report] = :change_not_reported
         | 
| 181 | 
            +
                  elsif status != @changes[path]
         | 
| 182 | 
            +
                    oopsies[path_to_report] = { :expected => status, :actual => @changes[path] } 
         | 
| 183 | 
            +
                  end
         | 
| 184 | 
            +
                  
         | 
| 185 | 
            +
                  unless oopsies.fwf_blank?
         | 
| 186 | 
            +
                    assert false, "Unexpected:" + oopsies.inspect
         | 
| 187 | 
            +
                  end
         | 
| 188 | 
            +
                end
         | 
| 189 | 
            +
              end
         | 
| 190 | 
            +
              
         | 
| 191 | 
            +
              def assert_change_count( i )
         | 
| 192 | 
            +
                assert defined?( @changes )
         | 
| 193 | 
            +
                assert_kind_of Hash, @changes
         | 
| 194 | 
            +
                assert_length i, @changes
         | 
| 195 | 
            +
              end
         | 
| 196 | 
            +
            end
         |