From 918d2cc616e2112ca5ab950e737abd2b32dc228e Mon Sep 17 00:00:00 2001 From: "Vincent \"MooZ\" Cruz" Date: Sat, 8 Dec 2012 19:12:46 +0100 Subject: [PATCH] Added arduino serial notifier and MariaMole project. --- DataFlash_test.cpp | 97 ++++++++++++ test/Callbacks.h | 56 ++++--- test/Runner.cpp | 16 +- test/Runner.h | 6 +- test/SerialNotifier.cpp | 149 ++++++++++++++++++ test/SerialNotifier.h | 80 ++++++++++ test/Utils.cpp | 2 +- test/example.cpp | 52 +++--- .../Arduino tests/Arduino tests.mmproj | 23 +++ .../Arduino tests/source/SerialTest.cpp | 38 +++++ 10 files changed, 465 insertions(+), 54 deletions(-) create mode 100644 DataFlash_test.cpp create mode 100644 test/SerialNotifier.cpp create mode 100644 test/SerialNotifier.h create mode 100644 test/workspace/Arduino tests/Arduino tests.mmproj create mode 100644 test/workspace/Arduino tests/source/SerialTest.cpp diff --git a/DataFlash_test.cpp b/DataFlash_test.cpp new file mode 100644 index 0000000..4a357ac --- /dev/null +++ b/DataFlash_test.cpp @@ -0,0 +1,97 @@ +#include +#include "DataFlash.h" + +#include "test/Dummy.h" + +class DataFlashFixture +{ + public: + static const int8_t CHIP_SELECT = 5; + static const int8_t RESET = 6; + static const int8_t WRITE_PROTECT = 7; + + public: + void Setup() + { + /* Initialize SPI */ + SPI.begin(); + + /* Let's wait 1 second, allowing use to press the serial monitor button :p */ + delay(1000); + + /* Initialize dataflash */ + m_dataflash.setup(CHIP_SELECT, RESET, WRITE_PROTECT); + + delay(10); + + /* Read status register */ + m_status = m_dataflash.status(); + + /* Read manufacturer and device ID */ + m_dataflash.readID(m_id); + } + + void TearDown() + { + /* Disable dataflash */ + m_data.disable(); + /* And SPI */ + SPI.end(); + } + + protected: + DataFlash m_dataflash; + uint8_t m_status; + DataFlash::ID m_id; +}; + +class SerialNotifier : public Dummy::CheckFailCallbackInterface +{ + public: + SerialNotifier() {} + virtual ~SerialNotifier() {} + + virtual void Notify(char const* expected, char const* value, Dummy::Infos const& infos) + { + Serial.print("%s: %s::%s failed at line %d (expected %s, value %s).\n", + infos.Filename(), infos.SuiteName(), infos.TestName(), infos.Line(), expected, value); + } +}; + + +SUITE(SingleDeviceTest) +{ + TEST_FIXTURE(InitializationTest, DataFlashFixture) + { + int i; + uint8_t validDensity[10] = + { 0x0c, 0x14, 0x1c, 0x24, 0x2c, 0x34, 0x3c, 0x10, 0x18, 0x20 }; + + CHECK(AT45_READY, m_status & AT45_READY); + for(i=0; i<10; i++) + { + CHECK(validDensity[i], m_status & 0x3f); + } + CHECK(0x1f, m_id.manufacture); + } + + TEST_FIXTURE(BufferReadWriteTest, DataFlashFixture) + { + // [todo] + } +} + +/* Arduino setup hook */ +void setup() +{ + Serial.begin(115200); + SerialNotifier notifier; + + res = Dummy::Runner::Instance().Run(¬ifier); + Serial.print("tests run %d\n\ttest failed %d\n\tcheck failed %d\n", res.total, res.failed, res.error); +} + +/* Arduino loop */ +void loop() +{} + diff --git a/test/Callbacks.h b/test/Callbacks.h index d273021..59d0751 100644 --- a/test/Callbacks.h +++ b/test/Callbacks.h @@ -34,6 +34,7 @@ #define CALLBACKS_H #include "Infos.h" +#include "Result.h" /** * @addtogroup DummyUnitTest @@ -42,54 +43,67 @@ namespace Dummy { /** - * CHECK failure notification interface. + * Test notification interface. **/ - class CheckFailCallbackInterface + class TestNotificationInterface { public: /** Destructor. **/ - virtual ~CheckFailCallbackInterface() {}; + virtual ~TestNotificationInterface() {}; + /** + * Test failure notification. + * @param [in] expected : expected value string. + * @param [in] value : tested value string. + * @param [in] infos : test informations. + **/ + virtual void NotifyFailure(char const* expected, char const* value, Infos const& infos) = 0; /** - * CHECK failure notification. - * @param [in] expected : expected value string. - * @param [in] value : tested value string. - * @param [in] infos : test informations. - **/ - virtual void Notify(char const* expected, char const* value, Infos const& infos) = 0; + * Tests result notification. + * @param [in] result : tests result. + **/ + virtual void NotifyResult(const Result& result) = 0; }; /** - * CHECK failure notification helper. + * Test notification helper. **/ template - class CheckFailCallback : public CheckFailCallbackInterface + class TestNotification : public TestNotificationInterface { public: - typedef void (T::*TNotifyProc) (char const*, char const*, Infos const&); + typedef void (T::*TNotifyFailureProc) (char const*, char const*, Infos const&); + typedef void (T::*TNotifyResultProc) (const Result& result); /** Constructor. **/ - CheckFailCallback(T* handler, TNotifyProc notify); + TestNotification(T* handler, TNotifyFailureProc notifyFailure, TNotifyResultProc notifyResult); /** Destructor. **/ - virtual ~CheckFailCallback() {} + virtual ~TestNotification() {} /** - * CHECK failure notification. + * Test failure notification. * @param [in] expected : expected value string. * @param [in] value : tested value string. * @param [in] infos : test informations. **/ - virtual void Notify(char const* expected, char const* value, Infos const& infos); + virtual void NotifyFailure(char const* expected, char const* value, Infos const& infos); + /** + * Tests result notification. + * @param [in] result : tests result. + **/ + virtual void NotifyResult(const Result& result); protected: T* m_handler; /**< Handler instance. **/ - TNotifyProc m_notify; /**< Handler method to be called on failure notification. **/ + TNotifyFailureProc m_notifyFailure; /**< Handler method to be called on failure notification. **/ + TNotifyResultProc m_notifyResult; /**< Handler method to be called on result notification. **/ }; /** Constructor. **/ template - CheckFailCallback::CheckFailCallback(T* handler, TNotifyProc notify) + TestNotification::TestNotification(T* handler, TNotifyFailureProc notifyFailure, TNotifyResultProc notifyResult) : m_handler(handler) - , m_notify(notify) + , m_notifyFailure(notifyFailure) + , m_notifyResult(notifyResult) {} /** @@ -99,9 +113,9 @@ namespace Dummy * @param [in] infos : test informations. **/ template - void CheckFailCallback::Notify(char const* expected, char const* value, Infos const& infos) + void TestNotification::NotifyFailure(char const* expected, char const* value, Infos const& infos) { - (m_handler->*(m_notify)) (expected, value, infos); + (m_handler->*(m_notifyFailure)) (expected, value, infos); } }; /** @} **/ diff --git a/test/Runner.cpp b/test/Runner.cpp index 82a93e7..1cb2281 100644 --- a/test/Runner.cpp +++ b/test/Runner.cpp @@ -40,7 +40,7 @@ namespace Dummy { /** Constructor **/ Runner::Runner() - : m_onCheckFailed(0) + : m_notify(0) , m_head(0) , m_tail(0) {} @@ -68,12 +68,12 @@ namespace Dummy /** * Process every test declared. - * @param [in] onCheckFailed : CHECK failure notification callback. + * @param [in] notify : Test notification callbacks. * @return Tests result. **/ - Result Runner::Run(CheckFailCallbackInterface* onCheckFailed) + Result Runner::Run(TestNotificationInterface* notify) { - m_onCheckFailed = onCheckFailed; + m_notify = notify; m_result.Reset(); for(Test* it=m_head; it!=0; it=it->m_next, ++m_result.total) { @@ -84,6 +84,10 @@ namespace Dummy ++m_result.failed; } } + if(m_notify) + { + m_notify->NotifyResult(m_result); + } return m_result; } @@ -96,9 +100,9 @@ namespace Dummy void Runner::OnCheckFailed(char const* expected, char const* value, Infos const& infos) { ++m_result.error; - if(m_onCheckFailed) + if(m_notify) { - m_onCheckFailed->Notify(expected, value, infos); + m_notify->NotifyFailure(expected, value, infos); } } diff --git a/test/Runner.h b/test/Runner.h index f3f474a..5107787 100644 --- a/test/Runner.h +++ b/test/Runner.h @@ -58,10 +58,10 @@ namespace Dummy /** * Process every test declared. - * @param [in] onCheckFailed : CHECK failure notification callback (optional). + * @param [in] notify : Notification callback (optional). * @return Tests result. **/ - Result Run(CheckFailCallbackInterface* onCheckFailed=0); + Result Run(TestNotificationInterface* notify=0); /** * CHECK failure notification. @@ -91,7 +91,7 @@ namespace Dummy protected: Result m_result; /** Test campaign results. **/ - CheckFailCallbackInterface* m_onCheckFailed; /** CHECK failure notification callback. **/ + TestNotificationInterface* m_notify; /** Test notification callbacks. **/ Test* m_head; /**< First element of the test list. **/ Test* m_tail; /**< Last element of the test list. **/ diff --git a/test/SerialNotifier.cpp b/test/SerialNotifier.cpp new file mode 100644 index 0000000..2652849 --- /dev/null +++ b/test/SerialNotifier.cpp @@ -0,0 +1,149 @@ +/**************************************************************************//** + * @file SerialNotifier.cpp + * + * @par Copyright: + * - Copyright (C) 2012 by Vincent Cruz. + * All rights reserved. + * + * @author Vincent Cruz cruz.vincent@gmail.com + * + * @par Description: + * Arduino serial text notifier. + * + * @par History: + * - Version 0.1, 08 Dec 2012. + * + * @par Licence: GPLv3 + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. @n + * @n + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. @n + * @n + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ +#include "SerialNotifier.h" + +#include + +/** + * @addtogroup DummyUnitTest + * @{ + **/ +namespace Dummy +{ + static const char* expectedPrefix = " expected="; + static size_t expectedPrefixLen = 10; + + static const char* valuePrefix = " value="; + static size_t valuePrefixLen = 7; + + /** + * Constructor. + */ + SerialNotifier::SerialNotifier(size_t maxValueLen, size_t maxFilenameLen, size_t maxSuitenameLen, size_t maxTestnameLen) + : m_allowedValueLen(maxValueLen) + , m_allowedFilenameLen(maxFilenameLen) + , m_allowedSuitenameLen(maxSuitenameLen) + , m_allowedTestnameLen(maxTestnameLen) + {} + /** + * Destructor. + */ + SerialNotifier::~SerialNotifier() + {} + /** + * Add current string to notification string and cut it if necessary. + * @param [out] out Notification string pointer. + * @param [in] in Input string. + * @param [in] len Input string length. + * @param [in] allowedLen Allowed output length. + **/ + void SerialNotifier::FormatString(char* &out, const char* in, size_t len, size_t allowedLen) + { + size_t i; + bool cutString = (len > allowedLen); + if(cutString) + { + char* dest = out + allowedLen; + out = dest; + in += len; + for(i=allowedLen; i>=3; i--) + { + *dest-- = *in--; + } + for(i=0; i<3; i++) + { + *dest-- = '.'; + } + } + else + { + for(i=0; i. + *****************************************************************************/ +#ifndef SERIAL_NOTIFIER_H +#define SERIAL_NOTIFIER_H + +#include +#include "Callbacks.h" + +/** + * @addtogroup DummyUnitTest + * @{ + **/ +namespace Dummy +{ + #define MAX_NOTIFICATION_STRING_LEN 128 + + /** + * Display test failure informations on the serial line. + * The notification is : "filename:line suite test expected_value test_value" + * If filename, suite, test or values are too long they are cut and "..." is appended. + */ + class SerialNotifier : public Dummy::TestNotificationInterface + { + public: + enum + { + DefaultValueLen = 32, + DefaultFilenameLen = 32, + DefaultSuitenameLen = 16, + DefaultTestnameLen = 16, + MaxStringLen = 127 + }; + + public: + SerialNotifier(size_t maxValueLen=DefaultValueLen, size_t maxFilenameLen=DefaultFilenameLen, size_t maxSuitenameLen=DefaultSuitenameLen, size_t maxTestnameLen=DefaultTestnameLen); + virtual ~SerialNotifier(); + virtual void NotifyFailure(char const* expected, char const* value, Dummy::Infos const& infos); + virtual void NotifyResult(const Result& result); + + protected: + void FormatString(char* &out, const char* in, size_t len, size_t allowedLen); + + protected: + size_t m_allowedValueLen; + size_t m_allowedFilenameLen; + size_t m_allowedSuitenameLen; + size_t m_allowedTestnameLen; + char m_notificationString[MAX_NOTIFICATION_STRING_LEN]; + }; +}; +/** @} **/ + +#endif // SERIAL_NOTIFIER_H \ No newline at end of file diff --git a/test/Utils.cpp b/test/Utils.cpp index 6bdf136..57b4388 100644 --- a/test/Utils.cpp +++ b/test/Utils.cpp @@ -70,7 +70,7 @@ namespace Dummy int Stringify(float value, char* buffer, int bufferLen) { - return snprintf(buffer, bufferLen, "%f", value); + return snprintf(buffer, bufferLen, "%f", (double)value); } int Stringify(char const* value, char* buffer, int bufferLen) diff --git a/test/example.cpp b/test/example.cpp index b7a7670..a576c47 100644 --- a/test/example.cpp +++ b/test/example.cpp @@ -1,26 +1,32 @@ -/* -Example code for a simple unit test framework. - -History: - -Version 0.1, 2011 - -Copyright (C) 2011 by Vincent Cruz. -cruz.vincent@gmail.com - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ +/**************************************************************************//** + * @file example.cpp + * + * @par Copyright: + * - Copyright (C) 2011 by Vincent Cruz. + * All rights reserved. + * + * @author Vincent Cruz cruz.vincent@gmail.com + * + * @par Description: + * Example code for a simple unit test framework. + * + * @par History: + * - Version 0.1, 2011 + * + * @par Licence: GPLv3 + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. @n + * @n + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. @n + * @n + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *****************************************************************************/ #include "Dummy.h" /* This is a simple test suite */ diff --git a/test/workspace/Arduino tests/Arduino tests.mmproj b/test/workspace/Arduino tests/Arduino tests.mmproj new file mode 100644 index 0000000..d05f611 --- /dev/null +++ b/test/workspace/Arduino tests/Arduino tests.mmproj @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/workspace/Arduino tests/source/SerialTest.cpp b/test/workspace/Arduino tests/source/SerialTest.cpp new file mode 100644 index 0000000..bca0d33 --- /dev/null +++ b/test/workspace/Arduino tests/source/SerialTest.cpp @@ -0,0 +1,38 @@ +#include + +#include "Dummy.h" +#include "SerialNotifier.h" + +/* Must be defined in order to satisfy linker. */ +extern "C" void atexit( void ) { } + +/* This is a simple test suite */ +SUITE(Suite0) +{ + TEST(Test0) + { + int a = 1; + CHECK(1, a); + CHECK("bar", "foo"); + } + + TEST(Test1) + { + CHECK(0, 1); + CHECK(5, 2); + } +} + +void setup() +{ + Serial.begin(9600); + + Dummy::SerialNotifier notifier; + Dummy::Result res; + + res = Dummy::Runner::Instance().Run(¬ifier); +} + +void loop() +{ +}