ruby_ext 0.5.9 → 0.5.10

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