diff options
Diffstat (limited to 'spec/ruby/core/dir')
-rw-r--r-- | spec/ruby/core/dir/children_spec.rb | 17 | ||||
-rw-r--r-- | spec/ruby/core/dir/each_child_spec.rb | 13 | ||||
-rw-r--r-- | spec/ruby/core/dir/each_spec.rb | 11 | ||||
-rw-r--r-- | spec/ruby/core/dir/entries_spec.rb | 2 | ||||
-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 | 1 | ||||
-rw-r--r-- | spec/ruby/core/dir/foreach_spec.rb | 10 | ||||
-rw-r--r-- | spec/ruby/core/dir/glob_spec.rb | 140 | ||||
-rw-r--r-- | spec/ruby/core/dir/home_spec.rb | 48 | ||||
-rw-r--r-- | spec/ruby/core/dir/mkdir_spec.rb | 18 | ||||
-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 | 33 |
14 files changed, 352 insertions, 38 deletions
diff --git a/spec/ruby/core/dir/children_spec.rb b/spec/ruby/core/dir/children_spec.rb index 03698cc246..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 @@ -113,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 @@ -131,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 520186e79e..7194273b95 100644 --- a/spec/ruby/core/dir/each_child_spec.rb +++ b/spec/ruby/core/dir/each_child_spec.rb @@ -86,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 91c30fccae..7462542acf 100644 --- a/spec/ruby/core/dir/entries_spec.rb +++ b/spec/ruby/core/dir/entries_spec.rb @@ -47,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 a8d6e69c44..087f46b331 100644 --- a/spec/ruby/core/dir/fixtures/common.rb +++ b/spec/ruby/core/dir/fixtures/common.rb @@ -82,6 +82,7 @@ module DirSpecs special/test{1}/file[1] special/{}/special + special/test\ +()[]{}/hello_world.erb ] platform_is_not :windows do diff --git a/spec/ruby/core/dir/foreach_spec.rb b/spec/ruby/core/dir/foreach_spec.rb index b0e18afeb5..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} + dirs.each { |dir| dir.encoding.should == Encoding::UTF_8 } - dirs = Dir.foreach("#{DirSpecs.mock_dir}/deeply/nested", encoding: Encoding::UTF_16LE).to_a.sort - dirs.each {|dir| dir.encoding.should == Encoding::UTF_16LE} + 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 } - Dir.foreach("#{DirSpecs.mock_dir}/deeply/nested", encoding: Encoding::UTF_16LE) do |f| - f.encoding.should == Encoding::UTF_16LE + 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 43dac73eee..32f515c81d 100644 --- a/spec/ruby/core/dir/glob_spec.rb +++ b/spec/ruby/core/dir/glob_spec.rb @@ -79,6 +79,7 @@ describe "Dir.glob" do nested/ nested/.dotsubir/ special/ + special/test\ +()[]{}/ special/test{1}/ special/{}/ subdir_one/ @@ -105,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 @@ -130,6 +131,7 @@ describe "Dir.glob" do ./nested/ ./nested/.dotsubir/ ./special/ + ./special/test\ +()[]{}/ ./special/test{1}/ ./special/{}/ ./subdir_one/ @@ -180,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 diff --git a/spec/ruby/core/dir/home_spec.rb b/spec/ruby/core/dir/home_spec.rb index 8377f1dc97..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 @@ -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/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 60d4a8c97a..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 @@ -27,24 +27,22 @@ describe :dir_glob, shared: true do -> {Dir.send(@method, "file_o*\0file_t*")}.should raise_error ArgumentError, /nul-separated/ end - ruby_version_is "3.0" do - it "result is sorted by default" do - result = Dir.send(@method, '*') - result.should == result.sort - 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 "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 "sort: false returns same files" do + result = Dir.send(@method,'*', sort: false) + result.sort.should == Dir.send(@method, '*').sort end - ruby_version_is "3.0"..."3.1" do + 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 @@ -111,6 +109,10 @@ describe :dir_glob, shared: true do 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 @@ -225,6 +227,7 @@ describe :dir_glob, shared: true do dir/ nested/ special/ + special/test\ +()[]{}/ special/test{1}/ special/{}/ subdir_one/ |