stouset-pathname3 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,377 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'lib/pathname3'
5
+
6
+ require 'fileutils'
7
+ require 'tmpdir'
8
+ require 'enumerator'
9
+
10
+ class TestPathname < Test::Unit::TestCase
11
+
12
+ def self.define_assertion(name, &block)
13
+ @defassert_num ||= {}
14
+ @defassert_num[name] ||= 0
15
+ @defassert_num[name] += 1
16
+ define_method("test_#{name}_#{@defassert_num[name]}", &block)
17
+ end
18
+
19
+ def self.defassert(name, result, *args)
20
+ define_assertion(name) {
21
+ assert_equal(result, self.send(name, *args), "#{name}(#{args.map {|a| a.inspect }.join(', ')})")
22
+ }
23
+ end
24
+
25
+ DOSISH = File::ALT_SEPARATOR != nil
26
+ DOSISH_DRIVE_LETTER = File.dirname("A:") == "A:."
27
+ DOSISH_UNC = File.dirname("//") == "//"
28
+
29
+ def cleanpath_aggressive(path)
30
+ Pathname.new(path).cleanpath.to_s
31
+ end
32
+
33
+ defassert(:cleanpath_aggressive, '/', '/')
34
+ defassert(:cleanpath_aggressive, '.', '')
35
+ defassert(:cleanpath_aggressive, '.', '.')
36
+ defassert(:cleanpath_aggressive, '..', '..')
37
+ defassert(:cleanpath_aggressive, 'a', 'a')
38
+ defassert(:cleanpath_aggressive, '/', '/.')
39
+ defassert(:cleanpath_aggressive, '/', '/..')
40
+ defassert(:cleanpath_aggressive, '/a', '/a')
41
+ defassert(:cleanpath_aggressive, '.', './')
42
+ defassert(:cleanpath_aggressive, '..', '../')
43
+ defassert(:cleanpath_aggressive, 'a', 'a/')
44
+ defassert(:cleanpath_aggressive, 'a/b', 'a//b')
45
+ defassert(:cleanpath_aggressive, 'a', 'a/.')
46
+ defassert(:cleanpath_aggressive, 'a', 'a/./')
47
+ defassert(:cleanpath_aggressive, '.', 'a/..')
48
+ defassert(:cleanpath_aggressive, '.', 'a/../')
49
+ defassert(:cleanpath_aggressive, '/a', '/a/.')
50
+ defassert(:cleanpath_aggressive, '..', './..')
51
+ defassert(:cleanpath_aggressive, '..', '../.')
52
+ defassert(:cleanpath_aggressive, '..', './../')
53
+ defassert(:cleanpath_aggressive, '..', '.././')
54
+ defassert(:cleanpath_aggressive, '/', '/./..')
55
+ defassert(:cleanpath_aggressive, '/', '/../.')
56
+ defassert(:cleanpath_aggressive, '/', '/./../')
57
+ defassert(:cleanpath_aggressive, '/', '/.././')
58
+ defassert(:cleanpath_aggressive, 'a/b/c', 'a/b/c')
59
+ defassert(:cleanpath_aggressive, 'b/c', './b/c')
60
+ defassert(:cleanpath_aggressive, 'a/c', 'a/./c')
61
+ defassert(:cleanpath_aggressive, 'a/b', 'a/b/.')
62
+ defassert(:cleanpath_aggressive, '.', 'a/../.')
63
+ defassert(:cleanpath_aggressive, '/a', '/../.././../a')
64
+ defassert(:cleanpath_aggressive, '../../d', 'a/b/../../../../c/../d')
65
+
66
+ if DOSISH_UNC
67
+ defassert(:cleanpath_aggressive, '//a/b/c', '//a/b/c/')
68
+ else
69
+ defassert(:cleanpath_aggressive, '/', '///')
70
+ defassert(:cleanpath_aggressive, '/a', '///a')
71
+ defassert(:cleanpath_aggressive, '/', '///..')
72
+ defassert(:cleanpath_aggressive, '/', '///.')
73
+ defassert(:cleanpath_aggressive, '/', '///a/../..')
74
+ end
75
+
76
+ def plus(path1, path2) # -> path
77
+ (Pathname.new(path1) + Pathname.new(path2)).to_s
78
+ end
79
+
80
+ defassert(:plus, '/', '/', '/')
81
+ defassert(:plus, 'a/b', 'a', 'b')
82
+ defassert(:plus, 'a', 'a', '.')
83
+ defassert(:plus, 'b', '.', 'b')
84
+ defassert(:plus, '.', '.', '.')
85
+ defassert(:plus, 'a/b', 'a', '/b')
86
+
87
+ defassert(:plus, '/', '/', '..')
88
+ defassert(:plus, '.', 'a', '..')
89
+ defassert(:plus, 'a', 'a/b', '..')
90
+ defassert(:plus, '../..', '..', '..')
91
+ defassert(:plus, '/c', '/', '../c')
92
+ defassert(:plus, 'c', 'a', '../c')
93
+ defassert(:plus, 'a/c', 'a/b', '../c')
94
+ defassert(:plus, '../../c', '..', '../c')
95
+
96
+ defassert(:plus, 'a/b/d/e', 'a//b/c', '../d//e')
97
+
98
+ def relative?(path)
99
+ Pathname.new(path).relative?
100
+ end
101
+
102
+ defassert(:relative?, false, '/')
103
+ defassert(:relative?, false, '/a')
104
+ defassert(:relative?, false, '/..')
105
+ defassert(:relative?, true, 'a')
106
+ defassert(:relative?, true, 'a/b')
107
+
108
+ if DOSISH_DRIVE_LETTER
109
+ defassert(:relative?, false, 'A:')
110
+ defassert(:relative?, false, 'A:/')
111
+ defassert(:relative?, false, 'A:/a')
112
+ end
113
+
114
+ if File.dirname('//') == '//'
115
+ defassert(:relative?, false, '//')
116
+ defassert(:relative?, false, '//a')
117
+ defassert(:relative?, false, '//a/')
118
+ defassert(:relative?, false, '//a/b')
119
+ defassert(:relative?, false, '//a/b/')
120
+ defassert(:relative?, false, '//a/b/c')
121
+ end
122
+
123
+ def relative_path_from(dest_directory, base_directory)
124
+ Pathname.new(dest_directory).relative_path_from(Pathname.new(base_directory)).to_s
125
+ end
126
+
127
+ defassert(:relative_path_from, "../a", "a", "b")
128
+ defassert(:relative_path_from, "../a", "a", "b/")
129
+ defassert(:relative_path_from, "../a", "a/", "b")
130
+ defassert(:relative_path_from, "../a", "a/", "b/")
131
+ defassert(:relative_path_from, "../a", "/a", "/b")
132
+ defassert(:relative_path_from, "../a", "/a", "/b/")
133
+ defassert(:relative_path_from, "../a", "/a/", "/b")
134
+ defassert(:relative_path_from, "../a", "/a/", "/b/")
135
+
136
+ defassert(:relative_path_from, "../b", "a/b", "a/c")
137
+ defassert(:relative_path_from, "../a", "../a", "../b")
138
+
139
+ defassert(:relative_path_from, "a", "a", ".")
140
+ defassert(:relative_path_from, "..", ".", "a")
141
+
142
+ defassert(:relative_path_from, ".", ".", ".")
143
+ defassert(:relative_path_from, ".", "..", "..")
144
+ defassert(:relative_path_from, "..", "..", ".")
145
+
146
+ defassert(:relative_path_from, "c/d", "/a/b/c/d", "/a/b")
147
+ defassert(:relative_path_from, "../..", "/a/b", "/a/b/c/d")
148
+ defassert(:relative_path_from, "../../../../e", "/e", "/a/b/c/d")
149
+ defassert(:relative_path_from, "../b/c", "a/b/c", "a/d")
150
+
151
+ defassert(:relative_path_from, "../a", "/../a", "/b")
152
+ defassert(:relative_path_from, "../../a", "../a", "b")
153
+ defassert(:relative_path_from, ".", "/a/../../b", "/b")
154
+ defassert(:relative_path_from, "..", "a/..", "a")
155
+ defassert(:relative_path_from, ".", "a/../b", "b")
156
+
157
+ defassert(:relative_path_from, "a", "a", "b/..")
158
+ defassert(:relative_path_from, "b/c", "b/c", "b/..")
159
+
160
+ def self.defassert_raise(name, exc, *args)
161
+ define_assertion(name) {
162
+ message = "#{name}(#{args.map {|a| a.inspect }.join(', ')})"
163
+ assert_raise(exc, message) { self.send(name, *args) }
164
+ }
165
+ end
166
+
167
+ defassert_raise(:relative_path_from, ArgumentError, "/", ".")
168
+ defassert_raise(:relative_path_from, ArgumentError, ".", "/")
169
+ defassert_raise(:relative_path_from, ArgumentError, "a", "..")
170
+ defassert_raise(:relative_path_from, ArgumentError, ".", "..")
171
+
172
+ def realpath(path)
173
+ Pathname.new(path).realpath.to_s
174
+ end
175
+
176
+ def test_realpath
177
+ begin
178
+ File.symlink(nil, nil)
179
+ rescue NotImplementedError
180
+ return
181
+ rescue TypeError
182
+ end
183
+ dir = "#{Dir.tmpdir}/tst-pathname-#$$"
184
+ Dir.mkdir(dir)
185
+ begin
186
+ File.symlink("not-exist-target", "#{dir}/not-exist")
187
+ assert_raise(Errno::ENOENT) { realpath("#{dir}/not-exist") }
188
+ File.symlink("loop", "#{dir}/loop")
189
+ assert_raise(Errno::ELOOP) { realpath("#{dir}/loop") }
190
+ ensure
191
+ FileUtils.rmtree(dir)
192
+ end
193
+ end
194
+
195
+ def descend(path)
196
+ Pathname.new(path).enum_for(:descend).map {|v| v.to_s }
197
+ end
198
+
199
+ defassert(:descend, %w[/ /a /a/b /a/b/c], "/a/b/c")
200
+ defassert(:descend, %w[a a/b a/b/c], "a/b/c")
201
+ defassert(:descend, %w[. ./a ./a/b ./a/b/c], "./a/b/c")
202
+ defassert(:descend, %w[a], "a/")
203
+
204
+ def ascend(path)
205
+ Pathname.new(path).enum_for(:ascend).map {|v| v.to_s }
206
+ end
207
+
208
+ defassert(:ascend, %w[/a/b/c /a/b /a /], "/a/b/c")
209
+ defassert(:ascend, %w[a/b/c a/b a], "a/b/c")
210
+ defassert(:ascend, %w[./a/b/c ./a/b ./a .], "./a/b/c")
211
+ defassert(:ascend, %w[a], "a/")
212
+
213
+ def test_initialize
214
+ p1 = Pathname.new('a')
215
+ assert_equal('a', p1.to_s)
216
+ p2 = Pathname.new(p1)
217
+ assert_equal(p1, p2)
218
+ end
219
+
220
+ def test_initialize_nul
221
+ assert_raise(ArgumentError) { Pathname.new("a\0") }
222
+ end
223
+
224
+ class AnotherStringLike # :nodoc:
225
+ def initialize(s) @s = s end
226
+ def to_str() @s end
227
+ def ==(other) @s == other end
228
+ end
229
+
230
+ def test_equality
231
+ obj = Pathname.new("a")
232
+ str = "a"
233
+ sym = :a
234
+ ano = AnotherStringLike.new("a")
235
+ assert_equal(true, obj == str)
236
+ assert_equal(true, str == obj)
237
+ assert_equal(true, obj == ano)
238
+ assert_equal(true, ano == obj)
239
+ assert_equal(false, obj == sym)
240
+ assert_equal(false, sym == obj)
241
+
242
+ obj2 = Pathname.new("a")
243
+ assert_equal(true, obj == obj2)
244
+ assert_equal(true, obj === obj2)
245
+ assert_equal(true, obj.eql?(obj2))
246
+ end
247
+
248
+ def test_hashkey
249
+ h = {}
250
+ h[Pathname.new("a")] = 1
251
+ h[Pathname.new("a")] = 2
252
+ assert_equal(1, h.size)
253
+ end
254
+
255
+ def assert_pathname_cmp(e, s1, s2)
256
+ p1 = Pathname.new(s1)
257
+ p2 = Pathname.new(s2)
258
+ r = p1 <=> p2
259
+ assert(e == r,
260
+ "#{p1.inspect} <=> #{p2.inspect}: <#{e}> expected but was <#{r}>")
261
+ end
262
+ def test_comparison
263
+ assert_pathname_cmp( 0, "a", "a")
264
+ assert_pathname_cmp( 1, "b", "a")
265
+ assert_pathname_cmp(-1, "a", "b")
266
+ ss = %w(
267
+ a
268
+ a/
269
+ a/b
270
+ a.
271
+ a0
272
+ )
273
+ s1 = ss.shift
274
+ ss.each {|s2|
275
+ assert_pathname_cmp(-1, s1, s2)
276
+ s1 = s2
277
+ }
278
+ end
279
+
280
+ def pathsub(path, pat, repl) Pathname.new(path).sub(pat, repl).to_s end
281
+ defassert(:pathsub, "a.o", "a.c", /\.c\z/, ".o")
282
+
283
+ def root?(path)
284
+ Pathname.new(path).root?
285
+ end
286
+
287
+ defassert(:root?, true, "/")
288
+ defassert(:root?, true, "//")
289
+ defassert(:root?, true, "///")
290
+ defassert(:root?, false, "")
291
+ defassert(:root?, false, "a")
292
+
293
+ def test_destructive_update
294
+ path = Pathname.new("a")
295
+ path.to_s.replace "b"
296
+ assert_equal(Pathname.new("a"), path)
297
+ end
298
+
299
+ def test_null_character
300
+ assert_raise(ArgumentError) { Pathname.new("\0") }
301
+ end
302
+
303
+ def test_taint
304
+ obj = Pathname.new("a"); assert_same(obj, obj.taint)
305
+ obj = Pathname.new("a"); assert_same(obj, obj.untaint)
306
+
307
+ assert_equal(false, Pathname.new("a" ) .tainted?)
308
+ assert_equal(false, Pathname.new("a" ) .to_s.tainted?)
309
+ assert_equal(true, Pathname.new("a" ).taint .tainted?)
310
+ assert_equal(true, Pathname.new("a" ).taint.to_s.tainted?)
311
+ assert_equal(true, Pathname.new("a".taint) .tainted?)
312
+ assert_equal(true, Pathname.new("a".taint) .to_s.tainted?)
313
+ assert_equal(true, Pathname.new("a".taint).taint .tainted?)
314
+ assert_equal(true, Pathname.new("a".taint).taint.to_s.tainted?)
315
+
316
+ str = "a"
317
+ path = Pathname.new(str)
318
+ str.taint
319
+ assert_equal(false, path .tainted?)
320
+ assert_equal(false, path.to_s.tainted?)
321
+ end
322
+
323
+ def test_untaint
324
+ obj = Pathname.new("a"); assert_same(obj, obj.untaint)
325
+
326
+ assert_equal(false, Pathname.new("a").taint.untaint .tainted?)
327
+ assert_equal(false, Pathname.new("a").taint.untaint.to_s.tainted?)
328
+
329
+ str = "a".taint
330
+ path = Pathname.new(str)
331
+ str.untaint
332
+ assert_equal(true, path .tainted?)
333
+ assert_equal(true, path.to_s.tainted?)
334
+ end
335
+
336
+ def test_freeze
337
+ obj = Pathname.new("a"); assert_same(obj, obj.freeze)
338
+
339
+ assert_equal(false, Pathname.new("a" ) .frozen?)
340
+ assert_equal(false, Pathname.new("a".freeze) .frozen?)
341
+ assert_equal(true, Pathname.new("a" ).freeze .frozen?)
342
+ assert_equal(true, Pathname.new("a".freeze).freeze .frozen?)
343
+ assert_equal(false, Pathname.new("a" ) .to_s.frozen?)
344
+ assert_equal(false, Pathname.new("a".freeze) .to_s.frozen?)
345
+ assert_equal(false, Pathname.new("a" ).freeze.to_s.frozen?)
346
+ assert_equal(false, Pathname.new("a".freeze).freeze.to_s.frozen?)
347
+ end
348
+
349
+ def test_to_s
350
+ str = "a"
351
+ obj = Pathname.new(str)
352
+ assert_equal(str, obj.to_s)
353
+ assert_not_same(str, obj.to_s)
354
+ assert_not_same(obj.to_s, obj.to_s)
355
+ end
356
+
357
+ def test_kernel_open
358
+ count = 0
359
+ result = Kernel.open(Pathname.new(__FILE__)) {|f|
360
+ assert(File.identical?(__FILE__, f))
361
+ count += 1
362
+ 2
363
+ }
364
+ assert_equal(1, count)
365
+ assert_equal(2, result)
366
+ end
367
+
368
+ def test_each_filename
369
+ result = []
370
+ Pathname.new("/usr/bin/ruby").each_filename {|f| result << f }
371
+ assert_equal(%w[/ usr bin ruby], result)
372
+ end
373
+
374
+ def test_kernel_pathname
375
+ assert_equal(Pathname.new("a"), Pathname("a"))
376
+ end
377
+ end
metadata ADDED
@@ -0,0 +1,59 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: stouset-pathname3
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.3
5
+ platform: ruby
6
+ authors:
7
+ - Stephen Touset
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-06-05 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Faster replacement for pathname and pathname2
17
+ email: stephen@touset.org
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files: []
23
+
24
+ files:
25
+ - CHANGES
26
+ - README
27
+ - LICENSE
28
+ - pathname3.gemspec
29
+ - lib/pathname3.rb
30
+ - test/lib/test_pathname.rb
31
+ - test/lib/test_pathname3.rb
32
+ has_rdoc: true
33
+ homepage: http://github.com/stouset/pathname3/
34
+ post_install_message:
35
+ rdoc_options: []
36
+
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: "0"
44
+ version:
45
+ required_rubygems_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ requirements: []
52
+
53
+ rubyforge_project:
54
+ rubygems_version: 1.0.1
55
+ signing_key:
56
+ specification_version: 2
57
+ summary: pathname3 is a third attempt at rewriting the eminently useful Pathname library in Ruby. The first version (packaged with Ruby) is extremely slow for many operations, as is the second one (by Daniel J. Berger). This version attempts to combine the best parts of both predecessors, while also maintaining speed. Namely, we use Daniel's String-based approach, while dumping Facade and sending messages to FileTest, File, Dir, and FileUtils explicitly (for clarity and predictability). Windows support will be provided in a later release. Donations of code toward this end would be appreciated.
58
+ test_files: []
59
+