epitools 0.5.14 → 0.5.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/VERSION +1 -1
- data/epitools.gemspec +1 -1
- data/lib/epitools/core_ext/enumerable.rb +46 -46
- data/lib/epitools/path.rb +77 -90
- data/spec/path_spec.rb +30 -19
- metadata +1 -1
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.5.
|
1
|
+
0.5.15
|
data/epitools.gemspec
CHANGED
@@ -19,8 +19,8 @@ module Enumerable
|
|
19
19
|
#
|
20
20
|
alias_method :includes?, :include?
|
21
21
|
|
22
|
-
|
23
|
-
#
|
22
|
+
|
23
|
+
#
|
24
24
|
# Skip the first n elements and return an Enumerator for the rest, or pass them
|
25
25
|
# in succession to the block, if given. This is like "drop", but returns an enumerator
|
26
26
|
# instead of converting the whole thing to an array.
|
@@ -38,32 +38,32 @@ module Enumerable
|
|
38
38
|
enum_for :skip, n
|
39
39
|
end
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
#
|
43
43
|
# Split this enumerable into chunks, given some boundary condition. (Returns an array of arrays.)
|
44
44
|
#
|
45
45
|
# Options:
|
46
|
-
# :include_boundary => true #=> include the element that you're splitting at in the results
|
46
|
+
# :include_boundary => true #=> include the element that you're splitting at in the results
|
47
47
|
# (default: false)
|
48
|
-
# :after => true #=> split after the matched element (only has an effect when used with :include_boundary)
|
48
|
+
# :after => true #=> split after the matched element (only has an effect when used with :include_boundary)
|
49
49
|
# (default: false)
|
50
50
|
# :once => flase #=> only perform one split (default: false)
|
51
51
|
#
|
52
|
-
# Examples:
|
53
|
-
# [1,2,3,4,5].split{ |e| e == 3 }
|
52
|
+
# Examples:
|
53
|
+
# [1,2,3,4,5].split{ |e| e == 3 }
|
54
54
|
# #=> [ [1,2], [4,5] ]
|
55
55
|
#
|
56
|
-
# [1,2,3,4,5].split(:include_boundary=>true) { |e| e == 3 }
|
57
|
-
# #=> [ [1,2], [3,4,5] ]
|
56
|
+
# [1,2,3,4,5].split(:include_boundary=>true) { |e| e == 3 }
|
57
|
+
# #=> [ [1,2], [3,4,5] ]
|
58
58
|
#
|
59
59
|
# chapters = File.read("ebook.txt").split(/Chapter \d+/, :include_boundary=>true)
|
60
60
|
# #=> [ ["Chapter 1", ...], ["Chapter 2", ...], etc. ]
|
61
61
|
#
|
62
62
|
def split_at(matcher=nil, options={}, &block)
|
63
63
|
# TODO: Ruby 1.9 returns Enumerators for everything now. Maybe use that?
|
64
|
-
|
64
|
+
|
65
65
|
return self unless self.any?
|
66
|
-
|
66
|
+
|
67
67
|
include_boundary = options[:include_boundary] || false
|
68
68
|
|
69
69
|
if matcher.nil?
|
@@ -79,18 +79,18 @@ module Enumerable
|
|
79
79
|
|
80
80
|
chunks = []
|
81
81
|
current_chunk = []
|
82
|
-
|
82
|
+
|
83
83
|
splits = 0
|
84
|
-
max_splits = options[:once] == true ? 1 : options[:max_splits]
|
84
|
+
max_splits = options[:once] == true ? 1 : options[:max_splits]
|
85
85
|
|
86
86
|
each do |e|
|
87
87
|
|
88
88
|
if boundary_test_proc.call(e) and (max_splits == nil or splits < max_splits)
|
89
|
-
|
90
|
-
if current_chunk.empty? and not include_boundary
|
89
|
+
|
90
|
+
if current_chunk.empty? and not include_boundary
|
91
91
|
next # hit 2 boundaries in a row... just keep moving, people!
|
92
92
|
end
|
93
|
-
|
93
|
+
|
94
94
|
if options[:after]
|
95
95
|
# split after boundary
|
96
96
|
current_chunk << e if include_boundary # include the boundary, if necessary
|
@@ -104,13 +104,13 @@ module Enumerable
|
|
104
104
|
end
|
105
105
|
|
106
106
|
splits += 1
|
107
|
-
|
107
|
+
|
108
108
|
else
|
109
109
|
current_chunk << e
|
110
110
|
end
|
111
111
|
|
112
112
|
end
|
113
|
-
|
113
|
+
|
114
114
|
chunks << current_chunk if current_chunk.any?
|
115
115
|
|
116
116
|
chunks # resultset
|
@@ -141,15 +141,15 @@ module Enumerable
|
|
141
141
|
|
142
142
|
#
|
143
143
|
# Sum the elements
|
144
|
-
#
|
144
|
+
#
|
145
145
|
def sum
|
146
146
|
if block_given?
|
147
|
-
inject(0) { |total,elem| total + yield(elem) }
|
147
|
+
inject(0) { |total,elem| total + yield(elem) }
|
148
148
|
else
|
149
149
|
inject(0) { |total,elem| total + elem }
|
150
150
|
end
|
151
151
|
end
|
152
|
-
|
152
|
+
|
153
153
|
#
|
154
154
|
# Average the elements
|
155
155
|
#
|
@@ -164,7 +164,7 @@ module Enumerable
|
|
164
164
|
# recursively on that element.
|
165
165
|
#
|
166
166
|
# Example:
|
167
|
-
# [ [1,2], [3,4] ].deep_map{|e| e ** 2 } #=> [ [1,4], [9,16] ]
|
167
|
+
# [ [1,2], [3,4] ].deep_map{|e| e ** 2 } #=> [ [1,4], [9,16] ]
|
168
168
|
#
|
169
169
|
def deep_map(depth=nil, &block)
|
170
170
|
map do |obj|
|
@@ -181,14 +181,14 @@ module Enumerable
|
|
181
181
|
|
182
182
|
alias_method :recursive_map, :deep_map
|
183
183
|
alias_method :map_recursively, :deep_map
|
184
|
-
alias_method :map_recursive, :deep_map
|
184
|
+
alias_method :map_recursive, :deep_map
|
185
185
|
|
186
186
|
#
|
187
187
|
# The same as "select", except that if an element is an Array or Enumerable, select is called
|
188
188
|
# recursively on that element.
|
189
189
|
#
|
190
190
|
# Example:
|
191
|
-
# [ [1,2], [3,4] ].deep_select{|e| e % 2 == 0 } #=> [ [2], [4] ]
|
191
|
+
# [ [1,2], [3,4] ].deep_select{|e| e % 2 == 0 } #=> [ [2], [4] ]
|
192
192
|
#
|
193
193
|
def deep_select(depth=nil, &block)
|
194
194
|
map do |*args|
|
@@ -211,9 +211,9 @@ module Enumerable
|
|
211
211
|
|
212
212
|
end.compact
|
213
213
|
end
|
214
|
-
|
214
|
+
|
215
215
|
alias_method :recursive_select, :deep_select
|
216
|
-
|
216
|
+
|
217
217
|
|
218
218
|
#
|
219
219
|
# Identical to "reduce" in ruby1.9 (or foldl in haskell.)
|
@@ -225,31 +225,31 @@ module Enumerable
|
|
225
225
|
result = nil
|
226
226
|
|
227
227
|
raise "Error: pass a parameter OR a block, not both!" unless !!methodname ^ block_given?
|
228
|
-
|
228
|
+
|
229
229
|
if methodname
|
230
|
-
|
230
|
+
|
231
231
|
each_with_index do |e,i|
|
232
232
|
if i == 0
|
233
|
-
result = e
|
233
|
+
result = e
|
234
234
|
next
|
235
235
|
end
|
236
|
-
|
237
|
-
result = result.send(methodname, e)
|
236
|
+
|
237
|
+
result = result.send(methodname, e)
|
238
238
|
end
|
239
|
-
|
239
|
+
|
240
240
|
else
|
241
|
-
|
241
|
+
|
242
242
|
each_with_index do |e,i|
|
243
243
|
if i == 0
|
244
|
-
result = e
|
244
|
+
result = e
|
245
245
|
next
|
246
246
|
end
|
247
|
-
|
248
|
-
result = block.call(result, e)
|
247
|
+
|
248
|
+
result = block.call(result, e)
|
249
249
|
end
|
250
|
-
|
250
|
+
|
251
251
|
end
|
252
|
-
|
252
|
+
|
253
253
|
result
|
254
254
|
end
|
255
255
|
|
@@ -269,16 +269,16 @@ module Enumerable
|
|
269
269
|
|
270
270
|
#
|
271
271
|
# Does the opposite of #zip -- converts [ [:a, 1], [:b, 2] ] to [ [:a, :b], [1, 2] ]
|
272
|
-
#
|
272
|
+
#
|
273
273
|
def unzip
|
274
274
|
# TODO: make it work for arrays containing uneven-length contents
|
275
275
|
to_a.transpose
|
276
276
|
end
|
277
|
-
|
277
|
+
|
278
278
|
#
|
279
279
|
# Associative grouping; groups all elements who share something in common with each other.
|
280
280
|
# You supply a block which takes two elements, and have it return true if they are "neighbours"
|
281
|
-
# (eg: belong in the same group).
|
281
|
+
# (eg: belong in the same group).
|
282
282
|
#
|
283
283
|
# Example:
|
284
284
|
# [1,2,5,6].group_neighbours_by { |a,b| b-a <= 1 } #=> [ [1,2], [5,6] ]
|
@@ -296,13 +296,13 @@ module Enumerable
|
|
296
296
|
cluster = [b]
|
297
297
|
end
|
298
298
|
end
|
299
|
-
|
299
|
+
|
300
300
|
result << cluster if cluster.any?
|
301
|
-
|
302
|
-
result
|
301
|
+
|
302
|
+
result
|
303
303
|
end
|
304
|
-
alias_method :group_neighbors_by, :group_neighbours_by
|
305
|
-
|
304
|
+
alias_method :group_neighbors_by, :group_neighbours_by
|
305
|
+
|
306
306
|
|
307
307
|
#
|
308
308
|
# Convert the array into a stable iterator (Iter) object.
|
data/lib/epitools/path.rb
CHANGED
@@ -67,6 +67,7 @@ class Path
|
|
67
67
|
# The file extension, including the . (eg: ".mp3")
|
68
68
|
attr_reader :ext
|
69
69
|
|
70
|
+
|
70
71
|
## initializers
|
71
72
|
|
72
73
|
def initialize(newpath, hints={})
|
@@ -74,13 +75,13 @@ class Path
|
|
74
75
|
end
|
75
76
|
|
76
77
|
def initialize_copy(other)
|
77
|
-
@dirs = other.dirs.dup
|
78
|
-
@base = other.base.dup
|
79
|
-
@ext = other.ext.dup
|
78
|
+
@dirs = other.dirs && other.dirs.dup
|
79
|
+
@base = other.base && other.base.dup
|
80
|
+
@ext = other.ext && other.ext.dup
|
80
81
|
end
|
81
82
|
|
82
|
-
def self.glob(str)
|
83
|
-
Dir[str].map { |entry| new(entry) }
|
83
|
+
def self.glob(str, hints={})
|
84
|
+
Dir[str].map { |entry| new(entry, hints) }
|
84
85
|
end
|
85
86
|
|
86
87
|
def self.[](path)
|
@@ -114,26 +115,6 @@ class Path
|
|
114
115
|
attr_writer :base
|
115
116
|
attr_writer :dirs
|
116
117
|
|
117
|
-
#
|
118
|
-
# Clear out the internal state of this object, so that it can be reinitialized.
|
119
|
-
#
|
120
|
-
def reset!
|
121
|
-
[:@dirs, :@base, :@ext].each { |var| remove_instance_variable var }
|
122
|
-
self
|
123
|
-
end
|
124
|
-
|
125
|
-
|
126
|
-
#
|
127
|
-
# Reload this path (update cached values.)
|
128
|
-
#
|
129
|
-
def reload!
|
130
|
-
temp = path
|
131
|
-
reset!
|
132
|
-
self.path = temp
|
133
|
-
self
|
134
|
-
end
|
135
|
-
|
136
|
-
|
137
118
|
#
|
138
119
|
# This is the core that initializes the whole class.
|
139
120
|
#
|
@@ -153,6 +134,13 @@ class Path
|
|
153
134
|
self.dir, self.filename = File.split(newpath)
|
154
135
|
end
|
155
136
|
end
|
137
|
+
|
138
|
+
# FIXME: Make this work with globs.
|
139
|
+
if hints[:relative]
|
140
|
+
update(relative_to(Path.pwd))
|
141
|
+
elsif hints[:relative_to]
|
142
|
+
update(relative_to(hints[:relative_to]))
|
143
|
+
end
|
156
144
|
end
|
157
145
|
|
158
146
|
def filename=(newfilename)
|
@@ -192,6 +180,30 @@ class Path
|
|
192
180
|
end
|
193
181
|
end
|
194
182
|
|
183
|
+
#
|
184
|
+
# Clear out the internal state of this object, so that it can be reinitialized.
|
185
|
+
#
|
186
|
+
def reset!
|
187
|
+
[:@dirs, :@base, :@ext].each { |var| remove_instance_variable var }
|
188
|
+
self
|
189
|
+
end
|
190
|
+
|
191
|
+
#
|
192
|
+
# Reload this path (update cached values.)
|
193
|
+
#
|
194
|
+
def reload!
|
195
|
+
temp = path
|
196
|
+
reset!
|
197
|
+
self.path = temp
|
198
|
+
self
|
199
|
+
end
|
200
|
+
|
201
|
+
def update(other)
|
202
|
+
@dirs = other.dirs
|
203
|
+
@base = other.base
|
204
|
+
@ext = other.ext
|
205
|
+
end
|
206
|
+
|
195
207
|
## getters
|
196
208
|
|
197
209
|
# Joins and returns the full path
|
@@ -203,6 +215,15 @@ class Path
|
|
203
215
|
end
|
204
216
|
end
|
205
217
|
|
218
|
+
#
|
219
|
+
# Is this a relative path?
|
220
|
+
#
|
221
|
+
def relative?
|
222
|
+
# FIXME: Need a Path::Relative subclass, so that "dir/filename" can be valid.
|
223
|
+
# (If the user changes dirs, the relative path should change too.)
|
224
|
+
dirs.first == ".."
|
225
|
+
end
|
226
|
+
|
206
227
|
#
|
207
228
|
# Path relative to current directory (Path.pwd)
|
208
229
|
#
|
@@ -210,44 +231,29 @@ class Path
|
|
210
231
|
relative_to(pwd)
|
211
232
|
end
|
212
233
|
|
213
|
-
def relative_to(
|
214
|
-
from = path.split(File::SEPARATOR)
|
215
|
-
to = Path[to].path.split(File::SEPARATOR)
|
216
|
-
p [from, to]
|
217
|
-
from.length.times do
|
218
|
-
break if from[0] != to[0]
|
219
|
-
from.shift; to.shift
|
220
|
-
end
|
221
|
-
fname = from.pop
|
222
|
-
join(*(from.map { RELATIVE_PARENTDIR } + to))
|
223
|
-
end
|
224
|
-
|
225
|
-
def relative_to2(anchor=nil)
|
226
|
-
anchor ||= Path.pwd
|
227
|
-
|
228
|
-
# operations to transform anchor into self
|
229
|
-
|
234
|
+
def relative_to(anchor)
|
230
235
|
# stage 1: go ".." until we find a common dir prefix
|
231
236
|
# (discard everything and go '/' if there's no common dir)
|
232
237
|
# stage 2: append the rest of the other path
|
233
238
|
|
234
|
-
|
235
|
-
smaller, bigger = [ anchor.dirs, self.dirs ].sort_by(&:size)
|
236
|
-
common_prefix_end = bigger.zip(smaller).index { |a,b | a != b }
|
237
|
-
common_prefix = bigger[0...common_prefix_end]
|
239
|
+
first_mismatch = dirs.zip(anchor.dirs).index { |a,b| a != b }
|
238
240
|
|
239
|
-
|
240
|
-
dots = nil
|
241
|
-
end
|
241
|
+
num_dots = anchor.dirs.size - first_mismatch
|
242
242
|
|
243
|
-
|
243
|
+
result = self.dup
|
244
|
+
result.dirs = ([".."] * num_dots) + dirs[first_mismatch..-1]
|
244
245
|
|
246
|
+
result
|
245
247
|
end
|
246
248
|
|
247
249
|
# The current directory (with a trailing /)
|
248
250
|
def dir
|
249
251
|
if dirs
|
250
|
-
|
252
|
+
if relative?
|
253
|
+
File.join(*dirs)
|
254
|
+
else
|
255
|
+
File::SEPARATOR + File.join(*dirs)
|
256
|
+
end
|
251
257
|
else
|
252
258
|
nil
|
253
259
|
end
|
@@ -356,8 +362,7 @@ class Path
|
|
356
362
|
end
|
357
363
|
|
358
364
|
def parent_of?(child)
|
359
|
-
|
360
|
-
child.path[/^#{Regexp.escape self.path}\/.+/] != nil
|
365
|
+
dirs == child.dirs[0...dirs.size]
|
361
366
|
end
|
362
367
|
|
363
368
|
## comparisons
|
@@ -384,6 +389,7 @@ class Path
|
|
384
389
|
|
385
390
|
#
|
386
391
|
# Path["/etc"].join("anything{}").path == "/etc/anything{}"
|
392
|
+
# (globs ignored)
|
387
393
|
#
|
388
394
|
def join(other)
|
389
395
|
Path.new File.join(self, other)
|
@@ -391,6 +397,7 @@ class Path
|
|
391
397
|
|
392
398
|
#
|
393
399
|
# Path["/etc"]/"passwd" == Path["/etc/passwd"]
|
400
|
+
# (globs permitted)
|
394
401
|
#
|
395
402
|
def /(other)
|
396
403
|
# / <- fixes jedit syntax highlighting bug.
|
@@ -578,41 +585,28 @@ class Path
|
|
578
585
|
# Path["Songy Song.aac"].rename(:dir=>"/music2")
|
579
586
|
# Path["/music2/Songy Song.aac"].exists? #=> true
|
580
587
|
#
|
581
|
-
def rename!(options)
|
582
|
-
raise "Broken!"
|
583
|
-
|
584
|
-
dest = rename(options)
|
585
|
-
self.path = dest.path # become dest
|
586
|
-
self
|
587
|
-
end
|
588
|
-
|
589
588
|
def rename(options)
|
590
|
-
raise "Broken!"
|
591
|
-
|
592
589
|
raise "Options must be a Hash" unless options.is_a? Hash
|
593
590
|
dest = self.with(options)
|
594
591
|
|
595
592
|
raise "Error: destination (#{dest.inspect}) already exists" if dest.exists?
|
596
593
|
File.rename(path, dest)
|
597
594
|
|
598
|
-
dest
|
595
|
+
update(dest)
|
596
|
+
|
597
|
+
self
|
599
598
|
end
|
600
599
|
|
601
600
|
#
|
602
601
|
# Renames the file the specified full path (like Dir.rename.)
|
603
602
|
#
|
604
603
|
def rename_to(path)
|
605
|
-
raise "Broken!"
|
606
|
-
|
607
604
|
rename :path=>path.to_s
|
608
605
|
end
|
609
|
-
alias_method :mv, :rename_to
|
610
606
|
|
611
607
|
def rename_to!(path)
|
612
|
-
raise "Broken!"
|
613
608
|
rename! :path=>path.to_s
|
614
609
|
end
|
615
|
-
alias_method :mv!, :rename_to!
|
616
610
|
|
617
611
|
#
|
618
612
|
# Generate two almost identical methods: mkdir and mkdir_p
|
@@ -646,17 +640,9 @@ raise "Broken!"
|
|
646
640
|
FileUtils.mv(path, dest)
|
647
641
|
end
|
648
642
|
|
649
|
-
def join(other)
|
650
|
-
if uri?
|
651
|
-
Path[URI.join(path, other).to_s]
|
652
|
-
else
|
653
|
-
Path[File.join(path, other)]
|
654
|
-
end
|
655
|
-
end
|
656
|
-
|
657
643
|
def ln_s(dest)
|
658
644
|
dest = Path[dest]
|
659
|
-
FileUtils.ln_s
|
645
|
+
FileUtils.ln_s(self, dest)
|
660
646
|
end
|
661
647
|
|
662
648
|
## Owners and permissions
|
@@ -1017,6 +1003,10 @@ raise "Broken!"
|
|
1017
1003
|
end
|
1018
1004
|
|
1019
1005
|
|
1006
|
+
class Path::Relative < Path
|
1007
|
+
# FIXME: Implement this.
|
1008
|
+
end
|
1009
|
+
|
1020
1010
|
#
|
1021
1011
|
# A wrapper for URL objects.
|
1022
1012
|
#
|
@@ -1042,32 +1032,24 @@ class Path::URL < Path
|
|
1042
1032
|
#
|
1043
1033
|
# When this is: http://host.com:port/path/filename.ext?param1=value1¶m2=value2&...
|
1044
1034
|
#
|
1045
|
-
def to_s
|
1046
|
-
uri.to_s
|
1047
|
-
end
|
1035
|
+
def to_s; uri.to_s; end
|
1048
1036
|
|
1049
1037
|
|
1050
1038
|
#
|
1051
1039
|
# ...this is: 'http'
|
1052
1040
|
#
|
1053
|
-
def scheme
|
1054
|
-
uri.scheme
|
1055
|
-
end
|
1041
|
+
def scheme; uri.scheme; end
|
1056
1042
|
alias_method :protocol, :scheme
|
1057
1043
|
|
1058
1044
|
#
|
1059
1045
|
# ...and this is: 'host.com'
|
1060
1046
|
#
|
1061
|
-
def host
|
1062
|
-
uri.host
|
1063
|
-
end
|
1047
|
+
def host; uri.host; end
|
1064
1048
|
|
1065
1049
|
#
|
1066
1050
|
# ...and this is: 80
|
1067
1051
|
#
|
1068
|
-
def port
|
1069
|
-
uri.port
|
1070
|
-
end
|
1052
|
+
def port; uri.port; end
|
1071
1053
|
|
1072
1054
|
#
|
1073
1055
|
# ...and this is: {param1: value1, param2: value2, ...etc... }
|
@@ -1080,6 +1062,11 @@ class Path::URL < Path
|
|
1080
1062
|
end
|
1081
1063
|
end
|
1082
1064
|
|
1065
|
+
def join(other)
|
1066
|
+
Path.new URI.join(path, other).to_s
|
1067
|
+
end
|
1068
|
+
|
1069
|
+
|
1083
1070
|
# ...and `path` is /path/filename.ext
|
1084
1071
|
|
1085
1072
|
def open(mode="r", &block)
|
data/spec/path_spec.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'epitools'
|
2
|
+
require 'epitools/permutations'
|
2
3
|
|
3
4
|
describe Path do
|
4
5
|
|
@@ -31,7 +32,11 @@ describe Path do
|
|
31
32
|
end
|
32
33
|
|
33
34
|
it "'relative_to's" do
|
34
|
-
Path["/etc"].relative_to(Path["/tmp"]).should == "../
|
35
|
+
Path["/etc"].relative_to(Path["/tmp"]).should == "../etc/"
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should glob with relative paths" do
|
39
|
+
raise "not implemented"
|
35
40
|
end
|
36
41
|
|
37
42
|
it "handles directories" do
|
@@ -204,14 +209,19 @@ describe Path do
|
|
204
209
|
end
|
205
210
|
|
206
211
|
it "renames" do
|
207
|
-
path = Path.
|
212
|
+
path = Path.tmp
|
208
213
|
|
209
|
-
|
214
|
+
path.rm
|
215
|
+
path.touch
|
216
|
+
|
217
|
+
path.exists?.should == true
|
218
|
+
|
219
|
+
old_name = path.to_s
|
210
220
|
|
211
221
|
path.rename(:ext=>".dat")
|
212
222
|
|
213
|
-
path.to_s.
|
214
|
-
path.to_s.
|
223
|
+
path.to_s.should == old_name+".dat"
|
224
|
+
path.to_s.should_not == old_name
|
215
225
|
end
|
216
226
|
|
217
227
|
it "rms" do
|
@@ -236,7 +246,7 @@ describe Path do
|
|
236
246
|
end
|
237
247
|
|
238
248
|
it "checksums" do
|
239
|
-
a, b = Path["
|
249
|
+
a, b = Path["**/*.rb"].take(2)
|
240
250
|
[:sha1, :sha2, :md5].each do |meth|
|
241
251
|
sum1 = a.send(meth)
|
242
252
|
sum2 = b.send(meth)
|
@@ -333,7 +343,8 @@ describe Path do
|
|
333
343
|
tmp.touch
|
334
344
|
tmp2.touch
|
335
345
|
|
336
|
-
|
346
|
+
tmp.mode.should == tmp2.mode
|
347
|
+
|
337
348
|
tmp.chmod("+x")
|
338
349
|
system("chmod", "+x", tmp2)
|
339
350
|
tmp.mode.should == tmp2.mode
|
@@ -350,14 +361,13 @@ describe Path do
|
|
350
361
|
tmp = Path.tmpfile
|
351
362
|
tmp.rm if tmp.exists?
|
352
363
|
tmp.mkdir
|
353
|
-
|
354
|
-
p tmp.dirs
|
364
|
+
|
355
365
|
#tmp.to_s.endswith('/').should == true
|
356
366
|
file = tmp/"file"
|
357
367
|
file.touch
|
358
|
-
|
368
|
+
|
359
369
|
file.dirs.should == tmp.dirs
|
360
|
-
file.filename.
|
370
|
+
file.filename.should_not == tmp.filename
|
361
371
|
end
|
362
372
|
|
363
373
|
it 'parents and childs properly' do
|
@@ -372,12 +382,12 @@ describe Path do
|
|
372
382
|
root => parent,
|
373
383
|
root => child,
|
374
384
|
root => neither,
|
375
|
-
}.each do |
|
376
|
-
|
377
|
-
|
385
|
+
}.each do |parent, child|
|
386
|
+
parent.should be_parent_of child
|
387
|
+
child.should_not be_parent_of parent
|
378
388
|
|
379
|
-
|
380
|
-
|
389
|
+
child.should be_child_of parent
|
390
|
+
parent.should_not be_child_of child
|
381
391
|
end
|
382
392
|
|
383
393
|
neither.parent_of?(child).should == false
|
@@ -388,7 +398,7 @@ describe Path do
|
|
388
398
|
path = Path.tmpfile
|
389
399
|
path.exe?.should == false
|
390
400
|
path.chmod(0o666)
|
391
|
-
|
401
|
+
|
392
402
|
(path.mode & 0o666).should > 0
|
393
403
|
end
|
394
404
|
|
@@ -407,8 +417,9 @@ describe Path do
|
|
407
417
|
end
|
408
418
|
|
409
419
|
it 'swaps two files' do
|
410
|
-
raise "errorn!"
|
411
420
|
# swap two regular files
|
421
|
+
|
422
|
+
|
412
423
|
# swap a symlink and a regular file
|
413
424
|
# swap two symlinks
|
414
425
|
end
|
@@ -426,7 +437,7 @@ describe Path do
|
|
426
437
|
|
427
438
|
it "shouldn't glob with Path#join" do
|
428
439
|
path = Path["/etc"].join("blah{}")
|
429
|
-
path.should == "/etc/blah{}"
|
440
|
+
path.path.should == "/etc/blah{}"
|
430
441
|
end
|
431
442
|
|
432
443
|
it "should glob with Path#/" do
|