bson 4.2.2 → 4.12.1

Sign up to get free protection for your applications and to get access to all the features.
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