ArduinoUnit 2.0
 All Classes Files Functions Variables Macros
ArduinoUnit.h
Go to the documentation of this file.
1 #pragma once
2 
9 #include <stdint.h>
10 #include <Print.h>
11 
12 #if ARDUINO >= 100 && ARDUINO < 103
13 #undef F
14 #undef PSTR
15 #define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];}))
16 
17 #define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
18 
19 #endif
20 
21 #if defined(__GNUC__) && (__GNUC__*100 + __GNUC_MINOR__ < 407)
22 // Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734
23 #ifdef PROGMEM
24 #undef PROGMEM
25 #define PROGMEM __attribute__((section(".progmem.data")))
26 #endif
27 #endif
28 
29 #include <utility/FakeStream.h>
30 #include <utility/MemoryFree.h>
31 
33 #define ARDUINO_UNIT_MAJOR_VERSION 2
34 
36 #define ARDUINO_UNIT_MINOR_VERSION 0
37 
38 //
39 // These define what you want for output from tests.
40 //
41 
51 #define TEST_VERBOSITY_TESTS_SUMMARY 0x01
52 
62 #define TEST_VERBOSITY_TESTS_FAILED 0x02
63 
73 #define TEST_VERBOSITY_TESTS_PASSED 0x04
74 
75 
85 #define TEST_VERBOSITY_TESTS_SKIPPED 0x08
86 
87 
97 #define TEST_VERBOSITY_TESTS_ALL 0x0F
98 
107 #define TEST_VERBOSITY_ASSERTIONS_FAILED 0x10
108 
117 #define TEST_VERBOSITY_ASSERTIONS_PASSED 0x20
118 
127 #define TEST_VERBOSITY_ASSERTIONS_ALL 0x30
128 
132 #define TEST_VERBOSITY_ALL 0x3F
133 
137 #define TEST_VERBOSITY_NONE 0x00
138 
139 
140 #ifndef TEST_MAX_VERBOSITY
141 
146 #define TEST_MAX_VERBOSITY TEST_VERBOSITY_ALL
147 #endif
148 
149 
162 #define TEST_VERBOSITY_EXISTS(OF) ((TEST_MAX_VERBOSITY & TEST_VERBOSITY_ ## OF) != 0)
163 
182 #define TEST_VERBOSITY_ALLOWED(OF) (TEST_VERBOSITY_EXISTS(OF) && ((Test::max_verbosity & TEST_VERBOSITY_ ## OF) != 0))
183 
189 #define TEST_VERBOSITY_REQUIRED(OF) (TEST_VERBOSITY_ALLOWED(OF) && ((Test::min_verbosity & TEST_VERBOSITY_ ## OF) != 0))
190 
196 #define TEST_VERBOSITY(OF) (TEST_VERBOSITY_ALLOWED(OF) && (((Test::min_verbosity & TEST_VERBOSITY_ ## OF ) != 0) || (((Test::current != 0) && ((Test::current->verbosity & TEST_VERBOSITY_ ## OF) != 0)))))
197 
279 class Test
280 {
281  private:
282  // allows for both ram/progmem based names
283  class String : public Printable {
284  public:
285  const uint32_t data;
286  String(const char *_data);
287  String(const __FlashStringHelper *_data);
288  void read(void *destination, uint16_t offset, uint8_t length) const;
289  uint16_t length() const;
290  int8_t compare(const Test::String &to) const;
291  size_t printTo(Print &p) const;
292  bool matches(const char *pattern) const;
293  };
294 
295  private:
296  // linked list structure for active tests
297  static Test* root;
298  Test *next;
299 
300  // static statistics for tests
301  static uint16_t passed;
302  static uint16_t failed;
303  static uint16_t skipped;
304  static uint16_t count;
305 
306  void resolve();
307  void remove();
308  void insert();
309 
310  public:
311 
315  static uint8_t max_verbosity;
316 
321  static uint8_t min_verbosity;
322 
323  static inline uint16_t getCurrentPassed() { return passed; }
324  static inline uint16_t getCurrentSkipped() { return skipped; }
325  static inline uint16_t getCurrentFailed() { return failed; }
326  static uint16_t getCurrentCount() { return count; }
327 
330  static const uint8_t UNSETUP;
331 
334  static const uint8_t LOOPING;
335 
340  static const uint8_t DONE_SKIP;
341 
343  static const uint8_t DONE_PASS;
344 
346  static const uint8_t DONE_FAIL;
347 
364  static Print *out;
365 
371  uint8_t state;
372 
378  static Test* current;
379 
381  String name;
382 
398  uint8_t verbosity;
399 
403  void pass();
404 
405 
409  void fail();
410 
411 
415  void skip();
416 
420  virtual void setup();
421 
423  virtual void loop() = 0;
424 
435  static void include(const char *pattern);
436 
445 static void exclude(const char *pattern);
446 
472  static void run();
473 
474  // Construct a test with a given name and verbosity level
475  Test(const __FlashStringHelper *_name, uint8_t _verbosity = TEST_VERBOSITY_TESTS_ALL|TEST_VERBOSITY_ASSERTIONS_FAILED);
476 
477  Test(const char *_name, uint8_t _verbosity = TEST_VERBOSITY_TESTS_ALL|TEST_VERBOSITY_ASSERTIONS_FAILED);
478 
479  virtual ~Test();
480 
481  template <typename T>
482  static bool assertion(const __FlashStringHelper *file, uint16_t line, const __FlashStringHelper *lhss, const T& lhs, const __FlashStringHelper *ops, bool (*op)(const T& lhs, const T& rhs), const __FlashStringHelper *rhss, const T& rhs) {
483  bool ok = op(lhs,rhs);
484  bool output = false;
485 
486  if ((!ok) && (current != 0)) current->fail();
487 
488 #if TEST_VERBOSITY_EXISTS(ASSERTIONS_PASSED)
489  if (ok && TEST_VERBOSITY(ASSERTIONS_PASSED)) {
490  output = true;
491  }
492 #endif
493 
494 #if TEST_VERBOSITY_EXISTS(ASSERTIONS_FAILED)
495  if ((!ok) && TEST_VERBOSITY(ASSERTIONS_FAILED)) {
496  output = true;
497  }
498 #endif
499 
500 #if TEST_VERBOSITY_EXISTS(ASSERTIONS_FAILED) || TEST_VERBOSITY_EXISTS(ASSERTIONS_PASSED)
501  if (output) {
502  out->print(file);
503  out->print(F(":"));
504  out->print(line);
505  out->print(F(":1: "));
506  out->print(ok ? F("pass") : F("fail"));
507  out->print(F(" assert ("));
508  out->print(lhss);
509  out->print(F("="));
510  out->print(lhs);
511  out->print(F(") "));
512  out->print(ops);
513  out->print(F(" ("));
514  out->print(rhss);
515  out->print(F("="));
516  out->print(rhs);
517  out->print(F(")"));
518  out->println();
519  }
520 #endif
521  return ok;
522  }
523 };
524 
528 class TestOnce : public Test {
529  public:
530  TestOnce(const __FlashStringHelper *name);
531  TestOnce(const char *name);
532  void loop();
533  virtual void once() = 0;
534 };
535 
537 template <typename T>
538 bool isEqual(const T& a, const T& b) { return a==b; }
539 
541 template <typename T>
542 bool isNotEqual(const T& a, const T& b) { return !(a==b); }
543 
545 template <typename T>
546 bool isLess(const T& a, const T& b) { return a < b; }
547 
549 template <typename T>
550 bool isMore(const T& a, const T& b) { return b < a; }
551 
553 template <typename T>
554 bool isLessOrEqual(const T& a, const T& b) { return !(b<a); }
555 
557 template <typename T>
558 bool isMoreOrEqual(const T& a, const T& b) { return !(a<b); }
559 
561 template <> bool isLess<const char*>(const char* const &a, const char* const &b);
562 
564 template <> bool isLessOrEqual<const char*>(const char* const &a, const char* const &b);
565 
567 template <> bool isEqual<const char*>(const char* const &a, const char* const &b);
568 
570 template <> bool isNotEqual<const char*>(const char* const &a, const char* const &b);
571 
573 template <> bool isMore<const char*>(const char* const &a, const char* const &b);
574 
576 template <> bool isMoreOrEqual<const char*>(const char* const &a, const char* const &b);
577 
578 
581 #define test(name) struct test_ ## name : TestOnce { test_ ## name() : TestOnce(F(#name)) {}; void once(); } test_ ## name ## _instance; void test_ ## name :: once()
582 
587 #define externTest(name) struct test_ ## name : TestOnce { test_ ## name(); void once(); }; extern test_##name test_##name##_instance
588 
594 #define testing(name) struct test_ ## name : Test { test_ ## name() : Test(F(#name)) {}; void loop(); } test_ ## name ## _instance; void test_ ## name :: loop()
595 
599 #define externTesting(name) struct test_ ## name : Test { test_ ## name(); void loop(); }; extern test_##name test_##name##_instance
600 
601 // helper define for the operators below
602 #define assertOp(arg1,op,op_name,arg2) if (!Test::assertion<typeof(arg2)>(F(__FILE__),__LINE__,F(#arg1),(arg1),F(op_name),op,F(#arg2),(arg2))) return;
603 
605 #define assertEqual(arg1,arg2) assertOp(arg1,isEqual,"==",arg2)
606 
608 #define assertNotEqual(arg1,arg2) assertOp(arg1,isNotEqual,"!=",arg2)
609 
611 #define assertLess(arg1,arg2) assertOp(arg1,isLess,"<",arg2)
612 
614 #define assertMore(arg1,arg2) assertOp(arg1,isMore,">",arg2)
615 
617 #define assertLessOrEqual(arg1,arg2) assertOp(arg1,isLessOrEqual,"<=",arg2)
618 
620 #define assertMoreOrEqual(arg1,arg2) assertOp(arg1,isMoreOrEqual,">=",arg2)
621 
623 #define assertTrue(arg) assertEqual(arg,true)
624 
626 #define assertFalse(arg) assertEqual(arg,false)
627 
628 #define checkTestDone(name) (test_##name##_instance.state >= Test::DONE_SKIP)
629 
631 #define checkTestNotDone(name) (test_##name##_instance.state < Test::DONE_SKIP)
632 
634 #define checkTestPass(name) (test_##name##_instance.state == Test::DONE_PASS)
635 
637 #define checkTestNotPass(name) (test_##name##_instance.state != Test::DONE_PASS)
638 
640 #define checkTestFail(name) (test_##name##_instance.state == Test::DONE_FAIL)
641 
643 #define checkTestNotFail(name) (test_##name##_instance.state != Test::DONE_FAIL)
644 
646 #define checkTestSkip(name) (test_##name##_instance.state == Test::DONE_SKIP)
647 
649 #define checkTestNotSkip(name) (test_##name##_instance.state != Test::DONE_SKIP)
650 
652 #define assertTestDone(name) assertMoreOrEqual(test_##name##_instance.state,Test::DONE_SKIP)
653 
654 #define assertTestNotDone(name) assertLess(test_##name##_instance.state,Test::DONE_SKIP)
655 
657 #define assertTestPass(name) assertEqual(test_##name##_instance.state,Test::DONE_PASS)
658 
660 #define assertTestNotPass(name) assertNotEqual(test_##name##_instance.state,Test::DONE_PASS)
661 
663 #define assertTestFail(name) assertEqual(test_##name##_instance.state,Test::DONE_FAIL)
664 
666 #define assertTestNotFail(name) assertNotEqual(test_##name##_instance.state,Test::DONE_FAIL)
667 
669 #define assertTestSkip(name) assertEqual(test_##name##_instance.state,Test::DONE_SKIP)
670 
672 #define assertTestNotSkip(name) assertNotEqual(test_##name##_instance.state,Test::DONE_SKIP)