bson 4.1.1 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +106 -7
  3. data/Rakefile +86 -43
  4. data/ext/bson/{native-endian.h → bson-endian.h} +14 -107
  5. data/ext/bson/bson-native.h +135 -0
  6. data/ext/bson/bytebuf.c +133 -0
  7. data/ext/bson/endian.c +117 -0
  8. data/ext/bson/extconf.rb +8 -3
  9. data/ext/bson/init.c +364 -0
  10. data/ext/bson/libbson-utf8.c +230 -0
  11. data/ext/bson/read.c +470 -0
  12. data/ext/bson/util.c +250 -0
  13. data/ext/bson/write.c +675 -0
  14. data/lib/bson/active_support.rb +19 -0
  15. data/lib/bson/array.rb +97 -30
  16. data/lib/bson/big_decimal.rb +77 -0
  17. data/lib/bson/binary.rb +510 -70
  18. data/lib/bson/boolean.rb +15 -4
  19. data/lib/bson/code.rb +25 -12
  20. data/lib/bson/code_with_scope.rb +41 -15
  21. data/lib/bson/config.rb +3 -28
  22. data/lib/bson/date.rb +16 -4
  23. data/lib/bson/date_time.rb +6 -4
  24. data/lib/bson/db_pointer.rb +110 -0
  25. data/lib/bson/dbref.rb +154 -0
  26. data/lib/bson/decimal128/builder.rb +456 -0
  27. data/lib/bson/decimal128.rb +272 -0
  28. data/lib/bson/document.rb +177 -7
  29. data/lib/bson/environment.rb +17 -2
  30. data/lib/bson/error/bson_decode_error.rb +11 -0
  31. data/lib/bson/error/ext_json_parse_error.rb +11 -0
  32. data/lib/bson/error/illegal_key.rb +23 -0
  33. data/lib/bson/error/invalid_binary_type.rb +37 -0
  34. data/lib/bson/error/invalid_dbref_argument.rb +12 -0
  35. data/lib/bson/error/invalid_decimal128_argument.rb +25 -0
  36. data/lib/bson/error/invalid_decimal128_range.rb +27 -0
  37. data/lib/bson/error/invalid_decimal128_string.rb +26 -0
  38. data/lib/bson/error/invalid_key.rb +24 -0
  39. data/lib/bson/error/invalid_object_id.rb +11 -0
  40. data/lib/bson/error/invalid_regexp_pattern.rb +13 -0
  41. data/lib/bson/error/unrepresentable_precision.rb +19 -0
  42. data/lib/bson/error/unserializable_class.rb +13 -0
  43. data/lib/bson/error/unsupported_binary_subtype.rb +12 -0
  44. data/lib/bson/error/unsupported_type.rb +11 -0
  45. data/lib/bson/error.rb +22 -0
  46. data/lib/bson/ext_json.rb +389 -0
  47. data/lib/bson/false_class.rb +6 -4
  48. data/lib/bson/float.rb +43 -7
  49. data/lib/bson/hash.rb +152 -37
  50. data/lib/bson/int32.rb +104 -6
  51. data/lib/bson/int64.rb +111 -8
  52. data/lib/bson/integer.rb +43 -9
  53. data/lib/bson/json.rb +3 -1
  54. data/lib/bson/max_key.rb +21 -10
  55. data/lib/bson/min_key.rb +21 -10
  56. data/lib/bson/nil_class.rb +7 -3
  57. data/lib/bson/object.rb +25 -17
  58. data/lib/bson/object_id.rb +98 -113
  59. data/lib/bson/open_struct.rb +59 -0
  60. data/lib/bson/regexp.rb +129 -56
  61. data/lib/bson/registry.rb +7 -10
  62. data/lib/bson/specialized.rb +8 -4
  63. data/lib/bson/string.rb +12 -32
  64. data/lib/bson/symbol.rb +107 -11
  65. data/lib/bson/time.rb +68 -7
  66. data/lib/bson/time_with_zone.rb +67 -0
  67. data/lib/bson/timestamp.rb +50 -10
  68. data/lib/bson/true_class.rb +6 -4
  69. data/lib/bson/undefined.rb +28 -2
  70. data/lib/bson/vector.rb +44 -0
  71. data/lib/bson/version.rb +6 -14
  72. data/lib/bson.rb +22 -12
  73. data/spec/README.md +14 -0
  74. data/spec/bson/array_spec.rb +38 -62
  75. data/spec/bson/big_decimal_spec.rb +328 -0
  76. data/spec/bson/binary_spec.rb +199 -53
  77. data/spec/bson/binary_uuid_spec.rb +190 -0
  78. data/spec/bson/boolean_spec.rb +2 -1
  79. data/spec/bson/byte_buffer_read_spec.rb +198 -0
  80. data/spec/bson/byte_buffer_spec.rb +122 -381
  81. data/spec/bson/byte_buffer_write_spec.rb +855 -0
  82. data/spec/bson/code_spec.rb +6 -4
  83. data/spec/bson/code_with_scope_spec.rb +6 -4
  84. data/spec/bson/config_spec.rb +1 -35
  85. data/spec/bson/date_spec.rb +2 -1
  86. data/spec/bson/date_time_spec.rb +55 -1
  87. data/spec/bson/dbref_legacy_spec.rb +186 -0
  88. data/spec/bson/dbref_spec.rb +487 -0
  89. data/spec/bson/decimal128_spec.rb +1840 -0
  90. data/spec/bson/document_as_spec.rb +61 -0
  91. data/spec/bson/document_spec.rb +205 -32
  92. data/spec/bson/ext_json_parse_spec.rb +346 -0
  93. data/spec/bson/false_class_spec.rb +9 -1
  94. data/spec/bson/float_spec.rb +42 -1
  95. data/spec/bson/hash_as_spec.rb +58 -0
  96. data/spec/bson/hash_spec.rb +318 -66
  97. data/spec/bson/int32_spec.rb +248 -1
  98. data/spec/bson/int64_spec.rb +308 -1
  99. data/spec/bson/integer_spec.rb +61 -3
  100. data/spec/bson/json_spec.rb +2 -1
  101. data/spec/bson/max_key_spec.rb +6 -4
  102. data/spec/bson/min_key_spec.rb +6 -4
  103. data/spec/bson/nil_class_spec.rb +2 -1
  104. data/spec/bson/object_id_spec.rb +95 -5
  105. data/spec/bson/object_spec.rb +3 -2
  106. data/spec/bson/open_struct_spec.rb +87 -0
  107. data/spec/bson/raw_spec.rb +594 -0
  108. data/spec/bson/regexp_spec.rb +61 -8
  109. data/spec/bson/registry_spec.rb +3 -2
  110. data/spec/bson/string_spec.rb +26 -33
  111. data/spec/bson/symbol_raw_spec.rb +70 -0
  112. data/spec/bson/symbol_spec.rb +77 -20
  113. data/spec/bson/time_spec.rb +206 -2
  114. data/spec/bson/time_with_zone_spec.rb +69 -0
  115. data/spec/bson/timestamp_spec.rb +58 -2
  116. data/spec/bson/true_class_spec.rb +9 -1
  117. data/spec/bson/undefined_spec.rb +28 -1
  118. data/spec/bson/vector_spec.rb +33 -0
  119. data/spec/bson_spec.rb +2 -1
  120. data/spec/runners/binary_vector.rb +78 -0
  121. data/spec/runners/common_driver.rb +348 -0
  122. data/spec/runners/corpus.rb +191 -0
  123. data/spec/runners/corpus_legacy.rb +248 -0
  124. data/spec/shared/LICENSE +20 -0
  125. data/spec/shared/bin/get-mongodb-download-url +17 -0
  126. data/spec/shared/bin/s3-copy +45 -0
  127. data/spec/shared/bin/s3-upload +69 -0
  128. data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
  129. data/spec/shared/lib/mrss/cluster_config.rb +231 -0
  130. data/spec/shared/lib/mrss/constraints.rb +378 -0
  131. data/spec/shared/lib/mrss/docker_runner.rb +298 -0
  132. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  133. data/spec/shared/lib/mrss/event_subscriber.rb +210 -0
  134. data/spec/shared/lib/mrss/lite_constraints.rb +238 -0
  135. data/spec/shared/lib/mrss/release/candidate.rb +281 -0
  136. data/spec/shared/lib/mrss/release/product_data.rb +144 -0
  137. data/spec/shared/lib/mrss/server_version_registry.rb +113 -0
  138. data/spec/shared/lib/mrss/session_registry.rb +69 -0
  139. data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
  140. data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
  141. data/spec/shared/lib/mrss/utils.rb +37 -0
  142. data/spec/shared/lib/tasks/candidate.rake +64 -0
  143. data/spec/shared/share/Dockerfile.erb +251 -0
  144. data/spec/shared/share/haproxy-1.conf +16 -0
  145. data/spec/shared/share/haproxy-2.conf +17 -0
  146. data/spec/shared/shlib/config.sh +27 -0
  147. data/spec/shared/shlib/distro.sh +84 -0
  148. data/spec/shared/shlib/server.sh +423 -0
  149. data/spec/shared/shlib/set_env.sh +110 -0
  150. data/spec/spec_helper.rb +61 -1
  151. data/spec/spec_tests/binary_vector_spec.rb +82 -0
  152. data/spec/spec_tests/common_driver_spec.rb +84 -0
  153. data/spec/spec_tests/corpus_legacy_spec.rb +72 -0
  154. data/spec/spec_tests/corpus_spec.rb +134 -0
  155. data/spec/spec_tests/data/binary_vector/README.md +61 -0
  156. data/spec/spec_tests/data/binary_vector/float32.json +65 -0
  157. data/spec/spec_tests/data/binary_vector/int8.json +57 -0
  158. data/spec/spec_tests/data/binary_vector/packed_bit.json +83 -0
  159. data/spec/spec_tests/data/corpus/README.md +15 -0
  160. data/spec/spec_tests/data/corpus/array.json +49 -0
  161. data/spec/spec_tests/data/corpus/binary.json +153 -0
  162. data/spec/spec_tests/data/corpus/boolean.json +27 -0
  163. data/spec/spec_tests/data/corpus/code.json +67 -0
  164. data/spec/spec_tests/data/corpus/code_w_scope.json +78 -0
  165. data/spec/spec_tests/data/corpus/datetime.json +42 -0
  166. data/spec/spec_tests/data/corpus/dbpointer.json +56 -0
  167. data/spec/spec_tests/data/corpus/dbref.json +51 -0
  168. data/spec/spec_tests/data/corpus/decimal128-1.json +317 -0
  169. data/spec/spec_tests/data/corpus/decimal128-2.json +793 -0
  170. data/spec/spec_tests/data/corpus/decimal128-3.json +1771 -0
  171. data/spec/spec_tests/data/corpus/decimal128-4.json +165 -0
  172. data/spec/spec_tests/data/corpus/decimal128-5.json +402 -0
  173. data/spec/spec_tests/data/corpus/decimal128-6.json +131 -0
  174. data/spec/spec_tests/data/corpus/decimal128-7.json +327 -0
  175. data/spec/spec_tests/data/corpus/document.json +60 -0
  176. data/spec/spec_tests/data/corpus/double.json +87 -0
  177. data/spec/spec_tests/data/corpus/int32.json +43 -0
  178. data/spec/spec_tests/data/corpus/int64.json +43 -0
  179. data/spec/spec_tests/data/corpus/maxkey.json +12 -0
  180. data/spec/spec_tests/data/corpus/minkey.json +12 -0
  181. data/spec/spec_tests/data/corpus/multi-type-deprecated.json +15 -0
  182. data/spec/spec_tests/data/corpus/multi-type.json +11 -0
  183. data/spec/spec_tests/data/corpus/null.json +12 -0
  184. data/spec/spec_tests/data/corpus/oid.json +28 -0
  185. data/spec/spec_tests/data/corpus/regex.json +65 -0
  186. data/spec/spec_tests/data/corpus/string.json +72 -0
  187. data/spec/spec_tests/data/corpus/symbol.json +80 -0
  188. data/spec/spec_tests/data/corpus/timestamp.json +34 -0
  189. data/spec/spec_tests/data/corpus/top.json +262 -0
  190. data/spec/spec_tests/data/corpus/undefined.json +15 -0
  191. data/spec/spec_tests/data/corpus_legacy/array.json +49 -0
  192. data/spec/spec_tests/data/corpus_legacy/binary.json +69 -0
  193. data/spec/spec_tests/data/corpus_legacy/boolean.json +27 -0
  194. data/spec/spec_tests/data/corpus_legacy/code.json +67 -0
  195. data/spec/spec_tests/data/corpus_legacy/code_w_scope.json +78 -0
  196. data/spec/spec_tests/data/corpus_legacy/document.json +36 -0
  197. data/spec/spec_tests/data/corpus_legacy/double.json +69 -0
  198. data/spec/spec_tests/data/corpus_legacy/failures/datetime.json +31 -0
  199. data/spec/spec_tests/data/corpus_legacy/failures/dbpointer.json +42 -0
  200. data/spec/spec_tests/data/corpus_legacy/failures/int64.json +38 -0
  201. data/spec/spec_tests/data/corpus_legacy/failures/symbol.json +62 -0
  202. data/spec/spec_tests/data/corpus_legacy/int32.json +38 -0
  203. data/spec/spec_tests/data/corpus_legacy/maxkey.json +12 -0
  204. data/spec/spec_tests/data/corpus_legacy/minkey.json +12 -0
  205. data/spec/spec_tests/data/corpus_legacy/null.json +12 -0
  206. data/spec/spec_tests/data/corpus_legacy/oid.json +28 -0
  207. data/spec/spec_tests/data/corpus_legacy/regex.json +37 -0
  208. data/spec/spec_tests/data/corpus_legacy/string.json +67 -0
  209. data/spec/spec_tests/data/corpus_legacy/timestamp.json +18 -0
  210. data/spec/spec_tests/data/corpus_legacy/top.json +62 -0
  211. data/spec/spec_tests/data/corpus_legacy/undefined.json +13 -0
  212. data/spec/spec_tests/data/decimal128/decimal128-1.json +363 -0
  213. data/spec/spec_tests/data/decimal128/decimal128-2.json +793 -0
  214. data/spec/spec_tests/data/decimal128/decimal128-3.json +1771 -0
  215. data/spec/spec_tests/data/decimal128/decimal128-4.json +165 -0
  216. data/spec/spec_tests/data/decimal128/decimal128-5.json +402 -0
  217. data/spec/spec_tests/data/decimal128/decimal128-6.json +131 -0
  218. data/spec/spec_tests/data/decimal128/decimal128-7.json +327 -0
  219. data/spec/support/shared_examples.rb +32 -11
  220. data/spec/support/spec_config.rb +17 -0
  221. data/spec/support/utils.rb +58 -0
  222. metadata +284 -45
  223. checksums.yaml.gz.sig +0 -3
  224. data/ext/bson/native.c +0 -722
  225. data.tar.gz.sig +0 -0
  226. metadata.gz.sig +0 -0
@@ -1,3 +1,4 @@
1
+ # rubocop:todo all
1
2
  require 'spec_helper'
2
3
 
3
4
  describe BSON::ByteBuffer do
@@ -13,478 +14,218 @@ describe BSON::ByteBuffer do
13
14
  end
14
15
  end
15
16
 
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
17
  describe '#length' do
18
+ context 'empty buffer' do
154
19
 
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
20
+ let(:buffer) do
21
+ described_class.new
22
+ end
188
23
 
189
- let(:buffer) do
190
- described_class.new
24
+ it 'is zero' do
25
+ expect(buffer.length).to eq(0)
26
+ end
191
27
  end
192
28
 
193
- context 'when the string is valid' do
29
+ context 'when the byte buffer is initialized with no bytes' do
194
30
 
195
- let!(:modified) do
196
- buffer.put_cstring('testing')
31
+ let(:buffer) do
32
+ described_class.new
197
33
  end
198
34
 
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
35
+ context '#put_int32' do
36
+ before do
37
+ buffer.put_int32(5)
38
+ end
202
39
 
203
- it 'increments the write position by the length + 1' do
204
- expect(modified.write_position).to eq(8)
40
+ it 'returns the length of the buffer' do
41
+ expect(buffer.length).to eq(4)
42
+ end
205
43
  end
206
44
  end
207
45
 
208
- context "when the string contains a null byte" do
46
+ context 'when the byte buffer is initialized with some bytes' do
209
47
 
210
- let(:string) do
211
- "test#{BSON::NULL_BYTE}ing"
48
+ let(:buffer) do
49
+ described_class.new("#{BSON::Int32::BSON_TYPE}#{BSON::Int32::BSON_TYPE}")
212
50
  end
213
51
 
214
- it "raises an error" do
215
- expect {
216
- buffer.put_cstring(string)
217
- }.to raise_error(ArgumentError)
52
+ it 'returns the length' do
53
+ expect(buffer.length).to eq(2)
218
54
  end
219
55
  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
56
 
236
- it 'increments the write position by 8' do
237
- expect(modified.write_position).to eq(8)
238
- end
239
- end
57
+ context 'after the byte buffer was read from' do
240
58
 
241
- describe '#put_int32' do
59
+ let(:buffer) do
60
+ described_class.new({}.to_bson.to_s)
61
+ end
242
62
 
243
- let(:buffer) do
244
- described_class.new
63
+ it 'returns the number of bytes remaining in the buffer' do
64
+ expect(buffer.length).to eq(5)
65
+ buffer.get_int32
66
+ expect(buffer.length).to eq(1)
67
+ end
245
68
  end
246
69
 
247
- context 'when the integer is 32 bit' do
248
-
249
- context 'when the integer is positive' do
70
+ context 'after the byte buffer was converted to string' do
250
71
 
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)
72
+ shared_examples 'returns the total buffer length' do
73
+ it 'returns the total buffer length' do
74
+ expect(buffer.length).to eq(5)
75
+ buffer.to_s.length.should == 5
76
+ expect(buffer.length).to eq(5)
265
77
  end
266
78
  end
267
79
 
268
- context 'when the integer is negative' do
269
-
270
- let!(:modified) do
271
- buffer.put_int32(Integer::MIN_32BIT + 1)
272
- end
80
+ context 'read buffer' do
273
81
 
274
- let(:expected) do
275
- [ Integer::MIN_32BIT + 1 ].pack(BSON::Int32::PACK)
82
+ let(:buffer) do
83
+ described_class.new({}.to_bson.to_s)
276
84
  end
277
85
 
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
86
+ include_examples 'returns the total buffer length'
285
87
  end
286
88
 
287
- context 'when the integer is not 32 bit' do
89
+ context 'write buffer' do
288
90
 
289
- it 'raises an exception' do
290
- expect {
291
- buffer.put_int32(Integer::MAX_64BIT - 1)
292
- }.to raise_error(RangeError)
91
+ let(:buffer) do
92
+ described_class.new.tap do |buffer|
93
+ buffer.put_bytes('hello')
94
+ end
293
95
  end
96
+
97
+ include_examples 'returns the total buffer length'
294
98
  end
295
99
  end
296
100
  end
297
101
 
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
102
+ describe '#rewind!' do
315
103
 
316
- it 'appends the int64 to the byte buffer' do
317
- expect(modified.to_s).to eq(expected)
318
- end
104
+ shared_examples_for 'a rewindable buffer' do
319
105
 
320
- it 'increments the write position by 8' do
321
- expect(modified.write_position).to eq(8)
322
- end
106
+ let(:string) do
107
+ "#{BSON::Int32::BSON_TYPE}#{BSON::Int32::BSON_TYPE}"
323
108
  end
324
109
 
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
110
+ before do
111
+ buffer.get_bytes(1)
112
+ buffer.rewind!
342
113
  end
343
114
 
344
- context 'when the integer is larger than 64 bit' do
115
+ it 'resets the read position to 0' do
116
+ expect(buffer.read_position).to eq(0)
117
+ end
345
118
 
346
- it 'raises an exception' do
347
- expect {
348
- buffer.put_int64(Integer::MAX_64BIT + 1)
349
- }.to raise_error(RangeError)
350
- end
119
+ it 'starts subsequent reads at position 0' do
120
+ expect(buffer.get_bytes(2)).to eq(string)
351
121
  end
352
122
  end
353
- end
354
-
355
- describe '#put_string' do
356
123
 
357
- context 'when the buffer does not need to be expanded' do
124
+ context 'when the buffer is instantiated with a string' do
358
125
 
359
126
  let(:buffer) do
360
- described_class.new
127
+ described_class.new(string)
361
128
  end
362
129
 
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
130
+ it_behaves_like 'a rewindable buffer'
377
131
  end
378
132
 
379
- context 'when the buffer needs to be expanded' do
133
+ context 'when the buffer is instantiated with nothing' do
380
134
 
381
135
  let(:buffer) do
382
136
  described_class.new
383
137
  end
384
138
 
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
139
+ before do
140
+ buffer.put_byte(BSON::Int32::BSON_TYPE).put_byte(BSON::Int32::BSON_TYPE)
402
141
  end
403
142
 
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
143
+ it_behaves_like 'a rewindable buffer'
144
+ end
415
145
 
416
- it 'increments the write position by length + 5' do
417
- expect(modified.write_position).to eq(string.bytesize + 9)
418
- end
419
- end
146
+ it 'does not change write position' do
147
+ buffer = described_class.new
148
+ buffer.put_byte(BSON::Int32::BSON_TYPE)
149
+ expect(buffer.write_position).to eq(1)
150
+ buffer.rewind!
151
+ expect(buffer.write_position).to eq(1)
420
152
  end
421
153
  end
422
154
 
423
- describe '#replace_int32' do
424
-
155
+ describe 'write followed by read' do
425
156
  let(:buffer) do
426
157
  described_class.new
427
158
  end
428
159
 
429
- let(:exp_first) do
430
- [ 5 ].pack(BSON::Int32::PACK)
160
+ context 'one cycle' do
161
+ it 'returns the written data' do
162
+ buffer.put_cstring('hello')
163
+ buffer.get_cstring.should == 'hello'
164
+ end
431
165
  end
432
166
 
433
- let(:exp_second) do
434
- [ 4 ].pack(BSON::Int32::PACK)
435
- end
167
+ context 'two cycles' do
168
+ it 'returns the written data' do
169
+ buffer.put_cstring('hello')
170
+ buffer.get_cstring.should == 'hello'
436
171
 
437
- let(:modified) do
438
- buffer.put_int32(0).put_int32(4).replace_int32(0, 5)
172
+ buffer.put_cstring('world')
173
+ buffer.get_cstring.should == 'world'
174
+ end
439
175
  end
440
176
 
441
- it 'replaces the int32 at the location' do
442
- expect(modified.to_s).to eq("#{exp_first}#{exp_second}")
443
- end
444
- end
177
+ context 'mixed cycles' do
178
+ it 'returns the written data' do
179
+ if BSON::Environment.jruby?
180
+ pending 'RUBY-2334'
181
+ end
445
182
 
446
- describe '#rewind!' do
183
+ buffer.put_int32(1)
184
+ buffer.put_int32(2)
447
185
 
448
- shared_examples_for 'a rewindable buffer' do
186
+ buffer.get_int32.should == 1
449
187
 
450
- let(:string) do
451
- "#{BSON::Int32::BSON_TYPE}#{BSON::Int32::BSON_TYPE}"
452
- end
188
+ buffer.put_int32(3)
453
189
 
454
- before do
455
- buffer.get_bytes(1)
456
- buffer.rewind!
190
+ buffer.get_int32.should == 2
191
+ buffer.get_int32.should == 3
457
192
  end
193
+ end
194
+ end
458
195
 
459
- it 'resets the read position to 0' do
460
- expect(buffer.read_position).to eq(0)
196
+ describe '#to_s' do
197
+ context 'read buffer' do
198
+ let(:buffer) do
199
+ described_class.new("\x18\x00\x00\x00*\x00\x00\x00")
461
200
  end
462
201
 
463
- it 'starts subsequent reads at position 0' do
464
- expect(buffer.get_bytes(2)).to eq(string)
202
+ it 'returns the data' do
203
+ buffer.to_s.should == "\x18\x00\x00\x00*\x00\x00\x00"
465
204
  end
466
- end
467
-
468
- context 'when the buffer is instantiated with a string' do
469
205
 
470
- let(:buffer) do
471
- described_class.new(string)
206
+ it 'returns the remaining buffer contents after a read' do
207
+ buffer.to_s.should == "\x18\x00\x00\x00*\x00\x00\x00"
208
+ buffer.get_int32.should == 24
209
+ buffer.to_s.should == "*\x00\x00\x00"
472
210
  end
473
-
474
- it_behaves_like 'a rewindable buffer'
475
211
  end
476
212
 
477
- context 'when the buffer is instantiated with nothing' do
478
-
213
+ context 'write buffer' do
479
214
  let(:buffer) do
480
- described_class.new
215
+ described_class.new.tap do |buffer|
216
+ buffer.put_int32(24)
217
+ end
481
218
  end
482
219
 
483
- before do
484
- buffer.put_byte(BSON::Int32::BSON_TYPE).put_byte(BSON::Int32::BSON_TYPE)
220
+ it 'returns the data' do
221
+ buffer.to_s.should == "\x18\x00\x00\x00".force_encoding('binary')
485
222
  end
486
223
 
487
- it_behaves_like 'a rewindable buffer'
224
+ it 'returns the complete buffer contents after a write' do
225
+ buffer.to_s.should == "\x18\x00\x00\x00".force_encoding('binary')
226
+ buffer.put_int32(42)
227
+ buffer.to_s.should == "\x18\x00\x00\x00*\x00\x00\x00".force_encoding('binary')
228
+ end
488
229
  end
489
230
  end
490
231
  end