Commit dd6efb4d authored by Pavel Vainerman's avatar Pavel Vainerman

(test): добавил тесты для TriggerOutput. Исправил ошибки.

ПЕРЕИМЕНОВАЛ "TriggerOutput" --> "TriggerOUT"
parent e9d5d0a6
......@@ -22,15 +22,15 @@
*/
// --------------------------------------------------------------------------
//---------------------------------------------------------------------------
#ifndef TriggerOutput_H_
#define TriggerOutput_H_
#ifndef TriggerOUT_H_
#define TriggerOUT_H_
//---------------------------------------------------------------------------
#include <map>
//---------------------------------------------------------------------------
/*!
\par Описание
Этот триггер гарантирует, что значению "val" будет равен всегда только один выход (или ни одного).
При помощи TriggerOutput::set(), на определённый выход подаётся "val"(val также может быть = "0"),
При помощи TriggerOUT::set(), на определённый выход подаётся "val"(val также может быть = "0"),
при этом все остальные выходы выставляются в "0".
Работает в следующей последовательности: сперва выставляются все выходы в "0", а потом
уже нужный (единственный) выход выставляется в "val".
......@@ -45,7 +45,7 @@
\par Пример использования
\code
#include "TriggerOutput.h"
#include "TriggerOUT.h"
class MyClass
{
......@@ -60,7 +60,7 @@
...
MyClass rec;
// Создание:
TriggerOutput<MyClass,int,int> tr_out(&rec, &MyClass::out);
TriggerOUT<MyClass,int,int> tr_out(&rec, &MyClass::out);
// формируем OUT триггер с двумя 'выходами'
tr_out.add(1,0);
......@@ -81,8 +81,8 @@
\endcode
*/
template<class Caller, typename OutIdType, typename ValueType>
class TriggerOutput
template<class Caller, typename OutIdType=int, typename ValueType=bool>
class TriggerOUT
{
public:
......@@ -92,8 +92,8 @@ class TriggerOutput
*/
typedef void(Caller::* Action)(OutIdType out, ValueType val);
TriggerOutput(Caller* r, Action a);
~TriggerOutput();
TriggerOUT(Caller* r, Action a);
~TriggerOUT();
/*! получить текущее значение указанного 'выхода' */
......@@ -118,7 +118,7 @@ class TriggerOutput
void reset();
protected:
void check(OutIdType newout);
void resetOuts( OutIdType outIgnore );
typedef std::map<OutIdType, ValueType> OutList;
OutList outs; // список выходов
......@@ -129,6 +129,6 @@ class TriggerOutput
};
//---------------------------------------------------------------------------
#include "TriggerOutput.tcc"
#include "TriggerOUT.tcc"
//---------------------------------------------------------------------------
#endif
......@@ -23,48 +23,46 @@
// --------------------------------------------------------------------------
//---------------------------------------------------------------------------
#include "TriggerOutput.h"
#include "TriggerOUT.h"
//---------------------------------------------------------------------------
template<class Caller, typename OutIdType, typename ValueType>
TriggerOutput<Caller,OutIdType,ValueType>::TriggerOutput( Caller* r, Action a):
TriggerOUT<Caller,OutIdType,ValueType>::TriggerOUT( Caller* r, Action a):
cal(r),
act(a)
{
}
template <class Caller, typename OutIdType, typename ValueType>
TriggerOutput<Caller,OutIdType,ValueType>::~TriggerOutput()
TriggerOUT<Caller,OutIdType,ValueType>::~TriggerOUT()
{
}
//---------------------------------------------------------------------------
template <class Caller, typename OutIdType, typename ValueType>
void TriggerOutput<Caller,OutIdType,ValueType>::add(OutIdType num, ValueType val)
void TriggerOUT<Caller,OutIdType,ValueType>::add(OutIdType num, ValueType val)
{
outs[num] = val;
set(num,val);
try
{
(cal->*act)(num,val);
}
catch(...){}
resetOuts(num); // выставляем сперва все нули
(cal->*act)(num,val); // потом выставляем указанный выход
}
//---------------------------------------------------------------------------
template <class Caller, typename OutIdType, typename ValueType>
void TriggerOutput<Caller,OutIdType,ValueType>::remove(OutIdType num)
void TriggerOUT<Caller,OutIdType,ValueType>::remove(OutIdType num)
{
typename OutList::iterator it=outs.find(num);
auto it=outs.find(num);
if( it!=outs.end() )
outs.erase(it);
}
//---------------------------------------------------------------------------
template <class Caller, typename OutIdType, typename ValueType>
bool TriggerOutput<Caller,OutIdType,ValueType>::getState(OutIdType out)
bool TriggerOUT<Caller,OutIdType,ValueType>::getState(OutIdType out)
{
typename OutList::iterator it=outs.find(out);
auto it=outs.find(out);
if( it!=outs.end() )
return it->second;
......@@ -72,55 +70,47 @@ bool TriggerOutput<Caller,OutIdType,ValueType>::getState(OutIdType out)
}
//---------------------------------------------------------------------------
template <class Caller, typename OutIdType, typename ValueType>
void TriggerOutput<Caller,OutIdType,ValueType>::set(OutIdType out, ValueType val)
void TriggerOUT<Caller,OutIdType,ValueType>::set(OutIdType out, ValueType val)
{
typename OutList::iterator it=outs.find(out);
auto it=outs.find(out);
if( it==outs.end() )
return;
// потом val
ValueType prev(it->second);
// сперва сбрасываем все остальные выходы
resetOuts(out); // выставляем сперва все нули
// потом выставляем заданный выход
ValueType prev = it->second;
it->second = val;
if( prev != val )
{
check(out); // выставляем сперва все нули
try
{
(cal->*act)(it->first, it->second);
}
catch(...){}
}
(cal->*act)(it->first, it->second);
}
//---------------------------------------------------------------------------
template <class Caller, typename OutIdType, typename ValueType>
void TriggerOutput<Caller,OutIdType,ValueType>::check(OutIdType newout)
void TriggerOUT<Caller,OutIdType,ValueType>::resetOuts( OutIdType outIgnore )
{
for( typename OutList::iterator it=outs.begin(); it!=outs.end(); ++it )
for( auto it=outs.begin(); it!=outs.end(); ++it )
{
if( it->first != newout && it->second )
if( it->first != outIgnore && it->second )
{
it->second = 0;
// try
// {
(cal->*act)(it->first, it->second);
// }
// catch(...){}
(cal->*act)(it->first, it->second);
}
}
}
//---------------------------------------------------------------------------
template <class Caller, typename OutIdType, typename ValueType>
void TriggerOutput<Caller,OutIdType,ValueType>::update()
void TriggerOUT<Caller,OutIdType,ValueType>::update()
{
for( typename OutList::iterator it=outs.begin(); it!=outs.end(); ++it )
for( auto it=outs.begin(); it!=outs.end(); ++it )
(cal->*act)(it->first, it->second);
}
//---------------------------------------------------------------------------
template <class Caller, typename OutIdType, typename ValueType>
void TriggerOutput<Caller,OutIdType,ValueType>::reset()
void TriggerOUT<Caller,OutIdType,ValueType>::reset()
{
for( typename OutList::iterator it=outs.begin(); it!=outs.end(); ++it )
for( auto it=outs.begin(); it!=outs.end(); ++it )
{
it->second = 0;
(cal->*act)(it->first, it->second);
......
......@@ -7,7 +7,7 @@ noinst_PROGRAMS = tests tests_with_conf
#umutex threadtst dlog
tests_SOURCES = tests.cc passivetimer.cc hourglass.cc delaytimer.cc unixml.cc sscanf_hex.cc \
callbacktimer.cc trigger.cc triggerOR.cc triggerAND.cc
callbacktimer.cc trigger.cc triggerOR.cc triggerAND.cc triggerOUT.cc
tests_LDADD = $(top_builddir)/lib/libUniSet2.la $(SIGC_LIBS) $(COMCPP_LIBS)
tests_CPPFLAGS = -I$(top_builddir)/include -I$(includedir)/Catch $(SIGC_CFLAGS) $(COMCPP_CFLAGS)
......
#include <catch.hpp>
#include "TriggerOUT.h"
#include "UniSetTypes.h"
using namespace std;
class MyTestClass
{
public:
MyTestClass():out1(0),out2(0),out3(0){}
~MyTestClass(){}
void setOut( int outID, bool state )
{
if( outID == 1 )
out1++;
else if( outID == 2 )
out2++;
else if( outID == 3 )
out3++;
}
inline int getOut1Counter(){ return out1; }
inline int getOut2Counter(){ return out2; }
inline int getOut3Counter(){ return out3; }
private:
int out1;
int out2;
int out3;
};
TEST_CASE("TriggerOUT", "[TriggerOUT]" )
{
SECTION("Constructor")
{
MyTestClass tc;
TriggerOUT<MyTestClass> tr(&tc, &MyTestClass::setOut);
tr.add(1, true);
REQUIRE( tc.getOut1Counter() == 1 );
CHECK( tr.getState(1) );
tr.add(2, false);
REQUIRE( tc.getOut1Counter() == 2 );
REQUIRE( tc.getOut2Counter() == 1 );
CHECK_FALSE( tr.getState(1) );
CHECK_FALSE( tr.getState(2) );
tr.add(3, true);
REQUIRE( tc.getOut2Counter() == 1 );
REQUIRE( tc.getOut3Counter() == 1 );
CHECK_FALSE( tr.getState(1) );
CHECK_FALSE( tr.getState(2) );
CHECK( tr.getState(3) );
}
SECTION("Working")
{
MyTestClass tc;
TriggerOUT<MyTestClass> tr(&tc, &MyTestClass::setOut);
tr.add(1, false);
tr.add(2, false);
tr.add(3, false);
REQUIRE( tc.getOut1Counter() == 1 );
REQUIRE( tc.getOut2Counter() == 1 );
REQUIRE( tc.getOut3Counter() == 1 );
CHECK_FALSE( tr.getState(1) );
CHECK_FALSE( tr.getState(2) );
CHECK_FALSE( tr.getState(3) );
tr.set(1, true);
REQUIRE( tc.getOut1Counter() == 2 );
REQUIRE( tc.getOut2Counter() == 1 );
REQUIRE( tc.getOut3Counter() == 1 );
CHECK( tr.getState(1) );
CHECK_FALSE( tr.getState(2) );
CHECK_FALSE( tr.getState(3) );
tr.set(2, true);
REQUIRE( tc.getOut1Counter() == 3 );
REQUIRE( tc.getOut2Counter() == 2 );
REQUIRE( tc.getOut3Counter() == 1 );
CHECK_FALSE( tr.getState(1) );
CHECK( tr.getState(2) );
CHECK_FALSE( tr.getState(3) );
tr.set(3, false);
CHECK_FALSE( tr.getState(1) );
CHECK_FALSE( tr.getState(2) );
CHECK_FALSE( tr.getState(3) );
REQUIRE( tc.getOut1Counter() == 3 );
REQUIRE( tc.getOut2Counter() == 3 );
REQUIRE( tc.getOut3Counter() == 1 );
tr.set(3,true);
REQUIRE( tc.getOut1Counter() == 3 );
REQUIRE( tc.getOut2Counter() == 3 );
REQUIRE( tc.getOut3Counter() == 2 );
CHECK_FALSE( tr.getState(1) );
CHECK_FALSE( tr.getState(2) );
CHECK( tr.getState(3) );
// обращение к несуществующему выходу
tr.set(10,true);
REQUIRE( tc.getOut1Counter() == 3 );
REQUIRE( tc.getOut2Counter() == 3 );
REQUIRE( tc.getOut3Counter() == 2 );
CHECK_FALSE( tr.getState(1) );
CHECK_FALSE( tr.getState(2) );
CHECK( tr.getState(3) );
tr.set(-10,true);
REQUIRE( tc.getOut1Counter() == 3 );
REQUIRE( tc.getOut2Counter() == 3 );
REQUIRE( tc.getOut3Counter() == 2 );
CHECK_FALSE( tr.getState(1) );
CHECK_FALSE( tr.getState(2) );
CHECK( tr.getState(3) );
tr.set(0,true);
REQUIRE( tc.getOut1Counter() == 3 );
REQUIRE( tc.getOut2Counter() == 3 );
REQUIRE( tc.getOut3Counter() == 2 );
CHECK_FALSE( tr.getState(1) );
CHECK_FALSE( tr.getState(2) );
CHECK( tr.getState(3) );
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment