diff options
Diffstat (limited to 'spec/ruby/shared/file')
24 files changed, 991 insertions, 0 deletions
diff --git a/spec/ruby/shared/file/blockdev.rb b/spec/ruby/shared/file/blockdev.rb new file mode 100644 index 0000000000..b0b3ea040a --- /dev/null +++ b/spec/ruby/shared/file/blockdev.rb @@ -0,0 +1,9 @@ +describe :file_blockdev, shared: true do + it "returns true/false depending if the named file is a block device" do + @object.send(@method, tmp("")).should == false + end + + it "accepts an object that has a #to_path method" do + @object.send(@method, mock_to_path(tmp(""))).should == false + end +end diff --git a/spec/ruby/shared/file/chardev.rb b/spec/ruby/shared/file/chardev.rb new file mode 100644 index 0000000000..8a7a89fd05 --- /dev/null +++ b/spec/ruby/shared/file/chardev.rb @@ -0,0 +1,9 @@ +describe :file_chardev, shared: true do + it "returns true/false depending if the named file is a char device" do + @object.send(@method, tmp("")).should == false + end + + it "accepts an object that has a #to_path method" do + @object.send(@method, mock_to_path(tmp(""))).should == false + end +end diff --git a/spec/ruby/shared/file/directory.rb b/spec/ruby/shared/file/directory.rb new file mode 100644 index 0000000000..8ba933a601 --- /dev/null +++ b/spec/ruby/shared/file/directory.rb @@ -0,0 +1,66 @@ +describe :file_directory, shared: true do + before :each do + @dir = tmp("file_directory") + @file = tmp("file_directory.txt") + + mkdir_p @dir + touch @file + end + + after :each do + rm_r @dir, @file + end + + it "returns true if the argument is a directory" do + @object.send(@method, @dir).should be_true + end + + it "returns false if the argument is not a directory" do + @object.send(@method, @file).should be_false + end + + it "accepts an object that has a #to_path method" do + @object.send(@method, mock_to_path(@dir)).should be_true + end + + it "raises a TypeError when passed an Integer" do + -> { @object.send(@method, 1) }.should raise_error(TypeError) + -> { @object.send(@method, bignum_value) }.should raise_error(TypeError) + end + + it "raises a TypeError when passed nil" do + -> { @object.send(@method, nil) }.should raise_error(TypeError) + end +end + +describe :file_directory_io, shared: true do + before :each do + @dir = tmp("file_directory_io") + @file = tmp("file_directory_io.txt") + + mkdir_p @dir + touch @file + end + + after :each do + rm_r @dir, @file + end + + it "returns false if the argument is an IO that's not a directory" do + @object.send(@method, STDIN).should be_false + end + + platform_is_not :windows do + it "returns true if the argument is an IO that is a directory" do + File.open(@dir, "r") do |f| + @object.send(@method, f).should be_true + end + end + end + + it "calls #to_io to convert a non-IO object" do + io = mock('FileDirectoryIO') + io.should_receive(:to_io).and_return(STDIN) + @object.send(@method, io).should be_false + end +end diff --git a/spec/ruby/shared/file/executable.rb b/spec/ruby/shared/file/executable.rb new file mode 100644 index 0000000000..baa156de98 --- /dev/null +++ b/spec/ruby/shared/file/executable.rb @@ -0,0 +1,83 @@ +describe :file_executable, shared: true do + before :each do + @file1 = tmp('temp1.txt') + @file2 = tmp('temp2.txt') + + touch @file1 + touch @file2 + + File.chmod(0755, @file1) + end + + after :each do + rm_r @file1, @file2 + end + + platform_is_not :windows, :android do + it "returns true if named file is executable by the effective user id of the process, otherwise false" do + @object.send(@method, '/etc/passwd').should == false + @object.send(@method, @file1).should == true + @object.send(@method, @file2).should == false + end + + it "returns true if the argument is an executable file" do + @object.send(@method, @file1).should == true + @object.send(@method, @file2).should == false + end + + it "accepts an object that has a #to_path method" do + @object.send(@method, mock_to_path(@file1)).should == true + end + end + + it "raises an ArgumentError if not passed one argument" do + -> { @object.send(@method) }.should raise_error(ArgumentError) + end + + it "raises a TypeError if not passed a String type" do + -> { @object.send(@method, 1) }.should raise_error(TypeError) + -> { @object.send(@method, nil) }.should raise_error(TypeError) + -> { @object.send(@method, false) }.should raise_error(TypeError) + end + + platform_is_not :windows do + as_superuser do + context "when run by a superuser" do + before :each do + @file = tmp('temp3.txt') + touch @file + end + + after :each do + rm_r @file + end + + it "returns true if file owner has permission to execute" do + File.chmod(0766, @file) + @object.send(@method, @file).should == true + end + + it "returns true if group has permission to execute" do + File.chmod(0676, @file) + @object.send(@method, @file).should == true + end + + it "returns true if other have permission to execute" do + File.chmod(0667, @file) + @object.send(@method, @file).should == true + end + + it "return false if nobody has permission to execute" do + File.chmod(0666, @file) + @object.send(@method, @file).should == false + end + end + end + end +end + +describe :file_executable_missing, shared: true do + it "returns false if the file does not exist" do + @object.send(@method, 'fake_file').should == false + end +end diff --git a/spec/ruby/shared/file/executable_real.rb b/spec/ruby/shared/file/executable_real.rb new file mode 100644 index 0000000000..bf2734ea07 --- /dev/null +++ b/spec/ruby/shared/file/executable_real.rb @@ -0,0 +1,81 @@ +describe :file_executable_real, shared: true do + before :each do + @file1 = tmp('temp1.txt.exe') + @file2 = tmp('temp2.txt') + + touch @file1 + touch @file2 + + File.chmod(0755, @file1) + end + + after :each do + rm_r @file1, @file2 + end + + platform_is_not :windows do + it "returns true if the file its an executable" do + @object.send(@method, @file1).should == true + @object.send(@method, @file2).should == false + end + + it "accepts an object that has a #to_path method" do + @object.send(@method, mock_to_path(@file1)).should == true + end + end + + it "returns true if named file is readable by the real user id of the process, otherwise false" do + @object.send(@method, @file1).should == true + end + + it "raises an ArgumentError if not passed one argument" do + -> { @object.send(@method) }.should raise_error(ArgumentError) + end + + it "raises a TypeError if not passed a String type" do + -> { @object.send(@method, 1) }.should raise_error(TypeError) + -> { @object.send(@method, nil) }.should raise_error(TypeError) + -> { @object.send(@method, false) }.should raise_error(TypeError) + end + + platform_is_not :windows do + as_real_superuser do + context "when run by a real superuser" do + before :each do + @file = tmp('temp3.txt') + touch @file + end + + after :each do + rm_r @file + end + + it "returns true if file owner has permission to execute" do + File.chmod(0766, @file) + @object.send(@method, @file).should == true + end + + it "returns true if group has permission to execute" do + File.chmod(0676, @file) + @object.send(@method, @file).should == true + end + + it "returns true if other have permission to execute" do + File.chmod(0667, @file) + @object.send(@method, @file).should == true + end + + it "return false if nobody has permission to execute" do + File.chmod(0666, @file) + @object.send(@method, @file).should == false + end + end + end + end +end + +describe :file_executable_real_missing, shared: true do + it "returns false if the file does not exist" do + @object.send(@method, 'fake_file').should == false + end +end diff --git a/spec/ruby/shared/file/exist.rb b/spec/ruby/shared/file/exist.rb new file mode 100644 index 0000000000..67424146c5 --- /dev/null +++ b/spec/ruby/shared/file/exist.rb @@ -0,0 +1,19 @@ +describe :file_exist, shared: true do + it "returns true if the file exist" do + @object.send(@method, __FILE__).should == true + @object.send(@method, 'a_fake_file').should == false + end + + it "raises an ArgumentError if not passed one argument" do + -> { @object.send(@method) }.should raise_error(ArgumentError) + -> { @object.send(@method, __FILE__, __FILE__) }.should raise_error(ArgumentError) + end + + it "raises a TypeError if not passed a String type" do + -> { @object.send(@method, nil) }.should raise_error(TypeError) + end + + it "accepts an object that has a #to_path method" do + @object.send(@method, mock_to_path(__FILE__)).should == true + end +end diff --git a/spec/ruby/shared/file/file.rb b/spec/ruby/shared/file/file.rb new file mode 100644 index 0000000000..c1748a88b3 --- /dev/null +++ b/spec/ruby/shared/file/file.rb @@ -0,0 +1,45 @@ +describe :file_file, shared: true do + before :each do + platform_is :windows do + @null = "NUL" + @dir = "C:\\" + end + + platform_is_not :windows do + @null = "/dev/null" + @dir = "/bin" + end + + @file = tmp("test.txt") + touch @file + end + + after :each do + rm_r @file + end + + it "returns true if the named file exists and is a regular file." do + @object.send(@method, @file).should == true + @object.send(@method, @dir).should == false + end + + it "accepts an object that has a #to_path method" do + @object.send(@method, mock_to_path(@file)).should == true + end + + platform_is_not :windows do + it "returns true if the null device exists and is a regular file." do + @object.send(@method, @null).should == false # May fail on MS Windows + end + end + + it "raises an ArgumentError if not passed one argument" do + -> { @object.send(@method) }.should raise_error(ArgumentError) + -> { @object.send(@method, @null, @file) }.should raise_error(ArgumentError) + end + + it "raises a TypeError if not passed a String type" do + -> { @object.send(@method, nil) }.should raise_error(TypeError) + -> { @object.send(@method, 1) }.should raise_error(TypeError) + end +end diff --git a/spec/ruby/shared/file/grpowned.rb b/spec/ruby/shared/file/grpowned.rb new file mode 100644 index 0000000000..24e84c28e3 --- /dev/null +++ b/spec/ruby/shared/file/grpowned.rb @@ -0,0 +1,39 @@ +describe :file_grpowned, shared: true do + before :each do + @file = tmp('i_exist') + touch(@file) { |f| f.puts "file_content" } + File.chown(nil, Process.gid, @file) rescue nil + end + + after :each do + rm_r @file + end + + platform_is_not :windows do + it "returns true if the file exist" do + @object.send(@method, @file).should be_true + end + + it "accepts an object that has a #to_path method" do + @object.send(@method, mock_to_path(@file)).should be_true + end + + it 'takes non primary groups into account' do + group = (Process.groups - [Process.egid]).first + + if group + File.chown(nil, group, @file) + + @object.send(@method, @file).should == true + else + skip "No supplementary groups" + end + end + end + + platform_is :windows do + it "returns false if the file exist" do + @object.send(@method, @file).should be_false + end + end +end diff --git a/spec/ruby/shared/file/identical.rb b/spec/ruby/shared/file/identical.rb new file mode 100644 index 0000000000..b7a2904839 --- /dev/null +++ b/spec/ruby/shared/file/identical.rb @@ -0,0 +1,51 @@ +describe :file_identical, shared: true do + before :each do + @file1 = tmp('file_identical.txt') + @file2 = tmp('file_identical2.txt') + @link = tmp('file_identical.lnk') + @non_exist = 'non_exist' + + touch(@file1) { |f| f.puts "file1" } + touch(@file2) { |f| f.puts "file2" } + + rm_r @link + begin + File.link(@file1, @link) + rescue Errno::EACCES + File.symlink(@file1, @link) + end + end + + after :each do + rm_r @link, @file1, @file2 + end + + it "returns true for a file and its link" do + @object.send(@method, @file1, @link).should == true + end + + it "returns false if any of the files doesn't exist" do + @object.send(@method, @file1, @non_exist).should be_false + @object.send(@method, @non_exist, @file1).should be_false + @object.send(@method, @non_exist, @non_exist).should be_false + end + + it "accepts an object that has a #to_path method" do + @object.send(@method, mock_to_path(@file1), mock_to_path(@link)).should == true + end + + it "raises an ArgumentError if not passed two arguments" do + -> { @object.send(@method, @file1, @file2, @link) }.should raise_error(ArgumentError) + -> { @object.send(@method, @file1) }.should raise_error(ArgumentError) + end + + it "raises a TypeError if not passed String types" do + -> { @object.send(@method, 1,1) }.should raise_error(TypeError) + end + + it "returns true if both named files are identical" do + @object.send(@method, @file1, @file1).should be_true + @object.send(@method, @link, @link).should be_true + @object.send(@method, @file1, @file2).should be_false + end +end diff --git a/spec/ruby/shared/file/owned.rb b/spec/ruby/shared/file/owned.rb new file mode 100644 index 0000000000..4a08a4ed89 --- /dev/null +++ b/spec/ruby/shared/file/owned.rb @@ -0,0 +1,3 @@ +describe :file_owned, shared: true do + it "accepts an object that has a #to_path method" +end diff --git a/spec/ruby/shared/file/pipe.rb b/spec/ruby/shared/file/pipe.rb new file mode 100644 index 0000000000..7e150b9167 --- /dev/null +++ b/spec/ruby/shared/file/pipe.rb @@ -0,0 +1,3 @@ +describe :file_pipe, shared: true do + it "accepts an object that has a #to_path method" +end diff --git a/spec/ruby/shared/file/readable.rb b/spec/ruby/shared/file/readable.rb new file mode 100644 index 0000000000..7b45e23e36 --- /dev/null +++ b/spec/ruby/shared/file/readable.rb @@ -0,0 +1,49 @@ +describe :file_readable, shared: true do + before :each do + @file = tmp('i_exist') + platform_is :windows do + @file2 = File.join(ENV["WINDIR"], "system32/drivers/etc/services").tr(File::SEPARATOR, File::ALT_SEPARATOR) + end + platform_is_not :windows, :android do + @file2 = "/etc/passwd" + end + platform_is :android do + @file2 = "/system/bin/sh" + end + end + + after :each do + rm_r @file + end + + it "returns true if named file is readable by the effective user id of the process, otherwise false" do + @object.send(@method, @file2).should == true + File.open(@file,'w') { @object.send(@method, @file).should == true } + end + + it "accepts an object that has a #to_path method" do + @object.send(@method, mock_to_path(@file2)).should == true + end + + platform_is_not :windows do + as_superuser do + context "when run by a superuser" do + it "returns true unconditionally" do + file = tmp('temp.txt') + touch file + + File.chmod(0333, file) + @object.send(@method, file).should == true + + rm_r file + end + end + end + end +end + +describe :file_readable_missing, shared: true do + it "returns false if the file does not exist" do + @object.send(@method, 'fake_file').should == false + end +end diff --git a/spec/ruby/shared/file/readable_real.rb b/spec/ruby/shared/file/readable_real.rb new file mode 100644 index 0000000000..32d38bc7a2 --- /dev/null +++ b/spec/ruby/shared/file/readable_real.rb @@ -0,0 +1,39 @@ +describe :file_readable_real, shared: true do + before :each do + @file = tmp('i_exist') + end + + after :each do + rm_r @file + end + + it "returns true if named file is readable by the real user id of the process, otherwise false" do + File.open(@file,'w') { @object.send(@method, @file).should == true } + end + + it "accepts an object that has a #to_path method" do + File.open(@file,'w') { @object.send(@method, mock_to_path(@file)).should == true } + end + + platform_is_not :windows do + as_real_superuser do + context "when run by a real superuser" do + it "returns true unconditionally" do + file = tmp('temp.txt') + touch file + + File.chmod(0333, file) + @object.send(@method, file).should == true + + rm_r file + end + end + end + end +end + +describe :file_readable_real_missing, shared: true do + it "returns false if the file does not exist" do + @object.send(@method, 'fake_file').should == false + end +end diff --git a/spec/ruby/shared/file/setgid.rb b/spec/ruby/shared/file/setgid.rb new file mode 100644 index 0000000000..9893795832 --- /dev/null +++ b/spec/ruby/shared/file/setgid.rb @@ -0,0 +1,2 @@ +describe :file_setgid, shared: true do +end diff --git a/spec/ruby/shared/file/setuid.rb b/spec/ruby/shared/file/setuid.rb new file mode 100644 index 0000000000..6401674a94 --- /dev/null +++ b/spec/ruby/shared/file/setuid.rb @@ -0,0 +1,2 @@ +describe :file_setuid, shared: true do +end diff --git a/spec/ruby/shared/file/size.rb b/spec/ruby/shared/file/size.rb new file mode 100644 index 0000000000..cba99fe6a5 --- /dev/null +++ b/spec/ruby/shared/file/size.rb @@ -0,0 +1,124 @@ +describe :file_size, shared: true do + before :each do + @exists = tmp('i_exist') + touch(@exists) { |f| f.write 'rubinius' } + end + + after :each do + rm_r @exists + end + + it "returns the size of the file if it exists and is not empty" do + @object.send(@method, @exists).should == 8 + end + + it "accepts a String-like (to_str) parameter" do + obj = mock("file") + obj.should_receive(:to_str).and_return(@exists) + + @object.send(@method, obj).should == 8 + end + + it "accepts an object that has a #to_path method" do + @object.send(@method, mock_to_path(@exists)).should == 8 + end +end + +describe :file_size_to_io, shared: true do + before :each do + @exists = tmp('i_exist') + touch(@exists) { |f| f.write 'rubinius' } + @file = File.open(@exists, 'r') + end + + after :each do + @file.close unless @file.closed? + rm_r @exists + end + + it "calls #to_io to convert the argument to an IO" do + obj = mock("io like") + obj.should_receive(:to_io).and_return(@file) + + @object.send(@method, obj).should == 8 + end +end + +describe :file_size_raise_when_missing, shared: true do + before :each do + # TODO: missing_file + @missing = tmp("i_dont_exist") + rm_r @missing + end + + after :each do + rm_r @missing + end + + it "raises an error if file_name doesn't exist" do + -> {@object.send(@method, @missing)}.should raise_error(Errno::ENOENT) + end +end + +describe :file_size_nil_when_missing, shared: true do + before :each do + # TODO: missing_file + @missing = tmp("i_dont_exist") + rm_r @missing + end + + after :each do + rm_r @missing + end + + it "returns nil if file_name doesn't exist or has 0 size" do + @object.send(@method, @missing).should == nil + end +end + +describe :file_size_0_when_empty, shared: true do + before :each do + @empty = tmp("i_am_empty") + touch @empty + end + + after :each do + rm_r @empty + end + + it "returns 0 if the file is empty" do + @object.send(@method, @empty).should == 0 + end +end + +describe :file_size_nil_when_empty, shared: true do + before :each do + @empty = tmp("i_am_empt") + touch @empty + end + + after :each do + rm_r @empty + end + + it "returns nil if file_name is empty" do + @object.send(@method, @empty).should == nil + end +end + +describe :file_size_with_file_argument, shared: true do + before :each do + @exists = tmp('i_exist') + touch(@exists) { |f| f.write 'rubinius' } + end + + after :each do + rm_r @exists + end + + it "accepts a File argument" do + File.open(@exists) do |f| + @object.send(@method, f).should == 8 + end + end +end diff --git a/spec/ruby/shared/file/socket.rb b/spec/ruby/shared/file/socket.rb new file mode 100644 index 0000000000..ef6c482d1c --- /dev/null +++ b/spec/ruby/shared/file/socket.rb @@ -0,0 +1,33 @@ +describe :file_socket, shared: true do + it "returns false if the file is not a socket" do + filename = tmp("i_exist") + touch(filename) + + @object.send(@method, filename).should == false + + rm_r filename + end + + it "returns true if the file is a socket" do + require 'socket' + + # We need a really short name here. + # On Linux the path length is limited to 107, see unix(7). + name = tmp("s") + server = UNIXServer.new(name) + + @object.send(@method, name).should == true + + server.close + rm_r name + end + + it "accepts an object that has a #to_path method" do + obj = Object.new + def obj.to_path + __FILE__ + end + + @object.send(@method, obj).should == false + end +end diff --git a/spec/ruby/shared/file/sticky.rb b/spec/ruby/shared/file/sticky.rb new file mode 100644 index 0000000000..e07fa22fd7 --- /dev/null +++ b/spec/ruby/shared/file/sticky.rb @@ -0,0 +1,29 @@ +describe :file_sticky, shared: true do + before :each do + @dir = tmp('sticky_dir') + Dir.rmdir(@dir) if File.exist?(@dir) + end + + after :each do + Dir.rmdir(@dir) if File.exist?(@dir) + end + + platform_is_not :windows, :darwin, :freebsd, :netbsd, :openbsd, :aix do + it "returns true if the named file has the sticky bit, otherwise false" do + Dir.mkdir @dir, 01755 + + @object.send(@method, @dir).should == true + @object.send(@method, '/').should == false + end + end + + it "accepts an object that has a #to_path method" +end + +describe :file_sticky_missing, shared: true do + platform_is_not :windows do + it "returns false if the file dies not exist" do + @object.send(@method, 'fake_file').should == false + end + end +end diff --git a/spec/ruby/shared/file/symlink.rb b/spec/ruby/shared/file/symlink.rb new file mode 100644 index 0000000000..d1c1dc94df --- /dev/null +++ b/spec/ruby/shared/file/symlink.rb @@ -0,0 +1,46 @@ +describe :file_symlink, shared: true do + before :each do + @file = tmp("test.txt") + @link = tmp("test.lnk") + + rm_r @link + touch @file + end + + after :each do + rm_r @link, @file + end + + platform_is_not :windows do + it "returns true if the file is a link" do + File.symlink(@file, @link) + @object.send(@method, @link).should == true + end + + it "accepts an object that has a #to_path method" do + File.symlink(@file, @link) + @object.send(@method, mock_to_path(@link)).should == true + end + end +end + +describe :file_symlink_nonexistent, shared: true do + before :each do + @file = tmp("test.txt") + @link = tmp("test.lnk") + + rm_r @link + touch @file + end + + after :each do + rm_r @link + rm_r @file + end + + platform_is_not :windows do + it "returns false if the file does not exist" do + @object.send(@method, "non_existent_link").should == false + end + end +end diff --git a/spec/ruby/shared/file/world_readable.rb b/spec/ruby/shared/file/world_readable.rb new file mode 100644 index 0000000000..1dce7a580f --- /dev/null +++ b/spec/ruby/shared/file/world_readable.rb @@ -0,0 +1,49 @@ +require_relative '../../spec_helper' + +describe :file_world_readable, shared: true do + + before :each do + @file = tmp('world-readable') + touch @file + end + + after :each do + rm_r @file + end + + platform_is_not :windows do + it "returns nil if the file is chmod 600" do + File.chmod(0600, @file) + @object.world_readable?(@file).should be_nil + end + + it "returns nil if the file is chmod 000" do + File.chmod(0000, @file) + @object.world_readable?(@file).should be_nil + end + + it "returns nil if the file is chmod 700" do + File.chmod(0700, @file) + @object.world_readable?(@file).should be_nil + end + end + + # We don't specify what the Integer is because it's system dependent + it "returns an Integer if the file is chmod 644" do + File.chmod(0644, @file) + @object.world_readable?(@file).should be_an_instance_of(Integer) + end + + it "returns an Integer if the file is a directory and chmod 644" do + dir = tmp(rand().to_s + '-ww') + Dir.mkdir(dir) + Dir.should.exist?(dir) + File.chmod(0644, dir) + @object.world_readable?(dir).should be_an_instance_of(Integer) + Dir.rmdir(dir) + end + + it "coerces the argument with #to_path" do + @object.world_readable?(mock_to_path(@file)) + end +end diff --git a/spec/ruby/shared/file/world_writable.rb b/spec/ruby/shared/file/world_writable.rb new file mode 100644 index 0000000000..7ed252dcf3 --- /dev/null +++ b/spec/ruby/shared/file/world_writable.rb @@ -0,0 +1,49 @@ +require_relative '../../spec_helper' + +describe :file_world_writable, shared: true do + + before :each do + @file = tmp('world-writable') + touch @file + end + + after :each do + rm_r @file + end + + platform_is_not :windows do + it "returns nil if the file is chmod 600" do + File.chmod(0600, @file) + @object.world_writable?(@file).should be_nil + end + + it "returns nil if the file is chmod 000" do + File.chmod(0000, @file) + @object.world_writable?(@file).should be_nil + end + + it "returns nil if the file is chmod 700" do + File.chmod(0700, @file) + @object.world_writable?(@file).should be_nil + end + + # We don't specify what the Integer is because it's system dependent + it "returns an Integer if the file is chmod 777" do + File.chmod(0777, @file) + @object.world_writable?(@file).should be_an_instance_of(Integer) + end + + it "returns an Integer if the file is a directory and chmod 777" do + dir = tmp(rand().to_s + '-ww') + Dir.mkdir(dir) + Dir.should.exist?(dir) + File.chmod(0777, dir) + @object.world_writable?(dir).should be_an_instance_of(Integer) + Dir.rmdir(dir) + end + end + + it "coerces the argument with #to_path" do + @object.world_writable?(mock_to_path(@file)) + end +end diff --git a/spec/ruby/shared/file/writable.rb b/spec/ruby/shared/file/writable.rb new file mode 100644 index 0000000000..65ea2c1781 --- /dev/null +++ b/spec/ruby/shared/file/writable.rb @@ -0,0 +1,44 @@ +describe :file_writable, shared: true do + before :each do + @file = tmp('i_exist') + end + + after :each do + rm_r @file + end + + it "returns true if named file is writable by the effective user id of the process, otherwise false" do + platform_is_not :windows, :android do + as_user do + @object.send(@method, "/etc/passwd").should == false + end + end + File.open(@file,'w') { @object.send(@method, @file).should == true } + end + + it "accepts an object that has a #to_path method" do + File.open(@file,'w') { @object.send(@method, mock_to_path(@file)).should == true } + end + + platform_is_not :windows do + as_superuser do + context "when run by a superuser" do + it "returns true unconditionally" do + file = tmp('temp.txt') + touch file + + File.chmod(0555, file) + @object.send(@method, file).should == true + + rm_r file + end + end + end + end +end + +describe :file_writable_missing, shared: true do + it "returns false if the file does not exist" do + @object.send(@method, 'fake_file').should == false + end +end diff --git a/spec/ruby/shared/file/writable_real.rb b/spec/ruby/shared/file/writable_real.rb new file mode 100644 index 0000000000..b4a0a58c6e --- /dev/null +++ b/spec/ruby/shared/file/writable_real.rb @@ -0,0 +1,49 @@ +describe :file_writable_real, shared: true do + before :each do + @file = tmp('i_exist') + end + + after :each do + rm_r @file + end + + it "returns true if named file is writable by the real user id of the process, otherwise false" do + File.open(@file,'w') { @object.send(@method, @file).should == true } + end + + it "accepts an object that has a #to_path method" do + File.open(@file,'w') { @object.send(@method, mock_to_path(@file)).should == true } + end + + it "raises an ArgumentError if not passed one argument" do + -> { File.writable_real? }.should raise_error(ArgumentError) + end + + it "raises a TypeError if not passed a String type" do + -> { @object.send(@method, 1) }.should raise_error(TypeError) + -> { @object.send(@method, nil) }.should raise_error(TypeError) + -> { @object.send(@method, false) }.should raise_error(TypeError) + end + + platform_is_not :windows do + as_real_superuser do + context "when run by a real superuser" do + it "returns true unconditionally" do + file = tmp('temp.txt') + touch file + + File.chmod(0555, file) + @object.send(@method, file).should == true + + rm_r file + end + end + end + end +end + +describe :file_writable_real_missing, shared: true do + it "returns false if the file does not exist" do + @object.send(@method, 'fake_file').should == false + end +end diff --git a/spec/ruby/shared/file/zero.rb b/spec/ruby/shared/file/zero.rb new file mode 100644 index 0000000000..6a9399a021 --- /dev/null +++ b/spec/ruby/shared/file/zero.rb @@ -0,0 +1,68 @@ +describe :file_zero, shared: true do + before :each do + @zero_file = tmp("test.txt") + @nonzero_file = tmp("test2.txt") + @dir = tmp("dir") + + Dir.mkdir @dir + touch @zero_file + touch(@nonzero_file) { |f| f.puts "hello" } + end + + after :each do + rm_r @zero_file, @nonzero_file + rm_r @dir + end + + it "returns true if the file is empty" do + @object.send(@method, @zero_file).should == true + end + + it "returns false if the file is not empty" do + @object.send(@method, @nonzero_file).should == false + end + + it "accepts an object that has a #to_path method" do + @object.send(@method, mock_to_path(@zero_file)).should == true + end + + platform_is :windows do + it "returns true for NUL" do + @object.send(@method, 'NUL').should == true + @object.send(@method, 'nul').should == true + end + end + + platform_is_not :windows do + it "returns true for /dev/null" do + @object.send(@method, File.realpath('/dev/null')).should == true + end + end + + it "raises an ArgumentError if not passed one argument" do + -> { File.zero? }.should raise_error(ArgumentError) + end + + it "raises a TypeError if not passed a String type" do + -> { @object.send(@method, nil) }.should raise_error(TypeError) + -> { @object.send(@method, true) }.should raise_error(TypeError) + -> { @object.send(@method, false) }.should raise_error(TypeError) + end + + it "returns true inside a block opening a file if it is empty" do + File.open(@zero_file,'w') do + @object.send(@method, @zero_file).should == true + end + end + + # See https://bugs.ruby-lang.org/issues/449 for background + it "returns true or false for a directory" do + @object.send(@method, @dir).should be_true_or_false + end +end + +describe :file_zero_missing, shared: true do + it "returns false if the file does not exist" do + @object.send(@method, 'fake_file').should == false + end +end |
