Line data Source code
1 :
2 : /* Copyright (c) 2013-2015, EPFL/Blue Brain Project
3 : * Raphael Dumusc <raphael.dumusc@epfl.ch>
4 : *
5 : * This file is part of Lunchbox <https://github.com/Eyescale/Lunchbox>
6 : *
7 : * This library is free software; you can redistribute it and/or modify it under
8 : * the terms of the GNU Lesser General Public License version 2.1 as published
9 : * by the Free Software Foundation.
10 : *
11 : * This library is distributed in the hope that it will be useful, but WITHOUT
12 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14 : * details.
15 : *
16 : * You should have received a copy of the GNU Lesser General Public License
17 : * along with this library; if not, write to the Free Software Foundation, Inc.,
18 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 : */
20 :
21 : #define BOOST_TEST_MODULE PluginFactory
22 :
23 : #include <lunchbox/types.h>
24 : #include <lunchbox/pluginFactory.h>
25 : #include <lunchbox/pluginRegisterer.h>
26 : #include <servus/uri.h>
27 :
28 : #include <boost/test/unit_test.hpp>
29 : #include <boost/scoped_ptr.hpp>
30 :
31 : #define VALID_VALUE 10
32 : #define INVALID_VALUE 0
33 :
34 8 : struct InitData
35 : {
36 : servus::URI uri;
37 : };
38 :
39 : namespace boost
40 : {
41 4 : template<> inline std::string lexical_cast( const InitData& data )
42 : {
43 4 : return lexical_cast< std::string >( data.uri );
44 : }
45 : }
46 :
47 2 : class PluginInterface
48 : {
49 : public:
50 : typedef PluginInterface PluginT;
51 2 : virtual ~PluginInterface() {}
52 : virtual int getValue() = 0;
53 : };
54 :
55 2 : class TypedPluginInterface
56 : {
57 : public:
58 : typedef TypedPluginInterface PluginT;
59 : typedef InitData InitDataT;
60 2 : virtual ~TypedPluginInterface() {}
61 : virtual int getValue() = 0;
62 : };
63 :
64 4 : class MyPlugin : public PluginInterface
65 : {
66 : public:
67 2 : explicit MyPlugin( const servus::URI& ) {}
68 2 : static bool handles( const servus::URI& ) { return true; }
69 2 : int getValue() final { return VALID_VALUE; }
70 : };
71 :
72 4 : class MyTypedPlugin : public TypedPluginInterface
73 : {
74 : public:
75 2 : explicit MyTypedPlugin( const InitData& ) {}
76 2 : static bool handles( const InitData& ) { return true; }
77 2 : int getValue() final { return VALID_VALUE; }
78 : };
79 :
80 0 : class MyDummyPlugin : public PluginInterface
81 : {
82 : public:
83 0 : explicit MyDummyPlugin( const servus::URI& ) {}
84 2 : static bool handles( const servus::URI& ) { return false; }
85 0 : int getValue() final { return INVALID_VALUE; }
86 : };
87 :
88 0 : class MyTypedDummyPlugin : public TypedPluginInterface
89 : {
90 : public:
91 0 : explicit MyTypedDummyPlugin( const InitData& ) {}
92 2 : static bool handles( const InitData& ) { return false; }
93 0 : int getValue() final { return INVALID_VALUE; }
94 : };
95 :
96 : typedef lunchbox::PluginFactory< PluginInterface> MyPluginFactory;
97 : typedef lunchbox::PluginFactory< TypedPluginInterface,
98 : InitData > MyTypedPluginFactory;
99 :
100 : typedef boost::scoped_ptr< PluginInterface > PluginInterfacePtr;
101 : typedef boost::scoped_ptr< TypedPluginInterface > TypedPluginInterfacePtr;
102 :
103 4 : void tryCreatePlugin( PluginInterfacePtr& plugin )
104 : {
105 4 : MyPluginFactory& factory = MyPluginFactory::getInstance();
106 6 : plugin.reset( factory.create( servus::URI( "XYZ" )));
107 2 : }
108 :
109 4 : void tryCreateTypedPlugin( TypedPluginInterfacePtr& plugin )
110 : {
111 4 : MyTypedPluginFactory& factory = MyTypedPluginFactory::getInstance();
112 6 : plugin.reset( factory.create( InitData() ));
113 2 : }
114 :
115 3 : BOOST_AUTO_TEST_CASE( testWhenNoPluginIsRegisteredCreateThrowsRuntimeError )
116 : {
117 1 : MyPluginFactory::getInstance().deregisterAll();
118 :
119 1 : PluginInterfacePtr plugin;
120 1 : BOOST_CHECK_THROW( tryCreatePlugin( plugin ), std::runtime_error );
121 1 : }
122 :
123 3 : BOOST_AUTO_TEST_CASE( testWhenNoTypedPluginIsRegisteredCreateThrowsRuntimeErr )
124 : {
125 1 : MyTypedPluginFactory::getInstance().deregisterAll();
126 :
127 1 : TypedPluginInterfacePtr plugin;
128 1 : BOOST_CHECK_THROW( tryCreateTypedPlugin( plugin ), std::runtime_error );
129 1 : }
130 :
131 :
132 3 : BOOST_AUTO_TEST_CASE( testWhenPluginRegistererIsInstantiatedPluginIsRegistered )
133 : {
134 1 : MyPluginFactory::getInstance().deregisterAll();
135 :
136 1 : lunchbox::PluginRegisterer< MyPlugin > registerer;
137 :
138 1 : PluginInterfacePtr plugin;
139 1 : BOOST_REQUIRE_NO_THROW( tryCreatePlugin( plugin ));
140 1 : BOOST_CHECK_EQUAL( plugin->getValue(), VALID_VALUE );
141 1 : }
142 :
143 3 : BOOST_AUTO_TEST_CASE(
144 : testWhenTypedPluginRegistererIsInstantiatedPluginIsRegistered )
145 : {
146 1 : MyTypedPluginFactory::getInstance().deregisterAll();
147 :
148 1 : lunchbox::PluginRegisterer< MyTypedPlugin > registerer;
149 :
150 1 : TypedPluginInterfacePtr plugin;
151 1 : BOOST_REQUIRE_NO_THROW( tryCreateTypedPlugin( plugin ));
152 1 : BOOST_CHECK_EQUAL( plugin->getValue(), VALID_VALUE );
153 1 : }
154 :
155 3 : BOOST_AUTO_TEST_CASE( testWhenPluginsDontHandleURICreateThrowsRuntimeError )
156 : {
157 1 : MyPluginFactory::getInstance().deregisterAll();
158 :
159 1 : lunchbox::PluginRegisterer< MyDummyPlugin > registerer;
160 :
161 1 : PluginInterfacePtr plugin;
162 1 : BOOST_CHECK_THROW( tryCreatePlugin( plugin ), std::runtime_error );
163 1 : }
164 :
165 3 : BOOST_AUTO_TEST_CASE( testWhenTypedPlginsDontHandleURICreateThrowsRuntimeError )
166 : {
167 1 : MyTypedPluginFactory::getInstance().deregisterAll();
168 :
169 1 : lunchbox::PluginRegisterer< MyTypedDummyPlugin > registerer;
170 :
171 1 : TypedPluginInterfacePtr plugin;
172 1 : BOOST_CHECK_THROW( tryCreateTypedPlugin( plugin ), std::runtime_error );
173 1 : }
174 :
175 3 : BOOST_AUTO_TEST_CASE( testWhenOnePluginHandlesURICreateInstanciesCorrectType )
176 : {
177 1 : MyPluginFactory::getInstance().deregisterAll();
178 :
179 1 : lunchbox::PluginRegisterer< MyDummyPlugin > registerer1;
180 1 : lunchbox::PluginRegisterer< MyPlugin > registerer2;
181 :
182 1 : PluginInterfacePtr plugin;
183 1 : BOOST_REQUIRE_NO_THROW( tryCreatePlugin( plugin ));
184 1 : BOOST_CHECK_EQUAL( plugin->getValue(), VALID_VALUE );
185 1 : }
186 :
187 3 : BOOST_AUTO_TEST_CASE( testWhenOneTypedPluginHandlesURICreateInstCorrectType )
188 : {
189 1 : MyTypedPluginFactory::getInstance().deregisterAll();
190 :
191 1 : lunchbox::PluginRegisterer< MyTypedDummyPlugin > registerer1;
192 1 : lunchbox::PluginRegisterer< MyTypedPlugin > registerer2;
193 :
194 1 : TypedPluginInterfacePtr plugin;
195 1 : BOOST_REQUIRE_NO_THROW( tryCreateTypedPlugin( plugin ));
196 1 : BOOST_CHECK_EQUAL( plugin->getValue(), VALID_VALUE );
197 4 : }
|