spruz 0.1.0

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/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