file-find 0.4.0 → 0.5.0
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/{CHANGES → CHANGES.md} +39 -19
- data/Gemfile +3 -0
- data/LICENSE +177 -0
- data/{MANIFEST → MANIFEST.md} +4 -2
- data/README.md +109 -0
- data/Rakefile +4 -6
- data/file-find.gemspec +13 -5
- data/lib/file/find.rb +9 -6
- data/spec/file_find_spec.rb +613 -0
- metadata +48 -30
- metadata.gz.sig +0 -0
- data/README +0 -96
- data/test/test_file_find.rb +0 -568
data/Rakefile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'rake'
|
2
2
|
require 'rake/clean'
|
3
|
-
require '
|
3
|
+
require 'rspec/core/rake_task'
|
4
4
|
|
5
5
|
CLEAN.include("**/*.gem", "**/*.rbc", "**/link*")
|
6
6
|
|
@@ -21,10 +21,8 @@ namespace :gem do
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
t.warning = true
|
27
|
-
t.verbose = true
|
24
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
25
|
+
t.pattern = ['spec/file_find_spec.rb']
|
28
26
|
end
|
29
27
|
|
30
|
-
task :default => :
|
28
|
+
task :default => :spec
|
data/file-find.gemspec
CHANGED
@@ -2,20 +2,28 @@ require 'rubygems'
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |spec|
|
4
4
|
spec.name = 'file-find'
|
5
|
-
spec.version = '0.
|
5
|
+
spec.version = '0.5.0'
|
6
6
|
spec.author = 'Daniel Berger'
|
7
7
|
spec.license = 'Apache-2.0'
|
8
8
|
spec.summary = 'A better way to find files'
|
9
9
|
spec.email = 'djberg96@gmail.com'
|
10
10
|
spec.homepage = 'http://github.com/djberg96/file-find'
|
11
|
-
spec.test_file = '
|
11
|
+
spec.test_file = 'spec/file_find_spec.rb'
|
12
12
|
spec.files = Dir['**/*'].reject{ |f| f.include?('git') }
|
13
13
|
spec.cert_chain = Dir['certs/*']
|
14
14
|
|
15
|
-
spec.
|
15
|
+
spec.metadata = {
|
16
|
+
'homepage_uri' => 'https://github.com/djberg96/file-find',
|
17
|
+
'bug_tracker_uri' => 'https://github.com/djberg96/file-find/issues',
|
18
|
+
'changelog_uri' => 'https://github.com/djberg96/file-find/blob/master/CHANGES.md',
|
19
|
+
'documentation_uri' => 'https://github.com/djberg96/file-find/wiki',
|
20
|
+
'source_code_uri' => 'https://github.com/djberg96/file-find',
|
21
|
+
'wiki_uri' => 'https://github.com/djberg96/file-find/wiki'
|
22
|
+
}
|
16
23
|
|
17
|
-
spec.add_dependency('sys-admin', '
|
18
|
-
spec.add_development_dependency('
|
24
|
+
spec.add_dependency('sys-admin', '~> 1.7')
|
25
|
+
spec.add_development_dependency('rspec', '~> 3.9')
|
26
|
+
spec.add_development_dependency('fakefs', '~> 1.3')
|
19
27
|
spec.add_development_dependency('rake')
|
20
28
|
|
21
29
|
spec.description = <<-EOF
|
data/lib/file/find.rb
CHANGED
@@ -9,7 +9,7 @@ end
|
|
9
9
|
|
10
10
|
class File::Find
|
11
11
|
# The version of the file-find library
|
12
|
-
VERSION = '0.
|
12
|
+
VERSION = '0.5.0'.freeze
|
13
13
|
|
14
14
|
# :stopdoc:
|
15
15
|
VALID_OPTIONS = %w[
|
@@ -235,12 +235,15 @@ class File::Find
|
|
235
235
|
rescue Errno::ENOENT, Errno::EACCES
|
236
236
|
next
|
237
237
|
rescue Errno::ELOOP
|
238
|
-
stat_method
|
239
|
-
|
238
|
+
if stat_method.to_s != 'lstat'
|
239
|
+
stat_method = :lstat # Handle recursive symlinks
|
240
|
+
retry
|
241
|
+
end
|
240
242
|
end
|
241
243
|
|
242
|
-
# We need to escape any brackets in the directory name.
|
243
|
-
|
244
|
+
# We need to escape any brackets in the directory name, unless already escaped.
|
245
|
+
temp = File.dirname(file).gsub(/(?<!\\)([\[\]])/, '\\\\\1')
|
246
|
+
glob = File.join(temp, @name)
|
244
247
|
|
245
248
|
# Dir[] doesn't like backslashes
|
246
249
|
if File::ALT_SEPARATOR
|
@@ -257,7 +260,7 @@ class File::Find
|
|
257
260
|
end
|
258
261
|
|
259
262
|
if @maxdepth || @mindepth
|
260
|
-
file_depth = file.split(File::SEPARATOR).length
|
263
|
+
file_depth = file.split(File::SEPARATOR).reject{ |e| e.size.zero? }.length
|
261
264
|
current_base_path = [@path].flatten.find{ |tpath| file.include?(tpath) }
|
262
265
|
path_depth = current_base_path.split(File::SEPARATOR).length
|
263
266
|
|
@@ -0,0 +1,613 @@
|
|
1
|
+
######################################################################
|
2
|
+
# file_find_spec.rb
|
3
|
+
#
|
4
|
+
# Test case for the file-find library. You should run this via the
|
5
|
+
# 'rake spec' task.
|
6
|
+
######################################################################
|
7
|
+
require 'rspec'
|
8
|
+
require 'file-find'
|
9
|
+
require 'sys-admin'
|
10
|
+
require 'pp' # stops fakefs class mismatch errors
|
11
|
+
require 'tmpdir'
|
12
|
+
require 'fakefs/spec_helpers'
|
13
|
+
|
14
|
+
RSpec.describe File::Find do
|
15
|
+
include FakeFS::SpecHelpers
|
16
|
+
|
17
|
+
let(:windows) { File::ALT_SEPARATOR }
|
18
|
+
let(:ruby_file) { 'file_find_test.rb' }
|
19
|
+
let(:doc_file) { 'file_find_test.doc' }
|
20
|
+
let(:text_file1) { 'file_find_test1.txt' }
|
21
|
+
let(:text_file2) { 'file_find_test2.txt' }
|
22
|
+
|
23
|
+
let(:rule) { File::Find.new }
|
24
|
+
let(:txt_rule) { File::Find.new(:name => '*.txt') }
|
25
|
+
|
26
|
+
before(:all) do
|
27
|
+
@loguser = Sys::Admin.get_user(Sys::Admin.get_login)
|
28
|
+
@logroup = Sys::Admin.get_group(@loguser.gid)
|
29
|
+
end
|
30
|
+
|
31
|
+
context "constants", :constants => true do
|
32
|
+
example "version constant is set to expected value" do
|
33
|
+
expect(File::Find::VERSION).to eq('0.5.0')
|
34
|
+
expect(File::Find::VERSION).to be_frozen
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "path", :path => true do
|
39
|
+
example "path accessor basic functionality" do
|
40
|
+
expect(rule).to respond_to(:path)
|
41
|
+
expect(rule).to respond_to(:path=)
|
42
|
+
end
|
43
|
+
|
44
|
+
example "path method returns expected value" do
|
45
|
+
expect(rule.path).to eq(Dir.pwd)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "options", :options => true do
|
50
|
+
example "options accessor basic functionality" do
|
51
|
+
expect(rule).to respond_to(:options)
|
52
|
+
expect(rule).to respond_to(:options=)
|
53
|
+
end
|
54
|
+
|
55
|
+
example "options method returns expected value" do
|
56
|
+
expect(txt_rule.options).to eq({:name => '*.txt'})
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "atime", :atime => true do
|
61
|
+
before do
|
62
|
+
FileUtils.touch(ruby_file)
|
63
|
+
end
|
64
|
+
|
65
|
+
example "atime accessor basic functionality" do
|
66
|
+
expect(rule).to respond_to(:atime)
|
67
|
+
expect(rule).to respond_to(:atime=)
|
68
|
+
end
|
69
|
+
|
70
|
+
example "atime method returns expected default value" do
|
71
|
+
expect(rule.atime).to be_nil
|
72
|
+
end
|
73
|
+
|
74
|
+
example "find with atime option works as expected" do
|
75
|
+
rule1 = File::Find.new(:name => "*.rb", :atime => 0)
|
76
|
+
rule2 = File::Find.new(:name => "*.rb", :atime => 1)
|
77
|
+
|
78
|
+
expect(rule1.find.empty?).to be false
|
79
|
+
expect(rule2.find.empty?).to be true
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context "ctime", :ctime => true do
|
84
|
+
before do
|
85
|
+
FileUtils.touch(ruby_file)
|
86
|
+
end
|
87
|
+
|
88
|
+
example "ctime accessor basic functionality" do
|
89
|
+
expect(rule).to respond_to(:ctime)
|
90
|
+
expect(rule).to respond_to(:ctime=)
|
91
|
+
end
|
92
|
+
|
93
|
+
example "ctime method returns expected default value" do
|
94
|
+
expect(rule.ctime).to be_nil
|
95
|
+
end
|
96
|
+
|
97
|
+
example "find with ctime option works as expected" do
|
98
|
+
rule1 = File::Find.new(:name => "*.rb", :ctime => 0)
|
99
|
+
rule2 = File::Find.new(:name => "*.rb", :ctime => 1)
|
100
|
+
|
101
|
+
expect(rule1.find.empty?).to be false
|
102
|
+
expect(rule2.find.empty?).to be true
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context "find", :find => true do
|
107
|
+
example "find method basic functionality" do
|
108
|
+
expect(rule).to respond_to(:find)
|
109
|
+
expect{ rule.find }.not_to raise_error
|
110
|
+
end
|
111
|
+
|
112
|
+
example "find method returns expected value" do
|
113
|
+
expect(rule.find).to be_kind_of(Array)
|
114
|
+
expect(rule.find{}).to be_nil
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context "filetest", :filetest => true do
|
119
|
+
before do
|
120
|
+
FileUtils.touch(doc_file, :mode => 0644)
|
121
|
+
end
|
122
|
+
|
123
|
+
example "filetest accessor basic functionality" do
|
124
|
+
expect(rule).to respond_to(:filetest)
|
125
|
+
expect(rule).to respond_to(:filetest=)
|
126
|
+
expect{ rule.filetest }.not_to raise_error
|
127
|
+
end
|
128
|
+
|
129
|
+
example "filetest method returns expected value" do
|
130
|
+
expect(rule.filetest).to be_kind_of(Array)
|
131
|
+
end
|
132
|
+
|
133
|
+
example "valid filetest options work as expected" do
|
134
|
+
expect{ File::Find.new(:readable? => true) }.not_to raise_error
|
135
|
+
expect{ File::Find.new(:writable? => true) }.not_to raise_error
|
136
|
+
end
|
137
|
+
|
138
|
+
example "find method works with filetest option" do
|
139
|
+
rule = File::Find.new(:name => "*.doc", :writable? => true)
|
140
|
+
|
141
|
+
expect(rule.find.map{ |f| File.basename(f) }).to eq([doc_file])
|
142
|
+
FileUtils.chmod(0444, doc_file)
|
143
|
+
expect(rule.find).to eq([])
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context "mtime", :mtime => true do
|
148
|
+
before do
|
149
|
+
FileUtils.touch(ruby_file)
|
150
|
+
end
|
151
|
+
|
152
|
+
example "mtime accessor basic functionality" do
|
153
|
+
expect(rule).to respond_to(:mtime)
|
154
|
+
expect(rule).to respond_to(:mtime=)
|
155
|
+
end
|
156
|
+
|
157
|
+
example "mtime method returns expected default value" do
|
158
|
+
expect(rule.mtime).to be_nil
|
159
|
+
end
|
160
|
+
|
161
|
+
example "find with mtime option works as expected" do
|
162
|
+
rule1 = File::Find.new(:name => "*.rb", :mtime => 0)
|
163
|
+
rule2 = File::Find.new(:name => "*.rb", :mtime => 1)
|
164
|
+
|
165
|
+
expect(rule1.find.empty?).to be false
|
166
|
+
expect(rule2.find.empty?).to be true
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
context "ftype", :ftype => true do
|
171
|
+
before do
|
172
|
+
FileUtils.touch(ruby_file)
|
173
|
+
end
|
174
|
+
|
175
|
+
example "ftype accessor basic functionality" do
|
176
|
+
expect(rule).to respond_to(:ftype)
|
177
|
+
expect(rule).to respond_to(:ftype=)
|
178
|
+
end
|
179
|
+
|
180
|
+
example "ftype method returns expected default value" do
|
181
|
+
expect(rule.ftype).to be_nil
|
182
|
+
end
|
183
|
+
|
184
|
+
example "ftype method works as expected" do
|
185
|
+
rule1 = File::Find.new(:name => "*.rb", :ftype => "file")
|
186
|
+
rule2 = File::Find.new(:name => "*.rb", :ftype => "characterSpecial")
|
187
|
+
|
188
|
+
expect(rule1.find.empty?).to be false
|
189
|
+
expect(rule2.find.empty?).to be true
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
context "group", :group => true do
|
194
|
+
before do
|
195
|
+
FileUtils.touch(doc_file)
|
196
|
+
end
|
197
|
+
|
198
|
+
example "group accessor basic functionality" do
|
199
|
+
expect(rule).to respond_to(:group)
|
200
|
+
expect(rule).to respond_to(:group=)
|
201
|
+
end
|
202
|
+
|
203
|
+
example "group method returns expected default value" do
|
204
|
+
expect(rule.group).to be_nil
|
205
|
+
end
|
206
|
+
|
207
|
+
# TODO: Update example for Windows
|
208
|
+
example "find with numeric group id works as expected" do
|
209
|
+
skip 'group example skipped on MS Windows' if windows
|
210
|
+
rule = File::Find.new(:name => '*.doc', :group => @loguser.gid)
|
211
|
+
expect(rule.find).to eq([File.expand_path(doc_file)])
|
212
|
+
end
|
213
|
+
|
214
|
+
# TODO: Update example for Windows
|
215
|
+
example "find with string group id works as expected" do
|
216
|
+
skip 'group example skipped on MS Windows' if windows
|
217
|
+
|
218
|
+
rule = File::Find.new(:name => '*.doc', :group => @logroup.name)
|
219
|
+
expect(rule.find).to eq([File.expand_path(doc_file)])
|
220
|
+
end
|
221
|
+
|
222
|
+
example "find with bogus group returns empty results" do
|
223
|
+
skip 'group test skipped on MS Windows' if windows
|
224
|
+
|
225
|
+
rule1 = File::Find.new(:name => '*.doc', :group => 'totallybogus')
|
226
|
+
rule2 = File::Find.new(:name => '*.doc', :group => 99999999)
|
227
|
+
expect(rule1.find).to eq([])
|
228
|
+
expect(rule2.find).to eq([])
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
context "inum", :inum => true do
|
233
|
+
example "inum accessor basic functionality" do
|
234
|
+
expect(rule).to respond_to(:inum)
|
235
|
+
expect(rule).to respond_to(:inum=)
|
236
|
+
end
|
237
|
+
|
238
|
+
example "inum method returns expected default value" do
|
239
|
+
expect(rule.inum).to be_nil
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
context "follow", :follow => true do
|
244
|
+
example "follow accessor basic functionality" do
|
245
|
+
expect(rule).to respond_to(:follow)
|
246
|
+
expect(rule).to respond_to(:follow=)
|
247
|
+
end
|
248
|
+
|
249
|
+
example "follow method returns expected default value" do
|
250
|
+
expect(rule.follow).to be true
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
context "links", :links => true do
|
255
|
+
before do
|
256
|
+
FileUtils.touch(ruby_file)
|
257
|
+
FileUtils.touch(doc_file)
|
258
|
+
end
|
259
|
+
|
260
|
+
example "links accessor basic functionality" do
|
261
|
+
expect(rule).to respond_to(:links)
|
262
|
+
expect(rule).to respond_to(:links=)
|
263
|
+
end
|
264
|
+
|
265
|
+
example "links method returns expected default value" do
|
266
|
+
expect(rule.links).to be_nil
|
267
|
+
end
|
268
|
+
|
269
|
+
example "links method returns expected result" do
|
270
|
+
# skip if @@windows && !@@elevated # TODO: Update
|
271
|
+
|
272
|
+
rule1 = File::Find.new(:name => '*.rb', :links => 2)
|
273
|
+
rule2 = File::Find.new(:name => '*.doc', :links => 1)
|
274
|
+
|
275
|
+
expect(rule1.find).to eq([])
|
276
|
+
expect(rule2.find).to eq([File.expand_path(doc_file)])
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
context "brackets", :brackets => true do
|
281
|
+
before do
|
282
|
+
allow(FakeFS::FileSystem).to receive(:find).and_call_original
|
283
|
+
allow(FakeFS::FileSystem).to receive(:find).with(anything, 0, false)
|
284
|
+
end
|
285
|
+
|
286
|
+
example "find method works on dirs that contain brackets" do
|
287
|
+
skip 'dirs with brackets example skipped on MS Windows' if windows
|
288
|
+
|
289
|
+
# We use absolute paths here because of fakefs, which converts it anyway
|
290
|
+
bracket_files = ['/bracket/a[1]/a.foo', '/bracket/a [2] /b.foo', '/bracket/[a] b [c]/d.foo' ]
|
291
|
+
bracket_paths = ['/bracket/a[1]', '/bracket/a [2] ', '/bracket/[a] b [c]', '/bracket/[z] x' ]
|
292
|
+
|
293
|
+
bracket_paths.each{ |e| FakeFS::FileSystem.add(e) }
|
294
|
+
bracket_files.each{ |e| FileUtils.touch(e) }
|
295
|
+
|
296
|
+
file_rule = File::Find.new(
|
297
|
+
:ftype => 'file',
|
298
|
+
:path => ['/bracket']
|
299
|
+
)
|
300
|
+
|
301
|
+
dir_rule = File::Find.new(
|
302
|
+
:ftype => 'directory',
|
303
|
+
:path => ['/bracket']
|
304
|
+
)
|
305
|
+
|
306
|
+
file_results = file_rule.find
|
307
|
+
dir_results = dir_rule.find
|
308
|
+
|
309
|
+
expect(file_results).to match_array(bracket_files)
|
310
|
+
expect(dir_results).to match_array(bracket_paths)
|
311
|
+
end
|
312
|
+
end
|
313
|
+
|
314
|
+
context "maxdepth", :maxdepth => true do
|
315
|
+
before do
|
316
|
+
fs = FakeFS::FileSystem.add('a1/a2/a3')
|
317
|
+
rule.pattern = "*.foo"
|
318
|
+
|
319
|
+
FileUtils.touch('a1/a.foo')
|
320
|
+
FileUtils.touch('a1/a2/b.foo')
|
321
|
+
FileUtils.touch('a1/a2/c.foo')
|
322
|
+
FileUtils.touch('a1/a2/a3/d.foo')
|
323
|
+
FileUtils.touch('a1/a2/a3/e.foo')
|
324
|
+
FileUtils.touch('a1/a2/a3/f.foo')
|
325
|
+
end
|
326
|
+
|
327
|
+
example "maxdepth_basic" do
|
328
|
+
expect(rule).to respond_to(:maxdepth)
|
329
|
+
expect(rule).to respond_to(:maxdepth=)
|
330
|
+
expect(rule.maxdepth).to be_nil
|
331
|
+
end
|
332
|
+
|
333
|
+
example "find with maxdepth option returns expected results" do
|
334
|
+
rule.maxdepth = 1
|
335
|
+
|
336
|
+
expect(rule.find).to eq([])
|
337
|
+
|
338
|
+
rule.maxdepth = 2
|
339
|
+
expect(rule.find.map{ |e| File.basename(e) }).to eq(['a.foo'])
|
340
|
+
|
341
|
+
rule.maxdepth = 3
|
342
|
+
expect(rule.find.map{ |e| File.basename(e) }).to match_array(['a.foo', 'b.foo', 'c.foo'])
|
343
|
+
end
|
344
|
+
|
345
|
+
example "find with nil maxdepth option returns everything" do
|
346
|
+
rule.maxdepth = nil
|
347
|
+
results = ['a.foo', 'b.foo', 'c.foo', 'd.foo', 'e.foo', 'f.foo']
|
348
|
+
expect(rule.find.map{ |e| File.basename(e) }).to match_array(results)
|
349
|
+
end
|
350
|
+
|
351
|
+
example "find with maxdepth option returns expected results for directories" do
|
352
|
+
rule.pattern = "a3"
|
353
|
+
|
354
|
+
rule.maxdepth = 1
|
355
|
+
expect(rule.find).to eq([])
|
356
|
+
|
357
|
+
rule.maxdepth = 2
|
358
|
+
expect(rule.find).to eq([])
|
359
|
+
|
360
|
+
rule.maxdepth = 3
|
361
|
+
expect(rule.find.map{ |e| File.basename(e) }).to eq(['a3'])
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
context "mindepth", :mindepth => true do
|
366
|
+
before do
|
367
|
+
fs = FakeFS::FileSystem.add('a1/a2/a3')
|
368
|
+
rule.pattern = "*.min"
|
369
|
+
|
370
|
+
FileUtils.touch('z.min')
|
371
|
+
FileUtils.touch('a1/a.min')
|
372
|
+
FileUtils.touch('a1/a2/b.min')
|
373
|
+
FileUtils.touch('a1/a2/c.min')
|
374
|
+
FileUtils.touch('a1/a2/a3/d.min')
|
375
|
+
FileUtils.touch('a1/a2/a3/e.min')
|
376
|
+
FileUtils.touch('a1/a2/a3/f.min')
|
377
|
+
end
|
378
|
+
|
379
|
+
example "mindepth accessor basic functionality" do
|
380
|
+
expect(rule).to respond_to(:mindepth)
|
381
|
+
expect(rule).to respond_to(:mindepth=)
|
382
|
+
expect(rule.mindepth).to be_nil
|
383
|
+
end
|
384
|
+
|
385
|
+
example "mindepth method returns expected default value" do
|
386
|
+
expect(rule.mindepth).to be_nil
|
387
|
+
end
|
388
|
+
|
389
|
+
example "find with mindepth option returns expected results at depth 0" do
|
390
|
+
rule.mindepth = 0
|
391
|
+
array = ['a.min', 'b.min', 'c.min', 'd.min', 'e.min', 'f.min', 'z.min']
|
392
|
+
expect(rule.find.map{ |e| File.basename(e) }).to match_array(array)
|
393
|
+
end
|
394
|
+
|
395
|
+
example "find with mindepth option returns expected results at depth 1" do
|
396
|
+
rule.mindepth = 1
|
397
|
+
array = ['a.min', 'b.min', 'c.min', 'd.min', 'e.min', 'f.min', 'z.min']
|
398
|
+
expect(rule.find.map{ |e| File.basename(e) }).to match_array(array)
|
399
|
+
end
|
400
|
+
|
401
|
+
example "find with mindepth option returns expected results at depth 2" do
|
402
|
+
rule.mindepth = 2
|
403
|
+
array = ['a.min', 'b.min', 'c.min', 'd.min', 'e.min', 'f.min']
|
404
|
+
expect(rule.find.map{ |e| File.basename(e) }).to match_array(array)
|
405
|
+
end
|
406
|
+
|
407
|
+
example "find with mindepth option returns expected results at depth 3" do
|
408
|
+
rule.mindepth = 3
|
409
|
+
array = ['b.min', 'c.min', 'd.min', 'e.min', 'f.min']
|
410
|
+
expect(rule.find.map{ |e| File.basename(e) }).to match_array(array)
|
411
|
+
end
|
412
|
+
|
413
|
+
example "find with mindepth option returns expected results at depth 4" do
|
414
|
+
rule.mindepth = 4
|
415
|
+
array = ['d.min', 'e.min', 'f.min']
|
416
|
+
expect(rule.find.map{ |e| File.basename(e) }).to match_array(array)
|
417
|
+
end
|
418
|
+
|
419
|
+
example "find with mindepth option returns expected results at depth 5" do
|
420
|
+
rule.mindepth = 5
|
421
|
+
expect(rule.find.map{ |e| File.basename(e) }).to eq([])
|
422
|
+
end
|
423
|
+
|
424
|
+
example "find with mindepth option returns expected results for directories" do
|
425
|
+
rule.pattern = 'a1'
|
426
|
+
rule.mindepth = 1
|
427
|
+
|
428
|
+
expect(rule.find.map{ |e| File.basename(e) }).to eq(['a1'])
|
429
|
+
|
430
|
+
rule.mindepth = 2
|
431
|
+
expect(rule.find).to eq([])
|
432
|
+
|
433
|
+
rule.mindepth = 3
|
434
|
+
expect(rule.find).to eq([])
|
435
|
+
end
|
436
|
+
end
|
437
|
+
|
438
|
+
context "mount", :mount => true do
|
439
|
+
example "mount accessor basic functionality" do
|
440
|
+
expect(rule).to respond_to(:mount)
|
441
|
+
expect(rule).to respond_to(:mount=)
|
442
|
+
end
|
443
|
+
|
444
|
+
example "mount method returns expected default value" do
|
445
|
+
expect(rule.mount).to be_nil
|
446
|
+
end
|
447
|
+
end
|
448
|
+
|
449
|
+
context "name", :name => true do
|
450
|
+
example "name accessor basic functionality" do
|
451
|
+
expect(rule).to respond_to(:name)
|
452
|
+
expect(rule).to respond_to(:name=)
|
453
|
+
end
|
454
|
+
|
455
|
+
example "name method returns expected default value" do
|
456
|
+
expect(txt_rule.name).to eq('*.txt')
|
457
|
+
end
|
458
|
+
|
459
|
+
example "pattern is an alias for name" do
|
460
|
+
expect(rule.method(:name)).to eq(rule.method(:pattern))
|
461
|
+
expect(rule.method(:name=)).to eq(rule.method(:pattern=))
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
context "perm", :perm => true do
|
466
|
+
before do
|
467
|
+
FileUtils.touch(ruby_file)
|
468
|
+
FileUtils.touch(text_file1)
|
469
|
+
FileUtils.touch(text_file2)
|
470
|
+
File.chmod(0464, ruby_file)
|
471
|
+
File.chmod(0644, text_file1)
|
472
|
+
File.chmod(0644, text_file2)
|
473
|
+
end
|
474
|
+
|
475
|
+
example "perm accessor basic functionality" do
|
476
|
+
expect(rule).to respond_to(:perm)
|
477
|
+
expect(rule).to respond_to(:perm=)
|
478
|
+
end
|
479
|
+
|
480
|
+
example "perm method returns expected default value" do
|
481
|
+
expect(rule.perm).to be_nil
|
482
|
+
end
|
483
|
+
|
484
|
+
example "perm method returns expected results" do
|
485
|
+
results = File::Find.new(:name => "*test1*", :perm => 0644).find
|
486
|
+
|
487
|
+
expect(results.length).to eq(1)
|
488
|
+
expect(File.basename(results.first)).to eq(text_file1)
|
489
|
+
end
|
490
|
+
|
491
|
+
example "perm method works with symbolic permissions" do
|
492
|
+
skip 'symbolic perm spec skipped on MS Windows' if windows
|
493
|
+
|
494
|
+
results1 = File::Find.new(:name => "file*", :perm => "g=rw").find
|
495
|
+
results2 = File::Find.new(:name => "file*", :perm => "u=rw").find
|
496
|
+
|
497
|
+
expect(results1.length).to eq(1)
|
498
|
+
expect(results2.length).to eq(2)
|
499
|
+
expect(File.basename(results1.first)).to eq(ruby_file)
|
500
|
+
expect(results2.map{ |e| File.basename(e) }.sort).to eq([text_file1, text_file2])
|
501
|
+
end
|
502
|
+
end
|
503
|
+
|
504
|
+
context "prune", :prune => true do
|
505
|
+
before do
|
506
|
+
FileUtils.touch(text_file1)
|
507
|
+
end
|
508
|
+
|
509
|
+
example "prune accessor basic functionality" do
|
510
|
+
expect(rule).to respond_to(:prune)
|
511
|
+
expect(rule).to respond_to(:prune=)
|
512
|
+
end
|
513
|
+
|
514
|
+
example "prune method returns expected default value" do
|
515
|
+
expect(rule.prune).to be_nil
|
516
|
+
end
|
517
|
+
|
518
|
+
example "find method with prune option works as expected" do
|
519
|
+
rule = File::Find.new(:name => "*.txt", :prune => 'foo')
|
520
|
+
expect(File.basename(rule.find.first)).to eq(text_file1)
|
521
|
+
end
|
522
|
+
end
|
523
|
+
|
524
|
+
context "size", :size => true do
|
525
|
+
example "size accessor basic functionality" do
|
526
|
+
expect(rule).to respond_to(:size)
|
527
|
+
expect(rule).to respond_to(:size=)
|
528
|
+
end
|
529
|
+
|
530
|
+
example "size method returns expected default value" do
|
531
|
+
expect(rule.size).to be_nil
|
532
|
+
end
|
533
|
+
end
|
534
|
+
|
535
|
+
context "user", :user => true do
|
536
|
+
before do
|
537
|
+
FileUtils.touch(doc_file)
|
538
|
+
end
|
539
|
+
|
540
|
+
example "user accessor basic functionality" do
|
541
|
+
expect(rule).to respond_to(:user)
|
542
|
+
expect(rule).to respond_to(:user=)
|
543
|
+
end
|
544
|
+
|
545
|
+
example "user method returns expected default value" do
|
546
|
+
expect(rule.user).to be_nil
|
547
|
+
end
|
548
|
+
|
549
|
+
example "user method works with numeric id as expected" do
|
550
|
+
if windows && elevated
|
551
|
+
uid = @loguser.gid # Windows assigns the group if any member is an admin
|
552
|
+
else
|
553
|
+
uid = @loguser.uid
|
554
|
+
end
|
555
|
+
|
556
|
+
rule = File::Find.new(:name => '*.doc', :user => uid)
|
557
|
+
expect(rule.find).to eq([File.expand_path(doc_file)])
|
558
|
+
end
|
559
|
+
|
560
|
+
example "user method works with string as expected" do
|
561
|
+
skip if windows && elevated
|
562
|
+
rule = File::Find.new(:name => '*.doc', :user => @loguser.name)
|
563
|
+
expect(rule.find).to eq([File.expand_path(doc_file)])
|
564
|
+
end
|
565
|
+
|
566
|
+
example "find method with user option using invalid user returns expected results" do
|
567
|
+
rule1 = File::Find.new(:name => '*.doc', :user => 'totallybogus')
|
568
|
+
rule2 = File::Find.new(:name => '*.doc', :user => 99999999)
|
569
|
+
expect(rule1.find).to eq([])
|
570
|
+
expect(rule2.find).to eq([])
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
574
|
+
context "previous", :previous => true do
|
575
|
+
example "previous method basic functionality" do
|
576
|
+
expect(rule).to respond_to(:previous)
|
577
|
+
end
|
578
|
+
end
|
579
|
+
|
580
|
+
example "an error is raised if the path does not exist" do
|
581
|
+
expect{ File::Find.new(:path => '/bogus/dir').find }.to raise_error(Errno::ENOENT)
|
582
|
+
end
|
583
|
+
|
584
|
+
example "an error is raised if an invalid option is passed" do
|
585
|
+
expect{ File::Find.new(:bogus => 1) }.to raise_error(ArgumentError)
|
586
|
+
expect{ File::Find.new(:bogus? => true) }.to raise_error(ArgumentError)
|
587
|
+
end
|
588
|
+
|
589
|
+
context "eloop", :eloop => true do
|
590
|
+
# Have to disable fakefs for this test because of bug: https://github.com/fakefs/fakefs/issues/459
|
591
|
+
before do
|
592
|
+
FakeFS.deactivate!
|
593
|
+
end
|
594
|
+
|
595
|
+
# TODO: Update example for Windows
|
596
|
+
example 'eloop handling works as expected' do
|
597
|
+
skip 'eloop handling example skipped on MS Windows' if windows
|
598
|
+
|
599
|
+
Dir.chdir(Dir.mktmpdir) do
|
600
|
+
File.symlink('eloop0', 'eloop1')
|
601
|
+
File.symlink('eloop1', 'eloop0')
|
602
|
+
expected = ['./eloop0', './eloop1']
|
603
|
+
|
604
|
+
results = File::Find.new(:path => '.', :follow => true).find
|
605
|
+
expect(results.sort).to eq(expected)
|
606
|
+
end
|
607
|
+
end
|
608
|
+
|
609
|
+
after do
|
610
|
+
FakeFS.activate!
|
611
|
+
end
|
612
|
+
end
|
613
|
+
end
|