AUnit  1.0.0
Unit testing framework for Arduino platforms inspired by ArduinoUnit and Google Test.
Test.h
1 /*
2 MIT License
3 
4 Copyright (c) 2018 Brian T. Park
5 
6 Permission is hereby granted, free of charge, to any person obtaining a copy
7 of this software and associated documentation files (the "Software"), to deal
8 in the Software without restriction, including without limitation the rights
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 copies of the Software, and to permit persons to whom the Software is
11 furnished to do so, subject to the following conditions:
12 
13 The above copyright notice and this permission notice shall be included in all
14 copies or substantial portions of the Software.
15 
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 SOFTWARE.
23 */
24 
25 // Significant portions of the design and implementation of this file came from
26 // https://github.com/mmurdoch/arduinounit/blob/master/src/ArduinoUnit.h
27 
28 #ifndef AUNIT_TEST_H
29 #define AUNIT_TEST_H
30 
31 #include <stdint.h>
32 #include "FCString.h"
33 #include "Verbosity.h"
34 
35 namespace aunit {
36 
43 class Test {
44  public:
45  // The LifeCycle states are used by TestRunner to determine what a Test
46  // should do. Unlike the assertion Status, the LfeCycle is mostly hidden
47  // from client code. The state transition diagram looks like this:
48  //
49  // include()/exclude()
50  // .---------------------> Excluded -----------.
51  // v v
52  // New Finished -> (out of list)
53  // \ setup() assertion() teardown() ^
54  // -------> Setup -------> Asserted ----------'
55 
57  static const uint8_t kLifeCycleNew = 0;
58 
65  static const uint8_t kLifeCycleExcluded = 1;
66 
74  static const uint8_t kLifeCycleSetup = 2;
75 
80  static const uint8_t kLifeCycleAsserted = 3;
81 
88  static const uint8_t kLifeCycleFinished = 4;
89 
90  // The assertion Status is the result of an "assertion()". In addition to
91  // the usual pass() and fail(), there are meta-assertions such as skip()
92  // and expire(). When the Status is changed from kStatusUnknown, the
93  // lifeCycle state changes to kLifeCycleAsserted.
94 
96  static const uint8_t kStatusUnknown = 0;
97 
99  static const uint8_t kStatusPassed = 1;
100 
102  static const uint8_t kStatusFailed = 2;
103 
105  static const uint8_t kStatusSkipped = 3;
106 
108  static const uint8_t kStatusExpired = 4;
109 
115  static Test** getRoot();
116 
118  Test();
119 
120  // NOTE: Don't create a virtual destructor. That's the normal best practice
121  // for classes that will be used polymorphically. However, this class will
122  // never be deleted polymorphically (i.e. through its pointer) so it
123  // doesn't need a virtual destructor. In fact, adding it causes flash and
124  // static memory to increase dramatically because each test() and testing()
125  // macro creates a new subclass. AceButtonTest flash memory increases from
126  // 18928 to 20064 bytes, and static memory increases from 917 to 1055
127  // bytes.
128 
136  virtual void setup() {}
137 
145  virtual void teardown() {}
146 
152  virtual void loop() = 0;
153 
155  void resolve();
156 
158  const internal::FCString& getName() const { return mName; }
159 
161  uint8_t getLifeCycle() { return mLifeCycle; }
162 
163  void setLifeCycle(uint8_t state) { mLifeCycle = state; }
164 
166  uint8_t getStatus() { return mStatus; }
167 
173  void setStatus(uint8_t status) {
174  if (status != kStatusUnknown) {
175  setLifeCycle(kLifeCycleAsserted);
176  }
177  mStatus = status;
178  }
179 
181  void setPassOrFail(bool ok);
182 
188  Test** getNext() { return &mNext; }
189 
196  bool isDone() { return mStatus != kStatusUnknown; }
197 
199  bool isNotDone() { return !isDone(); }
200 
202  bool isPassed() { return mStatus == kStatusPassed; }
203 
205  bool isNotPassed() { return !isPassed(); }
206 
208  bool isFailed() { return mStatus == kStatusFailed; }
209 
211  bool isNotFailed() { return !isFailed(); }
212 
214  bool isSkipped() { return mStatus == kStatusSkipped; }
215 
217  bool isNotSkipped() { return !isSkipped(); }
218 
220  bool isExpired() { return mStatus == kStatusExpired; }
221 
223  bool isNotExpired() { return !isExpired(); }
224 
229  void skip() { setStatus(kStatusSkipped); }
230 
235  void expire() { setStatus(kStatusExpired); }
236 
238  void enableVerbosity(uint8_t verbosity) { mVerbosity |= verbosity; }
239 
241  void disableVerbosity(uint8_t verbosity) { mVerbosity &= ~verbosity; }
242 
243  protected:
248  void fail() { setStatus(kStatusFailed); }
249 
256  void pass() { setStatus(kStatusPassed); }
257 
258  void init(const char* name) {
259  mName = internal::FCString(name);
260  mLifeCycle = kLifeCycleNew;
261  mStatus = kStatusUnknown;
262  mVerbosity = 0;
263  insert();
264  }
265 
266  void init(const __FlashStringHelper* name) {
267  mName = internal::FCString(name);
268  mLifeCycle = kLifeCycleNew;
269  mStatus = kStatusUnknown;
270  mVerbosity = 0;
271  insert();
272  }
273 
275  bool isVerbosity(uint8_t verbosity) { return mVerbosity & verbosity; }
276 
278  uint8_t getVerbosity() { return mVerbosity; }
279 
280  private:
281  // Disable copy-constructor and assignment operator
282  Test(const Test&) = delete;
283  Test& operator=(const Test&) = delete;
284 
286  void insert();
287 
288  internal::FCString mName;
289  uint8_t mLifeCycle;
290  uint8_t mStatus;
291  uint8_t mVerbosity;
292  Test* mNext;
293 };
294 
295 }
296 
297 #endif
void disableVerbosity(uint8_t verbosity)
Disable the given verbosity of the current test.
Definition: Test.h:241
Base class of all test cases.
Definition: Test.h:43
const internal::FCString & getName() const
Get the name of the test.
Definition: Test.h:158
void expire()
Mark the test as expired (i.e.
Definition: Test.h:235
static const uint8_t kStatusUnknown
Test status is unknown.
Definition: Test.h:96
static const uint8_t kStatusFailed
Test has failed, or fail() was called.
Definition: Test.h:102
void fail()
Mark the test as failed.
Definition: Test.h:248
static const uint8_t kLifeCycleAsserted
Test is asserted (using pass(), fail(), expired() or skipped()) and the getStatus() has been determin...
Definition: Test.h:80
void setPassOrFail(bool ok)
Set the status to Passed or Failed depending on ok.
Definition: Test.cpp:50
void resolve()
Print out the summary of the current test.
Definition: Test.cpp:73
A union of (const char*) and (const __FlashStringHelper*) with a discriminator.
Definition: FCString.h:55
bool isNotDone()
Return true if test is not has been asserted.
Definition: Test.h:199
static const uint8_t kStatusPassed
Test has passed, or pass() was called.
Definition: Test.h:99
bool isNotPassed()
Return true if test is not passed.
Definition: Test.h:205
uint8_t getVerbosity()
Get the verbosity.
Definition: Test.h:278
Test()
Empty constructor.
Definition: Test.cpp:41
uint8_t getLifeCycle()
Get the life cycle state of the test.
Definition: Test.h:161
Test ** getNext()
Return the next pointer as a pointer to the pointer, similar to getRoot().
Definition: Test.h:188
static const uint8_t kStatusSkipped
Test is skipped through the exclude() method or skip() was called.
Definition: Test.h:105
bool isPassed()
Return true if test is passed.
Definition: Test.h:202
virtual void setup()
Optional method that performs any initialization.
Definition: Test.h:136
static const uint8_t kLifeCycleExcluded
Test is Excluded by an exclude() method.
Definition: Test.h:65
virtual void loop()=0
The user-provided test case function.
void pass()
Mark the test as passed.
Definition: Test.h:256
void enableVerbosity(uint8_t verbosity)
Enable the given verbosity of the current test.
Definition: Test.h:238
static Test ** getRoot()
Get the pointer to the root pointer.
Definition: Test.cpp:36
bool isExpired()
Return true if test is expired.
Definition: Test.h:220
static const uint8_t kLifeCycleFinished
The test has completed its life cycle.
Definition: Test.h:88
bool isVerbosity(uint8_t verbosity)
Determine if any of the given verbosity is enabled.
Definition: Test.h:275
void skip()
Mark the test as skipped.
Definition: Test.h:229
bool isDone()
Return true if test has been asserted.
Definition: Test.h:196
bool isNotFailed()
Return true if test is not failed.
Definition: Test.h:211
static const uint8_t kLifeCycleNew
Test is new, needs to be setup.
Definition: Test.h:57
bool isFailed()
Return true if test is failed.
Definition: Test.h:208
static const uint8_t kLifeCycleSetup
Test has been set up by calling setup() and ready to execute the test code.
Definition: Test.h:74
static const uint8_t kStatusExpired
Test has timed out, or expire() called.
Definition: Test.h:108
bool isNotSkipped()
Return true if test is not skipped.
Definition: Test.h:217
virtual void teardown()
Optional method that performs any clean up after the test ends for any reasons, either passing or oth...
Definition: Test.h:145
bool isSkipped()
Return true if test is skipped.
Definition: Test.h:214
bool isNotExpired()
Return true if test is not expired.
Definition: Test.h:223
void setStatus(uint8_t status)
Set the status of the test.
Definition: Test.h:173
uint8_t getStatus()
Get the status of the test.
Definition: Test.h:166