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,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