fun_with_files 0.0.14 → 0.0.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.markdown +15 -3
  3. data/Gemfile +17 -7
  4. data/{README.rdoc → README.markdown} +12 -11
  5. data/Rakefile +3 -3
  6. data/VERSION +1 -1
  7. data/lib/fun_with/files/bootstrapper.rb +87 -0
  8. data/lib/fun_with/files/core_extensions/file.rb +15 -3
  9. data/lib/fun_with/files/core_extensions/set.rb +12 -0
  10. data/lib/fun_with/files/core_extensions/true_class.rb +11 -0
  11. data/lib/fun_with/files/digest_methods.rb +50 -17
  12. data/lib/fun_with/files/directory_builder.rb +9 -4
  13. data/lib/fun_with/files/downloader.rb +29 -16
  14. data/lib/fun_with/files/errors.rb +9 -1
  15. data/lib/fun_with/files/file_manipulation_methods.rb +25 -15
  16. data/lib/fun_with/files/file_orderer.rb +2 -0
  17. data/lib/fun_with/files/file_path.rb +242 -156
  18. data/lib/fun_with/files/file_path_class_methods.rb +23 -2
  19. data/lib/fun_with/files/file_permission_methods.rb +18 -7
  20. data/lib/fun_with/files/file_requirements.rb +63 -7
  21. data/lib/fun_with/files/requirements/manager.rb +104 -0
  22. data/lib/fun_with/files/root_path.rb +3 -3
  23. data/lib/fun_with/files/stat_methods.rb +33 -0
  24. data/lib/fun_with/files/string_behavior.rb +6 -2
  25. data/lib/fun_with/files/utils/byte_size.rb +143 -0
  26. data/lib/fun_with/files/utils/opts.rb +26 -0
  27. data/lib/fun_with/files/utils/succession.rb +47 -0
  28. data/lib/fun_with/files/utils/timestamp.rb +47 -0
  29. data/lib/fun_with/files/utils/timestamp_format.rb +31 -0
  30. data/lib/fun_with/files/watcher.rb +157 -0
  31. data/lib/fun_with/files/watchers/directory_watcher.rb +67 -0
  32. data/lib/fun_with/files/watchers/file_watcher.rb +45 -0
  33. data/lib/fun_with/files/watchers/missing_watcher.rb +23 -0
  34. data/lib/fun_with/files/watchers/node_watcher.rb +44 -0
  35. data/lib/fun_with/testing/assertions/fun_with_files.rb +91 -0
  36. data/lib/fun_with/testing/test_case_extensions.rb +12 -0
  37. data/lib/fun_with_files.rb +5 -31
  38. data/test/helper.rb +13 -5
  39. data/test/test_core_extensions.rb +6 -0
  40. data/test/test_descent.rb +2 -2
  41. data/test/test_directory_builder.rb +29 -10
  42. data/test/test_extension_methods.rb +62 -0
  43. data/test/test_file_manipulation.rb +4 -4
  44. data/test/test_file_path.rb +83 -56
  45. data/test/test_file_requirements.rb +36 -0
  46. data/test/test_fun_with_files.rb +1 -1
  47. data/test/test_fwf_assertions.rb +62 -0
  48. data/test/test_moving_files.rb +111 -0
  49. data/test/test_permission_methods.rb +22 -0
  50. data/test/test_root_path.rb +9 -0
  51. data/test/test_stat_methods.rb +17 -0
  52. data/test/test_timestamping.rb +74 -0
  53. data/test/test_utils_bytesize.rb +71 -0
  54. data/test/test_utils_succession.rb +30 -0
  55. data/test/test_watchers.rb +196 -0
  56. metadata +59 -13
  57. /data/lib/fun_with/files/core_extensions/{false.rb → false_class.rb} +0 -0
  58. /data/lib/fun_with/files/core_extensions/{nil.rb → nil_class.rb} +0 -0
@@ -0,0 +1,157 @@
1
+ # You want to watch a list of files or directories for changes
2
+ # (files created, deleted, or modified), and then return a... list?
3
+ # of changes.
4
+ #
5
+ # Tricky part is, what constitutes a "change" for a directory.
6
+ # or a file, for that matter.
7
+ #
8
+ # Cool expansion: customize the sorts of changes that trigger actions.
9
+ # You can already do that to some extent with the user-code that the
10
+ # change list is delivered to
11
+ #
12
+ # usr/ (modified, watched)
13
+ # bin/ (modified)
14
+ # new_directory/ (created)
15
+ # README.txt (created)
16
+ # bash (unchanged)
17
+ #
18
+ # lib/ (modified)
19
+ # libgpg.so (unchanged)
20
+ # libmysql.so (deleted)
21
+ # libzip.so (modified)
22
+ # libjpeg.so (file_created)
23
+ # you_have_been_hacked_by_chinese.txt (file_created)
24
+ # cache/ (deleted)
25
+ # firefox/ (deleted)
26
+ # cached_item.jpg (deleted)
27
+ # cached_folder/ (deleted)
28
+ # cache_file.csv (deleted)
29
+ #
30
+ # When you find a change in a subdirector/file, the :modified status
31
+ # propagates up the tree.
32
+ # Feels like a job for a visitor.
33
+ #
34
+ # If you create the top-level watcher, it could create any sub-watchers
35
+ # for the files and folders. It asks its watchers to update their
36
+ # statuses and report back.
37
+ #
38
+ # But the top-level one should know that it's the top level, so it
39
+ # shouldn't be deleting its watchers that might be, for example,
40
+ # waiting for a file to come into being.
41
+ #
42
+ # Hence, anyone using this code probably ought to stick to using the main Watcher
43
+ # class, and not worry about the ones it uses in the background
44
+ #
45
+ # Filters can be added
46
+ module FunWith
47
+ module Files
48
+ class Watcher
49
+ def self.watch( *paths, interval: 1.0, notice: [], ignore: [], &block )
50
+ watcher = self.new( paths ).sleep_interval( interval ).filter( notice: notice, ignore: ignore )
51
+
52
+ if block_given?
53
+ watcher.watch( &block )
54
+ else
55
+ watcher
56
+ end
57
+ end
58
+
59
+ def self.factory( path )
60
+ path = path.fwf_filepath
61
+
62
+ if path.exist?
63
+ if path.directory?
64
+ Watchers::DirectoryWatcher.new( path )
65
+ elsif path.file?
66
+ Watchers::FileWatcher.new( path )
67
+ end
68
+ else
69
+ Watchers::MissingWatcher.new( path )
70
+ end
71
+ end
72
+
73
+ def initialize( paths )
74
+ @sleep_interval = 1.0
75
+ @notice_filters = []
76
+ @ignore_filters = []
77
+
78
+ # Create a watcher for every single thing that we're
79
+ # asking it to watch
80
+ @watchers = paths.inject({}) do |watchers, path|
81
+ watchers[path.fwf_filepath] = self.class.factory( path )
82
+ watchers
83
+ end
84
+ end
85
+
86
+ def sleep_interval( i )
87
+ @sleep_interval = i
88
+ self
89
+ end
90
+
91
+ def watch( &block )
92
+ while true
93
+ sleep( @sleep_interval )
94
+ yield self.update
95
+ end
96
+ end
97
+
98
+ def filter( notice: [], ignore: [] )
99
+ @notice_filters += [notice].flatten
100
+ @ignore_filters += [ignore].flatten
101
+
102
+ self
103
+ end
104
+
105
+ # returns a hash of the changes that have happened in the file system being monitored,
106
+ def update
107
+ {}.tap do |changes|
108
+ for path, watcher in @watchers
109
+ changes.merge!( watcher.update )
110
+ replace_watcher( path, changes[path] ) # a DirectoryWatcher might need to be replaced with a MissingWatcher, for example, or vice-versa
111
+
112
+ # corner case: if a directory is created, everything created under the directory
113
+ # is deemed to have also been created at the same time
114
+ if path.directory? && changes[path] == :created
115
+ changes.merge!( path.glob(:all).inject({}){ |memo,path| memo[path] = :created ; memo } )
116
+ end
117
+ end
118
+
119
+ apply_filters( changes )
120
+ end
121
+ end
122
+
123
+ def replace_watcher( path, change )
124
+ case change
125
+ when nil
126
+ # didn't change
127
+ when :deleted, :created
128
+ @watchers[path] = self.class.factory( path )
129
+ end
130
+ end
131
+
132
+ #
133
+ def apply_filters( changes )
134
+ apply_notice_filters( changes )
135
+ apply_ignore_filters( changes )
136
+ changes
137
+ end
138
+
139
+ def apply_notice_filters( changes )
140
+ for filter in @notice_filters
141
+ for path in changes.keys
142
+ changes.delete( path ) if path !~ filter
143
+ end
144
+ end
145
+ end
146
+
147
+ def apply_ignore_filters( changes )
148
+ for filter in @ignore_filters
149
+ for path in changes.keys
150
+ changes.delete( path ) if path =~ filter
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
157
+
@@ -0,0 +1,67 @@
1
+ module FunWith
2
+ module Files
3
+ module Watchers
4
+ class DirectoryWatcher < NodeWatcher
5
+ def initialize( path )
6
+ set_path( path )
7
+ @watchers = create_watchers( self.path.entries )
8
+ end
9
+
10
+
11
+ # returns a hash of changes
12
+ def update
13
+ new_changeset do
14
+ if self.path.exist?
15
+ update_existing_files
16
+ find_new_files
17
+ else
18
+ # If the directory is gone, you can assume the same is true
19
+ # for all the files it held.
20
+ report_files( self.all_paths, :deleted )
21
+ end
22
+ end
23
+ end
24
+
25
+ def update_existing_files
26
+ # first, check on the files we're supposed to be keeping track of
27
+ for path, watcher in @watchers
28
+ @changes[path] = :deleted unless path.exist?
29
+ @changes.merge!( watcher.update )
30
+
31
+ # While the main Watcher will continue to monitor the places it's
32
+ # been told, even if they're missing, the subwatchers just disappear
33
+ # when the files they're watching do.
34
+ @watchers.delete( path ) unless path.exist?
35
+ end
36
+ end
37
+
38
+ def find_new_files
39
+ # next, get the updated list of files/folders beneath this directory
40
+ current_paths = self.path.entries
41
+
42
+ for path in current_paths
43
+ unless @watchers.has_key?( path )
44
+ w = Watcher.factory( path )
45
+
46
+ report_files( w.all_paths, :created )
47
+
48
+ @watchers[path] = w
49
+ end
50
+ end
51
+ end
52
+
53
+ # modify the current list of changes by adding "deleted" for
54
+ # every file/folder below this one.
55
+ def report_files( paths, status )
56
+ for path in paths
57
+ @changes[path] = status
58
+ end
59
+ end
60
+
61
+ def all_paths
62
+ @watchers.map{|path, watcher| watcher.all_paths }.flatten + [self.path]
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,45 @@
1
+
2
+ module FunWith
3
+ module Files
4
+ module Watchers
5
+ class FileWatcher < NodeWatcher
6
+ attr_accessor :last_modified
7
+
8
+ def initialize( path )
9
+ set_path( path )
10
+ refresh_last_modified
11
+ end
12
+
13
+ def refresh_last_modified
14
+ self.last_modified = self.path.stat.mtime if self.path.exist?
15
+ end
16
+
17
+ def modified?
18
+ self.path.exist? && self.last_modified < self.path.stat.mtime
19
+ end
20
+
21
+ def deleted?
22
+ ! self.path.exist?
23
+ end
24
+
25
+ def update
26
+ if deleted?
27
+ { self.path => :deleted }
28
+ elsif modified?
29
+ refresh_last_modified
30
+ { self.path => :modified }
31
+ else
32
+ {}
33
+ end
34
+ end
35
+
36
+ # returns all paths below it in the hierarchy, including
37
+ # the path of the node itself. In this case, there's
38
+ # only one path to return.
39
+ def all_paths
40
+ [self.path]
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,23 @@
1
+ module FunWith
2
+ module Files
3
+ module Watchers
4
+ # Watches a path where nothing currently exists, and reports a change if
5
+ # something appears there.
6
+ class MissingWatcher < NodeWatcher
7
+ def initialize( path )
8
+ set_path( path )
9
+ end
10
+
11
+ # The fact that the watcher now needs to be replaced with a File/DirectoryWatcher
12
+ # must be handled elsewhere.
13
+ def update
14
+ self.path.exist? ? {self.path => :created } : {}
15
+ end
16
+
17
+ def all_paths
18
+ []
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,44 @@
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
13
+ module FunWith
14
+ module Files
15
+ module Watchers
16
+ class NodeWatcher
17
+ attr_accessor :path
18
+
19
+ def set_path( path )
20
+ self.path = path.fwf_filepath
21
+ end
22
+
23
+ def create_watchers( paths )
24
+ {}.tap do |watchers|
25
+ for path in paths
26
+ watchers[path.fwf_filepath] = Watcher.factory( path )
27
+ end
28
+ end
29
+ end
30
+
31
+ # sets up an object variable for changes, then clears it and returns
32
+ # the changes. I got sick of passing the changes hash around.
33
+ def new_changeset( &block )
34
+ @changes = {}
35
+ yield
36
+
37
+ changes = @changes
38
+ @changes = {}
39
+ changes
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,91 @@
1
+ module FunWith
2
+ module Testing
3
+ module Assertions
4
+ module FunWithFiles
5
+ # The object given must be an instance of class FilePath
6
+ def assert_fwf_filepath( file, msg = nil )
7
+ msg = message(msg){ "File <#{file}> should be a FunWith::Files::FilePath" }
8
+ assert_kind_of FunWith::Files::FilePath, file, msg
9
+ end
10
+
11
+ # The object given is an instance of class FilePath, and points to
12
+ # a file that exists.
13
+ def assert_file( file, msg = nil )
14
+ assert_fwf_filepath( file, message(nil){ "...is not a file." } )
15
+
16
+ msg = message(msg){ "File should exist at <#{file}>." }
17
+ assert file.file?, msg
18
+ end
19
+
20
+ # The object given is a filepath, but doesn't point to
21
+ # an existing file or directory.
22
+ def assert_no_file( file, msg = nil )
23
+ assert_fwf_filepath( file, message )
24
+ msg = message(msg){ "No file/directory should exist at <#{file}>." }
25
+ refute file.file?, msg
26
+ end
27
+
28
+ # The object given is a filepath, and points to a directory
29
+ def assert_directory( file, msg = nil )
30
+ assert_fwf_filepath( file, msg )
31
+ msg = message(msg){ "<#{file}> should be a directory." }
32
+ assert file.directory?, msg
33
+ end
34
+
35
+ # The object given is a filepath, but doesn't point to a directory.
36
+ def assert_not_directory( file, msg = nil )
37
+ assert_fwf_filepath( file, message )
38
+ msg = message(msg){ "<#{file}> shouldn't be a directory." }
39
+ refute file.directory?
40
+ end
41
+
42
+ # The object given is a filepath.
43
+ # It points to a file that exists.
44
+ # That file is empty.
45
+ def assert_empty_file( file, msg = nil )
46
+ assert_fwf_filepath( file )
47
+ msg = message(msg){ "Empty file should exist at <#{file}>." }
48
+ assert file.file? && file.empty?, msg
49
+ end
50
+
51
+ # The object given is a filepath.
52
+ # It points to a directory that exists.
53
+ # That directory is empty.
54
+ def assert_empty_directory( file, msg = nil )
55
+ assert_fwf_filepath( file )
56
+ msg = message(msg){ "Empty directory should exist at <#{file}>." }
57
+ assert file.directory? && file.empty?, msg
58
+ end
59
+
60
+
61
+ # The object given is a filepath.
62
+ # It points to a file that exists.
63
+ # That file contains content.
64
+ def assert_file_has_content( file, msg = nil )
65
+ assert_fwf_filepath( file, message )
66
+ msg = message(msg){ "File should exist at <#{file}>, and have content." }
67
+ assert file.exist?, msg.call + "(file does not exist)"
68
+ assert file.file?, msg.call + "(not a file)"
69
+ refute file.empty?, msg.call + "(file is not empty)"
70
+ end
71
+
72
+ alias :assert_file_not_empty :assert_file_has_content
73
+
74
+
75
+ def assert_file_contents( file, content, msg = nil )
76
+ assert_file( file )
77
+
78
+ case content
79
+ when String
80
+ # message = build_message( message, "File <#{file}> contents should be #{content[0..99].inspect}#{'...(truncated)' if content.length > 100}" )
81
+ assert_equal( content, file.read, msg )
82
+ when Regexp
83
+ assert_match( content, file.read, msg )
84
+ end
85
+ end
86
+
87
+
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,12 @@
1
+ # The bulk of FunWith::Testing::TestCase can be found in the fun_with_testing gem.
2
+
3
+ module FunWith
4
+ module Testing
5
+ module TestCaseExtensions
6
+ def install_fun_with_files_assertions
7
+ include FunWith::Testing::Assertions::Basics # some of the FWF assertions rely on these
8
+ include FunWith::Testing::Assertions::FunWithFiles
9
+ end
10
+ end
11
+ end
12
+ end
@@ -1,38 +1,12 @@
1
1
  require 'xdg'
2
2
  require 'digest' # stdlib
3
3
  require 'pathname' # stdlib
4
+ require 'set'
4
5
  require 'tmpdir' # Dir.tmpdir
5
6
 
7
+ require 'debug'
6
8
 
7
- for fil in ["string", "array", "false", "hash", "nil", "object"]
8
- require_relative File.join( "fun_with", "files", "core_extensions", fil )
9
- end
9
+ require_relative 'fun_with/files/bootstrapper'
10
+ # sets up everything needed to load .requir(), which loads everything else
11
+ FunWith::Files::Bootstrapper.bootstrap
10
12
 
11
- for klass in ["String", "Object", "NilClass", "Hash", "FalseClass", "Array"]
12
- Kernel.const_get(klass).send( :include, FunWith::Files::CoreExtensions.const_get(klass))
13
- end
14
-
15
-
16
- for fil in ["file_path", "string_behavior", "file_manipulation_methods", "file_permission_methods", "digest_methods", "file_requirements"]
17
- require_relative File.join( "fun_with", "files", fil )
18
- end
19
-
20
-
21
- # These have some FilePath methods required by .requir()
22
- for mod in [ FunWith::Files::StringBehavior,
23
- FunWith::Files::FileManipulationMethods,
24
- FunWith::Files::FilePermissionMethods,
25
- FunWith::Files::DigestMethods,
26
- FunWith::Files::FileRequirements ]
27
- FunWith::Files::FilePath.send( :include, mod )
28
- end
29
-
30
- lib_dir = File.dirname(__FILE__).fwf_filepath( "fun_with" )
31
-
32
- # And requir() everything else
33
- lib_dir.requir
34
-
35
- FunWith::Files::RootPath.rootify( FunWith::Files, __FILE__.fwf_filepath.dirname.up )
36
- FunWith::Files::FilePath.extend( FunWith::Files::FilePathClassMethods )
37
-
38
- FunWith::Files.extend( FunWith::Files::GemAPI )
data/test/helper.rb CHANGED
@@ -21,13 +21,21 @@ require 'fun_with_files'
21
21
 
22
22
  class FunWith::Files::TestCase < FunWith::Testing::TestCase
23
23
  include FunWith::Files
24
- include FunWith::Testing::Assertions::FunWithFiles
25
- include FunWith::Testing::Assertions::Basics
24
+ include FunWith::Files::Errors
25
+
26
+
27
+ self.install_fun_with_files_assertions
28
+ # include FunWith::Testing::Assertions::FunWithFiles
29
+ # include FunWith::Testing::Assertions::Basics
26
30
 
27
31
  def tmpdir( &block )
28
- FilePath.tmpdir do |d|
29
- @tmpdir = d
30
- yield
32
+ if block_given?
33
+ FilePath.tmpdir do |d|
34
+ @tmpdir = d
35
+ yield
36
+ end
37
+ else
38
+ @tmpdir = FilePath.tmpdir # remember to remove the directory when you're done
31
39
  end
32
40
  end
33
41
 
@@ -26,6 +26,12 @@ class TestCoreExtensions < FunWith::Files::TestCase
26
26
  should "fwf_blank? nicely." do
27
27
  assert_equal false, { 1 => 2 }.fwf_blank?
28
28
  assert_equal true, {}.fwf_blank?
29
+ assert_equal true, true.fwf_present?
30
+ end
31
+
32
+ should "respond to fwf_filepath" do
33
+ assert_respond_to ".", :fwf_filepath
34
+ assert_respond_to ".".fwf_filepath, :fwf_filepath
29
35
  end
30
36
  end
31
37
  end
data/test/test_descent.rb CHANGED
@@ -7,11 +7,11 @@ class TestDescent < FunWith::Files::TestCase
7
7
  ascent = []
8
8
  descent = []
9
9
 
10
- FunWith::Files.root.ascend do |path|
10
+ root.ascend do |path|
11
11
  ascent << path
12
12
  end
13
13
 
14
- FunWith::Files.root.descend do |path|
14
+ root.descend do |path|
15
15
  descent << path
16
16
  end
17
17
 
@@ -54,7 +54,7 @@ class TestDirectoryBuilder < FunWith::Files::TestCase
54
54
  gemfile = b.current_path.join("Gemfile")
55
55
  assert gemfile.exist?
56
56
  assert !gemfile.zero?
57
- assert_equal 1, gemfile.grep( /jeweler/ ).length
57
+ assert_equal 1, gemfile.grep( /fun_with_testing/ ).length
58
58
  end
59
59
  end
60
60
 
@@ -70,18 +70,37 @@ class TestDirectoryBuilder < FunWith::Files::TestCase
70
70
  should "download random crap from all over the Internet" do
71
71
  if_internet_works do
72
72
  DirectoryBuilder.tmpdir do |b|
73
- gist_url = "http://bannedsorcery.com/downloads/testfile.txt"
74
- gist_text = "This is a file\n==============\n\n**silent**: But _bold_! [Link](http://slashdot.org)\n"
75
- b.download( gist_url, "gist.txt" )
73
+ # The file Bryce uses on Github to prove to Keybase that he owns this Github account
74
+ # I used to host a test file on my own site, but apparently if you stop paying DigitalOcean
75
+ # for a few measly months your website goes away. Github will probably provide a more
76
+ # stable target.
77
+ url = "https://gist.githubusercontent.com/darthschmoo/ac3ca60338ed41e87b94448f9e851fd3/raw" +
78
+ "/3cba6b60b552266f4d5aa92d307ef2cda0cf228b/fun_with_files.download.txt"
79
+
80
+ dest_file = "download.01.txt"
81
+ dest_file2 = "download.02.txt"
82
+
83
+ downloaded_text = "You have successfully downloaded a file. Huzzah!"
84
+ downloaded_text_md5 = "2e9d3a924ea36c860c3dd491166ec1ce"
85
+ downloaded_text_sha1 = "d9be1d5b5c8bd1de6b1dcb99e02cab8e35ed9659"
86
+ downloaded_text_sha256 = "dc9a6e5d571b39b9754b9592a3b586db8186121d37ec72f7fcbf45241cc43aa6"
87
+
88
+ b.download( url, dest_file,
89
+ :md5 => downloaded_text_md5,
90
+ :sha1 => downloaded_text_sha1,
91
+ :sha256 => downloaded_text_sha256
92
+ )
93
+
76
94
 
77
- b.file( "gist.txt.2" ) do
78
- b.download( gist_url )
95
+ b.file( dest_file2 ) do
96
+ b.download( url )
79
97
  end
80
98
 
81
99
  assert b.current_file.nil?
82
- assert b.current_path.join("gist.txt").exist?
83
- assert b.current_path.join("gist.txt.2").exist?
84
- assert_equal gist_text, b.current_path.join("gist.txt").read
100
+ assert b.current_path.join( dest_file ).exist?
101
+ assert b.current_path.join( dest_file2 ).exist?
102
+ assert_equal downloaded_text, b.current_path.join( dest_file ).read
103
+ assert_equal downloaded_text, b.current_path.join( dest_file2 ).read
85
104
  end
86
105
  end
87
106
  end
@@ -112,7 +131,7 @@ class TestDirectoryBuilder < FunWith::Files::TestCase
112
131
  end
113
132
  end
114
133
 
115
- assert "Hello", b.current_path.join("earth", "air", "fire", "water", "hello.txt").read
134
+ assert_equal "Hello", b.current_path.join("earth", "air", "fire", "water", "hello.txt").read
116
135
 
117
136
  b.dir( "fire", "water", "earth", "air" ) do
118
137
  assert b.current_path.exist?
@@ -0,0 +1,62 @@
1
+ require 'helper'
2
+
3
+ class TestExtensionMethods < FunWith::Files::TestCase
4
+ context "Testing extension methods" do
5
+ setup do
6
+ @bash = "/bin/bash".fwf_filepath
7
+ @log = "/var/log/apache/access.log".fwf_filepath
8
+ @older_log = "/var/log/apache/access.log.9"
9
+ end
10
+
11
+ context "Testing ext?()" do
12
+ should "correctly identify the extension" do
13
+ assert_true @bash.ext?("")
14
+
15
+ assert_true @log.ext?(".log")
16
+ assert_true @log.ext?(:log)
17
+ assert_false @log.ext?(".blog")
18
+ assert_true @log.ext?(:blog, :flog, :frog, :log)
19
+ end
20
+
21
+ should "run a block if the extension matches" do
22
+ var = 5
23
+
24
+ @log.ext?(:log) do |f|
25
+ assert_equal @log, f
26
+ var = 6
27
+ end
28
+
29
+ assert_equal 6, var
30
+ end
31
+ end
32
+
33
+ context "Testing file.ext()" do
34
+
35
+ should "draw a blank on bash file" do
36
+ assert_blank @bash.ext
37
+ assert_equal "", @bash.ext
38
+ end
39
+
40
+ should "add an extension when an extension is given as an argument" do
41
+ bash2 = @bash.ext( 12 )
42
+
43
+ assert_fwf_filepath bash2
44
+ assert_equal "12", bash2.ext
45
+
46
+ for ext in [:exe, "exe"]
47
+ bash2 = @bash.ext( ext )
48
+ assert_fwf_filepath bash2
49
+ assert_equal "exe", bash2.ext
50
+ end
51
+ end
52
+
53
+ should "add multiple extensions when multiple extensions are given" do
54
+ for args in [ [:tar, :gz], ["tar", "gz"], [".tar", ".gz"] ]
55
+ bash2 = @bash.ext( *args )
56
+ assert_equal "gz", bash2.ext
57
+ assert_equal "/bin/bash.tar.gz", bash2.path
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end