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 =
Short Inspect ###
200- SHORT_INSPECT_WORD_BREAK_LENGTH =
20- SHORT_INSPECT_ELLIPSES =
"..."- NOTIFIERS =
Notifiers ###
{}
- @@disabled_method_for_method =
Enable ###
Hash.new(:must_just_return)
- @@disabled_handlers =
[]
Class Attribute Summary collapse
-
.notifier ⇒ Object
should respond_to? :call with Note argument.
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
.notifier ⇒ Object
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 |
.disable ⇒ Object
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 |
.enable ⇒ Object
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 |
.short_inspect(obj) ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/must_be/core.rb', line 9 def self.short_inspect(obj) s = obj.inspect if s.bytesize > SHORT_INSPECT_CUTOFF_LENGTH real_cutoff = SHORT_INSPECT_CUTOFF_LENGTH - SHORT_INSPECT_ELLIPSES.length left_side = (real_cutoff + 1) / 2 right_side = -(real_cutoff / 2) left_start = left_side - SHORT_INSPECT_WORD_BREAK_LENGTH left_word_break_area = s[left_start, SHORT_INSPECT_WORD_BREAK_LENGTH] left_word_break = left_word_break_area.rindex(/\b\s/) start = left_word_break ? left_start + left_word_break + 1 : left_side right_start = right_side right_word_break_area = s[right_start, SHORT_INSPECT_WORD_BREAK_LENGTH] right_word_break = right_word_break_area.index(/\s\b/) stop = right_word_break ? right_start + right_word_break : right_side s = s.dup s[start...stop] = SHORT_INSPECT_ELLIPSES end s 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( = nil, &block) if block_given? unless block.arity > 1 ? yield(self, ) : yield(self) if must_notify() 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( = nil, &block) if block_given? if block.arity > 1 ? yield(self, ) : yield(self) if must_notify() 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, = nil) note = Note === receiver ? receiver : Note.new(receiver, assertion, args, block, ) 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
289 290 291 |
# File 'lib/must_be/containers.rb', line 289 def must_only_ever_contain(*cases) MustBe.must_only_ever_contain(self, cases) end |
#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 |