1
#include "core/plugin.h"
3
// This prevents an instantiation error - not sure why ATM
4
#include "core/screen.h"
6
// Get rid of stupid macro from X.h
7
// Why, oh why, are we including X.h?
10
#include <gtest/gtest.h>
11
#include <gmock/gmock.h>
17
class PluginFilesystem
21
LoadPlugin(CompPlugin *p, const char *path, const char *name) const = 0;
24
UnloadPlugin(CompPlugin *p) const = 0;
26
virtual CompStringList
27
ListPlugins(const char *path) const = 0;
29
static PluginFilesystem const* instance;
33
virtual ~PluginFilesystem() {}
36
class MockPluginFilesystem : public PluginFilesystem
39
MOCK_CONST_METHOD3(LoadPlugin, bool (CompPlugin *, const char *, const char *));
41
MOCK_CONST_METHOD1(UnloadPlugin, void (CompPlugin *p));
43
MOCK_CONST_METHOD1(ListPlugins, CompStringList (const char *path));
46
class MockVTable : public CompPlugin::VTable
49
MOCK_METHOD0(init, bool ());
54
ThunkLoadPluginProc(CompPlugin *p, const char *path_, const char *name)
56
return PluginFilesystem::instance->LoadPlugin(p, path_, name);
60
ThunkUnloadPluginProc(CompPlugin *p)
62
PluginFilesystem::instance->UnloadPlugin(p);
67
ThunkListPluginsProc(const char *path)
69
return PluginFilesystem::instance->ListPlugins(path);
72
PluginFilesystem::PluginFilesystem()
74
::loaderLoadPlugin = ::ThunkLoadPluginProc;
75
::loaderUnloadPlugin = ::ThunkUnloadPluginProc;
76
::loaderListPlugins = ::ThunkListPluginsProc;
81
PluginFilesystem const* PluginFilesystem::instance = 0;
83
} // (abstract) namespace
87
TEST(PluginTest, load_non_existant_plugin_must_fail)
89
MockPluginFilesystem mockfs;
91
using namespace testing;
93
EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))).
94
WillOnce(Return(false));
96
EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(PLUGINDIR), StrEq("dummy"))).
97
WillOnce(Return(false));
99
EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), Eq((void*)0), StrEq("dummy"))).
100
WillOnce(Return(false));
102
EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(AtMost(0));
103
EXPECT_CALL(mockfs, ListPlugins(_)).Times(AtMost(0));
105
ASSERT_EQ(0, CompPlugin::load("dummy"));
108
TEST(PluginTest, load_plugin_from_HOME_PLUGINDIR_succeeds)
110
MockPluginFilesystem mockfs;
112
using namespace testing;
114
EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))).
115
WillOnce(Return(true));
117
EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(PLUGINDIR), StrEq("dummy"))).
120
EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), Eq((void*)0), StrEq("dummy"))).
123
EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(1);
124
EXPECT_CALL(mockfs, ListPlugins(_)).Times(AtMost(0));
126
CompPlugin* cp = CompPlugin::load("dummy");
127
ASSERT_NE((void*)0, cp);
129
CompPlugin::unload(cp);
132
TEST(PluginTest, load_plugin_from_PLUGINDIR_succeeds)
134
MockPluginFilesystem mockfs;
136
using namespace testing;
138
EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))).
139
WillOnce(Return(false));
141
EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(PLUGINDIR), StrEq("dummy"))).
142
WillOnce(Return(true));
144
EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), Eq((void*)0), StrEq("dummy"))).
147
EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(1);
148
EXPECT_CALL(mockfs, ListPlugins(_)).Times(AtMost(0));
150
CompPlugin* cp = CompPlugin::load("dummy");
151
ASSERT_NE((void*)0, cp);
153
CompPlugin::unload(cp);
156
TEST(PluginTest, load_plugin_from_void_succeeds)
158
MockPluginFilesystem mockfs;
160
using namespace testing;
162
EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))).
163
WillOnce(Return(false));
165
EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(PLUGINDIR), StrEq("dummy"))).
166
WillOnce(Return(false));
168
EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), Eq((void*)0), StrEq("dummy"))).
169
WillOnce(Return(true));
171
EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(1);
172
EXPECT_CALL(mockfs, ListPlugins(_)).Times(AtMost(0));
174
CompPlugin* cp = CompPlugin::load("dummy");
175
ASSERT_NE((void*)0, cp);
177
CompPlugin::unload(cp);
181
TEST(PluginTest, list_plugins_none)
183
MockPluginFilesystem mockfs;
185
using namespace testing;
187
EXPECT_CALL(mockfs, LoadPlugin(_, _, _)).Times(AtMost(0));
188
EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(AtMost(0));
190
EXPECT_CALL(mockfs, ListPlugins(EndsWith(HOME_PLUGINDIR))).
191
WillOnce(Return(CompStringList()));
193
EXPECT_CALL(mockfs, ListPlugins(EndsWith(PLUGINDIR))).
194
WillOnce(Return(CompStringList()));
196
EXPECT_CALL(mockfs, ListPlugins(Eq((void*)0))).
197
WillOnce(Return(CompStringList()));
199
CompStringList cl = CompPlugin::availablePlugins();
200
ASSERT_EQ(0, cl.size());
204
TEST(PluginTest, list_plugins_some)
206
std::string one = "one";
207
std::string two = "two";
208
std::string three = "three";
210
CompStringList home(1, one);
211
CompStringList plugin(1, two);
212
CompStringList local(1, three);
214
MockPluginFilesystem mockfs;
216
using namespace testing;
218
EXPECT_CALL(mockfs, LoadPlugin(_, _, _)).Times(AtMost(0));
219
EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(AtMost(0));
221
EXPECT_CALL(mockfs, ListPlugins(EndsWith(HOME_PLUGINDIR))).WillOnce(Return(home));
222
EXPECT_CALL(mockfs, ListPlugins(EndsWith(PLUGINDIR))).WillOnce(Return(plugin));
223
EXPECT_CALL(mockfs, ListPlugins(Eq((void*)0))).WillOnce(Return(local));
225
CompStringList cl = CompPlugin::availablePlugins();
226
ASSERT_EQ(3, cl.size());
228
ASSERT_THAT(cl, Contains(one));
229
ASSERT_THAT(cl, Contains(two));
230
ASSERT_THAT(cl, Contains(three));
233
TEST(PluginTest, list_plugins_are_deduped)
235
std::string one = "one";
236
std::string two = "two";
237
std::string three = "three";
239
CompStringList home(1, one);
240
CompStringList plugin(1, two);
241
CompStringList local(1, three);
243
plugin.push_back(one);
244
local.push_back(two);
246
MockPluginFilesystem mockfs;
248
using namespace testing;
250
EXPECT_CALL(mockfs, LoadPlugin(_, _, _)).Times(AtMost(0));
251
EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(AtMost(0));
253
EXPECT_CALL(mockfs, ListPlugins(EndsWith(HOME_PLUGINDIR))).WillOnce(Return(home));
254
EXPECT_CALL(mockfs, ListPlugins(EndsWith(PLUGINDIR))).WillOnce(Return(plugin));
255
EXPECT_CALL(mockfs, ListPlugins(Eq((void*)0))).WillOnce(Return(local));
257
CompStringList cl = CompPlugin::availablePlugins();
258
ASSERT_EQ(3, cl.size());
260
ASSERT_THAT(cl, Contains(one));
261
ASSERT_THAT(cl, Contains(two));
262
ASSERT_THAT(cl, Contains(three));
266
TEST(PluginTest, when_we_push_plugin_init_is_called)
268
MockPluginFilesystem mockfs;
270
using namespace testing;
272
EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(HOME_PLUGINDIR), StrEq("dummy"))).
273
WillOnce(Return(true));
275
EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), EndsWith(PLUGINDIR), StrEq("dummy"))).
278
EXPECT_CALL(mockfs, LoadPlugin(Ne((void*)0), Eq((void*)0), StrEq("dummy"))).
281
EXPECT_CALL(mockfs, UnloadPlugin(_)).Times(1);
282
EXPECT_CALL(mockfs, ListPlugins(_)).Times(0);
284
MockVTable mockVtable;
285
EXPECT_CALL(mockVtable, init()).WillOnce(Return(true));
287
CompPlugin* cp = CompPlugin::load("dummy");
289
cp->vTable = &mockVtable;
291
CompPlugin::push(cp);
292
ASSERT_EQ(cp, CompPlugin::pop());
293
CompPlugin::unload(cp);