bson 4.2.2 → 4.12.1

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 (169) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +25 -7
  5. data/Rakefile +16 -9
  6. data/ext/bson/{native-endian.h → bson-endian.h} +5 -99
  7. data/ext/bson/bson-native.h +125 -0
  8. data/ext/bson/bytebuf.c +133 -0
  9. data/ext/bson/endian.c +117 -0
  10. data/ext/bson/init.c +355 -0
  11. data/ext/bson/libbson-utf8.c +230 -0
  12. data/ext/bson/read.c +411 -0
  13. data/ext/bson/util.c +95 -0
  14. data/ext/bson/write.c +680 -0
  15. data/lib/bson.rb +6 -3
  16. data/lib/bson/active_support.rb +17 -0
  17. data/lib/bson/array.rb +57 -17
  18. data/lib/bson/binary.rb +185 -13
  19. data/lib/bson/boolean.rb +12 -3
  20. data/lib/bson/code.rb +16 -2
  21. data/lib/bson/code_with_scope.rb +32 -5
  22. data/lib/bson/config.rb +1 -1
  23. data/lib/bson/date.rb +12 -2
  24. data/lib/bson/date_time.rb +2 -2
  25. data/lib/bson/db_pointer.rb +110 -0
  26. data/lib/bson/decimal128.rb +17 -3
  27. data/lib/bson/decimal128/builder.rb +1 -1
  28. data/lib/bson/document.rb +152 -5
  29. data/lib/bson/environment.rb +2 -1
  30. data/lib/bson/error.rb +27 -0
  31. data/lib/bson/ext_json.rb +383 -0
  32. data/lib/bson/false_class.rb +1 -1
  33. data/lib/bson/float.rb +48 -2
  34. data/lib/bson/hash.rb +68 -17
  35. data/lib/bson/int32.rb +52 -13
  36. data/lib/bson/int64.rb +59 -15
  37. data/lib/bson/integer.rb +36 -2
  38. data/lib/bson/json.rb +1 -1
  39. data/lib/bson/max_key.rb +13 -1
  40. data/lib/bson/min_key.rb +13 -1
  41. data/lib/bson/nil_class.rb +4 -2
  42. data/lib/bson/object.rb +28 -1
  43. data/lib/bson/object_id.rb +16 -2
  44. data/lib/bson/open_struct.rb +1 -1
  45. data/lib/bson/regexp.rb +27 -4
  46. data/lib/bson/registry.rb +3 -3
  47. data/lib/bson/specialized.rb +4 -2
  48. data/lib/bson/string.rb +5 -3
  49. data/lib/bson/symbol.rb +99 -7
  50. data/lib/bson/time.rb +63 -4
  51. data/lib/bson/time_with_zone.rb +54 -0
  52. data/lib/bson/timestamp.rb +44 -6
  53. data/lib/bson/true_class.rb +1 -1
  54. data/lib/bson/undefined.rb +12 -1
  55. data/lib/bson/version.rb +2 -2
  56. data/spec/bson/array_spec.rb +18 -1
  57. data/spec/bson/binary_spec.rb +100 -3
  58. data/spec/bson/binary_uuid_spec.rb +189 -0
  59. data/spec/bson/boolean_spec.rb +1 -1
  60. data/spec/bson/byte_buffer_read_spec.rb +197 -0
  61. data/spec/bson/byte_buffer_spec.rb +121 -381
  62. data/spec/bson/byte_buffer_write_spec.rb +854 -0
  63. data/spec/bson/code_spec.rb +1 -1
  64. data/spec/bson/code_with_scope_spec.rb +1 -1
  65. data/spec/bson/date_spec.rb +1 -1
  66. data/spec/bson/date_time_spec.rb +54 -1
  67. data/spec/bson/decimal128_spec.rb +35 -35
  68. data/spec/bson/document_as_spec.rb +46 -0
  69. data/spec/bson/document_spec.rb +197 -30
  70. data/spec/bson/ext_json_parse_spec.rb +308 -0
  71. data/spec/bson/false_class_spec.rb +1 -1
  72. data/spec/bson/float_spec.rb +37 -1
  73. data/spec/bson/hash_as_spec.rb +57 -0
  74. data/spec/bson/hash_spec.rb +209 -1
  75. data/spec/bson/int32_spec.rb +180 -6
  76. data/spec/bson/int64_spec.rb +199 -6
  77. data/spec/bson/integer_spec.rb +29 -3
  78. data/spec/bson/json_spec.rb +1 -1
  79. data/spec/bson/max_key_spec.rb +1 -1
  80. data/spec/bson/min_key_spec.rb +1 -1
  81. data/spec/bson/nil_class_spec.rb +1 -1
  82. data/spec/bson/object_id_spec.rb +1 -1
  83. data/spec/bson/object_spec.rb +1 -1
  84. data/spec/bson/open_struct_spec.rb +1 -1
  85. data/spec/bson/raw_spec.rb +34 -2
  86. data/spec/bson/regexp_spec.rb +1 -1
  87. data/spec/bson/registry_spec.rb +1 -1
  88. data/spec/bson/string_spec.rb +19 -1
  89. data/spec/bson/symbol_raw_spec.rb +45 -0
  90. data/spec/bson/symbol_spec.rb +63 -3
  91. data/spec/bson/time_spec.rb +205 -2
  92. data/spec/bson/time_with_zone_spec.rb +68 -0
  93. data/spec/bson/timestamp_spec.rb +56 -1
  94. data/spec/bson/true_class_spec.rb +1 -1
  95. data/spec/bson/undefined_spec.rb +1 -1
  96. data/spec/bson_spec.rb +1 -1
  97. data/spec/{support → runners}/common_driver.rb +1 -1
  98. data/spec/runners/corpus.rb +185 -0
  99. data/spec/{support/corpus.rb → runners/corpus_legacy.rb} +41 -59
  100. data/spec/spec_helper.rb +40 -3
  101. data/spec/{bson/driver_bson_spec.rb → spec_tests/common_driver_spec.rb} +1 -0
  102. data/spec/{bson/corpus_spec.rb → spec_tests/corpus_legacy_spec.rb} +10 -7
  103. data/spec/spec_tests/corpus_spec.rb +124 -0
  104. data/spec/spec_tests/data/corpus/README.md +15 -0
  105. data/spec/spec_tests/data/corpus/array.json +49 -0
  106. data/spec/spec_tests/data/corpus/binary.json +113 -0
  107. data/spec/spec_tests/data/corpus/boolean.json +27 -0
  108. data/spec/spec_tests/data/corpus/code.json +67 -0
  109. data/spec/spec_tests/data/corpus/code_w_scope.json +78 -0
  110. data/spec/spec_tests/data/corpus/datetime.json +42 -0
  111. data/spec/spec_tests/data/corpus/dbpointer.json +56 -0
  112. data/spec/spec_tests/data/corpus/dbref.json +31 -0
  113. data/spec/spec_tests/data/corpus/decimal128-1.json +317 -0
  114. data/spec/spec_tests/data/corpus/decimal128-2.json +793 -0
  115. data/spec/spec_tests/data/corpus/decimal128-3.json +1771 -0
  116. data/spec/spec_tests/data/corpus/decimal128-4.json +117 -0
  117. data/spec/spec_tests/data/corpus/decimal128-5.json +402 -0
  118. data/spec/spec_tests/data/corpus/decimal128-6.json +119 -0
  119. data/spec/spec_tests/data/corpus/decimal128-7.json +323 -0
  120. data/spec/spec_tests/data/corpus/document.json +36 -0
  121. data/spec/spec_tests/data/corpus/double.json +87 -0
  122. data/spec/spec_tests/data/corpus/int32.json +43 -0
  123. data/spec/spec_tests/data/corpus/int64.json +43 -0
  124. data/spec/spec_tests/data/corpus/maxkey.json +12 -0
  125. data/spec/spec_tests/data/corpus/minkey.json +12 -0
  126. data/spec/spec_tests/data/corpus/multi-type-deprecated.json +15 -0
  127. data/spec/spec_tests/data/corpus/multi-type.json +11 -0
  128. data/spec/spec_tests/data/corpus/null.json +12 -0
  129. data/spec/spec_tests/data/corpus/oid.json +28 -0
  130. data/spec/spec_tests/data/corpus/regex.json +65 -0
  131. data/spec/spec_tests/data/corpus/string.json +72 -0
  132. data/spec/spec_tests/data/corpus/symbol.json +80 -0
  133. data/spec/spec_tests/data/corpus/timestamp.json +34 -0
  134. data/spec/spec_tests/data/corpus/top.json +236 -0
  135. data/spec/spec_tests/data/corpus/undefined.json +15 -0
  136. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/array.json +8 -2
  137. data/spec/{support/corpus-tests/failures → spec_tests/data/corpus_legacy}/binary.json +0 -0
  138. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/boolean.json +0 -0
  139. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/code.json +1 -1
  140. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/code_w_scope.json +1 -1
  141. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/document.json +1 -1
  142. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/double.json +1 -1
  143. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/datetime.json +0 -0
  144. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/dbpointer.json +0 -0
  145. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/int64.json +0 -0
  146. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/failures/symbol.json +0 -0
  147. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/int32.json +1 -1
  148. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/maxkey.json +1 -1
  149. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/minkey.json +1 -1
  150. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/null.json +1 -1
  151. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/oid.json +0 -0
  152. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/regex.json +1 -1
  153. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/string.json +0 -0
  154. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/timestamp.json +1 -1
  155. data/spec/{support/corpus-tests → spec_tests/data/corpus_legacy}/top.json +0 -0
  156. data/spec/{support/corpus-tests/failures → spec_tests/data/corpus_legacy}/undefined.json +0 -0
  157. data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-1.json +0 -0
  158. data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-2.json +0 -0
  159. data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-3.json +0 -0
  160. data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-4.json +0 -0
  161. data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-5.json +0 -0
  162. data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-6.json +0 -0
  163. data/spec/{support/driver-spec-tests → spec_tests/data}/decimal128/decimal128-7.json +0 -0
  164. data/spec/support/shared_examples.rb +3 -5
  165. data/spec/support/spec_config.rb +16 -0
  166. data/spec/support/utils.rb +10 -0
  167. metadata +227 -124
  168. metadata.gz.sig +0 -0
  169. data/ext/bson/bson_native.c +0 -762
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2009-2014 MongoDB Inc.
1
+ # Copyright (C) 2009-2020 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -0,0 +1,197 @@
1
+ require 'spec_helper'
2
+
3
+ describe BSON::ByteBuffer do
4
+
5
+ describe '#get_byte' do
6
+
7
+ let(:buffer) do
8
+ described_class.new(BSON::Int32::BSON_TYPE)
9
+ end
10
+
11
+ let!(:byte) do
12
+ buffer.get_byte
13
+ end
14
+
15
+ it 'gets the byte from the buffer' do
16
+ expect(byte).to eq(BSON::Int32::BSON_TYPE)
17
+ end
18
+
19
+ it 'increments the read position by 1' do
20
+ expect(buffer.read_position).to eq(1)
21
+ end
22
+ end
23
+
24
+ describe '#get_bytes' do
25
+
26
+ let(:string) do
27
+ "#{BSON::Int32::BSON_TYPE}#{BSON::Int32::BSON_TYPE}"
28
+ end
29
+
30
+ let(:buffer) do
31
+ described_class.new(string)
32
+ end
33
+
34
+ let!(:bytes) do
35
+ buffer.get_bytes(2)
36
+ end
37
+
38
+ it 'gets the bytes from the buffer' do
39
+ expect(bytes).to eq(string)
40
+ end
41
+
42
+ it 'increments the position by the length' do
43
+ expect(buffer.read_position).to eq(string.bytesize)
44
+ end
45
+ end
46
+
47
+ describe '#get_cstring' do
48
+
49
+ let(:buffer) do
50
+ described_class.new("testing#{BSON::NULL_BYTE}")
51
+ end
52
+
53
+ let!(:string) do
54
+ buffer.get_cstring
55
+ end
56
+
57
+ it 'gets the cstring from the buffer' do
58
+ expect(string).to eq("testing")
59
+ end
60
+
61
+ it 'increments the position by string length + 1' do
62
+ expect(buffer.read_position).to eq(8)
63
+ end
64
+ end
65
+
66
+ describe '#get_double' do
67
+
68
+ let(:buffer) do
69
+ described_class.new(12.5.to_bson.to_s)
70
+ end
71
+
72
+ let!(:double) do
73
+ buffer.get_double
74
+ end
75
+
76
+ it 'gets the double from the buffer' do
77
+ expect(double).to eq(12.5)
78
+ end
79
+
80
+ it 'increments the read position by 8' do
81
+ expect(buffer.read_position).to eq(8)
82
+ end
83
+ end
84
+
85
+ describe '#get_int32' do
86
+
87
+ let(:buffer) do
88
+ described_class.new(12.to_bson.to_s)
89
+ end
90
+
91
+ let!(:int32) do
92
+ buffer.get_int32
93
+ end
94
+
95
+ it 'gets the int32 from the buffer' do
96
+ expect(int32).to eq(12)
97
+ end
98
+
99
+ it 'increments the position by 4' do
100
+ expect(buffer.read_position).to eq(4)
101
+ end
102
+ end
103
+
104
+ describe '#get_uint32' do
105
+ context 'when using 2^32-1' do
106
+ let(:buffer) do
107
+ described_class.new(4294967295.to_bson.to_s)
108
+ end
109
+
110
+ let!(:int32) do
111
+ buffer.get_uint32
112
+ end
113
+
114
+ it 'gets the uint32 from the buffer' do
115
+ expect(int32).to eq(4294967295)
116
+ end
117
+
118
+ it 'increments the position by 4' do
119
+ expect(buffer.read_position).to eq(4)
120
+ end
121
+ end
122
+
123
+ context 'when using 2^32-2' do
124
+ let(:buffer) do
125
+ described_class.new(4294967294.to_bson.to_s)
126
+ end
127
+
128
+ let!(:int32) do
129
+ buffer.get_uint32
130
+ end
131
+
132
+ it 'gets the uint32 from the buffer' do
133
+ expect(int32).to eq(4294967294)
134
+ end
135
+
136
+ it 'increments the position by 4' do
137
+ expect(buffer.read_position).to eq(4)
138
+ end
139
+ end
140
+
141
+ context 'when using 0' do
142
+ let(:buffer) do
143
+ described_class.new(0.to_bson.to_s)
144
+ end
145
+
146
+ let!(:int32) do
147
+ buffer.get_uint32
148
+ end
149
+
150
+ it 'gets the uint32 from the buffer' do
151
+ expect(int32).to eq(0)
152
+ end
153
+
154
+ it 'increments the position by 4' do
155
+ expect(buffer.read_position).to eq(4)
156
+ end
157
+ end
158
+ end
159
+
160
+ describe '#get_int64' do
161
+
162
+ let(:buffer) do
163
+ described_class.new((Integer::MAX_64BIT - 1).to_bson.to_s)
164
+ end
165
+
166
+ let!(:int64) do
167
+ buffer.get_int64
168
+ end
169
+
170
+ it 'gets the int64 from the buffer' do
171
+ expect(int64).to eq(Integer::MAX_64BIT - 1)
172
+ end
173
+
174
+ it 'increments the position by 8' do
175
+ expect(buffer.read_position).to eq(8)
176
+ end
177
+ end
178
+
179
+ describe '#get_string' do
180
+
181
+ let(:buffer) do
182
+ described_class.new("#{8.to_bson.to_s}testing#{BSON::NULL_BYTE}")
183
+ end
184
+
185
+ let!(:string) do
186
+ buffer.get_string
187
+ end
188
+
189
+ it 'gets the string from the buffer' do
190
+ expect(string).to eq("testing")
191
+ end
192
+
193
+ it 'increments the position by string length + 5' do
194
+ expect(buffer.read_position).to eq(12)
195
+ end
196
+ end
197
+ end
@@ -13,478 +13,218 @@ describe BSON::ByteBuffer do
13
13
  end
14
14
  end
15
15
 
16
- describe '#get_byte' do
17
-
18
- let(:buffer) do
19
- described_class.new(BSON::Int32::BSON_TYPE)
20
- end
21
-
22
- let!(:byte) do
23
- buffer.get_byte
24
- end
25
-
26
- it 'gets the byte from the buffer' do
27
- expect(byte).to eq(BSON::Int32::BSON_TYPE)
28
- end
29
-
30
- it 'increments the read position by 1' do
31
- expect(buffer.read_position).to eq(1)
32
- end
33
- end
34
-
35
- describe '#get_bytes' do
36
-
37
- let(:string) do
38
- "#{BSON::Int32::BSON_TYPE}#{BSON::Int32::BSON_TYPE}"
39
- end
40
-
41
- let(:buffer) do
42
- described_class.new(string)
43
- end
44
-
45
- let!(:bytes) do
46
- buffer.get_bytes(2)
47
- end
48
-
49
- it 'gets the bytes from the buffer' do
50
- expect(bytes).to eq(string)
51
- end
52
-
53
- it 'increments the position by the length' do
54
- expect(buffer.read_position).to eq(string.bytesize)
55
- end
56
- end
57
-
58
- describe '#get_cstring' do
59
-
60
- let(:buffer) do
61
- described_class.new("testing#{BSON::NULL_BYTE}")
62
- end
63
-
64
- let!(:string) do
65
- buffer.get_cstring
66
- end
67
-
68
- it 'gets the cstring from the buffer' do
69
- expect(string).to eq("testing")
70
- end
71
-
72
- it 'increments the position by string length + 1' do
73
- expect(buffer.read_position).to eq(8)
74
- end
75
- end
76
-
77
- describe '#get_double' do
78
-
79
- let(:buffer) do
80
- described_class.new("#{12.5.to_bson.to_s}")
81
- end
82
-
83
- let!(:double) do
84
- buffer.get_double
85
- end
86
-
87
- it 'gets the double from the buffer' do
88
- expect(double).to eq(12.5)
89
- end
90
-
91
- it 'increments the read position by 8' do
92
- expect(buffer.read_position).to eq(8)
93
- end
94
- end
95
-
96
- describe '#get_int32' do
97
-
98
- let(:buffer) do
99
- described_class.new("#{12.to_bson.to_s}")
100
- end
101
-
102
- let!(:int32) do
103
- buffer.get_int32
104
- end
105
-
106
- it 'gets the int32 from the buffer' do
107
- expect(int32).to eq(12)
108
- end
109
-
110
- it 'increments the position by 4' do
111
- expect(buffer.read_position).to eq(4)
112
- end
113
- end
114
-
115
- describe '#get_int64' do
116
-
117
- let(:buffer) do
118
- described_class.new("#{(Integer::MAX_64BIT - 1).to_bson.to_s}")
119
- end
120
-
121
- let!(:int64) do
122
- buffer.get_int64
123
- end
124
-
125
- it 'gets the int64 from the buffer' do
126
- expect(int64).to eq(Integer::MAX_64BIT - 1)
127
- end
128
-
129
- it 'increments the position by 8' do
130
- expect(buffer.read_position).to eq(8)
131
- end
132
- end
133
-
134
- describe '#get_string' do
135
-
136
- let(:buffer) do
137
- described_class.new("#{8.to_bson.to_s}testing#{BSON::NULL_BYTE}")
138
- end
139
-
140
- let!(:string) do
141
- buffer.get_string
142
- end
143
-
144
- it 'gets the string from the buffer' do
145
- expect(string).to eq("testing")
146
- end
147
-
148
- it 'increments the position by string length + 5' do
149
- expect(buffer.read_position).to eq(12)
150
- end
151
- end
152
-
153
16
  describe '#length' do
17
+ context 'empty buffer' do
154
18
 
155
- let(:buffer) do
156
- described_class.new
157
- end
158
-
159
- before do
160
- buffer.put_int32(5)
161
- end
162
-
163
- it 'returns the length of the buffer' do
164
- expect(buffer.length).to eq(4)
165
- end
166
- end
167
-
168
- describe '#put_byte' do
169
-
170
- let(:buffer) do
171
- described_class.new
172
- end
173
-
174
- let!(:modified) do
175
- buffer.put_byte(BSON::Int32::BSON_TYPE)
176
- end
177
-
178
- it 'appends the byte to the byte buffer' do
179
- expect(modified.to_s).to eq(BSON::Int32::BSON_TYPE.chr)
180
- end
181
-
182
- it 'increments the write position by 1' do
183
- expect(modified.write_position).to eq(1)
184
- end
185
- end
186
-
187
- describe '#put_cstring' do
19
+ let(:buffer) do
20
+ described_class.new
21
+ end
188
22
 
189
- let(:buffer) do
190
- described_class.new
23
+ it 'is zero' do
24
+ expect(buffer.length).to eq(0)
25
+ end
191
26
  end
192
27
 
193
- context 'when the string is valid' do
28
+ context 'when the byte buffer is initialized with no bytes' do
194
29
 
195
- let!(:modified) do
196
- buffer.put_cstring('testing')
30
+ let(:buffer) do
31
+ described_class.new
197
32
  end
198
33
 
199
- it 'appends the string plus null byte to the byte buffer' do
200
- expect(modified.to_s).to eq("testing#{BSON::NULL_BYTE}")
201
- end
34
+ context '#put_int32' do
35
+ before do
36
+ buffer.put_int32(5)
37
+ end
202
38
 
203
- it 'increments the write position by the length + 1' do
204
- expect(modified.write_position).to eq(8)
39
+ it 'returns the length of the buffer' do
40
+ expect(buffer.length).to eq(4)
41
+ end
205
42
  end
206
43
  end
207
44
 
208
- context "when the string contains a null byte" do
45
+ context 'when the byte buffer is initialized with some bytes' do
209
46
 
210
- let(:string) do
211
- "test#{BSON::NULL_BYTE}ing"
47
+ let(:buffer) do
48
+ described_class.new("#{BSON::Int32::BSON_TYPE}#{BSON::Int32::BSON_TYPE}")
212
49
  end
213
50
 
214
- it "raises an error" do
215
- expect {
216
- buffer.put_cstring(string)
217
- }.to raise_error(ArgumentError)
51
+ it 'returns the length' do
52
+ expect(buffer.length).to eq(2)
218
53
  end
219
54
  end
220
- end
221
-
222
- describe '#put_double' do
223
-
224
- let(:buffer) do
225
- described_class.new
226
- end
227
-
228
- let!(:modified) do
229
- buffer.put_double(1.2332)
230
- end
231
-
232
- it 'appends the double to the buffer' do
233
- expect(modified.to_s).to eq([ 1.2332 ].pack(Float::PACK))
234
- end
235
55
 
236
- it 'increments the write position by 8' do
237
- expect(modified.write_position).to eq(8)
238
- end
239
- end
56
+ context 'after the byte buffer was read from' do
240
57
 
241
- describe '#put_int32' do
58
+ let(:buffer) do
59
+ described_class.new({}.to_bson.to_s)
60
+ end
242
61
 
243
- let(:buffer) do
244
- described_class.new
62
+ it 'returns the number of bytes remaining in the buffer' do
63
+ expect(buffer.length).to eq(5)
64
+ buffer.get_int32
65
+ expect(buffer.length).to eq(1)
66
+ end
245
67
  end
246
68
 
247
- context 'when the integer is 32 bit' do
248
-
249
- context 'when the integer is positive' do
69
+ context 'after the byte buffer was converted to string' do
250
70
 
251
- let!(:modified) do
252
- buffer.put_int32(Integer::MAX_32BIT - 1)
253
- end
254
-
255
- let(:expected) do
256
- [ Integer::MAX_32BIT - 1 ].pack(BSON::Int32::PACK)
257
- end
258
-
259
- it 'appends the int32 to the byte buffer' do
260
- expect(modified.to_s).to eq(expected)
261
- end
262
-
263
- it 'increments the write position by 4' do
264
- expect(modified.write_position).to eq(4)
71
+ shared_examples 'returns the total buffer length' do
72
+ it 'returns the total buffer length' do
73
+ expect(buffer.length).to eq(5)
74
+ buffer.to_s.length.should == 5
75
+ expect(buffer.length).to eq(5)
265
76
  end
266
77
  end
267
78
 
268
- context 'when the integer is negative' do
269
-
270
- let!(:modified) do
271
- buffer.put_int32(Integer::MIN_32BIT + 1)
272
- end
79
+ context 'read buffer' do
273
80
 
274
- let(:expected) do
275
- [ Integer::MIN_32BIT + 1 ].pack(BSON::Int32::PACK)
81
+ let(:buffer) do
82
+ described_class.new({}.to_bson.to_s)
276
83
  end
277
84
 
278
- it 'appends the int32 to the byte buffer' do
279
- expect(modified.to_s).to eq(expected)
280
- end
281
-
282
- it 'increments the write position by 4' do
283
- expect(modified.write_position).to eq(4)
284
- end
85
+ include_examples 'returns the total buffer length'
285
86
  end
286
87
 
287
- context 'when the integer is not 32 bit' do
88
+ context 'write buffer' do
288
89
 
289
- it 'raises an exception' do
290
- expect {
291
- buffer.put_int32(Integer::MAX_64BIT - 1)
292
- }.to raise_error(RangeError)
90
+ let(:buffer) do
91
+ described_class.new.tap do |buffer|
92
+ buffer.put_bytes('hello')
93
+ end
293
94
  end
95
+
96
+ include_examples 'returns the total buffer length'
294
97
  end
295
98
  end
296
99
  end
297
100
 
298
- describe '#put_int64' do
299
-
300
- let(:buffer) do
301
- described_class.new
302
- end
303
-
304
- context 'when the integer is 64 bit' do
305
-
306
- context 'when the integer is positive' do
307
-
308
- let!(:modified) do
309
- buffer.put_int64(Integer::MAX_64BIT - 1)
310
- end
311
-
312
- let(:expected) do
313
- [ Integer::MAX_64BIT - 1 ].pack(BSON::Int64::PACK)
314
- end
101
+ describe '#rewind!' do
315
102
 
316
- it 'appends the int64 to the byte buffer' do
317
- expect(modified.to_s).to eq(expected)
318
- end
103
+ shared_examples_for 'a rewindable buffer' do
319
104
 
320
- it 'increments the write position by 8' do
321
- expect(modified.write_position).to eq(8)
322
- end
105
+ let(:string) do
106
+ "#{BSON::Int32::BSON_TYPE}#{BSON::Int32::BSON_TYPE}"
323
107
  end
324
108
 
325
- context 'when the integer is negative' do
326
-
327
- let!(:modified) do
328
- buffer.put_int64(Integer::MIN_64BIT + 1)
329
- end
330
-
331
- let(:expected) do
332
- [ Integer::MIN_64BIT + 1 ].pack(BSON::Int64::PACK)
333
- end
334
-
335
- it 'appends the int64 to the byte buffer' do
336
- expect(modified.to_s).to eq(expected)
337
- end
338
-
339
- it 'increments the write position by 8' do
340
- expect(modified.write_position).to eq(8)
341
- end
109
+ before do
110
+ buffer.get_bytes(1)
111
+ buffer.rewind!
342
112
  end
343
113
 
344
- context 'when the integer is larger than 64 bit' do
114
+ it 'resets the read position to 0' do
115
+ expect(buffer.read_position).to eq(0)
116
+ end
345
117
 
346
- it 'raises an exception' do
347
- expect {
348
- buffer.put_int64(Integer::MAX_64BIT + 1)
349
- }.to raise_error(RangeError)
350
- end
118
+ it 'starts subsequent reads at position 0' do
119
+ expect(buffer.get_bytes(2)).to eq(string)
351
120
  end
352
121
  end
353
- end
354
-
355
- describe '#put_string' do
356
122
 
357
- context 'when the buffer does not need to be expanded' do
123
+ context 'when the buffer is instantiated with a string' do
358
124
 
359
125
  let(:buffer) do
360
- described_class.new
126
+ described_class.new(string)
361
127
  end
362
128
 
363
- context 'when the string is UTF-8' do
364
-
365
- let!(:modified) do
366
- buffer.put_string('testing')
367
- end
368
-
369
- it 'appends the string to the byte buffer' do
370
- expect(modified.to_s).to eq("#{8.to_bson.to_s}testing#{BSON::NULL_BYTE}")
371
- end
372
-
373
- it 'increments the write position by length + 5' do
374
- expect(modified.write_position).to eq(12)
375
- end
376
- end
129
+ it_behaves_like 'a rewindable buffer'
377
130
  end
378
131
 
379
- context 'when the buffer needs to be expanded' do
132
+ context 'when the buffer is instantiated with nothing' do
380
133
 
381
134
  let(:buffer) do
382
135
  described_class.new
383
136
  end
384
137
 
385
- let(:string) do
386
- 300.times.inject(""){ |s, i| s << "#{i}" }
387
- end
388
-
389
- context 'when no bytes exist in the buffer' do
390
-
391
- let!(:modified) do
392
- buffer.put_string(string)
393
- end
394
-
395
- it 'appends the string to the byte buffer' do
396
- expect(modified.to_s).to eq("#{(string.bytesize + 1).to_bson.to_s}#{string}#{BSON::NULL_BYTE}")
397
- end
398
-
399
- it 'increments the write position by length + 5' do
400
- expect(modified.write_position).to eq(string.bytesize + 5)
401
- end
138
+ before do
139
+ buffer.put_byte(BSON::Int32::BSON_TYPE).put_byte(BSON::Int32::BSON_TYPE)
402
140
  end
403
141
 
404
- context 'when bytes exist in the buffer' do
405
-
406
- let!(:modified) do
407
- buffer.put_int32(4).put_string(string)
408
- end
409
-
410
- it 'appends the string to the byte buffer' do
411
- expect(modified.to_s).to eq(
412
- "#{[ 4 ].pack(BSON::Int32::PACK)}#{(string.bytesize + 1).to_bson.to_s}#{string}#{BSON::NULL_BYTE}"
413
- )
414
- end
142
+ it_behaves_like 'a rewindable buffer'
143
+ end
415
144
 
416
- it 'increments the write position by length + 5' do
417
- expect(modified.write_position).to eq(string.bytesize + 9)
418
- end
419
- end
145
+ it 'does not change write position' do
146
+ buffer = described_class.new
147
+ buffer.put_byte(BSON::Int32::BSON_TYPE)
148
+ expect(buffer.write_position).to eq(1)
149
+ buffer.rewind!
150
+ expect(buffer.write_position).to eq(1)
420
151
  end
421
152
  end
422
153
 
423
- describe '#replace_int32' do
424
-
154
+ describe 'write followed by read' do
425
155
  let(:buffer) do
426
156
  described_class.new
427
157
  end
428
158
 
429
- let(:exp_first) do
430
- [ 5 ].pack(BSON::Int32::PACK)
159
+ context 'one cycle' do
160
+ it 'returns the written data' do
161
+ buffer.put_cstring('hello')
162
+ buffer.get_cstring.should == 'hello'
163
+ end
431
164
  end
432
165
 
433
- let(:exp_second) do
434
- [ 4 ].pack(BSON::Int32::PACK)
435
- end
166
+ context 'two cycles' do
167
+ it 'returns the written data' do
168
+ buffer.put_cstring('hello')
169
+ buffer.get_cstring.should == 'hello'
436
170
 
437
- let(:modified) do
438
- buffer.put_int32(0).put_int32(4).replace_int32(0, 5)
171
+ buffer.put_cstring('world')
172
+ buffer.get_cstring.should == 'world'
173
+ end
439
174
  end
440
175
 
441
- it 'replaces the int32 at the location' do
442
- expect(modified.to_s).to eq("#{exp_first}#{exp_second}")
443
- end
444
- end
176
+ context 'mixed cycles' do
177
+ it 'returns the written data' do
178
+ if BSON::Environment.jruby?
179
+ pending 'RUBY-2334'
180
+ end
445
181
 
446
- describe '#rewind!' do
182
+ buffer.put_int32(1)
183
+ buffer.put_int32(2)
447
184
 
448
- shared_examples_for 'a rewindable buffer' do
185
+ buffer.get_int32.should == 1
449
186
 
450
- let(:string) do
451
- "#{BSON::Int32::BSON_TYPE}#{BSON::Int32::BSON_TYPE}"
452
- end
187
+ buffer.put_int32(3)
453
188
 
454
- before do
455
- buffer.get_bytes(1)
456
- buffer.rewind!
189
+ buffer.get_int32.should == 2
190
+ buffer.get_int32.should == 3
457
191
  end
192
+ end
193
+ end
458
194
 
459
- it 'resets the read position to 0' do
460
- expect(buffer.read_position).to eq(0)
195
+ describe '#to_s' do
196
+ context 'read buffer' do
197
+ let(:buffer) do
198
+ described_class.new("\x18\x00\x00\x00*\x00\x00\x00")
461
199
  end
462
200
 
463
- it 'starts subsequent reads at position 0' do
464
- expect(buffer.get_bytes(2)).to eq(string)
201
+ it 'returns the data' do
202
+ buffer.to_s.should == "\x18\x00\x00\x00*\x00\x00\x00"
465
203
  end
466
- end
467
-
468
- context 'when the buffer is instantiated with a string' do
469
204
 
470
- let(:buffer) do
471
- described_class.new(string)
205
+ it 'returns the remaining buffer contents after a read' do
206
+ buffer.to_s.should == "\x18\x00\x00\x00*\x00\x00\x00"
207
+ buffer.get_int32.should == 24
208
+ buffer.to_s.should == "*\x00\x00\x00"
472
209
  end
473
-
474
- it_behaves_like 'a rewindable buffer'
475
210
  end
476
211
 
477
- context 'when the buffer is instantiated with nothing' do
478
-
212
+ context 'write buffer' do
479
213
  let(:buffer) do
480
- described_class.new
214
+ described_class.new.tap do |buffer|
215
+ buffer.put_int32(24)
216
+ end
481
217
  end
482
218
 
483
- before do
484
- buffer.put_byte(BSON::Int32::BSON_TYPE).put_byte(BSON::Int32::BSON_TYPE)
219
+ it 'returns the data' do
220
+ buffer.to_s.should == "\x18\x00\x00\x00".force_encoding('binary')
485
221
  end
486
222
 
487
- it_behaves_like 'a rewindable buffer'
223
+ it 'returns the complete buffer contents after a write' do
224
+ buffer.to_s.should == "\x18\x00\x00\x00".force_encoding('binary')
225
+ buffer.put_int32(42)
226
+ buffer.to_s.should == "\x18\x00\x00\x00*\x00\x00\x00".force_encoding('binary')
227
+ end
488
228
  end
489
229
  end
490
230
  end