Module: MustBe
- Included in:
- Object
- Defined in:
- lib/must_be/core.rb,
lib/must_be/basic.rb,
lib/must_be/proxy.rb,
lib/must_be/containers.rb,
lib/must_be/nonstandard_control_flow.rb
Defined Under Namespace
Modules: MustOnlyEverContain
Classes: ContainerNote, Note, PairNote, Proxy
Constant Summary
collapse
- SHORT_INSPECT_CUTOFF_LENGTH =
200
- SHORT_INSPECT_WORD_BREAK_LENGTH =
20
- SHORT_INSPECT_ELLIPSES =
"..."
- NOTIFIERS =
{}
- @@disabled_method_for_method =
Hash.new(:must_just_return)
- @@disabled_handlers =
[]
Class Attribute Summary collapse
Class Method Summary
collapse
-
.check_pair_against_hash_cases(key, value, cases, negate = false) ⇒ Object
-
.def_notifier(constant_name, key = nil, ¬ifier) ⇒ Object
-
.disable ⇒ Object
-
.enable ⇒ Object
-
.enabled? ⇒ Boolean
-
.match_any_case?(v, cases) ⇒ Boolean
-
.must_check_member_against_cases(container, member, cases, negate = false) ⇒ Object
-
.must_check_pair_against_hash_cases(container, key, value, cases, negate = false) ⇒ Object
-
.must_only_contain(container, cases, negate = false) ⇒ Object
-
.must_only_ever_contain(container, cases, negate = false) ⇒ Object
-
.register_disabled_handler(&handler) ⇒ Object
-
.register_disabled_method(method_name, disabled_method_name = method_name) ⇒ Object
-
.set_notifier_from_env(key = ) ⇒ Object
-
.short_inspect(obj) ⇒ Object
Instance Method Summary
collapse
-
#must(message = nil, &block) ⇒ Object
-
#must_be(*cases) ⇒ Object
-
#must_be_a(*modules) ⇒ Object
-
#must_be_boolean ⇒ Object
-
#must_be_close(expected, delta = 0.1) ⇒ Object
-
#must_be_false ⇒ Object
-
#must_be_in(*collection) ⇒ Object
-
#must_be_nil ⇒ Object
-
#must_be_true ⇒ Object
-
#must_check(check_block = nil, &block) ⇒ Object
-
#must_just_return(*args) ⇒ Object
-
#must_just_yield(*args) ⇒ Object
-
#must_never_ever_contain(*cases) ⇒ Object
-
#must_not(message = nil, &block) ⇒ Object
-
#must_not_be(*cases) ⇒ Object
-
#must_not_be_a(*modules) ⇒ Object
-
#must_not_be_close(expected, delta = 0.1) ⇒ Object
-
#must_not_be_in(*collection) ⇒ Object
-
#must_not_be_nil ⇒ Object
-
#must_not_contain(*cases) ⇒ Object
-
#must_not_raise(*args, &block) ⇒ Object
-
#must_not_throw(*args, &block) ⇒ Object
-
#must_notify(receiver = nil, assertion = nil, args = nil, block = nil, additional_message = nil) ⇒ Object
-
#must_only_contain(*cases) ⇒ Object
-
#must_only_ever_contain(*cases) ⇒ Object
-
#must_raise(*args, &block) ⇒ Object
-
#must_throw(*args, &block) ⇒ Object
Class Attribute Details
should respond_to? :call with Note argument.
100
101
102
|
# File 'lib/must_be/core.rb', line 100
def notifier
@notifier
end
|
Class Method Details
.check_pair_against_hash_cases(key, value, cases, negate = false) ⇒ Object
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
# File 'lib/must_be/containers.rb', line 65
def self.check_pair_against_hash_cases(key, value, cases, negate = false)
if negate
if cases.empty?
!key and !value
else
cases.all? do |c|
c.all? do |k, v|
not (match_any_case?(key, k) and match_any_case?(value, v))
end
end
end
else
if cases.empty?
key and value
else
cases.any? do |c|
c.any? do |k, v|
match_any_case?(key, k) and match_any_case?(value, v)
end
end
end
end
end
|
.def_notifier(constant_name, key = nil, ¬ifier) ⇒ Object
102
103
104
105
|
# File 'lib/must_be/core.rb', line 102
def def_notifier(constant_name, key = nil, ¬ifier)
const_set(constant_name, notifier)
NOTIFIERS[key] = constant_name if key
end
|
38
39
40
41
42
43
44
45
46
47
48
49
|
# File 'lib/must_be/core.rb', line 38
def disable
return unless enabled?
@disabled_methods = instance_methods.map do |method_name|
method_name = method_name.to_sym
method = instance_method(method_name)
disabled_method_name = @@disabled_method_for_method[method_name]
alias_method method_name, disabled_method_name
[method_name, method]
end
invoke_disabled_handlers
end
|
51
52
53
54
55
56
57
58
59
|
# File 'lib/must_be/core.rb', line 51
def enable
return if enabled?
@disabled_methods.each do |method_record|
define_method(*method_record)
end
@disabled_methods = nil
invoke_disabled_handlers
end
|
.enabled? ⇒ Boolean
61
62
63
|
# File 'lib/must_be/core.rb', line 61
def enabled?
@disabled_methods.nil?
end
|
.match_any_case?(v, cases) ⇒ Boolean
2
3
4
5
|
# File 'lib/must_be/basic.rb', line 2
def self.match_any_case?(v, cases)
cases = [cases] unless cases.is_a? Array
cases.any? {|c| c === v }
end
|
.must_check_member_against_cases(container, member, cases, negate = false) ⇒ Object
89
90
91
92
93
94
95
96
97
98
99
100
101
|
# File 'lib/must_be/containers.rb', line 89
def self.must_check_member_against_cases(container, member, cases,
negate = false)
member.must_check(lambda do
if negate
member.must_not_be(*cases)
else
member.must_be(*cases)
end
end) do |note|
note = ContainerNote.new(note, container)
block_given? ? yield(note) : note
end
end
|
.must_check_pair_against_hash_cases(container, key, value, cases, negate = false) ⇒ Object
103
104
105
106
107
108
109
|
# File 'lib/must_be/containers.rb', line 103
def self.must_check_pair_against_hash_cases(container, key, value, cases,
negate = false)
unless MustBe.check_pair_against_hash_cases(key, value, cases, negate)
note = PairNote.new(key, value, cases, container, negate)
must_notify(block_given? ? yield(note) : note)
end
end
|
.must_only_contain(container, cases, negate = false) ⇒ Object
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
# File 'lib/must_be/containers.rb', line 111
def self.must_only_contain(container, cases, negate = false)
prefix = negate ? "must_not_contain: " : "must_only_contain: "
advice = MustOnlyEverContain.registered_class(container)
if advice and advice.respond_to? :must_only_contain_check
advice.must_only_contain_check(container, cases, negate)
elsif container.respond_to? :each_pair
container.each_pair do |key, value|
MustBe.must_check_pair_against_hash_cases(container, key, value,
cases, negate) do |note|
note.prefix = prefix
note
end
end
else
container.each do |member|
MustBe.must_check_member_against_cases(container, member, cases,
negate) do |note|
note.prefix = prefix
note
end
end
end
container
end
|
.must_only_ever_contain(container, cases, negate = false) ⇒ Object
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
|
# File 'lib/must_be/containers.rb', line 268
def self.must_only_ever_contain(container, cases, negate = false)
unless container.singleton_methods.empty?
method_name = "must_#{negate ? "never" : "only"}_ever_contain"
raise ArgumentError, "#{method_name} adds singleton methods but"\
" receiver #{MustBe.short_inspect(container)} already"\
" has singleton methods #{container.singleton_methods.inspect}"
end
advice = MustOnlyEverContain.registered_class(container)
if advice
container.extend advice
container.must_only_ever_contain_backtrace = caller
container.must_only_ever_contain_negate = negate
container.must_only_ever_contain_cases = cases
else
raise TypeError,
"No MustOnlyEverContain.registered_class for #{container.class}"
end
container
end
|
.register_disabled_handler(&handler) ⇒ Object
71
72
73
74
|
# File 'lib/must_be/core.rb', line 71
def register_disabled_handler(&handler)
@@disabled_handlers << handler
handler[enabled?] unless enabled?
end
|
.register_disabled_method(method_name, disabled_method_name = method_name) ⇒ Object
65
66
67
68
69
|
# File 'lib/must_be/core.rb', line 65
def register_disabled_method(method_name,
disabled_method_name = method_name)
@@disabled_method_for_method[method_name.to_sym] =
disabled_method_name.to_sym
end
|
.set_notifier_from_env(key = ) ⇒ Object
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
# File 'lib/must_be/core.rb', line 107
def set_notifier_from_env(key = ENV['MUST_BE__NOTIFIER'])
key = key.to_sym
if key == :disable
disable
return
end
constant_name = NOTIFIERS[key]
unless constant_name
raise ArgumentError, "no MustBe::NOTIFIERS called #{key.inspect}"
end
self.notifier = const_get(constant_name)
end
|
Instance Method Details
#must(message = nil, &block) ⇒ Object
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
# File 'lib/must_be/proxy.rb', line 33
def must(message = nil, &block)
if block_given?
unless block.arity > 1 ? yield(self, message) : yield(self)
if message
must_notify(message)
else
must_notify(self, :must, nil, block)
end
end
self
else
Proxy.new(self, :must)
end
end
|
#must_be(*cases) ⇒ Object
7
8
9
10
11
12
|
# File 'lib/must_be/basic.rb', line 7
def must_be(*cases)
unless cases.empty? ? self : MustBe.match_any_case?(self, cases)
must_notify(self, :must_be, cases, nil, ", but matches #{self.class}")
end
self
end
|
#must_be_a(*modules) ⇒ Object
43
44
45
|
# File 'lib/must_be/basic.rb', line 43
def must_be_a(*modules)
must_be_a__body(modules, :none?, :must_be_a)
end
|
#must_be_boolean ⇒ Object
87
88
89
90
91
92
|
# File 'lib/must_be/basic.rb', line 87
def must_be_boolean
unless self == true or self == false
must_notify(self, :must_be_boolean)
end
self
end
|
#must_be_close(expected, delta = 0.1) ⇒ Object
94
95
96
97
98
99
100
101
|
# File 'lib/must_be/basic.rb', line 94
def must_be_close(expected, delta = 0.1)
difference = (self - expected).abs
unless difference < delta
must_notify(self, :must_be_close, [expected, delta], nil,
", difference is #{difference}")
end
self
end
|
#must_be_false ⇒ Object
82
83
84
85
|
# File 'lib/must_be/basic.rb', line 82
def must_be_false
must_notify(self, :must_be_false) unless self == false
self
end
|
#must_be_in(*collection) ⇒ Object
51
52
53
54
55
56
57
|
# File 'lib/must_be/basic.rb', line 51
def must_be_in(*collection)
cs = collection.size == 1 ? collection[0] : collection
unless cs.include? self
must_notify(self, :must_be_in, collection)
end
self
end
|
#must_be_nil ⇒ Object
67
68
69
70
|
# File 'lib/must_be/basic.rb', line 67
def must_be_nil
must_notify(self, :must_be_nil) unless nil?
self
end
|
#must_be_true ⇒ Object
77
78
79
80
|
# File 'lib/must_be/basic.rb', line 77
def must_be_true
must_notify(self, :must_be_true) unless self == true
self
end
|
#must_check(check_block = nil, &block) ⇒ Object
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
|
# File 'lib/must_be/core.rb', line 213
def must_check(check_block = nil, &block)
if check_block
result = nil
note = must_check do |obj|
result = check_block.arity.zero? ? check_block[] : check_block[obj]
end
if note
must_notify(block[note])
end
return result
end
begin
was_checking = Thread.current[:must_check__is_checking]
Thread.current[:must_check__is_checking] = true
already_found = Thread.current[:must_check__found_note]
Thread.current[:must_check__found_note] = nil
yield(self)
Thread.current[:must_check__found_note]
ensure
Thread.current[:must_check__is_checking] = was_checking
Thread.current[:must_check__found_note] = already_found
end
end
|
#must_just_return(*args) ⇒ Object
83
84
85
|
# File 'lib/must_be/core.rb', line 83
def must_just_return(*args)
self
end
|
#must_just_yield(*args) ⇒ Object
89
90
91
|
# File 'lib/must_be/core.rb', line 89
def must_just_yield(*args)
yield
end
|
#must_never_ever_contain(*cases) ⇒ Object
293
294
295
|
# File 'lib/must_be/containers.rb', line 293
def must_never_ever_contain(*cases)
MustBe.must_only_ever_contain(self, cases, true)
end
|
#must_not(message = nil, &block) ⇒ Object
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
# File 'lib/must_be/proxy.rb', line 48
def must_not(message = nil, &block)
if block_given?
if block.arity > 1 ? yield(self, message) : yield(self)
if message
must_notify(message)
else
must_notify(self, :must_not, nil, block)
end
end
self
else
Proxy.new(self, :must_not)
end
end
|
#must_not_be(*cases) ⇒ Object
14
15
16
17
18
19
|
# File 'lib/must_be/basic.rb', line 14
def must_not_be(*cases)
if cases.empty? ? self : MustBe.match_any_case?(self, cases)
must_notify(self, :must_not_be, cases, nil, ", but matches #{self.class}")
end
self
end
|
#must_not_be_a(*modules) ⇒ Object
47
48
49
|
# File 'lib/must_be/basic.rb', line 47
def must_not_be_a(*modules)
must_be_a__body(modules, :any?, :must_not_be_a)
end
|
#must_not_be_close(expected, delta = 0.1) ⇒ Object
103
104
105
106
107
108
|
# File 'lib/must_be/basic.rb', line 103
def must_not_be_close(expected, delta = 0.1)
if (self - expected).abs < delta
must_notify(self, :must_not_be_close, [expected, delta])
end
self
end
|
#must_not_be_in(*collection) ⇒ Object
59
60
61
62
63
64
65
|
# File 'lib/must_be/basic.rb', line 59
def must_not_be_in(*collection)
cs = collection.size == 1 ? collection[0] : collection
if cs.include? self
must_notify(self, :must_not_be_in, collection)
end
self
end
|
#must_not_be_nil ⇒ Object
72
73
74
75
|
# File 'lib/must_be/basic.rb', line 72
def must_not_be_nil
must_notify(self, :must_not_be_nil) if nil?
self
end
|
#must_not_contain(*cases) ⇒ Object
141
142
143
|
# File 'lib/must_be/containers.rb', line 141
def must_not_contain(*cases)
MustBe.must_only_contain(self, cases, true)
end
|
#must_not_raise(*args, &block) ⇒ Object
76
77
78
|
# File 'lib/must_be/nonstandard_control_flow.rb', line 76
def must_not_raise(*args, &block)
must_raise__body(:must_not_raise, args, &block)
end
|
#must_not_throw(*args, &block) ⇒ Object
153
154
155
|
# File 'lib/must_be/nonstandard_control_flow.rb', line 153
def must_not_throw(*args, &block)
must_throw__body(:must_not_throw, args, &block)
end
|
#must_notify(receiver = nil, assertion = nil, args = nil, block = nil, additional_message = nil) ⇒ Object
201
202
203
204
205
206
207
208
209
210
211
|
# File 'lib/must_be/core.rb', line 201
def must_notify(receiver = nil, assertion= nil, args = nil, block = nil,
additional_message = nil)
note = Note === receiver ? receiver :
Note.new(receiver, assertion, args, block, additional_message)
if Thread.current[:must_check__is_checking]
Thread.current[:must_check__found_note] = note
else
raise note if MustBe.notifier.call(note)
end
note
end
|
#must_only_contain(*cases) ⇒ Object
137
138
139
|
# File 'lib/must_be/containers.rb', line 137
def must_only_contain(*cases)
MustBe.must_only_contain(self, cases)
end
|
#must_only_ever_contain(*cases) ⇒ Object
#must_raise(*args, &block) ⇒ Object
72
73
74
|
# File 'lib/must_be/nonstandard_control_flow.rb', line 72
def must_raise(*args, &block)
must_raise__body(:must_raise, args, &block)
end
|
#must_throw(*args, &block) ⇒ Object
149
150
151
|
# File 'lib/must_be/nonstandard_control_flow.rb', line 149
def must_throw(*args, &block)
must_throw__body(:must_throw, args, &block)
end
|