praxis 2.0.pre.17 → 2.0.pre.21
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +54 -0
- data/.simplecov +3 -1
- data/.travis.yml +2 -1
- data/CHANGELOG.md +19 -0
- data/CONTRIBUTING.md +2 -79
- data/Gemfile +5 -1
- data/Guardfile +6 -4
- data/LICENSE +0 -2
- data/MAINTAINERS.md +1 -0
- data/README.md +15 -22
- data/Rakefile +4 -2
- data/bin/praxis +55 -58
- data/lib/praxis/action_definition/headers_dsl_compiler.rb +5 -6
- data/lib/praxis/action_definition.rb +65 -95
- data/lib/praxis/api_definition.rb +21 -29
- data/lib/praxis/api_general_info.rb +55 -66
- data/lib/praxis/application.rb +15 -32
- data/lib/praxis/blueprint.rb +80 -73
- data/lib/praxis/bootloader.rb +24 -33
- data/lib/praxis/bootloader_stages/environment.rb +5 -10
- data/lib/praxis/bootloader_stages/file_loader.rb +3 -6
- data/lib/praxis/bootloader_stages/plugin_config_load.rb +4 -6
- data/lib/praxis/bootloader_stages/plugin_config_prepare.rb +2 -2
- data/lib/praxis/bootloader_stages/plugin_loader.rb +3 -7
- data/lib/praxis/bootloader_stages/plugin_setup.rb +3 -3
- data/lib/praxis/bootloader_stages/routing.rb +5 -8
- data/lib/praxis/bootloader_stages/subgroup_loader.rb +2 -10
- data/lib/praxis/bootloader_stages/warn_unloaded_files.rb +15 -19
- data/lib/praxis/callbacks.rb +12 -11
- data/lib/praxis/collection.rb +11 -14
- data/lib/praxis/config.rb +17 -28
- data/lib/praxis/config_hash.rb +2 -1
- data/lib/praxis/controller.rb +7 -6
- data/lib/praxis/dispatcher.rb +34 -42
- data/lib/praxis/docs/open_api/info_object.rb +11 -8
- data/lib/praxis/docs/open_api/media_type_object.rb +18 -17
- data/lib/praxis/docs/open_api/operation_object.rb +7 -4
- data/lib/praxis/docs/open_api/parameter_object.rb +17 -14
- data/lib/praxis/docs/open_api/paths_object.rb +11 -9
- data/lib/praxis/docs/open_api/request_body_object.rb +14 -13
- data/lib/praxis/docs/open_api/response_object.rb +24 -18
- data/lib/praxis/docs/open_api/responses_object.rb +3 -1
- data/lib/praxis/docs/open_api/schema_object.rb +61 -29
- data/lib/praxis/docs/open_api/server_object.rb +5 -2
- data/lib/praxis/docs/open_api/tag_object.rb +9 -6
- data/lib/praxis/docs/open_api_generator.rb +114 -150
- data/lib/praxis/endpoint_definition.rb +60 -77
- data/lib/praxis/error_handler.rb +2 -2
- data/lib/praxis/exception.rb +2 -0
- data/lib/praxis/exceptions/config.rb +3 -1
- data/lib/praxis/exceptions/config_load.rb +2 -0
- data/lib/praxis/exceptions/config_validation.rb +3 -1
- data/lib/praxis/exceptions/invalid_configuration.rb +3 -1
- data/lib/praxis/exceptions/invalid_response.rb +3 -1
- data/lib/praxis/exceptions/invalid_trait.rb +3 -1
- data/lib/praxis/exceptions/stage_not_found.rb +3 -1
- data/lib/praxis/exceptions/validation.rb +4 -3
- data/lib/praxis/extensions/attribute_filtering/active_record_filter_query_builder.rb +163 -149
- data/lib/praxis/extensions/attribute_filtering/active_record_patches/5x.rb +18 -13
- data/lib/praxis/extensions/attribute_filtering/active_record_patches/6_0.rb +13 -9
- data/lib/praxis/extensions/attribute_filtering/active_record_patches/6_1_plus.rb +14 -11
- data/lib/praxis/extensions/attribute_filtering/active_record_patches.rb +12 -9
- data/lib/praxis/extensions/attribute_filtering/filter_tree_node.rb +8 -5
- data/lib/praxis/extensions/attribute_filtering/filtering_params.rb +89 -65
- data/lib/praxis/extensions/attribute_filtering/filters_parser.rb +68 -62
- data/lib/praxis/extensions/attribute_filtering.rb +3 -1
- data/lib/praxis/extensions/field_expansion.rb +6 -4
- data/lib/praxis/extensions/field_selection/active_record_query_selector.rb +10 -8
- data/lib/praxis/extensions/field_selection/field_selector.rb +91 -92
- data/lib/praxis/extensions/field_selection/sequel_query_selector.rb +12 -12
- data/lib/praxis/extensions/field_selection.rb +3 -1
- data/lib/praxis/extensions/pagination/active_record_pagination_handler.rb +6 -4
- data/lib/praxis/extensions/pagination/header_generator.rb +16 -11
- data/lib/praxis/extensions/pagination/ordering_params.rb +29 -28
- data/lib/praxis/extensions/pagination/pagination_handler.rb +44 -42
- data/lib/praxis/extensions/pagination/pagination_params.rb +29 -48
- data/lib/praxis/extensions/pagination/sequel_pagination_handler.rb +8 -7
- data/lib/praxis/extensions/pagination.rb +10 -15
- data/lib/praxis/extensions/rails_compat/request_methods.rb +3 -4
- data/lib/praxis/extensions/rails_compat.rb +2 -0
- data/lib/praxis/extensions/rendering.rb +12 -12
- data/lib/praxis/field_expander.rb +8 -9
- data/lib/praxis/file_group.rb +8 -12
- data/lib/praxis/finalizable.rb +1 -0
- data/lib/praxis/handlers/json.rb +5 -2
- data/lib/praxis/handlers/plain.rb +2 -1
- data/lib/praxis/handlers/www_form.rb +6 -3
- data/lib/praxis/handlers/{xml-sample.rb → xml_sample.rb} +26 -22
- data/lib/praxis/mapper/active_model_compat.rb +13 -10
- data/lib/praxis/mapper/resource.rb +196 -181
- data/lib/praxis/mapper/selector_generator.rb +106 -112
- data/lib/praxis/mapper/sequel_compat.rb +70 -67
- data/lib/praxis/media_type.rb +2 -2
- data/lib/praxis/media_type_identifier.rb +26 -22
- data/lib/praxis/middleware_app.rb +18 -15
- data/lib/praxis/multipart/parser.rb +46 -51
- data/lib/praxis/multipart/part.rb +78 -110
- data/lib/praxis/notifications.rb +2 -4
- data/lib/praxis/plugin.rb +11 -18
- data/lib/praxis/plugin_concern.rb +12 -15
- data/lib/praxis/plugins/mapper_plugin.rb +15 -13
- data/lib/praxis/plugins/pagination_plugin.rb +8 -6
- data/lib/praxis/plugins/rails_plugin.rb +33 -28
- data/lib/praxis/renderer.rb +11 -15
- data/lib/praxis/request.rb +48 -44
- data/lib/praxis/request_stages/action.rb +4 -6
- data/lib/praxis/request_stages/load_request.rb +2 -4
- data/lib/praxis/request_stages/request_stage.rb +19 -23
- data/lib/praxis/request_stages/response.rb +4 -6
- data/lib/praxis/request_stages/validate.rb +3 -5
- data/lib/praxis/request_stages/validate_params_and_headers.rb +15 -22
- data/lib/praxis/request_stages/validate_payload.rb +25 -28
- data/lib/praxis/request_superclassing.rb +3 -3
- data/lib/praxis/resource_definition.rb +1 -0
- data/lib/praxis/response.rb +24 -26
- data/lib/praxis/response_definition.rb +77 -122
- data/lib/praxis/response_template.rb +11 -15
- data/lib/praxis/responses/http.rb +23 -44
- data/lib/praxis/responses/internal_server_error.rb +18 -21
- data/lib/praxis/responses/multipart_ok.rb +4 -9
- data/lib/praxis/responses/validation_error.rb +8 -15
- data/lib/praxis/route.rb +8 -10
- data/lib/praxis/router/rack.rb +13 -7
- data/lib/praxis/router/simple.rb +10 -5
- data/lib/praxis/router.rb +27 -34
- data/lib/praxis/routing_config.rb +52 -29
- data/lib/praxis/simple_media_type.rb +5 -8
- data/lib/praxis/stage.rb +17 -25
- data/lib/praxis/tasks/api_docs.rb +17 -16
- data/lib/praxis/tasks/console.rb +3 -1
- data/lib/praxis/tasks/environment.rb +2 -0
- data/lib/praxis/tasks/routes.rb +26 -24
- data/lib/praxis/tasks.rb +3 -1
- data/lib/praxis/trait.rb +37 -46
- data/lib/praxis/types/fuzzy_hash.rb +13 -14
- data/lib/praxis/types/media_type_common.rb +11 -10
- data/lib/praxis/types/multipart_array/part_definition.rb +14 -17
- data/lib/praxis/types/multipart_array.rb +100 -115
- data/lib/praxis/validation_handler.rb +5 -3
- data/lib/praxis/version.rb +3 -1
- data/lib/praxis.rb +4 -5
- data/praxis.gemspec +22 -21
- data/spec/functional_spec.rb +44 -56
- data/spec/praxis/action_definition_spec.rb +39 -48
- data/spec/praxis/api_definition_spec.rb +45 -47
- data/spec/praxis/api_general_info_spec.rb +28 -29
- data/spec/praxis/application_spec.rb +18 -14
- data/spec/praxis/blueprint_spec.rb +33 -34
- data/spec/praxis/bootloader_spec.rb +32 -30
- data/spec/praxis/callbacks_spec.rb +37 -37
- data/spec/praxis/collection_spec.rb +18 -25
- data/spec/praxis/config_hash_spec.rb +5 -4
- data/spec/praxis/config_spec.rb +27 -26
- data/spec/praxis/controller_spec.rb +8 -9
- data/spec/praxis/endpoint_definition_spec.rb +25 -32
- data/spec/praxis/extensions/attribute_filtering/active_record_filter_query_builder_spec.rb +171 -114
- data/spec/praxis/extensions/attribute_filtering/filter_tree_node_spec.rb +22 -21
- data/spec/praxis/extensions/attribute_filtering/filtering_params_spec.rb +112 -60
- data/spec/praxis/extensions/attribute_filtering/filters_parser_spec.rb +37 -38
- data/spec/praxis/extensions/field_expansion_spec.rb +8 -10
- data/spec/praxis/extensions/field_selection/active_record_query_selector_spec.rb +14 -13
- data/spec/praxis/extensions/field_selection/field_selector_spec.rb +9 -16
- data/spec/praxis/extensions/field_selection/sequel_query_selector_spec.rb +50 -49
- data/spec/praxis/extensions/pagination/active_record_pagination_handler_spec.rb +32 -31
- data/spec/praxis/extensions/rendering_spec.rb +9 -9
- data/spec/praxis/extensions/support/spec_resources_active_model.rb +32 -49
- data/spec/praxis/extensions/support/spec_resources_sequel.rb +48 -48
- data/spec/praxis/field_expander_spec.rb +6 -5
- data/spec/praxis/file_group_spec.rb +3 -1
- data/spec/praxis/handlers/json_spec.rb +6 -5
- data/spec/praxis/mapper/resource_spec.rb +39 -29
- data/spec/praxis/mapper/selector_generator_spec.rb +80 -46
- data/spec/praxis/media_type_identifier_spec.rb +13 -10
- data/spec/praxis/media_type_spec.rb +12 -12
- data/spec/praxis/middleware_app_spec.rb +23 -22
- data/spec/praxis/multipart/parser_spec.rb +7 -9
- data/spec/praxis/notifications_spec.rb +4 -4
- data/spec/praxis/plugin_concern_spec.rb +5 -6
- data/spec/praxis/renderer_spec.rb +10 -9
- data/spec/praxis/request_spec.rb +38 -41
- data/spec/praxis/request_stages/action_spec.rb +14 -15
- data/spec/praxis/request_stages/request_stage_spec.rb +30 -41
- data/spec/praxis/request_stages/validate_spec.rb +3 -1
- data/spec/praxis/response_definition_spec.rb +79 -92
- data/spec/praxis/response_spec.rb +35 -40
- data/spec/praxis/responses/internal_server_error_spec.rb +6 -9
- data/spec/praxis/responses/validation_error_spec.rb +17 -18
- data/spec/praxis/route_spec.rb +4 -7
- data/spec/praxis/router_spec.rb +69 -79
- data/spec/praxis/routing_config_spec.rb +15 -14
- data/spec/praxis/stage_spec.rb +56 -53
- data/spec/praxis/trait_spec.rb +17 -17
- data/spec/praxis/types/fuzzy_hash_spec.rb +11 -9
- data/spec/praxis/types/multipart_array/part_definition_spec.rb +3 -2
- data/spec/praxis/types/multipart_array_spec.rb +33 -48
- data/spec/spec_app/app/concerns/authenticated.rb +5 -5
- data/spec/spec_app/app/concerns/basic_api.rb +3 -1
- data/spec/spec_app/app/concerns/log_wrapper.rb +5 -3
- data/spec/spec_app/app/controllers/base_class.rb +6 -5
- data/spec/spec_app/app/controllers/instances.rb +31 -34
- data/spec/spec_app/app/controllers/volumes.rb +6 -6
- data/spec/spec_app/app/responses/multipart.rb +1 -2
- data/spec/spec_app/app/responses/other_response.rb +2 -2
- data/spec/spec_app/config/environment.rb +19 -6
- data/spec/spec_app/config.ru +4 -3
- data/spec/spec_app/design/api.rb +13 -15
- data/spec/spec_app/design/media_types/instance.rb +6 -6
- data/spec/spec_app/design/media_types/volume.rb +2 -1
- data/spec/spec_app/design/media_types/volume_snapshot.rb +2 -1
- data/spec/spec_app/design/resources/instances.rb +11 -17
- data/spec/spec_app/design/resources/volume_snapshots.rb +4 -5
- data/spec/spec_app/design/resources/volumes.rb +4 -5
- data/spec/spec_helper.rb +11 -13
- data/spec/support/be_deep_equal_matcher.rb +5 -0
- data/spec/support/spec_authorization_plugin.rb +7 -12
- data/spec/support/spec_blueprints.rb +5 -4
- data/spec/support/spec_complex_authentication_plugin.rb +17 -34
- data/spec/support/spec_endpoint_definitions.rb +2 -3
- data/spec/support/spec_media_types.rb +28 -35
- data/spec/support/spec_resources.rb +22 -16
- data/spec/support/spec_simple_authentication_plugin.rb +5 -9
- data/tasks/loader.thor +4 -2
- data/tasks/thor/app.rb +7 -5
- data/tasks/thor/example.rb +23 -22
- data/tasks/thor/model.rb +7 -7
- data/tasks/thor/scaffold.rb +23 -23
- data/tasks/thor/templates/generator/example_app/app/v1/resources/user.rb +0 -8
- data/tasks/thor/templates/generator/scaffold/implementation/resources/item.rb +1 -2
- metadata +72 -84
- data/MAINTAINERS +0 -2
- data/TODO.md +0 -25
- data/spec/praxis/api_resource_spec.rb +0 -0
- data/spec/praxis/dispatcher_spec.rb +0 -0
- data/spec/spec_app/app/responses/bulk_response.rb +0 -0
|
@@ -1,56 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'sequel'
|
|
2
4
|
|
|
3
5
|
require 'praxis/mapper/sequel_compat'
|
|
4
6
|
|
|
5
|
-
|
|
6
7
|
# Creates a new in-memory DB, and the necessary tables (and mini-seeds) for the sequel models in this file
|
|
7
8
|
def create_and_seed_tables
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
9
|
+
sequeldb = Sequel.sqlite
|
|
10
|
+
# sequeldb.loggers = [Logger.new($stdout)] # Uncomment to see sequel logs
|
|
11
|
+
|
|
12
|
+
sequeldb.create_table! :sequel_simple_models do
|
|
13
|
+
primary_key :id
|
|
14
|
+
String :simple_name
|
|
15
|
+
Integer :parent_id
|
|
16
|
+
String :parent_uuid
|
|
17
|
+
Integer :other_model_id
|
|
18
|
+
String :added_column
|
|
19
|
+
end
|
|
20
|
+
sequeldb.create_table! :sequel_other_models do
|
|
21
|
+
primary_key :id
|
|
22
|
+
end
|
|
23
|
+
sequeldb.create_table! :sequel_parent_models do
|
|
24
|
+
primary_key :id
|
|
25
|
+
String :uuid
|
|
26
|
+
end
|
|
27
|
+
sequeldb.create_table! :sequel_tag_models do
|
|
28
|
+
primary_key :id
|
|
29
|
+
String :tag_name
|
|
30
|
+
end
|
|
31
|
+
sequeldb.create_table! :sequel_simple_models_sequel_tag_models do
|
|
32
|
+
Integer :sequel_simple_model_id
|
|
33
|
+
Integer :tag_id
|
|
18
34
|
end
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
sequeldb[:sequel_other_models] << { id: 22 }
|
|
40
|
-
|
|
41
|
-
sequeldb[:sequel_tag_models] << { id: 1 , tag_name: 'blue' }
|
|
42
|
-
sequeldb[:sequel_tag_models] << { id: 2 , tag_name: 'red' }
|
|
43
|
-
|
|
44
|
-
# Simple model 1 is tagged as blue and red
|
|
45
|
-
sequeldb[:sequel_simple_models_sequel_tag_models] << { sequel_simple_model_id: 1, tag_id: 1 }
|
|
46
|
-
sequeldb[:sequel_simple_models_sequel_tag_models] << { sequel_simple_model_id: 1, tag_id: 2 }
|
|
47
|
-
# Simple model 2 is tagged as red
|
|
48
|
-
sequeldb[:sequel_simple_models_sequel_tag_models] << { sequel_simple_model_id: 2, tag_id: 2 }
|
|
49
|
-
|
|
50
|
-
# It's weird to have a parent id and parent uuid (which points to different actual parents)
|
|
51
|
-
# But it allows us to check pointing to both PKs and not PK columns
|
|
52
|
-
sequeldb[:sequel_simple_models] << { id: 1 , simple_name: 'Simple1', parent_id: 1, other_model_id: 11, parent_uuid: 'deadbeef1'}
|
|
53
|
-
sequeldb[:sequel_simple_models] << { id: 2 , simple_name: 'Simple2', parent_id: 2, other_model_id: 22, parent_uuid: 'deadbeef1'}
|
|
35
|
+
|
|
36
|
+
sequeldb[:sequel_parent_models] << { id: 1, uuid: 'deadbeef1' }
|
|
37
|
+
sequeldb[:sequel_parent_models] << { id: 2, uuid: 'deadbeef2' }
|
|
38
|
+
|
|
39
|
+
sequeldb[:sequel_other_models] << { id: 11 }
|
|
40
|
+
sequeldb[:sequel_other_models] << { id: 22 }
|
|
41
|
+
|
|
42
|
+
sequeldb[:sequel_tag_models] << { id: 1, tag_name: 'blue' }
|
|
43
|
+
sequeldb[:sequel_tag_models] << { id: 2, tag_name: 'red' }
|
|
44
|
+
|
|
45
|
+
# Simple model 1 is tagged as blue and red
|
|
46
|
+
sequeldb[:sequel_simple_models_sequel_tag_models] << { sequel_simple_model_id: 1, tag_id: 1 }
|
|
47
|
+
sequeldb[:sequel_simple_models_sequel_tag_models] << { sequel_simple_model_id: 1, tag_id: 2 }
|
|
48
|
+
# Simple model 2 is tagged as red
|
|
49
|
+
sequeldb[:sequel_simple_models_sequel_tag_models] << { sequel_simple_model_id: 2, tag_id: 2 }
|
|
50
|
+
|
|
51
|
+
# It's weird to have a parent id and parent uuid (which points to different actual parents)
|
|
52
|
+
# But it allows us to check pointing to both PKs and not PK columns
|
|
53
|
+
sequeldb[:sequel_simple_models] << { id: 1, simple_name: 'Simple1', parent_id: 1, other_model_id: 11, parent_uuid: 'deadbeef1' }
|
|
54
|
+
sequeldb[:sequel_simple_models] << { id: 2, simple_name: 'Simple2', parent_id: 2, other_model_id: 22, parent_uuid: 'deadbeef1' }
|
|
54
55
|
end
|
|
55
56
|
|
|
56
57
|
create_and_seed_tables
|
|
@@ -76,7 +77,6 @@ class SequelTagModel < Sequel::Model
|
|
|
76
77
|
include Praxis::Mapper::SequelCompat
|
|
77
78
|
end
|
|
78
79
|
|
|
79
|
-
|
|
80
80
|
# A set of resource classes for use in specs
|
|
81
81
|
class SequelBaseResource < Praxis::Mapper::Resource
|
|
82
82
|
end
|
|
@@ -100,7 +100,7 @@ class SequelSimpleResource < SequelBaseResource
|
|
|
100
100
|
|
|
101
101
|
# Forces to add an extra column (added_column)...and yet another (parent_id) that will serve
|
|
102
102
|
# to check that if that's already automatically added due to an association, it won't interfere or duplicate
|
|
103
|
-
property :parent, dependencies: [
|
|
103
|
+
property :parent, dependencies: %i[parent added_column parent_id]
|
|
104
104
|
|
|
105
105
|
property :name, dependencies: [:simple_name]
|
|
106
106
|
end
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
+
|
|
2
3
|
require 'spec_helper'
|
|
3
4
|
|
|
4
5
|
describe Praxis::FieldExpander do
|
|
5
6
|
let(:field_expander) { Praxis::FieldExpander.new }
|
|
6
7
|
let(:expanded_person_default_fieldset) do
|
|
7
8
|
# The only ones that are not already leaves is the full name, which can expand to first, last
|
|
8
|
-
PersonBlueprint.default_fieldset.merge!(full_name: {first: true, last: true})
|
|
9
|
+
PersonBlueprint.default_fieldset.merge!(full_name: { first: true, last: true })
|
|
9
10
|
end
|
|
10
11
|
let(:expanded_address_default_fieldset) do
|
|
11
12
|
# AddressBlueprint' default fieldset already has all attributes as leaves
|
|
@@ -96,20 +97,20 @@ describe Praxis::FieldExpander do
|
|
|
96
97
|
|
|
97
98
|
context 'expanding a two-dimensional collection' do
|
|
98
99
|
it 'expands the fields discarding the collection nexting nesting' do
|
|
99
|
-
matrix_type =
|
|
100
|
+
matrix_type = Attributor::Collection.of(Attributor::Collection.of(FullName))
|
|
100
101
|
expect(field_expander.expand(matrix_type)).to eq(first: true, last: true)
|
|
101
102
|
end
|
|
102
103
|
end
|
|
103
104
|
|
|
104
105
|
context 'circular expansions' do
|
|
105
106
|
it 'preserve field object identity for circular references' do
|
|
106
|
-
result = field_expander.expand(PersonBlueprint, address: {resident: true}, work_address: {resident: true})
|
|
107
|
+
result = field_expander.expand(PersonBlueprint, address: { resident: true }, work_address: { resident: true })
|
|
107
108
|
expect(result[:address][:resident]).to be(result[:work_address][:resident])
|
|
108
109
|
end
|
|
109
110
|
|
|
110
111
|
context 'with collections of Blueprints' do
|
|
111
112
|
it 'still preserves object identity' do
|
|
112
|
-
result = field_expander.expand(PersonBlueprint, address: {resident: true}, prior_addresses: {resident: true})
|
|
113
|
+
result = field_expander.expand(PersonBlueprint, address: { resident: true }, prior_addresses: { resident: true })
|
|
113
114
|
expect(result[:address][:resident]).to be(result[:prior_addresses][:resident])
|
|
114
115
|
end
|
|
115
116
|
end
|
|
@@ -146,4 +147,4 @@ describe Praxis::FieldExpander do
|
|
|
146
147
|
expect(field_expander.expand(type, true)).to eq(expected)
|
|
147
148
|
end
|
|
148
149
|
end
|
|
149
|
-
end
|
|
150
|
+
end
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'spec_helper'
|
|
2
4
|
|
|
3
5
|
describe Praxis::FileGroup do
|
|
4
6
|
let(:app) { Praxis::Application.instance }
|
|
5
7
|
let(:layout) { app.file_layout }
|
|
6
8
|
|
|
7
|
-
context '#initialize' do
|
|
9
|
+
context '#initialize' do
|
|
8
10
|
it 'raises an error if given nil for the base path' do
|
|
9
11
|
expect { Praxis::FileGroup.new(nil) }.to raise_error(ArgumentError)
|
|
10
12
|
end
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'spec_helper'
|
|
2
4
|
|
|
3
5
|
describe Praxis::Handlers::JSON do
|
|
4
|
-
let(:dictionary) { {
|
|
6
|
+
let(:dictionary) { { 'foo' => 1 } }
|
|
5
7
|
let(:dictionary_json) { '{"foo":1}' }
|
|
6
8
|
|
|
7
|
-
let(:array) { [1,2,3] }
|
|
9
|
+
let(:array) { [1, 2, 3] }
|
|
8
10
|
let(:array_json) { '[1,2,3]' }
|
|
9
11
|
|
|
10
12
|
describe '#parse' do
|
|
@@ -14,14 +16,13 @@ describe Praxis::Handlers::JSON do
|
|
|
14
16
|
|
|
15
17
|
it 'handles arrays' do
|
|
16
18
|
expect(subject.parse(array_json)).to eq(array)
|
|
17
|
-
|
|
18
19
|
end
|
|
19
20
|
end
|
|
20
21
|
|
|
21
22
|
# slightly cheesy: use #parse to test #generate by round-tripping everything
|
|
22
23
|
describe '#generate' do
|
|
23
24
|
it 'pretty-prints' do
|
|
24
|
-
result = subject.generate({
|
|
25
|
+
result = subject.generate({ 'foo' => 1 })
|
|
25
26
|
expect(result).to include("\n")
|
|
26
27
|
expect(result).to match(/^ /m)
|
|
27
28
|
end
|
|
@@ -34,4 +35,4 @@ describe Praxis::Handlers::JSON do
|
|
|
34
35
|
expect(subject.parse(subject.generate(array))).to eq(array)
|
|
35
36
|
end
|
|
36
37
|
end
|
|
37
|
-
end
|
|
38
|
+
end
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'spec_helper'
|
|
2
4
|
|
|
3
5
|
describe Praxis::Mapper::Resource do
|
|
4
6
|
let(:parent_record) { ParentModel.new(id: 100, name: 'george sr') }
|
|
5
|
-
let(:parent_records) { [ParentModel.new(id: 101, name:
|
|
7
|
+
let(:parent_records) { [ParentModel.new(id: 101, name: 'georgia'), ParentModel.new(id: 102, name: 'georgina')] }
|
|
6
8
|
let(:record) { SimpleModel.new(id: 103, name: 'george xvi') }
|
|
7
|
-
let(:model) { SimpleModel}
|
|
9
|
+
let(:model) { SimpleModel }
|
|
8
10
|
|
|
9
11
|
context 'configuration' do
|
|
10
12
|
subject(:resource) { SimpleResource }
|
|
@@ -30,10 +32,10 @@ describe Praxis::Mapper::Resource do
|
|
|
30
32
|
context 'retrieving resources' do
|
|
31
33
|
context 'getting a single resource' do
|
|
32
34
|
before do
|
|
33
|
-
|
|
35
|
+
expect(SimpleModel).to receive(:get).with(name: 'george xvi').and_return(record)
|
|
34
36
|
end
|
|
35
37
|
|
|
36
|
-
subject(:resource) { SimpleResource.get(:
|
|
38
|
+
subject(:resource) { SimpleResource.get(name: 'george xvi') }
|
|
37
39
|
|
|
38
40
|
it { is_expected.to be_kind_of(SimpleResource) }
|
|
39
41
|
|
|
@@ -45,7 +47,7 @@ describe Praxis::Mapper::Resource do
|
|
|
45
47
|
expect(SimpleModel).to receive(:all).with(name: ['george xvi']).and_return([record])
|
|
46
48
|
end
|
|
47
49
|
|
|
48
|
-
subject(:resource_collection) { SimpleResource.all(:
|
|
50
|
+
subject(:resource_collection) { SimpleResource.all(name: ['george xvi']) }
|
|
49
51
|
|
|
50
52
|
it { is_expected.to be_kind_of(Array) }
|
|
51
53
|
|
|
@@ -58,7 +60,6 @@ describe Praxis::Mapper::Resource do
|
|
|
58
60
|
end
|
|
59
61
|
|
|
60
62
|
context 'delegating to the underlying model' do
|
|
61
|
-
|
|
62
63
|
subject { SimpleResource.new(record) }
|
|
63
64
|
|
|
64
65
|
it 'does respond_to attributes in the model' do
|
|
@@ -66,13 +67,13 @@ describe Praxis::Mapper::Resource do
|
|
|
66
67
|
end
|
|
67
68
|
|
|
68
69
|
it 'does not respond_to :id if the model does not have it' do
|
|
69
|
-
resource = OtherResource.new(OtherModel.new(:
|
|
70
|
+
resource = OtherResource.new(OtherModel.new(name: 'foo'))
|
|
70
71
|
expect(resource).not_to respond_to(:id)
|
|
71
72
|
end
|
|
72
73
|
|
|
73
74
|
it 'returns raw results for simple attributes' do
|
|
74
75
|
expect(record).to receive(:name).and_call_original
|
|
75
|
-
expect(subject.name).to eq(
|
|
76
|
+
expect(subject.name).to eq('george xvi')
|
|
76
77
|
end
|
|
77
78
|
|
|
78
79
|
it 'wraps model objects in Resource instances' do
|
|
@@ -81,14 +82,14 @@ describe Praxis::Mapper::Resource do
|
|
|
81
82
|
parent = subject.parent
|
|
82
83
|
|
|
83
84
|
expect(parent).to be_kind_of(ParentResource)
|
|
84
|
-
expect(parent.name).to eq(
|
|
85
|
+
expect(parent.name).to eq('george sr')
|
|
85
86
|
expect(parent.record).to eq(parent_record)
|
|
86
87
|
end
|
|
87
88
|
|
|
88
|
-
context
|
|
89
|
-
let(:record) { YamlArrayModel.new(:
|
|
89
|
+
context 'for serialized array associations' do
|
|
90
|
+
let(:record) { YamlArrayModel.new(id: 1) }
|
|
90
91
|
|
|
91
|
-
subject { YamlArrayResource.new(record)}
|
|
92
|
+
subject { YamlArrayResource.new(record) }
|
|
92
93
|
|
|
93
94
|
it 'wraps arrays of model objects in an array of resource instances' do
|
|
94
95
|
expect(record).to receive(:parents).and_return(parent_records)
|
|
@@ -98,34 +99,33 @@ describe Praxis::Mapper::Resource do
|
|
|
98
99
|
expect(parents).to be_kind_of(Array)
|
|
99
100
|
|
|
100
101
|
parents.each { |parent| expect(parent).to be_kind_of(ParentResource) }
|
|
101
|
-
expect(parents.collect
|
|
102
|
+
expect(parents.collect(&:record)).to match_array(parent_records)
|
|
102
103
|
end
|
|
103
104
|
end
|
|
104
105
|
end
|
|
105
106
|
|
|
106
107
|
context 'resource_delegate' do
|
|
107
|
-
let(:other_name) {
|
|
108
|
-
let(:other_attribute) {
|
|
109
|
-
let(:other_record) { OtherModel.new(:
|
|
108
|
+
let(:other_name) { 'foo' }
|
|
109
|
+
let(:other_attribute) { 'other value' }
|
|
110
|
+
let(:other_record) { OtherModel.new(name: other_name, other_attribute: other_attribute) }
|
|
110
111
|
let(:other_resource) { OtherResource.new(other_record) }
|
|
111
112
|
|
|
112
|
-
let(:record) { SimpleModel.new(id: 105, name:
|
|
113
|
+
let(:record) { SimpleModel.new(id: 105, name: 'george xvi', other_name: other_name) }
|
|
113
114
|
|
|
114
115
|
subject(:resource) { SimpleResource.new(record) }
|
|
115
|
-
|
|
116
|
+
|
|
116
117
|
it 'delegates to the target' do
|
|
117
118
|
expect(record).to receive(:other_model).and_return(other_record)
|
|
118
119
|
expect(resource.other_attribute).to eq(other_attribute)
|
|
119
120
|
end
|
|
120
121
|
end
|
|
121
122
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
let(:
|
|
125
|
-
let(:
|
|
126
|
-
let(:other_record) { OtherModel.new(:name => other_name, :other_attribute => other_attribute)}
|
|
123
|
+
context 'memoized resource creation' do
|
|
124
|
+
let(:other_name) { 'foo' }
|
|
125
|
+
let(:other_attribute) { 'other value' }
|
|
126
|
+
let(:other_record) { OtherModel.new(name: other_name, other_attribute: other_attribute) }
|
|
127
127
|
let(:other_resource) { OtherResource.new(other_record) }
|
|
128
|
-
let(:record) { SimpleModel.new(id: 105, name:
|
|
128
|
+
let(:record) { SimpleModel.new(id: 105, name: 'george xvi', other_name: other_name) }
|
|
129
129
|
|
|
130
130
|
subject(:resource) { SimpleResource.new(record) }
|
|
131
131
|
|
|
@@ -134,10 +134,21 @@ describe Praxis::Mapper::Resource do
|
|
|
134
134
|
expect(resource.other_resource).to be(SimpleResource.new(record).other_resource)
|
|
135
135
|
end
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
it 'memoizes result of related associations' do
|
|
138
|
+
expect(record).to receive(:parent).once.and_return(parent_record)
|
|
139
|
+
expect(resource.parent).to be(resource.parent)
|
|
140
|
+
end
|
|
138
141
|
|
|
142
|
+
it 'can clear memoization' do
|
|
143
|
+
expect(record).to receive(:parent).twice.and_return(parent_record)
|
|
139
144
|
|
|
140
|
-
|
|
145
|
+
expect(resource.parent).to be(resource.parent) # One time only calling the record parent method
|
|
146
|
+
resource.clear_memoization
|
|
147
|
+
expect(resource.parent).to be(resource.parent) # One time only time calling the record parent method after the reset
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
context '.wrap' do
|
|
141
152
|
it 'memoizes resource creation' do
|
|
142
153
|
expect(SimpleResource.wrap(record)).to be(SimpleResource.wrap(record))
|
|
143
154
|
end
|
|
@@ -153,9 +164,9 @@ describe Praxis::Mapper::Resource do
|
|
|
153
164
|
expect(wrapped_set).to be_kind_of(Array)
|
|
154
165
|
expect(wrapped_set.length).to be(1)
|
|
155
166
|
end
|
|
156
|
-
|
|
167
|
+
|
|
157
168
|
it 'works with non-enumerable objects, that respond to collect' do
|
|
158
|
-
collectable = double(
|
|
169
|
+
collectable = double('ArrayProxy', to_a: [record, record])
|
|
159
170
|
|
|
160
171
|
wrapped_set = SimpleResource.wrap(collectable)
|
|
161
172
|
expect(wrapped_set.length).to be(2)
|
|
@@ -165,5 +176,4 @@ describe Praxis::Mapper::Resource do
|
|
|
165
176
|
expect(SimpleResource.wrap(record)).to be(OtherResource.wrap(record))
|
|
166
177
|
end
|
|
167
178
|
end
|
|
168
|
-
|
|
169
179
|
end
|