micronaut 0.2.9

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.
Files changed (79) hide show
  1. data/History.txt +15 -0
  2. data/LICENSE +45 -0
  3. data/README.markdown +66 -0
  4. data/RSPEC-LICENSE +23 -0
  5. data/Rakefile +78 -0
  6. data/VERSION.yml +4 -0
  7. data/bin/micronaut +4 -0
  8. data/examples/example_helper.rb +54 -0
  9. data/examples/lib/micronaut/behaviour_example.rb +351 -0
  10. data/examples/lib/micronaut/configuration_example.rb +133 -0
  11. data/examples/lib/micronaut/example_example.rb +67 -0
  12. data/examples/lib/micronaut/expectations/extensions/object_example.rb +146 -0
  13. data/examples/lib/micronaut/expectations/fail_with_example.rb +17 -0
  14. data/examples/lib/micronaut/expectations/wrap_expectation_example.rb +27 -0
  15. data/examples/lib/micronaut/formatters/base_formatter_example.rb +117 -0
  16. data/examples/lib/micronaut/formatters/documentation_formatter_example.rb +5 -0
  17. data/examples/lib/micronaut/formatters/progress_formatter_example.rb +29 -0
  18. data/examples/lib/micronaut/kernel_extensions_example.rb +13 -0
  19. data/examples/lib/micronaut/matchers/be_close_example.rb +52 -0
  20. data/examples/lib/micronaut/matchers/be_example.rb +298 -0
  21. data/examples/lib/micronaut/matchers/change_example.rb +360 -0
  22. data/examples/lib/micronaut/matchers/description_generation_example.rb +175 -0
  23. data/examples/lib/micronaut/matchers/eql_example.rb +35 -0
  24. data/examples/lib/micronaut/matchers/equal_example.rb +35 -0
  25. data/examples/lib/micronaut/matchers/has_example.rb +69 -0
  26. data/examples/lib/micronaut/matchers/have_example.rb +392 -0
  27. data/examples/lib/micronaut/matchers/include_example.rb +103 -0
  28. data/examples/lib/micronaut/matchers/match_example.rb +43 -0
  29. data/examples/lib/micronaut/matchers/matcher_methods_example.rb +78 -0
  30. data/examples/lib/micronaut/matchers/operator_matcher_example.rb +193 -0
  31. data/examples/lib/micronaut/matchers/raise_error_example.rb +348 -0
  32. data/examples/lib/micronaut/matchers/respond_to_example.rb +54 -0
  33. data/examples/lib/micronaut/matchers/satisfy_example.rb +36 -0
  34. data/examples/lib/micronaut/matchers/simple_matcher_example.rb +93 -0
  35. data/examples/lib/micronaut/matchers/throw_symbol_example.rb +125 -0
  36. data/examples/lib/micronaut/mocha_example.rb +29 -0
  37. data/examples/lib/micronaut/runner_example.rb +41 -0
  38. data/examples/lib/micronaut/world_example.rb +98 -0
  39. data/examples/lib/micronaut_example.rb +43 -0
  40. data/examples/resources/example_classes.rb +67 -0
  41. data/lib/micronaut.rb +40 -0
  42. data/lib/micronaut/behaviour.rb +217 -0
  43. data/lib/micronaut/configuration.rb +162 -0
  44. data/lib/micronaut/example.rb +112 -0
  45. data/lib/micronaut/expectations.rb +45 -0
  46. data/lib/micronaut/expectations/extensions/object.rb +92 -0
  47. data/lib/micronaut/expectations/handler.rb +51 -0
  48. data/lib/micronaut/expectations/wrap_expectation.rb +52 -0
  49. data/lib/micronaut/formatters.rb +12 -0
  50. data/lib/micronaut/formatters/base_formatter.rb +127 -0
  51. data/lib/micronaut/formatters/base_text_formatter.rb +139 -0
  52. data/lib/micronaut/formatters/documentation_formatter.rb +78 -0
  53. data/lib/micronaut/formatters/progress_formatter.rb +30 -0
  54. data/lib/micronaut/kernel_extensions.rb +11 -0
  55. data/lib/micronaut/matchers.rb +141 -0
  56. data/lib/micronaut/matchers/be.rb +204 -0
  57. data/lib/micronaut/matchers/be_close.rb +37 -0
  58. data/lib/micronaut/matchers/change.rb +148 -0
  59. data/lib/micronaut/matchers/eql.rb +26 -0
  60. data/lib/micronaut/matchers/equal.rb +26 -0
  61. data/lib/micronaut/matchers/generated_descriptions.rb +36 -0
  62. data/lib/micronaut/matchers/has.rb +19 -0
  63. data/lib/micronaut/matchers/have.rb +153 -0
  64. data/lib/micronaut/matchers/include.rb +80 -0
  65. data/lib/micronaut/matchers/match.rb +22 -0
  66. data/lib/micronaut/matchers/method_missing.rb +9 -0
  67. data/lib/micronaut/matchers/operator_matcher.rb +50 -0
  68. data/lib/micronaut/matchers/raise_error.rb +128 -0
  69. data/lib/micronaut/matchers/respond_to.rb +50 -0
  70. data/lib/micronaut/matchers/satisfy.rb +50 -0
  71. data/lib/micronaut/matchers/simple_matcher.rb +135 -0
  72. data/lib/micronaut/matchers/throw_symbol.rb +108 -0
  73. data/lib/micronaut/mocking/with_absolutely_nothing.rb +11 -0
  74. data/lib/micronaut/mocking/with_mocha.rb +15 -0
  75. data/lib/micronaut/mocking/with_rr.rb +24 -0
  76. data/lib/micronaut/rake_task.rb +84 -0
  77. data/lib/micronaut/runner.rb +60 -0
  78. data/lib/micronaut/world.rb +75 -0
  79. metadata +165 -0
@@ -0,0 +1,175 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../../example_helper")
2
+
3
+ describe Micronaut::Matchers do
4
+
5
+ describe "should be able to generate their own descriptions" do
6
+
7
+ after do
8
+ Micronaut::Matchers.clear_generated_description
9
+ end
10
+
11
+ it "should == expected" do
12
+ "this".should == "this"
13
+ Micronaut::Matchers.generated_description.should == "should == \"this\""
14
+ end
15
+
16
+ it "should not == expected" do
17
+ "this".should_not == "that"
18
+ Micronaut::Matchers.generated_description.should == "should not == \"that\""
19
+ end
20
+
21
+ it "should be empty (arbitrary predicate)" do
22
+ [].should be_empty
23
+ Micronaut::Matchers.generated_description.should == "should be empty"
24
+ end
25
+
26
+ it "should not be empty (arbitrary predicate)" do
27
+ [1].should_not be_empty
28
+ Micronaut::Matchers.generated_description.should == "should not be empty"
29
+ end
30
+
31
+ it "should be true" do
32
+ true.should be_true
33
+ Micronaut::Matchers.generated_description.should == "should be true"
34
+ end
35
+
36
+ it "should be false" do
37
+ false.should be_false
38
+ Micronaut::Matchers.generated_description.should == "should be false"
39
+ end
40
+
41
+ it "should be nil" do
42
+ nil.should be_nil
43
+ Micronaut::Matchers.generated_description.should == "should be nil"
44
+ end
45
+
46
+ it "should be > n" do
47
+ 5.should be > 3
48
+ Micronaut::Matchers.generated_description.should == "should be > 3"
49
+ end
50
+
51
+ it "should be predicate arg1, arg2 and arg3" do
52
+ 5.0.should be_between(0,10)
53
+ Micronaut::Matchers.generated_description.should == "should be between 0 and 10"
54
+ end
55
+
56
+ it "should be_few_words predicate should be transformed to 'be few words'" do
57
+ 5.should be_kind_of(Fixnum)
58
+ Micronaut::Matchers.generated_description.should == "should be kind of Fixnum"
59
+ end
60
+
61
+ it "should preserve a proper prefix for be predicate" do
62
+ 5.should be_a_kind_of(Fixnum)
63
+ Micronaut::Matchers.generated_description.should == "should be a kind of Fixnum"
64
+ 5.should be_an_instance_of(Fixnum)
65
+ Micronaut::Matchers.generated_description.should == "should be an instance of Fixnum"
66
+ end
67
+
68
+ it "should equal" do
69
+ expected = "expected"
70
+ expected.should equal(expected)
71
+ Micronaut::Matchers.generated_description.should == "should equal \"expected\""
72
+ end
73
+
74
+ it "should_not equal" do
75
+ 5.should_not equal(37)
76
+ Micronaut::Matchers.generated_description.should == "should not equal 37"
77
+ end
78
+
79
+ it "should eql" do
80
+ "string".should eql("string")
81
+ Micronaut::Matchers.generated_description.should == "should eql \"string\""
82
+ end
83
+
84
+ it "should not eql" do
85
+ "a".should_not eql(:a)
86
+ Micronaut::Matchers.generated_description.should == "should not eql :a"
87
+ end
88
+
89
+ it "should have_key" do
90
+ {:a => "a"}.should have_key(:a)
91
+ Micronaut::Matchers.generated_description.should == "should have key :a"
92
+ end
93
+
94
+ it "should have n items" do
95
+ team.should have(3).players
96
+ Micronaut::Matchers.generated_description.should == "should have 3 players"
97
+ end
98
+
99
+ it "should have at least n items" do
100
+ team.should have_at_least(2).players
101
+ Micronaut::Matchers.generated_description.should == "should have at least 2 players"
102
+ end
103
+
104
+ it "should have at most n items" do
105
+ team.should have_at_most(4).players
106
+ Micronaut::Matchers.generated_description.should == "should have at most 4 players"
107
+ end
108
+
109
+ it "should include" do
110
+ [1,2,3].should include(3)
111
+ Micronaut::Matchers.generated_description.should == "should include 3"
112
+ end
113
+
114
+ it "should match" do
115
+ "this string".should match(/this string/)
116
+ Micronaut::Matchers.generated_description.should == "should match /this string/"
117
+ end
118
+
119
+ it "should raise_error" do
120
+ lambda { raise }.should raise_error
121
+ Micronaut::Matchers.generated_description.should == "should raise Exception"
122
+ end
123
+
124
+ it "should raise_error with type" do
125
+ lambda { raise }.should raise_error(RuntimeError)
126
+ Micronaut::Matchers.generated_description.should == "should raise RuntimeError"
127
+ end
128
+
129
+ it "should raise_error with type and message" do
130
+ lambda { raise "there was an error" }.should raise_error(RuntimeError, "there was an error")
131
+ Micronaut::Matchers.generated_description.should == "should raise RuntimeError with \"there was an error\""
132
+ end
133
+
134
+ it "should respond_to" do
135
+ [].should respond_to(:insert)
136
+ Micronaut::Matchers.generated_description.should == "should respond to [:insert]"
137
+ end
138
+
139
+ it "should throw symbol" do
140
+ lambda { throw :what_a_mess }.should throw_symbol
141
+ Micronaut::Matchers.generated_description.should == "should throw a Symbol"
142
+ end
143
+
144
+ it "should throw symbol (with named symbol)" do
145
+ lambda { throw :what_a_mess }.should throw_symbol(:what_a_mess)
146
+ Micronaut::Matchers.generated_description.should == "should throw :what_a_mess"
147
+ end
148
+
149
+ def team
150
+ Class.new do
151
+ def players
152
+ [1,2,3]
153
+ end
154
+ end.new
155
+ end
156
+
157
+ end
158
+
159
+ describe "a matcher with no description" do
160
+
161
+ def matcher
162
+ Class.new do
163
+ def matches?(ignore); true; end
164
+ def failure_message; ""; end
165
+ end.new
166
+ end
167
+
168
+ it "should provide a helpful message when used in a string-less example block" do
169
+ 5.should matcher
170
+ Micronaut::Matchers.generated_description.should =~ /When you call.*description method/m
171
+ end
172
+
173
+ end
174
+
175
+ end
@@ -0,0 +1,35 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../../example_helper")
2
+
3
+ describe Micronaut::Matchers do
4
+
5
+ describe "eql" do
6
+
7
+ it "should match when actual.eql?(expected)" do
8
+ eql(1).matches?(1).should be_true
9
+ end
10
+
11
+ it "should not match when !actual.eql?(expected)" do
12
+ eql(1).matches?(2).should be_false
13
+ end
14
+
15
+ it "should describe itself" do
16
+ matcher = eql(1)
17
+ matcher.matches?(1)
18
+ matcher.description.should == "eql 1"
19
+ end
20
+
21
+ it "should provide message, expected and actual on #failure_message" do
22
+ matcher = eql("1")
23
+ matcher.matches?(1)
24
+ matcher.failure_message.should == ["expected \"1\", got 1 (using .eql?)", "1", 1]
25
+ end
26
+
27
+ it "should provide message, expected and actual on #negative_failure_message" do
28
+ matcher = eql(1)
29
+ matcher.matches?(1)
30
+ matcher.negative_failure_message.should == ["expected 1 not to equal 1 (using .eql?)", 1, 1]
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,35 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../../example_helper")
2
+
3
+ describe Micronaut::Matchers do
4
+
5
+ describe "equal" do
6
+
7
+ it "should match when actual.equal?(expected)" do
8
+ equal(1).matches?(1).should be_true
9
+ end
10
+
11
+ it "should not match when !actual.equal?(expected)" do
12
+ equal("1").matches?("1").should be_false
13
+ end
14
+
15
+ it "should describe itself" do
16
+ matcher = equal(1)
17
+ matcher.matches?(1)
18
+ matcher.description.should == "equal 1"
19
+ end
20
+
21
+ it "should provide message, expected and actual on #failure_message" do
22
+ matcher = equal("1")
23
+ matcher.matches?(1)
24
+ matcher.failure_message.should == ["expected \"1\", got 1 (using .equal?)", "1", 1]
25
+ end
26
+
27
+ it "should provide message, expected and actual on #negative_failure_message" do
28
+ matcher = equal(1)
29
+ matcher.matches?(1)
30
+ matcher.negative_failure_message.should == ["expected 1 not to equal 1 (using .equal?)", 1, 1]
31
+ end
32
+
33
+ end
34
+
35
+ end
@@ -0,0 +1,69 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../../example_helper")
2
+
3
+ describe Micronaut::Matchers do
4
+
5
+ describe "should have_sym(*args)" do
6
+
7
+ it "should pass if #has_sym?(*args) returns true" do
8
+ {:a => "A"}.should have_key(:a)
9
+ end
10
+
11
+ it "should fail if #has_sym?(*args) returns false" do
12
+ lambda {
13
+ {:b => "B"}.should have_key(:a)
14
+ }.should fail_with("expected #has_key?(:a) to return true, got false")
15
+ end
16
+
17
+ it "should fail if target does not respond to #has_sym?" do
18
+ lambda { Object.new.should have_key(:a) }.should raise_error(NoMethodError)
19
+ end
20
+
21
+ it "should re-raise an exception thrown in #has_sym?(*args)" do
22
+ o = Object.new
23
+ def o.has_sym?(*args)
24
+ raise "Funky exception"
25
+ end
26
+ lambda { o.should have_sym(:foo) }.should raise_error("Funky exception")
27
+ end
28
+
29
+ end
30
+
31
+ describe "should_not have_sym(*args)" do
32
+
33
+ it "should pass if #has_sym?(*args) returns false" do
34
+ {:a => "A"}.should_not have_key(:b)
35
+ end
36
+
37
+ it "should fail if #has_sym?(*args) returns true" do
38
+ lambda {
39
+ {:a => "A"}.should_not have_key(:a)
40
+ }.should fail_with("expected #has_key?(:a) to return false, got true")
41
+ end
42
+
43
+ it "should fail if target does not respond to #has_sym?" do
44
+ lambda {
45
+ Object.new.should have_key(:a)
46
+ }.should raise_error(NoMethodError)
47
+ end
48
+
49
+ it "should reraise an exception thrown in #has_sym?(*args)" do
50
+ o = Object.new
51
+ def o.has_sym?(*args)
52
+ raise "Funky exception"
53
+ end
54
+ lambda { o.should_not have_sym(:foo) }.should raise_error("Funky exception")
55
+ end
56
+
57
+ end
58
+
59
+ describe "has" do
60
+
61
+ it "should work when the target implements #send" do
62
+ o = {:a => "A"}
63
+ def o.send(*args); raise "DOH! Library developers shouldn't use #send!" end
64
+ lambda { o.should have_key(:a) }.should_not raise_error
65
+ end
66
+
67
+ end
68
+
69
+ end
@@ -0,0 +1,392 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../../example_helper")
2
+
3
+ describe Micronaut::Matchers, "have" do
4
+
5
+ before do
6
+ unless defined?(::ActiveSupport::Inflector)
7
+ @active_support_was_not_defined
8
+ module ::ActiveSupport
9
+ class Inflector
10
+ def self.pluralize(string)
11
+ string.to_s + 's'
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ def create_collection_owner_with(n)
19
+ owner = Micronaut::Expectations::Helper::CollectionOwner.new
20
+ (1..n).each do |n|
21
+ owner.add_to_collection_with_length_method(n)
22
+ owner.add_to_collection_with_size_method(n)
23
+ end
24
+ owner
25
+ end
26
+
27
+ describe "should have(n).items" do
28
+
29
+ it "should pass if target has a collection of items with n members" do
30
+ owner = create_collection_owner_with(3)
31
+ owner.should have(3).items_in_collection_with_length_method
32
+ owner.should have(3).items_in_collection_with_size_method
33
+ end
34
+
35
+ it "should convert :no to 0" do
36
+ owner = create_collection_owner_with(0)
37
+ owner.should have(:no).items_in_collection_with_length_method
38
+ owner.should have(:no).items_in_collection_with_size_method
39
+ end
40
+
41
+ it "should fail if target has a collection of items with < n members" do
42
+ owner = create_collection_owner_with(3)
43
+ lambda {
44
+ owner.should have(4).items_in_collection_with_length_method
45
+ }.should fail_with("expected 4 items_in_collection_with_length_method, got 3")
46
+ lambda {
47
+ owner.should have(4).items_in_collection_with_size_method
48
+ }.should fail_with("expected 4 items_in_collection_with_size_method, got 3")
49
+ end
50
+
51
+ it "should fail if target has a collection of items with > n members" do
52
+ owner = create_collection_owner_with(3)
53
+ lambda {
54
+ owner.should have(2).items_in_collection_with_length_method
55
+ }.should fail_with("expected 2 items_in_collection_with_length_method, got 3")
56
+ lambda {
57
+ owner.should have(2).items_in_collection_with_size_method
58
+ }.should fail_with("expected 2 items_in_collection_with_size_method, got 3")
59
+ end
60
+ end
61
+
62
+ describe 'should have(1).item when ActiveSupport::Inflector is defined' do
63
+
64
+ it 'should pluralize the collection name' do
65
+ owner = create_collection_owner_with(1)
66
+ owner.should have(1).item
67
+ end
68
+
69
+ after do
70
+ if @active_support_was_not_defined
71
+ Object.__send__ :remove_const, :ActiveSupport
72
+ end
73
+ end
74
+ end
75
+
76
+ describe 'should have(1).item when Inflector is defined' do
77
+
78
+ before do
79
+ unless defined?(::Inflector)
80
+ @inflector_was_not_defined
81
+ class ::Inflector
82
+ def self.pluralize(string)
83
+ string.to_s + 's'
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ it 'should pluralize the collection name' do
90
+ owner = create_collection_owner_with(1)
91
+ owner.should have(1).item
92
+ end
93
+
94
+ after do
95
+ if @inflector_was_not_defined
96
+ Object.__send__ :remove_const, :Inflector
97
+ end
98
+ end
99
+ end
100
+
101
+ describe "should have(n).items where result responds to items but returns something other than a collection" do
102
+ it "should provide a meaningful error" do
103
+ owner = Class.new do
104
+ def items
105
+ Object.new
106
+ end
107
+ end.new
108
+ lambda do
109
+ owner.should have(3).items
110
+ end.should raise_error("expected items to be a collection but it does not respond to #length or #size")
111
+ end
112
+ end
113
+
114
+ describe "should_not have(n).items" do
115
+
116
+ it "should pass if target has a collection of items with < n members" do
117
+ owner = create_collection_owner_with(3)
118
+ owner.should_not have(4).items_in_collection_with_length_method
119
+ owner.should_not have(4).items_in_collection_with_size_method
120
+ end
121
+
122
+ it "should pass if target has a collection of items with > n members" do
123
+ owner = create_collection_owner_with(3)
124
+ owner.should_not have(2).items_in_collection_with_length_method
125
+ owner.should_not have(2).items_in_collection_with_size_method
126
+ end
127
+
128
+ it "should fail if target has a collection of items with n members" do
129
+ owner = create_collection_owner_with(3)
130
+ lambda {
131
+ owner.should_not have(3).items_in_collection_with_length_method
132
+ }.should fail_with("expected target not to have 3 items_in_collection_with_length_method, got 3")
133
+ lambda {
134
+ owner.should_not have(3).items_in_collection_with_size_method
135
+ }.should fail_with("expected target not to have 3 items_in_collection_with_size_method, got 3")
136
+ end
137
+ end
138
+
139
+ describe "should have_exactly(n).items" do
140
+
141
+ it "should pass if target has a collection of items with n members" do
142
+ owner = create_collection_owner_with(3)
143
+ owner.should have_exactly(3).items_in_collection_with_length_method
144
+ owner.should have_exactly(3).items_in_collection_with_size_method
145
+ end
146
+
147
+ it "should convert :no to 0" do
148
+ owner = create_collection_owner_with(0)
149
+ owner.should have_exactly(:no).items_in_collection_with_length_method
150
+ owner.should have_exactly(:no).items_in_collection_with_size_method
151
+ end
152
+
153
+ it "should fail if target has a collection of items with < n members" do
154
+ owner = create_collection_owner_with(3)
155
+ lambda {
156
+ owner.should have_exactly(4).items_in_collection_with_length_method
157
+ }.should fail_with("expected 4 items_in_collection_with_length_method, got 3")
158
+ lambda {
159
+ owner.should have_exactly(4).items_in_collection_with_size_method
160
+ }.should fail_with("expected 4 items_in_collection_with_size_method, got 3")
161
+ end
162
+
163
+ it "should fail if target has a collection of items with > n members" do
164
+ owner = create_collection_owner_with(3)
165
+ lambda {
166
+ owner.should have_exactly(2).items_in_collection_with_length_method
167
+ }.should fail_with("expected 2 items_in_collection_with_length_method, got 3")
168
+ lambda {
169
+ owner.should have_exactly(2).items_in_collection_with_size_method
170
+ }.should fail_with("expected 2 items_in_collection_with_size_method, got 3")
171
+ end
172
+ end
173
+
174
+ describe "should have_at_least(n).items" do
175
+
176
+ it "should pass if target has a collection of items with n members" do
177
+ owner = create_collection_owner_with(3)
178
+ owner.should have_at_least(3).items_in_collection_with_length_method
179
+ owner.should have_at_least(3).items_in_collection_with_size_method
180
+ end
181
+
182
+ it "should pass if target has a collection of items with > n members" do
183
+ owner = create_collection_owner_with(3)
184
+ owner.should have_at_least(2).items_in_collection_with_length_method
185
+ owner.should have_at_least(2).items_in_collection_with_size_method
186
+ end
187
+
188
+ it "should fail if target has a collection of items with < n members" do
189
+ owner = create_collection_owner_with(3)
190
+ lambda {
191
+ owner.should have_at_least(4).items_in_collection_with_length_method
192
+ }.should fail_with("expected at least 4 items_in_collection_with_length_method, got 3")
193
+ lambda {
194
+ owner.should have_at_least(4).items_in_collection_with_size_method
195
+ }.should fail_with("expected at least 4 items_in_collection_with_size_method, got 3")
196
+ end
197
+
198
+ it "should provide educational negative failure messages" do
199
+ #given
200
+ owner = create_collection_owner_with(3)
201
+ length_matcher = have_at_least(3).items_in_collection_with_length_method
202
+ size_matcher = have_at_least(3).items_in_collection_with_size_method
203
+
204
+ #when
205
+ length_matcher.matches?(owner)
206
+ size_matcher.matches?(owner)
207
+
208
+ #then
209
+ length_matcher.negative_failure_message.should == <<-EOF
210
+ Isn't life confusing enough?
211
+ Instead of having to figure out the meaning of this:
212
+ should_not have_at_least(3).items_in_collection_with_length_method
213
+ We recommend that you use this instead:
214
+ should have_at_most(2).items_in_collection_with_length_method
215
+ EOF
216
+
217
+ size_matcher.negative_failure_message.should == <<-EOF
218
+ Isn't life confusing enough?
219
+ Instead of having to figure out the meaning of this:
220
+ should_not have_at_least(3).items_in_collection_with_size_method
221
+ We recommend that you use this instead:
222
+ should have_at_most(2).items_in_collection_with_size_method
223
+ EOF
224
+ end
225
+ end
226
+
227
+ describe "should have_at_most(n).items" do
228
+
229
+ it "should pass if target has a collection of items with n members" do
230
+ owner = create_collection_owner_with(3)
231
+ owner.should have_at_most(3).items_in_collection_with_length_method
232
+ owner.should have_at_most(3).items_in_collection_with_size_method
233
+ end
234
+
235
+ it "should fail if target has a collection of items with > n members" do
236
+ owner = create_collection_owner_with(3)
237
+ lambda {
238
+ owner.should have_at_most(2).items_in_collection_with_length_method
239
+ }.should fail_with("expected at most 2 items_in_collection_with_length_method, got 3")
240
+ lambda {
241
+ owner.should have_at_most(2).items_in_collection_with_size_method
242
+ }.should fail_with("expected at most 2 items_in_collection_with_size_method, got 3")
243
+ end
244
+
245
+ it "should pass if target has a collection of items with < n members" do
246
+ owner = create_collection_owner_with(3)
247
+ owner.should have_at_most(4).items_in_collection_with_length_method
248
+ owner.should have_at_most(4).items_in_collection_with_size_method
249
+ end
250
+
251
+ it "should provide educational negative failure messages" do
252
+ #given
253
+ owner = create_collection_owner_with(3)
254
+ length_matcher = have_at_most(3).items_in_collection_with_length_method
255
+ size_matcher = have_at_most(3).items_in_collection_with_size_method
256
+
257
+ #when
258
+ length_matcher.matches?(owner)
259
+ size_matcher.matches?(owner)
260
+
261
+ #then
262
+ length_matcher.negative_failure_message.should == <<-EOF
263
+ Isn't life confusing enough?
264
+ Instead of having to figure out the meaning of this:
265
+ should_not have_at_most(3).items_in_collection_with_length_method
266
+ We recommend that you use this instead:
267
+ should have_at_least(4).items_in_collection_with_length_method
268
+ EOF
269
+
270
+ size_matcher.negative_failure_message.should == <<-EOF
271
+ Isn't life confusing enough?
272
+ Instead of having to figure out the meaning of this:
273
+ should_not have_at_most(3).items_in_collection_with_size_method
274
+ We recommend that you use this instead:
275
+ should have_at_least(4).items_in_collection_with_size_method
276
+ EOF
277
+ end
278
+ end
279
+
280
+ describe "have(n).items(args, block)" do
281
+ it "should pass args to target" do
282
+ target = mock("target")
283
+ target.expects(:items).with("arg1","arg2").returns([1,2,3])
284
+ target.should have(3).items("arg1","arg2")
285
+ end
286
+
287
+ it "should pass block to target" do
288
+ target = mock("target")
289
+ block = lambda { 5 }
290
+ target.expects(:items).with("arg1","arg2", block).returns([1,2,3])
291
+ target.should have(3).items("arg1","arg2", block)
292
+ end
293
+ end
294
+
295
+ describe "have(n).items where target IS a collection" do
296
+ it "should reference the number of items IN the collection" do
297
+ [1,2,3].should have(3).items
298
+ end
299
+
300
+ it "should fail when the number of items IN the collection is not as expected" do
301
+ lambda { [1,2,3].should have(7).items }.should fail_with("expected 7 items, got 3")
302
+ end
303
+ end
304
+
305
+ describe "have(n).characters where target IS a String" do
306
+ it "should pass if the length is correct" do
307
+ "this string".should have(11).characters
308
+ end
309
+
310
+ it "should fail if the length is incorrect" do
311
+ lambda { "this string".should have(12).characters }.should fail_with("expected 12 characters, got 11")
312
+ end
313
+ end
314
+
315
+ describe "have(n).things on an object which is not a collection nor contains one" do
316
+ it "should fail" do
317
+ lambda { Object.new.should have(2).things }.should raise_error(NoMethodError, /undefined method `things' for #<Object:/)
318
+ end
319
+ end
320
+
321
+ describe Micronaut::Matchers::Have, "for a collection owner that implements #send" do
322
+
323
+ before do
324
+ @collection = Object.new
325
+ def @collection.floozles; [1,2] end
326
+ def @collection.send(*args); raise "DOH! Library developers shouldn't use #send!" end
327
+ end
328
+
329
+ it "should work in the straightforward case" do
330
+ lambda {
331
+ @collection.should have(2).floozles
332
+ }.should_not raise_error
333
+ end
334
+
335
+ it "should work when doing automatic pluralization" do
336
+ lambda {
337
+ @collection.should have_at_least(1).floozle
338
+ }.should_not raise_error
339
+ end
340
+
341
+ it "should blow up when the owner doesn't respond to that method" do
342
+ lambda {
343
+ @collection.should have(99).problems
344
+ }.should raise_error(NoMethodError, /problems/)
345
+ end
346
+ end
347
+
348
+ describe Micronaut::Matchers::Have do
349
+ it "should have method_missing as private" do
350
+ with_ruby '1.8' do
351
+ Micronaut::Matchers::Have.private_instance_methods.should include("method_missing")
352
+ end
353
+ with_ruby '1.9' do
354
+ Have.private_instance_methods.should include(:method_missing)
355
+ end
356
+ end
357
+
358
+ describe "respond_to?" do
359
+
360
+ before do
361
+ @have = Micronaut::Matchers::Have.new(:foo)
362
+ @a_method_which_have_defines = Micronaut::Matchers::Have.instance_methods.first
363
+ @a_method_which_object_defines = Object.instance_methods.first
364
+ end
365
+
366
+ it "should be true for a method which Have defines" do
367
+ @have.should respond_to(@a_method_which_have_defines)
368
+ end
369
+
370
+ it "should be true for a method that it's superclass (Object) defines" do
371
+ @have.should respond_to(@a_method_which_object_defines)
372
+ end
373
+
374
+ it "should be false for a method which neither Object nor nor Have defines" do
375
+ @have.should_not respond_to(:foo_bar_baz)
376
+ end
377
+
378
+ it "should be false if the owner doesn't respond to the method" do
379
+ have = Micronaut::Matchers::Have.new(99)
380
+ have.should_not respond_to(:problems)
381
+ end
382
+
383
+ it "should be true if the owner responds to the method" do
384
+ have = Micronaut::Matchers::Have.new(:a_symbol)
385
+ have.should respond_to(:to_sym)
386
+ end
387
+
388
+ end
389
+
390
+ end
391
+
392
+ end