riak-client 2.5.0 → 2.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +1 -0
  3. data/RELNOTES.md +3 -0
  4. data/lib/riak/bucket.rb +1 -1
  5. data/lib/riak/client.rb +14 -7
  6. data/lib/riak/client/beefcake/messages.rb +13 -0
  7. data/lib/riak/multi.rb +101 -0
  8. data/lib/riak/multiexist.rb +14 -0
  9. data/lib/riak/multiget.rb +7 -107
  10. data/lib/riak/version.rb +1 -1
  11. metadata +12 -234
  12. data/.document +0 -5
  13. data/.gitignore +0 -44
  14. data/.rspec +0 -2
  15. data/Gemfile +0 -17
  16. data/Guardfile +0 -20
  17. data/Rakefile +0 -124
  18. data/riak-client.gemspec +0 -71
  19. data/spec/failover/failover.rb +0 -59
  20. data/spec/fixtures/bitcask.txt +0 -25
  21. data/spec/fixtures/cat.jpg +0 -0
  22. data/spec/fixtures/multipart-basic-conflict.txt +0 -15
  23. data/spec/fixtures/multipart-blank.txt +0 -7
  24. data/spec/fixtures/multipart-mapreduce.txt +0 -10
  25. data/spec/fixtures/multipart-with-body.txt +0 -16
  26. data/spec/fixtures/multipart-with-marked-tombstones.txt +0 -17
  27. data/spec/fixtures/multipart-with-unmarked-tombstone.txt +0 -16
  28. data/spec/fixtures/server.cert.crt +0 -15
  29. data/spec/fixtures/server.cert.key +0 -15
  30. data/spec/fixtures/test.pem +0 -1
  31. data/spec/fixtures/yz_schema_template.xml +0 -18
  32. data/spec/integration/riak/bucket_types_spec.rb +0 -308
  33. data/spec/integration/riak/conflict_resolution_spec.rb +0 -96
  34. data/spec/integration/riak/counters_spec.rb +0 -36
  35. data/spec/integration/riak/crdt/configuration_spec.rb +0 -38
  36. data/spec/integration/riak/crdt_search_spec.rb +0 -176
  37. data/spec/integration/riak/crdt_spec.rb +0 -332
  38. data/spec/integration/riak/crdt_validation/map_spec.rb +0 -63
  39. data/spec/integration/riak/crdt_validation/set_spec.rb +0 -122
  40. data/spec/integration/riak/encodings/crdt_spec.rb +0 -122
  41. data/spec/integration/riak/encodings/kv_spec.rb +0 -87
  42. data/spec/integration/riak/encodings/yz_spec.rb +0 -142
  43. data/spec/integration/riak/preflist_spec.rb +0 -43
  44. data/spec/integration/riak/properties_spec.rb +0 -69
  45. data/spec/integration/riak/protobuffs/interrupted_request_spec.rb +0 -33
  46. data/spec/integration/riak/protobuffs/timeouts_spec.rb +0 -178
  47. data/spec/integration/riak/protobuffs_backends_spec.rb +0 -40
  48. data/spec/integration/riak/search_spec.rb +0 -104
  49. data/spec/integration/riak/secondary_index_spec.rb +0 -72
  50. data/spec/integration/riak/security_spec.rb +0 -105
  51. data/spec/integration/riak/threading_spec.rb +0 -154
  52. data/spec/integration/riak/time_series_spec.rb +0 -212
  53. data/spec/integration/yokozuna/index_spec.rb +0 -61
  54. data/spec/integration/yokozuna/queries_spec.rb +0 -115
  55. data/spec/integration/yokozuna/schema_spec.rb +0 -49
  56. data/spec/riak/beefcake_protobuffs_backend/bucket_properties_operator_spec.rb +0 -247
  57. data/spec/riak/beefcake_protobuffs_backend/crdt_operator_spec.rb +0 -244
  58. data/spec/riak/beefcake_protobuffs_backend/object_methods_spec.rb +0 -53
  59. data/spec/riak/beefcake_protobuffs_backend/protocol_spec.rb +0 -189
  60. data/spec/riak/beefcake_protobuffs_backend/ts_cell_codec_spec.rb +0 -124
  61. data/spec/riak/beefcake_protobuffs_backend_spec.rb +0 -162
  62. data/spec/riak/bucket_properties_spec.rb +0 -135
  63. data/spec/riak/bucket_spec.rb +0 -275
  64. data/spec/riak/bucket_type_spec.rb +0 -50
  65. data/spec/riak/bucket_typed/bucket_spec.rb +0 -78
  66. data/spec/riak/client_spec.rb +0 -304
  67. data/spec/riak/core_ext/to_param_spec.rb +0 -15
  68. data/spec/riak/counter_spec.rb +0 -122
  69. data/spec/riak/crdt/counter_spec.rb +0 -55
  70. data/spec/riak/crdt/hyper_log_log_spec.rb +0 -56
  71. data/spec/riak/crdt/inner_counter_spec.rb +0 -21
  72. data/spec/riak/crdt/inner_flag_spec.rb +0 -39
  73. data/spec/riak/crdt/inner_map_spec.rb +0 -47
  74. data/spec/riak/crdt/inner_register_spec.rb +0 -40
  75. data/spec/riak/crdt/inner_set_spec.rb +0 -33
  76. data/spec/riak/crdt/map_spec.rb +0 -78
  77. data/spec/riak/crdt/set_spec.rb +0 -61
  78. data/spec/riak/crdt/shared_examples.rb +0 -88
  79. data/spec/riak/crdt/typed_collection_spec.rb +0 -225
  80. data/spec/riak/escape_spec.rb +0 -72
  81. data/spec/riak/feature_detection_spec.rb +0 -77
  82. data/spec/riak/index_collection_spec.rb +0 -53
  83. data/spec/riak/instrumentation_spec.rb +0 -124
  84. data/spec/riak/link_spec.rb +0 -85
  85. data/spec/riak/list_buckets_spec.rb +0 -41
  86. data/spec/riak/map_reduce/filter_builder_spec.rb +0 -32
  87. data/spec/riak/map_reduce/phase_spec.rb +0 -142
  88. data/spec/riak/map_reduce_spec.rb +0 -434
  89. data/spec/riak/multiget_spec.rb +0 -81
  90. data/spec/riak/node_spec.rb +0 -26
  91. data/spec/riak/robject_spec.rb +0 -542
  92. data/spec/riak/search/index_spec.rb +0 -72
  93. data/spec/riak/search/query_spec.rb +0 -88
  94. data/spec/riak/search/result_collection_spec.rb +0 -89
  95. data/spec/riak/search/result_document_spec.rb +0 -106
  96. data/spec/riak/search/schema_spec.rb +0 -63
  97. data/spec/riak/search_spec.rb +0 -107
  98. data/spec/riak/secondary_index_spec.rb +0 -225
  99. data/spec/riak/serializers_spec.rb +0 -121
  100. data/spec/riak/stamp_spec.rb +0 -54
  101. data/spec/riak/time_series/deletion_spec.rb +0 -33
  102. data/spec/riak/time_series/listing_spec.rb +0 -51
  103. data/spec/riak/time_series/submission_spec.rb +0 -35
  104. data/spec/riak/util/gzip_spec.rb +0 -49
  105. data/spec/riak/walk_spec_spec.rb +0 -203
  106. data/spec/spec_helper.rb +0 -67
  107. data/spec/support/certs/README.md +0 -13
  108. data/spec/support/certs/ca.crt +0 -21
  109. data/spec/support/certs/client.crl +0 -13
  110. data/spec/support/certs/client.crt +0 -94
  111. data/spec/support/certs/client.csr +0 -18
  112. data/spec/support/certs/client.key +0 -27
  113. data/spec/support/certs/empty_ca.crt +0 -21
  114. data/spec/support/certs/server.crl +0 -13
  115. data/spec/support/certs/server.crt +0 -94
  116. data/spec/support/certs/server.key +0 -27
  117. data/spec/support/crdt_search_config.rb +0 -112
  118. data/spec/support/crdt_search_fixtures.rb +0 -42
  119. data/spec/support/integration_setup.rb +0 -10
  120. data/spec/support/search_config.rb +0 -83
  121. data/spec/support/search_corpus_setup.rb +0 -39
  122. data/spec/support/test_client.rb +0 -52
  123. data/spec/support/test_client.yml.example +0 -10
  124. data/spec/support/unified_backend_examples.rb +0 -402
  125. data/spec/support/version_filter.rb +0 -12
  126. data/spec/support/wait_until.rb +0 -20
@@ -1,26 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Riak::Client::Node do
4
- before :each do
5
- @client = Riak::Client.new
6
- @node = Riak::Client::Node.new @client
7
- end
8
-
9
- describe 'when initializing' do
10
- it 'defaults to the local interface on port 8087' do
11
- node = Riak::Client::Node.new @client
12
- expect(node.host).to eq('127.0.0.1')
13
- expect(node.pb_port).to eq(8087)
14
- end
15
-
16
- it 'accepts a host' do
17
- node = Riak::Client::Node.new(@client, :host => 'riak.basho.com')
18
- expect(node.host).to eq("riak.basho.com")
19
- end
20
-
21
- it 'accepts a Protobuffs port' do
22
- node = Riak::Client::Node.new @client, :pb_port => 9000
23
- expect(node.pb_port).to eq(9000)
24
- end
25
- end
26
- end
@@ -1,542 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Riak::RObject do
4
- before :each do
5
- @client = Riak::Client.new
6
- @bucket = Riak::Bucket.new(@client, "foo")
7
- end
8
-
9
- describe "initialization" do
10
- it "sets the bucket" do
11
- @object = Riak::RObject.new(@bucket, "bar")
12
- expect(@object.bucket).to eq(@bucket)
13
- end
14
-
15
- it "sets the key" do
16
- @object = Riak::RObject.new(@bucket, "bar")
17
- expect(@object.key).to eq("bar")
18
- end
19
-
20
- it "initializes the links to an empty set" do
21
- @object = Riak::RObject.new(@bucket, "bar")
22
- expect(@object.links).to eq(Set.new)
23
- end
24
-
25
- it "initializes the meta to an empty hash" do
26
- @object = Riak::RObject.new(@bucket, "bar")
27
- expect(@object.meta).to eq({})
28
- end
29
-
30
- it "initializes indexes to an empty hash with a Set for the default value" do
31
- @object = Riak::RObject.new(@bucket, "bar")
32
- expect(@object.indexes).to be_kind_of(Hash)
33
- expect(@object.indexes).to be_empty
34
- expect(@object.indexes['foo_bin']).to be_kind_of(Set)
35
- end
36
-
37
- it "yields itself to a given block" do
38
- Riak::RObject.new(@bucket, "bar") do |r|
39
- expect(r.key).to eq("bar")
40
- end
41
- end
42
- end
43
-
44
- describe "serialization" do
45
- before :each do
46
- @object = Riak::RObject.new(@bucket, "bar")
47
- end
48
-
49
- it 'delegates #serialize to the appropriate serializer for the content type' do
50
- @object.content_type = 'text/plain'
51
- expect(Riak::Serializers).to respond_to(:serialize).with(2).arguments
52
- expect(Riak::Serializers).to receive(:serialize).with('text/plain', "foo").and_return("serialized foo")
53
- expect(@object.content.serialize("foo")).to eq("serialized foo")
54
- end
55
-
56
- it 'delegates #deserialize to the appropriate serializer for the content type' do
57
- @object.content_type = 'text/plain'
58
- expect(Riak::Serializers).to respond_to(:deserialize).with(2).arguments
59
- expect(Riak::Serializers).to receive(:deserialize).with('text/plain', "foo").and_return("deserialized foo")
60
- expect(@object.content.deserialize("foo")).to eq("deserialized foo")
61
- end
62
- end
63
-
64
- describe "data access methods" do
65
- before :each do
66
- @object = Riak::RObject.new(@bucket, "bar")
67
- @object.content_type = "application/json"
68
- end
69
-
70
- describe "for raw data" do
71
- describe "when unserialized data was already provided" do
72
- before do
73
- @object.data = { 'some' => 'data' }
74
- end
75
-
76
- it "resets unserialized forms when stored" do
77
- @object.raw_data = value = '{ "raw": "json" }'
78
-
79
- expect(@object.raw_data).to eq(value)
80
- expect(@object.data).to eq({ "raw" => "json" })
81
- end
82
-
83
- it "lazily serializes when read" do
84
- expect(@object.raw_data).to eq('{"some":"data"}')
85
- end
86
- end
87
-
88
- it "only marshal/demarshals when necessary" do
89
- expect(@object).not_to receive(:serialize)
90
- expect(@object).not_to receive(:deserialize)
91
- @object.raw_data = value = "{not even valid json!}}"
92
- expect(@object.raw_data).to eq(value)
93
- end
94
- end
95
-
96
- describe "for unserialized data" do
97
- describe "when raw data was already provided" do
98
- before do
99
- @object.raw_data = '{"some":"data"}'
100
- end
101
-
102
- it "resets previously stored raw data" do
103
- @object.data = value = { "new" => "data" }
104
- expect(@object.raw_data).to eq('{"new":"data"}')
105
- expect(@object.data).to eq(value)
106
- end
107
-
108
- it "lazily deserializes when read" do
109
- expect(@object.data).to eq({ "some" => "data" })
110
- end
111
-
112
- context 'for an IO-like object' do
113
- let(:io_object) { double(:read => 'the io object') }
114
-
115
- it 'reads the object before deserializing it' do
116
- expect(@object.content).to receive(:deserialize).with('the io object').and_return('deserialized')
117
- @object.raw_data = io_object
118
- expect(@object.data).to eq('deserialized')
119
- end
120
-
121
- it 'does not allow it to be assigned directly to data' do
122
- # it should be assigned to raw_data instead
123
- expect {
124
- @object.data = io_object
125
- }.to raise_error(ArgumentError)
126
- end
127
- end
128
- end
129
-
130
- it "only marshal/demarshals when necessary" do
131
- expect(@object).not_to receive(:serialize)
132
- expect(@object).not_to receive(:deserialize)
133
- @object.data = value = { "some" => "data" }
134
- expect(@object.data).to eq(value)
135
- end
136
- end
137
- end
138
-
139
-
140
- describe "instantiating new object from a map reduce operation" do
141
- before :each do
142
- allow(@client).to receive(:[]).and_return(@bucket)
143
-
144
- @sample_response = [
145
- {"bucket"=>"users",
146
- "key"=>"A2IbUQ2KEMbe4WGtdL97LoTi1DN%5B%28%5C%2F%29%5D",
147
- "vclock"=> "a85hYGBgzmDKBVIsCfs+fc9gSN9wlA8q/hKosDpIOAsA",
148
- "values"=> [
149
- {"metadata"=>
150
- {"Links"=>[%w(addresses A2cbUQ2KEMbeyWGtdz97LoTi1DN home_address)],
151
- "X-Riak-VTag"=>"5bnavU3rrubcxLI8EvFXhB",
152
- "content-type"=>"application/json",
153
- "X-Riak-Last-Modified"=>"Mon, 12 Jul 2010 21:37:43 GMT",
154
- "X-Riak-Meta"=>{"X-Riak-Meta-King-Of-Robots"=>"I"},
155
- "index" => {
156
- "email_bin" => ["sean@basho.com", "seancribbs@gmail.com"],
157
- "rank_int" => 50
158
- }
159
- },
160
- "data"=>
161
- "{\"email\":\"mail@test.com\",\"_type\":\"User\"}"
162
- }
163
- ]
164
- }
165
- ]
166
- @object = Riak::RObject.load_from_mapreduce(@client, @sample_response).first
167
- expect(@object).to be_kind_of(Riak::RObject)
168
- end
169
-
170
- it "loads the content type" do
171
- expect(@object.content_type).to eq("application/json")
172
- end
173
-
174
- it "loads the body data" do
175
- expect(@object.data).to be_present
176
- end
177
-
178
- it "deserializes the body data" do
179
- expect(@object.data).to eq({"email" => "mail@test.com", "_type" => "User"})
180
- end
181
-
182
- it "sets the vclock" do
183
- expect(@object.vclock).to eq("a85hYGBgzmDKBVIsCfs+fc9gSN9wlA8q/hKosDpIOAsA")
184
- expect(@object.causal_context).to eq @object.vclock
185
- end
186
-
187
- it "loads and parse links" do
188
- expect(@object.links.size).to eq(1)
189
- expect(@object.links.first.url).to eq("/riak/addresses/A2cbUQ2KEMbeyWGtdz97LoTi1DN")
190
- expect(@object.links.first.rel).to eq("home_address")
191
- end
192
-
193
- it "loads and parse indexes" do
194
- expect(@object.indexes.size).to eq(2)
195
- expect(@object.indexes['email_bin'].size).to eq(2)
196
- expect(@object.indexes['rank_int'].size).to eq(1)
197
- end
198
-
199
- it "sets the ETag" do
200
- expect(@object.etag).to eq("5bnavU3rrubcxLI8EvFXhB")
201
- end
202
-
203
- it "sets modified date" do
204
- expect(@object.last_modified.to_i).to eq(Time.httpdate("Mon, 12 Jul 2010 21:37:43 GMT").to_i)
205
- end
206
-
207
- it "loads meta information" do
208
- expect(@object.meta["King-Of-Robots"]).to eq(["I"])
209
- end
210
-
211
- it "sets the key" do
212
- expect(@object.key).to eq("A2IbUQ2KEMbe4WGtdL97LoTi1DN[(\\/)]")
213
- end
214
-
215
- it "doesn't set conflict when there is none" do
216
- expect(@object.conflict?).to be_falsey
217
- end
218
-
219
- it "doesn't set tombstone when there is none" do
220
- expect(@object.tombstone?).to be_falsey
221
- end
222
-
223
- it 'returns [RContent] for siblings' do
224
- expect(@object.siblings).to eq([@object.content])
225
- end
226
-
227
- describe "when there are multiple values in an object" do
228
- before :each do
229
- response = @sample_response.dup
230
- response[0]['values'] << {
231
- "metadata"=> {
232
- "Links"=>[],
233
- "X-Riak-VTag"=>"7jDZLdu0fIj2iRsjGD8qq8",
234
- "content-type"=>"application/json",
235
- "X-Riak-Last-Modified"=>"Mon, 14 Jul 2010 19:28:27 GMT",
236
- "X-Riak-Meta"=>[]
237
- },
238
- "data"=> "{\"email\":\"mail@domain.com\",\"_type\":\"User\"}"
239
- }
240
- @object = Riak::RObject.load_from_mapreduce( @client, response ).first
241
- end
242
-
243
- it "exposes siblings" do
244
- expect(@object.siblings.size).to eq(2)
245
- expect(@object.siblings[0].etag).to eq("5bnavU3rrubcxLI8EvFXhB")
246
- expect(@object.siblings[1].etag).to eq("7jDZLdu0fIj2iRsjGD8qq8")
247
- end
248
-
249
- it "raises the conflict? flag when in conflict" do
250
- expect { @object.data }.to raise_error(Riak::Conflict)
251
- expect(@object).to be_conflict
252
- end
253
- end
254
- end
255
-
256
- it "doesn't allow duplicate links" do
257
- @object = Riak::RObject.new(@bucket, "foo")
258
- @object.links << Riak::Link.new("/riak/foo/baz", "next")
259
- @object.links << Riak::Link.new("/riak/foo/baz", "next")
260
- expect(@object.links.length).to eq(1)
261
- end
262
-
263
- it "allows mass-overwriting indexes while preserving default behavior" do
264
- @object = described_class.new(@bucket, 'foo')
265
- @object.indexes = {"ts_int" => [12345], "foo_bin" => "bar"}
266
- expect(@object.indexes['ts_int']).to eq(Set.new([12345]))
267
- expect(@object.indexes['foo_bin']).to eq(Set.new(["bar"]))
268
- expect(@object.indexes['unset_bin']).to eq(Set.new)
269
- end
270
-
271
- describe "when storing the object normally" do
272
- before :each do
273
- @backend = double("Backend")
274
- allow(@client).to receive(:backend).and_yield(@backend)
275
- @object = Riak::RObject.new(@bucket)
276
- @object.content_type = "text/plain"
277
- @object.data = "This is some text."
278
- # @headers = @object.store_headers
279
- end
280
-
281
- it "raises an error when the content_type is blank" do
282
- expect do
283
- @object.content_type = nil
284
- @object.store
285
- end.to raise_error(ArgumentError)
286
- expect do
287
- @object.content_type = ' '
288
- @object.store
289
- end.to raise_error(ArgumentError)
290
- end
291
-
292
- it "raises an error when given an empty string as key" do
293
- expect do
294
- @object.key = ''
295
- @object.store
296
- end.to raise_error(ArgumentError)
297
- end
298
-
299
- it "passes quorum parameters and returnbody to the backend" do
300
- @object.key = 'foo'
301
- expect(@backend).to receive(:store_object).
302
- with(@object,
303
- returnbody: false,
304
- w: 3,
305
- dw: 2).
306
- and_return(true)
307
- @object.store(returnbody: false, w: 3, dw: 2)
308
- end
309
-
310
- it "raises an error if the object is in conflict" do
311
- @object.siblings << Riak::RContent.new(@object)
312
- expect { @object.store }.to raise_error(Riak::Conflict)
313
- end
314
- end
315
-
316
- describe "when reloading the object" do
317
- before :each do
318
- @backend = double("Backend")
319
- allow(@client).to receive(:backend).and_yield(@backend)
320
- @object = Riak::RObject.new(@bucket, "bar")
321
- @object.vclock = "somereallylongstring"
322
- end
323
-
324
- it "returns without requesting if the key is blank" do
325
- @object.key = nil
326
- expect(@backend).not_to receive(:reload_object)
327
- @object.reload
328
- end
329
-
330
- it "returns without requesting if the vclock is blank" do
331
- @object.vclock = nil
332
- expect(@backend).not_to receive(:reload_object)
333
- @object.reload
334
- end
335
-
336
- it "reloads the object if the key is present" do
337
- expect(@backend).to receive(:reload_object).with(@object, {}).and_return(@object)
338
- @object.reload
339
- end
340
-
341
- it "passes the requested R quorum to the backend" do
342
- expect(@backend).to receive(:reload_object).with(@object, :r => 2).and_return(@object)
343
- @object.reload :r => 2
344
- end
345
-
346
- it "disables matching conditions if the key is present and the :force option is given" do
347
- expect(@backend).to receive(:reload_object) do |obj, _|
348
- expect(obj.etag).to be_nil
349
- expect(obj.last_modified).to be_nil
350
- obj
351
- end
352
- @object.reload :force => true
353
- end
354
- end
355
-
356
- describe "when deleting" do
357
- before :each do
358
- @backend = double("Backend")
359
- allow(@client).to receive(:backend).and_yield(@backend)
360
- @object = Riak::RObject.new(@bucket, "bar")
361
- end
362
-
363
- it "makes a DELETE request to the Riak server and freeze the object" do
364
- expect(@backend).to receive(:delete_object).with(@bucket, "bar", {})
365
- @object.delete
366
- expect(@object).to be_frozen
367
- end
368
-
369
- it "does nothing when the key is blank" do
370
- expect(@backend).not_to receive(:delete_object)
371
- @object.key = nil
372
- @object.delete
373
- end
374
-
375
- it "raises a failed request exception when the backend returns a server error" do
376
- expect(@backend).to receive(:delete_object).
377
- and_raise(Riak::ProtobuffsFailedRequest.new(:server_error, "server error"))
378
- expect { @object.delete }.to raise_error(Riak::FailedRequest)
379
- end
380
-
381
- it "sends the vector clock to the backend if present" do
382
- @object.vclock = "somevclock"
383
- expect(@backend).to receive(:delete_object).with(@bucket, "bar", {:vclock => "somevclock"})
384
- @object.delete
385
- end
386
- end
387
-
388
- it "doesn't convert to link without a tag" do
389
- @object = Riak::RObject.new(@bucket, "bar")
390
- expect { @object.to_link }.to raise_error
391
- end
392
-
393
- it "converts to a link having the same url and a supplied tag" do
394
- @object = Riak::RObject.new(@bucket, "bar")
395
- expect(@object.to_link("next")).to eq(Riak::Link.new("/riak/foo/bar", "next"))
396
- end
397
-
398
- it "escapes the bucket and key when converting to a link" do
399
- @object = Riak::RObject.new(@bucket, "deep/path")
400
- expect(@bucket).to receive(:name).and_return("bucket spaces")
401
- expect(@object.to_link("bar").url).to eq("/riak/bucket%20spaces/deep%2Fpath")
402
- end
403
-
404
- describe "#inspect" do
405
- let(:object) { Riak::RObject.new(@bucket) }
406
-
407
- it "provides useful output even when the key is nil" do
408
- expect { object.inspect }.not_to raise_error
409
- expect(object.inspect).to be_kind_of(String)
410
- end
411
-
412
- it 'uses the serializer output in inspect' do
413
- object.raw_data = { 'a' => 7 }
414
- object.content_type = 'inspect/type'
415
- Riak::Serializers['inspect/type'] = Object.new.tap do |o|
416
- def o.load(object)
417
- "serialize for inspect"
418
- end
419
- end
420
-
421
- expect(object.inspect).to match(/serialize for inspect/)
422
- end
423
- end
424
-
425
- describe '.on_conflict' do
426
- it 'adds the hook to the list of on conflict hooks' do
427
- hook_run = false
428
- expect(described_class.on_conflict_hooks).to be_empty
429
- described_class.on_conflict { hook_run = true }
430
- expect(described_class.on_conflict_hooks.size).to eq(1)
431
- described_class.on_conflict_hooks.first.call
432
- expect(hook_run).to eq(true)
433
- end
434
- end
435
-
436
- describe '#attempt_conflict_resolution' do
437
- let(:conflicted_robject) do
438
- Riak::RObject.new(@bucket, "conflicted") do |r|
439
- r.siblings = [ Riak::RContent.new(r), Riak::RContent.new(r)]
440
- end
441
- end
442
- let(:resolved_robject) { Riak::RObject.new(@bucket, "resolved") }
443
- let(:invoked_resolvers) { [] }
444
- let(:resolver_1) do
445
- lambda do |r|
446
- invoked_resolvers << :resolver_1
447
- nil
448
- end
449
- end
450
- let(:resolver_2) do
451
- lambda do |r|
452
- invoked_resolvers << :resolver_2
453
- :not_an_robject
454
- end
455
- end
456
- let(:resolver_3) do
457
- lambda do |r|
458
- invoked_resolvers << :resolver_3
459
- r
460
- end
461
- end
462
- let(:resolver_4) do
463
- lambda do |r|
464
- invoked_resolvers << :resolver_4
465
- resolved_robject
466
- end
467
- end
468
-
469
- before(:each) do
470
- described_class.on_conflict(&resolver_1)
471
- described_class.on_conflict(&resolver_2)
472
- end
473
-
474
- it 'calls each resolver until one of them returns an robject' do
475
- described_class.on_conflict(&resolver_3)
476
- described_class.on_conflict(&resolver_4)
477
- conflicted_robject.attempt_conflict_resolution
478
- expect(invoked_resolvers).to eq([:resolver_1, :resolver_2, :resolver_3])
479
- end
480
-
481
- it 'returns the robject returned by the last invoked resolver' do
482
- described_class.on_conflict(&resolver_4)
483
- expect(conflicted_robject.attempt_conflict_resolution).to be(resolved_robject)
484
- end
485
-
486
- it 'allows the resolver to return the original robject' do
487
- described_class.on_conflict(&resolver_3)
488
- expect(conflicted_robject.attempt_conflict_resolution).to be(conflicted_robject)
489
- end
490
-
491
- it 'returns the robject and does not call any resolvers if the robject is not in conflict' do
492
- expect(resolved_robject.attempt_conflict_resolution).to be(resolved_robject)
493
- expect(invoked_resolvers).to eq([])
494
- end
495
-
496
- it 'returns the original robject if none of the resolvers returns an robject' do
497
- expect(conflicted_robject.attempt_conflict_resolution).to be(conflicted_robject)
498
- expect(invoked_resolvers).to eq([:resolver_1, :resolver_2])
499
- end
500
- end
501
-
502
- describe "when working with a tombstone object" do
503
- before :each do
504
- @backend = double("Backend")
505
- allow(@client).to receive(:backend).and_yield(@backend)
506
- @object =Riak::RObject.new(@bucket)
507
- @object.siblings.clear
508
- @object.vclock = "notnil"
509
- end
510
-
511
- it "sets the tombstone flag" do
512
- expect(@object.tombstone?).to be true
513
- end
514
-
515
- it "does not set the conflict flag" do
516
- expect(@object.conflict?).to be_falsey
517
- end
518
-
519
- it "does not allow you to store a tombstone" do
520
- expect { @object.store }.to raise_error(Riak::Tombstone)
521
- end
522
-
523
- it "does not allow you to fetch a value" do
524
- expect { @object.content }.to raise_error(Riak::Tombstone)
525
- end
526
-
527
- it "allows you to revive the object" do
528
- @object.revive
529
- expect(@object.tombstone?).to be_falsey
530
- expect(@object.siblings.empty?).to be_falsey
531
- end
532
-
533
- it "allows revived objects to be stored" do
534
- expect(@object.tombstone?).to be true
535
- @object.revive
536
- @object.content_type = "text/plain"
537
- @object.data = "This is some text."
538
- expect(@backend).to receive(:store_object).and_return(true)
539
- @object.store
540
- end
541
- end
542
- end