opal-rspec-cj 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
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,12 @@
1
+ module RSpec
2
+ module Matchers
3
+
4
+ private
5
+
6
+ def method_missing(method, *args, &block)
7
+ return Matchers::BuiltIn::BePredicate.new(method, *args, &block) if method.to_s =~ /^be_/
8
+ return Matchers::BuiltIn::Has.new(method, *args, &block) if method.to_s =~ /^have_/
9
+ super
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,99 @@
1
+ module RSpec
2
+ module Matchers
3
+ class OperatorMatcher
4
+ class << self
5
+ def registry
6
+ @registry ||= {}
7
+ end
8
+
9
+ def register(klass, operator, matcher)
10
+ registry[klass] ||= {}
11
+ registry[klass][operator] = matcher
12
+ end
13
+
14
+ def unregister(klass, operator)
15
+ registry[klass] && registry[klass].delete(operator)
16
+ end
17
+
18
+ def get(klass, operator)
19
+ klass.ancestors.each { |ancestor|
20
+ matcher = registry[ancestor] && registry[ancestor][operator]
21
+ return matcher if matcher
22
+ }
23
+
24
+ nil
25
+ end
26
+ end
27
+
28
+ def initialize(actual)
29
+ @actual = actual
30
+ end
31
+
32
+ def self.use_custom_matcher_or_delegate(operator)
33
+ define_method(operator) do |expected|
34
+ if uses_generic_implementation_of?(operator) && matcher = OperatorMatcher.get(@actual.class, operator)
35
+ @actual.__send__(::RSpec::Matchers.last_should, matcher.new(expected))
36
+ else
37
+ eval_match(@actual, operator, expected)
38
+ end
39
+ end
40
+
41
+ negative_operator = operator.sub(/^=/, '!')
42
+ if negative_operator != operator && respond_to?(negative_operator)
43
+ define_method(negative_operator) do |expected|
44
+ opposite_should = ::RSpec::Matchers.last_should == :should ? :should_not : :should
45
+ raise "RSpec does not support `#{::RSpec::Matchers.last_should} #{negative_operator} expected`. " +
46
+ "Use `#{opposite_should} #{operator} expected` instead."
47
+ end
48
+ end
49
+ end
50
+
51
+ ['==', '===', '=~', '>', '>=', '<', '<='].each do |operator|
52
+ use_custom_matcher_or_delegate operator
53
+ end
54
+
55
+ def fail_with_message(message)
56
+ RSpec::Expectations.fail_with(message, @expected, @actual)
57
+ end
58
+
59
+ def description
60
+ "#{@operator} #{@expected.inspect}"
61
+ end
62
+
63
+ private
64
+
65
+ def uses_generic_implementation_of?(op)
66
+ Expectations.method_handle_for(@actual, op).owner == ::Kernel
67
+ rescue NameError
68
+ false
69
+ end
70
+
71
+ def eval_match(actual, operator, expected)
72
+ ::RSpec::Matchers.last_matcher = self
73
+ @operator, @expected = operator, expected
74
+ __delegate_operator(actual, operator, expected)
75
+ end
76
+ end
77
+
78
+ module BuiltIn
79
+ class PositiveOperatorMatcher < OperatorMatcher
80
+ def __delegate_operator(actual, operator, expected)
81
+ if actual.__send__(operator, expected)
82
+ true
83
+ elsif ['==','===', '=~'].include?(operator)
84
+ fail_with_message("expected: #{expected.inspect}\n got: #{actual.inspect} (using #{operator})")
85
+ else
86
+ fail_with_message("expected: #{operator} #{expected.inspect}\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}")
87
+ end
88
+ end
89
+ end
90
+
91
+ class NegativeOperatorMatcher < OperatorMatcher
92
+ def __delegate_operator(actual, operator, expected)
93
+ return false unless actual.__send__(operator, expected)
94
+ return fail_with_message("expected not: #{operator} #{expected.inspect}\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}")
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,70 @@
1
+ module RSpec
2
+ module Matchers
3
+ module Pretty
4
+ def split_words(sym)
5
+ sym.to_s.gsub(/_/,' ')
6
+ end
7
+
8
+ def to_sentence(words)
9
+ return "" unless words
10
+ words = Array(words).map { |w| to_word(w) }
11
+ case words.length
12
+ when 0
13
+ ""
14
+ when 1
15
+ " #{words[0]}"
16
+ when 2
17
+ " #{words[0]} and #{words[1]}"
18
+ else
19
+ " #{words[0...-1].join(', ')}, and #{words[-1]}"
20
+ end
21
+ end
22
+
23
+ def _pretty_print(array)
24
+ result = ""
25
+ array.each_with_index do |item, index|
26
+ if index < (array.length - 2)
27
+ result << "#{item.inspect}, "
28
+ elsif index < (array.length - 1)
29
+ result << "#{item.inspect} and "
30
+ else
31
+ result << "#{item.inspect}"
32
+ end
33
+ end
34
+ result
35
+ end
36
+
37
+ def to_word(item)
38
+ is_matcher_with_description?(item) ? item.description : item.inspect
39
+ end
40
+
41
+ def name_to_sentence
42
+ split_words(name)
43
+ end
44
+
45
+ def expected_to_sentence
46
+ to_sentence(@expected) if defined?(@expected)
47
+ end
48
+
49
+ def name
50
+ defined?(@name) ? @name : underscore(self.class.name.split("::").last)
51
+ end
52
+
53
+ # Borrowed from ActiveSupport
54
+ def underscore(camel_cased_word)
55
+ word = camel_cased_word.to_s.dup
56
+ word.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
57
+ word.gsub!(/([a-z\d])([A-Z])/,'\1_\2')
58
+ word.tr!("-", "_")
59
+ word.downcase!
60
+ word
61
+ end
62
+
63
+ private
64
+
65
+ def is_matcher_with_description?(object)
66
+ RSpec::Matchers.is_a_matcher?(object) && object.respond_to?(:description)
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,11 @@
1
+ # Include Matchers for other test frameworks. Note that MiniTest _must_
2
+ # come before TU because on ruby 1.9, T::U::TC is a subclass of MT::U::TC
3
+ # and a 1.9 bug can lead to infinite recursion from the `super` call in our
4
+ # method_missing hook. See this gist for more info:
5
+ # https://gist.github.com/845896
6
+ if defined?(MiniTest::Unit::TestCase)
7
+ MiniTest::Unit::TestCase.send(:include, RSpec::Matchers)
8
+ end
9
+ if defined?(Test::Unit::TestCase)
10
+ Test::Unit::TestCase.send(:include, RSpec::Matchers)
11
+ end
@@ -0,0 +1,100 @@
1
+ require 'rspec/mocks/framework'
2
+ require 'rspec/mocks/version'
3
+
4
+ module RSpec
5
+
6
+ module Mocks
7
+ class << self
8
+ attr_accessor :space
9
+
10
+ def setup(host)
11
+ (class << host; self; end).class_exec do
12
+ include RSpec::Mocks::ExampleMethods
13
+ end
14
+ self.space ||= RSpec::Mocks::Space.new
15
+ end
16
+
17
+ def verify
18
+ space.verify_all
19
+ end
20
+
21
+ def teardown
22
+ space.reset_all
23
+ end
24
+
25
+ def proxy_for(object)
26
+ space.proxy_for(object)
27
+ end
28
+
29
+ def proxies_of(klass)
30
+ space.proxies_of(klass)
31
+ end
32
+
33
+ def any_instance_recorder_for(klass)
34
+ space.any_instance_recorder_for(klass)
35
+ end
36
+
37
+ # Adds an allowance (stub) on `subject`
38
+ #
39
+ # @param subject the subject to which the message will be added
40
+ # @param message a symbol, representing the message that will be
41
+ # added.
42
+ # @param opts a hash of options, :expected_from is used to set the
43
+ # original call site
44
+ # @param block an optional implementation for the allowance
45
+ #
46
+ # @example Defines the implementation of `foo` on `bar`, using the passed block
47
+ # x = 0
48
+ # RSpec::Mocks.allow_message(bar, :foo) { x += 1 }
49
+ def allow_message(subject, message, opts={}, &block)
50
+ orig_caller = opts.fetch(:expected_from) {
51
+ CallerFilter.first_non_rspec_line
52
+ }
53
+ ::RSpec::Mocks.proxy_for(subject).
54
+ add_stub(orig_caller, message, opts, &block)
55
+ end
56
+
57
+ # Sets a message expectation on `subject`.
58
+ # @param subject the subject on which the message will be expected
59
+ # @param message a symbol, representing the message that will be
60
+ # expected.
61
+ # @param opts a hash of options, :expected_from is used to set the
62
+ # original call site
63
+ # @param block an optional implementation for the expectation
64
+ #
65
+ # @example Expect the message `foo` to receive `bar`, then call it
66
+ # RSpec::Mocks.expect_message(bar, :foo)
67
+ # bar.foo
68
+ def expect_message(subject, message, opts={}, &block)
69
+ orig_caller = opts.fetch(:expected_from) {
70
+ CallerFilter.first_non_rspec_line
71
+ }
72
+ ::RSpec::Mocks.proxy_for(subject).
73
+ add_message_expectation(orig_caller, message, opts, &block)
74
+ end
75
+
76
+ # @api private
77
+ KERNEL_METHOD_METHOD = ::Kernel.instance_method(:method)
78
+
79
+ # @api private
80
+ # Used internally to get a method handle for a particular object
81
+ # and method name.
82
+ #
83
+ # Includes handling for a few special cases:
84
+ #
85
+ # - Objects that redefine #method (e.g. an HTTPRequest struct)
86
+ # - BasicObject subclasses that mixin a Kernel dup (e.g. SimpleDelegator)
87
+ def method_handle_for(object, method_name)
88
+ if ::Kernel === object
89
+ KERNEL_METHOD_METHOD.bind(object).call(method_name)
90
+ else
91
+ object.method(method_name)
92
+ end
93
+ end
94
+ end
95
+
96
+ # @private
97
+ IGNORED_BACKTRACE_LINE = 'this backtrace line is ignored'
98
+ end
99
+ end
100
+
@@ -0,0 +1,92 @@
1
+ module RSpec
2
+ module Mocks
3
+ module AnyInstance
4
+ class Chain
5
+ def initialize(recorder, *args, &block)
6
+ @recorder = recorder
7
+ @expectation_args = args
8
+ @expectation_block = block
9
+ end
10
+
11
+ module Customizations
12
+ # @macro [attach] record
13
+ # @method $1(*args, &block)
14
+ # Records the `$1` message for playback against an instance that
15
+ # invokes a method stubbed or mocked using `any_instance`.
16
+ #
17
+ # @see RSpec::Mocks::MessageExpectation#$1
18
+ #
19
+ def self.record(method_name)
20
+ define_method(method_name) do |*args, &block|
21
+ record(method_name, *args, &block)
22
+ end
23
+ end
24
+
25
+ record :and_return
26
+ record :and_raise
27
+ record :and_throw
28
+ record :and_yield
29
+ record :and_call_original
30
+ record :with
31
+ record :once
32
+ record :twice
33
+ record :any_number_of_times
34
+ record :exactly
35
+ record :times
36
+ record :never
37
+ record :at_least
38
+ record :at_most
39
+ end
40
+
41
+ include Customizations
42
+
43
+ # @private
44
+ def playback!(instance)
45
+ message_expectation = create_message_expectation_on(instance)
46
+ messages.inject(message_expectation) do |object, message|
47
+ object.__send__(*message.first, &message.last)
48
+ end
49
+ end
50
+
51
+ # @private
52
+ def constrained_to_any_of?(*constraints)
53
+ constraints.any? do |constraint|
54
+ messages.any? do |message|
55
+ message.first.first == constraint
56
+ end
57
+ end
58
+ end
59
+
60
+ # @private
61
+ def expectation_fulfilled!
62
+ @expectation_fulfilled = true
63
+ end
64
+
65
+ def never
66
+ ErrorGenerator.raise_double_negation_error("expect_any_instance_of(MyClass)") if negated?
67
+ super
68
+ end
69
+
70
+ private
71
+
72
+ def negated?
73
+ messages.any? { |(message, *_), _| message == :never }
74
+ end
75
+
76
+ def messages
77
+ @messages ||= []
78
+ end
79
+
80
+ def last_message
81
+ messages.last.first.first unless messages.empty?
82
+ end
83
+
84
+ def record(rspec_method_name, *args, &block)
85
+ verify_invocation_order(rspec_method_name, *args, &block)
86
+ messages << [args.unshift(rspec_method_name), block]
87
+ self
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,47 @@
1
+ module RSpec
2
+ module Mocks
3
+ module AnyInstance
4
+ # @api private
5
+ class ExpectationChain < Chain
6
+ def expectation_fulfilled?
7
+ @expectation_fulfilled || constrained_to_any_of?(:never, :any_number_of_times)
8
+ end
9
+
10
+ def initialize(*args, &block)
11
+ @expectation_fulfilled = false
12
+ super
13
+ end
14
+
15
+ private
16
+ def verify_invocation_order(rspec_method_name, *args, &block)
17
+ end
18
+ end
19
+
20
+ # @api private
21
+ class PositiveExpectationChain < ExpectationChain
22
+
23
+ private
24
+
25
+ def create_message_expectation_on(instance)
26
+ proxy = ::RSpec::Mocks.proxy_for(instance)
27
+ expected_from = IGNORED_BACKTRACE_LINE
28
+ me = proxy.add_message_expectation(expected_from, *@expectation_args, &@expectation_block)
29
+ if RSpec::Mocks.configuration.yield_receiver_to_any_instance_implementation_blocks?
30
+ me.and_yield_receiver_to_implementation
31
+ end
32
+
33
+ me
34
+ end
35
+
36
+ def invocation_order
37
+ @invocation_order ||= {
38
+ :with => [nil],
39
+ :and_return => [:with, nil],
40
+ :and_raise => [:with, nil]
41
+ }
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+
@@ -0,0 +1,75 @@
1
+ module RSpec
2
+ module Mocks
3
+ module AnyInstance
4
+ # @private
5
+ class MessageChains
6
+ def initialize
7
+ @chains_by_method_name = Hash.new { |h, k| h[k] = [] }
8
+ end
9
+
10
+ # @private
11
+ def [](method_name)
12
+ @chains_by_method_name[method_name]
13
+ end
14
+
15
+ # @private
16
+ def add(method_name, chain)
17
+ @chains_by_method_name[method_name] << chain
18
+ chain
19
+ end
20
+
21
+ # @private
22
+ def remove_stub_chains_for!(method_name)
23
+ @chains_by_method_name[method_name].reject! do |chain|
24
+ StubChain === chain
25
+ end
26
+ end
27
+
28
+ # @private
29
+ def has_expectation?(method_name)
30
+ @chains_by_method_name[method_name].find do |chain|
31
+ ExpectationChain === chain
32
+ end
33
+ end
34
+
35
+ # @private
36
+ def all_expectations_fulfilled?
37
+ @chains_by_method_name.all? do |method_name, chains|
38
+ chains.all? { |chain| chain.expectation_fulfilled? }
39
+ end
40
+ end
41
+
42
+ # @private
43
+ def unfulfilled_expectations
44
+ @chains_by_method_name.map do |method_name, chains|
45
+ method_name.to_s if ExpectationChain === chains.last unless chains.last.expectation_fulfilled?
46
+ end.compact
47
+ end
48
+
49
+ # @private
50
+ def received_expected_message!(method_name)
51
+ @chains_by_method_name[method_name].each do |chain|
52
+ chain.expectation_fulfilled!
53
+ end
54
+ end
55
+
56
+ # @private
57
+ def playback!(instance, method_name)
58
+ raise_if_second_instance_to_receive_message(instance)
59
+ @chains_by_method_name[method_name].each do |chain|
60
+ chain.playback!(instance)
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ def raise_if_second_instance_to_receive_message(instance)
67
+ @instance_with_expectation ||= instance if ExpectationChain === instance
68
+ if ExpectationChain === instance && !@instance_with_expectation.equal?(instance)
69
+ raise RSpec::Mocks::MockExpectationError, "Exactly one instance should have received the following message(s) but didn't: #{unfulfilled_expectations.sort.join(', ')}"
70
+ end
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end