rr 1.1.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +3 -43
  3. data/CHANGES.md +46 -0
  4. data/CREDITS.md +5 -0
  5. data/Gemfile +3 -12
  6. data/README.md +25 -24
  7. data/Rakefile +16 -38
  8. data/doc/02_syntax_comparison.md +1 -0
  9. data/lib/rr/core_ext/array.rb +2 -0
  10. data/lib/rr/core_ext/hash.rb +2 -0
  11. data/lib/rr/deprecations.rb +97 -0
  12. data/lib/rr/double_definitions/double_injections/any_instance_of.rb +1 -1
  13. data/lib/rr/double_definitions/double_injections/instance.rb +2 -2
  14. data/lib/rr/dsl.rb +152 -0
  15. data/lib/rr/injections/method_missing_injection.rb +6 -2
  16. data/lib/rr/integrations/minitest_4.rb +1 -1
  17. data/lib/rr/integrations/minitest_4_active_support.rb +1 -1
  18. data/lib/rr/integrations/rspec/invocation_matcher.rb +0 -8
  19. data/lib/rr/integrations/rspec_2.rb +20 -2
  20. data/lib/rr/recorded_call.rb +29 -0
  21. data/lib/rr/recorded_calls.rb +8 -4
  22. data/lib/rr/space.rb +1 -1
  23. data/lib/rr/spy_verification.rb +13 -5
  24. data/lib/rr/version.rb +1 -1
  25. data/lib/rr/wildcard_matchers.rb +10 -10
  26. data/lib/rr/without_autohook.rb +5 -13
  27. data/rr.gemspec +3 -3
  28. data/spec/defines_spec_suite_tasks.rb +12 -0
  29. data/spec/global_helper.rb +5 -0
  30. data/spec/spec_suite_configuration.rb +1 -7
  31. data/spec/suites.yml +1 -1
  32. data/spec/suites/rspec_2/functional/any_instance_of_spec.rb +133 -33
  33. data/spec/suites/rspec_2/functional/dont_allow_spec.rb +13 -8
  34. data/spec/suites/rspec_2/functional/mock_bang_spec.rb +20 -0
  35. data/spec/suites/rspec_2/functional/mock_instance_of_spec.rb +14 -0
  36. data/spec/suites/rspec_2/functional/mock_instance_of_strong_spec.rb +15 -0
  37. data/spec/suites/rspec_2/functional/mock_proxy_instance_of_spec.rb +15 -0
  38. data/spec/suites/rspec_2/functional/mock_proxy_spec.rb +14 -0
  39. data/spec/suites/rspec_2/functional/mock_spec.rb +8 -232
  40. data/spec/suites/rspec_2/functional/mock_strong_spec.rb +14 -0
  41. data/spec/suites/rspec_2/functional/received_spec.rb +16 -0
  42. data/spec/suites/rspec_2/functional/spy_spec.rb +89 -28
  43. data/spec/suites/rspec_2/functional/stub_bang_spec.rb +20 -0
  44. data/spec/suites/rspec_2/functional/stub_instance_of_spec.rb +15 -0
  45. data/spec/suites/rspec_2/functional/stub_instance_of_strong_spec.rb +15 -0
  46. data/spec/suites/rspec_2/functional/stub_proxy_instance_of_spec.rb +16 -0
  47. data/spec/suites/rspec_2/functional/stub_proxy_spec.rb +45 -0
  48. data/spec/suites/rspec_2/functional/stub_spec.rb +42 -161
  49. data/spec/suites/rspec_2/functional/stub_strong_spec.rb +15 -0
  50. data/spec/suites/rspec_2/helper.rb +2 -2
  51. data/spec/suites/rspec_2/support/mixins/double_definition_creator_helpers.rb +173 -0
  52. data/spec/suites/rspec_2/support/mixins/mock_definition_creator_helpers.rb +45 -0
  53. data/spec/suites/rspec_2/support/mixins/proxy_definition_creator_helpers.rb +33 -0
  54. data/spec/suites/rspec_2/support/mixins/stub_creator_helpers.rb +43 -0
  55. data/spec/suites/rspec_2/support/mixins/stub_definition_creator_helpers.rb +45 -0
  56. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/argument_expectations_with_never_called_qualifier.rb +39 -0
  57. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/argument_expectations_with_times_called_qualifier.rb +50 -0
  58. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/argument_expectations_without_qualifiers.rb +131 -0
  59. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/dont_allow.rb +148 -0
  60. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/mock_instance_of.rb +26 -0
  61. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/mock_instance_of_strong.rb +28 -0
  62. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/mock_proxy.rb +11 -0
  63. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/mock_strong.rb +37 -0
  64. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/mocking.rb +107 -0
  65. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/stub_instance_of.rb +32 -0
  66. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/stub_instance_of_strong.rb +39 -0
  67. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/stub_proxy.rb +11 -0
  68. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/stub_strong.rb +37 -0
  69. data/spec/suites/rspec_2/support/shared_contexts/double_definition_creators/stubbing.rb +57 -0
  70. data/spec/suites/rspec_2/support/shared_examples/double_definition_creators/array_flatten_bug.rb +35 -0
  71. data/spec/suites/rspec_2/support/shared_examples/double_definition_creators/block_form.rb +31 -0
  72. data/spec/suites/rspec_2/support/shared_examples/double_definition_creators/comparing_arity.rb +63 -0
  73. data/spec/suites/rspec_2/support/shared_examples/double_definition_creators/object_is_proxy.rb +43 -0
  74. data/spec/suites/rspec_2/support/shared_examples/double_definition_creators/sequential_invocations.rb +26 -0
  75. data/spec/suites/rspec_2/support/shared_examples/double_definition_creators/setting_implementation.rb +51 -0
  76. data/spec/suites/rspec_2/support/shared_examples/double_definition_creators/yields.rb +81 -0
  77. data/spec/suites/rspec_2/unit/core_ext/enumerable_spec.rb +0 -28
  78. data/spec/suites/rspec_2/unit/deprecations_spec.rb +27 -0
  79. data/spec/suites/rspec_2/unit/dsl/double_creators_spec.rb +133 -0
  80. data/spec/suites/rspec_2/unit/dsl/space_spec.rb +99 -0
  81. data/spec/suites/rspec_2/unit/dsl/wildcard_matchers_spec.rb +67 -0
  82. data/spec/suites/rspec_2/unit/integrations/rspec_spec.rb +4 -19
  83. data/spec/suites/rspec_2/unit/space_spec.rb +5 -3
  84. data/spec/suites/rspec_2/unit/spy_verification_spec.rb +1 -1
  85. data/spec/support/adapter.rb +1 -1
  86. data/spec/support/adapter_tests/rspec.rb +19 -15
  87. data/spec/support/project/generator.rb +0 -4
  88. metadata +55 -48
  89. data/gemfiles/ruby_18_rspec_1.gemfile +0 -14
  90. data/gemfiles/ruby_18_rspec_1.gemfile.lock +0 -38
  91. data/gemfiles/ruby_18_rspec_1_rails_2.gemfile +0 -18
  92. data/gemfiles/ruby_18_rspec_1_rails_2.gemfile.lock +0 -64
  93. data/gemfiles/ruby_19_rspec_2_rails_3.gemfile +0 -15
  94. data/gemfiles/ruby_19_rspec_2_rails_3.gemfile.lock +0 -123
  95. data/lib/rr/adapters.rb +0 -34
  96. data/lib/rr/adapters/rr_methods.rb +0 -142
  97. data/lib/rr/integrations/rspec_1.rb +0 -46
  98. data/lib/rr/integrations/test_unit_1.rb +0 -63
  99. data/lib/rr/integrations/test_unit_2.rb +0 -17
  100. data/lib/rr/integrations/test_unit_200.rb +0 -27
  101. data/lib/rr/integrations/test_unit_200_active_support.rb +0 -25
  102. data/lib/rr/integrations/test_unit_2_active_support.rb +0 -38
  103. data/spec/suites/rspec_1/helper.rb +0 -24
  104. data/spec/suites/rspec_1/integration/rspec_1_spec.rb +0 -93
  105. data/spec/suites/rspec_1/integration/test_unit_1_spec.rb +0 -102
  106. data/spec/suites/rspec_1/integration/test_unit_2_spec.rb +0 -109
  107. data/spec/suites/rspec_1/spec_helper.rb +0 -3
  108. data/spec/suites/rspec_1_rails_2/integration/astc_rails_2_spec.rb +0 -141
  109. data/spec/suites/rspec_1_rails_2/integration/rspec_1_rails_2_spec.rb +0 -132
  110. data/spec/suites/rspec_1_rails_2/integration/test_unit_1_rails_2_spec.rb +0 -141
  111. data/spec/suites/rspec_1_rails_2/integration/test_unit_2_rails_2_spec.rb +0 -148
  112. data/spec/suites/rspec_1_rails_2/spec_helper.rb +0 -3
  113. data/spec/suites/rspec_2/functional/dsl_spec.rb +0 -13
  114. data/spec/suites/rspec_2/functional/instance_of_spec.rb +0 -14
  115. data/spec/suites/rspec_2/functional/proxy_spec.rb +0 -136
  116. data/spec/suites/rspec_2/functional/strong_spec.rb +0 -79
  117. data/spec/suites/rspec_2/integration/test_unit_200_spec.rb +0 -102
  118. data/spec/suites/rspec_2/integration/test_unit_2_spec.rb +0 -109
  119. data/spec/suites/rspec_2/unit/adapters/rr_methods/double_creators_spec.rb +0 -135
  120. data/spec/suites/rspec_2/unit/adapters/rr_methods/space_spec.rb +0 -101
  121. data/spec/suites/rspec_2/unit/adapters/rr_methods/wildcard_matchers_spec.rb +0 -69
  122. data/spec/suites/rspec_2_rails_3/integration/astc_rails_3_spec.rb +0 -141
  123. data/spec/suites/rspec_2_rails_3/integration/minitest_4_rails_3_spec.rb +0 -148
  124. data/spec/suites/rspec_2_rails_3/integration/rspec_2_rails_3_spec.rb +0 -172
  125. data/spec/suites/rspec_2_rails_3/integration/test_unit_200_rails_3_spec.rb +0 -141
  126. data/spec/suites/rspec_2_rails_3/integration/test_unit_2_rails_3_spec.rb +0 -148
  127. data/spec/suites/rspec_2_rails_3/spec_helper.rb +0 -3
  128. data/spec/suites/rspec_2_rails_4/integration/test_unit_200_rails_4_spec.rb +0 -142
  129. data/spec/suites/rspec_2_rails_4/integration/test_unit_2_rails_4_spec.rb +0 -149
data/rr.gemspec CHANGED
@@ -6,11 +6,11 @@ require File.expand_path('../lib/rr/version', __FILE__)
6
6
  Gem::Specification.new do |gem|
7
7
  gem.name = 'rr'
8
8
  gem.version = RR.version
9
- gem.authors = ['Brian Takita', 'Elliot Winkler']
10
- gem.email = ['elliot.winkler@gmail.com']
9
+ gem.authors = ['Kouhei Sutou', 'Brian Takita', 'Elliot Winkler']
10
+ gem.email = ['kou@cozmixng.org']
11
11
  gem.description = 'RR is a test double framework that features a rich selection of double techniques and a terse syntax.'
12
12
  gem.summary = 'RR is a test double framework that features a rich selection of double techniques and a terse syntax.'
13
- gem.homepage = 'http://rr.github.com/rr'
13
+ gem.homepage = 'https://rr.github.io/rr'
14
14
  gem.license = 'MIT'
15
15
 
16
16
  gem.files = FileList[
@@ -33,6 +33,18 @@ class DefinesSpecSuiteTasks
33
33
  end
34
34
  end
35
35
  end
36
+
37
+ require 'rspec/core/rake_task'
38
+
39
+ desc "Run the unit tests"
40
+ RSpec::Core::RakeTask.new(:unit) do |t|
41
+ t.pattern = 'spec/suites/rspec_2/unit/**/*_spec.rb'
42
+ end
43
+
44
+ desc "Run the functional (API) tests"
45
+ RSpec::Core::RakeTask.new(:functional) do |t|
46
+ t.pattern = 'spec/suites/rspec_2/functional/**/*_spec.rb'
47
+ end
36
48
  end
37
49
 
38
50
  namespace :travis do
@@ -30,4 +30,9 @@ module RR
30
30
  end
31
31
  end
32
32
 
33
+ lib_path = File.expand_path("../../lib", __FILE__)
34
+ $LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include?(lib_path)
35
+
33
36
  Dir[ File.expand_path('../support/**/*.rb', __FILE__) ].each { |fn| require fn }
37
+
38
+ $stdout.sync = true
@@ -26,18 +26,12 @@ class SpecSuiteConfiguration
26
26
  end
27
27
 
28
28
  def current_ruby_id
29
- ruby_18? ? '18' : '19'
29
+ '19'
30
30
  end
31
31
 
32
32
  def matching_current_ruby_version?
33
33
  ruby_id == current_ruby_id
34
34
  end
35
-
36
- private
37
-
38
- def ruby_18?
39
- RUBY_VERSION =~ /^1\.8/
40
- end
41
35
  end
42
36
 
43
37
  attr_reader :ruby_groups, :runners
@@ -21,4 +21,4 @@
21
21
  - name: rspec_2_rails_4
22
22
  desc: 'RSpec 2 + Rails 4'
23
23
  env:
24
- SPEC_OPTS: '--require $PWD/spec/custom_formatter_for_rspec_2 --format CustomFormatterForRSpec2 --backtrace'
24
+ SPEC_OPTS: '--require $PWD/spec/custom_formatter_for_rspec_2 --format CustomFormatterForRSpec2 --backtrace --fail-fast'
@@ -1,47 +1,147 @@
1
1
  require File.expand_path('../../spec_helper', __FILE__)
2
2
 
3
- describe '#any_instance_of' do
4
- context "when passed a block" do
5
- it "applies to instances instantiated before the Double expectation was created" do
6
- subject_class = Class.new
7
- subject = subject_class.new
8
- class_called = false
9
- any_instance_of(subject_class) do |o|
10
- stub(o).to_s {"Subject is stubbed"}
11
- stub.proxy(o).class {|klass| class_called = true; klass}
12
- stub(o).foobar {:baz}
13
- end
14
-
15
- expect(subject.to_s).to eq "Subject is stubbed"
16
- expect(subject.class).to eq subject_class
17
- expect(class_called).to eq true
18
- expect(subject.foobar).to eq :baz
3
+ describe 'any_instance_of' do
4
+ context 'stubs for instance methods of a class' do
5
+ context 'via block form' do
6
+ context 'for existing methods' do
7
+ it "can be defined" do
8
+ a_class = Class.new { def some_method; 'value'; end }
9
+ any_instance_of(a_class) { |c| stub(c).some_method { 'value' } }
10
+ instance = a_class.new
11
+ expect(instance.some_method).to eq 'value'
12
+ end
19
13
 
20
- RR.reset
14
+ it "can be reset" do
15
+ a_class = Class.new { def some_method; 'original value'; end }
16
+ any_instance_of(a_class) { |c| stub(c).some_method { 'value' } }
17
+ RR.reset
18
+ instance = a_class.new
19
+ expect(instance.some_method).to eq 'original value'
20
+ end
21
+ end
21
22
 
22
- expect(subject.to_s).to_not eq "Subject is stubbed"
23
- class_called = false
24
- expect(subject.class).to eq subject_class
25
- expect(class_called).to eq false
26
- expect(subject).to_not respond_to(:baz)
23
+ context 'for non-existing methods' do
24
+ it "can be defined" do
25
+ a_class = Class.new
26
+ any_instance_of(a_class) { |c| stub(c).some_method { 'value' } }
27
+ instance = a_class.new
28
+ expect(instance.some_method).to eq 'value'
29
+ end
30
+
31
+ it "can be reset" do
32
+ a_class = Class.new
33
+ any_instance_of(a_class) { |c| stub(c).some_method { 'value' } }
34
+ RR.reset
35
+ instance = a_class.new
36
+ expect(instance).not_to respond_to(:some_method)
37
+ end
38
+ end
27
39
  end
28
- end
29
40
 
30
- context "when passed a Hash" do
31
- it "stubs methods (key) with the value on instances instantiated before the Double expectation was created" do
32
- subject_class = Class.new
33
- subject = subject_class.new
34
- expect(subject).to_not respond_to(:baz)
41
+ context 'via hash form' do
42
+ context 'for existing methods' do
43
+ it "can be defined" do
44
+ a_class = Class.new { def some_method; 'value'; end }
45
+ any_instance_of(a_class, :some_method => lambda { 'value' })
46
+ instance = a_class.new
47
+ expect(instance.some_method).to eq 'value'
48
+ end
49
+
50
+ it "can be reset" do
51
+ a_class = Class.new { def some_method; 'original value'; end }
52
+ any_instance_of(a_class, :some_method => lambda { 'value' })
53
+ RR.reset
54
+ instance = a_class.new
55
+ expect(instance.some_method).to eq 'original value'
56
+ end
57
+ end
58
+
59
+ context 'for non-existing methods' do
60
+ it "can be defined" do
61
+ a_class = Class.new
62
+ any_instance_of(a_class, :some_method => lambda { 'value' })
63
+ instance = a_class.new
64
+ expect(instance.some_method).to eq 'value'
65
+ end
35
66
 
36
- any_instance_of(subject_class, :to_s => "Subject is stubbed", :foobar => lambda {:baz})
67
+ it "can be reset" do
68
+ a_class = Class.new
69
+ any_instance_of(a_class, :some_method => lambda { 'value' })
70
+ RR.reset
71
+ instance = a_class.new
72
+ expect(instance).not_to respond_to(:some_method)
73
+ end
74
+ end
75
+ end
76
+ end
37
77
 
38
- expect(subject.to_s).to eq "Subject is stubbed"
39
- expect(subject.foobar).to eq :baz
78
+ context 'stub-proxies for instance methods of a class' do
79
+ it "can be defined" do
80
+ a_class = Class.new { def some_method; 'value'; end }
81
+ any_instance_of(a_class) { |c| stub.proxy(c).some_method { 'value' } }
82
+ instance = a_class.new
83
+ expect(instance.some_method).to eq 'value'
84
+ end
40
85
 
86
+ it "can be reset" do
87
+ a_class = Class.new { def some_method; 'original value'; end }
88
+ any_instance_of(a_class) { |c| stub.proxy(c).some_method { 'value' } }
41
89
  RR.reset
90
+ instance = a_class.new
91
+ expect(instance.some_method).to eq 'original value'
92
+ end
93
+ end
42
94
 
43
- expect(subject.to_s).to_not eq "Subject is stubbed"
44
- expect(subject).to_not respond_to(:baz)
95
+ context 'mocks for instance methods of a class' do
96
+ context 'for existing methods' do
97
+ it "can be defined" do
98
+ a_class = Class.new { def some_method; 'value'; end }
99
+ any_instance_of(a_class) { |c| mock(c).some_method { 'value' } }
100
+ instance = a_class.new
101
+ expect(instance.some_method).to eq 'value'
102
+ end
103
+
104
+ it "can be reset" do
105
+ a_class = Class.new { def some_method; 'original value'; end }
106
+ any_instance_of(a_class) { |c| mock(c).some_method { 'value' } }
107
+ RR.reset
108
+ instance = a_class.new
109
+ expect(instance.some_method).to eq 'original value'
110
+ end
111
+ end
112
+
113
+ context 'for non-existing methods' do
114
+ it "can be defined" do
115
+ a_class = Class.new
116
+ any_instance_of(a_class) { |c| mock(c).some_method { 'value' } }
117
+ instance = a_class.new
118
+ expect(instance.some_method).to eq 'value'
119
+ end
120
+
121
+ it "can be reset" do
122
+ a_class = Class.new
123
+ any_instance_of(a_class) { |c| mock(c).some_method { 'value' } }
124
+ RR.reset
125
+ instance = a_class.new
126
+ expect(instance).not_to respond_to(:some_method)
127
+ end
128
+ end
129
+ end
130
+
131
+ context 'mock-proxies for instance methods of a class' do
132
+ it "can be defined" do
133
+ a_class = Class.new { def some_method; 'value'; end }
134
+ any_instance_of(a_class) { |c| mock.proxy(c).some_method { 'value' } }
135
+ instance = a_class.new
136
+ expect(instance.some_method).to eq 'value'
137
+ end
138
+
139
+ it "can be reset" do
140
+ a_class = Class.new { def some_method; 'original value'; end }
141
+ any_instance_of(a_class) { |c| mock.proxy(c).some_method { 'value' } }
142
+ RR.reset
143
+ instance = a_class.new
144
+ expect(instance.some_method).to eq 'original value'
45
145
  end
46
146
  end
47
147
  end
@@ -1,12 +1,17 @@
1
1
  require File.expand_path('../../spec_helper', __FILE__)
2
2
 
3
- describe '#dont_allow' do
4
- subject { Object.new }
5
-
6
- it "raises a TimesCalledError if the method is actually called" do
7
- dont_allow(subject).foobar
8
- expect {
9
- subject.foobar
10
- }.to raise_error(RR::Errors::TimesCalledError)
3
+ describe 'dont_allow', is_mock: true, is_dont_allow: true do
4
+ include MockDefinitionCreatorHelpers
5
+
6
+ context 'against instance methods', method_type: :instance do
7
+ include_context 'tests for a double definition creator method that supports dont_allow'
8
+ end
9
+
10
+ context 'against class methods', method_type: :class do
11
+ include_context 'tests for a double definition creator method that supports dont_allow'
12
+ end
13
+
14
+ def double_definition_creator_for(object, &block)
15
+ dont_allow(object, &block)
11
16
  end
12
17
  end
@@ -0,0 +1,20 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ describe 'mock!' do
4
+ it "is a terser way of creating an object and mocking it" do
5
+ object = mock!.some_method { 'value' }.subject
6
+ expect(object.some_method).to eq 'value'
7
+ end
8
+
9
+ it "can be used inside the implementation block of a double" do
10
+ object = Object.new
11
+ stub(object).some_method { mock!.another_method { 'value' } }
12
+ expect(object.some_method.another_method).to eq 'value'
13
+ end
14
+
15
+ it "can be called on a double" do
16
+ object = Object.new
17
+ stub(object).some_method.mock!.another_method { 'value' }
18
+ expect(object.some_method.another_method).to eq 'value'
19
+ end
20
+ end
@@ -0,0 +1,14 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ permutations =
4
+ %w(mock instance_of).permutation.map { |parts| parts.join('.') }
5
+
6
+ permutations.each do |permutation|
7
+ describe permutation, is_mock: true, is_instance_of: true do
8
+ include_context 'mock + instance_of'
9
+
10
+ define_method(:double_definition_creator_for) do |object, &block|
11
+ eval(permutation + '(object, &block)')
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ permutations =
4
+ %w(mock instance_of strong).permutation.to_a.
5
+ map { |parts| parts.join('.') }
6
+
7
+ permutations.each do |permutation|
8
+ describe permutation, is_mock: true, is_instance_of: true, is_strong: true do
9
+ include_context 'mock + instance_of + strong'
10
+
11
+ define_method(:double_definition_creator_for) do |object, &block|
12
+ eval(permutation + '(object, &block)')
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ permutations =
4
+ %w(mock proxy instance_of).permutation.map { |parts| parts.join('.') }
5
+
6
+ permutations.each do |permutation|
7
+ describe permutation, is_mock: true, is_proxy: true, is_instance_of: true do
8
+ include_context 'mock + instance_of'
9
+ include ProxyDefinitionCreatorHelpers
10
+
11
+ define_method(:double_definition_creator_for) do |object, &block|
12
+ eval(permutation + '(object, &block)')
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ require File.expand_path('../../spec_helper', __FILE__)
2
+
3
+ permutations =
4
+ %w(mock proxy).permutation.map { |parts| parts.join('.') }
5
+
6
+ permutations.each do |permutation|
7
+ describe permutation, is_mock: true, is_proxy: true do
8
+ include_context 'mock + proxy'
9
+
10
+ define_method(:double_definition_creator_for) do |object, &block|
11
+ eval(permutation + '(object, &block)')
12
+ end
13
+ end
14
+ end
@@ -1,241 +1,17 @@
1
1
  require File.expand_path('../../spec_helper', __FILE__)
2
2
 
3
- describe '#mock' do
4
- subject { Object.new }
3
+ describe 'mock', is_mock: true do
4
+ include MockDefinitionCreatorHelpers
5
5
 
6
- it "creates a mock DoubleInjection Double" do
7
- mock(subject).foobar(1, 2) {:baz}
8
- expect(subject.foobar(1, 2)).to eq :baz
6
+ context 'against instance methods', method_type: :instance do
7
+ include_context 'tests for a double definition creator method that supports mocking'
9
8
  end
10
9
 
11
- it "mocks via inline call" do
12
- mock(subject).to_s {"a value"}
13
- expect(subject.to_s).to eq "a value"
14
- expect { subject.to_s }.to raise_error(RR::Errors::TimesCalledError)
15
- RR.reset
10
+ context 'against class methods', method_type: :class do
11
+ include_context 'tests for a double definition creator method that supports mocking'
16
12
  end
17
13
 
18
- describe ".once.ordered" do
19
- it "returns the values in the ordered called" do
20
- mock(subject).to_s {"value 1"}.ordered
21
- mock(subject).to_s {"value 2"}.twice
22
- expect(subject.to_s).to eq "value 1"
23
- expect(subject.to_s).to eq "value 2"
24
- expect(subject.to_s).to eq "value 2"
25
- expect { subject.to_s }.to raise_error(RR::Errors::TimesCalledError)
26
- RR.reset
27
- end
28
- end
29
-
30
- context "when the subject is a proxy for the object with the defined method" do
31
- it "stubs the method on the proxy object" do
32
- proxy_target = Class.new {def foobar; :original_foobar; end}.new
33
- proxy = Class.new do
34
- def initialize(target)
35
- @target = target
36
- end
37
-
38
- instance_methods.each do |m|
39
- unless m =~ /^_/ || m.to_s == 'object_id' || m.to_s == 'method_missing'
40
- alias_method "__blank_slated_#{m}", m
41
- undef_method m
42
- end
43
- end
44
-
45
- def method_missing(method_name, *args, &block)
46
- @target.send(method_name, *args, &block)
47
- end
48
- end.new(proxy_target)
49
- expect(proxy.methods).to match_array(proxy_target.methods)
50
-
51
- mock(proxy).foobar {:new_foobar}
52
- expect(proxy.foobar).to eq :new_foobar
53
- end
54
- end
55
-
56
- it 'allows terse chaining' do
57
- mock(subject).first(1) {mock(Object.new).second(2) {mock(Object.new).third(3) {4}}}
58
- expect(subject.first(1).second(2).third(3)).to eq 4
59
-
60
- mock(subject).first(1) {mock!.second(2) {mock!.third(3) {4}}}
61
- expect(subject.first(1).second(2).third(3)).to eq 4
62
-
63
- mock(subject).first(1) {mock!.second(2).mock!.third(3) {4}}
64
- expect(subject.first(1).second(2).third(3)).to eq 4
65
-
66
- mock(subject).first(1) {mock!.second(2).mock! {third(3) {4}}}
67
- expect(subject.first(1).second(2).third(3)).to eq 4
68
-
69
- mock(subject).first(1).mock!.second(2).mock!.third(3) {4}
70
- expect(subject.first(1).second(2).third(3)).to eq 4
71
- end
72
-
73
- it 'allows chaining with proxy' do
74
- pending "this is failing with a TimesCalledError"
75
-
76
- find_return_value = Object.new
77
- def find_return_value.child
78
- :the_child
79
- end
80
- (class << subject; self; end).class_eval do
81
- define_method(:find) do |id|
82
- id == '1' ? find_return_value : raise(ArgumentError)
83
- end
84
- end
85
-
86
- mock.proxy(subject).find('1').mock.proxy!.child
87
- expect(subject.find('1').child).to eq :the_child
88
- end
89
-
90
- it 'allows branched chaining' do
91
- mock(subject).first do
92
- mock! do |expect|
93
- expect.branch1 {mock!.branch11 {11}}
94
- expect.branch2 {mock!.branch22 {22}}
95
- end
96
- end
97
- o = subject.first
98
- expect(o.branch1.branch11).to eq 11
99
- expect(o.branch2.branch22).to eq 22
100
- end
101
-
102
- it 'allows chained ordering' do
103
- mock(subject).to_s {"value 1"}.then.to_s {"value 2"}.twice.then.to_s {"value 3"}.once
104
- expect(subject.to_s).to eq "value 1"
105
- expect(subject.to_s).to eq "value 2"
106
- expect(subject.to_s).to eq "value 2"
107
- expect(subject.to_s).to eq "value 3"
108
- expect { subject.to_s }.to raise_error(RR::Errors::TimesCalledError)
109
- RR.reset
110
- end
111
-
112
- it "mocks via block with argument" do
113
- mock subject do |c|
114
- c.to_s {"a value"}
115
- c.to_sym {:crazy}
116
- end
117
- expect(subject.to_s).to eq "a value"
118
- expect(subject.to_sym).to eq :crazy
119
- end
120
-
121
- it "mocks via block without argument" do
122
- mock subject do
123
- to_s {"a value"}
124
- to_sym {:crazy}
125
- end
126
- expect(subject.to_s).to eq "a value"
127
- expect(subject.to_sym).to eq :crazy
128
- end
129
-
130
- it "has wildcard matchers" do
131
- mock(subject).foobar(
132
- is_a(String),
133
- anything,
134
- numeric,
135
- boolean,
136
- duck_type(:to_s),
137
- /abc/
138
- ) {"value 1"}.twice
139
- expect(subject.foobar(
140
- 'hello',
141
- Object.new,
142
- 99,
143
- false,
144
- "My String",
145
- "Tabcola"
146
- )).to eq("value 1")
147
- expect {
148
- subject.foobar(:failure)
149
- }.to raise_error(RR::Errors::DoubleNotFoundError)
150
-
151
- RR.reset
152
- end
153
-
154
- it "mocks methods without letters" do
155
- mock(subject, :==).with(55)
156
-
157
- subject == 55
158
- expect {
159
- subject == 99
160
- }.to raise_error(RR::Errors::DoubleNotFoundError)
161
-
162
- RR.reset
163
- end
164
-
165
- it "expects a method call to a mock via another mock's block yield only once" do
166
- cage = Object.new
167
- cat = Object.new
168
- mock(cat).miau # should be expected to be called only once
169
- mock(cage).find_cat.yields(cat)
170
- mock(cage).cats
171
- cage.find_cat { |c| c.miau }
172
- cage.cats
173
- end
174
-
175
- describe "on class method" do
176
- class SampleClass1
177
- def self.hello; "hello!"; end
178
- end
179
-
180
- class SampleClass2 < SampleClass1; end
181
-
182
- it "can mock" do
183
- mock(SampleClass1).hello { "hola!" }
184
-
185
- expect(SampleClass1.hello).to eq "hola!"
186
- end
187
-
188
- it "does not override subclasses" do
189
- mock(SampleClass1).hello { "hi!" }
190
- SampleClass1.hello
191
- expect(SampleClass2.hello).to eq "hello!"
192
- end
193
-
194
- it "should not get affected from a previous example" do
195
- expect(SampleClass2.hello).to eq "hello!"
196
- end
197
- end
198
-
199
- # bug #44
200
- describe 'when wrapped in an array that is then flattened' do
201
- context 'when the method being mocked is not defined' do
202
- it "does not raise an error" do
203
- mock(subject).foo
204
- subject.foo
205
- expect([subject].flatten).to eq [subject]
206
- end
207
-
208
- it "honors a #to_ary that already exists" do
209
- subject.instance_eval do
210
- def to_ary; []; end
211
- end
212
- mock(subject).foo
213
- subject.foo
214
- expect([subject].flatten).to eq []
215
- end
216
- end
217
-
218
- context 'when the method being mocked is defined' do
219
- before do
220
- subject.instance_eval do
221
- def foo; end
222
- end
223
- end
224
-
225
- it "does not raise an error" do
226
- mock(subject).foo
227
- subject.foo
228
- expect([subject].flatten).to eq [subject]
229
- end
230
-
231
- it "honors a #to_ary that already exists" do
232
- eigen(subject).class_eval do
233
- def to_ary; []; end
234
- end
235
- mock(subject).foo
236
- subject.foo
237
- expect([subject].flatten).to eq []
238
- end
239
- end
14
+ def double_definition_creator_for(object, &block)
15
+ mock(object, &block)
240
16
  end
241
17
  end