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,145 @@
1
+ module Shoulda
2
+ module Matchers
3
+ module ActionController
4
+ # The `render_with_layout` matcher asserts that an action is rendered with
5
+ # a particular layout.
6
+ #
7
+ # class PostsController < ApplicationController
8
+ # def show
9
+ # render layout: 'posts'
10
+ # end
11
+ # end
12
+ #
13
+ # # RSpec
14
+ # RSpec.describe PostsController, type: :controller do
15
+ # describe 'GET #show' do
16
+ # before { get :show }
17
+ #
18
+ # it { should render_with_layout('posts') }
19
+ # end
20
+ # end
21
+ #
22
+ # # Minitest (Shoulda)
23
+ # class PostsControllerTest < ActionController::TestCase
24
+ # context 'GET #show' do
25
+ # setup { get :show }
26
+ #
27
+ # should render_with_layout('posts')
28
+ # end
29
+ # end
30
+ #
31
+ # It can also be used to assert that the action is not rendered with a
32
+ # layout at all:
33
+ #
34
+ # class PostsController < ApplicationController
35
+ # def sidebar
36
+ # render layout: false
37
+ # end
38
+ # end
39
+ #
40
+ # # RSpec
41
+ # RSpec.describe PostsController, type: :controller do
42
+ # describe 'GET #sidebar' do
43
+ # before { get :sidebar }
44
+ #
45
+ # it { should_not render_with_layout }
46
+ # end
47
+ # end
48
+ #
49
+ # # Minitest (Shoulda)
50
+ # class PostsControllerTest < ActionController::TestCase
51
+ # context 'GET #sidebar' do
52
+ # setup { get :sidebar }
53
+ #
54
+ # should_not render_with_layout
55
+ # end
56
+ # end
57
+ #
58
+ # @return [RenderWithLayoutMatcher]
59
+ #
60
+ def render_with_layout(expected_layout = nil)
61
+ RenderWithLayoutMatcher.new(expected_layout).in_context(self)
62
+ end
63
+
64
+ # @private
65
+ class RenderWithLayoutMatcher
66
+ def initialize(expected_layout)
67
+ @expected_layout =
68
+ if expected_layout
69
+ expected_layout.to_s
70
+ else
71
+ nil
72
+ end
73
+ @controller = nil
74
+ end
75
+
76
+ # Used to provide access to layouts recorded by
77
+ # ActionController::TemplateAssertions in Rails 3
78
+ def in_context(context)
79
+ @context = context
80
+ self
81
+ end
82
+
83
+ def matches?(controller)
84
+ @controller = controller
85
+ rendered_with_layout? && rendered_with_expected_layout?
86
+ end
87
+
88
+ def failure_message
89
+ "Expected #{expectation}, but #{result}"
90
+ end
91
+
92
+ def failure_message_when_negated
93
+ "Did not expect #{expectation}, but #{result}"
94
+ end
95
+
96
+ def description
97
+ String.new('render with ').tap do |string|
98
+ string <<
99
+ if @expected_layout.nil?
100
+ 'a layout'
101
+ else
102
+ "the #{@expected_layout.inspect} layout"
103
+ end
104
+ end
105
+ end
106
+
107
+ private
108
+
109
+ def rendered_with_layout?
110
+ !rendered_layouts.empty?
111
+ end
112
+
113
+ def rendered_with_expected_layout?
114
+ @expected_layout.nil? || rendered_layouts.include?(@expected_layout)
115
+ end
116
+
117
+ def rendered_layouts
118
+ recorded_layouts.keys.compact.map { |layout|
119
+ layout.sub(%r{^layouts/}, '')
120
+ }
121
+ end
122
+
123
+ def recorded_layouts
124
+ if @context
125
+ @context.instance_variable_get('@_layouts')
126
+ else
127
+ {}
128
+ end
129
+ end
130
+
131
+ def expectation
132
+ "to #{description}"
133
+ end
134
+
135
+ def result
136
+ if rendered_with_layout?
137
+ "rendered with #{rendered_layouts.map(&:inspect).join(', ')}"
138
+ else
139
+ 'rendered without a layout'
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,115 @@
1
+ module Shoulda
2
+ module Matchers
3
+ module ActionController
4
+ # The `rescue_from` matcher tests usage of the `rescue_from` macro. It
5
+ # asserts that an exception and method are present in the list of
6
+ # exception handlers, and that the handler method exists.
7
+ #
8
+ # class ApplicationController < ActionController::Base
9
+ # rescue_from ActiveRecord::RecordNotFound, with: :handle_not_found
10
+ #
11
+ # private
12
+ #
13
+ # def handle_not_found
14
+ # # ...
15
+ # end
16
+ # end
17
+ #
18
+ # # RSpec
19
+ # RSpec.describe ApplicationController, type: :controller do
20
+ # it do
21
+ # should rescue_from(ActiveRecord::RecordNotFound).
22
+ # with(:handle_not_found)
23
+ # end
24
+ # end
25
+ #
26
+ # # Minitest (Shoulda)
27
+ # class ApplicationControllerTest < ActionController::TestCase
28
+ # should rescue_from(ActiveRecord::RecordNotFound).
29
+ # with(:handle_not_found)
30
+ # end
31
+ #
32
+ # @return [RescueFromMatcher]
33
+ #
34
+ def rescue_from(exception)
35
+ RescueFromMatcher.new exception
36
+ end
37
+
38
+ # @private
39
+ class RescueFromMatcher
40
+ def initialize(exception)
41
+ @exception = exception
42
+ @expected_method = nil
43
+ @controller = nil
44
+ end
45
+
46
+ def with(method)
47
+ @expected_method = method
48
+ self
49
+ end
50
+
51
+ def matches?(controller)
52
+ @controller = controller
53
+ rescues_from_exception? && method_name_matches? && handler_exists?
54
+ end
55
+
56
+ def description
57
+ description = "rescue from #{exception}"
58
+ description << " with ##{expected_method}" if expected_method
59
+ description
60
+ end
61
+
62
+ def failure_message
63
+ "Expected #{expectation}"
64
+ end
65
+
66
+ def failure_message_when_negated
67
+ "Did not expect #{expectation}"
68
+ end
69
+
70
+ protected
71
+
72
+ attr_reader :controller, :exception, :expected_method, :handlers
73
+
74
+ def expectation
75
+ expectation = "#{controller} to rescue from #{exception}"
76
+
77
+ if expected_method && !method_name_matches?
78
+ expectation << " with ##{expected_method}"
79
+ end
80
+
81
+ unless handler_exists?
82
+ expectation << " but #{controller} does not respond to"\
83
+ " #{expected_method}"
84
+ end
85
+ expectation
86
+ end
87
+
88
+ def rescues_from_exception?
89
+ @handlers = controller.rescue_handlers.select do |handler|
90
+ handler.first == exception.to_s
91
+ end
92
+ handlers.any?
93
+ end
94
+
95
+ def method_name_matches?
96
+ if expected_method.present?
97
+ handlers.any? do |handler|
98
+ handler.last == expected_method
99
+ end
100
+ else
101
+ true
102
+ end
103
+ end
104
+
105
+ def handler_exists?
106
+ if expected_method.present?
107
+ controller.respond_to? expected_method, true
108
+ else
109
+ true
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,148 @@
1
+ module Shoulda
2
+ module Matchers
3
+ module ActionController
4
+ # The `respond_with` matcher tests that an action responds with a certain
5
+ # status code.
6
+ #
7
+ # You can specify that the status should be a number:
8
+ #
9
+ # class PostsController < ApplicationController
10
+ # def index
11
+ # render status: 403
12
+ # end
13
+ # end
14
+ #
15
+ # # RSpec
16
+ # RSpec.describe PostsController, type: :controller do
17
+ # describe 'GET #index' do
18
+ # before { get :index }
19
+ #
20
+ # it { should respond_with(403) }
21
+ # end
22
+ # end
23
+ #
24
+ # # Minitest (Shoulda)
25
+ # class PostsControllerTest < ActionController::TestCase
26
+ # context 'GET #index' do
27
+ # setup { get :index }
28
+ #
29
+ # should respond_with(403)
30
+ # end
31
+ # end
32
+ #
33
+ # You can specify that the status should be within a range of numbers:
34
+ #
35
+ # class PostsController < ApplicationController
36
+ # def destroy
37
+ # render status: 508
38
+ # end
39
+ # end
40
+ #
41
+ # # RSpec
42
+ # RSpec.describe PostsController, type: :controller do
43
+ # describe 'DELETE #destroy' do
44
+ # before { delete :destroy }
45
+ #
46
+ # it { should respond_with(500..600) }
47
+ # end
48
+ # end
49
+ #
50
+ # # Minitest (Shoulda)
51
+ # class PostsControllerTest < ActionController::TestCase
52
+ # context 'DELETE #destroy' do
53
+ # setup { delete :destroy }
54
+ #
55
+ # should respond_with(500..600)
56
+ # end
57
+ # end
58
+ #
59
+ # Finally, you can specify that the status should be a symbol:
60
+ #
61
+ # class PostsController < ApplicationController
62
+ # def show
63
+ # render status: :locked
64
+ # end
65
+ # end
66
+ #
67
+ # # RSpec
68
+ # RSpec.describe PostsController, type: :controller do
69
+ # describe 'GET #show' do
70
+ # before { get :show }
71
+ #
72
+ # it { should respond_with(:locked) }
73
+ # end
74
+ # end
75
+ #
76
+ # # Minitest (Shoulda)
77
+ # class PostsControllerTest < ActionController::TestCase
78
+ # context 'GET #show' do
79
+ # setup { get :show }
80
+ #
81
+ # should respond_with(:locked)
82
+ # end
83
+ # end
84
+ #
85
+ # @return [RespondWithMatcher]
86
+ #
87
+ def respond_with(status)
88
+ RespondWithMatcher.new(status)
89
+ end
90
+
91
+ # @private
92
+ class RespondWithMatcher
93
+ def initialize(status)
94
+ @status = symbol_to_status_code(status)
95
+ end
96
+
97
+ def matches?(controller)
98
+ @controller = controller
99
+ correct_status_code? || correct_status_code_range?
100
+ end
101
+
102
+ def failure_message
103
+ "Expected #{expectation}"
104
+ end
105
+
106
+ def failure_message_when_negated
107
+ "Did not expect #{expectation}"
108
+ end
109
+
110
+ def description
111
+ "respond with #{@status}"
112
+ end
113
+
114
+ protected
115
+
116
+ def correct_status_code?
117
+ response_code == @status
118
+ end
119
+
120
+ def correct_status_code_range?
121
+ @status.is_a?(Range) &&
122
+ @status.include?(response_code)
123
+ end
124
+
125
+ def response_code
126
+ @controller.response.response_code
127
+ end
128
+
129
+ def symbol_to_status_code(potential_symbol)
130
+ case potential_symbol
131
+ when :success then 200
132
+ when :redirect then 300..399
133
+ when :missing then 404
134
+ when :error then 500..599
135
+ when Symbol
136
+ ::Rack::Utils.status_code(potential_symbol)
137
+ else
138
+ potential_symbol
139
+ end
140
+ end
141
+
142
+ def expectation
143
+ "response to be a #{@status}, but was #{response_code}"
144
+ end
145
+ end
146
+ end
147
+ end
148
+ end
@@ -0,0 +1,207 @@
1
+ module Shoulda
2
+ module Matchers
3
+ module ActionController
4
+ # The `route` matcher tests that a route resolves to a controller,
5
+ # action, and params; and that the controller, action, and params
6
+ # generates the same route. For an RSpec suite, this is like using a
7
+ # combination of `route_to` and `be_routable`. In a test suite using
8
+ # Minitest + Shoulda, it provides a more expressive syntax over
9
+ # `assert_routing`.
10
+ #
11
+ # You can use this matcher either in a controller test case or in a
12
+ # routing test case. For instance, given these routes:
13
+ #
14
+ # My::Application.routes.draw do
15
+ # get '/posts', to: 'posts#index'
16
+ # get '/posts/:id', to: 'posts#show'
17
+ # end
18
+ #
19
+ # You could choose to write tests for these routes alongside other tests
20
+ # for PostsController:
21
+ #
22
+ # class PostsController < ApplicationController
23
+ # # ...
24
+ # end
25
+ #
26
+ # # RSpec
27
+ # RSpec.describe PostsController, type: :controller do
28
+ # it { should route(:get, '/posts').to(action: :index) }
29
+ # it { should route(:get, '/posts/1').to(action: :show, id: 1) }
30
+ # end
31
+ #
32
+ # # Minitest (Shoulda)
33
+ # class PostsControllerTest < ActionController::TestCase
34
+ # should route(:get, '/posts').to(action: 'index')
35
+ # should route(:get, '/posts/1').to(action: :show, id: 1)
36
+ # end
37
+ #
38
+ # Or you could place the tests along with other route tests:
39
+ #
40
+ # # RSpec
41
+ # describe 'Routing', type: :routing do
42
+ # it do
43
+ # should route(:get, '/posts').
44
+ # to(controller: :posts, action: :index)
45
+ # end
46
+ #
47
+ # it do
48
+ # should route(:get, '/posts/1').
49
+ # to('posts#show', id: 1)
50
+ # end
51
+ # end
52
+ #
53
+ # # Minitest (Shoulda)
54
+ # class RoutesTest < ActionController::IntegrationTest
55
+ # should route(:get, '/posts').
56
+ # to(controller: :posts, action: :index)
57
+ #
58
+ # should route(:get, '/posts/1').
59
+ # to('posts#show', id: 1)
60
+ # end
61
+ #
62
+ # Notice that in the former case, as we are inside of a test case for
63
+ # PostsController, we do not have to specify that the routes resolve to
64
+ # this controller. In the latter case we specify this using the
65
+ # `controller` key passed to the `to` qualifier.
66
+ #
67
+ # #### Specifying a port
68
+ #
69
+ # If the route you're testing has a constraint on it that limits the route
70
+ # to a particular port, you can specify it by passing a `port` option to
71
+ # the matcher:
72
+ #
73
+ # class PortConstraint
74
+ # def initialize(port)
75
+ # @port = port
76
+ # end
77
+ #
78
+ # def matches?(request)
79
+ # request.port == @port
80
+ # end
81
+ # end
82
+ #
83
+ # My::Application.routes.draw do
84
+ # get '/posts',
85
+ # to: 'posts#index',
86
+ # constraints: PortConstraint.new(12345)
87
+ # end
88
+ #
89
+ # # RSpec
90
+ # describe 'Routing', type: :routing do
91
+ # it do
92
+ # should route(:get, '/posts', port: 12345).
93
+ # to('posts#index')
94
+ # end
95
+ # end
96
+ #
97
+ # # Minitest (Shoulda)
98
+ # class RoutesTest < ActionController::IntegrationTest
99
+ # should route(:get, '/posts', port: 12345).
100
+ # to('posts#index')
101
+ # end
102
+ #
103
+ # #### Qualifiers
104
+ #
105
+ # ##### to
106
+ #
107
+ # Use `to` to specify the action (along with the controller, if needed)
108
+ # that the route resolves to.
109
+ #
110
+ # `to` takes either keyword arguments (`controller` and `action`) or a
111
+ # string that represents the controller/action pair:
112
+ #
113
+ # route(:get, '/posts').to(action: index)
114
+ # route(:get, '/posts').to(controller: :posts, action: index)
115
+ # route(:get, '/posts').to('posts#index')
116
+ #
117
+ # If there are parameters in your route, then specify those too:
118
+ #
119
+ # route(:get, '/posts/1').to('posts#show', id: 1)
120
+ #
121
+ # You may also specify special parameters such as `:format`:
122
+ #
123
+ # route(:get, '/posts').to('posts#index', format: :json)
124
+ #
125
+ # @return [RouteMatcher]
126
+ #
127
+ def route(method, path, port: nil)
128
+ RouteMatcher.new(self, method, path, port:)
129
+ end
130
+
131
+ # @private
132
+ class RouteMatcher
133
+ def initialize(context, method, path, port: nil)
134
+ @context = context
135
+ @method = method
136
+ @path = add_port_to_path(normalize_path(path), port)
137
+ @params = {}
138
+ end
139
+
140
+ attr_reader :failure_message
141
+
142
+ def to(*args)
143
+ @params = RouteParams.new(args).normalize
144
+ self
145
+ end
146
+
147
+ def in_context(context)
148
+ @context = context
149
+ self
150
+ end
151
+
152
+ def matches?(controller)
153
+ guess_controller_if_necessary(controller)
154
+
155
+ route_recognized?
156
+ end
157
+
158
+ def description
159
+ "route #{method.to_s.upcase} #{path} to/from #{params.inspect}"
160
+ end
161
+
162
+ def failure_message_when_negated
163
+ "Didn't expect to #{description}"
164
+ end
165
+
166
+ private
167
+
168
+ attr_reader :context, :method, :path, :params
169
+
170
+ def normalize_path(path)
171
+ if path.start_with?('/')
172
+ path
173
+ else
174
+ "/#{path}"
175
+ end
176
+ end
177
+
178
+ def add_port_to_path(path, port)
179
+ if port
180
+ "https://example.com:#{port}" + path
181
+ else
182
+ path
183
+ end
184
+ end
185
+
186
+ def guess_controller_if_necessary(controller)
187
+ params[:controller] ||= controller.controller_path
188
+ end
189
+
190
+ def route_recognized?
191
+ context.send(
192
+ :assert_routing,
193
+ { method:, path: },
194
+ params,
195
+ )
196
+ true
197
+ rescue ::ActionController::RoutingError => e
198
+ @failure_message = e.message
199
+ false
200
+ rescue Shoulda::Matchers.assertion_exception_class => e
201
+ @failure_message = e.message
202
+ false
203
+ end
204
+ end
205
+ end
206
+ end
207
+ end
@@ -0,0 +1,62 @@
1
+ module Shoulda
2
+ module Matchers
3
+ module ActionController
4
+ # @private
5
+ class RouteParams
6
+ PARAMS_TO_SYMBOLIZE = %i{format}.freeze
7
+
8
+ def initialize(args)
9
+ @args = args
10
+ end
11
+
12
+ def normalize
13
+ if controller_and_action_given_as_string?
14
+ extract_params_from_string
15
+ else
16
+ stringify_params
17
+ end
18
+ end
19
+
20
+ protected
21
+
22
+ attr_reader :args
23
+
24
+ def controller_and_action_given_as_string?
25
+ args[0].is_a?(String)
26
+ end
27
+
28
+ def extract_params_from_string
29
+ controller, action = args[0].split('#')
30
+ params = (args[1] || {}).merge!(controller:, action:)
31
+ normalize_values(params)
32
+ end
33
+
34
+ def stringify_params
35
+ normalize_values(args[0])
36
+ end
37
+
38
+ def normalize_values(hash)
39
+ hash.each_with_object({}) do |(key, value), hash_copy|
40
+ hash_copy[key] = symbolize_or_stringify(key, value)
41
+ end
42
+ end
43
+
44
+ def symbolize_or_stringify(key, value)
45
+ if PARAMS_TO_SYMBOLIZE.include?(key)
46
+ value.to_sym
47
+ else
48
+ stringify(value)
49
+ end
50
+ end
51
+
52
+ def stringify(value)
53
+ if value.is_a?(Array)
54
+ value.map(&:to_param)
55
+ else
56
+ value.to_param
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,34 @@
1
+ module Shoulda
2
+ module Matchers
3
+ module ActionController
4
+ # @private
5
+ class SessionStore
6
+ attr_accessor :controller
7
+
8
+ def name
9
+ 'session'
10
+ end
11
+
12
+ def has_key?(key)
13
+ session.key?(key)
14
+ end
15
+
16
+ def has_value?(expected_value)
17
+ session.values.any? do |actual_value|
18
+ expected_value === actual_value
19
+ end
20
+ end
21
+
22
+ def empty?
23
+ session.empty?
24
+ end
25
+
26
+ private
27
+
28
+ def session
29
+ controller.session
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end