summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--file.c20
-rw-r--r--spec/ruby/core/file/absolute_path_spec.rb53
2 files changed, 73 insertions, 0 deletions
diff --git a/file.c b/file.c
index b1ba4c3cfc2..1c14c7e7025 100644
--- a/file.c
+++ b/file.c
@@ -4106,6 +4106,25 @@ s_absolute_path(int c, const VALUE * v, VALUE _)
return rb_file_s_absolute_path(c, v);
}
+/*
+ * call-seq:
+ * File.absolute_path?(file_name) -> true or false
+ *
+ * Returns <code>true</code> if +file_name+ is an absolute path, and
+ * <code>false</code> otherwise.
+ *
+ * File.absolute_path?("c:/foo") #=> false (on Linux), true (on Windows)
+ */
+
+static VALUE
+s_absolute_path_p(VALUE klass, VALUE fname)
+{
+ VALUE path = rb_get_path(fname);
+
+ if (!rb_is_absolute_path(RSTRING_PTR(path))) return Qfalse;
+ return Qtrue;
+}
+
enum rb_realpath_mode {
RB_REALPATH_CHECK,
RB_REALPATH_DIR,
@@ -6504,6 +6523,7 @@ Init_File(void)
rb_define_singleton_method(rb_cFile, "mkfifo", rb_file_s_mkfifo, -1);
rb_define_singleton_method(rb_cFile, "expand_path", s_expand_path, -1);
rb_define_singleton_method(rb_cFile, "absolute_path", s_absolute_path, -1);
+ rb_define_singleton_method(rb_cFile, "absolute_path?", s_absolute_path_p, 1);
rb_define_singleton_method(rb_cFile, "realpath", rb_file_s_realpath, -1);
rb_define_singleton_method(rb_cFile, "realdirpath", rb_file_s_realdirpath, -1);
rb_define_singleton_method(rb_cFile, "basename", rb_file_s_basename, -1);
diff --git a/spec/ruby/core/file/absolute_path_spec.rb b/spec/ruby/core/file/absolute_path_spec.rb
index d6f3f060c76..52839cf1cc4 100644
--- a/spec/ruby/core/file/absolute_path_spec.rb
+++ b/spec/ruby/core/file/absolute_path_spec.rb
@@ -1,5 +1,58 @@
require_relative '../../spec_helper'
+ruby_version_is "2.7" do
+ describe "File.absolute_path?" do
+ before :each do
+ @abs = File.expand_path(__FILE__)
+ end
+
+ it "returns true if it's an absolute pathname" do
+ File.absolute_path?(@abs).should be_true
+ end
+
+ it "returns false if it's a relative path" do
+ File.absolute_path?(File.basename(__FILE__)).should be_false
+ end
+
+ it "returns false if it's a tricky relative path" do
+ File.absolute_path?("C:foo\\bar").should be_false
+ end
+
+ it "does not expand '~' to a home directory." do
+ File.absolute_path?('~').should be_false
+ end
+
+ it "does not expand '~user' to a home directory." do
+ path = File.dirname(@abs)
+ Dir.chdir(path) do
+ File.absolute_path?('~user').should be_false
+ end
+ end
+
+ it "calls #to_path on its argument" do
+ mock = mock_to_path(File.expand_path(__FILE__))
+
+ File.absolute_path?(mock).should be_true
+ end
+
+ platform_is_not :windows do
+ it "takes into consideration the platform's root" do
+ File.absolute_path?("C:\\foo\\bar").should be_false
+ File.absolute_path?("C:/foo/bar").should be_false
+ File.absolute_path?("/foo/bar\\baz").should be_true
+ end
+ end
+
+ platform_is :windows do
+ it "takes into consideration the platform path separator(s)" do
+ File.absolute_path?("C:\\foo\\bar").should be_true
+ File.absolute_path?("C:/foo/bar").should be_true
+ File.absolute_path?("/foo/bar\\baz").should be_false
+ end
+ end
+ end
+end
+
describe "File.absolute_path" do
before :each do
@abs = File.expand_path(__FILE__)