cuprum-rails 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +145 -0
- data/DEVELOPMENT.md +20 -0
- data/README.md +356 -63
- data/lib/cuprum/rails/action.rb +32 -16
- data/lib/cuprum/rails/actions/create.rb +62 -15
- data/lib/cuprum/rails/actions/destroy.rb +23 -7
- data/lib/cuprum/rails/actions/edit.rb +23 -7
- data/lib/cuprum/rails/actions/index.rb +30 -10
- data/lib/cuprum/rails/actions/middleware/associations/cache.rb +112 -0
- data/lib/cuprum/rails/actions/middleware/associations/find.rb +23 -0
- data/lib/cuprum/rails/actions/middleware/associations/parent.rb +70 -0
- data/lib/cuprum/rails/actions/middleware/associations/query.rb +140 -0
- data/lib/cuprum/rails/actions/middleware/associations.rb +12 -0
- data/lib/cuprum/rails/actions/middleware/log_request.rb +126 -0
- data/lib/cuprum/rails/actions/middleware/log_result.rb +51 -0
- data/lib/cuprum/rails/actions/middleware/resources/find.rb +44 -0
- data/lib/cuprum/rails/actions/middleware/resources/query.rb +91 -0
- data/lib/cuprum/rails/actions/middleware/resources.rb +11 -0
- data/lib/cuprum/rails/actions/middleware.rb +13 -0
- data/lib/cuprum/rails/actions/new.rb +16 -4
- data/lib/cuprum/rails/actions/parameter_validation.rb +60 -0
- data/lib/cuprum/rails/actions/resource_action.rb +119 -42
- data/lib/cuprum/rails/actions/show.rb +23 -7
- data/lib/cuprum/rails/actions/update.rb +70 -22
- data/lib/cuprum/rails/actions.rb +11 -7
- data/lib/cuprum/rails/collection.rb +27 -47
- data/lib/cuprum/rails/command.rb +3 -1
- data/lib/cuprum/rails/commands/destroy_one.rb +10 -6
- data/lib/cuprum/rails/commands/find_many.rb +8 -1
- data/lib/cuprum/rails/commands/find_matching.rb +1 -1
- data/lib/cuprum/rails/commands/find_one.rb +8 -0
- data/lib/cuprum/rails/commands/insert_one.rb +17 -6
- data/lib/cuprum/rails/commands/update_one.rb +16 -5
- data/lib/cuprum/rails/constraints/parameters_contract.rb +14 -0
- data/lib/cuprum/rails/constraints.rb +10 -0
- data/lib/cuprum/rails/controller.rb +12 -2
- data/lib/cuprum/rails/controllers/action.rb +100 -0
- data/lib/cuprum/rails/controllers/class_methods/actions.rb +33 -7
- data/lib/cuprum/rails/controllers/class_methods/configuration.rb +36 -0
- data/lib/cuprum/rails/controllers/class_methods/middleware.rb +88 -0
- data/lib/cuprum/rails/controllers/class_methods/validations.rb +2 -2
- data/lib/cuprum/rails/controllers/configuration.rb +41 -1
- data/lib/cuprum/rails/controllers/middleware.rb +59 -0
- data/lib/cuprum/rails/controllers.rb +2 -0
- data/lib/cuprum/rails/errors/invalid_parameters.rb +55 -0
- data/lib/cuprum/rails/errors/invalid_statement.rb +11 -0
- data/lib/cuprum/rails/errors/missing_parameter.rb +42 -0
- data/lib/cuprum/rails/errors/resource_error.rb +46 -0
- data/lib/cuprum/rails/errors.rb +6 -1
- data/lib/cuprum/rails/map_errors.rb +29 -1
- data/lib/cuprum/rails/query.rb +1 -1
- data/lib/cuprum/rails/repository.rb +12 -25
- data/lib/cuprum/rails/request.rb +149 -60
- data/lib/cuprum/rails/resource.rb +119 -85
- data/lib/cuprum/rails/responders/base_responder.rb +78 -0
- data/lib/cuprum/rails/responders/html/plural_resource.rb +9 -39
- data/lib/cuprum/rails/responders/html/rendering.rb +81 -0
- data/lib/cuprum/rails/responders/html/resource.rb +107 -0
- data/lib/cuprum/rails/responders/html/singular_resource.rb +9 -38
- data/lib/cuprum/rails/responders/html.rb +2 -0
- data/lib/cuprum/rails/responders/html_responder.rb +8 -52
- data/lib/cuprum/rails/responders/json/resource.rb +3 -3
- data/lib/cuprum/rails/responders/json_responder.rb +31 -16
- data/lib/cuprum/rails/responders/matching.rb +29 -27
- data/lib/cuprum/rails/responders/serialization.rb +11 -9
- data/lib/cuprum/rails/responders.rb +1 -0
- data/lib/cuprum/rails/responses/head_response.rb +24 -0
- data/lib/cuprum/rails/responses/html/redirect_back_response.rb +55 -0
- data/lib/cuprum/rails/responses/html/redirect_response.rb +19 -4
- data/lib/cuprum/rails/responses/html/render_response.rb +17 -5
- data/lib/cuprum/rails/responses/html.rb +6 -2
- data/lib/cuprum/rails/responses.rb +1 -0
- data/lib/cuprum/rails/result.rb +36 -0
- data/lib/cuprum/rails/routes.rb +36 -23
- data/lib/cuprum/rails/rspec/contract_helpers.rb +57 -0
- data/lib/cuprum/rails/rspec/contracts/action_contracts.rb +754 -0
- data/lib/cuprum/rails/rspec/contracts/actions/create_contracts.rb +289 -0
- data/lib/cuprum/rails/rspec/contracts/actions/destroy_contracts.rb +164 -0
- data/lib/cuprum/rails/rspec/contracts/actions/edit_contracts.rb +73 -0
- data/lib/cuprum/rails/rspec/contracts/actions/index_contracts.rb +108 -0
- data/lib/cuprum/rails/rspec/contracts/actions/new_contracts.rb +111 -0
- data/lib/cuprum/rails/rspec/contracts/actions/show_contracts.rb +72 -0
- data/lib/cuprum/rails/rspec/contracts/actions/update_contracts.rb +263 -0
- data/lib/cuprum/rails/rspec/contracts/actions.rb +8 -0
- data/lib/cuprum/rails/rspec/contracts/command_contracts.rb +479 -0
- data/lib/cuprum/rails/rspec/contracts/responder_contracts.rb +232 -0
- data/lib/cuprum/rails/rspec/contracts/routes_contracts.rb +363 -0
- data/lib/cuprum/rails/rspec/contracts/serializers_contracts.rb +70 -0
- data/lib/cuprum/rails/rspec/contracts.rb +8 -0
- data/lib/cuprum/rails/rspec/matchers/be_a_result_matcher.rb +64 -0
- data/lib/cuprum/rails/rspec/matchers.rb +41 -0
- data/lib/cuprum/rails/serializers/base_serializer.rb +60 -0
- data/lib/cuprum/rails/serializers/context.rb +84 -0
- data/lib/cuprum/rails/serializers/json/active_record_serializer.rb +2 -2
- data/lib/cuprum/rails/serializers/json/array_serializer.rb +9 -8
- data/lib/cuprum/rails/serializers/json/attributes_serializer.rb +95 -172
- data/lib/cuprum/rails/serializers/json/error_serializer.rb +2 -2
- data/lib/cuprum/rails/serializers/json/hash_serializer.rb +9 -8
- data/lib/cuprum/rails/serializers/json/identity_serializer.rb +3 -3
- data/lib/cuprum/rails/serializers/json/properties_serializer.rb +252 -0
- data/lib/cuprum/rails/serializers/json.rb +2 -1
- data/lib/cuprum/rails/serializers.rb +3 -1
- data/lib/cuprum/rails/version.rb +1 -1
- data/lib/cuprum/rails.rb +19 -16
- metadata +73 -131
- data/lib/cuprum/rails/controller_action.rb +0 -121
- data/lib/cuprum/rails/errors/missing_parameters.rb +0 -33
- data/lib/cuprum/rails/errors/missing_primary_key.rb +0 -46
- data/lib/cuprum/rails/errors/undefined_permitted_attributes.rb +0 -34
- data/lib/cuprum/rails/rspec/command_contract.rb +0 -460
- data/lib/cuprum/rails/rspec/define_route_contract.rb +0 -84
- data/lib/cuprum/rails/serializers/json/serializer.rb +0 -66
@@ -1,121 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'forwardable'
|
4
|
-
|
5
|
-
require 'cuprum/rails'
|
6
|
-
|
7
|
-
module Cuprum::Rails
|
8
|
-
# @api private
|
9
|
-
#
|
10
|
-
# Implements a controller action.
|
11
|
-
#
|
12
|
-
# @note This class should not be initialized directly. Instead, use the
|
13
|
-
# Cuprum::Rails::Controller.action class method to define an action.
|
14
|
-
class ControllerAction
|
15
|
-
extend Forwardable
|
16
|
-
|
17
|
-
# @param configuration [Cuprum::Rails::Controllers::Configuration] the
|
18
|
-
# configuration for the originating controller.
|
19
|
-
# @param action_class [Class] The class of the action command. Must be
|
20
|
-
# constructible with keyword :resource.
|
21
|
-
# @param action_name [String, Symbol] The name of the action.
|
22
|
-
# @param member_action [Boolean] True if the action acts on a collection
|
23
|
-
# item, not on the collection as a whole.
|
24
|
-
# @param serializers
|
25
|
-
# [Hash<Class, Object>, Hash<Symbol, Hash<Class, Object>>] The serializers
|
26
|
-
# for converting result values into serialized data.
|
27
|
-
def initialize(
|
28
|
-
configuration,
|
29
|
-
action_class:,
|
30
|
-
action_name:,
|
31
|
-
member_action: false,
|
32
|
-
serializers: {}
|
33
|
-
)
|
34
|
-
@configuration = configuration
|
35
|
-
@action_class = action_class
|
36
|
-
@action_name = action_name
|
37
|
-
@member_action = !!member_action # rubocop:disable Style/DoubleNegation
|
38
|
-
@serializers = serializers
|
39
|
-
end
|
40
|
-
|
41
|
-
# @return [Class] the class of the action command.
|
42
|
-
attr_reader :action_class
|
43
|
-
|
44
|
-
# @return [String, Symbol] the name of the action.
|
45
|
-
attr_reader :action_name
|
46
|
-
|
47
|
-
# @return [Cuprum::Rails::Controllers::Configuration] the configuration for
|
48
|
-
# the originating controller.
|
49
|
-
attr_reader :configuration
|
50
|
-
|
51
|
-
# @return [Hash<Class, Object>, Hash<Symbol, Hash<Class, Object>>] the
|
52
|
-
# serializers for converting result values into serialized data.
|
53
|
-
attr_reader :serializers
|
54
|
-
|
55
|
-
# @!method resource
|
56
|
-
# @return [Cuprum::Rails::Resource] the resource defined for the
|
57
|
-
# controller.
|
58
|
-
|
59
|
-
# @!method responder_for(format)
|
60
|
-
# Finds the configured responder for the requested format.
|
61
|
-
#
|
62
|
-
# @param format [Symbol] The format to respond to.
|
63
|
-
#
|
64
|
-
# @return [Class] the responder class defined for the format.
|
65
|
-
#
|
66
|
-
# @raise [Cuprum::Rails::Controller::UnknownFormatError] if the controller
|
67
|
-
# does not define a responder for the given format.
|
68
|
-
|
69
|
-
def_delegators :@configuration,
|
70
|
-
:resource,
|
71
|
-
:responder_for
|
72
|
-
|
73
|
-
# Executes the controller action.
|
74
|
-
#
|
75
|
-
# 1. Initializes the action command with the resource.
|
76
|
-
# 2. Calls the command with the request.
|
77
|
-
# 3. Builds the responder with the resource and action metadata.
|
78
|
-
# 4. Calls the responder with the action result.
|
79
|
-
#
|
80
|
-
# @param request [ActionDispatch::Request] The request to process.
|
81
|
-
#
|
82
|
-
# @return [#call] The response object.
|
83
|
-
def call(request)
|
84
|
-
responder = build_responder(request)
|
85
|
-
action = action_class.new(resource: resource)
|
86
|
-
result = action.call(request: request)
|
87
|
-
|
88
|
-
responder.call(result)
|
89
|
-
end
|
90
|
-
|
91
|
-
# @return [Boolean] true if the action acts on a collection item, not on the
|
92
|
-
# collection as a whole.
|
93
|
-
def member_action?
|
94
|
-
@member_action
|
95
|
-
end
|
96
|
-
|
97
|
-
private
|
98
|
-
|
99
|
-
def build_responder(request)
|
100
|
-
responder_class = responder_for(request.format)
|
101
|
-
|
102
|
-
responder_class.new(
|
103
|
-
action_name: action_name,
|
104
|
-
member_action: member_action?,
|
105
|
-
resource: resource,
|
106
|
-
serializers: merge_serializers_for(request.format)
|
107
|
-
)
|
108
|
-
end
|
109
|
-
|
110
|
-
def merge_serializers_for(format)
|
111
|
-
scoped_serializers(configuration.serializers, format: format)
|
112
|
-
.merge(scoped_serializers(serializers, format: format))
|
113
|
-
end
|
114
|
-
|
115
|
-
def scoped_serializers(serializers, format:)
|
116
|
-
serializers
|
117
|
-
.select { |key, _| key.is_a?(Class) }
|
118
|
-
.merge(serializers.fetch(format, {}))
|
119
|
-
end
|
120
|
-
end
|
121
|
-
end
|
@@ -1,33 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'cuprum/error'
|
4
|
-
|
5
|
-
require 'cuprum/rails/errors'
|
6
|
-
|
7
|
-
module Cuprum::Rails::Errors
|
8
|
-
# Error class when a parameters hash does not include a resource.
|
9
|
-
class MissingParameters < Cuprum::Error
|
10
|
-
# Short string used to identify the type of error.
|
11
|
-
TYPE = 'cuprum.rails.errors.missing_parameters'
|
12
|
-
|
13
|
-
# @param resource_name [Cuprum::Rails::Resource] The name of the resource.
|
14
|
-
def initialize(resource_name:)
|
15
|
-
@resource_name = resource_name
|
16
|
-
|
17
|
-
super(message: default_message, resource_name: resource_name)
|
18
|
-
end
|
19
|
-
|
20
|
-
# @return [Cuprum::Rails::Resource] the name of the resource.
|
21
|
-
attr_reader :resource_name
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def as_json_data
|
26
|
-
{ 'resource_name' => resource_name }
|
27
|
-
end
|
28
|
-
|
29
|
-
def default_message
|
30
|
-
"The #{resource_name.inspect} parameter is missing or empty"
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'cuprum/error'
|
4
|
-
|
5
|
-
require 'cuprum/rails/errors'
|
6
|
-
|
7
|
-
module Cuprum::Rails::Errors
|
8
|
-
# Error class when a parameters hash does not include a primary key.
|
9
|
-
class MissingPrimaryKey < Cuprum::Error
|
10
|
-
# Short string used to identify the type of error.
|
11
|
-
TYPE = 'cuprum.rails.errors.missing_primary_key'
|
12
|
-
|
13
|
-
# @param primary_key [String, Symbol] The name of the resource primary key.
|
14
|
-
# @param resource_name [Cuprum::Rails::Resource] The name of the resource.
|
15
|
-
def initialize(primary_key:, resource_name:)
|
16
|
-
@primary_key = primary_key
|
17
|
-
@resource_name = resource_name
|
18
|
-
|
19
|
-
super(
|
20
|
-
message: default_message,
|
21
|
-
primary_key: primary_key,
|
22
|
-
resource_name: resource_name
|
23
|
-
)
|
24
|
-
end
|
25
|
-
|
26
|
-
# @return [String] the name of the resource primary key.
|
27
|
-
attr_reader :primary_key
|
28
|
-
|
29
|
-
# @return [Cuprum::Rails::Resource] the name of the resource.
|
30
|
-
attr_reader :resource_name
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def as_json_data
|
35
|
-
{
|
36
|
-
'primary_key' => primary_key,
|
37
|
-
'resource_name' => resource_name
|
38
|
-
}
|
39
|
-
end
|
40
|
-
|
41
|
-
def default_message
|
42
|
-
"Unable to find #{resource_name} because the #{primary_key.inspect}" \
|
43
|
-
' parameter is missing or empty'
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,34 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'cuprum/error'
|
4
|
-
|
5
|
-
require 'cuprum/rails/errors'
|
6
|
-
|
7
|
-
module Cuprum::Rails::Errors
|
8
|
-
# Error class when a resource does not define permitted attributes.
|
9
|
-
class UndefinedPermittedAttributes < Cuprum::Error
|
10
|
-
# Short string used to identify the type of error.
|
11
|
-
TYPE = 'cuprum.rails.errors.undefined_permitted_attributes'
|
12
|
-
|
13
|
-
# @param resource_name [Cuprum::Rails::Resource] The name of the resource.
|
14
|
-
def initialize(resource_name:)
|
15
|
-
@resource_name = resource_name
|
16
|
-
|
17
|
-
super(message: default_message, resource_name: resource_name)
|
18
|
-
end
|
19
|
-
|
20
|
-
# @return [Cuprum::Rails::Resource] the name of the resource.
|
21
|
-
attr_reader :resource_name
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def as_json_data
|
26
|
-
{ 'resource_name' => resource_name }
|
27
|
-
end
|
28
|
-
|
29
|
-
def default_message
|
30
|
-
"Resource #{resource_name.inspect} does not define" \
|
31
|
-
' permitted attributes'
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
@@ -1,460 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'cuprum/rails/rspec'
|
4
|
-
|
5
|
-
require 'support/book'
|
6
|
-
require 'support/tome'
|
7
|
-
|
8
|
-
module Cuprum::Rails::RSpec
|
9
|
-
# Contract validating the behavior of a Rails command implementation.
|
10
|
-
COMMAND_CONTRACT = lambda do
|
11
|
-
describe '.subclass' do
|
12
|
-
let(:subclass) { described_class.subclass }
|
13
|
-
let(:constructor_options) do
|
14
|
-
{
|
15
|
-
record_class: Book,
|
16
|
-
optional_key: 'optional value'
|
17
|
-
}
|
18
|
-
end
|
19
|
-
|
20
|
-
it 'should define the class method' do
|
21
|
-
expect(described_class)
|
22
|
-
.to respond_to(:subclass)
|
23
|
-
.with(0).arguments
|
24
|
-
.and_any_keywords
|
25
|
-
end
|
26
|
-
|
27
|
-
it { expect(subclass).to be_a Class }
|
28
|
-
|
29
|
-
it { expect(subclass).to be < described_class }
|
30
|
-
|
31
|
-
it 'should define the constructor' do
|
32
|
-
expect(subclass)
|
33
|
-
.to respond_to(:new)
|
34
|
-
.with(0).arguments
|
35
|
-
.and_any_keywords
|
36
|
-
end
|
37
|
-
|
38
|
-
it 'should return the record class' do
|
39
|
-
expect(subclass.new(**constructor_options).record_class)
|
40
|
-
.to be record_class
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'should return the options' do
|
44
|
-
expect(subclass.new(**constructor_options).options)
|
45
|
-
.to be == { optional_key: 'optional value' }
|
46
|
-
end
|
47
|
-
|
48
|
-
describe 'with options' do
|
49
|
-
let(:default_options) do
|
50
|
-
{
|
51
|
-
record_class: Book,
|
52
|
-
custom_key: 'custom value'
|
53
|
-
}
|
54
|
-
end
|
55
|
-
let(:constructor_options) do
|
56
|
-
{
|
57
|
-
optional_key: 'optional value'
|
58
|
-
}
|
59
|
-
end
|
60
|
-
let(:subclass) { described_class.subclass(**default_options) }
|
61
|
-
|
62
|
-
it { expect(subclass).to be_a Class }
|
63
|
-
|
64
|
-
it { expect(subclass).to be < described_class }
|
65
|
-
|
66
|
-
it 'should define the constructor' do
|
67
|
-
expect(subclass)
|
68
|
-
.to respond_to(:new)
|
69
|
-
.with(0).arguments
|
70
|
-
.and_any_keywords
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'should return the record class' do
|
74
|
-
expect(subclass.new(**constructor_options).record_class)
|
75
|
-
.to be record_class
|
76
|
-
end
|
77
|
-
|
78
|
-
it 'should return the options' do
|
79
|
-
expect(subclass.new(**constructor_options).options)
|
80
|
-
.to be == {
|
81
|
-
custom_key: 'custom value',
|
82
|
-
optional_key: 'optional value'
|
83
|
-
}
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
describe '#collection_name' do
|
89
|
-
let(:expected) { record_class.name.underscore.pluralize }
|
90
|
-
|
91
|
-
include_examples 'should define reader',
|
92
|
-
:collection_name,
|
93
|
-
-> { be == expected }
|
94
|
-
|
95
|
-
context 'when initialized with collection_name: string' do
|
96
|
-
let(:collection_name) { 'books' }
|
97
|
-
let(:constructor_options) do
|
98
|
-
super().merge(collection_name: collection_name)
|
99
|
-
end
|
100
|
-
|
101
|
-
it { expect(command.collection_name).to be == collection_name }
|
102
|
-
end
|
103
|
-
|
104
|
-
context 'when initialized with collection_name: symbol' do
|
105
|
-
let(:collection_name) { :books }
|
106
|
-
let(:constructor_options) do
|
107
|
-
super().merge(collection_name: collection_name)
|
108
|
-
end
|
109
|
-
|
110
|
-
it { expect(command.collection_name).to be == collection_name.to_s }
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
describe '#member_name' do
|
115
|
-
def tools
|
116
|
-
SleepingKingStudios::Tools::Toolbelt.instance
|
117
|
-
end
|
118
|
-
|
119
|
-
include_examples 'should have reader',
|
120
|
-
:member_name,
|
121
|
-
-> { record_class.name.underscore }
|
122
|
-
|
123
|
-
context 'when initialized with collection_name: value' do
|
124
|
-
let(:collection_name) { :books }
|
125
|
-
|
126
|
-
it 'should return the singular collection name' do
|
127
|
-
expect(command.member_name)
|
128
|
-
.to be == tools.str.singularize(collection_name.to_s)
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
context 'when initialized with member_name: string' do
|
133
|
-
let(:member_name) { 'tome' }
|
134
|
-
let(:constructor_options) { super().merge(member_name: member_name) }
|
135
|
-
|
136
|
-
it 'should return the singular collection name' do
|
137
|
-
expect(command.member_name).to be member_name
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
context 'when initialized with member_name: symbol' do
|
142
|
-
let(:member_name) { :tome }
|
143
|
-
let(:constructor_options) { super().merge(member_name: member_name) }
|
144
|
-
|
145
|
-
it 'should return the singular collection name' do
|
146
|
-
expect(command.member_name).to be == member_name.to_s
|
147
|
-
end
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
describe '#options' do
|
152
|
-
let(:expected_options) do
|
153
|
-
defined?(super()) ? super() : constructor_options
|
154
|
-
end
|
155
|
-
|
156
|
-
include_examples 'should define reader',
|
157
|
-
:options,
|
158
|
-
-> { be == expected_options }
|
159
|
-
|
160
|
-
context 'when initialized with options' do
|
161
|
-
let(:constructor_options) { super().merge({ key: 'value' }) }
|
162
|
-
let(:expected_options) { super().merge({ key: 'value' }) }
|
163
|
-
|
164
|
-
it { expect(command.options).to be == expected_options }
|
165
|
-
end
|
166
|
-
end
|
167
|
-
|
168
|
-
describe '#primary_key_name' do
|
169
|
-
include_examples 'should define reader', :primary_key_name, :id
|
170
|
-
|
171
|
-
context 'with a record class with custom primary key' do
|
172
|
-
let(:record_class) { Tome }
|
173
|
-
|
174
|
-
include_examples 'should define reader', :primary_key_name, :uuid
|
175
|
-
end
|
176
|
-
end
|
177
|
-
|
178
|
-
describe '#primary_key_type' do
|
179
|
-
include_examples 'should define reader', :primary_key_type, Integer
|
180
|
-
|
181
|
-
context 'with a record class with custom primary key' do
|
182
|
-
let(:record_class) { Tome }
|
183
|
-
|
184
|
-
include_examples 'should define reader', :primary_key_type, String
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
describe '#record_class' do
|
189
|
-
include_examples 'should define reader',
|
190
|
-
:record_class,
|
191
|
-
-> { record_class }
|
192
|
-
end
|
193
|
-
|
194
|
-
describe '#validate_entity' do
|
195
|
-
let(:expected_error) do
|
196
|
-
type = record_class
|
197
|
-
contract = Stannum::Contracts::ParametersContract.new do
|
198
|
-
keyword :entity, type
|
199
|
-
end
|
200
|
-
errors = contract.errors_for(
|
201
|
-
{
|
202
|
-
arguments: [],
|
203
|
-
block: nil,
|
204
|
-
keywords: { entity: nil }
|
205
|
-
}
|
206
|
-
)
|
207
|
-
|
208
|
-
Cuprum::Collections::Errors::InvalidParameters.new(
|
209
|
-
command: command,
|
210
|
-
errors: errors
|
211
|
-
)
|
212
|
-
end
|
213
|
-
|
214
|
-
it 'should define the private method' do
|
215
|
-
expect(command)
|
216
|
-
.to respond_to(:validate_entity, true)
|
217
|
-
.with(1).argument
|
218
|
-
end
|
219
|
-
|
220
|
-
describe 'with nil' do
|
221
|
-
it 'should return a failing result' do
|
222
|
-
expect(command.send(:validate_entity, nil))
|
223
|
-
.to be_a_failing_result
|
224
|
-
.with_error(expected_error)
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
describe 'with an Object' do
|
229
|
-
it 'should return a failing result' do
|
230
|
-
expect(command.send(:validate_entity, Object.new.freeze))
|
231
|
-
.to be_a_failing_result
|
232
|
-
.with_error(expected_error)
|
233
|
-
end
|
234
|
-
end
|
235
|
-
|
236
|
-
describe 'with an invalid record instance' do
|
237
|
-
it 'should return a failing result' do
|
238
|
-
expect(command.send(:validate_entity, Tome.new))
|
239
|
-
.to be_a_failing_result
|
240
|
-
.with_error(expected_error)
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
describe 'with a valid record instance' do
|
245
|
-
it 'should not return a result' do
|
246
|
-
expect(command.send(:validate_entity, Book.new))
|
247
|
-
.not_to be_a_result
|
248
|
-
end
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
describe '#validate_primary_key' do
|
253
|
-
let(:primary_key_type) { Integer }
|
254
|
-
let(:expected_error) do
|
255
|
-
type = primary_key_type
|
256
|
-
contract = Stannum::Contracts::ParametersContract.new do
|
257
|
-
keyword :primary_key, type
|
258
|
-
end
|
259
|
-
errors = contract.errors_for(
|
260
|
-
{
|
261
|
-
arguments: [],
|
262
|
-
block: nil,
|
263
|
-
keywords: { primary_key: nil }
|
264
|
-
}
|
265
|
-
)
|
266
|
-
|
267
|
-
Cuprum::Collections::Errors::InvalidParameters.new(
|
268
|
-
command: command,
|
269
|
-
errors: errors
|
270
|
-
)
|
271
|
-
end
|
272
|
-
|
273
|
-
it 'should define the private method' do
|
274
|
-
expect(command)
|
275
|
-
.to respond_to(:validate_primary_key, true)
|
276
|
-
.with(1).argument
|
277
|
-
end
|
278
|
-
|
279
|
-
describe 'with nil' do
|
280
|
-
it 'should return a failing result' do
|
281
|
-
expect(command.send(:validate_primary_key, nil))
|
282
|
-
.to be_a_failing_result
|
283
|
-
.with_error(expected_error)
|
284
|
-
end
|
285
|
-
end
|
286
|
-
|
287
|
-
describe 'with an Object' do
|
288
|
-
it 'should return a failing result' do
|
289
|
-
expect(command.send(:validate_primary_key, Object.new.freeze))
|
290
|
-
.to be_a_failing_result
|
291
|
-
.with_error(expected_error)
|
292
|
-
end
|
293
|
-
end
|
294
|
-
|
295
|
-
describe 'with a String' do
|
296
|
-
it 'should return a failing result' do
|
297
|
-
expect(command.send(:validate_primary_key, '12345'))
|
298
|
-
.to be_a_failing_result
|
299
|
-
.with_error(expected_error)
|
300
|
-
end
|
301
|
-
end
|
302
|
-
|
303
|
-
describe 'with an Integer' do
|
304
|
-
it 'should not return a result' do
|
305
|
-
expect(command.send(:validate_primary_key, 12_345)).not_to be_a_result
|
306
|
-
end
|
307
|
-
end
|
308
|
-
|
309
|
-
context 'with a record class with custom primary key' do
|
310
|
-
let(:record_class) { Tome }
|
311
|
-
let(:primary_key_type) { String }
|
312
|
-
|
313
|
-
describe 'with an Integer' do
|
314
|
-
it 'should return a failing result' do
|
315
|
-
expect(command.send(:validate_primary_key, 12_345))
|
316
|
-
.to be_a_failing_result
|
317
|
-
.with_error(expected_error)
|
318
|
-
end
|
319
|
-
end
|
320
|
-
|
321
|
-
describe 'with a String' do
|
322
|
-
it 'should not return a result' do
|
323
|
-
expect(command.send(:validate_primary_key, '12345'))
|
324
|
-
.not_to be_a_result
|
325
|
-
end
|
326
|
-
end
|
327
|
-
end
|
328
|
-
end
|
329
|
-
|
330
|
-
describe '#validate_primary_keys' do
|
331
|
-
let(:primary_keys) { nil }
|
332
|
-
let(:primary_key_type) { Integer }
|
333
|
-
let(:expected_error) do
|
334
|
-
type = primary_key_type
|
335
|
-
contract = Stannum::Contracts::ParametersContract.new do
|
336
|
-
keyword :primary_keys,
|
337
|
-
Stannum::Constraints::Types::ArrayType.new(item_type: type)
|
338
|
-
end
|
339
|
-
errors = contract.errors_for(
|
340
|
-
{
|
341
|
-
arguments: [],
|
342
|
-
block: nil,
|
343
|
-
keywords: { primary_keys: primary_keys }
|
344
|
-
}
|
345
|
-
)
|
346
|
-
|
347
|
-
Cuprum::Collections::Errors::InvalidParameters.new(
|
348
|
-
command: command,
|
349
|
-
errors: errors
|
350
|
-
)
|
351
|
-
end
|
352
|
-
|
353
|
-
it 'should define the private method' do
|
354
|
-
expect(command)
|
355
|
-
.to respond_to(:validate_primary_keys, true)
|
356
|
-
.with(1).argument
|
357
|
-
end
|
358
|
-
|
359
|
-
describe 'with nil' do
|
360
|
-
it 'should return a failing result' do
|
361
|
-
expect(command.send(:validate_primary_keys, nil))
|
362
|
-
.to be_a_failing_result
|
363
|
-
.with_error(expected_error)
|
364
|
-
end
|
365
|
-
end
|
366
|
-
|
367
|
-
describe 'with an Object' do
|
368
|
-
it 'should return a failing result' do
|
369
|
-
expect(command.send(:validate_primary_keys, Object.new.freeze))
|
370
|
-
.to be_a_failing_result
|
371
|
-
.with_error(expected_error)
|
372
|
-
end
|
373
|
-
end
|
374
|
-
|
375
|
-
describe 'with a String' do
|
376
|
-
it 'should return a failing result' do
|
377
|
-
expect(command.send(:validate_primary_keys, '12345'))
|
378
|
-
.to be_a_failing_result
|
379
|
-
.with_error(expected_error)
|
380
|
-
end
|
381
|
-
end
|
382
|
-
|
383
|
-
describe 'with an Integer' do
|
384
|
-
it 'should return a failing result' do
|
385
|
-
expect(command.send(:validate_primary_keys, 12_345))
|
386
|
-
.to be_a_failing_result
|
387
|
-
.with_error(expected_error)
|
388
|
-
end
|
389
|
-
end
|
390
|
-
|
391
|
-
describe 'with an empty Array' do
|
392
|
-
it 'should not return a result' do
|
393
|
-
expect(command.send(:validate_primary_keys, []))
|
394
|
-
.not_to be_a_result
|
395
|
-
end
|
396
|
-
end
|
397
|
-
|
398
|
-
describe 'with an Array with nil values' do
|
399
|
-
let(:primary_keys) { Array.new(3, nil) }
|
400
|
-
|
401
|
-
it 'should return a failing result' do
|
402
|
-
expect(command.send(:validate_primary_keys, primary_keys))
|
403
|
-
.to be_a_failing_result
|
404
|
-
.with_error(expected_error)
|
405
|
-
end
|
406
|
-
end
|
407
|
-
|
408
|
-
describe 'with an Array with Object values' do
|
409
|
-
let(:primary_keys) { Array.new(3) { Object.new.freeze } }
|
410
|
-
|
411
|
-
it 'should return a failing result' do
|
412
|
-
expect(command.send(:validate_primary_keys, primary_keys))
|
413
|
-
.to be_a_failing_result
|
414
|
-
.with_error(expected_error)
|
415
|
-
end
|
416
|
-
end
|
417
|
-
|
418
|
-
describe 'with an Array with String values' do
|
419
|
-
let(:primary_keys) { %w[ichi ni san] }
|
420
|
-
|
421
|
-
it 'should return a failing result' do
|
422
|
-
expect(command.send(:validate_primary_keys, primary_keys))
|
423
|
-
.to be_a_failing_result
|
424
|
-
.with_error(expected_error)
|
425
|
-
end
|
426
|
-
end
|
427
|
-
|
428
|
-
describe 'with an Array with Integer values' do
|
429
|
-
it 'should not return a result' do
|
430
|
-
expect(command.send(:validate_primary_keys, [0, 1, 2]))
|
431
|
-
.not_to be_a_result
|
432
|
-
end
|
433
|
-
end
|
434
|
-
|
435
|
-
context 'with a record class with custom primary key' do
|
436
|
-
let(:record_class) { Tome }
|
437
|
-
let(:primary_key_type) { String }
|
438
|
-
|
439
|
-
describe 'with an Array with String values' do
|
440
|
-
let(:primary_keys) { %w[ichi ni san] }
|
441
|
-
|
442
|
-
it 'should not return a result' do
|
443
|
-
expect(command.send(:validate_primary_keys, primary_keys))
|
444
|
-
.not_to be_a_result
|
445
|
-
end
|
446
|
-
end
|
447
|
-
|
448
|
-
describe 'with an Array with Integer values' do
|
449
|
-
let(:primary_keys) { [0, 1, 2] }
|
450
|
-
|
451
|
-
it 'should return a failing result' do
|
452
|
-
expect(command.send(:validate_primary_keys, primary_keys))
|
453
|
-
.to be_a_failing_result
|
454
|
-
.with_error(expected_error)
|
455
|
-
end
|
456
|
-
end
|
457
|
-
end
|
458
|
-
end
|
459
|
-
end
|
460
|
-
end
|