cuprum-collections 0.5.1 → 0.6.0.rc.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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +47 -0
  3. data/lib/cuprum/collections/adaptable/collection.rb +18 -0
  4. data/lib/cuprum/collections/adaptable/command.rb +22 -0
  5. data/lib/cuprum/collections/adaptable/commands/abstract_assign_one.rb +27 -0
  6. data/lib/cuprum/collections/adaptable/commands/abstract_build_one.rb +25 -0
  7. data/lib/cuprum/collections/adaptable/commands/abstract_validate_one.rb +35 -0
  8. data/lib/cuprum/collections/adaptable/commands.rb +15 -0
  9. data/lib/cuprum/collections/adaptable/query.rb +64 -0
  10. data/lib/cuprum/collections/adaptable.rb +13 -0
  11. data/lib/cuprum/collections/adapter.rb +300 -0
  12. data/lib/cuprum/collections/adapters/data_adapter.rb +82 -0
  13. data/lib/cuprum/collections/adapters/entity_adapter.rb +76 -0
  14. data/lib/cuprum/collections/adapters/hash_adapter.rb +48 -0
  15. data/lib/cuprum/collections/adapters.rb +14 -0
  16. data/lib/cuprum/collections/basic/collection.rb +2 -20
  17. data/lib/cuprum/collections/basic/commands/destroy_one.rb +1 -1
  18. data/lib/cuprum/collections/basic/commands/find_many.rb +0 -31
  19. data/lib/cuprum/collections/basic/commands/find_matching.rb +0 -94
  20. data/lib/cuprum/collections/basic/commands/find_one.rb +0 -18
  21. data/lib/cuprum/collections/basic/commands/insert_one.rb +1 -1
  22. data/lib/cuprum/collections/basic/commands/update_one.rb +1 -1
  23. data/lib/cuprum/collections/basic/scopes/criteria_scope.rb +36 -21
  24. data/lib/cuprum/collections/basic.rb +6 -5
  25. data/lib/cuprum/collections/collection.rb +6 -0
  26. data/lib/cuprum/collections/collection_command.rb +1 -1
  27. data/lib/cuprum/collections/commands/abstract_find_many.rb +40 -3
  28. data/lib/cuprum/collections/commands/abstract_find_matching.rb +102 -0
  29. data/lib/cuprum/collections/commands/abstract_find_one.rb +23 -1
  30. data/lib/cuprum/collections/commands/associations/find_many.rb +1 -3
  31. data/lib/cuprum/collections/commands/associations/require_many.rb +1 -1
  32. data/lib/cuprum/collections/commands/find_one_matching.rb +10 -10
  33. data/lib/cuprum/collections/commands/query_command.rb +6 -4
  34. data/lib/cuprum/collections/commands/upsert.rb +0 -2
  35. data/lib/cuprum/collections/constraints/order/attributes_array.rb +5 -4
  36. data/lib/cuprum/collections/constraints/order/attributes_hash.rb +5 -4
  37. data/lib/cuprum/collections/constraints/order/sort_direction.rb +2 -2
  38. data/lib/cuprum/collections/constraints/ordering.rb +11 -9
  39. data/lib/cuprum/collections/constraints/query_hash.rb +2 -2
  40. data/lib/cuprum/collections/errors/abstract_find_error.rb +101 -23
  41. data/lib/cuprum/collections/errors/extra_attributes.rb +3 -3
  42. data/lib/cuprum/collections/errors/failed_validation.rb +3 -3
  43. data/lib/cuprum/collections/errors/missing_default_contract.rb +12 -4
  44. data/lib/cuprum/collections/queries.rb +4 -0
  45. data/lib/cuprum/collections/relation.rb +0 -2
  46. data/lib/cuprum/collections/relations/parameters.rb +120 -68
  47. data/lib/cuprum/collections/repository.rb +71 -6
  48. data/lib/cuprum/collections/rspec/contracts/query_contracts.rb +23 -4
  49. data/lib/cuprum/collections/rspec/contracts/repository_contracts.rb +18 -0
  50. data/lib/cuprum/collections/rspec/contracts/scope_contracts.rb +51 -0
  51. data/lib/cuprum/collections/rspec/contracts/scopes/builder_contracts.rb +10 -0
  52. data/lib/cuprum/collections/rspec/contracts/scopes/composition_contracts.rb +8 -0
  53. data/lib/cuprum/collections/rspec/contracts/scopes/criteria_contracts.rb +18 -366
  54. data/lib/cuprum/collections/rspec/contracts/scopes/logical_contracts.rb +30 -0
  55. data/lib/cuprum/collections/rspec/contracts/scopes.rb +2 -0
  56. data/lib/cuprum/collections/rspec/contracts.rb +2 -10
  57. data/lib/cuprum/collections/rspec/deferred/adapter_examples.rb +1077 -0
  58. data/lib/cuprum/collections/rspec/deferred/collection_examples.rb +27 -7
  59. data/lib/cuprum/collections/rspec/deferred/commands/assign_one_examples.rb +4 -4
  60. data/lib/cuprum/collections/rspec/deferred/commands/build_one_examples.rb +2 -2
  61. data/lib/cuprum/collections/rspec/deferred/commands/destroy_one_examples.rb +2 -2
  62. data/lib/cuprum/collections/rspec/deferred/commands/find_many_examples.rb +5 -5
  63. data/lib/cuprum/collections/rspec/deferred/commands/find_matching_examples.rb +45 -12
  64. data/lib/cuprum/collections/rspec/deferred/commands/find_one_examples.rb +2 -2
  65. data/lib/cuprum/collections/rspec/deferred/commands/insert_one_examples.rb +1 -1
  66. data/lib/cuprum/collections/rspec/deferred/commands/update_one_examples.rb +1 -1
  67. data/lib/cuprum/collections/rspec/deferred/query_examples.rb +930 -0
  68. data/lib/cuprum/collections/rspec/deferred/relation_examples.rb +48 -17
  69. data/lib/cuprum/collections/rspec/deferred/repository_examples.rb +961 -0
  70. data/lib/cuprum/collections/rspec/deferred/scope_examples.rb +598 -0
  71. data/lib/cuprum/collections/rspec/deferred/scopes/all_examples.rb +391 -0
  72. data/lib/cuprum/collections/rspec/deferred/scopes/builder_examples.rb +857 -0
  73. data/lib/cuprum/collections/rspec/deferred/scopes/composition_examples.rb +93 -0
  74. data/lib/cuprum/collections/rspec/deferred/scopes/conjunction_examples.rb +438 -0
  75. data/lib/cuprum/collections/rspec/deferred/scopes/criteria_examples.rb +1941 -0
  76. data/lib/cuprum/collections/rspec/deferred/scopes/disjunction_examples.rb +415 -0
  77. data/lib/cuprum/collections/rspec/deferred/scopes/none_examples.rb +385 -0
  78. data/lib/cuprum/collections/rspec/deferred/scopes/parser_examples.rb +740 -0
  79. data/lib/cuprum/collections/rspec/deferred/scopes.rb +8 -0
  80. data/lib/cuprum/collections/scope.rb +2 -2
  81. data/lib/cuprum/collections/scopes/container.rb +5 -4
  82. data/lib/cuprum/collections/scopes/criteria/parser.rb +24 -48
  83. data/lib/cuprum/collections/scopes/criteria.rb +7 -6
  84. data/lib/cuprum/collections/version.rb +4 -4
  85. data/lib/cuprum/collections.rb +5 -1
  86. metadata +47 -11
  87. data/lib/cuprum/collections/rspec/contracts/association_contracts.rb +0 -2127
  88. data/lib/cuprum/collections/rspec/contracts/basic.rb +0 -11
  89. data/lib/cuprum/collections/rspec/contracts/collection_contracts.rb +0 -387
  90. data/lib/cuprum/collections/rspec/contracts/command_contracts.rb +0 -169
  91. data/lib/cuprum/collections/rspec/contracts/relation_contracts.rb +0 -1264
@@ -15,7 +15,9 @@ module Cuprum::Collections
15
15
  LESS_THAN: :less_than,
16
16
  LESS_THAN_OR_EQUAL_TO: :less_than_or_equal_to,
17
17
  NOT_EQUAL: :not_equal,
18
+ NOT_NULL: :not_null,
18
19
  NOT_ONE_OF: :not_one_of,
20
+ NULL: :null,
19
21
  ONE_OF: :one_of
20
22
  ).freeze
21
23
 
@@ -46,7 +48,9 @@ module Cuprum::Collections
46
48
  Operators::LESS_THAN => Operators::GREATER_THAN_OR_EQUAL_TO, # rubocop:disable Layout/LineLength
47
49
  Operators::LESS_THAN_OR_EQUAL_TO => Operators::GREATER_THAN,
48
50
  Operators::NOT_EQUAL => Operators::EQUAL,
51
+ Operators::NOT_NULL => Operators::NULL,
49
52
  Operators::NOT_ONE_OF => Operators::ONE_OF,
53
+ Operators::NULL => Operators::NOT_NULL,
50
54
  Operators::ONE_OF => Operators::NOT_ONE_OF
51
55
  }.freeze
52
56
 
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'set'
4
-
5
3
  require 'cuprum/collections'
6
4
  require 'cuprum/collections/relations/options'
7
5
  require 'cuprum/collections/relations/parameters'
@@ -13,40 +13,48 @@ module Cuprum::Collections::Relations
13
13
  ].freeze
14
14
  private_constant :IGNORED_PARAMETERS
15
15
 
16
- PARAMETER_KEYS = %i[entity_class name qualified_name].freeze
16
+ OPTIONAL_PARAMETER_KEYS =
17
+ %i[default_entity_class plural_name singular_name].freeze
18
+ private_constant :OPTIONAL_PARAMETER_KEYS
19
+
20
+ REQUIRED_PARAMETER_KEYS = %i[entity_class name qualified_name].freeze
21
+ private_constant :REQUIRED_PARAMETER_KEYS
22
+
23
+ PARAMETER_KEYS = (OPTIONAL_PARAMETER_KEYS + REQUIRED_PARAMETER_KEYS).freeze
17
24
  private_constant :PARAMETER_KEYS
18
25
 
19
26
  class << self # rubocop:disable Metrics/ClassLength
20
- # @overload resolve_parameters(entity_class: nil, singular_name: nil, name: nil, qualified_name: nil)
27
+ # @overload resolve_parameters(**options)
21
28
  # Helper method for resolving a Relation's required parameters.
22
29
  #
23
- # The returned Hash will define the :entity_class, :singular_name,
24
- # :name, and :qualified_name keys.
30
+ # At least one of the following options must be provided: name,
31
+ # qualified_name, or entity_class. The returned Hash will include the
32
+ # above keys as well as :singular_name and :plural_name.
25
33
  #
26
- # @param entity_class [Class, String] the class of entity represented
27
- # by the relation.
28
- # @param singular_name [String] the name of an entity in the relation.
29
- # @param name [String] the name of the relation.
30
- # @param qualified_name [String] a scoped name for the relation.
34
+ # @param options [Hash] the parameters to resolve.
35
+ #
36
+ # @option options default_entity_class [Class, String, nil] if given,
37
+ # this value will be assigned to the entity class if the entity_class
38
+ # is absent; it will *not* be used to derive other properties.
39
+ # @option options entity_class [Class, String] the class of entity
40
+ # represented by the relation.
41
+ # @option options name [String] the name of the relation.
42
+ # @option options plural_name [String] the name of a group of entities
43
+ # in the relation.
44
+ # @option options qualified_name [String] a scoped name for the
45
+ # relation.
46
+ # @option options singular_name [String] the name of an entity in the
47
+ # relation.
31
48
  #
32
49
  # @return [Hash] the resolved parameters.
33
- def resolve_parameters(params) # rubocop:disable Metrics/MethodLength
50
+ def resolve_parameters(params)
34
51
  validate_parameters(**params)
35
52
 
36
- entity_class = entity_class_from(**params)
37
- class_name = entity_class_name(entity_class)
38
- name = relation_name_from(**params, class_name:)
39
- plural_name = plural_name_from(**params, name:)
40
- qualified_name = qualified_name_from(**params, class_name:)
41
- singular_name = singular_name_from(**params, name:)
42
-
43
- {
44
- entity_class:,
45
- name:,
46
- plural_name:,
47
- qualified_name:,
48
- singular_name:
49
- }
53
+ if has_key?(params, :entity_class)
54
+ resolve_parameters_from_entity_class(**params)
55
+ else
56
+ resolve_parameters_from_name(**params)
57
+ end
50
58
  end
51
59
 
52
60
  private
@@ -59,65 +67,109 @@ module Cuprum::Collections::Relations
59
67
  .join('::')
60
68
  end
61
69
 
62
- def entity_class_from(**params)
63
- if has_key?(params, :entity_class)
64
- entity_class = params[:entity_class]
65
-
66
- return entity_class.is_a?(Class) ? entity_class : entity_class.to_s
67
- end
68
-
69
- if has_key?(params, :qualified_name)
70
- return classify(params[:qualified_name])
71
- end
72
-
73
- classify(params[:name])
74
- end
75
-
76
- def entity_class_name(entity_class, scoped: true)
77
- (entity_class.is_a?(Class) ? entity_class.name : entity_class)
78
- .split('::')
79
- .map { |str| tools.string_tools.underscore(str) }
80
- .then { |ary| scoped ? ary.join('/') : ary.last }
81
- end
82
-
83
70
  def has_key?(params, key) # rubocop:disable Naming/PredicatePrefix
84
71
  return false unless params.key?(key)
85
72
 
86
73
  !params[key].nil?
87
74
  end
88
75
 
89
- def plural_name_from(name:, **parameters)
90
- if parameters.key?(:plural_name) && !parameters[:plural_name].nil?
91
- return validate_parameter(
92
- parameters[:plural_name],
93
- as: 'plural name'
94
- )
95
- end
76
+ def resolve_entity_class(params)
77
+ entity_class =
78
+ if has_key?(params, :default_entity_class)
79
+ params[:default_entity_class]
80
+ else
81
+ classify(params[:qualified_name])
82
+ end
83
+
84
+ params.update(entity_class:)
85
+ end
86
+
87
+ def resolve_entity_name(params)
88
+ entity_class = params[:entity_class]
89
+ entity_name =
90
+ (entity_class.is_a?(Class) ? entity_class.name : entity_class)
91
+ .split('::')
92
+ .map { |str| tools.string_tools.underscore(str) }
93
+ .join('/')
96
94
 
97
- tools.string_tools.pluralize(name)
95
+ params.update(entity_name:)
98
96
  end
99
97
 
100
- def qualified_name_from(class_name:, **params)
101
- return params[:qualified_name].to_s if has_key?(params, :qualified_name)
98
+ def resolve_name(params)
99
+ name =
100
+ if has_key?(params, :name)
101
+ params[:name].to_s
102
+ elsif has_key?(params, :entity_name)
103
+ tools.string_tools.pluralize(params[:entity_name].split('/').last)
104
+ else
105
+ params[:qualified_name].split('/').last
106
+ end
107
+
108
+ params.update(name:)
109
+ end
102
110
 
103
- tools.string_tools.pluralize(class_name)
111
+ def resolve_parameters_from_entity_class(**params)
112
+ params
113
+ .slice(*PARAMETER_KEYS)
114
+ .then { |hsh| resolve_entity_name(hsh) }
115
+ .then { |hsh| resolve_qualified_name(hsh) }
116
+ .then { |hsh| resolve_name(hsh) }
117
+ .then { |hsh| resolve_plural_name(hsh) }
118
+ .then { |hsh| resolve_singular_name(hsh) }
119
+ .tap { |hsh| hsh.delete(:default_entity_class) }
120
+ .tap { |hsh| hsh.delete(:entity_name) }
104
121
  end
105
122
 
106
- def relation_name_from(class_name:, **params)
107
- return params[:name].to_s if has_key?(params, :name)
123
+ def resolve_parameters_from_name(**params)
124
+ params
125
+ .slice(*PARAMETER_KEYS)
126
+ .then { |hsh| resolve_qualified_name(hsh) }
127
+ .then { |hsh| resolve_name(hsh) }
128
+ .then { |hsh| resolve_plural_name(hsh) }
129
+ .then { |hsh| resolve_singular_name(hsh) }
130
+ .then { |hsh| resolve_entity_class(hsh) }
131
+ .tap { |hsh| hsh.delete(:default_entity_class) }
132
+ end
108
133
 
109
- tools.string_tools.pluralize(class_name.split('/').last)
134
+ def resolve_plural_name(params)
135
+ plural_name =
136
+ if has_key?(params, :plural_name)
137
+ validate_parameter(
138
+ params[:plural_name],
139
+ as: 'plural name'
140
+ )
141
+ else
142
+ tools.string_tools.pluralize(params[:name])
143
+ end
144
+
145
+ params.update(plural_name:)
110
146
  end
111
147
 
112
- def singular_name_from(name:, **parameters)
113
- if parameters.key?(:singular_name) && !parameters[:singular_name].nil?
114
- return validate_parameter(
115
- parameters[:singular_name],
116
- as: 'singular name'
117
- )
118
- end
148
+ def resolve_qualified_name(params)
149
+ qualified_name =
150
+ if has_key?(params, :qualified_name)
151
+ params[:qualified_name].to_s
152
+ elsif has_key?(params, :entity_name)
153
+ tools.string_tools.pluralize(params[:entity_name])
154
+ elsif has_key?(params, :name)
155
+ tools.string_tools.pluralize(params[:name])
156
+ end
157
+
158
+ params.update(qualified_name:)
159
+ end
119
160
 
120
- tools.string_tools.singularize(name)
161
+ def resolve_singular_name(params)
162
+ singular_name =
163
+ if has_key?(params, :singular_name)
164
+ validate_parameter(
165
+ params[:singular_name],
166
+ as: 'singular name'
167
+ )
168
+ else
169
+ tools.string_tools.singularize(params[:name])
170
+ end
171
+
172
+ params.update(singular_name:)
121
173
  end
122
174
 
123
175
  def tools
@@ -144,7 +196,7 @@ module Cuprum::Collections::Relations
144
196
  end
145
197
 
146
198
  def validate_parameter_keys(params)
147
- return if PARAMETER_KEYS.any? { |key| has_key?(params, key) }
199
+ return if REQUIRED_PARAMETER_KEYS.any? { |key| has_key?(params, key) }
148
200
 
149
201
  raise ArgumentError, "name or entity class can't be blank"
150
202
  end
@@ -14,7 +14,7 @@ module Cuprum::Collections
14
14
  # and so on. The application may instead aggregate all of its collections into
15
15
  # a single repository, relying on the shared interface of all Collection
16
16
  # implementations.
17
- class Repository
17
+ class Repository # rubocop:disable Metrics/ClassLength
18
18
  extend Forwardable
19
19
 
20
20
  # Error raised when trying to call an abstract repository method.
@@ -29,8 +29,11 @@ module Cuprum::Collections
29
29
  # Error raised when trying to access a collection that is not defined.
30
30
  class UndefinedCollectionError < StandardError; end
31
31
 
32
+ # @yieldparam [Cuprum::Collections::Repository] the created repository.
32
33
  def initialize
33
34
  @collections = {}
35
+
36
+ yield self if block_given?
34
37
  end
35
38
 
36
39
  # @!method keys
@@ -73,6 +76,8 @@ module Cuprum::Collections
73
76
  def add(collection, force: false)
74
77
  validate_collection!(collection)
75
78
 
79
+ raise FrozenError, frozen_error_message if frozen?
80
+
76
81
  if !force && key?(collection.qualified_name.to_s)
77
82
  raise DuplicateCollectionError,
78
83
  "collection #{collection.qualified_name} already exists"
@@ -84,10 +89,10 @@ module Cuprum::Collections
84
89
  end
85
90
  alias << add
86
91
 
87
- # @overload create(collection_name: nil, entity_class: nil, force: false, **options)
92
+ # @overload create(name: nil, entity_class: nil, force: false, **options)
88
93
  # Adds a new collection with the given name to the repository.
89
94
  #
90
- # @param collection_name [String] the name of the new collection.
95
+ # @param name [String] the name of the new collection.
91
96
  # @param entity_class [Class, String] the class of entity represented in
92
97
  # the collection.
93
98
  # @param force [true, false] if true, override an existing collection with
@@ -98,14 +103,31 @@ module Cuprum::Collections
98
103
  #
99
104
  # @raise [DuplicateCollectionError] if a collection with the same name
100
105
  # already exists in the repository.
101
- def create(force: false, **options)
102
- collection = build_collection(**options)
106
+ def create(force: false, **)
107
+ collection = build_collection(**)
103
108
 
104
109
  add(collection, force:)
105
110
 
106
111
  collection
107
112
  end
108
113
 
114
+ # @overload find(name: nil, entity_class: nil, **options)
115
+ def find(**parameters)
116
+ qualified_name = qualified_name_for(**parameters)
117
+ collection = @collections[qualified_name]
118
+
119
+ unless collection
120
+ raise UndefinedCollectionError,
121
+ "repository does not define collection #{qualified_name.inspect}"
122
+ end
123
+
124
+ return collection if collection.matches?(**parameters)
125
+
126
+ error_message = partial_match_error_message(collection:, parameters:)
127
+
128
+ raise DuplicateCollectionError, error_message
129
+ end
130
+
109
131
  # @overload find_or_create(collection_name: nil, entity_class: nil, **options)
110
132
  # Finds or creates a new collection with the given name.
111
133
  #
@@ -118,7 +140,12 @@ module Cuprum::Collections
118
140
  #
119
141
  # @raise [DuplicateCollectionError] if a collection with the same name
120
142
  # but different parameters already exists in the repository.
121
- def find_or_create(**parameters)
143
+ def find_or_create(**parameters) # rubocop:disable Metrics/MethodLength
144
+ tools.core_tools.deprecate(
145
+ "#{self.class.name}#find_or_create()",
146
+ message: 'Use #create or #find method.'
147
+ )
148
+
122
149
  qualified_name = qualified_name_for(**parameters)
123
150
 
124
151
  unless key?(qualified_name)
@@ -144,6 +171,22 @@ module Cuprum::Collections
144
171
  @collections.key?(qualified_name.to_s)
145
172
  end
146
173
 
174
+ # Removes the specified collection from the repository.
175
+ #
176
+ # @param qualified_name [String, Symbol] the name of the collection to
177
+ # remove.
178
+ #
179
+ # @return [Cuprum::Collections::Collection] the removed collection.
180
+ def remove(qualified_name:)
181
+ raise FrozenError, frozen_error_message if frozen?
182
+
183
+ collection = find(qualified_name:)
184
+
185
+ @collections.delete(collection.qualified_name)
186
+
187
+ collection
188
+ end
189
+
147
190
  private
148
191
 
149
192
  def build_collection(**)
@@ -152,12 +195,34 @@ module Cuprum::Collections
152
195
  'subclass and implement the #build_collection method.'
153
196
  end
154
197
 
198
+ def frozen_error_message
199
+ "can't modify frozen #{self.class.name}"
200
+ end
201
+
202
+ def partial_match_error_message(collection:, parameters:)
203
+ non_matching =
204
+ parameters
205
+ .each_key
206
+ .reject { |key| collection.public_send(key) == parameters[key] }
207
+ expected = parameters.slice(*non_matching)
208
+ actual = non_matching.to_h { |key| [key, collection.public_send(key)] }
209
+ name = collection.qualified_name.inspect
210
+
211
+ "collection #{name} exists but does not match:\n" \
212
+ "\n expected: #{expected.inspect}" \
213
+ "\n actual: #{actual.inspect}"
214
+ end
215
+
155
216
  def qualified_name_for(**parameters)
156
217
  Cuprum::Collections::Relations::Parameters
157
218
  .resolve_parameters(parameters)
158
219
  .fetch(:qualified_name)
159
220
  end
160
221
 
222
+ def tools
223
+ SleepingKingStudios::Tools::Toolbelt.instance
224
+ end
225
+
161
226
  def valid_collection?(collection)
162
227
  collection.respond_to?(:qualified_name)
163
228
  end
@@ -2,12 +2,17 @@
2
2
 
3
3
  require 'cuprum/collections/queries'
4
4
  require 'cuprum/collections/rspec/contracts'
5
+ require 'cuprum/collections/rspec/deferred/query_examples'
5
6
  require 'cuprum/collections/rspec/fixtures'
6
7
 
7
8
  module Cuprum::Collections::RSpec::Contracts
8
9
  # Contracts for asserting on Query objects.
9
10
  module QueryContracts
11
+ include Cuprum::Collections::RSpec::Deferred::QueryExamples
12
+
10
13
  # Contract validating the behavior of a Query implementation.
14
+ #
15
+ # @deprecated 0.6.0
11
16
  module ShouldBeAQuery
12
17
  extend RSpec::SleepingKingStudios::Contract
13
18
 
@@ -27,6 +32,11 @@ module Cuprum::Collections::RSpec::Contracts
27
32
  contract do |abstract: false|
28
33
  include Cuprum::Collections::RSpec::Contracts::QueryContracts
29
34
 
35
+ SleepingKingStudios::Tools::CoreTools.deprecate(
36
+ 'QueryContracts "should be a query"',
37
+ message: 'Use Deferred::QueryExamples instead.'
38
+ )
39
+
30
40
  shared_context 'when initialized with a scope' do
31
41
  let(:initial_scope) do
32
42
  Cuprum::Collections::Scope.new do |scope|
@@ -97,7 +107,8 @@ module Cuprum::Collections::RSpec::Contracts
97
107
  context 'when the collection has many items' do
98
108
  let(:data) { BOOKS_FIXTURES }
99
109
 
100
- include_contract 'should query the collection', :ignore_order do
110
+ include_deferred 'should query the collection', ignore_order: true \
111
+ do
101
112
  it { expect(scoped_query.count).to be == expected_data.count }
102
113
 
103
114
  wrap_context 'when the query has composed filters' do
@@ -167,7 +178,7 @@ module Cuprum::Collections::RSpec::Contracts
167
178
  context 'when the collection has many items' do
168
179
  let(:data) { BOOKS_FIXTURES }
169
180
 
170
- include_contract 'should query the collection' do
181
+ include_deferred 'should query the collection' do
171
182
  include_examples 'should enumerate the matching data'
172
183
 
173
184
  wrap_context 'when the query has composed filters' do
@@ -215,7 +226,8 @@ module Cuprum::Collections::RSpec::Contracts
215
226
  context 'when the collection has many items' do
216
227
  let(:data) { BOOKS_FIXTURES }
217
228
 
218
- include_contract 'should query the collection', :ignore_order do
229
+ include_deferred 'should query the collection', ignore_order: true \
230
+ do
219
231
  include_examples 'should check the existence of matching data'
220
232
 
221
233
  wrap_context 'when the query has composed filters' do
@@ -549,7 +561,7 @@ module Cuprum::Collections::RSpec::Contracts
549
561
  context 'when the collection has many items' do
550
562
  let(:data) { BOOKS_FIXTURES }
551
563
 
552
- include_contract 'should query the collection' do
564
+ include_deferred 'should query the collection' do
553
565
  it { expect(queried_data).to be == expected_data }
554
566
 
555
567
  wrap_context 'when the query has composed filters' do
@@ -766,12 +778,19 @@ module Cuprum::Collections::RSpec::Contracts
766
778
  end
767
779
 
768
780
  # Contract validating the behavior when performing queries.
781
+ #
782
+ # @deprecate 0.6.0 Use Deferred::QueryExamples instead.
769
783
  module ShouldQueryTheCollectionContract
770
784
  extend RSpec::SleepingKingStudios::Contract
771
785
 
772
786
  contract do |*tags, &examples|
773
787
  ignore_order = tags.include?(:ignore_order)
774
788
 
789
+ SleepingKingStudios::Tools::CoreTools.deprecate(
790
+ 'QueryContracts "should query the collection"',
791
+ message: 'Use Deferred::QueryExamples instead.'
792
+ )
793
+
775
794
  shared_examples 'should query the collection' do
776
795
  # :nocov:
777
796
  if examples
@@ -4,8 +4,13 @@ require 'cuprum/collections/rspec/contracts'
4
4
 
5
5
  module Cuprum::Collections::RSpec::Contracts
6
6
  # Contracts for asserting on Repository objects.
7
+ #
8
+ # @deprecated 0.6.0 Use RepositoryExamples instead.
9
+ # Note - requires defining a #build_collection(**options) helper method.
7
10
  module RepositoryContracts
8
11
  # Contract validating the behavior of a Repository.
12
+ #
13
+ # @deprecated 0.6.0
9
14
  module ShouldBeARepositoryContract
10
15
  extend RSpec::SleepingKingStudios::Contract
11
16
 
@@ -23,6 +28,14 @@ module Cuprum::Collections::RSpec::Contracts
23
28
  # @option options entity_class [Class, String] the expected entity
24
29
  # class.
25
30
  contract do |abstract: false, **options|
31
+ SleepingKingStudios::Tools::Toolbelt
32
+ .instance
33
+ .core_tools
34
+ .deprecate(
35
+ 'Cuprum::Collections::RSpec::Contracts::RepositoryContracts',
36
+ message: 'Use RepositoryExamples instead.'
37
+ )
38
+
26
39
  shared_examples 'should create the collection' do
27
40
  let(:configured_collection_class) do
28
41
  return super() if defined?(super())
@@ -443,6 +456,11 @@ module Cuprum::Collections::RSpec::Contracts
443
456
  'repository subclass and implement the #build_collection method.'
444
457
  end
445
458
 
459
+ before(:example) do
460
+ allow(SleepingKingStudios::Tools::Toolbelt.instance.core_tools)
461
+ .to receive(:deprecate)
462
+ end
463
+
446
464
  def create_collection(safe: true, **options)
447
465
  if safe
448
466
  begin
@@ -8,6 +8,8 @@ module Cuprum::Collections::RSpec::Contracts
8
8
  # Contracts for asserting on scope objects.
9
9
  module ScopeContracts
10
10
  # Contract validating the behavior of a scope implementation.
11
+ #
12
+ # @deprecated 0.6.0
11
13
  module ShouldBeAScopeContract
12
14
  extend RSpec::SleepingKingStudios::Contract
13
15
 
@@ -19,6 +21,16 @@ module Cuprum::Collections::RSpec::Contracts
19
21
  # @param invertible [Boolean] if true, the scope defines an
20
22
  # implementation of the #invert method. Defaults to false.
21
23
  contract do |invertible: false|
24
+ message = 'Use deferred examples "should implement the Scope methods"'
25
+
26
+ SleepingKingStudios::Tools::Toolbelt
27
+ .instance
28
+ .core_tools
29
+ .deprecate(
30
+ 'ShouldBeAScopeContract',
31
+ message:
32
+ )
33
+
22
34
  describe '#==' do
23
35
  it { expect(subject == nil).to be false } # rubocop:disable Style/NilComparison
24
36
 
@@ -73,6 +85,8 @@ module Cuprum::Collections::RSpec::Contracts
73
85
  end
74
86
 
75
87
  # Contract validating the behavior of a Container scope implementation.
88
+ #
89
+ # @deprecated 0.6.0
76
90
  module ShouldBeAContainerScopeContract
77
91
  extend RSpec::SleepingKingStudios::Contract
78
92
 
@@ -84,6 +98,17 @@ module Cuprum::Collections::RSpec::Contracts
84
98
  # @param invertible [Boolean] if true, the scope defines an
85
99
  # implementation of the #invert method. Defaults to false.
86
100
  contract do |invertible: false|
101
+ message =
102
+ 'Use deferred examples "should implement the Scope methods" and ' \
103
+ '"should define child scopes"'
104
+ SleepingKingStudios::Tools::Toolbelt
105
+ .instance
106
+ .core_tools
107
+ .deprecate(
108
+ 'ShouldBeADisjunctionScopeContract',
109
+ message:
110
+ )
111
+
87
112
  shared_context 'with scopes' do
88
113
  let(:scopes) do
89
114
  [
@@ -272,6 +297,8 @@ module Cuprum::Collections::RSpec::Contracts
272
297
  end
273
298
 
274
299
  # Contract validating the behavior of an All scope implementation.
300
+ #
301
+ # @deprecated 0.6.0
275
302
  module ShouldBeAnAllScopeContract
276
303
  extend RSpec::SleepingKingStudios::Contract
277
304
 
@@ -283,6 +310,17 @@ module Cuprum::Collections::RSpec::Contracts
283
310
  # @param abstract [Boolean] if true, the scope is abstract and does not
284
311
  # define a #call implementation. Defaults to false.
285
312
  contract do |abstract: false|
313
+ message =
314
+ 'Use deferred examples "should implement the AllScope methods"'
315
+
316
+ SleepingKingStudios::Tools::Toolbelt
317
+ .instance
318
+ .core_tools
319
+ .deprecate(
320
+ 'ShouldBeAnAllScopeContract',
321
+ message:
322
+ )
323
+
286
324
  include_contract 'should be a scope', invertible: true
287
325
 
288
326
  describe '#==' do
@@ -653,6 +691,8 @@ module Cuprum::Collections::RSpec::Contracts
653
691
  end
654
692
 
655
693
  # Contract validating the behavior of a None scope implementation.
694
+ #
695
+ # @deprecated 0.6.0
656
696
  module ShouldBeANoneScopeContract
657
697
  extend RSpec::SleepingKingStudios::Contract
658
698
 
@@ -664,6 +704,17 @@ module Cuprum::Collections::RSpec::Contracts
664
704
  # @param abstract [Boolean] if true, the scope is abstract and does not
665
705
  # define a #call implementation. Defaults to false.
666
706
  contract do |abstract: false|
707
+ message =
708
+ 'Use deferred examples "should implement the NoneScope methods"'
709
+
710
+ SleepingKingStudios::Tools::Toolbelt
711
+ .instance
712
+ .core_tools
713
+ .deprecate(
714
+ 'ShouldBeANoneScopeContract',
715
+ message:
716
+ )
717
+
667
718
  include_contract 'should be a scope', invertible: true
668
719
 
669
720
  describe '#==' do
@@ -15,6 +15,8 @@ module Cuprum::Collections::RSpec::Contracts::Scopes
15
15
  include Cuprum::Collections::RSpec::Contracts::Scopes::CriteriaContracts
16
16
 
17
17
  # Contract validating the behavior of a scope builder implementation.
18
+ #
19
+ # @deprecated 0.6.0
18
20
  module ShouldBeAScopeBuilderContract
19
21
  extend RSpec::SleepingKingStudios::Contract
20
22
 
@@ -44,6 +46,14 @@ module Cuprum::Collections::RSpec::Contracts::Scopes
44
46
  disjunction_scope_class = contract_options[:disjunction_class]
45
47
  none_scope_class = contract_options[:none_class]
46
48
 
49
+ SleepingKingStudios::Tools::Toolbelt
50
+ .instance
51
+ .core_tools
52
+ .deprecate(
53
+ 'ShouldBeAScopeBuilderContract',
54
+ message: 'Use deferred examples "should build collection Scopes"'
55
+ )
56
+
47
57
  shared_context 'with container scope helpers' do
48
58
  let(:scope) { build_container(scopes:) }
49
59