Skip to content

Commit

Permalink
Adding Dir.glob (ref #4, ref #5)
Browse files Browse the repository at this point in the history
  • Loading branch information
simonc committed Jul 18, 2014
1 parent 1dab496 commit 06ed359
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 1 deletion.
15 changes: 15 additions & 0 deletions lib/memfs/dir.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,19 @@ def self.getwd
end
class << self; alias :pwd :getwd; end

def self.glob(patterns, flags = 0)
patterns = [*patterns]
list = fs.paths.select do |path|
patterns.any? do |pattern|
File.fnmatch?(pattern, path, flags | GLOB_FLAGS)
end
end
# FIXME: ugly special case for /* and /
list.delete('/') if patterns.first == '/*'
return list unless block_given?
list.each { |path| yield path } and nil
end

def self.home(*args)
original_dir_class.home(*args)
end
Expand Down Expand Up @@ -130,6 +143,8 @@ def tell

private

GLOB_FLAGS = File::FNM_EXTGLOB | File::FNM_PATHNAME

attr_accessor :entry, :max_seek, :state

def self.original_dir_class
Expand Down
4 changes: 4 additions & 0 deletions lib/memfs/fake/directory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ def path
name == '/' ? '/' : super
end

def paths
[path] + entries.reject { |p| %w[. ..].include?(p) }.values.map(&:paths).flatten
end

def remove_entry(entry)
entries.delete(entry.name)
end
Expand Down
4 changes: 4 additions & 0 deletions lib/memfs/fake/entry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ def path
MemFs::File.join(parts)
end

def paths
[path]
end

def touch
self.atime = self.mtime = Time.now
end
Expand Down
4 changes: 4 additions & 0 deletions lib/memfs/file_system.rb
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ def mkdir(path)
find_parent!(path).add_entry Fake::Directory.new(path)
end

def paths
root.paths
end

def rename(old_name, new_name)
file = find!(old_name)
file.delete
Expand Down
55 changes: 55 additions & 0 deletions spec/memfs/dir_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,61 @@ module MemFs
end
end

describe '.glob' do
before do
fs.clear!
3.times do |dirnum|
fs.mkdir "/test#{dirnum}"
fs.mkdir "/test#{dirnum}/subdir"
3.times do |filenum|
fs.touch "/test#{dirnum}/subdir/file#{filenum}"
end
end
end

shared_examples 'returning matching filenames' do |pattern, filenames|
it "with #{pattern}" do
expect(subject.glob(pattern)).to eq filenames
end
end

it_behaves_like 'returning matching filenames', '/', %w[/]
it_behaves_like 'returning matching filenames', '/test0', %w[/test0]
it_behaves_like 'returning matching filenames', '/*', %w[/tmp /test0 /test1 /test2]
it_behaves_like 'returning matching filenames', '/test*', %w[/test0 /test1 /test2]
it_behaves_like 'returning matching filenames', '/*0', %w[/test0]
it_behaves_like 'returning matching filenames', '/*es*', %w[/test0 /test1 /test2]
it_behaves_like 'returning matching filenames', '/**/file0', %w[/test0/subdir/file0 /test1/subdir/file0 /test2/subdir/file0]
it_behaves_like 'returning matching filenames', '/test?', %w[/test0 /test1 /test2]
it_behaves_like 'returning matching filenames', '/test[01]', %w[/test0 /test1]
it_behaves_like 'returning matching filenames', '/test[^2]', %w[/test0 /test1]
it_behaves_like 'returning matching filenames', '/test{1,2}', %w[/test1 /test2]

context 'when a flag is given' do
it 'uses it to compare filenames' do
expect(subject.glob('/TEST*', File::FNM_CASEFOLD)).to eq \
%w[/test0 /test1 /test2]
end
end

context 'when a block is given' do
it 'calls the block with every matching filenames' do
expect{ |blk| subject.glob('/test*', &blk) }.to \
yield_successive_args('/test0', '/test1', '/test2')
end

it 'returns nil' do
expect(subject.glob('/*') {}).to be nil
end
end

context 'when pattern is an array of patterns' do
it 'returns the list of files matching any pattern' do
expect(subject.glob(['/*0', '/*1'])).to eq %w[/test0 /test1]
end
end
end

describe '.home' do
it 'returns the home directory of the current user' do
expect(subject.home).to eq ENV['HOME']
Expand Down
16 changes: 15 additions & 1 deletion spec/memfs/fake/directory_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module MemFs
module Fake
describe Directory do
let(:directory) { Directory.new('/test') }
let(:directory) { Directory.new('test') }

describe '.new' do
it "sets . in the entries list" do
Expand Down Expand Up @@ -101,6 +101,20 @@ module Fake
end
end

describe '#paths' do
before do
subdir = Directory.new('subdir')
directory.add_entry(subdir)
subdir.add_entry File.new('file1')
subdir.add_entry File.new('file2')
end

it 'returns the path of the directory and its entries recursively' do
expect(directory.paths).to eq \
%w[test test/subdir test/subdir/file1 test/subdir/file2]
end
end

describe "#remove_entry" do
let(:file) { File.new('file') }

Expand Down
6 changes: 6 additions & 0 deletions spec/memfs/fake/entry_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@ module Fake
end
end

describe 'paths' do
it 'returns an array containing the entry path' do
expect(entry.paths).to eq ['/parent/test']
end
end

describe "#touch" do
let(:time) { Time.now - 5000 }

Expand Down
12 changes: 12 additions & 0 deletions spec/memfs/file_system_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,18 @@ module MemFs
end
end

describe '#paths' do
before do
subject.mkdir('/test-dir/subdir')
subject.touch('/test-dir/subdir/file1', '/test-dir/subdir/file2')
end

it 'returns the list of all the existing paths' do
expect(subject.paths).to eq \
%w[/ /tmp /test-dir /test-dir/subdir /test-dir/subdir/file1 /test-dir/subdir/file2]
end
end

describe "#pwd" do
it_behaves_like 'aliased method', :pwd, :getwd
end
Expand Down

0 comments on commit 06ed359

Please sign in to comment.