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) Lumiera.org
5  2018, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 * *****************************************************/
22 
30 #include "lib/test/run.hpp"
31 #include "lib/test/test-helper.hpp"
32 #include "lib/format-util.hpp"
35 #include "lib/format-string.hpp"
36 #include "lib/format-cout.hpp"
37 #include "lib/util.hpp"
38 
39 #include <string>
40 
42 using lib::time::Time;
43 using std::string;
44 
45 
46 namespace lib {
47 namespace diff{
48 namespace test{
49 
50  namespace {//Test fixture....
51 
52  // define some GenNode elements
53  // to act as templates within the concrete diff
54  // NOTE: everything in this diff language is by-value
55  const GenNode ATTRIB1("α", 1), // attribute α = 1
56  ATTRIB2("β", int64_t(2)), // attribute α = 2L (int64_t)
57  ATTRIB3("γ", 3.45), // attribute γ = 3.45 (double)
58  TYPE_X("type", "ξ"), // a "magic" type attribute "Xi"
59  TYPE_Z("type", "ζ"), //
60  CHILD_A("a"), // unnamed string child node
61  CHILD_B('b'), // unnamed char child node
62  CHILD_T(Time(12,34,56,78)), // unnamed time value child
63  SUB_NODE = MakeRec().genNode(), // empty anonymous node used to open a sub scope
64  ATTRIB_NODE = MakeRec().genNode("δ"), // empty named node to be attached as attribute δ
65  GAMMA_PI("γ", 3.14159265); // happens to have the same identity (ID) as ATTRIB3
66 
67  }//(End)Test fixture
68 
69  using LERR_(DIFF_CONFLICT);
70 
71 
72 
73 
74 
75  /**************************************************************************/
88  : public Test
90  {
92 
93  DiffSeq
94  populationDiff()
95  {
96  return snapshot({ins(ATTRIB1)
97  , ins(ATTRIB3)
98  , ins(ATTRIB3)
99  , ins(CHILD_B)
100  , ins(CHILD_B)
101  , ins(CHILD_T)
102  });
103  } // ==> ATTRIB1, ATTRIB3, (ATTRIB3), CHILD_B, CHILD_B, CHILD_T
104 
105  DiffSeq
106  reorderingDiff()
107  {
108  return snapshot({after(Ref::ATTRIBS)
109  , ins(ATTRIB2)
110  , del(CHILD_B)
111  , ins(SUB_NODE)
112  , find(CHILD_T)
113  , pick(CHILD_B)
114  , skip(CHILD_T)
115  });
116  } // ==> ATTRIB1, ATTRIB3, (ATTRIB3), ATTRIB2, SUB_NODE, CHILD_T, CHILD_B
117 
118  DiffSeq
119  mutationDiff()
120  {
121  return snapshot({after(CHILD_B)
122  , after(Ref::END)
123  , set(GAMMA_PI)
124  , mut(SUB_NODE)
125  , ins(TYPE_X)
126  , ins(ATTRIB2)
127  , ins(CHILD_B)
128  , ins(CHILD_A)
129  , emu(SUB_NODE)
130  , ins(ATTRIB_NODE)
131  , mut(ATTRIB_NODE)
132  , ins(TYPE_Z)
133  , ins(CHILD_A)
134  , ins(CHILD_A)
135  , ins(CHILD_A)
136  , emu(ATTRIB_NODE)
137  });
138  } // ==> ATTRIB1, ATTRIB3 := π, (ATTRIB3), ATTRIB2,
139  // ATTRIB_NODE{ type ζ, CHILD_A, CHILD_A, CHILD_A }
140  // SUB_NODE{ type ξ, ATTRIB2, CHILD_B, CHILD_A },
141  // CHILD_T, CHILD_B
142 
143 
144 
145 
146  virtual void
147  run (Arg)
148  {
149  fail_or_ignore();
151  }
152 
153 
166  void
168  {
169  struct HappyBlackHole
170  {
171  bool diligent = true;
172 
173  void
174  buildMutator (TreeMutator::Handle buff)
175  {
176  if (diligent)
177  buff.emplace(
178  TreeMutator());
179  else
180  buff.emplace(
182  .ignoreAllChanges());
183  }
184  };
185 
186  HappyBlackHole subject;
187  DiffApplicator<HappyBlackHole> application(subject);
188 
189  VERIFY_ERROR(DIFF_CONFLICT, application.consume(populationDiff()) );
190  VERIFY_ERROR(DIFF_CONFLICT, application.consume(reorderingDiff()) );
191  VERIFY_ERROR(DIFF_CONFLICT, application.consume(mutationDiff()) );
192 
193  subject.diligent = false;
194 
195  application.consume(populationDiff());
196  application.consume(reorderingDiff());
197  application.consume(mutationDiff());
198  }
199 
200 
209  void
211  {
212  struct Scrounger
213  {
214  double loot = 0.0;
215 
216  void
217  buildMutator (TreeMutator::Handle buff)
218  {
219  buff.emplace (
221  .ignoreAllChanges()
222  .change("γ", [&](double val) { loot = val; }));
223  }
224  };
225 
226  Scrounger subject;
227  DiffApplicator<Scrounger> application(subject);
228 
229  const auto NOTHING = 0.0;
230  const auto VAL_1 = ATTRIB3.data.get<double>();
231  const auto VAL_2 = GAMMA_PI.data.get<double>();
232 
233  CHECK (subject.loot == NOTHING);
234 
235  application.consume(populationDiff());
236  CHECK (subject.loot == VAL_1);
237 
238  application.consume(reorderingDiff());
239  CHECK (subject.loot == VAL_1);
240 
241  application.consume(mutationDiff());
242  CHECK (subject.loot == VAL_2);
243  }
244 
245  };
246 
247 
249  LAUNCHER (DiffIgnoreChanges_test, "unit common");
250 
251 
252 
253 }}} // 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:49
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:308
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:113
static const Ref END
symbolic ID ref "_END_"
Definition: gen-node.hpp:871
Simple 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:874
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:231
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...