diff options
Diffstat (limited to 'spec/ruby/core/dir/shared')
| -rw-r--r-- | spec/ruby/core/dir/shared/chroot.rb | 21 | ||||
| -rw-r--r-- | spec/ruby/core/dir/shared/closed.rb | 2 | ||||
| -rw-r--r-- | spec/ruby/core/dir/shared/delete.rb | 38 | ||||
| -rw-r--r-- | spec/ruby/core/dir/shared/exist.rb | 11 | ||||
| -rw-r--r-- | spec/ruby/core/dir/shared/glob.rb | 147 | ||||
| -rw-r--r-- | spec/ruby/core/dir/shared/open.rb | 20 | ||||
| -rw-r--r-- | spec/ruby/core/dir/shared/path.rb | 22 | ||||
| -rw-r--r-- | spec/ruby/core/dir/shared/pwd.rb | 20 |
8 files changed, 197 insertions, 84 deletions
diff --git a/spec/ruby/core/dir/shared/chroot.rb b/spec/ruby/core/dir/shared/chroot.rb index 2ed033dfed..a8f7c10a19 100644 --- a/spec/ruby/core/dir/shared/chroot.rb +++ b/spec/ruby/core/dir/shared/chroot.rb @@ -2,8 +2,8 @@ describe :dir_chroot_as_root, shared: true do before :all do DirSpecs.create_mock_dirs - @real_root = "../" * (File.dirname(__FILE__).count('/') - 1) - @ref_dir = File.join("/", Dir.new('/').entries.first) + @real_root = "../" * (__dir__.count('/') - 1) + @ref_dir = File.join("/", File.basename(Dir["/*"].first)) end after :all do @@ -14,24 +14,27 @@ describe :dir_chroot_as_root, shared: true do DirSpecs.delete_mock_dirs end + # Pending until https://github.com/ruby/ruby/runs/8075149420 is fixed + compilations_ci = ENV["GITHUB_WORKFLOW"] == "Compilations" + it "can be used to change the process' root directory" do - lambda { Dir.send(@method, File.dirname(__FILE__)) }.should_not raise_error - File.exist?("/#{File.basename(__FILE__)}").should be_true - end + -> { Dir.send(@method, __dir__) }.should_not raise_error + File.should.exist?("/#{File.basename(__FILE__)}") + end unless compilations_ci it "returns 0 if successful" do Dir.send(@method, '/').should == 0 end it "raises an Errno::ENOENT exception if the directory doesn't exist" do - lambda { Dir.send(@method, 'xgwhwhsjai2222jg') }.should raise_error(Errno::ENOENT) + -> { Dir.send(@method, 'xgwhwhsjai2222jg') }.should raise_error(Errno::ENOENT) end it "can be escaped from with ../" do Dir.send(@method, @real_root) - File.exist?(@ref_dir).should be_true - File.exist?("/#{File.basename(__FILE__)}").should be_false - end + File.should.exist?(@ref_dir) + File.should_not.exist?("/#{File.basename(__FILE__)}") + end unless compilations_ci it "calls #to_path on non-String argument" do p = mock('path') diff --git a/spec/ruby/core/dir/shared/closed.rb b/spec/ruby/core/dir/shared/closed.rb index a1bce06a08..17d8332c2a 100644 --- a/spec/ruby/core/dir/shared/closed.rb +++ b/spec/ruby/core/dir/shared/closed.rb @@ -1,6 +1,6 @@ describe :dir_closed, shared: true do it "raises an IOError when called on a closed Dir instance" do - lambda { + -> { dir = Dir.open DirSpecs.mock_dir dir.close dir.send(@method) {} diff --git a/spec/ruby/core/dir/shared/delete.rb b/spec/ruby/core/dir/shared/delete.rb index 8db17d985f..a81b059759 100644 --- a/spec/ruby/core/dir/shared/delete.rb +++ b/spec/ruby/core/dir/shared/delete.rb @@ -17,24 +17,14 @@ describe :dir_delete, shared: true do Dir.send(@method, p) end - platform_is_not :solaris do - it "raises an Errno::ENOTEMPTY when trying to remove a nonempty directory" do - lambda do - Dir.send @method, DirSpecs.mock_rmdir("nonempty") - end.should raise_error(Errno::ENOTEMPTY) - end - end - - platform_is :solaris do - it "raises an Errno::EEXIST when trying to remove a nonempty directory" do - lambda do - Dir.send @method, DirSpecs.mock_rmdir("nonempty") - end.should raise_error(Errno::EEXIST) - end + it "raises an Errno::ENOTEMPTY when trying to remove a nonempty directory" do + -> do + Dir.send @method, DirSpecs.mock_rmdir("nonempty") + end.should raise_error(Errno::ENOTEMPTY) end it "raises an Errno::ENOENT when trying to remove a non-existing directory" do - lambda do + -> do Dir.send @method, DirSpecs.nonexistent end.should raise_error(Errno::ENOENT) end @@ -42,20 +32,22 @@ describe :dir_delete, shared: true do it "raises an Errno::ENOTDIR when trying to remove a non-directory" do file = DirSpecs.mock_rmdir("nonempty/regular") touch(file) - lambda do + -> do Dir.send @method, file end.should raise_error(Errno::ENOTDIR) end # this won't work on Windows, since chmod(0000) does not remove all permissions platform_is_not :windows do - it "raises an Errno::EACCES if lacking adequate permissions to remove the directory" do - parent = DirSpecs.mock_rmdir("noperm") - child = DirSpecs.mock_rmdir("noperm", "child") - File.chmod(0000, parent) - lambda do - Dir.send @method, child - end.should raise_error(Errno::EACCES) + as_user do + it "raises an Errno::EACCES if lacking adequate permissions to remove the directory" do + parent = DirSpecs.mock_rmdir("noperm") + child = DirSpecs.mock_rmdir("noperm", "child") + File.chmod(0000, parent) + -> do + Dir.send @method, child + end.should raise_error(Errno::EACCES) + end end end end diff --git a/spec/ruby/core/dir/shared/exist.rb b/spec/ruby/core/dir/shared/exist.rb index fbd2c9862d..3097f57715 100644 --- a/spec/ruby/core/dir/shared/exist.rb +++ b/spec/ruby/core/dir/shared/exist.rb @@ -1,6 +1,6 @@ describe :dir_exist, shared: true do it "returns true if the given directory exists" do - Dir.send(@method, File.dirname(__FILE__)).should be_true + Dir.send(@method, __dir__).should be_true end it "returns true for '.'" do @@ -20,7 +20,7 @@ describe :dir_exist, shared: true do end it "understands relative paths" do - Dir.send(@method, File.dirname(__FILE__) + '/../').should be_true + Dir.send(@method, __dir__ + '/../').should be_true end it "returns false if the given directory doesn't exist" do @@ -28,18 +28,19 @@ describe :dir_exist, shared: true do end it "doesn't require the name to have a trailing slash" do - dir = File.dirname(__FILE__) + dir = __dir__ dir.sub!(/\/$/,'') Dir.send(@method, dir).should be_true end it "doesn't expand paths" do + skip "$HOME not valid directory" unless ENV['HOME'] && File.directory?(ENV['HOME']) Dir.send(@method, File.expand_path('~')).should be_true Dir.send(@method, '~').should be_false end it "returns false if the argument exists but is a file" do - File.exist?(__FILE__).should be_true + File.should.exist?(__FILE__) Dir.send(@method, __FILE__).should be_false end @@ -50,7 +51,7 @@ describe :dir_exist, shared: true do it "calls #to_path on non String arguments" do p = mock('path') - p.should_receive(:to_path).and_return(File.dirname(__FILE__)) + p.should_receive(:to_path).and_return(__dir__) Dir.send(@method, p) end end diff --git a/spec/ruby/core/dir/shared/glob.rb b/spec/ruby/core/dir/shared/glob.rb index d2201cd6cd..b1fc924f08 100644 --- a/spec/ruby/core/dir/shared/glob.rb +++ b/spec/ruby/core/dir/shared/glob.rb @@ -11,11 +11,9 @@ describe :dir_glob, shared: true do DirSpecs.delete_mock_dirs end - with_feature :encoding do - it "raises an Encoding::CompatibilityError if the argument encoding is not compatible with US-ASCII" do - pattern = "file*".force_encoding Encoding::UTF_16BE - lambda { Dir.send(@method, pattern) }.should raise_error(Encoding::CompatibilityError) - end + it "raises an Encoding::CompatibilityError if the argument encoding is not compatible with US-ASCII" do + pattern = "files*".dup.force_encoding Encoding::UTF_16BE + -> { Dir.send(@method, pattern) }.should raise_error(Encoding::CompatibilityError) end it "calls #to_path to convert a pattern" do @@ -25,9 +23,29 @@ describe :dir_glob, shared: true do Dir.send(@method, obj).should == %w[file_one.ext] end - it "splits the string on \\0 if there is only one string given" do - Dir.send(@method, "file_o*\0file_t*").should == - %w!file_one.ext file_two.ext! + it "raises an ArgumentError if the string contains \\0" do + -> {Dir.send(@method, "file_o*\0file_t*")}.should raise_error ArgumentError, /nul-separated/ + end + + it "result is sorted by default" do + result = Dir.send(@method, '*') + result.should == result.sort + end + + it "result is sorted with sort: true" do + result = Dir.send(@method, '*', sort: true) + result.should == result.sort + end + + it "sort: false returns same files" do + result = Dir.send(@method,'*', sort: false) + result.sort.should == Dir.send(@method, '*').sort + end + + it "raises an ArgumentError if sort: is not true or false" do + -> { Dir.send(@method, '*', sort: 0) }.should raise_error ArgumentError, /expected true or false/ + -> { Dir.send(@method, '*', sort: nil) }.should raise_error ArgumentError, /expected true or false/ + -> { Dir.send(@method, '*', sort: 'false') }.should raise_error ArgumentError, /expected true or false/ end it "matches non-dotfiles with '*'" do @@ -38,6 +56,7 @@ describe :dir_glob, shared: true do dir_filename_ordering file_one.ext file_two.ext + nested nondotfile special subdir_one @@ -55,6 +74,10 @@ describe :dir_glob, shared: true do Dir.send(@method, 'special/+').should == ['special/+'] end + it "matches directories with special characters when escaped" do + Dir.send(@method, 'special/\{}/special').should == ["special/{}/special"] + end + platform_is_not :windows do it "matches regexp special *" do Dir.send(@method, 'special/\*').should == ['special/*'] @@ -67,6 +90,14 @@ describe :dir_glob, shared: true do it "matches regexp special |" do Dir.send(@method, 'special/|').should == ['special/|'] end + + it "matches files with backslashes in their name" do + Dir.glob('special/\\\\{a,b}').should == ['special/\a'] + end + + it "matches directory with special characters in their name in complex patterns" do + Dir.glob("special/test +()\\[\\]\\{\\}/hello_world{.{en},}{.{html},}{+{phone},}{.{erb},}").should == ['special/test +()[]{}/hello_world.erb'] + end end it "matches regexp special ^" do @@ -105,8 +136,8 @@ describe :dir_glob, shared: true do Dir.send(@method, 'special/test\{1\}/*').should == ['special/test{1}/file[1]'] end - it "matches dotfiles with '.*'" do - Dir.send(@method, '.*').sort.should == %w|. .. .dotfile .dotsubdir|.sort + it "matches dotfiles except .. with '.*'" do + Dir.send(@method, '.*').sort.should == %w|. .dotfile .dotsubdir|.sort end it "matches non-dotfiles with '*<non-special characters>'" do @@ -141,6 +172,7 @@ describe :dir_glob, shared: true do dir_filename_ordering file_one.ext file_two.ext + nested nondotfile special subdir_one @@ -150,8 +182,8 @@ describe :dir_glob, shared: true do Dir.send(@method, '**').sort.should == expected end - it "matches dotfiles in the current directory with '.**'" do - Dir.send(@method, '.**').sort.should == %w|. .. .dotsubdir .dotfile|.sort + it "matches dotfiles in the current directory except .. with '.**'" do + Dir.send(@method, '.**').sort.should == %w|. .dotsubdir .dotfile|.sort end it "recursively matches any nondot subdirectories with '**/'" do @@ -162,8 +194,11 @@ describe :dir_glob, shared: true do deeply/nested/directory/ deeply/nested/directory/structure/ dir/ + nested/ special/ + special/test\ +()[]{}/ special/test{1}/ + special/{}/ subdir_one/ subdir_two/ ] @@ -171,9 +206,17 @@ describe :dir_glob, shared: true do Dir.send(@method, '**/').sort.should == expected end - it "recursively matches any subdirectories including ./ and ../ with '.**/'" do + it "recursively matches any subdirectories except './' or '../' with '**/' from the base directory if that is specified" do + expected = %w[ + nested/directory + ] + + Dir.send(@method, '**/*ory', base: 'deeply').sort.should == expected + end + + it "recursively matches any subdirectories including ./ with '.**/'" do Dir.chdir("#{DirSpecs.mock_dir}/subdir_one") do - Dir.send(@method, '.**/').sort.should == %w|./ ../|.sort + Dir.send(@method, '.**/').should == ['./'] end end @@ -216,7 +259,7 @@ describe :dir_glob, shared: true do end it "matches dot or non-dotfiles with '{,.}*'" do - Dir.send(@method, '{,.}*').sort.should == DirSpecs.expected_paths + Dir.send(@method, '{,.}*').sort.should == DirSpecs.expected_glob_paths end it "respects the order of {} expressions, expanding left most first" do @@ -262,11 +305,11 @@ describe :dir_glob, shared: true do subdir_two/nondotfile.ext] end - it "ignores matching through directories that doen't exist" do + it "ignores matching through directories that doesn't exist" do Dir.send(@method, "deeply/notthere/blah*/whatever").should == [] end - it "ignores matching only directories under an nonexistant path" do + it "ignores matching only directories under an nonexistent path" do Dir.send(@method, "deeply/notthere/blah/").should == [] end @@ -275,6 +318,76 @@ describe :dir_glob, shared: true do Dir.send(@method, "special/こんにちは{,.txt}").should == ["special/こんにちは.txt"] end end + + context ":base option passed" do + before :each do + @mock_dir = File.expand_path tmp('dir_glob_mock') + + %w[ + a/b/x + a/b/c/y + a/b/c/d/z + ].each do |path| + file = File.join @mock_dir, path + mkdir_p File.dirname(file) + touch file + end + end + + after :each do + rm_r @mock_dir + end + + it "matches entries only from within the specified directory" do + path = File.join(@mock_dir, "a/b/c") + Dir.send(@method, "*", base: path).sort.should == %w( d y ) + end + + it "accepts both relative and absolute paths" do + require 'pathname' + + path_abs = File.join(@mock_dir, "a/b/c") + path_rel = Pathname.new(path_abs).relative_path_from(Pathname.new(Dir.pwd)) + + result_abs = Dir.send(@method, "*", base: path_abs).sort + result_rel = Dir.send(@method, "*", base: path_rel).sort + + result_abs.should == %w( d y ) + result_rel.should == %w( d y ) + end + + it "returns [] if specified path does not exist" do + path = File.join(@mock_dir, "fake-name") + File.should_not.exist?(path) + + Dir.send(@method, "*", base: path).should == [] + end + + it "returns [] if specified path is a file" do + path = File.join(@mock_dir, "a/b/x") + File.should.exist?(path) + + Dir.send(@method, "*", base: path).should == [] + end + + it "raises TypeError when cannot convert value to string" do + -> { + Dir.send(@method, "*", base: []) + }.should raise_error(TypeError) + end + + it "handles '' as current directory path" do + Dir.chdir @mock_dir do + Dir.send(@method, "*", base: "").should == %w( a ) + end + end + + it "handles nil as current directory path" do + Dir.chdir @mock_dir do + Dir.send(@method, "*", base: nil).should == %w( a ) + end + end + end end describe :dir_glob_recursive, shared: true do diff --git a/spec/ruby/core/dir/shared/open.rb b/spec/ruby/core/dir/shared/open.rb index 7f4fe5c2a6..920845cba1 100644 --- a/spec/ruby/core/dir/shared/open.rb +++ b/spec/ruby/core/dir/shared/open.rb @@ -6,7 +6,7 @@ describe :dir_open, shared: true do end it "raises a SystemCallError if the directory does not exist" do - lambda do + -> do Dir.send @method, DirSpecs.nonexistent end.should raise_error(SystemCallError) end @@ -21,20 +21,20 @@ describe :dir_open, shared: true do it "closes the Dir instance when the block exits if given a block" do closed_dir = Dir.send(@method, DirSpecs.mock_dir) { |dir| dir } - lambda { closed_dir.read }.should raise_error(IOError) + -> { closed_dir.read }.should raise_error(IOError) end it "closes the Dir instance when the block exits the block even due to an exception" do closed_dir = nil - lambda do + -> do Dir.send(@method, DirSpecs.mock_dir) do |dir| closed_dir = dir raise "dir specs" end end.should raise_error(RuntimeError, "dir specs") - lambda { closed_dir.read }.should raise_error(IOError) + -> { closed_dir.read }.should raise_error(IOError) end it "calls #to_path on non-String arguments" do @@ -52,7 +52,7 @@ describe :dir_open, shared: true do options = mock("dir_open") options.should_receive(:to_hash).and_return({ encoding: Encoding::UTF_8 }) - dir = Dir.send(@method, DirSpecs.mock_dir, options) {|d| d } + dir = Dir.send(@method, DirSpecs.mock_dir, **options) {|d| d } dir.should be_kind_of(Dir) end @@ -60,4 +60,14 @@ describe :dir_open, shared: true do dir = Dir.send(@method, DirSpecs.mock_dir, encoding: nil) {|d| d } dir.should be_kind_of(Dir) end + + platform_is_not :windows do + it 'sets the close-on-exec flag for the directory file descriptor' do + Dir.send(@method, DirSpecs.mock_dir) do |dir| + io = IO.for_fd(dir.fileno) + io.autoclose = false + io.should.close_on_exec? + end + end + end end diff --git a/spec/ruby/core/dir/shared/path.rb b/spec/ruby/core/dir/shared/path.rb index 829eeb04c2..494dcca775 100644 --- a/spec/ruby/core/dir/shared/path.rb +++ b/spec/ruby/core/dir/shared/path.rb @@ -1,6 +1,6 @@ -require File.expand_path('../../../../spec_helper', __FILE__) -require File.expand_path('../../fixtures/common', __FILE__) -require File.expand_path('../closed', __FILE__) +require_relative '../../../spec_helper' +require_relative '../fixtures/common' +require_relative 'closed' describe :dir_path, shared: true do it "returns the path that was supplied to .new or .open" do @@ -18,15 +18,13 @@ describe :dir_path, shared: true do dir.send(@method).should == DirSpecs.mock_dir end - with_feature :encoding do - it "returns a String with the same encoding as the argument to .open" do - path = DirSpecs.mock_dir.force_encoding Encoding::IBM866 - dir = Dir.open path - begin - dir.send(@method).encoding.should equal(Encoding::IBM866) - ensure - dir.close - end + it "returns a String with the same encoding as the argument to .open" do + path = DirSpecs.mock_dir.force_encoding Encoding::IBM866 + dir = Dir.open path + begin + dir.send(@method).encoding.should equal(Encoding::IBM866) + ensure + dir.close end end end diff --git a/spec/ruby/core/dir/shared/pwd.rb b/spec/ruby/core/dir/shared/pwd.rb index 5f041a9d41..2a8d7fe790 100644 --- a/spec/ruby/core/dir/shared/pwd.rb +++ b/spec/ruby/core/dir/shared/pwd.rb @@ -1,8 +1,6 @@ describe :dir_pwd, shared: true do - with_feature :encoding do - before :each do - @fs_encoding = Encoding.find('filesystem') - end + before :each do + @fs_encoding = Encoding.find('filesystem') end it "returns the current working directory" do @@ -36,14 +34,12 @@ describe :dir_pwd, shared: true do end end - with_feature :encoding do - it "returns a String with the filesystem encoding" do - enc = Dir.send(@method).encoding - if @fs_encoding == Encoding::US_ASCII - [Encoding::US_ASCII, Encoding::ASCII_8BIT].should include(enc) - else - enc.should equal(@fs_encoding) - end + it "returns a String with the filesystem encoding" do + enc = Dir.send(@method).encoding + if @fs_encoding == Encoding::US_ASCII + [Encoding::US_ASCII, Encoding::BINARY].should include(enc) + else + enc.should equal(@fs_encoding) end end end |
