ruby_ext 0.4.6

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 (49) hide show
  1. data/Rakefile +64 -0
  2. data/lib/ruby_ext/array.rb +13 -0
  3. data/lib/ruby_ext/basic_object.rb +22 -0
  4. data/lib/ruby_ext/class.rb +11 -0
  5. data/lib/ruby_ext/declarative_cache.rb +85 -0
  6. data/lib/ruby_ext/deep_clone.rb +62 -0
  7. data/lib/ruby_ext/extra_blank_slate.rb +16 -0
  8. data/lib/ruby_ext/file.rb +20 -0
  9. data/lib/ruby_ext/hash.rb +15 -0
  10. data/lib/ruby_ext/kernel.rb +69 -0
  11. data/lib/ruby_ext/micelaneous.rb +14 -0
  12. data/lib/ruby_ext/module.rb +119 -0
  13. data/lib/ruby_ext/multiple_inheritance.rb +76 -0
  14. data/lib/ruby_ext/must.rb +192 -0
  15. data/lib/ruby_ext/not_defined.rb +2 -0
  16. data/lib/ruby_ext/object.rb +8 -0
  17. data/lib/ruby_ext/observable2.rb +23 -0
  18. data/lib/ruby_ext/open_constructor.rb +51 -0
  19. data/lib/ruby_ext/open_object.rb +157 -0
  20. data/lib/ruby_ext/prepare_arguments.rb +105 -0
  21. data/lib/ruby_ext/prototype_inheritance.rb +110 -0
  22. data/lib/ruby_ext/should.rb +166 -0
  23. data/lib/ruby_ext/string.rb +44 -0
  24. data/lib/ruby_ext/symbol.rb +21 -0
  25. data/lib/ruby_ext/synchronize.rb +24 -0
  26. data/lib/ruby_ext/tuple.rb +7 -0
  27. data/lib/ruby_ext.rb +50 -0
  28. data/lib/spec_ext.rb +10 -0
  29. data/readme.md +66 -0
  30. data/spec/_prototype_inheritance_spec.rb +190 -0
  31. data/spec/array_spec.rb +8 -0
  32. data/spec/declarative_cache_spec.rb +115 -0
  33. data/spec/deep_clone_spec.rb +37 -0
  34. data/spec/helper.rb +20 -0
  35. data/spec/kernel_spec/TheNamespace/ClassA.rb +7 -0
  36. data/spec/kernel_spec/another_class.rb +5 -0
  37. data/spec/kernel_spec/the_namespace/class_b.rb +11 -0
  38. data/spec/kernel_spec.rb +53 -0
  39. data/spec/module_spec.rb +160 -0
  40. data/spec/multiple_inheritance_spec.rb +131 -0
  41. data/spec/must_spec.rb +29 -0
  42. data/spec/observable2_spec.rb +42 -0
  43. data/spec/open_constructor_spec.rb +36 -0
  44. data/spec/open_object_spec.rb +29 -0
  45. data/spec/prepare_arguments_spec.rb +46 -0
  46. data/spec/should_spec.rb +24 -0
  47. data/spec/spec.opts +2 -0
  48. data/spec/synchronize_spec.rb +80 -0
  49. metadata +127 -0
@@ -0,0 +1,37 @@
1
+ require "#{File.dirname __FILE__}/helper"
2
+ require "ruby_ext/deep_clone"
3
+
4
+ describe 'deep_clone' do
5
+ it "basic" do
6
+ hash, array = {}, ['value']
7
+ hash['key'] = array
8
+
9
+ hash2 = hash.deep_clone
10
+ array2 = hash2['key']
11
+
12
+ hash2.should == hash
13
+ hash2.object_id.should_not == hash.object_id
14
+
15
+ array2.should == array
16
+ array2.object_id.should_not == array.object_id
17
+ end
18
+
19
+ it do
20
+ class Metadata
21
+ attr_accessor :registry
22
+
23
+ def initialize
24
+ @registry = {}
25
+ end
26
+ end
27
+
28
+ m = Metadata.new
29
+ m.registry[:a] = 1
30
+
31
+ m2 = m.deep_clone
32
+ m2.registry.should include(:a)
33
+ m2.registry[:b] = 2
34
+
35
+ m.registry.should == {:a => 1}
36
+ end
37
+ end
data/spec/helper.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'spec'
2
+ require 'spec_ext'
3
+
4
+ ruby_ext_dir = File.expand_path("#{File.dirname(__FILE__)}/../..")
5
+ $LOAD_PATH << "#{ruby_ext_dir}/lib"
6
+
7
+ %w{
8
+ file
9
+ kernel
10
+ open_object
11
+ module
12
+ not_defined
13
+ object
14
+ class
15
+ string
16
+ symbol
17
+ extra_blank_slate
18
+ must
19
+ deep_clone
20
+ }.each{|f| require "ruby_ext/#{f}"}
@@ -0,0 +1,7 @@
1
+ module TheNamespace
2
+ class ClassA
3
+ def self.problem_method
4
+ raise_without_self "Some problem"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ class AnotherClass
2
+ def self.exclude_multiple_classes
3
+ TheNamespace::ClassB.exclude_multiple_classes
4
+ end
5
+ end
@@ -0,0 +1,11 @@
1
+ module TheNamespace
2
+ class ClassB
3
+ def self.problem_method
4
+ raise_without_self "Some problem"
5
+ end
6
+
7
+ def self.exclude_multiple_classes
8
+ raise_without_self "Some problem", AnotherClass
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,53 @@
1
+ require "#{File.dirname __FILE__}/helper"
2
+ require "ruby_ext/kernel"
3
+
4
+ describe 'Kernel' do
5
+ class Respond
6
+ def test; 2 end
7
+ end
8
+
9
+ after :all do
10
+ [:TheNamespace, :AnotherClass].each{|c| Object.send :remove_const, c if Object.const_defined? c}
11
+ end
12
+
13
+ it "respond_to" do
14
+ r = Respond.new
15
+ r.respond_to(:not_exist).should be_nil
16
+ r.respond_to(:test).should == 2
17
+ end
18
+
19
+ it "raise_without_self" do
20
+ dir = File.dirname __FILE__
21
+ require "#{dir}/kernel_spec/TheNamespace/ClassA"
22
+ require "#{dir}/kernel_spec/the_namespace/class_b"
23
+ require "#{dir}/kernel_spec/another_class"
24
+
25
+ begin
26
+ TheNamespace::ClassA.problem_method
27
+ rescue StandardError => e
28
+ e.message.should =~ /Some problem/
29
+ stack = e.backtrace
30
+ stack.any?{|line| line =~ /ClassA/}.should be_false
31
+ stack.any?{|line| line =~ /kernel_spec/}.should be_true
32
+ end
33
+
34
+ begin
35
+ TheNamespace::ClassB.problem_method
36
+ rescue StandardError => e
37
+ e.message.should =~ /Some problem/
38
+ stack = e.backtrace
39
+ stack.any?{|line| line =~ /class_b/}.should be_false
40
+ stack.any?{|line| line =~ /kernel_spec/}.should be_true
41
+ end
42
+
43
+ begin
44
+ AnotherClass.exclude_multiple_classes
45
+ rescue StandardError => e
46
+ e.message.should =~ /Some problem/
47
+ stack = e.backtrace
48
+ stack.any?{|line| line =~ /class_b/}.should be_false
49
+ stack.any?{|line| line =~ /another_class/}.should be_false
50
+ stack.any?{|line| line =~ /kernel_spec/}.should be_true
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,160 @@
1
+ require "#{File.dirname __FILE__}/helper"
2
+ require "ruby_ext/module"
3
+ require 'ruby_ext/multiple_inheritance'
4
+
5
+ describe "Module" do
6
+ after :each do
7
+ remove_constants %w(
8
+ A X Y Z
9
+ InheritableAccessorForModule
10
+ InheritableAccessorForClass
11
+ InheritableAccessor
12
+ InheritableAccessorBase
13
+ InheritableAccessorA
14
+ InheritableAccessorB
15
+ )
16
+ end
17
+
18
+ it "Namespace" do
19
+ class A
20
+ class B
21
+ class C
22
+
23
+ end
24
+ end
25
+ end
26
+
27
+ File.namespace.should == nil
28
+ A::B::C.namespace.should == A::B
29
+ end
30
+
31
+ # class AnonymousClass
32
+ # class << self
33
+ # def anonymous_name
34
+ # self.name
35
+ # end
36
+ # end
37
+ # end
38
+
39
+ it "name" do
40
+ class A
41
+ class B
42
+ class C
43
+
44
+ end
45
+ end
46
+ end
47
+
48
+ A::B::C.name.should == "A::B::C"
49
+ end
50
+
51
+ it "each_ancestor" do
52
+ class X; end
53
+ class Y < X; end
54
+ class Z < Y; end
55
+
56
+ list = []
57
+ Z.each_ancestor{|a| list << a}
58
+ list.should include Y
59
+ list.should include X
60
+ list.should_not include Z
61
+ list.should_not include Object
62
+ list.should_not include Kernel
63
+
64
+ list = []
65
+ Z.each_ancestor(true){|a| list << a}
66
+ list.should include Y
67
+ list.should include X
68
+ list.should_not include Z
69
+ list.should include Object
70
+ list.should include Kernel
71
+ end
72
+
73
+ it "each_namespace" do
74
+ class A
75
+ class B
76
+ class C
77
+
78
+ end
79
+ end
80
+ end
81
+
82
+ list = []
83
+ A::B::C.each_namespace{|n| list << n}
84
+ list.should == [A::B, A]
85
+ end
86
+
87
+ it "is?" do
88
+ File.is?(IO).should be_true
89
+ end
90
+
91
+ class WrapMethod
92
+ def method_name value
93
+ 10*value
94
+ end
95
+ end
96
+
97
+ it "wrap_method" do
98
+ WrapMethod.wrap_method :method_name do |old, value|
99
+ send(old, value)*value
100
+ end
101
+ WrapMethod.new.method_name(10).should == 1000
102
+ end
103
+
104
+ it "escape_method" do
105
+ Object.escape_method("><=?")
106
+ end
107
+
108
+ it "inheritable_accessor" do
109
+ module InheritableAccessorForModule
110
+ module ClassMethods
111
+ inheritable_accessor :callbacks, [:set_user]
112
+ inheritable_accessor :layout, "for_module"
113
+ end
114
+ end
115
+
116
+ class InheritableAccessorForClass
117
+ class << self
118
+ inheritable_accessor :callbacks2, []
119
+ inheritable_accessor :layout2, "for_class"
120
+ end
121
+ callbacks2 << :set_user
122
+ end
123
+
124
+ class InheritableAccessor < InheritableAccessorForClass
125
+ inherit InheritableAccessorForModule
126
+ callbacks << :set_model
127
+ callbacks2 << :set_model
128
+ self.layout2 = "anoter_layout"
129
+ end
130
+
131
+ InheritableAccessorForClass.callbacks2.should == [:set_user]
132
+ InheritableAccessor.callbacks.should == [:set_user, :set_model]
133
+ InheritableAccessor.callbacks2.should == [:set_user, :set_model]
134
+
135
+ InheritableAccessorForClass.layout2.should == "for_class"
136
+ InheritableAccessor.layout2.should == "anoter_layout"
137
+ InheritableAccessor.layout.should == "for_module"
138
+ end
139
+
140
+ it "inheritable_accessor (from error)" do
141
+ module InheritableAccessorBase
142
+ module ClassMethods
143
+ inheritable_accessor :callbacks, []
144
+ end
145
+ end
146
+
147
+ class InheritableAccessorA
148
+ inherit InheritableAccessorBase
149
+ callbacks << :a
150
+ end
151
+
152
+ class InheritableAccessorB
153
+ inherit InheritableAccessorBase
154
+ callbacks << :b
155
+ end
156
+
157
+ InheritableAccessorA.callbacks.should == [:a]
158
+ InheritableAccessorB.callbacks.should == [:b]
159
+ end
160
+ end
@@ -0,0 +1,131 @@
1
+ require "#{File.dirname __FILE__}/helper"
2
+ require "ruby_ext/multiple_inheritance"
3
+
4
+ describe "Multiple Inheritance" do
5
+ after :each do
6
+ remove_constants %w(M A M2 B AddedAfterInheritance)
7
+ end
8
+
9
+ it "showcase" do
10
+ module M
11
+ def instance_method; end
12
+
13
+ class_methods do
14
+ def class_method; end
15
+ end
16
+
17
+ def self.inherited target
18
+ target.send :attr_accessor, :some_accessor
19
+ end
20
+ end
21
+
22
+ M.should respond_to(:class_method)
23
+
24
+ class A
25
+ inherit M
26
+ end
27
+
28
+ A.should respond_to(:class_method)
29
+ A.new.should respond_to(:instance_method)
30
+ A.new.should respond_to(:some_accessor)
31
+
32
+ M.directly_included_by.should == [A].to_set
33
+ end
34
+
35
+ it "should inherit all ancestors class methods" do
36
+ module M
37
+ def instance_method; end
38
+
39
+ class_methods do
40
+ def class_method; end
41
+ end
42
+ end
43
+
44
+ module M2
45
+ inherit M
46
+
47
+ class_methods do
48
+ def class_method2; end
49
+ end
50
+ end
51
+
52
+ class B
53
+ inherit M2
54
+ end
55
+
56
+ M2.should respond_to(:class_method)
57
+
58
+ B.should respond_to(:class_method)
59
+ B.should respond_to(:class_method2)
60
+ B.new.should respond_to(:instance_method)
61
+
62
+ M.directly_included_by.should == [M2].to_set
63
+ M2.directly_included_by.should == [B].to_set
64
+ end
65
+
66
+ it "shouldn't redefine ancestors class methods" do
67
+ module M
68
+ class_methods do
69
+ def class_method; end
70
+ end
71
+ end
72
+
73
+ module M2
74
+ inherit M
75
+
76
+ class_methods do
77
+ def class_method2; end
78
+ end
79
+ end
80
+
81
+ class A
82
+ inherit M
83
+ end
84
+
85
+ A.should_not respond_to(:class_method2)
86
+ end
87
+
88
+ it "should also allow to explicitly use ClassMethods prototype (from error)" do
89
+ module A
90
+ module ClassMethods
91
+ attr_accessor :callbacks
92
+ end
93
+ end
94
+
95
+ class B
96
+ inherit A
97
+ end
98
+
99
+ B.should respond_to(:callbacks)
100
+ end
101
+
102
+ it "methods defined on base class after inheritance must be propagated to all descendants" do
103
+ module M; end
104
+
105
+ class A
106
+ inherit M
107
+ end
108
+
109
+ A.instance_methods.should_not include('method_added_after_inheritance')
110
+ M.send(:define_method, :method_added_after_inheritance){}
111
+ M.instance_methods.should include('method_added_after_inheritance')
112
+ A.instance_methods.should include('method_added_after_inheritance')
113
+ end
114
+
115
+ it "modules included in base class after inheritance must be propagated to all descendants" do
116
+ module M; end
117
+
118
+ class A
119
+ inherit M
120
+ end
121
+
122
+ module AddedAfterInheritance
123
+ def module_added_after_inheritance; end
124
+ end
125
+
126
+ M.instance_methods.should_not include('module_added_after_inheritance')
127
+ M.inherit AddedAfterInheritance
128
+ M.instance_methods.should include('module_added_after_inheritance')
129
+ A.instance_methods.should include('module_added_after_inheritance')
130
+ end
131
+ end
data/spec/must_spec.rb ADDED
@@ -0,0 +1,29 @@
1
+ require "#{File.dirname __FILE__}/helper"
2
+ require "ruby_ext/array"
3
+ require "ruby_ext/must"
4
+
5
+ describe 'Assert' do
6
+ it 'must & must_not' do
7
+ lambda{must_be.never_called}.should raise_error(/ever/)
8
+ lambda{nil.must_not_be.nil}.should raise_error(/nil/)
9
+ 1.must_not_be.nil
10
+ 1.must_be.== 1
11
+ lambda{1.must_be.== 2}.should raise_error(%r{==})
12
+ 1.must_be.in 1, 2
13
+ 0.must_be.in 0..1
14
+ "".must_be.a String
15
+ 1.must_be.< 2
16
+ end
17
+
18
+ it 'must_be & must_not_be' do
19
+ [].must_be.empty
20
+ [''].must_not_be.empty
21
+
22
+ lambda{[''].must_be.empty}.should raise_error(/must be/)
23
+ lambda{[].must_not_be.empty}.should raise_error(/must not be/)
24
+ end
25
+
26
+ it "should return result" do
27
+ [].must_be.empty.should == []
28
+ end
29
+ end
@@ -0,0 +1,42 @@
1
+ require "#{File.dirname __FILE__}/helper"
2
+ require "ruby_ext/observable2"
3
+
4
+ describe "Observable" do
5
+ class AnObservable
6
+ include Observable2
7
+ end
8
+
9
+ it "Method without Parameters" do
10
+ mock = mock("Observer")
11
+ obs = AnObservable.new
12
+ obs.add_observer mock
13
+ mock.should_receive(:update).with(2)
14
+ obs.notify_observers :update, 2
15
+ end
16
+
17
+ # it "Method without Parameters" do
18
+ # mock = mock("Observer")
19
+ # obs = AnObservable.new
20
+ # obs.add_observer(mock, :method => :custom_update, :filter => lambda{|o| o == 2})
21
+ # mock.should_receive(:custom_update).with(2)
22
+ # obs.notify_observers 2
23
+ # obs.notify_observers 4
24
+ # end
25
+ #
26
+ # it "With Block" do
27
+ # mock = mock("Observer")
28
+ # mock.should_receive(:got)
29
+ # obs = AnObservable.new
30
+ # obs.add_observer{mock.got}
31
+ # obs.notify_observers
32
+ # end
33
+ #
34
+ # it "With Block and Filter" do
35
+ # mock = mock("Observer")
36
+ # obs = AnObservable.new
37
+ # obs.add_observer(:filter => lambda{|o| o == 2}){|o| mock.got o}
38
+ # mock.should_receive(:got).with(2)
39
+ # obs.notify_observers 2
40
+ # obs.notify_observers 4
41
+ # end
42
+ end
@@ -0,0 +1,36 @@
1
+ require "#{File.dirname __FILE__}/helper"
2
+ require "ruby_ext/open_constructor"
3
+
4
+ describe 'OpenConstructor' do
5
+ class Test
6
+ include OpenConstructor
7
+ attr_accessor :name, :value
8
+ end
9
+
10
+ it 'should initialize atributes from Hash' do
11
+ t = Test.new.set(:name => 'name', :value => 'value')
12
+ [t.name, t.value].should == ['name', 'value']
13
+ end
14
+
15
+ it 'should initialize atributes from any Object' do
16
+ t = Test.new.set(:name => 'name', :value => 'value')
17
+ t2 = Test.new.set t
18
+ [t2.name, t2.value].should == ['name', 'value']
19
+ end
20
+
21
+ it 'restrict copied values' do
22
+ t = Test.new.set(:name => 'name', :value => 'value')
23
+ t2 = Test.new.set t, [:name]
24
+ [t2.name, t2.value].should == ['name', nil]
25
+
26
+ t = {:name => 'name', :value => 'value'}
27
+ t2 = Test.new.set t, [:name]
28
+ [t2.name, t2.value].should == ['name', nil]
29
+ end
30
+
31
+ it 'to_hash' do
32
+ h = {:name => 'name', :value => 'value'}
33
+ t = Test.new.set h
34
+ t.to_hash.should == h
35
+ end
36
+ end
@@ -0,0 +1,29 @@
1
+ require "#{File.dirname __FILE__}/helper"
2
+ require "ruby_ext/array"
3
+
4
+ describe 'OpenObject' do
5
+ it 'should be comparable with hashes' do
6
+ {}.to_openobject.should == {}
7
+ {}.should == {}.to_openobject
8
+
9
+ {:a => :b}.to_openobject.should == {:a => :b}
10
+ {'a' => :b}.to_openobject.should == {:a => :b}
11
+
12
+ {:a => :b}.to_openobject.should == {'a' => :b}
13
+ {'a' => :b}.to_openobject.should == {'a' => :b}
14
+
15
+ {:a => :b}.to_openobject.should_not == {:a => :c}
16
+ end
17
+
18
+ it "must be hash (from error)" do
19
+ {}.to_openobject.is_a?(Hash).should be_true
20
+ end
21
+
22
+ it 'merge! should be indifferent to string and symbol' do
23
+ oo = OpenObject.new
24
+ oo.merge! :a => true
25
+ oo.a.should be_true
26
+ oo.merge! 'b' => true
27
+ oo.b.should be_true
28
+ end
29
+ end
@@ -0,0 +1,46 @@
1
+ require "#{File.dirname __FILE__}/helper"
2
+ require "ruby_ext/prepare_arguments"
3
+
4
+ describe "Prepare Arguments" do
5
+
6
+ it "basic parsing" do
7
+ ArgumentsParser.register :m, [:object, :array, :hash]
8
+ ArgumentsParser.parse_arguments_for(:m, :o, 1).should == [:o, [1], {}]
9
+ end
10
+
11
+ it "basic method wrapping" do
12
+ class BMWTest
13
+ def add content, options
14
+ :ok
15
+ end
16
+ prepare_arguments_for :add, {:type => :object, :required => true}, :hash
17
+ end
18
+
19
+ BMWTest.new.add('text').should == :ok
20
+ end
21
+
22
+ it "except_last_hash for array" do
23
+ ArgumentsParser.register :m, [{:type => :array, :range => :except_last_hash}, :hash]
24
+ ArgumentsParser.parse_arguments_for(:m, 1, 2, 3, :a => :b).should == [[1, 2, 3], {:a => :b}]
25
+ ArgumentsParser.parse_arguments_for(:m, :a => :b).should == [[], {:a => :b}]
26
+ ArgumentsParser.parse_arguments_for(:m, 1, 2, 3).should == [[1, 2, 3], {}]
27
+ end
28
+
29
+ it "except_last_hash for object" do
30
+ ArgumentsParser.register :m, [{:type => :object, :range => :except_last_hash}, :hash]
31
+ ArgumentsParser.parse_arguments_for(:m, 1, :a => :b).should == [1, {:a => :b}]
32
+ ArgumentsParser.parse_arguments_for(:m, :a => :b).should == [nil, {:a => :b}]
33
+ ArgumentsParser.parse_arguments_for(:m, 1).should == [1, {}]
34
+ end
35
+
36
+ it "default value" do
37
+ ArgumentsParser.register :m, [{:type => :object, :default => ""}]
38
+ ArgumentsParser.parse_arguments_for(:m).should == [""]
39
+ end
40
+
41
+ it "string" do
42
+ ArgumentsParser.register :m, [:string]
43
+ ArgumentsParser.parse_arguments_for(:m).should == [""]
44
+ end
45
+
46
+ end
@@ -0,0 +1,24 @@
1
+ require "#{File.dirname __FILE__}/helper"
2
+ require "ruby_ext/should"
3
+
4
+ describe 'Assert' do
5
+ it 'should! & should_not!' do
6
+ lambda{should! :be_never_called}.should raise_error(/ever/)
7
+ lambda{nil.should_not! :be_nil}.should raise_error(/nil/)
8
+ 1.should_not! :be_nil
9
+ 1.should! :==, 1
10
+ lambda{1.should! :==, 2}.should raise_error(%r{==})
11
+ 1.should! :be_in, [1, 2]
12
+ "".should! :be_a, String
13
+ String.should! :be, String
14
+ 1.should! :<, 2
15
+ end
16
+
17
+ it 'should_be! & should_not_be!' do
18
+ [].should_be! :empty
19
+ [''].should_not_be! :empty
20
+
21
+ lambda{[''].should_be! :empty}.should raise_error(/should be/)
22
+ lambda{[].should_not_be! :empty}.should raise_error(/should not be/)
23
+ end
24
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --reverse