cuprum-collections 0.1.0 → 0.3.0.rc.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/README.md +321 -15
  4. data/lib/cuprum/collections/basic/collection.rb +13 -0
  5. data/lib/cuprum/collections/basic/commands/destroy_one.rb +4 -3
  6. data/lib/cuprum/collections/basic/commands/find_many.rb +1 -1
  7. data/lib/cuprum/collections/basic/commands/insert_one.rb +4 -3
  8. data/lib/cuprum/collections/basic/commands/update_one.rb +4 -3
  9. data/lib/cuprum/collections/basic/query.rb +3 -3
  10. data/lib/cuprum/collections/basic/repository.rb +67 -0
  11. data/lib/cuprum/collections/commands/abstract_find_many.rb +33 -32
  12. data/lib/cuprum/collections/commands/abstract_find_one.rb +4 -3
  13. data/lib/cuprum/collections/commands/create.rb +60 -0
  14. data/lib/cuprum/collections/commands/find_one_matching.rb +134 -0
  15. data/lib/cuprum/collections/commands/update.rb +74 -0
  16. data/lib/cuprum/collections/commands/upsert.rb +162 -0
  17. data/lib/cuprum/collections/commands.rb +7 -2
  18. data/lib/cuprum/collections/errors/abstract_find_error.rb +210 -0
  19. data/lib/cuprum/collections/errors/already_exists.rb +4 -72
  20. data/lib/cuprum/collections/errors/extra_attributes.rb +8 -18
  21. data/lib/cuprum/collections/errors/failed_validation.rb +5 -18
  22. data/lib/cuprum/collections/errors/invalid_parameters.rb +7 -15
  23. data/lib/cuprum/collections/errors/invalid_query.rb +5 -15
  24. data/lib/cuprum/collections/errors/missing_default_contract.rb +5 -17
  25. data/lib/cuprum/collections/errors/not_found.rb +4 -67
  26. data/lib/cuprum/collections/errors/not_unique.rb +18 -0
  27. data/lib/cuprum/collections/errors/unknown_operator.rb +7 -17
  28. data/lib/cuprum/collections/errors.rb +13 -1
  29. data/lib/cuprum/collections/queries/ordering.rb +4 -2
  30. data/lib/cuprum/collections/repository.rb +105 -0
  31. data/lib/cuprum/collections/rspec/assign_one_command_contract.rb +2 -2
  32. data/lib/cuprum/collections/rspec/build_one_command_contract.rb +1 -1
  33. data/lib/cuprum/collections/rspec/collection_contract.rb +140 -103
  34. data/lib/cuprum/collections/rspec/destroy_one_command_contract.rb +8 -6
  35. data/lib/cuprum/collections/rspec/find_many_command_contract.rb +114 -34
  36. data/lib/cuprum/collections/rspec/find_one_command_contract.rb +12 -9
  37. data/lib/cuprum/collections/rspec/insert_one_command_contract.rb +4 -3
  38. data/lib/cuprum/collections/rspec/query_contract.rb +3 -3
  39. data/lib/cuprum/collections/rspec/querying_contract.rb +2 -2
  40. data/lib/cuprum/collections/rspec/repository_contract.rb +235 -0
  41. data/lib/cuprum/collections/rspec/update_one_command_contract.rb +4 -3
  42. data/lib/cuprum/collections/version.rb +3 -3
  43. data/lib/cuprum/collections.rb +1 -0
  44. metadata +25 -91
@@ -58,10 +58,15 @@ module Cuprum::Collections::RSpec
58
58
  describe 'with an array of invalid primary keys' do
59
59
  let(:primary_keys) { invalid_primary_key_values }
60
60
  let(:expected_error) do
61
- Cuprum::Collections::Errors::NotFound.new(
62
- collection_name: command.collection_name,
63
- primary_key_name: primary_key_name,
64
- primary_key_values: primary_keys
61
+ Cuprum::Errors::MultipleErrors.new(
62
+ errors: primary_keys.map do |primary_key|
63
+ Cuprum::Collections::Errors::NotFound.new(
64
+ attribute_name: primary_key_name,
65
+ attribute_value: primary_key,
66
+ collection_name: command.collection_name,
67
+ primary_key: true
68
+ )
69
+ end
65
70
  )
66
71
  end
67
72
 
@@ -79,7 +84,6 @@ module Cuprum::Collections::RSpec
79
84
  .map do |key|
80
85
  mapped_data.find { |item| item[primary_key_name.to_s] == key }
81
86
  end
82
- .compact
83
87
  end
84
88
  let(:expected_data) do
85
89
  defined?(super()) ? super() : matching_data
@@ -88,10 +92,15 @@ module Cuprum::Collections::RSpec
88
92
  describe 'with an array of invalid primary keys' do
89
93
  let(:primary_keys) { invalid_primary_key_values }
90
94
  let(:expected_error) do
91
- Cuprum::Collections::Errors::NotFound.new(
92
- collection_name: command.collection_name,
93
- primary_key_name: primary_key_name,
94
- primary_key_values: primary_keys
95
+ Cuprum::Errors::MultipleErrors.new(
96
+ errors: primary_keys.map do |primary_key|
97
+ Cuprum::Collections::Errors::NotFound.new(
98
+ attribute_name: primary_key_name,
99
+ attribute_value: primary_key,
100
+ collection_name: command.collection_name,
101
+ primary_key: true
102
+ )
103
+ end
95
104
  )
96
105
  end
97
106
 
@@ -107,10 +116,17 @@ module Cuprum::Collections::RSpec
107
116
  invalid_primary_key_values + valid_primary_key_values
108
117
  end
109
118
  let(:expected_error) do
110
- Cuprum::Collections::Errors::NotFound.new(
111
- collection_name: command.collection_name,
112
- primary_key_name: primary_key_name,
113
- primary_key_values: invalid_primary_key_values
119
+ Cuprum::Errors::MultipleErrors.new(
120
+ errors: primary_keys.map do |primary_key|
121
+ next nil unless invalid_primary_key_values.include?(primary_key)
122
+
123
+ Cuprum::Collections::Errors::NotFound.new(
124
+ attribute_name: primary_key_name,
125
+ attribute_value: primary_key,
126
+ collection_name: command.collection_name,
127
+ primary_key: true
128
+ )
129
+ end
114
130
  )
115
131
  end
116
132
 
@@ -145,10 +161,15 @@ module Cuprum::Collections::RSpec
145
161
  describe 'with an array of invalid primary keys' do
146
162
  let(:primary_keys) { invalid_primary_key_values }
147
163
  let(:expected_error) do
148
- Cuprum::Collections::Errors::NotFound.new(
149
- collection_name: command.collection_name,
150
- primary_key_name: primary_key_name,
151
- primary_key_values: primary_keys
164
+ Cuprum::Errors::MultipleErrors.new(
165
+ errors: invalid_primary_key_values.map do |primary_key|
166
+ Cuprum::Collections::Errors::NotFound.new(
167
+ attribute_name: primary_key_name,
168
+ attribute_value: primary_key,
169
+ collection_name: command.collection_name,
170
+ primary_key: true
171
+ )
172
+ end
152
173
  )
153
174
  end
154
175
 
@@ -163,6 +184,22 @@ module Cuprum::Collections::RSpec
163
184
  let(:primary_keys) do
164
185
  invalid_primary_key_values + valid_primary_key_values
165
186
  end
187
+ let(:expected_error) do
188
+ Cuprum::Errors::MultipleErrors.new(
189
+ errors: primary_keys.map do |primary_key|
190
+ unless invalid_primary_key_values.include?(primary_key)
191
+ next nil
192
+ end
193
+
194
+ Cuprum::Collections::Errors::NotFound.new(
195
+ attribute_name: primary_key_name,
196
+ attribute_value: primary_key,
197
+ collection_name: command.collection_name,
198
+ primary_key: true
199
+ )
200
+ end
201
+ )
202
+ end
166
203
 
167
204
  it 'should return a passing result' do
168
205
  expect(
@@ -170,6 +207,7 @@ module Cuprum::Collections::RSpec
170
207
  )
171
208
  .to be_a_passing_result
172
209
  .with_value(expected_data)
210
+ .and_error(expected_error)
173
211
  end
174
212
  end
175
213
 
@@ -226,10 +264,15 @@ module Cuprum::Collections::RSpec
226
264
  describe 'with an array of invalid primary keys' do
227
265
  let(:primary_keys) { invalid_primary_key_values }
228
266
  let(:expected_error) do
229
- Cuprum::Collections::Errors::NotFound.new(
230
- collection_name: command.collection_name,
231
- primary_key_name: primary_key_name,
232
- primary_key_values: primary_keys
267
+ Cuprum::Errors::MultipleErrors.new(
268
+ errors: primary_keys.map do |primary_key|
269
+ Cuprum::Collections::Errors::NotFound.new(
270
+ attribute_name: primary_key_name,
271
+ attribute_value: primary_key,
272
+ collection_name: command.collection_name,
273
+ primary_key: true
274
+ )
275
+ end
233
276
  )
234
277
  end
235
278
 
@@ -246,10 +289,15 @@ module Cuprum::Collections::RSpec
246
289
  describe 'with a valid array of primary keys' do
247
290
  let(:primary_keys) { valid_primary_key_values }
248
291
  let(:expected_error) do
249
- Cuprum::Collections::Errors::NotFound.new(
250
- collection_name: command.collection_name,
251
- primary_key_name: primary_key_name,
252
- primary_key_values: primary_keys
292
+ Cuprum::Errors::MultipleErrors.new(
293
+ errors: primary_keys.map do |primary_key|
294
+ Cuprum::Collections::Errors::NotFound.new(
295
+ attribute_name: primary_key_name,
296
+ attribute_value: primary_key,
297
+ collection_name: command.collection_name,
298
+ primary_key: true
299
+ )
300
+ end
253
301
  )
254
302
  end
255
303
 
@@ -264,20 +312,32 @@ module Cuprum::Collections::RSpec
264
312
  describe 'with a scope that matches some keys' do
265
313
  let(:scope_filter) { -> { { series: nil } } }
266
314
  let(:matching_data) do
267
- super().select { |item| item['series'].nil? }
315
+ super().map do |item|
316
+ next nil unless item['series'].nil?
317
+
318
+ item
319
+ end
268
320
  end
269
321
 
270
322
  describe 'with a valid array of primary keys' do
271
323
  let(:primary_keys) { valid_primary_key_values }
272
324
  let(:expected_error) do
273
- found_keys =
274
- matching_data.map { |item| item[primary_key_name.to_s] }
275
- missing_keys = primary_keys - found_keys
276
-
277
- Cuprum::Collections::Errors::NotFound.new(
278
- collection_name: command.collection_name,
279
- primary_key_name: primary_key_name,
280
- primary_key_values: missing_keys
325
+ found_keys =
326
+ matching_data
327
+ .compact
328
+ .map { |item| item[primary_key_name.to_s] }
329
+
330
+ Cuprum::Errors::MultipleErrors.new(
331
+ errors: primary_keys.map do |primary_key|
332
+ next if found_keys.include?(primary_key)
333
+
334
+ Cuprum::Collections::Errors::NotFound.new(
335
+ attribute_name: primary_key_name,
336
+ attribute_value: primary_key,
337
+ collection_name: command.collection_name,
338
+ primary_key: true
339
+ )
340
+ end
281
341
  )
282
342
  end
283
343
 
@@ -291,6 +351,25 @@ module Cuprum::Collections::RSpec
291
351
  describe 'with allow_partial: true' do
292
352
  describe 'with a valid array of primary keys' do
293
353
  let(:primary_keys) { valid_primary_key_values }
354
+ let(:expected_error) do
355
+ found_keys =
356
+ matching_data
357
+ .compact
358
+ .map { |item| item[primary_key_name.to_s] }
359
+
360
+ Cuprum::Errors::MultipleErrors.new(
361
+ errors: primary_keys.map do |primary_key|
362
+ next if found_keys.include?(primary_key)
363
+
364
+ Cuprum::Collections::Errors::NotFound.new(
365
+ attribute_name: primary_key_name,
366
+ attribute_value: primary_key,
367
+ collection_name: command.collection_name,
368
+ primary_key: true
369
+ )
370
+ end
371
+ )
372
+ end
294
373
 
295
374
  it 'should return a passing result' do
296
375
  expect(
@@ -302,6 +381,7 @@ module Cuprum::Collections::RSpec
302
381
  )
303
382
  .to be_a_passing_result
304
383
  .with_value(expected_data)
384
+ .and_error(expected_error)
305
385
  end
306
386
  end
307
387
  end
@@ -47,9 +47,10 @@ module Cuprum::Collections::RSpec
47
47
  let(:primary_key) { invalid_primary_key_value }
48
48
  let(:expected_error) do
49
49
  Cuprum::Collections::Errors::NotFound.new(
50
- collection_name: command.collection_name,
51
- primary_key_name: primary_key_name,
52
- primary_key_values: primary_key
50
+ attribute_name: primary_key_name,
51
+ attribute_value: primary_key,
52
+ collection_name: command.collection_name,
53
+ primary_key: true
53
54
  )
54
55
  end
55
56
 
@@ -73,9 +74,10 @@ module Cuprum::Collections::RSpec
73
74
  let(:primary_key) { invalid_primary_key_value }
74
75
  let(:expected_error) do
75
76
  Cuprum::Collections::Errors::NotFound.new(
76
- collection_name: command.collection_name,
77
- primary_key_name: primary_key_name,
78
- primary_key_values: primary_key
77
+ attribute_name: primary_key_name,
78
+ attribute_value: primary_key,
79
+ collection_name: command.collection_name,
80
+ primary_key: true
79
81
  )
80
82
  end
81
83
 
@@ -120,9 +122,10 @@ module Cuprum::Collections::RSpec
120
122
  let(:primary_key) { valid_primary_key_value }
121
123
  let(:expected_error) do
122
124
  Cuprum::Collections::Errors::NotFound.new(
123
- collection_name: command.collection_name,
124
- primary_key_name: primary_key_name,
125
- primary_key_values: primary_key
125
+ attribute_name: primary_key_name,
126
+ attribute_value: primary_key,
127
+ collection_name: command.collection_name,
128
+ primary_key: true
126
129
  )
127
130
  end
128
131
 
@@ -61,9 +61,10 @@ module Cuprum::Collections::RSpec
61
61
  let(:data) { fixtures_data }
62
62
  let(:expected_error) do
63
63
  Cuprum::Collections::Errors::AlreadyExists.new(
64
- collection_name: collection_name,
65
- primary_key_name: primary_key_name,
66
- primary_key_values: attributes[primary_key_name]
64
+ attribute_name: primary_key_name,
65
+ attribute_value: attributes[primary_key_name],
66
+ collection_name: collection_name,
67
+ primary_key: true
67
68
  )
68
69
  end
69
70
 
@@ -386,8 +386,8 @@ module Cuprum::Collections::RSpec # rubocop:disable Style/Documentation
386
386
  describe '#order' do
387
387
  let(:default_order) { defined?(super()) ? super() : {} }
388
388
  let(:error_message) do
389
- 'order must be a list of attribute names and/or a hash of attribute' \
390
- ' names with values :asc or :desc'
389
+ 'order must be a list of attribute names and/or a hash of attribute ' \
390
+ 'names with values :asc or :desc'
391
391
  end
392
392
 
393
393
  it 'should define the method' do
@@ -397,7 +397,7 @@ module Cuprum::Collections::RSpec # rubocop:disable Style/Documentation
397
397
  .and_unlimited_arguments
398
398
  end
399
399
 
400
- it { expect(query).to alias_method(:order).as(:order_by) }
400
+ it { expect(query).to have_aliased_method(:order).as(:order_by) }
401
401
 
402
402
  describe 'with no arguments' do
403
403
  it { expect(query.order).to be == default_order }
@@ -76,8 +76,8 @@ module Cuprum::Collections::RSpec
76
76
  end
77
77
  end
78
78
 
79
- shared_context 'when the query has where: a greater_than_or_equal_to' \
80
- ' filter' \
79
+ shared_context 'when the query has where: a greater_than_or_equal_to ' \
80
+ 'filter' \
81
81
  do
82
82
  let(:filter) do
83
83
  -> { { published_at: greater_than_or_equal_to('1970-12-01') } }
@@ -0,0 +1,235 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rspec/sleeping_king_studios/contract'
4
+
5
+ require 'cuprum/collections/rspec'
6
+
7
+ module Cuprum::Collections::RSpec
8
+ # Contract validating the behavior of a Repository.
9
+ module RepositoryContract
10
+ extend RSpec::SleepingKingStudios::Contract
11
+
12
+ # @!method apply(example_group)
13
+ # Adds the contract to the example group.
14
+ #
15
+ # @param example_group [RSpec::Core::ExampleGroup] The example group to
16
+ # which the contract is applied.
17
+ contract do
18
+ describe '#[]' do
19
+ let(:error_class) do
20
+ described_class::UndefinedCollectionError
21
+ end
22
+ let(:error_message) do
23
+ "repository does not define collection #{collection_name.inspect}"
24
+ end
25
+
26
+ it { expect(repository).to respond_to(:[]).with(1).argument }
27
+
28
+ describe 'with nil' do
29
+ let(:collection_name) { nil }
30
+
31
+ it 'should raise an exception' do
32
+ expect { repository[collection_name] }
33
+ .to raise_error(error_class, error_message)
34
+ end
35
+ end
36
+
37
+ describe 'with an object' do
38
+ let(:collection_name) { Object.new.freeze }
39
+
40
+ it 'should raise an exception' do
41
+ expect { repository[collection_name] }
42
+ .to raise_error(error_class, error_message)
43
+ end
44
+ end
45
+
46
+ describe 'with an invalid string' do
47
+ let(:collection_name) { 'invalid_name' }
48
+
49
+ it 'should raise an exception' do
50
+ expect { repository[collection_name] }
51
+ .to raise_error(error_class, error_message)
52
+ end
53
+ end
54
+
55
+ describe 'with an invalid symbol' do
56
+ let(:collection_name) { :invalid_name }
57
+
58
+ it 'should raise an exception' do
59
+ expect { repository[collection_name] }
60
+ .to raise_error(error_class, error_message)
61
+ end
62
+ end
63
+
64
+ wrap_context 'when the repository has many collections' do
65
+ describe 'with an invalid string' do
66
+ let(:collection_name) { 'invalid_name' }
67
+
68
+ it 'should raise an exception' do
69
+ expect { repository[collection_name] }
70
+ .to raise_error(error_class, error_message)
71
+ end
72
+ end
73
+
74
+ describe 'with an invalid symbol' do
75
+ let(:collection_name) { :invalid_name }
76
+
77
+ it 'should raise an exception' do
78
+ expect { repository[collection_name] }
79
+ .to raise_error(error_class, error_message)
80
+ end
81
+ end
82
+
83
+ describe 'with a valid string' do
84
+ let(:collection) { collections.values.first }
85
+ let(:collection_name) { collections.keys.first }
86
+
87
+ it { expect(repository[collection_name]).to be collection }
88
+ end
89
+
90
+ describe 'with a valid symbol' do
91
+ let(:collection) { collections.values.first }
92
+ let(:collection_name) { collections.keys.first.intern }
93
+
94
+ it { expect(repository[collection_name]).to be collection }
95
+ end
96
+ end
97
+ end
98
+
99
+ describe '#add' do
100
+ let(:error_class) do
101
+ described_class::InvalidCollectionError
102
+ end
103
+ let(:error_message) do
104
+ "#{collection.inspect} is not a valid collection"
105
+ end
106
+
107
+ it 'should define the method' do
108
+ expect(repository)
109
+ .to respond_to(:add)
110
+ .with(1).argument
111
+ .and_keywords(:force)
112
+ end
113
+
114
+ it 'should alias #add as #<<' do
115
+ expect(repository.method(:<<)).to be == repository.method(:add)
116
+ end
117
+
118
+ describe 'with nil' do
119
+ let(:collection) { nil }
120
+
121
+ it 'should raise an exception' do
122
+ expect { repository.add(collection) }
123
+ .to raise_error(error_class, error_message)
124
+ end
125
+ end
126
+
127
+ describe 'with an object' do
128
+ let(:collection) { Object.new.freeze }
129
+
130
+ it 'should raise an exception' do
131
+ expect { repository.add(collection) }
132
+ .to raise_error(error_class, error_message)
133
+ end
134
+ end
135
+
136
+ describe 'with a collection' do
137
+ it { expect(repository.add(example_collection)).to be repository }
138
+
139
+ it 'should add the collection to the repository' do
140
+ repository.add(example_collection)
141
+
142
+ expect(repository[example_collection.qualified_name])
143
+ .to be example_collection
144
+ end
145
+
146
+ describe 'with force: true' do
147
+ it 'should add the collection to the repository' do
148
+ repository.add(example_collection, force: true)
149
+
150
+ expect(repository[example_collection.qualified_name])
151
+ .to be example_collection
152
+ end
153
+ end
154
+
155
+ context 'when the collection already exists' do
156
+ let(:error_message) do
157
+ "collection #{example_collection.qualified_name} already exists"
158
+ end
159
+
160
+ before(:example) do
161
+ allow(repository)
162
+ .to receive(:key?)
163
+ .with(example_collection.qualified_name)
164
+ .and_return(true)
165
+ end
166
+
167
+ it 'should raise an exception' do
168
+ expect { repository.add(example_collection) }
169
+ .to raise_error(
170
+ described_class::DuplicateCollectionError,
171
+ error_message
172
+ )
173
+ end
174
+
175
+ it 'should not update the repository' do
176
+ begin
177
+ repository.add(example_collection)
178
+ rescue described_class::DuplicateCollectionError
179
+ # Do nothing.
180
+ end
181
+
182
+ expect { repository[example_collection.qualified_name] }
183
+ .to raise_error(
184
+ described_class::UndefinedCollectionError,
185
+ 'repository does not define collection ' \
186
+ "#{example_collection.qualified_name.inspect}"
187
+ )
188
+ end
189
+
190
+ describe 'with force: true' do
191
+ it 'should add the collection to the repository' do
192
+ repository.add(example_collection, force: true)
193
+
194
+ expect(repository[example_collection.qualified_name])
195
+ .to be example_collection
196
+ end
197
+ end
198
+ end
199
+ end
200
+ end
201
+
202
+ describe '#key?' do
203
+ it { expect(repository).to respond_to(:key?).with(1).argument }
204
+
205
+ it { expect(repository.key? nil).to be false }
206
+
207
+ it { expect(repository.key? Object.new.freeze).to be false }
208
+
209
+ it { expect(repository.key? 'invalid_name').to be false }
210
+
211
+ it { expect(repository.key? :invalid_name).to be false }
212
+
213
+ wrap_context 'when the repository has many collections' do
214
+ it { expect(repository.key? 'invalid_name').to be false }
215
+
216
+ it { expect(repository.key? :invalid_name).to be false }
217
+
218
+ it { expect(repository.key? collections.keys.first).to be true }
219
+
220
+ it 'should include the key' do
221
+ expect(repository.key? collections.keys.first.intern).to be true
222
+ end
223
+ end
224
+ end
225
+
226
+ describe '#keys' do
227
+ include_examples 'should define reader', :keys, []
228
+
229
+ wrap_context 'when the repository has many collections' do
230
+ it { expect(repository.keys).to be == collections.keys }
231
+ end
232
+ end
233
+ end
234
+ end
235
+ end
@@ -32,9 +32,10 @@ module Cuprum::Collections::RSpec
32
32
  context 'when the item does not exist in the collection' do
33
33
  let(:expected_error) do
34
34
  Cuprum::Collections::Errors::NotFound.new(
35
- collection_name: collection_name,
36
- primary_key_name: primary_key_name,
37
- primary_key_values: attributes[primary_key_name]
35
+ attribute_name: primary_key_name,
36
+ attribute_value: attributes[primary_key_name],
37
+ collection_name: collection_name,
38
+ primary_key: true
38
39
  )
39
40
  end
40
41
  let(:matching_data) { mapped_data.first }
@@ -11,13 +11,13 @@ module Cuprum
11
11
  # Major version.
12
12
  MAJOR = 0
13
13
  # Minor version.
14
- MINOR = 1
14
+ MINOR = 3
15
15
  # Patch version.
16
16
  PATCH = 0
17
17
  # Prerelease version.
18
- PRERELEASE = nil
18
+ PRERELEASE = :rc
19
19
  # Build metadata.
20
- BUILD = nil
20
+ BUILD = 0
21
21
 
22
22
  class << self
23
23
  # Generates the gem version string from the Version constants.
@@ -9,6 +9,7 @@ module Cuprum
9
9
  autoload :Base, 'cuprum/collections/base'
10
10
  autoload :Basic, 'cuprum/collections/basic'
11
11
  autoload :Command, 'cuprum/collections/command'
12
+ autoload :Errors, 'cuprum/collections/errors'
12
13
 
13
14
  # @return [String] the absolute path to the gem directory.
14
15
  def self.gem_path