rspec 0.7.5.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (194) hide show
  1. data/CHANGES +60 -1
  2. data/EXAMPLES.rd +38 -19
  3. data/MIT-LICENSE +1 -1
  4. data/README +24 -17
  5. data/RELEASE-PLAN +117 -0
  6. data/Rakefile +24 -18
  7. data/TODO.0.8.0 +5 -0
  8. data/examples/auto_spec_name_generation_example.rb +18 -0
  9. data/examples/custom_expectation_matchers.rb +53 -0
  10. data/examples/dynamic_spec.rb +9 -0
  11. data/examples/io_processor_spec.rb +2 -2
  12. data/examples/mocking_example.rb +4 -4
  13. data/examples/partial_mock_example.rb +2 -2
  14. data/examples/predicate_example.rb +2 -2
  15. data/examples/stack_spec.rb +32 -36
  16. data/examples/stubbing_example.rb +19 -19
  17. data/examples/test_case_spec.rb +6 -6
  18. data/lib/spec.rb +3 -0
  19. data/lib/spec/callback.rb +8 -0
  20. data/lib/spec/callback/extensions/object.rb +4 -0
  21. data/lib/spec/deprecated.rb +3 -0
  22. data/lib/spec/expectations.rb +44 -17
  23. data/lib/spec/expectations/extensions.rb +1 -2
  24. data/lib/spec/expectations/extensions/object.rb +78 -130
  25. data/lib/spec/expectations/extensions/string_and_symbol.rb +17 -0
  26. data/lib/spec/expectations/handler.rb +47 -0
  27. data/lib/spec/expectations/should/base.rb +32 -29
  28. data/lib/spec/expectations/should/change.rb +1 -1
  29. data/lib/spec/expectations/should/have.rb +9 -17
  30. data/lib/spec/expectations/should/not.rb +54 -56
  31. data/lib/spec/expectations/should/should.rb +59 -65
  32. data/lib/spec/expectations/sugar.rb +27 -4
  33. data/lib/spec/matchers.rb +160 -0
  34. data/lib/spec/matchers/be.rb +161 -0
  35. data/lib/spec/matchers/be_close.rb +37 -0
  36. data/lib/spec/matchers/change.rb +120 -0
  37. data/lib/spec/matchers/eql.rb +43 -0
  38. data/lib/spec/matchers/equal.rb +43 -0
  39. data/lib/spec/matchers/has.rb +44 -0
  40. data/lib/spec/matchers/have.rb +140 -0
  41. data/lib/spec/matchers/include.rb +50 -0
  42. data/lib/spec/matchers/match.rb +41 -0
  43. data/lib/spec/matchers/raise_error.rb +100 -0
  44. data/lib/spec/matchers/respond_to.rb +35 -0
  45. data/lib/spec/matchers/satisfy.rb +47 -0
  46. data/lib/spec/matchers/throw_symbol.rb +75 -0
  47. data/lib/spec/mocks.rb +224 -1
  48. data/lib/spec/mocks/argument_expectation.rb +16 -2
  49. data/lib/spec/mocks/error_generator.rb +5 -3
  50. data/lib/spec/mocks/errors.rb +2 -2
  51. data/lib/spec/mocks/extensions/object.rb +1 -1
  52. data/lib/spec/mocks/message_expectation.rb +29 -19
  53. data/lib/spec/mocks/{mock_methods.rb → methods.rb} +5 -5
  54. data/lib/spec/mocks/mock.rb +2 -2
  55. data/lib/spec/mocks/mock_handler.rb +81 -68
  56. data/lib/spec/rake/spectask.rb +7 -12
  57. data/lib/spec/rake/verify_rcov.rb +1 -1
  58. data/lib/spec/runner.rb +117 -0
  59. data/lib/spec/runner/command_line.rb +8 -5
  60. data/lib/spec/runner/context.rb +13 -37
  61. data/lib/spec/runner/context_eval.rb +4 -3
  62. data/lib/spec/runner/context_runner.rb +7 -4
  63. data/lib/spec/runner/drb_command_line.rb +1 -1
  64. data/lib/spec/runner/execution_context.rb +3 -11
  65. data/lib/spec/runner/extensions/kernel.rb +7 -5
  66. data/lib/spec/runner/extensions/object.rb +4 -1
  67. data/lib/spec/runner/formatter/base_text_formatter.rb +11 -3
  68. data/lib/spec/runner/formatter/html_formatter.rb +21 -10
  69. data/lib/spec/runner/heckle_runner.rb +24 -8
  70. data/lib/spec/runner/heckle_runner_win.rb +10 -0
  71. data/lib/spec/runner/option_parser.rb +58 -13
  72. data/lib/spec/runner/spec_matcher.rb +22 -29
  73. data/lib/spec/runner/spec_parser.rb +1 -0
  74. data/lib/spec/runner/specification.rb +36 -22
  75. data/lib/spec/translator.rb +87 -0
  76. data/lib/spec/version.rb +16 -7
  77. data/spec/spec/callback/callback_container_spec.rb +27 -0
  78. data/spec/spec/callback/module_spec.rb +37 -0
  79. data/spec/spec/callback/object_spec.rb +90 -0
  80. data/spec/spec/callback/object_with_class_callback_spec.rb +19 -0
  81. data/spec/spec/expectations/differs/default_spec.rb +107 -0
  82. data/spec/spec/expectations/extensions/object_spec.rb +46 -0
  83. data/spec/spec/expectations/fail_with_spec.rb +71 -0
  84. data/spec/spec/expectations/should/should_==_spec.rb +19 -0
  85. data/spec/spec/expectations/should/should_=~_spec.rb +13 -0
  86. data/spec/spec/expectations/should/should_be_a_kind_of_spec.rb +21 -0
  87. data/spec/spec/expectations/should/should_be_an_instance_of_spec.rb +30 -0
  88. data/spec/spec/expectations/should/should_be_arbitrary_predicate_spec.rb +81 -0
  89. data/spec/spec/expectations/should/should_be_close_spec.rb +18 -0
  90. data/spec/spec/expectations/should/should_be_comparison_operator_spec.rb +44 -0
  91. data/spec/spec/expectations/should/should_be_false_spec.rb +39 -0
  92. data/spec/spec/expectations/should/should_be_spec.rb +11 -0
  93. data/spec/spec/expectations/should/should_be_true_spec.rb +27 -0
  94. data/spec/spec/expectations/should/should_change_spec.rb +184 -0
  95. data/spec/spec/expectations/should/should_eql_spec.rb +11 -0
  96. data/spec/spec/expectations/should/should_equal_spec.rb +11 -0
  97. data/spec/spec/expectations/should/should_have_at_least_spec.rb +53 -0
  98. data/spec/spec/expectations/should/should_have_at_most_spec.rb +45 -0
  99. data/spec/spec/expectations/should/should_have_key_spec.rb +21 -0
  100. data/spec/spec/expectations/should/should_have_spec.rb +64 -0
  101. data/spec/spec/expectations/should/should_include_spec.rb +59 -0
  102. data/spec/spec/expectations/should/should_match_spec.rb +25 -0
  103. data/spec/spec/expectations/should/should_not_==_spec.rb +15 -0
  104. data/spec/spec/expectations/should/should_not_be_a_kind_of_spec.rb +21 -0
  105. data/spec/spec/expectations/should/should_not_be_an_instance_of_spec.rb +11 -0
  106. data/spec/spec/expectations/should/should_not_be_arbitrary_predicate_spec.rb +68 -0
  107. data/spec/spec/expectations/should/should_not_be_spec.rb +11 -0
  108. data/spec/spec/expectations/should/should_not_change_spec.rb +24 -0
  109. data/spec/spec/expectations/should/should_not_eql_spec.rb +11 -0
  110. data/spec/spec/expectations/should/should_not_equal_spec.rb +11 -0
  111. data/spec/spec/expectations/should/should_not_have_key_spec.rb +15 -0
  112. data/spec/spec/expectations/should/should_not_include_spec.rb +58 -0
  113. data/spec/spec/expectations/should/should_not_match_spec.rb +11 -0
  114. data/spec/spec/expectations/should/should_not_raise_spec.rb +75 -0
  115. data/spec/spec/expectations/should/should_not_respond_to_spec.rb +15 -0
  116. data/spec/spec/expectations/should/should_not_throw_spec.rb +35 -0
  117. data/spec/spec/expectations/should/should_raise_spec.rb +66 -0
  118. data/spec/spec/expectations/should/should_respond_to_spec.rb +15 -0
  119. data/spec/spec/expectations/should/should_satisfy_spec.rb +35 -0
  120. data/spec/spec/expectations/should/should_throw_spec.rb +27 -0
  121. data/spec/spec/matchers/be_close_spec.rb +33 -0
  122. data/spec/spec/matchers/be_spec.rb +182 -0
  123. data/spec/spec/matchers/change_spec.rb +232 -0
  124. data/spec/spec/matchers/description_generation_spec.rb +147 -0
  125. data/spec/spec/matchers/eql_spec.rb +41 -0
  126. data/spec/spec/matchers/equal_spec.rb +41 -0
  127. data/spec/spec/matchers/handler_spec.rb +75 -0
  128. data/spec/spec/matchers/has_spec.rb +37 -0
  129. data/spec/spec/matchers/have_spec.rb +259 -0
  130. data/spec/spec/matchers/include_spec.rb +33 -0
  131. data/spec/spec/matchers/match_spec.rb +37 -0
  132. data/spec/spec/matchers/matcher_methods_spec.rb +85 -0
  133. data/spec/spec/matchers/raise_error_spec.rb +147 -0
  134. data/spec/spec/matchers/respond_to_spec.rb +30 -0
  135. data/spec/spec/matchers/satisfy_spec.rb +36 -0
  136. data/spec/spec/matchers/throw_symbol_spec.rb +59 -0
  137. data/spec/spec/mocks/any_number_of_times_spec.rb +34 -0
  138. data/spec/spec/mocks/at_least_spec.rb +97 -0
  139. data/spec/spec/mocks/at_most_spec.rb +97 -0
  140. data/spec/spec/mocks/bug_report_7611_spec.rb +19 -0
  141. data/spec/spec/mocks/bug_report_7805_spec.rb +22 -0
  142. data/spec/spec/mocks/bug_report_8165_spec.rb +31 -0
  143. data/spec/spec/mocks/bug_report_8302_spec.rb +26 -0
  144. data/spec/spec/mocks/failing_mock_argument_constraints_spec.rb +74 -0
  145. data/spec/spec/mocks/mock_ordering_spec.rb +80 -0
  146. data/spec/spec/mocks/mock_spec.rb +407 -0
  147. data/spec/spec/mocks/multiple_return_value_spec.rb +113 -0
  148. data/spec/spec/mocks/null_object_mock_spec.rb +40 -0
  149. data/spec/spec/mocks/once_counts_spec.rb +56 -0
  150. data/spec/spec/mocks/options_hash_spec.rb +31 -0
  151. data/spec/spec/mocks/partial_mock_spec.rb +52 -0
  152. data/spec/spec/mocks/partial_mock_using_mocks_directly_spec.rb +64 -0
  153. data/spec/spec/mocks/passing_mock_argument_constraints_spec.rb +92 -0
  154. data/spec/spec/mocks/precise_counts_spec.rb +56 -0
  155. data/spec/spec/mocks/record_messages_spec.rb +26 -0
  156. data/spec/spec/mocks/stub_spec.rb +159 -0
  157. data/spec/spec/mocks/twice_counts_spec.rb +67 -0
  158. data/spec/spec/runner/command_line_spec.rb +32 -0
  159. data/spec/spec/runner/context_matching_spec.rb +28 -0
  160. data/spec/spec/runner/context_runner_spec.rb +100 -0
  161. data/spec/spec/runner/context_spec.rb +405 -0
  162. data/spec/spec/runner/drb_command_line_spec.rb +74 -0
  163. data/spec/spec/runner/execution_context_spec.rb +52 -0
  164. data/spec/spec/runner/formatter/html_formatter_spec.rb +40 -0
  165. data/spec/spec/runner/formatter/progress_bar_formatter_dry_run_spec.rb +21 -0
  166. data/spec/spec/runner/formatter/progress_bar_formatter_failure_dump_spec.rb +36 -0
  167. data/spec/spec/runner/formatter/progress_bar_formatter_spec.rb +78 -0
  168. data/spec/spec/runner/formatter/rdoc_formatter_dry_run_spec.rb +18 -0
  169. data/spec/spec/runner/formatter/rdoc_formatter_spec.rb +41 -0
  170. data/spec/spec/runner/formatter/specdoc_formatter_dry_run_spec.rb +21 -0
  171. data/spec/spec/runner/formatter/specdoc_formatter_spec.rb +46 -0
  172. data/spec/spec/runner/heckle_runner_spec.rb +63 -0
  173. data/spec/spec/runner/heckler_spec.rb +14 -0
  174. data/spec/spec/runner/kernel_ext_spec.rb +16 -0
  175. data/spec/spec/runner/noisy_backtrace_tweaker_spec.rb +45 -0
  176. data/spec/spec/runner/object_ext_spec.rb +11 -0
  177. data/spec/spec/runner/option_parser_spec.rb +269 -0
  178. data/spec/spec/runner/quiet_backtrace_tweaker_spec.rb +47 -0
  179. data/spec/spec/runner/reporter_spec.rb +126 -0
  180. data/spec/spec/runner/spec_matcher_spec.rb +107 -0
  181. data/spec/spec/runner/spec_name_generation_spec.rb +102 -0
  182. data/spec/spec/runner/spec_parser_spec.rb +37 -0
  183. data/spec/spec/runner/specification_class_spec.rb +72 -0
  184. data/spec/spec/runner/specification_instance_spec.rb +160 -0
  185. data/spec/spec/runner/specification_should_raise_spec.rb +136 -0
  186. data/spec/spec/spec_classes.rb +102 -0
  187. data/spec/spec/translator_spec.rb +79 -0
  188. data/spec/spec_helper.rb +35 -0
  189. metadata +141 -9
  190. data/bin/drbspec +0 -3
  191. data/lib/spec/expectations/diff.rb +0 -28
  192. data/lib/spec/expectations/extensions/numeric.rb +0 -19
  193. data/lib/spec/expectations/extensions/string.rb +0 -22
  194. data/lib/spec/expectations/message_builder.rb +0 -13
@@ -0,0 +1,140 @@
1
+ module Spec
2
+ module Matchers
3
+
4
+ class Have #:nodoc:
5
+ def initialize(expected, relativity=:exactly)
6
+ @expected = (expected == :no ? 0 : expected)
7
+ @relativity = relativity
8
+ end
9
+
10
+ def relativities
11
+ @relativities ||= {
12
+ :exactly => "",
13
+ :at_least => "at least ",
14
+ :at_most => "at most "
15
+ }
16
+ end
17
+
18
+ def method_missing(sym, *args, &block)
19
+ @collection_name = sym
20
+ @args = args
21
+ @block = block
22
+ self
23
+ end
24
+
25
+ def matches?(collection_owner)
26
+ if collection_owner.respond_to?(collection_name)
27
+ collection = collection_owner.send(collection_name, *@args, &@block)
28
+ elsif (collection_owner.respond_to?(:length) || collection_owner.respond_to?(:size))
29
+ collection = collection_owner
30
+ else
31
+ collection_owner.send(collection_name, *@args, &@block)
32
+ end
33
+ @actual = collection.length if collection.respond_to?(:length)
34
+ @actual = collection.size if collection.respond_to?(:size)
35
+ return @actual >= @expected if @relativity == :at_least
36
+ return @actual <= @expected if @relativity == :at_most
37
+ return @actual == @expected
38
+ end
39
+
40
+ def failure_message
41
+ "expected #{relative_expectation} #{collection_name}, got #{@actual}"
42
+ end
43
+
44
+ def negative_failure_message
45
+ if @relativity == :exactly
46
+ return "expected target not to have #{@expected} #{collection_name}, got #{@actual}"
47
+ elsif @relativity == :at_most
48
+ return <<-EOF
49
+ Isn't life confusing enough?
50
+ Instead of having to figure out the meaning of this:
51
+ should_not have_at_most(#{@expected}).#{collection_name}
52
+ We recommend that you use this instead:
53
+ should have_at_least(#{@expected + 1}).#{collection_name}
54
+ EOF
55
+ elsif @relativity == :at_least
56
+ return <<-EOF
57
+ Isn't life confusing enough?
58
+ Instead of having to figure out the meaning of this:
59
+ should_not have_at_least(#{@expected}).#{collection_name}
60
+ We recommend that you use this instead:
61
+ should have_at_most(#{@expected - 1}).#{collection_name}
62
+ EOF
63
+ end
64
+ end
65
+
66
+ def description
67
+ "have #{relative_expectation} #{collection_name}"
68
+ end
69
+
70
+ private
71
+ def collection_name
72
+ @collection_name
73
+ end
74
+
75
+ def relative_expectation
76
+ "#{relativities[@relativity]}#{@expected}"
77
+ end
78
+ end
79
+
80
+ # :call-seq:
81
+ # should have(number).named_collection__or__sugar
82
+ # should_not have(number).named_collection__or__sugar
83
+ #
84
+ # Passes if receiver is a collection with the submitted
85
+ # number of items OR if the receiver OWNS a collection
86
+ # with the submitted number of items.
87
+ #
88
+ # If the receiver OWNS the collection, you must use the name
89
+ # of the collection. So if a <tt>Team</tt> instance has a
90
+ # collection named <tt>#players</tt>, you must use that name
91
+ # to set the expectation.
92
+ #
93
+ # If the receiver IS the collection, you can use any name
94
+ # you like for <tt>named_collection</tt>. We'd recommend using
95
+ # either "elements", "members", or "items" as these are all
96
+ # standard ways of describing the things IN a collection.
97
+ #
98
+ # This also works for Strings, letting you set an expectation
99
+ # about its length
100
+ #
101
+ # == Examples
102
+ #
103
+ # # Passes if team.players.size == 11
104
+ # team.should have(11).players
105
+ #
106
+ # # Passes if [1,2,3].length == 3
107
+ # [1,2,3].should have(3).items #"items" is pure sugar
108
+ #
109
+ # # Passes if "this string".length == 11
110
+ # "this string".should have(11).characters #"characters" is pure sugar
111
+ def have(n)
112
+ Matchers::Have.new(n)
113
+ end
114
+ alias :have_exactly :have
115
+
116
+ # :call-seq:
117
+ # should have_at_least(number).items
118
+ #
119
+ # Exactly like have() with >=.
120
+ #
121
+ # == Warning
122
+ #
123
+ # +should_not+ +have_at_least+ is not supported
124
+ def have_at_least(n)
125
+ Matchers::Have.new(n, :at_least)
126
+ end
127
+
128
+ # :call-seq:
129
+ # should have_at_most(number).items
130
+ #
131
+ # Exactly like have() with <=.
132
+ #
133
+ # == Warning
134
+ #
135
+ # +should_not+ +have_at_most+ is not supported
136
+ def have_at_most(n)
137
+ Matchers::Have.new(n, :at_most)
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,50 @@
1
+ module Spec
2
+ module Matchers
3
+
4
+ class Include #:nodoc:
5
+
6
+ def initialize(expected)
7
+ @expected = expected
8
+ end
9
+
10
+ def matches?(actual)
11
+ @actual = actual
12
+ actual.include?(@expected)
13
+ end
14
+
15
+ def failure_message
16
+ _message
17
+ end
18
+
19
+ def negative_failure_message
20
+ _message("not ")
21
+ end
22
+
23
+ def description
24
+ "include #{@expected.inspect}"
25
+ end
26
+
27
+ private
28
+ def _message(maybe_not="")
29
+ "expected #{@actual.inspect} #{maybe_not}to include #{@expected.inspect}"
30
+ end
31
+ end
32
+
33
+ # :call-seq:
34
+ # should include(expected)
35
+ # should_not include(expected)
36
+ #
37
+ # Passes if actual includes expected. This works for
38
+ # collections and Strings
39
+ #
40
+ # == Examples
41
+ #
42
+ # [1,2,3].should include(3)
43
+ # [1,2,3].should_not include(4)
44
+ # "spread".should include("read")
45
+ # "spread".should_not include("red")
46
+ def include(expected)
47
+ Matchers::Include.new(expected)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,41 @@
1
+ module Spec
2
+ module Matchers
3
+
4
+ class Match #:nodoc:
5
+ def initialize(expected)
6
+ @expected = expected
7
+ end
8
+
9
+ def matches?(actual)
10
+ @actual = actual
11
+ return true if actual =~ @expected
12
+ return false
13
+ end
14
+
15
+ def failure_message
16
+ return "expected #{@actual.inspect} to match #{@expected.inspect}", @expected, @actual
17
+ end
18
+
19
+ def negative_failure_message
20
+ return "expected #{@actual.inspect} not to match #{@expected.inspect}", @expected, @actual
21
+ end
22
+
23
+ def description
24
+ "match #{@expected.inspect}"
25
+ end
26
+ end
27
+
28
+ # :call-seq:
29
+ # should match(regexp)
30
+ # should_not match(regexp)
31
+ #
32
+ # Given a Regexp, passes if actual =~ regexp
33
+ #
34
+ # == Examples
35
+ #
36
+ # email.should match(/^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i)
37
+ def match(regexp)
38
+ Matchers::Match.new(regexp)
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,100 @@
1
+ module Spec
2
+ module Matchers
3
+
4
+ class RaiseError #:nodoc:
5
+ def initialize(exception=Exception, message=nil)
6
+ @expected_error = exception
7
+ @expected_message = message
8
+ end
9
+
10
+ def matches?(proc)
11
+ @raised_expected_error = false
12
+ @raised_other = false
13
+ begin
14
+ proc.call
15
+ rescue @expected_error => @actual_error
16
+ if @expected_message.nil?
17
+ @raised_expected_error = true
18
+ else
19
+ case @expected_message
20
+ when Regexp
21
+ if @expected_message =~ @actual_error.message
22
+ @raised_expected_error = true
23
+ else
24
+ @raised_other = true
25
+ end
26
+ else
27
+ if @actual_error.message == @expected_message
28
+ @raised_expected_error = true
29
+ else
30
+ @raised_other = true
31
+ end
32
+ end
33
+ end
34
+ rescue => @actual_error
35
+ @raised_other = true
36
+ ensure
37
+ return @raised_expected_error
38
+ end
39
+ end
40
+
41
+ def failure_message
42
+ return "expected #{expected_error}#{actual_error}" if @raised_other || !@raised_expected_error
43
+ end
44
+
45
+ def negative_failure_message
46
+ "expected no #{expected_error}#{actual_error}"
47
+ end
48
+
49
+ def description
50
+ "raise #{expected_error}"
51
+ end
52
+
53
+ private
54
+ def expected_error
55
+ case @expected_message
56
+ when nil
57
+ @expected_error
58
+ when Regexp
59
+ "#{@expected_error} with message matching #{@expected_message.inspect}"
60
+ else
61
+ "#{@expected_error} with #{@expected_message.inspect}"
62
+ end
63
+ end
64
+
65
+ def actual_error
66
+ @actual_error.nil? ? " but nothing was raised" : ", got #{@actual_error.inspect}"
67
+ end
68
+ end
69
+
70
+ # :call-seq:
71
+ # should raise_error()
72
+ # should raise_error(NamedError)
73
+ # should raise_error(NamedError, String)
74
+ # should raise_error(NamedError, Regexp)
75
+ # should_not raise_error()
76
+ # should_not raise_error(NamedError)
77
+ # should_not raise_error(NamedError, String)
78
+ # should_not raise_error(NamedError, Regexp)
79
+ #
80
+ # With no args, matches if any error is raised.
81
+ # With a named error, matches only if that specific error is raised.
82
+ # With a named error and messsage specified as a String, matches only if both match.
83
+ # With a named error and messsage specified as a Regexp, matches only if both match.
84
+ #
85
+ # == Examples
86
+ #
87
+ # lambda { do_something_risky }.should raise_error
88
+ # lambda { do_something_risky }.should raise_error(PoorRiskDecisionError)
89
+ # lambda { do_something_risky }.should raise_error(PoorRiskDecisionError, "that was too risky")
90
+ # lambda { do_something_risky }.should raise_error(PoorRiskDecisionError, /oo ri/)
91
+ #
92
+ # lambda { do_something_risky }.should_not raise_error
93
+ # lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError)
94
+ # lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError, "that was too risky")
95
+ # lambda { do_something_risky }.should_not raise_error(PoorRiskDecisionError, /oo ri/)
96
+ def raise_error(error=Exception, message=nil)
97
+ Matchers::RaiseError.new(error, message)
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,35 @@
1
+ module Spec
2
+ module Matchers
3
+
4
+ class RespondTo #:nodoc:
5
+ def initialize(sym)
6
+ @sym = sym
7
+ end
8
+
9
+ def matches?(target)
10
+ return target.respond_to?(@sym)
11
+ end
12
+
13
+ def failure_message
14
+ "expected target to respond to #{@sym.inspect}"
15
+ end
16
+
17
+ def negative_failure_message
18
+ "expected target not to respond to #{@sym.inspect}"
19
+ end
20
+
21
+ def description
22
+ "respond to ##{@sym.to_s}"
23
+ end
24
+ end
25
+
26
+ # :call-seq:
27
+ # should respond_to(:sym)
28
+ # should_not respond_to(:sym)
29
+ #
30
+ # Matches if the target object responds to :sym
31
+ def respond_to(sym)
32
+ Matchers::RespondTo.new(sym)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,47 @@
1
+ module Spec
2
+ module Matchers
3
+
4
+ class Satisfy #:nodoc:
5
+ def initialize(&block)
6
+ @block = block
7
+ end
8
+
9
+ def matches?(actual, &block)
10
+ @block = block if block
11
+ @actual = actual
12
+ @block.call(actual)
13
+ end
14
+
15
+ def failure_message
16
+ "expected #{@actual} to satisfy block"
17
+ end
18
+
19
+ def negative_failure_message
20
+ "expected #{@actual} not to satisfy block"
21
+ end
22
+ end
23
+
24
+ # :call-seq:
25
+ # should satisfy {}
26
+ # should_not satisfy {}
27
+ #
28
+ # Passes if the submitted block returns true. Yields target to the
29
+ # block.
30
+ #
31
+ # Generally speaking, this should be thought of as a last resort when
32
+ # you can't find any other way to specify the behaviour you wish to
33
+ # specify.
34
+ #
35
+ # If you do find yourself in such a situation, you could always write
36
+ # a custom matcher, which would likely make your specs more expressive.
37
+ #
38
+ # == Examples
39
+ #
40
+ # 5.should satisfy { |n|
41
+ # n > 3
42
+ # }
43
+ def satisfy(&block)
44
+ Matchers::Satisfy.new(&block)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,75 @@
1
+ module Spec
2
+ module Matchers
3
+
4
+ class ThrowSymbol #:nodoc:
5
+ def initialize(expected=nil)
6
+ @expected = expected
7
+ end
8
+
9
+ def matches?(proc)
10
+ begin
11
+ proc.call
12
+ rescue NameError => e
13
+ @actual = extract_sym_from_name_error(e)
14
+ ensure
15
+ if @expected.nil?
16
+ return @actual.nil? ? false : true
17
+ else
18
+ return @actual == @expected
19
+ end
20
+ end
21
+ end
22
+
23
+ def failure_message
24
+ if @actual
25
+ "expected #{expected}, got #{@actual.inspect}"
26
+ else
27
+ "expected #{expected} but nothing was thrown"
28
+ end
29
+ end
30
+
31
+ def negative_failure_message
32
+ if @expected
33
+ "expected #{expected} not to be thrown"
34
+ else
35
+ "expected no Symbol, got :#{@actual}"
36
+ end
37
+ end
38
+
39
+ def description
40
+ "throw #{expected}"
41
+ end
42
+
43
+ private
44
+
45
+ def expected
46
+ @expected.nil? ? "a Symbol" : @expected.inspect
47
+ end
48
+
49
+ def extract_sym_from_name_error(error)
50
+ return "#{error.message.split("`").last.split("'").first}".to_sym
51
+ end
52
+ end
53
+
54
+ # :call-seq:
55
+ # should throw_symbol()
56
+ # should throw_symbol(:sym)
57
+ # should_not throw_symbol()
58
+ # should_not throw_symbol(:sym)
59
+ #
60
+ # Given a Symbol argument, matches if a proc throws the specified Symbol.
61
+ #
62
+ # Given no argument, matches if a proc throws any Symbol.
63
+ #
64
+ # == Examples
65
+ #
66
+ # lambda { do_something_risky }.should throw_symbol
67
+ # lambda { do_something_risky }.should throw_symbol(:that_was_risky)
68
+ #
69
+ # lambda { do_something_risky }.should_not throw_symbol
70
+ # lambda { do_something_risky }.should_not throw_symbol(:that_was_risky)
71
+ def throw_symbol(sym=nil)
72
+ Matchers::ThrowSymbol.new(sym)
73
+ end
74
+ end
75
+ end