tree-diff-application: unit test PASS
well... this was quite a piece of work Added some documentation, but a complete documentation, preferably to the website, would be desirable, as would be a more complete test covering the negative corner cases
This commit is contained in:
parent
eb829e6994
commit
34d79ee8df
5 changed files with 236 additions and 75 deletions
|
|
@ -40,16 +40,49 @@
|
|||
** a switch from scope to scope, which adds a lot of complexity. So the list diff
|
||||
** application strategy can be seen as blueprint and demonstration of principles.
|
||||
**
|
||||
** Another point in question is weather see the diff application as manipulating
|
||||
** a target data structure, or rather building a reshaped copy. The fact that
|
||||
** GenNode and Record are designed as immutable values seems to favour the latter,
|
||||
** yet the very reason to engage into building this diff framework was how to
|
||||
** handle partial updates within a expectedly very large UI model, reflecting
|
||||
** Another point in question is weather to treat the diff application as
|
||||
** manipulating a target data structure, or rather building a reshaped copy.
|
||||
** The fact that GenNode and Record are designed as immutable values seems to favour
|
||||
** the latter, yet the very reason to engage into building this diff framework was
|
||||
** how to handle partial updates within a expectedly very large UI model, reflecting
|
||||
** the actual session model in Proc-Layer. So we end up working on a Mutator,
|
||||
** which clearly signals we're going to reshape and re-rig the target data.
|
||||
**
|
||||
** @see diff-list-application-test.cpp
|
||||
** @see VerbToken
|
||||
** \par State and nested scopes
|
||||
** Within the level of a single #Record, our tree diff language works similar to
|
||||
** the list diff (with the addition of the \c after(ID) verb, which is just a
|
||||
** shortcut to accept parts of the contents unaltered). But after possibly rearranging
|
||||
** the contents of an "object" (Record), the diff might open some of its child "objects"
|
||||
** by entering a nested scope. This is done with the \c mut(ID)....emu(ID) bracketing
|
||||
** construct. On the implementation side, this means we need to use a stack somehow.
|
||||
** The decision was to manage this stack explicitly, as a std::stack (heap memory).
|
||||
** Each entry on this stack is a "context frame" for list diff. Which makes the
|
||||
** tree diff applicator a highly statefull component.
|
||||
**
|
||||
** Even more so, since -- for \em performance reasons -- we try to alter the
|
||||
** tree shaped data structure \em in-place. We want to avoid the copy of possibly
|
||||
** deep sub-trees, when in the end we might be just rearranging their sequence order.
|
||||
** This design decision comes at a price tag though
|
||||
** - it subverts the immutable nature of \c Record<GenNode> and leads to
|
||||
** high dependency on data layout and implementation details of the latter.
|
||||
** This is at least prominently marked by working on a diff::Record::Mutator,
|
||||
** so the client has first to "open up" the otherwise immutable tree
|
||||
** - the actual list diff on each level works by first \em moving the entire
|
||||
** Record contents away into a temporary buffer and then \em moving them
|
||||
** back into new shape one by one. In case of a diff conflict (i.e. a
|
||||
** mismatch between the actual data structure and the assumptions made
|
||||
** for the diff message on the sender / generator side), an exception
|
||||
** is thrown, leaving the client with a possibly corrupted tree, where
|
||||
** parts might even still be stashed away in the temporary buffer,
|
||||
** and thus be lost.
|
||||
** We consider this unfortunate, yet justified by the very nature of applying a diff.
|
||||
** When the user needs safety or transactional behaviour, a deep copy should be made
|
||||
** before attaching the #DiffApplicator
|
||||
**
|
||||
** @see DiffTreeApplication_test
|
||||
** @see DiffListApplication_test
|
||||
** @see GenNodeBasic_test
|
||||
** @see tree-diff.hpp
|
||||
**
|
||||
*/
|
||||
|
||||
|
|
@ -169,7 +202,7 @@ namespace diff{
|
|||
throw error::State(_Fmt("Unable locate position 'after(%s)'") % elm.idi
|
||||
, LUMIERA_ERROR_DIFF_CONFLICT);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
__expect_valid_parent_scope (GenNode::ID const& idi)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -27,12 +27,29 @@
|
|||
** this building block defines the set of operations to express both structural
|
||||
** and content changes in a given data structure.
|
||||
**
|
||||
** @todo UNIMPLEMENTED as of 12/14
|
||||
** This »tree diff language« does not rely on any concrete data structure or layout,
|
||||
** just on some general assumptions regarding the ordering and structure of the data.
|
||||
** - top level is a root record
|
||||
** - a record has a type, a collection of named attributes, and a collection of children
|
||||
** - all elements within a record are conceived as elements in ordered sequence, with the
|
||||
** attributes first, followed by the children. The end of the attribute scope is given
|
||||
** by the the appearance of the first unnamed entry, i.e the first child.
|
||||
** - the individual elements in these sequences have a distinguishable identity and
|
||||
** optionally a name (a named element is an attribute).
|
||||
** - moreover, the elements carry a typed payload data element, which possibly is
|
||||
** a \em nested record ("nested child object").
|
||||
** - the typing of the elements is outside the scope of the diff language; it is
|
||||
** assumed that the receiver knows what types to expect and how to deal with them.
|
||||
** - only nested records may be \em mutated by the diff. All other elements can
|
||||
** only be inserted, moved or deleted (like elements in list diff)
|
||||
** By implementing the #TreeDiffInterpreter interface (visitor), a concrete usage
|
||||
** can receive a diff description and possibly apply it to suitable target data.
|
||||
**
|
||||
** @see diff-language.cpp
|
||||
** @see diff-tree-application-test.cpp
|
||||
** @see tree-diff.cpp
|
||||
** @see GenNode
|
||||
** @see tree-diff-application.cpp
|
||||
** @see DiffTreeApplication_test
|
||||
** @see list-diff.cpp
|
||||
** @see diff::GenNode
|
||||
**
|
||||
*/
|
||||
|
||||
|
|
@ -54,9 +71,52 @@ namespace diff{
|
|||
* Interpreter interface to define the operations ("verbs"),
|
||||
* which describe differences or changes in hierarchical data structure.
|
||||
* The meaning of the verbs is as follows:
|
||||
* - \c TODO
|
||||
*
|
||||
* @todo to be defined
|
||||
* - \c ins prompts to insert the given argument element at the \em current
|
||||
* processing position into the target sequence. This operation
|
||||
* allows to inject new data
|
||||
* - \c del requires to delete the \em next element at \em current position.
|
||||
* For sake of verification, the ID of the argument payload is
|
||||
* required to match the ID of the element about to be discarded.
|
||||
* - \c pick just accepts the \em next element at \em current position into
|
||||
* the resulting altered sequence. Again, the ID of the argument
|
||||
* has to match the ID of the element to be picked, for sake
|
||||
* of verification.
|
||||
* - \c find effect a re-ordering of the target scope contents: it requires
|
||||
* to \em search for the (next respective single occurrence of the)
|
||||
* given element further down into the remainder of the current
|
||||
* record scope (but not into nested child scopes). The designated
|
||||
* element is to be retrieved and inserted as the next element
|
||||
* at current position.
|
||||
* - \c skip processing hint, emitted at the position where an element
|
||||
* previously extracted by a \c find verb happened to sit within
|
||||
* the old order. This allows an optimising implementation to “fetch”
|
||||
* a copy and just drop or skip the original, thereby avoiding to
|
||||
* shift any other elements.
|
||||
* - \c after shortcut to \c pick existing elements up to the designated point.
|
||||
* As a special notation, \c after(Ref::ATTRIBUTES) allows to fast forward
|
||||
* to the first child element, while \c after(Ref::END) means to accept
|
||||
* all of the existing data contents as-is (possibly to append further
|
||||
* elements after that point.
|
||||
* - \c mut bracketing construct to open a nested sub scope. The element
|
||||
* designated by the ID of the argument needs to be a #Record
|
||||
* ("nested child object"). Moreover, this element must have been
|
||||
* mentioned with the preceding diff verbs at that level, which means
|
||||
* that the element as such must already be present in the altered
|
||||
* target structure. The \c mut(ID) verb then opens this nested
|
||||
* record for diff handling, and all subsequent diff verbs are to be
|
||||
* interpreted relative to this scope, until the corresponding
|
||||
* \c emu(ID) verb is encountered. As a special notation, right
|
||||
* after handling an element with the list diff verbs (i.e. \c ins
|
||||
* or \c pick or \c find), it is allowed immediately to open the
|
||||
* nested scope with \c mut(Ref::THIS) -- which circumvents the
|
||||
* problem that it is sometimes difficult to know the precise ID,
|
||||
* especially when hand-writing a diff to populate a data structure.
|
||||
* - \c emu bracketing construct and counterpart to \c mut(ID). This verb
|
||||
* must be given precisely at the end of the nested scope (it is
|
||||
* not allowed to "return" from the middle of a scope, for sake
|
||||
* of sanity). At this point, ths child scope is left and the
|
||||
* parent scope with all existing diff state is popped from an
|
||||
* internal stack
|
||||
*/
|
||||
class TreeDiffInterpreter
|
||||
{
|
||||
|
|
|
|||
|
|
@ -158,6 +158,11 @@ return: 0
|
|||
END
|
||||
|
||||
|
||||
TEST "Diff: reshape a tree data structure through diff" DiffTreeApplication_test <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
|
||||
TEST "A Digxel (numeric component)" Digxel_test <<END
|
||||
out-lit: empty____## +0.0 ##
|
||||
out-lit: value____##-88.8 ##
|
||||
|
|
|
|||
|
|
@ -51,13 +51,13 @@ namespace test{
|
|||
const GenNode ATTRIB1("α", 1), // attribute α = 1
|
||||
ATTRIB2("β", 2L), // attribute α = 2L (int64_t)
|
||||
ATTRIB3("γ", 3.45), // attribute γ = 3.45 (double)
|
||||
TYPE_X("type", "X"), // a "magic" type attribute "X"
|
||||
TYPE_X("type", "X"), // a "magic" type attribute "X"
|
||||
TYPE_Y("type", "Y"), //
|
||||
CHILD_A("a"), // unnamed string child node
|
||||
CHILD_B('b'), // unnamed char child node
|
||||
CHILD_T(Time(12,34,56,78)), // unnamed time value child
|
||||
SUB_NODE = MakeRec().genNode(), // empty anonymous node used to open a sub scope
|
||||
ATTRIB_NODE = MakeRec().genNode("δ"), // empty named node to be attached as attribute δ
|
||||
ATTRIB_NODE = MakeRec().genNode("δ"), // empty named node to be attached as attribute δ
|
||||
CHILD_NODE = SUB_NODE; // yet another child node, same ID as SUB_NODE (!)
|
||||
|
||||
}//(End)Test fixture
|
||||
|
|
@ -71,13 +71,29 @@ namespace test{
|
|||
|
||||
|
||||
/***********************************************************************//**
|
||||
* @test Demonstration/Concept: a description language for list differences.
|
||||
* @test Demonstration/Concept: a description language for tree differences.
|
||||
* The representation is given as a linearised sequence of verb tokens.
|
||||
* This test demonstrates the application of such a diff representation
|
||||
* to a given source list, transforming this list to hold the intended
|
||||
* target list contents.
|
||||
*
|
||||
* @see session-structure-mapping-test.cpp
|
||||
* In addition to the verbs used for list diffing, here we additionally
|
||||
* have to deal with nested scopes, which can be entered thorough a
|
||||
* bracketing construct \c mut(ID)...emu(ID).
|
||||
* This test demonstrates the application of such diff sequences
|
||||
* - in the first step, an empty root #Record<GenNode> is populated
|
||||
* with a type-ID, three named attribute values, three child values
|
||||
* 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.
|
||||
* @remarks to follow this test, you should be familiar both with our
|
||||
* \link diff::Record generic data record \endlink, as well as with
|
||||
* the \link diff::GenNode variant data node \endlink. 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.
|
||||
* @see GenericRecordRepresentation_test
|
||||
* @see GenNodeBasic_test
|
||||
* @see DiffListApplication_test
|
||||
* @see diff-tree-application.hpp
|
||||
* @see tree-diff.hpp
|
||||
*/
|
||||
class DiffTreeApplication_test
|
||||
: public Test
|
||||
|
|
@ -115,7 +131,7 @@ namespace test{
|
|||
, pick(Ref::CHILD) // pick a child anonymously
|
||||
, mut(Ref::THIS) // mutate the current element (the one just picked)
|
||||
, ins(ATTRIB3)
|
||||
, ins(ATTRIB_NODE)
|
||||
, ins(ATTRIB_NODE) // attributes can also be nested objects
|
||||
, find(CHILD_A)
|
||||
, del(CHILD_B)
|
||||
, ins(CHILD_NODE)
|
||||
|
|
@ -125,7 +141,7 @@ namespace test{
|
|||
, ins(TYPE_Y)
|
||||
, ins(ATTRIB2)
|
||||
, emu(CHILD_NODE)
|
||||
, mut(ATTRIB_NODE)
|
||||
, mut(ATTRIB_NODE) // mutation can be out-of order, target found by ID
|
||||
, ins(CHILD_A)
|
||||
, ins(CHILD_A)
|
||||
, ins(CHILD_A)
|
||||
|
|
@ -141,41 +157,44 @@ namespace test{
|
|||
Rec::Mutator target;
|
||||
Rec& subject = target;
|
||||
DiffApplicator<Rec::Mutator> application(target);
|
||||
|
||||
// Part I : apply diff to populate
|
||||
application.consume(populationDiff());
|
||||
|
||||
CHECK (!isnil (subject)); // nonempty -- content has been added
|
||||
CHECK ("X" == subject.getType()); // type was set to "X"
|
||||
CHECK (1 == subject.get("α").data.get<int>()); // has gotten our int attribute "α"
|
||||
CHECK (2L == subject.get("β").data.get<int64_t>()); // ... the long attribute "β"
|
||||
CHECK (3.45 == subject.get("γ").data.get<double>()); // ... and double attribute "γ"
|
||||
auto scope = subject.scope(); // look into the scope contents...
|
||||
CHECK ( *scope == CHILD_A); // there is CHILD_A
|
||||
CHECK (*++scope == CHILD_T); // followed by a copy of CHILD_T
|
||||
CHECK (*++scope == CHILD_T); // and another copy of CHILD_T
|
||||
CHECK (*++scope == MakeRec().appendChild(CHILD_B) // and there is a nested Record
|
||||
.appendChild(CHILD_A) // with CHILD_B
|
||||
.genNode(SUB_NODE.idi.getSym())); // and CHILD_A
|
||||
CHECK (isnil(++scope)); // thats all -- no more children
|
||||
CHECK (!isnil (subject)); // nonempty -- content has been added
|
||||
CHECK ("X" == subject.getType()); // type was set to "X"
|
||||
CHECK (1 == subject.get("α").data.get<int>()); // has gotten our int attribute "α"
|
||||
CHECK (2L == subject.get("β").data.get<int64_t>()); // ... the long attribute "β"
|
||||
CHECK (3.45 == subject.get("γ").data.get<double>()); // ... and double attribute "γ"
|
||||
auto scope = subject.scope(); // look into the scope contents...
|
||||
CHECK ( *scope == CHILD_A); // there is CHILD_A
|
||||
CHECK (*++scope == CHILD_T); // followed by a copy of CHILD_T
|
||||
CHECK (*++scope == CHILD_T); // and another copy of CHILD_T
|
||||
CHECK (*++scope == MakeRec().appendChild(CHILD_B) // and there is a nested Record
|
||||
.appendChild(CHILD_A) // with CHILD_B
|
||||
.genNode(SUB_NODE.idi.getSym())); // and CHILD_A
|
||||
CHECK (isnil(++scope)); // thats all -- no more children
|
||||
|
||||
application.consume(mutationDiff());
|
||||
CHECK (join (subject.keys()) == "α, β, γ"); // the attributes weren't altered
|
||||
scope = subject.scope(); // but the scope was reordered
|
||||
CHECK ( *scope == CHILD_T); // CHILD_T
|
||||
CHECK (*++scope == CHILD_A); // CHILD_A
|
||||
Rec nested = (++scope)->data.get<Rec>(); // and our nested Record, which too has been altered:
|
||||
CHECK (nested.get("γ").data.get<double>() == 3.45); // it carries now an attribute "δ", which is again
|
||||
CHECK (nested.get("δ").data.get<Rec>() == MakeRec().appendChild(CHILD_A) // a nested Record with three children CHILD_A
|
||||
.appendChild(CHILD_A) //
|
||||
.appendChild(CHILD_A) //
|
||||
.genNode("δ")); //
|
||||
auto subScope = nested.scope(); // and within the nested sub-scope we find
|
||||
CHECK ( *subScope == CHILD_A); // CHILD_A
|
||||
CHECK (*++subScope == MakeRec().type("Y") // a yet-again nested sub-Record of type "Y"
|
||||
.set("β", 2L ) // with just an attribute "β" == 2L
|
||||
.genNode(CHILD_NODE.idi.getSym())); // (and an empty child scope)
|
||||
CHECK (*++subScope == CHILD_T); // followed by another copy of CHILD_T
|
||||
CHECK (isnil (++subScope)); //
|
||||
CHECK (isnil (++scope)); // and nothing beyond that.
|
||||
// Part II : apply the second diff
|
||||
application.consume(mutationDiff());
|
||||
CHECK (join (subject.keys()) == "α, β, γ"); // the attributes weren't altered
|
||||
scope = subject.scope(); // but the scope was reordered
|
||||
CHECK ( *scope == CHILD_T); // CHILD_T
|
||||
CHECK (*++scope == CHILD_A); // CHILD_A
|
||||
Rec nested = (++scope)->data.get<Rec>(); // and our nested Record, which too has been altered:
|
||||
CHECK (nested.get("γ").data.get<double>() == 3.45); // it carries now an attribute "δ", which is again
|
||||
CHECK (nested.get("δ") == MakeRec().appendChild(CHILD_A) // a nested Record with three children CHILD_A
|
||||
.appendChild(CHILD_A) //
|
||||
.appendChild(CHILD_A) //
|
||||
.genNode("δ")); //
|
||||
auto subScope = nested.scope(); // and within the nested sub-scope we find
|
||||
CHECK ( *subScope == CHILD_A); // CHILD_A
|
||||
CHECK (*++subScope == MakeRec().type("Y") // a yet-again nested sub-Record of type "Y"
|
||||
.set("β", 2L ) // with just an attribute "β" == 2L
|
||||
.genNode(CHILD_NODE.idi.getSym())); // (and an empty child scope)
|
||||
CHECK (*++subScope == CHILD_T); // followed by another copy of CHILD_T
|
||||
CHECK (isnil (++subScope)); //
|
||||
CHECK (isnil (++scope)); // and nothing beyond that.
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1072,10 +1072,10 @@
|
|||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1443733567706" HGAP="76" ID="ID_143203937" MODIFIED="1443741888841" TEXT="Diff-Language" VSHIFT="15">
|
||||
<node CREATED="1443733567706" HGAP="76" ID="ID_143203937" MODIFIED="1446356861829" TEXT="Diff-Language" VSHIFT="15">
|
||||
<cloud COLOR="#cfba9d"/>
|
||||
<font NAME="SansSerif" SIZE="14"/>
|
||||
<icon BUILTIN="prepare"/>
|
||||
<icon BUILTIN="go"/>
|
||||
<node CREATED="1443733726563" ID="ID_410650103" MODIFIED="1443733731422" TEXT="Grundlagen">
|
||||
<node CREATED="1443733732938" ID="ID_73184558" MODIFIED="1443733737277" TEXT="Folge von Verben"/>
|
||||
<node CREATED="1443733738296" ID="ID_994909291" MODIFIED="1443733743181" TEXT="konstante Größe"/>
|
||||
|
|
@ -1711,9 +1711,9 @@
|
|||
<node CREATED="1443741923547" ID="ID_1978439060" MODIFIED="1443741930738" TEXT="Listen-Diff">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#990000" CREATED="1443741931858" ID="ID_484829805" MODIFIED="1443741945481" TEXT="Baum-Diff">
|
||||
<icon BUILTIN="flag"/>
|
||||
<node CREATED="1445295424277" ID="ID_1084177503" MODIFIED="1445644243570">
|
||||
<node CREATED="1443741931858" ID="ID_484829805" MODIFIED="1446356837301" TEXT="Baum-Diff">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node CREATED="1445295424277" FOLDED="true" ID="ID_1084177503" MODIFIED="1446356540880">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
|
|
@ -1846,8 +1846,8 @@
|
|||
<node CREATED="1445389311690" ID="ID_1926972913" MODIFIED="1445389323819" TEXT="und dieses rekursiv..."/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#391f9e" CREATED="1445391990778" HGAP="148" ID="ID_464295846" MODIFIED="1445392206014" TEXT="Implementierung" VSHIFT="4">
|
||||
<icon BUILTIN="pencil"/>
|
||||
<node COLOR="#391f9e" CREATED="1445391990778" HGAP="148" ID="ID_464295846" MODIFIED="1446356481059" TEXT="Implementierung" VSHIFT="4">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1445392080175" ID="ID_341024968" MODIFIED="1445392101243">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
|
@ -1882,7 +1882,7 @@
|
|||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1446159438278" HGAP="29" ID="ID_563496669" MODIFIED="1446159498995" VSHIFT="8">
|
||||
<node CREATED="1446159438278" FOLDED="true" HGAP="29" ID="ID_563496669" MODIFIED="1446356526122" VSHIFT="8">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
|
|
@ -1892,8 +1892,8 @@
|
|||
Problem: <b><font color="#ed1c02" size="4">Rekursion</font></b>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<icon BUILTIN="clanbomber"/>
|
||||
<node CREATED="1446159517914" ID="ID_1749096609" MODIFIED="1446159530661" TEXT="wir müssen rekursiv in Sub-Scope einsteigen"/>
|
||||
<node CREATED="1446159531745" ID="ID_1660140345" MODIFIED="1446159550795" TEXT="eingeschachtelt wieder ein Record::Mutator"/>
|
||||
|
|
@ -1920,8 +1920,7 @@
|
|||
ist der gesammte Diff für den eingeschachtelten Kontext konsumiert
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1446159744053" ID="ID_1735127502" MODIFIED="1446159765190" TEXT="pro">
|
||||
|
|
@ -1956,8 +1955,7 @@
|
|||
und legt einen neuen Mutator an für den nested scope
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="idea"/>
|
||||
</node>
|
||||
<node CREATED="1446160209758" ID="ID_1949126696" MODIFIED="1446160211514" TEXT="pro">
|
||||
|
|
@ -1984,8 +1982,7 @@
|
|||
interner Stack
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
|
|
@ -2004,12 +2001,37 @@
|
|||
also den TreeMutator, vermutlich das andere Modell (rekursiv konsumieren) verwenden.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1446356556349" ID="ID_1068649765" MODIFIED="1446356607845" TEXT="offen...">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1446356564244" ID="ID_211629813" MODIFIED="1446356584315" TEXT="find nicht per == sondern per match">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
<node CREATED="1446356765393" ID="ID_293921295" MODIFIED="1446356827238" TEXT="IDs in Testdaten für GenNodeBaisc_test">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Problem sind mal wieder die automatisch generierten IDs.
|
||||
</p>
|
||||
<p>
|
||||
Die sind natürlich anders, wenn wir die ganze Testsuite ausführen...
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<icon BUILTIN="flag"/>
|
||||
</node>
|
||||
<node CREATED="1446356588505" ID="ID_895292312" MODIFIED="1446356602250" TEXT="gründlicher Test">
|
||||
<icon BUILTIN="yes"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1444522895718" ID="ID_598781690" MODIFIED="1444522897802" TEXT="Generierung">
|
||||
|
|
@ -2585,5 +2607,27 @@
|
|||
<node CREATED="1439842379420" ID="ID_1336697213" MODIFIED="1439842385655" TEXT="gtk-Abhängigkeiten"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1446356359992" HGAP="9" ID="ID_1850896628" MODIFIED="1446356445623" POSITION="left" TEXT="QA" VSHIFT="69">
|
||||
<icon BUILTIN="prepare"/>
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#990000" CREATED="1446356368070" ID="ID_768449868" MODIFIED="1446356423988" TEXT="ouch">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node CREATED="1446356379653" ID="ID_1354454865" MODIFIED="1446356404198" TEXT="CHECK: typed-counter-test.cpp:329: thread_1: simpleUsageTest: (1 == myCounter.size())">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
sporadischer Fehlschlag am 1.11.2015
|
||||
</p>
|
||||
<p>
|
||||
wir kann das passieren?
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
</map>
|
||||
|
|
|
|||
Loading…
Reference in a new issue