shoulda-matchers 2.8.0 → 3.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (171) hide show
  1. checksums.yaml +4 -4
  2. data/.hound_config/ruby.yml +7 -0
  3. data/.travis.yml +11 -54
  4. data/Appraisals +45 -100
  5. data/CONTRIBUTING.md +51 -7
  6. data/Gemfile +7 -19
  7. data/Gemfile.lock +60 -134
  8. data/Guardfile +5 -0
  9. data/NEWS.md +203 -0
  10. data/README.md +95 -50
  11. data/Rakefile +1 -0
  12. data/doc_config/yard/templates/default/layout/html/setup.rb +1 -1
  13. data/gemfiles/4.0.0.gemfile +10 -7
  14. data/gemfiles/4.0.0.gemfile.lock +103 -79
  15. data/gemfiles/4.0.1.gemfile +10 -7
  16. data/gemfiles/4.0.1.gemfile.lock +109 -83
  17. data/gemfiles/4.1.gemfile +10 -7
  18. data/gemfiles/4.1.gemfile.lock +109 -85
  19. data/gemfiles/4.2.gemfile +10 -9
  20. data/gemfiles/4.2.gemfile.lock +86 -78
  21. data/lib/shoulda/matchers.rb +13 -18
  22. data/lib/shoulda/matchers/action_controller.rb +4 -1
  23. data/lib/shoulda/matchers/action_controller/flash_store.rb +95 -0
  24. data/lib/shoulda/matchers/action_controller/{strong_parameters_matcher.rb → permit_matcher.rb} +147 -30
  25. data/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +1 -1
  26. data/lib/shoulda/matchers/action_controller/render_template_matcher.rb +1 -1
  27. data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +1 -1
  28. data/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +1 -1
  29. data/lib/shoulda/matchers/action_controller/route_matcher.rb +5 -1
  30. data/lib/shoulda/matchers/action_controller/route_params.rb +15 -6
  31. data/lib/shoulda/matchers/action_controller/session_store.rb +34 -0
  32. data/lib/shoulda/matchers/action_controller/set_flash_matcher.rb +30 -136
  33. data/lib/shoulda/matchers/action_controller/set_session_matcher.rb +28 -109
  34. data/lib/shoulda/matchers/action_controller/set_session_or_flash_matcher.rb +103 -0
  35. data/lib/shoulda/matchers/active_model/allow_mass_assignment_of_matcher.rb +1 -12
  36. data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +79 -10
  37. data/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +10 -0
  38. data/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +21 -0
  39. data/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +24 -0
  40. data/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +22 -5
  41. data/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +29 -10
  42. data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +27 -10
  43. data/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +27 -12
  44. data/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +56 -20
  45. data/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +3 -11
  46. data/lib/shoulda/matchers/active_model/validation_message_finder.rb +65 -0
  47. data/lib/shoulda/matchers/active_record/association_matcher.rb +40 -6
  48. data/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +21 -7
  49. data/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +11 -40
  50. data/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +1 -1
  51. data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +2 -6
  52. data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +137 -22
  53. data/lib/shoulda/matchers/configuration.rb +20 -0
  54. data/lib/shoulda/matchers/doublespeak.rb +11 -1
  55. data/lib/shoulda/matchers/doublespeak/double.rb +29 -11
  56. data/lib/shoulda/matchers/doublespeak/double_collection.rb +4 -3
  57. data/lib/shoulda/matchers/doublespeak/method_call.rb +35 -0
  58. data/lib/shoulda/matchers/doublespeak/object_double.rb +7 -2
  59. data/lib/shoulda/matchers/doublespeak/proxy_implementation.rb +4 -3
  60. data/lib/shoulda/matchers/doublespeak/stub_implementation.rb +3 -3
  61. data/lib/shoulda/matchers/doublespeak/world.rb +21 -1
  62. data/lib/shoulda/matchers/integrations.rb +43 -0
  63. data/lib/shoulda/matchers/integrations/configuration.rb +68 -0
  64. data/lib/shoulda/matchers/integrations/configuration_error.rb +9 -0
  65. data/lib/shoulda/matchers/integrations/inclusion.rb +20 -0
  66. data/lib/shoulda/matchers/integrations/libraries.rb +15 -0
  67. data/lib/shoulda/matchers/integrations/libraries/action_controller.rb +31 -0
  68. data/lib/shoulda/matchers/integrations/libraries/active_model.rb +26 -0
  69. data/lib/shoulda/matchers/integrations/libraries/active_record.rb +26 -0
  70. data/lib/shoulda/matchers/integrations/libraries/missing_library.rb +19 -0
  71. data/lib/shoulda/matchers/integrations/libraries/rails.rb +30 -0
  72. data/lib/shoulda/matchers/integrations/rails.rb +12 -0
  73. data/lib/shoulda/matchers/integrations/registry.rb +28 -0
  74. data/lib/shoulda/matchers/integrations/test_frameworks.rb +16 -0
  75. data/lib/shoulda/matchers/integrations/test_frameworks/active_support_test_case.rb +37 -0
  76. data/lib/shoulda/matchers/integrations/test_frameworks/minitest_4.rb +36 -0
  77. data/lib/shoulda/matchers/integrations/test_frameworks/minitest_5.rb +37 -0
  78. data/lib/shoulda/matchers/integrations/test_frameworks/missing_test_framework.rb +40 -0
  79. data/lib/shoulda/matchers/integrations/test_frameworks/rspec.rb +29 -0
  80. data/lib/shoulda/matchers/integrations/test_frameworks/test_unit.rb +36 -0
  81. data/lib/shoulda/matchers/rails_shim.rb +0 -40
  82. data/lib/shoulda/matchers/version.rb +1 -1
  83. data/script/SUPPORTED_VERSIONS +1 -1
  84. data/script/update_gems_in_all_appraisals +14 -0
  85. data/shoulda-matchers.gemspec +2 -2
  86. data/spec/acceptance/active_model_integration_spec.rb +4 -1
  87. data/spec/acceptance/independent_matchers_spec.rb +6 -6
  88. data/spec/acceptance/multiple_libraries_integration_spec.rb +52 -0
  89. data/spec/acceptance/rails_integration_spec.rb +15 -5
  90. data/spec/acceptance_spec_helper.rb +8 -0
  91. data/spec/doublespeak_spec_helper.rb +14 -0
  92. data/spec/support/acceptance/adds_shoulda_matchers_to_project.rb +110 -0
  93. data/spec/support/acceptance/helpers.rb +2 -0
  94. data/spec/support/acceptance/helpers/base_helpers.rb +6 -1
  95. data/spec/support/acceptance/helpers/command_helpers.rb +6 -2
  96. data/spec/support/acceptance/helpers/minitest_helpers.rb +0 -8
  97. data/spec/support/acceptance/helpers/n_unit_helpers.rb +25 -0
  98. data/spec/support/acceptance/helpers/rspec_helpers.rb +2 -0
  99. data/spec/support/acceptance/helpers/step_helpers.rb +13 -19
  100. data/spec/support/acceptance/matchers/have_output.rb +1 -1
  101. data/spec/support/tests/bundle.rb +1 -1
  102. data/spec/support/tests/command_runner.rb +25 -13
  103. data/spec/support/tests/current_bundle.rb +47 -0
  104. data/spec/support/tests/database.rb +28 -0
  105. data/spec/support/tests/database_adapters/postgresql.rb +25 -0
  106. data/spec/support/tests/database_adapters/sqlite3.rb +26 -0
  107. data/spec/support/tests/database_configuration.rb +33 -0
  108. data/spec/support/tests/database_configuration_registry.rb +28 -0
  109. data/spec/support/tests/filesystem.rb +25 -2
  110. data/spec/support/unit/helpers/active_record_versions.rb +12 -0
  111. data/spec/support/unit/helpers/class_builder.rb +6 -2
  112. data/spec/support/unit/helpers/column_type_helpers.rb +26 -0
  113. data/spec/support/unit/helpers/controller_builder.rb +0 -28
  114. data/spec/support/unit/helpers/database_helpers.rb +18 -0
  115. data/spec/support/unit/helpers/model_builder.rb +38 -6
  116. data/spec/support/unit/helpers/rails_versions.rb +2 -2
  117. data/spec/support/unit/matchers/fail_with_message_including_matcher.rb +9 -8
  118. data/spec/support/unit/matchers/fail_with_message_matcher.rb +1 -1
  119. data/spec/support/unit/rails_application.rb +29 -13
  120. data/spec/support/unit/record_validating_confirmation_builder.rb +1 -2
  121. data/spec/support/unit/shared_examples/set_session_or_flash.rb +355 -0
  122. data/spec/unit/shoulda/matchers/action_controller/permit_matcher_spec.rb +433 -0
  123. data/spec/unit/shoulda/matchers/action_controller/render_with_layout_matcher_spec.rb +1 -5
  124. data/spec/unit/shoulda/matchers/action_controller/route_matcher_spec.rb +37 -0
  125. data/spec/unit/shoulda/matchers/action_controller/set_flash_matcher_spec.rb +23 -147
  126. data/spec/unit/shoulda/matchers/action_controller/set_session_matcher_spec.rb +8 -285
  127. data/spec/unit/shoulda/matchers/action_controller/set_session_or_flash_matcher_spec.rb +562 -0
  128. data/spec/unit/shoulda/matchers/active_model/allow_value_matcher_spec.rb +81 -14
  129. data/spec/unit/shoulda/matchers/active_model/disallow_value_matcher_spec.rb +16 -8
  130. data/spec/unit/shoulda/matchers/active_model/numericality_matchers/comparison_matcher_spec.rb +101 -9
  131. data/spec/unit/shoulda/matchers/active_model/numericality_matchers/even_number_matcher_spec.rb +39 -1
  132. data/spec/unit/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher_spec.rb +39 -1
  133. data/spec/unit/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher_spec.rb +39 -0
  134. data/spec/unit/shoulda/matchers/active_model/validate_exclusion_of_matcher_spec.rb +0 -17
  135. data/spec/unit/shoulda/matchers/active_model/validate_inclusion_of_matcher_spec.rb +0 -17
  136. data/spec/unit/shoulda/matchers/active_model/validate_length_of_matcher_spec.rb +0 -17
  137. data/spec/unit/shoulda/matchers/active_model/validate_numericality_of_matcher_spec.rb +838 -271
  138. data/spec/unit/shoulda/matchers/active_model/validate_presence_of_matcher_spec.rb +0 -19
  139. data/spec/unit/shoulda/matchers/active_record/association_matcher_spec.rb +93 -0
  140. data/spec/unit/shoulda/matchers/active_record/association_matchers/model_reflection_spec.rb +3 -3
  141. data/spec/unit/shoulda/matchers/active_record/define_enum_for_matcher_spec.rb +25 -0
  142. data/spec/unit/shoulda/matchers/active_record/validate_uniqueness_of_matcher_spec.rb +905 -0
  143. data/spec/unit/shoulda/matchers/doublespeak/double_collection_spec.rb +17 -11
  144. data/spec/unit/shoulda/matchers/doublespeak/double_implementation_registry_spec.rb +1 -1
  145. data/spec/unit/shoulda/matchers/doublespeak/double_spec.rb +144 -43
  146. data/spec/unit/shoulda/matchers/doublespeak/object_double_spec.rb +1 -1
  147. data/spec/unit/shoulda/matchers/doublespeak/proxy_implementation_spec.rb +36 -11
  148. data/spec/unit/shoulda/matchers/doublespeak/stub_implementation_spec.rb +29 -16
  149. data/spec/unit/shoulda/matchers/doublespeak/world_spec.rb +8 -5
  150. data/spec/unit/shoulda/matchers/doublespeak_spec.rb +1 -1
  151. data/spec/unit_spec_helper.rb +15 -14
  152. data/spec/warnings_spy.rb +1 -1
  153. metadata +68 -29
  154. data/docs.watchr +0 -5
  155. data/gemfiles/3.0.gemfile +0 -26
  156. data/gemfiles/3.0.gemfile.lock +0 -173
  157. data/gemfiles/3.1.gemfile +0 -32
  158. data/gemfiles/3.1.gemfile.lock +0 -212
  159. data/gemfiles/3.1_1.9.2.gemfile +0 -32
  160. data/gemfiles/3.1_1.9.2.gemfile.lock +0 -212
  161. data/gemfiles/3.2.gemfile +0 -33
  162. data/gemfiles/3.2.gemfile.lock +0 -212
  163. data/gemfiles/3.2_1.9.2.gemfile +0 -31
  164. data/gemfiles/3.2_1.9.2.gemfile.lock +0 -207
  165. data/lib/shoulda/matchers/assertion_error.rb +0 -27
  166. data/lib/shoulda/matchers/doublespeak/structs.rb +0 -10
  167. data/lib/shoulda/matchers/integrations/nunit_test_case_detection.rb +0 -39
  168. data/lib/shoulda/matchers/integrations/rspec.rb +0 -19
  169. data/lib/shoulda/matchers/integrations/test_unit.rb +0 -34
  170. data/spec/unit/shoulda/matchers/action_controller/strong_parameters_matcher_spec.rb +0 -331
  171. data/spec/unit/shoulda/matchers/active_model/validate_uniqueness_of_matcher_spec.rb +0 -564
@@ -16,7 +16,7 @@ module UnitTests
16
16
  @actual = ex.message
17
17
  end
18
18
 
19
- @actual && @actual == expected
19
+ @actual && @actual == expected.sub(/\n\z/, '')
20
20
  end
21
21
 
22
22
  def failure_message
@@ -1,18 +1,26 @@
1
+ require_relative '../tests/bundle'
1
2
  require_relative '../tests/command_runner'
3
+ require_relative '../tests/database'
2
4
  require_relative '../tests/filesystem'
3
- require_relative '../tests/bundle'
5
+
6
+ require 'yaml'
4
7
 
5
8
  module UnitTests
6
9
  class RailsApplication
7
10
  def initialize
8
11
  @fs = Tests::Filesystem.new
9
12
  @bundle = Tests::Bundle.new
13
+ @database = Tests::Database.instance
10
14
  end
11
15
 
12
16
  def create
13
17
  fs.clean
14
18
  generate
15
- fs.within_project { install_gems }
19
+
20
+ fs.within_project do
21
+ install_gems
22
+ remove_unwanted_gems
23
+ end
16
24
  end
17
25
 
18
26
  def load
@@ -51,7 +59,7 @@ module UnitTests
51
59
 
52
60
  protected
53
61
 
54
- attr_reader :fs, :shell, :bundle
62
+ attr_reader :fs, :shell, :bundle, :database
55
63
 
56
64
  private
57
65
 
@@ -66,6 +74,7 @@ module UnitTests
66
74
  def generate
67
75
  rails_new
68
76
  fix_available_locales_warning
77
+ write_database_configuration
69
78
  end
70
79
 
71
80
  def rails_new
@@ -75,17 +84,17 @@ module UnitTests
75
84
  def fix_available_locales_warning
76
85
  # See here for more on this:
77
86
  # http://stackoverflow.com/questions/20361428/rails-i18n-validation-deprecation-warning
78
-
79
- filename = 'config/application.rb'
80
-
81
- lines = fs.read(filename).split("\n")
82
- lines.insert(-3, <<EOT)
87
+ fs.transform('config/application.rb') do |lines|
88
+ lines.insert(-3, <<-EOT)
83
89
  if I18n.respond_to?(:enforce_available_locales=)
84
90
  I18n.enforce_available_locales = false
85
91
  end
86
- EOT
92
+ EOT
93
+ end
94
+ end
87
95
 
88
- fs.write(filename, lines.join("\n"))
96
+ def write_database_configuration
97
+ YAML.dump(database.config.to_hash, fs.open('config/database.yml', 'w'))
89
98
  end
90
99
 
91
100
  def load_environment
@@ -93,15 +102,22 @@ EOT
93
102
  end
94
103
 
95
104
  def run_migrations
96
- ActiveRecord::Migration.verbose = false
97
- ActiveRecord::Migrator.migrate(migrations_directory)
105
+ fs.within_project do
106
+ run_command! 'bundle exec rake db:drop db:create db:migrate'
107
+ end
98
108
  end
99
109
 
100
110
  def install_gems
101
111
  bundle.install_gems
102
112
  end
103
113
 
104
- private
114
+ def remove_unwanted_gems
115
+ bundle.updating do
116
+ bundle.remove_gem 'debugger'
117
+ bundle.remove_gem 'byebug'
118
+ bundle.remove_gem 'web-console'
119
+ end
120
+ end
105
121
 
106
122
  def run_command!(*args)
107
123
  Tests::CommandRunner.run!(*args)
@@ -34,8 +34,7 @@ module UnitTests
34
34
  end
35
35
 
36
36
  def attribute_that_receives_error
37
- Shoulda::Matchers::RailsShim.
38
- validates_confirmation_of_error_attribute(self)
37
+ confirmation_attribute
39
38
  end
40
39
 
41
40
  protected
@@ -0,0 +1,355 @@
1
+ shared_examples_for 'set session or flash matcher' do
2
+ context 'without any qualifiers' do
3
+ it 'produces the right description' do
4
+ expected_description = "should set any key in #{store_name}"
5
+ matcher = set_store
6
+
7
+ expect(matcher.description).to eq expected_description
8
+ end
9
+
10
+ context 'in the positive' do
11
+ context 'if the store is not empty' do
12
+ it 'accepts' do
13
+ controller = controller_with_store('any key' => 'any value')
14
+ expect(controller).to set_store
15
+ end
16
+ end
17
+
18
+ context 'if the store is empty' do
19
+ it 'rejects' do
20
+ controller = controller_with_empty_store
21
+ expect(controller).not_to set_store
22
+ end
23
+
24
+ it 'produces the correct failure message' do
25
+ controller = controller_with_empty_store
26
+ expected_message = %<Expected #{controller.class} to set any key in #{store_name}, but it did not>
27
+
28
+ expect { expect(controller).to set_store }.
29
+ to fail_with_message(expected_message)
30
+ end
31
+ end
32
+ end
33
+
34
+ context 'in the negative' do
35
+ context 'if the given key is present in the store' do
36
+ it 'produces the correct failure message' do
37
+ controller = controller_with_store('any key' => 'any value')
38
+ expected_message = %<Expected #{controller.class} not to set any key in #{store_name}, but it did>
39
+ assertion = proc do
40
+ expect(controller).not_to set_store
41
+ end
42
+
43
+ expect(&assertion).to fail_with_message(expected_message)
44
+ end
45
+ end
46
+ end
47
+ end
48
+
49
+ context 'with #[]' do
50
+ it 'produces the right description' do
51
+ matcher = set_store['the key']
52
+ expected_description = %<should set #{store_name}["the key"]>
53
+
54
+ expect(matcher.description).to eq expected_description
55
+ end
56
+
57
+ context 'in the positive' do
58
+ context 'if the given key is present in the store' do
59
+ it 'accepts' do
60
+ controller = controller_with_store('the key' => 'any value')
61
+ expect(controller).to set_store['the key']
62
+ end
63
+ end
64
+
65
+ context 'if the given key is not present in the store' do
66
+ it 'rejects' do
67
+ controller = controller_with_empty_store
68
+ expect(controller).not_to set_store['the key']
69
+ end
70
+
71
+ it 'produces the correct failure message' do
72
+ controller = controller_with_empty_store
73
+ expected_message = %<Expected #{controller.class} to set #{store_name}["the key"], but it did not>
74
+ assertion = proc do
75
+ expect(controller).to set_store['the key']
76
+ end
77
+
78
+ expect(&assertion).to fail_with_message(expected_message)
79
+ end
80
+ end
81
+ end
82
+
83
+ context 'in the negative' do
84
+ context 'if the given key is present in the store' do
85
+ it 'produces the correct failure message' do
86
+ controller = controller_with_store('the key' => 'any value')
87
+ expected_message = %<Expected #{controller.class} not to set #{store_name}["the key"], but it did>
88
+ assertion = proc do
89
+ expect(controller).not_to set_store['the key']
90
+ end
91
+
92
+ expect(&assertion).to fail_with_message(expected_message)
93
+ end
94
+ end
95
+ end
96
+ end
97
+
98
+ context 'with #to' do
99
+ context 'given a static value' do
100
+ it 'produces the right description' do
101
+ matcher = set_store.to('the value')
102
+ expected_description = %<should set any key in #{store_name} to "the value">
103
+
104
+ expect(matcher.description).to eq expected_description
105
+ end
106
+
107
+ context 'in the positive' do
108
+ context 'if the given value is present in the store' do
109
+ it 'accepts' do
110
+ controller = controller_with_store('any key' => 'the value')
111
+ expect(controller).to set_store.to('the value')
112
+ end
113
+
114
+ it 'accepts given a value of nil' do
115
+ controller = controller_with_store('any key' => nil)
116
+ expect(controller).to set_store.to(nil)
117
+ end
118
+
119
+ it 'accepts given a value of false' do
120
+ controller = controller_with_store('any key' => false)
121
+ expect(controller).to set_store.to(false)
122
+ end
123
+ end
124
+
125
+ context 'if the given value is not present in the store' do
126
+ it 'rejects' do
127
+ controller = controller_with_empty_store
128
+ expect(controller).not_to set_store.to('the value')
129
+ end
130
+
131
+ it 'rejects checking for nil' do
132
+ controller = controller_with_empty_store
133
+ expect(controller).not_to set_store.to(nil)
134
+ end
135
+
136
+ it 'produces the correct failure message' do
137
+ controller = controller_with_empty_store
138
+ expected_message = %<Expected #{controller.class} to set any key in #{store_name} to "the value", but it did not>
139
+ assertion = proc do
140
+ expect(controller).to set_store.to('the value')
141
+ end
142
+
143
+ expect(&assertion).to fail_with_message(expected_message)
144
+ end
145
+ end
146
+ end
147
+
148
+ context 'in the negative' do
149
+ context 'if the given value is present in the store' do
150
+ it 'produces the correct failure message' do
151
+ controller = controller_with_store('any key' => 'the value')
152
+ expected_message = %<Expected #{controller.class} not to set any key in #{store_name} to "the value", but it did>
153
+ assertion = proc do
154
+ expect(controller).not_to set_store.to('the value')
155
+ end
156
+
157
+ expect(&assertion).to fail_with_message(expected_message)
158
+ end
159
+ end
160
+ end
161
+ end
162
+
163
+ context 'given a regexp' do
164
+ it 'produces the right description' do
165
+ matcher = set_store.to(/value/)
166
+ expected_description = %<should set any key in #{store_name} to a value matching /value/>
167
+
168
+ expect(matcher.description).to eq expected_description
169
+ end
170
+
171
+ context 'in the positive' do
172
+ context 'if the given value is present in the store' do
173
+ it 'accepts' do
174
+ controller = controller_with_store('any key' => 'the value')
175
+ expect(controller).to set_store.to(/value/)
176
+ end
177
+
178
+ it 'accepts given a value of nil' do
179
+ controller = controller_with_store('any key' => nil)
180
+ expect(controller).to set_store.to(nil)
181
+ end
182
+
183
+ it 'accepts given a value of false' do
184
+ controller = controller_with_store('any key' => false)
185
+ expect(controller).to set_store.to(false)
186
+ end
187
+ end
188
+
189
+ context 'if the given value is not present in the store' do
190
+ it 'rejects' do
191
+ controller = controller_with_empty_store
192
+ expect(controller).not_to set_store.to(/value/)
193
+ end
194
+
195
+ it 'produces the correct failure message' do
196
+ controller = controller_with_empty_store
197
+ expected_message = %<Expected #{controller.class} to set any key in #{store_name} to a value matching /value/, but it did not>
198
+ assertion = proc do
199
+ expect(controller).to set_store.to(/value/)
200
+ end
201
+
202
+ expect(&assertion).to fail_with_message(expected_message)
203
+ end
204
+ end
205
+ end
206
+
207
+ context 'in the negative' do
208
+ context 'if the given value is present in the store' do
209
+ it 'produces the correct failure message' do
210
+ controller = controller_with_store('any key' => 'the value')
211
+ expected_message = %<Expected #{controller.class} not to set any key in #{store_name} to a value matching /value/, but it did>
212
+ assertion = proc do
213
+ expect(controller).not_to set_store.to(/value/)
214
+ end
215
+
216
+ expect(&assertion).to fail_with_message(expected_message)
217
+ end
218
+ end
219
+ end
220
+ end
221
+ end
222
+
223
+ context 'with #[] + #to' do
224
+ context 'given a static value' do
225
+ it 'produces the right description' do
226
+ expected_description = %<should set #{store_name}["the key"] to "the value">
227
+ matcher = set_store['the key'].to('the value')
228
+
229
+ expect(matcher.description).to eq expected_description
230
+ end
231
+
232
+ context 'in the positive' do
233
+ context 'if the given value is present in the store' do
234
+ it 'accepts' do
235
+ controller = controller_with_store('the key' => 'the value')
236
+ expect(controller).to set_store['the key'].to('the value')
237
+ end
238
+ end
239
+
240
+ context 'if the given value is not present in the store' do
241
+ it 'rejects' do
242
+ controller = controller_with_empty_store
243
+ expect(controller).not_to set_store['the key'].to('the value')
244
+ end
245
+
246
+ it 'produces the correct failure message' do
247
+ controller = controller_with_empty_store
248
+ expected_message = %<Expected #{controller.class} to set #{store_name}["the key"] to "the value", but it did not>
249
+ assertion = proc do
250
+ expect(controller).to set_store['the key'].to('the value')
251
+ end
252
+
253
+ expect(&assertion).to fail_with_message(expected_message)
254
+ end
255
+ end
256
+ end
257
+
258
+ context 'in the negative' do
259
+ context 'if the given value is present in the store' do
260
+ it 'produces the correct failure message' do
261
+ controller = controller_with_store('the key' => 'the value')
262
+ expected_message = %<Expected #{controller.class} not to set #{store_name}["the key"] to "the value", but it did>
263
+ assertion = proc do
264
+ expect(controller).not_to set_store['the key'].to('the value')
265
+ end
266
+
267
+ expect(&assertion).to fail_with_message(expected_message)
268
+ end
269
+ end
270
+ end
271
+ end
272
+
273
+ context 'given a dynamic value' do
274
+ it 'produces the right description' do
275
+ context = double('context', method_in_context: 'the value')
276
+ matcher = set_store['the key'].
277
+ in_context(context).
278
+ to { method_in_context }
279
+ expected_description = %<should set #{store_name}["the key"] to "the value">
280
+
281
+ expect(matcher.description).to eq expected_description
282
+ end
283
+
284
+ context 'in the positive' do
285
+ context 'if the value evaluated in the context is present in the store' do
286
+ it 'accepts' do
287
+ controller = controller_with_store('the key' => 'the value')
288
+ context = double('context', method_in_context: 'the value')
289
+
290
+ expect(controller).to set_store['the key'].
291
+ in_context(context).
292
+ to { method_in_context }
293
+ end
294
+ end
295
+
296
+ context 'if the value evaluated in the context is not present in the store' do
297
+ it 'rejects' do
298
+ controller = controller_with_empty_store
299
+ context = double('context', method_in_context: 'the value')
300
+
301
+ expect(controller).not_to set_store['the key'].
302
+ in_context(context).
303
+ to { method_in_context }
304
+ end
305
+
306
+ it 'produces the correct failure message' do
307
+ controller = controller_with_empty_store
308
+ context = double('context', method_in_context: 'the value')
309
+ expected_message = %<Expected #{controller.class} to set #{store_name}["the key"] to "the value", but it did not>
310
+ assertion = proc do
311
+ expect(controller).to set_store['the key'].
312
+ in_context(context).
313
+ to { method_in_context }
314
+ end
315
+
316
+ expect(&assertion).to fail_with_message(expected_message)
317
+ end
318
+ end
319
+ end
320
+
321
+ context 'in the negative' do
322
+ context 'if the value evaluated in the context is present in the store' do
323
+ it 'produces the correct failure message' do
324
+ context = double('context', method_in_context: 'the value')
325
+ controller = controller_with_store('the key' => 'the value')
326
+ expected_message = %<Expected #{controller.class} not to set #{store_name}["the key"] to "the value", but it did>
327
+ assertion = proc do
328
+ expect(controller).not_to set_store['the key'].
329
+ in_context(context).
330
+ to { method_in_context }
331
+ end
332
+
333
+ expect(&assertion).to fail_with_message(expected_message)
334
+ end
335
+ end
336
+ end
337
+ end
338
+ end
339
+
340
+ def controller_with_empty_store
341
+ build_fake_response
342
+ end
343
+
344
+ def controller_with_store(store_contents)
345
+ context = self
346
+
347
+ build_fake_response do
348
+ store = context.store_within(self)
349
+
350
+ store_contents.each do |key, value|
351
+ store[key] = value
352
+ end
353
+ end
354
+ end
355
+ end