praxis 2.0.pre.18 → 2.0.pre.19

Sign up to get free protection for your applications and to get access to all the features.
Files changed (235) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +54 -0
  3. data/.simplecov +3 -1
  4. data/.travis.yml +2 -1
  5. data/CHANGELOG.md +6 -0
  6. data/CONTRIBUTING.md +2 -79
  7. data/Gemfile +5 -1
  8. data/Guardfile +6 -4
  9. data/LICENSE +0 -2
  10. data/MAINTAINERS.md +1 -0
  11. data/README.md +15 -22
  12. data/Rakefile +4 -2
  13. data/bin/praxis +55 -58
  14. data/lib/praxis/action_definition/headers_dsl_compiler.rb +5 -6
  15. data/lib/praxis/action_definition.rb +64 -94
  16. data/lib/praxis/api_definition.rb +21 -29
  17. data/lib/praxis/api_general_info.rb +55 -66
  18. data/lib/praxis/application.rb +15 -32
  19. data/lib/praxis/blueprint.rb +64 -73
  20. data/lib/praxis/bootloader.rb +24 -33
  21. data/lib/praxis/bootloader_stages/environment.rb +5 -10
  22. data/lib/praxis/bootloader_stages/file_loader.rb +3 -6
  23. data/lib/praxis/bootloader_stages/plugin_config_load.rb +4 -6
  24. data/lib/praxis/bootloader_stages/plugin_config_prepare.rb +2 -2
  25. data/lib/praxis/bootloader_stages/plugin_loader.rb +3 -7
  26. data/lib/praxis/bootloader_stages/plugin_setup.rb +3 -3
  27. data/lib/praxis/bootloader_stages/routing.rb +5 -8
  28. data/lib/praxis/bootloader_stages/subgroup_loader.rb +2 -10
  29. data/lib/praxis/bootloader_stages/warn_unloaded_files.rb +15 -19
  30. data/lib/praxis/callbacks.rb +12 -11
  31. data/lib/praxis/collection.rb +10 -13
  32. data/lib/praxis/config.rb +17 -28
  33. data/lib/praxis/config_hash.rb +2 -1
  34. data/lib/praxis/controller.rb +7 -6
  35. data/lib/praxis/dispatcher.rb +34 -42
  36. data/lib/praxis/docs/open_api/info_object.rb +11 -8
  37. data/lib/praxis/docs/open_api/media_type_object.rb +18 -17
  38. data/lib/praxis/docs/open_api/operation_object.rb +6 -3
  39. data/lib/praxis/docs/open_api/parameter_object.rb +17 -14
  40. data/lib/praxis/docs/open_api/paths_object.rb +11 -9
  41. data/lib/praxis/docs/open_api/request_body_object.rb +14 -13
  42. data/lib/praxis/docs/open_api/response_object.rb +24 -18
  43. data/lib/praxis/docs/open_api/responses_object.rb +3 -1
  44. data/lib/praxis/docs/open_api/schema_object.rb +16 -16
  45. data/lib/praxis/docs/open_api/server_object.rb +5 -2
  46. data/lib/praxis/docs/open_api/tag_object.rb +6 -3
  47. data/lib/praxis/docs/open_api_generator.rb +92 -95
  48. data/lib/praxis/endpoint_definition.rb +60 -77
  49. data/lib/praxis/error_handler.rb +2 -2
  50. data/lib/praxis/exception.rb +2 -0
  51. data/lib/praxis/exceptions/config.rb +3 -1
  52. data/lib/praxis/exceptions/config_load.rb +2 -0
  53. data/lib/praxis/exceptions/config_validation.rb +3 -1
  54. data/lib/praxis/exceptions/invalid_configuration.rb +3 -1
  55. data/lib/praxis/exceptions/invalid_response.rb +3 -1
  56. data/lib/praxis/exceptions/invalid_trait.rb +3 -1
  57. data/lib/praxis/exceptions/stage_not_found.rb +3 -1
  58. data/lib/praxis/exceptions/validation.rb +4 -3
  59. data/lib/praxis/extensions/attribute_filtering/active_record_filter_query_builder.rb +163 -149
  60. data/lib/praxis/extensions/attribute_filtering/active_record_patches/5x.rb +18 -13
  61. data/lib/praxis/extensions/attribute_filtering/active_record_patches/6_0.rb +13 -9
  62. data/lib/praxis/extensions/attribute_filtering/active_record_patches/6_1_plus.rb +14 -11
  63. data/lib/praxis/extensions/attribute_filtering/active_record_patches.rb +12 -9
  64. data/lib/praxis/extensions/attribute_filtering/filter_tree_node.rb +8 -5
  65. data/lib/praxis/extensions/attribute_filtering/filtering_params.rb +89 -65
  66. data/lib/praxis/extensions/attribute_filtering/filters_parser.rb +68 -62
  67. data/lib/praxis/extensions/attribute_filtering.rb +3 -1
  68. data/lib/praxis/extensions/field_expansion.rb +6 -4
  69. data/lib/praxis/extensions/field_selection/active_record_query_selector.rb +10 -8
  70. data/lib/praxis/extensions/field_selection/field_selector.rb +91 -92
  71. data/lib/praxis/extensions/field_selection/sequel_query_selector.rb +12 -12
  72. data/lib/praxis/extensions/field_selection.rb +3 -1
  73. data/lib/praxis/extensions/pagination/active_record_pagination_handler.rb +6 -4
  74. data/lib/praxis/extensions/pagination/header_generator.rb +16 -11
  75. data/lib/praxis/extensions/pagination/ordering_params.rb +29 -28
  76. data/lib/praxis/extensions/pagination/pagination_handler.rb +44 -42
  77. data/lib/praxis/extensions/pagination/pagination_params.rb +29 -48
  78. data/lib/praxis/extensions/pagination/sequel_pagination_handler.rb +8 -7
  79. data/lib/praxis/extensions/pagination.rb +10 -15
  80. data/lib/praxis/extensions/rails_compat/request_methods.rb +3 -4
  81. data/lib/praxis/extensions/rails_compat.rb +2 -0
  82. data/lib/praxis/extensions/rendering.rb +12 -12
  83. data/lib/praxis/field_expander.rb +8 -9
  84. data/lib/praxis/file_group.rb +8 -12
  85. data/lib/praxis/finalizable.rb +1 -0
  86. data/lib/praxis/handlers/json.rb +5 -2
  87. data/lib/praxis/handlers/plain.rb +2 -1
  88. data/lib/praxis/handlers/www_form.rb +6 -3
  89. data/lib/praxis/handlers/{xml-sample.rb → xml_sample.rb} +26 -22
  90. data/lib/praxis/mapper/active_model_compat.rb +13 -10
  91. data/lib/praxis/mapper/resource.rb +171 -180
  92. data/lib/praxis/mapper/selector_generator.rb +106 -112
  93. data/lib/praxis/mapper/sequel_compat.rb +70 -67
  94. data/lib/praxis/media_type.rb +2 -2
  95. data/lib/praxis/media_type_identifier.rb +26 -22
  96. data/lib/praxis/middleware_app.rb +18 -15
  97. data/lib/praxis/multipart/parser.rb +46 -51
  98. data/lib/praxis/multipart/part.rb +78 -110
  99. data/lib/praxis/notifications.rb +2 -4
  100. data/lib/praxis/plugin.rb +11 -18
  101. data/lib/praxis/plugin_concern.rb +12 -15
  102. data/lib/praxis/plugins/mapper_plugin.rb +15 -13
  103. data/lib/praxis/plugins/pagination_plugin.rb +8 -6
  104. data/lib/praxis/plugins/rails_plugin.rb +33 -28
  105. data/lib/praxis/renderer.rb +11 -15
  106. data/lib/praxis/request.rb +46 -47
  107. data/lib/praxis/request_stages/action.rb +4 -6
  108. data/lib/praxis/request_stages/load_request.rb +2 -4
  109. data/lib/praxis/request_stages/request_stage.rb +19 -23
  110. data/lib/praxis/request_stages/response.rb +4 -6
  111. data/lib/praxis/request_stages/validate.rb +3 -5
  112. data/lib/praxis/request_stages/validate_params_and_headers.rb +15 -16
  113. data/lib/praxis/request_stages/validate_payload.rb +25 -27
  114. data/lib/praxis/request_superclassing.rb +3 -3
  115. data/lib/praxis/resource_definition.rb +1 -0
  116. data/lib/praxis/response.rb +13 -25
  117. data/lib/praxis/response_definition.rb +77 -122
  118. data/lib/praxis/response_template.rb +11 -15
  119. data/lib/praxis/responses/http.rb +23 -44
  120. data/lib/praxis/responses/internal_server_error.rb +18 -21
  121. data/lib/praxis/responses/multipart_ok.rb +4 -9
  122. data/lib/praxis/responses/validation_error.rb +8 -15
  123. data/lib/praxis/route.rb +8 -10
  124. data/lib/praxis/router/rack.rb +13 -7
  125. data/lib/praxis/router/simple.rb +10 -5
  126. data/lib/praxis/router.rb +27 -34
  127. data/lib/praxis/routing_config.rb +52 -29
  128. data/lib/praxis/simple_media_type.rb +5 -8
  129. data/lib/praxis/stage.rb +17 -25
  130. data/lib/praxis/tasks/api_docs.rb +15 -15
  131. data/lib/praxis/tasks/console.rb +3 -1
  132. data/lib/praxis/tasks/environment.rb +2 -0
  133. data/lib/praxis/tasks/routes.rb +26 -24
  134. data/lib/praxis/tasks.rb +3 -1
  135. data/lib/praxis/trait.rb +37 -46
  136. data/lib/praxis/types/fuzzy_hash.rb +13 -14
  137. data/lib/praxis/types/media_type_common.rb +11 -10
  138. data/lib/praxis/types/multipart_array/part_definition.rb +14 -17
  139. data/lib/praxis/types/multipart_array.rb +88 -112
  140. data/lib/praxis/validation_handler.rb +5 -3
  141. data/lib/praxis/version.rb +3 -1
  142. data/lib/praxis.rb +4 -5
  143. data/praxis.gemspec +22 -21
  144. data/spec/functional_spec.rb +40 -52
  145. data/spec/praxis/action_definition_spec.rb +36 -46
  146. data/spec/praxis/api_definition_spec.rb +45 -47
  147. data/spec/praxis/api_general_info_spec.rb +28 -29
  148. data/spec/praxis/application_spec.rb +18 -14
  149. data/spec/praxis/blueprint_spec.rb +33 -34
  150. data/spec/praxis/bootloader_spec.rb +32 -30
  151. data/spec/praxis/callbacks_spec.rb +37 -37
  152. data/spec/praxis/collection_spec.rb +18 -25
  153. data/spec/praxis/config_hash_spec.rb +5 -4
  154. data/spec/praxis/config_spec.rb +27 -26
  155. data/spec/praxis/controller_spec.rb +8 -9
  156. data/spec/praxis/endpoint_definition_spec.rb +25 -32
  157. data/spec/praxis/extensions/attribute_filtering/active_record_filter_query_builder_spec.rb +171 -114
  158. data/spec/praxis/extensions/attribute_filtering/filter_tree_node_spec.rb +22 -21
  159. data/spec/praxis/extensions/attribute_filtering/filtering_params_spec.rb +112 -60
  160. data/spec/praxis/extensions/attribute_filtering/filters_parser_spec.rb +37 -38
  161. data/spec/praxis/extensions/field_expansion_spec.rb +8 -10
  162. data/spec/praxis/extensions/field_selection/active_record_query_selector_spec.rb +14 -13
  163. data/spec/praxis/extensions/field_selection/field_selector_spec.rb +9 -16
  164. data/spec/praxis/extensions/field_selection/sequel_query_selector_spec.rb +50 -49
  165. data/spec/praxis/extensions/pagination/active_record_pagination_handler_spec.rb +32 -31
  166. data/spec/praxis/extensions/rendering_spec.rb +9 -9
  167. data/spec/praxis/extensions/support/spec_resources_active_model.rb +32 -49
  168. data/spec/praxis/extensions/support/spec_resources_sequel.rb +48 -48
  169. data/spec/praxis/field_expander_spec.rb +6 -5
  170. data/spec/praxis/file_group_spec.rb +3 -1
  171. data/spec/praxis/handlers/json_spec.rb +6 -5
  172. data/spec/praxis/mapper/resource_spec.rb +27 -30
  173. data/spec/praxis/mapper/selector_generator_spec.rb +50 -50
  174. data/spec/praxis/media_type_identifier_spec.rb +13 -10
  175. data/spec/praxis/media_type_spec.rb +12 -12
  176. data/spec/praxis/middleware_app_spec.rb +23 -22
  177. data/spec/praxis/multipart/parser_spec.rb +7 -9
  178. data/spec/praxis/notifications_spec.rb +4 -4
  179. data/spec/praxis/plugin_concern_spec.rb +5 -6
  180. data/spec/praxis/renderer_spec.rb +10 -9
  181. data/spec/praxis/request_spec.rb +38 -41
  182. data/spec/praxis/request_stages/action_spec.rb +14 -15
  183. data/spec/praxis/request_stages/request_stage_spec.rb +30 -41
  184. data/spec/praxis/request_stages/validate_spec.rb +3 -1
  185. data/spec/praxis/response_definition_spec.rb +79 -92
  186. data/spec/praxis/response_spec.rb +28 -39
  187. data/spec/praxis/responses/internal_server_error_spec.rb +6 -9
  188. data/spec/praxis/responses/validation_error_spec.rb +17 -18
  189. data/spec/praxis/route_spec.rb +4 -7
  190. data/spec/praxis/router_spec.rb +69 -79
  191. data/spec/praxis/routing_config_spec.rb +15 -14
  192. data/spec/praxis/stage_spec.rb +56 -53
  193. data/spec/praxis/trait_spec.rb +17 -18
  194. data/spec/praxis/types/fuzzy_hash_spec.rb +11 -9
  195. data/spec/praxis/types/multipart_array/part_definition_spec.rb +3 -2
  196. data/spec/praxis/types/multipart_array_spec.rb +33 -48
  197. data/spec/spec_app/app/concerns/authenticated.rb +5 -5
  198. data/spec/spec_app/app/concerns/basic_api.rb +3 -1
  199. data/spec/spec_app/app/concerns/log_wrapper.rb +5 -3
  200. data/spec/spec_app/app/controllers/base_class.rb +6 -5
  201. data/spec/spec_app/app/controllers/instances.rb +31 -34
  202. data/spec/spec_app/app/controllers/volumes.rb +6 -6
  203. data/spec/spec_app/app/responses/multipart.rb +1 -2
  204. data/spec/spec_app/app/responses/other_response.rb +2 -2
  205. data/spec/spec_app/config/environment.rb +19 -6
  206. data/spec/spec_app/config.ru +4 -3
  207. data/spec/spec_app/design/api.rb +13 -15
  208. data/spec/spec_app/design/media_types/instance.rb +5 -5
  209. data/spec/spec_app/design/media_types/volume.rb +2 -1
  210. data/spec/spec_app/design/media_types/volume_snapshot.rb +2 -1
  211. data/spec/spec_app/design/resources/instances.rb +9 -15
  212. data/spec/spec_app/design/resources/volume_snapshots.rb +4 -5
  213. data/spec/spec_app/design/resources/volumes.rb +4 -5
  214. data/spec/spec_helper.rb +11 -13
  215. data/spec/support/be_deep_equal_matcher.rb +5 -0
  216. data/spec/support/spec_authorization_plugin.rb +7 -12
  217. data/spec/support/spec_blueprints.rb +2 -1
  218. data/spec/support/spec_complex_authentication_plugin.rb +17 -34
  219. data/spec/support/spec_endpoint_definitions.rb +2 -3
  220. data/spec/support/spec_media_types.rb +28 -35
  221. data/spec/support/spec_resources.rb +20 -18
  222. data/spec/support/spec_simple_authentication_plugin.rb +5 -9
  223. data/tasks/loader.thor +4 -2
  224. data/tasks/thor/app.rb +7 -5
  225. data/tasks/thor/example.rb +23 -22
  226. data/tasks/thor/model.rb +7 -7
  227. data/tasks/thor/scaffold.rb +23 -23
  228. data/tasks/thor/templates/generator/example_app/app/v1/resources/user.rb +0 -8
  229. data/tasks/thor/templates/generator/scaffold/implementation/resources/item.rb +1 -2
  230. metadata +72 -84
  231. data/MAINTAINERS +0 -2
  232. data/TODO.md +0 -25
  233. data/spec/praxis/api_resource_spec.rb +0 -0
  234. data/spec/praxis/dispatcher_spec.rb +0 -0
  235. data/spec/spec_app/app/responses/bulk_response.rb +0 -0
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Praxis::RequestStages::RequestStage do
4
-
5
6
  let(:controller_class) do
6
7
  Class.new do
7
8
  include Praxis::Controller
@@ -11,15 +12,14 @@ describe Praxis::RequestStages::RequestStage do
11
12
  let(:stage_class) { Class.new(Praxis::RequestStages::RequestStage) }
12
13
 
13
14
  let(:request) { Praxis::Request.new({}) }
14
- let(:controller){ controller_class.new(request) }
15
+ let(:controller) { controller_class.new(request) }
15
16
 
17
+ let(:action) { instance_double('Praxis::ActionDefinition') }
18
+ let(:context) { double('context', controller: controller, action: action) }
16
19
 
17
- let(:action){ instance_double("Praxis::ActionDefinition") }
18
- let(:context){ double("context", controller: controller , action: action) }
19
-
20
- let(:substage_1) { instance_double('Praxis::RequestStage') }
21
- let(:substage_2) { instance_double('Praxis::RequestStage') }
22
- let(:substage_3) { instance_double('Praxis::RequestStage') }
20
+ let(:substage1) { instance_double('Praxis::RequestStage') }
21
+ let(:substage2) { instance_double('Praxis::RequestStage') }
22
+ let(:substage3) { instance_double('Praxis::RequestStage') }
23
23
 
24
24
  let(:before_callbacks) { double('before_callbacks') }
25
25
  let(:after_callbacks) { double('after_callbacks') }
@@ -28,19 +28,18 @@ describe Praxis::RequestStages::RequestStage do
28
28
 
29
29
  subject(:stage) { stage_class.new(:action, context) }
30
30
 
31
-
32
31
  before do
33
32
  # clear any pre-existing callbacks that may have been added by plugins
34
- controller_class.before_callbacks = Hash.new
35
- controller_class.after_callbacks = Hash.new
33
+ controller_class.before_callbacks = ({})
34
+ controller_class.after_callbacks = ({})
36
35
  end
37
36
 
38
37
  context 'for an abstract stage' do
39
38
  subject(:stage) { Praxis::RequestStages::RequestStage.new(:action, context) }
40
39
  it 'raises NotImplementedError for undefined #execute' do
41
- expect {
40
+ expect do
42
41
  stage.execute
43
- }.to raise_error(NotImplementedError,/Subclass must implement Stage#execute/)
42
+ end.to raise_error(NotImplementedError, /Subclass must implement Stage#execute/)
44
43
  end
45
44
  end
46
45
 
@@ -57,16 +56,16 @@ describe Praxis::RequestStages::RequestStage do
57
56
  end
58
57
  end
59
58
 
60
- context "#execute" do
59
+ context '#execute' do
61
60
  before do
62
- stage.stages.push(substage_1, substage_2, substage_3)
61
+ stage.stages.push(substage1, substage2, substage3)
63
62
  end
64
63
 
65
64
  context 'when all stages succeed' do
66
- it "runs them all and returns nil" do
67
- expect(substage_1).to receive(:run).once
68
- expect(substage_2).to receive(:run).once
69
- expect(substage_3).to receive(:run).once
65
+ it 'runs them all and returns nil' do
66
+ expect(substage1).to receive(:run).once
67
+ expect(substage2).to receive(:run).once
68
+ expect(substage3).to receive(:run).once
70
69
  expect(stage.execute).to be(nil)
71
70
  end
72
71
  end
@@ -74,12 +73,12 @@ describe Praxis::RequestStages::RequestStage do
74
73
  context 'when one stage returns a Response' do
75
74
  let(:response) { Praxis::Responses::Ok.new }
76
75
  before do
77
- expect(substage_1).to receive(:run).once
78
- expect(substage_2).to receive(:run).once.and_return(response)
76
+ expect(substage1).to receive(:run).once
77
+ expect(substage2).to receive(:run).once.and_return(response)
79
78
  end
80
79
 
81
- it "runs no further stages after that" do
82
- expect(substage_3).to_not receive(:run)
80
+ it 'runs no further stages after that' do
81
+ expect(substage3).to_not receive(:run)
83
82
  stage.execute
84
83
  end
85
84
 
@@ -88,12 +87,10 @@ describe Praxis::RequestStages::RequestStage do
88
87
 
89
88
  expect(controller.response).to be(response)
90
89
  end
91
-
92
90
  end
93
91
  end
94
92
 
95
- context "#run" do
96
-
93
+ context '#run' do
97
94
  let(:before_callbacks) { double('before_callbacks') }
98
95
  let(:after_callbacks) { double('after_callbacks') }
99
96
 
@@ -113,14 +110,13 @@ describe Praxis::RequestStages::RequestStage do
113
110
  allow(controller_class).to receive(:after_callbacks).once.and_return(controller_after_callbacks)
114
111
  end
115
112
 
116
- it "sets up and executes callbacks" do
113
+ it 'sets up and executes callbacks' do
117
114
  expect(stage).to receive(:execute)
118
115
  expect(stage).to receive(:execute_callbacks).once.with(before_callbacks)
119
116
  expect(stage).to receive(:execute_callbacks).once.with(after_callbacks)
120
117
  expect(stage).to receive(:execute_controller_callbacks).once.with(controller_before_callbacks)
121
118
  expect(stage).to receive(:execute_controller_callbacks).once.with(controller_after_callbacks)
122
119
  end
123
-
124
120
  end
125
121
 
126
122
  context 'when the before execute_controller_callbacks return a Response' do
@@ -131,7 +127,6 @@ describe Praxis::RequestStages::RequestStage do
131
127
  expect(stage).to receive(:execute_controller_callbacks).once.and_return(response)
132
128
  end
133
129
 
134
-
135
130
  it 'does not call "execute"' do
136
131
  expect(stage).to_not receive(:execute)
137
132
  end
@@ -140,22 +135,20 @@ describe Praxis::RequestStages::RequestStage do
140
135
  expect(stage).to_not receive(:after_callbacks)
141
136
  expect(controller_class).to_not receive(:after_callbacks)
142
137
  end
143
-
144
138
  end
145
139
 
146
140
  context 'with substages' do
147
141
  before do
148
- stage.stages.push(substage_1, substage_2, substage_3)
142
+ stage.stages.push(substage1, substage2, substage3)
149
143
  end
150
144
 
151
-
152
145
  context 'when one returns a Response' do
153
146
  let(:response) { Praxis::Responses::Unauthorized.new }
154
147
 
155
148
  before do
156
- expect(substage_1).to receive(:run).once
157
- expect(substage_2).to receive(:run).once.and_return(response)
158
- expect(substage_3).to_not receive(:run)
149
+ expect(substage1).to receive(:run).once
150
+ expect(substage2).to receive(:run).once.and_return(response)
151
+ expect(substage3).to_not receive(:run)
159
152
  end
160
153
 
161
154
  it 'runs no after callbacks (including from the controller) ' do
@@ -165,14 +158,10 @@ describe Praxis::RequestStages::RequestStage do
165
158
 
166
159
  it 'assigns controller.response' do
167
160
  # twice, because we do it once in #execute, and again in #run...
168
- expect(controller).to receive(:response=).
169
- with(response).twice.and_call_original
161
+ expect(controller).to receive(:response=)
162
+ .with(response).twice.and_call_original
170
163
  end
171
-
172
164
  end
173
165
  end
174
166
  end
175
-
176
-
177
-
178
167
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Praxis::RequestStages::Validate do
@@ -19,7 +21,7 @@ describe Praxis::RequestStages::Validate do
19
21
 
20
22
  let(:request) do
21
23
  r = Praxis::Request.new(env)
22
- r.route_params = {id: 1}
24
+ r.route_params = { id: 1 }
23
25
  r.action = action
24
26
  r
25
27
  end
@@ -1,15 +1,17 @@
1
- require "spec_helper"
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
2
4
 
3
5
  describe Praxis::ResponseDefinition do
4
6
  subject(:response_definition) { Praxis::ResponseDefinition.new(name, &block) }
5
7
  let(:name) { 'response_name' }
6
8
 
7
9
  let(:block) do
8
- Proc.new do
10
+ proc do
9
11
  status 200
10
12
  description 'test description'
11
- header( "X-Header", "value", description: 'Very nais header')
12
- header( "Content-Type", "application/some-type" )
13
+ header('X-Header', 'value', description: 'Very nais header')
14
+ header('Content-Type', 'application/some-type')
13
15
  end
14
16
  end
15
17
 
@@ -17,11 +19,10 @@ describe Praxis::ResponseDefinition do
17
19
  its(:description) { should == 'test description' }
18
20
  its(:parts) { should be(nil) }
19
21
  let(:response_status) { 200 }
20
- let(:response_content_type) { "application/some-type" }
21
- let(:response_headers) { { "X-Header" => "value", "Content-Type" => response_content_type, "Location" => '/somewhere/over/the/rainbow'} }
22
-
23
- let(:response) { instance_double("Praxis::Response", status: response_status , headers: response_headers, content_type: response_content_type ) }
22
+ let(:response_content_type) { 'application/some-type' }
23
+ let(:response_headers) { { 'X-Header' => 'value', 'Content-Type' => response_content_type, 'Location' => '/somewhere/over/the/rainbow' } }
24
24
 
25
+ let(:response) { instance_double('Praxis::Response', status: response_status, headers: response_headers, content_type: response_content_type) }
25
26
 
26
27
  context '#media_type' do
27
28
  it 'accepts a MediaType object and returns the media_type that was set' do
@@ -42,11 +43,11 @@ describe Praxis::ResponseDefinition do
42
43
  end
43
44
 
44
45
  it 'should return an error when media_type is not a String or a MediaType' do
45
- expect{ response_definition.media_type Object.new }.to raise_error(Praxis::Exceptions::InvalidConfiguration)
46
+ expect { response_definition.media_type Object.new }.to raise_error(Praxis::Exceptions::InvalidConfiguration)
46
47
  end
47
48
 
48
49
  it 'should return an error when media_type is a Symbol other than :controller_defined' do
49
- expect{ response_definition.media_type :symbol }.to raise_error(Praxis::Exceptions::InvalidConfiguration)
50
+ expect { response_definition.media_type :symbol }.to raise_error(Praxis::Exceptions::InvalidConfiguration)
50
51
  end
51
52
  end
52
53
 
@@ -73,7 +74,7 @@ describe Praxis::ResponseDefinition do
73
74
  end
74
75
 
75
76
  # TODO: Complete/correct the "example" generation when it is done in the ResponseDefinition class
76
- #context 'with media_type set to a MediaType' do
77
+ # context 'with media_type set to a MediaType' do
77
78
  # let(:media_type) { Person }
78
79
  #
79
80
  # let(:expected_context) { "Person-#{name}" }
@@ -87,17 +88,17 @@ describe Praxis::ResponseDefinition do
87
88
  # it 'is rendered in the describe output' do
88
89
  # expect(response_definition.describe[:example]).to eq(example.render)
89
90
  # end
90
- #end
91
+ # end
91
92
  end
92
93
 
93
94
  context '#location' do
94
95
  it 'accepts a String' do
95
- response_definition.location "string_location"
96
- expect(response_definition.location).to eq("string_location")
96
+ response_definition.location 'string_location'
97
+ expect(response_definition.location).to eq('string_location')
97
98
  end
98
99
 
99
100
  it 'accepts a Regex' do
100
- response_definition.location /regex_location/
101
+ response_definition.location(/regex_location/)
101
102
  expect(response_definition.location).to eq(/regex_location/)
102
103
  end
103
104
 
@@ -114,31 +115,30 @@ describe Praxis::ResponseDefinition do
114
115
 
115
116
  subject(:parts) { response_definition.parts }
116
117
 
117
- it{ should be_kind_of(Praxis::ResponseDefinition) }
118
- its('media_type.identifier'){ should == 'application/special' }
119
- its(:name){ should be(:ok) }
120
- its(:status){ should be( 200 ) }
121
-
118
+ it { should be_kind_of(Praxis::ResponseDefinition) }
119
+ its('media_type.identifier') { should == 'application/special' }
120
+ its(:name) { should be(:ok) }
121
+ its(:status) { should be(200) }
122
122
  end
123
123
  context 'without a :like argument, and without a block' do
124
124
  it 'complains' do
125
- expect{
125
+ expect do
126
126
  response_definition.parts media_type: 'application/special'
127
- }.to raise_error(ArgumentError, /needs a :like argument or a block/)
127
+ end.to raise_error(ArgumentError, /needs a :like argument or a block/)
128
128
  end
129
129
  end
130
130
  context 'with a :like argument, and a block' do
131
131
  it 'complains' do
132
- expect{
132
+ expect do
133
133
  response_definition.parts like: :something, media_type: 'application/special' do
134
134
  end
135
- }.to raise_error(ArgumentError, /does not allow :like and a block simultaneously/)
135
+ end.to raise_error(ArgumentError, /does not allow :like and a block simultaneously/)
136
136
  end
137
137
  end
138
138
 
139
139
  context 'with a proc' do
140
140
  let(:the_proc) do
141
- Proc.new do
141
+ proc do
142
142
  status 201
143
143
  media_type 'from_proc'
144
144
  end
@@ -150,10 +150,9 @@ describe Praxis::ResponseDefinition do
150
150
 
151
151
  subject(:parts) { response_definition.parts }
152
152
 
153
- it{ should be_kind_of(Praxis::ResponseDefinition) }
154
- its('media_type.identifier'){ should == 'from_proc' }
155
- its(:status){ should be( 201 ) }
156
-
153
+ it { should be_kind_of(Praxis::ResponseDefinition) }
154
+ its('media_type.identifier') { should == 'from_proc' }
155
+ its(:status) { should be(201) }
157
156
  end
158
157
 
159
158
  context 'with a block' do
@@ -166,10 +165,9 @@ describe Praxis::ResponseDefinition do
166
165
 
167
166
  subject(:parts) { response_definition.parts }
168
167
 
169
- it{ should be_kind_of(Praxis::ResponseDefinition) }
170
- its('media_type.identifier'){ should == 'from_proc' }
171
- its(:status){ should be( 201 ) }
172
-
168
+ it { should be_kind_of(Praxis::ResponseDefinition) }
169
+ its('media_type.identifier') { should == 'from_proc' }
170
+ its(:status) { should be(201) }
173
171
  end
174
172
  end
175
173
  # context '#multipart' do
@@ -217,8 +215,7 @@ describe Praxis::ResponseDefinition do
217
215
 
218
216
  context '#validate' do
219
217
  context 'functional test' do
220
-
221
- it "calls all the validation sub-functions" do
218
+ it 'calls all the validation sub-functions' do
222
219
  expect(response_definition).to receive(:validate_status!).once
223
220
  expect(response_definition).to receive(:validate_headers!).once
224
221
  expect(response_definition).to receive(:validate_content_type!).once
@@ -227,68 +224,64 @@ describe Praxis::ResponseDefinition do
227
224
  end
228
225
 
229
226
  describe 'custom validate_xxx! methods' do
230
-
231
- describe "#validate_status!" do
227
+ describe '#validate_status!' do
232
228
  context 'that is completely valid' do
233
229
  it 'should succeed' do
234
- expect {
230
+ expect do
235
231
  response_definition.validate_status!(response)
236
- }.to_not raise_error
232
+ end.to_not raise_error
237
233
  end
238
234
  end
239
235
 
240
-
241
236
  context 'with internal error' do
242
237
  let(:response_status) { 500 }
243
238
  it 'should raise an error that later gets swallowed' do
244
- expect {
239
+ expect do
245
240
  response_definition.validate_status!(response)
246
- }.to raise_error(Praxis::Exceptions::Validation)
241
+ end.to raise_error(Praxis::Exceptions::Validation)
247
242
  end
248
243
  end
249
-
250
244
  end
251
245
 
252
- describe "#validate_headers!" do
246
+ describe '#validate_headers!' do
253
247
  context 'when there are missing headers' do
254
248
  it 'should raise error' do
255
249
  response_definition.header('X-Unknown', 'test')
256
- expect {
250
+ expect do
257
251
  response_definition.validate_headers!(response)
258
- }.to raise_error(Praxis::Exceptions::Validation)
252
+ end.to raise_error(Praxis::Exceptions::Validation)
259
253
  end
260
254
  end
261
255
  context 'when headers with same names are returned' do
262
256
  it 'a simply required header should not raise error just by being there' do
263
257
  response_definition.header('X-Header', nil)
264
- expect {
258
+ expect do
265
259
  response_definition.validate_headers!(response)
266
- }.to_not raise_error
260
+ end.to_not raise_error
267
261
  end
268
262
  it 'an exact string header should not raise error if it fully matches' do
269
263
  response_definition.header('X-Header', 'value')
270
- expect {
264
+ expect do
271
265
  response_definition.validate_headers!(response)
272
- }.to_not raise_error
266
+ end.to_not raise_error
273
267
  end
274
268
  it 'a regexp header should not raise error if it matches the regexp' do
275
269
  response_definition.header('X-Header', /value/)
276
- expect {
270
+ expect do
277
271
  response_definition.validate_headers!(response)
278
- }.to_not raise_error
272
+ end.to_not raise_error
279
273
  end
280
274
  it 'a regexp header should raise error if it does not match the regexp' do
281
275
  response_definition.header('X-Header', /anotherthing/)
282
- expect {
276
+ expect do
283
277
  response_definition.validate_headers!(response)
284
- }.to raise_error(Praxis::Exceptions::Validation)
278
+ end.to raise_error(Praxis::Exceptions::Validation)
285
279
  end
286
280
  end
287
281
  end
288
282
 
289
- describe "#validate_content_type!" do
290
-
291
- let(:response_headers) { {'Content-Type' => content_type } }
283
+ describe '#validate_content_type!' do
284
+ let(:response_headers) { { 'Content-Type' => content_type } }
292
285
  let(:content_type) { 'application/none' }
293
286
 
294
287
  let(:media_type) do
@@ -299,9 +292,9 @@ describe Praxis::ResponseDefinition do
299
292
 
300
293
  context 'for definition without media_type defined' do
301
294
  it 'should not check that it matches the content type' do
302
- expect {
295
+ expect do
303
296
  response_definition.validate_content_type!(response)
304
- }.to_not raise_error
297
+ end.to_not raise_error
305
298
  end
306
299
  end
307
300
 
@@ -312,60 +305,58 @@ describe Praxis::ResponseDefinition do
312
305
  let(:response_content_type) { content_type }
313
306
 
314
307
  it 'validates successfully' do
315
- expect {
308
+ expect do
316
309
  response_definition.validate_content_type!(response)
317
- }.to_not raise_error
310
+ end.to_not raise_error
318
311
  end
319
312
  end
320
313
 
321
314
  context 'when content type includes a parameter' do
322
315
  let(:response_content_type) { "#{content_type}; collection=true" }
323
316
  it 'validates successfully' do
324
- expect {
317
+ expect do
325
318
  response_definition.validate_content_type!(response)
326
- }.to_not raise_error
319
+ end.to_not raise_error
327
320
  end
328
321
  end
329
322
 
330
323
  context 'when content type does not match' do
331
- let(:response_content_type) { "application/will_never_match" }
324
+ let(:response_content_type) { 'application/will_never_match' }
332
325
 
333
326
  it 'should raise error telling you so' do
334
- expect {
327
+ expect do
335
328
  response_definition.validate_content_type!(response)
336
- }.to raise_error(Praxis::Exceptions::Validation)
329
+ end.to raise_error(Praxis::Exceptions::Validation)
337
330
  end
338
331
  end
339
332
 
340
333
  context 'when content type is not set' do
341
334
  let(:response_headers) { {} }
342
335
  it 'should still raise an error' do
343
- expect {
336
+ expect do
344
337
  response_definition.validate_content_type!(response)
345
- }.to raise_error(Praxis::Exceptions::Validation)
338
+ end.to raise_error(Praxis::Exceptions::Validation)
346
339
  end
347
340
  end
348
341
  end
349
342
  end
350
343
  end
351
-
352
344
  end
353
345
 
354
-
355
346
  context 'with invalid definitions' do
356
347
  it 'raises an error if status code is not part of the definition' do
357
348
  expect do
358
349
  Praxis::ResponseDefinition.new('response name') do
359
- description "testing"
350
+ description 'testing'
360
351
  end
361
352
  end.to raise_error(Praxis::Exceptions::InvalidConfiguration)
362
353
  end
363
354
  end
364
355
 
365
356
  context '.describe' do
366
- let(:description) { "A description" }
357
+ let(:description) { 'A description' }
367
358
  let(:location) { %r{/my/url/} }
368
- let(:headers) { {'Header1' => 'Value1'} }
359
+ let(:headers) { { 'Header1' => 'Value1' } }
369
360
  let(:parts) { nil }
370
361
  let(:parts_block) { nil }
371
362
 
@@ -380,7 +371,7 @@ describe Praxis::ResponseDefinition do
380
371
  response.description(description) if description
381
372
  response.location(location) if location
382
373
  if parts || parts_block
383
- parts ? response.parts(nil, **parts, &parts_block) : response.parts(nil, &parts_block)
374
+ parts ? response.parts(nil, **parts, &parts_block) : response.parts(nil, &parts_block)
384
375
  end
385
376
 
386
377
  headers&.each do |(name, value)|
@@ -403,7 +394,6 @@ describe Praxis::ResponseDefinition do
403
394
  it 'properly encodes the example bodies' do
404
395
  expect(JSON.parse(examples['json'][:body])).to be_kind_of(Hash)
405
396
  end
406
-
407
397
  end
408
398
 
409
399
  context 'which does not have a identifier' do
@@ -416,51 +406,48 @@ describe Praxis::ResponseDefinition do
416
406
  expect(subject['json'][:content_type]).to eq('application/json')
417
407
  end
418
408
  end
419
-
420
-
421
409
  end
422
410
 
423
-
424
411
  context 'for a definition without parts' do
425
- it{ should be_kind_of(::Hash) }
426
- its([:description]){ should be(description) }
427
- its([:location]){ should == {value: location.inspect ,type: :regexp} }
412
+ it { should be_kind_of(::Hash) }
413
+ its([:description]) { should be(description) }
414
+ its([:location]) { should == { value: location.inspect, type: :regexp } }
428
415
 
429
416
  it 'should have a header defined with value and type keys' do
430
- expect( output[:headers] ).to have(2).keys
431
- expect( output[:headers]['Header1'] ).to eq({value: 'Value1' ,type: :string })
432
- expect( output[:headers]['Location'] ).to eq({value: "/\\/my\\/url\\//" ,type: :regexp })
417
+ expect(output[:headers]).to have(2).keys
418
+ expect(output[:headers]['Header1']).to eq({ value: 'Value1', type: :string })
419
+ expect(output[:headers]['Location']).to eq({ value: '/\\/my\\/url\\//', type: :regexp })
433
420
  end
434
421
  end
435
422
 
436
423
  context 'for a definition with (homogeneous) parts' do
437
- subject(:described_parts){ output[:parts_like] }
424
+ subject(:described_parts) { output[:parts_like] }
438
425
  context 'using :like' do
439
- let(:parts) { {like: :ok, media_type: 'foobar'} }
426
+ let(:parts) { { like: :ok, media_type: 'foobar' } }
440
427
 
441
428
  it 'should contain a parts_like key with a hash' do
442
- expect( output ).to have_key(:parts_like)
429
+ expect(output).to have_key(:parts_like)
443
430
  end
444
431
 
445
- it{ should be_kind_of(::Hash) }
432
+ it { should be_kind_of(::Hash) }
446
433
  it 'has the right type info' do
447
434
  expect(subject[:payload][:type]).to match(id: 'Praxis-SimpleMediaType', name: 'Praxis::SimpleMediaType', family: 'string', identifier: 'foobar')
448
435
  end
449
- its([:status]){ should == 200 }
436
+ its([:status]) { should == 200 }
450
437
  end
451
438
  context 'using a full response definition block' do
452
439
  let(:parts_block) do
453
- Proc.new do
440
+ proc do
454
441
  status 234
455
442
  media_type 'custom_media'
456
443
  end
457
444
  end
458
445
 
459
446
  it 'should contain a parts_like key with a hash' do
460
- expect( output ).to have_key(:parts_like)
447
+ expect(output).to have_key(:parts_like)
461
448
  end
462
449
 
463
- it{ should be_kind_of(::Hash) }
450
+ it { should be_kind_of(::Hash) }
464
451
  it 'has the right type info' do
465
452
  expect(subject[:payload][:type]).to match(id: 'Praxis-SimpleMediaType', name: 'Praxis::SimpleMediaType', family: 'string', identifier: 'custom_media')
466
453
  end