AUnit  1.7.1
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() const { return mLifeCycle; }
162 
163  void setLifeCycle(uint8_t state) { mLifeCycle = state; }
164 
166  uint8_t getStatus() const { 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() const { return mStatus != kStatusUnknown; }
197 
199  bool isNotDone() const { return !isDone(); }
200 
202  bool isPassed() const { return mStatus == kStatusPassed; }
203 
205  bool isNotPassed() const { return !isPassed(); }
206 
208  bool isFailed() const { return mStatus == kStatusFailed; }
209 
211  bool isNotFailed() const { return !isFailed(); }
212 
214  bool isSkipped() const { return mStatus == kStatusSkipped; }
215 
217  bool isNotSkipped() const { return !isSkipped(); }
218 
220  bool isExpired() const { return mStatus == kStatusExpired; }
221 
223  bool isNotExpired() const { return !isExpired(); }
224 
230 
236 
238  void enableVerbosity(uint8_t verbosity) { mVerbosity |= verbosity; }
239 
241  void disableVerbosity(uint8_t verbosity) { mVerbosity &= ~verbosity; }
242 
243  protected:
249 
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) const { return mVerbosity & verbosity; }
276 
278  uint8_t getVerbosity() const { 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
Base class of all test cases.
Definition: Test.h:43
bool isNotDone() const
Return true if test is not has been asserted.
Definition: Test.h:199
Test()
Empty constructor.
Definition: Test.cpp:41
bool isDone() const
Return true if test has been asserted.
Definition: Test.h:196
virtual void loop()=0
The user-provided test case function.
bool isNotPassed() const
Return true if test is not passed.
Definition: Test.h:205
bool isPassed() const
Return true if test is passed.
Definition: Test.h:202
static const uint8_t kLifeCycleNew
Test is new, needs to be setup.
Definition: Test.h:57
static Test ** getRoot()
Get the pointer to the root pointer.
Definition: Test.cpp:36
void enableVerbosity(uint8_t verbosity)
Enable the given verbosity of the current test.
Definition: Test.h:238
bool isNotFailed() const
Return true if test is not failed.
Definition: Test.h:211
static const uint8_t kLifeCycleSetup
Test has been set up by calling setup() and ready to execute the test code.
Definition: Test.h:74
uint8_t getLifeCycle() const
Get the life cycle state of the test.
Definition: Test.h:161
static const uint8_t kStatusFailed
Test has failed, or fail() was called.
Definition: Test.h:102
bool isVerbosity(uint8_t verbosity) const
Determine if any of the given verbosity is enabled.
Definition: Test.h:275
bool isNotExpired() const
Return true if test is not expired.
Definition: Test.h:223
static const uint8_t kLifeCycleFinished
The test has completed its life cycle.
Definition: Test.h:88
void setStatus(uint8_t status)
Set the status of the test.
Definition: Test.h:173
static const uint8_t kStatusPassed
Test has passed, or pass() was called.
Definition: Test.h:99
bool isFailed() const
Return true if test is failed.
Definition: Test.h:208
void fail()
Mark the test as failed.
Definition: Test.h:248
bool isSkipped() const
Return true if test is skipped.
Definition: Test.h:214
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
static const uint8_t kStatusExpired
Test has timed out, or expire() called.
Definition: Test.h:108
uint8_t getVerbosity() const
Get the verbosity.
Definition: Test.h:278
void skip()
Mark the test as skipped.
Definition: Test.h:229
static const uint8_t kLifeCycleAsserted
Test is asserted (using pass(), fail(), expired() or skipped()) and the getStatus() has been determin...
Definition: Test.h:80
bool isNotSkipped() const
Return true if test is not skipped.
Definition: Test.h:217
static const uint8_t kStatusUnknown
Test status is unknown.
Definition: Test.h:96
static const uint8_t kStatusSkipped
Test is skipped through the exclude() method or skip() was called.
Definition: Test.h:105
uint8_t getStatus() const
Get the status of the test.
Definition: Test.h:166
void expire()
Mark the test as expired (i.e.
Definition: Test.h:235
static const uint8_t kLifeCycleExcluded
Test is Excluded by an exclude() method.
Definition: Test.h:65
void resolve()
Print out the summary of the current test.
Definition: Test.cpp:73
Test ** getNext()
Return the next pointer as a pointer to the pointer, similar to getRoot().
Definition: Test.h:188
void disableVerbosity(uint8_t verbosity)
Disable the given verbosity of the current test.
Definition: Test.h:241
virtual void setup()
Optional method that performs any initialization.
Definition: Test.h:136
void pass()
Mark the test as passed.
Definition: Test.h:256
void setPassOrFail(bool ok)
Set the status to Passed or Failed depending on ok.
Definition: Test.cpp:50
bool isExpired() const
Return true if test is expired.
Definition: Test.h:220
const internal::FCString & getName() const
Get the name of the test.
Definition: Test.h:158
A union of (const char*) and (const __FlashStringHelper*) with a discriminator.
Definition: FCString.h:58