зеркало из https://github.com/github/ruby.git
* lib/pathname.rb: use File.basename to decompose pathnames.
experimental Windows support. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9622 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
14a0dd769e
Коммит
66283e1c0f
|
@ -1,3 +1,8 @@
|
||||||
|
Sun Nov 27 05:37:20 2005 Tanaka Akira <akr@m17n.org>
|
||||||
|
|
||||||
|
* lib/pathname.rb: use File.basename to decompose pathnames.
|
||||||
|
experimental Windows support.
|
||||||
|
|
||||||
Sun Nov 27 00:56:13 2005 NAKAMURA, Hiroshi <nahi@ruby-lang.org>
|
Sun Nov 27 00:56:13 2005 NAKAMURA, Hiroshi <nahi@ruby-lang.org>
|
||||||
|
|
||||||
* lib/wsdl/xmlSchema/complexContent.rb: missing
|
* lib/wsdl/xmlSchema/complexContent.rb: missing
|
||||||
|
|
770
lib/pathname.rb
770
lib/pathname.rb
|
@ -15,8 +15,8 @@
|
||||||
# == Pathname
|
# == Pathname
|
||||||
#
|
#
|
||||||
# Pathname represents a pathname which locates a file in a filesystem.
|
# Pathname represents a pathname which locates a file in a filesystem.
|
||||||
# It supports only Unix style pathnames. It does not represent the file
|
# It does not represent the file itself.
|
||||||
# itself. A Pathname can be relative or absolute. It's not until you try to
|
# A Pathname can be relative or absolute. It's not until you try to
|
||||||
# reference the file that it even matters whether the file exists or not.
|
# reference the file that it even matters whether the file exists or not.
|
||||||
#
|
#
|
||||||
# Pathname is immutable. It has no method for destructive update.
|
# Pathname is immutable. It has no method for destructive update.
|
||||||
|
@ -240,6 +240,47 @@ class Pathname
|
||||||
Pathname.new(@path.sub(pattern, *rest, &block))
|
Pathname.new(@path.sub(pattern, *rest, &block))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if File::ALT_SEPARATOR
|
||||||
|
SEPARATOR_PAT = /[#{Regexp.quote File::ALT_SEPARATOR}#{Regexp.quote File::SEPARATOR}]/
|
||||||
|
else
|
||||||
|
SEPARATOR_PAT = /#{Regexp.quote File::SEPARATOR}/
|
||||||
|
end
|
||||||
|
|
||||||
|
# chop_basename(path) -> [pre-basename, basename] or nil
|
||||||
|
def chop_basename(path)
|
||||||
|
base = File.basename(path)
|
||||||
|
if /\A#{SEPARATOR_PAT}?\z/ =~ base
|
||||||
|
return nil
|
||||||
|
else
|
||||||
|
return path[0, path.rindex(base)], base
|
||||||
|
end
|
||||||
|
end
|
||||||
|
private :chop_basename
|
||||||
|
|
||||||
|
# split_names(path) -> prefix, [name, ...]
|
||||||
|
def split_names(path)
|
||||||
|
names = []
|
||||||
|
while r = chop_basename(path)
|
||||||
|
path, basename = r
|
||||||
|
names.unshift basename
|
||||||
|
end
|
||||||
|
return path, names
|
||||||
|
end
|
||||||
|
private :split_names
|
||||||
|
|
||||||
|
def prepend_prefix(prefix, relpath)
|
||||||
|
if relpath.empty?
|
||||||
|
File.dirname(prefix)
|
||||||
|
elsif /#{SEPARATOR_PAT}/ =~ prefix
|
||||||
|
prefix = File.dirname(prefix)
|
||||||
|
prefix = File.join(prefix, "") if File.basename(prefix + 'a') != 'a'
|
||||||
|
prefix + relpath
|
||||||
|
else
|
||||||
|
prefix + relpath
|
||||||
|
end
|
||||||
|
end
|
||||||
|
private :prepend_prefix
|
||||||
|
|
||||||
# Returns clean pathname of +self+ with consecutive slashes and useless dots
|
# Returns clean pathname of +self+ with consecutive slashes and useless dots
|
||||||
# removed. The filesystem is not accessed.
|
# removed. The filesystem is not accessed.
|
||||||
#
|
#
|
||||||
|
@ -261,118 +302,142 @@ class Pathname
|
||||||
# Nothing more, nothing less.
|
# Nothing more, nothing less.
|
||||||
#
|
#
|
||||||
def cleanpath_aggressive
|
def cleanpath_aggressive
|
||||||
# cleanpath_aggressive assumes:
|
path = @path
|
||||||
# * no symlink
|
|
||||||
# * all pathname prefix contained in the pathname is existing directory
|
|
||||||
return Pathname.new('') if @path == ''
|
|
||||||
absolute = absolute?
|
|
||||||
names = []
|
names = []
|
||||||
@path.scan(%r{[^/]+}) {|name|
|
pre = path
|
||||||
next if name == '.'
|
while r = chop_basename(pre)
|
||||||
if name == '..'
|
pre, base = r
|
||||||
if names.empty?
|
case base
|
||||||
next if absolute
|
when '.'
|
||||||
|
when '..'
|
||||||
|
names.unshift base
|
||||||
|
else
|
||||||
|
if names[0] == '..'
|
||||||
|
names.shift
|
||||||
else
|
else
|
||||||
if names.last != '..'
|
names.unshift base
|
||||||
names.pop
|
|
||||||
next
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
names << name
|
end
|
||||||
}
|
if /#{SEPARATOR_PAT}/o =~ File.basename(pre)
|
||||||
return Pathname.new(absolute ? '/' : '.') if names.empty?
|
names.shift while names[0] == '..'
|
||||||
path = absolute ? '/' : ''
|
end
|
||||||
path << names.join('/')
|
Pathname.new(prepend_prefix(pre, File.join(*names)))
|
||||||
Pathname.new(path)
|
|
||||||
end
|
end
|
||||||
private :cleanpath_aggressive
|
private :cleanpath_aggressive
|
||||||
|
|
||||||
|
# has_trailing_separator?(path) -> bool
|
||||||
|
def has_trailing_separator?(path)
|
||||||
|
if r = chop_basename(path)
|
||||||
|
pre, basename = r
|
||||||
|
pre.length + basename.length < path.length
|
||||||
|
else
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
private :has_trailing_separator?
|
||||||
|
|
||||||
|
# add_trailing_separator(path) -> path
|
||||||
|
def add_trailing_separator(path)
|
||||||
|
if File.basename(path + 'a') == 'a'
|
||||||
|
path
|
||||||
|
else
|
||||||
|
File.join(path, "") # xxx: Is File.join is appropriate to add separator?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
private :add_trailing_separator
|
||||||
|
|
||||||
|
def del_trailing_separator(path)
|
||||||
|
if r = chop_basename(path)
|
||||||
|
pre, basename = r
|
||||||
|
pre + basename
|
||||||
|
elsif /#{SEPARATOR_PAT}+\z/o =~ path
|
||||||
|
$` + File.dirname(path)[/#{SEPARATOR_PAT}*\z/o]
|
||||||
|
else
|
||||||
|
path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
private :del_trailing_separator
|
||||||
|
|
||||||
def cleanpath_conservative
|
def cleanpath_conservative
|
||||||
return Pathname.new('') if @path == ''
|
path = @path
|
||||||
names = @path.scan(%r{[^/]+})
|
names = []
|
||||||
last_dot = names.last == '.'
|
pre = path
|
||||||
names.delete('.')
|
while r = chop_basename(pre)
|
||||||
names.shift while names.first == '..' if absolute?
|
pre, base = r
|
||||||
return Pathname.new(absolute? ? '/' : '.') if names.empty?
|
names.unshift base if base != '.'
|
||||||
path = absolute? ? '/' : ''
|
end
|
||||||
path << names.join('/')
|
if /#{SEPARATOR_PAT}/o =~ File.basename(pre)
|
||||||
if names.last != '..'
|
names.shift while names[0] == '..'
|
||||||
if last_dot
|
end
|
||||||
path << '/.'
|
if names.empty?
|
||||||
elsif %r{/\z} =~ @path
|
File.dirname(pre)
|
||||||
path << '/'
|
else
|
||||||
|
if names.last != '..' && File.basename(path) == '.'
|
||||||
|
names << '.'
|
||||||
|
end
|
||||||
|
result = prepend_prefix(pre, File.join(*names))
|
||||||
|
if /\A(?:\.|\.\.)\z/ !~ names.last && has_trailing_separator?(path)
|
||||||
|
Pathname.new(add_trailing_separator(result))
|
||||||
|
else
|
||||||
|
Pathname.new(result)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
Pathname.new(path)
|
|
||||||
end
|
end
|
||||||
private :cleanpath_conservative
|
private :cleanpath_conservative
|
||||||
|
|
||||||
|
def realpath_rec(prefix, unresolved, h)
|
||||||
|
resolved = []
|
||||||
|
until unresolved.empty?
|
||||||
|
n = unresolved.shift
|
||||||
|
if n == '.'
|
||||||
|
next
|
||||||
|
elsif n == '..'
|
||||||
|
resolved.pop
|
||||||
|
else
|
||||||
|
path = prepend_prefix(prefix, File.join(*(resolved + [n])))
|
||||||
|
if h.include? path
|
||||||
|
if h[path] == :resolving
|
||||||
|
raise Errno::ELOOP.new(path)
|
||||||
|
else
|
||||||
|
prefix, *resolved = h[path]
|
||||||
|
end
|
||||||
|
else
|
||||||
|
s = File.lstat(path)
|
||||||
|
if s.symlink?
|
||||||
|
h[path] = :resolving
|
||||||
|
link_prefix, link_names = split_names(File.readlink(path))
|
||||||
|
if link_prefix == ''
|
||||||
|
prefix, *resolved = h[path] = realpath_rec(prefix, resolved + link_names, h)
|
||||||
|
else
|
||||||
|
prefix, *resolved = h[path] = realpath_rec(link_prefix, link_names, h)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
resolved << n
|
||||||
|
h[path] = [prefix, *resolved]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return prefix, *resolved
|
||||||
|
end
|
||||||
|
private :realpath_rec
|
||||||
|
|
||||||
#
|
#
|
||||||
# Returns a real (absolute) pathname of +self+ in the actual filesystem.
|
# Returns a real (absolute) pathname of +self+ in the actual filesystem.
|
||||||
# The real pathname doesn't contain symlinks or useless dots.
|
# The real pathname doesn't contain symlinks or useless dots.
|
||||||
#
|
#
|
||||||
# No arguments should be given; the old behaviour is *obsoleted*.
|
# No arguments should be given; the old behaviour is *obsoleted*.
|
||||||
#
|
#
|
||||||
def realpath(*args)
|
def realpath
|
||||||
unless args.empty?
|
path = @path
|
||||||
warn "The argument for Pathname#realpath is obsoleted."
|
prefix, names = split_names(path)
|
||||||
end
|
if prefix == ''
|
||||||
force_absolute = args.fetch(0, true)
|
prefix, names2 = split_names(Dir.pwd)
|
||||||
|
names = names2 + names
|
||||||
if %r{\A/} =~ @path
|
|
||||||
top = '/'
|
|
||||||
unresolved = @path.scan(%r{[^/]+})
|
|
||||||
elsif force_absolute
|
|
||||||
# Although POSIX getcwd returns a pathname which contains no symlink,
|
|
||||||
# 4.4BSD-Lite2 derived getcwd may return the environment variable $PWD
|
|
||||||
# which may contain a symlink.
|
|
||||||
# So the return value of Dir.pwd should be examined.
|
|
||||||
top = '/'
|
|
||||||
unresolved = Dir.pwd.scan(%r{[^/]+}) + @path.scan(%r{[^/]+})
|
|
||||||
else
|
|
||||||
top = ''
|
|
||||||
unresolved = @path.scan(%r{[^/]+})
|
|
||||||
end
|
|
||||||
resolved = []
|
|
||||||
|
|
||||||
until unresolved.empty?
|
|
||||||
case unresolved.last
|
|
||||||
when '.'
|
|
||||||
unresolved.pop
|
|
||||||
when '..'
|
|
||||||
resolved.unshift unresolved.pop
|
|
||||||
else
|
|
||||||
loop_check = {}
|
|
||||||
while (stat = File.lstat(path = top + unresolved.join('/'))).symlink?
|
|
||||||
symlink_id = "#{stat.dev}:#{stat.ino}"
|
|
||||||
raise Errno::ELOOP.new(path) if loop_check[symlink_id]
|
|
||||||
loop_check[symlink_id] = true
|
|
||||||
if %r{\A/} =~ (link = File.readlink(path))
|
|
||||||
top = '/'
|
|
||||||
unresolved = link.scan(%r{[^/]+})
|
|
||||||
else
|
|
||||||
unresolved[-1,1] = link.scan(%r{[^/]+})
|
|
||||||
end
|
|
||||||
end
|
|
||||||
next if (filename = unresolved.pop) == '.'
|
|
||||||
if filename != '..' && resolved.first == '..'
|
|
||||||
resolved.shift
|
|
||||||
else
|
|
||||||
resolved.unshift filename
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if top == '/'
|
|
||||||
resolved.shift while resolved[0] == '..'
|
|
||||||
end
|
|
||||||
|
|
||||||
if resolved.empty?
|
|
||||||
Pathname.new(top.empty? ? '.' : '/')
|
|
||||||
else
|
|
||||||
Pathname.new(top + resolved.join('/'))
|
|
||||||
end
|
end
|
||||||
|
prefix, *names = realpath_rec(prefix, names, {})
|
||||||
|
Pathname.new(prepend_prefix(prefix, File.join(*names)))
|
||||||
end
|
end
|
||||||
|
|
||||||
# #parent returns the parent directory.
|
# #parent returns the parent directory.
|
||||||
|
@ -402,18 +467,22 @@ class Pathname
|
||||||
# pathnames which points to roots such as <tt>/usr/..</tt>.
|
# pathnames which points to roots such as <tt>/usr/..</tt>.
|
||||||
#
|
#
|
||||||
def root?
|
def root?
|
||||||
%r{\A/+\z} =~ @path ? true : false
|
!!(chop_basename(@path) == nil && /#{SEPARATOR_PAT}/o =~ @path)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Predicate method for testing whether a path is absolute.
|
# Predicate method for testing whether a path is absolute.
|
||||||
# It returns +true+ if the pathname begins with a slash.
|
# It returns +true+ if the pathname begins with a slash.
|
||||||
def absolute?
|
def absolute?
|
||||||
%r{\A/} =~ @path ? true : false
|
!relative?
|
||||||
end
|
end
|
||||||
|
|
||||||
# The opposite of #absolute?
|
# The opposite of #absolute?
|
||||||
def relative?
|
def relative?
|
||||||
!absolute?
|
path = @path
|
||||||
|
while r = chop_basename(path)
|
||||||
|
path, basename = r
|
||||||
|
end
|
||||||
|
path == ''
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -423,7 +492,7 @@ class Pathname
|
||||||
# # yields "usr", "bin", and "ruby".
|
# # yields "usr", "bin", and "ruby".
|
||||||
#
|
#
|
||||||
def each_filename # :yield: s
|
def each_filename # :yield: s
|
||||||
@path.scan(%r{[^/]+}) { yield $& }
|
split_names(@path).each {|filename| yield filename }
|
||||||
end
|
end
|
||||||
|
|
||||||
# Iterates over and yields a new Pathname object
|
# Iterates over and yields a new Pathname object
|
||||||
|
@ -445,22 +514,9 @@ class Pathname
|
||||||
# It doesn't access actual filesystem.
|
# It doesn't access actual filesystem.
|
||||||
#
|
#
|
||||||
def descend
|
def descend
|
||||||
paths = []
|
vs = []
|
||||||
v = self
|
ascend {|v| vs << v }
|
||||||
if absolute?
|
vs.reverse_each {|v| yield v }
|
||||||
until v.root?
|
|
||||||
paths << v
|
|
||||||
v = v.dirname
|
|
||||||
end
|
|
||||||
paths << v
|
|
||||||
else
|
|
||||||
until v.basename == v
|
|
||||||
paths << v
|
|
||||||
v = v.dirname
|
|
||||||
end
|
|
||||||
paths << v
|
|
||||||
end
|
|
||||||
paths.reverse_each {|path| yield path }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Iterates over and yields a new Pathname object
|
# Iterates over and yields a new Pathname object
|
||||||
|
@ -482,22 +538,13 @@ class Pathname
|
||||||
# It doesn't access actual filesystem.
|
# It doesn't access actual filesystem.
|
||||||
#
|
#
|
||||||
def ascend
|
def ascend
|
||||||
paths = []
|
path = @path
|
||||||
v = self
|
yield self
|
||||||
if absolute?
|
while r = chop_basename(path)
|
||||||
until v.root?
|
path, name = r
|
||||||
paths << v
|
break if path.empty?
|
||||||
v = v.dirname
|
yield Pathname.new(del_trailing_separator(path))
|
||||||
end
|
|
||||||
paths << v
|
|
||||||
else
|
|
||||||
until v.basename == v
|
|
||||||
paths << v
|
|
||||||
v = v.dirname
|
|
||||||
end
|
|
||||||
paths << v
|
|
||||||
end
|
end
|
||||||
paths.each {|path| yield path }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -512,30 +559,47 @@ class Pathname
|
||||||
#
|
#
|
||||||
def +(other)
|
def +(other)
|
||||||
other = Pathname.new(other) unless Pathname === other
|
other = Pathname.new(other) unless Pathname === other
|
||||||
|
Pathname.new(plus(@path, other.to_s))
|
||||||
|
end
|
||||||
|
|
||||||
return other if other.absolute?
|
def plus(path1, path2) # -> path
|
||||||
|
prefix2 = path2
|
||||||
path1 = @path
|
index_list2 = []
|
||||||
path2 = other.to_s
|
basename_list2 = []
|
||||||
while m2 = %r{\A\.\.(?:/+|\z)}.match(path2) and
|
while r2 = chop_basename(prefix2)
|
||||||
m1 = %r{(\A|/+)([^/]+)\z}.match(path1) and
|
prefix2, basename2 = r2
|
||||||
%r{\A(?:\.|\.\.)\z} !~ m1[2]
|
index_list2.unshift prefix2.length
|
||||||
path1 = m1[1].empty? ? '.' : '/' if (path1 = m1.pre_match).empty?
|
basename_list2.unshift basename2
|
||||||
path2 = '.' if (path2 = m2.post_match).empty?
|
|
||||||
end
|
end
|
||||||
if %r{\A/+\z} =~ path1
|
return path2 if prefix2 != ''
|
||||||
while m2 = %r{\A\.\.(?:/+|\z)}.match(path2)
|
prefix1 = path1
|
||||||
path2 = '.' if (path2 = m2.post_match).empty?
|
while true
|
||||||
|
while !basename_list2.empty? && basename_list2.first == '.'
|
||||||
|
index_list2.shift
|
||||||
|
basename_list2.shift
|
||||||
|
end
|
||||||
|
break unless r1 = chop_basename(prefix1)
|
||||||
|
prefix1, basename1 = r1
|
||||||
|
next if basename1 == '.'
|
||||||
|
if basename1 == '..' || basename_list2.empty? || basename_list2.first != '..'
|
||||||
|
prefix1 = prefix1 + basename1
|
||||||
|
break
|
||||||
|
end
|
||||||
|
index_list2.shift
|
||||||
|
basename_list2.shift
|
||||||
|
end
|
||||||
|
r1 = chop_basename(prefix1)
|
||||||
|
if !r1 && /#{SEPARATOR_PAT}/o =~ File.basename(prefix1)
|
||||||
|
while !basename_list2.empty? && basename_list2.first == '..'
|
||||||
|
index_list2.shift
|
||||||
|
basename_list2.shift
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
if !basename_list2.empty?
|
||||||
return Pathname.new(path2) if path1 == '.'
|
suffix2 = path2[index_list2.first..-1]
|
||||||
return Pathname.new(path1) if path2 == '.'
|
r1 ? File.join(prefix1, suffix2) : prefix1 + suffix2
|
||||||
|
|
||||||
if %r{/\z} =~ path1
|
|
||||||
Pathname.new(path1 + path2)
|
|
||||||
else
|
else
|
||||||
Pathname.new(path1 + '/' + path2)
|
r1 ? prefix1 : File.dirname(prefix1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -605,44 +669,42 @@ class Pathname
|
||||||
# This method has existed since 1.8.1.
|
# This method has existed since 1.8.1.
|
||||||
#
|
#
|
||||||
def relative_path_from(base_directory)
|
def relative_path_from(base_directory)
|
||||||
if self.absolute? != base_directory.absolute?
|
dest_directory = self.cleanpath.to_s
|
||||||
raise ArgumentError,
|
base_directory = base_directory.cleanpath.to_s
|
||||||
"relative path between absolute and relative path: #{self.inspect}, #{base_directory.inspect}"
|
dest_prefix = dest_directory
|
||||||
|
dest_names = []
|
||||||
|
while r = chop_basename(dest_prefix)
|
||||||
|
dest_prefix, basename = r
|
||||||
|
dest_names.unshift basename if basename != '.'
|
||||||
end
|
end
|
||||||
|
base_prefix = base_directory
|
||||||
dest = []
|
base_names = []
|
||||||
self.cleanpath.each_filename {|f|
|
while r = chop_basename(base_prefix)
|
||||||
next if f == '.'
|
base_prefix, basename = r
|
||||||
dest << f
|
base_names.unshift basename if basename != '.'
|
||||||
}
|
|
||||||
|
|
||||||
base = []
|
|
||||||
base_directory.cleanpath.each_filename {|f|
|
|
||||||
next if f == '.'
|
|
||||||
base << f
|
|
||||||
}
|
|
||||||
|
|
||||||
while !base.empty? && !dest.empty? && base[0] == dest[0]
|
|
||||||
base.shift
|
|
||||||
dest.shift
|
|
||||||
end
|
end
|
||||||
|
if dest_prefix != base_prefix
|
||||||
if base.include? '..'
|
raise ArgumentError, "different prefix: #{dest_prefix.inspect} and #{base_directory.inspect}"
|
||||||
|
end
|
||||||
|
while !dest_names.empty? &&
|
||||||
|
!base_names.empty? &&
|
||||||
|
dest_names.first == base_names.first
|
||||||
|
dest_names.shift
|
||||||
|
base_names.shift
|
||||||
|
end
|
||||||
|
if base_names.include? '..'
|
||||||
raise ArgumentError, "base_directory has ..: #{base_directory.inspect}"
|
raise ArgumentError, "base_directory has ..: #{base_directory.inspect}"
|
||||||
end
|
end
|
||||||
|
base_names.fill('..')
|
||||||
base.fill '..'
|
relpath_names = base_names + dest_names
|
||||||
relpath = base + dest
|
if relpath_names.empty?
|
||||||
if relpath.empty?
|
Pathname.new('.')
|
||||||
Pathname.new(".")
|
|
||||||
else
|
else
|
||||||
Pathname.new(relpath.join('/'))
|
Pathname.new(File.join(*relpath_names))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
class Pathname # * IO *
|
class Pathname # * IO *
|
||||||
#
|
#
|
||||||
# #each_line iterates over the line in the file. It yields a String object
|
# #each_line iterates over the line in the file. It yields a String object
|
||||||
|
@ -966,357 +1028,3 @@ class Pathname # * mixed *
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if $0 == __FILE__
|
|
||||||
require 'test/unit'
|
|
||||||
|
|
||||||
class PathnameTest < Test::Unit::TestCase # :nodoc:
|
|
||||||
def test_initialize
|
|
||||||
p1 = Pathname.new('a')
|
|
||||||
assert_equal('a', p1.to_s)
|
|
||||||
p2 = Pathname.new(p1)
|
|
||||||
assert_equal(p1, p2)
|
|
||||||
end
|
|
||||||
|
|
||||||
class AnotherStringLike # :nodoc:
|
|
||||||
def initialize(s) @s = s end
|
|
||||||
def to_str() @s end
|
|
||||||
def ==(other) @s == other end
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_equality
|
|
||||||
obj = Pathname.new("a")
|
|
||||||
str = "a"
|
|
||||||
sym = :a
|
|
||||||
ano = AnotherStringLike.new("a")
|
|
||||||
assert_equal(false, obj == str)
|
|
||||||
assert_equal(false, str == obj)
|
|
||||||
assert_equal(false, obj == ano)
|
|
||||||
assert_equal(false, ano == obj)
|
|
||||||
assert_equal(false, obj == sym)
|
|
||||||
assert_equal(false, sym == obj)
|
|
||||||
|
|
||||||
obj2 = Pathname.new("a")
|
|
||||||
assert_equal(true, obj == obj2)
|
|
||||||
assert_equal(true, obj === obj2)
|
|
||||||
assert_equal(true, obj.eql?(obj2))
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_hashkey
|
|
||||||
h = {}
|
|
||||||
h[Pathname.new("a")] = 1
|
|
||||||
h[Pathname.new("a")] = 2
|
|
||||||
assert_equal(1, h.size)
|
|
||||||
end
|
|
||||||
|
|
||||||
def assert_pathname_cmp(e, s1, s2)
|
|
||||||
p1 = Pathname.new(s1)
|
|
||||||
p2 = Pathname.new(s2)
|
|
||||||
r = p1 <=> p2
|
|
||||||
assert(e == r,
|
|
||||||
"#{p1.inspect} <=> #{p2.inspect}: <#{e}> expected but was <#{r}>")
|
|
||||||
end
|
|
||||||
def test_comparison
|
|
||||||
assert_pathname_cmp( 0, "a", "a")
|
|
||||||
assert_pathname_cmp( 1, "b", "a")
|
|
||||||
assert_pathname_cmp(-1, "a", "b")
|
|
||||||
ss = %w(
|
|
||||||
a
|
|
||||||
a/
|
|
||||||
a/b
|
|
||||||
a.
|
|
||||||
a0
|
|
||||||
)
|
|
||||||
s1 = ss.shift
|
|
||||||
ss.each {|s2|
|
|
||||||
assert_pathname_cmp(-1, s1, s2)
|
|
||||||
s1 = s2
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_comparison_string
|
|
||||||
assert_equal(nil, Pathname.new("a") <=> "a")
|
|
||||||
assert_equal(nil, "a" <=> Pathname.new("a"))
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_syntactical
|
|
||||||
assert_equal(true, Pathname.new("/").root?)
|
|
||||||
assert_equal(true, Pathname.new("//").root?)
|
|
||||||
assert_equal(true, Pathname.new("///").root?)
|
|
||||||
assert_equal(false, Pathname.new("").root?)
|
|
||||||
assert_equal(false, Pathname.new("a").root?)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_cleanpath
|
|
||||||
assert_equal('/', Pathname.new('/').cleanpath(true).to_s)
|
|
||||||
assert_equal('/', Pathname.new('//').cleanpath(true).to_s)
|
|
||||||
assert_equal('', Pathname.new('').cleanpath(true).to_s)
|
|
||||||
|
|
||||||
assert_equal('.', Pathname.new('.').cleanpath(true).to_s)
|
|
||||||
assert_equal('..', Pathname.new('..').cleanpath(true).to_s)
|
|
||||||
assert_equal('a', Pathname.new('a').cleanpath(true).to_s)
|
|
||||||
assert_equal('/', Pathname.new('/.').cleanpath(true).to_s)
|
|
||||||
assert_equal('/', Pathname.new('/..').cleanpath(true).to_s)
|
|
||||||
assert_equal('/a', Pathname.new('/a').cleanpath(true).to_s)
|
|
||||||
assert_equal('.', Pathname.new('./').cleanpath(true).to_s)
|
|
||||||
assert_equal('..', Pathname.new('../').cleanpath(true).to_s)
|
|
||||||
assert_equal('a/', Pathname.new('a/').cleanpath(true).to_s)
|
|
||||||
|
|
||||||
assert_equal('a/b', Pathname.new('a//b').cleanpath(true).to_s)
|
|
||||||
assert_equal('a/.', Pathname.new('a/.').cleanpath(true).to_s)
|
|
||||||
assert_equal('a/.', Pathname.new('a/./').cleanpath(true).to_s)
|
|
||||||
assert_equal('a/..', Pathname.new('a/../').cleanpath(true).to_s)
|
|
||||||
assert_equal('/a/.', Pathname.new('/a/.').cleanpath(true).to_s)
|
|
||||||
assert_equal('..', Pathname.new('./..').cleanpath(true).to_s)
|
|
||||||
assert_equal('..', Pathname.new('../.').cleanpath(true).to_s)
|
|
||||||
assert_equal('..', Pathname.new('./../').cleanpath(true).to_s)
|
|
||||||
assert_equal('..', Pathname.new('.././').cleanpath(true).to_s)
|
|
||||||
assert_equal('/', Pathname.new('/./..').cleanpath(true).to_s)
|
|
||||||
assert_equal('/', Pathname.new('/../.').cleanpath(true).to_s)
|
|
||||||
assert_equal('/', Pathname.new('/./../').cleanpath(true).to_s)
|
|
||||||
assert_equal('/', Pathname.new('/.././').cleanpath(true).to_s)
|
|
||||||
|
|
||||||
assert_equal('a/b/c', Pathname.new('a/b/c').cleanpath(true).to_s)
|
|
||||||
assert_equal('b/c', Pathname.new('./b/c').cleanpath(true).to_s)
|
|
||||||
assert_equal('a/c', Pathname.new('a/./c').cleanpath(true).to_s)
|
|
||||||
assert_equal('a/b/.', Pathname.new('a/b/.').cleanpath(true).to_s)
|
|
||||||
assert_equal('a/..', Pathname.new('a/../.').cleanpath(true).to_s)
|
|
||||||
|
|
||||||
assert_equal('/a', Pathname.new('/../.././../a').cleanpath(true).to_s)
|
|
||||||
assert_equal('a/b/../../../../c/../d',
|
|
||||||
Pathname.new('a/b/../../../../c/../d').cleanpath(true).to_s)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_cleanpath_no_symlink
|
|
||||||
assert_equal('/', Pathname.new('/').cleanpath.to_s)
|
|
||||||
assert_equal('/', Pathname.new('//').cleanpath.to_s)
|
|
||||||
assert_equal('', Pathname.new('').cleanpath.to_s)
|
|
||||||
|
|
||||||
assert_equal('.', Pathname.new('.').cleanpath.to_s)
|
|
||||||
assert_equal('..', Pathname.new('..').cleanpath.to_s)
|
|
||||||
assert_equal('a', Pathname.new('a').cleanpath.to_s)
|
|
||||||
assert_equal('/', Pathname.new('/.').cleanpath.to_s)
|
|
||||||
assert_equal('/', Pathname.new('/..').cleanpath.to_s)
|
|
||||||
assert_equal('/a', Pathname.new('/a').cleanpath.to_s)
|
|
||||||
assert_equal('.', Pathname.new('./').cleanpath.to_s)
|
|
||||||
assert_equal('..', Pathname.new('../').cleanpath.to_s)
|
|
||||||
assert_equal('a', Pathname.new('a/').cleanpath.to_s)
|
|
||||||
|
|
||||||
assert_equal('a/b', Pathname.new('a//b').cleanpath.to_s)
|
|
||||||
assert_equal('a', Pathname.new('a/.').cleanpath.to_s)
|
|
||||||
assert_equal('a', Pathname.new('a/./').cleanpath.to_s)
|
|
||||||
assert_equal('.', Pathname.new('a/../').cleanpath.to_s)
|
|
||||||
assert_equal('/a', Pathname.new('/a/.').cleanpath.to_s)
|
|
||||||
assert_equal('..', Pathname.new('./..').cleanpath.to_s)
|
|
||||||
assert_equal('..', Pathname.new('../.').cleanpath.to_s)
|
|
||||||
assert_equal('..', Pathname.new('./../').cleanpath.to_s)
|
|
||||||
assert_equal('..', Pathname.new('.././').cleanpath.to_s)
|
|
||||||
assert_equal('/', Pathname.new('/./..').cleanpath.to_s)
|
|
||||||
assert_equal('/', Pathname.new('/../.').cleanpath.to_s)
|
|
||||||
assert_equal('/', Pathname.new('/./../').cleanpath.to_s)
|
|
||||||
assert_equal('/', Pathname.new('/.././').cleanpath.to_s)
|
|
||||||
|
|
||||||
assert_equal('a/b/c', Pathname.new('a/b/c').cleanpath.to_s)
|
|
||||||
assert_equal('b/c', Pathname.new('./b/c').cleanpath.to_s)
|
|
||||||
assert_equal('a/c', Pathname.new('a/./c').cleanpath.to_s)
|
|
||||||
assert_equal('a/b', Pathname.new('a/b/.').cleanpath.to_s)
|
|
||||||
assert_equal('.', Pathname.new('a/../.').cleanpath.to_s)
|
|
||||||
|
|
||||||
assert_equal('/a', Pathname.new('/../.././../a').cleanpath.to_s)
|
|
||||||
assert_equal('../../d', Pathname.new('a/b/../../../../c/../d').cleanpath.to_s)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_destructive_update
|
|
||||||
path = Pathname.new("a")
|
|
||||||
path.to_s.replace "b"
|
|
||||||
assert_equal(Pathname.new("a"), path)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_null_character
|
|
||||||
assert_raise(ArgumentError) { Pathname.new("\0") }
|
|
||||||
end
|
|
||||||
|
|
||||||
def assert_relpath(result, dest, base)
|
|
||||||
assert_equal(Pathname.new(result),
|
|
||||||
Pathname.new(dest).relative_path_from(Pathname.new(base)))
|
|
||||||
end
|
|
||||||
|
|
||||||
def assert_relpath_err(dest, base)
|
|
||||||
assert_raise(ArgumentError) {
|
|
||||||
Pathname.new(dest).relative_path_from(Pathname.new(base))
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_relative_path_from
|
|
||||||
assert_relpath("../a", "a", "b")
|
|
||||||
assert_relpath("../a", "a", "b/")
|
|
||||||
assert_relpath("../a", "a/", "b")
|
|
||||||
assert_relpath("../a", "a/", "b/")
|
|
||||||
assert_relpath("../a", "/a", "/b")
|
|
||||||
assert_relpath("../a", "/a", "/b/")
|
|
||||||
assert_relpath("../a", "/a/", "/b")
|
|
||||||
assert_relpath("../a", "/a/", "/b/")
|
|
||||||
|
|
||||||
assert_relpath("../b", "a/b", "a/c")
|
|
||||||
assert_relpath("../a", "../a", "../b")
|
|
||||||
|
|
||||||
assert_relpath("a", "a", ".")
|
|
||||||
assert_relpath("..", ".", "a")
|
|
||||||
|
|
||||||
assert_relpath(".", ".", ".")
|
|
||||||
assert_relpath(".", "..", "..")
|
|
||||||
assert_relpath("..", "..", ".")
|
|
||||||
|
|
||||||
assert_relpath("c/d", "/a/b/c/d", "/a/b")
|
|
||||||
assert_relpath("../..", "/a/b", "/a/b/c/d")
|
|
||||||
assert_relpath("../../../../e", "/e", "/a/b/c/d")
|
|
||||||
assert_relpath("../b/c", "a/b/c", "a/d")
|
|
||||||
|
|
||||||
assert_relpath("../a", "/../a", "/b")
|
|
||||||
assert_relpath("../../a", "../a", "b")
|
|
||||||
assert_relpath(".", "/a/../../b", "/b")
|
|
||||||
assert_relpath("..", "a/..", "a")
|
|
||||||
assert_relpath(".", "a/../b", "b")
|
|
||||||
|
|
||||||
assert_relpath("a", "a", "b/..")
|
|
||||||
assert_relpath("b/c", "b/c", "b/..")
|
|
||||||
|
|
||||||
assert_relpath_err("/", ".")
|
|
||||||
assert_relpath_err(".", "/")
|
|
||||||
assert_relpath_err("a", "..")
|
|
||||||
assert_relpath_err(".", "..")
|
|
||||||
end
|
|
||||||
|
|
||||||
def assert_pathname_plus(a, b, c)
|
|
||||||
a = Pathname.new(a)
|
|
||||||
b = Pathname.new(b)
|
|
||||||
c = Pathname.new(c)
|
|
||||||
d = b + c
|
|
||||||
assert(a == d,
|
|
||||||
"#{b.inspect} + #{c.inspect}: #{a.inspect} expected but was #{d.inspect}")
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_plus
|
|
||||||
assert_pathname_plus('a/b', 'a', 'b')
|
|
||||||
assert_pathname_plus('a', 'a', '.')
|
|
||||||
assert_pathname_plus('b', '.', 'b')
|
|
||||||
assert_pathname_plus('.', '.', '.')
|
|
||||||
assert_pathname_plus('/b', 'a', '/b')
|
|
||||||
|
|
||||||
assert_pathname_plus('/', '/', '..')
|
|
||||||
assert_pathname_plus('.', 'a', '..')
|
|
||||||
assert_pathname_plus('a', 'a/b', '..')
|
|
||||||
assert_pathname_plus('../..', '..', '..')
|
|
||||||
assert_pathname_plus('/c', '/', '../c')
|
|
||||||
assert_pathname_plus('c', 'a', '../c')
|
|
||||||
assert_pathname_plus('a/c', 'a/b', '../c')
|
|
||||||
assert_pathname_plus('../../c', '..', '../c')
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_taint
|
|
||||||
obj = Pathname.new("a"); assert_same(obj, obj.taint)
|
|
||||||
obj = Pathname.new("a"); assert_same(obj, obj.untaint)
|
|
||||||
|
|
||||||
assert_equal(false, Pathname.new("a" ) .tainted?)
|
|
||||||
assert_equal(false, Pathname.new("a" ) .to_s.tainted?)
|
|
||||||
assert_equal(true, Pathname.new("a" ).taint .tainted?)
|
|
||||||
assert_equal(true, Pathname.new("a" ).taint.to_s.tainted?)
|
|
||||||
assert_equal(true, Pathname.new("a".taint) .tainted?)
|
|
||||||
assert_equal(true, Pathname.new("a".taint) .to_s.tainted?)
|
|
||||||
assert_equal(true, Pathname.new("a".taint).taint .tainted?)
|
|
||||||
assert_equal(true, Pathname.new("a".taint).taint.to_s.tainted?)
|
|
||||||
|
|
||||||
str = "a"
|
|
||||||
path = Pathname.new(str)
|
|
||||||
str.taint
|
|
||||||
assert_equal(false, path .tainted?)
|
|
||||||
assert_equal(false, path.to_s.tainted?)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_untaint
|
|
||||||
obj = Pathname.new("a"); assert_same(obj, obj.untaint)
|
|
||||||
|
|
||||||
assert_equal(false, Pathname.new("a").taint.untaint .tainted?)
|
|
||||||
assert_equal(false, Pathname.new("a").taint.untaint.to_s.tainted?)
|
|
||||||
|
|
||||||
str = "a".taint
|
|
||||||
path = Pathname.new(str)
|
|
||||||
str.untaint
|
|
||||||
assert_equal(true, path .tainted?)
|
|
||||||
assert_equal(true, path.to_s.tainted?)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_freeze
|
|
||||||
obj = Pathname.new("a"); assert_same(obj, obj.freeze)
|
|
||||||
|
|
||||||
assert_equal(false, Pathname.new("a" ) .frozen?)
|
|
||||||
assert_equal(false, Pathname.new("a".freeze) .frozen?)
|
|
||||||
assert_equal(true, Pathname.new("a" ).freeze .frozen?)
|
|
||||||
assert_equal(true, Pathname.new("a".freeze).freeze .frozen?)
|
|
||||||
assert_equal(false, Pathname.new("a" ) .to_s.frozen?)
|
|
||||||
assert_equal(false, Pathname.new("a".freeze) .to_s.frozen?)
|
|
||||||
assert_equal(false, Pathname.new("a" ).freeze.to_s.frozen?)
|
|
||||||
assert_equal(false, Pathname.new("a".freeze).freeze.to_s.frozen?)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_to_s
|
|
||||||
str = "a"
|
|
||||||
obj = Pathname.new(str)
|
|
||||||
assert_equal(str, obj.to_s)
|
|
||||||
assert_not_same(str, obj.to_s)
|
|
||||||
assert_not_same(obj.to_s, obj.to_s)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_kernel_open
|
|
||||||
count = 0
|
|
||||||
stat1 = File.stat(__FILE__)
|
|
||||||
result = Kernel.open(Pathname.new(__FILE__)) {|f|
|
|
||||||
stat2 = f.stat
|
|
||||||
assert_equal(stat1.dev, stat2.dev)
|
|
||||||
assert_equal(stat1.ino, stat2.ino)
|
|
||||||
assert_equal(stat1.size, stat2.size)
|
|
||||||
count += 1
|
|
||||||
2
|
|
||||||
}
|
|
||||||
assert_equal(1, count)
|
|
||||||
assert_equal(2, result)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_descend_abs
|
|
||||||
rs = %w[/ /a /a/b /a/b/c].map {|s| Pathname.new(s) }
|
|
||||||
Pathname.new("/a/b/c").descend {|v| assert_equal(rs.shift, v) }
|
|
||||||
assert_equal([], rs)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_descend_rel
|
|
||||||
rs = %w[a a/b a/b/c].map {|s| Pathname.new(s) }
|
|
||||||
Pathname.new("a/b/c").descend {|v| assert_equal(rs.shift, v) }
|
|
||||||
assert_equal([], rs)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_descend_rel_with_current_dir
|
|
||||||
rs = %w[. ./a ./a/b ./a/b/c].map {|s| Pathname.new(s) }
|
|
||||||
Pathname.new("./a/b/c").descend {|v| assert_equal(rs.shift, v) }
|
|
||||||
assert_equal([], rs)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_ascend_abs
|
|
||||||
rs = %w[/a/b/c /a/b /a /].map {|s| Pathname.new(s) }
|
|
||||||
Pathname.new("/a/b/c").ascend {|v| assert_equal(rs.shift, v) }
|
|
||||||
assert_equal([], rs)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_ascend_rel
|
|
||||||
rs = %w[a/b/c a/b a].map {|s| Pathname.new(s) }
|
|
||||||
Pathname.new("a/b/c").ascend {|v| assert_equal(rs.shift, v) }
|
|
||||||
assert_equal([], rs)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_ascend_rel_with_current_dir
|
|
||||||
rs = %w[./a/b/c ./a/b ./a .].map {|s| Pathname.new(s) }
|
|
||||||
Pathname.new("./a/b/c").ascend {|v| assert_equal(rs.shift, v) }
|
|
||||||
assert_equal([], rs)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
|
@ -0,0 +1,465 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
require 'test/unit'
|
||||||
|
require 'pathname'
|
||||||
|
|
||||||
|
require 'fileutils'
|
||||||
|
require 'tempfile'
|
||||||
|
|
||||||
|
class TestPathname < Test::Unit::TestCase
|
||||||
|
def self.define_assertion(name, &block)
|
||||||
|
@defassert_num ||= {}
|
||||||
|
@defassert_num[name] ||= 0
|
||||||
|
@defassert_num[name] += 1
|
||||||
|
define_method("test_#{name}_#{@defassert_num[name]}", &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.defassert(name, result, *args)
|
||||||
|
define_assertion(name) {
|
||||||
|
assert_equal(result, self.send(name, *args), "#{name}(#{args.map {|a| a.inspect }.join(', ')})")
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
DOSISH = File::ALT_SEPARATOR != nil
|
||||||
|
DOSISH_DRIVE_LETTER = File.dirname("A:") == "A:."
|
||||||
|
DOSISH_UNC = File.dirname("//") == "//"
|
||||||
|
|
||||||
|
def cleanpath_aggressive(path)
|
||||||
|
Pathname.new(path).cleanpath.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
defassert(:cleanpath_aggressive, '/', '/')
|
||||||
|
defassert(:cleanpath_aggressive, '.', '')
|
||||||
|
defassert(:cleanpath_aggressive, '.', '.')
|
||||||
|
defassert(:cleanpath_aggressive, '..', '..')
|
||||||
|
defassert(:cleanpath_aggressive, 'a', 'a')
|
||||||
|
defassert(:cleanpath_aggressive, '/', '/.')
|
||||||
|
defassert(:cleanpath_aggressive, '/', '/..')
|
||||||
|
defassert(:cleanpath_aggressive, '/a', '/a')
|
||||||
|
defassert(:cleanpath_aggressive, '.', './')
|
||||||
|
defassert(:cleanpath_aggressive, '..', '../')
|
||||||
|
defassert(:cleanpath_aggressive, 'a', 'a/')
|
||||||
|
defassert(:cleanpath_aggressive, 'a/b', 'a//b')
|
||||||
|
defassert(:cleanpath_aggressive, 'a', 'a/.')
|
||||||
|
defassert(:cleanpath_aggressive, 'a', 'a/./')
|
||||||
|
defassert(:cleanpath_aggressive, '.', 'a/..')
|
||||||
|
defassert(:cleanpath_aggressive, '.', 'a/../')
|
||||||
|
defassert(:cleanpath_aggressive, '/a', '/a/.')
|
||||||
|
defassert(:cleanpath_aggressive, '..', './..')
|
||||||
|
defassert(:cleanpath_aggressive, '..', '../.')
|
||||||
|
defassert(:cleanpath_aggressive, '..', './../')
|
||||||
|
defassert(:cleanpath_aggressive, '..', '.././')
|
||||||
|
defassert(:cleanpath_aggressive, '/', '/./..')
|
||||||
|
defassert(:cleanpath_aggressive, '/', '/../.')
|
||||||
|
defassert(:cleanpath_aggressive, '/', '/./../')
|
||||||
|
defassert(:cleanpath_aggressive, '/', '/.././')
|
||||||
|
defassert(:cleanpath_aggressive, 'a/b/c', 'a/b/c')
|
||||||
|
defassert(:cleanpath_aggressive, 'b/c', './b/c')
|
||||||
|
defassert(:cleanpath_aggressive, 'a/c', 'a/./c')
|
||||||
|
defassert(:cleanpath_aggressive, 'a/b', 'a/b/.')
|
||||||
|
defassert(:cleanpath_aggressive, '.', 'a/../.')
|
||||||
|
defassert(:cleanpath_aggressive, '/a', '/../.././../a')
|
||||||
|
defassert(:cleanpath_aggressive, '../../d', 'a/b/../../../../c/../d')
|
||||||
|
|
||||||
|
if DOSISH_UNC
|
||||||
|
defassert(:cleanpath_aggressive, '//a/b/c', '//a/b/c/')
|
||||||
|
else
|
||||||
|
defassert(:cleanpath_aggressive, '/', '///')
|
||||||
|
defassert(:cleanpath_aggressive, '/a', '///a')
|
||||||
|
defassert(:cleanpath_aggressive, '/', '///..')
|
||||||
|
defassert(:cleanpath_aggressive, '/', '///.')
|
||||||
|
defassert(:cleanpath_aggressive, '/', '///a/../..')
|
||||||
|
end
|
||||||
|
|
||||||
|
def cleanpath_conservative(path)
|
||||||
|
Pathname.new(path).cleanpath(true).to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
defassert(:cleanpath_conservative, '/', '/')
|
||||||
|
defassert(:cleanpath_conservative, '.', '')
|
||||||
|
defassert(:cleanpath_conservative, '.', '.')
|
||||||
|
defassert(:cleanpath_conservative, '..', '..')
|
||||||
|
defassert(:cleanpath_conservative, 'a', 'a')
|
||||||
|
defassert(:cleanpath_conservative, '/', '/.')
|
||||||
|
defassert(:cleanpath_conservative, '/', '/..')
|
||||||
|
defassert(:cleanpath_conservative, '/a', '/a')
|
||||||
|
defassert(:cleanpath_conservative, '.', './')
|
||||||
|
defassert(:cleanpath_conservative, '..', '../')
|
||||||
|
defassert(:cleanpath_conservative, 'a/', 'a/')
|
||||||
|
defassert(:cleanpath_conservative, 'a/b', 'a//b')
|
||||||
|
defassert(:cleanpath_conservative, 'a/.', 'a/.')
|
||||||
|
defassert(:cleanpath_conservative, 'a/.', 'a/./')
|
||||||
|
defassert(:cleanpath_conservative, 'a/..', 'a/../')
|
||||||
|
defassert(:cleanpath_conservative, '/a/.', '/a/.')
|
||||||
|
defassert(:cleanpath_conservative, '..', './..')
|
||||||
|
defassert(:cleanpath_conservative, '..', '../.')
|
||||||
|
defassert(:cleanpath_conservative, '..', './../')
|
||||||
|
defassert(:cleanpath_conservative, '..', '.././')
|
||||||
|
defassert(:cleanpath_conservative, '/', '/./..')
|
||||||
|
defassert(:cleanpath_conservative, '/', '/../.')
|
||||||
|
defassert(:cleanpath_conservative, '/', '/./../')
|
||||||
|
defassert(:cleanpath_conservative, '/', '/.././')
|
||||||
|
defassert(:cleanpath_conservative, 'a/b/c', 'a/b/c')
|
||||||
|
defassert(:cleanpath_conservative, 'b/c', './b/c')
|
||||||
|
defassert(:cleanpath_conservative, 'a/c', 'a/./c')
|
||||||
|
defassert(:cleanpath_conservative, 'a/b/.', 'a/b/.')
|
||||||
|
defassert(:cleanpath_conservative, 'a/..', 'a/../.')
|
||||||
|
defassert(:cleanpath_conservative, '/a', '/../.././../a')
|
||||||
|
defassert(:cleanpath_conservative, 'a/b/../../../../c/../d', 'a/b/../../../../c/../d')
|
||||||
|
|
||||||
|
if DOSISH_UNC
|
||||||
|
defassert(:cleanpath_conservative, '//', '//')
|
||||||
|
else
|
||||||
|
defassert(:cleanpath_conservative, '/', '//')
|
||||||
|
end
|
||||||
|
|
||||||
|
# has_trailing_separator?(path) -> bool
|
||||||
|
def has_trailing_separator?(path)
|
||||||
|
Pathname.allocate.funcall(:has_trailing_separator?, path)
|
||||||
|
end
|
||||||
|
|
||||||
|
defassert(:has_trailing_separator?, false, "/")
|
||||||
|
defassert(:has_trailing_separator?, false, "///")
|
||||||
|
defassert(:has_trailing_separator?, false, "a")
|
||||||
|
defassert(:has_trailing_separator?, true, "a/")
|
||||||
|
|
||||||
|
def add_trailing_separator(path)
|
||||||
|
Pathname.allocate.funcall(:add_trailing_separator, path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def del_trailing_separator(path)
|
||||||
|
Pathname.allocate.funcall(:del_trailing_separator, path)
|
||||||
|
end
|
||||||
|
|
||||||
|
defassert(:del_trailing_separator, "/", "/")
|
||||||
|
defassert(:del_trailing_separator, "/a", "/a")
|
||||||
|
defassert(:del_trailing_separator, "/a", "/a/")
|
||||||
|
defassert(:del_trailing_separator, "/a", "/a//")
|
||||||
|
defassert(:del_trailing_separator, ".", ".")
|
||||||
|
defassert(:del_trailing_separator, ".", "./")
|
||||||
|
defassert(:del_trailing_separator, ".", ".//")
|
||||||
|
|
||||||
|
if DOSISH_DRIVE_LETTER
|
||||||
|
defassert(:del_trailing_separator, "A:", "A:")
|
||||||
|
defassert(:del_trailing_separator, "A:/", "A:/")
|
||||||
|
defassert(:del_trailing_separator, "A:/", "A://")
|
||||||
|
defassert(:del_trailing_separator, "A:.", "A:.")
|
||||||
|
defassert(:del_trailing_separator, "A:.", "A:./")
|
||||||
|
defassert(:del_trailing_separator, "A:.", "A:.//")
|
||||||
|
end
|
||||||
|
|
||||||
|
if DOSISH_UNC
|
||||||
|
defassert(:del_trailing_separator, "//", "//")
|
||||||
|
defassert(:del_trailing_separator, "//a", "//a")
|
||||||
|
defassert(:del_trailing_separator, "//a", "//a/")
|
||||||
|
defassert(:del_trailing_separator, "//a", "//a//")
|
||||||
|
defassert(:del_trailing_separator, "//a/b", "//a/b")
|
||||||
|
defassert(:del_trailing_separator, "//a/b", "//a/b/")
|
||||||
|
defassert(:del_trailing_separator, "//a/b", "//a/b//")
|
||||||
|
defassert(:del_trailing_separator, "//a/b/c", "//a/b/c")
|
||||||
|
defassert(:del_trailing_separator, "//a/b/c", "//a/b/c/")
|
||||||
|
defassert(:del_trailing_separator, "//a/b/c", "//a/b/c//")
|
||||||
|
else
|
||||||
|
defassert(:del_trailing_separator, "/", "///")
|
||||||
|
defassert(:del_trailing_separator, "///a", "///a/")
|
||||||
|
end
|
||||||
|
|
||||||
|
if DOSISH
|
||||||
|
defassert(:del_trailing_separator, "a", "a\\")
|
||||||
|
defassert(:del_trailing_separator, "\225\\", "\225\\\\") # SJIS
|
||||||
|
end
|
||||||
|
|
||||||
|
def plus(path1, path2) # -> path
|
||||||
|
(Pathname.new(path1) + Pathname.new(path2)).to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
defassert(:plus, '/', '/', '/')
|
||||||
|
defassert(:plus, 'a/b', 'a', 'b')
|
||||||
|
defassert(:plus, 'a', 'a', '.')
|
||||||
|
defassert(:plus, 'b', '.', 'b')
|
||||||
|
defassert(:plus, '.', '.', '.')
|
||||||
|
defassert(:plus, '/b', 'a', '/b')
|
||||||
|
|
||||||
|
defassert(:plus, '/', '/', '..')
|
||||||
|
defassert(:plus, '.', 'a', '..')
|
||||||
|
defassert(:plus, 'a', 'a/b', '..')
|
||||||
|
defassert(:plus, '../..', '..', '..')
|
||||||
|
defassert(:plus, '/c', '/', '../c')
|
||||||
|
defassert(:plus, 'c', 'a', '../c')
|
||||||
|
defassert(:plus, 'a/c', 'a/b', '../c')
|
||||||
|
defassert(:plus, '../../c', '..', '../c')
|
||||||
|
|
||||||
|
defassert(:plus, 'a//b/d//e', 'a//b/c', '../d//e')
|
||||||
|
|
||||||
|
def relative?(path)
|
||||||
|
Pathname.new(path).relative?
|
||||||
|
end
|
||||||
|
|
||||||
|
defassert(:relative?, false, '/')
|
||||||
|
defassert(:relative?, false, '/a')
|
||||||
|
defassert(:relative?, false, '/..')
|
||||||
|
defassert(:relative?, true, 'a')
|
||||||
|
defassert(:relative?, true, 'a/b')
|
||||||
|
|
||||||
|
if DOSISH_DRIVE_LETTER
|
||||||
|
defassert(:relative?, false, 'A:')
|
||||||
|
defassert(:relative?, false, 'A:/')
|
||||||
|
defassert(:relative?, false, 'A:/a')
|
||||||
|
end
|
||||||
|
|
||||||
|
if File.dirname('//') == '//'
|
||||||
|
defassert(:relative?, false, '//')
|
||||||
|
defassert(:relative?, false, '//a')
|
||||||
|
defassert(:relative?, false, '//a/')
|
||||||
|
defassert(:relative?, false, '//a/b')
|
||||||
|
defassert(:relative?, false, '//a/b/')
|
||||||
|
defassert(:relative?, false, '//a/b/c')
|
||||||
|
end
|
||||||
|
|
||||||
|
def relative_path_from(dest_directory, base_directory)
|
||||||
|
Pathname.new(dest_directory).relative_path_from(Pathname.new(base_directory)).to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
defassert(:relative_path_from, "../a", "a", "b")
|
||||||
|
defassert(:relative_path_from, "../a", "a", "b/")
|
||||||
|
defassert(:relative_path_from, "../a", "a/", "b")
|
||||||
|
defassert(:relative_path_from, "../a", "a/", "b/")
|
||||||
|
defassert(:relative_path_from, "../a", "/a", "/b")
|
||||||
|
defassert(:relative_path_from, "../a", "/a", "/b/")
|
||||||
|
defassert(:relative_path_from, "../a", "/a/", "/b")
|
||||||
|
defassert(:relative_path_from, "../a", "/a/", "/b/")
|
||||||
|
|
||||||
|
defassert(:relative_path_from, "../b", "a/b", "a/c")
|
||||||
|
defassert(:relative_path_from, "../a", "../a", "../b")
|
||||||
|
|
||||||
|
defassert(:relative_path_from, "a", "a", ".")
|
||||||
|
defassert(:relative_path_from, "..", ".", "a")
|
||||||
|
|
||||||
|
defassert(:relative_path_from, ".", ".", ".")
|
||||||
|
defassert(:relative_path_from, ".", "..", "..")
|
||||||
|
defassert(:relative_path_from, "..", "..", ".")
|
||||||
|
|
||||||
|
defassert(:relative_path_from, "c/d", "/a/b/c/d", "/a/b")
|
||||||
|
defassert(:relative_path_from, "../..", "/a/b", "/a/b/c/d")
|
||||||
|
defassert(:relative_path_from, "../../../../e", "/e", "/a/b/c/d")
|
||||||
|
defassert(:relative_path_from, "../b/c", "a/b/c", "a/d")
|
||||||
|
|
||||||
|
defassert(:relative_path_from, "../a", "/../a", "/b")
|
||||||
|
defassert(:relative_path_from, "../../a", "../a", "b")
|
||||||
|
defassert(:relative_path_from, ".", "/a/../../b", "/b")
|
||||||
|
defassert(:relative_path_from, "..", "a/..", "a")
|
||||||
|
defassert(:relative_path_from, ".", "a/../b", "b")
|
||||||
|
|
||||||
|
defassert(:relative_path_from, "a", "a", "b/..")
|
||||||
|
defassert(:relative_path_from, "b/c", "b/c", "b/..")
|
||||||
|
|
||||||
|
def self.defassert_raise(name, exc, *args)
|
||||||
|
define_assertion(name) {
|
||||||
|
message = "#{name}(#{args.map {|a| a.inspect }.join(', ')})"
|
||||||
|
assert_raise(exc, message) { self.send(name, *args) }
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
defassert_raise(:relative_path_from, ArgumentError, "/", ".")
|
||||||
|
defassert_raise(:relative_path_from, ArgumentError, ".", "/")
|
||||||
|
defassert_raise(:relative_path_from, ArgumentError, "a", "..")
|
||||||
|
defassert_raise(:relative_path_from, ArgumentError, ".", "..")
|
||||||
|
|
||||||
|
def realpath(path)
|
||||||
|
Pathname.new(path).realpath.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_realpath
|
||||||
|
begin
|
||||||
|
File.symlink(nil, nil)
|
||||||
|
rescue NotImplementedError
|
||||||
|
return
|
||||||
|
rescue TypeError
|
||||||
|
end
|
||||||
|
dir = "#{Dir.tmpdir}/tst-pathname-#$$"
|
||||||
|
Dir.mkdir(dir)
|
||||||
|
begin
|
||||||
|
File.symlink("not-exist-target", "#{dir}/not-exist")
|
||||||
|
assert_raise(Errno::ENOENT) { realpath("#{dir}/not-exist") }
|
||||||
|
File.symlink("loop", "#{dir}/loop")
|
||||||
|
assert_raise(Errno::ELOOP) { realpath("#{dir}/loop") }
|
||||||
|
ensure
|
||||||
|
FileUtils.rmtree(dir)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def descend(path)
|
||||||
|
Pathname.new(path).enum_for(:descend).map {|v| v.to_s }
|
||||||
|
end
|
||||||
|
|
||||||
|
defassert(:descend, %w[/ /a /a/b /a/b/c], "/a/b/c")
|
||||||
|
defassert(:descend, %w[a a/b a/b/c], "a/b/c")
|
||||||
|
defassert(:descend, %w[. ./a ./a/b ./a/b/c], "./a/b/c")
|
||||||
|
defassert(:descend, %w[a/], "a/")
|
||||||
|
|
||||||
|
def ascend(path)
|
||||||
|
Pathname.new(path).enum_for(:ascend).map {|v| v.to_s }
|
||||||
|
end
|
||||||
|
|
||||||
|
defassert(:ascend, %w[/a/b/c /a/b /a /], "/a/b/c")
|
||||||
|
defassert(:ascend, %w[a/b/c a/b a], "a/b/c")
|
||||||
|
defassert(:ascend, %w[./a/b/c ./a/b ./a .], "./a/b/c")
|
||||||
|
defassert(:ascend, %w[a/], "a/")
|
||||||
|
|
||||||
|
def test_initialize
|
||||||
|
p1 = Pathname.new('a')
|
||||||
|
assert_equal('a', p1.to_s)
|
||||||
|
p2 = Pathname.new(p1)
|
||||||
|
assert_equal(p1, p2)
|
||||||
|
end
|
||||||
|
|
||||||
|
class AnotherStringLike # :nodoc:
|
||||||
|
def initialize(s) @s = s end
|
||||||
|
def to_str() @s end
|
||||||
|
def ==(other) @s == other end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_equality
|
||||||
|
obj = Pathname.new("a")
|
||||||
|
str = "a"
|
||||||
|
sym = :a
|
||||||
|
ano = AnotherStringLike.new("a")
|
||||||
|
assert_equal(false, obj == str)
|
||||||
|
assert_equal(false, str == obj)
|
||||||
|
assert_equal(false, obj == ano)
|
||||||
|
assert_equal(false, ano == obj)
|
||||||
|
assert_equal(false, obj == sym)
|
||||||
|
assert_equal(false, sym == obj)
|
||||||
|
|
||||||
|
obj2 = Pathname.new("a")
|
||||||
|
assert_equal(true, obj == obj2)
|
||||||
|
assert_equal(true, obj === obj2)
|
||||||
|
assert_equal(true, obj.eql?(obj2))
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_hashkey
|
||||||
|
h = {}
|
||||||
|
h[Pathname.new("a")] = 1
|
||||||
|
h[Pathname.new("a")] = 2
|
||||||
|
assert_equal(1, h.size)
|
||||||
|
end
|
||||||
|
|
||||||
|
def assert_pathname_cmp(e, s1, s2)
|
||||||
|
p1 = Pathname.new(s1)
|
||||||
|
p2 = Pathname.new(s2)
|
||||||
|
r = p1 <=> p2
|
||||||
|
assert(e == r,
|
||||||
|
"#{p1.inspect} <=> #{p2.inspect}: <#{e}> expected but was <#{r}>")
|
||||||
|
end
|
||||||
|
def test_comparison
|
||||||
|
assert_pathname_cmp( 0, "a", "a")
|
||||||
|
assert_pathname_cmp( 1, "b", "a")
|
||||||
|
assert_pathname_cmp(-1, "a", "b")
|
||||||
|
ss = %w(
|
||||||
|
a
|
||||||
|
a/
|
||||||
|
a/b
|
||||||
|
a.
|
||||||
|
a0
|
||||||
|
)
|
||||||
|
s1 = ss.shift
|
||||||
|
ss.each {|s2|
|
||||||
|
assert_pathname_cmp(-1, s1, s2)
|
||||||
|
s1 = s2
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_comparison_string
|
||||||
|
assert_equal(nil, Pathname.new("a") <=> "a")
|
||||||
|
assert_equal(nil, "a" <=> Pathname.new("a"))
|
||||||
|
end
|
||||||
|
|
||||||
|
def root?(path)
|
||||||
|
Pathname.new(path).root?
|
||||||
|
end
|
||||||
|
|
||||||
|
defassert(:root?, true, "/")
|
||||||
|
defassert(:root?, true, "//")
|
||||||
|
defassert(:root?, true, "///")
|
||||||
|
defassert(:root?, false, "")
|
||||||
|
defassert(:root?, false, "a")
|
||||||
|
|
||||||
|
def test_destructive_update
|
||||||
|
path = Pathname.new("a")
|
||||||
|
path.to_s.replace "b"
|
||||||
|
assert_equal(Pathname.new("a"), path)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_null_character
|
||||||
|
assert_raise(ArgumentError) { Pathname.new("\0") }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_taint
|
||||||
|
obj = Pathname.new("a"); assert_same(obj, obj.taint)
|
||||||
|
obj = Pathname.new("a"); assert_same(obj, obj.untaint)
|
||||||
|
|
||||||
|
assert_equal(false, Pathname.new("a" ) .tainted?)
|
||||||
|
assert_equal(false, Pathname.new("a" ) .to_s.tainted?)
|
||||||
|
assert_equal(true, Pathname.new("a" ).taint .tainted?)
|
||||||
|
assert_equal(true, Pathname.new("a" ).taint.to_s.tainted?)
|
||||||
|
assert_equal(true, Pathname.new("a".taint) .tainted?)
|
||||||
|
assert_equal(true, Pathname.new("a".taint) .to_s.tainted?)
|
||||||
|
assert_equal(true, Pathname.new("a".taint).taint .tainted?)
|
||||||
|
assert_equal(true, Pathname.new("a".taint).taint.to_s.tainted?)
|
||||||
|
|
||||||
|
str = "a"
|
||||||
|
path = Pathname.new(str)
|
||||||
|
str.taint
|
||||||
|
assert_equal(false, path .tainted?)
|
||||||
|
assert_equal(false, path.to_s.tainted?)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_untaint
|
||||||
|
obj = Pathname.new("a"); assert_same(obj, obj.untaint)
|
||||||
|
|
||||||
|
assert_equal(false, Pathname.new("a").taint.untaint .tainted?)
|
||||||
|
assert_equal(false, Pathname.new("a").taint.untaint.to_s.tainted?)
|
||||||
|
|
||||||
|
str = "a".taint
|
||||||
|
path = Pathname.new(str)
|
||||||
|
str.untaint
|
||||||
|
assert_equal(true, path .tainted?)
|
||||||
|
assert_equal(true, path.to_s.tainted?)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_freeze
|
||||||
|
obj = Pathname.new("a"); assert_same(obj, obj.freeze)
|
||||||
|
|
||||||
|
assert_equal(false, Pathname.new("a" ) .frozen?)
|
||||||
|
assert_equal(false, Pathname.new("a".freeze) .frozen?)
|
||||||
|
assert_equal(true, Pathname.new("a" ).freeze .frozen?)
|
||||||
|
assert_equal(true, Pathname.new("a".freeze).freeze .frozen?)
|
||||||
|
assert_equal(false, Pathname.new("a" ) .to_s.frozen?)
|
||||||
|
assert_equal(false, Pathname.new("a".freeze) .to_s.frozen?)
|
||||||
|
assert_equal(false, Pathname.new("a" ).freeze.to_s.frozen?)
|
||||||
|
assert_equal(false, Pathname.new("a".freeze).freeze.to_s.frozen?)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_to_s
|
||||||
|
str = "a"
|
||||||
|
obj = Pathname.new(str)
|
||||||
|
assert_equal(str, obj.to_s)
|
||||||
|
assert_not_same(str, obj.to_s)
|
||||||
|
assert_not_same(obj.to_s, obj.to_s)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_kernel_open
|
||||||
|
count = 0
|
||||||
|
stat1 = File.stat(__FILE__)
|
||||||
|
result = Kernel.open(Pathname.new(__FILE__)) {|f|
|
||||||
|
stat2 = f.stat
|
||||||
|
assert_equal(stat1.dev, stat2.dev)
|
||||||
|
assert_equal(stat1.ino, stat2.ino)
|
||||||
|
assert_equal(stat1.size, stat2.size)
|
||||||
|
count += 1
|
||||||
|
2
|
||||||
|
}
|
||||||
|
assert_equal(1, count)
|
||||||
|
assert_equal(2, result)
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,4 +0,0 @@
|
||||||
require 'pathname'
|
|
||||||
require Pathname.new(__FILE__).dirname.join('inlinetest.rb')
|
|
||||||
target = __FILE__[/test_(.*\.rb)$/, 1]
|
|
||||||
InlineTest.loadtest(target)
|
|
Загрузка…
Ссылка в новой задаче