spruz 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/spruz/xt.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'spruz'
2
+ module Spruz
3
+ require 'spruz/xt/blank'
4
+ require 'spruz/xt/count_by'
5
+ require 'spruz/xt/full'
6
+ require 'spruz/xt/hash_union'
7
+ require 'spruz/xt/irb'
8
+ require 'spruz/xt/null'
9
+ require 'spruz/xt/round'
10
+ require 'spruz/xt/subhash'
11
+ require 'spruz/xt/time_dummy'
12
+ require 'spruz/xt/uniq_by'
13
+ require 'spruz/xt/p'
14
+ require 'spruz/xt/symbol_to_proc'
15
+ end
@@ -0,0 +1,67 @@
1
+ module Spruz
2
+ module Blank
3
+ module Object
4
+ def blank?
5
+ respond_to?(:empty?) ? empty? : !self
6
+ end
7
+
8
+ def present?
9
+ !blank?
10
+ end
11
+ end
12
+
13
+ module NilClass
14
+ def blank?
15
+ true
16
+ end
17
+ end
18
+
19
+ module FalseClass
20
+ def blank?
21
+ true
22
+ end
23
+ end
24
+
25
+ module TrueClass
26
+ def blank?
27
+ false
28
+ end
29
+ end
30
+
31
+ module Array
32
+ def self.included(modul)
33
+ modul.module_eval do
34
+ alias_method :blank?, :empty?
35
+ end
36
+ end
37
+ end
38
+
39
+ module Hash
40
+ def self.included(modul)
41
+ modul.module_eval do
42
+ alias_method :blank?, :empty?
43
+ end
44
+ end
45
+ end
46
+
47
+ module String
48
+ def blank?
49
+ self !~ /\S/
50
+ end
51
+ end
52
+
53
+ module Numeric
54
+ def blank?
55
+ false
56
+ end
57
+ end
58
+ end
59
+
60
+ unless Object.respond_to?(:blank?)
61
+ for k in Blank.constants
62
+ Object.const_get(k).class_eval do
63
+ include Blank.const_get(k)
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,11 @@
1
+ require 'spruz/count_by'
2
+
3
+ module Spruz
4
+ module ::Enumerable
5
+ include CountBy
6
+ end
7
+
8
+ class ::Array
9
+ include CountBy
10
+ end
11
+ end
@@ -0,0 +1,33 @@
1
+ require 'spruz/xt/blank'
2
+
3
+ module Spruz
4
+ module Full
5
+ # Returns the object if it isn't blank (as in Object#blank?), otherwise it
6
+ # returns nil. If a block was given as an argument and the object isn't
7
+ # blank, the block is executed with the object as its first argument. If an
8
+ # argument +dispatch+ was given and the object wasn't blank the method
9
+ # given by dispatch is called on the object. This is the same as
10
+ # foo.full?(&:bar) in the previous block form.
11
+ def full?(dispatch = nil, *args)
12
+ if blank?
13
+ obj = nil
14
+ #elsif Module === dispatch # TODO
15
+ # dispatch.found?(self)
16
+ elsif dispatch
17
+ obj = __send__(dispatch, *args)
18
+ obj = nil if obj.blank?
19
+ else
20
+ obj = self
21
+ end
22
+ if block_given? and obj
23
+ yield obj
24
+ else
25
+ obj
26
+ end
27
+ end
28
+ end
29
+
30
+ class ::Object
31
+ include Full
32
+ end
33
+ end
@@ -0,0 +1,11 @@
1
+ require 'spruz/hash_union'
2
+
3
+ module Spruz
4
+ class ::Hash
5
+ if method_defined?(:|)
6
+ warn "#{self}#| already defined, didn't include at #{__FILE__}:#{__LINE__}"
7
+ else
8
+ include HashUnion
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ require 'irb'
2
+
3
+ module Spruz
4
+ IRB = ::IRB
5
+
6
+ module ::IRB
7
+ def self.examine(binding = TOPLEVEL_BINDING)
8
+ setup nil
9
+ workspace = WorkSpace.new binding
10
+ irb = Irb.new workspace
11
+ @CONF[:MAIN_CONTEXT] = irb.context
12
+ catch(:IRB_EXIT) { irb.eval_input }
13
+ rescue Interrupt
14
+ exit
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,5 @@
1
+ require 'spruz/null'
2
+
3
+ module Spruz
4
+ ::NULL = Spruz::NULL
5
+ end
data/lib/spruz/xt/p.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'spruz/p'
2
+
3
+ module Spruz
4
+ class ::Object
5
+ include Spruz::P
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ require 'spruz/partial_application'
2
+
3
+ module Spruz
4
+ class ::Proc
5
+ include PartialApplication
6
+ end
7
+
8
+ class ::Method
9
+ include PartialApplication
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ require 'spruz/round'
2
+
3
+ module Spruz
4
+ module Round
5
+ class ::Float
6
+ include Round
7
+ end
8
+
9
+ class ::Integer
10
+ include Round
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ require 'spruz/shuffle'
2
+
3
+ module Spruz
4
+ class ::Array
5
+ if method_defined?(:shuffle)
6
+ warn "#{self}#shuffle already defined, didn't include at #{__FILE__}:#{__LINE__}"
7
+ else
8
+ include Shuffle
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ require 'spruz/subhash'
2
+
3
+ module Spruz
4
+ class ::Hash
5
+ include Spruz::Subhash
6
+
7
+ def subhash!(*patterns)
8
+ replace subhash(*patterns)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ require 'spruz/to_proc'
2
+
3
+ module Spruz
4
+ unless ::Symbol.method_defined?(:to_proc)
5
+ class ::Symbol
6
+ include ToProc
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,7 @@
1
+ require 'spruz/time_dummy'
2
+
3
+ module Spruz
4
+ class ::Time
5
+ include TimeDummy
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ require 'spruz/uniq_by'
2
+
3
+ module Spruz
4
+ module ::Enumerable
5
+ include UniqBy
6
+ end
7
+
8
+ class ::Array
9
+ include UniqBy
10
+
11
+ def uniq_by!(&b)
12
+ replace uniq_by(&b)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,431 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ require 'spruz'
5
+
6
+ module Spruz
7
+ class MinimizeTest < Test::Unit::TestCase
8
+ class ::Array
9
+ include Spruz::Minimize
10
+ end
11
+
12
+ def test_minimize
13
+ assert_equal [], [].minimize
14
+ assert_equal [ 1..1 ], [ 1 ].minimize
15
+ assert_equal [ 1..2 ], [ 1, 2 ].minimize
16
+ assert_equal [ 1..1, 7..7 ], [ 1, 7 ].minimize
17
+ assert_equal [ 1..3, 7..7, 11..14 ],
18
+ [ 1, 2, 3, 7, 11, 12, 13, 14 ].minimize
19
+ assert_equal [ 'A'..'C', 'G'..'G', 'K'..'M' ],
20
+ [ 'A', 'B', 'C', 'G', 'K', 'L', 'M' ].minimize
21
+ end
22
+
23
+ def test_minimize!
24
+ assert_equal [], [].minimize!
25
+ assert_equal [ 1..1 ], [ 1 ].minimize!
26
+ assert_equal [ 1..2 ], [ 1, 2 ].minimize!
27
+ assert_equal [ 1..1, 7..7 ], [ 1, 7 ].minimize!
28
+ assert_equal [ 1..3, 7..7, 11..14 ],
29
+ [ 1, 2, 3, 7, 11, 12, 13, 14 ].minimize!
30
+ assert_equal [ 'A'..'C', 'G'..'G', 'K'..'M' ],
31
+ [ 'A', 'B', 'C', 'G', 'K', 'L', 'M' ].minimize!
32
+ end
33
+
34
+ def test_unminimize
35
+ assert_equal [], [].unminimize
36
+ assert_equal [ 1 ], [ 1..1 ].unminimize
37
+ assert_equal [ 1, 2 ], [ 1..2 ].unminimize
38
+ assert_equal [ 1, 7 ], [ 1..1, 7..7 ].unminimize
39
+ assert_equal [ 1, 2, 3, 7, 11, 12, 13, 14 ],
40
+ [ 1..3, 7..7, 11..14 ].unminimize
41
+ assert_equal [ 'A', 'B', 'C', 'G', 'K', 'L', 'M' ],
42
+ [ 'A'..'C', 'G'..'G', 'K'..'M' ].unminimize
43
+ end
44
+
45
+ def test_unminimize!
46
+ assert_equal [], [].unminimize!
47
+ assert_equal [ 1 ], [ 1..1 ].unminimize!
48
+ assert_equal [ 1, 2 ], [ 1..2 ].unminimize!
49
+ assert_equal [ 1, 7 ], [ 1..1, 7..7 ].unminimize!
50
+ assert_equal [ 1, 2, 3, 7, 11, 12, 13, 14 ],
51
+ [ 1..3, 7..7, 11..14 ].unminimize!
52
+ assert_equal [ 'A', 'B', 'C', 'G', 'K', 'L', 'M' ],
53
+ [ 'A'..'C', 'G'..'G', 'K'..'M' ].unminimize!
54
+ end
55
+ end
56
+
57
+ class PartialApplicationTest < Test::Unit::TestCase
58
+ require 'spruz/xt/partial_application'
59
+
60
+ def mul(x, y) x * y end
61
+
62
+ define_method(:dup) { |y| method(:mul).partial(2)[y] }
63
+
64
+ define_method(:trip) { |y| method(:mul).partial(3)[y] }
65
+
66
+
67
+ def test_proc
68
+ mul = lambda { |x, y| x * y }
69
+ klon = mul.partial
70
+ dup = mul.partial(2)
71
+ trip = mul.partial(3)
72
+ assert_equal [ 6, 9, 12 ], [ dup[3], trip[3], mul[4, 3] ]
73
+ assert_equal [ 6, 9, 12 ], [ dup[3], trip[3], klon[4, 3] ]
74
+ assert_raises(ArgumentError) do
75
+ mul.partial(1, 2, 3)
76
+ end
77
+ end
78
+
79
+ def test_method
80
+ assert_equal [ 6, 9, 12 ], [ dup(3), trip(3), mul(4, 3) ]
81
+ end
82
+ end
83
+
84
+ class GeneratorTest < Test::Unit::TestCase
85
+ def setup
86
+ @numeric = [ 1, 2, 3 ]
87
+ @string = %w[a b c]
88
+ @chars = 'abc'
89
+ end
90
+
91
+ def test_generator
92
+ g = Spruz::Generator[@numeric, @string]
93
+ assert_equal 2, g.size
94
+ g.add_dimension(@chars, :each_byte)
95
+ assert_equal 3, g.size
96
+ assert_equal\
97
+ [[1, "a", 97],
98
+ [1, "a", 98],
99
+ [1, "a", 99],
100
+ [1, "b", 97],
101
+ [1, "b", 98],
102
+ [1, "b", 99],
103
+ [1, "c", 97],
104
+ [1, "c", 98],
105
+ [1, "c", 99],
106
+ [2, "a", 97],
107
+ [2, "a", 98],
108
+ [2, "a", 99],
109
+ [2, "b", 97],
110
+ [2, "b", 98],
111
+ [2, "b", 99],
112
+ [2, "c", 97],
113
+ [2, "c", 98],
114
+ [2, "c", 99],
115
+ [3, "a", 97],
116
+ [3, "a", 98],
117
+ [3, "a", 99],
118
+ [3, "b", 97],
119
+ [3, "b", 98],
120
+ [3, "b", 99],
121
+ [3, "c", 97],
122
+ [3, "c", 98],
123
+ [3, "c", 99]], g.to_a
124
+ end
125
+ end
126
+
127
+ class RoundTest < Test::Unit::TestCase
128
+ require 'spruz/xt/round'
129
+
130
+ def test_standard
131
+ assert_equal(1, 1.round)
132
+ assert_equal(-1, -1.round)
133
+ assert_equal(2, 1.5.round)
134
+ assert_equal(-1, -1.4.round)
135
+ assert_equal(-2, -1.5.round)
136
+ end
137
+
138
+ def test_inclusion
139
+ assert_equal(10, 12.round(-1))
140
+ assert_equal(-10, -12.round(-1))
141
+ assert_raises(ArgumentError) { 12.round(-2) }
142
+ assert_raises(ArgumentError) { -12.round(-2) }
143
+ assert_equal(1.6, 1.55.round(1))
144
+ assert_equal(2, 1.55.round(0))
145
+ assert_equal(-1.5, -1.45.round(1))
146
+ assert_equal(-1, -1.45.round(0))
147
+ assert_equal(-1.6, -1.55.round(1))
148
+ assert_equal(-2, -1.55.round(0))
149
+ end
150
+ end
151
+
152
+ class ModuleGroupTest < Test::Unit::TestCase
153
+ MyClasses = Spruz::ModuleGroup[ Array, String, Hash ]
154
+
155
+ def test_module_group
156
+ assert MyClasses === []
157
+ assert MyClasses === ""
158
+ assert MyClasses === {}
159
+ assert !(MyClasses === :nix)
160
+ case []
161
+ when MyClasses
162
+ assert true
163
+ when Array
164
+ assert false
165
+ end
166
+ case :nix
167
+ when MyClasses
168
+ assert false
169
+ when Array
170
+ assert false
171
+ when Symbol
172
+ assert true
173
+ end
174
+ end
175
+ end
176
+
177
+ class UniqByTest < Test::Unit::TestCase
178
+ require 'spruz/xt/uniq_by'
179
+
180
+ class Point < Struct.new :x, :y
181
+ end
182
+
183
+ def test_uniq_by
184
+ assert_equal [ 1, 2, 3 ], [ 1, 2, 2, 3 ].uniq_by
185
+ assert_equal [ 1, 2, 3 ], [ 1, 2, 2, 3 ].uniq_by!
186
+ p1 = Point.new 1, 2
187
+ p2 = Point.new 2, 2
188
+ p3 = Point.new 2, 2
189
+ p4 = Point.new 3, 3
190
+ a = [ p1, p2, p3, p4 ]
191
+ a_uniq = a.uniq_by { |p| p.y }
192
+ assert_equal 2, a_uniq.size
193
+ assert a_uniq.include?(p4)
194
+ assert [ p1, p2, p3 ].any? { |p| a_uniq.include? p }
195
+ a.uniq_by! { |p| p.y }
196
+ assert_equal 2, a.size
197
+ assert a.include?(p4)
198
+ assert [ p1, p2, p3 ].any? { |p| a.include? p }
199
+ end
200
+ end
201
+
202
+ class CountByTest < Test::Unit::TestCase
203
+ require 'spruz/xt/count_by'
204
+
205
+ def test_count_by
206
+ assert_equal 0, [].count_by { |x| x % 2 == 0 }
207
+ assert_equal 0, [ 1 ].count_by { |x| x % 2 == 0 }
208
+ assert_equal 1, [ 1 ].count_by { |x| x % 2 == 1 }
209
+ assert_equal 1, [ 1, 2 ].count_by { |x| x % 2 == 0 }
210
+ assert_equal 1, [ 1, 2 ].count_by { |x| x % 2 == 1 }
211
+ assert_equal 2, [ 1, 2, 3, 4, 5 ].count_by { |x| x % 2 == 0 }
212
+ assert_equal 3, [ 1, 2, 3, 4, 5 ].count_by { |x| x % 2 == 1 }
213
+ end
214
+ end
215
+
216
+ if Spruz::Shuffle === Array
217
+ class ShuffleTest < Test::Unit::TestCase
218
+ require 'spruz/xt/shuffle'
219
+
220
+ def setup
221
+ @a = [ 1, 2, 3 ]
222
+ srand 666
223
+ end
224
+
225
+ def test_shuffle
226
+ assert_equal(a = [2, 3, 1], a = @a.shuffle)
227
+ assert_not_same @a, a
228
+ assert_equal(b = [3, 1, 2], b = @a.shuffle)
229
+ assert_not_same a, b
230
+ assert_not_same @a, b
231
+ end
232
+
233
+ def test_shuffle_bang
234
+ assert_equal([2, 3, 1], a = @a.shuffle!)
235
+ assert_same @a, a
236
+ assert_equal([1, 2, 3], b = @a.shuffle!)
237
+ assert_same a, b
238
+ assert_same @a, b
239
+ end
240
+ end
241
+ end
242
+
243
+ class LimitedTest < Test::Unit::TestCase
244
+ class ::Array
245
+ include Spruz::Shuffle
246
+ end
247
+
248
+ def test_limited
249
+ count = {}
250
+ limited = Spruz::Limited.new(5)
251
+ 5.times do
252
+ limited.execute do
253
+ count[Thread.current] = true
254
+ sleep
255
+ end
256
+ end
257
+ until count.size >= 5
258
+ sleep 0.1
259
+ end
260
+ assert_equal 5, count.keys.uniq.size
261
+ end
262
+ end
263
+
264
+ class MemoizeTest < Test::Unit::TestCase
265
+ class A
266
+ def initialize(var)
267
+ @var = var
268
+ end
269
+
270
+ def foo(n)
271
+ r = n * @var
272
+ @var += 1
273
+ r
274
+ end
275
+ memoize_method :foo
276
+
277
+ def bar(n)
278
+ r = n * @var
279
+ @var += 1
280
+ r
281
+ end
282
+ memoize_function :bar
283
+ end
284
+
285
+ def setup
286
+ @a23 = A.new(23)
287
+ @a42 = A.new(42)
288
+ end
289
+
290
+ def test_memoize_method
291
+ assert Module.__memoize_cache__.empty?
292
+ assert_equal 2 * 23, @a23.foo(2)
293
+ assert_equal 2 * 23, @a23.foo(2)
294
+ assert_equal 3 * 24, @a23.foo(3)
295
+ assert_equal 2 * 42, @a42.foo(2)
296
+ assert_equal 2 * 42, @a42.foo(2)
297
+ assert_equal 3 * 43, @a42.foo(3)
298
+ assert !Module.__memoize_cache__.empty?
299
+ @a23, @a42 = nil, nil
300
+ GC.start
301
+ # XXX test fails atm, assert Module.__memoize_cache__.empty?
302
+ end
303
+
304
+ def test_memoize_function
305
+ assert A.__memoize_cache__.empty?
306
+ assert_equal 2 * 23, @a23.bar(2)
307
+ assert_equal 2 * 23, @a23.bar(2)
308
+ assert_equal 3 * 24, @a23.bar(3)
309
+ assert_equal 2 * 23, @a42.bar(2)
310
+ assert_equal 2 * 23, @a42.bar(2)
311
+ assert_equal 3 * 24, @a42.bar(3)
312
+ assert !A.__memoize_cache__.empty?
313
+ end
314
+ end
315
+
316
+ class HashUnionTest < Test::Unit::TestCase
317
+ require 'spruz/xt/hash_union'
318
+
319
+ def test_union
320
+ defaults = { 'foo' => true, 'bar' => false, 'quux' => nil }
321
+ hash = { 'foo' => false }
322
+ assert_equal [ ['bar', false], ['foo', false], ['quux', nil] ],
323
+ (hash | defaults).sort
324
+ hash |= defaults
325
+ assert_equal [ ['bar', false], ['foo', false], ['quux', nil] ],
326
+ hash.sort
327
+ hash = { 'foo' => false }
328
+ hash |= {
329
+ 'quux' => true,
330
+ 'baz' => 23,
331
+ } | defaults
332
+ assert_equal [ ['bar', false], [ 'baz', 23 ], ['foo', false],
333
+ ['quux', true] ],
334
+ hash.sort
335
+ end
336
+ end
337
+
338
+ class SubhashTest < Test::Unit::TestCase
339
+ require 'spruz/xt/subhash'
340
+
341
+ def test_subhash
342
+ h = { 'foo1' => 1, 'foo2' => 2, 'bar666' => 666 }
343
+ assert_equal [ [ 'bar666', 666 ] ], h.subhash(/\Abar/).to_a
344
+ assert h.subhash(/\Abaz/).empty?
345
+ assert_equal [ [ 'foo1', 1 ], [ 'foo2', 2 ] ], h.subhash(/\Afoo\d/).to_a
346
+ assert_equal [ [ 'foo2', 2 ] ], h.subhash('foo2').to_a
347
+ end
348
+
349
+ def test_subhash_bang
350
+ h = { 'foo1' => 1, 'foo2' => 2, 'bar666' => 666 }
351
+ h.subhash!('foo2')
352
+ assert_equal [ [ 'foo2', 2 ] ], h.to_a
353
+ end
354
+
355
+ def test_subhash_with_block
356
+ h = { 'foo1' => 1, 'foo2' => 2, 'bar666' => 666 }
357
+ assert h.subhash(/\Abaz/) { :foo }.empty?
358
+ assert_equal [ [ 'foo1', 1 ], [ 'foo2', 2 ] ],
359
+ h.subhash(/\Afoo(\d)/) { |_,_,m| Integer(m[1]) }.to_a
360
+ end
361
+ end
362
+
363
+ class NullTest < Test::Unit::TestCase
364
+ require 'spruz/xt/null'
365
+
366
+ def test_null
367
+ assert_equal NULL, NULL.foo
368
+ assert_equal NULL, NULL.foo.bar
369
+ assert_equal 'NULL', NULL.inspect
370
+ assert_equal '', NULL.to_s
371
+ end
372
+ end
373
+
374
+ class TimeDummyTest < Test::Unit::TestCase
375
+ require 'spruz/xt/time_dummy'
376
+ require 'time'
377
+
378
+ def test_time_dummy
379
+ time = Time.parse('2009-09-09 21:09:09')
380
+ assert_not_equal time, Time.now
381
+ Time.dummy = time
382
+ assert_equal time, Time.now
383
+ Time.dummy = nil
384
+ assert_not_equal time, Time.now
385
+ end
386
+ end
387
+
388
+ class BlankFullTest < Test::Unit::TestCase
389
+ require 'spruz/xt/full'
390
+ require 'spruz/xt/symbol_to_proc'
391
+ require 'set'
392
+
393
+ def test_blank
394
+ assert !true.blank?
395
+ assert false.blank?
396
+ assert nil.blank?
397
+ assert [].blank?
398
+ assert ![23].blank?
399
+ assert Set[].blank?
400
+ assert !Set[23].blank?
401
+ assert({}.blank?)
402
+ assert !{ :foo => 23 }.blank?
403
+ assert "".blank?
404
+ assert " ".blank?
405
+ assert !"foo".blank?
406
+ end
407
+
408
+ def test_full
409
+ assert_equal true, true.full?
410
+ assert_nil false.full?
411
+ assert_nil nil.full?
412
+ assert_nil [].full?
413
+ assert_equal [ 23 ], [ 23 ].full?
414
+ assert_nil Set[].full?
415
+ assert_equal Set[23], Set[23].full?
416
+ assert_nil({}.full?)
417
+ assert_equal({ :foo => 23 }, { :foo => 23 }.full?)
418
+ assert_nil "".full?
419
+ assert_nil " ".full?
420
+ assert_equal "foo", "foo".full?
421
+ assert_nil " ".full?(&:size)
422
+ assert_equal 3, "foo".full?(&:size)
423
+ assert_nil " ".full?(&:size)
424
+ assert_equal 3, "foo".full?(&:size)
425
+ assert_nil " ".full?(:size)
426
+ assert_equal 3, "foo".full?(:size)
427
+ assert_nil " ".full?(:size)
428
+ assert_equal 3, "foo".full?(:size)
429
+ end
430
+ end
431
+ end