diff --git a/src/lib/diff/test-mutation-target.hpp b/src/lib/diff/test-mutation-target.hpp index b5626b98a..1890ea719 100644 --- a/src/lib/diff/test-mutation-target.hpp +++ b/src/lib/diff/test-mutation-target.hpp @@ -51,17 +51,15 @@ #include "lib/diff/record.hpp" #include "lib/diff/tree-mutator.hpp" #include "lib/idi/genfunc.hpp" +#include "lib/format-string.hpp" #include "lib/format-util.hpp" #include "lib/test/event-log.hpp" #include "lib/util.hpp" -//#include "lib/format-string.hpp" #include -//#include #include #include #include -//#include namespace lib { @@ -69,15 +67,15 @@ namespace diff{ namespace error = lumiera::error; -//using util::_Fmt; + using lib::Literal; using lib::test::EventLog; using lib::test::EventMatch; - using lib::Literal; using iter_stl::eachElm; using util::unConst; using util::isnil; using util::join; -// using std::function; + using util::_Fmt; + using std::string; using std::forward; using std::move; @@ -194,7 +192,11 @@ namespace diff{ /** * Test adapter to watch and verify how the * TreeMutator binds to custom tree data structures. - * @todo WIP 2/2016 + * As a data structure, the TestMutationTarget builds an + * »External Tree Description« reflecting the actual data structure, + * as can be inferred through listening to all handled diff mutation primitives. + * Besides, each of these primitives is recorded in the embedded \ref EventLog. + * @see TreeManipulationBinding_test::mutateDummy() */ class TestMutationTarget : boost::noncopyable @@ -263,6 +265,23 @@ namespace diff{ log_.event ("skipSrc", isnil(content.idi.getSym())? util::BOTTOM_INDICATOR : renderNode(content)); } + void + logAssignment (GenNode const& target, string oldPayload) + { + log_.event ("assignElm", _Fmt{"%s: %s ⤅ %s"} + % target.idi.getSym() + % oldPayload + % render(target.data)); + } + + void + logMutation (GenNode const& target) + { + log_.event ("mutateChild", _Fmt{"%s: start mutation...%s"} + % target.idi.getSym() + % render(target.data)); + } + /* === Diagnostic / Verification === */ @@ -327,9 +346,6 @@ namespace diff{ { return log_; } - - - private: }; @@ -443,13 +459,15 @@ namespace diff{ } /** locate element already accepted into the taget sequence - * and assigne the designated payload value to it. */ + * and assign the designated payload value to it. */ virtual bool assignElm (GenNode const& spec) { Iter targetElm = target_.locate (spec.idi); if (not targetElm) return false; + string logOldPayload{render(targetElm->data)}; *targetElm = spec; + target_.logAssignment (*targetElm, logOldPayload); return true; } @@ -458,8 +476,13 @@ namespace diff{ virtual bool mutateChild (GenNode const& spec, TreeMutator::MutatorBuffer targetBuff) { - UNIMPLEMENTED("locate and open sub mutator"); - return false; + Iter targetElm = target_.locate (spec.idi); + if (not targetElm) return false; + bool otherSuccessfulMutation = PAR::mutateChild (spec, targetBuff); + if (not otherSuccessfulMutation) // Test mode only -- + targetBuff.create (TreeMutator::build()); // no other layer was able to provide a mutator + target_.logMutation (*targetElm); + return true; } diff --git a/src/lib/diff/tree-mutator.hpp b/src/lib/diff/tree-mutator.hpp index 1c90ddb9f..dd1ba8ef6 100644 --- a/src/lib/diff/tree-mutator.hpp +++ b/src/lib/diff/tree-mutator.hpp @@ -110,9 +110,9 @@ namespace lib { { } - template + template BA& - create (ARGS&& ...args) + create (SUB&& subMutator) { if (sizeof(SUB) > maxSiz_) throw error::Fatal("Unable to implant implementation object of size " @@ -122,7 +122,7 @@ namespace lib { using Holder = InPlaceBuffer; Holder& holder = *static_cast (buffer_); - return holder.create (std::forward (args)...); + return holder.create (std::forward (subMutator)); } template diff --git a/tests/library/diff/tree-manipulation-binding-test.cpp b/tests/library/diff/tree-manipulation-binding-test.cpp index 111ecc51d..2da4084c4 100644 --- a/tests/library/diff/tree-manipulation-binding-test.cpp +++ b/tests/library/diff/tree-manipulation-binding-test.cpp @@ -226,16 +226,18 @@ namespace test{ CHECK (mutator3.acceptSrc (ATTRIB3)); // and accept the second copy of attribute γ CHECK (mutator3.matchSrc (SUB_NODE)); // this /would/ be the next source element, but... - CHECK (not contains(target.showContent(), "γ = 3.14159265")); + CHECK (not contains(target.showContent(), "γ = 3.1415927")); CHECK (mutator3.assignElm(GAMMA_PI)); // ...we assign a new payload to the current element first - CHECK ( contains(target.showContent(), "γ = 3.14159265")); + CHECK ( contains(target.showContent(), "γ = 3.1415927")); CHECK (mutator3.accept_until (Ref::END)); // fast forward, since we do not want to re-order anything + cout << "Content after assignment; " + << target.showContent() <