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.
- checksums.yaml +5 -5
- data/README.md +106 -7
- data/Rakefile +86 -43
- data/ext/bson/{native-endian.h → bson-endian.h} +14 -107
- data/ext/bson/bson-native.h +135 -0
- data/ext/bson/bytebuf.c +133 -0
- data/ext/bson/endian.c +117 -0
- data/ext/bson/extconf.rb +8 -3
- data/ext/bson/init.c +364 -0
- data/ext/bson/libbson-utf8.c +230 -0
- data/ext/bson/read.c +470 -0
- data/ext/bson/util.c +250 -0
- data/ext/bson/write.c +675 -0
- data/lib/bson/active_support.rb +19 -0
- data/lib/bson/array.rb +97 -30
- data/lib/bson/big_decimal.rb +77 -0
- data/lib/bson/binary.rb +510 -70
- data/lib/bson/boolean.rb +15 -4
- data/lib/bson/code.rb +25 -12
- data/lib/bson/code_with_scope.rb +41 -15
- data/lib/bson/config.rb +3 -28
- data/lib/bson/date.rb +16 -4
- data/lib/bson/date_time.rb +6 -4
- data/lib/bson/db_pointer.rb +110 -0
- data/lib/bson/dbref.rb +154 -0
- data/lib/bson/decimal128/builder.rb +456 -0
- data/lib/bson/decimal128.rb +272 -0
- data/lib/bson/document.rb +177 -7
- data/lib/bson/environment.rb +17 -2
- data/lib/bson/error/bson_decode_error.rb +11 -0
- data/lib/bson/error/ext_json_parse_error.rb +11 -0
- data/lib/bson/error/illegal_key.rb +23 -0
- data/lib/bson/error/invalid_binary_type.rb +37 -0
- data/lib/bson/error/invalid_dbref_argument.rb +12 -0
- data/lib/bson/error/invalid_decimal128_argument.rb +25 -0
- data/lib/bson/error/invalid_decimal128_range.rb +27 -0
- data/lib/bson/error/invalid_decimal128_string.rb +26 -0
- data/lib/bson/error/invalid_key.rb +24 -0
- data/lib/bson/error/invalid_object_id.rb +11 -0
- data/lib/bson/error/invalid_regexp_pattern.rb +13 -0
- data/lib/bson/error/unrepresentable_precision.rb +19 -0
- data/lib/bson/error/unserializable_class.rb +13 -0
- data/lib/bson/error/unsupported_binary_subtype.rb +12 -0
- data/lib/bson/error/unsupported_type.rb +11 -0
- data/lib/bson/error.rb +22 -0
- data/lib/bson/ext_json.rb +389 -0
- data/lib/bson/false_class.rb +6 -4
- data/lib/bson/float.rb +43 -7
- data/lib/bson/hash.rb +152 -37
- data/lib/bson/int32.rb +104 -6
- data/lib/bson/int64.rb +111 -8
- data/lib/bson/integer.rb +43 -9
- data/lib/bson/json.rb +3 -1
- data/lib/bson/max_key.rb +21 -10
- data/lib/bson/min_key.rb +21 -10
- data/lib/bson/nil_class.rb +7 -3
- data/lib/bson/object.rb +25 -17
- data/lib/bson/object_id.rb +98 -113
- data/lib/bson/open_struct.rb +59 -0
- data/lib/bson/regexp.rb +129 -56
- data/lib/bson/registry.rb +7 -10
- data/lib/bson/specialized.rb +8 -4
- data/lib/bson/string.rb +12 -32
- data/lib/bson/symbol.rb +107 -11
- data/lib/bson/time.rb +68 -7
- data/lib/bson/time_with_zone.rb +67 -0
- data/lib/bson/timestamp.rb +50 -10
- data/lib/bson/true_class.rb +6 -4
- data/lib/bson/undefined.rb +28 -2
- data/lib/bson/vector.rb +44 -0
- data/lib/bson/version.rb +6 -14
- data/lib/bson.rb +22 -12
- data/spec/README.md +14 -0
- data/spec/bson/array_spec.rb +38 -62
- data/spec/bson/big_decimal_spec.rb +328 -0
- data/spec/bson/binary_spec.rb +199 -53
- data/spec/bson/binary_uuid_spec.rb +190 -0
- data/spec/bson/boolean_spec.rb +2 -1
- data/spec/bson/byte_buffer_read_spec.rb +198 -0
- data/spec/bson/byte_buffer_spec.rb +122 -381
- data/spec/bson/byte_buffer_write_spec.rb +855 -0
- data/spec/bson/code_spec.rb +6 -4
- data/spec/bson/code_with_scope_spec.rb +6 -4
- data/spec/bson/config_spec.rb +1 -35
- data/spec/bson/date_spec.rb +2 -1
- data/spec/bson/date_time_spec.rb +55 -1
- data/spec/bson/dbref_legacy_spec.rb +186 -0
- data/spec/bson/dbref_spec.rb +487 -0
- data/spec/bson/decimal128_spec.rb +1840 -0
- data/spec/bson/document_as_spec.rb +61 -0
- data/spec/bson/document_spec.rb +205 -32
- data/spec/bson/ext_json_parse_spec.rb +346 -0
- data/spec/bson/false_class_spec.rb +9 -1
- data/spec/bson/float_spec.rb +42 -1
- data/spec/bson/hash_as_spec.rb +58 -0
- data/spec/bson/hash_spec.rb +318 -66
- data/spec/bson/int32_spec.rb +248 -1
- data/spec/bson/int64_spec.rb +308 -1
- data/spec/bson/integer_spec.rb +61 -3
- data/spec/bson/json_spec.rb +2 -1
- data/spec/bson/max_key_spec.rb +6 -4
- data/spec/bson/min_key_spec.rb +6 -4
- data/spec/bson/nil_class_spec.rb +2 -1
- data/spec/bson/object_id_spec.rb +95 -5
- data/spec/bson/object_spec.rb +3 -2
- data/spec/bson/open_struct_spec.rb +87 -0
- data/spec/bson/raw_spec.rb +594 -0
- data/spec/bson/regexp_spec.rb +61 -8
- data/spec/bson/registry_spec.rb +3 -2
- data/spec/bson/string_spec.rb +26 -33
- data/spec/bson/symbol_raw_spec.rb +70 -0
- data/spec/bson/symbol_spec.rb +77 -20
- data/spec/bson/time_spec.rb +206 -2
- data/spec/bson/time_with_zone_spec.rb +69 -0
- data/spec/bson/timestamp_spec.rb +58 -2
- data/spec/bson/true_class_spec.rb +9 -1
- data/spec/bson/undefined_spec.rb +28 -1
- data/spec/bson/vector_spec.rb +33 -0
- data/spec/bson_spec.rb +2 -1
- data/spec/runners/binary_vector.rb +78 -0
- data/spec/runners/common_driver.rb +348 -0
- data/spec/runners/corpus.rb +191 -0
- data/spec/runners/corpus_legacy.rb +248 -0
- data/spec/shared/LICENSE +20 -0
- data/spec/shared/bin/get-mongodb-download-url +17 -0
- data/spec/shared/bin/s3-copy +45 -0
- data/spec/shared/bin/s3-upload +69 -0
- data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
- data/spec/shared/lib/mrss/cluster_config.rb +231 -0
- data/spec/shared/lib/mrss/constraints.rb +378 -0
- data/spec/shared/lib/mrss/docker_runner.rb +298 -0
- data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
- data/spec/shared/lib/mrss/event_subscriber.rb +210 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +238 -0
- data/spec/shared/lib/mrss/release/candidate.rb +281 -0
- data/spec/shared/lib/mrss/release/product_data.rb +144 -0
- data/spec/shared/lib/mrss/server_version_registry.rb +113 -0
- data/spec/shared/lib/mrss/session_registry.rb +69 -0
- data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
- data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
- data/spec/shared/lib/mrss/utils.rb +37 -0
- data/spec/shared/lib/tasks/candidate.rake +64 -0
- data/spec/shared/share/Dockerfile.erb +251 -0
- data/spec/shared/share/haproxy-1.conf +16 -0
- data/spec/shared/share/haproxy-2.conf +17 -0
- data/spec/shared/shlib/config.sh +27 -0
- data/spec/shared/shlib/distro.sh +84 -0
- data/spec/shared/shlib/server.sh +423 -0
- data/spec/shared/shlib/set_env.sh +110 -0
- data/spec/spec_helper.rb +61 -1
- data/spec/spec_tests/binary_vector_spec.rb +82 -0
- data/spec/spec_tests/common_driver_spec.rb +84 -0
- data/spec/spec_tests/corpus_legacy_spec.rb +72 -0
- data/spec/spec_tests/corpus_spec.rb +134 -0
- data/spec/spec_tests/data/binary_vector/README.md +61 -0
- data/spec/spec_tests/data/binary_vector/float32.json +65 -0
- data/spec/spec_tests/data/binary_vector/int8.json +57 -0
- data/spec/spec_tests/data/binary_vector/packed_bit.json +83 -0
- data/spec/spec_tests/data/corpus/README.md +15 -0
- data/spec/spec_tests/data/corpus/array.json +49 -0
- data/spec/spec_tests/data/corpus/binary.json +153 -0
- data/spec/spec_tests/data/corpus/boolean.json +27 -0
- data/spec/spec_tests/data/corpus/code.json +67 -0
- data/spec/spec_tests/data/corpus/code_w_scope.json +78 -0
- data/spec/spec_tests/data/corpus/datetime.json +42 -0
- data/spec/spec_tests/data/corpus/dbpointer.json +56 -0
- data/spec/spec_tests/data/corpus/dbref.json +51 -0
- data/spec/spec_tests/data/corpus/decimal128-1.json +317 -0
- data/spec/spec_tests/data/corpus/decimal128-2.json +793 -0
- data/spec/spec_tests/data/corpus/decimal128-3.json +1771 -0
- data/spec/spec_tests/data/corpus/decimal128-4.json +165 -0
- data/spec/spec_tests/data/corpus/decimal128-5.json +402 -0
- data/spec/spec_tests/data/corpus/decimal128-6.json +131 -0
- data/spec/spec_tests/data/corpus/decimal128-7.json +327 -0
- data/spec/spec_tests/data/corpus/document.json +60 -0
- data/spec/spec_tests/data/corpus/double.json +87 -0
- data/spec/spec_tests/data/corpus/int32.json +43 -0
- data/spec/spec_tests/data/corpus/int64.json +43 -0
- data/spec/spec_tests/data/corpus/maxkey.json +12 -0
- data/spec/spec_tests/data/corpus/minkey.json +12 -0
- data/spec/spec_tests/data/corpus/multi-type-deprecated.json +15 -0
- data/spec/spec_tests/data/corpus/multi-type.json +11 -0
- data/spec/spec_tests/data/corpus/null.json +12 -0
- data/spec/spec_tests/data/corpus/oid.json +28 -0
- data/spec/spec_tests/data/corpus/regex.json +65 -0
- data/spec/spec_tests/data/corpus/string.json +72 -0
- data/spec/spec_tests/data/corpus/symbol.json +80 -0
- data/spec/spec_tests/data/corpus/timestamp.json +34 -0
- data/spec/spec_tests/data/corpus/top.json +262 -0
- data/spec/spec_tests/data/corpus/undefined.json +15 -0
- data/spec/spec_tests/data/corpus_legacy/array.json +49 -0
- data/spec/spec_tests/data/corpus_legacy/binary.json +69 -0
- data/spec/spec_tests/data/corpus_legacy/boolean.json +27 -0
- data/spec/spec_tests/data/corpus_legacy/code.json +67 -0
- data/spec/spec_tests/data/corpus_legacy/code_w_scope.json +78 -0
- data/spec/spec_tests/data/corpus_legacy/document.json +36 -0
- data/spec/spec_tests/data/corpus_legacy/double.json +69 -0
- data/spec/spec_tests/data/corpus_legacy/failures/datetime.json +31 -0
- data/spec/spec_tests/data/corpus_legacy/failures/dbpointer.json +42 -0
- data/spec/spec_tests/data/corpus_legacy/failures/int64.json +38 -0
- data/spec/spec_tests/data/corpus_legacy/failures/symbol.json +62 -0
- data/spec/spec_tests/data/corpus_legacy/int32.json +38 -0
- data/spec/spec_tests/data/corpus_legacy/maxkey.json +12 -0
- data/spec/spec_tests/data/corpus_legacy/minkey.json +12 -0
- data/spec/spec_tests/data/corpus_legacy/null.json +12 -0
- data/spec/spec_tests/data/corpus_legacy/oid.json +28 -0
- data/spec/spec_tests/data/corpus_legacy/regex.json +37 -0
- data/spec/spec_tests/data/corpus_legacy/string.json +67 -0
- data/spec/spec_tests/data/corpus_legacy/timestamp.json +18 -0
- data/spec/spec_tests/data/corpus_legacy/top.json +62 -0
- data/spec/spec_tests/data/corpus_legacy/undefined.json +13 -0
- data/spec/spec_tests/data/decimal128/decimal128-1.json +363 -0
- data/spec/spec_tests/data/decimal128/decimal128-2.json +793 -0
- data/spec/spec_tests/data/decimal128/decimal128-3.json +1771 -0
- data/spec/spec_tests/data/decimal128/decimal128-4.json +165 -0
- data/spec/spec_tests/data/decimal128/decimal128-5.json +402 -0
- data/spec/spec_tests/data/decimal128/decimal128-6.json +131 -0
- data/spec/spec_tests/data/decimal128/decimal128-7.json +327 -0
- data/spec/support/shared_examples.rb +32 -11
- data/spec/support/spec_config.rb +17 -0
- data/spec/support/utils.rb +58 -0
- metadata +284 -45
- checksums.yaml.gz.sig +0 -3
- data/ext/bson/native.c +0 -722
- data.tar.gz.sig +0 -0
- metadata.gz.sig +0 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# rubocop:todo all
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
require 'runners/common_driver'
|
|
4
|
+
|
|
5
|
+
describe 'Driver common bson tests' do
|
|
6
|
+
|
|
7
|
+
specs = DRIVER_COMMON_BSON_TESTS.map { |file| BSON::CommonDriver::Spec.new(file) }
|
|
8
|
+
|
|
9
|
+
specs.each do |spec|
|
|
10
|
+
|
|
11
|
+
context(spec.description) do
|
|
12
|
+
|
|
13
|
+
spec.valid_tests.each do |test|
|
|
14
|
+
|
|
15
|
+
context(test.description << ' - ' << test.string) do
|
|
16
|
+
|
|
17
|
+
it 'decodes the subject and displays as the correct string' do
|
|
18
|
+
expect(test.object.to_s).to eq(test.expected_to_string)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it 'encodes the decoded object correctly (roundtrips)' do
|
|
22
|
+
expect(test.reencoded_hex).to eq(test.subject.upcase)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'creates the correct object from extended json', if: test.from_ext_json? do
|
|
26
|
+
expect(test.from_json_string).to eq(test.object)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
it 'serializes to a string', if: test.to_ext_json? do
|
|
30
|
+
expect(test.document_as_extended_json).to eq(test.ext_json)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it 'creates the correct extended json document from the decoded object', if: test.to_ext_json? do
|
|
34
|
+
expect(test.document_as_extended_json).to eq(test.ext_json)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'parses the string value to the same value as the decoded document', if: test.from_string? do
|
|
38
|
+
expect(BSON::Decimal128.new(test.string)).to eq(test.object)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'parses the #to_s (match_string) value to the same value as the decoded document', if: test.match_string do
|
|
42
|
+
expect(BSON::Decimal128.new(test.match_string)).to eq(test.object)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
it 'creates the correct object from a non canonical string and then prints to the correct string', if: test.match_string do
|
|
46
|
+
expect(BSON::Decimal128.new(test.string).to_s).to eq(test.match_string)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'can be converted to a native type' do
|
|
50
|
+
expect(test.native_type_conversion).to be_a(test.native_type)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
spec.invalid_tests.each do |test|
|
|
56
|
+
|
|
57
|
+
context(test.description << " - " << test.subject ) do
|
|
58
|
+
|
|
59
|
+
let(:error) do
|
|
60
|
+
ex = nil
|
|
61
|
+
begin
|
|
62
|
+
test.parse_invalid_string
|
|
63
|
+
rescue => e
|
|
64
|
+
ex = e
|
|
65
|
+
end
|
|
66
|
+
ex
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
let(:valid_errors) do
|
|
70
|
+
[
|
|
71
|
+
BSON::Error::InvalidDecimal128String,
|
|
72
|
+
BSON::Error::InvalidDecimal128Range,
|
|
73
|
+
BSON::Error::UnrepresentablePrecision,
|
|
74
|
+
]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'raises an exception when parsing' do
|
|
78
|
+
expect(error.class).to satisfy { |e| valid_errors.include?(e) }
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# rubocop:todo all
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
require 'runners/corpus_legacy'
|
|
4
|
+
|
|
5
|
+
describe 'Driver BSON Corpus Legacy spec tests' do
|
|
6
|
+
|
|
7
|
+
BSON_CORPUS_LEGACY_TESTS.each do |path|
|
|
8
|
+
basename = File.basename(path)
|
|
9
|
+
# All of the tests in the failures subdir are failing apparently
|
|
10
|
+
#basename = path.sub(/.*corpus-tests\//, '')
|
|
11
|
+
|
|
12
|
+
spec = BSON::CorpusLegacy::Spec.new(path)
|
|
13
|
+
|
|
14
|
+
context("(#{basename}): #{spec.description}") do
|
|
15
|
+
|
|
16
|
+
spec.valid_tests.each do |test|
|
|
17
|
+
|
|
18
|
+
context("VALID CASE: #{test.description}") do
|
|
19
|
+
|
|
20
|
+
it 'roundtrips the given bson correctly' do
|
|
21
|
+
expect(test.reencoded_bson).to eq(test.correct_bson)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
context 'when the canonical bson is roundtripped', if: test.test_canonical_bson? do
|
|
25
|
+
|
|
26
|
+
it 'encodes the canonical bson correctly' do
|
|
27
|
+
expect(test.reencoded_canonical_bson).to eq(test.correct_bson)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
context 'when the document can be represented as extended json', if: test.test_extjson? do
|
|
32
|
+
|
|
33
|
+
it 'decodes from the given bson, then encodes the document as extended json correctly' do
|
|
34
|
+
expect(test.extjson_from_bson).to eq(test.correct_extjson)
|
|
35
|
+
expect(test.extjson_from_bson[test.test_key]).to eq(test.correct_extjson[test.test_key])
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it 'decodes from extended json, then encodes the document as extended json correctly' do
|
|
39
|
+
expect(test.extjson_from_encoded_extjson).to eq(test.correct_extjson)
|
|
40
|
+
expect(test.extjson_from_encoded_extjson[test.test_key]).to eq(test.correct_extjson[test.test_key])
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context 'when the canonical bson can be represented as extended json', if: (test.test_canonical_bson? && test.test_extjson?) do
|
|
44
|
+
|
|
45
|
+
it 'encodes the canonical bson correctly as extended json' do
|
|
46
|
+
expect(test.extjson_from_canonical_bson).to eq(test.correct_extjson)
|
|
47
|
+
expect(test.extjson_from_canonical_bson[test.test_key]).to eq(test.correct_extjson[test.test_key])
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
spec.invalid_tests.each do |test|
|
|
55
|
+
|
|
56
|
+
context("INVALID CASE: #{test.description}") do
|
|
57
|
+
|
|
58
|
+
let(:error) do
|
|
59
|
+
begin; test.reencoded_bson; false; rescue => e; e; end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it 'raises an error' do
|
|
63
|
+
skip 'This test case does not raise and error but should' unless error
|
|
64
|
+
expect do
|
|
65
|
+
test.reencoded_bson
|
|
66
|
+
end.to raise_error(error.class)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# rubocop:todo all
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
require 'runners/corpus'
|
|
4
|
+
|
|
5
|
+
describe 'BSON Corpus spec tests' do
|
|
6
|
+
|
|
7
|
+
BSON_CORPUS_TESTS.each do |path|
|
|
8
|
+
basename = File.basename(path)
|
|
9
|
+
# All of the tests in the failures subdir are failing apparently
|
|
10
|
+
#basename = path.sub(/.*corpus-tests\//, '')
|
|
11
|
+
|
|
12
|
+
spec = BSON::Corpus::Spec.new(path)
|
|
13
|
+
|
|
14
|
+
context("(#{basename}): #{spec.description}") do
|
|
15
|
+
|
|
16
|
+
spec.valid_tests&.each do |test|
|
|
17
|
+
|
|
18
|
+
context("valid: #{test.description}") do
|
|
19
|
+
|
|
20
|
+
let(:decoded_canonical_bson) do
|
|
21
|
+
BSON::Document.from_bson(BSON::ByteBuffer.new(test.canonical_bson), mode: :bson)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'round-trips canonical bson' do
|
|
25
|
+
decoded_canonical_bson.to_bson.to_s.should == test.canonical_bson
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
=begin
|
|
29
|
+
it 'converts bson to canonical extended json' do
|
|
30
|
+
pending
|
|
31
|
+
raise NotImplementedError
|
|
32
|
+
end
|
|
33
|
+
=end
|
|
34
|
+
|
|
35
|
+
it 'converts bson to canonical extended json' do
|
|
36
|
+
decoded_canonical_bson.as_extended_json.should == test.canonical_extjson_doc
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
if test.relaxed_extjson
|
|
40
|
+
it 'converts bson to relaxed extended json' do
|
|
41
|
+
decoded_canonical_bson.as_extended_json(mode: :relaxed).should == test.relaxed_extjson_doc
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
let(:parsed_relaxed_extjson) do
|
|
45
|
+
BSON::ExtJSON.parse_obj(test.relaxed_extjson_doc, mode: :bson)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
let(:round_tripped_relaxed_extjson) do
|
|
49
|
+
parsed_relaxed_extjson.as_extended_json(mode: :relaxed)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Relaxed extended json may parse into something other than the
|
|
53
|
+
# canonical bson. For example, relaxed extjson representation for
|
|
54
|
+
# a small int64 is a number that would serialize to an int32.
|
|
55
|
+
# But round-tripping extended json back to extjson should produce
|
|
56
|
+
# the same representation we started with.
|
|
57
|
+
it 'round-trips relaxed extended json' do
|
|
58
|
+
round_tripped_relaxed_extjson.should == test.relaxed_extjson_doc
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
if test.degenerate_bson
|
|
63
|
+
|
|
64
|
+
let(:decoded_degenerate_bson) do
|
|
65
|
+
BSON::Document.from_bson(BSON::ByteBuffer.new(test.degenerate_bson), mode: :relaxed)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it 'round-trips degenerate bson to canonical bson' do
|
|
69
|
+
decoded_degenerate_bson.to_bson.to_s.should == test.canonical_bson
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
let(:parsed_canonical_extjson) do
|
|
74
|
+
BSON::ExtJSON.parse_obj(test.canonical_extjson_doc, mode: :bson)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
unless test.lossy?
|
|
78
|
+
it 'converts canonical extended json to bson' do
|
|
79
|
+
parsed_canonical_extjson.to_bson.to_s.should == test.canonical_bson
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
spec.decode_error_tests&.each do |test|
|
|
87
|
+
|
|
88
|
+
context("decode error: #{test.description}") do
|
|
89
|
+
|
|
90
|
+
let(:decoded_bson) do
|
|
91
|
+
BSON::Document.from_bson(BSON::ByteBuffer.new(test.bson), mode: :bson)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Until bson-ruby gets an exception hierarchy, we can only rescue
|
|
95
|
+
# the basic Exception here.
|
|
96
|
+
# https://jira.mongodb.org/browse/RUBY-1806
|
|
97
|
+
it 'raises an exception' do
|
|
98
|
+
expect do
|
|
99
|
+
decoded_bson
|
|
100
|
+
end.to raise_error(Exception)
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
spec.parse_error_tests&.each do |test|
|
|
106
|
+
|
|
107
|
+
context("parse error: #{test.description}") do
|
|
108
|
+
|
|
109
|
+
# As per:
|
|
110
|
+
# https://github.com/mongodb/specifications/blob/e7ee829329400786e01279b4f37d4e440d1e9cfa/source/bson-corpus/bson-corpus.rst#decimal128-type-0x13
|
|
111
|
+
#
|
|
112
|
+
# Values under test must be parsed in a type-specific manner.
|
|
113
|
+
let(:parsed_value) do
|
|
114
|
+
case spec.bson_type
|
|
115
|
+
when BSON::Decimal128::BSON_TYPE
|
|
116
|
+
BSON::Decimal128.new(test.string)
|
|
117
|
+
else
|
|
118
|
+
BSON::ExtJSON.parse(test.string, mode: :bson)
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Until bson-ruby gets an exception hierarchy, we can only rescue
|
|
123
|
+
# the basic Exception here.
|
|
124
|
+
# https://jira.mongodb.org/browse/RUBY-1806
|
|
125
|
+
it 'raises an exception' do
|
|
126
|
+
expect do
|
|
127
|
+
parsed_value
|
|
128
|
+
end.to raise_error(Exception)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Testing Binary subtype 9: Vector
|
|
2
|
+
|
|
3
|
+
The JSON files in this directory tree are platform-independent tests that drivers can use to prove their conformance to
|
|
4
|
+
the specification.
|
|
5
|
+
|
|
6
|
+
These tests focus on the roundtrip of the list of numbers as input/output, along with their data type and byte padding.
|
|
7
|
+
|
|
8
|
+
Additional tests exist in `bson_corpus/tests/binary.json` but do not sufficiently test the end-to-end process of Vector
|
|
9
|
+
to BSON. For this reason, drivers must create a bespoke test runner for the vector subtype.
|
|
10
|
+
|
|
11
|
+
## Format
|
|
12
|
+
|
|
13
|
+
The test data corpus consists of a JSON file for each data type (dtype). Each file contains a number of test cases,
|
|
14
|
+
under the top-level key "tests". Each test case pertains to a single vector. The keys provide the specification of the
|
|
15
|
+
vector. Valid cases also include the Canonical BSON format of a document {test_key: binary}. The "test_key" is common,
|
|
16
|
+
and specified at the top level.
|
|
17
|
+
|
|
18
|
+
#### Top level keys
|
|
19
|
+
|
|
20
|
+
Each JSON file contains three top-level keys.
|
|
21
|
+
|
|
22
|
+
- `description`: human-readable description of what is in the file
|
|
23
|
+
- `test_key`: name used for key when encoding/decoding a BSON document containing the single BSON Binary for the test
|
|
24
|
+
case. Applies to *every* case.
|
|
25
|
+
- `tests`: array of test case objects, each of which have the following keys. Valid cases will also contain additional
|
|
26
|
+
binary and json encoding values.
|
|
27
|
+
|
|
28
|
+
#### Keys of individual tests cases
|
|
29
|
+
|
|
30
|
+
- `description`: string describing the test.
|
|
31
|
+
- `valid`: boolean indicating if the vector, dtype, and padding should be considered a valid input.
|
|
32
|
+
- `vector`: (required if valid is true) list of numbers
|
|
33
|
+
- `dtype_hex`: string defining the data type in hex (e.g. "0x10", "0x27")
|
|
34
|
+
- `dtype_alias`: (optional) string defining the data dtype, perhaps as Enum.
|
|
35
|
+
- `padding`: (optional) integer for byte padding. Defaults to 0.
|
|
36
|
+
- `canonical_bson`: (required if valid is true) an (uppercase) big-endian hex representation of a BSON byte string.
|
|
37
|
+
|
|
38
|
+
## Required tests
|
|
39
|
+
|
|
40
|
+
#### To prove correct in a valid case (`valid: true`), one MUST
|
|
41
|
+
|
|
42
|
+
- encode a document from the numeric values, dtype, and padding, along with the "test_key", and assert this matches the
|
|
43
|
+
canonical_bson string.
|
|
44
|
+
- decode the canonical_bson into its binary form, and then assert that the numeric values, dtype, and padding all match
|
|
45
|
+
those provided in the JSON.
|
|
46
|
+
|
|
47
|
+
Note: For floating point number types, exact numerical matches may not be possible. Drivers that natively support the
|
|
48
|
+
floating-point type being tested (e.g., when testing float32 vector values in a driver that natively supports float32),
|
|
49
|
+
MUST assert that the input float array is the same after encoding and decoding.
|
|
50
|
+
|
|
51
|
+
#### To prove correct in an invalid case (`valid:false`), one MUST
|
|
52
|
+
|
|
53
|
+
- if the vector field is present, raise an exception when attempting to encode a document from the numeric values,
|
|
54
|
+
dtype, and padding.
|
|
55
|
+
- if the canonical_bson field is present, raise an exception when attempting to deserialize it into the corresponding
|
|
56
|
+
numeric values, as the field contains corrupted data.
|
|
57
|
+
|
|
58
|
+
## FAQ
|
|
59
|
+
|
|
60
|
+
- What MongoDB Server version does this apply to?
|
|
61
|
+
- Files in the "specifications" repository have no version scheme. They are not tied to a MongoDB server version.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Tests of Binary subtype 9, Vectors, with dtype FLOAT32",
|
|
3
|
+
"test_key": "vector",
|
|
4
|
+
"tests": [
|
|
5
|
+
{
|
|
6
|
+
"description": "Simple Vector FLOAT32",
|
|
7
|
+
"valid": true,
|
|
8
|
+
"vector": [127.0, 7.0],
|
|
9
|
+
"dtype_hex": "0x27",
|
|
10
|
+
"dtype_alias": "FLOAT32",
|
|
11
|
+
"padding": 0,
|
|
12
|
+
"canonical_bson": "1C00000005766563746F72000A0000000927000000FE420000E04000"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"description": "Vector with decimals and negative value FLOAT32",
|
|
16
|
+
"valid": true,
|
|
17
|
+
"vector": [127.7, -7.7],
|
|
18
|
+
"dtype_hex": "0x27",
|
|
19
|
+
"dtype_alias": "FLOAT32",
|
|
20
|
+
"padding": 0,
|
|
21
|
+
"canonical_bson": "1C00000005766563746F72000A0000000927006666FF426666F6C000"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"description": "Empty Vector FLOAT32",
|
|
25
|
+
"valid": true,
|
|
26
|
+
"vector": [],
|
|
27
|
+
"dtype_hex": "0x27",
|
|
28
|
+
"dtype_alias": "FLOAT32",
|
|
29
|
+
"padding": 0,
|
|
30
|
+
"canonical_bson": "1400000005766563746F72000200000009270000"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"description": "Infinity Vector FLOAT32",
|
|
34
|
+
"valid": true,
|
|
35
|
+
"vector": [{"$numberDouble": "-Infinity"}, 0.0, {"$numberDouble": "Infinity"} ],
|
|
36
|
+
"dtype_hex": "0x27",
|
|
37
|
+
"dtype_alias": "FLOAT32",
|
|
38
|
+
"padding": 0,
|
|
39
|
+
"canonical_bson": "2000000005766563746F72000E000000092700000080FF000000000000807F00"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"description": "FLOAT32 with padding",
|
|
43
|
+
"valid": false,
|
|
44
|
+
"vector": [127.0, 7.0],
|
|
45
|
+
"dtype_hex": "0x27",
|
|
46
|
+
"dtype_alias": "FLOAT32",
|
|
47
|
+
"padding": 3,
|
|
48
|
+
"canonical_bson": "1C00000005766563746F72000A0000000927030000FE420000E04000"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"description": "Insufficient vector data with 3 bytes FLOAT32",
|
|
52
|
+
"valid": false,
|
|
53
|
+
"dtype_hex": "0x27",
|
|
54
|
+
"dtype_alias": "FLOAT32",
|
|
55
|
+
"canonical_bson": "1700000005766563746F7200050000000927002A2A2A00"
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"description": "Insufficient vector data with 5 bytes FLOAT32",
|
|
59
|
+
"valid": false,
|
|
60
|
+
"dtype_hex": "0x27",
|
|
61
|
+
"dtype_alias": "FLOAT32",
|
|
62
|
+
"canonical_bson": "1900000005766563746F7200070000000927002A2A2A2A2A00"
|
|
63
|
+
}
|
|
64
|
+
]
|
|
65
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Tests of Binary subtype 9, Vectors, with dtype INT8",
|
|
3
|
+
"test_key": "vector",
|
|
4
|
+
"tests": [
|
|
5
|
+
{
|
|
6
|
+
"description": "Simple Vector INT8",
|
|
7
|
+
"valid": true,
|
|
8
|
+
"vector": [127, 7],
|
|
9
|
+
"dtype_hex": "0x03",
|
|
10
|
+
"dtype_alias": "INT8",
|
|
11
|
+
"padding": 0,
|
|
12
|
+
"canonical_bson": "1600000005766563746F7200040000000903007F0700"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"description": "Empty Vector INT8",
|
|
16
|
+
"valid": true,
|
|
17
|
+
"vector": [],
|
|
18
|
+
"dtype_hex": "0x03",
|
|
19
|
+
"dtype_alias": "INT8",
|
|
20
|
+
"padding": 0,
|
|
21
|
+
"canonical_bson": "1400000005766563746F72000200000009030000"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"description": "Overflow Vector INT8",
|
|
25
|
+
"valid": false,
|
|
26
|
+
"vector": [128],
|
|
27
|
+
"dtype_hex": "0x03",
|
|
28
|
+
"dtype_alias": "INT8",
|
|
29
|
+
"padding": 0
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"description": "Underflow Vector INT8",
|
|
33
|
+
"valid": false,
|
|
34
|
+
"vector": [-129],
|
|
35
|
+
"dtype_hex": "0x03",
|
|
36
|
+
"dtype_alias": "INT8",
|
|
37
|
+
"padding": 0
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"description": "INT8 with padding",
|
|
41
|
+
"valid": false,
|
|
42
|
+
"vector": [127, 7],
|
|
43
|
+
"dtype_hex": "0x03",
|
|
44
|
+
"dtype_alias": "INT8",
|
|
45
|
+
"padding": 3,
|
|
46
|
+
"canonical_bson": "1600000005766563746F7200040000000903037F0700"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"description": "INT8 with float inputs",
|
|
50
|
+
"valid": false,
|
|
51
|
+
"vector": [127.77, 7.77],
|
|
52
|
+
"dtype_hex": "0x03",
|
|
53
|
+
"dtype_alias": "INT8",
|
|
54
|
+
"padding": 0
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Tests of Binary subtype 9, Vectors, with dtype PACKED_BIT",
|
|
3
|
+
"test_key": "vector",
|
|
4
|
+
"tests": [
|
|
5
|
+
{
|
|
6
|
+
"description": "Padding specified with no vector data PACKED_BIT",
|
|
7
|
+
"valid": false,
|
|
8
|
+
"vector": [],
|
|
9
|
+
"dtype_hex": "0x10",
|
|
10
|
+
"dtype_alias": "PACKED_BIT",
|
|
11
|
+
"padding": 1,
|
|
12
|
+
"canonical_bson": "1400000005766563746F72000200000009100100"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"description": "Simple Vector PACKED_BIT",
|
|
16
|
+
"valid": true,
|
|
17
|
+
"vector": [127, 7],
|
|
18
|
+
"dtype_hex": "0x10",
|
|
19
|
+
"dtype_alias": "PACKED_BIT",
|
|
20
|
+
"padding": 0,
|
|
21
|
+
"canonical_bson": "1600000005766563746F7200040000000910007F0700"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"description": "Empty Vector PACKED_BIT",
|
|
25
|
+
"valid": true,
|
|
26
|
+
"vector": [],
|
|
27
|
+
"dtype_hex": "0x10",
|
|
28
|
+
"dtype_alias": "PACKED_BIT",
|
|
29
|
+
"padding": 0,
|
|
30
|
+
"canonical_bson": "1400000005766563746F72000200000009100000"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"description": "PACKED_BIT with padding",
|
|
34
|
+
"valid": true,
|
|
35
|
+
"vector": [127, 7],
|
|
36
|
+
"dtype_hex": "0x10",
|
|
37
|
+
"dtype_alias": "PACKED_BIT",
|
|
38
|
+
"padding": 3,
|
|
39
|
+
"canonical_bson": "1600000005766563746F7200040000000910037F0700"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"description": "Overflow Vector PACKED_BIT",
|
|
43
|
+
"valid": false,
|
|
44
|
+
"vector": [256],
|
|
45
|
+
"dtype_hex": "0x10",
|
|
46
|
+
"dtype_alias": "PACKED_BIT",
|
|
47
|
+
"padding": 0
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"description": "Underflow Vector PACKED_BIT",
|
|
51
|
+
"valid": false,
|
|
52
|
+
"vector": [-1],
|
|
53
|
+
"dtype_hex": "0x10",
|
|
54
|
+
"dtype_alias": "PACKED_BIT",
|
|
55
|
+
"padding": 0
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"description": "Vector with float values PACKED_BIT",
|
|
59
|
+
"valid": false,
|
|
60
|
+
"vector": [127.5],
|
|
61
|
+
"dtype_hex": "0x10",
|
|
62
|
+
"dtype_alias": "PACKED_BIT",
|
|
63
|
+
"padding": 0
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"description": "Exceeding maximum padding PACKED_BIT",
|
|
67
|
+
"valid": false,
|
|
68
|
+
"vector": [1],
|
|
69
|
+
"dtype_hex": "0x10",
|
|
70
|
+
"dtype_alias": "PACKED_BIT",
|
|
71
|
+
"padding": 8,
|
|
72
|
+
"canonical_bson": "1500000005766563746F7200030000000910080100"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"description": "Negative padding PACKED_BIT",
|
|
76
|
+
"valid": false,
|
|
77
|
+
"vector": [1],
|
|
78
|
+
"dtype_hex": "0x10",
|
|
79
|
+
"dtype_alias": "PACKED_BIT",
|
|
80
|
+
"padding": -1
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
There are the following deliberate changes made to the corpus tests in Ruby:
|
|
2
|
+
|
|
3
|
+
1. In double.js, Ruby appears to offer less precision than the spec tests
|
|
4
|
+
demand:
|
|
5
|
+
|
|
6
|
+
irb(main):001:0> -1.23456789012345677E+18
|
|
7
|
+
=> -1.2345678901234568e+18
|
|
8
|
+
|
|
9
|
+
Because of this, -1.23456789012345677E+18 was changed to -1.2345678901234568e+18.
|
|
10
|
+
The "e" was lowercased as well. Both the precision reduction and the lowercasing
|
|
11
|
+
of "e" changes are also present in the Python driver, which appears to be
|
|
12
|
+
affected by the same precision limitation.
|
|
13
|
+
|
|
14
|
+
2. In datetime.js, the millisecond component of iso8601 serialization of
|
|
15
|
+
timestamps is always present, even if it is zero.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Array",
|
|
3
|
+
"bson_type": "0x04",
|
|
4
|
+
"test_key": "a",
|
|
5
|
+
"valid": [
|
|
6
|
+
{
|
|
7
|
+
"description": "Empty",
|
|
8
|
+
"canonical_bson": "0D000000046100050000000000",
|
|
9
|
+
"canonical_extjson": "{\"a\" : []}"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"description": "Single Element Array",
|
|
13
|
+
"canonical_bson": "140000000461000C0000001030000A0000000000",
|
|
14
|
+
"canonical_extjson": "{\"a\" : [{\"$numberInt\": \"10\"}]}"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"description": "Single Element Array with index set incorrectly to empty string",
|
|
18
|
+
"degenerate_bson": "130000000461000B00000010000A0000000000",
|
|
19
|
+
"canonical_bson": "140000000461000C0000001030000A0000000000",
|
|
20
|
+
"canonical_extjson": "{\"a\" : [{\"$numberInt\": \"10\"}]}"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"description": "Single Element Array with index set incorrectly to ab",
|
|
24
|
+
"degenerate_bson": "150000000461000D000000106162000A0000000000",
|
|
25
|
+
"canonical_bson": "140000000461000C0000001030000A0000000000",
|
|
26
|
+
"canonical_extjson": "{\"a\" : [{\"$numberInt\": \"10\"}]}"
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"description": "Multi Element Array with duplicate indexes",
|
|
30
|
+
"degenerate_bson": "1b000000046100130000001030000a000000103000140000000000",
|
|
31
|
+
"canonical_bson": "1b000000046100130000001030000a000000103100140000000000",
|
|
32
|
+
"canonical_extjson": "{\"a\" : [{\"$numberInt\": \"10\"}, {\"$numberInt\": \"20\"}]}"
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"decodeErrors": [
|
|
36
|
+
{
|
|
37
|
+
"description": "Array length too long: eats outer terminator",
|
|
38
|
+
"bson": "140000000461000D0000001030000A0000000000"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"description": "Array length too short: leaks terminator",
|
|
42
|
+
"bson": "140000000461000B0000001030000A0000000000"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"description": "Invalid Array: bad string length in field",
|
|
46
|
+
"bson": "1A00000004666F6F00100000000230000500000062617A000000"
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|