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.
@@ -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
@@ -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