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,4 +1,8 @@
1
- require "spec_helper"
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Style/StringConcatenation
4
+
5
+ require 'spec_helper'
2
6
 
3
7
  describe Praxis::MediaTypeIdentifier do
4
8
  let(:example) { 'application/ice-cream+sundae; nuts="true"; fudge="true"' }
@@ -14,7 +18,7 @@ describe Praxis::MediaTypeIdentifier do
14
18
  end
15
19
 
16
20
  context 'of empty string values' do
17
- let(:example) { "" }
21
+ let(:example) { '' }
18
22
  it 'returns nil' do
19
23
  expect(subject).to be(nil)
20
24
  end
@@ -47,8 +51,6 @@ describe Praxis::MediaTypeIdentifier do
47
51
  # pending("need to stop using a regexp to do a context-free parser's job")
48
52
  # expect(described_class.new(tricky_example).parameters['sauce']).to eq('yes; absolutely')
49
53
  # end
50
-
51
-
52
54
  end
53
55
 
54
56
  context 'given a malformed type' do
@@ -164,7 +166,7 @@ describe Praxis::MediaTypeIdentifier do
164
166
 
165
167
  let(:with_suffix) { 'application/vnd.widget+xml' }
166
168
  let(:with_subtype) { 'text/xml' }
167
- let(:with_both) { 'text/json+xml' } #nonsensical but valid!
169
+ let(:with_both) { 'text/json+xml' } # nonsensical but valid!
168
170
 
169
171
  it 'uses the suffix' do
170
172
  expect(subject.new(with_suffix).handler_name).to eq('xml')
@@ -192,15 +194,15 @@ describe Praxis::MediaTypeIdentifier do
192
194
 
193
195
  it 'adds parameters' do
194
196
  expect(simple_subject + 'nuts=true').to \
195
- eq(described_class.new('application/vnd.icecream; nuts=true'))
197
+ eq(described_class.new('application/vnd.icecream; nuts=true'))
196
198
 
197
199
  expect(simple_subject + '; nuts=true').to \
198
- eq(described_class.new('application/vnd.icecream; nuts=true'))
200
+ eq(described_class.new('application/vnd.icecream; nuts=true'))
199
201
  end
200
202
 
201
203
  it 'adds suffix and parameters' do
202
204
  expect(simple_subject + 'xml; nuts=true').to \
203
- eq(described_class.new('application/vnd.icecream+xml; nuts=true'))
205
+ eq(described_class.new('application/vnd.icecream+xml; nuts=true'))
204
206
  end
205
207
 
206
208
  it 'replaces the suffix' do
@@ -210,7 +212,7 @@ describe Praxis::MediaTypeIdentifier do
210
212
 
211
213
  it 'replaces existing parameters and adds new ones' do
212
214
  expect(complex_subject + 'nuts=false; cherry=true').to \
213
- eq(described_class.new('application/vnd.icecream+json; cherry=true; nuts=false'))
215
+ eq(described_class.new('application/vnd.icecream+json; cherry=true; nuts=false'))
214
216
 
215
217
  expect(complex_subject + '; nuts=false; cherry=true').to \
216
218
  eq(described_class.new('application/vnd.icecream+json; cherry=true; nuts=false'))
@@ -235,4 +237,5 @@ describe Praxis::MediaTypeIdentifier do
235
237
  end
236
238
  end
237
239
  end
238
- end
240
+ end
241
+ # rubocop:enable Style/StringConcatenation
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Praxis::MediaType do
@@ -5,19 +7,18 @@ describe Praxis::MediaType do
5
7
  let(:manager_resource) { instance_double(Person, id: 101, name: /[:name:]/.gen, href: '/') }
6
8
  let(:custodian_resource) { instance_double(Person, id: 102, name: /[:name:]/.gen, href: '/') }
7
9
  let(:residents_summary_resource) do
8
- instance_double(Person::CollectionSummary, href: "/people", size: 2)
10
+ instance_double(Person::CollectionSummary, href: '/people', size: 2)
9
11
  end
10
12
 
11
13
  let(:resource) do
12
14
  double('address',
13
- id: 1,
14
- name: 'Home',
15
- owner: owner_resource,
16
- manager: manager_resource,
17
- custodian: custodian_resource,
18
- residents_summary: residents_summary_resource,
19
- fields: {id: true, name: true}
20
- )
15
+ id: 1,
16
+ name: 'Home',
17
+ owner: owner_resource,
18
+ manager: manager_resource,
19
+ custodian: custodian_resource,
20
+ residents_summary: residents_summary_resource,
21
+ fields: { id: true, name: true })
21
22
  end
22
23
 
23
24
  subject(:address) { Address.new(resource) }
@@ -28,7 +29,6 @@ describe Praxis::MediaType do
28
29
  its(:owner) { should be_instance_of(Person) }
29
30
  end
30
31
 
31
-
32
32
  context 'accessor methods' do
33
33
  subject(:address_klass) { address.class }
34
34
 
@@ -41,12 +41,12 @@ describe Praxis::MediaType do
41
41
  its(:description) { should be_kind_of(String) }
42
42
  end
43
43
 
44
- context "rendering" do
44
+ context 'rendering' do
45
45
  subject(:output) { address.render }
46
46
 
47
47
  its([:id]) { should eq(address.id) }
48
48
  its([:name]) { should eq(address.name) }
49
49
  its([:owner]) { should eq(Person.dump(owner_resource)) }
50
- its([:fields]) { should eq(address.fields.dump ) }
50
+ its([:fields]) { should eq(address.fields.dump) }
51
51
  end
52
52
  end
@@ -1,73 +1,74 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Praxis::MiddlewareApp do
4
-
5
- let(:init_args){ { root: 'here'} }
6
- let(:middleware) { Praxis::MiddlewareApp.for( **init_args ) }
7
- let(:instance){ middleware.new(target)}
6
+ let(:init_args) { { root: 'here' } }
7
+ let(:middleware) { Praxis::MiddlewareApp.for(**init_args) }
8
+ let(:instance) { middleware.new(target) }
8
9
 
9
10
  context '.for' do
10
11
  it 'does not initialize the Application instance yet' do
11
- expect( Praxis::Application.instance ).to_not receive(:setup)
12
+ expect(Praxis::Application.instance).to_not receive(:setup)
12
13
  middleware
13
14
  end
14
15
  it 'returns its class' do
15
- expect( middleware ).to be < Praxis::MiddlewareApp
16
+ expect(middleware).to be < Praxis::MiddlewareApp
16
17
  end
17
18
  end
18
19
 
19
20
  context 'instantiated' do
20
- subject{ instance }
21
- let(:target_response){ [201,{}] }
22
- let(:target){ double("target app", call: target_response) }
21
+ subject { instance }
22
+ let(:target_response) { [201, {}] }
23
+ let(:target) { double('target app', call: target_response) }
23
24
  it 'saves the target app' do
24
25
  expect(subject.target).to be(target)
25
26
  end
26
27
  it 'does not initialize the Application instance yet' do
27
- expect( Praxis::Application.instance ).to_not receive(:setup)
28
+ expect(Praxis::Application.instance).to_not receive(:setup)
28
29
  subject
29
30
  end
30
-
31
+
31
32
  context '.call' do
32
- let(:env){ {} }
33
- let(:praxis_response){ [200,{}] }
34
- subject(:response){ instance.call(env) }
33
+ let(:env) { {} }
34
+ let(:praxis_response) { [200, {}] }
35
+ subject(:response) { instance.call(env) }
35
36
  before do
36
37
  # always invokes the praxis app
37
- expect( Praxis::Application.instance ).to receive(:call).with( env ).once.and_return(praxis_response)
38
+ expect(Praxis::Application.instance).to receive(:call).with(env).once.and_return(praxis_response)
38
39
  end
39
40
 
40
41
  context 'when it has not been setup yet' do
41
42
  it 'initializes the application singleton with the passed parameters' do
42
- expect( Praxis::Application.instance ).to receive(:setup).with( init_args ).once
43
+ expect(Praxis::Application.instance).to receive(:setup).with(init_args).once
43
44
  subject
44
45
  end
45
46
  end
46
47
  context 'when it has already been setup' do
47
48
  it 'does NOT call instance setup' do
48
49
  middleware.setup
49
- expect( Praxis::Application.instance ).to_not receive(:setup)
50
+ expect(Praxis::Application.instance).to_not receive(:setup)
50
51
  subject
51
52
  end
52
53
  end
53
54
 
54
55
  context 'properly handled (non-404 and 405) responses from praxis' do
55
56
  it 'are returned straight through' do
56
- expect( response ).to be(praxis_response)
57
+ expect(response).to be(praxis_response)
57
58
  end
58
59
  end
59
60
 
60
61
  context '404/405 responses with X-Cascade = pass' do
61
- let(:praxis_response){ [404, {'X-Cascade' => 'pass'}]}
62
+ let(:praxis_response) { [404, { 'X-Cascade' => 'pass' }] }
62
63
  it 'are forwarded to the target app' do
63
- expect( response ).to be(target_response)
64
+ expect(response).to be(target_response)
64
65
  end
65
66
  end
66
67
 
67
68
  context '404/405 responses without X-Cascade = pass' do
68
- let(:praxis_response){ [404, {}]}
69
+ let(:praxis_response) { [404, {}] }
69
70
  it 'returned straight through' do
70
- expect( response ).to be(praxis_response)
71
+ expect(response).to be(praxis_response)
71
72
  end
72
73
  end
73
74
  end
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Praxis::MultipartParser do
4
-
5
6
  let(:form) do
6
7
  form_data = MIME::Multipart::FormData.new
7
8
 
@@ -36,17 +37,16 @@ describe Praxis::MultipartParser do
36
37
  form.add text, 'file', 'docker'
37
38
  end
38
39
 
39
- subject(:part) { parts.find { |p| p.name == 'file'} }
40
- #subject(:part_body) { part.body }
41
-
40
+ subject(:part) { parts.find { |p| p.name == 'file' } }
41
+ # subject(:part_body) { part.body }
42
42
 
43
43
  its(:payload) { should be_kind_of(Tempfile) }
44
- its(:filename) { should eq("docker") }
45
- its(:name) { should eq("file") }
44
+ its(:filename) { should eq('docker') }
45
+ its(:name) { should eq('file') }
46
46
 
47
47
  context 'headers' do
48
48
  subject(:part_headers) { part.headers }
49
- its(['Content-Type']) { should eq("text/plain") }
49
+ its(['Content-Type']) { should eq('text/plain') }
50
50
  its(['Content-Disposition']) { should match(/filename=docker/) }
51
51
  end
52
52
 
@@ -56,7 +56,5 @@ describe Praxis::MultipartParser do
56
56
  part.payload.rewind
57
57
  expect(part.payload.read).to eq('DOCKER_HOST=tcp://127.0.0.1:2375')
58
58
  end
59
-
60
59
  end
61
-
62
60
  end
@@ -1,11 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Praxis::Notifications do
4
-
5
6
  let(:events) { [] }
6
7
 
7
8
  before do
8
- Praxis::Notifications.subscribe('render') do |name, start, finish, id, payload|
9
+ Praxis::Notifications.subscribe('render') do |_name, _start, _finish, _id, payload|
9
10
  events << payload
10
11
  end
11
12
 
@@ -17,7 +18,6 @@ describe Praxis::Notifications do
17
18
 
18
19
  it 'works' do
19
20
  expect(events).to have(2).items
20
- expect(events).to match [{extra: :information}, {extra: :single}]
21
+ expect(events).to match [{ extra: :information }, { extra: :single }]
21
22
  end
22
-
23
23
  end
@@ -1,21 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Praxis::PluginConcern do
4
-
5
6
  it 'works' do
6
7
  expect(Praxis::Request.instance_methods).to include(:user_abilities)
7
8
  end
8
9
 
9
10
  context 'ActionDefinition' do
10
11
  subject(:action) { ApiResources::Instances.actions[:terminate] }
11
- its(:required_abilities) { should match_array [:terminate, :read] }
12
+ its(:required_abilities) { should match_array %i[terminate read] }
12
13
 
13
14
  context '#describe' do
14
15
  subject(:describe) { action.describe }
15
- it { should have_key :required_abilities}
16
- its([:required_abilities]) { should match_array action.required_abilities}
16
+ it { should have_key :required_abilities }
17
+ its([:required_abilities]) { should match_array action.required_abilities }
17
18
  end
18
-
19
19
  end
20
-
21
20
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative '../spec_helper'
3
4
 
4
5
  describe Praxis::Renderer do
@@ -30,7 +31,7 @@ describe Praxis::Renderer do
30
31
  address: {
31
32
  state: true,
32
33
  street: true,
33
- resident: { name: true }
34
+ resident: { name: true }
34
35
  },
35
36
  prior_addresses: { name: true },
36
37
  work_address: true,
@@ -45,15 +46,15 @@ describe Praxis::Renderer do
45
46
  subject(:output) { renderer.render(person, fields) }
46
47
 
47
48
  it 'renders existing attributes' do
48
- expect(output.keys).to match_array([:name, :full_name, :alive, :address, :prior_addresses, :metadata, :aliases])
49
+ expect(output.keys).to match_array(%i[name full_name alive address prior_addresses metadata aliases])
49
50
 
50
51
  expect(output[:name]).to eq person.name
51
52
  expect(output[:full_name]).to eq(first: person.full_name.first, last: person.full_name.last)
52
53
  expect(output[:alive]).to be false
53
54
 
54
55
  expect(output[:address]).to eq(state: person.address.state,
55
- street: person.address.street,
56
- resident: { name: person.address.resident.name })
56
+ street: person.address.street,
57
+ resident: { name: person.address.resident.name })
57
58
 
58
59
  expected_prior_addresses = prior_addresses.collect { |addr| { name: addr.name } }
59
60
  expect(output[:prior_addresses]).to match_array(expected_prior_addresses)
@@ -118,18 +119,18 @@ describe Praxis::Renderer do
118
119
 
119
120
  context 'rendering stuff that breaks badly' do
120
121
  it 'does not break badly' do
121
- expect{renderer.render(person, {tags: true})}.to_not raise_error
122
+ expect { renderer.render(person, { tags: true }) }.to_not raise_error
122
123
  end
123
124
  end
124
125
 
125
126
  context 'caching rendered objects' do
126
- let(:fields) { {full_name: true} }
127
+ let(:fields) { { full_name: true } }
127
128
  it 'caches and returns identical results for the same field objects' do
128
129
  expect(person).to receive(:full_name).once.and_call_original
129
130
 
130
- render_1 = renderer.render(person, fields)
131
- render_2 = renderer.render(person, fields)
132
- expect(render_1).to be(render_2)
131
+ render1 = renderer.render(person, fields)
132
+ render2 = renderer.render(person, fields)
133
+ expect(render1).to be(render2)
133
134
  end
134
135
  end
135
136
 
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Praxis::Request do
4
- let(:path) { '/instances/1?junk=foo&api_version=1.0' }
6
+ let(:path) { '/instances/1?junk=foo&api_version=1.0' }
5
7
  let(:rack_input) { StringIO.new('{"something": "given"}') }
6
- let(:env_content_type){ 'application/json' }
8
+ let(:env_content_type) { 'application/json' }
7
9
  let(:env) do
8
10
  env = Rack::MockRequest.env_for(path)
9
11
  env['rack.input'] = rack_input
@@ -17,9 +19,9 @@ describe Praxis::Request do
17
19
 
18
20
  let(:context) do
19
21
  {
20
- params: [Attributor::ROOT_PREFIX, "params".freeze],
21
- headers: [Attributor::ROOT_PREFIX, "headers".freeze],
22
- payload: [Attributor::ROOT_PREFIX, "payload".freeze]
22
+ params: [Attributor::ROOT_PREFIX, 'params'],
23
+ headers: [Attributor::ROOT_PREFIX, 'headers'],
24
+ payload: [Attributor::ROOT_PREFIX, 'payload']
23
25
  }.freeze
24
26
  end
25
27
 
@@ -29,9 +31,9 @@ describe Praxis::Request do
29
31
  request
30
32
  end
31
33
 
32
- its(:verb) { should eq("GET") }
34
+ its(:verb) { should eq('GET') }
33
35
  its(:path) { should eq('/instances/1') }
34
- its(:raw_params) { should eq({'junk' => 'foo'}) }
36
+ its(:raw_params) { should eq({ 'junk' => 'foo' }) }
35
37
  its(:version) { should eq('1.0') }
36
38
 
37
39
  context 'path versioning' do
@@ -42,26 +44,24 @@ describe Praxis::Request do
42
44
  allow(
43
45
  Praxis::ApiDefinition.instance.info
44
46
  ).to receive(:base_path).and_return('/api/v:api_version')
45
-
46
47
  end
47
48
 
48
49
  let(:path) { '/api/v2.0/instances/1' }
49
50
 
50
-
51
51
  its(:version) { should eq '2.0' }
52
- #its('class.path_version_prefix'){ should eq("/v") }
53
- #its(:path_version_matcher){ should be_kind_of(Regexp) }
54
- #it 'uses a "/v*" default matcher with a "version" named capture' do
52
+ # its('class.path_version_prefix'){ should eq("/v") }
53
+ # its(:path_version_matcher){ should be_kind_of(Regexp) }
54
+ # it 'uses a "/v*" default matcher with a "version" named capture' do
55
55
  # match = subject.path_version_matcher.match("/v5.5/something")
56
56
  # expect(match).to_not be(nil)
57
57
  # expect(match['version']).to eq("5.5")
58
- #end
58
+ # end
59
59
  end
60
60
 
61
61
  context 'loading api version' do
62
- #let(:request) { Praxis::Request.new(env) }
63
- subject(:version){ request.version }
64
- let(:versioning_scheme){ Praxis::Request::VERSION_USING_DEFAULTS }
62
+ # let(:request) { Praxis::Request.new(env) }
63
+ subject(:version) { request.version }
64
+ let(:versioning_scheme) { Praxis::Request::VERSION_USING_DEFAULTS }
65
65
  before do
66
66
  allow(
67
67
  Praxis::Application.instance
@@ -69,18 +69,18 @@ describe Praxis::Request do
69
69
  end
70
70
 
71
71
  context 'using X-Api-Header' do
72
- let(:env){ {'HTTP_X_API_VERSION' => "5.0", "PATH_INFO" => "/something"} }
73
- let(:versioning_scheme){ :header }
72
+ let(:env) { { 'HTTP_X_API_VERSION' => '5.0', 'PATH_INFO' => '/something' } }
73
+ let(:versioning_scheme) { :header }
74
74
  it { should eq('5.0') }
75
75
  end
76
76
  context 'using query param' do
77
77
  let(:env) { Rack::MockRequest.env_for('/instances/1?junk=foo&api_version=5.0') }
78
- let(:versioning_scheme){ :params }
78
+ let(:versioning_scheme) { :params }
79
79
  it { should eq('5.0') }
80
80
  end
81
81
  context 'using path (with the default pattern matcher)' do
82
- let(:env){ Rack::MockRequest.env_for('/v5.0/instances/1?junk=foo') }
83
- let(:versioning_scheme){ :path }
82
+ let(:env) { Rack::MockRequest.env_for('/v5.0/instances/1?junk=foo') }
83
+ let(:versioning_scheme) { :path }
84
84
 
85
85
  before do
86
86
  allow(
@@ -92,21 +92,21 @@ describe Praxis::Request do
92
92
 
93
93
  context 'using a method that it is not allowed in the definition' do
94
94
  context 'allowing query param but passing it through a header' do
95
- let(:env){ {'HTTP_X_API_VERSION' => "5.0", "PATH_INFO" => "/something"} }
96
- let(:versioning_scheme){ :params }
95
+ let(:env) { { 'HTTP_X_API_VERSION' => '5.0', 'PATH_INFO' => '/something' } }
96
+ let(:versioning_scheme) { :params }
97
97
  it { should eq('n/a') }
98
98
  end
99
99
  context 'allowing header but passing it through param' do
100
100
  let(:env) { Rack::MockRequest.env_for('/instances/1?junk=foo&api_version=5.0') }
101
- let(:versioning_scheme){ :header }
101
+ let(:versioning_scheme) { :header }
102
102
  it { should eq('n/a') }
103
103
  end
104
104
  end
105
105
 
106
106
  context 'using defaults' do
107
- subject(:version){ request.version }
107
+ subject(:version) { request.version }
108
108
  context 'would succeed if passed through the header' do
109
- let(:env){ {'HTTP_X_API_VERSION' => "5.0", "PATH_INFO" => "/something"} }
109
+ let(:env) { { 'HTTP_X_API_VERSION' => '5.0', 'PATH_INFO' => '/something' } }
110
110
  it { should eq('5.0') }
111
111
  end
112
112
  context 'would succeed if passed through params' do
@@ -126,9 +126,9 @@ describe Praxis::Request do
126
126
  form_data
127
127
  end
128
128
 
129
- let(:rack_input) {
129
+ let(:rack_input) do
130
130
  StringIO.new(form.body.to_s)
131
- }
131
+ end
132
132
 
133
133
  let(:env) do
134
134
  env = Rack::MockRequest.env_for('/instances/1?junk=foo&api_version=1.0')
@@ -138,21 +138,18 @@ describe Praxis::Request do
138
138
  env
139
139
  end
140
140
 
141
- #its(:multipart?) { should be(true) }
141
+ # its(:multipart?) { should be(true) }
142
142
 
143
143
  it 'works' do
144
- #p request #.body
145
- #p request #.parts
144
+ # p request #.body
145
+ # p request #.parts
146
146
  end
147
-
148
-
149
147
  end
150
148
 
151
149
  context '#load_headers' do
152
-
153
150
  it 'is done preserving the original case' do
154
151
  request.load_headers(context[:headers])
155
- expect(request.headers).to eq({"Authorization" => "Secret"})
152
+ expect(request.headers).to eq({ 'Authorization' => 'Secret' })
156
153
  end
157
154
 
158
155
  it 'performs it using the memoized rack keys from the action (Hacky but...performance is important)' do
@@ -161,7 +158,7 @@ describe Praxis::Request do
161
158
  end
162
159
  end
163
160
 
164
- context "performs request validation" do
161
+ context 'performs request validation' do
165
162
  before(:each) do
166
163
  request.load_headers(context[:headers])
167
164
  request.load_params(context[:params])
@@ -205,17 +202,17 @@ describe Praxis::Request do
205
202
  end
206
203
 
207
204
  context '#load_payload' do
208
- let(:load_context){ context[:payload] }
209
- let(:parsed_result){ double("parsed") }
205
+ let(:load_context) { context[:payload] }
206
+ let(:parsed_result) { double('parsed') }
210
207
 
211
208
  after do
212
- expect(request.action.payload).to receive(:load).with(parsed_result, load_context, content_type: request.content_type.to_s )
213
- request.load_payload( load_context )
209
+ expect(request.action.payload).to receive(:load).with(parsed_result, load_context, content_type: request.content_type.to_s)
210
+ request.load_payload(load_context)
214
211
  end
215
212
 
216
213
  context 'that is json encoded' do
217
214
  let(:rack_input) { StringIO.new('{"one":1,"sub_hash":{"first":"hello"}}') }
218
- let(:env_content_type){ 'application/json' }
215
+ let(:env_content_type) { 'application/json' }
219
216
  let(:parsed_result) { Praxis::Handlers::JSON.new.parse(request.raw_payload) }
220
217
 
221
218
  it 'decodes using the JSON handler' do end
@@ -1,17 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe Praxis::RequestStages::Action do
4
-
5
6
  let(:controller) do
6
7
  Class.new do
7
8
  include Praxis::Controller
8
9
  end.new(request)
9
10
  end
10
11
 
11
- let(:action) { double("action", name: "foo") }
12
- let(:response){ Praxis::Responses::Ok.new }
13
- let(:app){ double("App", controller: controller, action:action, request: request)}
14
- let(:action_stage){ Praxis::RequestStages::Action.new(action.name,app) }
12
+ let(:action) { double('action', name: 'foo') }
13
+ let(:response) { Praxis::Responses::Ok.new }
14
+ let(:app) { double('App', controller: controller, action: action, request: request) }
15
+ let(:action_stage) { Praxis::RequestStages::Action.new(action.name, app) }
15
16
 
16
17
  let(:request) do
17
18
  env = Rack::MockRequest.env_for('/instances/1?cloud_id=1&api_version=1.0')
@@ -23,19 +24,17 @@ describe Praxis::RequestStages::Action do
23
24
  request
24
25
  end
25
26
 
26
-
27
27
  context '.execute' do
28
28
  before do
29
29
  expect(controller).to receive(action_stage.name) do |args|
30
30
  if args
31
31
  expect(args).to eq({})
32
32
  else
33
- expect(args).to eq(nil)
33
+ expect(args).to eq(nil)
34
34
  end
35
35
  end.and_return(controller_response)
36
-
37
36
  end
38
- let(:controller_response){ controller.response }
37
+ let(:controller_response) { controller.response }
39
38
 
40
39
  it 'always call the right controller method' do
41
40
  action_stage.execute
@@ -47,28 +46,28 @@ describe Praxis::RequestStages::Action do
47
46
  end
48
47
 
49
48
  it 'sends the right ActiveSupport::Notification' do
50
- expect(ActiveSupport::Notifications).to receive(:instrument).with('praxis.request_stage.execute', {controller: an_instance_of(controller.class)}).and_call_original
49
+ expect(ActiveSupport::Notifications).to receive(:instrument).with('praxis.request_stage.execute', { controller: an_instance_of(controller.class) }).and_call_original
51
50
  action_stage.execute
52
51
  end
53
52
 
54
53
  context 'if the controller method returns a string' do
55
- let(:controller_response){ "this is the body"}
54
+ let(:controller_response) { 'this is the body' }
56
55
  it 'sets the response body with it (and save the request too)' do
57
56
  action_stage.execute
58
- expect(controller.response.body).to eq("this is the body")
57
+ expect(controller.response.body).to eq('this is the body')
59
58
  end
60
59
  end
61
60
  context 'if the controller method returns a response object' do
62
- let(:controller_response){ Praxis::Responses::Created.new }
61
+ let(:controller_response) { Praxis::Responses::Created.new }
63
62
  it 'set that response in the controller' do
64
63
  action_stage.execute
65
64
  expect(controller.response).to eq(controller_response)
66
65
  end
67
66
  end
68
67
  context 'if the controller method returns neither a string or a response' do
69
- let(:controller_response){ nil }
68
+ let(:controller_response) { nil }
70
69
  it 'an error is raised ' do
71
- expect{ action_stage.execute }.to raise_error(/Only Response objects or Strings allowed/)
70
+ expect { action_stage.execute }.to raise_error(/Only Response objects or Strings allowed/)
72
71
  end
73
72
  end
74
73
  end