AUnit  0.4.0
Unit testing framework for Arduino platforms inspired by ArduinoUnit and Google Test.
Assertion.cpp
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 #include <Arduino.h> // definition of Print
26 #include "TestRunner.h" // seems like a circular reference but ok from cpp file
27 #include "Printer.h"
28 #include "Assertion.h"
29 
30 namespace aunit {
31 
32 
33 // This can be a template function because it is accessed only through the
34 // various assertXxx() methods. Those assertXxx() methods are explicitly
35 // overloaded for the various types that we want to support.
36 //
37 // Prints something like the following:
38 // Assertion failed: (5) == (6), file Test.ino, line 820.
39 // Assertion passed: (6) == (6), file Test.ino, line 820.
40 template <typename A, typename B>
41 void printAssertionMessage(bool ok, const char* file, uint16_t line,
42  const A& lhs, const char *opName, const B& rhs) {
43 
44  // Don't use F() strings here because flash memory strings are not deduped by
45  // the compiler, so each template instantiation of this method causes a
46  // duplication of all the strings below. See
47  // https://github.com/mmurdoch/arduinounit/issues/70
48  // for more info.
49  Print* printer = Printer::getPrinter();
50  printer->print("Assertion ");
51  printer->print(ok ? "passed" : "failed");
52  printer->print(": (");
53  printer->print(lhs);
54  printer->print(") ");
55  printer->print(opName);
56  printer->print(" (");
57  printer->print(rhs);
58  printer->print(')');
59  // reuse string in MataAssertion::printAssertionTestStatusMessage()
60  printer->print(", file ");
61  printer->print(file);
62  printer->print(", line ");
63  printer->print(line);
64  printer->println('.');
65 }
66 
68  return (ok && isVerbosity(Verbosity::kAssertionPassed)) ||
70 }
71 
72 bool Assertion::assertion(const char* file, uint16_t line, bool lhs,
73  const char* opName, bool (*op)(bool lhs, bool rhs),
74  bool rhs) {
75  if (isDone()) return false;
76  bool ok = op(lhs, rhs);
77  if (isOutputEnabled(ok)) {
78  printAssertionMessage(ok, file, line, lhs, opName, rhs);
79  }
80  setPassOrFail(ok);
81  return ok;
82 }
83 
84 bool Assertion::assertion(const char* file, uint16_t line, char lhs,
85  const char* opName, bool (*op)(char lhs, char rhs),
86  char rhs) {
87  if (isDone()) return false;
88  bool ok = op(lhs, rhs);
89  if (isOutputEnabled(ok)) {
90  printAssertionMessage(ok, file, line, lhs, opName, rhs);
91  }
92  setPassOrFail(ok);
93  return ok;
94 }
95 
96 bool Assertion::assertion(const char* file, uint16_t line, int lhs,
97  const char* opName, bool (*op)(int lhs, int rhs),
98  int rhs) {
99  if (isDone()) return false;
100  bool ok = op(lhs, rhs);
101  if (isOutputEnabled(ok)) {
102  printAssertionMessage(ok, file, line, lhs, opName, rhs);
103  }
104  setPassOrFail(ok);
105  return ok;
106 }
107 
108 bool Assertion::assertion(const char* file, uint16_t line, unsigned int lhs,
109  const char* opName, bool (*op)(unsigned int lhs, unsigned int rhs),
110  unsigned int rhs) {
111  if (isDone()) return false;
112  bool ok = op(lhs, rhs);
113  if (isOutputEnabled(ok)) {
114  printAssertionMessage(ok, file, line, lhs, opName, rhs);
115  }
116  setPassOrFail(ok);
117  return ok;
118 }
119 
120 bool Assertion::assertion(const char* file, uint16_t line, long lhs,
121  const char* opName, bool (*op)(long lhs, long rhs),
122  long rhs) {
123  if (isDone()) return false;
124  bool ok = op(lhs, rhs);
125  if (isOutputEnabled(ok)) {
126  printAssertionMessage(ok, file, line, lhs, opName, rhs);
127  }
128  setPassOrFail(ok);
129  return ok;
130 }
131 
132 bool Assertion::assertion(const char* file, uint16_t line, unsigned long lhs,
133  const char* opName, bool (*op)(unsigned long lhs, unsigned long rhs),
134  unsigned long rhs) {
135  if (isDone()) return false;
136  bool ok = op(lhs, rhs);
137  if (isOutputEnabled(ok)) {
138  printAssertionMessage(ok, file, line, lhs, opName, rhs);
139  }
140  setPassOrFail(ok);
141  return ok;
142 }
143 
144 bool Assertion::assertion(const char* file, uint16_t line, double lhs,
145  const char* opName, bool (*op)(double lhs, double rhs),
146  double rhs) {
147  if (isDone()) return false;
148  bool ok = op(lhs, rhs);
149  if (isOutputEnabled(ok)) {
150  printAssertionMessage(ok, file, line, lhs, opName, rhs);
151  }
152  setPassOrFail(ok);
153  return ok;
154 }
155 
156 bool Assertion::assertion(const char* file, uint16_t line, const char* lhs,
157  const char* opName, bool (*op)(const char* lhs, const char* rhs),
158  const char* rhs) {
159  if (isDone()) return false;
160  bool ok = op(lhs, rhs);
161  if (isOutputEnabled(ok)) {
162  printAssertionMessage(ok, file, line, lhs, opName, rhs);
163  }
164  setPassOrFail(ok);
165  return ok;
166 }
167 
168 bool Assertion::assertion(const char* file, uint16_t line, const char* lhs,
169  const char *opName, bool (*op)(const char* lhs, const String& rhs),
170  const String& rhs) {
171  if (isDone()) return false;
172  bool ok = op(lhs, rhs);
173  if (isOutputEnabled(ok)) {
174  printAssertionMessage(ok, file, line, lhs, opName, rhs);
175  }
176  setPassOrFail(ok);
177  return ok;
178 }
179 
180 bool Assertion::assertion(const char* file, uint16_t line, const char* lhs,
181  const char *opName,
182  bool (*op)(const char* lhs, const __FlashStringHelper* rhs),
183  const __FlashStringHelper* rhs) {
184  if (isDone()) return false;
185  bool ok = op(lhs, rhs);
186  if (isOutputEnabled(ok)) {
187  printAssertionMessage(ok, file, line, lhs, opName, rhs);
188  }
189  setPassOrFail(ok);
190  return ok;
191 }
192 
193 bool Assertion::assertion(const char* file, uint16_t line, const String& lhs,
194  const char *opName, bool (*op)(const String& lhs, const char* rhs),
195  const char* rhs) {
196  if (isDone()) return false;
197  bool ok = op(lhs, rhs);
198  if (isOutputEnabled(ok)) {
199  printAssertionMessage(ok, file, line, lhs, opName, rhs);
200  }
201  setPassOrFail(ok);
202  return ok;
203 }
204 
205 bool Assertion::assertion(const char* file, uint16_t line, const String& lhs,
206  const char *opName, bool (*op)(const String& lhs, const String& rhs),
207  const String& rhs) {
208  if (isDone()) return false;
209  bool ok = op(lhs, rhs);
210  if (isOutputEnabled(ok)) {
211  printAssertionMessage(ok, file, line, lhs, opName, rhs);
212  }
213  setPassOrFail(ok);
214  return ok;
215 }
216 
217 bool Assertion::assertion(const char* file, uint16_t line, const String& lhs,
218  const char *opName,
219  bool (*op)(const String& lhs, const __FlashStringHelper* rhs),
220  const __FlashStringHelper* rhs) {
221  if (isDone()) return false;
222  bool ok = op(lhs, rhs);
223  if (isOutputEnabled(ok)) {
224  printAssertionMessage(ok, file, line, lhs, opName, rhs);
225  }
226  setPassOrFail(ok);
227  return ok;
228 }
229 
230 bool Assertion::assertion(const char* file, uint16_t line,
231  const __FlashStringHelper* lhs, const char *opName,
232  bool (*op)(const __FlashStringHelper* lhs, const char* rhs),
233  const char* rhs) {
234  if (isDone()) return false;
235  bool ok = op(lhs, rhs);
236  if (isOutputEnabled(ok)) {
237  printAssertionMessage(ok, file, line, lhs, opName, rhs);
238  }
239  setPassOrFail(ok);
240  return ok;
241 }
242 
243 bool Assertion::assertion(const char* file, uint16_t line,
244  const __FlashStringHelper* lhs, const char *opName,
245  bool (*op)(const __FlashStringHelper* lhs, const String& rhs),
246  const String& rhs) {
247  if (isDone()) return false;
248  bool ok = op(lhs, rhs);
249  if (isOutputEnabled(ok)) {
250  printAssertionMessage(ok, file, line, lhs, opName, rhs);
251  }
252  setPassOrFail(ok);
253  return ok;
254 }
255 
256 bool Assertion::assertion(const char* file, uint16_t line,
257  const __FlashStringHelper* lhs, const char *opName,
258  bool (*op)(const __FlashStringHelper* lhs, const __FlashStringHelper* rhs),
259  const __FlashStringHelper* rhs) {
260  if (isDone()) return false;
261  bool ok = op(lhs, rhs);
262  if (isOutputEnabled(ok)) {
263  printAssertionMessage(ok, file, line, lhs, opName, rhs);
264  }
265  setPassOrFail(ok);
266  return ok;
267 }
268 
269 }
void setPassOrFail(bool ok)
Set the status to Passed or Failed depending on ok.
Definition: Test.cpp:57
bool isOutputEnabled(bool ok)
Returns true if an assertion message should be printed.
Definition: Assertion.cpp:67
bool isVerbosity(uint8_t verbosity)
Determine if any of the given verbosity is enabled.
Definition: Test.h:181
static const uint8_t kAssertionPassed
Print assertXxx() passed message.
Definition: Verbosity.h:40
bool isDone()
Return true if test is done (passed, failed, skipped, expired).
Definition: Test.h:118
Various assertXxx() macros are defined in this header.
static Print * getPrinter()
Get the output printer used by the various assertion() methods and the TestRunner.
Definition: Printer.h:50
static const uint8_t kAssertionFailed
Print assertXxx() failed message.
Definition: Verbosity.h:43