From 78a04377a964a7c64e6fd619086d85b7be83683f Mon Sep 17 00:00:00 2001 From: Pawel Podhajski Date: Wed, 17 Jan 2018 10:28:26 +0100 Subject: [PATCH 1/8] Added new Planar device suppport --- doc/Changelog.md | 2 + tests/cpp/core/MultiScreenControllerTests.cpp | 96 +++++++++++ .../cpp/core/ScreenControllerFactoryTests.cpp | 160 ++++++++++++++++++ tests/mock/CMakeLists.txt | 1 + tests/mock/MockScreenController.h | 73 ++++++++ tide/core/types.h | 16 ++ tide/master/MultiScreenController.cpp | 4 +- tide/master/MultiScreenController.h | 4 +- tide/master/PlanarController.cpp | 14 +- tide/master/PlanarController.h | 3 +- tide/master/ScreenControllerFactory.cpp | 68 ++++++-- tide/master/ScreenControllerFactory.h | 12 ++ 12 files changed, 430 insertions(+), 23 deletions(-) create mode 100644 tests/cpp/core/MultiScreenControllerTests.cpp create mode 100644 tests/cpp/core/ScreenControllerFactoryTests.cpp create mode 100644 tests/mock/MockScreenController.h diff --git a/doc/Changelog.md b/doc/Changelog.md index ee050485..dff42789 100644 --- a/doc/Changelog.md +++ b/doc/Changelog.md @@ -3,6 +3,8 @@ Changelog {#changelog} # Release 1.5 (git master) +* [229](https://github.com/BlueBrain/Tide/pull/229): + Different models of Planar TV can be controlled now. * [226](https://github.com/BlueBrain/Tide/pull/226): New pyramidify tool to simplify the creation of multiple TIFF image pyramids. * [224](https://github.com/BlueBrain/Tide/pull/224): diff --git a/tests/cpp/core/MultiScreenControllerTests.cpp b/tests/cpp/core/MultiScreenControllerTests.cpp new file mode 100644 index 00000000..927d78c0 --- /dev/null +++ b/tests/cpp/core/MultiScreenControllerTests.cpp @@ -0,0 +1,96 @@ +/*********************************************************************/ +/* Copyright (c) 2017, EPFL/Blue Brain Project */ +/* Pawel Podhajski */ +/* All rights reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* 1. Redistributions of source code must retain the above */ +/* copyright notice, this list of conditions and the following */ +/* disclaimer. */ +/* */ +/* 2. Redistributions in binary form must reproduce the above */ +/* copyright notice, this list of conditions and the following */ +/* disclaimer in the documentation and/or other materials */ +/* provided with the distribution. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF TEXAS AT */ +/* AUSTIN ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, */ +/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */ +/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ +/* DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT */ +/* AUSTIN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ +/* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ +/* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE */ +/* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR */ +/* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */ +/* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ +/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT */ +/* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ +/* POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/* The views and conclusions contained in the software and */ +/* documentation are those of the authors and should not be */ +/* interpreted as representing official policies, either expressed */ +/* or implied, of Ecole polytechnique federale de Lausanne. */ +/*********************************************************************/ + +#define BOOST_TEST_MODULE MutliScreenControllerTest + +#include + +#include "MockScreenController.h" +#include "MultiScreenController.h" +#include "ScreenController.h" +#include "types.h" + + +BOOST_AUTO_TEST_CASE(testUniformScreenStates) +{ + auto mockController1 = new MockScreenController(ScreenState::ON); + auto mockController2 = new MockScreenController(ScreenState::ON); + std::vector> controllers; + + controllers.push_back(std::unique_ptr(mockController1)); + controllers.push_back(std::unique_ptr(mockController2)); + + auto multiController = new MultiScreenController(std::move(controllers)); + multiController->getState(); + BOOST_CHECK_EQUAL(multiController->getState(), ScreenState::ON); +} + +BOOST_AUTO_TEST_CASE(testDifferentScreenStates) +{ + auto mockControllerOn = new MockScreenController(ScreenState::ON); + auto mockControllerOff = new MockScreenController(ScreenState::OFF); + std::vector> controllers; + + controllers.push_back(std::unique_ptr(mockControllerOn)); + controllers.push_back(std::unique_ptr(mockControllerOff)); + + auto multiController = new MultiScreenController(std::move(controllers)); + multiController->getState(); + + BOOST_CHECK_EQUAL(multiController->getState(), ScreenState::UNDEF); + +} + +BOOST_AUTO_TEST_CASE(testSignals) +{ + auto mockController = new MockScreenController(ScreenState::ON); + std::vector> controllers; + controllers.push_back(std::unique_ptr(mockController)); + + auto multiController = new MultiScreenController(std::move(controllers)); + + multiController->checkPowerState(); + BOOST_CHECK_EQUAL(multiController->getState(), ScreenState::ON); + + multiController->powerOff(); + BOOST_CHECK_EQUAL(multiController->getState(), ScreenState::OFF); + + multiController->powerOn(); + BOOST_CHECK_EQUAL(multiController->getState(), ScreenState::ON); +} diff --git a/tests/cpp/core/ScreenControllerFactoryTests.cpp b/tests/cpp/core/ScreenControllerFactoryTests.cpp new file mode 100644 index 00000000..4e57bacb --- /dev/null +++ b/tests/cpp/core/ScreenControllerFactoryTests.cpp @@ -0,0 +1,160 @@ +/*********************************************************************/ +/* Copyright (c) 2017, EPFL/Blue Brain Project */ +/* Pawel Podhajski */ +/* All rights reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* 1. Redistributions of source code must retain the above */ +/* copyright notice, this list of conditions and the following */ +/* disclaimer. */ +/* */ +/* 2. Redistributions in binary form must reproduce the above */ +/* copyright notice, this list of conditions and the following */ +/* disclaimer in the documentation and/or other materials */ +/* provided with the distribution. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF TEXAS AT */ +/* AUSTIN ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, */ +/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */ +/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ +/* DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT */ +/* AUSTIN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ +/* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ +/* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE */ +/* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR */ +/* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */ +/* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ +/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT */ +/* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ +/* POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/* The views and conclusions contained in the software and */ +/* documentation are those of the authors and should not be */ +/* interpreted as representing official policies, either expressed */ +/* or implied, of Ecole polytechnique federale de Lausanne. */ +/*********************************************************************/ + +#define BOOST_TEST_MODULE ScreenControllerFactoryTest + +#include + +#include "MultiScreenController.h" +#include "PlanarController.h" +#include "ScreenControllerFactory.h" + +#include + +inline std::ostream& operator<<(std::ostream& str, + const PlanarController::Type& type) +{ + switch (type) + { + case PlanarController::Type::TV_UR9850: + str << "TV_UR9850"; + break; + case PlanarController::Type::TV_UR9851: + str << "TV_UR9851"; + break; + case PlanarController::Type::Matrix: + str << "Matrix"; + break; + default: + break; + } + return str; +} + +BOOST_AUTO_TEST_CASE(testException) +{ + BOOST_CHECK_THROW(ScreenControllerFactory::create("/dev/null;/dev/das"), + std::runtime_error); + BOOST_CHECK_THROW(ScreenControllerFactory::create( + "/dev/null#UR9850;/dev/null#UR9851"), + std::runtime_error); + BOOST_CHECK_THROW(ScreenControllerFactory::create("/dev/null#UR9850"), + std::runtime_error); + BOOST_CHECK_THROW(ScreenControllerFactory::create("/dev/null"), + std::runtime_error) +} + +BOOST_AUTO_TEST_CASE(testNonseparatedSerial) +{ + QMap expectedMatrix; + expectedMatrix.insert("/dev/usb1", PlanarController::Type::Matrix); + + const auto processedMatrix = + ScreenControllerFactory::processInputString("/dev/usb1"); + + BOOST_CHECK_EQUAL_COLLECTIONS(expectedMatrix.begin(), expectedMatrix.end(), + processedMatrix.begin(), + processedMatrix.end()); + + QMap expectedUR9850; + expectedUR9850.insert("/dev/usb1", PlanarController::Type::TV_UR9850); + + const auto processedUR9850 = + ScreenControllerFactory::processInputString("/dev/usb1#UR9850"); + + BOOST_CHECK_EQUAL_COLLECTIONS(expectedUR9850.begin(), expectedUR9850.end(), + processedUR9850.begin(), + processedUR9850.end()); + + QMap expectedUR9851; + expectedUR9851.insert("/dev/usb1", PlanarController::Type::TV_UR9851); + + const auto processedUR9851 = + ScreenControllerFactory::processInputString("/dev/usb1#UR9851"); + + BOOST_CHECK_EQUAL_COLLECTIONS(expectedUR9851.begin(), expectedUR9851.end(), + processedUR9851.begin(), + processedUR9851.end()); +} + +BOOST_AUTO_TEST_CASE(testSeparatedSerials) +{ + QMap expected; + expected.insert("/dev/usb1", PlanarController::Type::Matrix); + expected.insert("/dev/usb2", PlanarController::Type::TV_UR9850); + expected.insert("/dev/usb3", PlanarController::Type::TV_UR9851); + const auto processed = ScreenControllerFactory::processInputString( + "/dev/usb1;/dev/usb2#UR9850;/dev/usb3#UR9851"); + + BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), + processed.begin(), processed.end()); +} + +BOOST_AUTO_TEST_CASE(testEmptySerial) +{ + QMap expected; + expected.insert("/dev/usb1", PlanarController::Type::Matrix); + const auto processed = + ScreenControllerFactory::processInputString(";/dev/usb1"); + + BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), + processed.begin(), processed.end()); +} + +BOOST_AUTO_TEST_CASE(testEmptySerialDeviceWithHash) +{ + QMap expected; + expected.insert("/dev/usb1", PlanarController::Type::Matrix); + const auto processed = + ScreenControllerFactory::processInputString("#UR9850;/dev/usb1"); + + BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), + processed.begin(), processed.end()); +} + +BOOST_AUTO_TEST_CASE(testEmptySerialTypeWithHash) +{ + QMap expected; + expected.insert("/dev/usb1", PlanarController::Type::Matrix); + const auto processed = + ScreenControllerFactory::processInputString("/dev/usb1#"); + + BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), + processed.begin(), processed.end()); +} diff --git a/tests/mock/CMakeLists.txt b/tests/mock/CMakeLists.txt index 3a15a175..937c1e25 100644 --- a/tests/mock/CMakeLists.txt +++ b/tests/mock/CMakeLists.txt @@ -19,5 +19,6 @@ target_sources(TideMock INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/MinimalGlobalQtApp.h" "${CMAKE_CURRENT_SOURCE_DIR}/MockNetworkBarrier.h" "${CMAKE_CURRENT_SOURCE_DIR}/MockTouchEvents.h" + "${CMAKE_CURRENT_SOURCE_DIR}/MockScreenController.h" "${CMAKE_CURRENT_SOURCE_DIR}/QGuiAppFixture.h" ) diff --git a/tests/mock/MockScreenController.h b/tests/mock/MockScreenController.h new file mode 100644 index 00000000..bb614351 --- /dev/null +++ b/tests/mock/MockScreenController.h @@ -0,0 +1,73 @@ +/*********************************************************************/ +/* Copyright (c) 2017, EPFL/Blue Brain Project */ +/* Raphael Dumusc */ +/* All rights reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* 1. Redistributions of source code must retain the above */ +/* copyright notice, this list of conditions and the following */ +/* disclaimer. */ +/* */ +/* 2. Redistributions in binary form must reproduce the above */ +/* copyright notice, this list of conditions and the following */ +/* disclaimer in the documentation and/or other materials */ +/* provided with the distribution. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF TEXAS AT */ +/* AUSTIN ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, */ +/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */ +/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ +/* DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT */ +/* AUSTIN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ +/* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ +/* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE */ +/* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR */ +/* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */ +/* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ +/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT */ +/* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ +/* POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/* The views and conclusions contained in the software and */ +/* documentation are those of the authors and should not be */ +/* interpreted as representing official policies, either expressed */ +/* or implied, of Ecole polytechnique federale de Lausanne. */ +/*********************************************************************/ + +#ifndef MOCKSCREENCONTROLLER_H +#define MOCKSCREENCONTROLLER_H + +#include "ScreenController.h" +#include "types.h" + +#include + +class MockScreenController : public ScreenController +{ + Q_OBJECT +public: + MockScreenController(ScreenState state) + : _state(state) + { + } + ScreenState getState() const { return _state; } + void checkPowerState() { emit powerStateChanged(_state); } + bool powerOn() + { + _state = ScreenState::ON; + return true; + } + bool powerOff() + { + _state = ScreenState::OFF; + return true; + } + +private: + ScreenState _state; +}; + +#endif diff --git a/tide/core/types.h b/tide/core/types.h index 650af05b..b7e68589 100644 --- a/tide/core/types.h +++ b/tide/core/types.h @@ -202,6 +202,22 @@ inline std::ostream& operator<<(std::ostream& str, const QPointF& p) return str; } +inline std::ostream& operator<<(std::ostream& str, const ScreenState state) +{ + switch (state) + { + case ScreenState::ON: + str << "ON"; + return str; + case ScreenState::OFF: + str << "OFF"; + return str; + default: + str << "UNDEF"; + } + return str; +} + inline std::ostream& operator<<(std::ostream& str, const QRectF& r) { str << r.x() << ',' << r.y() << ' ' << r.width() << 'x' << r.height(); diff --git a/tide/master/MultiScreenController.cpp b/tide/master/MultiScreenController.cpp index ae461c1b..54dab7dd 100644 --- a/tide/master/MultiScreenController.cpp +++ b/tide/master/MultiScreenController.cpp @@ -43,7 +43,7 @@ #include "PlanarController.h" MultiScreenController::MultiScreenController( - std::vector>&& controllers) + std::vector>&& controllers) : _controllers{std::move(controllers)} { for (auto& controller : _controllers) @@ -84,7 +84,7 @@ bool MultiScreenController::powerOff() bool success = true; for (auto& controller : _controllers) { - if (controller->powerOff()) + if (!controller->powerOff()) success = false; } return success; diff --git a/tide/master/MultiScreenController.h b/tide/master/MultiScreenController.h index 1f72d8e8..1238c2cf 100644 --- a/tide/master/MultiScreenController.h +++ b/tide/master/MultiScreenController.h @@ -60,7 +60,7 @@ class MultiScreenController : public ScreenController * @param controllers the list of controllers */ MultiScreenController( - std::vector>&& controllers); + std::vector>&& controllers); /** Get the power state of controlled displays. */ ScreenState getState() const final; @@ -75,7 +75,7 @@ class MultiScreenController : public ScreenController bool powerOff() final; private: - std::vector> _controllers; + std::vector> _controllers; }; #endif diff --git a/tide/master/PlanarController.cpp b/tide/master/PlanarController.cpp index 3f9e0f2a..02eac942 100644 --- a/tide/master/PlanarController.cpp +++ b/tide/master/PlanarController.cpp @@ -57,11 +57,15 @@ PlanarController::PlanarController(const QString& serialport, const Type type) if (!_serial.open(QIODevice::ReadWrite)) throw std::runtime_error("Could not open " + serialport.toStdString()); - connect(&_serial, &QSerialPort::readyRead, [this]() { + connect(&_serial, &QSerialPort::readyRead, [this, type]() { if (_serial.canReadLine()) { QString output(_serial.readLine()); output = output.trimmed(); + // TV_UR9850 returns "(0;PWR=0)" + // Others return DISPLAY.POWER=O or DISPLAY.POWER=OFF + if (type == Type::TV_UR9850) + output.remove(")"); ScreenState previousState = _state; if (output.endsWith("OFF") || output.endsWith("0")) _state = ScreenState::OFF; @@ -107,9 +111,11 @@ PlanarController::PlanarConfig PlanarController::_getConfig( { switch (type) { - case Type::TV: - return {19200, "DISPLAY.POWER=ON\r", "DISPLAY.POWER=OFF\r", - "DISPLAY.POWER?\r"}; + case Type::TV_UR9851: + return {19200, "DISPLAY.POWER=ON\n", "DISPLAY.POWER=OFF\n", + "DISPLAY.POWER?\n"}; + case Type::TV_UR9850: + return {19200, "(PWR=1)\r", "(PWR=0)\r", "(PWR?)\r"}; case Type::Matrix: return {9600, "OPA1DISPLAY.POWER=ON\r", "OPA1DISPLAY.POWER=OFF\r", "OPA1DISPLAY.POWER?\r"}; diff --git a/tide/master/PlanarController.h b/tide/master/PlanarController.h index 12b31889..82ada854 100644 --- a/tide/master/PlanarController.h +++ b/tide/master/PlanarController.h @@ -61,7 +61,8 @@ class PlanarController : public ScreenController enum class Type { Matrix, - TV + TV_UR9850, + TV_UR9851 }; /** diff --git a/tide/master/ScreenControllerFactory.cpp b/tide/master/ScreenControllerFactory.cpp index 9fe363a0..ad6ab73e 100644 --- a/tide/master/ScreenControllerFactory.cpp +++ b/tide/master/ScreenControllerFactory.cpp @@ -40,30 +40,70 @@ #include "ScreenControllerFactory.h" #include "MultiScreenController.h" -#include "PlanarController.h" +#include #include +namespace +{ +PlanarController::Type _getType(const QString& name = "Matrix") +{ + if (name == "UR9850") + return PlanarController::Type::TV_UR9850; + if (name == "UR9851") + return PlanarController::Type::TV_UR9851; + return PlanarController::Type::Matrix; +} +} + std::unique_ptr ScreenControllerFactory::create( const QString& ports) { - auto serialports = ports.split(';'); - if (serialports.length() == 0) + const auto connections = processInputString(ports); + if (connections.size() == 0) return nullptr; - if (serialports.length() == 1) - { - return std::unique_ptr( - new PlanarController(serialports[0], - PlanarController::Type::Matrix)); - } - std::vector> controllers; - for (const auto serialport : serialports) + std::vector> controllers; + for (const auto key : connections.keys()) { - auto controller = std::unique_ptr( - new PlanarController(serialport, PlanarController::Type::TV)); - controllers.push_back(std::move(controller)); + controllers.emplace_back( + new PlanarController(key, connections.value(key))); } + if (controllers.size() == 1) + return std::move(controllers[0]); + return std::unique_ptr( new MultiScreenController(std::move(controllers))); } + +QMap + ScreenControllerFactory::processInputString(const QString& ports) +{ + QMap map; + + const auto connections = ports.split(';'); + if (connections.length() == 0) + return map; + for (auto connection : connections) + { + if (connection.isEmpty()) + continue; + + if (connection.contains("#")) + { + auto serialEntity = connection.split("#"); + const auto& serialPort = serialEntity[0]; + if (serialPort.isEmpty()) + continue; + const auto type = _getType(serialEntity[1]); + map.insert(serialPort, type); + } + else + { + const auto& serialPort = connection; + const auto type = _getType(); + map.insert(serialPort, type); + } + } + return map; +} diff --git a/tide/master/ScreenControllerFactory.h b/tide/master/ScreenControllerFactory.h index 7869354b..f012c28e 100644 --- a/tide/master/ScreenControllerFactory.h +++ b/tide/master/ScreenControllerFactory.h @@ -40,6 +40,7 @@ #ifndef ScreenControllerFactory_H #define ScreenControllerFactory_H +#include "PlanarController.h" #include "ScreenController.h" /** @@ -48,7 +49,18 @@ class ScreenControllerFactory { public: + /** + * Create a ScreenController. + * @param ports a configurable combination of port and device type. + */ static std::unique_ptr create(const QString& ports); + + /** + * Process and validate a combination of port and device type. + * @param ports a configurable combination of port and device type. + */ + static QMap processInputString( + const QString& ports); }; #endif From 8c76f78b9f8306548523065c38dbf2ed1ed7788a Mon Sep 17 00:00:00 2001 From: Pawel Jozef Podhajski Date: Fri, 19 Jan 2018 11:13:31 +0100 Subject: [PATCH 2/8] CR1 --- tests/cpp/core/MultiScreenControllerTests.cpp | 70 ++++++++++++------- .../cpp/core/ScreenControllerFactoryTests.cpp | 39 ++++++----- tests/mock/MockScreenController.h | 11 ++- tide/core/types.h | 5 +- tide/master/PlanarController.cpp | 4 +- tide/master/ScreenControllerFactory.cpp | 20 +++--- tide/master/ScreenControllerFactory.h | 2 +- 7 files changed, 89 insertions(+), 62 deletions(-) diff --git a/tests/cpp/core/MultiScreenControllerTests.cpp b/tests/cpp/core/MultiScreenControllerTests.cpp index 927d78c0..2996214e 100644 --- a/tests/cpp/core/MultiScreenControllerTests.cpp +++ b/tests/cpp/core/MultiScreenControllerTests.cpp @@ -1,5 +1,5 @@ /*********************************************************************/ -/* Copyright (c) 2017, EPFL/Blue Brain Project */ +/* Copyright (c) 2018, EPFL/Blue Brain Project */ /* Pawel Podhajski */ /* All rights reserved. */ /* */ @@ -46,51 +46,69 @@ #include "ScreenController.h" #include "types.h" - BOOST_AUTO_TEST_CASE(testUniformScreenStates) { - auto mockController1 = new MockScreenController(ScreenState::ON); - auto mockController2 = new MockScreenController(ScreenState::ON); std::vector> controllers; - controllers.push_back(std::unique_ptr(mockController1)); - controllers.push_back(std::unique_ptr(mockController2)); + controllers.emplace_back(new MockScreenController(ScreenState::ON)); + controllers.emplace_back(new MockScreenController(ScreenState::ON)); + + MultiScreenController multiController(std::move(controllers)); + + multiController.powerOn(); + + for (auto& controller : controllers) + { + BOOST_CHECK( + static_cast(*controller).powerOnCalled); + } + multiController.powerOff(); + + for (auto& controller : controllers) + { + BOOST_CHECK( + static_cast(*controller).powerOffCalled); + } + BOOST_CHECK_EQUAL(multiController.getState(), ScreenState::OFF); - auto multiController = new MultiScreenController(std::move(controllers)); - multiController->getState(); - BOOST_CHECK_EQUAL(multiController->getState(), ScreenState::ON); } BOOST_AUTO_TEST_CASE(testDifferentScreenStates) { - auto mockControllerOn = new MockScreenController(ScreenState::ON); - auto mockControllerOff = new MockScreenController(ScreenState::OFF); std::vector> controllers; + controllers.emplace_back(new MockScreenController(ScreenState::ON)); + controllers.emplace_back(new MockScreenController(ScreenState::OFF)); - controllers.push_back(std::unique_ptr(mockControllerOn)); - controllers.push_back(std::unique_ptr(mockControllerOff)); - - auto multiController = new MultiScreenController(std::move(controllers)); - multiController->getState(); - - BOOST_CHECK_EQUAL(multiController->getState(), ScreenState::UNDEF); + MultiScreenController multiController(std::move(controllers)); + multiController.getState(); + BOOST_CHECK_EQUAL(multiController.getState(), ScreenState::UNDEF); } -BOOST_AUTO_TEST_CASE(testSignals) +BOOST_AUTO_TEST_CASE(testSignalAndControllers) { auto mockController = new MockScreenController(ScreenState::ON); std::vector> controllers; controllers.push_back(std::unique_ptr(mockController)); - auto multiController = new MultiScreenController(std::move(controllers)); + MultiScreenController multiController(std::move(controllers)); + + bool emitted = false; + + QObject::connect(&multiController, &MultiScreenController::powerStateChanged, + [this, &emitted]() { emitted = true; }); - multiController->checkPowerState(); - BOOST_CHECK_EQUAL(multiController->getState(), ScreenState::ON); + multiController.checkPowerState(); + BOOST_CHECK_EQUAL(multiController.getState(), ScreenState::ON); + BOOST_CHECK_EQUAL(emitted, true); - multiController->powerOff(); - BOOST_CHECK_EQUAL(multiController->getState(), ScreenState::OFF); + emitted = false; + multiController.powerOff(); + BOOST_CHECK_EQUAL(multiController.getState(), ScreenState::OFF); + BOOST_CHECK_EQUAL(emitted, true); - multiController->powerOn(); - BOOST_CHECK_EQUAL(multiController->getState(), ScreenState::ON); + emitted = false; + multiController.powerOn(); + BOOST_CHECK_EQUAL(multiController.getState(), ScreenState::ON); + BOOST_CHECK_EQUAL(emitted, true); } diff --git a/tests/cpp/core/ScreenControllerFactoryTests.cpp b/tests/cpp/core/ScreenControllerFactoryTests.cpp index 4e57bacb..a3d55b85 100644 --- a/tests/cpp/core/ScreenControllerFactoryTests.cpp +++ b/tests/cpp/core/ScreenControllerFactoryTests.cpp @@ -1,5 +1,5 @@ /*********************************************************************/ -/* Copyright (c) 2017, EPFL/Blue Brain Project */ +/* Copyright (c) 2018, EPFL/Blue Brain Project */ /* Pawel Podhajski */ /* All rights reserved. */ /* */ @@ -48,7 +48,7 @@ #include inline std::ostream& operator<<(std::ostream& str, - const PlanarController::Type& type) + const PlanarController::Type type) { switch (type) { @@ -82,31 +82,31 @@ BOOST_AUTO_TEST_CASE(testException) BOOST_AUTO_TEST_CASE(testNonseparatedSerial) { - QMap expectedMatrix; - expectedMatrix.insert("/dev/usb1", PlanarController::Type::Matrix); + const QMap expectedMatrix{ + {"/dev/usb1", PlanarController::Type::Matrix}}; const auto processedMatrix = - ScreenControllerFactory::processInputString("/dev/usb1"); + ScreenControllerFactory::parseInputString("/dev/usb1"); BOOST_CHECK_EQUAL_COLLECTIONS(expectedMatrix.begin(), expectedMatrix.end(), processedMatrix.begin(), processedMatrix.end()); - QMap expectedUR9850; - expectedUR9850.insert("/dev/usb1", PlanarController::Type::TV_UR9850); + const QMap expectedUR9850{ + {"/dev/usb1", PlanarController::Type::TV_UR9850}}; const auto processedUR9850 = - ScreenControllerFactory::processInputString("/dev/usb1#UR9850"); + ScreenControllerFactory::parseInputString("/dev/usb1#UR9850"); BOOST_CHECK_EQUAL_COLLECTIONS(expectedUR9850.begin(), expectedUR9850.end(), processedUR9850.begin(), processedUR9850.end()); - QMap expectedUR9851; - expectedUR9851.insert("/dev/usb1", PlanarController::Type::TV_UR9851); + const QMap expectedUR9851{ + {"/dev/usb1", PlanarController::Type::TV_UR9851}}; const auto processedUR9851 = - ScreenControllerFactory::processInputString("/dev/usb1#UR9851"); + ScreenControllerFactory::parseInputString("/dev/usb1#UR9851"); BOOST_CHECK_EQUAL_COLLECTIONS(expectedUR9851.begin(), expectedUR9851.end(), processedUR9851.begin(), @@ -115,11 +115,12 @@ BOOST_AUTO_TEST_CASE(testNonseparatedSerial) BOOST_AUTO_TEST_CASE(testSeparatedSerials) { - QMap expected; - expected.insert("/dev/usb1", PlanarController::Type::Matrix); - expected.insert("/dev/usb2", PlanarController::Type::TV_UR9850); - expected.insert("/dev/usb3", PlanarController::Type::TV_UR9851); - const auto processed = ScreenControllerFactory::processInputString( + const QMap expected{ + {"/dev/usb1", PlanarController::Type::Matrix}, + {"/dev/usb2", PlanarController::Type::TV_UR9850}, + {"/dev/usb3", PlanarController::Type::TV_UR9851}}; + + const auto processed = ScreenControllerFactory::parseInputString( "/dev/usb1;/dev/usb2#UR9850;/dev/usb3#UR9851"); BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), @@ -131,7 +132,7 @@ BOOST_AUTO_TEST_CASE(testEmptySerial) QMap expected; expected.insert("/dev/usb1", PlanarController::Type::Matrix); const auto processed = - ScreenControllerFactory::processInputString(";/dev/usb1"); + ScreenControllerFactory::parseInputString(";/dev/usb1"); BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), processed.begin(), processed.end()); @@ -142,7 +143,7 @@ BOOST_AUTO_TEST_CASE(testEmptySerialDeviceWithHash) QMap expected; expected.insert("/dev/usb1", PlanarController::Type::Matrix); const auto processed = - ScreenControllerFactory::processInputString("#UR9850;/dev/usb1"); + ScreenControllerFactory::parseInputString("#UR9850;/dev/usb1"); BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), processed.begin(), processed.end()); @@ -153,7 +154,7 @@ BOOST_AUTO_TEST_CASE(testEmptySerialTypeWithHash) QMap expected; expected.insert("/dev/usb1", PlanarController::Type::Matrix); const auto processed = - ScreenControllerFactory::processInputString("/dev/usb1#"); + ScreenControllerFactory::parseInputString("/dev/usb1#"); BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), processed.begin(), processed.end()); diff --git a/tests/mock/MockScreenController.h b/tests/mock/MockScreenController.h index bb614351..bf66c7f0 100644 --- a/tests/mock/MockScreenController.h +++ b/tests/mock/MockScreenController.h @@ -1,6 +1,6 @@ /*********************************************************************/ -/* Copyright (c) 2017, EPFL/Blue Brain Project */ -/* Raphael Dumusc */ +/* Copyright (c) 2018, EPFL/Blue Brain Project */ +/* Pawel Podhajski */ /* All rights reserved. */ /* */ /* Redistribution and use in source and binary forms, with or */ @@ -58,14 +58,21 @@ class MockScreenController : public ScreenController bool powerOn() { _state = ScreenState::ON; + emit powerStateChanged(_state); + powerOnCalled = true; return true; } bool powerOff() { _state = ScreenState::OFF; + emit powerStateChanged(_state); + powerOffCalled = true; return true; } + bool powerOffCalled = false; + bool powerOnCalled = false; + private: ScreenState _state; }; diff --git a/tide/core/types.h b/tide/core/types.h index b7e68589..462adb78 100644 --- a/tide/core/types.h +++ b/tide/core/types.h @@ -208,12 +208,13 @@ inline std::ostream& operator<<(std::ostream& str, const ScreenState state) { case ScreenState::ON: str << "ON"; - return str; + break; case ScreenState::OFF: str << "OFF"; - return str; + break; default: str << "UNDEF"; + break; } return str; } diff --git a/tide/master/PlanarController.cpp b/tide/master/PlanarController.cpp index 02eac942..37522ffc 100644 --- a/tide/master/PlanarController.cpp +++ b/tide/master/PlanarController.cpp @@ -111,11 +111,11 @@ PlanarController::PlanarConfig PlanarController::_getConfig( { switch (type) { + case Type::TV_UR9850: + return {19200, "(PWR=1)\r", "(PWR=0)\r", "(PWR?)\r"}; case Type::TV_UR9851: return {19200, "DISPLAY.POWER=ON\n", "DISPLAY.POWER=OFF\n", "DISPLAY.POWER?\n"}; - case Type::TV_UR9850: - return {19200, "(PWR=1)\r", "(PWR=0)\r", "(PWR?)\r"}; case Type::Matrix: return {9600, "OPA1DISPLAY.POWER=ON\r", "OPA1DISPLAY.POWER=OFF\r", "OPA1DISPLAY.POWER?\r"}; diff --git a/tide/master/ScreenControllerFactory.cpp b/tide/master/ScreenControllerFactory.cpp index ad6ab73e..d211fd9f 100644 --- a/tide/master/ScreenControllerFactory.cpp +++ b/tide/master/ScreenControllerFactory.cpp @@ -41,12 +41,12 @@ #include "MultiScreenController.h" -#include +#include #include namespace { -PlanarController::Type _getType(const QString& name = "Matrix") +PlanarController::Type _getType(const QString& name) { if (name == "UR9850") return PlanarController::Type::TV_UR9850; @@ -59,8 +59,8 @@ PlanarController::Type _getType(const QString& name = "Matrix") std::unique_ptr ScreenControllerFactory::create( const QString& ports) { - const auto connections = processInputString(ports); - if (connections.size() == 0) + const auto connections = parseInputString(ports); + if (connections.empty()) return nullptr; std::vector> controllers; @@ -76,22 +76,22 @@ std::unique_ptr ScreenControllerFactory::create( new MultiScreenController(std::move(controllers))); } -QMap - ScreenControllerFactory::processInputString(const QString& ports) +QMap ScreenControllerFactory::parseInputString( + const QString& ports) { QMap map; const auto connections = ports.split(';'); - if (connections.length() == 0) + if (connections.empty()) return map; - for (auto connection : connections) + for (const auto& connection : connections) { if (connection.isEmpty()) continue; if (connection.contains("#")) { - auto serialEntity = connection.split("#"); + const auto serialEntity = connection.split("#"); const auto& serialPort = serialEntity[0]; if (serialPort.isEmpty()) continue; @@ -101,7 +101,7 @@ QMap else { const auto& serialPort = connection; - const auto type = _getType(); + const auto type = _getType(""); map.insert(serialPort, type); } } diff --git a/tide/master/ScreenControllerFactory.h b/tide/master/ScreenControllerFactory.h index f012c28e..35f8b0c1 100644 --- a/tide/master/ScreenControllerFactory.h +++ b/tide/master/ScreenControllerFactory.h @@ -59,7 +59,7 @@ class ScreenControllerFactory * Process and validate a combination of port and device type. * @param ports a configurable combination of port and device type. */ - static QMap processInputString( + static QMap parseInputString( const QString& ports); }; From cee7f392c95c16846ea02fe377e5ad0ae2d696be Mon Sep 17 00:00:00 2001 From: Pawel Podhajski Date: Fri, 19 Jan 2018 14:54:05 +0100 Subject: [PATCH 3/8] cr2 --- tests/cpp/core/MultiScreenControllerTests.cpp | 27 +++++++------- .../cpp/core/ScreenControllerFactoryTests.cpp | 35 ++++++++++--------- tests/mock/MockScreenController.h | 11 +++--- tide/core/types.h | 2 +- tide/master/PlanarController.cpp | 6 ++-- tide/master/ScreenControllerFactory.cpp | 7 ++-- tide/master/ScreenControllerFactory.h | 1 + 7 files changed, 47 insertions(+), 42 deletions(-) diff --git a/tests/cpp/core/MultiScreenControllerTests.cpp b/tests/cpp/core/MultiScreenControllerTests.cpp index 2996214e..90880a64 100644 --- a/tests/cpp/core/MultiScreenControllerTests.cpp +++ b/tests/cpp/core/MultiScreenControllerTests.cpp @@ -49,12 +49,13 @@ BOOST_AUTO_TEST_CASE(testUniformScreenStates) { std::vector> controllers; - - controllers.emplace_back(new MockScreenController(ScreenState::ON)); - controllers.emplace_back(new MockScreenController(ScreenState::ON)); + controllers.emplace_back(new MockScreenController(ScreenState::UNDEF)); + controllers.emplace_back(new MockScreenController(ScreenState::UNDEF)); MultiScreenController multiController(std::move(controllers)); + BOOST_CHECK_EQUAL(multiController.getState(), ScreenState::UNDEF); + multiController.powerOn(); for (auto& controller : controllers) @@ -62,6 +63,9 @@ BOOST_AUTO_TEST_CASE(testUniformScreenStates) BOOST_CHECK( static_cast(*controller).powerOnCalled); } + + BOOST_CHECK_EQUAL(multiController.getState(), ScreenState::ON); + multiController.powerOff(); for (auto& controller : controllers) @@ -70,7 +74,6 @@ BOOST_AUTO_TEST_CASE(testUniformScreenStates) static_cast(*controller).powerOffCalled); } BOOST_CHECK_EQUAL(multiController.getState(), ScreenState::OFF); - } BOOST_AUTO_TEST_CASE(testDifferentScreenStates) @@ -85,30 +88,26 @@ BOOST_AUTO_TEST_CASE(testDifferentScreenStates) BOOST_CHECK_EQUAL(multiController.getState(), ScreenState::UNDEF); } -BOOST_AUTO_TEST_CASE(testSignalAndControllers) +BOOST_AUTO_TEST_CASE(testSignal) { - auto mockController = new MockScreenController(ScreenState::ON); std::vector> controllers; - controllers.push_back(std::unique_ptr(mockController)); - + controllers.emplace_back(new MockScreenController(ScreenState::ON)); MultiScreenController multiController(std::move(controllers)); bool emitted = false; QObject::connect(&multiController, &MultiScreenController::powerStateChanged, - [this, &emitted]() { emitted = true; }); + [&emitted]() { emitted = true; }); multiController.checkPowerState(); - BOOST_CHECK_EQUAL(multiController.getState(), ScreenState::ON); - BOOST_CHECK_EQUAL(emitted, true); + BOOST_CHECK(emitted); emitted = false; multiController.powerOff(); - BOOST_CHECK_EQUAL(multiController.getState(), ScreenState::OFF); - BOOST_CHECK_EQUAL(emitted, true); + BOOST_CHECK(emitted); emitted = false; multiController.powerOn(); BOOST_CHECK_EQUAL(multiController.getState(), ScreenState::ON); - BOOST_CHECK_EQUAL(emitted, true); + BOOST_CHECK(emitted); } diff --git a/tests/cpp/core/ScreenControllerFactoryTests.cpp b/tests/cpp/core/ScreenControllerFactoryTests.cpp index a3d55b85..e6f7b70a 100644 --- a/tests/cpp/core/ScreenControllerFactoryTests.cpp +++ b/tests/cpp/core/ScreenControllerFactoryTests.cpp @@ -52,21 +52,24 @@ inline std::ostream& operator<<(std::ostream& str, { switch (type) { + case PlanarController::Type::Matrix: + str << "Matrix"; + break; case PlanarController::Type::TV_UR9850: str << "TV_UR9850"; break; case PlanarController::Type::TV_UR9851: str << "TV_UR9851"; break; - case PlanarController::Type::Matrix: - str << "Matrix"; - break; - default: - break; } return str; } +BOOST_AUTO_TEST_CASE(testEmpty) +{ + BOOST_CHECK(!ScreenControllerFactory::create("")); +} + BOOST_AUTO_TEST_CASE(testException) { BOOST_CHECK_THROW(ScreenControllerFactory::create("/dev/null;/dev/das"), @@ -80,7 +83,7 @@ BOOST_AUTO_TEST_CASE(testException) std::runtime_error) } -BOOST_AUTO_TEST_CASE(testNonseparatedSerial) +BOOST_AUTO_TEST_CASE(testSingleController) { const QMap expectedMatrix{ {"/dev/usb1", PlanarController::Type::Matrix}}; @@ -113,7 +116,7 @@ BOOST_AUTO_TEST_CASE(testNonseparatedSerial) processedUR9851.end()); } -BOOST_AUTO_TEST_CASE(testSeparatedSerials) +BOOST_AUTO_TEST_CASE(testMultipleConnectionsWithType) { const QMap expected{ {"/dev/usb1", PlanarController::Type::Matrix}, @@ -127,10 +130,10 @@ BOOST_AUTO_TEST_CASE(testSeparatedSerials) processed.begin(), processed.end()); } -BOOST_AUTO_TEST_CASE(testEmptySerial) +BOOST_AUTO_TEST_CASE(testMultipleConnectionsWithOneEmpty) { - QMap expected; - expected.insert("/dev/usb1", PlanarController::Type::Matrix); + const QMap expected{ + {"/dev/usb1", PlanarController::Type::Matrix}}; const auto processed = ScreenControllerFactory::parseInputString(";/dev/usb1"); @@ -138,10 +141,10 @@ BOOST_AUTO_TEST_CASE(testEmptySerial) processed.begin(), processed.end()); } -BOOST_AUTO_TEST_CASE(testEmptySerialDeviceWithHash) +BOOST_AUTO_TEST_CASE(testMultipleConnectionsWithOneEmptyDevice) { - QMap expected; - expected.insert("/dev/usb1", PlanarController::Type::Matrix); + const QMap expected{ + {"/dev/usb1", PlanarController::Type::Matrix}}; const auto processed = ScreenControllerFactory::parseInputString("#UR9850;/dev/usb1"); @@ -149,10 +152,10 @@ BOOST_AUTO_TEST_CASE(testEmptySerialDeviceWithHash) processed.begin(), processed.end()); } -BOOST_AUTO_TEST_CASE(testEmptySerialTypeWithHash) +BOOST_AUTO_TEST_CASE(testConnectionsWithEmptyDeviceType) { - QMap expected; - expected.insert("/dev/usb1", PlanarController::Type::Matrix); + const QMap expected{ + {"/dev/usb1", PlanarController::Type::Matrix}}; const auto processed = ScreenControllerFactory::parseInputString("/dev/usb1#"); diff --git a/tests/mock/MockScreenController.h b/tests/mock/MockScreenController.h index bf66c7f0..1a7ef2cc 100644 --- a/tests/mock/MockScreenController.h +++ b/tests/mock/MockScreenController.h @@ -48,21 +48,24 @@ class MockScreenController : public ScreenController { Q_OBJECT + public: MockScreenController(ScreenState state) : _state(state) { } - ScreenState getState() const { return _state; } - void checkPowerState() { emit powerStateChanged(_state); } - bool powerOn() + ScreenState getState() const final { return _state; } + void checkPowerState() final { emit powerStateChanged(_state); } + + bool powerOn() final { _state = ScreenState::ON; emit powerStateChanged(_state); powerOnCalled = true; return true; } - bool powerOff() + + bool powerOff() final { _state = ScreenState::OFF; emit powerStateChanged(_state); diff --git a/tide/core/types.h b/tide/core/types.h index 462adb78..0868adac 100644 --- a/tide/core/types.h +++ b/tide/core/types.h @@ -212,7 +212,7 @@ inline std::ostream& operator<<(std::ostream& str, const ScreenState state) case ScreenState::OFF: str << "OFF"; break; - default: + case ScreenState::UNDEF: str << "UNDEF"; break; } diff --git a/tide/master/PlanarController.cpp b/tide/master/PlanarController.cpp index 37522ffc..491571da 100644 --- a/tide/master/PlanarController.cpp +++ b/tide/master/PlanarController.cpp @@ -111,14 +111,14 @@ PlanarController::PlanarConfig PlanarController::_getConfig( { switch (type) { + case Type::Matrix: + return {9600, "OPA1DISPLAY.POWER=ON\r", "OPA1DISPLAY.POWER=OFF\r", + "OPA1DISPLAY.POWER?\r"}; case Type::TV_UR9850: return {19200, "(PWR=1)\r", "(PWR=0)\r", "(PWR?)\r"}; case Type::TV_UR9851: return {19200, "DISPLAY.POWER=ON\n", "DISPLAY.POWER=OFF\n", "DISPLAY.POWER?\n"}; - case Type::Matrix: - return {9600, "OPA1DISPLAY.POWER=ON\r", "OPA1DISPLAY.POWER=OFF\r", - "OPA1DISPLAY.POWER?\r"}; default: throw std::invalid_argument("Non existing serial type"); } diff --git a/tide/master/ScreenControllerFactory.cpp b/tide/master/ScreenControllerFactory.cpp index d211fd9f..8e759b79 100644 --- a/tide/master/ScreenControllerFactory.cpp +++ b/tide/master/ScreenControllerFactory.cpp @@ -64,10 +64,9 @@ std::unique_ptr ScreenControllerFactory::create( return nullptr; std::vector> controllers; - for (const auto key : connections.keys()) + for (const auto& kv : connections.toStdMap()) { - controllers.emplace_back( - new PlanarController(key, connections.value(key))); + controllers.emplace_back(new PlanarController(kv.first, kv.second)); } if (controllers.size() == 1) return std::move(controllers[0]); @@ -89,7 +88,7 @@ QMap ScreenControllerFactory::parseInputString( if (connection.isEmpty()) continue; - if (connection.contains("#")) + if (!connection.endsWith("#") && connection.contains("#")) { const auto serialEntity = connection.split("#"); const auto& serialPort = serialEntity[0]; diff --git a/tide/master/ScreenControllerFactory.h b/tide/master/ScreenControllerFactory.h index 35f8b0c1..08a0f137 100644 --- a/tide/master/ScreenControllerFactory.h +++ b/tide/master/ScreenControllerFactory.h @@ -58,6 +58,7 @@ class ScreenControllerFactory /** * Process and validate a combination of port and device type. * @param ports a configurable combination of port and device type. + * @internal */ static QMap parseInputString( const QString& ports); From 5f276f6431914ba28d1e30f7fd4384a2eb6f56ad Mon Sep 17 00:00:00 2001 From: Pawel Podhajski Date: Fri, 19 Jan 2018 16:26:04 +0100 Subject: [PATCH 4/8] cr3 --- tests/cpp/CMakeLists.txt | 7 ++ tests/cpp/core/MultiScreenControllerTests.cpp | 2 - tests/mock/CMakeLists.txt | 9 ++- tests/mock/MockScreenController.cpp | 71 +++++++++++++++++++ tests/mock/MockScreenController.h | 26 ++----- tide/master/MasterApplication.cpp | 5 +- tide/master/MultiScreenController.h | 1 - tide/master/ScreenControllerFactory.cpp | 8 ++- 8 files changed, 100 insertions(+), 29 deletions(-) create mode 100644 tests/mock/MockScreenController.cpp mode change 100644 => 100755 tide/master/ScreenControllerFactory.cpp diff --git a/tests/cpp/CMakeLists.txt b/tests/cpp/CMakeLists.txt index 5ea914a0..f345d9c4 100644 --- a/tests/cpp/CMakeLists.txt +++ b/tests/cpp/CMakeLists.txt @@ -32,6 +32,13 @@ else() ) endif() +if(NOT TIDE_ENABLE_PLANAR_CONTROLLER) + list(APPEND EXCLUDE_FROM_TESTS + core/MultiScreenControllerTests.cpp + core/ScreenControllerFactoryTests.cpp + ) +endif() + if(X11_FOUND) list(APPEND TEST_LIBRARIES ${X11_LIBRARIES}) else() diff --git a/tests/cpp/core/MultiScreenControllerTests.cpp b/tests/cpp/core/MultiScreenControllerTests.cpp index 90880a64..d73e1078 100644 --- a/tests/cpp/core/MultiScreenControllerTests.cpp +++ b/tests/cpp/core/MultiScreenControllerTests.cpp @@ -43,8 +43,6 @@ #include "MockScreenController.h" #include "MultiScreenController.h" -#include "ScreenController.h" -#include "types.h" BOOST_AUTO_TEST_CASE(testUniformScreenStates) { diff --git a/tests/mock/CMakeLists.txt b/tests/mock/CMakeLists.txt index 937c1e25..6ab5f16f 100644 --- a/tests/mock/CMakeLists.txt +++ b/tests/mock/CMakeLists.txt @@ -19,6 +19,13 @@ target_sources(TideMock INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}/MinimalGlobalQtApp.h" "${CMAKE_CURRENT_SOURCE_DIR}/MockNetworkBarrier.h" "${CMAKE_CURRENT_SOURCE_DIR}/MockTouchEvents.h" - "${CMAKE_CURRENT_SOURCE_DIR}/MockScreenController.h" + "${CMAKE_CURRENT_SOURCE_DIR}/QGuiAppFixture.h" ) + +if(TIDE_ENABLE_PLANAR_CONTROLLER) + target_sources(TideMock INTERFACE + "${CMAKE_CURRENT_SOURCE_DIR}/MockScreenController.h" + "${CMAKE_CURRENT_SOURCE_DIR}/MockScreenController.cpp" + ) +endif() diff --git a/tests/mock/MockScreenController.cpp b/tests/mock/MockScreenController.cpp new file mode 100644 index 00000000..ec90c199 --- /dev/null +++ b/tests/mock/MockScreenController.cpp @@ -0,0 +1,71 @@ +/*********************************************************************/ +/* Copyright (c) 2018, EPFL/Blue Brain Project */ +/* Pawel Podhajski */ +/* All rights reserved. */ +/* */ +/* Redistribution and use in source and binary forms, with or */ +/* without modification, are permitted provided that the following */ +/* conditions are met: */ +/* */ +/* 1. Redistributions of source code must retain the above */ +/* copyright notice, this list of conditions and the following */ +/* disclaimer. */ +/* */ +/* 2. Redistributions in binary form must reproduce the above */ +/* copyright notice, this list of conditions and the following */ +/* disclaimer in the documentation and/or other materials */ +/* provided with the distribution. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF TEXAS AT */ +/* AUSTIN ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, */ +/* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */ +/* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ +/* DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT */ +/* AUSTIN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ +/* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ +/* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE */ +/* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR */ +/* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */ +/* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ +/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT */ +/* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ +/* POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/* The views and conclusions contained in the software and */ +/* documentation are those of the authors and should not be */ +/* interpreted as representing official policies, either expressed */ +/* or implied, of Ecole polytechnique federale de Lausanne. */ +/*********************************************************************/ + +#include "MockScreenController.h" + +MockScreenController::MockScreenController(ScreenState state) + : _state(state) +{ +} + +ScreenState MockScreenController::getState() const +{ + return _state; +} + +void MockScreenController::checkPowerState() +{ + emit powerStateChanged(_state); +} + +bool MockScreenController::powerOn() +{ + _state = ScreenState::ON; + emit powerStateChanged(_state); + powerOnCalled = true; + return true; +} + +bool MockScreenController::powerOff() +{ + _state = ScreenState::OFF; + emit powerStateChanged(_state); + powerOffCalled = true; + return true; +} diff --git a/tests/mock/MockScreenController.h b/tests/mock/MockScreenController.h index 1a7ef2cc..2e8a6021 100644 --- a/tests/mock/MockScreenController.h +++ b/tests/mock/MockScreenController.h @@ -50,28 +50,12 @@ class MockScreenController : public ScreenController Q_OBJECT public: - MockScreenController(ScreenState state) - : _state(state) - { - } - ScreenState getState() const final { return _state; } - void checkPowerState() final { emit powerStateChanged(_state); } + MockScreenController(ScreenState state); - bool powerOn() final - { - _state = ScreenState::ON; - emit powerStateChanged(_state); - powerOnCalled = true; - return true; - } - - bool powerOff() final - { - _state = ScreenState::OFF; - emit powerStateChanged(_state); - powerOffCalled = true; - return true; - } + ScreenState getState() const final; + void checkPowerState() final; + bool powerOn() final; + bool powerOff() final; bool powerOffCalled = false; bool powerOnCalled = false; diff --git a/tide/master/MasterApplication.cpp b/tide/master/MasterApplication.cpp index 2a9e1353..55482f77 100644 --- a/tide/master/MasterApplication.cpp +++ b/tide/master/MasterApplication.cpp @@ -46,7 +46,6 @@ #include "MasterSceneRenderer.h" #include "PixelStreamWindowManager.h" #include "QmlTypeRegistration.h" -#include "ScreenControllerFactory.h" #include "ScreenshotAssembler.h" #include "StateSerializationHelper.h" #include "control/DisplayGroupController.h" @@ -71,6 +70,10 @@ #if TIDE_ENABLE_REST_INTERFACE #include "LoggingUtility.h" #include "rest/RestInterface.h" + +#endif +#if TIDE_ENABLE_PLANAR_CONTROLLER +#include "ScreenControllerFactory.h" #endif #include diff --git a/tide/master/MultiScreenController.h b/tide/master/MultiScreenController.h index 1238c2cf..194abb9d 100644 --- a/tide/master/MultiScreenController.h +++ b/tide/master/MultiScreenController.h @@ -41,7 +41,6 @@ #define MultiScreenController_H #include "PlanarController.h" -#include "ScreenController.h" #include "types.h" #include diff --git a/tide/master/ScreenControllerFactory.cpp b/tide/master/ScreenControllerFactory.cpp old mode 100644 new mode 100755 index 8e759b79..6a6e266e --- a/tide/master/ScreenControllerFactory.cpp +++ b/tide/master/ScreenControllerFactory.cpp @@ -64,9 +64,11 @@ std::unique_ptr ScreenControllerFactory::create( return nullptr; std::vector> controllers; - for (const auto& kv : connections.toStdMap()) + QMapIterator i(connections); + while (i.hasNext()) { - controllers.emplace_back(new PlanarController(kv.first, kv.second)); + i.next(); + controllers.emplace_back(new PlanarController(i.key(), i.value())); } if (controllers.size() == 1) return std::move(controllers[0]); @@ -88,7 +90,7 @@ QMap ScreenControllerFactory::parseInputString( if (connection.isEmpty()) continue; - if (!connection.endsWith("#") && connection.contains("#")) + if (connection.contains("#")) { const auto serialEntity = connection.split("#"); const auto& serialPort = serialEntity[0]; From efd947c55cba79a28aeb96fc35f9713e875fea9a Mon Sep 17 00:00:00 2001 From: Pawel Podhajski Date: Mon, 22 Jan 2018 12:20:50 +0100 Subject: [PATCH 5/8] cmake library fix --- tests/cpp/CMakeLists.txt | 8 ++-- .../cpp/core/ScreenControllerFactoryTests.cpp | 2 +- tests/mock/CMakeLists.txt | 39 ++++++++++--------- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/tests/cpp/CMakeLists.txt b/tests/cpp/CMakeLists.txt index f345d9c4..9f6bce99 100644 --- a/tests/cpp/CMakeLists.txt +++ b/tests/cpp/CMakeLists.txt @@ -33,10 +33,10 @@ else() endif() if(NOT TIDE_ENABLE_PLANAR_CONTROLLER) - list(APPEND EXCLUDE_FROM_TESTS - core/MultiScreenControllerTests.cpp - core/ScreenControllerFactoryTests.cpp - ) + list(APPEND EXCLUDE_FROM_TESTS + core/MultiScreenControllerTests.cpp + core/ScreenControllerFactoryTests.cpp + ) endif() if(X11_FOUND) diff --git a/tests/cpp/core/ScreenControllerFactoryTests.cpp b/tests/cpp/core/ScreenControllerFactoryTests.cpp index e6f7b70a..3453b7f7 100644 --- a/tests/cpp/core/ScreenControllerFactoryTests.cpp +++ b/tests/cpp/core/ScreenControllerFactoryTests.cpp @@ -80,7 +80,7 @@ BOOST_AUTO_TEST_CASE(testException) BOOST_CHECK_THROW(ScreenControllerFactory::create("/dev/null#UR9850"), std::runtime_error); BOOST_CHECK_THROW(ScreenControllerFactory::create("/dev/null"), - std::runtime_error) + std::runtime_error); } BOOST_AUTO_TEST_CASE(testSingleController) diff --git a/tests/mock/CMakeLists.txt b/tests/mock/CMakeLists.txt index 6ab5f16f..64cf73ac 100644 --- a/tests/mock/CMakeLists.txt +++ b/tests/mock/CMakeLists.txt @@ -5,27 +5,28 @@ # # Generates a mock library used by the cpp unit tests. +set(TIDEMOCK_HEADERS + GlobalQtApp.h + glVersion.h + glxDisplay.h + imageCompare.h + MinimalGlobalQtApp.h + MockNetworkBarrier.h + MockTouchEvents.h + QGuiAppFixture.h +) + +if(TIDE_ENABLE_PLANAR_CONTROLLER) + list(APPEND TIDEMOCK_HEADERS MockScreenController.h) + set(TIDEMOCK_SOURCES MockScreenController.cpp) +endif() + +set(TIDEMOCK_LINK_LIBRARIES TideMaster ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} + Qt5::Core Qt5::Network) + set(TIDEMOCK_INCLUDE_NAME tide/mock) set(TIDEMOCK_OMIT_LIBRARY_HEADER ON) set(TIDEMOCK_OMIT_CHECK_TARGETS ON) set(TIDEMOCK_OMIT_INSTALL ON) -common_library(TideMock) -target_sources(TideMock INTERFACE - "${CMAKE_CURRENT_SOURCE_DIR}/GlobalQtApp.h" - "${CMAKE_CURRENT_SOURCE_DIR}/glVersion.h" - "${CMAKE_CURRENT_SOURCE_DIR}/glxDisplay.h" - "${CMAKE_CURRENT_SOURCE_DIR}/imageCompare.h" - "${CMAKE_CURRENT_SOURCE_DIR}/MinimalGlobalQtApp.h" - "${CMAKE_CURRENT_SOURCE_DIR}/MockNetworkBarrier.h" - "${CMAKE_CURRENT_SOURCE_DIR}/MockTouchEvents.h" - - "${CMAKE_CURRENT_SOURCE_DIR}/QGuiAppFixture.h" -) - -if(TIDE_ENABLE_PLANAR_CONTROLLER) - target_sources(TideMock INTERFACE - "${CMAKE_CURRENT_SOURCE_DIR}/MockScreenController.h" - "${CMAKE_CURRENT_SOURCE_DIR}/MockScreenController.cpp" - ) -endif() +common_library(TideMock) From 6f3fb9d0b153e2929f9b9db5dc82c52741f5770c Mon Sep 17 00:00:00 2001 From: Raphael Dumusc Date: Mon, 22 Jan 2018 16:22:31 +0100 Subject: [PATCH 6/8] Clarify test names a bit --- tests/cpp/core/ScreenControllerFactoryTests.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/cpp/core/ScreenControllerFactoryTests.cpp b/tests/cpp/core/ScreenControllerFactoryTests.cpp index 3453b7f7..f773137b 100644 --- a/tests/cpp/core/ScreenControllerFactoryTests.cpp +++ b/tests/cpp/core/ScreenControllerFactoryTests.cpp @@ -65,12 +65,12 @@ inline std::ostream& operator<<(std::ostream& str, return str; } -BOOST_AUTO_TEST_CASE(testEmpty) +BOOST_AUTO_TEST_CASE(testEmptySerialDeviceReturnsNullptr) { BOOST_CHECK(!ScreenControllerFactory::create("")); } -BOOST_AUTO_TEST_CASE(testException) +BOOST_AUTO_TEST_CASE(testExceptionWhenSerialDeviceCannotBeOpened) { BOOST_CHECK_THROW(ScreenControllerFactory::create("/dev/null;/dev/das"), std::runtime_error); @@ -83,7 +83,7 @@ BOOST_AUTO_TEST_CASE(testException) std::runtime_error); } -BOOST_AUTO_TEST_CASE(testSingleController) +BOOST_AUTO_TEST_CASE(testParsingSingleController) { const QMap expectedMatrix{ {"/dev/usb1", PlanarController::Type::Matrix}}; @@ -116,7 +116,7 @@ BOOST_AUTO_TEST_CASE(testSingleController) processedUR9851.end()); } -BOOST_AUTO_TEST_CASE(testMultipleConnectionsWithType) +BOOST_AUTO_TEST_CASE(testParsingMultipleConnectionsWithType) { const QMap expected{ {"/dev/usb1", PlanarController::Type::Matrix}, @@ -130,7 +130,7 @@ BOOST_AUTO_TEST_CASE(testMultipleConnectionsWithType) processed.begin(), processed.end()); } -BOOST_AUTO_TEST_CASE(testMultipleConnectionsWithOneEmpty) +BOOST_AUTO_TEST_CASE(testParsingMultipleConnectionsWithOneEmpty) { const QMap expected{ {"/dev/usb1", PlanarController::Type::Matrix}}; @@ -141,7 +141,7 @@ BOOST_AUTO_TEST_CASE(testMultipleConnectionsWithOneEmpty) processed.begin(), processed.end()); } -BOOST_AUTO_TEST_CASE(testMultipleConnectionsWithOneEmptyDevice) +BOOST_AUTO_TEST_CASE(testParsingMultipleConnectionsWithOneEmptyDevice) { const QMap expected{ {"/dev/usb1", PlanarController::Type::Matrix}}; @@ -152,7 +152,7 @@ BOOST_AUTO_TEST_CASE(testMultipleConnectionsWithOneEmptyDevice) processed.begin(), processed.end()); } -BOOST_AUTO_TEST_CASE(testConnectionsWithEmptyDeviceType) +BOOST_AUTO_TEST_CASE(testParsingConnectionsWithEmptyDeviceType) { const QMap expected{ {"/dev/usb1", PlanarController::Type::Matrix}}; From 75d3cbd46dc2eb50c7b5d035cbabed5bbf7c24b1 Mon Sep 17 00:00:00 2001 From: Raphael Dumusc Date: Mon, 22 Jan 2018 16:24:43 +0100 Subject: [PATCH 7/8] TideMock: remove extra link libraries --- tests/mock/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/mock/CMakeLists.txt b/tests/mock/CMakeLists.txt index 64cf73ac..d9271bb7 100644 --- a/tests/mock/CMakeLists.txt +++ b/tests/mock/CMakeLists.txt @@ -21,8 +21,7 @@ if(TIDE_ENABLE_PLANAR_CONTROLLER) set(TIDEMOCK_SOURCES MockScreenController.cpp) endif() -set(TIDEMOCK_LINK_LIBRARIES TideMaster ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} - Qt5::Core Qt5::Network) +set(TIDEMOCK_LINK_LIBRARIES TideMaster) set(TIDEMOCK_INCLUDE_NAME tide/mock) set(TIDEMOCK_OMIT_LIBRARY_HEADER ON) From 262a82a59f41a0a9adb32995dc21756eb3a2b07f Mon Sep 17 00:00:00 2001 From: Raphael Dumusc Date: Mon, 22 Jan 2018 16:26:08 +0100 Subject: [PATCH 8/8] correct spacing --- tide/master/MasterApplication.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tide/master/MasterApplication.cpp b/tide/master/MasterApplication.cpp index 55482f77..0946a23d 100644 --- a/tide/master/MasterApplication.cpp +++ b/tide/master/MasterApplication.cpp @@ -70,8 +70,8 @@ #if TIDE_ENABLE_REST_INTERFACE #include "LoggingUtility.h" #include "rest/RestInterface.h" - #endif + #if TIDE_ENABLE_PLANAR_CONTROLLER #include "ScreenControllerFactory.h" #endif