Lumiera  0.pre.03
»edit your freedom«
diff-ignore-changes-test.cpp
Go to the documentation of this file.
1 /*
2  DiffIgnoreChanges(Test) - apply diff to black hole
3 
4  Copyright (C)
5  2018, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 * *****************************************************************/
13 
21 #include "lib/test/run.hpp"
22 #include "lib/test/test-helper.hpp"
23 #include "lib/format-util.hpp"
26 #include "lib/format-string.hpp"
27 #include "lib/format-cout.hpp"
28 #include "lib/util.hpp"
29 
30 #include <string>
31 
33 using lib::time::Time;
34 using std::string;
35 
36 
37 namespace lib {
38 namespace diff{
39 namespace test{
40 
41  namespace {//Test fixture....
42 
43  // define some GenNode elements
44  // to act as templates within the concrete diff
45  // NOTE: everything in this diff language is by-value
46  const GenNode ATTRIB1("α", 1), // attribute α = 1
47  ATTRIB2("β", int64_t(2)), // attribute α = 2L (int64_t)
48  ATTRIB3("γ", 3.45), // attribute γ = 3.45 (double)
49  TYPE_X("type", "ξ"), // a "magic" type attribute "Xi"
50  TYPE_Z("type", "ζ"), //
51  CHILD_A("a"), // unnamed string child node
52  CHILD_B('b'), // unnamed char child node
53  CHILD_T(Time(12,34,56,78)), // unnamed time value child
54  SUB_NODE = MakeRec().genNode(), // empty anonymous node used to open a sub scope
55  ATTRIB_NODE = MakeRec().genNode("δ"), // empty named node to be attached as attribute δ
56  GAMMA_PI("γ", 3.14159265); // happens to have the same identity (ID) as ATTRIB3
57 
58  }//(End)Test fixture
59 
60  using LERR_(DIFF_CONFLICT);
61 
62 
63 
64 
65 
66  /**************************************************************************/
79  : public Test
81  {
83 
84  DiffSeq
85  populationDiff()
86  {
87  return snapshot({ins(ATTRIB1)
88  , ins(ATTRIB3)
89  , ins(ATTRIB3)
90  , ins(CHILD_B)
91  , ins(CHILD_B)
92  , ins(CHILD_T)
93  });
94  } // ==> ATTRIB1, ATTRIB3, (ATTRIB3), CHILD_B, CHILD_B, CHILD_T
95 
96  DiffSeq
97  reorderingDiff()
98  {
99  return snapshot({after(Ref::ATTRIBS)
100  , ins(ATTRIB2)
101  , del(CHILD_B)
102  , ins(SUB_NODE)
103  , find(CHILD_T)
104  , pick(CHILD_B)
105  , skip(CHILD_T)
106  });
107  } // ==> ATTRIB1, ATTRIB3, (ATTRIB3), ATTRIB2, SUB_NODE, CHILD_T, CHILD_B
108 
109  DiffSeq
110  mutationDiff()
111  {
112  return snapshot({after(CHILD_B)
113  , after(Ref::END)
114  , set(GAMMA_PI)
115  , mut(SUB_NODE)
116  , ins(TYPE_X)
117  , ins(ATTRIB2)
118  , ins(CHILD_B)
119  , ins(CHILD_A)
120  , emu(SUB_NODE)
121  , ins(ATTRIB_NODE)
122  , mut(ATTRIB_NODE)
123  , ins(TYPE_Z)
124  , ins(CHILD_A)
125  , ins(CHILD_A)
126  , ins(CHILD_A)
127  , emu(ATTRIB_NODE)
128  });
129  } // ==> ATTRIB1, ATTRIB3 := π, (ATTRIB3), ATTRIB2,
130  // ATTRIB_NODE{ type ζ, CHILD_A, CHILD_A, CHILD_A }
131  // SUB_NODE{ type ξ, ATTRIB2, CHILD_B, CHILD_A },
132  // CHILD_T, CHILD_B
133 
134 
135 
136 
137  virtual void
138  run (Arg)
139  {
140  fail_or_ignore();
142  }
143 
144 
157  void
159  {
160  struct HappyBlackHole
161  {
162  bool diligent = true;
163 
164  void
165  buildMutator (TreeMutator::Handle buff)
166  {
167  if (diligent)
168  buff.emplace(
169  TreeMutator());
170  else
171  buff.emplace(
173  .ignoreAllChanges());
174  }
175  };
176 
177  HappyBlackHole subject;
178  DiffApplicator<HappyBlackHole> application(subject);
179 
180  VERIFY_ERROR(DIFF_CONFLICT, application.consume(populationDiff()) );
181  VERIFY_ERROR(DIFF_CONFLICT, application.consume(reorderingDiff()) );
182  VERIFY_ERROR(DIFF_CONFLICT, application.consume(mutationDiff()) );
183 
184  subject.diligent = false;
185 
186  application.consume(populationDiff());
187  application.consume(reorderingDiff());
188  application.consume(mutationDiff());
189  }
190 
191 
200  void
202  {
203  struct Scrounger
204  {
205  double loot = 0.0;
206 
207  void
208  buildMutator (TreeMutator::Handle buff)
209  {
210  buff.emplace (
212  .ignoreAllChanges()
213  .change("γ", [&](double val) { loot = val; }));
214  }
215  };
216 
217  Scrounger subject;
218  DiffApplicator<Scrounger> application(subject);
219 
220  const auto NOTHING = 0.0;
221  const auto VAL_1 = ATTRIB3.data.get<double>();
222  const auto VAL_2 = GAMMA_PI.data.get<double>();
223 
224  CHECK (subject.loot == NOTHING);
225 
226  application.consume(populationDiff());
227  CHECK (subject.loot == VAL_1);
228 
229  application.consume(reorderingDiff());
230  CHECK (subject.loot == VAL_1);
231 
232  application.consume(mutationDiff());
233  CHECK (subject.loot == VAL_2);
234  }
235 
236  };
237 
238 
240  LAUNCHER (DiffIgnoreChanges_test, "unit common");
241 
242 
243 
244 }}} // namespace lib::diff::test
Concrete implementation to apply structural changes to hierarchical data structures.
Automatically use custom string conversion in C++ stream output.
Definition: run.hpp:40
Front-end for printf-style string template interpolation.
#define VERIFY_ERROR(ERROR_ID, ERRONEOUS_STATEMENT)
Macro to verify that a statement indeed raises an exception.
iter_stl::IterSnapshot< VAL > snapshot(std::initializer_list< VAL > const &&ili)
Take a snapshot of the given std::initializer_list.
Implementation namespace for support and library code.
Lumiera&#39;s internal time value datatype.
Definition: timevalue.hpp:299
static Builder< TreeMutator > build()
DSL: start building a custom adapted tree mutator, where the operations are tied by closures or wrapp...
SUB & emplace(SUB &&implementation)
move-construct an instance of a subclass into the opaque buffer
A handle to allow for safe »remote implantation« of an unknown subclass into a given opaque InPlaceBu...
Definition: record.hpp:104
static const Ref END
symbolic ID ref "_END_"
Definition: gen-node.hpp:862
Simplistic test class runner.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
A collection of frequently used helper functions to support unit testing.
static const Ref ATTRIBS
symbolic ID ref "_ATTRIBS_"
Definition: gen-node.hpp:865
Collection of small helpers and convenience shortcuts for diagnostics & formatting.
materialised iterator contents.
Diagnostic helper for unit tests regarding mutation of custom data.
generic data element node within a tree
Definition: gen-node.hpp:222
generic builder to apply a diff description to a given target data structure.
Customisable intermediary to abstract mutating operations on arbitrary, hierarchical object-like data...