utilrb 0.2

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.
Files changed (65) hide show
  1. data/Changes.txt +20 -0
  2. data/License.txt +26 -0
  3. data/Manifest.txt +64 -0
  4. data/README.txt +44 -0
  5. data/Rakefile +46 -0
  6. data/bm/allocation.rb +7 -0
  7. data/bm/speed.rb +19 -0
  8. data/ext/extconf.rb +5 -0
  9. data/ext/faster.cc +48 -0
  10. data/ext/swap.cc +61 -0
  11. data/ext/value_set.cc +290 -0
  12. data/lib/utilrb.rb +2 -0
  13. data/lib/utilrb/array.rb +2 -0
  14. data/lib/utilrb/array/to_s.rb +16 -0
  15. data/lib/utilrb/common.rb +50 -0
  16. data/lib/utilrb/enumerable.rb +2 -0
  17. data/lib/utilrb/enumerable/null.rb +18 -0
  18. data/lib/utilrb/enumerable/random_element.rb +16 -0
  19. data/lib/utilrb/enumerable/sequence.rb +24 -0
  20. data/lib/utilrb/enumerable/uniq.rb +61 -0
  21. data/lib/utilrb/exception.rb +2 -0
  22. data/lib/utilrb/exception/full_message.rb +8 -0
  23. data/lib/utilrb/gc.rb +2 -0
  24. data/lib/utilrb/gc/force.rb +11 -0
  25. data/lib/utilrb/hash.rb +2 -0
  26. data/lib/utilrb/hash/slice.rb +6 -0
  27. data/lib/utilrb/hash/to_s.rb +6 -0
  28. data/lib/utilrb/hash/to_sym_keys.rb +6 -0
  29. data/lib/utilrb/kernel.rb +2 -0
  30. data/lib/utilrb/kernel/arity.rb +10 -0
  31. data/lib/utilrb/kernel/options.rb +69 -0
  32. data/lib/utilrb/kernel/poll.rb +24 -0
  33. data/lib/utilrb/kernel/require.rb +12 -0
  34. data/lib/utilrb/kernel/swap.rb +2 -0
  35. data/lib/utilrb/logger.rb +3 -0
  36. data/lib/utilrb/logger/forward.rb +15 -0
  37. data/lib/utilrb/logger/hierarchy.rb +34 -0
  38. data/lib/utilrb/module.rb +2 -0
  39. data/lib/utilrb/module/ancestor_p.rb +6 -0
  40. data/lib/utilrb/module/attr_enumerable.rb +28 -0
  41. data/lib/utilrb/module/define_method.rb +30 -0
  42. data/lib/utilrb/module/include.rb +30 -0
  43. data/lib/utilrb/module/inherited_enumerable.rb +122 -0
  44. data/lib/utilrb/object.rb +2 -0
  45. data/lib/utilrb/object/address.rb +14 -0
  46. data/lib/utilrb/object/attribute.rb +89 -0
  47. data/lib/utilrb/object/singleton_class.rb +53 -0
  48. data/lib/utilrb/objectstats.rb +52 -0
  49. data/lib/utilrb/time.rb +2 -0
  50. data/lib/utilrb/time/to_hms.rb +6 -0
  51. data/lib/utilrb/unbound_method.rb +2 -0
  52. data/lib/utilrb/unbound_method/call.rb +5 -0
  53. data/lib/utilrb/value_set.rb +17 -0
  54. data/test/test_array.rb +9 -0
  55. data/test/test_config.rb +4 -0
  56. data/test/test_enumerable.rb +89 -0
  57. data/test/test_gc.rb +39 -0
  58. data/test/test_hash.rb +22 -0
  59. data/test/test_kernel.rb +70 -0
  60. data/test/test_misc.rb +42 -0
  61. data/test/test_module.rb +127 -0
  62. data/test/test_object.rb +65 -0
  63. data/test/test_objectstats.rb +19 -0
  64. data/test/test_unbound_method.rb +23 -0
  65. metadata +128 -0
@@ -0,0 +1,6 @@
1
+ class Time
2
+ def to_hms
3
+ sec, usec = tv_sec, tv_usec
4
+ "%i:%02i:%02i.%03i" % [sec / 3600, (sec % 3600) / 60, sec % 60, usec / 1000]
5
+ end
6
+ end
@@ -0,0 +1,2 @@
1
+ require 'utilrb/kernel/require'
2
+ require_dir(__FILE__)
@@ -0,0 +1,5 @@
1
+ class UnboundMethod
2
+ def call(obj, *args, &block)
3
+ bind(obj).call(*args, &block)
4
+ end
5
+ end
@@ -0,0 +1,17 @@
1
+ require 'utilrb/common'
2
+
3
+ Utilrb.require_faster("ValueSet") do
4
+ class ValueSet
5
+ def <<(obj); insert(obj) ; self end
6
+ alias :| :union
7
+ alias :& :intersection
8
+ alias :- :difference
9
+ include Enumerable
10
+
11
+ def to_s
12
+ base = super[0..-2]
13
+ "#{base} { #{to_a.map { |o| o.to_s }.join(", ")} }"
14
+ end
15
+ alias :inspect :to_s
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ require 'test_config'
2
+ require 'utilrb/array'
3
+
4
+ class TC_Array < Test::Unit::TestCase
5
+ def test_to_s
6
+ assert_equal("1, 2", [1, 2].to_s)
7
+ end
8
+ end
9
+
@@ -0,0 +1,4 @@
1
+ require 'test/unit'
2
+ $LOAD_PATH.unshift File.expand_path('../lib', File.dirname(__FILE__))
3
+ BASE_TEST_DIR=File.expand_path(File.dirname(__FILE__)) unless defined? BASE_TEST_DIR
4
+
@@ -0,0 +1,89 @@
1
+ require 'test_config'
2
+
3
+ require 'utilrb/enumerable'
4
+ require 'utilrb/value_set'
5
+
6
+ class TC_Enumerable < Test::Unit::TestCase
7
+
8
+ def test_enum_uniq
9
+ # Test the enum_uniq enumerator
10
+ assert_equal([:a, :b, :c], [:a, :b, :a, :c].enum_uniq { |k| k }.to_a)
11
+ assert_equal([:a, :b, :c], [:a, :b, :a, :c].enum_uniq.to_a)
12
+ enum = [:a, :b, :a, :c].enum_uniq
13
+ assert_equal(enum, enum.each)
14
+
15
+ a, b, c, d = [1, 2], [1, 3], [2, 3], [3, 4]
16
+
17
+ test = [a, b, c, d]
18
+ assert_equal([a, c, d], test.enum_uniq { |x, y| x }.to_a)
19
+ assert_equal([a, b, d], test.enum_uniq { |x, y| y }.to_a)
20
+
21
+ klass = Class.new do
22
+ def initialize(base); @base = base end
23
+ def each(&iterator); @base.each { |x, y| yield [x, y] } end
24
+ include Enumerable
25
+ end
26
+ test = klass.new(test)
27
+ assert_equal([a, c, d], test.enum_uniq { |x, y| x }.to_a)
28
+ assert_equal([a, b, d], test.enum_uniq { |x, y| y }.to_a)
29
+
30
+ klass = Struct.new :x, :y
31
+ test = test.map { |x, y| klass.new(x, y) }
32
+ a, b, c, d = *test
33
+ assert_equal([a, c, d], [a, b, c, d].enum_uniq { |v| v.x }.to_a)
34
+ assert_equal([a, b, d], [a, b, c, d].enum_uniq { |v| v.y }.to_a)
35
+ end
36
+
37
+ def test_each_uniq
38
+ assert_equal([:a, :b, :c], [:a, :b, :a, :c].enum_for(:each_uniq).to_a)
39
+ end
40
+
41
+ def test_enum_sequence
42
+ c1 = [:a, :b, :c]
43
+ c2 = [:d, :e, :f]
44
+ assert_equal([:a, :b, :c, :d, :e, :f], (c1.to_enum + c2.to_enum).to_a)
45
+ assert_equal([:a, :b, :c, :d, :e, :f], [c1, c2].inject(null_enum) { |a, b| a + b }.to_a)
46
+ end
47
+
48
+ def test_random_element
49
+ # Test on arrays
50
+ set = (1..100).to_a
51
+ 100.times { set.delete(set.random_element) }
52
+ assert(set.empty?)
53
+ assert_equal(nil, [].random_element)
54
+
55
+ # Test on non-empty collection which defines #size
56
+ set = Hash[*(1..100).map { |i| [(?a + i).to_s, i] }.flatten]
57
+ 100.times { set.delete(set.random_element.first) }
58
+ assert(set.empty?)
59
+ assert_equal(nil, {}.random_element)
60
+ end
61
+
62
+ Utilrb.require_faster('test_value_set') do
63
+ def test_value_set
64
+ a = [1, 3, 3, 4, 6, 8].to_value_set
65
+ b = [1, 2, 4, 3, 11, 11].to_value_set
66
+ assert_equal(5, a.size)
67
+ assert_equal([1, 3, 4, 6, 8], a.to_a)
68
+ assert(a.include?(1))
69
+ assert(a.include_all?([4, 1, 8]))
70
+ assert(!a.include_all?(b))
71
+
72
+ assert(a.object_id == a.to_value_set.object_id)
73
+
74
+ assert_equal([1, 2, 3, 4, 6, 8, 11], (a.union(b)).to_a)
75
+ assert_equal([1, 3, 4], (a.intersection(b)).to_a)
76
+ assert_equal([6, 8], (a.difference(b)).to_a)
77
+
78
+ a.delete(1)
79
+ assert(! a.include?(1))
80
+ a.merge(b);
81
+ assert_equal([1, 2, 3, 4, 6, 8, 11].to_value_set, a)
82
+
83
+ assert([].to_value_set.empty?)
84
+
85
+ assert([1, 2, 4, 3].to_value_set.clear.empty?)
86
+ end
87
+ end
88
+ end
89
+
@@ -0,0 +1,39 @@
1
+ require 'test_config'
2
+
3
+ require 'utilrb/gc'
4
+ require 'enumerator'
5
+
6
+ class TC_GC < Test::Unit::TestCase
7
+ def allocate(&block)
8
+ ObjectSpace.define_finalizer(Object.new, &block)
9
+ nil
10
+ end
11
+
12
+ def allocate(&block)
13
+ # Allocate twice since it seems the last object stays on stack
14
+ # (and is not GC'ed)
15
+ 2.times { ObjectSpace.define_finalizer(Object.new, &block) }
16
+ nil
17
+ end
18
+
19
+ def test_force
20
+ finalized = false
21
+ allocate { finalized = true }
22
+ GC.start
23
+ assert( finalized )
24
+
25
+ GC.disable
26
+ finalized = false
27
+ allocate { finalized = true }
28
+ GC.start
29
+ assert( !finalized )
30
+ GC.force
31
+ assert( finalized )
32
+ assert( GC.disable )
33
+
34
+ GC.enable
35
+ GC.force
36
+ assert( !GC.enable )
37
+ end
38
+ end
39
+
@@ -0,0 +1,22 @@
1
+ require 'test_config'
2
+ require 'enumerator'
3
+ require 'set'
4
+
5
+ require 'utilrb/hash'
6
+
7
+ class TC_Hash < Test::Unit::TestCase
8
+ def test_slice
9
+ test = { :a => 1, :b => 2, :c => 3 }
10
+ assert_equal({:a => 1, :c => 3}, test.slice(:a, :c))
11
+ assert_equal({:a => 1, :c => 3}, test.slice(:a, :c, :d))
12
+ end
13
+
14
+ def test_to_sym_keys
15
+ assert_equal({ :a => 10, :b => 20, :c => 30 }, { 'a' => 10, 'b' => 20, :c => 30 }.to_sym_keys)
16
+ end
17
+
18
+ def test_to_s
19
+ assert_equal("1 => 2, 2 => 3", { 1 => 2, 2 => 3 }.to_s)
20
+ end
21
+ end
22
+
@@ -0,0 +1,70 @@
1
+ require 'test_config'
2
+
3
+ require 'utilrb/kernel/options'
4
+ require 'utilrb/kernel/arity'
5
+ require 'utilrb/kernel/swap'
6
+
7
+ class TC_Kernel < Test::Unit::TestCase
8
+ def test_validate_options
9
+ valid_options = [ :a, :b, :c ]
10
+ valid_test = { :a => 1, :c => 2 }
11
+ invalid_test = { :k => nil }
12
+ assert_nothing_raised(ArgumentError) { validate_options(valid_test, valid_options) }
13
+ assert_raise(ArgumentError) { validate_options(invalid_test, valid_options) }
14
+
15
+ check_array = validate_options( valid_test, valid_options )
16
+ assert_equal( valid_test, check_array )
17
+ check_empty_array = validate_options( nil, valid_options )
18
+ assert_equal( {}, check_empty_array )
19
+
20
+ # Check default value settings
21
+ default_values = { :a => nil, :b => nil, :c => nil, :d => 15, :e => [] }
22
+ new_options = nil
23
+ assert_nothing_raised(ArgumentError) { new_options = validate_options(valid_test, default_values) }
24
+ assert_equal(15, new_options[:d])
25
+ assert_equal([], new_options[:e])
26
+ assert( !new_options.has_key?(:b) )
27
+ end
28
+
29
+ def test_arity
30
+ object = Class.new do
31
+ def arity_1(a); end
32
+ def arity_any(*a); end
33
+ def arity_1_more(a, *b); end
34
+ end.new
35
+
36
+ assert_nothing_raised { check_arity(object.method(:arity_1), 1) }
37
+ assert_raises(ArgumentError) { check_arity(object.method(:arity_1), 0) }
38
+ assert_raises(ArgumentError) { check_arity(object.method(:arity_1), 2) }
39
+
40
+ assert_nothing_raised { check_arity(object.method(:arity_any), 0) }
41
+ assert_nothing_raised { check_arity(object.method(:arity_any), 2) }
42
+
43
+ assert_nothing_raised { check_arity(object.method(:arity_1_more), 1) }
44
+ assert_raises(ArgumentError) { check_arity(object.method(:arity_1_more), 0) }
45
+ assert_nothing_raised { check_arity(object.method(:arity_1_more), 2) }
46
+ end
47
+
48
+ Utilrb.require_faster('is_singleton?') do
49
+ def test_is_singleton
50
+ klass = Class.new
51
+ singl_klass = (class << klass; self end)
52
+ obj = klass.new
53
+
54
+ assert(!klass.is_singleton?)
55
+ assert(!obj.is_singleton?)
56
+ assert(singl_klass.is_singleton?)
57
+ end
58
+ end
59
+
60
+ Utilrb.require_faster('test_swap') do
61
+ def test_swap
62
+ obj = Array.new
63
+ Kernel.swap!(obj, Hash.new)
64
+ assert_instance_of Hash, obj
65
+
66
+ GC.start
67
+ end
68
+ end
69
+ end
70
+
@@ -0,0 +1,42 @@
1
+ require 'test_config'
2
+
3
+ class TC_Misc < Test::Unit::TestCase
4
+ def test_super_idiom
5
+ base = Class.new do
6
+ attr_reader :base
7
+ def initialize
8
+ super if defined? super
9
+ @base = true
10
+ end
11
+ end
12
+ assert_nothing_raised { base.new }
13
+
14
+ derived = Class.new(base) do
15
+ attr_reader :derived
16
+ def initialize
17
+ super if defined? super
18
+ @derived = true
19
+ end
20
+ end
21
+ obj = nil
22
+ assert_nothing_raised { obj = derived.new }
23
+ assert( obj.base )
24
+ assert( obj.derived )
25
+
26
+ mod = Module.new do
27
+ attr_reader :module
28
+ def initialize
29
+ super if defined? super
30
+ @module = true
31
+ end
32
+ end
33
+ obj = nil
34
+ base.class_eval { include mod }
35
+
36
+ assert_nothing_raised { obj = derived.new }
37
+ assert( obj.base )
38
+ assert( obj.module )
39
+ assert( obj.derived )
40
+ end
41
+ end
42
+
@@ -0,0 +1,127 @@
1
+ require 'test_config'
2
+
3
+ require 'flexmock'
4
+ require 'set'
5
+ require 'enumerator'
6
+ require 'utilrb/module'
7
+
8
+ class TC_Module < Test::Unit::TestCase
9
+ def test_include
10
+ class_extension = Module.new do
11
+ def tag; end
12
+ end
13
+
14
+ m = Module.new do
15
+ const_set(:ClassExtension, class_extension)
16
+ end
17
+
18
+ m2 = Module.new { include m }
19
+ assert(m2::ClassExtension.method_defined?(:tag))
20
+ k = Class.new do
21
+ include m2
22
+ end
23
+ assert(k.respond_to?(:tag))
24
+ end
25
+
26
+ def test_define_method_with_block
27
+ FlexMock.use do |mock|
28
+ mock.should_receive(:called).once
29
+ block_obj = lambda { mock.called }
30
+ test_obj = self
31
+ method = lambda do |block, a, b|
32
+ test_obj.assert_equal(a, 1)
33
+ test_obj.assert_equal(b, 2)
34
+ test_obj.assert_equal(block, block_obj)
35
+ block_obj.call
36
+ end
37
+
38
+ klass = Class.new do
39
+ define_method_with_block(:call, &method)
40
+ end
41
+ klass.new.call(1, 2, &block_obj)
42
+ end
43
+ end
44
+
45
+ def test_attr_enumerable
46
+ klass = Class.new do
47
+ attr_enumerable(:mapped, :map) { Hash.new }
48
+ end
49
+
50
+ obj = klass.new
51
+ obj.map[:a] = [10, 20]
52
+ obj.map[:b] = 10
53
+ assert_equal( [[:a, [10, 20]], [:b, 10]].to_set, obj.enum_for(:each_mapped).to_set )
54
+ assert_equal( [10, 20], obj.enum_for(:each_mapped, :a).to_a )
55
+ end
56
+
57
+ def test_inherited_enumerable_module
58
+ m = Module.new do
59
+ inherited_enumerable(:signature, :signatures) { Array.new }
60
+ end
61
+ k = Class.new do
62
+ include m
63
+ inherited_enumerable(:child_attribute) { Array.new }
64
+ end
65
+
66
+ # Add another attribute *after* k has been defined
67
+ m.class_eval do
68
+ inherited_enumerable(:mapped, :map, :map => true) { Hash.new }
69
+ end
70
+ check_inherited_enumerable(m, k)
71
+ end
72
+
73
+ def test_inherited_enumerable_class
74
+ a = Class.new do
75
+ inherited_enumerable(:signature, :signatures) { Array.new }
76
+ inherited_enumerable(:mapped, :map, :map => true) { Hash.new }
77
+ end
78
+ b = Class.new(a) do
79
+ include Module.new # include an empty module between a and b to check that the module
80
+ # is skipped transparently
81
+ inherited_enumerable(:child_attribute) { Array.new }
82
+ end
83
+ check_inherited_enumerable(a, b)
84
+
85
+ # Test for singleton class support
86
+ object = b.new
87
+ assert(object.singleton_class.respond_to?(:signatures))
88
+ object.singleton_class.signatures << :in_singleton
89
+ assert_equal([:in_singleton], object.singleton_class.signatures)
90
+ assert_equal([:in_singleton, :in_derived, :in_base], object.singleton_class.enum_for(:each_signature).to_a)
91
+ end
92
+
93
+ def check_inherited_enumerable(base, derived)
94
+ assert(base.respond_to?(:each_signature))
95
+ assert(base.respond_to?(:signatures))
96
+ assert(!base.respond_to?(:has_signature?))
97
+ assert(!base.respond_to?(:find_signatures))
98
+
99
+ assert(base.respond_to?(:each_mapped))
100
+ assert(base.respond_to?(:map))
101
+ assert(base.respond_to?(:has_mapped?))
102
+
103
+ base.signatures << :in_base
104
+ base.map[:base] = 10
105
+ base.map[:overriden] = 20
106
+ assert_equal([:in_base], base.enum_for(:each_signature).to_a)
107
+ assert_equal([10].to_set, base.enum_for(:each_mapped, :base, false).to_set)
108
+
109
+ assert(!base.respond_to?(:child_attribute))
110
+ assert(!base.respond_to?(:each_child_attribute))
111
+ assert(derived.respond_to?(:child_attribute))
112
+ assert(derived.respond_to?(:each_child_attribute))
113
+
114
+ derived.signatures << :in_derived
115
+
116
+ derived.map[:overriden] = 15
117
+ derived.map[:derived] = 25
118
+
119
+ assert_equal([:in_derived, :in_base], derived.enum_for(:each_signature).to_a)
120
+ assert_equal([20, 15].to_set, derived.enum_for(:each_mapped, :overriden, false).to_set)
121
+ assert_equal([15].to_set, derived.enum_for(:each_mapped, :overriden, true).to_set)
122
+ assert_equal([25].to_set, derived.enum_for(:each_mapped, :derived).to_set)
123
+ assert_equal([[:base, 10], [:overriden, 20], [:overriden, 15], [:derived, 25]].to_set, derived.enum_for(:each_mapped, nil, false).to_set)
124
+ assert_equal([[:base, 10], [:overriden, 15], [:derived, 25]].to_set, derived.enum_for(:each_mapped, nil, true).to_set)
125
+ end
126
+ end
127
+