opal-rspec-cj 0.4.4

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 (176) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/.gitmodules +15 -0
  4. data/.travis.yml +13 -0
  5. data/.yardopts +5 -0
  6. data/CHANGELOG.md +25 -0
  7. data/Gemfile +8 -0
  8. data/README.md +147 -0
  9. data/Rakefile +26 -0
  10. data/config.ru +10 -0
  11. data/example/Gemfile +4 -0
  12. data/example/README.md +13 -0
  13. data/example/Rakefile +8 -0
  14. data/example/opal/user.rb +11 -0
  15. data/example/spec/user_spec.rb +15 -0
  16. data/lib/opal-rspec.rb +2 -0
  17. data/lib/opal/rspec.rb +20 -0
  18. data/lib/opal/rspec/rake_task.rb +63 -0
  19. data/lib/opal/rspec/version.rb +5 -0
  20. data/opal-rspec.gemspec +21 -0
  21. data/opal/opal-rspec.rb +1 -0
  22. data/opal/opal/rspec.rb +25 -0
  23. data/opal/opal/rspec/async.rb +289 -0
  24. data/opal/opal/rspec/browser_formatter.rb +188 -0
  25. data/opal/opal/rspec/fixes.rb +116 -0
  26. data/opal/opal/rspec/requires.rb +45 -0
  27. data/opal/opal/rspec/runner.rb +69 -0
  28. data/opal/opal/rspec/sprockets_runner.rb.erb +11 -0
  29. data/opal/opal/rspec/text_formatter.rb +74 -0
  30. data/spec/async_spec.rb +38 -0
  31. data/spec/example_spec.rb +163 -0
  32. data/spec/matchers_spec.rb +201 -0
  33. data/spec/mock_spec.rb +63 -0
  34. data/spec/named_subject_spec.rb +11 -0
  35. data/spec/should_syntax_spec.rb +17 -0
  36. data/vendor/spec_runner.js +50 -0
  37. data/vendor_lib/rspec-expectations.rb +1 -0
  38. data/vendor_lib/rspec.rb +3 -0
  39. data/vendor_lib/rspec/autorun.rb +2 -0
  40. data/vendor_lib/rspec/core.rb +203 -0
  41. data/vendor_lib/rspec/core/backport_random.rb +302 -0
  42. data/vendor_lib/rspec/core/backtrace_formatter.rb +65 -0
  43. data/vendor_lib/rspec/core/command_line.rb +36 -0
  44. data/vendor_lib/rspec/core/configuration.rb +1129 -0
  45. data/vendor_lib/rspec/core/configuration_options.rb +143 -0
  46. data/vendor_lib/rspec/core/drb_command_line.rb +26 -0
  47. data/vendor_lib/rspec/core/drb_options.rb +87 -0
  48. data/vendor_lib/rspec/core/dsl.rb +26 -0
  49. data/vendor_lib/rspec/core/example.rb +312 -0
  50. data/vendor_lib/rspec/core/example_group.rb +540 -0
  51. data/vendor_lib/rspec/core/filter_manager.rb +224 -0
  52. data/vendor_lib/rspec/core/flat_map.rb +17 -0
  53. data/vendor_lib/rspec/core/formatters.rb +54 -0
  54. data/vendor_lib/rspec/core/formatters/base_formatter.rb +291 -0
  55. data/vendor_lib/rspec/core/formatters/base_text_formatter.rb +307 -0
  56. data/vendor_lib/rspec/core/formatters/deprecation_formatter.rb +193 -0
  57. data/vendor_lib/rspec/core/formatters/documentation_formatter.rb +67 -0
  58. data/vendor_lib/rspec/core/formatters/helpers.rb +82 -0
  59. data/vendor_lib/rspec/core/formatters/html_formatter.rb +155 -0
  60. data/vendor_lib/rspec/core/formatters/html_printer.rb +408 -0
  61. data/vendor_lib/rspec/core/formatters/json_formatter.rb +99 -0
  62. data/vendor_lib/rspec/core/formatters/progress_formatter.rb +32 -0
  63. data/vendor_lib/rspec/core/formatters/snippet_extractor.rb +101 -0
  64. data/vendor_lib/rspec/core/hooks.rb +535 -0
  65. data/vendor_lib/rspec/core/memoized_helpers.rb +431 -0
  66. data/vendor_lib/rspec/core/metadata.rb +313 -0
  67. data/vendor_lib/rspec/core/mocking/with_absolutely_nothing.rb +11 -0
  68. data/vendor_lib/rspec/core/mocking/with_flexmock.rb +27 -0
  69. data/vendor_lib/rspec/core/mocking/with_mocha.rb +52 -0
  70. data/vendor_lib/rspec/core/mocking/with_rr.rb +27 -0
  71. data/vendor_lib/rspec/core/mocking/with_rspec.rb +27 -0
  72. data/vendor_lib/rspec/core/option_parser.rb +234 -0
  73. data/vendor_lib/rspec/core/ordering.rb +154 -0
  74. data/vendor_lib/rspec/core/pending.rb +110 -0
  75. data/vendor_lib/rspec/core/project_initializer.rb +88 -0
  76. data/vendor_lib/rspec/core/rake_task.rb +128 -0
  77. data/vendor_lib/rspec/core/reporter.rb +132 -0
  78. data/vendor_lib/rspec/core/ruby_project.rb +44 -0
  79. data/vendor_lib/rspec/core/runner.rb +97 -0
  80. data/vendor_lib/rspec/core/shared_context.rb +53 -0
  81. data/vendor_lib/rspec/core/shared_example_group.rb +146 -0
  82. data/vendor_lib/rspec/core/shared_example_group/collection.rb +27 -0
  83. data/vendor_lib/rspec/core/version.rb +7 -0
  84. data/vendor_lib/rspec/core/warnings.rb +22 -0
  85. data/vendor_lib/rspec/core/world.rb +131 -0
  86. data/vendor_lib/rspec/expectations.rb +75 -0
  87. data/vendor_lib/rspec/expectations/differ.rb +154 -0
  88. data/vendor_lib/rspec/expectations/errors.rb +9 -0
  89. data/vendor_lib/rspec/expectations/expectation_target.rb +87 -0
  90. data/vendor_lib/rspec/expectations/extensions.rb +1 -0
  91. data/vendor_lib/rspec/expectations/extensions/object.rb +29 -0
  92. data/vendor_lib/rspec/expectations/fail_with.rb +79 -0
  93. data/vendor_lib/rspec/expectations/handler.rb +68 -0
  94. data/vendor_lib/rspec/expectations/syntax.rb +182 -0
  95. data/vendor_lib/rspec/expectations/version.rb +8 -0
  96. data/vendor_lib/rspec/matchers.rb +633 -0
  97. data/vendor_lib/rspec/matchers/built_in.rb +39 -0
  98. data/vendor_lib/rspec/matchers/built_in/base_matcher.rb +68 -0
  99. data/vendor_lib/rspec/matchers/built_in/be.rb +213 -0
  100. data/vendor_lib/rspec/matchers/built_in/be_instance_of.rb +15 -0
  101. data/vendor_lib/rspec/matchers/built_in/be_kind_of.rb +11 -0
  102. data/vendor_lib/rspec/matchers/built_in/be_within.rb +55 -0
  103. data/vendor_lib/rspec/matchers/built_in/change.rb +141 -0
  104. data/vendor_lib/rspec/matchers/built_in/cover.rb +21 -0
  105. data/vendor_lib/rspec/matchers/built_in/eq.rb +22 -0
  106. data/vendor_lib/rspec/matchers/built_in/eql.rb +23 -0
  107. data/vendor_lib/rspec/matchers/built_in/equal.rb +48 -0
  108. data/vendor_lib/rspec/matchers/built_in/exist.rb +26 -0
  109. data/vendor_lib/rspec/matchers/built_in/has.rb +48 -0
  110. data/vendor_lib/rspec/matchers/built_in/include.rb +61 -0
  111. data/vendor_lib/rspec/matchers/built_in/match.rb +17 -0
  112. data/vendor_lib/rspec/matchers/built_in/match_array.rb +51 -0
  113. data/vendor_lib/rspec/matchers/built_in/raise_error.rb +154 -0
  114. data/vendor_lib/rspec/matchers/built_in/respond_to.rb +74 -0
  115. data/vendor_lib/rspec/matchers/built_in/satisfy.rb +30 -0
  116. data/vendor_lib/rspec/matchers/built_in/start_and_end_with.rb +48 -0
  117. data/vendor_lib/rspec/matchers/built_in/throw_symbol.rb +94 -0
  118. data/vendor_lib/rspec/matchers/built_in/yield.rb +297 -0
  119. data/vendor_lib/rspec/matchers/compatibility.rb +14 -0
  120. data/vendor_lib/rspec/matchers/configuration.rb +113 -0
  121. data/vendor_lib/rspec/matchers/dsl.rb +23 -0
  122. data/vendor_lib/rspec/matchers/generated_descriptions.rb +35 -0
  123. data/vendor_lib/rspec/matchers/matcher.rb +301 -0
  124. data/vendor_lib/rspec/matchers/method_missing.rb +12 -0
  125. data/vendor_lib/rspec/matchers/operator_matcher.rb +99 -0
  126. data/vendor_lib/rspec/matchers/pretty.rb +70 -0
  127. data/vendor_lib/rspec/matchers/test_unit_integration.rb +11 -0
  128. data/vendor_lib/rspec/mocks.rb +100 -0
  129. data/vendor_lib/rspec/mocks/any_instance/chain.rb +92 -0
  130. data/vendor_lib/rspec/mocks/any_instance/expectation_chain.rb +47 -0
  131. data/vendor_lib/rspec/mocks/any_instance/message_chains.rb +75 -0
  132. data/vendor_lib/rspec/mocks/any_instance/recorder.rb +200 -0
  133. data/vendor_lib/rspec/mocks/any_instance/stub_chain.rb +45 -0
  134. data/vendor_lib/rspec/mocks/any_instance/stub_chain_chain.rb +23 -0
  135. data/vendor_lib/rspec/mocks/argument_list_matcher.rb +104 -0
  136. data/vendor_lib/rspec/mocks/argument_matchers.rb +264 -0
  137. data/vendor_lib/rspec/mocks/arity_calculator.rb +66 -0
  138. data/vendor_lib/rspec/mocks/configuration.rb +111 -0
  139. data/vendor_lib/rspec/mocks/error_generator.rb +203 -0
  140. data/vendor_lib/rspec/mocks/errors.rb +12 -0
  141. data/vendor_lib/rspec/mocks/example_methods.rb +201 -0
  142. data/vendor_lib/rspec/mocks/extensions/marshal.rb +17 -0
  143. data/vendor_lib/rspec/mocks/framework.rb +36 -0
  144. data/vendor_lib/rspec/mocks/instance_method_stasher.rb +112 -0
  145. data/vendor_lib/rspec/mocks/matchers/have_received.rb +99 -0
  146. data/vendor_lib/rspec/mocks/matchers/receive.rb +112 -0
  147. data/vendor_lib/rspec/mocks/matchers/receive_messages.rb +72 -0
  148. data/vendor_lib/rspec/mocks/message_expectation.rb +643 -0
  149. data/vendor_lib/rspec/mocks/method_double.rb +209 -0
  150. data/vendor_lib/rspec/mocks/method_reference.rb +95 -0
  151. data/vendor_lib/rspec/mocks/mock.rb +7 -0
  152. data/vendor_lib/rspec/mocks/mutate_const.rb +406 -0
  153. data/vendor_lib/rspec/mocks/object_reference.rb +90 -0
  154. data/vendor_lib/rspec/mocks/order_group.rb +82 -0
  155. data/vendor_lib/rspec/mocks/proxy.rb +269 -0
  156. data/vendor_lib/rspec/mocks/proxy_for_nil.rb +37 -0
  157. data/vendor_lib/rspec/mocks/space.rb +95 -0
  158. data/vendor_lib/rspec/mocks/standalone.rb +3 -0
  159. data/vendor_lib/rspec/mocks/stub_chain.rb +51 -0
  160. data/vendor_lib/rspec/mocks/syntax.rb +374 -0
  161. data/vendor_lib/rspec/mocks/targets.rb +90 -0
  162. data/vendor_lib/rspec/mocks/test_double.rb +109 -0
  163. data/vendor_lib/rspec/mocks/verifying_double.rb +77 -0
  164. data/vendor_lib/rspec/mocks/verifying_message_expecation.rb +60 -0
  165. data/vendor_lib/rspec/mocks/verifying_proxy.rb +151 -0
  166. data/vendor_lib/rspec/mocks/version.rb +7 -0
  167. data/vendor_lib/rspec/support.rb +6 -0
  168. data/vendor_lib/rspec/support/caller_filter.rb +56 -0
  169. data/vendor_lib/rspec/support/spec.rb +14 -0
  170. data/vendor_lib/rspec/support/spec/deprecation_helpers.rb +29 -0
  171. data/vendor_lib/rspec/support/spec/in_sub_process.rb +40 -0
  172. data/vendor_lib/rspec/support/spec/stderr_splitter.rb +50 -0
  173. data/vendor_lib/rspec/support/version.rb +7 -0
  174. data/vendor_lib/rspec/support/warnings.rb +41 -0
  175. data/vendor_lib/rspec/version.rb +5 -0
  176. metadata +268 -0
@@ -0,0 +1,74 @@
1
+ module RSpec
2
+ module Matchers
3
+ module BuiltIn
4
+ class RespondTo
5
+ def initialize(*names)
6
+ @names = names
7
+ @expected_arity = nil
8
+ end
9
+
10
+ def matches?(actual)
11
+ find_failing_method_names(actual, :reject).empty?
12
+ end
13
+ alias == matches?
14
+
15
+ def does_not_match?(actual)
16
+ find_failing_method_names(actual, :select).empty?
17
+ end
18
+
19
+ def failure_message_for_should
20
+ "expected #{@actual.inspect} to respond to #{@failing_method_names.collect {|name| name.inspect }.join(', ')}#{with_arity}"
21
+ end
22
+
23
+ def failure_message_for_should_not
24
+ failure_message_for_should.sub(/to respond to/, 'not to respond to')
25
+ end
26
+
27
+ def description
28
+ "respond to #{pp_names}#{with_arity}"
29
+ end
30
+
31
+ def with(n)
32
+ @expected_arity = n
33
+ self
34
+ end
35
+
36
+ def argument
37
+ self
38
+ end
39
+ alias :arguments :argument
40
+
41
+ private
42
+
43
+ def find_failing_method_names(actual, filter_method)
44
+ @actual = actual
45
+ @failing_method_names = @names.__send__(filter_method) do |name|
46
+ @actual.respond_to?(name) && matches_arity?(actual, name)
47
+ end
48
+ end
49
+
50
+ def matches_arity?(actual, name)
51
+ return true unless @expected_arity
52
+
53
+ actual_arity = actual.method(name).arity
54
+ if actual_arity < 0
55
+ # ~ inverts the one's complement and gives us the number of required args
56
+ ~actual_arity <= @expected_arity
57
+ else
58
+ actual_arity == @expected_arity
59
+ end
60
+ end
61
+
62
+ def with_arity
63
+ @expected_arity.nil?? "" :
64
+ " with #{@expected_arity} argument#{@expected_arity == 1 ? '' : 's'}"
65
+ end
66
+
67
+ def pp_names
68
+ # Ruby 1.9 returns the same thing for array.to_s as array.inspect, so just use array.inspect here
69
+ @names.length == 1 ? "##{@names.first}" : @names.inspect
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,30 @@
1
+ module RSpec
2
+ module Matchers
3
+ module BuiltIn
4
+ class Satisfy
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
+ alias == matches?
15
+
16
+ def failure_message_for_should
17
+ "expected #{@actual} to satisfy block"
18
+ end
19
+
20
+ def failure_message_for_should_not
21
+ "expected #{@actual} not to satisfy block"
22
+ end
23
+
24
+ def description
25
+ "satisfy block"
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,48 @@
1
+ module RSpec
2
+ module Matchers
3
+ module BuiltIn
4
+ class StartAndEndWith < BaseMatcher
5
+ def initialize(*expected)
6
+ @expected = expected.length == 1 ? expected.first : expected
7
+ end
8
+
9
+ def matches?(actual)
10
+ @actual = actual.respond_to?(:[]) ? actual : (raise ArgumentError.new("#{actual.inspect} does not respond to :[]"))
11
+ begin
12
+ @expected.respond_to?(:length) ? subset_matches?(@expected, @actual) : element_matches?(@expected, @actual)
13
+ rescue ArgumentError
14
+ raise ArgumentError.new("#{actual.inspect} does not have ordered elements")
15
+ end
16
+ end
17
+
18
+ def failure_message_for_should
19
+ "expected #{@actual.inspect} to #{self.class.name.split('::').last.sub(/With/,'').downcase} with #{@expected.inspect}"
20
+ end
21
+
22
+ def failure_message_for_should_not
23
+ "expected #{@actual.inspect} not to #{self.class.name.split('::').last.sub(/With/,'').downcase} with #{@expected.inspect}"
24
+ end
25
+ end
26
+
27
+ class StartWith < StartAndEndWith
28
+ def subset_matches?(expected, actual)
29
+ actual[0, expected.length] == expected
30
+ end
31
+
32
+ def element_matches?(expected, actual)
33
+ @actual[0] == @expected
34
+ end
35
+ end
36
+
37
+ class EndWith < StartAndEndWith
38
+ def subset_matches?(expected, actual)
39
+ actual[-expected.length, expected.length] == expected
40
+ end
41
+
42
+ def element_matches?(expected, actual)
43
+ actual[-1] == expected
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,94 @@
1
+ module RSpec
2
+ module Matchers
3
+ module BuiltIn
4
+ class ThrowSymbol
5
+ def initialize(expected_symbol = nil, expected_arg=nil)
6
+ @expected_symbol = expected_symbol
7
+ @expected_arg = expected_arg
8
+ @caught_symbol = @caught_arg = nil
9
+ end
10
+
11
+ def matches?(given_proc)
12
+ begin
13
+ if @expected_symbol.nil?
14
+ given_proc.call
15
+ else
16
+ @caught_arg = catch :proc_did_not_throw_anything do
17
+ catch @expected_symbol do
18
+ given_proc.call
19
+ throw :proc_did_not_throw_anything, :nothing_thrown
20
+ end
21
+ end
22
+
23
+ if @caught_arg == :nothing_thrown
24
+ @caught_arg = nil
25
+ else
26
+ @caught_symbol = @expected_symbol
27
+ end
28
+ end
29
+
30
+ # Ruby 1.8 uses NameError with `symbol'
31
+ # Ruby 1.9 uses ArgumentError with :symbol
32
+ rescue NameError, ArgumentError => e
33
+ unless e.message =~ /uncaught throw (`|\:)([a-zA-Z0-9_]*)(')?/
34
+ other_exception = e
35
+ raise
36
+ end
37
+ @caught_symbol = $2.to_sym
38
+ rescue => other_exception
39
+ raise
40
+ ensure
41
+ unless other_exception
42
+ if @expected_symbol.nil?
43
+ return !@caught_symbol.nil?
44
+ else
45
+ if @expected_arg.nil?
46
+ return @caught_symbol == @expected_symbol
47
+ else
48
+ return (@caught_symbol == @expected_symbol) & (@caught_arg == @expected_arg)
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ alias == matches?
55
+
56
+ def failure_message_for_should
57
+ "expected #{expected} to be thrown, got #{caught}"
58
+ end
59
+
60
+ def failure_message_for_should_not
61
+ "expected #{expected('no Symbol')}#{' not' if @expected_symbol} to be thrown, got #{caught}"
62
+ end
63
+
64
+ def description
65
+ "throw #{expected}"
66
+ end
67
+
68
+ private
69
+
70
+ def expected(symbol_desc = 'a Symbol')
71
+ throw_description(@expected_symbol || symbol_desc, @expected_arg)
72
+ end
73
+
74
+ def caught
75
+ throw_description(@caught_symbol || 'nothing', @caught_arg)
76
+ end
77
+
78
+ def throw_description(symbol, arg)
79
+ symbol_description = symbol.is_a?(String) ? symbol : symbol.inspect
80
+
81
+ arg_description = if arg
82
+ " with #{arg.inspect}"
83
+ elsif @expected_arg && @caught_symbol == @expected_symbol
84
+ " with no argument"
85
+ else
86
+ ""
87
+ end
88
+
89
+ symbol_description + arg_description
90
+ end
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,297 @@
1
+ module RSpec
2
+ module Matchers
3
+ module BuiltIn
4
+ class YieldProbe
5
+ def self.probe(block)
6
+ probe = new
7
+ assert_valid_expect_block!(block)
8
+ block.call(probe)
9
+ probe.assert_used!
10
+ probe
11
+ end
12
+
13
+ attr_accessor :num_yields, :yielded_args
14
+
15
+ def initialize
16
+ @used = false
17
+ self.num_yields, self.yielded_args = 0, []
18
+ end
19
+
20
+ def to_proc
21
+ @used = true
22
+
23
+ probe = self
24
+ Proc.new do |*args|
25
+ probe.num_yields += 1
26
+ probe.yielded_args << args
27
+ nil # to indicate the block does not return a meaningful value
28
+ end
29
+ end
30
+
31
+ def single_yield_args
32
+ yielded_args.first
33
+ end
34
+
35
+ def yielded_once?(matcher_name)
36
+ case num_yields
37
+ when 1 then true
38
+ when 0 then false
39
+ else
40
+ raise "The #{matcher_name} matcher is not designed to be used with a " +
41
+ "method that yields multiple times. Use the yield_successive_args " +
42
+ "matcher for that case."
43
+ end
44
+ end
45
+
46
+ def successive_yield_args
47
+ yielded_args.map do |arg_array|
48
+ arg_array.size == 1 ? arg_array.first : arg_array
49
+ end
50
+ end
51
+
52
+ def assert_used!
53
+ return if @used
54
+ raise "You must pass the argument yielded to your expect block on " +
55
+ "to the method-under-test as a block. It acts as a probe that " +
56
+ "allows the matcher to detect whether or not the method-under-test " +
57
+ "yields, and, if so, how many times, and what the yielded arguments " +
58
+ "are."
59
+ end
60
+
61
+ def self.assert_valid_expect_block!(block)
62
+ return if block.arity == 1
63
+ raise "Your expect block must accept an argument to be used with this " +
64
+ "matcher. Pass the argument as a block on to the method you are testing."
65
+ end
66
+ end
67
+
68
+ class YieldControl < BaseMatcher
69
+ def initialize
70
+ @expectation_type = nil
71
+ @expected_yields_count = nil
72
+ end
73
+
74
+ def matches?(block)
75
+ probe = YieldProbe.probe(block)
76
+
77
+ if @expectation_type
78
+ probe.num_yields.send(@expectation_type, @expected_yields_count)
79
+ else
80
+ probe.yielded_once?(:yield_control)
81
+ end
82
+ end
83
+
84
+ def once
85
+ exactly(1)
86
+ self
87
+ end
88
+
89
+ def twice
90
+ exactly(2)
91
+ self
92
+ end
93
+
94
+ def exactly(number)
95
+ set_expected_yields_count(:==, number)
96
+ self
97
+ end
98
+
99
+ def at_most(number)
100
+ set_expected_yields_count(:<=, number)
101
+ self
102
+ end
103
+
104
+ def at_least(number)
105
+ set_expected_yields_count(:>=, number)
106
+ self
107
+ end
108
+
109
+ def times
110
+ self
111
+ end
112
+
113
+ def failure_message_for_should
114
+ 'expected given block to yield control'.tap do |failure_message|
115
+ failure_message << relativity_failure_message
116
+ end
117
+ end
118
+
119
+ def failure_message_for_should_not
120
+ 'expected given block not to yield control'.tap do |failure_message|
121
+ failure_message << relativity_failure_message
122
+ end
123
+ end
124
+
125
+ private
126
+
127
+ def set_expected_yields_count(relativity, n)
128
+ @expectation_type = relativity
129
+ @expected_yields_count = case n
130
+ when Numeric then n
131
+ when :once then 1
132
+ when :twice then 2
133
+ end
134
+ end
135
+
136
+ def relativity_failure_message
137
+ return '' unless @expected_yields_count
138
+ " #{human_readable_expecation_type}#{human_readable_count}"
139
+ end
140
+
141
+ def human_readable_expecation_type
142
+ case @expectation_type
143
+ when :<= then 'at most '
144
+ when :>= then 'at least '
145
+ else ''
146
+ end
147
+ end
148
+
149
+ def human_readable_count
150
+ case @expected_yields_count
151
+ when 1 then "once"
152
+ when 2 then "twice"
153
+ else "#{@expected_yields_count} times"
154
+ end
155
+ end
156
+ end
157
+
158
+ class YieldWithNoArgs < BaseMatcher
159
+
160
+ def matches?(block)
161
+ @probe = YieldProbe.probe(block)
162
+ @probe.yielded_once?(:yield_with_no_args) && @probe.single_yield_args.empty?
163
+ end
164
+
165
+ def failure_message_for_should
166
+ "expected given block to yield with no arguments, but #{failure_reason}"
167
+ end
168
+
169
+ def failure_message_for_should_not
170
+ "expected given block not to yield with no arguments, but did"
171
+ end
172
+
173
+ private
174
+
175
+ def failure_reason
176
+ if @probe.num_yields.zero?
177
+ "did not yield"
178
+ else
179
+ "yielded with arguments: #{@probe.single_yield_args.inspect}"
180
+ end
181
+ end
182
+ end
183
+
184
+ class YieldWithArgs
185
+ def initialize(*args)
186
+ @expected = args
187
+ end
188
+
189
+ def matches?(block)
190
+ @probe = YieldProbe.probe(block)
191
+ @actual = @probe.single_yield_args
192
+ @probe.yielded_once?(:yield_with_args) && args_match?
193
+ end
194
+ alias == matches?
195
+
196
+ def failure_message_for_should
197
+ "expected given block to yield with arguments, but #{positive_failure_reason}"
198
+ end
199
+
200
+ def failure_message_for_should_not
201
+ "expected given block not to yield with arguments, but #{negative_failure_reason}"
202
+ end
203
+
204
+ def description
205
+ desc = "yield with args"
206
+ desc << "(" + @expected.map { |e| e.inspect }.join(", ") + ")" unless @expected.empty?
207
+ desc
208
+ end
209
+
210
+ private
211
+
212
+ def positive_failure_reason
213
+ if @probe.num_yields.zero?
214
+ "did not yield"
215
+ else
216
+ @positive_args_failure
217
+ end
218
+ end
219
+
220
+ def negative_failure_reason
221
+ if all_args_match?
222
+ "yielded with expected arguments" +
223
+ "\nexpected not: #{@expected.inspect}" +
224
+ "\n got: #{@actual.inspect} (compared using === and ==)"
225
+ else
226
+ "did"
227
+ end
228
+ end
229
+
230
+ def args_match?
231
+ if @expected.empty? # expect {...}.to yield_with_args
232
+ @positive_args_failure = "yielded with no arguments" if @actual.empty?
233
+ return !@actual.empty?
234
+ end
235
+
236
+ unless match = all_args_match?
237
+ @positive_args_failure = "yielded with unexpected arguments" +
238
+ "\nexpected: #{@expected.inspect}" +
239
+ "\n got: #{@actual.inspect} (compared using === and ==)"
240
+ end
241
+
242
+ match
243
+ end
244
+
245
+ def all_args_match?
246
+ return false if @expected.size != @actual.size
247
+
248
+ @expected.zip(@actual).all? do |expected, actual|
249
+ expected === actual || actual == expected
250
+ end
251
+ end
252
+ end
253
+
254
+ class YieldSuccessiveArgs
255
+ def initialize(*args)
256
+ @expected = args
257
+ end
258
+
259
+ def matches?(block)
260
+ @probe = YieldProbe.probe(block)
261
+ @actual = @probe.successive_yield_args
262
+ args_match?
263
+ end
264
+ alias == matches?
265
+
266
+ def failure_message_for_should
267
+ "expected given block to yield successively with arguments, but yielded with unexpected arguments" +
268
+ "\nexpected: #{@expected.inspect}" +
269
+ "\n got: #{@actual.inspect} (compared using === and ==)"
270
+ end
271
+
272
+ def failure_message_for_should_not
273
+ "expected given block not to yield successively with arguments, but yielded with expected arguments" +
274
+ "\nexpected not: #{@expected.inspect}" +
275
+ "\n got: #{@actual.inspect} (compared using === and ==)"
276
+ end
277
+
278
+ def description
279
+ desc = "yield successive args"
280
+ desc << "(" + @expected.map { |e| e.inspect }.join(", ") + ")"
281
+ desc
282
+ end
283
+
284
+ private
285
+
286
+ def args_match?
287
+ return false if @expected.size != @actual.size
288
+
289
+ @expected.zip(@actual).all? do |expected, actual|
290
+ expected === actual || actual == expected
291
+ end
292
+ end
293
+ end
294
+ end
295
+ end
296
+ end
297
+