diff options
Diffstat (limited to 'src/mongo/db/ops/modifier_unset_test.cpp')
-rw-r--r-- | src/mongo/db/ops/modifier_unset_test.cpp | 628 |
1 files changed, 315 insertions, 313 deletions
diff --git a/src/mongo/db/ops/modifier_unset_test.cpp b/src/mongo/db/ops/modifier_unset_test.cpp index 3ca4957e94c..d68f471c7e7 100644 --- a/src/mongo/db/ops/modifier_unset_test.cpp +++ b/src/mongo/db/ops/modifier_unset_test.cpp @@ -42,410 +42,412 @@ namespace { - using mongo::Array; - using mongo::BSONObj; - using mongo::fromjson; - using mongo::LogBuilder; - using mongo::ModifierInterface; - using mongo::ModifierUnset; - using mongo::Status; - using mongo::StringData; - using mongo::mutablebson::Document; - using mongo::mutablebson::Element; - - /** Helper to build and manipulate a $set mod. */ - class Mod { - public: - Mod() : _mod() {} - - explicit Mod(BSONObj modObj) { - _modObj = modObj; - ASSERT_OK(_mod.init(_modObj["$unset"].embeddedObject().firstElement(), - ModifierInterface::Options::normal())); - } - - Status prepare(Element root, - StringData matchedField, - ModifierInterface::ExecInfo* execInfo) { - return _mod.prepare(root, matchedField, execInfo); - } - - Status apply() const { - return _mod.apply(); - } - - Status log(LogBuilder* logBuilder) const { - return _mod.log(logBuilder); - } - - ModifierUnset& mod() { return _mod; } - - BSONObj modObj() { return _modObj; } - - private: - ModifierUnset _mod; - BSONObj _modObj; - }; - - // - // Simple mod - // - - TEST(SimpleMod, PrepareNoOp) { - Document doc(fromjson("{}")); - Mod modUnset(fromjson("{$unset: {a: true}}")); - - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); - - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a"); - ASSERT_TRUE(execInfo.noOp); +using mongo::Array; +using mongo::BSONObj; +using mongo::fromjson; +using mongo::LogBuilder; +using mongo::ModifierInterface; +using mongo::ModifierUnset; +using mongo::Status; +using mongo::StringData; +using mongo::mutablebson::Document; +using mongo::mutablebson::Element; + +/** Helper to build and manipulate a $set mod. */ +class Mod { +public: + Mod() : _mod() {} + + explicit Mod(BSONObj modObj) { + _modObj = modObj; + ASSERT_OK(_mod.init(_modObj["$unset"].embeddedObject().firstElement(), + ModifierInterface::Options::normal())); } - TEST(SimpleMod, PrepareApplyNormal) { - Document doc(fromjson("{a: 1, b: 2}")); - Mod modUnset(fromjson("{$unset: {a: true}}")); + Status prepare(Element root, StringData matchedField, ModifierInterface::ExecInfo* execInfo) { + return _mod.prepare(root, matchedField, execInfo); + } - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); + Status apply() const { + return _mod.apply(); + } - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a"); - ASSERT_FALSE(execInfo.noOp); + Status log(LogBuilder* logBuilder) const { + return _mod.log(logBuilder); + } - ASSERT_OK(modUnset.apply()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); - ASSERT_EQUALS(fromjson("{b: 2}"), doc); + ModifierUnset& mod() { + return _mod; } - TEST(SimpleMod, PrepareApplyInPlace) { - Document doc(fromjson("{x: 0, a: 1}")); - Mod modUnset(fromjson("{$unset: {a: true}}")); + BSONObj modObj() { + return _modObj; + } - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); +private: + ModifierUnset _mod; + BSONObj _modObj; +}; - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a"); - ASSERT_FALSE(execInfo.noOp); +// +// Simple mod +// - ASSERT_OK(modUnset.apply()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); // TODO turn in-place on for this. - ASSERT_EQUALS(fromjson("{x: 0}"), doc); - } +TEST(SimpleMod, PrepareNoOp) { + Document doc(fromjson("{}")); + Mod modUnset(fromjson("{$unset: {a: true}}")); - TEST(SimpleMod, PrepareApplyGeneratesEmptyDocument) { - Document doc(fromjson("{a: 1}")); - Mod modUnset(fromjson("{$unset: {a: true}}")); + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); + ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a"); + ASSERT_TRUE(execInfo.noOp); +} - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a"); - ASSERT_FALSE(execInfo.noOp); +TEST(SimpleMod, PrepareApplyNormal) { + Document doc(fromjson("{a: 1, b: 2}")); + Mod modUnset(fromjson("{$unset: {a: true}}")); - ASSERT_OK(modUnset.apply()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); // TODO turn in-place on for this. - ASSERT_EQUALS(fromjson("{}"), doc); - } + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); - TEST(SimpleMod, PrepareApplyUnsetSubtree) { - Document doc(fromjson("{a: {b: 1}, c: 2}")); - Mod modUnset(fromjson("{$unset: {a: true}}")); + ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a"); + ASSERT_FALSE(execInfo.noOp); - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); + ASSERT_OK(modUnset.apply()); + ASSERT_FALSE(doc.isInPlaceModeEnabled()); + ASSERT_EQUALS(fromjson("{b: 2}"), doc); +} - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a"); - ASSERT_FALSE(execInfo.noOp); +TEST(SimpleMod, PrepareApplyInPlace) { + Document doc(fromjson("{x: 0, a: 1}")); + Mod modUnset(fromjson("{$unset: {a: true}}")); - ASSERT_OK(modUnset.apply()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); - ASSERT_EQUALS(fromjson("{c: 2}"), doc); - } + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); - TEST(SimpleMod, LogNormal) { - BSONObj obj = fromjson("{a: 1}"); - Document doc(obj); - Mod modUnset(fromjson("{$unset: {a: true}}")); + ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a"); + ASSERT_FALSE(execInfo.noOp); - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); + ASSERT_OK(modUnset.apply()); + ASSERT_FALSE(doc.isInPlaceModeEnabled()); // TODO turn in-place on for this. + ASSERT_EQUALS(fromjson("{x: 0}"), doc); +} - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a"); - ASSERT_FALSE(execInfo.noOp); +TEST(SimpleMod, PrepareApplyGeneratesEmptyDocument) { + Document doc(fromjson("{a: 1}")); + Mod modUnset(fromjson("{$unset: {a: true}}")); - Document logDoc; - LogBuilder logBuilder(logDoc.root()); - ASSERT_OK(modUnset.log(&logBuilder)); - ASSERT_EQUALS(modUnset.modObj(), logDoc); - } + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); - // - // Dotted mod - // + ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a"); + ASSERT_FALSE(execInfo.noOp); - TEST(DottedMod, PrepareNoOp) { - Document doc(fromjson("{c:2}")); - Mod modUnset(fromjson("{$unset: {'a.b': true}}")); + ASSERT_OK(modUnset.apply()); + ASSERT_FALSE(doc.isInPlaceModeEnabled()); // TODO turn in-place on for this. + ASSERT_EQUALS(fromjson("{}"), doc); +} - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); +TEST(SimpleMod, PrepareApplyUnsetSubtree) { + Document doc(fromjson("{a: {b: 1}, c: 2}")); + Mod modUnset(fromjson("{$unset: {a: true}}")); - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.b"); - ASSERT_TRUE(execInfo.noOp); - } + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); - TEST(DottedMod, PrepareApplyNormal) { - Document doc(fromjson("{a: {b: 1}, c: 2}")); - Mod modUnset(fromjson("{$unset: {'a.b': true}}")); + ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a"); + ASSERT_FALSE(execInfo.noOp); - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); + ASSERT_OK(modUnset.apply()); + ASSERT_FALSE(doc.isInPlaceModeEnabled()); + ASSERT_EQUALS(fromjson("{c: 2}"), doc); +} - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.b"); - ASSERT_FALSE(execInfo.noOp); +TEST(SimpleMod, LogNormal) { + BSONObj obj = fromjson("{a: 1}"); + Document doc(obj); + Mod modUnset(fromjson("{$unset: {a: true}}")); - ASSERT_OK(modUnset.apply()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); - ASSERT_EQUALS(fromjson("{a:{}, c:2}"), doc); - } + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); - TEST(DottedMod, PrepareApplyInPlace) { - Document doc(fromjson("{x: 0, a: {b: 1}}")); - Mod modUnset(fromjson("{$unset: {'a.b': true}}")); + ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a"); + ASSERT_FALSE(execInfo.noOp); - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); + Document logDoc; + LogBuilder logBuilder(logDoc.root()); + ASSERT_OK(modUnset.log(&logBuilder)); + ASSERT_EQUALS(modUnset.modObj(), logDoc); +} - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.b"); - ASSERT_FALSE(execInfo.noOp); +// +// Dotted mod +// - ASSERT_OK(modUnset.apply()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); // TODO turn in-place on for this. - ASSERT_EQUALS(fromjson("{x: 0, a:{}}"), doc); - } +TEST(DottedMod, PrepareNoOp) { + Document doc(fromjson("{c:2}")); + Mod modUnset(fromjson("{$unset: {'a.b': true}}")); - TEST(DottedMod, PrepareApplyUnsetNestedSubobject) { - Document doc(fromjson("{a: {b: {c: 1}}}")); - Mod modUnset(fromjson("{$unset: {'a.b': true}}")); + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); + ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.b"); + ASSERT_TRUE(execInfo.noOp); +} - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.b"); - ASSERT_FALSE(execInfo.noOp); +TEST(DottedMod, PrepareApplyNormal) { + Document doc(fromjson("{a: {b: 1}, c: 2}")); + Mod modUnset(fromjson("{$unset: {'a.b': true}}")); - ASSERT_OK(modUnset.apply()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); // TODO turn in-place on for this. - ASSERT_EQUALS(fromjson("{a: {}}"), doc); - } + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); - // - // Indexed mod - // + ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.b"); + ASSERT_FALSE(execInfo.noOp); - TEST(IndexedMod, PrepareNoOp) { - Document doc(fromjson("{a:[]}")); - Mod modUnset(fromjson("{$unset: {'a.0': true}}")); + ASSERT_OK(modUnset.apply()); + ASSERT_FALSE(doc.isInPlaceModeEnabled()); + ASSERT_EQUALS(fromjson("{a:{}, c:2}"), doc); +} - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); +TEST(DottedMod, PrepareApplyInPlace) { + Document doc(fromjson("{x: 0, a: {b: 1}}")); + Mod modUnset(fromjson("{$unset: {'a.b': true}}")); - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.0"); - ASSERT_TRUE(execInfo.noOp); - } + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); - TEST(IndexedMod, PrepareApplyNormal) { - Document doc(fromjson("{a:[0,1,2]}")); - Mod modUnset(fromjson("{$unset: {'a.0': true}}")); + ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.b"); + ASSERT_FALSE(execInfo.noOp); - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); + ASSERT_OK(modUnset.apply()); + ASSERT_FALSE(doc.isInPlaceModeEnabled()); // TODO turn in-place on for this. + ASSERT_EQUALS(fromjson("{x: 0, a:{}}"), doc); +} - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.0"); - ASSERT_FALSE(execInfo.noOp); +TEST(DottedMod, PrepareApplyUnsetNestedSubobject) { + Document doc(fromjson("{a: {b: {c: 1}}}")); + Mod modUnset(fromjson("{$unset: {'a.b': true}}")); - ASSERT_OK(modUnset.apply()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); - ASSERT_EQUALS(fromjson("{a:[null,1,2]}"), doc); - } + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); - TEST(IndexedMod, PrepareApplyInPlace) { - Document doc(fromjson("{b:1, a:[1]}")); - Mod modUnset(fromjson("{$unset: {'a.0': true}}")); + ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.b"); + ASSERT_FALSE(execInfo.noOp); - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); + ASSERT_OK(modUnset.apply()); + ASSERT_FALSE(doc.isInPlaceModeEnabled()); // TODO turn in-place on for this. + ASSERT_EQUALS(fromjson("{a: {}}"), doc); +} - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.0"); - ASSERT_FALSE(execInfo.noOp); +// +// Indexed mod +// - ASSERT_OK(modUnset.apply()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); // TODO turn in-place on for this. - ASSERT_EQUALS(fromjson("{b:1, a:[null]}"), doc); - } +TEST(IndexedMod, PrepareNoOp) { + Document doc(fromjson("{a:[]}")); + Mod modUnset(fromjson("{$unset: {'a.0': true}}")); - TEST(IndexedMod, PrepareApplyInPlaceNuance) { - // Can't change the encoding in the middle of a bson stream. - Document doc(fromjson("{a:[1], b:1}")); - Mod modUnset(fromjson("{$unset: {'a.0': true}}")); + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); + ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.0"); + ASSERT_TRUE(execInfo.noOp); +} - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.0"); - ASSERT_FALSE(execInfo.noOp); +TEST(IndexedMod, PrepareApplyNormal) { + Document doc(fromjson("{a:[0,1,2]}")); + Mod modUnset(fromjson("{$unset: {'a.0': true}}")); - ASSERT_OK(modUnset.apply()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); - ASSERT_EQUALS(fromjson("{a:[null], b:1}"), doc); - } + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); - TEST(IndexedMod, PrepareApplyInnerObject) { - Document doc(fromjson("{a:[{b:1}]}")); - Mod modUnset(fromjson("{$unset: {'a.0.b': true}}")); + ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.0"); + ASSERT_FALSE(execInfo.noOp); - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); + ASSERT_OK(modUnset.apply()); + ASSERT_FALSE(doc.isInPlaceModeEnabled()); + ASSERT_EQUALS(fromjson("{a:[null,1,2]}"), doc); +} - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.0.b"); - ASSERT_FALSE(execInfo.noOp); +TEST(IndexedMod, PrepareApplyInPlace) { + Document doc(fromjson("{b:1, a:[1]}")); + Mod modUnset(fromjson("{$unset: {'a.0': true}}")); - ASSERT_OK(modUnset.apply()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); - ASSERT_EQUALS(fromjson("{a:[{}]}"), doc); - } + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); - TEST(IndexedMod, PrepareApplyObject) { - Document doc(fromjson("{a:[{b:1}]}")); - Mod modUnset(fromjson("{$unset: {'a.0': true}}")); + ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.0"); + ASSERT_FALSE(execInfo.noOp); - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); + ASSERT_OK(modUnset.apply()); + ASSERT_FALSE(doc.isInPlaceModeEnabled()); // TODO turn in-place on for this. + ASSERT_EQUALS(fromjson("{b:1, a:[null]}"), doc); +} - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.0"); - ASSERT_FALSE(execInfo.noOp); +TEST(IndexedMod, PrepareApplyInPlaceNuance) { + // Can't change the encoding in the middle of a bson stream. + Document doc(fromjson("{a:[1], b:1}")); + Mod modUnset(fromjson("{$unset: {'a.0': true}}")); - ASSERT_OK(modUnset.apply()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); - ASSERT_EQUALS(fromjson("{a:[null]}"), doc); - } + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); - TEST(IndexedMod, LogNormal) { - Document doc(fromjson("{a:[0,1,2]}")); - Mod modUnset(fromjson("{$unset: {'a.0': true}}")); + ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.0"); + ASSERT_FALSE(execInfo.noOp); - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); + ASSERT_OK(modUnset.apply()); + ASSERT_FALSE(doc.isInPlaceModeEnabled()); + ASSERT_EQUALS(fromjson("{a:[null], b:1}"), doc); +} - Document logDoc; - LogBuilder logBuilder(logDoc.root()); - ASSERT_OK(modUnset.log(&logBuilder)); - ASSERT_EQUALS(modUnset.modObj(), logDoc); - } +TEST(IndexedMod, PrepareApplyInnerObject) { + Document doc(fromjson("{a:[{b:1}]}")); + Mod modUnset(fromjson("{$unset: {'a.0.b': true}}")); - // - // Positional mod - // + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); - TEST(PositionalMod, PrepareNoOp) { - Document doc(fromjson("{a:[{b:0}]}")); - Mod modUnset(fromjson("{$unset: {'a.$.b': true}}")); + ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.0.b"); + ASSERT_FALSE(execInfo.noOp); - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "1", &execInfo)); + ASSERT_OK(modUnset.apply()); + ASSERT_FALSE(doc.isInPlaceModeEnabled()); + ASSERT_EQUALS(fromjson("{a:[{}]}"), doc); +} - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.1.b"); - ASSERT_TRUE(execInfo.noOp); - } +TEST(IndexedMod, PrepareApplyObject) { + Document doc(fromjson("{a:[{b:1}]}")); + Mod modUnset(fromjson("{$unset: {'a.0': true}}")); - TEST(PositionalMod, PrepareMissingPositional) { - Document doc(fromjson("{a:[{b:0},{c:1}]}")); - Mod modUnset(fromjson("{$unset: {'a.$.b': true}}")); + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); - ModifierInterface::ExecInfo execInfo; - ASSERT_NOT_OK(modUnset.prepare(doc.root(), "" /* no position */, &execInfo)); - } + ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.0"); + ASSERT_FALSE(execInfo.noOp); - TEST(PositionalMod, PrepareApplyNormal) { - Document doc(fromjson("{a:[{b:0},{c:1}]}")); - Mod modUnset(fromjson("{$unset: {'a.$.b': true}}")); + ASSERT_OK(modUnset.apply()); + ASSERT_FALSE(doc.isInPlaceModeEnabled()); + ASSERT_EQUALS(fromjson("{a:[null]}"), doc); +} - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "0", &execInfo)); +TEST(IndexedMod, LogNormal) { + Document doc(fromjson("{a:[0,1,2]}")); + Mod modUnset(fromjson("{$unset: {'a.0': true}}")); - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.0.b"); - ASSERT_FALSE(execInfo.noOp); + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "", &execInfo)); - ASSERT_OK(modUnset.apply()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); - ASSERT_EQUALS(fromjson("{a: [{}, {c:1}]}"), doc); - } + Document logDoc; + LogBuilder logBuilder(logDoc.root()); + ASSERT_OK(modUnset.log(&logBuilder)); + ASSERT_EQUALS(modUnset.modObj(), logDoc); +} - TEST(PositionalMod, PrepareApplyObject) { - Document doc(fromjson("{a:[{b:0},{c:1}]}")); - Mod modUnset(fromjson("{$unset: {'a.$': true}}")); +// +// Positional mod +// - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "0", &execInfo)); +TEST(PositionalMod, PrepareNoOp) { + Document doc(fromjson("{a:[{b:0}]}")); + Mod modUnset(fromjson("{$unset: {'a.$.b': true}}")); - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.0"); - ASSERT_FALSE(execInfo.noOp); + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "1", &execInfo)); - ASSERT_OK(modUnset.apply()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); - ASSERT_EQUALS(fromjson("{a: [null, {c:1}]}"), doc); - } + ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.1.b"); + ASSERT_TRUE(execInfo.noOp); +} - TEST(PositionalMod, PrepareApplyInPlace) { - Document doc(fromjson("{b:1, a:[{b:1}]}")); - Mod modUnset(fromjson("{$unset: {'a.$.b': true}}")); +TEST(PositionalMod, PrepareMissingPositional) { + Document doc(fromjson("{a:[{b:0},{c:1}]}")); + Mod modUnset(fromjson("{$unset: {'a.$.b': true}}")); - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "0", &execInfo)); + ModifierInterface::ExecInfo execInfo; + ASSERT_NOT_OK(modUnset.prepare(doc.root(), "" /* no position */, &execInfo)); +} - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.0.b"); - ASSERT_FALSE(execInfo.noOp); +TEST(PositionalMod, PrepareApplyNormal) { + Document doc(fromjson("{a:[{b:0},{c:1}]}")); + Mod modUnset(fromjson("{$unset: {'a.$.b': true}}")); - ASSERT_OK(modUnset.apply()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); // TODO turn in-place on for this. - ASSERT_EQUALS(fromjson("{b:1, a:[{}]}"), doc); - } + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "0", &execInfo)); - TEST(PositionalMod, LogNormal) { - Document doc(fromjson("{b:1, a:[{b:1}]}")); - Mod modUnset(fromjson("{$unset: {'a.$.b': true}}")); + ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.0.b"); + ASSERT_FALSE(execInfo.noOp); - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "0", &execInfo)); + ASSERT_OK(modUnset.apply()); + ASSERT_FALSE(doc.isInPlaceModeEnabled()); + ASSERT_EQUALS(fromjson("{a: [{}, {c:1}]}"), doc); +} - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.0.b"); - ASSERT_FALSE(execInfo.noOp); +TEST(PositionalMod, PrepareApplyObject) { + Document doc(fromjson("{a:[{b:0},{c:1}]}")); + Mod modUnset(fromjson("{$unset: {'a.$': true}}")); - Document logDoc; - LogBuilder logBuilder(logDoc.root()); - ASSERT_OK(modUnset.log(&logBuilder)); - ASSERT_EQUALS(fromjson("{$unset: {'a.0.b': true}}"), logDoc); - } + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "0", &execInfo)); - TEST(LegacyData, CanUnsetInvalidField) { - Document doc(fromjson("{b:1, a:[{$b:1}]}")); - Mod modUnset(fromjson("{$unset: {'a.$.$b': true}}")); + ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.0"); + ASSERT_FALSE(execInfo.noOp); - ModifierInterface::ExecInfo execInfo; - ASSERT_OK(modUnset.prepare(doc.root(), "0", &execInfo)); + ASSERT_OK(modUnset.apply()); + ASSERT_FALSE(doc.isInPlaceModeEnabled()); + ASSERT_EQUALS(fromjson("{a: [null, {c:1}]}"), doc); +} - ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.0.$b"); - ASSERT_FALSE(execInfo.noOp); +TEST(PositionalMod, PrepareApplyInPlace) { + Document doc(fromjson("{b:1, a:[{b:1}]}")); + Mod modUnset(fromjson("{$unset: {'a.$.b': true}}")); - ASSERT_OK(modUnset.apply()); - ASSERT_FALSE(doc.isInPlaceModeEnabled()); - ASSERT_EQUALS(fromjson("{b:1, a:[{}]}"), doc); + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "0", &execInfo)); - Document logDoc; - LogBuilder logBuilder(logDoc.root()); - ASSERT_OK(modUnset.log(&logBuilder)); - ASSERT_EQUALS(fromjson("{$unset: {'a.0.$b': true}}"), logDoc); - } + ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.0.b"); + ASSERT_FALSE(execInfo.noOp); + + ASSERT_OK(modUnset.apply()); + ASSERT_FALSE(doc.isInPlaceModeEnabled()); // TODO turn in-place on for this. + ASSERT_EQUALS(fromjson("{b:1, a:[{}]}"), doc); +} + +TEST(PositionalMod, LogNormal) { + Document doc(fromjson("{b:1, a:[{b:1}]}")); + Mod modUnset(fromjson("{$unset: {'a.$.b': true}}")); + + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "0", &execInfo)); + + ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.0.b"); + ASSERT_FALSE(execInfo.noOp); + + Document logDoc; + LogBuilder logBuilder(logDoc.root()); + ASSERT_OK(modUnset.log(&logBuilder)); + ASSERT_EQUALS(fromjson("{$unset: {'a.0.b': true}}"), logDoc); +} + +TEST(LegacyData, CanUnsetInvalidField) { + Document doc(fromjson("{b:1, a:[{$b:1}]}")); + Mod modUnset(fromjson("{$unset: {'a.$.$b': true}}")); + + ModifierInterface::ExecInfo execInfo; + ASSERT_OK(modUnset.prepare(doc.root(), "0", &execInfo)); + + ASSERT_EQUALS(execInfo.fieldRef[0]->dottedField(), "a.0.$b"); + ASSERT_FALSE(execInfo.noOp); + + ASSERT_OK(modUnset.apply()); + ASSERT_FALSE(doc.isInPlaceModeEnabled()); + ASSERT_EQUALS(fromjson("{b:1, a:[{}]}"), doc); + + Document logDoc; + LogBuilder logBuilder(logDoc.root()); + ASSERT_OK(modUnset.log(&logBuilder)); + ASSERT_EQUALS(fromjson("{$unset: {'a.0.$b': true}}"), logDoc); +} -} // unnamed namespace +} // unnamed namespace |