utilrb 0.2

Sign up to get free protection for your applications and to get access to all the features.
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
+