ruby_ext 0.5.9 → 0.5.10

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 (40) hide show
  1. data/Rakefile +2 -3
  2. data/lib/rake_ext/project.rb +1 -2
  3. data/lib/rspec_ext.rb +37 -35
  4. data/lib/rspec_ext/nokogiri.rb +26 -0
  5. data/lib/ruby_ext/core.rb +3 -5
  6. data/lib/ruby_ext/core/array.rb +1 -1
  7. data/lib/ruby_ext/core/basic_object.rb +1 -1
  8. data/lib/ruby_ext/core/deep_clone.rb +3 -10
  9. data/lib/ruby_ext/core/enumerable.rb +3 -3
  10. data/lib/ruby_ext/core/false_class.rb +1 -1
  11. data/lib/ruby_ext/core/hash.rb +23 -7
  12. data/lib/ruby_ext/core/module.rb +37 -57
  13. data/lib/ruby_ext/core/multiple_inheritance.rb +3 -3
  14. data/lib/ruby_ext/core/must.rb +0 -16
  15. data/lib/ruby_ext/core/nil_class.rb +5 -0
  16. data/lib/ruby_ext/core/object.rb +7 -7
  17. data/lib/ruby_ext/core/open_object.rb +7 -25
  18. data/lib/ruby_ext/core/string.rb +1 -6
  19. data/lib/ruby_ext/more.rb +2 -0
  20. data/lib/ruby_ext/more/callbacks.rb +37 -0
  21. data/lib/ruby_ext/more/declarative_cache.rb +45 -56
  22. data/lib/yaml_fix.rb +9 -0
  23. data/spec/core/array_spec.rb +1 -1
  24. data/spec/core/deep_clone_spec.rb +4 -2
  25. data/spec/core/enumerable.rb +1 -1
  26. data/spec/core/module_spec.rb +65 -107
  27. data/spec/core/multiple_inheritance_spec.rb +4 -4
  28. data/spec/core/must_spec.rb +1 -1
  29. data/spec/core/object_spec.rb +6 -6
  30. data/spec/core/open_object_spec.rb +1 -1
  31. data/spec/more/callbacks_spec.rb +90 -20
  32. data/spec/more/declarative_cache_spec.rb +96 -75
  33. data/spec/more/observable_spec.rb +10 -34
  34. data/spec/more/open_constructor_spec.rb +14 -11
  35. data/spec/spec_helper.rb +2 -0
  36. metadata +5 -6
  37. data/lib/rspec_ext/xhtml.rb +0 -48
  38. data/lib/ruby_ext/fixes.rb +0 -6
  39. data/spec/core/spec_helper.rb +0 -2
  40. data/spec/more/spec_helper.rb +0 -2
@@ -40,14 +40,6 @@ class MustAssertions < BasicObject
40
40
  end
41
41
  alias_method :an, :a
42
42
 
43
- # def be klass = nil
44
- # if klass.class == Array
45
- # klass.any?{|k| @obj.respond_to :is?, k}
46
- # else
47
- # @obj.respond_to :is?, klass
48
- # end
49
- # end
50
-
51
43
  def include o
52
44
  @obj.include? o
53
45
  end
@@ -184,12 +176,4 @@ Object.class_eval do
184
176
  def must_not_be
185
177
  must_not.be
186
178
  end
187
-
188
- # def must_have
189
- # must.have
190
- # end
191
- #
192
- # def must_not_have
193
- # must_not.have
194
- # end
195
179
  end
@@ -1,3 +1,8 @@
1
1
  class NilClass
2
2
  def blank?; true end
3
+
4
+ def to_openobject deep = false
5
+ OpenObject.new
6
+ end
7
+ alias_method :to_oo, :to_openobject
3
8
  end
@@ -9,13 +9,13 @@ Object.class_eval do
9
9
  respond_to?(:empty?) ? empty? : !self
10
10
  end
11
11
 
12
- def metaclass &block
13
- (class << self; self; end)
14
- end
15
- def metaclass_eval &block
16
- metaclass.class_eval(&block)
17
- self
18
- end
12
+ # def metaclass &block
13
+ # (class << self; self; end)
14
+ # end
15
+ # def metaclass_eval &block
16
+ # metaclass.class_eval(&block)
17
+ # self
18
+ # end
19
19
 
20
20
  def respond_to method, *args
21
21
  respond_to?(method) ? send(method, *args) : nil
@@ -126,6 +126,13 @@ class OpenObject < Hash
126
126
  # support :extract_options for OpenObject (Rails integration)
127
127
  def extractable_options?; true end
128
128
 
129
+ def deep_clone
130
+ clone = super
131
+ clone.clear
132
+ each{|k, v| clone[k.deep_clone] = v.deep_clone}
133
+ clone
134
+ end
135
+
129
136
  protected
130
137
  def method_missing m, arg = nil, &block
131
138
  type = m[-1,1]
@@ -140,29 +147,4 @@ class OpenObject < Hash
140
147
  self[m]
141
148
  end
142
149
  end
143
- end
144
-
145
-
146
- #
147
- # Core Extensions
148
- #
149
- class NilClass
150
- def to_openobject deep = false
151
- OpenObject.new
152
- end
153
- alias_method :to_oo, :to_openobject
154
- end
155
-
156
- class Hash
157
- def to_openobject deep = false
158
- OpenObject.initialize_from self, deep
159
- end
160
- alias_method :to_oo, :to_openobject
161
-
162
- alias_method :oo_eql, :==
163
- def == other
164
- true if self.equal? other
165
- other == self if other.is_a? OpenObject
166
- oo_eql other
167
- end
168
150
  end
@@ -1,4 +1,4 @@
1
- String.class_eval do
1
+ class String
2
2
  def indent spaces = 2
3
3
  indent = ' ' * spaces
4
4
  gsub /^/, indent
@@ -20,11 +20,6 @@ String.class_eval do
20
20
  [self]
21
21
  end
22
22
 
23
- def self.secure_token
24
- original = [Time.now, (1..10).map{ rand.to_s }]
25
- Digest::SHA1.hexdigest(original.flatten.join('--'))
26
- end
27
-
28
23
  def underscore
29
24
  word = self.dup
30
25
  word.gsub!(/::/, '/')
data/lib/ruby_ext/more.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require 'ruby_ext/core'
2
2
 
3
+ require 'set'
4
+
3
5
  module RubyExt
4
6
  %w(Callbacks DeclarativeCache Observable OpenConstructor Tuple).each do |const|
5
7
  autoload const, "ruby_ext/more/#{const.underscore}"
@@ -176,6 +176,22 @@ module RubyExt::Callbacks
176
176
  end
177
177
  end
178
178
 
179
+ # We need to prevent callback from rinning multiple times if nested
180
+ # (need this for wrapping methods with callbacks to correctly call super).
181
+ def run_callbacks_only_once callback_name, data = {}, &block
182
+ set = Thread.current[callback_name] ||= {}
183
+ if set.include? object_id
184
+ block.call if block
185
+ else
186
+ begin
187
+ set[object_id] = true
188
+ run_callbacks callback_name, data, &block
189
+ ensure
190
+ set.delete object_id
191
+ end
192
+ end
193
+ end
194
+
179
195
  module ClassMethods
180
196
  inheritable_accessor :callbacks, {}
181
197
 
@@ -206,5 +222,26 @@ module RubyExt::Callbacks
206
222
  (self.callbacks[callback_name] ||= []) << callback
207
223
  end
208
224
 
225
+ def wrap_method_with_callbacks method, callback
226
+ method_without_callback = :"#{method}_without_#{callback}_of_#{self.alias}"
227
+ if method_defined? method_without_callback
228
+ raise "can't wrap method #{method} with #{callback} of #{self.alias} twice!"
229
+ end
230
+
231
+ alias_method method_without_callback, method
232
+ define_method method do |*args, &block|
233
+ # We can't use run_callbacks, because in case of the `super`
234
+ # call it will be runned twice.
235
+ run_callbacks_only_once callback do
236
+ send method_without_callback, *args, &block
237
+ end
238
+ end
239
+ end
240
+
241
+ def wrap_with_callback callback
242
+ instance_methods(false).each do |method|
243
+ wrap_method_with_callbacks method, callback
244
+ end
245
+ end
209
246
  end
210
247
  end
@@ -1,78 +1,67 @@
1
- require 'monitor'
2
-
3
1
  module RubyExt::DeclarativeCache
4
- DISABLED = false
2
+ class << self
5
3
 
6
- warn "CASHE DISABLED" if DISABLED
7
- unless DISABLED
8
- class << self
4
+ def cache_method klass, *methods
5
+ methods.each do |method|
6
+ klass.class_eval do
7
+ escaped_method = escape_method method
8
+ method_with_cache = :"#{escaped_method}_with_cache"
9
+ method_without_cache = :"#{escaped_method}_without_cache"
10
+ iv_check = "@#{escaped_method}_cache_check"
11
+ iv = "@#{escaped_method}_cache"
9
12
 
10
- def cache_method klass, *methods
11
- methods.each do |method|
12
- klass.class_eval do
13
- escaped_method = escape_method(method)
14
- method_with_cache, method_without_cache = "#{escaped_method}_with_cache".to_sym, "#{escaped_method}_without_cache".to_sym
15
- iv_check = "@#{escaped_method}_cache_check"
16
- iv = "@#{escaped_method}_cache"
13
+ alias_method method_without_cache, method
17
14
 
18
- if instance_methods.include?(method_with_cache) or instance_methods.include?(method_without_cache)
19
- warn "can't cache the :#{method} twice!"
20
- else
21
- alias_method method_without_cache, method
15
+ define_method method_with_cache do |*args|
16
+ raise "You tried to use cache without params for method with \
17
+ params (use 'cache_method_with_params' instead)!" unless args.empty?
22
18
 
23
- define_method method_with_cache do |*args|
24
- raise "You tried to use cache without params for method with params (use 'cache_method_with_params' instead)!" unless args.empty?
25
- unless cached = instance_variable_get(iv)
26
- unless check = instance_variable_get(iv_check)
27
- cached = send method_without_cache
28
- instance_variable_set iv, cached
29
- instance_variable_set iv_check, true
30
- end
31
- end
32
- cached
19
+ unless cached = instance_variable_get(iv)
20
+ unless check = instance_variable_get(iv_check)
21
+ cached = send method_without_cache
22
+ instance_variable_set iv, cached
23
+ instance_variable_set iv_check, true
33
24
  end
34
-
35
- alias_method method, method_with_cache
36
25
  end
26
+ cached
37
27
  end
28
+
29
+ alias_method method, method_with_cache
38
30
  end
39
31
  end
32
+ end
40
33
 
41
- def cache_method_with_params klass, *methods
42
- methods.each do |method|
43
- klass.class_eval do
44
- escaped_method = escape_method(method)
45
- method_with_cache, method_without_cache = "#{escaped_method}_with_cache".to_sym, "#{escaped_method}_without_cache".to_sym
46
- iv_check = "@#{escaped_method}_cache_check"
47
- iv = "@#{escaped_method}_cache"
48
-
49
- if instance_methods.include?(method_with_cache) or instance_methods.include?(method_without_cache)
50
- warn "can't cache the :#{method} twice!"
51
- else
52
- alias_method method_without_cache, method
53
-
54
- define_method method_with_cache do |*args|
55
- unless results = instance_variable_get(iv)
56
- results = Hash.new(NotDefined)
57
- instance_variable_set iv, results
58
- end
34
+ def cache_method_with_params klass, *methods
35
+ methods.each do |method|
36
+ klass.class_eval do
37
+ escaped_method = escape_method method
38
+ method_with_cache = :"#{escaped_method}_with_cache"
39
+ method_without_cache = :"#{escaped_method}_without_cache"
40
+ iv_check = "@#{escaped_method}_cache_check"
41
+ iv = "@#{escaped_method}_cache"
59
42
 
60
- result = results[args]
43
+ alias_method method_without_cache, method
61
44
 
62
- if result.equal? NotDefined
63
- result = send method_without_cache, *args
64
- results[args] = result
65
- end
45
+ define_method method_with_cache do |*args|
46
+ unless results = instance_variable_get(iv)
47
+ results = Hash.new(NotDefined)
48
+ instance_variable_set iv, results
49
+ end
66
50
 
67
- result
68
- end
51
+ result = results[args]
69
52
 
70
- alias_method method, method_with_cache
53
+ if result.equal? NotDefined
54
+ result = send method_without_cache, *args
55
+ results[args] = result
71
56
  end
57
+
58
+ result
72
59
  end
60
+
61
+ alias_method method, method_with_cache
73
62
  end
74
63
  end
75
-
76
64
  end
65
+
77
66
  end
78
67
  end
data/lib/yaml_fix.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'yaml'
2
+
3
+ begin
4
+ require 'psych'
5
+ YAML::ENGINE.yamler = 'psych'
6
+ rescue Exception
7
+ warn "can't load 'psych', the new YAML engine (probably the 'libyaml' is not installed), usng 'sych' a deprecated one, \
8
+ there may be some problems with encoding."
9
+ end
@@ -1,4 +1,4 @@
1
- require "core/spec_helper"
1
+ require "spec_helper"
2
2
 
3
3
  describe 'Array' do
4
4
  it 'sfilter' do
@@ -1,6 +1,8 @@
1
- require "core/spec_helper"
1
+ require "spec_helper"
2
2
 
3
3
  describe 'deep_clone' do
4
+ after{remove_constants :Metadata}
5
+
4
6
  it "basic" do
5
7
  hash, array = {}, ['value']
6
8
  hash['key'] = array
@@ -15,7 +17,7 @@ describe 'deep_clone' do
15
17
  array2.object_id.should_not == array.object_id
16
18
  end
17
19
 
18
- it do
20
+ it 'cloning object tree' do
19
21
  class Metadata
20
22
  attr_accessor :registry
21
23
 
@@ -1,4 +1,4 @@
1
- require "core/spec_helper"
1
+ require "spec_helper"
2
2
 
3
3
  describe 'Enumerable' do
4
4
  it 'every' do
@@ -1,151 +1,109 @@
1
- require "core/spec_helper"
1
+ require "spec_helper"
2
2
 
3
3
  describe "Module" do
4
- after do
5
- remove_constants %w(
6
- A X Y Z
7
- InheritableAccessorForModule
8
- InheritableAccessorForClass
9
- InheritableAccessor
10
- InheritableAccessorBase
11
- InheritableAccessorA
12
- InheritableAccessorB
13
- )
14
- end
4
+ after{remove_constants :A, :B, :C, :ABase}
15
5
 
16
- it "Namespace" do
6
+ it "namespace" do
17
7
  class A
18
8
  class B
19
- class C
20
-
21
- end
9
+ class C; end
22
10
  end
23
11
  end
24
12
 
25
- File.namespace.should == nil
13
+ A.namespace.should == nil
26
14
  A::B::C.namespace.should == A::B
27
15
  end
28
16
 
29
- # class AnonymousClass
30
- # class << self
31
- # def anonymous_name
32
- # self.name
33
- # end
34
- # end
35
- # end
36
-
37
- it "name" do
17
+ it "alias" do
38
18
  class A
39
19
  class B
40
- class C
41
-
42
- end
20
+ class C; end
43
21
  end
44
22
  end
45
23
 
24
+ A::B::C.alias.should == 'C'
46
25
  A::B::C.name.should == "A::B::C"
47
26
  end
48
27
 
49
- it "each_ancestor" do
50
- class X; end
51
- class Y < X; end
52
- class Z < Y; end
53
-
54
- list = []
55
- Z.each_ancestor{|a| list << a}
56
- list.should include Y
57
- list.should include X
58
- list.should_not include Z
59
- list.should_not include Object
60
- list.should_not include Kernel
61
-
62
- list = []
63
- Z.each_ancestor(true){|a| list << a}
64
- list.should include Y
65
- list.should include X
66
- list.should_not include Z
67
- list.should include Object
68
- list.should include Kernel
28
+ it "is?" do
29
+ Fixnum.is?(Numeric).should be_true
69
30
  end
70
31
 
71
- it "each_namespace" do
72
- class A
73
- class B
74
- class C
32
+ it "escape_method" do
33
+ Module.escape_method(:">_<_=_?").should == :gt_lt_assign_qst
34
+ end
75
35
 
36
+ describe "inheritable_accessor" do
37
+ it "module" do
38
+ module A
39
+ module ClassMethods
40
+ inheritable_accessor :callbacks, [:a]
41
+ inheritable_accessor :layout, 'a'
76
42
  end
77
43
  end
78
- end
79
-
80
- list = []
81
- A::B::C.each_namespace{|n| list << n}
82
- list.should == [A::B, A]
83
- end
84
44
 
85
- it "is?" do
86
- File.is?(IO).should be_true
87
- end
45
+ class B
46
+ inherit A
47
+ callbacks << :b
48
+ self.layout = 'b'
49
+ end
88
50
 
89
- class WrapMethod
90
- def method_name value
91
- 10*value
51
+ B.callbacks.should == [:a, :b]
52
+ B.layout.should == 'b'
92
53
  end
93
- end
94
-
95
- it "escape_method" do
96
- Object.escape_method("><=?")
97
- end
98
54
 
99
- it "inheritable_accessor" do
100
- module InheritableAccessorForModule
101
- module ClassMethods
102
- inheritable_accessor :callbacks, [:set_user]
103
- inheritable_accessor :layout, "for_module"
55
+ it "class" do
56
+ class A
57
+ class << self
58
+ inheritable_accessor :callbacks, [:a]
59
+ inheritable_accessor :layout, 'a'
60
+ end
61
+ callbacks << :a2
104
62
  end
105
- end
106
63
 
107
- class InheritableAccessorForClass
108
- class << self
109
- inheritable_accessor :callbacks2, []
110
- inheritable_accessor :layout2, "for_class"
64
+ class B < A
65
+ callbacks << :b
66
+ self.layout = 'b'
111
67
  end
112
- callbacks2 << :set_user
113
- end
114
68
 
115
- class InheritableAccessor < InheritableAccessorForClass
116
- inherit InheritableAccessorForModule
117
- callbacks << :set_model
118
- callbacks2 << :set_model
119
- self.layout2 = "anoter_layout"
69
+ A.callbacks.should == [:a, :a2]
70
+ B.callbacks.should == [:a, :a2, :b]
71
+
72
+ A.layout.should == 'a'
73
+ B.layout.should == 'b'
120
74
  end
121
75
 
122
- InheritableAccessorForClass.callbacks2.should == [:set_user]
123
- InheritableAccessor.callbacks.should == [:set_user, :set_model]
124
- InheritableAccessor.callbacks2.should == [:set_user, :set_model]
76
+ it "should correcly clone attributes (from error)" do
77
+ module ABase
78
+ module ClassMethods
79
+ inheritable_accessor :callbacks, []
80
+ end
81
+ end
125
82
 
126
- InheritableAccessorForClass.layout2.should == "for_class"
127
- InheritableAccessor.layout2.should == "anoter_layout"
128
- InheritableAccessor.layout.should == "for_module"
129
- end
83
+ class A
84
+ inherit ABase
85
+ callbacks << :a
86
+ end
130
87
 
131
- it "inheritable_accessor (from error)" do
132
- module InheritableAccessorBase
133
- module ClassMethods
134
- inheritable_accessor :callbacks, []
88
+ class B
89
+ inherit ABase
90
+ callbacks << :b
135
91
  end
136
- end
137
92
 
138
- class InheritableAccessorA
139
- inherit InheritableAccessorBase
140
- callbacks << :a
93
+ A.callbacks.should == [:a]
94
+ B.callbacks.should == [:b]
141
95
  end
96
+ end
142
97
 
143
- class InheritableAccessorB
144
- inherit InheritableAccessorBase
145
- callbacks << :b
98
+ it "delegate" do
99
+ class A
100
+ attr_accessor :target
101
+ delegate :a, to: :target
146
102
  end
147
103
 
148
- InheritableAccessorA.callbacks.should == [:a]
149
- InheritableAccessorB.callbacks.should == [:b]
104
+ a = A.new
105
+ a.target = stub
106
+ a.target.should_receive(:a).with(:b)
107
+ a.a :b
150
108
  end
151
109
  end