AUnit  1.7.1
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 <stdint.h>
26 #include <Arduino.h> // definition of Print
27 #include "Flash.h"
28 #include "Printer.h"
29 #include "Assertion.h"
30 
31 #if ! defined(ARDUINO_ARCH_STM32)
32 #include "print64.h"
33 #endif
34 
35 namespace aunit {
36 
37 using namespace internal;
38 
39 namespace internal {
40 
41 // This can be a template function because it is accessed only through the
42 // various assertXxx() methods. Those assertXxx() methods are explicitly
43 // overloaded for the various types that we want to support.
44 //
45 // Prints something like the following:
46 // Test.ino:820: Assertion failed: (5) == (6).
47 // Test.ino:820: Assertion passed: (6) == (6).
48 template <typename A, typename B>
49 void printAssertionMessage(
50  Print* printer,
51  bool ok,
52  const char* file,
53  uint16_t line,
54  const A& lhs,
55  const char* opName,
56  const B& rhs
57 ) {
58 
59  // Don't use F() strings here because flash memory strings are not deduped by
60  // the compiler, so each template instantiation of this method causes a
61  // duplication of all the strings below. See
62  // https://github.com/mmurdoch/arduinounit/issues/70
63  // for more info. Normal (const char*) strings will be deduped by the
64  // compiler/linker.
65  printer->print(file);
66  printer->print(':');
67  printer->print(line);
68  printer->print(": Assertion ");
69  printer->print(ok ? "passed" : "failed");
70  printer->print(": (");
71  printer->print(lhs);
72  printer->print(") ");
73  printer->print(opName);
74  printer->print(" (");
75  printer->print(rhs);
76  printer->print(')');
77  printer->println('.');
78 }
79 
80 // Special version of (bool, bool) because Arduino Print.h converts
81 // bool into int, which prints out "(1) == (0)", which isn't as useful.
82 // This prints "(true) == (false)".
83 void printAssertionMessage(
84  Print* printer,
85  bool ok,
86  const char* file,
87  uint16_t line,
88  bool lhs,
89  const char* opName,
90  bool rhs
91 ) {
92 
93  // Don't use F() strings here. Same reason as above.
94  printer->print(file);
95  printer->print(':');
96  printer->print(line);
97  printer->print(": Assertion ");
98  printer->print(ok ? "passed" : "failed");
99  printer->print(": (");
100  printer->print(lhs ? "true" : "false");
101  printer->print(") ");
102  printer->print(opName);
103  printer->print(" (");
104  printer->print(rhs ? "true" : "false");
105  printer->print(')');
106  printer->println('.');
107 }
108 
109 #if ! defined(ARDUINO_ARCH_STM32)
110 
111 // Version for (long long, long long) because Print.h does not support int64.
112 void printAssertionMessage(
113  Print* printer,
114  bool ok,
115  const char* file,
116  uint16_t line,
117  long long& lhs,
118  const char* opName,
119  long long& rhs
120 ) {
121 
122  // Don't use F() strings here. Same reason as above.
123  printer->print(file);
124  printer->print(':');
125  printer->print(line);
126  printer->print(": Assertion ");
127  printer->print(ok ? "passed" : "failed");
128  printer->print(": (");
129  print64(*printer, lhs);
130  printer->print(") ");
131  printer->print(opName);
132  printer->print(" (");
133  print64(*printer, rhs);
134  printer->print(')');
135  printer->println('.');
136 }
137 
138 // Version for (unsigned long long, unsigned long long) because Print.h does
139 // not support int64.
140 void printAssertionMessage(
141  Print* printer,
142  bool ok,
143  const char* file,
144  uint16_t line,
145  unsigned long long& lhs,
146  const char* opName,
147  unsigned long long& rhs
148 ) {
149 
150  // Don't use F() strings here. Same reason as above.
151  printer->print(file);
152  printer->print(':');
153  printer->print(line);
154  printer->print(": Assertion ");
155  printer->print(ok ? "passed" : "failed");
156  printer->print(": (");
157  print64(*printer, lhs);
158  printer->print(") ");
159  printer->print(opName);
160  printer->print(" (");
161  print64(*printer, rhs);
162  printer->print(')');
163  printer->println('.');
164 }
165 
166 #endif // ARDUINO_ARCH_STM32
167 
168 // Special version for (const void*, const void*).
169 void printAssertionMessage(
170  Print* printer,
171  bool ok,
172  const char* file,
173  uint16_t line,
174  const void* lhs,
175  const char* opName,
176  const void* rhs
177 ) {
178 
179  // Don't use F() strings here. Same reason as above.
180  // Technically, we should cast to (uintptr_t). But all Arduino
181  // microcontrollers are 32-bit, so we can cast to (unsigned long) to avoid
182  // calling print64().
183  printer->print(file);
184  printer->print(':');
185  printer->print(line);
186  printer->print(": Assertion ");
187  printer->print(ok ? "passed" : "failed");
188  printer->print(": (0x");
189  printer->print((unsigned long) lhs, HEX);
190  printer->print(") ");
191  printer->print(opName);
192  printer->print(" (0x");
193  printer->print((unsigned long) rhs, HEX);
194  printer->print(')');
195  printer->println('.');
196 }
197 
198 // Special version for assertTrue(arg) and assertFalse(arg).
199 // Prints:
200 // "Test.ino:24: Assertion passed/failed: (arg) is true."
201 // "Test.ino:24: Assertion passed/failed: (arg) is false."
202 void printAssertionBoolMessage(
203  Print* printer,
204  bool ok,
205  const char* file,
206  uint16_t line,
207  bool arg,
208  bool value
209 ) {
210 
211  // Don't use F() strings here. Same reason as above.
212  printer->print(file);
213  printer->print(':');
214  printer->print(line);
215  printer->print(": Assertion ");
216  printer->print(ok ? "passed" : "failed");
217  printer->print(": (");
218  printer->print(arg ? "true" : "false");
219  printer->print(") is ");
220  printer->print(value ? "true" : "false");
221  printer->println('.');
222 }
223 
224 template <typename A>
225 void printAssertionNearMessage(
226  Print* printer,
227  bool ok,
228  const char* file,
229  uint16_t line,
230  const A& lhs,
231  const A& rhs,
232  const char* opName,
233  const A& error
234 ) {
235  printer->print(file);
236  printer->print(':');
237  printer->print(line);
238  printer->print(": Assertion ");
239  printer->print(ok ? "passed" : "failed");
240  printer->print(": |(");
241  printer->print(lhs);
242  printer->print(") - (");
243  printer->print(rhs);
244  printer->print(")| ");
245  printer->print(opName);
246  printer->print(" (");
247  printer->print(error);
248  printer->print(')');
249  printer->println('.');
250 }
251 
252 } // namespace
253 
254 bool Assertion::isOutputEnabled(bool ok) const {
255  return (ok && isVerbosity(Verbosity::kAssertionPassed)) ||
256  (!ok && isVerbosity(Verbosity::kAssertionFailed));
257 }
258 
260  const char* file,
261  uint16_t line,
262  bool arg,
263  bool value
264 ) {
265  if (isDone()) return false;
266  bool ok = (arg == value);
267  if (isOutputEnabled(ok)) {
268  printAssertionBoolMessage(Printer::getPrinter(), ok, file, line,
269  arg, value);
270  }
271  setPassOrFail(ok);
272  return ok;
273 }
274 
276  const char* file,
277  uint16_t line,
278  bool lhs,
279  const char* opName,
280  bool (*op)(bool lhs, bool rhs),
281  bool rhs
282 ) {
283  if (isDone()) return false;
284  bool ok = op(lhs, rhs);
285  if (isOutputEnabled(ok)) {
286  printAssertionMessage(Printer::getPrinter(), ok, file, line,
287  lhs, opName, rhs);
288  }
289  setPassOrFail(ok);
290  return ok;
291 }
292 
294  const char* file,
295  uint16_t line,
296  char lhs,
297  const char* opName,
298  bool (*op)(char lhs, char rhs),
299  char rhs
300 ) {
301  if (isDone()) return false;
302  bool ok = op(lhs, rhs);
303  if (isOutputEnabled(ok)) {
304  printAssertionMessage(Printer::getPrinter(), ok, file, line,
305  lhs, opName, rhs);
306  }
307  setPassOrFail(ok);
308  return ok;
309 }
310 
312  const char* file,
313  uint16_t line,
314  int lhs,
315  const char* opName,
316  bool (*op)(int lhs, int rhs),
317  int rhs
318 ) {
319  if (isDone()) return false;
320  bool ok = op(lhs, rhs);
321  if (isOutputEnabled(ok)) {
322  printAssertionMessage(Printer::getPrinter(), ok, file, line,
323  lhs, opName, rhs);
324  }
325  setPassOrFail(ok);
326  return ok;
327 }
328 
330  const char* file,
331  uint16_t line,
332  unsigned int lhs,
333  const char* opName,
334  bool (*op)(unsigned int lhs, unsigned int rhs),
335  unsigned int rhs
336 ) {
337  if (isDone()) return false;
338  bool ok = op(lhs, rhs);
339  if (isOutputEnabled(ok)) {
340  printAssertionMessage(Printer::getPrinter(), ok, file, line,
341  lhs, opName, rhs);
342  }
343  setPassOrFail(ok);
344  return ok;
345 }
346 
348  const char* file,
349  uint16_t line,
350  long lhs,
351  const char* opName,
352  bool (*op)(long lhs, long rhs),
353  long rhs
354 ) {
355  if (isDone()) return false;
356  bool ok = op(lhs, rhs);
357  if (isOutputEnabled(ok)) {
358  printAssertionMessage(Printer::getPrinter(), ok, file, line,
359  lhs, opName, rhs);
360  }
361  setPassOrFail(ok);
362  return ok;
363 }
364 
366  const char* file,
367  uint16_t line,
368  unsigned long lhs,
369  const char* opName,
370  bool (*op)(unsigned long lhs, unsigned long rhs),
371  unsigned long rhs
372 ) {
373  if (isDone()) return false;
374  bool ok = op(lhs, rhs);
375  if (isOutputEnabled(ok)) {
376  printAssertionMessage(Printer::getPrinter(), ok, file, line,
377  lhs, opName, rhs);
378  }
379  setPassOrFail(ok);
380  return ok;
381 }
382 
384  const char* file,
385  uint16_t line,
386  long long lhs,
387  const char* opName,
388  bool (*op)(long long lhs, long long rhs),
389  long long rhs
390 ) {
391  if (isDone()) return false;
392  bool ok = op(lhs, rhs);
393  if (isOutputEnabled(ok)) {
394  printAssertionMessage(Printer::getPrinter(), ok, file, line,
395  lhs, opName, rhs);
396  }
397  setPassOrFail(ok);
398  return ok;
399 }
400 
402  const char* file,
403  uint16_t line,
404  unsigned long long lhs,
405  const char* opName,
406  bool (*op)(unsigned long long lhs, unsigned long long rhs),
407  unsigned long long rhs
408 ) {
409  if (isDone()) return false;
410  bool ok = op(lhs, rhs);
411  if (isOutputEnabled(ok)) {
412  printAssertionMessage(Printer::getPrinter(), ok, file, line,
413  lhs, opName, rhs);
414  }
415  setPassOrFail(ok);
416  return ok;
417 }
418 
420  const char* file,
421  uint16_t line,
422  double lhs,
423  const char* opName,
424  bool (*op)(double lhs, double rhs),
425  double rhs
426 ) {
427  if (isDone()) return false;
428  bool ok = op(lhs, rhs);
429  if (isOutputEnabled(ok)) {
430  printAssertionMessage(Printer::getPrinter(), ok, file, line,
431  lhs, opName, rhs);
432  }
433  setPassOrFail(ok);
434  return ok;
435 }
436 
438  const char* file,
439  uint16_t line,
440  const void* lhs,
441  const char* opName,
442  bool (*op)(const void* lhs, const void* rhs),
443  const void* rhs
444 ) {
445  if (isDone()) return false;
446  bool ok = op(lhs, rhs);
447  if (isOutputEnabled(ok)) {
448  printAssertionMessage(Printer::getPrinter(), ok, file, line,
449  lhs, opName, rhs);
450  }
451  setPassOrFail(ok);
452  return ok;
453 }
454 
456  const char* file,
457  uint16_t line,
458  const char* lhs,
459  const char* opName,
460  bool (*op)(const char* lhs, const char* rhs),
461  const char* rhs
462 ) {
463  if (isDone()) return false;
464  bool ok = op(lhs, rhs);
465  if (isOutputEnabled(ok)) {
466  printAssertionMessage(Printer::getPrinter(), ok, file, line,
467  lhs, opName, rhs);
468  }
469  setPassOrFail(ok);
470  return ok;
471 }
472 
474  const char* file,
475  uint16_t line,
476  const char* lhs,
477  const char* opName,
478  bool (*op)(const char* lhs, const String& rhs),
479  const String& rhs
480 ) {
481  if (isDone()) return false;
482  bool ok = op(lhs, rhs);
483  if (isOutputEnabled(ok)) {
484  printAssertionMessage(Printer::getPrinter(), ok, file, line,
485  lhs, opName, rhs);
486  }
487  setPassOrFail(ok);
488  return ok;
489 }
490 
492  const char* file,
493  uint16_t line,
494  const char* lhs,
495  const char* opName,
496  bool (*op)(const char* lhs, const __FlashStringHelper* rhs),
497  const __FlashStringHelper* rhs
498 ) {
499  if (isDone()) return false;
500  bool ok = op(lhs, rhs);
501  if (isOutputEnabled(ok)) {
502  printAssertionMessage(Printer::getPrinter(), ok, file, line,
503  lhs, opName, rhs);
504  }
505  setPassOrFail(ok);
506  return ok;
507 }
508 
510  const char* file,
511  uint16_t line,
512  const String& lhs,
513  const char* opName,
514  bool (*op)(const String& lhs, const char* rhs),
515  const char* rhs
516 ) {
517  if (isDone()) return false;
518  bool ok = op(lhs, rhs);
519  if (isOutputEnabled(ok)) {
520  printAssertionMessage(Printer::getPrinter(), ok, file, line,
521  lhs, opName, rhs);
522  }
523  setPassOrFail(ok);
524  return ok;
525 }
526 
528  const char* file,
529  uint16_t line,
530  const String& lhs,
531  const char* opName,
532  bool (*op)(const String& lhs, const String& rhs),
533  const String& rhs
534 ) {
535  if (isDone()) return false;
536  bool ok = op(lhs, rhs);
537  if (isOutputEnabled(ok)) {
538  printAssertionMessage(Printer::getPrinter(), ok, file, line,
539  lhs, opName, rhs);
540  }
541  setPassOrFail(ok);
542  return ok;
543 }
544 
546  const char* file,
547  uint16_t line,
548  const String& lhs,
549  const char* opName,
550  bool (*op)(const String& lhs, const __FlashStringHelper* rhs),
551  const __FlashStringHelper* rhs
552 ) {
553  if (isDone()) return false;
554  bool ok = op(lhs, rhs);
555  if (isOutputEnabled(ok)) {
556  printAssertionMessage(Printer::getPrinter(), ok, file, line,
557  lhs, opName, rhs);
558  }
559  setPassOrFail(ok);
560  return ok;
561 }
562 
564  const char* file,
565  uint16_t line,
566  const __FlashStringHelper* lhs,
567  const char* opName,
568  bool (*op)(const __FlashStringHelper* lhs, const char* rhs),
569  const char* rhs
570 ) {
571  if (isDone()) return false;
572  bool ok = op(lhs, rhs);
573  if (isOutputEnabled(ok)) {
574  printAssertionMessage(Printer::getPrinter(), ok, file, line,
575  lhs, opName, rhs);
576  }
577  setPassOrFail(ok);
578  return ok;
579 }
580 
582  const char* file,
583  uint16_t line,
584  const __FlashStringHelper* lhs,
585  const char* opName,
586  bool (*op)(const __FlashStringHelper* lhs, const String& rhs),
587  const String& rhs
588 ) {
589  if (isDone()) return false;
590  bool ok = op(lhs, rhs);
591  if (isOutputEnabled(ok)) {
592  printAssertionMessage(Printer::getPrinter(), ok, file, line,
593  lhs, opName, rhs);
594  }
595  setPassOrFail(ok);
596  return ok;
597 }
598 
600  const char* file,
601  uint16_t line,
602  const __FlashStringHelper* lhs,
603  const char* opName,
604  bool (*op)(const __FlashStringHelper* lhs, const __FlashStringHelper* rhs),
605  const __FlashStringHelper* rhs
606 ) {
607  if (isDone()) return false;
608  bool ok = op(lhs, rhs);
609  if (isOutputEnabled(ok)) {
610  printAssertionMessage(Printer::getPrinter(), ok, file, line,
611  lhs, opName, rhs);
612  }
613  setPassOrFail(ok);
614  return ok;
615 }
616 
618  const char* file,
619  uint16_t line,
620  int lhs,
621  int rhs,
622  int error,
623  const char* opName,
624  bool (*opNear)(int lhs, int rhs, int error)
625 ) {
626  if (isDone()) return false;
627  bool ok = opNear(lhs, rhs, error);
628  if (isOutputEnabled(ok)) {
629  printAssertionNearMessage(Printer::getPrinter(), ok, file, line,
630  lhs, rhs, opName, error);
631  }
632  setPassOrFail(ok);
633  return ok;
634 }
635 
637  const char* file,
638  uint16_t line,
639  unsigned int lhs,
640  unsigned int rhs,
641  unsigned int error,
642  const char* opName,
643  bool (*opNear)(unsigned int lhs, unsigned int rhs, unsigned int error)
644 ) {
645  if (isDone()) return false;
646  bool ok = opNear(lhs, rhs, error);
647  if (isOutputEnabled(ok)) {
648  printAssertionNearMessage(Printer::getPrinter(), ok, file, line,
649  lhs, rhs, opName, error);
650  }
651  setPassOrFail(ok);
652  return ok;
653 }
654 
656  const char* file,
657  uint16_t line,
658  long lhs,
659  long rhs,
660  long error,
661  const char* opName,
662  bool (*opNear)(long lhs, long rhs, long error)
663 ) {
664  if (isDone()) return false;
665  bool ok = opNear(lhs, rhs, error);
666  if (isOutputEnabled(ok)) {
667  printAssertionNearMessage(Printer::getPrinter(), ok, file, line,
668  lhs, rhs, opName, error);
669  }
670  setPassOrFail(ok);
671  return ok;
672 }
673 
675  const char* file,
676  uint16_t line,
677  unsigned long lhs,
678  unsigned long rhs,
679  unsigned long error,
680  const char* opName,
681  bool (*opNear)(unsigned long lhs, unsigned long rhs, unsigned long error)
682 ) {
683  if (isDone()) return false;
684  bool ok = opNear(lhs, rhs, error);
685  if (isOutputEnabled(ok)) {
686  printAssertionNearMessage(Printer::getPrinter(), ok, file, line,
687  lhs, rhs, opName, error);
688  }
689  setPassOrFail(ok);
690  return ok;
691 }
692 
694  const char* file,
695  uint16_t line,
696  double lhs,
697  double rhs,
698  double error,
699  const char* opName,
700  bool (*opNear)(double lhs, double rhs, double error)
701 ) {
702  if (isDone()) return false;
703  bool ok = opNear(lhs, rhs, error);
704  if (isOutputEnabled(ok)) {
705  printAssertionNearMessage(Printer::getPrinter(), ok, file, line,
706  lhs, rhs, opName, error);
707  }
708  setPassOrFail(ok);
709  return ok;
710 }
711 
712 //---------------------------------------------------------------------------
713 
714 namespace internal {
715 
716 // Verbose versions of above which accept the string arguments of the
717 // assertXxx() macros, so that the error messages are more verbose.
718 //
719 // Prints something like the following:
720 // Test.ino:820: Assertion failed: (x=5) == (y=6).
721 // Test.ino:820: Assertion passed: (x=6) == (y=6).
722 template <typename A, typename B>
723 void printAssertionMessageVerbose(
724  Print* printer,
725  bool ok,
726  const char* file,
727  uint16_t line,
728  const A& lhs,
729  const __FlashStringHelper* lhsString,
730  const char* opName,
731  const B& rhs,
732  const __FlashStringHelper* rhsString
733 ) {
734 
735  // Don't use F() strings here because flash memory strings are not deduped by
736  // the compiler, so each template instantiation of this method causes a
737  // duplication of all the strings below. See
738  // https://github.com/mmurdoch/arduinounit/issues/70
739  // for more info.
740  printer->print(file);
741  printer->print(':');
742  printer->print(line);
743  printer->print(": Assertion ");
744  printer->print(ok ? "passed" : "failed");
745  printer->print(": (");
746  printer->print(lhsString);
747  printer->print('=');
748  printer->print(lhs);
749  printer->print(") ");
750  printer->print(opName);
751  printer->print(" (");
752  printer->print(rhsString);
753  printer->print('=');
754  printer->print(rhs);
755  printer->print(')');
756  printer->println('.');
757 }
758 
759 // Special version of (bool, bool) because Arduino Print.h converts
760 // bool into int, which prints out "(1) == (0)", which isn't as useful.
761 // This prints "(x=true) == (y=false)".
762 void printAssertionMessageVerbose(
763  Print* printer,
764  bool ok,
765  const char* file,
766  uint16_t line,
767  bool lhs,
768  const __FlashStringHelper* lhsString,
769  const char* opName,
770  bool rhs,
771  const __FlashStringHelper* rhsString
772 ) {
773 
774  // Don't use F() strings here. Same reason as above.
775  printer->print(file);
776  printer->print(':');
777  printer->print(line);
778  printer->print(": Assertion ");
779  printer->print(ok ? "passed" : "failed");
780  printer->print(": (");
781  printer->print(lhsString);
782  printer->print('=');
783  printer->print(lhs ? "true" : "false");
784  printer->print(") ");
785  printer->print(opName);
786  printer->print(" (");
787  printer->print(rhsString);
788  printer->print('=');
789  printer->print(rhs ? "true" : "false");
790  printer->print(')');
791  printer->println('.');
792 }
793 
794 #if ! defined(ARDUINO_ARCH_STM32)
795 
796 // Version for (long long, long long) because Print.h does not support int64.
797 void printAssertionMessageVerbose(
798  Print* printer,
799  bool ok,
800  const char* file,
801  uint16_t line,
802  long long& lhs,
803  const __FlashStringHelper* lhsString,
804  const char* opName,
805  long long& rhs,
806  const __FlashStringHelper* rhsString
807 ) {
808 
809  // Don't use F() strings here. Same reason as above.
810  printer->print(file);
811  printer->print(':');
812  printer->print(line);
813  printer->print(": Assertion ");
814  printer->print(ok ? "passed" : "failed");
815  printer->print(": (");
816  printer->print(lhsString);
817  printer->print('=');
818  print64(*printer, lhs);
819  printer->print(") ");
820  printer->print(opName);
821  printer->print(" (");
822  printer->print(rhsString);
823  printer->print('=');
824  print64(*printer, rhs);
825  printer->print(')');
826  printer->println('.');
827 }
828 
829 // Version for (unsigned long long, unsigned long long) because Print.h does
830 // not support int64.
831 void printAssertionMessageVerbose(
832  Print* printer,
833  bool ok,
834  const char* file,
835  uint16_t line,
836  unsigned long long& lhs,
837  const __FlashStringHelper* lhsString,
838  const char* opName,
839  unsigned long long& rhs,
840  const __FlashStringHelper* rhsString
841 ) {
842 
843  // Don't use F() strings here. Same reason as above.
844  printer->print(file);
845  printer->print(':');
846  printer->print(line);
847  printer->print(": Assertion ");
848  printer->print(ok ? "passed" : "failed");
849  printer->print(": (");
850  printer->print(lhsString);
851  printer->print('=');
852  print64(*printer, lhs);
853  printer->print(") ");
854  printer->print(opName);
855  printer->print(" (");
856  printer->print(rhsString);
857  printer->print('=');
858  print64(*printer, rhs);
859  printer->print(')');
860  printer->println('.');
861 }
862 
863 #endif // ARDUINO_ARCH_STM32
864 
865 // Special version for (const void*, const void *).
866 void printAssertionMessageVerbose(
867  Print* printer,
868  bool ok,
869  const char* file,
870  uint16_t line,
871  const void* lhs,
872  const __FlashStringHelper* lhsString,
873  const char* opName,
874  const void* rhs,
875  const __FlashStringHelper* rhsString
876 ) {
877 
878  // Don't use F() strings here. Same reason as above.
879  // Technically, we should cast to (uintptr_t). But all Arduino
880  // microcontrollers are 32-bit, so we can cast to (unsigned long) to avoid
881  // calling print64().
882  printer->print(file);
883  printer->print(':');
884  printer->print(line);
885  printer->print(": Assertion ");
886  printer->print(ok ? "passed" : "failed");
887  printer->print(": (");
888  printer->print(lhsString);
889  printer->print("=0x");
890  printer->print((unsigned long) lhs, HEX);
891  printer->print(") ");
892  printer->print(opName);
893  printer->print(" (");
894  printer->print(rhsString);
895  printer->print("=0x");
896  printer->print((unsigned long) rhs, HEX);
897  printer->print(')');
898  printer->println('.');
899 }
900 
901 // Special version for assertTrue(arg) and assertFalse(arg).
902 // Prints:
903 // "Test.ino:123: Assertion passed/failed: (x=arg) is true"
904 // "Test.ino:123: Assertion passed/failed: (x=arg) is false"
905 void printAssertionBoolMessageVerbose(
906  Print* printer,
907  bool ok,
908  const char* file,
909  uint16_t line,
910  bool arg,
911  const __FlashStringHelper* argString,
912  bool value
913 ) {
914 
915  // Don't use F() strings here. Same reason as above.
916  printer->print(file);
917  printer->print(':');
918  printer->print(line);
919  printer->print(": Assertion ");
920  printer->print(ok ? "passed" : "failed");
921  printer->print(": (");
922  printer->print(argString);
923  printer->print('=');
924  printer->print(arg ? "true" : "false");
925  printer->print(") is ");
926  printer->print(value ? "true" : "false");
927  printer->println('.');
928 }
929 
930 template <typename A>
931 void printAssertionNearMessageVerbose(
932  Print* printer,
933  bool ok,
934  const char* file,
935  uint16_t line,
936  const A& lhs,
937  const __FlashStringHelper* lhsString,
938  const A& rhs,
939  const __FlashStringHelper* rhsString,
940  const char* opName,
941  const A& error,
942  const __FlashStringHelper* errorString
943 ) {
944  printer->print(file);
945  printer->print(':');
946  printer->print(line);
947  printer->print(": Assertion ");
948  printer->print(ok ? "passed" : "failed");
949  printer->print(": |(");
950  printer->print(lhsString);
951  printer->print('=');
952  printer->print(lhs);
953  printer->print(") - (");
954  printer->print(rhsString);
955  printer->print('=');
956  printer->print(rhs);
957  printer->print(")| ");
958  printer->print(opName);
959  printer->print(" (");
960  printer->print(errorString);
961  printer->print('=');
962  printer->print(error);
963  printer->print(')');
964  printer->println('.');
965 }
966 
967 } // namespace
968 
970  const char* file,
971  uint16_t line,
972  bool arg,
973  const __FlashStringHelper* argString,
974  bool value
975 ) {
976  if (isDone()) return false;
977  bool ok = (arg == value);
978  if (isOutputEnabled(ok)) {
979  printAssertionBoolMessageVerbose(Printer::getPrinter(), ok, file, line,
980  arg, argString, value);
981  }
982  setPassOrFail(ok);
983  return ok;
984 }
985 
987  const char* file,
988  uint16_t line,
989  bool lhs,
990  const __FlashStringHelper* lhsString,
991  const char* opName,
992  bool (*op)(bool lhs, bool rhs),
993  bool rhs,
994  const __FlashStringHelper* rhsString
995 ) {
996  if (isDone()) return false;
997  bool ok = op(lhs, rhs);
998  if (isOutputEnabled(ok)) {
999  printAssertionMessageVerbose(Printer::getPrinter(), ok, file, line,
1000  lhs, lhsString, opName, rhs, rhsString);
1001  }
1002  setPassOrFail(ok);
1003  return ok;
1004 }
1005 
1007  const char* file,
1008  uint16_t line,
1009  char lhs,
1010  const __FlashStringHelper* lhsString,
1011  const char* opName,
1012  bool (*op)(char lhs, char rhs),
1013  char rhs,
1014  const __FlashStringHelper* rhsString
1015 ) {
1016  if (isDone()) return false;
1017  bool ok = op(lhs, rhs);
1018  if (isOutputEnabled(ok)) {
1019  printAssertionMessageVerbose(Printer::getPrinter(), ok, file, line,
1020  lhs, lhsString, opName, rhs, rhsString);
1021  }
1022  setPassOrFail(ok);
1023  return ok;
1024 }
1025 
1027  const char* file,
1028  uint16_t line,
1029  int lhs,
1030  const __FlashStringHelper* lhsString,
1031  const char* opName,
1032  bool (*op)(int lhs, int rhs),
1033  int rhs,
1034  const __FlashStringHelper* rhsString
1035 ) {
1036  if (isDone()) return false;
1037  bool ok = op(lhs, rhs);
1038  if (isOutputEnabled(ok)) {
1039  printAssertionMessageVerbose(Printer::getPrinter(), ok, file, line,
1040  lhs, lhsString, opName, rhs, rhsString);
1041  }
1042  setPassOrFail(ok);
1043  return ok;
1044 }
1045 
1047  const char* file,
1048  uint16_t line,
1049  unsigned int lhs,
1050  const __FlashStringHelper* lhsString,
1051  const char* opName,
1052  bool (*op)(unsigned int lhs, unsigned int rhs),
1053  unsigned int rhs,
1054  const __FlashStringHelper* rhsString
1055 ) {
1056  if (isDone()) return false;
1057  bool ok = op(lhs, rhs);
1058  if (isOutputEnabled(ok)) {
1059  printAssertionMessageVerbose(Printer::getPrinter(), ok, file, line,
1060  lhs, lhsString, opName, rhs, rhsString);
1061  }
1062  setPassOrFail(ok);
1063  return ok;
1064 }
1065 
1067  const char* file,
1068  uint16_t line,
1069  long lhs,
1070  const __FlashStringHelper* lhsString,
1071  const char* opName,
1072  bool (*op)(long lhs, long rhs),
1073  long rhs,
1074  const __FlashStringHelper* rhsString
1075 ) {
1076  if (isDone()) return false;
1077  bool ok = op(lhs, rhs);
1078  if (isOutputEnabled(ok)) {
1079  printAssertionMessageVerbose(Printer::getPrinter(), ok, file, line,
1080  lhs, lhsString, opName, rhs, rhsString);
1081  }
1082  setPassOrFail(ok);
1083  return ok;
1084 }
1085 
1087  const char* file,
1088  uint16_t line,
1089  unsigned long lhs,
1090  const __FlashStringHelper* lhsString,
1091  const char* opName,
1092  bool (*op)(unsigned long lhs, unsigned long rhs),
1093  unsigned long rhs,
1094  const __FlashStringHelper* rhsString
1095 ) {
1096  if (isDone()) return false;
1097  bool ok = op(lhs, rhs);
1098  if (isOutputEnabled(ok)) {
1099  printAssertionMessageVerbose(Printer::getPrinter(), ok, file, line,
1100  lhs, lhsString, opName, rhs, rhsString);
1101  }
1102  setPassOrFail(ok);
1103  return ok;
1104 }
1105 
1107  const char* file,
1108  uint16_t line,
1109  long long lhs,
1110  const __FlashStringHelper* lhsString,
1111  const char* opName,
1112  bool (*op)(long long lhs, long long rhs),
1113  long long rhs,
1114  const __FlashStringHelper* rhsString
1115 ) {
1116  if (isDone()) return false;
1117  bool ok = op(lhs, rhs);
1118  if (isOutputEnabled(ok)) {
1119  printAssertionMessageVerbose(Printer::getPrinter(), ok, file, line,
1120  lhs, lhsString, opName, rhs, rhsString);
1121  }
1122  setPassOrFail(ok);
1123  return ok;
1124 }
1125 
1127  const char* file,
1128  uint16_t line,
1129  unsigned long long lhs,
1130  const __FlashStringHelper* lhsString,
1131  const char* opName,
1132  bool (*op)(unsigned long long lhs, unsigned long long rhs),
1133  unsigned long long rhs,
1134  const __FlashStringHelper* rhsString
1135 ) {
1136  if (isDone()) return false;
1137  bool ok = op(lhs, rhs);
1138  if (isOutputEnabled(ok)) {
1139  printAssertionMessageVerbose(Printer::getPrinter(), ok, file, line,
1140  lhs, lhsString, opName, rhs, rhsString);
1141  }
1142  setPassOrFail(ok);
1143  return ok;
1144 }
1145 
1147  const char* file,
1148  uint16_t line,
1149  double lhs,
1150  const __FlashStringHelper* lhsString,
1151  const char* opName,
1152  bool (*op)(double lhs, double rhs),
1153  double rhs,
1154  const __FlashStringHelper* rhsString
1155 ) {
1156  if (isDone()) return false;
1157  bool ok = op(lhs, rhs);
1158  if (isOutputEnabled(ok)) {
1159  printAssertionMessageVerbose(Printer::getPrinter(), ok, file, line,
1160  lhs, lhsString, opName, rhs, rhsString);
1161  }
1162  setPassOrFail(ok);
1163  return ok;
1164 }
1165 
1167  const char* file,
1168  uint16_t line,
1169  const void* lhs,
1170  const __FlashStringHelper* lhsString,
1171  const char* opName,
1172  bool (*op)(const void* lhs, const void* rhs),
1173  const void* rhs,
1174  const __FlashStringHelper* rhsString
1175 ) {
1176  if (isDone()) return false;
1177  bool ok = op(lhs, rhs);
1178  if (isOutputEnabled(ok)) {
1179  printAssertionMessageVerbose(Printer::getPrinter(), ok, file, line,
1180  lhs, lhsString, opName, rhs, rhsString);
1181  }
1182  setPassOrFail(ok);
1183  return ok;
1184 }
1185 
1187  const char* file,
1188  uint16_t line,
1189  const char* lhs,
1190  const __FlashStringHelper* lhsString,
1191  const char* opName,
1192  bool (*op)(const char* lhs, const char* rhs),
1193  const char* rhs,
1194  const __FlashStringHelper* rhsString
1195 ) {
1196  if (isDone()) return false;
1197  bool ok = op(lhs, rhs);
1198  if (isOutputEnabled(ok)) {
1199  printAssertionMessageVerbose(Printer::getPrinter(), ok, file, line,
1200  lhs, lhsString, opName, rhs, rhsString);
1201  }
1202  setPassOrFail(ok);
1203  return ok;
1204 }
1205 
1207  const char* file,
1208  uint16_t line,
1209  const char* lhs,
1210  const __FlashStringHelper* lhsString,
1211  const char* opName,
1212  bool (*op)(const char* lhs, const String& rhs),
1213  const String& rhs,
1214  const __FlashStringHelper* rhsString
1215 ) {
1216  if (isDone()) return false;
1217  bool ok = op(lhs, rhs);
1218  if (isOutputEnabled(ok)) {
1219  printAssertionMessageVerbose(Printer::getPrinter(), ok, file, line,
1220  lhs, lhsString, opName, rhs, rhsString);
1221  }
1222  setPassOrFail(ok);
1223  return ok;
1224 }
1225 
1227  const char* file,
1228  uint16_t line,
1229  const char* lhs,
1230  const __FlashStringHelper* lhsString,
1231  const char* opName,
1232  bool (*op)(const char* lhs, const __FlashStringHelper* rhs),
1233  const __FlashStringHelper* rhs,
1234  const __FlashStringHelper* rhsString
1235 ) {
1236  if (isDone()) return false;
1237  bool ok = op(lhs, rhs);
1238  if (isOutputEnabled(ok)) {
1239  printAssertionMessageVerbose(Printer::getPrinter(), ok, file, line,
1240  lhs, lhsString, opName, rhs, rhsString);
1241  }
1242  setPassOrFail(ok);
1243  return ok;
1244 }
1245 
1247  const char* file,
1248  uint16_t line,
1249  const String& lhs,
1250  const __FlashStringHelper* lhsString,
1251  const char* opName,
1252  bool (*op)(const String& lhs, const char* rhs),
1253  const char* rhs,
1254  const __FlashStringHelper* rhsString
1255 ) {
1256  if (isDone()) return false;
1257  bool ok = op(lhs, rhs);
1258  if (isOutputEnabled(ok)) {
1259  printAssertionMessageVerbose(Printer::getPrinter(), ok, file, line,
1260  lhs, lhsString, opName, rhs, rhsString);
1261  }
1262  setPassOrFail(ok);
1263  return ok;
1264 }
1265 
1267  const char* file,
1268  uint16_t line,
1269  const String& lhs,
1270  const __FlashStringHelper* lhsString,
1271  const char* opName,
1272  bool (*op)(const String& lhs, const String& rhs),
1273  const String& rhs,
1274  const __FlashStringHelper* rhsString
1275 ) {
1276  if (isDone()) return false;
1277  bool ok = op(lhs, rhs);
1278  if (isOutputEnabled(ok)) {
1279  printAssertionMessageVerbose(Printer::getPrinter(), ok, file, line,
1280  lhs, lhsString, opName, rhs, rhsString);
1281  }
1282  setPassOrFail(ok);
1283  return ok;
1284 }
1285 
1287  const char* file,
1288  uint16_t line,
1289  const String& lhs,
1290  const __FlashStringHelper* lhsString,
1291  const char* opName,
1292  bool (*op)(const String& lhs, const __FlashStringHelper* rhs),
1293  const __FlashStringHelper* rhs,
1294  const __FlashStringHelper* rhsString
1295 ) {
1296  if (isDone()) return false;
1297  bool ok = op(lhs, rhs);
1298  if (isOutputEnabled(ok)) {
1299  printAssertionMessageVerbose(Printer::getPrinter(), ok, file, line,
1300  lhs, lhsString, opName, rhs, rhsString);
1301  }
1302  setPassOrFail(ok);
1303  return ok;
1304 }
1305 
1307  const char* file,
1308  uint16_t line,
1309  const __FlashStringHelper* lhs,
1310  const __FlashStringHelper* lhsString,
1311  const char* opName,
1312  bool (*op)(const __FlashStringHelper* lhs,
1313  const char* rhs),
1314  const char* rhs,
1315  const __FlashStringHelper* rhsString
1316 ) {
1317  if (isDone()) return false;
1318  bool ok = op(lhs, rhs);
1319  if (isOutputEnabled(ok)) {
1320  printAssertionMessageVerbose(Printer::getPrinter(), ok, file, line,
1321  lhs, lhsString, opName, rhs, rhsString);
1322  }
1323  setPassOrFail(ok);
1324  return ok;
1325 }
1326 
1328  const char* file,
1329  uint16_t line,
1330  const __FlashStringHelper* lhs,
1331  const __FlashStringHelper* lhsString,
1332  const char* opName,
1333  bool (*op)(const __FlashStringHelper* lhs, const String& rhs),
1334  const String& rhs,
1335  const __FlashStringHelper* rhsString
1336 ) {
1337  if (isDone()) return false;
1338  bool ok = op(lhs, rhs);
1339  if (isOutputEnabled(ok)) {
1340  printAssertionMessageVerbose(Printer::getPrinter(), ok, file, line,
1341  lhs, lhsString, opName, rhs, rhsString);
1342  }
1343  setPassOrFail(ok);
1344  return ok;
1345 }
1346 
1348  const char* file,
1349  uint16_t line,
1350  const __FlashStringHelper* lhs,
1351  const __FlashStringHelper* lhsString,
1352  const char* opName,
1353  bool (*op)(const __FlashStringHelper* lhs, const __FlashStringHelper* rhs),
1354  const __FlashStringHelper* rhs,
1355  const __FlashStringHelper* rhsString
1356 ) {
1357  if (isDone()) return false;
1358  bool ok = op(lhs, rhs);
1359  if (isOutputEnabled(ok)) {
1360  printAssertionMessageVerbose(Printer::getPrinter(), ok, file, line,
1361  lhs, lhsString, opName, rhs, rhsString);
1362  }
1363  setPassOrFail(ok);
1364  return ok;
1365 }
1366 
1368  const char* file,
1369  uint16_t line,
1370  int lhs,
1371  const __FlashStringHelper* lhsString,
1372  int rhs,
1373  const __FlashStringHelper* rhsString,
1374  int error,
1375  const __FlashStringHelper* errorString,
1376  const char* opName,
1377  bool (*opNear)(int lhs, int rhs, int error)
1378 ) {
1379  if (isDone()) return false;
1380  bool ok = opNear(lhs, rhs, error);
1381  if (isOutputEnabled(ok)) {
1382  printAssertionNearMessageVerbose(Printer::getPrinter(), ok, file, line,
1383  lhs, lhsString, rhs, rhsString, opName, error, errorString);
1384  }
1385  setPassOrFail(ok);
1386  return ok;
1387 }
1388 
1390  const char* file,
1391  uint16_t line,
1392  unsigned int lhs,
1393  const __FlashStringHelper* lhsString,
1394  unsigned int rhs,
1395  const __FlashStringHelper* rhsString,
1396  unsigned int error,
1397  const __FlashStringHelper* errorString,
1398  const char* opName,
1399  bool (*opNear)(unsigned int lhs, unsigned int rhs, unsigned int error)
1400 ) {
1401  if (isDone()) return false;
1402  bool ok = opNear(lhs, rhs, error);
1403  if (isOutputEnabled(ok)) {
1404  printAssertionNearMessageVerbose(Printer::getPrinter(), ok, file, line,
1405  lhs, lhsString, rhs, rhsString, opName, error, errorString);
1406  }
1407  setPassOrFail(ok);
1408  return ok;
1409 }
1410 
1412  const char* file,
1413  uint16_t line,
1414  long lhs,
1415  const __FlashStringHelper* lhsString,
1416  long rhs,
1417  const __FlashStringHelper* rhsString,
1418  long error,
1419  const __FlashStringHelper* errorString,
1420  const char* opName,
1421  bool (*opNear)(long lhs, long rhs, long error)
1422 ) {
1423  if (isDone()) return false;
1424  bool ok = opNear(lhs, rhs, error);
1425  if (isOutputEnabled(ok)) {
1426  printAssertionNearMessageVerbose(Printer::getPrinter(), ok, file, line,
1427  lhs, lhsString, rhs, rhsString, opName, error, errorString);
1428  }
1429  setPassOrFail(ok);
1430  return ok;
1431 }
1432 
1434  const char* file,
1435  uint16_t line,
1436  unsigned long lhs,
1437  const __FlashStringHelper* lhsString,
1438  unsigned long rhs,
1439  const __FlashStringHelper* rhsString,
1440  unsigned long error,
1441  const __FlashStringHelper* errorString,
1442  const char* opName,
1443  bool (*opNear)(unsigned long lhs, unsigned long rhs, unsigned long error)
1444 ) {
1445  if (isDone()) return false;
1446  bool ok = opNear(lhs, rhs, error);
1447  if (isOutputEnabled(ok)) {
1448  printAssertionNearMessageVerbose(Printer::getPrinter(), ok, file, line,
1449  lhs, lhsString, rhs, rhsString, opName, error, errorString);
1450  }
1451  setPassOrFail(ok);
1452  return ok;
1453 }
1454 
1456  const char* file,
1457  uint16_t line,
1458  double lhs,
1459  const __FlashStringHelper* lhsString,
1460  double rhs,
1461  const __FlashStringHelper* rhsString,
1462  double error,
1463  const __FlashStringHelper* errorString,
1464  const char* opName,
1465  bool (*opNear)(double lhs, double rhs, double error)
1466 ) {
1467  if (isDone()) return false;
1468  bool ok = opNear(lhs, rhs, error);
1469  if (isOutputEnabled(ok)) {
1470  printAssertionNearMessageVerbose(Printer::getPrinter(), ok, file, line,
1471  lhs, lhsString, rhs, rhsString, opName, error, errorString);
1472  }
1473  setPassOrFail(ok);
1474  return ok;
1475 }
1476 
1477 }
Various macros to smooth over the differences among the various platforms with regards to their suppo...
bool assertionBool(const char *file, uint16_t line, bool arg, bool value)
Used by assertTrue() and assertFalse().
Definition: Assertion.cpp:259
bool assertionBoolVerbose(const char *file, uint16_t line, bool arg, const __FlashStringHelper *argString, bool value)
Used by assertTrue() and assertFalse().
Definition: Assertion.cpp:969
bool assertion(const char *file, uint16_t line, bool lhs, const char *opName, bool(*op)(bool lhs, bool rhs), bool rhs)
Used by assertXxx(bool, bool).
Definition: Assertion.cpp:275
bool assertionNearVerbose(const char *file, uint16_t line, int lhs, const __FlashStringHelper *lhsString, int rhs, const __FlashStringHelper *rhsString, int error, const __FlashStringHelper *errorString, const char *opName, bool(*compareNear)(int lhs, int rhs, int error))
Used by assertNear(int, int).
Definition: Assertion.cpp:1367
bool isOutputEnabled(bool ok) const
Returns true if an assertion message should be printed.
Definition: Assertion.cpp:254
bool assertionVerbose(const char *file, uint16_t line, bool lhs, const __FlashStringHelper *lhsString, const char *opName, bool(*op)(bool lhs, bool rhs), bool rhs, const __FlashStringHelper *rhsString)
Used by assertEqual(bool, bool).
Definition: Assertion.cpp:986
bool assertionNear(const char *file, uint16_t line, int lhs, int rhs, int error, const char *opName, bool(*compareNear)(int lhs, int rhs, int error))
Used by assertNear(int, int).
Definition: Assertion.cpp:617
static Print * getPrinter()
Get the output printer used by the various assertion() methods and the TestRunner.
Definition: Printer.h:48
static const uint8_t kAssertionFailed
Print assertXxx() failed message.
Definition: Verbosity.h:43
static const uint8_t kAssertionPassed
Print assertXxx() passed message.
Definition: Verbosity.h:40
Helper routines to print 'long long' and 'unsigned long long' because the Print::print() methods in P...