cuprum-collections 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +59 -0
  3. data/CODE_OF_CONDUCT.md +132 -0
  4. data/DEVELOPMENT.md +25 -0
  5. data/LICENSE +22 -0
  6. data/README.md +950 -0
  7. data/lib/cuprum/collections/base.rb +11 -0
  8. data/lib/cuprum/collections/basic/collection.rb +135 -0
  9. data/lib/cuprum/collections/basic/command.rb +112 -0
  10. data/lib/cuprum/collections/basic/commands/assign_one.rb +54 -0
  11. data/lib/cuprum/collections/basic/commands/build_one.rb +45 -0
  12. data/lib/cuprum/collections/basic/commands/destroy_one.rb +48 -0
  13. data/lib/cuprum/collections/basic/commands/find_many.rb +65 -0
  14. data/lib/cuprum/collections/basic/commands/find_matching.rb +126 -0
  15. data/lib/cuprum/collections/basic/commands/find_one.rb +49 -0
  16. data/lib/cuprum/collections/basic/commands/insert_one.rb +50 -0
  17. data/lib/cuprum/collections/basic/commands/update_one.rb +52 -0
  18. data/lib/cuprum/collections/basic/commands/validate_one.rb +69 -0
  19. data/lib/cuprum/collections/basic/commands.rb +18 -0
  20. data/lib/cuprum/collections/basic/query.rb +160 -0
  21. data/lib/cuprum/collections/basic/query_builder.rb +69 -0
  22. data/lib/cuprum/collections/basic/rspec/command_contract.rb +392 -0
  23. data/lib/cuprum/collections/basic/rspec.rb +8 -0
  24. data/lib/cuprum/collections/basic.rb +22 -0
  25. data/lib/cuprum/collections/command.rb +26 -0
  26. data/lib/cuprum/collections/commands/abstract_find_many.rb +77 -0
  27. data/lib/cuprum/collections/commands/abstract_find_matching.rb +64 -0
  28. data/lib/cuprum/collections/commands/abstract_find_one.rb +44 -0
  29. data/lib/cuprum/collections/commands.rb +8 -0
  30. data/lib/cuprum/collections/constraints/attribute_name.rb +22 -0
  31. data/lib/cuprum/collections/constraints/order/attributes_array.rb +26 -0
  32. data/lib/cuprum/collections/constraints/order/attributes_hash.rb +27 -0
  33. data/lib/cuprum/collections/constraints/order/complex_ordering.rb +46 -0
  34. data/lib/cuprum/collections/constraints/order/sort_direction.rb +32 -0
  35. data/lib/cuprum/collections/constraints/order.rb +8 -0
  36. data/lib/cuprum/collections/constraints/ordering.rb +114 -0
  37. data/lib/cuprum/collections/constraints/query_hash.rb +25 -0
  38. data/lib/cuprum/collections/constraints.rb +8 -0
  39. data/lib/cuprum/collections/errors/already_exists.rb +86 -0
  40. data/lib/cuprum/collections/errors/extra_attributes.rb +66 -0
  41. data/lib/cuprum/collections/errors/failed_validation.rb +66 -0
  42. data/lib/cuprum/collections/errors/invalid_parameters.rb +50 -0
  43. data/lib/cuprum/collections/errors/invalid_query.rb +55 -0
  44. data/lib/cuprum/collections/errors/missing_default_contract.rb +49 -0
  45. data/lib/cuprum/collections/errors/not_found.rb +81 -0
  46. data/lib/cuprum/collections/errors/unknown_operator.rb +71 -0
  47. data/lib/cuprum/collections/errors.rb +8 -0
  48. data/lib/cuprum/collections/queries/ordering.rb +74 -0
  49. data/lib/cuprum/collections/queries/parse.rb +22 -0
  50. data/lib/cuprum/collections/queries/parse_block.rb +206 -0
  51. data/lib/cuprum/collections/queries/parse_strategy.rb +91 -0
  52. data/lib/cuprum/collections/queries.rb +25 -0
  53. data/lib/cuprum/collections/query.rb +247 -0
  54. data/lib/cuprum/collections/query_builder.rb +61 -0
  55. data/lib/cuprum/collections/rspec/assign_one_command_contract.rb +168 -0
  56. data/lib/cuprum/collections/rspec/build_one_command_contract.rb +93 -0
  57. data/lib/cuprum/collections/rspec/collection_contract.rb +153 -0
  58. data/lib/cuprum/collections/rspec/destroy_one_command_contract.rb +106 -0
  59. data/lib/cuprum/collections/rspec/find_many_command_contract.rb +327 -0
  60. data/lib/cuprum/collections/rspec/find_matching_command_contract.rb +194 -0
  61. data/lib/cuprum/collections/rspec/find_one_command_contract.rb +154 -0
  62. data/lib/cuprum/collections/rspec/fixtures.rb +89 -0
  63. data/lib/cuprum/collections/rspec/insert_one_command_contract.rb +83 -0
  64. data/lib/cuprum/collections/rspec/query_builder_contract.rb +92 -0
  65. data/lib/cuprum/collections/rspec/query_contract.rb +650 -0
  66. data/lib/cuprum/collections/rspec/querying_contract.rb +298 -0
  67. data/lib/cuprum/collections/rspec/update_one_command_contract.rb +79 -0
  68. data/lib/cuprum/collections/rspec/validate_one_command_contract.rb +96 -0
  69. data/lib/cuprum/collections/rspec.rb +8 -0
  70. data/lib/cuprum/collections/version.rb +59 -0
  71. data/lib/cuprum/collections.rb +26 -0
  72. metadata +219 -0
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cuprum/collections/constraints/attribute_name'
4
+ require 'cuprum/collections/constraints/order'
5
+ require 'cuprum/collections/constraints/order/sort_direction'
6
+
7
+ module Cuprum::Collections::Constraints::Order
8
+ # Asserts that the object is a Hash of attribute names and sort directions.
9
+ class AttributesHash < Stannum::Constraints::Types::HashType
10
+ # @return [Cuprum::Collections::Constraints::Order::AttributesArray] a
11
+ # cached instance of the constraint with default options.
12
+ def self.instance
13
+ @instance ||= new
14
+ end
15
+
16
+ # @param options [Hash<Symbol, Object>] Configuration options for the
17
+ # constraint. Defaults to an empty Hash.
18
+ def initialize(**options)
19
+ super(
20
+ key_type: Cuprum::Collections::Constraints::AttributeName.instance,
21
+ value_type: Cuprum::Collections::Constraints::Order::SortDirection
22
+ .instance,
23
+ **options
24
+ )
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cuprum/collections/constraints/order'
4
+ require 'cuprum/collections/constraints/order/attributes_array'
5
+ require 'cuprum/collections/constraints/order/attributes_hash'
6
+
7
+ module Cuprum::Collections::Constraints::Order
8
+ # Asserts that the object is an attributes Array with an sort order Hash.
9
+ class ComplexOrdering < Stannum::Constraints::Base
10
+ # @return [Cuprum::Collections::Constraints::Order::AttributesArray] a
11
+ # cached instance of the constraint with default options.
12
+ def self.instance
13
+ @instance ||= new
14
+ end
15
+
16
+ # Checks that the given object is a complex ordering.
17
+ #
18
+ # A complex ordering is a data structure consisting of an Array of zero or
19
+ # more attribute names, with the last item in the array a Hash of attribute
20
+ # names and sort directions, e.g. [:title, :author, { publisher: 'asc' }].
21
+ #
22
+ # @param actual [Object] The object to match.
23
+ #
24
+ # @return [true, false] true if the object matches the expected properties
25
+ # or behavior, otherwise false.
26
+ def matches?(actual)
27
+ return false unless actual.is_a?(Array)
28
+
29
+ array = actual.dup
30
+ hash = array.pop
31
+
32
+ array_constraint.matches?(array) && hash_constraint.matches?(hash)
33
+ end
34
+ alias match? matches?
35
+
36
+ private
37
+
38
+ def array_constraint
39
+ Cuprum::Collections::Constraints::Order::AttributesArray.instance
40
+ end
41
+
42
+ def hash_constraint
43
+ Cuprum::Collections::Constraints::Order::AttributesHash.instance
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'stannum/constraints/enum'
4
+
5
+ require 'cuprum/collections/constraints/order'
6
+
7
+ module Cuprum::Collections::Constraints::Order
8
+ # Asserts that the object is a valid direction for a sort.
9
+ class SortDirection < Stannum::Constraints::Enum
10
+ # The :type of the error generated for a matching object.
11
+ NEGATED_TYPE = 'cuprum.collections.constraints.is_valid_sort_direction'
12
+
13
+ # The :type of the error generated for a non-matching object.
14
+ TYPE = 'cuprum.collections.constraints.is_not_valid_sort_direction'
15
+
16
+ # @return [Cuprum::Collections::Constraints::AttributeName] a cached
17
+ # instance of the constraint with default options.
18
+ def self.instance
19
+ @instance ||= new
20
+ end
21
+
22
+ def initialize(**options)
23
+ super(*sort_directions, **options)
24
+ end
25
+
26
+ private
27
+
28
+ def sort_directions
29
+ %w[asc ascending desc descending] + %i[asc ascending desc descending]
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cuprum/collections/constraints'
4
+
5
+ module Cuprum::Collections::Constraints
6
+ # Namespace for constraints that validate query ordering.
7
+ module Order; end
8
+ end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'stannum/constraints/types/array_type'
4
+ require 'stannum/constraints/types/hash_type'
5
+ require 'stannum/constraints/union'
6
+ require 'stannum/support/optional'
7
+
8
+ require 'cuprum/collections/constraints'
9
+ require 'cuprum/collections/constraints/attribute_name'
10
+ require 'cuprum/collections/constraints/order/attributes_array'
11
+ require 'cuprum/collections/constraints/order/attributes_hash'
12
+ require 'cuprum/collections/constraints/order/complex_ordering'
13
+
14
+ module Cuprum::Collections::Constraints
15
+ # Asserts that the object is a valid query ordering.
16
+ #
17
+ # A valid ordering can be any of the following:
18
+ # - An attribute name (a non-empty string or symbol).
19
+ # e.g. 'name' or :title
20
+ # - An array of attribute names
21
+ # e.g. ['author', 'title']
22
+ # - A hash with attribute key names, whose values are valid sort directions.
23
+ # e.g. { author: :ascending, title: :descending }
24
+ # - An array of attribute names, followed by a valid hash.
25
+ # e.g. ['author', { title: :descending }]
26
+ #
27
+ # Valid sort directions are :ascending and :descending (or :asc and :desc),
28
+ # and can be either strings or symbols.
29
+ class Ordering < Stannum::Constraints::Union
30
+ include Stannum::Support::Optional
31
+
32
+ # The :type of the error generated for a matching object.
33
+ NEGATED_TYPE = 'cuprum.collections.constraints.is_valid_ordering'
34
+
35
+ # The :type of the error generated for a non-matching object.
36
+ TYPE = 'cuprum.collections.constraints.is_not_valid_ordering'
37
+
38
+ # @return [Cuprum::Collections::Constraints::Order::AttributesArray] a
39
+ # cached instance of the constraint with default options.
40
+ def self.instance
41
+ @instance ||= new
42
+ end
43
+
44
+ # @param options [Hash<Symbol, Object>] Configuration options for the
45
+ # constraint. Defaults to an empty Hash.
46
+ def initialize(optional: nil, required: nil, **options)
47
+ super(
48
+ *ordering_constraints,
49
+ **resolve_required_option(
50
+ optional: optional,
51
+ required: required,
52
+ **options
53
+ )
54
+ )
55
+ end
56
+
57
+ # @overload errors_for(actual, errors: nil)
58
+ # Generates an errors object for the given object.
59
+ #
60
+ # @param actual [Object] The object to generate errors for.
61
+ # @param errors [Stannum::Errors] The errors object to append errors to.
62
+ # If an errors object is not given, a new errors object will be created.
63
+ #
64
+ # @return [Stannum::Errors] the given or generated errors object.
65
+ def errors_for(_actual, errors: nil)
66
+ (errors || Stannum::Errors.new).add(type)
67
+ end
68
+
69
+ # Checks that the given object matches the constraint.
70
+ #
71
+ # @param actual [Object] The object to match.
72
+ #
73
+ # @return [true, false] true if the object is a valid ordering; otherwise
74
+ # false.
75
+ def matches?(actual)
76
+ return true if optional? && actual.nil?
77
+
78
+ super
79
+ end
80
+ alias match? matches?
81
+
82
+ # @overload negated_errors_for(actual, errors: nil)
83
+ # Generates an errors object for the given object when negated.
84
+ #
85
+ # @param actual [Object] The object to generate errors for.
86
+ # @param errors [Stannum::Errors] The errors object to append errors to.
87
+ # If an errors object is not given, a new errors object will be created.
88
+ #
89
+ # @return [Stannum::Errors] the given or generated errors object.
90
+ def negated_errors_for(_actual, errors: nil)
91
+ (errors || Stannum::Errors.new).add(negated_type)
92
+ end
93
+
94
+ # Creates a copy of the constraint and updates the copy's options.
95
+ #
96
+ # @param options [Hash] The options to update.
97
+ #
98
+ # @return [Stannum::Constraints::Base] the copied constraint.
99
+ def with_options(**options)
100
+ super(**resolve_required_option(**options))
101
+ end
102
+
103
+ private
104
+
105
+ def ordering_constraints
106
+ [
107
+ Cuprum::Collections::Constraints::AttributeName.instance,
108
+ Cuprum::Collections::Constraints::Order::AttributesArray.instance,
109
+ Cuprum::Collections::Constraints::Order::AttributesHash.instance,
110
+ Cuprum::Collections::Constraints::Order::ComplexOrdering.instance
111
+ ]
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'stannum/constraints/types/hash_type'
4
+
5
+ require 'cuprum/collections/constraints'
6
+ require 'cuprum/collections/constraints/attribute_name'
7
+
8
+ module Cuprum::Collections::Constraints
9
+ # Asserts that the object is a Hash with valid attribute name keys.
10
+ class QueryHash < Stannum::Constraints::Types::HashType
11
+ def initialize(**options)
12
+ super(
13
+ allow_empty: true,
14
+ key_type: attribute_name_constraint,
15
+ **options
16
+ )
17
+ end
18
+
19
+ private
20
+
21
+ def attribute_name_constraint
22
+ Cuprum::Collections::Constraints::AttributeName.instance
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cuprum/collections'
4
+
5
+ module Cuprum::Collections
6
+ # Namespace for Stannum constraints, which are used for parameter validation.
7
+ module Constraints; end
8
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cuprum/error'
4
+
5
+ require 'cuprum/collections/errors'
6
+
7
+ module Cuprum::Collections::Errors
8
+ # Returned when an insert command is called with an existing record.
9
+ class AlreadyExists < Cuprum::Error
10
+ # Short string used to identify the type of error.
11
+ TYPE = 'cuprum.collections.errors.already_exists'
12
+
13
+ # @param collection_name [String, Symbol] The name of the collection.
14
+ # @param primary_key_name [String, Symbol] The name of the primary key
15
+ # attribute.
16
+ # @param primary_key_values [Object, Array] The expected values of the
17
+ # primary key attribute.
18
+ def initialize(collection_name:, primary_key_name:, primary_key_values:)
19
+ @collection_name = collection_name
20
+ @primary_key_name = primary_key_name
21
+ @primary_key_values = Array(primary_key_values)
22
+
23
+ super(
24
+ collection_name: collection_name,
25
+ message: default_message,
26
+ primary_key_name: primary_key_name,
27
+ primary_key_values: primary_key_values
28
+ )
29
+ end
30
+
31
+ # @return [String, Symbol] the name of the collection.
32
+ attr_reader :collection_name
33
+
34
+ # @return [String, Symbol] the name of the primary key attribute.
35
+ attr_reader :primary_key_name
36
+
37
+ # @return [Array] The expected values of the primary key attribute.
38
+ attr_reader :primary_key_values
39
+
40
+ # @return [Hash] a serializable hash representation of the error.
41
+ def as_json
42
+ {
43
+ 'data' => {
44
+ 'collection_name' => collection_name,
45
+ 'primary_key_name' => primary_key_name,
46
+ 'primary_key_values' => primary_key_values
47
+ },
48
+ 'message' => message,
49
+ 'type' => type
50
+ }
51
+ end
52
+
53
+ # @return [String] short string used to identify the type of error.
54
+ def type
55
+ TYPE
56
+ end
57
+
58
+ private
59
+
60
+ def default_message
61
+ primary_keys = primary_key_values.map(&:inspect).join(', ')
62
+
63
+ "#{entity_name} already exist#{singular? ? 's' : ''} with" \
64
+ " #{primary_key_name} #{primary_keys}"
65
+ end
66
+
67
+ def entity_name
68
+ entity_name = collection_name
69
+ entity_name = tools.str.singularize(entity_name) if singular?
70
+
71
+ titleize(entity_name)
72
+ end
73
+
74
+ def singular?
75
+ primary_key_values.size == 1
76
+ end
77
+
78
+ def titleize(string)
79
+ tools.str.underscore(string).split('_').map(&:capitalize).join(' ')
80
+ end
81
+
82
+ def tools
83
+ SleepingKingStudios::Tools::Toolbelt.instance
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cuprum/error'
4
+
5
+ require 'cuprum/collections/errors'
6
+
7
+ module Cuprum::Collections::Errors
8
+ # Error returned when assigning invalid attributes to an entity.
9
+ class ExtraAttributes < Cuprum::Error
10
+ # Short string used to identify the type of error.
11
+ TYPE = 'cuprum.collections.errors.extra_attributes'
12
+
13
+ # @param entity_class [Class] The class of the assigned entity.
14
+ # @param extra_attributes [Array<String>] The names of the extra attributes
15
+ # that were assigned to the entity.
16
+ # @param valid_attributes [Array<String>] The names of valid attributes for
17
+ # the entity.
18
+ def initialize(entity_class:, extra_attributes:, valid_attributes:)
19
+ @entity_class = entity_class
20
+ @extra_attributes = extra_attributes
21
+ @valid_attributes = valid_attributes
22
+
23
+ super(
24
+ entity_class: entity_class,
25
+ extra_attributes: extra_attributes,
26
+ message: default_message,
27
+ valid_attributes: valid_attributes
28
+ )
29
+ end
30
+
31
+ # @return [Class] the class of the assigned entity.
32
+ attr_reader :entity_class
33
+
34
+ # @return [Array<String>] The names of the extra attributes that were
35
+ # assigned to the entity.
36
+ attr_reader :extra_attributes
37
+
38
+ # @return [Array<String>] The names of valid attributes for the entity.
39
+ attr_reader :valid_attributes
40
+
41
+ # @return [Hash] a serializable hash representation of the error.
42
+ def as_json
43
+ {
44
+ 'data' => {
45
+ 'entity_class' => entity_class.name,
46
+ 'extra_attributes' => extra_attributes,
47
+ 'valid_attributes' => valid_attributes
48
+ },
49
+ 'message' => message,
50
+ 'type' => type
51
+ }
52
+ end
53
+
54
+ # @return [String] short string used to identify the type of error.
55
+ def type
56
+ TYPE
57
+ end
58
+
59
+ private
60
+
61
+ def default_message
62
+ "invalid attributes for #{entity_class.name}:" \
63
+ " #{extra_attributes.join(', ')}"
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cuprum/error'
4
+
5
+ require 'cuprum/collections/errors'
6
+
7
+ module Cuprum::Collections::Errors
8
+ # Error returned when a collection item fails validation.
9
+ class FailedValidation < Cuprum::Error
10
+ COMPARABLE_PROPERTIES = %i[entity_class errors message].freeze
11
+ private_constant :COMPARABLE_PROPERTIES
12
+
13
+ # Short string used to identify the type of error.
14
+ TYPE = 'cuprum.collections.errors.failed_validation'
15
+
16
+ # @param entity_class [Class] The class of the assigned entity.
17
+ # @param errors [Stannum::Errors] The errors generated when validating the
18
+ # entity.
19
+ def initialize(entity_class:, errors:)
20
+ @entity_class = entity_class
21
+ @errors = errors
22
+
23
+ super(
24
+ entity_class: entity_class,
25
+ errors: errors,
26
+ message: default_message
27
+ )
28
+ end
29
+
30
+ # @return [Class] the class of the assigned entity.
31
+ attr_reader :entity_class
32
+
33
+ # @return [Stannum::Errors] The errors generated when validating the entity.
34
+ attr_reader :errors
35
+
36
+ # @return [Hash] a serializable hash representation of the error.
37
+ def as_json
38
+ {
39
+ 'data' => {
40
+ 'entity_class' => entity_class.name,
41
+ 'errors' => format_errors
42
+ },
43
+ 'message' => message,
44
+ 'type' => type
45
+ }
46
+ end
47
+
48
+ # @return [String] short string used to identify the type of error.
49
+ def type
50
+ TYPE
51
+ end
52
+
53
+ private
54
+
55
+ def default_message
56
+ "#{entity_class.name} failed validation"
57
+ end
58
+
59
+ def format_errors
60
+ errors
61
+ .with_messages
62
+ .group_by_path { |err| err[:message] }
63
+ .transform_keys { |path| path.map(&:to_s).join('.') }
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cuprum/error'
4
+
5
+ require 'cuprum/collections/errors'
6
+
7
+ module Cuprum::Collections::Errors
8
+ # An error returned when a command is called with invalid parameters.
9
+ class InvalidParameters < Cuprum::Error
10
+ # Short string used to identify the type of error.
11
+ TYPE = 'cuprum.collections.errors.invalid_parameters'
12
+
13
+ # @param command [Cuprum::Command] the called command.
14
+ # @param errors [Stannum::Errors] the errors returned by the parameters
15
+ # contract.
16
+ def initialize(command:, errors:)
17
+ @command = command
18
+ @errors = errors
19
+
20
+ super(
21
+ command: command,
22
+ errors: errors,
23
+ message: "invalid parameters for command #{command.class}"
24
+ )
25
+ end
26
+
27
+ # @return [Hash] a serializable hash representation of the error.
28
+ def as_json
29
+ {
30
+ 'data' => {
31
+ 'command_class' => command.class.name,
32
+ 'errors' => errors.to_a
33
+ },
34
+ 'message' => message,
35
+ 'type' => type
36
+ }
37
+ end
38
+
39
+ # @return [Cuprum::Command] the called command.
40
+ attr_reader :command
41
+
42
+ # @return [Stannum::Errors] the errors returned by the parameters contract.
43
+ attr_reader :errors
44
+
45
+ # @return [String] short string used to identify the type of error.
46
+ def type
47
+ TYPE
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cuprum/error'
4
+
5
+ require 'cuprum/collections/errors'
6
+
7
+ module Cuprum::Collections::Errors
8
+ # An error returned when a query is created with invalid filter parameters.
9
+ class InvalidQuery < Cuprum::Error
10
+ # Short string used to identify the type of error.
11
+ TYPE = 'cuprum.collections.errors.invalid_query'
12
+
13
+ # @param errors [Stannum::Errors] The errors returned by the query builder.
14
+ # @param strategy [Symbol] The strategy used to construct the query.
15
+ def initialize(errors:, strategy:, message: nil)
16
+ @errors = errors
17
+ @strategy = strategy
18
+
19
+ super(
20
+ errors: errors,
21
+ message: message || default_message,
22
+ strategy: strategy
23
+ )
24
+ end
25
+
26
+ # @return [Stannum::Errors] the errors returned by the query builder.
27
+ attr_reader :errors
28
+
29
+ # @return [Symbol] the strategy used to construct the query.
30
+ attr_reader :strategy
31
+
32
+ # @return [Hash] a serializable hash representation of the error.
33
+ def as_json
34
+ {
35
+ 'data' => {
36
+ 'errors' => errors.to_a,
37
+ 'strategy' => strategy
38
+ },
39
+ 'message' => message,
40
+ 'type' => type
41
+ }
42
+ end
43
+
44
+ # @return [String] short string used to identify the type of error.
45
+ def type
46
+ TYPE
47
+ end
48
+
49
+ private
50
+
51
+ def default_message
52
+ "unable to parse query with strategy #{strategy.inspect}"
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'cuprum/error'
4
+
5
+ require 'cuprum/collections/errors'
6
+
7
+ module Cuprum::Collections::Errors
8
+ # Error returned when validating an entity without a contract.
9
+ class MissingDefaultContract < Cuprum::Error
10
+ # Short string used to identify the type of error.
11
+ TYPE = 'cuprum.collections.errors.missing_default_contract'
12
+
13
+ # @param entity_class [Class] The class of the assigned entity.
14
+ def initialize(entity_class:)
15
+ @entity_class = entity_class
16
+
17
+ super(
18
+ entity_class: entity_class,
19
+ message: default_message
20
+ )
21
+ end
22
+
23
+ # @return [Class] the class of the assigned entity.
24
+ attr_reader :entity_class
25
+
26
+ # @return [Hash] a serializable hash representation of the error.
27
+ def as_json
28
+ {
29
+ 'data' => {
30
+ 'entity_class' => entity_class.name
31
+ },
32
+ 'message' => message,
33
+ 'type' => type
34
+ }
35
+ end
36
+
37
+ # @return [String] short string used to identify the type of error.
38
+ def type
39
+ TYPE
40
+ end
41
+
42
+ private
43
+
44
+ def default_message
45
+ "attempted to validate a #{entity_class.name}, but #{entity_class.name}" \
46
+ ' does not define a default contract'
47
+ end
48
+ end
49
+ end