epitools 0.5.1 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Guardfile +16 -0
- data/VERSION +1 -1
- data/epitools.gemspec +13 -6
- data/lib/epitools.rb +48 -6
- data/lib/epitools/autoloads.rb +14 -3
- data/lib/epitools/browser.rb +8 -1
- data/lib/epitools/core_ext.rb +207 -0
- data/lib/epitools/core_ext/array.rb +98 -0
- data/lib/epitools/core_ext/enumerable.rb +306 -0
- data/lib/epitools/core_ext/hash.rb +201 -0
- data/lib/epitools/core_ext/numbers.rb +254 -0
- data/lib/epitools/core_ext/object.rb +195 -0
- data/lib/epitools/core_ext/string.rb +338 -0
- data/lib/epitools/core_ext/truthiness.rb +64 -0
- data/lib/epitools/iter.rb +22 -8
- data/lib/epitools/mimemagic.rb +0 -1
- data/lib/epitools/path.rb +149 -36
- data/lib/epitools/rash.rb +49 -37
- data/lib/epitools/term.rb +5 -1
- data/spec/{basetypes_spec.rb → core_ext_spec.rb} +190 -37
- data/spec/iter_spec.rb +9 -27
- data/spec/path_spec.rb +104 -46
- data/spec/permutations_spec.rb +3 -2
- data/spec/rash_spec.rb +21 -7
- data/spec/spec_helper.rb +36 -5
- metadata +34 -12
- data/lib/epitools/basetypes.rb +0 -1135
- data/lib/epitools/string_to_proc.rb +0 -78
data/lib/epitools/rash.rb
CHANGED
@@ -14,6 +14,7 @@ class Rash
|
|
14
14
|
def initialize(initial={})
|
15
15
|
@hash = {}
|
16
16
|
@regexes = []
|
17
|
+
@ranges = []
|
17
18
|
@regex_counts = Hash.new(0)
|
18
19
|
@optimize_every = 500
|
19
20
|
@lookups = 0
|
@@ -21,59 +22,70 @@ class Rash
|
|
21
22
|
update(initial)
|
22
23
|
end
|
23
24
|
|
25
|
+
def update(other)
|
26
|
+
for key, value in other
|
27
|
+
self[key] = value
|
28
|
+
end
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
24
32
|
def []=(key, value)
|
25
|
-
|
33
|
+
case key
|
34
|
+
when Regexp
|
26
35
|
#key = normalize_regex(key) # this used to just do: /#{regexp}/
|
27
36
|
@regexes << key
|
37
|
+
when Range
|
38
|
+
@ranges << key
|
28
39
|
end
|
29
40
|
@hash[key] = value
|
30
41
|
end
|
31
42
|
|
32
|
-
|
33
|
-
|
43
|
+
#
|
44
|
+
# Return the first thing that matches the key.
|
45
|
+
#
|
46
|
+
def [](key)
|
47
|
+
all(key).first
|
34
48
|
end
|
35
49
|
|
36
|
-
|
37
|
-
|
38
|
-
|
50
|
+
#
|
51
|
+
# Return everything that matches the query.
|
52
|
+
#
|
53
|
+
def all(query)
|
54
|
+
return Enumerator.new(self, :all, query) unless block_given?
|
39
55
|
|
40
|
-
|
41
|
-
|
56
|
+
if @hash.include? query
|
57
|
+
yield @hash[query]
|
58
|
+
return
|
59
|
+
end
|
42
60
|
|
43
|
-
case
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
61
|
+
case query
|
62
|
+
when String
|
63
|
+
optimize_if_necessary!
|
64
|
+
@regexes.each do |regex|
|
65
|
+
if match = regex.match(query)
|
66
|
+
@regex_counts[regex] += 1
|
67
|
+
value = @hash[regex]
|
68
|
+
if value.responds_to? :call
|
69
|
+
yield value.call(match)
|
70
|
+
else
|
71
|
+
yield value
|
54
72
|
end
|
55
73
|
end
|
56
|
-
|
57
|
-
when Regexp
|
58
|
-
|
59
|
-
matches = search_strings(key)
|
60
|
-
|
61
|
-
if matches.any?
|
62
|
-
return matches
|
63
|
-
end
|
74
|
+
end
|
64
75
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
76
|
+
when Integer
|
77
|
+
@ranges.each do |range|
|
78
|
+
yield @hash[range] if range.include? query
|
79
|
+
end
|
80
|
+
|
81
|
+
when Regexp
|
82
|
+
# TODO: this doesn't seem very useful. should I ditch it? let me know!
|
83
|
+
@hash.each do |key,val|
|
84
|
+
yield val if key.is_a? String and query =~ key
|
85
|
+
end
|
71
86
|
|
72
|
-
def update(other)
|
73
|
-
for key, value in other
|
74
|
-
self[key] = value
|
75
87
|
end
|
76
|
-
|
88
|
+
|
77
89
|
end
|
78
90
|
|
79
91
|
def method_missing(*args, &block)
|
data/lib/epitools/term.rb
CHANGED
@@ -54,7 +54,7 @@ module Term
|
|
54
54
|
|
55
55
|
def initialize(data, options={})
|
56
56
|
@data = data.map(&:to_s)
|
57
|
-
@strip_color = options[:strip_color] || options[:strip_ansi]
|
57
|
+
@strip_color = options[:ansi] || options[:colorized] || options[:colored] || options[:strip_color] || options[:strip_ansi]
|
58
58
|
|
59
59
|
if strip_color
|
60
60
|
@max_size = @data.map { |e| e.strip_color.size }.max
|
@@ -116,6 +116,10 @@ module Term
|
|
116
116
|
render sliced_into(num_columns)
|
117
117
|
end
|
118
118
|
|
119
|
+
def to_s
|
120
|
+
by_rows
|
121
|
+
end
|
122
|
+
|
119
123
|
def render(rows, options={})
|
120
124
|
num_cols = rows.first.size
|
121
125
|
result = []
|
@@ -17,27 +17,35 @@ describe Object do
|
|
17
17
|
c = Cookie.new; c.size = 10; c.chips = 200
|
18
18
|
w = c.with(:chips=>50)
|
19
19
|
|
20
|
-
w.size.should
|
20
|
+
w.size.should == c.size
|
21
21
|
w.chips.should_not == c.chips
|
22
|
-
w.should_not
|
22
|
+
w.should_not === c
|
23
23
|
end
|
24
24
|
|
25
25
|
it "in?" do
|
26
|
-
5.in?([1,2,3,4,5,6]).should
|
27
|
-
5.in?(1..10).should
|
28
|
-
5.in?(20..30).should
|
26
|
+
5.in?([1,2,3,4,5,6]).should == true
|
27
|
+
5.in?(1..10).should == true
|
28
|
+
5.in?(20..30).should == false
|
29
29
|
"butt".in?("butts!!!").should == true
|
30
30
|
end
|
31
31
|
|
32
|
-
it "
|
32
|
+
it "times" do
|
33
33
|
lambda {
|
34
|
-
|
34
|
+
time("time test") { x = 10 }
|
35
35
|
}.should_not raise_error
|
36
36
|
|
37
37
|
lambda {
|
38
|
-
|
38
|
+
time("time test") { raise "ERROR" }
|
39
39
|
}.should raise_error
|
40
40
|
end
|
41
|
+
|
42
|
+
it "benches" do
|
43
|
+
lambda { bench { rand } }.should_not raise_error
|
44
|
+
lambda { bench(20) { rand } }.should_not raise_error
|
45
|
+
lambda { bench }.should raise_error
|
46
|
+
lambda { bench(:rand => proc { rand }, :notrand => proc { 1 }) }.should_not raise_error
|
47
|
+
lambda { bench(200, :rand => proc { rand }, :notrand => proc { 1 }) }.should_not raise_error
|
48
|
+
end
|
41
49
|
|
42
50
|
it "trys" do
|
43
51
|
s = Struct.new(:a,:b).new
|
@@ -53,21 +61,21 @@ describe Object do
|
|
53
61
|
|
54
62
|
def s.test(a); a; end
|
55
63
|
|
56
|
-
s.test(1).should
|
57
|
-
s.try(:test, 1).should
|
64
|
+
s.test(1).should == 1
|
65
|
+
s.try(:test, 1).should == 1
|
58
66
|
|
59
67
|
lambda { s.test }.should raise_error
|
60
68
|
lambda { s.try(:test) }.should raise_error
|
61
69
|
|
62
70
|
def s.blocky; yield; end
|
63
|
-
|
64
|
-
s.blocky{ 1 }.should
|
65
|
-
s.try(:blocky){ 1 }.should
|
71
|
+
|
72
|
+
s.blocky{ 1 }.should == 1
|
73
|
+
s.try(:blocky){ 1 }.should == 1
|
66
74
|
s.try(:nonexistant){ 1 }.should == nil
|
67
75
|
end
|
68
76
|
|
69
77
|
it "nots" do
|
70
|
-
10.even?.should
|
78
|
+
10.even?.should == true
|
71
79
|
10.not.even?.should == false
|
72
80
|
end
|
73
81
|
|
@@ -123,33 +131,47 @@ end
|
|
123
131
|
describe Numeric do
|
124
132
|
|
125
133
|
it "commatizes" do
|
126
|
-
123.commatize.should
|
127
|
-
1234.commatize.should
|
128
|
-
12983287123.commatize.should
|
129
|
-
-12983287123.commatize.should
|
134
|
+
123.commatize.should == "123"
|
135
|
+
1234.commatize.should == "1,234"
|
136
|
+
12983287123.commatize.should == "12,983,287,123"
|
137
|
+
-12983287123.commatize.should == "-12,983,287,123"
|
130
138
|
-12983287123.4411.commatize.should == "-12,983,287,123.4411"
|
131
139
|
end
|
132
140
|
|
133
141
|
it "does time things" do
|
134
|
-
1.second.should
|
135
|
-
1.minute.should
|
136
|
-
2.minutes.should
|
137
|
-
2.hours.should
|
138
|
-
2.5.days.should
|
139
|
-
|
140
|
-
5.days.ago.to_i.should
|
141
|
-
1.year.ago.year.should
|
142
|
+
1.second.should == 1
|
143
|
+
1.minute.should == 60
|
144
|
+
2.minutes.should == 120
|
145
|
+
2.hours.should == 120*60
|
146
|
+
2.5.days.should == 3600*24*2.5
|
147
|
+
|
148
|
+
5.days.ago.to_i.should == (Time.now - 5.days).to_i
|
149
|
+
1.year.ago.year.should == Time.now.year - 1
|
142
150
|
5.days.from_now.to_i.should == (Time.now + 5.days).to_i
|
143
151
|
end
|
144
152
|
|
145
|
-
|
153
|
+
it "thingses" do
|
154
|
+
10.things.should == [0,1,2,3,4,5,6,7,8,9]
|
155
|
+
4.things {|n| n * 5 }.should == [0,5,10,15]
|
156
|
+
-1.things.should == []
|
157
|
+
end
|
146
158
|
|
159
|
+
it "maths" do
|
160
|
+
10.cos.should == Math.cos(10)
|
161
|
+
20.sin.should == Math.sin(20)
|
162
|
+
1.5.exp.should == Math.exp(1.5)
|
163
|
+
|
164
|
+
253.log(5).should == Math.log(253,5)
|
165
|
+
(2**(4212.log(2))).should == 4212.0
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
147
169
|
|
148
170
|
describe String do
|
149
171
|
|
150
172
|
it "rot13s" do
|
151
173
|
message = "Unbreakable Code"
|
152
|
-
message.rot13.should_not
|
174
|
+
message.rot13.should_not == message
|
153
175
|
message.rot13.rot13.should == message
|
154
176
|
end
|
155
177
|
|
@@ -205,6 +227,14 @@ describe String do
|
|
205
227
|
"blahblahblah".startswith("blah").should == true
|
206
228
|
"blahblahblah".endswith("blah").should == true
|
207
229
|
end
|
230
|
+
|
231
|
+
it "amounts" do
|
232
|
+
"cookie".amount(5).should == "5 cookies"
|
233
|
+
"cookie".amount(0).should == "0 cookies"
|
234
|
+
"shirt".amount(17).should == "17 shirts"
|
235
|
+
"dollar".amount(-10).should == "-10 dollars"
|
236
|
+
"love".amount(1).should == "1 love"
|
237
|
+
end
|
208
238
|
|
209
239
|
end
|
210
240
|
|
@@ -304,6 +334,11 @@ describe Array do
|
|
304
334
|
(b/2).should == [[1,2],[3,4]]
|
305
335
|
end
|
306
336
|
|
337
|
+
it "includes?s" do
|
338
|
+
[:a, :b, :c].includes?(:c).should == true
|
339
|
+
[:a, :b, :c].includes?(5).should == false
|
340
|
+
end
|
341
|
+
|
307
342
|
end
|
308
343
|
|
309
344
|
|
@@ -346,10 +381,17 @@ describe Enumerable do
|
|
346
381
|
[1,1,3,3].average.should == 2.0
|
347
382
|
end
|
348
383
|
|
349
|
-
it "
|
350
|
-
[[1,2],[3,4]].
|
351
|
-
[1,2,3,4].
|
352
|
-
[[],[],1,2,3,4].
|
384
|
+
it "maps deeply" do
|
385
|
+
[[1,2],[3,4]].deep_map {|e| e ** 2}.should == [[1,4],[9,16]]
|
386
|
+
[1,2,3,4].deep_map {|e| e ** 2}.should == [1,4,9,16]
|
387
|
+
[[],[],1,2,3,4].deep_map {|e| e ** 2}.should == [[], [], 1, 4, 9, 16]
|
388
|
+
end
|
389
|
+
|
390
|
+
it "selects deeply" do
|
391
|
+
[[1,2],[3,4]].deep_select {|e| e % 2 == 0 }.should == [2,4]
|
392
|
+
{1=>2, 3=>{4=>5, 6=>7}}.deep_select {|k,v| k == 1 }.should == {1=>2}
|
393
|
+
#[1,2,3,4].deep_select {|e| e ** 2}.should == [1,4,9,16]
|
394
|
+
#[[],[],1,2,3,4].deep_select {|e| e ** 2}.should == [[], [], 1, 4, 9, 16]
|
353
395
|
end
|
354
396
|
|
355
397
|
it "foldl's" do
|
@@ -374,6 +416,12 @@ describe Enumerable do
|
|
374
416
|
result = a.group_neighbours_by { |a,b| b-a <= 1 }
|
375
417
|
result.should == [[1,2],[5,6,7],[10,11],[13]]
|
376
418
|
end
|
419
|
+
|
420
|
+
it "includes?s" do
|
421
|
+
[:a, :b, :c].to_enum.includes?(:c).should == true
|
422
|
+
[:a, :b, :c].to_enum.includes?(5).should == false
|
423
|
+
end
|
424
|
+
|
377
425
|
end
|
378
426
|
|
379
427
|
describe Hash do
|
@@ -384,24 +432,25 @@ describe Hash do
|
|
384
432
|
|
385
433
|
it "maps keys" do
|
386
434
|
h = @h.map_keys{|k| k.upcase}
|
387
|
-
h.keys.should
|
435
|
+
h.keys.should == @h.keys.map{|k| k.upcase}
|
388
436
|
h.values.should == @h.values
|
389
437
|
|
390
438
|
h.map_keys! { 1 }
|
391
|
-
h.keys.should
|
439
|
+
h.keys.should == [1]
|
392
440
|
end
|
393
441
|
|
394
442
|
it "maps values" do
|
395
443
|
h = @h.map_values{|v| v.upcase}
|
444
|
+
|
396
445
|
h.values.should == @h.values.map{|v| v.upcase}
|
397
|
-
h.keys.should
|
398
|
-
h.map_values!{ 1 }
|
446
|
+
h.keys.should == @h.keys
|
447
|
+
h.map_values! { 1 }
|
399
448
|
h.values.should == [1,1]
|
400
449
|
end
|
401
450
|
|
402
451
|
it "mkdir_p's and trees" do
|
403
452
|
h = {}
|
404
|
-
h.mkdir_p(["a", "b", "c"]).should
|
453
|
+
h.mkdir_p(["a", "b", "c"]).should == {"a"=>{"b"=>{"c"=>{}}}}
|
405
454
|
h.mkdir_p(["a", "b", "whoa"]).should == {"a"=>{"b"=>{"c"=>{}, "whoa"=>{}}}}
|
406
455
|
|
407
456
|
lambda {
|
@@ -416,6 +465,63 @@ describe Hash do
|
|
416
465
|
params.to_query.in?(["donkeys=7&stubborn=true", "stubborn=true&donkeys=7"]).should == true
|
417
466
|
end
|
418
467
|
|
468
|
+
it "includes?s and key?s" do
|
469
|
+
@h.key?("key1").should == true
|
470
|
+
@h.includes?("key1").should == true
|
471
|
+
end
|
472
|
+
|
473
|
+
end
|
474
|
+
|
475
|
+
|
476
|
+
describe Time do
|
477
|
+
it "time in words" do
|
478
|
+
Time.now.in_words.should == "just now"
|
479
|
+
1.second.ago.in_words.should == "1 second ago"
|
480
|
+
2.seconds.ago.in_words.should == "2 seconds ago"
|
481
|
+
3.weeks.ago.in_words.should == "3 weeks ago"
|
482
|
+
4.5.weeks.ago.in_words.should == "1 month ago"
|
483
|
+
2.months.ago.in_words.should == "2 months ago"
|
484
|
+
2.years.ago.in_words.should == "2 years ago"
|
485
|
+
2.5.years.ago.in_words.should == "2 years ago"
|
486
|
+
|
487
|
+
2.5.years.from_now.in_words.should == "2 years from now"
|
488
|
+
end
|
489
|
+
end
|
490
|
+
|
491
|
+
|
492
|
+
describe Binding do
|
493
|
+
a = 1
|
494
|
+
b = proc { a }
|
495
|
+
|
496
|
+
b.binding.keys.should == [:a, :b]
|
497
|
+
b.binding.keys.should == b.binding.local_variables
|
498
|
+
|
499
|
+
b.binding[:a].should == 1
|
500
|
+
b.binding["a"].should == 1
|
501
|
+
b.binding[:b].should == b
|
502
|
+
|
503
|
+
b.binding[:a] = 5
|
504
|
+
b.binding[:a].should == 5
|
505
|
+
b.call.should == 5
|
506
|
+
end
|
507
|
+
|
508
|
+
describe Proc do
|
509
|
+
|
510
|
+
it "joins procs" do
|
511
|
+
a = proc { 1 } & proc { 2 }
|
512
|
+
a.call.should == [1,2]
|
513
|
+
|
514
|
+
a &= proc { 3 }
|
515
|
+
a.call.should == [[1,2],3]
|
516
|
+
end
|
517
|
+
|
518
|
+
it "chains procs" do
|
519
|
+
b = proc { 1 } | proc { |input| input + 1 }
|
520
|
+
b.call.should == 2
|
521
|
+
b = b.chain( proc { |input| input + 1 } )
|
522
|
+
b.call(1).should == 3
|
523
|
+
end
|
524
|
+
|
419
525
|
end
|
420
526
|
|
421
527
|
|
@@ -427,6 +533,14 @@ describe BasicObject do
|
|
427
533
|
|
428
534
|
end
|
429
535
|
|
536
|
+
describe Range do
|
537
|
+
|
538
|
+
it "generates random numbers" do
|
539
|
+
r = 1..10
|
540
|
+
50.times { r.includes?(r.rand).should == true }
|
541
|
+
end
|
542
|
+
|
543
|
+
end
|
430
544
|
|
431
545
|
describe "truthiness" do
|
432
546
|
|
@@ -449,6 +563,22 @@ describe "truthiness" do
|
|
449
563
|
|
450
564
|
end
|
451
565
|
|
566
|
+
describe "proper grammar" do
|
567
|
+
|
568
|
+
it "responds_to?" do
|
569
|
+
proc{}.responds_to?(:call).should == true
|
570
|
+
end
|
571
|
+
|
572
|
+
it "includes?" do
|
573
|
+
[1,2,3,4,5].includes?(5).should == true
|
574
|
+
end
|
575
|
+
|
576
|
+
it "is_an?" do
|
577
|
+
Object.new.is_an?(Object).should == true
|
578
|
+
end
|
579
|
+
|
580
|
+
end
|
581
|
+
|
452
582
|
|
453
583
|
describe "metaclass" do
|
454
584
|
|
@@ -460,3 +590,26 @@ describe "metaclass" do
|
|
460
590
|
|
461
591
|
end
|
462
592
|
|
593
|
+
|
594
|
+
describe "global methods" do
|
595
|
+
|
596
|
+
it "locals's" do
|
597
|
+
require 'binding_of_caller'
|
598
|
+
|
599
|
+
a = 5
|
600
|
+
b = 10
|
601
|
+
_what_ = :splunge
|
602
|
+
|
603
|
+
locals.should == {:a=>5, :b=>10}
|
604
|
+
end
|
605
|
+
|
606
|
+
end
|
607
|
+
|
608
|
+
describe "to_jsons and to_yamls" do
|
609
|
+
data = {"a"=>"b", "yes"=>true, "hello"=>[1,2,3,4,5]}
|
610
|
+
data.to_json.from_json.should == data
|
611
|
+
|
612
|
+
data = {:a=>"b", 1=>true, "hello"=>[1,2,3,4,5]}
|
613
|
+
data.to_yaml.from_yaml.should == data
|
614
|
+
end
|
615
|
+
|