summaryrefslogtreecommitdiff
path: root/src/mongo/db/bson
diff options
context:
space:
mode:
authorCharlie Swanson <charlie.swanson@mongodb.com>2017-01-19 13:15:24 -0500
committerCharlie Swanson <charlie.swanson@mongodb.com>2017-01-20 15:35:14 -0500
commitd60dd07f3f470b702092b6b54e15586a5177d8a1 (patch)
treed98831d11a724d99ceccf9d8df6560399ba8b65b /src/mongo/db/bson
parent2c6c114e3952e952de1a395f987f1c5b83d209fe (diff)
downloadmongo-d60dd07f3f470b702092b6b54e15586a5177d8a1.tar.gz
SERVER-27437 Add dotted path expansion for Documents.
Diffstat (limited to 'src/mongo/db/bson')
-rw-r--r--src/mongo/db/bson/dotted_path_support_test.cpp212
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