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,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- describe Grape::Middleware::Versioner do
4
- let(:klass) { described_class }
5
-
6
- it 'recognizes :path' do
7
- expect(klass.using(:path)).to eq(Grape::Middleware::Versioner::Path)
8
- end
9
-
10
- it 'recognizes :header' do
11
- expect(klass.using(:header)).to eq(Grape::Middleware::Versioner::Header)
12
- end
13
-
14
- it 'recognizes :param' do
15
- expect(klass.using(:param)).to eq(Grape::Middleware::Versioner::Param)
16
- end
17
-
18
- it 'recognizes :accept_version_header' do
19
- expect(klass.using(:accept_version_header)).to eq(Grape::Middleware::Versioner::AcceptVersionHeader)
20
- end
21
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- describe 'A named API' do
4
- subject(:api_name) { NamedAPI.endpoints.last.options[:for].to_s }
5
-
6
- let(:api) do
7
- Class.new(Grape::API) do
8
- get 'test' do
9
- 'response'
10
- end
11
- end
12
- end
13
-
14
- before { stub_const('NamedAPI', api) }
15
-
16
- it 'can access the name of the API' do
17
- expect(api_name).to eq 'NamedAPI'
18
- end
19
- end
@@ -1,86 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- describe Grape::Parser do
4
- subject { described_class }
5
-
6
- describe '.builtin_parsers' do
7
- it 'returns an instance of Hash' do
8
- expect(subject.builtin_parsers).to be_an_instance_of(Hash)
9
- end
10
-
11
- it 'includes json and xml parsers by default' do
12
- expect(subject.builtin_parsers).to include(json: Grape::Parser::Json, xml: Grape::Parser::Xml)
13
- end
14
- end
15
-
16
- describe '.parsers' do
17
- it 'returns an instance of Hash' do
18
- expect(subject.parsers(**{})).to be_an_instance_of(Hash)
19
- end
20
-
21
- it 'includes built-in parsers' do
22
- expect(subject.parsers(**{})).to include(subject.builtin_parsers)
23
- end
24
-
25
- context 'with :parsers option' do
26
- let(:parsers) { { customized: Class.new } }
27
-
28
- it 'includes passed :parsers values' do
29
- expect(subject.parsers(parsers: parsers)).to include(parsers)
30
- end
31
- end
32
-
33
- context 'with added parser by using `register` keyword' do
34
- let(:added_parser) { Class.new }
35
-
36
- before { subject.register :added, added_parser }
37
-
38
- it 'includes added parser' do
39
- expect(subject.parsers(**{})).to include(added: added_parser)
40
- end
41
- end
42
- end
43
-
44
- describe '.parser_for' do
45
- let(:options) { {} }
46
-
47
- it 'calls .parsers' do
48
- expect(subject).to receive(:parsers).with(any_args).and_return(subject.builtin_parsers)
49
- subject.parser_for(:json, **options)
50
- end
51
-
52
- it 'returns parser correctly' do
53
- expect(subject.parser_for(:json)).to eq(Grape::Parser::Json)
54
- end
55
-
56
- context 'when parser is available' do
57
- before { subject.register :customized_json, Grape::Parser::Json }
58
-
59
- it 'returns registered parser if available' do
60
- expect(subject.parser_for(:customized_json)).to eq(Grape::Parser::Json)
61
- end
62
- end
63
-
64
- context 'when parser is an instance of Symbol' do
65
- before do
66
- allow(subject).to receive(:foo).and_return(:bar)
67
- subject.register :foo, :foo
68
- end
69
-
70
- it 'returns an instance of Method' do
71
- expect(subject.parser_for(:foo)).to be_an_instance_of(Method)
72
- end
73
-
74
- it 'returns object which can be called' do
75
- method = subject.parser_for(:foo)
76
- expect(method.call).to eq(:bar)
77
- end
78
- end
79
-
80
- context 'when parser does not exist' do
81
- it 'returns nil' do
82
- expect(subject.parser_for(:undefined)).to be_nil
83
- end
84
- end
85
- end
86
- end
@@ -1,252 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Grape
4
- describe Path do
5
- describe '#initialize' do
6
- it 'remembers the path' do
7
- path = described_class.new('/:id', anything, anything)
8
- expect(path.raw_path).to eql('/:id')
9
- end
10
-
11
- it 'remembers the namespace' do
12
- path = described_class.new(anything, '/users', anything)
13
- expect(path.namespace).to eql('/users')
14
- end
15
-
16
- it 'remebers the settings' do
17
- path = described_class.new(anything, anything, foo: 'bar')
18
- expect(path.settings).to eql(foo: 'bar')
19
- end
20
- end
21
-
22
- describe '#mount_path' do
23
- it 'is nil when no mount path setting exists' do
24
- path = described_class.new(anything, anything, {})
25
- expect(path.mount_path).to be_nil
26
- end
27
-
28
- it 'is nil when the mount path is nil' do
29
- path = described_class.new(anything, anything, mount_path: nil)
30
- expect(path.mount_path).to be_nil
31
- end
32
-
33
- it 'splits the mount path' do
34
- path = described_class.new(anything, anything, mount_path: %w[foo bar])
35
- expect(path.mount_path).to eql(%w[foo bar])
36
- end
37
- end
38
-
39
- describe '#root_prefix' do
40
- it 'is nil when no root prefix setting exists' do
41
- path = described_class.new(anything, anything, {})
42
- expect(path.root_prefix).to be_nil
43
- end
44
-
45
- it 'is nil when the mount path is nil' do
46
- path = described_class.new(anything, anything, root_prefix: nil)
47
- expect(path.root_prefix).to be_nil
48
- end
49
-
50
- it 'splits the mount path' do
51
- path = described_class.new(anything, anything, root_prefix: 'hello/world')
52
- expect(path.root_prefix).to eql(%w[hello world])
53
- end
54
- end
55
-
56
- describe '#uses_path_versioning?' do
57
- it 'is false when the version setting is nil' do
58
- path = described_class.new(anything, anything, version: nil)
59
- expect(path.uses_path_versioning?).to be false
60
- end
61
-
62
- it 'is false when the version option is header' do
63
- path = described_class.new(
64
- anything,
65
- anything,
66
- version: 'v1',
67
- version_options: { using: :header }
68
- )
69
-
70
- expect(path.uses_path_versioning?).to be false
71
- end
72
-
73
- it 'is true when the version option is path' do
74
- path = described_class.new(
75
- anything,
76
- anything,
77
- version: 'v1',
78
- version_options: { using: :path }
79
- )
80
-
81
- expect(path.uses_path_versioning?).to be true
82
- end
83
- end
84
-
85
- describe '#namespace?' do
86
- it 'is false when the namespace is nil' do
87
- path = described_class.new(anything, nil, anything)
88
- expect(path).not_to be_namespace
89
- end
90
-
91
- it 'is false when the namespace starts with whitespace' do
92
- path = described_class.new(anything, ' /foo', anything)
93
- expect(path).not_to be_namespace
94
- end
95
-
96
- it 'is false when the namespace is the root path' do
97
- path = described_class.new(anything, '/', anything)
98
- expect(path.namespace?).to be false
99
- end
100
-
101
- it 'is true otherwise' do
102
- path = described_class.new(anything, '/world', anything)
103
- expect(path.namespace?).to be true
104
- end
105
- end
106
-
107
- describe '#path?' do
108
- it 'is false when the path is nil' do
109
- path = described_class.new(nil, anything, anything)
110
- expect(path).not_to be_path
111
- end
112
-
113
- it 'is false when the path starts with whitespace' do
114
- path = described_class.new(' /foo', anything, anything)
115
- expect(path).not_to be_path
116
- end
117
-
118
- it 'is false when the path is the root path' do
119
- path = described_class.new('/', anything, anything)
120
- expect(path.path?).to be false
121
- end
122
-
123
- it 'is true otherwise' do
124
- path = described_class.new('/hello', anything, anything)
125
- expect(path.path?).to be true
126
- end
127
- end
128
-
129
- describe '#path' do
130
- context 'mount_path' do
131
- it 'is not included when it is nil' do
132
- path = described_class.new(nil, nil, mount_path: '/foo/bar')
133
- expect(path.path).to eql '/foo/bar'
134
- end
135
-
136
- it 'is included when it is not nil' do
137
- path = described_class.new(nil, nil, {})
138
- expect(path.path).to eql('/')
139
- end
140
- end
141
-
142
- context 'root_prefix' do
143
- it 'is not included when it is nil' do
144
- path = described_class.new(nil, nil, {})
145
- expect(path.path).to eql('/')
146
- end
147
-
148
- it 'is included after the mount path' do
149
- path = described_class.new(
150
- nil,
151
- nil,
152
- mount_path: '/foo',
153
- root_prefix: '/hello'
154
- )
155
-
156
- expect(path.path).to eql('/foo/hello')
157
- end
158
- end
159
-
160
- it 'uses the namespace after the mount path and root prefix' do
161
- path = described_class.new(
162
- nil,
163
- 'namespace',
164
- mount_path: '/foo',
165
- root_prefix: '/hello'
166
- )
167
-
168
- expect(path.path).to eql('/foo/hello/namespace')
169
- end
170
-
171
- it 'uses the raw path after the namespace' do
172
- path = described_class.new(
173
- 'raw_path',
174
- 'namespace',
175
- mount_path: '/foo',
176
- root_prefix: '/hello'
177
- )
178
-
179
- expect(path.path).to eql('/foo/hello/namespace/raw_path')
180
- end
181
- end
182
-
183
- describe '#suffix' do
184
- context 'when using a specific format' do
185
- it 'accepts specified format' do
186
- path = described_class.new(nil, nil, {})
187
- allow(path).to receive(:uses_specific_format?).and_return(true)
188
- allow(path).to receive(:settings).and_return({ format: :json })
189
-
190
- expect(path.suffix).to eql('(.json)')
191
- end
192
- end
193
-
194
- context 'when path versioning is used' do
195
- it "includes a '/'" do
196
- path = described_class.new(nil, nil, {})
197
- allow(path).to receive(:uses_specific_format?).and_return(false)
198
- allow(path).to receive(:uses_path_versioning?).and_return(true)
199
-
200
- expect(path.suffix).to eql('(/.:format)')
201
- end
202
- end
203
-
204
- context 'when path versioning is not used' do
205
- it "does not include a '/' when the path has a namespace" do
206
- path = described_class.new(nil, 'namespace', {})
207
- allow(path).to receive(:uses_specific_format?).and_return(false)
208
- allow(path).to receive(:uses_path_versioning?).and_return(true)
209
-
210
- expect(path.suffix).to eql('(.:format)')
211
- end
212
-
213
- it "does not include a '/' when the path has a path" do
214
- path = described_class.new('/path', nil, {})
215
- allow(path).to receive(:uses_specific_format?).and_return(false)
216
- allow(path).to receive(:uses_path_versioning?).and_return(true)
217
-
218
- expect(path.suffix).to eql('(.:format)')
219
- end
220
-
221
- it "includes a '/' otherwise" do
222
- path = described_class.new(nil, nil, {})
223
- allow(path).to receive(:uses_specific_format?).and_return(false)
224
- allow(path).to receive(:uses_path_versioning?).and_return(true)
225
-
226
- expect(path.suffix).to eql('(/.:format)')
227
- end
228
- end
229
- end
230
-
231
- describe '#path_with_suffix' do
232
- it 'combines the path and suffix' do
233
- path = described_class.new(nil, nil, {})
234
- allow(path).to receive(:path).and_return('/the/path')
235
- allow(path).to receive(:suffix).and_return('suffix')
236
-
237
- expect(path.path_with_suffix).to eql('/the/pathsuffix')
238
- end
239
-
240
- context 'when using a specific format' do
241
- it 'might have a suffix with specified format' do
242
- path = described_class.new(nil, nil, {})
243
- allow(path).to receive(:path).and_return('/the/path')
244
- allow(path).to receive(:uses_specific_format?).and_return(true)
245
- allow(path).to receive(:settings).and_return({ format: :json })
246
-
247
- expect(path.path_with_suffix).to eql('/the/path(.json)')
248
- end
249
- end
250
- end
251
- end
252
- end
@@ -1,71 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Grape
4
- module Presenters
5
- module PresenterSpec
6
- class Dummy
7
- include Grape::DSL::InsideRoute
8
-
9
- attr_reader :env, :request, :new_settings
10
-
11
- def initialize
12
- @env = {}
13
- @header = {}
14
- @new_settings = { namespace_inheritable: {}, namespace_stackable: {} }
15
- end
16
- end
17
- end
18
-
19
- describe Presenter do
20
- subject { PresenterSpec::Dummy.new }
21
-
22
- describe 'represent' do
23
- let(:object_mock) do
24
- Object.new
25
- end
26
-
27
- it 'represent object' do
28
- expect(described_class.represent(object_mock)).to eq object_mock
29
- end
30
- end
31
-
32
- describe 'present' do
33
- let(:hash_mock) do
34
- { key: :value }
35
- end
36
-
37
- describe 'instance' do
38
- before do
39
- subject.present hash_mock, with: described_class
40
- end
41
-
42
- it 'presents dummy hash' do
43
- expect(subject.body).to eq hash_mock
44
- end
45
- end
46
-
47
- describe 'multiple presenter' do
48
- let(:hash_mock1) do
49
- { key1: :value1 }
50
- end
51
-
52
- let(:hash_mock2) do
53
- { key2: :value2 }
54
- end
55
-
56
- describe 'instance' do
57
- before do
58
- subject.present hash_mock1, with: described_class
59
- subject.present hash_mock2, with: described_class
60
- end
61
-
62
- it 'presents both dummy presenter' do
63
- expect(subject.body[:key1]).to eq hash_mock1[:key1]
64
- expect(subject.body[:key2]).to eq hash_mock2[:key2]
65
- end
66
- end
67
- end
68
- end
69
- end
70
- end
71
- end
@@ -1,126 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Grape
4
- describe Request do
5
- let(:default_method) { 'GET' }
6
- let(:default_params) { {} }
7
- let(:default_options) do
8
- {
9
- method: method,
10
- params: params
11
- }
12
- end
13
- let(:default_env) do
14
- Rack::MockRequest.env_for('/', options)
15
- end
16
- let(:method) { default_method }
17
- let(:params) { default_params }
18
- let(:options) { default_options }
19
- let(:env) { default_env }
20
-
21
- let(:request) do
22
- described_class.new(env)
23
- end
24
-
25
- describe '#params' do
26
- let(:params) do
27
- {
28
- a: '123',
29
- b: 'xyz'
30
- }
31
- end
32
-
33
- it 'by default returns stringified parameter keys' do
34
- expect(request.params).to eq(ActiveSupport::HashWithIndifferentAccess.new('a' => '123', 'b' => 'xyz'))
35
- end
36
-
37
- context 'when build_params_with: Grape::Extensions::Hash::ParamBuilder is specified' do
38
- let(:request) do
39
- described_class.new(env, build_params_with: Grape::Extensions::Hash::ParamBuilder)
40
- end
41
-
42
- it 'returns symbolized params' do
43
- expect(request.params).to eq(a: '123', b: 'xyz')
44
- end
45
- end
46
-
47
- describe 'with grape.routing_args' do
48
- let(:options) do
49
- default_options.merge('grape.routing_args' => routing_args)
50
- end
51
- let(:routing_args) do
52
- {
53
- version: '123',
54
- route_info: '456',
55
- c: 'ccc'
56
- }
57
- end
58
-
59
- it 'cuts version and route_info' do
60
- expect(request.params).to eq(ActiveSupport::HashWithIndifferentAccess.new(a: '123', b: 'xyz', c: 'ccc'))
61
- end
62
- end
63
- end
64
-
65
- describe 'when the build_params_with is set to Hashie' do
66
- subject(:request_params) { described_class.new(env, **opts).params }
67
-
68
- context 'when the API does not include a specific param builder' do
69
- let(:opts) { {} }
70
-
71
- it { is_expected.to be_a(Hash) }
72
- end
73
-
74
- context 'when the API includes a specific param builder' do
75
- let(:opts) { { build_params_with: Grape::Extensions::Hashie::Mash::ParamBuilder } }
76
-
77
- it { is_expected.to be_a(Hashie::Mash) }
78
- end
79
- end
80
-
81
- describe '#headers' do
82
- let(:options) do
83
- default_options.merge(request_headers)
84
- end
85
-
86
- describe 'with http headers in env' do
87
- let(:request_headers) do
88
- {
89
- 'HTTP_X_GRAPE_IS_COOL' => 'yeah'
90
- }
91
- end
92
-
93
- it 'cuts HTTP_ prefix and capitalizes header name words' do
94
- expect(request.headers).to eq('X-Grape-Is-Cool' => 'yeah')
95
- end
96
- end
97
-
98
- describe 'with non-HTTP_* stuff in env' do
99
- let(:request_headers) do
100
- {
101
- 'HTP_X_GRAPE_ENTITY_TOO' => 'but now we are testing Grape'
102
- }
103
- end
104
-
105
- it 'does not include them' do
106
- expect(request.headers).to eq({})
107
- end
108
- end
109
-
110
- describe 'with symbolic header names' do
111
- let(:request_headers) do
112
- {
113
- HTTP_GRAPE_LIKES_SYMBOLIC: 'it is true'
114
- }
115
- end
116
- let(:env) do
117
- default_env.merge(request_headers)
118
- end
119
-
120
- it 'converts them to string' do
121
- expect(request.headers).to eq('Grape-Likes-Symbolic' => 'it is true')
122
- end
123
- end
124
- end
125
- end
126
- end