AUnit  0.3.1
Unit testing framework for Arduino platforms inspired by ArduinoUnit.
Test.h
Go to the documentation of this file.
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 
35 #ifndef AUNIT_TEST_H
36 #define AUNIT_TEST_H
37 
38 #include <stdint.h>
39 #include "FCString.h"
40 
41 class __FlashStringHelper;
42 
43 // On the ESP8266 platform, The F() string cannot be placed in an inline
44 // context, because it interferes with other PROGMEM strings. See
45 // https://github.com/esp8266/Arduino/issues/3369. The solution was to move the
46 // constructor definition out from an inline function into a normal function
47 // defined outside of the class declaration..
48 
50 #define test(name) struct test_ ## name : aunit::TestOnce {\
51  test_ ## name();\
52  virtual void once() override;\
53 } test_ ## name ## _instance;\
54 test_ ## name :: test_ ## name() : TestOnce(F(#name)) {}\
55 void test_ ## name :: once()
56 
62 #define testing(name) struct test_ ## name : aunit::Test {\
63  test_ ## name();\
64  virtual void loop() override;\
65 } test_ ## name ## _instance;\
66 test_ ## name :: test_ ## name() : Test(F(#name)) {}\
67 void test_ ## name :: loop()
68 
74 #define externTest(name) struct test_ ## name : aunit::TestOnce {\
75  test_ ## name();\
76  void once();\
77 };\
78 extern test_##name test_##name##_instance
79 
86 #define externTesting(name) struct test_ ## name : aunit::Test {\
87  test_ ## name();\
88  void loop();\
89 };\
90 extern test_##name test_##name##_instance
91 
92 namespace aunit {
93 
100 class Test {
101  public:
102  // Don't change the order of Passed, Failed, Skipped or Expired without
103  // looking at the isDone() method.
104 
106  static const uint8_t kStatusNew = 0;
107 
109  static const uint8_t kStatusSetup = 1;
110 
112  static const uint8_t kStatusPassed = 2;
113 
115  static const uint8_t kStatusFailed = 3;
116 
118  static const uint8_t kStatusSkipped = 4;
119 
121  static const uint8_t kStatusExpired = 5;
122 
128  static Test** getRoot();
129 
135  explicit Test(const char* name);
136 
142  explicit Test(const __FlashStringHelper* name);
143 
148  virtual void setup() {}
149 
155  virtual void loop() = 0;
156 
158  const FCString& getName() { return mName; }
159 
161  uint8_t getStatus() { return mStatus; }
162 
164  void setStatus(uint8_t status) { mStatus = status; }
165 
167  void setPassOrFail(bool ok);
168 
174  Test** getNext() { return &mNext; }
175 
177  bool isDone() { return mStatus >= kStatusPassed; }
178 
180  bool isNotDone() { return !isDone(); }
181 
183  bool isPassed() { return mStatus == kStatusPassed; }
184 
186  bool isNotPassed() { return !isPassed(); }
187 
189  bool isFailed() { return mStatus == kStatusFailed; }
190 
192  bool isNotFailed() { return !isFailed(); }
193 
195  bool isSkipped() { return mStatus == kStatusSkipped; }
196 
198  bool isNotSkipped() { return !isSkipped(); }
199 
201  bool isExpired() { return mStatus == kStatusExpired; }
202 
204  bool isNotExpired() { return !isExpired(); }
205 
207  void skip() { mStatus = kStatusSkipped; }
208 
210  void expire() { mStatus = kStatusExpired; }
211 
212  protected:
214  void fail() { mStatus = kStatusFailed; }
215 
217  void pass() { mStatus = kStatusPassed; }
218 
219  private:
220  // Disable copy-constructor and assignment operator
221  Test(const Test&) = delete;
222  Test& operator=(const Test&) = delete;
223 
225  void insert();
226 
227  const FCString mName;
228  uint8_t mStatus;
229  Test* mNext;
230 };
231 
233 class TestOnce: public Test {
234  public:
236  explicit TestOnce(const char* name):
237  Test(name) {}
238 
240  explicit TestOnce(const __FlashStringHelper* name):
241  Test(name) {}
242 
248  virtual void loop() override;
249 
251  virtual void once() = 0;
252 
253  private:
254  // Disable copy-constructor and assignment operator
255  TestOnce(const TestOnce&) = delete;
256  TestOnce& operator=(const TestOnce&) = delete;
257 };
258 
259 }
260 #endif
virtual void once()=0
User-provided test case.
Base class of all test cases.
Definition: Test.h:100
void expire()
Mark the test as expired (i.e.
Definition: Test.h:210
TestOnce(const __FlashStringHelper *name)
Constructor.
Definition: Test.h:240
static const uint8_t kStatusFailed
Test has failed, or failed() was called.
Definition: Test.h:115
static const uint8_t kStatusNew
Test is new, needs to be setup.
Definition: Test.h:106
void fail()
Mark the test as failed.
Definition: Test.h:214
Similar to Test but performs the loop() method only once.
Definition: Test.h:233
Test(const char *name)
Constructor taking the name of the given test case.
Definition: Test.cpp:38
void setPassOrFail(bool ok)
Set the status to Passed or Failed depending on ok.
Definition: Test.cpp:54
bool isNotDone()
Return true if test is done (passed, failed, skipped, expired).
Definition: Test.h:180
static const uint8_t kStatusPassed
Test has passed, or pass() was called.
Definition: Test.h:112
bool isNotPassed()
Return true if test is passed.
Definition: Test.h:186
Test ** getNext()
Return the next pointer as a pointer to the pointer, similar to getRoot().
Definition: Test.h:174
static const uint8_t kStatusSkipped
Test is skipped, through the exclude() method or skip() was called.
Definition: Test.h:118
bool isPassed()
Return true if test is passed.
Definition: Test.h:183
virtual void setup()
Optional method that performs any initialization.
Definition: Test.h:148
virtual void loop()=0
The user-provided test case function.
void pass()
Mark the test as passed.
Definition: Test.h:217
static Test ** getRoot()
Get the pointer to the root pointer.
Definition: Test.cpp:33
bool isExpired()
Return true if test is expired.
Definition: Test.h:201
A union of (const char*) and (const __FlashStringHelper*) with a discriminator.
Definition: FCString.h:50
void skip()
Mark the test as skipped.
Definition: Test.h:207
bool isDone()
Return true if test is done (passed, failed, skipped, expired).
Definition: Test.h:177
bool isNotFailed()
Return true if test is failed.
Definition: Test.h:192
bool isFailed()
Return true if test is failed.
Definition: Test.h:189
TestOnce(const char *name)
Constructor.
Definition: Test.h:236
virtual void loop() override
Calls the user-provided once() method.
Definition: Test.cpp:77
static const uint8_t kStatusSetup
Test is set up.
Definition: Test.h:109
static const uint8_t kStatusExpired
Test has timed out, or expire() called.
Definition: Test.h:121
bool isNotSkipped()
Return true if test isNot skipped.
Definition: Test.h:198
const FCString & getName()
Get the name of the test.
Definition: Test.h:158
bool isSkipped()
Return true if test isNot skipped.
Definition: Test.h:195
bool isNotExpired()
Return true if test is expired.
Definition: Test.h:204
void setStatus(uint8_t status)
Set the status of the test.
Definition: Test.h:164
uint8_t getStatus()
Get the status of the test.
Definition: Test.h:161