must_be 1.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/.gitignore +2 -0
- data/README.md +348 -0
- data/Rakefile +27 -0
- data/VERSION +1 -0
- data/doc/readme/examples.rb +262 -0
- data/doc/readme/run_examples.rb +47 -0
- data/lib/must_be/attr_typed.rb +78 -0
- data/lib/must_be/basic.rb +120 -0
- data/lib/must_be/containers.rb +291 -0
- data/lib/must_be/containers_registered_classes.rb +83 -0
- data/lib/must_be/core.rb +247 -0
- data/lib/must_be/nonstandard_control_flow.rb +159 -0
- data/lib/must_be/proxy.rb +62 -0
- data/lib/must_be.rb +9 -0
- data/must_be.gemspec +71 -0
- data/spec/must_be/attr_typed_spec.rb +225 -0
- data/spec/must_be/basic_spec.rb +578 -0
- data/spec/must_be/containers_spec.rb +952 -0
- data/spec/must_be/core_spec.rb +675 -0
- data/spec/must_be/nonstandard_control_flow_spec.rb +845 -0
- data/spec/must_be/proxy_spec.rb +194 -0
- data/spec/notify_matcher_spec.rb +59 -0
- data/spec/spec_helper.rb +180 -0
- data/spec/typical_usage_spec.rb +176 -0
- metadata +98 -0
@@ -0,0 +1,194 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MustBe do
|
4
|
+
include MustBeExampleHelper
|
5
|
+
|
6
|
+
describe Proxy do
|
7
|
+
subject { Proxy.new(:moxie) }
|
8
|
+
|
9
|
+
context "when initialized with method other than :must or :must_not" do
|
10
|
+
it "should raise ArgumentError" do
|
11
|
+
expect do
|
12
|
+
Proxy.new(:moxie, :must_could)
|
13
|
+
end.should raise_error(ArgumentError,
|
14
|
+
"assertion (:must_could) must be :must or :must_not")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe "it should not forward" do
|
19
|
+
example "#__id__" do
|
20
|
+
subject.__id__.should_not == :moxie.__id__
|
21
|
+
end
|
22
|
+
|
23
|
+
example "#object_id" do
|
24
|
+
subject.object_id.should_not == :moxie.object_id
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
module ItShouldNotifyExpectations
|
30
|
+
def it_should_notify(message, &implementation)
|
31
|
+
example "#{message} should notify" do
|
32
|
+
instance_eval &implementation
|
33
|
+
should notify(message)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def it_should_not_notify(message, &implementation)
|
38
|
+
example "#{message} should not notify" do
|
39
|
+
instance_eval &implementation
|
40
|
+
should_not notify
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe '#must' do
|
46
|
+
extend ItShouldNotifyExpectations
|
47
|
+
|
48
|
+
context "when called with a block" do
|
49
|
+
it "should return the receiver" do
|
50
|
+
0xdad.must{}.object_id.should == 0xdad.object_id
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should notify if block returns false" do
|
54
|
+
:helm.must{|receiver| receiver == :harm }.should == :helm
|
55
|
+
should notify(":helm.must {}")
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should notify with message if provided" do
|
59
|
+
:ice.must("ice must be icy") do |receiver|
|
60
|
+
receiver == :icy
|
61
|
+
end.should == :ice
|
62
|
+
should notify("ice must be icy")
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should not notify if block returns true" do
|
66
|
+
:jinn.must{|receiver| receiver == :jinn }.should == :jinn
|
67
|
+
should_not notify
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should allow nested #must_notify" do
|
71
|
+
:keys.must("electrify kites") do |receiver, message|
|
72
|
+
must_notify("#{receiver} must #{message}")
|
73
|
+
true
|
74
|
+
end.should == :keys
|
75
|
+
should notify("keys must electrify kites")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context "when used to proxy" do
|
80
|
+
subject { 230579.must }
|
81
|
+
|
82
|
+
it_should_notify("230579.must.==(70581)") do
|
83
|
+
subject == 70581
|
84
|
+
end
|
85
|
+
|
86
|
+
it_should_not_notify("230579.must.>(411)") do
|
87
|
+
subject > 411
|
88
|
+
end
|
89
|
+
|
90
|
+
it_should_not_notify("230579.must.odd?") do
|
91
|
+
subject.odd?
|
92
|
+
end
|
93
|
+
|
94
|
+
it_should_notify("230579.must.between?(-4, 4)") do
|
95
|
+
subject.between?(-4, 4)
|
96
|
+
end
|
97
|
+
|
98
|
+
it_should_notify("230579.must.respond_to?(:finite?)") do
|
99
|
+
subject.respond_to? :finite?
|
100
|
+
end
|
101
|
+
|
102
|
+
it_should_not_notify("230579.must.instance_of?(Fixnum)") do
|
103
|
+
subject.instance_of? Fixnum
|
104
|
+
end
|
105
|
+
|
106
|
+
it_should_notify("230579.must.instance_of?(Integer)") do
|
107
|
+
subject.instance_of? Integer
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should have a different #object_id" do
|
111
|
+
subject.should == 230579
|
112
|
+
subject.object_id.should_not == 230579.object_id
|
113
|
+
end
|
114
|
+
|
115
|
+
context "after MustBe.disable" do
|
116
|
+
before_disable_after_enable
|
117
|
+
|
118
|
+
it "should have the same #object_id" do
|
119
|
+
subject.object_id.should == 230579.object_id
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe '#must_not' do
|
126
|
+
extend ItShouldNotifyExpectations
|
127
|
+
|
128
|
+
context "when called with a block" do
|
129
|
+
it "should return the receiver" do
|
130
|
+
0xdad.must_not{}.should == 0xdad
|
131
|
+
end
|
132
|
+
|
133
|
+
it "should notify if block returns true" do
|
134
|
+
:helm.must_not{|receiver| receiver == :helm }.should == :helm
|
135
|
+
should notify(":helm.must_not {}")
|
136
|
+
end
|
137
|
+
|
138
|
+
it "should notify with message if provided" do
|
139
|
+
:ice.must_not("ice must not be ice") do |receiver|
|
140
|
+
receiver == :ice
|
141
|
+
end.should == :ice
|
142
|
+
should notify("ice must not be ice")
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should not notify if block returns false" do
|
146
|
+
:jinn.must_not{|receiver| receiver == :gem }.should == :jinn
|
147
|
+
should_not notify
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should allow nested #must_notify" do
|
151
|
+
:keys.must_not("electrify kites") do |receiver, message|
|
152
|
+
must_notify("#{receiver} must not #{message}")
|
153
|
+
false
|
154
|
+
end.should == :keys
|
155
|
+
should notify("keys must not electrify kites")
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
context "when used to proxy" do
|
160
|
+
subject { 230579.must_not }
|
161
|
+
|
162
|
+
it_should_not_notify("230579.must_not.==(70581)") do
|
163
|
+
subject == 70581
|
164
|
+
end
|
165
|
+
|
166
|
+
it_should_notify("230579.must_not.>(411)") do
|
167
|
+
subject > 411
|
168
|
+
end
|
169
|
+
|
170
|
+
it_should_notify("230579.must_not.odd?") do
|
171
|
+
subject.odd?
|
172
|
+
end
|
173
|
+
|
174
|
+
it_should_not_notify("230579.must_not.between?(-4, 4)") do
|
175
|
+
subject.between?(-4, 4)
|
176
|
+
end
|
177
|
+
|
178
|
+
it_should_not_notify(
|
179
|
+
"230579.must_not.respond_to?(:finite?)") do
|
180
|
+
subject.respond_to? :finite?
|
181
|
+
end
|
182
|
+
|
183
|
+
it_should_notify("230579.must_not.instance_of?(Fixnum)") do
|
184
|
+
subject.instance_of? Fixnum
|
185
|
+
end
|
186
|
+
|
187
|
+
it_should_not_notify(
|
188
|
+
"230579.must_not.instance_of?(Integer)") do
|
189
|
+
subject.instance_of? Integer
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# Since the notify matcher has lots of cases, we should spec out each
|
4
|
+
# possible combination to make sure it has the expected behavior.
|
5
|
+
#
|
6
|
+
# Patterns are built by choosing:
|
7
|
+
# Whether there is a note:
|
8
|
+
# :note
|
9
|
+
# :no_note
|
10
|
+
# Polarity of the expectation:
|
11
|
+
# :should
|
12
|
+
# :should_not
|
13
|
+
# Message argument of notify matcher:
|
14
|
+
# nil
|
15
|
+
# 'same'
|
16
|
+
# 'different'
|
17
|
+
#
|
18
|
+
describe "Notify Matcher" do
|
19
|
+
include MustBeExampleHelper
|
20
|
+
|
21
|
+
def self.it_should_follow_pattern(note, polarity, message, result)
|
22
|
+
context "when there is #{note == :note ? "a" : "no"} note" do
|
23
|
+
message_arg = message ? %{("#{message}")} : ""
|
24
|
+
call = "#{polarity} notify#{message_arg}"
|
25
|
+
it "should #{result ? "fail" : "succeed"} if expecting #{call}" do
|
26
|
+
pattern_notify = lambda do
|
27
|
+
must_notify("same") if note == :note
|
28
|
+
send(polarity, notify(message))
|
29
|
+
end
|
30
|
+
|
31
|
+
pattern_notify.send(result ? :should : :should_not, raise_error(
|
32
|
+
Spec::Expectations::ExpectationNotMetError, result))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
it_should_follow_pattern :note, :should, nil, nil
|
38
|
+
it_should_follow_pattern :note, :should, 'same', nil
|
39
|
+
it_should_follow_pattern :note, :should, 'different',
|
40
|
+
'expected note with message: "different"' "\n"\
|
41
|
+
' got note with message: "same"'
|
42
|
+
it_should_follow_pattern :note, :should_not, nil,
|
43
|
+
'expected no note' "\n"\
|
44
|
+
'got note with message: "same"'
|
45
|
+
it_should_follow_pattern :note, :should_not, 'same',
|
46
|
+
'did NOT expect note with message: "same"' "\n"\
|
47
|
+
' got note with message: "same"'
|
48
|
+
it_should_follow_pattern :note, :should_not, 'different', nil
|
49
|
+
|
50
|
+
it_should_follow_pattern :no_note, :should, nil,
|
51
|
+
'expected a note'
|
52
|
+
it_should_follow_pattern :no_note, :should, 'same',
|
53
|
+
'expected a note with message: "same"'
|
54
|
+
it_should_follow_pattern :no_note, :should, 'different',
|
55
|
+
'expected a note with message: "different"'
|
56
|
+
it_should_follow_pattern :no_note, :should_not, nil, nil
|
57
|
+
it_should_follow_pattern :no_note, :should_not, 'same', nil
|
58
|
+
it_should_follow_pattern :no_note, :should_not, 'different', nil
|
59
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,180 @@
|
|
1
|
+
### MUST_BE__DO_NOT_AUTOMATICALLY_INCLUDE_IN_OBJECT ###
|
2
|
+
#
|
3
|
+
# Hard to describe within normal RSpec control flow. Instead we raise a
|
4
|
+
# RuntimeError if MUST_BE__DO_NOT_AUTOMATICALLY_INCLUDE_IN_OBJECT doesn't
|
5
|
+
# behave as expected.
|
6
|
+
#
|
7
|
+
|
8
|
+
ENV['MUST_BE__NOTIFIER'] = nil # to make `rake spec` work.
|
9
|
+
ENV['MUST_BE__DO_NOT_AUTOMATICALLY_INCLUDE_IN_OBJECT'] = "" # any string.
|
10
|
+
|
11
|
+
require 'lib/must_be'
|
12
|
+
|
13
|
+
if Object.include? MustBe
|
14
|
+
raise "MustBe should not be automatically included in Object."
|
15
|
+
end
|
16
|
+
|
17
|
+
def expect_error(error_type)
|
18
|
+
begin
|
19
|
+
raised_error = false
|
20
|
+
yield
|
21
|
+
rescue error_type
|
22
|
+
raised_error = true
|
23
|
+
end
|
24
|
+
raise "expected #{error_type}" unless raised_error
|
25
|
+
end
|
26
|
+
|
27
|
+
# Show that MustBe does not need to be included in Object to be useful.
|
28
|
+
def example_of_must_be_inclusion
|
29
|
+
example = Object.new
|
30
|
+
example.extend(MustBe)
|
31
|
+
example.must == example
|
32
|
+
example.must_not_be_nil
|
33
|
+
|
34
|
+
# must_only_contain and must_not_contain require contents to also include
|
35
|
+
# MustBe.
|
36
|
+
contents = Object.new
|
37
|
+
|
38
|
+
container = [contents]
|
39
|
+
container.extend(MustBe)
|
40
|
+
|
41
|
+
expect_error(NoMethodError) do
|
42
|
+
container.must_only_contain
|
43
|
+
end
|
44
|
+
|
45
|
+
contents.extend(MustBe)
|
46
|
+
expect_error(MustBe::Note) do
|
47
|
+
container.must_not_contain
|
48
|
+
end
|
49
|
+
end
|
50
|
+
example_of_must_be_inclusion
|
51
|
+
|
52
|
+
class Object
|
53
|
+
include MustBe
|
54
|
+
end
|
55
|
+
|
56
|
+
### MustBeExampleHelper ###
|
57
|
+
|
58
|
+
module MustBeExampleHelper
|
59
|
+
|
60
|
+
$default_must_be_notifier = MustBe.notifier
|
61
|
+
|
62
|
+
def self.included(example_group)
|
63
|
+
example_group.before do
|
64
|
+
MustBe.notifier = lambda do |note|
|
65
|
+
@note = note
|
66
|
+
false
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
class <<example_group
|
71
|
+
|
72
|
+
### Value Assertion ###
|
73
|
+
|
74
|
+
def it_should_have_must_be_value_assertion(method, value, alt = 411)
|
75
|
+
describe '##{method}' do
|
76
|
+
it "should not notify if receiver is #{value.inspect}" do
|
77
|
+
value.send(method).should == value
|
78
|
+
should_not notify
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should notify if receiver is not #{value.inspect}" do
|
82
|
+
alt.send(method).should == alt
|
83
|
+
should notify("#{alt.inspect}.#{method}")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def it_should_have_must_not_be_value_assertion(method, value, alt = 411)
|
89
|
+
describe '##{method}' do
|
90
|
+
it "should notify if receiver is #{value.inspect}" do
|
91
|
+
value.send(method)
|
92
|
+
should notify("#{value.inspect}.#{method}")
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should not notify if receiver is not #{value.inspect}" do
|
96
|
+
alt.send(method)
|
97
|
+
should_not notify
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
### Notify Example ###
|
103
|
+
|
104
|
+
def notify_example(expression, message = nil)
|
105
|
+
expression = expression.gsub(/\n\s*/, " ")
|
106
|
+
if message.is_a? Module
|
107
|
+
message = expression+", but matches #{message}"
|
108
|
+
end
|
109
|
+
example "#{expression} should #{message ? "" : "not "}notify" do
|
110
|
+
eval(expression)
|
111
|
+
if message == true
|
112
|
+
should notify
|
113
|
+
elsif message
|
114
|
+
should notify(message)
|
115
|
+
else
|
116
|
+
should_not notify
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
### Enable ###
|
122
|
+
|
123
|
+
def before_disable_after_enable
|
124
|
+
before do
|
125
|
+
MustBe.disable
|
126
|
+
end
|
127
|
+
|
128
|
+
after do
|
129
|
+
MustBe.enable
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def before_disable_and_reenable
|
134
|
+
before do
|
135
|
+
MustBe.disable
|
136
|
+
MustBe.enable
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
### Notify Matcher ###
|
143
|
+
|
144
|
+
def notify(message = nil)
|
145
|
+
simple_matcher do |given, matcher|
|
146
|
+
result, message =
|
147
|
+
if @note
|
148
|
+
if message
|
149
|
+
if message === @note.message
|
150
|
+
[true,
|
151
|
+
"did NOT expect note with message: #{message.inspect}\n"\
|
152
|
+
" got note with message: #{@note.message.inspect}"]
|
153
|
+
else
|
154
|
+
[false,
|
155
|
+
"expected note with message: #{message.inspect}\n"\
|
156
|
+
" got note with message: #{@note.message.inspect}"]
|
157
|
+
end
|
158
|
+
else
|
159
|
+
[true,
|
160
|
+
"expected no note\n"\
|
161
|
+
"got note with message: #{@note.message.inspect}"]
|
162
|
+
end
|
163
|
+
else
|
164
|
+
[false, if message
|
165
|
+
"expected a note with message: #{message.inspect}"
|
166
|
+
else
|
167
|
+
"expected a note"
|
168
|
+
end]
|
169
|
+
end
|
170
|
+
|
171
|
+
if result
|
172
|
+
matcher.negative_failure_message = message
|
173
|
+
else
|
174
|
+
matcher.failure_message = message
|
175
|
+
end
|
176
|
+
|
177
|
+
result
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MustBe, " typical usage" do
|
4
|
+
include MustBeExampleHelper
|
5
|
+
|
6
|
+
describe '#must_be', " notifies when receiver doesn't case-equal (===) any"\
|
7
|
+
" of its arguments" do
|
8
|
+
context "when called with a Class, it notifies unless"\
|
9
|
+
" receiver.is_a? Class" do
|
10
|
+
notify_example %{4.must_be(Numeric)}
|
11
|
+
notify_example %{4.must_be(Float)}, Fixnum
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when called with a regexp, it notifies unless"\
|
15
|
+
" regexp =~ receiver" do
|
16
|
+
notify_example %{"funny".must_be(/n{2}/)}
|
17
|
+
notify_example %{"funny".must_be(/\d/)}, String
|
18
|
+
end
|
19
|
+
|
20
|
+
context "when called with a range, it notifies unless"\
|
21
|
+
" range.include? receiver" do
|
22
|
+
notify_example %{5.must_be(1..5)}
|
23
|
+
notify_example %{5.must_be(1...5)}, Fixnum
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when called with an array, it notifies unless"\
|
27
|
+
" array == receiver" do
|
28
|
+
notify_example %{[3, 5].must_be([3, 5])}
|
29
|
+
notify_example %{3.must_be([3, 5])}, Fixnum
|
30
|
+
end
|
31
|
+
|
32
|
+
context "when called with a proc, it notifies unless proc[receiver]" do
|
33
|
+
notify_example %{:anything.must_be(lambda {|v| true })}
|
34
|
+
notify_example %{:anything.must_be(lambda {|v| false })}, true
|
35
|
+
end
|
36
|
+
|
37
|
+
context "when called with most other objects, it notifies unless"\
|
38
|
+
" object == receiver" do
|
39
|
+
notify_example %{:yep.must_be(:yep)}
|
40
|
+
notify_example %{:yep.must_be(:nope)}, Symbol
|
41
|
+
end
|
42
|
+
|
43
|
+
context "when called without arguments, it notifies if receiver is"\
|
44
|
+
" false or nil" do
|
45
|
+
notify_example %{5.must_be}
|
46
|
+
notify_example %{nil.must_be}, NilClass
|
47
|
+
notify_example %{false.must_be}, FalseClass
|
48
|
+
end
|
49
|
+
|
50
|
+
context "when called with multiple arguments, it notifies unless"\
|
51
|
+
" receiver case-equals (===) one of them" do
|
52
|
+
notify_example %{:happy.must_be(String, Symbol)}
|
53
|
+
notify_example %{934.must_be(String, Symbol)}, Fixnum
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '#must' do
|
58
|
+
context "when called with a block, it notifies if the result is"\
|
59
|
+
" false or nil" do
|
60
|
+
notify_example %{:helm.must("message") {|receiver, message| message ==
|
61
|
+
"mess" }}, "message"
|
62
|
+
notify_example %{:helm.must {|receiver| receiver == :helm }}
|
63
|
+
end
|
64
|
+
|
65
|
+
context "when called with no argument, it returns a proxy which notifies"\
|
66
|
+
" when a method returning false or nil is called" do
|
67
|
+
notify_example %{5.must == 4}, "5.must.==(4)"
|
68
|
+
notify_example %{5.must > 4}
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
describe '#must_only_contain' do
|
73
|
+
context "with Array receiver, it should notify unless each member in the"\
|
74
|
+
" array case-equals (===) one of the arguments" do
|
75
|
+
notify_example %{[1, :hi, "wow"].must_only_contain(Numeric, Symbol,
|
76
|
+
String)}
|
77
|
+
notify_example %{[1, :hi, "wow"].must_only_contain(Numeric, String)},
|
78
|
+
"must_only_contain: :hi.must_be(Numeric, String), but matches"\
|
79
|
+
" Symbol in container [1, :hi, \"wow\"]"
|
80
|
+
end
|
81
|
+
|
82
|
+
context "with Hash receiver, it should notify unless each pair"\
|
83
|
+
" case-equals (===) a pair in an argument hash" do
|
84
|
+
notify_example %{{:key => "value"}.must_only_contain({Symbol => [Symbol,
|
85
|
+
String]})}
|
86
|
+
notify_example %{{:key => "value"}.must_only_contain({Symbol => Symbol},
|
87
|
+
{Symbol => Numeric})}, "must_only_contain: pair {:key=>\"value\"}"\
|
88
|
+
" does not match [{Symbol=>Symbol}, {Symbol=>Numeric}] in"\
|
89
|
+
" container {:key=>\"value\"}"
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
describe '#must_only_ever_contain' do
|
94
|
+
context "like #must_only_contain, it notifies unless each member"\
|
95
|
+
" case-equals (===) one of the arguments" do
|
96
|
+
notify_example %{[1, :hi, "wow"].must_only_ever_contain(Numeric, Symbol,
|
97
|
+
String)}
|
98
|
+
notify_example %{[1, :hi, "wow"].must_only_ever_contain(Numeric,
|
99
|
+
String)},
|
100
|
+
"must_only_ever_contain: :hi.must_be(Numeric, String), but"\
|
101
|
+
" matches Symbol in container [1, :hi, \"wow\"]"
|
102
|
+
end
|
103
|
+
|
104
|
+
context "it notifies whenever the container is updated to hold an member"\
|
105
|
+
" which does not case-equal (===) one of the arguments" do
|
106
|
+
describe "[1, 2, 3].must_only_ever_contain(Numeric)" do
|
107
|
+
subject { [1, 2, 3].must_only_ever_contain(Numeric) }
|
108
|
+
|
109
|
+
notify_example %{subject << 3.14}
|
110
|
+
notify_example %{subject << nil}, "must_only_ever_contain:"\
|
111
|
+
" Array#<<(nil): nil.must_be(Numeric), but matches NilClass in"\
|
112
|
+
" container [1, 2, 3, nil]"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
describe '#must_notify', " is a primitive used to define other must_be"\
|
118
|
+
" methods" do
|
119
|
+
context "when called with a string, it notifies with a string message" do
|
120
|
+
notify_example %{must_notify("message")}, "message"
|
121
|
+
end
|
122
|
+
|
123
|
+
context "when called with multiple arguments, it notifies with method"\
|
124
|
+
" invocation details" do
|
125
|
+
notify_example %{must_notify(:receiver, :method_name,
|
126
|
+
[:arg, :arg, :arg], lambda {}, " additional message")},
|
127
|
+
":receiver.method_name(:arg, :arg, :arg) {} additional message"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe '#must_check', " interrupts normal notification" do
|
132
|
+
context "when called with a block, it yields to the block" do
|
133
|
+
example "#must_check returns a note if the block calls #must_notify" do
|
134
|
+
note = must_check do
|
135
|
+
must_notify("message")
|
136
|
+
end
|
137
|
+
note.message.should == "message"
|
138
|
+
should_not notify
|
139
|
+
end
|
140
|
+
|
141
|
+
example "#must_check returns nil if the block does not call"\
|
142
|
+
" #must_notify" do
|
143
|
+
note = must_check do
|
144
|
+
:would_not_notify
|
145
|
+
end
|
146
|
+
note.should be_nil
|
147
|
+
should_not notify
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context "when called with a proc and a block, #must_check calls the"\
|
152
|
+
" proc" do
|
153
|
+
example "#must_check passes the note to the block and notifies with"\
|
154
|
+
" the result of the block if the proc calls #must_notify" do
|
155
|
+
must_check(lambda do
|
156
|
+
must_notify("original message")
|
157
|
+
end) do |note|
|
158
|
+
note.message.should == "original message"
|
159
|
+
"new message"
|
160
|
+
end
|
161
|
+
should notify("new message")
|
162
|
+
end
|
163
|
+
|
164
|
+
example "the block is not called if the proc does not call"\
|
165
|
+
" #must_notify" do
|
166
|
+
did_call_block = false
|
167
|
+
must_check(lambda do
|
168
|
+
:would_not_notify
|
169
|
+
end) do |note|
|
170
|
+
did_call_block = true
|
171
|
+
end
|
172
|
+
did_call_block.should be_false
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: must_be
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
version: 1.0.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- William Taysom
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-09-12 00:00:00 +08:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: must_be provides runtime assertions which can easily be disabled in production environments. Likewise, the notifier can be customized to raise errors, log failure, enter the debugger, or anything else.
|
23
|
+
email: wtaysom@gmail.com
|
24
|
+
executables: []
|
25
|
+
|
26
|
+
extensions: []
|
27
|
+
|
28
|
+
extra_rdoc_files:
|
29
|
+
- README.md
|
30
|
+
files:
|
31
|
+
- .gitignore
|
32
|
+
- README.md
|
33
|
+
- Rakefile
|
34
|
+
- VERSION
|
35
|
+
- doc/readme/examples.rb
|
36
|
+
- doc/readme/run_examples.rb
|
37
|
+
- lib/must_be.rb
|
38
|
+
- lib/must_be/attr_typed.rb
|
39
|
+
- lib/must_be/basic.rb
|
40
|
+
- lib/must_be/containers.rb
|
41
|
+
- lib/must_be/containers_registered_classes.rb
|
42
|
+
- lib/must_be/core.rb
|
43
|
+
- lib/must_be/nonstandard_control_flow.rb
|
44
|
+
- lib/must_be/proxy.rb
|
45
|
+
- must_be.gemspec
|
46
|
+
- spec/must_be/attr_typed_spec.rb
|
47
|
+
- spec/must_be/basic_spec.rb
|
48
|
+
- spec/must_be/containers_spec.rb
|
49
|
+
- spec/must_be/core_spec.rb
|
50
|
+
- spec/must_be/nonstandard_control_flow_spec.rb
|
51
|
+
- spec/must_be/proxy_spec.rb
|
52
|
+
- spec/notify_matcher_spec.rb
|
53
|
+
- spec/spec_helper.rb
|
54
|
+
- spec/typical_usage_spec.rb
|
55
|
+
has_rdoc: true
|
56
|
+
homepage: http://github.com/wtaysom/must_be
|
57
|
+
licenses: []
|
58
|
+
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options:
|
61
|
+
- --charset=UTF-8
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
hash: 3
|
70
|
+
segments:
|
71
|
+
- 0
|
72
|
+
version: "0"
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 3
|
79
|
+
segments:
|
80
|
+
- 0
|
81
|
+
version: "0"
|
82
|
+
requirements: []
|
83
|
+
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 1.3.7
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: must_be Runtime Assertions
|
89
|
+
test_files:
|
90
|
+
- spec/must_be/attr_typed_spec.rb
|
91
|
+
- spec/must_be/basic_spec.rb
|
92
|
+
- spec/must_be/containers_spec.rb
|
93
|
+
- spec/must_be/core_spec.rb
|
94
|
+
- spec/must_be/nonstandard_control_flow_spec.rb
|
95
|
+
- spec/must_be/proxy_spec.rb
|
96
|
+
- spec/notify_matcher_spec.rb
|
97
|
+
- spec/spec_helper.rb
|
98
|
+
- spec/typical_usage_spec.rb
|