ruby_ext 0.5.10 → 4.0.0
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.
- data/Rakefile +1 -0
- data/lib/ruby_ext/core.rb +0 -1
- data/lib/ruby_ext/core/basic_object.rb +1 -1
- data/lib/ruby_ext/core/hash.rb +6 -6
- data/lib/ruby_ext/core/module.rb +10 -2
- data/lib/ruby_ext/core/string.rb +2 -8
- data/lib/ruby_ext/more.rb +5 -1
- data/lib/ruby_ext/more/callbacks.rb +55 -51
- data/lib/ruby_ext/more/callbacks_proxy.rb +18 -0
- data/lib/ruby_ext/more/must.rb +139 -0
- data/lib/ruby_ext/more/user_error.rb +2 -0
- data/readme.md +17 -10
- data/spec/more/callbacks_spec.rb +61 -58
- data/spec/more/must_spec.rb +48 -0
- metadata +6 -4
- data/lib/ruby_ext/core/must.rb +0 -179
- data/spec/core/must_spec.rb +0 -32
data/Rakefile
CHANGED
data/lib/ruby_ext/core.rb
CHANGED
data/lib/ruby_ext/core/hash.rb
CHANGED
@@ -29,12 +29,12 @@ Hash.class_eval do
|
|
29
29
|
|
30
30
|
# Haml relies on :inspect default format and it brokes haml, but I prefer new hash notation,
|
31
31
|
# disable it if You use Haml.
|
32
|
-
unless $dont_extend_hash_inspect
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
end
|
32
|
+
# unless $dont_extend_hash_inspect
|
33
|
+
# def inspect
|
34
|
+
# "{" + collect{|k, v| "#{k}: #{v}"}.join(', ') + "}"
|
35
|
+
# end
|
36
|
+
# alias_method :to_s, :inspect
|
37
|
+
# end
|
38
38
|
|
39
39
|
alias_method :blank?, :empty?
|
40
40
|
|
data/lib/ruby_ext/core/module.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
Module.class_eval do
|
2
2
|
def alias name = nil
|
3
3
|
if name
|
4
|
-
name.
|
5
|
-
name.
|
4
|
+
name.must.be_a String
|
5
|
+
name.must.be_present
|
6
6
|
@alias = name.to_s
|
7
7
|
else
|
8
8
|
@alias ||= self.name.split('::').last
|
@@ -36,6 +36,14 @@ Module.class_eval do
|
|
36
36
|
@namespace_for_cache[class_name]
|
37
37
|
end
|
38
38
|
|
39
|
+
def metaclass
|
40
|
+
class << self; self end
|
41
|
+
end
|
42
|
+
|
43
|
+
def metaclass_eval &block
|
44
|
+
metaclass.class_eval &block
|
45
|
+
end
|
46
|
+
|
39
47
|
def inheritable_accessor attribute_name, default_value
|
40
48
|
raise "Can be used only for Class and Module" unless self.class.is? Module
|
41
49
|
|
data/lib/ruby_ext/core/string.rb
CHANGED
@@ -39,14 +39,8 @@ class String
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def constantize
|
42
|
-
names =
|
43
|
-
names.
|
44
|
-
|
45
|
-
constant = Object
|
46
|
-
names.each do |name|
|
47
|
-
constant = constant.const_defined?(name) ? constant.const_get(name) : constant.const_missing(name)
|
48
|
-
end
|
49
|
-
constant
|
42
|
+
names = sub(/^::/, '').split '::'
|
43
|
+
names.reduce(Object){|memo, name| memo.const_get name, false}
|
50
44
|
end
|
51
45
|
|
52
46
|
def substitute(*args)
|
data/lib/ruby_ext/more.rb
CHANGED
@@ -1,9 +1,13 @@
|
|
1
1
|
require 'ruby_ext/core'
|
2
2
|
|
3
|
+
require 'ruby_ext/more/must'
|
4
|
+
|
3
5
|
require 'set'
|
4
6
|
|
7
|
+
# Lazy loading.
|
8
|
+
autoload :UserError, 'ruby_ext/more/user_error'
|
5
9
|
module RubyExt
|
6
|
-
%w(Callbacks DeclarativeCache Observable OpenConstructor Tuple).each do |const|
|
10
|
+
%w(Callbacks CallbacksProxy DeclarativeCache Observable OpenConstructor Tuple).each do |const|
|
7
11
|
autoload const, "ruby_ext/more/#{const.underscore}"
|
8
12
|
end
|
9
13
|
end
|
@@ -2,7 +2,7 @@ module RubyExt::Callbacks
|
|
2
2
|
class AbstractCallback
|
3
3
|
attr_reader :executor
|
4
4
|
def executor= executor
|
5
|
-
@executor = executor.
|
5
|
+
@executor = executor.must.be_a Symbol, Proc
|
6
6
|
end
|
7
7
|
|
8
8
|
attr_reader :conditions
|
@@ -21,15 +21,15 @@ module RubyExt::Callbacks
|
|
21
21
|
@conditions
|
22
22
|
end
|
23
23
|
|
24
|
-
def run? target, data
|
24
|
+
def run? target, method, data
|
25
25
|
if cond = conditions[:if]
|
26
26
|
evaluate_if(cond, target, data)
|
27
27
|
elsif cond = conditions[:unless]
|
28
28
|
!evaluate_if(cond, target, data)
|
29
29
|
elsif cond = conditions[:only]
|
30
|
-
evaluate_only(cond, data)
|
30
|
+
evaluate_only(cond, method, data)
|
31
31
|
elsif cond = conditions[:except]
|
32
|
-
!evaluate_only(cond, data)
|
32
|
+
!evaluate_only(cond, method, data)
|
33
33
|
else
|
34
34
|
true
|
35
35
|
end
|
@@ -44,19 +44,18 @@ module RubyExt::Callbacks
|
|
44
44
|
elsif cond.is_a? Proc
|
45
45
|
cond.call target, data
|
46
46
|
else
|
47
|
-
|
47
|
+
must.be_never_called
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
-
def evaluate_only cond, data
|
52
|
-
method
|
53
|
-
method.must_be.a Symbol if method
|
51
|
+
def evaluate_only cond, method, data
|
52
|
+
method.must.be_a Symbol if method
|
54
53
|
if cond.is_a? Symbol
|
55
54
|
cond == method
|
56
55
|
elsif cond.is_a? Array
|
57
56
|
cond.include? method
|
58
57
|
else
|
59
|
-
|
58
|
+
must.be_never_called
|
60
59
|
end
|
61
60
|
end
|
62
61
|
end
|
@@ -64,9 +63,9 @@ module RubyExt::Callbacks
|
|
64
63
|
class BeforeCallback < AbstractCallback
|
65
64
|
attr_accessor :terminator
|
66
65
|
|
67
|
-
def build_block target, data, &block
|
66
|
+
def build_block target, method, data, &block
|
68
67
|
-> do
|
69
|
-
if run? target, data
|
68
|
+
if run? target, method, data
|
70
69
|
block.call if run target, data
|
71
70
|
else
|
72
71
|
block.call
|
@@ -80,7 +79,7 @@ module RubyExt::Callbacks
|
|
80
79
|
elsif executor.is_a? Proc
|
81
80
|
executor.call target
|
82
81
|
else
|
83
|
-
|
82
|
+
must.be_never_called
|
84
83
|
end
|
85
84
|
|
86
85
|
!terminate?(target, callback_result)
|
@@ -101,9 +100,9 @@ module RubyExt::Callbacks
|
|
101
100
|
end
|
102
101
|
|
103
102
|
class AfterCallback < AbstractCallback
|
104
|
-
def build_block target, data, &block
|
103
|
+
def build_block target, method, data, &block
|
105
104
|
-> do
|
106
|
-
if run? target, data
|
105
|
+
if run? target, method, data
|
107
106
|
result = block.call
|
108
107
|
run target, data
|
109
108
|
result
|
@@ -119,15 +118,15 @@ module RubyExt::Callbacks
|
|
119
118
|
elsif executor.is_a? Proc
|
120
119
|
executor.call target
|
121
120
|
else
|
122
|
-
|
121
|
+
must.be_never_called
|
123
122
|
end
|
124
123
|
end
|
125
124
|
end
|
126
125
|
|
127
126
|
class AroundCallback < AbstractCallback
|
128
|
-
def build_block target, data, &block
|
127
|
+
def build_block target, method, data, &block
|
129
128
|
-> do
|
130
|
-
if run? target, data
|
129
|
+
if run? target, method, data
|
131
130
|
run target, data, &block
|
132
131
|
else
|
133
132
|
block.call
|
@@ -141,62 +140,67 @@ module RubyExt::Callbacks
|
|
141
140
|
elsif executor.is_a? Proc
|
142
141
|
executor.call target, block
|
143
142
|
else
|
144
|
-
|
143
|
+
must.be_never_called
|
145
144
|
end
|
146
145
|
end
|
147
146
|
end
|
148
147
|
|
149
|
-
def run_before_callbacks
|
150
|
-
|
151
|
-
self.class.callbacks[
|
152
|
-
if callback.is_a?
|
153
|
-
return false unless callback.run
|
148
|
+
def run_before_callbacks name, method, data = {}
|
149
|
+
name.must.be_a Symbol
|
150
|
+
self.class.callbacks[name].try :each do |callback|
|
151
|
+
if callback.is_a?(BeforeCallback) and callback.run?(self, method, data)
|
152
|
+
return false unless callback.run(self, data)
|
154
153
|
end
|
155
154
|
end
|
156
155
|
true
|
157
156
|
end
|
158
157
|
|
159
|
-
def run_after_callbacks
|
160
|
-
|
161
|
-
self.class.callbacks[
|
162
|
-
callback.
|
158
|
+
def run_after_callbacks name, method, data = {}
|
159
|
+
name.must.be_a Symbol
|
160
|
+
self.class.callbacks[name].try :each do |callback|
|
161
|
+
if callback.is_a?(AfterCallback) and callback.run?(self, method, data)
|
162
|
+
callback.run(self, data)
|
163
|
+
end
|
163
164
|
end
|
164
165
|
end
|
165
166
|
|
166
|
-
def run_callbacks
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
167
|
+
def run_callbacks name, method, data = {}, &block
|
168
|
+
name.must.be_a Symbol
|
169
|
+
run_callbacks_once name, method, block do
|
170
|
+
if callbacks = self.class.callbacks[name]
|
171
|
+
chain = block || -> {}
|
172
|
+
chain = callbacks.reverse.reduce chain do |chain, callback|
|
173
|
+
callback.build_block self, method, data, &chain
|
174
|
+
end
|
175
|
+
chain.call
|
176
|
+
else
|
177
|
+
block.call if block
|
172
178
|
end
|
173
|
-
chain.call
|
174
|
-
else
|
175
|
-
block.call if block
|
176
179
|
end
|
177
180
|
end
|
178
181
|
|
179
|
-
# We need to prevent callback from rinning multiple times if nested
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
if set.include?
|
184
|
-
|
182
|
+
# We need to prevent callback from rinning multiple times if nested.
|
183
|
+
def run_callbacks_once name, method, block_without_callbacks, &block
|
184
|
+
set = Thread.current[:callbacks] ||= {}
|
185
|
+
id = "#{object_id}/#{name}/#{method}"
|
186
|
+
if set.include? id
|
187
|
+
block_without_callbacks.call if block_without_callbacks
|
185
188
|
else
|
186
189
|
begin
|
187
|
-
set[
|
188
|
-
|
190
|
+
set[id] = true
|
191
|
+
block.call
|
189
192
|
ensure
|
190
|
-
set.delete
|
193
|
+
set.delete id
|
191
194
|
end
|
192
195
|
end
|
193
196
|
end
|
197
|
+
protected :run_callbacks_once
|
194
198
|
|
195
199
|
module ClassMethods
|
196
200
|
inheritable_accessor :callbacks, {}
|
197
201
|
|
198
|
-
def set_callback
|
199
|
-
|
202
|
+
def set_callback name, type, *executor_or_options, &block
|
203
|
+
name.must.be_a Symbol
|
200
204
|
type = type.to_sym
|
201
205
|
|
202
206
|
# Parsing arguments.
|
@@ -204,8 +208,8 @@ module RubyExt::Callbacks
|
|
204
208
|
"You can't provide both method name and block for filter!" if block and !executor_or_options.empty?
|
205
209
|
executor = block || executor_or_options.first
|
206
210
|
|
207
|
-
type.
|
208
|
-
executor.
|
211
|
+
type.must.be_in [:before, :around, :after]
|
212
|
+
executor.must.be_defined
|
209
213
|
|
210
214
|
# Creating callback.
|
211
215
|
callback = AbstractCallback.new
|
@@ -219,7 +223,7 @@ module RubyExt::Callbacks
|
|
219
223
|
callback.terminator = opt.delete :terminator if type == :before
|
220
224
|
callback.conditions = opt
|
221
225
|
|
222
|
-
(self.callbacks[
|
226
|
+
(self.callbacks[name] ||= []) << callback
|
223
227
|
end
|
224
228
|
|
225
229
|
def wrap_method_with_callbacks method, callback
|
@@ -232,7 +236,7 @@ module RubyExt::Callbacks
|
|
232
236
|
define_method method do |*args, &block|
|
233
237
|
# We can't use run_callbacks, because in case of the `super`
|
234
238
|
# call it will be runned twice.
|
235
|
-
|
239
|
+
run_callbacks callback, method do
|
236
240
|
send method_without_callback, *args, &block
|
237
241
|
end
|
238
242
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class RubyExt::CallbacksProxy < BasicObject
|
2
|
+
attr_reader :object
|
3
|
+
|
4
|
+
def initialize object, callback_name
|
5
|
+
@object, @callback_name = object, callback_name
|
6
|
+
end
|
7
|
+
|
8
|
+
def callback_proxy?
|
9
|
+
true
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
def method_missing m, *args, &block
|
14
|
+
object.run_callbacks @callback_name, m do
|
15
|
+
object.public_send m, *args, &block
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
Object.class_eval do
|
2
|
+
def must
|
3
|
+
::Must::PositiveExpectation.new self
|
4
|
+
end
|
5
|
+
|
6
|
+
def must_not
|
7
|
+
::Must::NegativeExpectation.new self
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
class AssertionError < RuntimeError; end
|
12
|
+
|
13
|
+
module Must
|
14
|
+
class Expectation < BasicObject
|
15
|
+
def initialize object
|
16
|
+
@object = object
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_s; inspect end
|
20
|
+
|
21
|
+
# Special case, shortcut to write `a.must.be b` instead of `a.must.be_equal_to b`.
|
22
|
+
def be *args
|
23
|
+
if args.size == 1
|
24
|
+
be_equal_to args.first
|
25
|
+
elsif args.empty?
|
26
|
+
self
|
27
|
+
else
|
28
|
+
raise ArgumentError, "invalid usage!"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
protected
|
33
|
+
attr_reader :object
|
34
|
+
|
35
|
+
def method_missing method, *args, &block
|
36
|
+
original_method = method
|
37
|
+
method, prefix, human_method = if method =~ /^be_/
|
38
|
+
[:"#{method.to_s[3..-1]}?", :be, :"#{method.to_s[3..-1]}"]
|
39
|
+
elsif method =~ /^have_/
|
40
|
+
[:"#{method.to_s[5..-1]}?", :have, :"#{method.to_s[5..-1]}"]
|
41
|
+
elsif method =~ /^[a-z_0-9]+$/
|
42
|
+
[:"#{method}?", nil, method]
|
43
|
+
else
|
44
|
+
[method, nil, method]
|
45
|
+
end
|
46
|
+
special_method = :"_#{method}"
|
47
|
+
|
48
|
+
# Defining method, to make it faster for future calls.
|
49
|
+
instance_methods = ::Must::Expectation.instance_methods false
|
50
|
+
if instance_methods.include? special_method
|
51
|
+
define_special_method original_method, special_method, human_method, prefix
|
52
|
+
else
|
53
|
+
define_method original_method, method, human_method, prefix
|
54
|
+
end
|
55
|
+
|
56
|
+
__send__ original_method, *args, &block
|
57
|
+
end
|
58
|
+
|
59
|
+
# Special expectations.
|
60
|
+
|
61
|
+
def _never_called?; false end
|
62
|
+
def _nil?; object.equal? nil end
|
63
|
+
def _defined?; !_nil? end
|
64
|
+
def _equal_to? o; object == o end
|
65
|
+
def _true?; !!object end
|
66
|
+
def _false?; !object end
|
67
|
+
def _a? *args; args.any?{|klass| object.is_a?(klass)} end
|
68
|
+
# def _include o; object.include? o end
|
69
|
+
# def _respond_to o; object.respond_to? o end
|
70
|
+
alias_method :_an?, :_a?
|
71
|
+
|
72
|
+
def _in? *args;
|
73
|
+
list = (args.size == 1 and args.first.respond_to?(:include?)) ? args.first : args
|
74
|
+
list.include? object
|
75
|
+
end
|
76
|
+
|
77
|
+
def p *args; ::Kernel.send :p, *args end
|
78
|
+
|
79
|
+
def fail_expectation positive, human_method, prefix, *args, &block
|
80
|
+
stack = ::Object.send(:caller).sfilter '/must.rb'
|
81
|
+
|
82
|
+
msg = " ASSERTION FAILED (#{stack.first}):\n"
|
83
|
+
msg << " #{object.inspect[0..100]} must"
|
84
|
+
msg << " not" unless positive
|
85
|
+
msg << " #{prefix}" if prefix
|
86
|
+
msg << " #{human_method}"
|
87
|
+
msg << " #{args.collect(&:inspect).join(', ')}" unless args.empty?
|
88
|
+
msg << " &..." if block
|
89
|
+
|
90
|
+
::Object.send :raise, ::AssertionError, msg, stack
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
class PositiveExpectation < Expectation
|
95
|
+
def inspect; "<#Must::PositiveExpectation #{object.inspect}>" end
|
96
|
+
|
97
|
+
protected
|
98
|
+
def define_special_method original_method, special_method, human_method, prefix
|
99
|
+
::Must::PositiveExpectation.define_method original_method do |*args, &block|
|
100
|
+
unless self.__send__ special_method, *args, &block
|
101
|
+
fail_expectation true, human_method, prefix, *args, &block
|
102
|
+
end
|
103
|
+
object
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def define_method original_method, method, human_method, prefix
|
108
|
+
::Must::PositiveExpectation.define_method original_method do |*args, &block|
|
109
|
+
unless object.send method, *args, &block
|
110
|
+
fail_expectation true, human_method, prefix, *args, &block
|
111
|
+
end
|
112
|
+
object
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
class NegativeExpectation < Expectation
|
118
|
+
def inspect; "<#Must::NegativeExpectation #{object.inspect}>" end
|
119
|
+
|
120
|
+
protected
|
121
|
+
def define_special_method original_method, special_method, human_method, prefix
|
122
|
+
::Must::NegativeExpectation.define_method original_method do |*args, &block|
|
123
|
+
if self.__send__ special_method, *args, &block
|
124
|
+
fail_expectation false, human_method, prefix, *args, &block
|
125
|
+
end
|
126
|
+
object
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def define_method original_method, method, human_method, prefix
|
131
|
+
::Must::NegativeExpectation.define_method original_method do |*args, &block|
|
132
|
+
if object.send method, *args, &block
|
133
|
+
fail_expectation false, human_method, prefix, *args, &block
|
134
|
+
end
|
135
|
+
object
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
data/readme.md
CHANGED
@@ -2,17 +2,24 @@ Collection of various utility classes and standard library extensions for Ruby l
|
|
2
2
|
|
3
3
|
## must - assertion tool, kind of RSpec assertions in runtime code
|
4
4
|
|
5
|
+
Expectations are generated dynamically, so it will be also available and have the same form
|
6
|
+
for any of Your custom methods.
|
7
|
+
|
8
|
+
It also doesn't pollute core Ruby classes very much, there are only 2 methods `must`, `must_not` added to
|
9
|
+
the `Object` class.
|
10
|
+
|
5
11
|
``` ruby
|
6
|
-
1.
|
7
|
-
|
8
|
-
|
9
|
-
value.
|
10
|
-
|
11
|
-
|
12
|
+
1.must.be_in 1..2
|
13
|
+
'a'.must.be_in 'a', 'b', 'c'
|
14
|
+
'a'.must.be_a String
|
15
|
+
'value'.must_not.be_nil
|
16
|
+
2.must.be > 1
|
17
|
+
[].must.be_empty
|
18
|
+
[1, 2, 3].must_not.have_any{|v| v == 4}
|
12
19
|
```
|
13
20
|
|
14
|
-
## inherit -
|
15
|
-
Do you remember this
|
21
|
+
## inherit - multiple inheritance in Ruby
|
22
|
+
Do you remember this `def self.included(base) ... end` You don't need it anymore.
|
16
23
|
|
17
24
|
``` ruby
|
18
25
|
module Feature
|
@@ -52,9 +59,9 @@ o.a => 'a'
|
|
52
59
|
o.to_hash => {a: 'a', b: 'b'}
|
53
60
|
```
|
54
61
|
|
55
|
-
##
|
62
|
+
## Callbacks
|
56
63
|
|
57
|
-
|
64
|
+
[TODO add desctiption]
|
58
65
|
|
59
66
|
# Usage
|
60
67
|
|
data/spec/more/callbacks_spec.rb
CHANGED
@@ -1,37 +1,53 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe "Callbacks" do
|
4
|
-
|
5
|
-
class ABase
|
6
|
-
inherit RubyExt::Callbacks
|
4
|
+
after{remove_constants :SomeClass, :AnotherClass}
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
describe 'basic' do
|
7
|
+
before do
|
8
|
+
class SomeClass
|
9
|
+
inherit RubyExt::Callbacks
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
set_callback :save, :before, :before_save
|
12
|
+
set_callback :save, :around, :around_save
|
13
|
+
set_callback :save, :after, :after_save
|
14
|
+
|
15
|
+
protected
|
16
|
+
def around_save
|
17
|
+
around_save_called
|
18
|
+
yield
|
19
|
+
end
|
20
|
+
end
|
17
21
|
end
|
18
|
-
end
|
19
|
-
after{remove_constants :ABase, :SomeClass, :AnotherClass}
|
20
22
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
23
|
+
it "basic" do
|
24
|
+
o = SomeClass.new
|
25
|
+
o.should_receive :before_save
|
26
|
+
o.should_receive :around_save_called
|
27
|
+
o.should_receive :after_save
|
28
|
+
o.run_callbacks(:save, :some_method){"result"}.should == "result"
|
29
|
+
end
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
it "should be possible to call before & after separatelly (in this mode :around is not available)" do
|
32
|
+
o = SomeClass.new
|
33
|
+
o.should_receive :before_save
|
34
|
+
o.run_before_callbacks :save, :some_method
|
35
|
+
o.should_receive :after_save
|
36
|
+
o.run_after_callbacks :save, :some_method
|
37
|
+
end
|
38
|
+
|
39
|
+
it "inheritance" do
|
40
|
+
class AnotherClass < SomeClass
|
41
|
+
set_callback :save, :before, :before_save2
|
42
|
+
end
|
43
|
+
|
44
|
+
o = AnotherClass.new
|
45
|
+
o.should_receive :before_save
|
46
|
+
o.should_receive :before_save2
|
47
|
+
o.should_receive :around_save_called
|
48
|
+
o.should_receive :after_save
|
49
|
+
o.run_callbacks(:save, :some_method){"result"}.should == "result"
|
50
|
+
end
|
35
51
|
end
|
36
52
|
|
37
53
|
it "blocks" do
|
@@ -55,7 +71,7 @@ describe "Callbacks" do
|
|
55
71
|
end
|
56
72
|
|
57
73
|
o = SomeClass.new
|
58
|
-
o.run_callbacks(:save){"result"}.should == "result"
|
74
|
+
o.run_callbacks(:save, :some_method){"result"}.should == "result"
|
59
75
|
o.result.should == [:before, :around_begin, :after, :around_end]
|
60
76
|
end
|
61
77
|
|
@@ -81,20 +97,7 @@ describe "Callbacks" do
|
|
81
97
|
o.should_receive(:around1_called).ordered.once
|
82
98
|
o.should_receive(:before2).ordered.once
|
83
99
|
o.should_receive(:after1).ordered.once
|
84
|
-
o.run_callbacks :save
|
85
|
-
end
|
86
|
-
|
87
|
-
it "inheritance" do
|
88
|
-
class SomeClass < ABase
|
89
|
-
set_callback :save, :before, :before_save2
|
90
|
-
end
|
91
|
-
|
92
|
-
o = SomeClass.new
|
93
|
-
o.should_receive :before_save
|
94
|
-
o.should_receive :before_save2
|
95
|
-
o.should_receive :around_save_called
|
96
|
-
o.should_receive :after_save
|
97
|
-
o.run_callbacks(:save){"result"}.should == "result"
|
100
|
+
o.run_callbacks :save, :some_method
|
98
101
|
end
|
99
102
|
|
100
103
|
it 'terminator' do
|
@@ -105,7 +108,7 @@ describe "Callbacks" do
|
|
105
108
|
set_callback :save, :before, :before_save2
|
106
109
|
|
107
110
|
def method
|
108
|
-
run_callbacks :save do
|
111
|
+
run_callbacks :save, :some_method do
|
109
112
|
"result"
|
110
113
|
end
|
111
114
|
end
|
@@ -118,7 +121,7 @@ describe "Callbacks" do
|
|
118
121
|
|
119
122
|
o = SomeClass.new
|
120
123
|
o.should_not_receive :before_save2
|
121
|
-
o.run_callbacks(:save){"result"}.should_not == "result"
|
124
|
+
o.run_callbacks(:save, :some_method){"result"}.should_not == "result"
|
122
125
|
end
|
123
126
|
|
124
127
|
it 'conditions' do
|
@@ -130,44 +133,44 @@ describe "Callbacks" do
|
|
130
133
|
|
131
134
|
o = SomeClass.new
|
132
135
|
o.should_not_receive :before_save
|
133
|
-
o.run_callbacks(:save,
|
136
|
+
o.run_callbacks(:save, :some_method){"result"}.should == 'result'
|
134
137
|
|
135
138
|
o = SomeClass.new
|
136
139
|
o.should_receive :before_save
|
137
|
-
o.run_callbacks(:save,
|
140
|
+
o.run_callbacks(:save, :another_method){"result"}.should == 'result'
|
138
141
|
end
|
139
142
|
|
140
143
|
it "if, unless conditions" do
|
141
144
|
c = RubyExt::Callbacks::AbstractCallback.new
|
142
145
|
c.conditions = {if: lambda{|target, inf| true}}
|
143
|
-
c.run?(nil, {}).should be_true
|
146
|
+
c.run?(nil, :some_method, {}).should be_true
|
144
147
|
|
145
148
|
c.conditions = {if: lambda{|target, inf| false}}
|
146
|
-
c.run?(nil, {}).should be_false
|
149
|
+
c.run?(nil, :some_method, {}).should be_false
|
147
150
|
|
148
151
|
c.conditions = {unless: lambda{|target, inf| true}}
|
149
|
-
c.run?(nil, {}).should be_false
|
152
|
+
c.run?(nil, :some_method, {}).should be_false
|
150
153
|
|
151
154
|
c.conditions = {unless: lambda{|target, inf| false}}
|
152
|
-
c.run?(nil, {}).should be_true
|
155
|
+
c.run?(nil, :some_method, {}).should be_true
|
153
156
|
end
|
154
157
|
|
155
158
|
it "only, except conditions" do
|
156
159
|
c = RubyExt::Callbacks::AbstractCallback.new
|
157
160
|
c.conditions = {only: :a}
|
158
|
-
c.run?(nil,
|
161
|
+
c.run?(nil, :a, {}).should be_true
|
159
162
|
|
160
163
|
c.conditions = {only: :b}
|
161
|
-
c.run?(nil,
|
164
|
+
c.run?(nil, :a, {}).should be_false
|
162
165
|
|
163
166
|
c.conditions = {except: :a}
|
164
|
-
c.run?(nil,
|
167
|
+
c.run?(nil, :a, {}).should be_false
|
165
168
|
|
166
169
|
c.conditions = {except: :b}
|
167
|
-
c.run?(nil,
|
170
|
+
c.run?(nil, :a, {}).should be_true
|
168
171
|
|
169
172
|
c.conditions = {only: :a}
|
170
|
-
c.run?(nil,
|
173
|
+
c.run?(nil, :a, {}).should be_true
|
171
174
|
end
|
172
175
|
|
173
176
|
|
@@ -184,7 +187,7 @@ describe "Callbacks" do
|
|
184
187
|
end
|
185
188
|
|
186
189
|
o = SomeClass.new
|
187
|
-
o.run_callbacks(:save){"result"}.should == 'another result'
|
190
|
+
o.run_callbacks(:save, :some_method){"result"}.should == 'another result'
|
188
191
|
end
|
189
192
|
|
190
193
|
describe "wrapping methods in callbacks" do
|
@@ -241,7 +244,7 @@ describe "Callbacks" do
|
|
241
244
|
o.update.should == 'ok2'
|
242
245
|
end
|
243
246
|
|
244
|
-
it "
|
247
|
+
it "callbacks should be runned only once" do
|
245
248
|
class SomeClass
|
246
249
|
inherit RubyExt::Callbacks
|
247
250
|
|
@@ -250,8 +253,8 @@ describe "Callbacks" do
|
|
250
253
|
|
251
254
|
o = SomeClass.new
|
252
255
|
o.should_receive(:before_save).once
|
253
|
-
(o.
|
254
|
-
o.
|
256
|
+
(o.run_callbacks :save, :some_method do
|
257
|
+
o.run_callbacks :save, :some_method do
|
255
258
|
'result'
|
256
259
|
end
|
257
260
|
end).should == 'result'
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe 'Assert' do
|
4
|
+
it 'misc' do
|
5
|
+
-> {must.be_never_called}.should raise_error(/must be never_called/)
|
6
|
+
-> {nil.must_not.be_nil}.should raise_error(/must not be nil/)
|
7
|
+
1.must_not.be_nil
|
8
|
+
|
9
|
+
1.must.be_in 1, 2
|
10
|
+
1.must.be_in [1, 2]
|
11
|
+
0.must.be_in 0..1
|
12
|
+
|
13
|
+
"".must.be_a String
|
14
|
+
"".must.be_a String, Symbol
|
15
|
+
|
16
|
+
2.must > 1
|
17
|
+
2.must.be > 1
|
18
|
+
|
19
|
+
1.must.be_defined
|
20
|
+
-> {nil.must.be_defined}.should raise_error(/must be defined/)
|
21
|
+
|
22
|
+
[1, 2].must.include 1
|
23
|
+
end
|
24
|
+
|
25
|
+
it "equality" do
|
26
|
+
1.must.be_equal_to 1
|
27
|
+
-> {1.must.be_equal_to 2}.should raise_error(/1 must be equal_to 2/)
|
28
|
+
1.must.be 1
|
29
|
+
-> {1.must.be 2}.should raise_error(/1 must be equal_to 2/)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'must & must_not' do
|
33
|
+
[].must.be_empty
|
34
|
+
[''].must_not.be_empty
|
35
|
+
|
36
|
+
-> {[''].must.be_empty}.should raise_error(/must be/)
|
37
|
+
-> {[].must_not.be_empty}.should raise_error(/must not be/)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should return result" do
|
41
|
+
[].must.be_empty.should == []
|
42
|
+
end
|
43
|
+
|
44
|
+
it "have", focus: true do
|
45
|
+
[1, 2, 3].must_not.have_any{|v| v == 4}
|
46
|
+
-> {[1, 2, 3].must_not.have_any{|v| v == 2}}.should raise_error(/[1, 2, 3] must not have any/)
|
47
|
+
end
|
48
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby_ext
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 4.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-
|
12
|
+
date: 2011-11-01 00:00:00.000000000Z
|
13
13
|
dependencies: []
|
14
14
|
description:
|
15
15
|
email:
|
@@ -31,7 +31,6 @@ files:
|
|
31
31
|
- lib/ruby_ext/core/hash.rb
|
32
32
|
- lib/ruby_ext/core/module.rb
|
33
33
|
- lib/ruby_ext/core/multiple_inheritance.rb
|
34
|
-
- lib/ruby_ext/core/must.rb
|
35
34
|
- lib/ruby_ext/core/nil_class.rb
|
36
35
|
- lib/ruby_ext/core/not_defined.rb
|
37
36
|
- lib/ruby_ext/core/object.rb
|
@@ -42,10 +41,13 @@ files:
|
|
42
41
|
- lib/ruby_ext/core/true_class.rb
|
43
42
|
- lib/ruby_ext/core.rb
|
44
43
|
- lib/ruby_ext/more/callbacks.rb
|
44
|
+
- lib/ruby_ext/more/callbacks_proxy.rb
|
45
45
|
- lib/ruby_ext/more/declarative_cache.rb
|
46
|
+
- lib/ruby_ext/more/must.rb
|
46
47
|
- lib/ruby_ext/more/observable.rb
|
47
48
|
- lib/ruby_ext/more/open_constructor.rb
|
48
49
|
- lib/ruby_ext/more/tuple.rb
|
50
|
+
- lib/ruby_ext/more/user_error.rb
|
49
51
|
- lib/ruby_ext/more.rb
|
50
52
|
- lib/ruby_ext.rb
|
51
53
|
- lib/yaml_fix.rb
|
@@ -54,11 +56,11 @@ files:
|
|
54
56
|
- spec/core/enumerable.rb
|
55
57
|
- spec/core/module_spec.rb
|
56
58
|
- spec/core/multiple_inheritance_spec.rb
|
57
|
-
- spec/core/must_spec.rb
|
58
59
|
- spec/core/object_spec.rb
|
59
60
|
- spec/core/open_object_spec.rb
|
60
61
|
- spec/more/callbacks_spec.rb
|
61
62
|
- spec/more/declarative_cache_spec.rb
|
63
|
+
- spec/more/must_spec.rb
|
62
64
|
- spec/more/observable_spec.rb
|
63
65
|
- spec/more/open_constructor_spec.rb
|
64
66
|
- spec/spec_helper.rb
|
data/lib/ruby_ext/core/must.rb
DELETED
@@ -1,179 +0,0 @@
|
|
1
|
-
class AssertionError < RuntimeError; end
|
2
|
-
|
3
|
-
class MustAssertions < BasicObject
|
4
|
-
attr_reader :obj
|
5
|
-
|
6
|
-
def initialize obj
|
7
|
-
@obj = obj
|
8
|
-
end
|
9
|
-
|
10
|
-
def == o
|
11
|
-
@obj == o
|
12
|
-
end
|
13
|
-
|
14
|
-
def =~ o
|
15
|
-
@obj =~ o
|
16
|
-
end
|
17
|
-
|
18
|
-
def never_called
|
19
|
-
false
|
20
|
-
end
|
21
|
-
|
22
|
-
def nil
|
23
|
-
@obj.equal? nil
|
24
|
-
end
|
25
|
-
|
26
|
-
def defined
|
27
|
-
@obj != nil
|
28
|
-
end
|
29
|
-
|
30
|
-
def respond_to method
|
31
|
-
@obj.respond_to? method
|
32
|
-
end
|
33
|
-
|
34
|
-
def a *args
|
35
|
-
if args.class == ::Array
|
36
|
-
args.any?{|k| @obj.is_a? k}
|
37
|
-
else
|
38
|
-
@obj.is_a? args
|
39
|
-
end
|
40
|
-
end
|
41
|
-
alias_method :an, :a
|
42
|
-
|
43
|
-
def include o
|
44
|
-
@obj.include? o
|
45
|
-
end
|
46
|
-
|
47
|
-
def in *args
|
48
|
-
if args.size == 1
|
49
|
-
obj = args.first
|
50
|
-
if obj.is_a?(::Array) or obj.is_a?(::Range)
|
51
|
-
obj.include? @obj
|
52
|
-
else
|
53
|
-
args.include? @obj
|
54
|
-
end
|
55
|
-
else
|
56
|
-
args.include? @obj
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def true
|
61
|
-
!!@obj
|
62
|
-
end
|
63
|
-
|
64
|
-
def false
|
65
|
-
!@obj
|
66
|
-
end
|
67
|
-
|
68
|
-
def empty
|
69
|
-
@obj.empty?
|
70
|
-
end
|
71
|
-
|
72
|
-
def blank
|
73
|
-
@obj.blank?
|
74
|
-
end
|
75
|
-
|
76
|
-
def present
|
77
|
-
!@obj.blank?
|
78
|
-
end
|
79
|
-
|
80
|
-
def > o
|
81
|
-
@obj > o
|
82
|
-
end
|
83
|
-
|
84
|
-
def < o
|
85
|
-
@obj < o
|
86
|
-
end
|
87
|
-
|
88
|
-
def >= o
|
89
|
-
@obj >= o
|
90
|
-
end
|
91
|
-
|
92
|
-
def <= o
|
93
|
-
@obj <= o
|
94
|
-
end
|
95
|
-
|
96
|
-
def exist *args
|
97
|
-
@obj.exist? *args
|
98
|
-
end
|
99
|
-
|
100
|
-
def be
|
101
|
-
@prefix = 'be'
|
102
|
-
self
|
103
|
-
end
|
104
|
-
|
105
|
-
def have
|
106
|
-
@prefix = 'have'
|
107
|
-
self
|
108
|
-
end
|
109
|
-
|
110
|
-
def self.assertions
|
111
|
-
special = [:be, :have]
|
112
|
-
public_instance_methods.select{|m| m !~ /^__/ and !special.include?(m)}
|
113
|
-
end
|
114
|
-
|
115
|
-
protected
|
116
|
-
# def method_missing m, *args, &b
|
117
|
-
# raise ::RuntimeError, "Assertion '#{m}' is unknown!", caller[1..-1]
|
118
|
-
# end
|
119
|
-
|
120
|
-
def failed method, negative, *args
|
121
|
-
stack = ::Object.send(:caller).sfilter('must.rb')
|
122
|
-
|
123
|
-
unless args.empty?
|
124
|
-
::Object.send :raise, ::AssertionError, "
|
125
|
-
ASSERTION FAILED (#{stack.first}):
|
126
|
-
#{@obj.inspect} must #{'not ' if negative}#{"#{@prefix} " if @prefix}#{method} #{args.collect{|a| a.inspect}.join(', ')}
|
127
|
-
", stack
|
128
|
-
else
|
129
|
-
::Object.send :raise, ::AssertionError, "
|
130
|
-
ASSERTION FAILED (#{stack.first}):
|
131
|
-
#{@obj.inspect} must #{'not ' if negative}#{"#{@prefix} " if @prefix}#{method}
|
132
|
-
", stack
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
class Must < MustAssertions
|
138
|
-
assertions.each do |m|
|
139
|
-
desition = "_#{m}"
|
140
|
-
alias_method desition, m
|
141
|
-
define_method m do |*args|
|
142
|
-
failed m, false, *args unless __send__(desition, *args)
|
143
|
-
@obj
|
144
|
-
end
|
145
|
-
end
|
146
|
-
|
147
|
-
def inspect
|
148
|
-
"<#Must>"
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
class MustNot < MustAssertions
|
153
|
-
assertions.each do |m|
|
154
|
-
desition = "_#{m}".to_sym
|
155
|
-
alias_method desition, m
|
156
|
-
define_method m do |*args|
|
157
|
-
failed m, true, *args if __send__(desition, *args)
|
158
|
-
@obj
|
159
|
-
end
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
|
-
Object.class_eval do
|
164
|
-
def must
|
165
|
-
Must.new(self)
|
166
|
-
end
|
167
|
-
|
168
|
-
def must_not
|
169
|
-
MustNot.new(self)
|
170
|
-
end
|
171
|
-
|
172
|
-
def must_be
|
173
|
-
must.be
|
174
|
-
end
|
175
|
-
|
176
|
-
def must_not_be
|
177
|
-
must_not.be
|
178
|
-
end
|
179
|
-
end
|
data/spec/core/must_spec.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe 'Assert' do
|
4
|
-
it 'must & must_not' do
|
5
|
-
-> {must_be.never_called}.should raise_error(/ever/)
|
6
|
-
-> {nil.must_not_be.nil}.should raise_error(/nil/)
|
7
|
-
1.must_not_be.nil
|
8
|
-
1.must_be.== 1
|
9
|
-
-> {1.must_be.== 2}.should raise_error(%r{==})
|
10
|
-
1.must_be.in 1, 2
|
11
|
-
1.must_be.in [1, 2]
|
12
|
-
0.must_be.in 0..1
|
13
|
-
"".must_be.a String
|
14
|
-
"".must_be.a String, Symbol
|
15
|
-
1.must_be.< 2
|
16
|
-
|
17
|
-
1.must_be.defined
|
18
|
-
-> {nil.must_be.defined}.should raise_error(/must be defined/)
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'must_be & must_not_be' do
|
22
|
-
[].must_be.empty
|
23
|
-
[''].must_not_be.empty
|
24
|
-
|
25
|
-
-> {[''].must_be.empty}.should raise_error(/must be/)
|
26
|
-
-> {[].must_not_be.empty}.should raise_error(/must not be/)
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should return result" do
|
30
|
-
[].must_be.empty.should == []
|
31
|
-
end
|
32
|
-
end
|