giga-safe-box 0.0.1

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 (140) hide show
  1. checksums.yaml +7 -0
  2. data/giga-safe-box.gemspec +11 -0
  3. data/shoulda-matchers-8.0.1/LICENSE +22 -0
  4. data/shoulda-matchers-8.0.1/README.md +567 -0
  5. data/shoulda-matchers-8.0.1/docs/errors/NonCaseSwappableValueError.md +111 -0
  6. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/callback_matcher.rb +121 -0
  7. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +70 -0
  8. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/flash_store.rb +86 -0
  9. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/permit_matcher.rb +445 -0
  10. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +96 -0
  11. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/render_template_matcher.rb +84 -0
  12. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +145 -0
  13. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +115 -0
  14. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/respond_with_matcher.rb +148 -0
  15. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/route_matcher.rb +207 -0
  16. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/route_params.rb +62 -0
  17. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/session_store.rb +34 -0
  18. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/set_flash_matcher.rb +228 -0
  19. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/set_session_matcher.rb +163 -0
  20. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/set_session_or_flash_matcher.rb +107 -0
  21. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller.rb +24 -0
  22. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_changed_value_error.rb +45 -0
  23. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_does_not_exist_error.rb +23 -0
  24. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter.rb +232 -0
  25. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter_and_validator.rb +62 -0
  26. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters.rb +40 -0
  27. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb +48 -0
  28. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/successful_check.rb +14 -0
  29. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/successful_setting.rb +14 -0
  30. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher.rb +695 -0
  31. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/comparison_matcher.rb +157 -0
  32. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +78 -0
  33. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/errors.rb +52 -0
  34. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +125 -0
  35. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/helpers.rb +37 -0
  36. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/numericality_matchers/even_number_matcher.rb +45 -0
  37. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +67 -0
  38. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher.rb +45 -0
  39. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher.rb +44 -0
  40. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/numericality_matchers/range_matcher.rb +71 -0
  41. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/numericality_matchers/submatchers.rb +53 -0
  42. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/numericality_matchers.rb +9 -0
  43. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/qualifiers/allow_blank.rb +26 -0
  44. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/qualifiers/allow_nil.rb +26 -0
  45. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/qualifiers/ignore_interference_by_writer.rb +101 -0
  46. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/qualifiers/ignoring_interference_by_writer.rb +21 -0
  47. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/qualifiers.rb +14 -0
  48. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +180 -0
  49. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +128 -0
  50. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_comparison_of_matcher.rb +567 -0
  51. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +185 -0
  52. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +272 -0
  53. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +664 -0
  54. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +575 -0
  55. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +711 -0
  56. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +428 -0
  57. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validation_matcher/build_description.rb +62 -0
  58. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validation_matcher.rb +195 -0
  59. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validation_message_finder.rb +63 -0
  60. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validator.rb +127 -0
  61. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model.rb +96 -0
  62. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +217 -0
  63. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matcher.rb +2134 -0
  64. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb +74 -0
  65. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/dependent_matcher.rb +62 -0
  66. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/inverse_of_matcher.rb +41 -0
  67. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +105 -0
  68. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +101 -0
  69. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +89 -0
  70. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +142 -0
  71. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/optional_matcher.rb +71 -0
  72. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/order_matcher.rb +41 -0
  73. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/required_matcher.rb +76 -0
  74. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/source_matcher.rb +42 -0
  75. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/through_matcher.rb +65 -0
  76. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers.rb +9 -0
  77. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +784 -0
  78. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/encrypt_matcher.rb +174 -0
  79. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/have_attached_matcher.rb +343 -0
  80. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +366 -0
  81. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +287 -0
  82. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/have_implicit_order_column.rb +104 -0
  83. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +95 -0
  84. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/have_rich_text_matcher.rb +83 -0
  85. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/have_secure_token_matcher.rb +132 -0
  86. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/normalize_matcher.rb +151 -0
  87. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/serialize_matcher.rb +203 -0
  88. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/uniqueness/model.rb +58 -0
  89. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/uniqueness/namespace.rb +39 -0
  90. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/uniqueness/test_model_creator.rb +49 -0
  91. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/uniqueness/test_models.rb +55 -0
  92. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/uniqueness.rb +14 -0
  93. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +1197 -0
  94. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record.rb +37 -0
  95. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/configuration.rb +31 -0
  96. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/double.rb +103 -0
  97. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/double_collection.rb +60 -0
  98. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/double_implementation_registry.rb +31 -0
  99. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/method_call.rb +44 -0
  100. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/object_double.rb +43 -0
  101. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/proxy_implementation.rb +32 -0
  102. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/stub_implementation.rb +31 -0
  103. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/world.rb +63 -0
  104. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak.rb +38 -0
  105. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/error.rb +29 -0
  106. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/independent/delegate_method_matcher/target_not_defined_error.rb +15 -0
  107. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/independent/delegate_method_matcher.rb +540 -0
  108. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/independent.rb +11 -0
  109. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/configuration.rb +70 -0
  110. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/configuration_error.rb +9 -0
  111. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/inclusion.rb +20 -0
  112. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/libraries/action_controller.rb +33 -0
  113. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/libraries/active_model.rb +26 -0
  114. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/libraries/active_record.rb +26 -0
  115. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/libraries/missing_library.rb +19 -0
  116. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/libraries/rails.rb +31 -0
  117. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/libraries/routing.rb +29 -0
  118. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/libraries.rb +16 -0
  119. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/rails.rb +12 -0
  120. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/registry.rb +28 -0
  121. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/test_frameworks/active_support_test_case.rb +37 -0
  122. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/test_frameworks/minitest_4.rb +36 -0
  123. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/test_frameworks/minitest_5.rb +37 -0
  124. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/test_frameworks/missing_test_framework.rb +40 -0
  125. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/test_frameworks/rspec.rb +29 -0
  126. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/test_frameworks/test_unit.rb +36 -0
  127. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/test_frameworks.rb +16 -0
  128. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations.rb +43 -0
  129. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/matcher_collection.rb +99 -0
  130. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/matcher_context.rb +36 -0
  131. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/rails_shim.rb +190 -0
  132. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/routing.rb +10 -0
  133. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/util/word_wrap.rb +211 -0
  134. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/util.rb +110 -0
  135. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/version.rb +6 -0
  136. data/shoulda-matchers-8.0.1/lib/shoulda/matchers/warn.rb +28 -0
  137. data/shoulda-matchers-8.0.1/lib/shoulda/matchers.rb +25 -0
  138. data/shoulda-matchers-8.0.1/lib/shoulda-matchers.rb +1 -0
  139. data/shoulda-matchers-8.0.1/shoulda-matchers.gemspec +43 -0
  140. metadata +178 -0
@@ -0,0 +1,540 @@
1
+ require 'shoulda/matchers/doublespeak'
2
+ require 'shoulda/matchers/matcher_context'
3
+
4
+ module Shoulda
5
+ module Matchers
6
+ module Independent
7
+ # The `delegate_method` matcher tests that an object forwards messages
8
+ # to other, internal objects by way of delegation.
9
+ #
10
+ # In this example, we test that Courier forwards a call to #deliver onto
11
+ # its PostOffice instance:
12
+ #
13
+ # require 'forwardable'
14
+ #
15
+ # class Courier
16
+ # extend Forwardable
17
+ #
18
+ # attr_reader :post_office
19
+ #
20
+ # def_delegators :post_office, :deliver
21
+ #
22
+ # def initialize
23
+ # @post_office = PostOffice.new
24
+ # end
25
+ # end
26
+ #
27
+ # # RSpec
28
+ # describe Courier do
29
+ # it { should delegate_method(:deliver).to(:post_office) }
30
+ # end
31
+ #
32
+ # # Minitest
33
+ # class CourierTest < Minitest::Test
34
+ # should delegate_method(:deliver).to(:post_office)
35
+ # end
36
+ #
37
+ # You can also use `delegate_method` with Rails's `delegate` macro:
38
+ #
39
+ # class Courier
40
+ # attr_reader :post_office
41
+ # delegate :deliver, to: :post_office
42
+ #
43
+ # def initialize
44
+ # @post_office = PostOffice.new
45
+ # end
46
+ # end
47
+ #
48
+ # describe Courier do
49
+ # it { should delegate_method(:deliver).to(:post_office) }
50
+ # end
51
+ #
52
+ # To employ some terminology, we would say that Courier's #deliver method
53
+ # is the *delegating method*, PostOffice is the *delegate object*, and
54
+ # PostOffice#deliver is the *delegate method*.
55
+ #
56
+ # #### Qualifiers
57
+ #
58
+ # ##### as
59
+ #
60
+ # Use `as` if the name of the delegate method is different from the name
61
+ # of the delegating method.
62
+ #
63
+ # Here, Courier has a #deliver method, but instead of calling #deliver on
64
+ # the PostOffice, it calls #ship:
65
+ #
66
+ # class Courier
67
+ # attr_reader :post_office
68
+ #
69
+ # def initialize
70
+ # @post_office = PostOffice.new
71
+ # end
72
+ #
73
+ # def deliver(package)
74
+ # post_office.ship(package)
75
+ # end
76
+ # end
77
+ #
78
+ # # RSpec
79
+ # describe Courier do
80
+ # it { should delegate_method(:deliver).to(:post_office).as(:ship) }
81
+ # end
82
+ #
83
+ # # Minitest
84
+ # class CourierTest < Minitest::Test
85
+ # should delegate_method(:deliver).to(:post_office).as(:ship)
86
+ # end
87
+ #
88
+ # ##### with_prefix
89
+ #
90
+ # Use `with_prefix` when using Rails's `delegate` helper along with the
91
+ # `:prefix` option.
92
+ #
93
+ # class Page < ActiveRecord::Base
94
+ # belongs_to :site
95
+ # delegate :name, to: :site, prefix: true
96
+ # delegate :title, to: :site, prefix: :root
97
+ # end
98
+ #
99
+ # # RSpec
100
+ # describe Page do
101
+ # it { should delegate_method(:name).to(:site).with_prefix }
102
+ # it { should delegate_method(:name).to(:site).with_prefix(true) }
103
+ # it { should delegate_method(:title).to(:site).with_prefix(:root) }
104
+ # end
105
+ #
106
+ # # Minitest
107
+ # class PageTest < Minitest::Test
108
+ # should delegate_method(:name).to(:site).with_prefix
109
+ # should delegate_method(:name).to(:site).with_prefix(true)
110
+ # should delegate_method(:title).to(:site).with_prefix(:root)
111
+ # end
112
+ #
113
+ # ##### with_arguments
114
+ #
115
+ # Use `with_arguments` to assert that the delegate method is called with
116
+ # certain arguments. Note that this qualifier can only be used when the
117
+ # delegating method takes no arguments; it does not support delegating
118
+ # or delegate methods that take arbitrary arguments.
119
+ #
120
+ # Here, when Courier#deliver_package calls PostOffice#deliver_package, it
121
+ # adds an options hash:
122
+ #
123
+ # class Courier
124
+ # attr_reader :post_office
125
+ #
126
+ # def initialize
127
+ # @post_office = PostOffice.new
128
+ # end
129
+ #
130
+ # def deliver_package
131
+ # post_office.deliver_package(expedited: true)
132
+ # end
133
+ # end
134
+ #
135
+ # # RSpec
136
+ # describe Courier do
137
+ # it do
138
+ # should delegate_method(:deliver_package).
139
+ # to(:post_office).
140
+ # with_arguments(expedited: true)
141
+ # end
142
+ # end
143
+ #
144
+ # # Minitest
145
+ # class CourierTest < Minitest::Test
146
+ # should delegate_method(:deliver_package).
147
+ # to(:post_office).
148
+ # with_arguments(expedited: true)
149
+ # end
150
+ #
151
+ # ##### allow_nil
152
+ #
153
+ # Use `allow_nil` if the delegation accounts for the fact that your
154
+ # delegate object could be nil. (This is mostly intended as an analogue to
155
+ # the `allow_nil` option that Rails' `delegate` helper takes.)
156
+ #
157
+ # class Account
158
+ # delegate :plan, to: :subscription, allow_nil: true
159
+ # end
160
+ #
161
+ # # RSpec
162
+ # describe Account do
163
+ # it { should delegate_method(:plan).to(:subscription).allow_nil }
164
+ # end
165
+ #
166
+ # # Minitest
167
+ # class PageTest < Minitest::Test
168
+ # should delegate_method(:plan).to(:subscription).allow_nil
169
+ # end
170
+ #
171
+ # ##### with_private
172
+ #
173
+ # Use `with_private` if the delegation accounts for the fact that your
174
+ # delegation is private. (This is mostly intended as an analogue to
175
+ # the `private` option that Rails' `delegate` helper takes.)
176
+ #
177
+ # class Account
178
+ # delegate :plan, to: :subscription, private: true
179
+ # end
180
+ #
181
+ # # RSpec
182
+ # describe Account do
183
+ # it { should delegate_method(:plan).to(:subscription).with_private }
184
+ # end
185
+ #
186
+ # # Minitest
187
+ # class PageTest < Minitest::Test
188
+ # should delegate_method(:plan).to(:subscription).with_private
189
+ # end
190
+ #
191
+ # @return [DelegateMethodMatcher]
192
+ def delegate_method(delegating_method)
193
+ DelegateMethodMatcher.new(delegating_method).in_context(self)
194
+ end
195
+
196
+ # @private
197
+ class DelegateMethodMatcher
198
+ def initialize(delegating_method)
199
+ @delegating_method = delegating_method
200
+
201
+ @delegate_method = @delegating_method
202
+ @delegate_object = Doublespeak::ObjectDouble.new
203
+
204
+ @context = nil
205
+ @subject = nil
206
+ @delegate_object_reader_method = nil
207
+ @delegated_arguments = []
208
+ @expects_to_allow_nil_delegate_object = false
209
+ @expects_private_delegation = false
210
+ end
211
+
212
+ def in_context(context)
213
+ @context = MatcherContext.new(context)
214
+ self
215
+ end
216
+
217
+ def matches?(subject)
218
+ @subject = subject
219
+
220
+ ensure_delegate_object_has_been_specified!
221
+
222
+ subject_has_delegating_method? &&
223
+ subject_has_delegate_object_reader_method? &&
224
+ subject_delegates_to_delegate_object_correctly? &&
225
+ subject_handles_nil_delegate_object? &&
226
+ subject_handles_private_delegation?
227
+ end
228
+
229
+ def description
230
+ string =
231
+ "delegate #{formatted_delegating_method_name} to the " +
232
+ "#{formatted_delegate_object_reader_method_name} object"
233
+
234
+ if expects_private_delegation?
235
+ string << ' privately'
236
+ end
237
+
238
+ if delegated_arguments.any?
239
+ string << " passing arguments #{delegated_arguments.inspect}"
240
+ end
241
+
242
+ if delegate_method != delegating_method
243
+ string << " as #{formatted_delegate_method}"
244
+ end
245
+
246
+ if expects_to_allow_nil_delegate_object?
247
+ string << ', allowing '
248
+ string << formatted_delegate_object_reader_method_name
249
+ string << ' to return nil'
250
+ end
251
+
252
+ string
253
+ end
254
+
255
+ def to(delegate_object_reader_method)
256
+ @delegate_object_reader_method = delegate_object_reader_method
257
+ self
258
+ end
259
+
260
+ def as(delegate_method)
261
+ @delegate_method = delegate_method
262
+ self
263
+ end
264
+
265
+ def with_arguments(*arguments)
266
+ @delegated_arguments = arguments
267
+ self
268
+ end
269
+
270
+ def with_prefix(prefix = nil)
271
+ @delegating_method =
272
+ :"#{build_delegating_method_prefix(prefix)}_#{delegate_method}"
273
+ delegate_method
274
+ self
275
+ end
276
+
277
+ def allow_nil
278
+ @expects_to_allow_nil_delegate_object = true
279
+ self
280
+ end
281
+
282
+ def with_private
283
+ @expects_private_delegation = true
284
+ self
285
+ end
286
+
287
+ def build_delegating_method_prefix(prefix)
288
+ case prefix
289
+ when true, nil then delegate_object_reader_method
290
+ else prefix
291
+ end
292
+ end
293
+
294
+ def failure_message
295
+ message = "Expected #{class_under_test} to #{description}.\n\n"
296
+
297
+ if failed_to_allow_nil_delegate_object? || failed_to_handle_private_delegation?
298
+ message << formatted_delegating_method_name(include_module: true)
299
+ message << ' did delegate to '
300
+ message << formatted_delegate_object_reader_method_name
301
+ end
302
+
303
+ if failed_to_allow_nil_delegate_object?
304
+ message << ' when it was non-nil, but it failed to account '
305
+ message << 'for when '
306
+ message << formatted_delegate_object_reader_method_name
307
+ message << ' *was* nil.'
308
+ elsif failed_to_handle_private_delegation?
309
+ message << ", but 'private: true' is missing."
310
+ else
311
+ message << 'Method calls sent to '
312
+ message << formatted_delegate_object_reader_method_name(
313
+ include_module: true,
314
+ )
315
+ message << ": #{formatted_calls_on_delegate_object}"
316
+ end
317
+
318
+ Shoulda::Matchers.word_wrap(message)
319
+ end
320
+
321
+ def failure_message_when_negated
322
+ "Expected #{class_under_test} not to #{description}, but it did."
323
+ end
324
+
325
+ protected
326
+
327
+ attr_reader \
328
+ :context,
329
+ :delegated_arguments,
330
+ :delegating_method,
331
+ :method,
332
+ :delegate_method,
333
+ :delegate_object,
334
+ :delegate_object_reader_method
335
+
336
+ def subject
337
+ @subject
338
+ end
339
+
340
+ def subject_is_a_class?
341
+ if @subject
342
+ @subject.is_a?(Class)
343
+ else
344
+ context.subject_is_a_class?
345
+ end
346
+ end
347
+
348
+ def class_under_test
349
+ if subject_is_a_class?
350
+ subject
351
+ else
352
+ subject.class
353
+ end
354
+ end
355
+
356
+ def expects_to_allow_nil_delegate_object?
357
+ @expects_to_allow_nil_delegate_object
358
+ end
359
+
360
+ def expects_private_delegation?
361
+ @expects_private_delegation
362
+ end
363
+
364
+ def formatted_delegate_method(options = {})
365
+ formatted_method_name_for(delegate_method, options)
366
+ end
367
+
368
+ def formatted_delegating_method_name(options = {})
369
+ formatted_method_name_for(delegating_method, options)
370
+ end
371
+
372
+ def formatted_delegate_object_reader_method_name(options = {})
373
+ formatted_method_name_for(delegate_object_reader_method, options)
374
+ end
375
+
376
+ def formatted_method_name_for(method_name, options)
377
+ possible_class_under_test(options) +
378
+ class_or_instance_method_indicator +
379
+ method_name.to_s
380
+ end
381
+
382
+ def possible_class_under_test(options)
383
+ if options[:include_module]
384
+ class_under_test.to_s
385
+ else
386
+ ''
387
+ end
388
+ end
389
+
390
+ def class_or_instance_method_indicator
391
+ if subject_is_a_class?
392
+ '.'
393
+ else
394
+ '#'
395
+ end
396
+ end
397
+
398
+ def delegate_object_received_call?
399
+ calls_to_delegate_method.any?
400
+ end
401
+
402
+ def delegate_object_received_call_with_delegated_arguments?
403
+ calls_to_delegate_method.any? do |call|
404
+ call.args == delegated_arguments
405
+ end
406
+ end
407
+
408
+ def subject_has_delegating_method?
409
+ if expects_private_delegation?
410
+ !subject.respond_to?(delegating_method) && subject.respond_to?(delegating_method, true)
411
+ else
412
+ subject.respond_to?(delegating_method)
413
+ end
414
+ end
415
+
416
+ def subject_has_delegate_object_reader_method?
417
+ subject.respond_to?(delegate_object_reader_method, true)
418
+ end
419
+
420
+ def ensure_delegate_object_has_been_specified!
421
+ if delegate_object_reader_method.to_s.empty?
422
+ raise DelegateObjectNotSpecified
423
+ end
424
+ end
425
+
426
+ def subject_delegates_to_delegate_object_correctly?
427
+ if expects_private_delegation?
428
+ privately_call_delegating_method_with_delegate_method_returning(delegate_object)
429
+ else
430
+ call_delegating_method_with_delegate_method_returning(delegate_object)
431
+ end
432
+
433
+ if delegated_arguments.any?
434
+ delegate_object_received_call_with_delegated_arguments?
435
+ else
436
+ delegate_object_received_call?
437
+ end
438
+ end
439
+
440
+ def subject_handles_nil_delegate_object?
441
+ @subject_handled_nil_delegate_object =
442
+ if expects_to_allow_nil_delegate_object?
443
+ begin
444
+ call_delegating_method_with_delegate_method_returning(nil)
445
+ true
446
+ rescue Module::DelegationError
447
+ false
448
+ rescue NoMethodError => e
449
+ if e.message =~ /undefined method [`']#{delegate_method}[`'] for nil/
450
+ false
451
+ else
452
+ raise e
453
+ end
454
+ end
455
+ else
456
+ true
457
+ end
458
+ end
459
+
460
+ def subject_handles_private_delegation?
461
+ @subject_handled_private_delegation =
462
+ if expects_private_delegation?
463
+ begin
464
+ call_delegating_method_with_delegate_method_returning(delegate_object)
465
+ true
466
+ rescue Module::DelegationError
467
+ false
468
+ rescue NoMethodError => e
469
+ if e.message =~ /private method [`']#{delegating_method}[`'] called for/
470
+ true
471
+ else
472
+ raise e
473
+ end
474
+ end
475
+ else
476
+ true
477
+ end
478
+ end
479
+
480
+ def failed_to_allow_nil_delegate_object?
481
+ expects_to_allow_nil_delegate_object? &&
482
+ !@subject_handled_nil_delegate_object
483
+ end
484
+
485
+ def failed_to_handle_private_delegation?
486
+ expects_private_delegation? &&
487
+ !@subject_handled_private_delegation
488
+ end
489
+
490
+ def call_delegating_method_with_delegate_method_returning(value)
491
+ register_subject_double_collection_to(value)
492
+
493
+ Doublespeak.with_doubles_activated do
494
+ subject.public_send(delegating_method, *delegated_arguments)
495
+ end
496
+ end
497
+
498
+ def privately_call_delegating_method_with_delegate_method_returning(value)
499
+ register_subject_double_collection_to(value)
500
+
501
+ Doublespeak.with_doubles_activated do
502
+ subject.__send__(delegating_method, *delegated_arguments)
503
+ end
504
+ end
505
+
506
+ def register_subject_double_collection_to(returned_value)
507
+ double_collection =
508
+ Doublespeak.double_collection_for(subject.singleton_class)
509
+ double_collection.register_stub(delegate_object_reader_method).
510
+ to_return(returned_value)
511
+ end
512
+
513
+ def calls_to_delegate_method
514
+ delegate_object.calls_to(delegate_method)
515
+ end
516
+
517
+ def calls_on_delegate_object
518
+ delegate_object.calls
519
+ end
520
+
521
+ def formatted_calls_on_delegate_object
522
+ String.new.tap do |string|
523
+ if calls_on_delegate_object.any?
524
+ string << "\n\n"
525
+ calls_on_delegate_object.each_with_index do |call, i|
526
+ name = call.method_name
527
+ args = call.args.map(&:inspect).join(', ')
528
+ string << "#{i + 1}) #{name}(#{args})\n"
529
+ end
530
+ else
531
+ string << ' (none)'
532
+ end
533
+
534
+ string.rstrip!
535
+ end
536
+ end
537
+ end
538
+ end
539
+ end
540
+ end
@@ -0,0 +1,11 @@
1
+ require 'shoulda/matchers/independent/delegate_method_matcher'
2
+ require 'shoulda/matchers/independent/delegate_method_matcher/target_not_defined_error'
3
+
4
+ module Shoulda
5
+ module Matchers
6
+ # This module provides matchers that are used to test behavior outside of
7
+ # Rails-specific classes.
8
+ module Independent
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,70 @@
1
+ module Shoulda
2
+ module Matchers
3
+ module Integrations
4
+ # @private
5
+ class Configuration
6
+ def self.apply(&block)
7
+ new(&block).apply
8
+ end
9
+
10
+ attr_reader :test_frameworks
11
+
12
+ def initialize(&block)
13
+ @test_frameworks = Set.new
14
+ @libraries = Set.new
15
+
16
+ test_framework :missing_test_framework
17
+ library :missing_library
18
+
19
+ block.call(self)
20
+ end
21
+
22
+ def test_framework(name)
23
+ clear_default_test_framework
24
+ @test_frameworks << Integrations.find_test_framework!(name)
25
+ end
26
+
27
+ def library(name)
28
+ @libraries << Integrations.find_library!(name)
29
+ end
30
+
31
+ def apply
32
+ if no_test_frameworks_added? && no_libraries_added?
33
+ raise ConfigurationError, <<EOT
34
+ shoulda-matchers is not configured correctly. You need to specify at least one
35
+ test framework and/or library. For example:
36
+
37
+ Shoulda::Matchers.configure do |config|
38
+ config.integrate do |with|
39
+ with.test_framework :rspec
40
+ with.library :rails
41
+ end
42
+ end
43
+ EOT
44
+ end
45
+
46
+ @test_frameworks.each do |test_framework|
47
+ test_framework.include(Shoulda::Matchers::Independent)
48
+ @libraries.each { |library| library.integrate_with(test_framework) }
49
+ end
50
+
51
+ self
52
+ end
53
+
54
+ private
55
+
56
+ def clear_default_test_framework
57
+ @test_frameworks.select!(&:present?)
58
+ end
59
+
60
+ def no_test_frameworks_added?
61
+ @test_frameworks.empty? || @test_frameworks.none?(&:present?)
62
+ end
63
+
64
+ def no_libraries_added?
65
+ @libraries.empty?
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,9 @@
1
+ module Shoulda
2
+ module Matchers
3
+ module Integrations
4
+ # @private
5
+ class ConfigurationError < StandardError
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,20 @@
1
+ module Shoulda
2
+ module Matchers
3
+ module Integrations
4
+ # @private
5
+ module Inclusion
6
+ def include_into(mod, *other_mods, &block)
7
+ mods_to_include = other_mods.dup
8
+ mods_to_extend = other_mods.dup
9
+
10
+ if block
11
+ mods_to_include << Module.new(&block)
12
+ end
13
+
14
+ mod.__send__(:include, *mods_to_include)
15
+ mod.extend(*mods_to_extend)
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,33 @@
1
+ module Shoulda
2
+ module Matchers
3
+ module Integrations
4
+ module Libraries
5
+ # @private
6
+ class ActionController
7
+ Integrations.register_library(self, :action_controller)
8
+
9
+ include Integrations::Inclusion
10
+ include Integrations::Rails
11
+
12
+ def integrate_with(test_framework)
13
+ test_framework.include(matchers_module, type: :controller)
14
+
15
+ tap do |instance|
16
+ ActiveSupport.on_load(:action_controller_test_case, run_once: true) do
17
+ instance.include_into(::ActionController::TestCase, instance.matchers_module) do
18
+ def subject # rubocop:disable Lint/NestedMethodDefinition
19
+ @controller
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ def matchers_module
27
+ Shoulda::Matchers::ActionController
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,26 @@
1
+ module Shoulda
2
+ module Matchers
3
+ module Integrations
4
+ module Libraries
5
+ # @private
6
+ class ActiveModel
7
+ Integrations.register_library(self, :active_model)
8
+
9
+ include Integrations::Inclusion
10
+ include Integrations::Rails
11
+
12
+ def integrate_with(test_framework)
13
+ test_framework.include(matchers_module, type: :model)
14
+ include_into(ActiveSupport::TestCase, matchers_module)
15
+ end
16
+
17
+ private
18
+
19
+ def matchers_module
20
+ Shoulda::Matchers::ActiveModel
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end