diff options
Diffstat (limited to 'spec/ruby/core/dir')
-rw-r--r-- | spec/ruby/core/dir/children_spec.rb | 25 | ||||
-rw-r--r-- | spec/ruby/core/dir/each_child_spec.rb | 20 | ||||
-rw-r--r-- | spec/ruby/core/dir/each_spec.rb | 11 | ||||
-rw-r--r-- | spec/ruby/core/dir/entries_spec.rb | 9 | ||||
-rw-r--r-- | spec/ruby/core/dir/exist_spec.rb | 8 | ||||
-rw-r--r-- | spec/ruby/core/dir/fchdir_spec.rb | 68 | ||||
-rw-r--r-- | spec/ruby/core/dir/fixtures/common.rb | 22 | ||||
-rw-r--r-- | spec/ruby/core/dir/foreach_spec.rb | 12 | ||||
-rw-r--r-- | spec/ruby/core/dir/glob_spec.rb | 167 | ||||
-rw-r--r-- | spec/ruby/core/dir/home_spec.rb | 50 | ||||
-rw-r--r-- | spec/ruby/core/dir/mkdir_spec.rb | 18 | ||||
-rw-r--r-- | spec/ruby/core/dir/read_spec.rb | 33 | ||||
-rw-r--r-- | spec/ruby/core/dir/shared/chroot.rb | 13 | ||||
-rw-r--r-- | spec/ruby/core/dir/shared/exist.rb | 8 | ||||
-rw-r--r-- | spec/ruby/core/dir/shared/glob.rb | 59 |
15 files changed, 466 insertions, 57 deletions
diff --git a/spec/ruby/core/dir/children_spec.rb b/spec/ruby/core/dir/children_spec.rb index 986c8f38c0..0ad3df4669 100644 --- a/spec/ruby/core/dir/children_spec.rb +++ b/spec/ruby/core/dir/children_spec.rb @@ -47,7 +47,7 @@ describe "Dir.children" do encoding = Encoding.find("filesystem") encoding = Encoding::BINARY if encoding == Encoding::US_ASCII platform_is_not :windows do - children.should include("こんにちは.txt".force_encoding(encoding)) + children.should include("こんにちは.txt".dup.force_encoding(encoding)) end children.first.encoding.should equal(Encoding.find("filesystem")) end @@ -105,14 +105,6 @@ describe "Dir#children" do dirs.each { |d| d.encoding.should == Encoding::UTF_8 } end - ruby_version_is ""..."2.7" do - it "accepts nil options" do - @dir = Dir.new("#{DirSpecs.mock_dir}/deeply/nested", nil) - dirs = @dir.to_a.sort - dirs.each { |d| d.encoding.should == Encoding.find("filesystem") } - end - end - it "returns children encoded with the filesystem encoding by default" do # This spec depends on the locale not being US-ASCII because if it is, the # children that are not ascii_only? will be BINARY encoded. @@ -121,7 +113,7 @@ describe "Dir#children" do encoding = Encoding.find("filesystem") encoding = Encoding::BINARY if encoding == Encoding::US_ASCII platform_is_not :windows do - children.should include("こんにちは.txt".force_encoding(encoding)) + children.should include("こんにちは.txt".dup.force_encoding(encoding)) end children.first.encoding.should equal(Encoding.find("filesystem")) end @@ -139,4 +131,17 @@ describe "Dir#children" do children = @dir.children.sort children.first.encoding.should equal(Encoding::EUC_KR) end + + it "returns the same result when called repeatedly" do + @dir = Dir.open DirSpecs.mock_dir + + a = [] + @dir.each {|dir| a << dir} + + b = [] + @dir.each {|dir| b << dir} + + a.sort.should == b.sort + a.sort.should == DirSpecs.expected_paths + end end diff --git a/spec/ruby/core/dir/each_child_spec.rb b/spec/ruby/core/dir/each_child_spec.rb index f7980991e5..7194273b95 100644 --- a/spec/ruby/core/dir/each_child_spec.rb +++ b/spec/ruby/core/dir/each_child_spec.rb @@ -15,13 +15,6 @@ describe "Dir.each_child" do dirs.each {|dir| dir.encoding.should == Encoding::UTF_8} end - ruby_version_is ""..."2.7" do - it "accepts nil options" do - dirs = Dir.each_child("#{DirSpecs.mock_dir}/deeply/nested", nil).to_a.sort - dirs.each {|dir| dir.encoding.should == Encoding.find("filesystem")} - end - end - it "yields all names in an existing directory to the provided block" do a, b = [], [] @@ -93,6 +86,19 @@ describe "Dir#each_child" do @dir.each_child { |f| f }.should == @dir end + it "returns the same result when called repeatedly" do + @dir = Dir.open DirSpecs.mock_dir + + a = [] + @dir.each {|dir| a << dir} + + b = [] + @dir.each {|dir| b << dir} + + a.sort.should == b.sort + a.sort.should == DirSpecs.expected_paths + end + describe "when no block is given" do it "returns an Enumerator" do @dir = Dir.new(DirSpecs.mock_dir) diff --git a/spec/ruby/core/dir/each_spec.rb b/spec/ruby/core/dir/each_spec.rb index 8c69a7212b..7674663d82 100644 --- a/spec/ruby/core/dir/each_spec.rb +++ b/spec/ruby/core/dir/each_spec.rb @@ -35,6 +35,17 @@ describe "Dir#each" do ls.should include(@dir.read) end + it "returns the same result when called repeatedly" do + a = [] + @dir.each {|dir| a << dir} + + b = [] + @dir.each {|dir| b << dir} + + a.sort.should == b.sort + a.sort.should == DirSpecs.expected_paths + end + describe "when no block is given" do it "returns an Enumerator" do @dir.each.should be_an_instance_of(Enumerator) diff --git a/spec/ruby/core/dir/entries_spec.rb b/spec/ruby/core/dir/entries_spec.rb index 9aa58657db..7462542acf 100644 --- a/spec/ruby/core/dir/entries_spec.rb +++ b/spec/ruby/core/dir/entries_spec.rb @@ -40,13 +40,6 @@ describe "Dir.entries" do dirs.each {|dir| dir.encoding.should == Encoding::UTF_8} end - ruby_version_is ""..."2.7" do - it "accepts nil options" do - dirs = Dir.entries("#{DirSpecs.mock_dir}/deeply/nested", nil).to_a.sort - dirs.each {|dir| dir.encoding.should == Encoding.find("filesystem")} - end - end - it "returns entries encoded with the filesystem encoding by default" do # This spec depends on the locale not being US-ASCII because if it is, the # entries that are not ascii_only? will be BINARY encoded. @@ -54,7 +47,7 @@ describe "Dir.entries" do encoding = Encoding.find("filesystem") encoding = Encoding::BINARY if encoding == Encoding::US_ASCII platform_is_not :windows do - entries.should include("こんにちは.txt".force_encoding(encoding)) + entries.should include("こんにちは.txt".dup.force_encoding(encoding)) end entries.first.encoding.should equal(Encoding.find("filesystem")) end diff --git a/spec/ruby/core/dir/exist_spec.rb b/spec/ruby/core/dir/exist_spec.rb index 43987b0f32..9023de533f 100644 --- a/spec/ruby/core/dir/exist_spec.rb +++ b/spec/ruby/core/dir/exist_spec.rb @@ -13,3 +13,11 @@ describe "Dir.exist?" do it_behaves_like :dir_exist, :exist? end + +ruby_version_is "3.2" do + describe "Dir.exists?" do + it "has been removed" do + Dir.should_not.respond_to?(:exists?) + end + end +end diff --git a/spec/ruby/core/dir/fchdir_spec.rb b/spec/ruby/core/dir/fchdir_spec.rb new file mode 100644 index 0000000000..429e569691 --- /dev/null +++ b/spec/ruby/core/dir/fchdir_spec.rb @@ -0,0 +1,68 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/common' + +ruby_version_is '3.3' do + guard -> { Dir.respond_to? :fchdir } do + describe "Dir.fchdir" do + before :all do + DirSpecs.create_mock_dirs + end + + after :all do + DirSpecs.delete_mock_dirs + end + + before :each do + @dirs = [Dir.new('.')] + @original = @dirs.first.fileno + end + + after :each do + Dir.fchdir(@original) + @dirs.each(&:close) + end + + it "changes to the specified directory" do + dir = Dir.new(DirSpecs.mock_dir) + @dirs << dir + Dir.fchdir dir.fileno + Dir.pwd.should == DirSpecs.mock_dir + end + + it "returns 0 when successfully changing directory" do + Dir.fchdir(@original).should == 0 + end + + it "returns the value of the block when a block is given" do + Dir.fchdir(@original) { :block_value }.should == :block_value + end + + it "changes to the specified directory for the duration of the block" do + pwd = Dir.pwd + dir = Dir.new(DirSpecs.mock_dir) + @dirs << dir + Dir.fchdir(dir.fileno) { Dir.pwd }.should == DirSpecs.mock_dir + Dir.pwd.should == pwd + end + + it "raises a SystemCallError if the file descriptor given is not valid" do + -> { Dir.fchdir(-1) }.should raise_error(SystemCallError) + -> { Dir.fchdir(-1) { } }.should raise_error(SystemCallError) + end + + it "raises a SystemCallError if the file descriptor given is not for a directory" do + -> { Dir.fchdir $stdout.fileno }.should raise_error(SystemCallError) + -> { Dir.fchdir($stdout.fileno) { } }.should raise_error(SystemCallError) + end + end + end + + guard_not -> { Dir.respond_to? :fchdir } do + describe "Dir.fchdir" do + it "raises NotImplementedError" do + -> { Dir.fchdir 1 }.should raise_error(NotImplementedError) + -> { Dir.fchdir(1) { } }.should raise_error(NotImplementedError) + end + end + end +end diff --git a/spec/ruby/core/dir/fixtures/common.rb b/spec/ruby/core/dir/fixtures/common.rb index a1ea3db215..087f46b331 100644 --- a/spec/ruby/core/dir/fixtures/common.rb +++ b/spec/ruby/core/dir/fixtures/common.rb @@ -81,6 +81,8 @@ module DirSpecs special/} special/test{1}/file[1] + special/{}/special + special/test\ +()[]{}/hello_world.erb ] platform_is_not :windows do @@ -91,19 +93,39 @@ module DirSpecs special/| special/こんにちは.txt + special/\a ] + @mock_dir_files << "special/_\u{1f60e}.erb" end end @mock_dir_files end + def self.mock_dir_links + unless @mock_dir_links + @mock_dir_links = [] + platform_is_not :windows do + @mock_dir_links += [ + ['special/ln', 'subdir_one'] + ] + end + end + @mock_dir_links + end + def self.create_mock_dirs mock_dir_files.each do |name| file = File.join mock_dir, name mkdir_p File.dirname(file) touch file end + mock_dir_links.each do |link, target| + full_link = File.join mock_dir, link + full_target = File.join mock_dir, target + + File.symlink full_target, full_link + end end def self.delete_mock_dirs diff --git a/spec/ruby/core/dir/foreach_spec.rb b/spec/ruby/core/dir/foreach_spec.rb index c3ddb27a84..9cf34b1d71 100644 --- a/spec/ruby/core/dir/foreach_spec.rb +++ b/spec/ruby/core/dir/foreach_spec.rb @@ -41,13 +41,13 @@ describe "Dir.foreach" do it "accepts an encoding keyword for the encoding of the entries" do dirs = Dir.foreach("#{DirSpecs.mock_dir}/deeply/nested", encoding: "utf-8").to_a.sort - dirs.each {|dir| dir.encoding.should == Encoding::UTF_8} - end + dirs.each { |dir| dir.encoding.should == Encoding::UTF_8 } + + dirs = Dir.foreach("#{DirSpecs.mock_dir}/deeply/nested", encoding: Encoding::ISO_8859_1).to_a.sort + dirs.each { |dir| dir.encoding.should == Encoding::ISO_8859_1 } - ruby_version_is ""..."2.7" do - it "accepts nil options" do - dirs = Dir.foreach("#{DirSpecs.mock_dir}/deeply/nested", nil).to_a.sort - dirs.each {|dir| dir.encoding.should == Encoding.find("filesystem")} + Dir.foreach("#{DirSpecs.mock_dir}/deeply/nested", encoding: Encoding::ISO_8859_1) do |f| + f.encoding.should == Encoding::ISO_8859_1 end end diff --git a/spec/ruby/core/dir/glob_spec.rb b/spec/ruby/core/dir/glob_spec.rb index 6533c9b65a..32f515c81d 100644 --- a/spec/ruby/core/dir/glob_spec.rb +++ b/spec/ruby/core/dir/glob_spec.rb @@ -79,7 +79,9 @@ describe "Dir.glob" do nested/ nested/.dotsubir/ special/ + special/test\ +()[]{}/ special/test{1}/ + special/{}/ subdir_one/ subdir_two/ ] @@ -104,11 +106,11 @@ describe "Dir.glob" do ruby_version_is '3.1' do it "recursively matches files and directories in nested dot subdirectory except . with 'nested/**/*' from the current directory and option File::FNM_DOTMATCH" do expected = %w[ - nested/. - nested/.dotsubir - nested/.dotsubir/.dotfile - nested/.dotsubir/nondotfile - ] + nested/. + nested/.dotsubir + nested/.dotsubir/.dotfile + nested/.dotsubir/nondotfile + ] Dir.glob('nested/**/*', File::FNM_DOTMATCH).sort.should == expected.sort end @@ -129,7 +131,9 @@ describe "Dir.glob" do ./nested/ ./nested/.dotsubir/ ./special/ + ./special/test\ +()[]{}/ ./special/test{1}/ + ./special/{}/ ./subdir_one/ ./subdir_two/ ] @@ -178,6 +182,134 @@ describe "Dir.glob" do Dir.glob('**/**/**').should_not.empty? end + it "handles **/** with base keyword argument" do + Dir.glob('**/**', base: "dir").should == ["filename_ordering"] + + expected = %w[ + nested + nested/directory + nested/directory/structure + nested/directory/structure/bar + nested/directory/structure/baz + nested/directory/structure/file_one + nested/directory/structure/file_one.ext + nested/directory/structure/foo + nondotfile + ].sort + + Dir.glob('**/**', base: "deeply").sort.should == expected + end + + it "handles **/ with base keyword argument" do + expected = %w[ + / + directory/ + directory/structure/ + ] + Dir.glob('**/', base: "deeply/nested").sort.should == expected + end + + it "handles **/nondotfile with base keyword argument" do + expected = %w[ + deeply/nondotfile + nondotfile + subdir_one/nondotfile + subdir_two/nondotfile + ] + Dir.glob('**/nondotfile', base: ".").sort.should == expected + end + + it "handles **/nondotfile with base keyword argument and FNM_DOTMATCH" do + expected = %w[ + .dotsubdir/nondotfile + deeply/nondotfile + nested/.dotsubir/nondotfile + nondotfile + subdir_one/nondotfile + subdir_two/nondotfile + ] + Dir.glob('**/nondotfile', File::FNM_DOTMATCH, base: ".").sort.should == expected + end + + it "handles **/.dotfile with base keyword argument" do + expected = %w[ + .dotfile + deeply/.dotfile + subdir_one/.dotfile + ] + Dir.glob('**/.dotfile', base: ".").sort.should == expected + end + + it "handles **/.dotfile with base keyword argument and FNM_DOTMATCH" do + expected = %w[ + .dotfile + .dotsubdir/.dotfile + deeply/.dotfile + nested/.dotsubir/.dotfile + subdir_one/.dotfile + ] + Dir.glob('**/.dotfile', File::FNM_DOTMATCH, base: ".").sort.should == expected + end + + it "handles **/.* with base keyword argument" do + expected = %w[ + .dotfile.ext + directory/structure/.ext + ].sort + + Dir.glob('**/.*', base: "deeply/nested").sort.should == expected + end + + # < 3.1 include a "." entry for every dir: ["directory/.", "directory/structure/.", ...] + ruby_version_is '3.1' do + it "handles **/.* with base keyword argument and FNM_DOTMATCH" do + expected = %w[ + . + .dotfile.ext + directory/structure/.ext + ].sort + + Dir.glob('**/.*', File::FNM_DOTMATCH, base: "deeply/nested").sort.should == expected + end + + it "handles **/** with base keyword argument and FNM_DOTMATCH" do + expected = %w[ + . + .dotfile.ext + directory + directory/structure + directory/structure/.ext + directory/structure/bar + directory/structure/baz + directory/structure/file_one + directory/structure/file_one.ext + directory/structure/foo + ].sort + + Dir.glob('**/**', File::FNM_DOTMATCH, base: "deeply/nested").sort.should == expected + end + end + + it "handles **/*pattern* with base keyword argument and FNM_DOTMATCH" do + expected = %w[ + .dotfile.ext + directory/structure/file_one + directory/structure/file_one.ext + ] + + Dir.glob('**/*file*', File::FNM_DOTMATCH, base: "deeply/nested").sort.should == expected + end + + it "handles **/glob with base keyword argument and FNM_EXTGLOB" do + expected = %w[ + directory/structure/bar + directory/structure/file_one + directory/structure/file_one.ext + ] + + Dir.glob('**/*{file,bar}*', File::FNM_EXTGLOB, base: "deeply/nested").sort.should == expected + end + it "handles simple filename patterns" do Dir.glob('.dotfile').should == ['.dotfile'] end @@ -220,5 +352,30 @@ describe "Dir.glob" do Dir.rmdir('no_permission') end end + + it "will follow symlinks when processing a `*/` pattern." do + expected = ['special/ln/nondotfile'] + Dir.glob('special/*/nondotfile').should == expected + end + + it "will not follow symlinks when recursively traversing directories" do + expected = %w[ + deeply/nondotfile + nondotfile + subdir_one/nondotfile + subdir_two/nondotfile + ] + Dir.glob('**/nondotfile').sort.should == expected + end + + it "will follow symlinks when testing directory after recursive directory in pattern" do + expected = %w[ + deeply/nondotfile + special/ln/nondotfile + subdir_one/nondotfile + subdir_two/nondotfile + ] + Dir.glob('**/*/nondotfile').sort.should == expected + end end end diff --git a/spec/ruby/core/dir/home_spec.rb b/spec/ruby/core/dir/home_spec.rb index 713ba9db9a..3cf745ab46 100644 --- a/spec/ruby/core/dir/home_spec.rb +++ b/spec/ruby/core/dir/home_spec.rb @@ -19,6 +19,44 @@ describe "Dir.home" do it "returns a non-frozen string" do Dir.home.should_not.frozen? end + + it "returns a string with the filesystem encoding" do + Dir.home.encoding.should == Encoding.find("filesystem") + end + + platform_is_not :windows do + it "works even if HOME is unset" do + ENV.delete('HOME') + Dir.home.should.start_with?('/') + Dir.home.encoding.should == Encoding.find("filesystem") + end + end + + platform_is :windows do + ruby_version_is "3.2" do + it "returns the home directory with forward slashs and as UTF-8" do + ENV['HOME'] = "C:\\rubyspäc\\home" + home = Dir.home + home.should == "C:/rubyspäc/home" + home.encoding.should == Encoding::UTF_8 + end + + it "retrieves the directory from HOME, USERPROFILE, HOMEDRIVE/HOMEPATH and the WinAPI in that order" do + old_dirs = [ENV.delete('HOME'), ENV.delete('USERPROFILE'), ENV.delete('HOMEDRIVE'), ENV.delete('HOMEPATH')] + + Dir.home.should == old_dirs[1].gsub("\\", "/") + ENV['HOMEDRIVE'] = "C:" + ENV['HOMEPATH'] = "\\rubyspec\\home1" + Dir.home.should == "C:/rubyspec/home1" + ENV['USERPROFILE'] = "C:\\rubyspec\\home2" + Dir.home.should == "C:/rubyspec/home2" + ENV['HOME'] = "C:\\rubyspec\\home3" + Dir.home.should == "C:/rubyspec/home3" + ensure + ENV['HOME'], ENV['USERPROFILE'], ENV['HOMEDRIVE'], ENV['HOMEPATH'] = *old_dirs + end + end + end end describe "when called with the current user name" do @@ -28,7 +66,7 @@ describe "Dir.home" do end end - platform_is_not :windows, :solaris, :android do + platform_is_not :windows, :solaris, :android, :wasi do it "returns the named user's home directory, from the user database" do Dir.home(ENV['USER']).should == `echo ~#{ENV['USER']}`.chomp end @@ -37,9 +75,19 @@ describe "Dir.home" do it "returns a non-frozen string" do Dir.home(ENV['USER']).should_not.frozen? end + + it "returns a string with the filesystem encoding" do + Dir.home(ENV['USER']).encoding.should == Encoding.find("filesystem") + end end it "raises an ArgumentError if the named user doesn't exist" do -> { Dir.home('geuw2n288dh2k') }.should raise_error(ArgumentError) end + + describe "when called with a nil user name" do + it "returns the current user's home directory, reading $HOME first" do + Dir.home(nil).should == "/rubyspec_home" + end + end end diff --git a/spec/ruby/core/dir/mkdir_spec.rb b/spec/ruby/core/dir/mkdir_spec.rb index 0ed28f5a99..076ec19dd9 100644 --- a/spec/ruby/core/dir/mkdir_spec.rb +++ b/spec/ruby/core/dir/mkdir_spec.rb @@ -46,7 +46,7 @@ describe "Dir.mkdir" do end end - it "calls #to_path on non-String arguments" do + it "calls #to_path on non-String path arguments" do DirSpecs.clear_dirs p = mock('path') p.should_receive(:to_path).and_return(DirSpecs.mock_dir('nonexisting')) @@ -54,6 +54,22 @@ describe "Dir.mkdir" do DirSpecs.clear_dirs end + it "calls #to_int on non-Integer permissions argument" do + DirSpecs.clear_dirs + path = DirSpecs.mock_dir('nonexisting') + permissions = mock('permissions') + permissions.should_receive(:to_int).and_return(0666) + Dir.mkdir(path, permissions) + DirSpecs.clear_dirs + end + + it "raises TypeError if non-Integer permissions argument does not have #to_int method" do + path = DirSpecs.mock_dir('nonexisting') + permissions = Object.new + + -> { Dir.mkdir(path, permissions) }.should raise_error(TypeError, 'no implicit conversion of Object into Integer') + end + it "raises a SystemCallError if any of the directories in the path before the last does not exist" do -> { Dir.mkdir "#{DirSpecs.nonexistent}/subdir" }.should raise_error(SystemCallError) end diff --git a/spec/ruby/core/dir/read_spec.rb b/spec/ruby/core/dir/read_spec.rb index 59de2e81cf..276930c6b7 100644 --- a/spec/ruby/core/dir/read_spec.rb +++ b/spec/ruby/core/dir/read_spec.rb @@ -39,5 +39,38 @@ describe "Dir#read" do entries.sort.should == DirSpecs.expected_paths end + platform_is_not :windows do + it "returns all directory entries even when encoding conversion will fail" do + dir = Dir.open(File.join(DirSpecs.mock_dir, 'special')) + utf8_entries = [] + begin + while entry = dir.read + utf8_entries << entry + end + ensure + dir.close + end + old_internal_encoding = Encoding::default_internal + old_external_encoding = Encoding::default_external + Encoding.default_internal = Encoding::UTF_8 + Encoding.default_external = Encoding::SHIFT_JIS + shift_jis_entries = [] + begin + Dir.open(File.join(DirSpecs.mock_dir, 'special')) do |d| + -> { + while entry = d.read + shift_jis_entries << entry + end + }.should_not raise_error + end + ensure + Encoding.default_internal = old_internal_encoding + Encoding.default_external = old_external_encoding + end + shift_jis_entries.size.should == utf8_entries.size + shift_jis_entries.filter { |f| f.encoding == Encoding::SHIFT_JIS }.size.should == 1 + end + end + it_behaves_like :dir_closed, :read end diff --git a/spec/ruby/core/dir/shared/chroot.rb b/spec/ruby/core/dir/shared/chroot.rb index b14a433670..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,10 +14,13 @@ 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 - -> { Dir.send(@method, File.dirname(__FILE__)) }.should_not raise_error + -> { Dir.send(@method, __dir__) }.should_not raise_error File.should.exist?("/#{File.basename(__FILE__)}") - end + end unless compilations_ci it "returns 0 if successful" do Dir.send(@method, '/').should == 0 @@ -31,7 +34,7 @@ describe :dir_chroot_as_root, shared: true do Dir.send(@method, @real_root) File.should.exist?(@ref_dir) File.should_not.exist?("/#{File.basename(__FILE__)}") - end + end unless compilations_ci it "calls #to_path on non-String argument" do p = mock('path') diff --git a/spec/ruby/core/dir/shared/exist.rb b/spec/ruby/core/dir/shared/exist.rb index 765d1b656c..2ea4f88a80 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,7 +28,7 @@ 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 @@ -50,7 +50,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 ae5c2a114b..745f02d46b 100644 --- a/spec/ruby/core/dir/shared/glob.rb +++ b/spec/ruby/core/dir/shared/glob.rb @@ -12,7 +12,7 @@ describe :dir_glob, shared: true do end it "raises an Encoding::CompatibilityError if the argument encoding is not compatible with US-ASCII" do - pattern = "file*".force_encoding Encoding::UTF_16BE + pattern = "file*".dup.force_encoding Encoding::UTF_16BE -> { Dir.send(@method, pattern) }.should raise_error(Encoding::CompatibilityError) end @@ -23,18 +23,43 @@ describe :dir_glob, shared: true do Dir.send(@method, obj).should == %w[file_one.ext] end - ruby_version_is ""..."2.7" do - it "splits the string on \\0 if there is only one string given and warns" do - -> { - Dir.send(@method, "file_o*\0file_t*").should == - %w!file_one.ext file_two.ext! - }.should complain(/warning: use glob patterns list instead of nul-separated patterns/) + 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 + + ruby_version_is ""..."3.1" do + it "result is sorted with any non false value of sort:" do + result = Dir.send(@method, '*', sort: 0) + result.should == result.sort + + result = Dir.send(@method, '*', sort: nil) + result.should == result.sort + + result = Dir.send(@method, '*', sort: 'false') + result.should == result.sort end end - ruby_version_is "2.7" do - it "raises an ArgumentError if the string contains \\0" do - -> {Dir.send(@method, "file_o*\0file_t*")}.should raise_error ArgumentError, /nul-separated/ + ruby_version_is "3.1" do + 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 end @@ -64,6 +89,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/*'] @@ -76,6 +105,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 @@ -190,7 +227,9 @@ describe :dir_glob, shared: true do dir/ nested/ special/ + special/test\ +()[]{}/ special/test{1}/ + special/{}/ subdir_one/ subdir_two/ ] |