diff --git a/tests/test_readers.cpp b/tests/test_readers.cpp new file mode 100644 --- /dev/null +++ b/tests/test_readers.cpp @@ -0,0 +1,210 @@ +/* + Copyright © 2018 Hasan Yavuz Özderya + + This file is part of serialplot. + + serialplot 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. + + serialplot 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 serialplot. If not, see . +*/ + +// This tells Catch to provide a main() - only do this in one cpp file per executable +#define CATCH_CONFIG_RUNNER +#include "catch.hpp" + +#include +#include +#include "binarystreamreader.h" +#include "asciireader.h" +#include "framedreader.h" +#include "demoreader.h" + +#include "test_helpers.h" + +static const int READYREAD_TIMEOUT = 10; // milliseconds + +TEST_CASE("reading data with BinaryStreamReader", "[reader]") +{ + QBuffer bufferDev; + BinaryStreamReader bs(&bufferDev); + bs.enable(true); + + TestSink sink; + bs.connectSink(&sink); + + REQUIRE(sink._numChannels == 1); + REQUIRE(sink._hasX == false); + + bufferDev.open(QIODevice::ReadWrite); + const char data[] = {0x01, 0x02, 0x03, 0x04}; + bufferDev.write(data, 4); + bufferDev.seek(0); + + QSignalSpy spy(&bufferDev, SIGNAL(readyRead())); + REQUIRE(spy.wait(READYREAD_TIMEOUT)); + REQUIRE(sink.totalFed == 4); +} + +TEST_CASE("disabled BinaryStreamReader shouldn't read", "[reader]") +{ + QBuffer bufferDev; + BinaryStreamReader bs(&bufferDev); // disabled by default + + TestSink sink; + bs.connectSink(&sink); + + REQUIRE(sink._numChannels == 1); + REQUIRE(sink._hasX == false); + + bufferDev.open(QIODevice::ReadWrite); + const char data[] = {0x01, 0x02, 0x03, 0x04}; + bufferDev.write(data, 4); + bufferDev.seek(0); + + QSignalSpy spy(&bufferDev, SIGNAL(readyRead())); + // readyRead isn't signaled because there are no connections to it + REQUIRE_FALSE(spy.wait(READYREAD_TIMEOUT)); + REQUIRE(sink.totalFed == 0); +} + +TEST_CASE("reading data with AsciiReader", "[reader, ascii]") +{ + QBuffer bufferDev; + AsciiReader reader(&bufferDev); + reader.enable(true); + + TestSink sink; + reader.connectSink(&sink); + + REQUIRE(sink._numChannels == 1); + REQUIRE(sink._hasX == false); + + // inject data to the buffer + bufferDev.open(QIODevice::ReadWrite); + bufferDev.write("0,1,3\n0,1,3\n0,1,3\n0,1,3\n"); + bufferDev.seek(0); + + QSignalSpy spy(&bufferDev, SIGNAL(readyRead())); + REQUIRE(spy.wait(READYREAD_TIMEOUT)); + REQUIRE(sink._numChannels == 3); + REQUIRE(sink._hasX == false); + REQUIRE(sink.totalFed == 3); +} + +TEST_CASE("AsciiReader shouldn't read when disabled", "[reader, ascii]") +{ + QBuffer bufferDev; + AsciiReader reader(&bufferDev); // disabled by default + + TestSink sink; + reader.connectSink(&sink); + + REQUIRE(sink._numChannels == 1); + REQUIRE(sink._hasX == false); + + // inject data to the buffer + bufferDev.open(QIODevice::ReadWrite); + bufferDev.write("0,1,3\n0,1,3\n0,1,3\n0,1,3\n"); + bufferDev.seek(0); + + QSignalSpy spy(&bufferDev, SIGNAL(readyRead())); + REQUIRE_FALSE(spy.wait(READYREAD_TIMEOUT)); + REQUIRE(sink._numChannels == 1); + REQUIRE(sink._hasX == false); + REQUIRE(sink.totalFed == 0); +} + +TEST_CASE("reading data with FramedReader", "[reader]") +{ + QBuffer bufferDev; + FramedReader reader(&bufferDev); + reader.enable(true); + + TestSink sink; + reader.connectSink(&sink); + + REQUIRE(sink._numChannels == 1); + REQUIRE(sink._hasX == false); + + bufferDev.open(QIODevice::ReadWrite); + const uint8_t data[] = {0xAA, 0xBB, 4, 0x01, 0x02, 0x03, 0x04}; + bufferDev.write((const char*) data, 7); + bufferDev.seek(0); + + QSignalSpy spy(&bufferDev, SIGNAL(readyRead())); + REQUIRE(spy.wait(READYREAD_TIMEOUT)); + REQUIRE(sink.totalFed == 4); +} + +TEST_CASE("FramedReader shouldn't read when disabled", "[reader]") +{ + QBuffer bufferDev; + FramedReader reader(&bufferDev); + + TestSink sink; + reader.connectSink(&sink); + + REQUIRE(sink._numChannels == 1); + REQUIRE(sink._hasX == false); + + bufferDev.open(QIODevice::ReadWrite); + const uint8_t data[] = {0xAA, 0xBB, 4, 0x01, 0x02, 0x03, 0x04}; + bufferDev.write((const char*) data, 7); + bufferDev.seek(0); + + QSignalSpy spy(&bufferDev, SIGNAL(readyRead())); + REQUIRE_FALSE(spy.wait(READYREAD_TIMEOUT)); + REQUIRE(sink.totalFed == 0); +} + +TEST_CASE("Generating data with DemoReader", "[reader, demo]") +{ + QBuffer bufferDev; // not actually used + DemoReader demoReader(&bufferDev); + demoReader.enable(true); + + TestSink sink; + demoReader.connectSink(&sink); + REQUIRE(sink._numChannels == 1); + REQUIRE(sink._hasX == false); + + // we need to wait somehow, we are not actually looking for signals + QSignalSpy spy(&bufferDev, SIGNAL(readyRead())); + REQUIRE_FALSE(spy.wait(1000)); // we need some time for demoreader to produce data + REQUIRE(sink.totalFed >= 9); +} + +TEST_CASE("DemoReader shouldn't generate data when paused", "[reader, demo]") +{ + QBuffer bufferDev; // not actually used + DemoReader demoReader(&bufferDev); // paused by default + + TestSink sink; + demoReader.connectSink(&sink); + REQUIRE(sink._numChannels == 1); + + // we need to wait somehow, we are not actually looking for signals + QSignalSpy spy(&bufferDev, SIGNAL(readyRead())); + REQUIRE_FALSE(spy.wait(1000)); // we need some time for demoreader to produce data + REQUIRE(sink.totalFed == 0); +} + +// Note: this is added because `QApplication` must be created for widgets +#include +int main(int argc, char* argv[]) +{ + QApplication a(argc, argv); + + int result = Catch::Session().run( argc, argv ); + + return result; +}