Changeset - 0bcc3039cc7c
[Not reviewed]
stream
0 5 0
Hasan Yavuz ÖZDERYA - 8 years ago 2017-12-03 14:34:59
hy@ozderya.net
added tests for Sink class and some improvements
5 files changed with 84 insertions and 4 deletions:
0 comments (0 inline, 0 general)
src/sink.cpp
Show inline comments
 
@@ -4,48 +4,49 @@
 
  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 <http://www.gnu.org/licenses/>.
 
*/
 

	
 
#include <QtGlobal>
 
#include "sink.h"
 

	
 
void Sink::connectFollower(Sink* sink)
 
{
 
    Q_ASSERT(!followers.contains(sink));
 

	
 
    followers.append(sink);
 
    sink->setNumChannels(numChannels(), hasX());
 
}
 

	
 
void Sink::disconnectFollower(Sink* sink)
 
{
 
    Q_ASSERT(followers.contains(sink));
 

	
 
    followers.removeOne(sink);
 
}
 

	
 
void Sink::feedIn(const SamplePack& data)
 
{
 
    for (auto sink : followers)
 
    {
 
        sink->feedIn(data);
 
    }
 
}
 

	
 
void Sink::setNumChannels(unsigned nc, bool x)
 
{
 
    for (auto sink : followers)
 
    {
 
        sink->setNumChannels(nc, x);
 
    }
 
}
src/sink.h
Show inline comments
 
@@ -17,36 +17,40 @@
 
  along with serialplot.  If not, see <http://www.gnu.org/licenses/>.
 
*/
 

	
 
#ifndef SINK_H
 
#define SINK_H
 

	
 
#include <QList>
 
#include "samplepack.h"
 

	
 
class Source;
 

	
 
class Sink
 
{
 
public:
 
    /// Connects a sink to get any data that this sink
 
    /// gets. Connecting an already connected sink is an error.
 
    void connectFollower(Sink* sink);
 
    /// Disconnects a follower. Disconnecting an unconnected sink is
 
    /// an error.
 
    void disconnectFollower(Sink* sink);
 

	
 
protected:
 
    /// Entry point for incoming data. Re-implementations should
 
    /// call this function to feed followers.
 
    void feedIn(const SamplePack& data);
 
    virtual void feedIn(const SamplePack& data);
 
    /// Is set by connected source. Re-implementations should call
 
    /// this function to update followers.
 
    void setNumChannels(unsigned nc, bool x);
 
    virtual void setNumChannels(unsigned nc, bool x);
 
    /// Returns true if sink has X data
 
    virtual bool hasX() const = 0;
 
    /// Returns number of channels
 
    virtual unsigned numChannels() const = 0;
 

	
 
    friend Source;
 

	
 
private:
 
    QList<Sink*> followers;
 
};
 

	
 
#endif // SINK_H
src/source.cpp
Show inline comments
 
@@ -22,32 +22,31 @@
 
#include "source.h"
 

	
 
void Source::connect(Sink* sink)
 
{
 
    Q_ASSERT(!sinks.contains(sink));
 

	
 
    sinks.append(sink);
 
}
 

	
 
void Source::disconnect(Sink* sink)
 
{
 
    Q_ASSERT(sinks.contains(sink));
 

	
 
    sinks.removeOne(sink);
 
}
 

	
 
void Source::feedOut(const SamplePack& data) const
 
{
 
    for (auto sink : sinks)
 
    {
 
        sink->feedIn(data);
 
    }
 
}
 

	
 
/// Updates "number of channels" of connected sinks
 
void Source::feedNumChannels(unsigned nc, bool x) const
 
{
 
    for (auto sink : sinks)
 
    {
 
        sink->setNumChannels(nc, x);
 
    }
 
}
tests/CMakeLists.txt
Show inline comments
 
@@ -2,31 +2,35 @@
 
# Copyright © 2017 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 <http://www.gnu.org/licenses/>.
 
#
 

	
 
# Find the QtWidgets library
 
find_package(Qt5Widgets)
 

	
 
include_directories("../src")
 

	
 
add_executable(Test EXCLUDE_FROM_ALL
 
  test.cpp ../src/samplepack.cpp)
 
  test.cpp
 
  ../src/samplepack.cpp
 
  ../src/sink.cpp
 
  ../src/source.cpp
 
  )
 
add_test(NAME test1 COMMAND Test)
 
qt5_use_modules(Test Widgets)
 

	
 
set(CMAKE_CTEST_COMMAND ctest -V)
 
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})
 
add_dependencies(check Test)
tests/test.cpp
Show inline comments
 
/*
 
  Copyright © 2017 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 <http://www.gnu.org/licenses/>.
 
*/
 

	
 
#define CATCH_CONFIG_MAIN  // This tells Catch to provide a main() - only do this in one cpp file
 
#include "catch.hpp"
 

	
 
#include "samplepack.h"
 
#include "source.h"
 

	
 
TEST_CASE("samplepack with no X", "[memory]")
 
{
 
    SamplePack pack(100, 3, false);
 

	
 
    REQUIRE_FALSE(pack.hasX());
 
    REQUIRE(pack.numChannels() == 3);
 
    REQUIRE(pack.numSamples() == 100);
 

	
 
    double* chan0 = pack.data(0);
 
    double* chan1 = pack.data(1);
 
    double* chan2 = pack.data(2);
 

	
 
    REQUIRE(chan0 == chan1 - 100);
 
    REQUIRE(chan1 == chan2 - 100);
 
}
 

	
 
TEST_CASE("samplepack with X", "[memory]")
 
{
 
    SamplePack pack(100, 3, true);
 

	
 
    REQUIRE(pack.hasX());
 
    REQUIRE(pack.numChannels() == 3);
 
    REQUIRE(pack.numSamples() == 100);
 
    REQUIRE(pack.xData() != nullptr);
 
}
 

	
 
class TestSink : public Sink
 
{
 
public:
 
    int totalFed;
 
    int _numChannels;
 
    bool _hasX;
 

	
 
    TestSink()
 
        {
 
            totalFed = 0;
 
            _numChannels = 0;
 
            _hasX = false;
 
        };
 

	
 
public:
 
    void feedIn(const SamplePack& data)
 
        {
 
            REQUIRE(data.numChannels() == numChannels());
 

	
 
            totalFed += data.numSamples();
 

	
 
            Sink::feedIn(data);
 
        };
 

	
 
    void setNumChannels(unsigned nc, bool x)
 
        {
 
            _numChannels = nc;
 
            _hasX = x;
 

	
 
            Sink::setNumChannels(nc, x);
 
        };
 

	
 
    virtual unsigned numChannels() const
 
        {
 
            return _numChannels;
 
        };
 

	
 
    virtual bool hasX() const
 
        {
 
            return _hasX;
 
        };
 
};
 

	
 
TEST_CASE("sink", "[memory, stream]")
 
{
 
    TestSink sink;
 
    SamplePack pack(100, 3, false);
 

	
 
    sink.setNumChannels(3, false);
 
    REQUIRE(sink.numChannels() == 3);
 

	
 
    sink.feedIn(pack);
 
    REQUIRE(sink.totalFed == 100);
 
    sink.feedIn(pack);
 
    REQUIRE(sink.totalFed == 200);
 

	
 
    TestSink follower;
 

	
 
    sink.connectFollower(&follower);
 
    REQUIRE(follower.numChannels() == 3);
 
    REQUIRE(follower.hasX() == false);
 

	
 
    sink.feedIn(pack);
 
    REQUIRE(sink.totalFed == 300);
 
    REQUIRE(follower.totalFed == 100);
 

	
 
    sink.setNumChannels(2, true);
 
    REQUIRE(follower.numChannels() == 2);
 
    REQUIRE(follower.hasX() == true);
 
}
0 comments (0 inline, 0 general)