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) Lumiera.org
5  2023, 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 
28 #include "lib/test/run.hpp"
29 #include "lib/test/test-helper.hpp"
30 //#include "vault/real-clock.hpp"
31 //#include "lib/time/timevalue.hpp"
33 #include "lib/format-cout.hpp"
35 #include "lib/test/testdummy.hpp"
36 //#include "lib/util.hpp"
37 
38 //#include <array>
39 //#include <functional>
40 
41 //using lib::time::Time;
42 //using lib::time::FSecs;
43 
44 //using util::isnil;
45 //using util::isSameObject;
46 //using lib::test::randStr;
47 //using lib::test::randTime;
48 using lib::test::Dummy;
49 //using std::array;
50 
51 
52 namespace vault{
53 namespace gear {
54 namespace test {
55 
56  namespace { // shorthands and parameters for test...
57 
58 
59  }//(End)test definitions
60 
61 
62 
63 
64  /*****************************************************************/
70  class SpecialJobFun_test : public Test
71  {
72 
73  virtual void
74  run (Arg)
75  {
76  simpleUsage();
78  }
79 
80 
84  void
86  {
87  bool hit{false}; // create directly from λ
88  SpecialJobFun specialFun{[&](JobParameter){ hit=true; }};
89 
90  CHECK (specialFun);
91  Job funJob{specialFun
94  };
95 
96  funJob.triggerJob();
97  CHECK (hit);
98  CHECK (not specialFun);
99  }
100 
101 
102 
114  void
116  {
117  CHECK (0 == Dummy::checksum());
118  { // Note: ▽▽▽ tracker in λ-closure
119  SpecialJobFun funTrack{[tracker=Dummy(23)]
120  (JobParameter param) mutable
121  {
122  int mark = param.invoKey.part.a;
123  tracker.setVal (mark);
124  }}; // △△△ invocation should alter checksum
125 
126  // one Dummy instance was implanted
127  CHECK (23 == Dummy::checksum());
128  InvocationInstanceID hiddenMessage;
129  hiddenMessage.part.a = 55;
130  Job funJob{funTrack
131  ,hiddenMessage
133  };
134 
135  CHECK (23 == Dummy::checksum());
136  funJob.triggerJob();
137  CHECK (55 == Dummy::checksum()); // the `funJob` front-end handle still keeps it alive
138  } // but when this front-end goes out of scope...
139  CHECK (0 == Dummy::checksum()); // the implanted tracker is also gone
140 
141  { // another investigation with the same technique...
142  auto trackingLambda = [tracker=Dummy(23)]
143  (JobParameter param) mutable
144  {
145  int mark = param.invoKey.part.a;
146  tracker.setVal (mark);
147  };
148  CHECK (23 == Dummy::checksum());
149 
150  SpecialJobFun frontEnd{move(trackingLambda)}; // this time the λ is moved in..
151  CHECK (23 == Dummy::checksum()); // the embedded tracker was copied into the Functor in heap memory
152  CHECK (2 == frontEnd.use_count()); // Note: both the front-end and the Functor in heap hold a use-reference
153 
154  auto otherHandle = frontEnd; // copy of front-end...
155  CHECK (3 == frontEnd.use_count()); // ...so there are three usages of the front-end handle now
156  CHECK (23 == Dummy::checksum()); // ...but only one tracker instance (in heap)
157 
158  frontEnd = SpecialJobFun(); // re-assign one front-end handle with an empty instance
159  CHECK (0 == frontEnd.use_count()); // thus `frontEnd` is no longer attached to the active instance
160  CHECK (2 == otherHandle.use_count()); // but the other copy still is
161  CHECK (not frontEnd);
162  CHECK (otherHandle);
163 
164  InvocationInstanceID hiddenMessage;
165  hiddenMessage.part.a = 55;
166  Job funJob{otherHandle // Note: don't pass the handle here, rather a JobFunctor& is extracted
167  ,hiddenMessage
169  };
170 
171  CHECK (2 == otherHandle.use_count());
172  CHECK (23 == Dummy::checksum());
173 
174  otherHandle = SpecialJobFun(); // now kill even the last front-end handle we had
175  CHECK (0 == otherHandle.use_count()); // thus _we_ have no way to reach the Functor in heap
176  CHECK (23 == Dummy::checksum()); // yet it stays alive, since it was not invoked yet
177 
178  funJob.triggerJob(); // after invocation, the Functor in heap memory self-destructs
179  CHECK (0 == Dummy::checksum()); // since it did hold the last reference
180  }
181  CHECK (0 == Dummy::checksum());
182  }
183  };
184 
185 
187  LAUNCHER (SpecialJobFun_test, "unit engine");
188 
189 
190 
191 }}} // namespace vault::gear::test
static const Time ANYTIME
border condition marker value. ANYTIME <= any time value
Definition: timevalue.hpp:322
Automatically use custom string conversion in C++ stream output.
Definition: run.hpp:49
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.
unittest helper code: test dummy objects to track instances.
Simple test class runner.
A collection of frequently used helper functions to support unit testing.
A Dummy object for tests.
Definition: testdummy.hpp:50
opaque ID attached to each individual job invocation.
Definition: job.h:112
Individual frame rendering task, forwarding to a closure.
Definition: job.h:277
Vault-Layer implementation namespace root.