AUnit  1.3
Unit testing framework for Arduino platforms inspired by ArduinoUnit and Google Test.
TestMacros.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 
36 #ifndef AUNIT_TEST_MACROS_H
37 #define AUNIT_TEST_MACROS_H
38 
39 #include <stdint.h>
40 #include <Arduino.h> // F() macro
41 #include "Flash.h" // AUNIT_F() macro
42 #include "FCString.h"
43 #include "TestOnce.h"
44 #include "TestAgain.h"
45 
46 // On the ESP8266 platform, the F() string cannot be placed in an inline
47 // context, because it interferes with other PROGMEM strings. See
48 // https://github.com/esp8266/Arduino/issues/3369. The solution was to move the
49 // constructor definition out from an inline function into a normal function
50 // defined outside of the class declaration. Unfortunately, if the user code
51 // has any other usage of F() in an inline context, those interfere with the
52 // F() used below. I have abandoned supporting the F() macro for these test*()
53 // macros on the ESP8266.
54 
62 #define test(...) \
63  GET_TEST(__VA_ARGS__, TEST2, TEST1)(__VA_ARGS__)
64 
65 #define GET_TEST(_1, _2, NAME, ...) NAME
66 
67 #define TEST1(name) \
68 class test_##name : public aunit::TestOnce {\
69 public:\
70  test_##name();\
71  void once() override;\
72 } test_##name##_instance;\
73 test_##name :: test_##name() {\
74  init(AUNIT_F(#name)); \
75 }\
76 void test_##name :: once()
77 
78 #define TEST2(suiteName, name) \
79 class suiteName##_##name : public aunit::TestOnce {\
80 public:\
81  suiteName##_##name();\
82  void once() override;\
83 } suiteName##_##name##_instance;\
84 suiteName##_##name :: suiteName##_##name() {\
85  init(AUNIT_F(#suiteName "_" #name)); \
86 }\
87 void suiteName##_##name :: once()
88 
98 #define testing(...) \
99  GET_TESTING(__VA_ARGS__, TESTING2, TESTING1)(__VA_ARGS__)
100 
101 #define GET_TESTING(_1, _2, NAME, ...) NAME
102 
103 #define TESTING1(name) \
104 class test_##name : public aunit::TestAgain {\
105 public:\
106  test_##name();\
107  void again() override;\
108 } test_##name##_instance;\
109 test_##name :: test_##name() {\
110  init(AUNIT_F(#name));\
111 }\
112 void test_##name :: again()
113 
114 #define TESTING2(suiteName, name) \
115 class suiteName##_##name : public aunit::TestAgain {\
116 public:\
117  suiteName##_##name();\
118  void again() override;\
119 } suiteName##_##name##_instance;\
120 suiteName##_##name :: suiteName##_##name() {\
121  init(AUNIT_F(#suiteName "_" #name));\
122 }\
123 void suiteName##_##name :: again()
124 
134 #define externTest(...) \
135  GET_EXTERN_TEST(__VA_ARGS__, EXTERN_TEST2, EXTERN_TEST1)(__VA_ARGS__)
136 
137 #define GET_EXTERN_TEST(_1, _2, NAME, ...) NAME
138 
139 #define EXTERN_TEST1(name) \
140 class test_##name : public aunit::TestOnce {\
141 public:\
142  test_##name();\
143  void once();\
144 };\
145 extern test_##name test_##name##_instance
146 
147 #define EXTERN_TEST2(suiteName, name) \
148 class suiteName##_##name : public aunit::TestOnce {\
149 public:\
150  suiteName##_##name();\
151  void once();\
152 };\
153 extern suiteName##_##name suiteName##_##name##_instance
154 
164 #define externTesting(...) \
165  GET_EXTERN_TESTING(__VA_ARGS__, EXTERN_TESTING2, EXTERN_TESTING1)(__VA_ARGS__)
166 
167 #define GET_EXTERN_TESTING(_1, _2, NAME, ...) NAME
168 
169 #define EXTERN_TESTING1(name) \
170 class test_ ## name : public aunit::TestAgain {\
171 public:\
172  test_ ## name();\
173  void again();\
174 };\
175 extern test_##name test_##name##_instance
176 
177 #define EXTERN_TESTING2(suiteName, name) \
178 class suiteName##_ ## name : public aunit::TestAgain {\
179 public:\
180  suiteName##_ ## name();\
181  void again();\
182 };\
183 extern suiteName##_##name suiteName##_##name##_instance
184 
190 #define testF(testClass, name) \
191 class testClass ## _ ## name : public testClass {\
192 public:\
193  testClass ## _ ## name();\
194  void once() override;\
195 } testClass ## _ ## name ## _instance;\
196 testClass ## _ ## name :: testClass ## _ ## name() {\
197  init(AUNIT_F(#testClass "_" #name));\
198 }\
199 void testClass ## _ ## name :: once()
200 
209 #define testingF(testClass, name) \
210 class testClass ## _ ## name : public testClass {\
211 public:\
212  testClass ## _ ## name();\
213  void again() override;\
214 } testClass ## _ ## name ## _instance;\
215 testClass ## _ ## name :: testClass ## _ ## name() {\
216  init(AUNIT_F(#testClass "_" #name));\
217 }\
218 void testClass ## _ ## name :: again()
219 
225 #define externTestF(testClass, name) \
226 class testClass ## _ ## name : public testClass {\
227 public:\
228  testClass ## _ ## name();\
229  void once() override;\
230 };\
231 extern testClass ## _ ## name testClass##_##name##_instance
232 
239 #define externTestingF(testClass, name) \
240 class testClass ## _ ## name : public testClass {\
241 public:\
242  testClass ## _ ## name();\
243  void again() override;\
244 };\
245 extern testClass ## _ ## name testClass##_##name##_instance
246 
247 #endif
Various macros to smooth over the differences among the various platforms with regards to their suppo...