grape 1.8.0 → 2.1.0

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 (210) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +65 -1
  3. data/README.md +377 -334
  4. data/UPGRADING.md +231 -6
  5. data/grape.gemspec +6 -10
  6. data/lib/grape/api/instance.rb +13 -10
  7. data/lib/grape/api.rb +17 -8
  8. data/lib/grape/content_types.rb +0 -2
  9. data/lib/grape/cookies.rb +2 -1
  10. data/lib/grape/dry_types.rb +0 -2
  11. data/lib/grape/dsl/desc.rb +23 -21
  12. data/lib/grape/dsl/headers.rb +1 -1
  13. data/lib/grape/dsl/inside_route.rb +47 -22
  14. data/lib/grape/dsl/parameters.rb +4 -3
  15. data/lib/grape/dsl/routing.rb +20 -4
  16. data/lib/grape/dsl/validations.rb +13 -0
  17. data/lib/grape/endpoint.rb +15 -10
  18. data/lib/grape/{util/env.rb → env.rb} +0 -5
  19. data/lib/grape/error_formatter/txt.rb +11 -10
  20. data/lib/grape/exceptions/base.rb +3 -3
  21. data/lib/grape/exceptions/missing_group_type.rb +1 -1
  22. data/lib/grape/exceptions/unsupported_group_type.rb +1 -1
  23. data/lib/grape/exceptions/validation.rb +0 -2
  24. data/lib/grape/exceptions/validation_array_errors.rb +1 -0
  25. data/lib/grape/exceptions/validation_errors.rb +1 -3
  26. data/lib/grape/extensions/hash.rb +5 -1
  27. data/lib/grape/http/headers.rb +18 -24
  28. data/lib/grape/{util/json.rb → json.rb} +1 -3
  29. data/lib/grape/locale/en.yml +3 -0
  30. data/lib/grape/middleware/auth/base.rb +0 -2
  31. data/lib/grape/middleware/auth/dsl.rb +0 -2
  32. data/lib/grape/middleware/auth/strategies.rb +1 -2
  33. data/lib/grape/middleware/base.rb +0 -2
  34. data/lib/grape/middleware/error.rb +55 -50
  35. data/lib/grape/middleware/formatter.rb +21 -18
  36. data/lib/grape/middleware/globals.rb +1 -3
  37. data/lib/grape/middleware/stack.rb +2 -3
  38. data/lib/grape/middleware/versioner/accept_version_header.rb +0 -2
  39. data/lib/grape/middleware/versioner/header.rb +17 -163
  40. data/lib/grape/middleware/versioner/param.rb +2 -4
  41. data/lib/grape/middleware/versioner/path.rb +1 -3
  42. data/lib/grape/namespace.rb +3 -4
  43. data/lib/grape/path.rb +24 -29
  44. data/lib/grape/railtie.rb +9 -0
  45. data/lib/grape/request.rb +3 -5
  46. data/lib/grape/router/base_route.rb +39 -0
  47. data/lib/grape/router/greedy_route.rb +20 -0
  48. data/lib/grape/router/pattern.rb +39 -30
  49. data/lib/grape/router/route.rb +22 -59
  50. data/lib/grape/router.rb +30 -36
  51. data/lib/grape/util/accept/header.rb +19 -0
  52. data/lib/grape/util/accept_header_handler.rb +105 -0
  53. data/lib/grape/util/base_inheritable.rb +4 -4
  54. data/lib/grape/util/cache.rb +0 -3
  55. data/lib/grape/util/endpoint_configuration.rb +1 -1
  56. data/lib/grape/util/header.rb +13 -0
  57. data/lib/grape/util/inheritable_values.rb +0 -2
  58. data/lib/grape/util/lazy/block.rb +29 -0
  59. data/lib/grape/util/lazy/object.rb +45 -0
  60. data/lib/grape/util/lazy/value.rb +38 -0
  61. data/lib/grape/util/lazy/value_array.rb +21 -0
  62. data/lib/grape/util/lazy/value_enumerable.rb +34 -0
  63. data/lib/grape/util/lazy/value_hash.rb +21 -0
  64. data/lib/grape/util/media_type.rb +70 -0
  65. data/lib/grape/util/reverse_stackable_values.rb +1 -6
  66. data/lib/grape/util/stackable_values.rb +1 -6
  67. data/lib/grape/util/strict_hash_configuration.rb +3 -3
  68. data/lib/grape/validations/attributes_doc.rb +38 -36
  69. data/lib/grape/validations/contract_scope.rb +71 -0
  70. data/lib/grape/validations/params_scope.rb +10 -9
  71. data/lib/grape/validations/types/array_coercer.rb +0 -2
  72. data/lib/grape/validations/types/build_coercer.rb +69 -71
  73. data/lib/grape/validations/types/dry_type_coercer.rb +1 -11
  74. data/lib/grape/validations/types/json.rb +0 -2
  75. data/lib/grape/validations/types/primitive_coercer.rb +0 -2
  76. data/lib/grape/validations/types/set_coercer.rb +0 -3
  77. data/lib/grape/validations/types.rb +0 -3
  78. data/lib/grape/validations/validators/base.rb +2 -1
  79. data/lib/grape/validations/validators/default_validator.rb +5 -1
  80. data/lib/grape/validations/validators/length_validator.rb +42 -0
  81. data/lib/grape/validations/validators/values_validator.rb +8 -3
  82. data/lib/grape/validations.rb +3 -7
  83. data/lib/grape/version.rb +1 -1
  84. data/lib/grape/{util/xml.rb → xml.rb} +1 -1
  85. data/lib/grape.rb +38 -269
  86. metadata +33 -274
  87. data/lib/grape/eager_load.rb +0 -20
  88. data/lib/grape/middleware/versioner/parse_media_type_patch.rb +0 -24
  89. data/lib/grape/router/attribute_translator.rb +0 -63
  90. data/lib/grape/util/lazy_block.rb +0 -27
  91. data/lib/grape/util/lazy_object.rb +0 -43
  92. data/lib/grape/util/lazy_value.rb +0 -91
  93. data/spec/grape/api/custom_validations_spec.rb +0 -213
  94. data/spec/grape/api/deeply_included_options_spec.rb +0 -56
  95. data/spec/grape/api/defines_boolean_in_params_spec.rb +0 -38
  96. data/spec/grape/api/documentation_spec.rb +0 -59
  97. data/spec/grape/api/inherited_helpers_spec.rb +0 -114
  98. data/spec/grape/api/instance_spec.rb +0 -103
  99. data/spec/grape/api/invalid_format_spec.rb +0 -45
  100. data/spec/grape/api/namespace_parameters_in_route_spec.rb +0 -38
  101. data/spec/grape/api/nested_helpers_spec.rb +0 -50
  102. data/spec/grape/api/optional_parameters_in_route_spec.rb +0 -43
  103. data/spec/grape/api/parameters_modification_spec.rb +0 -41
  104. data/spec/grape/api/patch_method_helpers_spec.rb +0 -79
  105. data/spec/grape/api/recognize_path_spec.rb +0 -21
  106. data/spec/grape/api/required_parameters_in_route_spec.rb +0 -37
  107. data/spec/grape/api/required_parameters_with_invalid_method_spec.rb +0 -26
  108. data/spec/grape/api/routes_with_requirements_spec.rb +0 -59
  109. data/spec/grape/api/shared_helpers_exactly_one_of_spec.rb +0 -41
  110. data/spec/grape/api/shared_helpers_spec.rb +0 -36
  111. data/spec/grape/api_remount_spec.rb +0 -509
  112. data/spec/grape/api_spec.rb +0 -4356
  113. data/spec/grape/dsl/callbacks_spec.rb +0 -45
  114. data/spec/grape/dsl/desc_spec.rb +0 -98
  115. data/spec/grape/dsl/headers_spec.rb +0 -62
  116. data/spec/grape/dsl/helpers_spec.rb +0 -100
  117. data/spec/grape/dsl/inside_route_spec.rb +0 -531
  118. data/spec/grape/dsl/logger_spec.rb +0 -24
  119. data/spec/grape/dsl/middleware_spec.rb +0 -60
  120. data/spec/grape/dsl/parameters_spec.rb +0 -180
  121. data/spec/grape/dsl/request_response_spec.rb +0 -225
  122. data/spec/grape/dsl/routing_spec.rb +0 -275
  123. data/spec/grape/dsl/settings_spec.rb +0 -261
  124. data/spec/grape/dsl/validations_spec.rb +0 -55
  125. data/spec/grape/endpoint/declared_spec.rb +0 -846
  126. data/spec/grape/endpoint_spec.rb +0 -1085
  127. data/spec/grape/entity_spec.rb +0 -336
  128. data/spec/grape/exceptions/base_spec.rb +0 -81
  129. data/spec/grape/exceptions/body_parse_errors_spec.rb +0 -185
  130. data/spec/grape/exceptions/invalid_accept_header_spec.rb +0 -358
  131. data/spec/grape/exceptions/invalid_formatter_spec.rb +0 -15
  132. data/spec/grape/exceptions/invalid_response_spec.rb +0 -11
  133. data/spec/grape/exceptions/invalid_versioner_option_spec.rb +0 -15
  134. data/spec/grape/exceptions/missing_group_type_spec.rb +0 -17
  135. data/spec/grape/exceptions/missing_mime_type_spec.rb +0 -17
  136. data/spec/grape/exceptions/missing_option_spec.rb +0 -15
  137. data/spec/grape/exceptions/unknown_options_spec.rb +0 -15
  138. data/spec/grape/exceptions/unknown_validator_spec.rb +0 -15
  139. data/spec/grape/exceptions/unsupported_group_type_spec.rb +0 -19
  140. data/spec/grape/exceptions/validation_errors_spec.rb +0 -92
  141. data/spec/grape/exceptions/validation_spec.rb +0 -19
  142. data/spec/grape/extensions/param_builders/hash_spec.rb +0 -83
  143. data/spec/grape/extensions/param_builders/hash_with_indifferent_access_spec.rb +0 -105
  144. data/spec/grape/extensions/param_builders/hashie/mash_spec.rb +0 -79
  145. data/spec/grape/grape_spec.rb +0 -9
  146. data/spec/grape/integration/global_namespace_function_spec.rb +0 -29
  147. data/spec/grape/integration/rack_sendfile_spec.rb +0 -48
  148. data/spec/grape/integration/rack_spec.rb +0 -51
  149. data/spec/grape/loading_spec.rb +0 -44
  150. data/spec/grape/middleware/auth/base_spec.rb +0 -31
  151. data/spec/grape/middleware/auth/dsl_spec.rb +0 -60
  152. data/spec/grape/middleware/auth/strategies_spec.rb +0 -120
  153. data/spec/grape/middleware/base_spec.rb +0 -221
  154. data/spec/grape/middleware/error_spec.rb +0 -85
  155. data/spec/grape/middleware/exception_spec.rb +0 -294
  156. data/spec/grape/middleware/formatter_spec.rb +0 -461
  157. data/spec/grape/middleware/globals_spec.rb +0 -30
  158. data/spec/grape/middleware/stack_spec.rb +0 -155
  159. data/spec/grape/middleware/versioner/accept_version_header_spec.rb +0 -122
  160. data/spec/grape/middleware/versioner/header_spec.rb +0 -345
  161. data/spec/grape/middleware/versioner/param_spec.rb +0 -171
  162. data/spec/grape/middleware/versioner/path_spec.rb +0 -62
  163. data/spec/grape/middleware/versioner_spec.rb +0 -21
  164. data/spec/grape/named_api_spec.rb +0 -19
  165. data/spec/grape/parser_spec.rb +0 -86
  166. data/spec/grape/path_spec.rb +0 -252
  167. data/spec/grape/presenters/presenter_spec.rb +0 -71
  168. data/spec/grape/request_spec.rb +0 -126
  169. data/spec/grape/util/inheritable_setting_spec.rb +0 -242
  170. data/spec/grape/util/inheritable_values_spec.rb +0 -79
  171. data/spec/grape/util/reverse_stackable_values_spec.rb +0 -134
  172. data/spec/grape/util/stackable_values_spec.rb +0 -128
  173. data/spec/grape/util/strict_hash_configuration_spec.rb +0 -38
  174. data/spec/grape/validations/attributes_doc_spec.rb +0 -153
  175. data/spec/grape/validations/instance_behaivour_spec.rb +0 -43
  176. data/spec/grape/validations/multiple_attributes_iterator_spec.rb +0 -38
  177. data/spec/grape/validations/params_scope_spec.rb +0 -1420
  178. data/spec/grape/validations/single_attribute_iterator_spec.rb +0 -56
  179. data/spec/grape/validations/types/array_coercer_spec.rb +0 -33
  180. data/spec/grape/validations/types/primitive_coercer_spec.rb +0 -150
  181. data/spec/grape/validations/types/set_coercer_spec.rb +0 -32
  182. data/spec/grape/validations/types_spec.rb +0 -111
  183. data/spec/grape/validations/validators/all_or_none_spec.rb +0 -162
  184. data/spec/grape/validations/validators/allow_blank_spec.rb +0 -575
  185. data/spec/grape/validations/validators/at_least_one_of_spec.rb +0 -205
  186. data/spec/grape/validations/validators/base_spec.rb +0 -38
  187. data/spec/grape/validations/validators/coerce_spec.rb +0 -1261
  188. data/spec/grape/validations/validators/default_spec.rb +0 -463
  189. data/spec/grape/validations/validators/exactly_one_of_spec.rb +0 -233
  190. data/spec/grape/validations/validators/except_values_spec.rb +0 -192
  191. data/spec/grape/validations/validators/mutual_exclusion_spec.rb +0 -214
  192. data/spec/grape/validations/validators/presence_spec.rb +0 -315
  193. data/spec/grape/validations/validators/regexp_spec.rb +0 -161
  194. data/spec/grape/validations/validators/same_as_spec.rb +0 -57
  195. data/spec/grape/validations/validators/values_spec.rb +0 -733
  196. data/spec/grape/validations/validators/zh-CN.yml +0 -10
  197. data/spec/grape/validations_spec.rb +0 -2030
  198. data/spec/integration/eager_load/eager_load_spec.rb +0 -15
  199. data/spec/integration/multi_json/json_spec.rb +0 -7
  200. data/spec/integration/multi_xml/xml_spec.rb +0 -7
  201. data/spec/shared/deprecated_class_examples.rb +0 -16
  202. data/spec/shared/versioning_examples.rb +0 -215
  203. data/spec/spec_helper.rb +0 -52
  204. data/spec/support/basic_auth_encode_helpers.rb +0 -11
  205. data/spec/support/chunks.rb +0 -14
  206. data/spec/support/content_type_helpers.rb +0 -15
  207. data/spec/support/endpoint_faker.rb +0 -25
  208. data/spec/support/file_streamer.rb +0 -13
  209. data/spec/support/integer_helpers.rb +0 -13
  210. data/spec/support/versioned_helpers.rb +0 -55
@@ -1,153 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- describe Grape::Validations::ParamsScope::AttributesDoc do
4
- shared_examples 'an optional doc attribute' do |attr|
5
- it 'does not mention it' do
6
- expected_opts.delete(attr)
7
- validations.delete(attr)
8
-
9
- expect(subject.first['nested[engine_age]']).not_to have_key(attr)
10
- end
11
- end
12
-
13
- let(:api) { Class.new(Grape::API::Instance) }
14
- let(:scope) do
15
- params = nil
16
- api_instance = api
17
-
18
- # just to get nested params
19
- Grape::Validations::ParamsScope.new(type: Hash, api: api) do
20
- params = Grape::Validations::ParamsScope.new(element: 'nested',
21
- type: Hash,
22
- api: api_instance,
23
- parent: self)
24
- end
25
-
26
- params
27
- end
28
-
29
- let(:validations) do
30
- {
31
- presence: true,
32
- desc: 'Age of...',
33
- documentation: 'Age is...',
34
- default: 1
35
- }
36
- end
37
-
38
- let(:doc) { described_class.new(api, scope) }
39
-
40
- describe '#extract_details' do
41
- subject { doc.extract_details(validations) }
42
-
43
- it 'cleans up doc attrs needed for documentation only' do
44
- subject
45
-
46
- expect(validations[:desc]).to be_nil
47
- expect(validations[:documentation]).to be_nil
48
- end
49
-
50
- it 'does not clean up doc attrs mandatory for validators' do
51
- subject
52
-
53
- expect(validations[:presence]).not_to be_nil
54
- expect(validations[:default]).not_to be_nil
55
- end
56
-
57
- it 'tells when attributes are required' do
58
- subject
59
-
60
- expect(doc.required).to be_truthy
61
- end
62
- end
63
-
64
- describe '#document' do
65
- subject do
66
- doc.extract_details validations
67
- doc.document attrs
68
- end
69
-
70
- let(:attrs) { %w[engine_age car_age] }
71
- let(:valid_values) { [1, 3, 5, 8] }
72
-
73
- let!(:expected_opts) do
74
- {
75
- required: true,
76
- desc: validations[:desc],
77
- documentation: validations[:documentation],
78
- default: validations[:default],
79
- type: 'Integer',
80
- values: valid_values
81
- }
82
- end
83
-
84
- before do
85
- doc.type = Integer
86
- doc.values = valid_values
87
- end
88
-
89
- context 'documentation is enabled' do
90
- subject do
91
- super()
92
- api.namespace_stackable(:params)
93
- end
94
-
95
- it 'documents attributes' do
96
- expect(subject.first).to eq('nested[engine_age]' => expected_opts,
97
- 'nested[car_age]' => expected_opts)
98
- end
99
-
100
- it_behaves_like 'an optional doc attribute', :default
101
- it_behaves_like 'an optional doc attribute', :documentation
102
- it_behaves_like 'an optional doc attribute', :desc
103
- it_behaves_like 'an optional doc attribute', :type do
104
- before { doc.type = nil }
105
- end
106
- it_behaves_like 'an optional doc attribute', :values do
107
- before { doc.values = nil }
108
- end
109
-
110
- context 'false as a default value' do
111
- before { validations[:default] = false }
112
-
113
- it 'is still documented' do
114
- doc = subject.first['nested[engine_age]']
115
-
116
- expect(doc).to have_key(:default)
117
- expect(doc[:default]).to be(false)
118
- end
119
- end
120
-
121
- context 'nil as a default value' do
122
- before { validations[:default] = nil }
123
-
124
- it 'is still documented' do
125
- doc = subject.first['nested[engine_age]']
126
-
127
- expect(doc).to have_key(:default)
128
- expect(doc[:default]).to be_nil
129
- end
130
- end
131
-
132
- context 'the description key instead of desc' do
133
- let!(:desc) { validations.delete(:desc) }
134
-
135
- before { validations[:description] = desc }
136
-
137
- it 'adds the given description' do
138
- expect(subject.first['nested[engine_age]'][:desc]).to eq(desc)
139
- end
140
- end
141
- end
142
-
143
- context 'documentation is disabled' do
144
- before { api.namespace_inheritable :do_not_document, true }
145
-
146
- it 'does not document attributes' do
147
- subject
148
-
149
- expect(api.namespace_stackable(:params)).to eq([])
150
- end
151
- end
152
- end
153
- end
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- describe 'Validator with instance variables' do
4
- let(:validator_type) do
5
- Class.new(Grape::Validations::Validators::Base) do
6
- def validate_param!(_attr_name, _params)
7
- if instance_variable_defined?(:@instance_variable) && @instance_variable
8
- raise Grape::Exceptions::Validation.new(params: ['params'],
9
- message: 'This should never happen')
10
- end
11
- @instance_variable = true
12
- end
13
- end
14
- end
15
- let(:app) do
16
- Class.new(Grape::API) do
17
- params do
18
- optional :param_to_validate, instance_validator: true
19
- optional :another_param_to_validate, instance_validator: true
20
- end
21
- get do
22
- 'noop'
23
- end
24
- end
25
- end
26
-
27
- before do
28
- Grape::Validations.register_validator('instance_validator', validator_type)
29
- end
30
-
31
- after do
32
- Grape::Validations.deregister_validator('instance_validator')
33
- end
34
-
35
- it 'passes validation every time' do
36
- expect(validator_type).to receive(:new).exactly(4).times.and_call_original
37
-
38
- 2.times do
39
- get '/', param_to_validate: 'value', another_param_to_validate: 'value'
40
- expect(last_response.status).to eq 200
41
- end
42
- end
43
- end
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- describe Grape::Validations::MultipleAttributesIterator do
4
- describe '#each' do
5
- subject(:iterator) { described_class.new(validator, scope, params) }
6
-
7
- let(:scope) { Grape::Validations::ParamsScope.new(api: Class.new(Grape::API)) }
8
- let(:validator) { double(attrs: %i[first second third]) }
9
-
10
- context 'when params is a hash' do
11
- let(:params) do
12
- { first: 'string', second: 'string' }
13
- end
14
-
15
- it 'yields the whole params hash without the list of attrs' do
16
- expect { |b| iterator.each(&b) }.to yield_with_args(params)
17
- end
18
- end
19
-
20
- context 'when params is an array' do
21
- let(:params) do
22
- [{ first: 'string1', second: 'string1' }, { first: 'string2', second: 'string2' }]
23
- end
24
-
25
- it 'yields each element of the array without the list of attrs' do
26
- expect { |b| iterator.each(&b) }.to yield_successive_args(params[0], params[1])
27
- end
28
- end
29
-
30
- context 'when params is empty optional placeholder' do
31
- let(:params) { [Grape::DSL::Parameters::EmptyOptionalValue] }
32
-
33
- it 'does not yield it' do
34
- expect { |b| iterator.each(&b) }.to yield_successive_args
35
- end
36
- end
37
- end
38
- end