diff options
Diffstat (limited to 'src/mongo/db/bson')
-rw-r--r-- | src/mongo/db/bson/dotted_path_support_test.cpp | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/src/mongo/db/bson/dotted_path_support_test.cpp b/src/mongo/db/bson/dotted_path_support_test.cpp index b18e949290f..06fa6dc2840 100644 --- a/src/mongo/db/bson/dotted_path_support_test.cpp +++ b/src/mongo/db/bson/dotted_path_support_test.cpp @@ -37,6 +37,7 @@ #include "mongo/bson/bsonmisc.h" #include "mongo/bson/bsonobj.h" #include "mongo/bson/bsonobjbuilder.h" +#include "mongo/bson/json.h" #include "mongo/db/bson/dotted_path_support.h" #include "mongo/unittest/unittest.h" @@ -267,5 +268,216 @@ TEST(ExtractAllElementsAlongPath, assertArrayComponentsAreEqual({0U}, actualArrayComponents); } +TEST(ExtractAllElementsAlongPath, DoesNotExpandArrayWithinTrailingArray) { + BSONObj obj = BSON("a" << BSON("b" << BSON_ARRAY(BSON_ARRAY(1 << 2) << BSON_ARRAY(3 << 4)))); + + BSONElementSet actualElements; + const bool expandArrayOnTrailingField = true; + std::set<size_t> actualArrayComponents; + dps::extractAllElementsAlongPath( + obj, "a.b", actualElements, expandArrayOnTrailingField, &actualArrayComponents); + + assertBSONElementSetsAreEqual({BSON("" << BSON_ARRAY(1 << 2)), BSON("" << BSON_ARRAY(3 << 4))}, + actualElements); + assertArrayComponentsAreEqual({1U}, actualArrayComponents); +} + +TEST(ExtractAllElementsAlongPath, ObjectWithTwoDimensionalArrayOfSubobjects) { + // Does not expand the array within the array. + BSONObj obj = fromjson("{a: [[{b: 0}, {b: 1}], [{b: 2}, {b: 3}]]}"); + + BSONElementSet actualElements; + const bool expandArrayOnTrailingField = true; + std::set<size_t> actualArrayComponents; + dps::extractAllElementsAlongPath( + obj, "a.b", actualElements, expandArrayOnTrailingField, &actualArrayComponents); + + assertBSONElementSetsAreEqual({}, actualElements); + assertArrayComponentsAreEqual({0U}, actualArrayComponents); +} + +TEST(ExtractAllElementsAlongPath, ObjectWithDiverseStructure) { + BSONObj obj = fromjson( + "{a: [" + " {b: 0}," + " [{b: 1}, {b: {c: -1}}]," + " 'no b here!'," + " {b: [{c: -2}, 'no c here!']}," + " {b: {c: [-3, -4]}}" + "]}"); + + BSONElementSet actualElements; + const bool expandArrayOnTrailingField = true; + std::set<size_t> actualArrayComponents; + dps::extractAllElementsAlongPath( + obj, "a.b.c", actualElements, expandArrayOnTrailingField, &actualArrayComponents); + + assertBSONElementSetsAreEqual({BSON("" << -2), BSON("" << -3), BSON("" << -4)}, actualElements); + assertArrayComponentsAreEqual({0U, 1U, 2U}, actualArrayComponents); +} + +TEST(ExtractAllElementsAlongPath, AcceptsNumericFieldNames) { + BSONObj obj = BSON("a" << BSON("0" << 1)); + + BSONElementSet actualElements; + const bool expandArrayOnTrailingField = true; + std::set<size_t> actualArrayComponents; + dps::extractAllElementsAlongPath( + obj, "a.0", actualElements, expandArrayOnTrailingField, &actualArrayComponents); + + assertBSONElementSetsAreEqual({BSON("" << 1)}, actualElements); + assertArrayComponentsAreEqual(std::set<size_t>{}, actualArrayComponents); +} + +TEST(ExtractAllElementsAlongPath, UsesNumericFieldNameToExtractElementFromArray) { + BSONObj obj = BSON("a" << BSON_ARRAY(1 << BSON("0" << 2))); + + BSONElementSet actualElements; + const bool expandArrayOnTrailingField = true; + std::set<size_t> actualArrayComponents; + dps::extractAllElementsAlongPath( + obj, "a.0", actualElements, expandArrayOnTrailingField, &actualArrayComponents); + + assertBSONElementSetsAreEqual({BSON("" << 1)}, actualElements); + assertArrayComponentsAreEqual(std::set<size_t>{}, actualArrayComponents); +} + +TEST(ExtractAllElementsAlongPath, TreatsNegativeIndexAsFieldName) { + BSONObj obj = BSON("a" << BSON_ARRAY(1 << BSON("-1" << 2) << BSON("b" << 3))); + + BSONElementSet actualElements; + const bool expandArrayOnTrailingField = true; + std::set<size_t> actualArrayComponents; + dps::extractAllElementsAlongPath( + obj, "a.-1", actualElements, expandArrayOnTrailingField, &actualArrayComponents); + + assertBSONElementSetsAreEqual({BSON("" << 2)}, actualElements); + assertArrayComponentsAreEqual({0U}, actualArrayComponents); +} + +TEST(ExtractAllElementsAlongPath, ExtractsNoValuesFromOutOfBoundsIndex) { + BSONObj obj = BSON("a" << BSON_ARRAY(1 << BSON("b" << 2) << BSON("10" << 3))); + + BSONElementSet actualElements; + const bool expandArrayOnTrailingField = true; + std::set<size_t> actualArrayComponents; + dps::extractAllElementsAlongPath( + obj, "a.10", actualElements, expandArrayOnTrailingField, &actualArrayComponents); + + assertBSONElementSetsAreEqual({}, actualElements); + assertArrayComponentsAreEqual(std::set<size_t>{}, actualArrayComponents); +} + +TEST(ExtractAllElementsAlongPath, DoesNotTreatHexStringAsIndexSpecification) { + BSONObj obj = BSON("a" << BSON_ARRAY(1 << BSON("0x2" << 2) << BSON("NOT THIS ONE" << 3))); + + BSONElementSet actualElements; + const bool expandArrayOnTrailingField = true; + std::set<size_t> actualArrayComponents; + dps::extractAllElementsAlongPath( + obj, "a.0x2", actualElements, expandArrayOnTrailingField, &actualArrayComponents); + + assertBSONElementSetsAreEqual({BSON("" << 2)}, actualElements); + assertArrayComponentsAreEqual({0U}, actualArrayComponents); +} + +TEST(ExtractAllElementsAlongPath, DoesNotAcceptLeadingPlusAsArrayIndex) { + BSONObj obj = BSON("a" << BSON_ARRAY(1 << BSON("+2" << 2) << BSON("NOT THIS ONE" << 3))); + + BSONElementSet actualElements; + const bool expandArrayOnTrailingField = true; + std::set<size_t> actualArrayComponents; + dps::extractAllElementsAlongPath( + obj, "a.+2", actualElements, expandArrayOnTrailingField, &actualArrayComponents); + + assertBSONElementSetsAreEqual({BSON("" << 2)}, actualElements); + assertArrayComponentsAreEqual({0U}, actualArrayComponents); +} + +TEST(ExtractAllElementsAlongPath, DoesNotAcceptTrailingCharactersForArrayIndex) { + BSONObj obj = BSON("a" << BSON_ARRAY(1 << BSON("2xyz" << 2) << BSON("NOT THIS ONE" << 3))); + + BSONElementSet actualElements; + const bool expandArrayOnTrailingField = true; + std::set<size_t> actualArrayComponents; + dps::extractAllElementsAlongPath( + obj, "a.2xyz", actualElements, expandArrayOnTrailingField, &actualArrayComponents); + + assertBSONElementSetsAreEqual({BSON("" << 2)}, actualElements); + assertArrayComponentsAreEqual({0U}, actualArrayComponents); +} + +TEST(ExtractAllElementsAlongPath, DoesNotAcceptNonDigitsForArrayIndex) { + BSONObj obj = BSON("a" << BSON_ARRAY(1 << BSON("2x4" << 2) << BSON("NOT THIS ONE" << 3))); + + BSONElementSet actualElements; + const bool expandArrayOnTrailingField = true; + std::set<size_t> actualArrayComponents; + dps::extractAllElementsAlongPath( + obj, "a.2x4", actualElements, expandArrayOnTrailingField, &actualArrayComponents); + + assertBSONElementSetsAreEqual({BSON("" << 2)}, actualElements); + assertArrayComponentsAreEqual({0U}, actualArrayComponents); +} + +TEST(ExtractAllElementsAlongPath, + DoesExtractNestedValuesFromWithinArraysTraversedWithPositionalPaths) { + BSONObj obj = BSON("a" << BSON_ARRAY(1 << BSON("2" << 2) << BSON("target" << 3))); + + BSONElementSet actualElements; + const bool expandArrayOnTrailingField = true; + std::set<size_t> actualArrayComponents; + dps::extractAllElementsAlongPath( + obj, "a.2.target", actualElements, expandArrayOnTrailingField, &actualArrayComponents); + + assertBSONElementSetsAreEqual({BSON("" << 3)}, actualElements); + assertArrayComponentsAreEqual(std::set<size_t>{}, actualArrayComponents); +} + +TEST(ExtractAllElementsAlongPath, DoesExpandMultiplePositionalPathSpecifications) { + BSONObj obj(fromjson("{a: [[{b: '(0, 0)'}, {b: '(0, 1)'}], [{b: '(1, 0)'}, {b: '(1, 1)'}]]}")); + + BSONElementSet actualElements; + const bool expandArrayOnTrailingField = true; + std::set<size_t> actualArrayComponents; + dps::extractAllElementsAlongPath( + obj, "a.1.0.b", actualElements, expandArrayOnTrailingField, &actualArrayComponents); + + assertBSONElementSetsAreEqual({BSON("" + << "(1, 0)")}, + actualElements); + assertArrayComponentsAreEqual(std::set<size_t>{}, actualArrayComponents); +} + +TEST(ExtractAllElementsAlongPath, DoesAcceptNumericInitialField) { + BSONObj obj = BSON("a" << 1 << "0" << 2); + + BSONElementSet actualElements; + const bool expandArrayOnTrailingField = true; + std::set<size_t> actualArrayComponents; + dps::extractAllElementsAlongPath( + obj, "0", actualElements, expandArrayOnTrailingField, &actualArrayComponents); + + assertBSONElementSetsAreEqual({BSON("" << 2)}, actualElements); + assertArrayComponentsAreEqual(std::set<size_t>{}, actualArrayComponents); +} + +TEST(ExtractAllElementsAlongPath, DoesExpandArrayFoundAfterPositionalSpecification) { + BSONObj obj(fromjson("{a: [[{b: '(0, 0)'}, {b: '(0, 1)'}], [{b: '(1, 0)'}, {b: '(1, 1)'}]]}")); + + BSONElementSet actualElements; + const bool expandArrayOnTrailingField = true; + std::set<size_t> actualArrayComponents; + dps::extractAllElementsAlongPath( + obj, "a.1.b", actualElements, expandArrayOnTrailingField, &actualArrayComponents); + + assertBSONElementSetsAreEqual({BSON("" + << "(1, 0)"), + BSON("" + << "(1, 1)")}, + actualElements); + assertArrayComponentsAreEqual({1U}, actualArrayComponents); +} + } // namespace } // namespace mongo |