diff --git a/.travis.yml b/.travis.yml
index 099073b46..099782b16 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -7,9 +7,10 @@ matrix:
sources:
- ubuntu-toolchain-r-test
packages:
- - g++
+ - g++-9
+ - gcc-9
env:
- - MATRIX_EVAL="CC=gcc-7 && CXX=g++-7"
+ - MATRIX_EVAL="CC=gcc-9 && CXX=g++-9"
before_install:
- eval "${MATRIX_EVAL}"
- pip install gcovr
diff --git a/src/ayab/global_hw_test.cpp b/src/ayab/global_hw_test.cpp
new file mode 100644
index 000000000..dfdc6be90
--- /dev/null
+++ b/src/ayab/global_hw_test.cpp
@@ -0,0 +1,87 @@
+/*!
+ * \file global_hw_test.cpp
+ * This file is part of AYAB.
+ *
+ * AYAB 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.
+ *
+ * AYAB 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 AYAB. If not, see .
+ *
+ * Original Work Copyright 2013 Christian Obersteiner, Andreas Müller
+ * Modified Work Copyright 2020 Sturla Lange, Tom Price
+ * http://ayab-knitting.com
+ */
+
+#include "hw_test.h"
+
+// static member functions
+
+void GlobalHardwareTest::helpCmd() {
+ m_instance->helpCmd();
+}
+
+void GlobalHardwareTest::sendCmd() {
+ m_instance->sendCmd();
+}
+
+void GlobalHardwareTest::beepCmd() {
+ m_instance->beepCmd();
+}
+
+void GlobalHardwareTest::setSingleCmd() {
+ m_instance->setSingleCmd();
+}
+
+void GlobalHardwareTest::setAllCmd() {
+ m_instance->setAllCmd();
+}
+
+void GlobalHardwareTest::readEOLsensorsCmd() {
+ m_instance->readEOLsensorsCmd();
+}
+
+void GlobalHardwareTest::readEncodersCmd() {
+ m_instance->readEncodersCmd();
+}
+
+void GlobalHardwareTest::autoReadCmd() {
+ m_instance->autoReadCmd();
+}
+
+void GlobalHardwareTest::autoTestCmd() {
+ m_instance->autoTestCmd();
+}
+
+void GlobalHardwareTest::stopCmd() {
+ m_instance->stopCmd();
+}
+
+void GlobalHardwareTest::quitCmd() {
+ m_instance->quitCmd();
+}
+
+void GlobalHardwareTest::unrecognizedCmd(const char *buffer) {
+ m_instance->unrecognizedCmd(buffer);
+}
+
+void GlobalHardwareTest::setUp() {
+ m_instance->setUp();
+}
+
+void GlobalHardwareTest::loop() {
+ m_instance->loop();
+}
+
+#ifndef AYAB_TESTS
+void GlobalHardwareTest::encoderAChange() {
+ m_instance->encoderAChange();
+}
+#endif // AYAB_TESTS
diff --git a/src/ayab/hw_test.cpp b/src/ayab/hw_test.cpp
index 6d1738883..6aab23995 100644
--- a/src/ayab/hw_test.cpp
+++ b/src/ayab/hw_test.cpp
@@ -25,16 +25,11 @@
#include "hw_test.h"
#include "knitter.h"
-extern Knitter *knitter;
-
-// initialise static members
-SerialCommand HardwareTest::m_sCmd = SerialCommand();
-bool HardwareTest::m_autoReadOn = false;
-bool HardwareTest::m_autoTestOn = false;
-bool HardwareTest::m_timerEvent = false;
-bool HardwareTest::m_timerEventOdd = false;
-unsigned long HardwareTest::m_lastTime = 0U;
+// public interface
+/*!
+ * \brief Help command handler.
+ */
void HardwareTest::helpCmd() {
Serial.println("The following commands are available:");
Serial.println("setSingle [0..15] [1/0]");
@@ -50,6 +45,9 @@ void HardwareTest::helpCmd() {
Serial.println("help");
}
+/*!
+ * \brief Send command handler.
+ */
void HardwareTest::sendCmd() {
Serial.println("Called send");
uint8_t p[] = {1, 2, 3};
@@ -57,10 +55,6 @@ void HardwareTest::sendCmd() {
Serial.print("\n");
}
-void HardwareTest::beep() {
- knitter->m_beeper.ready();
-}
-
/*!
* \brief Beep command handler.
*/
@@ -117,13 +111,6 @@ void HardwareTest::setAllCmd() {
knitter->setSolenoids(solenoidState);
}
-void HardwareTest::readEOLsensors() {
- Serial.print(" EOL_L: ");
- Serial.print(analogRead(EOL_PIN_L));
- Serial.print(" EOL_R: ");
- Serial.print(analogRead(EOL_PIN_R));
-}
-
/*!
* \brief Read EOL sensors command handler.
*/
@@ -133,18 +120,6 @@ void HardwareTest::readEOLsensorsCmd() {
Serial.print("\n");
}
-void HardwareTest::readEncoders() {
- Serial.print(" ENC_A: ");
- bool state = digitalRead(ENC_PIN_A);
- Serial.print(state ? "HIGH" : "LOW");
- Serial.print(" ENC_B: ");
- state = digitalRead(ENC_PIN_B);
- Serial.print(state ? "HIGH" : "LOW");
- Serial.print(" ENC_C: ");
- state = digitalRead(ENC_PIN_C);
- Serial.print(state ? "HIGH" : "LOW");
-}
-
/*!
* \brief Read encoders command handler.
*/
@@ -154,13 +129,6 @@ void HardwareTest::readEncodersCmd() {
Serial.print("\n");
}
-void HardwareTest::autoRead() {
- Serial.print("\n");
- readEOLsensors();
- readEncoders();
- Serial.print("\n");
-}
-
/*!
* \brief Auto read command handler.
*/
@@ -169,20 +137,6 @@ void HardwareTest::autoReadCmd() {
m_autoReadOn = true;
}
-void HardwareTest::autoTestEven() {
- Serial.println("Set even solenoids");
- digitalWrite(LED_PIN_A, 1);
- digitalWrite(LED_PIN_B, 1);
- knitter->setSolenoids(0xAAAA);
-}
-
-void HardwareTest::autoTestOdd() {
- Serial.println("Set odd solenoids");
- digitalWrite(LED_PIN_A, 0);
- digitalWrite(LED_PIN_B, 0);
- knitter->setSolenoids(0x5555);
-}
-
/*!
* \brief Auto test command handler.
*/
@@ -191,11 +145,17 @@ void HardwareTest::autoTestCmd() {
m_autoTestOn = true;
}
+/*!
+ * \brief Stop command handler.
+ */
void HardwareTest::stopCmd() {
m_autoReadOn = false;
m_autoTestOn = false;
}
+/*!
+ * \brief Quit command handler.
+ */
void HardwareTest::quitCmd() {
knitter->setQuitFlag(true);
knitter->setUpInterrupt();
@@ -215,25 +175,23 @@ void HardwareTest::unrecognizedCmd(const char *buffer) {
helpCmd();
}
-// Member functions
-
/*!
- * \brief Setup for hw tests.
+ * \brief Setup for hardware tests.
*/
void HardwareTest::setUp() {
// set up callbacks for SerialCommand commands
- m_sCmd.addCommand("setSingle", HardwareTest::setSingleCmd);
- m_sCmd.addCommand("setAll", HardwareTest::setAllCmd);
- m_sCmd.addCommand("readEOLsensors", HardwareTest::readEOLsensorsCmd);
- m_sCmd.addCommand("readEncoders", HardwareTest::readEncodersCmd);
- m_sCmd.addCommand("beep", HardwareTest::beepCmd);
- m_sCmd.addCommand("autoRead", HardwareTest::autoReadCmd);
- m_sCmd.addCommand("autoTest", HardwareTest::autoTestCmd);
- m_sCmd.addCommand("send", HardwareTest::sendCmd);
- m_sCmd.addCommand("stop", HardwareTest::stopCmd);
- m_sCmd.addCommand("quit", HardwareTest::quitCmd);
- m_sCmd.addCommand("help", HardwareTest::helpCmd);
- m_sCmd.setDefaultHandler(HardwareTest::unrecognizedCmd);
+ m_sCmd.addCommand("setSingle", GlobalHardwareTest::setSingleCmd);
+ m_sCmd.addCommand("setAll", GlobalHardwareTest::setAllCmd);
+ m_sCmd.addCommand("readEOLsensors", GlobalHardwareTest::readEOLsensorsCmd);
+ m_sCmd.addCommand("readEncoders", GlobalHardwareTest::readEncodersCmd);
+ m_sCmd.addCommand("beep", GlobalHardwareTest::beepCmd);
+ m_sCmd.addCommand("autoRead", GlobalHardwareTest::autoReadCmd);
+ m_sCmd.addCommand("autoTest", GlobalHardwareTest::autoTestCmd);
+ m_sCmd.addCommand("send", GlobalHardwareTest::sendCmd);
+ m_sCmd.addCommand("stop", GlobalHardwareTest::stopCmd);
+ m_sCmd.addCommand("quit", GlobalHardwareTest::quitCmd);
+ m_sCmd.addCommand("help", GlobalHardwareTest::helpCmd);
+ m_sCmd.setDefaultHandler(GlobalHardwareTest::unrecognizedCmd);
// Print welcome message
Serial.print("AYAB Hardware Test, Firmware v");
@@ -248,25 +206,16 @@ void HardwareTest::setUp() {
// attach interrupt for ENC_PIN_A(=2), interrupt #0
detachInterrupt(0);
#ifndef AYAB_TESTS
- attachInterrupt(0, encoderAChange, RISING);
+ attachInterrupt(0, GlobalHardwareTest::encoderAChange, RISING);
+#endif // AYAB_TESTS
m_lastTime = millis();
-#endif // AYAB_TESTS
m_autoReadOn = false;
m_autoTestOn = false;
m_timerEventOdd = false;
knitter->setQuitFlag(false);
}
-#ifndef AYAB_TESTS
-/*!
- * \brief Interrupt service routine for encoder A.
- */
-void HardwareTest::encoderAChange() {
- beep();
-}
-#endif // AYAB_TESTS
-
/*!
* \brief Main loop for hardware tests.
*/
@@ -278,6 +227,61 @@ void HardwareTest::loop() {
}
}
+// Private member functions
+
+void HardwareTest::beep() {
+ knitter->m_beeper.ready();
+}
+
+void HardwareTest::readEncoders() {
+ Serial.print(" ENC_A: ");
+ bool state = digitalRead(ENC_PIN_A);
+ Serial.print(state ? "HIGH" : "LOW");
+ Serial.print(" ENC_B: ");
+ state = digitalRead(ENC_PIN_B);
+ Serial.print(state ? "HIGH" : "LOW");
+ Serial.print(" ENC_C: ");
+ state = digitalRead(ENC_PIN_C);
+ Serial.print(state ? "HIGH" : "LOW");
+}
+
+void HardwareTest::readEOLsensors() {
+ Serial.print(" EOL_L: ");
+ Serial.print(analogRead(EOL_PIN_L));
+ Serial.print(" EOL_R: ");
+ Serial.print(analogRead(EOL_PIN_R));
+}
+
+void HardwareTest::autoRead() {
+ Serial.print("\n");
+ readEOLsensors();
+ readEncoders();
+ Serial.print("\n");
+}
+
+void HardwareTest::autoTestEven() {
+ Serial.println("Set even solenoids");
+ digitalWrite(LED_PIN_A, 1);
+ digitalWrite(LED_PIN_B, 1);
+ knitter->setSolenoids(0xAAAA);
+}
+
+void HardwareTest::autoTestOdd() {
+ Serial.println("Set odd solenoids");
+ digitalWrite(LED_PIN_A, 0);
+ digitalWrite(LED_PIN_B, 0);
+ knitter->setSolenoids(0x5555);
+}
+
+/*!
+ * \brief Interrupt service routine for encoder A.
+ */
+#ifndef AYAB_TESTS
+void HardwareTest::encoderAChange() {
+ beep();
+}
+#endif // AYAB_TESTS
+
/*!
* \brief Timer event every 500ms to handle auto functions.
*/
diff --git a/src/ayab/hw_test.h b/src/ayab/hw_test.h
index 9183c741a..b96fbff13 100644
--- a/src/ayab/hw_test.h
+++ b/src/ayab/hw_test.h
@@ -28,7 +28,31 @@
#include "beeper.h"
-class HardwareTest {
+class HardwareTestInterface {
+public:
+ virtual ~HardwareTestInterface(){};
+
+ virtual void helpCmd() = 0;
+ virtual void sendCmd() = 0;
+ virtual void beepCmd() = 0;
+ virtual void setSingleCmd() = 0;
+ virtual void setAllCmd() = 0;
+ virtual void readEOLsensorsCmd() = 0;
+ virtual void readEncodersCmd() = 0;
+ virtual void autoReadCmd() = 0;
+ virtual void autoTestCmd() = 0;
+ virtual void stopCmd() = 0;
+ virtual void quitCmd() = 0;
+ virtual void unrecognizedCmd(const char *buffer) = 0;
+
+ virtual void setUp() = 0;
+ virtual void loop() = 0;
+#ifndef AYAB_TESTS
+ virtual void encoderAChange() = 0;
+#endif
+};
+
+class HardwareTest : public HardwareTestInterface {
#if AYAB_TESTS
FRIEND_TEST(HardwareTestTest, test_setUp);
FRIEND_TEST(HardwareTestTest, test_loop_default);
@@ -37,6 +61,46 @@ class HardwareTest {
FRIEND_TEST(HardwareTestTest, test_loop_autoTestOdd);
friend class HardwareTestTest;
#endif
+
+public:
+ void helpCmd();
+ void sendCmd();
+ void beepCmd();
+ void setSingleCmd();
+ void setAllCmd();
+ void readEOLsensorsCmd();
+ void readEncodersCmd();
+ void autoReadCmd();
+ void autoTestCmd();
+ void stopCmd();
+ void quitCmd();
+ void unrecognizedCmd(const char *buffer);
+
+ void setUp();
+ void loop();
+#ifndef AYAB_TESTS
+ void encoderAChange();
+#endif
+
+private:
+ void beep();
+ void readEOLsensors();
+ void readEncoders();
+ void autoRead();
+ void autoTestEven();
+ void autoTestOdd();
+ void handleTimerEvent();
+
+ SerialCommand m_sCmd = SerialCommand();
+
+ bool m_autoReadOn = false;
+ bool m_autoTestOn = false;
+
+ unsigned long m_lastTime = 0U;
+ bool m_timerEventOdd = false;
+};
+
+class GlobalHardwareTest {
public:
static void helpCmd();
static void sendCmd();
@@ -53,30 +117,13 @@ class HardwareTest {
static void setUp();
static void loop();
-
- static SerialCommand m_sCmd;
- /* static bool m_quitFlag; */
-
-private:
- static void beep();
- static void readEOLsensors();
- static void readEncoders();
- static void autoRead();
- static void autoTestEven();
- static void autoTestOdd();
- static void handleTimerEvent();
-
#ifndef AYAB_TESTS
static void encoderAChange();
#endif
- static bool m_autoReadOn;
- static bool m_autoTestOn;
-
- static unsigned long m_lastTime;
- static bool m_timerEventOdd;
+ static HardwareTestInterface *m_instance;
};
-extern HardwareTest *hwTest;
+extern GlobalHardwareTest *hwTest;
#endif // HW_TEST_H_
diff --git a/src/ayab/knitter.cpp b/src/ayab/knitter.cpp
index fa30fa2e8..35eec65a5 100644
--- a/src/ayab/knitter.cpp
+++ b/src/ayab/knitter.cpp
@@ -35,7 +35,6 @@ constexpr uint16_t UINT16_MAX = 0xFFFFU;
#endif
extern Knitter *knitter;
-extern HardwareTest *hwTest;
#ifndef AYAB_TESTS
/*!
@@ -185,7 +184,7 @@ bool Knitter::startTest(Machine_t machineType) {
if (s_init == m_opState || s_ready == m_opState) {
m_opState = s_test;
m_machineType = machineType;
- HardwareTest::setUp();
+ GlobalHardwareTest::setUp();
success = true;
}
return success;
@@ -344,7 +343,7 @@ void Knitter::state_test() {
calculatePixelAndSolenoid();
indState();
}
- HardwareTest::loop();
+ GlobalHardwareTest::loop();
if (m_quitFlag) {
m_opState = s_ready;
}
diff --git a/src/ayab/main.cpp b/src/ayab/main.cpp
index ff0125be3..3fb1cccfb 100644
--- a/src/ayab/main.cpp
+++ b/src/ayab/main.cpp
@@ -27,17 +27,18 @@
#include "hw_test.h"
#include "knitter.h"
-// global definitions
+// global definition
// references everywhere else must use `extern`
Knitter *knitter;
-HardwareTest *hwTest;
+
+// initialize static member
+HardwareTestInterface *GlobalHardwareTest::m_instance = new HardwareTest();
/*!
* Setup - steps to take before going to the main loop.
*/
void setup() {
knitter = new Knitter();
- hwTest = new HardwareTest();
}
/*!
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 2ac2ce66e..0ac32270b 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -53,6 +53,7 @@ set(COMMON_SOURCES
${PROJECT_SOURCE_DIR}/test_serial_encoding.cpp
${SOURCE_DIRECTORY}/hw_test.cpp
+ ${SOURCE_DIRECTORY}/global_hw_test.cpp
${PROJECT_SOURCE_DIR}/test_hw_test.cpp
${PROJECT_SOURCE_DIR}/mocks/SerialCommand_mock.cpp
@@ -68,7 +69,12 @@ set(COMMON_FLAGS
-Wall -Wextra -Wpedantic
-Wno-vla
-Werror
- -fprofile-arcs -ftest-coverage
+ -fprofile-arcs -ftest-coverage
+
+ # exclude global_hw_test.cpp from profile analysis
+ # to avoid tedious mocking of these simple functions
+ -fprofile-exclude-files=global_hw_test.cpp
+
-g -Og
)
set(COMMON_LINKER_FLAGS
@@ -133,6 +139,7 @@ add_board(Mega)
add_executable(${PROJECT_NAME}_knitter
${PROJECT_SOURCE_DIR}/test_all.cpp
${SOURCE_DIRECTORY}/knitter.cpp
+ ${SOURCE_DIRECTORY}/global_hw_test.cpp
${PROJECT_SOURCE_DIR}/mocks/solenoids_mock.cpp
${PROJECT_SOURCE_DIR}/mocks/encoders_mock.cpp
${PROJECT_SOURCE_DIR}/mocks/beeper_mock.cpp
diff --git a/test/mocks/hw_test_mock.cpp b/test/mocks/hw_test_mock.cpp
index e25cfb5a6..c82c498ab 100644
--- a/test/mocks/hw_test_mock.cpp
+++ b/test/mocks/hw_test_mock.cpp
@@ -24,7 +24,8 @@
#include
static HardwareTestMock *gHardwareTestMock = NULL;
-HardwareTestMock *hardwareTestMockInstance() {
+
+HardwareTestMock *hwTestMockInstance() {
if (!gHardwareTestMock) {
gHardwareTestMock = new HardwareTestMock();
}
diff --git a/test/mocks/hw_test_mock.h b/test/mocks/hw_test_mock.h
index f317c991d..d8e60f372 100644
--- a/test/mocks/hw_test_mock.h
+++ b/test/mocks/hw_test_mock.h
@@ -27,7 +27,7 @@
#include
#include
-class HardwareTestMock {
+class HardwareTestMock : public HardwareTestInterface {
public:
MOCK_METHOD0(helpCmd, void());
MOCK_METHOD0(sendCmd, void());
@@ -45,7 +45,7 @@ class HardwareTestMock {
MOCK_METHOD0(loop, void());
};
-HardwareTestMock *hardwareTestMockInstance();
+HardwareTestMock *hwTestMockInstance();
void releaseHardwareTestMock();
#endif // HW_TEST_MOCK_H_
diff --git a/test/test_hw_test.cpp b/test/test_hw_test.cpp
index 026c2800a..0f6f41bcf 100644
--- a/test/test_hw_test.cpp
+++ b/test/test_hw_test.cpp
@@ -34,6 +34,9 @@ static char zero[2] = {48, 0}; // "0"
static char two[2] = {50, 0}; // "2"
static char twenty[3] = {50, 48, 0}; // "20"
+// initialize static member
+HardwareTestInterface *GlobalHardwareTest::m_instance = new HardwareTest();
+
class HardwareTestTest : public ::testing::Test {
protected:
void SetUp() override {
@@ -41,6 +44,7 @@ class HardwareTestTest : public ::testing::Test {
serialMock = serialMockInstance();
serialCommandMock = serialCommandMockInstance();
knitterMock = knitterMockInstance();
+ h = new HardwareTest();
}
void TearDown() override {
@@ -54,151 +58,149 @@ class HardwareTestTest : public ::testing::Test {
SerialMock *serialMock;
SerialCommandMock *serialCommandMock;
KnitterMock *knitterMock;
-
- void expect_test() {
- }
+ HardwareTest *h;
};
TEST_F(HardwareTestTest, test_setUp) {
EXPECT_CALL(*knitterMock, setQuitFlag);
- ASSERT_FALSE(HardwareTest::m_autoReadOn);
- ASSERT_FALSE(HardwareTest::m_autoTestOn);
- ASSERT_FALSE(HardwareTest::m_timerEvent);
- ASSERT_FALSE(HardwareTest::m_timerEventOdd);
- HardwareTest::setUp();
+ EXPECT_CALL(*arduinoMock, millis);
+ h->setUp();
+ ASSERT_FALSE(h->m_autoReadOn);
+ ASSERT_FALSE(h->m_autoTestOn);
+ ASSERT_FALSE(h->m_timerEventOdd);
}
TEST_F(HardwareTestTest, test_helpCmd) {
- HardwareTest::helpCmd();
+ h->helpCmd();
}
TEST_F(HardwareTestTest, test_sendCmd) {
EXPECT_CALL(*knitterMock, send);
- HardwareTest::sendCmd();
+ h->sendCmd();
}
TEST_F(HardwareTestTest, test_beepCmd) {
EXPECT_CALL(*arduinoMock, analogWrite).Times(AtLeast(1));
EXPECT_CALL(*arduinoMock, delay).Times(AtLeast(1));
- HardwareTest::beepCmd();
+ h->beepCmd();
}
TEST_F(HardwareTestTest, test_setSingleCmd_fail1) {
EXPECT_CALL(*serialCommandMock, next).WillOnce(Return(nullptr));
- HardwareTest::setSingleCmd();
+ h->setSingleCmd();
}
TEST_F(HardwareTestTest, test_setSingleCmd_fail2) {
EXPECT_CALL(*serialCommandMock, next).WillOnce(Return(twenty));
- HardwareTest::setSingleCmd();
+ h->setSingleCmd();
}
TEST_F(HardwareTestTest, test_setSingleCmd_fail3) {
EXPECT_CALL(*serialCommandMock, next)
.WillOnce(Return(zero))
.WillOnce(Return(nullptr));
- HardwareTest::setSingleCmd();
+ h->setSingleCmd();
}
TEST_F(HardwareTestTest, test_setSingleCmd_fail4) {
EXPECT_CALL(*serialCommandMock, next)
.WillOnce(Return(zero))
.WillOnce(Return(two));
- HardwareTest::setSingleCmd();
+ h->setSingleCmd();
}
TEST_F(HardwareTestTest, test_setSingleCmd_success) {
EXPECT_CALL(*serialCommandMock, next).WillRepeatedly(Return(zero));
EXPECT_CALL(*knitterMock, setSolenoid);
- HardwareTest::setSingleCmd();
+ h->setSingleCmd();
}
TEST_F(HardwareTestTest, test_setAllCmd_fail1) {
EXPECT_CALL(*serialCommandMock, next).WillOnce(Return(nullptr));
- HardwareTest::setAllCmd();
+ h->setAllCmd();
}
TEST_F(HardwareTestTest, test_setAllCmd_fail2) {
EXPECT_CALL(*serialCommandMock, next)
.WillOnce(Return(zero))
.WillOnce(Return(nullptr));
- HardwareTest::setAllCmd();
+ h->setAllCmd();
}
TEST_F(HardwareTestTest, test_setAllCmd_success) {
EXPECT_CALL(*serialCommandMock, next).WillRepeatedly(Return(zero));
EXPECT_CALL(*knitterMock, setSolenoids);
- HardwareTest::setAllCmd();
+ h->setAllCmd();
}
TEST_F(HardwareTestTest, test_readEOLsensorsCmd) {
- HardwareTest::readEOLsensorsCmd();
+ h->readEOLsensorsCmd();
}
TEST_F(HardwareTestTest, test_readEncodersCmd) {
// low
EXPECT_CALL(*arduinoMock, digitalRead).WillRepeatedly(Return(0));
- HardwareTest::readEncodersCmd();
+ h->readEncodersCmd();
// high
EXPECT_CALL(*arduinoMock, digitalRead).WillRepeatedly(Return(1));
- HardwareTest::readEncodersCmd();
+ h->readEncodersCmd();
}
TEST_F(HardwareTestTest, test_autoReadCmd) {
- HardwareTest::autoReadCmd();
+ h->autoReadCmd();
}
TEST_F(HardwareTestTest, test_autoTestCmd) {
- HardwareTest::autoTestCmd();
+ h->autoTestCmd();
}
TEST_F(HardwareTestTest, test_stopCmd) {
- HardwareTest::stopCmd();
+ h->stopCmd();
}
TEST_F(HardwareTestTest, test_quitCmd) {
EXPECT_CALL(*knitterMock, setQuitFlag);
- HardwareTest::quitCmd();
+ h->quitCmd();
}
TEST_F(HardwareTestTest, test_unrecognizedCmd) {
const char buffer[1] = {1};
- HardwareTest::unrecognizedCmd(buffer);
+ h->unrecognizedCmd(buffer);
}
TEST_F(HardwareTestTest, test_loop_default) {
- HardwareTest::m_lastTime = 0;
+ h->m_lastTime = 0;
EXPECT_CALL(*arduinoMock, millis).WillOnce(Return(499));
- HardwareTest::loop();
+ h->loop();
}
-TEST_F(HardwareTestTest, test_loop_autoRead) {
- HardwareTest::m_lastTime = 0;
+TEST_F(HardwareTestTest, test_nullTimerEvent) {
+ h->m_lastTime = 0;
EXPECT_CALL(*arduinoMock, millis).WillOnce(Return(500));
- HardwareTest::m_timerEventOdd = true;
- HardwareTest::m_autoReadOn = true;
- EXPECT_CALL(*arduinoMock, analogRead).Times(2);
- EXPECT_CALL(*arduinoMock, digitalRead).Times(3);
- HardwareTest::loop();
+ h->m_autoReadOn = false;
+ h->m_autoTestOn = false;
+ h->loop();
}
TEST_F(HardwareTestTest, test_loop_autoTestEven) {
- HardwareTest::m_lastTime = 0;
+ h->m_lastTime = 0;
EXPECT_CALL(*arduinoMock, millis).WillOnce(Return(500));
- HardwareTest::m_timerEventOdd = false;
- HardwareTest::m_autoTestOn = true;
+ h->m_timerEventOdd = false;
+ h->m_autoReadOn = true;
+ h->m_autoTestOn = true;
EXPECT_CALL(*arduinoMock, digitalWrite).Times(2);
EXPECT_CALL(*knitterMock, setSolenoids);
- HardwareTest::loop();
+ h->loop();
}
TEST_F(HardwareTestTest, test_loop_autoTestOdd) {
- HardwareTest::m_lastTime = 0;
+ h->m_lastTime = 0;
EXPECT_CALL(*arduinoMock, millis).WillOnce(Return(500));
- HardwareTest::m_timerEventOdd = true;
- HardwareTest::m_autoTestOn = true;
+ h->m_timerEventOdd = true;
+ h->m_autoReadOn = true;
+ h->m_autoTestOn = true;
EXPECT_CALL(*arduinoMock, digitalWrite).Times(2);
EXPECT_CALL(*knitterMock, setSolenoids);
- HardwareTest::loop();
+ h->loop();
}
diff --git a/test/test_knitter.cpp b/test/test_knitter.cpp
index 5e6dfae54..644fad2b1 100644
--- a/test/test_knitter.cpp
+++ b/test/test_knitter.cpp
@@ -33,12 +33,15 @@
using ::testing::_;
using ::testing::AtLeast;
+using ::testing::Mock;
using ::testing::Return;
// global definitions
// references everywhere else must use `extern`
Knitter *knitter;
-HardwareTest *hwTest;
+
+// initialize static member
+HardwareTestInterface *GlobalHardwareTest::m_instance = new HardwareTestMock();
void onPacketReceived(const uint8_t *buffer, size_t size) {
(void)buffer;
@@ -53,7 +56,9 @@ class KnitterTest : public ::testing::Test {
solenoidsMock = solenoidsMockInstance();
encodersMock = encodersMockInstance();
serialEncodingMock = serialEncodingMockInstance();
- hwTestMock = hardwareTestMockInstance();
+ hwTestMock =
+ static_cast(GlobalHardwareTest::m_instance);
+ Mock::AllowLeak(hwTestMock); // because it does not get destructed
expect_constructor();
k = new Knitter();
}
@@ -73,7 +78,8 @@ class KnitterTest : public ::testing::Test {
EncodersMock *encodersMock;
SerialEncodingMock *serialEncodingMock;
HardwareTestMock *hwTestMock;
- Knitter *&k = knitter; // `k` is alias of global `knitter`
+ HardwareTestMock *dummy;
+ Knitter *&k = knitter; // alias of global `knitter`
void expect_constructor() {
EXPECT_CALL(*arduinoMock, pinMode(ENC_PIN_A, INPUT));
@@ -182,6 +188,7 @@ class KnitterTest : public ::testing::Test {
expect_indState();
EXPECT_CALL(*hwTestMock, loop);
expected_fsm();
+ ASSERT_TRUE(Mock::VerifyAndClear(hwTestMock));
}
void expected_set_machine(Machine_t machineType) {
@@ -303,6 +310,8 @@ TEST_F(KnitterTest, test_fsm_test) {
expect_indState<0>();
EXPECT_CALL(*hwTestMock, loop);
expected_fsm();
+
+ ASSERT_TRUE(Mock::VerifyAndClear(hwTestMock));
}
/*!
@@ -373,6 +382,7 @@ TEST_F(KnitterTest, test_startTest) {
EXPECT_CALL(*hwTestMock, setUp);
ASSERT_EQ(k->startTest(Kh910), true);
ASSERT_EQ(k->getState(), s_test);
+ ASSERT_TRUE(Mock::VerifyAndClear(hwTestMock));
}
/*!
@@ -684,6 +694,8 @@ TEST_F(KnitterTest, test_calculatePixelAndSolenoid) {
// K carriage direction right
expected_isr(END_RIGHT[Kh270], Right, Left, Regular, Knit);
expected_test();
+
+ ASSERT_TRUE(Mock::VerifyAndClear(hwTestMock));
}
/*!
@@ -724,6 +736,7 @@ TEST_F(KnitterTest, test_quit_hw_test) {
EXPECT_CALL(*hwTestMock, loop);
k->state_test();
ASSERT_EQ(k->getState(), s_ready);
+ ASSERT_TRUE(Mock::VerifyAndClear(hwTestMock));
}
/*!