Skip to content

Commit dab4130

Browse files
author
Vitalii Arteev
committed
Add auxiliary API for Proxy
1 parent 63e4de6 commit dab4130

File tree

5 files changed

+203
-5
lines changed

5 files changed

+203
-5
lines changed

src/ipc/ipc-common/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ facelift_add_library(FaceliftIPCCommonLib
2323
IPCServiceAdapterBase.h
2424
NewIPCServiceAdapterBase.h
2525
IPCAttachedPropertyFactory.h
26+
observer.h
2627
HEADERS_NO_MOC
2728
AppendDBUSSignatureFunction.h
2829
ipc-serialization.h

src/ipc/ipc-common/IPCProxyBase.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
#include "ipc-common.h"
3434
#include "IPCProxyBaseBase.h"
3535
#include "IPCProxyBinderBase.h"
36-
36+
#include "observer.h"
3737

3838
#if defined(FaceliftIPCCommonLib_LIBRARY)
3939
# define FaceliftIPCCommonLib_EXPORT Q_DECL_EXPORT
@@ -49,10 +49,12 @@ class IPCProxyBase : public AdapterType, protected IPCProxyBaseBase
4949

5050
public:
5151
using InterfaceType = AdapterType;
52+
IsReadyObserver m_readyObserver{};
5253

5354
public:
5455
IPCProxyBase(QObject *parent) : AdapterType(parent)
5556
{
57+
QObject::connect(this, &InterfaceBase::readyChanged, &m_readyObserver, &IsReadyObserver::onReadyChanged);
5658
}
5759

5860
template<typename BinderType>

src/ipc/ipc-common/observer.h

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
/**********************************************************************
2+
**
3+
** Copyright (C) 2020 Luxoft Sweden AB
4+
**
5+
** This file is part of the FaceLift project
6+
**
7+
** Permission is hereby granted, freIPCServiceAdapterBasee of charge, to any person
8+
** obtaining a copy of this software and associated documentation files
9+
** (the "Software"), to deal in the Software without restriction,
10+
** including without limitation the rights to use, copy, modify, merge,
11+
** publish, distribute, sublicense, and/or sell copies of the Software,
12+
** and to permit persons to whom the Software is furnished to do so,
13+
** subject to the following conditions:
14+
**
15+
** The above copyright notice and this permission notice shall be
16+
** included in all copies or substantial portions of the Software.
17+
**
18+
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19+
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20+
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21+
** NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
22+
** BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23+
** ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24+
** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25+
** SOFTWARE.
26+
**
27+
** SPDX-License-Identifier: MIT
28+
**
29+
**********************************************************************/
30+
31+
#pragma once
32+
33+
#include <memory>
34+
#include <QVector>
35+
#include <QObject>
36+
37+
namespace facelift {
38+
39+
class IObserver : public QObject
40+
{
41+
Q_OBJECT
42+
public:
43+
virtual void onReadyChanged(std::shared_ptr<QMetaObject::Connection> connection) = 0;
44+
};
45+
46+
class IsReadyObserver: public QObject
47+
{
48+
Q_OBJECT
49+
QVector<IObserver *> m_observers{};
50+
51+
public:
52+
IsReadyObserver() {}
53+
54+
// Set observers
55+
void setObservers(const QVector<IObserver *> &observers) {
56+
m_observers = observers;
57+
for(auto observer: observers){
58+
auto connection = std::make_shared<QMetaObject::Connection>();
59+
*connection = QObject::connect(this, &IsReadyObserver::readyChanged, observer, [observer, connection](){
60+
observer->onReadyChanged( connection );
61+
});
62+
}
63+
}
64+
65+
// Get observers
66+
const QVector<IObserver *> &getObservers() const {
67+
return m_observers;
68+
}
69+
70+
Q_SIGNAL void readyChanged();
71+
72+
void onReadyChanged() {
73+
emit readyChanged();
74+
}
75+
};
76+
77+
// Single-time observer which will unregister itself when done
78+
template<typename T>
79+
class SingleTimeObserver : public IObserver
80+
{
81+
T m_function;
82+
83+
public:
84+
explicit SingleTimeObserver(T function) : m_function{function} {}
85+
~SingleTimeObserver() = default;
86+
87+
void onReadyChanged(std::shared_ptr<QMetaObject::Connection> connection) override {
88+
m_function();
89+
QObject::disconnect(*connection);
90+
}
91+
};
92+
93+
// Standard observer which will work for each signal
94+
template<typename T>
95+
class StandartObserver : public IObserver
96+
{
97+
T m_function;
98+
99+
public:
100+
explicit StandartObserver(T function) : m_function{function} {}
101+
~StandartObserver() = default;
102+
103+
void onReadyChanged(std::shared_ptr<QMetaObject::Connection> ) override {
104+
m_function();
105+
}
106+
};
107+
108+
}

tests/unittest/CMakeLists.txt

+20-4
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,34 @@ if(${GTEST_FOUND})
66
add_library(GTest::GMock UNKNOWN IMPORTED)
77
set_target_properties(GTest::GMock PROPERTIES IMPORTED_LOCATION ${GMOCK_LIBRARY})
88
else()
9-
message(WARNING "Google test/mock not found.")
9+
message(ERROR "Google test/mock not found.")
1010
endif()
1111

12+
find_package(Qt5 COMPONENTS Test REQUIRED)
13+
if(${QT5TEST_NOTFOUND})
14+
message(ERROR "Required package Qt5Test not found.")
15+
endif()
1216
find_package(Threads REQUIRED)
13-
set(FACELIFT_GTEST_LIBRARIES ${GTEST_BOTH_LIBRARIES} GTest::GMock Threads::Threads)
17+
if(${THREADS_NOTFOUND})
18+
message(ERROR "Required package Threads not found.")
19+
endif()
20+
set(FACELIFT_GTEST_LIBRARIES ${GTEST_BOTH_LIBRARIES} GTest::GMock Qt5::Test Threads::Threads)
1421
include_directories(${GTEST_INCLUDE_DIRS})
1522

1623
facelift_add_test(UnitTests
1724
SOURCES FaceliftUtilsTest.cpp
18-
LINK_LIBRARIES ${FACELIFT_GTEST_LIBRARIES} FaceliftCommonLib)
25+
LINK_LIBRARIES
26+
${FACELIFT_GTEST_LIBRARIES}
27+
FaceliftCommonLib
28+
)
1929

30+
facelift_add_test(UnitTestsObserver
31+
SOURCES FaceliftObserverTest.cpp
32+
LINK_LIBRARIES
33+
${FACELIFT_GTEST_LIBRARIES}
34+
FaceliftIPCCommonLib
35+
)
2036
else()
21-
message(WARNING "Required package google test not found!")
37+
message(ERROR "Required package google test not found!")
2238
endif()
2339

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#include <gtest/gtest.h>
2+
#include "IPCProxyBase.h"
3+
#include "InterfaceBase.h"
4+
#include <QSignalSpy>
5+
6+
namespace {
7+
8+
using namespace facelift;
9+
10+
class Counter
11+
{
12+
public:
13+
Counter() { m_value = 0; }
14+
15+
void incValue() {
16+
++m_value;
17+
}
18+
int getValue() const {
19+
return m_value;
20+
}
21+
private:
22+
int m_value;
23+
};
24+
25+
class IPCProxyBaseTest : public ::testing::Test
26+
{
27+
public:
28+
Counter c1;
29+
Counter c2;
30+
StandartObserver < std::function<void()> > * obs1 = new StandartObserver < std::function<void()> > (std::bind(&Counter::incValue, &c1) );
31+
SingleTimeObserver< std::function<void()> > * obs2 = new SingleTimeObserver< std::function<void()> > (std::bind(&Counter::incValue, &c2) );
32+
33+
IPCProxyBase<InterfaceBase> proxyBase{nullptr};
34+
35+
~IPCProxyBaseTest() {
36+
delete obs1;
37+
obs1 = nullptr;
38+
delete obs2;
39+
obs2 = nullptr;
40+
}
41+
};
42+
43+
TEST_F(IPCProxyBaseTest, testObservers)
44+
{
45+
// Set observers to proxy
46+
const auto expected = QVector<IObserver*>{obs1, obs2,};
47+
proxyBase.m_readyObserver.setObservers(expected);
48+
const auto actual = proxyBase.m_readyObserver.getObservers();
49+
50+
// Check values before calling a signal
51+
ASSERT_EQ(c1.getValue(), 0); // for StandartObserver
52+
ASSERT_EQ(c2.getValue(), 0); // for SingleTimeObserver
53+
54+
// Check handle of signal
55+
QSignalSpy spy(&proxyBase.m_readyObserver, &IsReadyObserver::readyChanged );
56+
ASSERT_EQ( spy.isValid(), true);
57+
spy.clear();
58+
59+
// Generate signal
60+
ASSERT_EQ(spy.count(), 0);
61+
proxyBase.readyChanged();
62+
proxyBase.readyChanged();
63+
proxyBase.readyChanged();
64+
ASSERT_EQ(spy.count(), 3);
65+
66+
// Check values after signal call
67+
ASSERT_EQ(c1.getValue(), 3); // for StandartObserver
68+
ASSERT_EQ(c2.getValue(), 1); // for SingleTimeObserver
69+
}
70+
71+
} // end namespace

0 commit comments

Comments
 (0)