Lumiera  0.pre.03
»edit your freedom«
special-job-fun-test.cpp
Go to the documentation of this file.
1 /*
2  SpecialJobFun(Test) - verify a disposable configurable job functor
3 
4  Copyright (C)
5  2023, 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 
19 #include "lib/test/run.hpp"
20 #include "lib/test/test-helper.hpp"
21 //#include "vault/real-clock.hpp"
22 //#include "lib/time/timevalue.hpp"
24 #include "lib/format-cout.hpp"
27 //#include "lib/util.hpp"
28 
29 //#include <array>
30 //#include <functional>
31 
32 //using lib::time::Time;
33 //using lib::time::FSecs;
34 
35 //using util::isnil;
36 //using util::isSameObject;
37 //using lib::test::randStr;
38 //using lib::test::randTime;
39 using lib::test::Dummy;
40 //using std::array;
41 
42 
43 namespace vault{
44 namespace gear {
45 namespace test {
46 
47  namespace { // shorthands and parameters for test...
48 
49 
50  }//(End)test definitions
51 
52 
53 
54 
55  /*****************************************************************/
61  class SpecialJobFun_test : public Test
62  {
63 
64  virtual void
65  run (Arg)
66  {
67  simpleUsage();
69  }
70 
71 
75  void
77  {
78  bool hit{false}; // create directly from λ
79  SpecialJobFun specialFun{[&](JobParameter){ hit=true; }};
80 
81  CHECK (specialFun);
82  Job funJob{specialFun
85  };
86 
87  funJob.triggerJob();
88  CHECK (hit);
89  CHECK (not specialFun);
90  }
91 
92 
93 
105  void
107  {
108  CHECK (0 == Dummy::checksum());
109  { // Note: ▽▽▽ tracker in λ-closure
110  SpecialJobFun funTrack{[tracker=Dummy(23)]
111  (JobParameter param) mutable
112  {
113  int mark = param.invoKey.part.a;
114  tracker.setVal (mark);
115  }}; // △△△ invocation should alter checksum
116 
117  // one Dummy instance was implanted
118  CHECK (23 == Dummy::checksum());
119  InvocationInstanceID hiddenMessage;
120  hiddenMessage.part.a = 55;
121  Job funJob{funTrack
122  ,hiddenMessage
124  };
125 
126  CHECK (23 == Dummy::checksum());
127  funJob.triggerJob();
128  CHECK (55 == Dummy::checksum()); // the `funJob` front-end handle still keeps it alive
129  } // but when this front-end goes out of scope...
130  CHECK (0 == Dummy::checksum()); // the implanted tracker is also gone
131 
132  { // another investigation with the same technique...
133  auto trackingLambda = [tracker=Dummy(23)]
134  (JobParameter param) mutable
135  {
136  int mark = param.invoKey.part.a;
137  tracker.setVal (mark);
138  };
139  CHECK (23 == Dummy::checksum());
140 
141  SpecialJobFun frontEnd{move(trackingLambda)}; // this time the λ is moved in..
142  CHECK (23 == Dummy::checksum()); // the embedded tracker was copied into the Functor in heap memory
143  CHECK (2 == frontEnd.use_count()); // Note: both the front-end and the Functor in heap hold a use-reference
144 
145  auto otherHandle = frontEnd; // copy of front-end...
146  CHECK (3 == frontEnd.use_count()); // ...so there are three usages of the front-end handle now
147  CHECK (23 == Dummy::checksum()); // ...but only one tracker instance (in heap)
148 
149  frontEnd = SpecialJobFun(); // re-assign one front-end handle with an empty instance
150  CHECK (0 == frontEnd.use_count()); // thus `frontEnd` is no longer attached to the active instance
151  CHECK (2 == otherHandle.use_count()); // but the other copy still is
152  CHECK (not frontEnd);
153  CHECK (otherHandle);
154 
155  InvocationInstanceID hiddenMessage;
156  hiddenMessage.part.a = 55;
157  Job funJob{otherHandle // Note: don't pass the handle here, rather a JobFunctor& is extracted
158  ,hiddenMessage
160  };
161 
162  CHECK (2 == otherHandle.use_count());
163  CHECK (23 == Dummy::checksum());
164 
165  otherHandle = SpecialJobFun(); // now kill even the last front-end handle we had
166  CHECK (0 == otherHandle.use_count()); // thus _we_ have no way to reach the Functor in heap
167  CHECK (23 == Dummy::checksum()); // yet it stays alive, since it was not invoked yet
168 
169  funJob.triggerJob(); // after invocation, the Functor in heap memory self-destructs
170  CHECK (0 == Dummy::checksum()); // since it did hold the last reference
171  }
172  CHECK (0 == Dummy::checksum());
173  }
174  };
175 
176 
178  LAUNCHER (SpecialJobFun_test, "unit engine");
179 
180 
181 
182 }}} // namespace vault::gear::test
static const Time ANYTIME
border condition marker value. ANYTIME <= any time value
Definition: timevalue.hpp:313
Automatically use custom string conversion in C++ stream output.
Definition: run.hpp:40
A configurable one-time job to invoke some special function.
Helpers typically used while writing tests.
Front-end to configure a special job functor for one-time use.
Simplistic test class runner.
unittest helper code: test dummy objects to track instances.
A collection of frequently used helper functions to support unit testing.
A Dummy object for tests.
opaque ID attached to each individual job invocation.
Definition: job.h:103
Individual frame rendering task, forwarding to a closure.
Definition: job.h:268
Vault-Layer implementation namespace root.