diff --git a/src/lib/diff/gen-node.cpp b/src/lib/diff/gen-node.cpp index f20985686..317a9234d 100644 --- a/src/lib/diff/gen-node.cpp +++ b/src/lib/diff/gen-node.cpp @@ -36,7 +36,7 @@ ** cases actually of interest. All other cases invoke the default handling, which ** returns \c false. ** - ** @see gen-node-basic-test.cpp + ** @see gen-node-test.cpp ** */ diff --git a/src/lib/diff/gen-node.hpp b/src/lib/diff/gen-node.hpp index 1e8a122c7..d8f376ab5 100644 --- a/src/lib/diff/gen-node.hpp +++ b/src/lib/diff/gen-node.hpp @@ -92,7 +92,7 @@ ** To begin with, for the task of diff detection and application, it is sufficient ** to get the children as traversable collection and to offer a depth-first expansion. ** - ** @see GenNodeBasic_test + ** @see GenNode_test ** @see diff-list-generation-test.cpp ** @see DiffDetector ** diff --git a/src/lib/diff/record.hpp b/src/lib/diff/record.hpp index f00ae35a8..3c95dc1e1 100644 --- a/src/lib/diff/record.hpp +++ b/src/lib/diff/record.hpp @@ -82,7 +82,7 @@ ** of Record entities as tree nodes within a GenNode monad, such a ** more elaborate approach was deemed unnecessary for the time being. ** - ** @see GenericRecordRepresentation_test + ** @see GenericRecord_test ** */ diff --git a/src/lib/diff/tree-diff-application.hpp b/src/lib/diff/tree-diff-application.hpp index 336df1888..2c3b19741 100644 --- a/src/lib/diff/tree-diff-application.hpp +++ b/src/lib/diff/tree-diff-application.hpp @@ -124,7 +124,7 @@ ** @see DiffTreeApplication_test ** @see DiffComplexApplication_test ** @see DiffListApplication_test - ** @see GenNodeBasic_test + ** @see GenNode_test ** @see tree-diff.hpp ** */ diff --git a/src/lib/diff/tree-diff-traits.hpp b/src/lib/diff/tree-diff-traits.hpp index 838aa10d5..302b5b67b 100644 --- a/src/lib/diff/tree-diff-traits.hpp +++ b/src/lib/diff/tree-diff-traits.hpp @@ -29,7 +29,7 @@ ** In a nutshell, if some private data structure wants to receive ** mutation diff messages... ** - it must either implement the interface DiffMutable - ** - or provide the function point `void buildMutator(TreeMutator::Handle)` + ** - or provide the extension point `void buildMutator(TreeMutator::Handle)` ** Additionally, when the size of the custom TreeMutator object exceeds some ** hard wired limit (200 bytes), then the target type also needs to define ** the extension point `size_t treeMutatorSize(TargetType)` @@ -41,7 +41,7 @@ ** @see DiffComplexApplication_test ** @see DiffTreeApplication_test ** @see DiffListApplication_test - ** @see GenNodeBasic_test + ** @see GenNode_test ** @see tree-diff.hpp ** */ diff --git a/src/lib/diff/tree-mutator-collection-binding.hpp b/src/lib/diff/tree-mutator-collection-binding.hpp index c7d9eabbe..06dc6fd37 100644 --- a/src/lib/diff/tree-mutator-collection-binding.hpp +++ b/src/lib/diff/tree-mutator-collection-binding.hpp @@ -31,9 +31,9 @@ ** Each concrete TreeMutator instance will be configured differently, and this ** adaptation is done by implementing binding templates, in the way of building ** blocks, attached and customised through lambdas. It is possible to layer - ** several bindings on top of a single TreeMutator -- and this header defines - ** a building block for one such layer, especially for binding to a representation - ** of "child objects" managed within a typical STL container. + ** several bindings on top of a single TreeMutator -- and especially this header + ** defines a building block for one such layer, especially for binding to a + ** representation of "child objects" managed within a typical STL container. ** ** As a _special case_, binding to a STL map is supported, while this usage is rather ** discouraged, since it contradicts the diff semantics due to intrinsic ordering. @@ -398,7 +398,7 @@ namespace diff{ binding_.inject (move(*pos_)); ++pos_; } - if (binding_.matches (spec, *pos_)) + if (pos_ and binding_.matches (spec, *pos_)) { binding_.inject (move(*pos_)); ++pos_; @@ -681,7 +681,7 @@ namespace diff{ * This function shall be used right within Builder::attach() * and wrap a language reference to the concrete collection * implementing the "object children". The result is a default configured - * binding, which should be further adapted with the builder functions, + * binding, which could be further adapted with the builder functions, * using lambdas as callback into the otherwise opaque implementation code. */ template diff --git a/src/lib/diff/tree-mutator.hpp b/src/lib/diff/tree-mutator.hpp index 17ce59b5d..719f5c8ff 100644 --- a/src/lib/diff/tree-mutator.hpp +++ b/src/lib/diff/tree-mutator.hpp @@ -400,8 +400,8 @@ namespace diff{ * allows to limit applicability of this whole binding (layer) to only some * diff specs. E.g., we may set up a binding for elements with value semantics * and another binding layer on top to deal with object like children (sub scopes). - * Please note that this selector also gets to judge the Ref::ATTRIBS spec, which - * means this layer's contents can be considered "attributes". + * Please note that this selector also gets to judge upon the Ref::ATTRIBS spec, + * which indicates if this layer's contents can be considered "attributes". * - the optional _setter closure_ (CollectionBindingBuilder::assignElement) accepts * a diff spec (GenNode) and should assign an equivalent value to the internal * data representation of the corresponding element (typically by constructing diff --git a/tests/15library.tests b/tests/15library.tests index d5a87508b..f351002a1 100644 --- a/tests/15library.tests +++ b/tests/15library.tests @@ -343,7 +343,7 @@ return: 0 END -TEST "Generic Object Record" GenericRecordRepresentation_test <».+«string».eggs.+«string».spam.+«string».spam diff --git a/tests/library/diff/diff-complex-application-test.cpp b/tests/library/diff/diff-complex-application-test.cpp index f0c0f1f0f..d3db25756 100644 --- a/tests/library/diff/diff-complex-application-test.cpp +++ b/tests/library/diff/diff-complex-application-test.cpp @@ -23,9 +23,10 @@ /** @file diff-complex-application-test.cpp ** unit test \ref DiffComplexApplication_test. ** Demonstrates the concept of tree mutation by diff messages. - ** This is an elaborate demonstration setup to highlight some - ** of the more intricate, the flexibility and support for - ** and complex opaque implementation variations. + ** This is an elaborate demonstration setup to show how a binding + ** is setup in practice and to highlight some of the more intricate + ** implementation corner cases, allowing for much flexibility when + ** binding to otherwise opaque target data structures. */ diff --git a/tests/library/diff/diff-tree-application-simple-test.cpp b/tests/library/diff/diff-tree-application-simple-test.cpp new file mode 100644 index 000000000..792639b85 --- /dev/null +++ b/tests/library/diff/diff-tree-application-simple-test.cpp @@ -0,0 +1,151 @@ +/* + DiffTreeApplicationSimple(Test) - demonstrate the basics of tree diff representation + + Copyright (C) Lumiera.org + 2019, Hermann Vosseler + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of + the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +* *****************************************************/ + +/** @file diff-tree-application-simple-test.cpp + ** unit test \ref DiffTreeApplicationSimple_test. + ** Demonstrates the basic concept of reshaping structured data + ** through a tree-diff sequence. + */ + + +#include "lib/test/run.hpp" +#include "lib/format-util.hpp" +#include "lib/diff/mutation-message.hpp" +#include "lib/diff/tree-diff-application.hpp" +#include "lib/format-util.hpp" +#include "lib/format-cout.hpp" +#include "lib/util.hpp" + +#include +#include + +//using util::isnil; +using std::string; +using std::vector; + + +namespace lib { +namespace diff{ +namespace test{ + + namespace {//Test fixture.... + + // some symbolic values to be used within the diff + const GenNode VAL_A("a"), + VAL_B("b"), + VAL_C("c"), + VAL_D("d"); + + /** render the child elements as string data for test/verification */ + string + contents (Rec const& object) + { + return util::join (transformIterator (object.scope() + ,[](GenNode const& n) { return n.data.get(); } + )); + } + }//(End)Test fixture + + + + + + + + + + /****************************************************************************//** + * @test Demonstration/Concept: apply a "tree diff" to reshape structured data. + * - the demo_one() constructs a "GenNode object", + * which is then mutated by applying a diff. + * - the demo_two() uses a STL collection (vector) as _opaque data structure,_ + * establishes a _diff binding_ to that structure and then applies basically + * the same diff to mutate the target data. + * @remarks This test is meant as introductory example to explain the meaning of + * the terms "diff", "diff verbs", "application", "mutation", "target data" + * and thus to show the basic ideas of Lumiera's »Diff Framework«. As can be + * expected, these examples are somewhat artificial and everything is made + * up as to look simple, while deliberately a lot of technical intricacies + * will be swept under the carpet. + * @see DiffTreeApplication_test extended demonstration of possible diff operations + * @see DiffComplexApplication_test handling arbitrary data structures + * @see GenericRecord_test + * @see GenNode_test + * @see DiffListApplication_test + * @see diff-tree-application.hpp + * @see tree-diff.hpp + * @see tree-diff-traits.hpp + */ + class DiffTreeApplicationSimple_test + : public Test + , TreeDiffLanguage + { + + virtual void + run (Arg) + { + demo_one(); +// demo_two(); + } + + /** + * a change represented symbolically as »diff sequence«. + * This is a sequence of _verbs_ to describe what should be done + * in order to mutate the target data. This example can be read as + * - first accept an existing element "a" as-is + * - after that insert a new element "d" into the sequence + * - next delete an existing element "b" from the sequence + * - and finally accept an existing element "c" into the result + */ + MutationMessage + someDiff() + { + return { pick(VAL_A) + , ins (VAL_D) + , del (VAL_B) + , pick(VAL_C) + }; + } + + + /** @test mutate a Record by applying a the sample diff */ + void + demo_one() + { + Rec::Mutator subject; + subject.scope(VAL_A, VAL_B, VAL_C); + + CHECK ("a, b, c" == contents(subject)); + + DiffApplicator{subject}.consume (someDiff()); + + CHECK ("a, d, c" == contents(subject)); + } + }; + + + /** Register this test class... */ + LAUNCHER (DiffTreeApplicationSimple_test, "unit common"); + + + +}}} // namespace lib::diff::test diff --git a/tests/library/diff/diff-tree-application-test.cpp b/tests/library/diff/diff-tree-application-test.cpp index f118994f5..385283213 100644 --- a/tests/library/diff/diff-tree-application-test.cpp +++ b/tests/library/diff/diff-tree-application-test.cpp @@ -1,5 +1,5 @@ /* - DiffTreeApplication(Test) - demonstrate the basics of tree diff representation + DiffTreeApplication(Test) - demonstrate the main features of tree diff representation Copyright (C) Lumiera.org 2015, Hermann Vosseler @@ -22,8 +22,11 @@ /** @file diff-tree-application-test.cpp ** unit test \ref DiffTreeApplication_test. - ** Demonstrates the basic concept of reshaping structured data - ** through a tree-diff sequence. + ** Demonstrates the most relevant operations for reshaping structured data + ** through a tree-diff sequence. Here, we use a lib::diff:Record + ** as target data, and the test focuses on demonstrating the possible operations. + ** @see [Introductory demonstration](\ref diff-tree-application-simple-test.cpp) + ** @see [More complex setup with opaque data](\ref diff-complex-application-test.cpp) */ @@ -89,19 +92,20 @@ namespace test{ * and a nested child-Record. * - the second step demonstrates various diff language constructs * to alter, reshape and mutate this data structure - * After applying those two diff sequences, we verify the data - * is indeed in the expected shape. + * After applying those two diff sequences, we verify that + * the mutated data is indeed in the reordered shape. * @remarks to follow this test, you should be familiar both with our * [generic data record](\ref diff::Record), as well as with the * [variant data node](\ref diff::GenNode). The key point to note * is the usage of Record elements as payload within GenNode, which - * allows to represent tree shaped object like data structures. + * allows to represent tree shaped object-like data structures. * @note literally the same test case is repeated in MutationMessage_test, * just there the diff is transported in a MutationMessage capsule, - * as is the case in the real application as well. + * as would be the case in the real application. * @see DiffComplexApplication_test handling arbitrary data structures - * @see GenericRecordRepresentation_test - * @see GenNodeBasic_test + * @see DiffTreeApplicationSimple_test introductory example demonstration + * @see GenericRecord_test + * @see GenNode_test * @see DiffListApplication_test * @see diff-tree-application.hpp * @see tree-diff.hpp diff --git a/tests/library/diff/gen-node-basic-test.cpp b/tests/library/diff/gen-node-test.cpp similarity index 99% rename from tests/library/diff/gen-node-basic-test.cpp rename to tests/library/diff/gen-node-test.cpp index 5967d656b..e2bd853d1 100644 --- a/tests/library/diff/gen-node-basic-test.cpp +++ b/tests/library/diff/gen-node-test.cpp @@ -1,5 +1,5 @@ /* - GenNodeBasic(Test) - fundamental properties of a generic tree node element + GenNode(Test) - fundamental properties of a generic tree node element Copyright (C) Lumiera.org 2015, Hermann Vosseler @@ -20,8 +20,8 @@ * *****************************************************/ -/** @file gen-node-basic-test.cpp - ** unit test \ref GenNodeBasic_test +/** @file gen-node-test.cpp + ** unit test \ref GenNode_test */ @@ -88,7 +88,7 @@ namespace test{ * @see IndexTable * @see DiffListApplication_test */ - class GenNodeBasic_test : public Test + class GenNode_test : public Test { virtual void @@ -951,7 +951,7 @@ namespace test{ /** Register this test class... */ - LAUNCHER (GenNodeBasic_test, "unit common"); + LAUNCHER (GenNode_test, "unit common"); diff --git a/tests/library/diff/generic-record-representation-test.cpp b/tests/library/diff/generic-record-test.cpp similarity index 97% rename from tests/library/diff/generic-record-representation-test.cpp rename to tests/library/diff/generic-record-test.cpp index 02f8ddc6a..632c78cb6 100644 --- a/tests/library/diff/generic-record-representation-test.cpp +++ b/tests/library/diff/generic-record-test.cpp @@ -1,5 +1,5 @@ /* - GenericRecordRepresentation(Test) - introspective representation of object-like data + GenericRecord(Test) - introspective representation of object-like data Copyright (C) Lumiera.org 2015, Hermann Vosseler @@ -20,8 +20,8 @@ * *****************************************************/ -/** @file generic-record-representation-test.cpp - ** unit test \ref GenericRecordRepresentation_test +/** @file generic-record-test.cpp + ** unit test \ref GenericRecord_test */ @@ -121,10 +121,10 @@ namespace test{ * do not normalise the content in any way; content is meant to reflect * other data structures, which are normalised and maintained by their owner. * - * @see GenNodeBasic_test + * @see GenNode_test * @see tree-diff.cpp */ - class GenericRecordRepresentation_test : public Test + class GenericRecord_test : public Test { virtual void @@ -375,7 +375,7 @@ namespace test{ /** Register this test class... */ - LAUNCHER (GenericRecordRepresentation_test, "unit common"); + LAUNCHER (GenericRecord_test, "unit common"); diff --git a/tests/library/diff/tree-mutator-binding-test.cpp b/tests/library/diff/tree-mutator-binding-test.cpp index 8059810b8..b3e224d4b 100644 --- a/tests/library/diff/tree-mutator-binding-test.cpp +++ b/tests/library/diff/tree-mutator-binding-test.cpp @@ -148,7 +148,7 @@ namespace test{ * @see TreeMutator * @see TreeMutator_test * @see DiffTreeApplication_test - * @see GenNodeBasic_test + * @see GenNode_test * @see AbstractTangible_test::mutate() */ class TreeMutatorBinding_test : public Test diff --git a/tests/library/diff/tree-mutator-test.cpp b/tests/library/diff/tree-mutator-test.cpp index a6ca65d11..5fc99bef4 100644 --- a/tests/library/diff/tree-mutator-test.cpp +++ b/tests/library/diff/tree-mutator-test.cpp @@ -62,8 +62,8 @@ namespace test{ * * @see TreeMutator * @see DiffComplexApplication_test a way more complex usage scenario - * @see GenNodeBasic_test - * @see GenericRecordRepresentation_test + * @see GenNode_test + * @see GenericRecord_test */ class TreeMutator_test : public Test { diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 524c2a04b..c380c4206 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -19576,6 +19576,9 @@ + + + @@ -21635,6 +21638,9 @@ + + + @@ -39360,11 +39366,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -40389,7 +40421,7 @@ - +