12
19
using namespace testing;
20
using ::testing::Invoke;
16
TEST(TestWindowThread, TestCreate)
18
nux::NuxInitialize(0);
19
nux::WindowThread *wnd_thread = nux::CreateNuxWindow("Nux Window", 300, 200,
20
nux::WINDOWSTYLE_NORMAL, NULL, false, NULL, NULL);
27
MOCK_METHOD0(dispatch, void());
29
MockFdDispatch(int fd) :
32
ON_CALL(*this, dispatch())
33
.WillByDefault(Invoke(this, &MockFdDispatch::ClearStream));
41
if (read(mFd, reinterpret_cast <void *>(buf), 2) == -1)
42
throw std::runtime_error(strerror(errno));
48
class TestWindowThread : public ::testing::Test
56
nux::NuxInitialize(0);
57
wnd_thread.reset (nux::CreateNuxWindow("Nux Window", 300, 200,
58
nux::WINDOWSTYLE_NORMAL, NULL,
59
false, TestWindowThread::WindowThreadInit,
62
if (pipe2(quit_pipe_, O_CLOEXEC) == -1)
63
throw std::runtime_error(strerror(errno));
65
if (pipe2(test_quit_pipe_, O_CLOEXEC) == -1)
66
throw std::runtime_error(strerror(errno));
68
WatchFdForEventsOnRun(quit_pipe_[0],
69
std::bind(&TestWindowThread::QuitMessage,
82
close(test_quit_pipe_[0]);
83
close(test_quit_pipe_[1]);
88
std::unique_ptr <nux::WindowThread> wnd_thread;
89
unsigned int seconds_to_quit;
90
nux::SystemThread *quit_thread;
92
void WatchFdForEventsOnRun(int fd,
93
const nux::WindowThread::FdWatchCallback &cb)
99
watched_fds.push_back(wfd);
102
/* Watchdog threads are really not that great, but ping-ponging between
103
* the window and application threads would over-complicate this test */
104
void QuitAfter(unsigned int seconds)
106
seconds_to_quit = seconds;
107
quit_thread = nux::CreateSystemThread(NULL, TestWindowThread::QuitTask, this);
108
quit_thread->Start(NULL);
117
pfd.fd = test_quit_pipe_[0];
119
if (poll(&pfd, 1, -1) == -1)
120
throw std::runtime_error(strerror(errno));
122
/* Something was written to the read end of our pipe,
123
* we can continue now */
128
typedef struct _WatchedFd
131
nux::WindowThread::FdWatchCallback callback;
134
static void WindowThreadInit(nux::NThread *, void *data)
136
TestWindowThread *tw = reinterpret_cast <TestWindowThread *>(data);
138
/* Monitor all nominated fd's */
139
for (std::vector<WatchedFd>::iterator it = tw->watched_fds.begin();
140
it != tw->watched_fds.end();
143
tw->wnd_thread->WatchFdForEvents(it->fd, it->callback);
147
static void QuitTask(nux::NThread *, void *data)
149
TestWindowThread *tw = reinterpret_cast <TestWindowThread *> (data);
151
nux::SleepForMilliseconds(tw->seconds_to_quit * 1000);
153
const char *buf = "w\0";
154
if (write(tw->quit_pipe_[1],
155
reinterpret_cast<void *>(const_cast<char *>(buf)),
157
throw std::runtime_error(strerror(errno));
162
wnd_thread->ExitMainLoop();
164
/* Send a message indicating that the main loop
165
* exited and we can safely continue */
166
const char *buf = "w\0";
167
if (write(test_quit_pipe_[1],
168
reinterpret_cast<void *>(const_cast<char *>(buf)),
170
throw std::runtime_error(strerror(errno));
173
std::vector<WatchedFd> watched_fds;
176
int test_quit_pipe_[2];
179
TEST_F(TestWindowThread, Create)
22
181
ASSERT_TRUE(wnd_thread != NULL);
23
182
EXPECT_EQ(wnd_thread->GetWindowTitle(), std::string("Nux Window"));
24
183
EXPECT_EQ(wnd_thread->IsModalWindow(), false);
26
185
EXPECT_EQ(wnd_thread->IsComputingLayout(), false);
27
186
EXPECT_EQ(wnd_thread->IsInsideLayoutCycle(), false);
189
TEST_F(TestWindowThread, WatchFd)
193
if (pipe2 (pipefd, O_CLOEXEC) == -1)
194
throw std::runtime_error(strerror(errno));
196
MockFdDispatch dispatch(pipefd[0]);
198
EXPECT_CALL(dispatch, dispatch());
200
WatchFdForEventsOnRun(pipefd[0], std::bind(&MockFdDispatch::dispatch, &dispatch));
201
const char *buf = "w\0";
202
if (write(pipefd[1], reinterpret_cast <void *> (const_cast <char *> (buf)), 2) == -1)
203
throw std::runtime_error (strerror(errno));
206
wnd_thread->Run(NULL);
208
/* We must wait for quit before closing the pipes */
215
TEST_F(TestWindowThread, MultiWatchFd)
217
int pipefd[2], pipefd2[2];
219
if (pipe2 (pipefd, O_CLOEXEC) == -1)
220
throw std::runtime_error(strerror(errno));
221
if (pipe2 (pipefd2, O_CLOEXEC) == -1)
222
throw std::runtime_error(strerror(errno));
224
MockFdDispatch dispatch(pipefd[0]), dispatch2(pipefd2[0]);
226
EXPECT_CALL(dispatch, dispatch());
227
EXPECT_CALL(dispatch2, dispatch());
229
WatchFdForEventsOnRun(pipefd[0], std::bind(&MockFdDispatch::dispatch, &dispatch));
230
WatchFdForEventsOnRun(pipefd2[0], std::bind(&MockFdDispatch::dispatch, &dispatch2));
231
const char *buf = "w\0";
232
if (write(pipefd[1], reinterpret_cast <void *> (const_cast <char *> (buf)), 2) == -1)
233
throw std::runtime_error (strerror(errno));
234
if (write(pipefd2[1], reinterpret_cast <void *> (const_cast <char *> (buf)), 2) == -1)
235
throw std::runtime_error (strerror(errno));
238
wnd_thread->Run(NULL);
240
/* We must wait for quit before closing the pipes */
249
TEST_F(TestWindowThread, OneFdEvent)
251
int pipefd[2], pipefd2[2];
253
if (pipe2 (pipefd, O_CLOEXEC) == -1)
254
throw std::runtime_error(strerror(errno));
255
if (pipe2 (pipefd2, O_CLOEXEC) == -1)
256
throw std::runtime_error(strerror(errno));
258
MockFdDispatch dispatch(pipefd[0]), dispatch2(pipefd2[0]);
260
EXPECT_CALL(dispatch, dispatch());
261
EXPECT_CALL(dispatch2, dispatch()).Times(0);
263
WatchFdForEventsOnRun(pipefd[0], std::bind(&MockFdDispatch::dispatch, &dispatch));
264
WatchFdForEventsOnRun(pipefd2[0], std::bind(&MockFdDispatch::dispatch, &dispatch2));
265
const char *buf = "w\0";
266
if (write(pipefd[1], reinterpret_cast <void *> (const_cast <char *> (buf)), 2) == -1)
267
throw std::runtime_error (strerror(errno));
270
wnd_thread->Run(NULL);
272
/* We must wait for quit before closing the pipes */