bson 1.12.5-java → 2.0.0-java

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of bson might be problematic. Click here for more details.

Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/CHANGELOG.md +80 -0
  5. data/CONTRIBUTING.md +42 -0
  6. data/NOTICE +2 -0
  7. data/README.md +190 -0
  8. data/Rakefile +109 -0
  9. data/lib/bson-ruby.jar +0 -0
  10. data/lib/bson.rb +60 -87
  11. data/lib/bson/array.rb +104 -0
  12. data/lib/bson/binary.rb +193 -0
  13. data/lib/bson/boolean.rb +48 -0
  14. data/lib/bson/code.rb +109 -0
  15. data/lib/bson/code_with_scope.rb +120 -0
  16. data/lib/bson/document.rb +549 -0
  17. data/lib/bson/encodable.rb +86 -0
  18. data/lib/bson/environment.rb +98 -0
  19. data/lib/bson/false_class.rb +61 -0
  20. data/lib/bson/float.rb +82 -0
  21. data/lib/bson/hash.rb +84 -0
  22. data/lib/bson/int32.rb +59 -0
  23. data/lib/bson/int64.rb +59 -0
  24. data/lib/bson/integer.rb +185 -0
  25. data/lib/bson/json.rb +37 -0
  26. data/lib/bson/max_key.rb +70 -0
  27. data/lib/bson/min_key.rb +70 -0
  28. data/lib/bson/nil_class.rb +70 -0
  29. data/lib/bson/object_id.rb +395 -0
  30. data/lib/bson/regexp.rb +124 -0
  31. data/lib/bson/registry.rb +70 -0
  32. data/lib/bson/specialized.rb +74 -0
  33. data/lib/bson/string.rb +203 -0
  34. data/lib/bson/symbol.rb +87 -0
  35. data/lib/bson/time.rb +72 -0
  36. data/lib/bson/timestamp.rb +113 -0
  37. data/lib/bson/true_class.rb +61 -0
  38. data/lib/bson/undefined.rb +74 -0
  39. data/lib/bson/version.rb +17 -0
  40. data/spec/bson/array_spec.rb +58 -0
  41. data/spec/bson/binary_spec.rb +115 -0
  42. data/spec/bson/boolean_spec.rb +48 -0
  43. data/spec/bson/code_spec.rb +42 -0
  44. data/spec/bson/code_with_scope_spec.rb +74 -0
  45. data/spec/bson/document_spec.rb +778 -0
  46. data/spec/bson/false_class_spec.rb +28 -0
  47. data/spec/bson/float_spec.rb +29 -0
  48. data/spec/bson/hash_spec.rb +56 -0
  49. data/spec/bson/int32_spec.rb +28 -0
  50. data/spec/bson/int64_spec.rb +28 -0
  51. data/spec/bson/integer_spec.rb +76 -0
  52. data/spec/bson/json_spec.rb +53 -0
  53. data/spec/bson/max_key_spec.rb +75 -0
  54. data/spec/bson/min_key_spec.rb +75 -0
  55. data/spec/bson/nil_class_spec.rb +29 -0
  56. data/spec/bson/object_id_spec.rb +527 -0
  57. data/spec/bson/regexp_spec.rb +89 -0
  58. data/spec/bson/registry_spec.rb +55 -0
  59. data/spec/bson/string_spec.rb +298 -0
  60. data/spec/bson/symbol_spec.rb +55 -0
  61. data/spec/bson/time_spec.rb +43 -0
  62. data/spec/bson/timestamp_spec.rb +74 -0
  63. data/spec/bson/true_class_spec.rb +28 -0
  64. data/spec/bson/undefined_spec.rb +29 -0
  65. data/{lib/bson/types/dbref.rb → spec/bson_spec.rb} +22 -16
  66. data/spec/spec_helper.rb +32 -0
  67. data/spec/support/shared_examples.rb +95 -0
  68. metadata +116 -48
  69. metadata.gz.sig +1 -1
  70. data/VERSION +0 -1
  71. data/bin/b2json +0 -63
  72. data/bin/j2bson +0 -64
  73. data/bson.gemspec +0 -34
  74. data/ext/jbson/lib/java-bson.jar +0 -0
  75. data/ext/jbson/target/jbson.jar +0 -0
  76. data/lib/bson/bson_c.rb +0 -37
  77. data/lib/bson/bson_java.rb +0 -49
  78. data/lib/bson/bson_ruby.rb +0 -645
  79. data/lib/bson/byte_buffer.rb +0 -241
  80. data/lib/bson/exceptions.rb +0 -37
  81. data/lib/bson/grow.rb +0 -173
  82. data/lib/bson/ordered_hash.rb +0 -197
  83. data/lib/bson/support/hash_with_indifferent_access.rb +0 -174
  84. data/lib/bson/types/binary.rb +0 -52
  85. data/lib/bson/types/code.rb +0 -55
  86. data/lib/bson/types/min_max_keys.rb +0 -56
  87. data/lib/bson/types/object_id.rb +0 -226
  88. data/lib/bson/types/regex.rb +0 -116
  89. data/lib/bson/types/timestamp.rb +0 -72
@@ -0,0 +1,42 @@
1
+ # Copyright (C) 2009-2013 MongoDB Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require "spec_helper"
16
+
17
+ describe BSON::Code do
18
+
19
+ describe "#as_json" do
20
+
21
+ let(:object) do
22
+ described_class.new("this.value = 5")
23
+ end
24
+
25
+ it "returns the binary data plus type" do
26
+ expect(object.as_json).to eq({ "$code" => "this.value = 5" })
27
+ end
28
+
29
+ it_behaves_like "a JSON serializable object"
30
+ end
31
+
32
+ describe "#to_bson/#from_bson" do
33
+
34
+ let(:type) { 13.chr }
35
+ let(:obj) { described_class.new("this.value = 5") }
36
+ let(:bson) { "#{15.to_bson}this.value = 5#{BSON::NULL_BYTE}" }
37
+
38
+ it_behaves_like "a bson element"
39
+ it_behaves_like "a serializable bson element"
40
+ it_behaves_like "a deserializable bson element"
41
+ end
42
+ end
@@ -0,0 +1,74 @@
1
+ # Copyright (C) 2009-2013 MongoDB Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require "spec_helper"
16
+
17
+ describe BSON::CodeWithScope do
18
+
19
+ describe "#as_json" do
20
+
21
+ let(:object) do
22
+ described_class.new("this.value = val", :val => "test")
23
+ end
24
+
25
+ it "returns the binary data plus type" do
26
+ expect(object.as_json).to eq(
27
+ { "$code" => "this.value = val", "$scope" => { :val => "test" }}
28
+ )
29
+ end
30
+
31
+ it_behaves_like "a JSON serializable object"
32
+ end
33
+
34
+ describe "#to_bson" do
35
+
36
+ let(:type) { 15.chr }
37
+ let(:code) { "this.value == name" }
38
+ let(:scope) do
39
+ { :name => "test" }
40
+ end
41
+ let(:obj) { described_class.new(code, scope) }
42
+ let(:bson) do
43
+ "#{47.to_bson}#{(code.length + 1).to_bson}#{code}#{BSON::NULL_BYTE}" +
44
+ "#{scope.to_bson}"
45
+ end
46
+
47
+ it_behaves_like "a bson element"
48
+ it_behaves_like "a serializable bson element"
49
+ end
50
+
51
+ describe "#from_bson" do
52
+
53
+ let(:type) { 15.chr }
54
+ let(:code) { "this.value == name" }
55
+ let(:scope) do
56
+ { "name" => "test" }
57
+ end
58
+ let(:obj) { described_class.new(code, scope) }
59
+ let(:bson) { StringIO.new(obj.to_bson) }
60
+ let!(:deserialized) { described_class.from_bson(bson) }
61
+
62
+ it "deserializes the javascript" do
63
+ expect(deserialized.javascript).to eq(code)
64
+ end
65
+
66
+ it "deserializes the scope" do
67
+ expect(deserialized.scope).to eq(scope)
68
+ end
69
+
70
+ it "does not leave any extra bytes" do
71
+ expect(bson.read(1)).to be_nil
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,778 @@
1
+ # encoding: utf-8
2
+
3
+ # Copyright (C) 2009-2013 MongoDB Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require "spec_helper"
18
+
19
+ describe BSON::Document do
20
+
21
+ let(:keys) { %w(blue green red pink orange) }
22
+ let(:vals) { %w(000099 009900 aa0000 cc0066 cc6633) }
23
+ let(:doc) { described_class.new }
24
+ let(:hash) do
25
+ {}
26
+ end
27
+ let(:enum_class) do
28
+ BSON::Environment.ruby_18? ? Enumerable::Enumerator : Enumerator
29
+ end
30
+
31
+ before do
32
+ keys.each_with_index do |key, index|
33
+ hash[key] = vals[index]
34
+ doc[key] = vals[index]
35
+ end
36
+ end
37
+
38
+ describe "#keys" do
39
+
40
+ it "retains the insertion order" do
41
+ expect(doc.keys).to eq(keys)
42
+ end
43
+ end
44
+
45
+ describe "#values" do
46
+
47
+ it "retains the insertion order" do
48
+ expect(doc.values).to eq(vals)
49
+ end
50
+ end
51
+
52
+ describe "#[]" do
53
+
54
+ let(:document) do
55
+ described_class["key", "value", "key2", "value"]
56
+ end
57
+
58
+ context "when provided string keys" do
59
+
60
+ it "returns the value" do
61
+ expect(document["key"]).to eq("value")
62
+ end
63
+ end
64
+
65
+ context "when provided symbol keys" do
66
+
67
+ it "returns the value" do
68
+ expect(document[:key]).to eq("value")
69
+ end
70
+ end
71
+ end
72
+
73
+ describe "#[]=" do
74
+
75
+ let(:key) { "purple" }
76
+ let(:val) { "5422a8" }
77
+
78
+ before do
79
+ doc[key] = val
80
+ end
81
+
82
+ it "updates the length" do
83
+ expect(doc.length).to eq(keys.length + 1)
84
+ end
85
+
86
+ it "adds the key to the end" do
87
+ expect(doc.keys.last).to eq(key)
88
+ end
89
+
90
+ it "adds the value to the end" do
91
+ expect(doc.values.last).to eq(val)
92
+ end
93
+
94
+ it "sets the value" do
95
+ expect(doc[key]).to eq(val)
96
+ end
97
+ end
98
+
99
+ describe "#delete" do
100
+
101
+ let(:key) { "white" }
102
+ let(:val) { "ffffff" }
103
+ let(:bad_key) { "black" }
104
+
105
+ before do
106
+ doc[key] = val
107
+ end
108
+
109
+ let!(:deleted) { doc.delete(key) }
110
+
111
+ it "returns the deleted value" do
112
+ expect(deleted).to eq(val)
113
+ end
114
+
115
+ it "removes the key from the list" do
116
+ expect(doc.keys.length).to eq(keys.length)
117
+ end
118
+
119
+ it "matches the keys length to the document length" do
120
+ expect(doc.length).to eq(doc.keys.length)
121
+ end
122
+
123
+ context "when removind a bad key" do
124
+
125
+ it "returns nil" do
126
+ expect(doc.delete(bad_key)).to be_nil
127
+ end
128
+ end
129
+ end
130
+
131
+ describe "#to_hash" do
132
+
133
+ it "returns the document" do
134
+ expect(doc.to_hash).to eq(doc)
135
+ end
136
+ end
137
+
138
+ describe "#to_a" do
139
+
140
+ it "returns the key/value pairs as an array" do
141
+ expect(doc.to_a).to eq(keys.zip(vals))
142
+ end
143
+ end
144
+
145
+ [ :has_key?, :key?, :include?, :member? ].each do |method|
146
+
147
+ describe "##{method}" do
148
+
149
+ context "when the key exists" do
150
+
151
+ it "returns true" do
152
+ expect(doc.send(method, "blue")).to be_true
153
+ end
154
+ end
155
+
156
+ context "when the key does not exist" do
157
+
158
+ it "returns false" do
159
+ expect(doc.send(method, "indigo")).to be_false
160
+ end
161
+ end
162
+ end
163
+ end
164
+
165
+ [ :has_value?, :value? ].each do |method|
166
+
167
+ describe "##{method}" do
168
+
169
+ context "when the value exists" do
170
+
171
+ it "returns true" do
172
+ expect(doc.send(method, "000099")).to be_true
173
+ end
174
+ end
175
+
176
+ context "when the value does not exist" do
177
+
178
+ it "returns false" do
179
+ expect(doc.send(method, "ABCABC")).to be_false
180
+ end
181
+ end
182
+ end
183
+ end
184
+
185
+ describe "#each_key" do
186
+
187
+ let(:iter_keys) {[]}
188
+
189
+ context "when passed a block" do
190
+
191
+ let!(:enum) do
192
+ doc.each_key{ |k| iter_keys << k }
193
+ end
194
+
195
+ it "returns the document" do
196
+ expect(enum).to equal(doc)
197
+ end
198
+
199
+ it "iterates over each of the keys" do
200
+ expect(iter_keys).to eq(keys)
201
+ end
202
+ end
203
+
204
+ context "when not passed a block" do
205
+
206
+ let!(:enum) do
207
+ doc.each_key
208
+ end
209
+
210
+ it "returns an enumerator" do
211
+ expect(enum).to be_a(enum_class)
212
+ end
213
+ end
214
+ end
215
+
216
+ describe "#each_value" do
217
+
218
+ let(:iter_vals) {[]}
219
+
220
+ context "when passed a block" do
221
+
222
+ let!(:enum) do
223
+ doc.each_value{ |v| iter_vals << v }
224
+ end
225
+
226
+ it "returns the document" do
227
+ expect(enum).to equal(doc)
228
+ end
229
+
230
+ it "iterates over each of the vals" do
231
+ expect(iter_vals).to eq(vals)
232
+ end
233
+ end
234
+
235
+ context "when not passed a block" do
236
+
237
+ let!(:enum) do
238
+ doc.each_value
239
+ end
240
+
241
+ it "returns an enumerator" do
242
+ expect(enum).to be_a(enum_class)
243
+ end
244
+ end
245
+ end
246
+
247
+ [ :each, :each_pair ].each do |method|
248
+
249
+ describe "##{method}" do
250
+
251
+ let(:iter_keys) {[]}
252
+ let(:iter_vals) {[]}
253
+
254
+ context "when passed a block" do
255
+
256
+ let!(:enum) do
257
+ doc.send(method) do |k, v|
258
+ iter_keys << k
259
+ iter_vals << v
260
+ end
261
+ end
262
+
263
+ it "returns the document" do
264
+ expect(enum).to equal(doc)
265
+ end
266
+
267
+ it "iterates over each of the keys" do
268
+ expect(iter_keys).to eq(keys)
269
+ end
270
+
271
+ it "iterates over each of the vals" do
272
+ expect(iter_vals).to eq(vals)
273
+ end
274
+ end
275
+
276
+ context "when not passed a block" do
277
+
278
+ let!(:enum) do
279
+ doc.send(method)
280
+ end
281
+
282
+ it "returns an enumerator" do
283
+ expect(enum).to be_a(enum_class)
284
+ end
285
+ end
286
+
287
+ context "when the document has been serialized" do
288
+
289
+ let(:deserialized) do
290
+ YAML.load(YAML.dump(doc))
291
+ end
292
+
293
+ let!(:enum) do
294
+ deserialized.send(method) do |k, v|
295
+ iter_keys << k
296
+ iter_vals << v
297
+ end
298
+ end
299
+
300
+ it "iterates over each of the keys" do
301
+ expect(iter_keys).to eq(keys)
302
+ end
303
+
304
+ it "iterates over each of the vals" do
305
+ expect(iter_vals).to eq(vals)
306
+ end
307
+ end
308
+ end
309
+ end
310
+
311
+ describe "#each_with_index" do
312
+
313
+ it "iterates over the document passing an index" do
314
+ doc.each_with_index do |pair, index|
315
+ expect(pair).to eq([ keys[index], vals[index] ])
316
+ end
317
+ end
318
+ end
319
+
320
+ describe "#find_all" do
321
+
322
+ it "iterates in the correct order" do
323
+ expect(doc.find_all{ true }.map(&:first)).to eq(keys)
324
+ end
325
+ end
326
+
327
+ describe "#select" do
328
+
329
+ it "iterates in the correct order" do
330
+ expect(doc.select{ true }.map(&:first)).to eq(keys)
331
+ end
332
+ end
333
+
334
+ [ :delete_if, :reject! ].each do |method|
335
+
336
+ describe "##{method}" do
337
+
338
+ let(:copy) { doc.dup }
339
+
340
+ before do
341
+ copy.delete("pink")
342
+ end
343
+
344
+ let!(:deleted) do
345
+ doc.send(method){ |k, _| k == "pink" }
346
+ end
347
+
348
+ it "deletes elements for which the block is true" do
349
+ expect(deleted).to eq(copy)
350
+ end
351
+
352
+ it "deletes the matching keys from the document" do
353
+ expect(doc.keys).to_not include("pink")
354
+ end
355
+
356
+ it "returns the same document" do
357
+ expect(deleted).to equal(doc)
358
+ end
359
+ end
360
+ end
361
+
362
+ describe "#reject" do
363
+
364
+ let(:copy) { doc.dup }
365
+
366
+ before do
367
+ copy.delete("pink")
368
+ end
369
+
370
+ let!(:deleted) do
371
+ doc.reject{ |k, _| k == "pink" }
372
+ end
373
+
374
+ it "deletes elements for which the block is true" do
375
+ expect(deleted).to eq(copy)
376
+ end
377
+
378
+ it "deletes the matching keys from the new document" do
379
+ expect(deleted.keys).to_not include("pink")
380
+ end
381
+
382
+ it "returns a new document" do
383
+ expect(deleted).to_not equal(doc)
384
+ end
385
+ end
386
+
387
+ describe "#clear" do
388
+
389
+ before do
390
+ doc.clear
391
+ end
392
+
393
+ it "clears out the keys" do
394
+ expect(doc.keys).to be_empty
395
+ end
396
+ end
397
+
398
+ describe "#merge" do
399
+
400
+ let(:other) { described_class.new }
401
+
402
+ context "when passed no block" do
403
+
404
+ before do
405
+ other["purple"] = "800080"
406
+ other["violet"] = "ee82ee"
407
+ end
408
+
409
+ let!(:merged) do
410
+ doc.merge(other)
411
+ end
412
+
413
+ it "merges the keys" do
414
+ expect(merged.keys).to eq(keys + [ "purple", "violet" ])
415
+ end
416
+
417
+ it "adds to the length" do
418
+ expect(merged.length).to eq(doc.length + other.length)
419
+ end
420
+
421
+ it "returns a new document" do
422
+ expect(merged).to_not equal(doc)
423
+ end
424
+ end
425
+
426
+ context "when passed a block" do
427
+
428
+ before do
429
+ other[:a] = 0
430
+ other[:b] = 0
431
+ end
432
+
433
+ let(:merged) do
434
+ other.merge(:b => 2, :c => 7) do |key, old_val, new_val|
435
+ new_val + 1
436
+ end
437
+ end
438
+
439
+ it "executes the block on each merged element" do
440
+ expect(merged[:a]).to eq(0)
441
+ expect(merged[:b]).to eq(3)
442
+ expect(merged[:c]).to eq(7)
443
+ end
444
+ end
445
+ end
446
+
447
+ describe "#merge!" do
448
+
449
+ let(:other) { described_class.new }
450
+
451
+ context "when passed no block" do
452
+
453
+ before do
454
+ other["purple"] = "800080"
455
+ other["violet"] = "ee82ee"
456
+ end
457
+
458
+ let(:merged) do
459
+ doc.merge!(other)
460
+ end
461
+
462
+ it "merges the keys" do
463
+ expect(merged.keys).to eq(keys + [ "purple", "violet" ])
464
+ end
465
+
466
+ it "adds to the length" do
467
+ expect(merged.length).to eq(doc.length)
468
+ end
469
+
470
+ it "returns the same document" do
471
+ expect(merged).to equal(doc)
472
+ end
473
+ end
474
+
475
+ context "when passed a block" do
476
+
477
+ before do
478
+ other[:a] = 0
479
+ other[:b] = 0
480
+ end
481
+
482
+ let!(:merged) do
483
+ other.merge!(:b => 2, :c => 7) do |key, old_val, new_val|
484
+ new_val + 1
485
+ end
486
+ end
487
+
488
+ it "executes the block on each merged element" do
489
+ expect(other[:a]).to eq(0)
490
+ expect(other[:b]).to eq(3)
491
+ expect(other[:c]).to eq(7)
492
+ end
493
+ end
494
+ end
495
+
496
+ describe "#shift" do
497
+
498
+ let(:pair) do
499
+ doc.shift
500
+ end
501
+
502
+ it "returns the first pair in the document" do
503
+ expect(pair).to eq([ keys.first, vals.first ])
504
+ end
505
+
506
+ it "removes the pair from the document" do
507
+ expect(doc.keys).to_not eq(pair.first)
508
+ end
509
+ end
510
+
511
+ describe "#inspect" do
512
+
513
+ it "includes the hash inspect" do
514
+ expect(doc.inspect).to include(hash.inspect)
515
+ end
516
+ end
517
+
518
+ describe "#initialize" do
519
+
520
+ context "when provided for splat args" do
521
+
522
+ context "when an even number of args" do
523
+
524
+ let(:alternate) do
525
+ described_class[1, 2, 3, 4]
526
+ end
527
+
528
+ it "treats the arguments are an array" do
529
+ expect(alternate.keys).to eq([ 1, 3 ])
530
+ end
531
+
532
+ it "instantiates a document" do
533
+ expect(alternate).to be_a(BSON::Document)
534
+ end
535
+ end
536
+
537
+ context "when an odd number of arguments" do
538
+
539
+ it "raises an argument error" do
540
+ expect {
541
+ described_class[1, 2, 3]
542
+ }.to raise_error(ArgumentError)
543
+ end
544
+ end
545
+ end
546
+
547
+ context "when provided an array" do
548
+
549
+ let(:alternate) do
550
+ described_class[[[ 1, 2 ], [ 3, 4 ], [ "missing" ]]]
551
+ end
552
+
553
+ it "sets the keys" do
554
+ expect(alternate.keys).to eq([ 1, 3, "missing" ])
555
+ end
556
+
557
+ it "sets the values" do
558
+ expect(alternate.values).to eq([ 2, 4, nil ])
559
+ end
560
+ end
561
+
562
+ if BSON::Environment.retaining_hash_order?
563
+
564
+ context "when provided hashes" do
565
+
566
+ let(:alternate) do
567
+ described_class[1 => 2, 3 => 4]
568
+ end
569
+
570
+ it "sets the keys" do
571
+ expect(alternate.keys).to eq([ 1, 3 ])
572
+ end
573
+
574
+ it "sets the values" do
575
+ expect(alternate.values).to eq([ 2, 4 ])
576
+ end
577
+ end
578
+ end
579
+ end
580
+
581
+ describe "#replace" do
582
+
583
+ let(:other) do
584
+ described_class[:black, "000000", :white, "000000"]
585
+ end
586
+
587
+ let!(:original) { doc.replace(other) }
588
+
589
+ it "replaces the keys" do
590
+ expect(doc.keys).to eq(other.keys)
591
+ end
592
+
593
+ it "returns the document" do
594
+ expect(original).to eq(doc)
595
+ end
596
+ end
597
+
598
+ describe "#update" do
599
+
600
+ let(:updated) { described_class.new }
601
+
602
+ before do
603
+ updated.update(:name => "Bob")
604
+ end
605
+
606
+ it "updates the keys" do
607
+ expect(updated.keys).to eq([ :name ])
608
+ end
609
+
610
+ it "updates the values" do
611
+ expect(updated.values).to eq([ "Bob" ])
612
+ end
613
+ end
614
+
615
+ describe "#invert" do
616
+
617
+ let(:expected) do
618
+ described_class[vals.zip(keys)]
619
+ end
620
+
621
+ it "inverts the hash in inverse order" do
622
+ expect(doc.invert).to eq(expected)
623
+ end
624
+
625
+ it "inverts the keys" do
626
+ expect(vals.zip(keys)).to eq(doc.invert.to_a)
627
+ end
628
+ end
629
+
630
+ describe "#to_bson/#from_bson" do
631
+
632
+ let(:type) { 3.chr }
633
+
634
+ it_behaves_like "a bson element"
635
+
636
+ context "when the hash is a single level" do
637
+
638
+ let(:obj) do
639
+ described_class["key","value"]
640
+ end
641
+
642
+ let(:bson) do
643
+ "#{20.to_bson}#{String::BSON_TYPE}key#{BSON::NULL_BYTE}" +
644
+ "#{6.to_bson}value#{BSON::NULL_BYTE}#{BSON::NULL_BYTE}"
645
+ end
646
+
647
+ it_behaves_like "a serializable bson element"
648
+ it_behaves_like "a deserializable bson element"
649
+ end
650
+
651
+ context "when the hash is embedded" do
652
+
653
+ let(:obj) do
654
+ described_class["field", BSON::Document["key", "value"]]
655
+ end
656
+
657
+ let(:bson) do
658
+ "#{32.to_bson}#{Hash::BSON_TYPE}field#{BSON::NULL_BYTE}" +
659
+ "#{20.to_bson}#{String::BSON_TYPE}key#{BSON::NULL_BYTE}" +
660
+ "#{6.to_bson}value#{BSON::NULL_BYTE}#{BSON::NULL_BYTE}#{BSON::NULL_BYTE}"
661
+ end
662
+
663
+ it_behaves_like "a serializable bson element"
664
+ it_behaves_like "a deserializable bson element"
665
+
666
+ let(:raw) do
667
+ StringIO.new(bson)
668
+ end
669
+
670
+ it "returns an instance of a BSON::Document" do
671
+ expect(described_class.from_bson(raw)).to be_a(BSON::Document)
672
+ end
673
+ end
674
+ end
675
+
676
+ context "when encoding and decoding" do
677
+
678
+ context "when the keys are utf-8" do
679
+
680
+ let(:document) do
681
+ described_class["gültig", "type"]
682
+ end
683
+
684
+ it_behaves_like "a document able to handle utf-8"
685
+ end
686
+
687
+ context "when the values are utf-8" do
688
+
689
+ let(:document) do
690
+ described_class["type", "gültig"]
691
+ end
692
+
693
+ it_behaves_like "a document able to handle utf-8"
694
+ end
695
+
696
+ context "when both the keys and values are utf-8" do
697
+
698
+ let(:document) do
699
+ described_class["gültig", "gültig"]
700
+ end
701
+
702
+ it_behaves_like "a document able to handle utf-8"
703
+ end
704
+
705
+ context "when the regexps are utf-8" do
706
+
707
+ let(:document) do
708
+ described_class["type", /^gültig/]
709
+ end
710
+
711
+ it_behaves_like "a document able to handle utf-8"
712
+ end
713
+
714
+ context "when the symbols are utf-8" do
715
+
716
+ let(:document) do
717
+ described_class["type", "gültig".to_sym]
718
+ end
719
+
720
+ it_behaves_like "a document able to handle utf-8"
721
+ end
722
+
723
+ context "when utf-8 string values are in an array" do
724
+
725
+ let(:document) do
726
+ described_class["type", ["gültig"]]
727
+ end
728
+
729
+ it_behaves_like "a document able to handle utf-8"
730
+ end
731
+
732
+ context "when utf-8 code values are present" do
733
+
734
+ let(:document) do
735
+ described_class["code", BSON::Code.new("// gültig")]
736
+ end
737
+
738
+ it_behaves_like "a document able to handle utf-8"
739
+ end
740
+
741
+ pending "when utf-8 code with scope values are present" do
742
+
743
+ let(:document) do
744
+ described_class["code", BSON::CodeWithScope.new("// gültig", {})]
745
+ end
746
+
747
+ it_behaves_like "a document able to handle utf-8"
748
+ end
749
+
750
+ context "when non utf-8 values exist" do
751
+
752
+ let(:string) { "gültig" }
753
+ let(:document) do
754
+ described_class["type", string.encode("iso-8859-1")]
755
+ end
756
+
757
+ it "encodes and decodes the document properly" do
758
+ expect(
759
+ BSON::Document.from_bson(StringIO.new(document.to_bson))
760
+ ).to eq({ "type" => string })
761
+ end
762
+ end
763
+
764
+ context "when binary strings with utf-8 values exist" do
765
+
766
+ let(:string) { "europäischen" }
767
+ let(:document) do
768
+ described_class["type", string.encode("binary", "binary")]
769
+ end
770
+
771
+ it "encodes and decodes the document properly" do
772
+ expect(
773
+ BSON::Document.from_bson(StringIO.new(document.to_bson))
774
+ ).to eq({ "type" => string })
775
+ end
776
+ end
777
+ end
778
+ end