Back to index

nux  3.0.0
gtest-nux-textentry.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright 2012 Canonical Ltd.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU Lesser General Public License version 3, as
00006  * published by the  Free Software Foundation.
00007  *
00008  * This program is distributed in the hope that it will be useful, but
00009  * WITHOUT ANY WARRANTY; without even the implied warranties of
00010  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00011  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00012  * License for more details.
00013  *
00014  * You should have received a copy of both the GNU Lesser General Public
00015  * License version 3 along with this program.  If not, see
00016  * <http://www.gnu.org/licenses/>
00017  *
00018  * Authored by: Marco Trevisan <marco.trevisan@canonical.com>
00019  *
00020  */
00021 
00022 #include "gtest-nux-utils.h"
00023 
00024 #include <gmock/gmock.h>
00025 
00026 #include "Nux/Nux.h"
00027 #include "Nux/TextEntry.h"
00028 #include "Nux/HLayout.h"
00029 #if defined(NUX_OS_LINUX)
00030 #include "Nux/InputMethodIBus.h"
00031 #endif
00032 
00033 using namespace testing;
00034 using namespace nux;
00035 
00036 namespace {
00037 
00038 class MockTextEntry : public TextEntry
00039 {
00040 public:
00041   MockTextEntry() : TextEntry("")
00042   {}
00043 
00044   bool InspectKeyEvent(Event const& event)
00045   {
00046     return TextEntry::InspectKeyEvent(event);
00047   }
00048 
00049   bool GetSelectionBounds(int* start, int* end) const
00050   {
00051     return TextEntry::GetSelectionBounds(start, end);
00052   }
00053 
00054   int GetCursor() const
00055   {
00056     return cursor_;
00057   }
00058 
00059   void SetCursor(int cursor)
00060   {
00061     TextEntry::SetCursor(cursor);
00062   }
00063 
00064   nux::IBusIMEContext* ime() const
00065   {
00066 #if defined(NUX_OS_LINUX)
00067     return ime_;
00068 #else
00069     return nullptr;
00070 #endif
00071   }
00072 
00073   void WaitEvent()
00074   {
00075     if (im_running())
00076       Utils::WaitForTimeoutMSec(100);
00077   }
00078 
00079   MOCK_METHOD0(CutClipboard, void());
00080   MOCK_METHOD0(CopyClipboard, void());
00081   MOCK_METHOD0(PasteClipboard, void());
00082 #if defined(NUX_OS_LINUX)
00083   MOCK_METHOD0(PastePrimaryClipboard, void());
00084 #endif
00085 };
00086 
00087 class TestEvent : public Event
00088 {
00089 public:
00090   TestEvent(KeyModifier keymod, unsigned long keysym)
00091   {
00092     type = NUX_KEYDOWN;
00093     key_modifiers = keymod;
00094 #if defined(NUX_OS_LINUX)
00095     x11_keysym = keysym;
00096 #elif defined(NUX_OS_WINDOWS)
00097     win32_keysym = keysym;
00098 #endif
00099   }
00100 
00101   TestEvent(unsigned long keysym)
00102   {
00103     type = NUX_KEYDOWN;
00104 #if defined(NUX_OS_LINUX)
00105     x11_keysym = keysym;
00106 #elif defined(NUX_OS_WINDOWS)
00107     win32_keysym = keysym;
00108 #endif
00109   }
00110 };
00111 
00112 class TestTextEntry : public Test
00113 {
00114 public:
00115   virtual void SetUp()
00116   {
00117     NuxInitialize(0);
00118     wnd_thread.reset(CreateNuxWindow("Nux Window", 300, 200, WINDOWSTYLE_NORMAL,
00119                      nullptr, false, NULL, NULL));
00120 
00121     text_entry = new MockTextEntry();
00122     HLayout* layout = new HLayout();
00123     layout->AddView(text_entry);
00124     wnd_thread->SetLayout(layout);
00125 
00126     GetWindowCompositor().SetKeyFocusArea(text_entry);
00127   }
00128 
00129   std::unique_ptr<WindowThread> wnd_thread;
00130   MockTextEntry* text_entry;
00131 };
00132 
00133 TEST_F(TestTextEntry, TestSetText)
00134 {
00135   EXPECT_EQ(text_entry->IsInTextInputMode(), false);
00136 
00137   text_entry->SetText("Nux");
00138   EXPECT_EQ(text_entry->GetText() == std::string("Nux"), true);
00139 
00140   EXPECT_EQ(text_entry->IsInTextInputMode(), true);
00141 }
00142 
00143 TEST_F(TestTextEntry, TestEnterText)
00144 {
00145   EXPECT_EQ(text_entry->IsInTextInputMode(), false);
00146 
00147   text_entry->EnterText("Nux");
00148 
00149   EXPECT_EQ(text_entry->GetText() == std::string("Nux"), true);
00150 
00151   EXPECT_EQ(text_entry->IsInTextInputMode(), true);
00152 }
00153 
00154 TEST_F(TestTextEntry, TestDeleteText)
00155 {
00156   EXPECT_EQ(text_entry->IsInTextInputMode(), false);
00157 
00158   text_entry->EnterText("Nux");
00159 
00160   EXPECT_EQ(text_entry->GetText() == std::string("Nux"), true);
00161 
00162   EXPECT_EQ(text_entry->IsInTextInputMode(), true);
00163 
00164   GetWindowCompositor().SetKeyFocusArea(nullptr);
00165 
00166   GetWindowCompositor().SetKeyFocusArea(text_entry);
00167 
00168   EXPECT_EQ(text_entry->IsInTextInputMode(), false);
00169 
00170   text_entry->DeleteText(0, 3);
00171 
00172   EXPECT_EQ(text_entry->GetText() == std::string(""), true);
00173 
00174   EXPECT_EQ(text_entry->IsInTextInputMode(), true);
00175 }
00176 
00177 #if defined(NUX_OS_LINUX)
00178 TEST_F(TestTextEntry, AltLinuxKeybindings)
00179 {
00180   for (unsigned long keysym = 0; keysym < XK_VoidSymbol; ++keysym)
00181   {
00182     TestEvent event(KEY_MODIFIER_ALT, keysym);
00183 
00184     if (text_entry->ime()->IsHotkeyEvent(event.type, event.GetKeySym(), event.key_modifiers))
00185       EXPECT_TRUE(text_entry->InspectKeyEvent(event));
00186     else
00187       EXPECT_FALSE(text_entry->InspectKeyEvent(event));
00188   }
00189 }
00190 
00191 TEST_F(TestTextEntry, SuperLinuxKeybindings)
00192 {
00193   for (unsigned long keysym = 0; keysym < XK_VoidSymbol; ++keysym)
00194   {
00195     TestEvent event(KEY_MODIFIER_SUPER, keysym);
00196 
00197     if (text_entry->ime()->IsHotkeyEvent(event.type, event.GetKeySym(), event.key_modifiers))
00198       EXPECT_TRUE(text_entry->InspectKeyEvent(event));
00199     else
00200       EXPECT_FALSE(text_entry->InspectKeyEvent(event));
00201   }
00202 }
00203 #endif
00204 
00205 TEST_F(TestTextEntry, InvalidKeys)
00206 {
00207   std::vector<std::string> invalid_chars = {"", "", "", "", "",
00208                                             "", "", "", "", "",
00209                                             "", "", ""};
00210   for (auto c : invalid_chars)
00211   {
00212     unsigned int keysym = g_utf8_get_char(c.c_str());
00213     text_entry->DeleteText(0, std::numeric_limits<int>::max());
00214     text_entry->key_down.emit(NUX_KEYDOWN, keysym, 0, c.c_str(), 1);
00215     text_entry->WaitEvent();
00216     EXPECT_EQ(text_entry->GetText(), "");
00217   }
00218 }
00219 
00220 TEST_F(TestTextEntry, CopyCtrlC)
00221 {
00222   EXPECT_CALL(*text_entry, CopyClipboard());
00223   TestEvent event(KEY_MODIFIER_CTRL, NUX_VK_c);
00224   GetWindowCompositor().ProcessEvent(event);
00225   text_entry->WaitEvent();
00226 }
00227 
00228 TEST_F(TestTextEntry, CopyCtrlIns)
00229 {
00230   EXPECT_CALL(*text_entry, CopyClipboard());
00231   TestEvent event(KEY_MODIFIER_CTRL, NUX_VK_INSERT);
00232   GetWindowCompositor().ProcessEvent(event);
00233   text_entry->WaitEvent();
00234 }
00235 
00236 TEST_F(TestTextEntry, PasteCtrlV)
00237 {
00238   EXPECT_CALL(*text_entry, PasteClipboard());
00239   TestEvent event(KEY_MODIFIER_CTRL, NUX_VK_v);
00240   GetWindowCompositor().ProcessEvent(event);
00241   text_entry->WaitEvent();
00242 }
00243 
00244 TEST_F(TestTextEntry, PasteShiftIns)
00245 {
00246   EXPECT_CALL(*text_entry, PasteClipboard());
00247   TestEvent event(KEY_MODIFIER_SHIFT, NUX_VK_INSERT);
00248   GetWindowCompositor().ProcessEvent(event);
00249   text_entry->WaitEvent();
00250 }
00251 
00252 #if defined(NUX_OS_LINUX)
00253 TEST_F(TestTextEntry, PastePrimaryClipboard)
00254 {
00255   EXPECT_CALL(*text_entry, PastePrimaryClipboard());
00256   text_entry->mouse_down.emit(0, 0, NUX_EVENT_BUTTON2_DOWN, 0);
00257 
00258   EXPECT_CALL(*text_entry, PastePrimaryClipboard()).Times(0);
00259   text_entry->mouse_down.emit(0, 0, NUX_EVENT_BUTTON1_DOWN, 0);
00260 
00261   EXPECT_CALL(*text_entry, PastePrimaryClipboard()).Times(0);
00262   text_entry->mouse_down.emit(0, 0, NUX_EVENT_BUTTON3_DOWN, 0);
00263 }
00264 #endif
00265 
00266 TEST_F(TestTextEntry, CutCtrlX)
00267 {
00268   EXPECT_CALL(*text_entry, CutClipboard());
00269   TestEvent event(KEY_MODIFIER_CTRL, NUX_VK_x);
00270   GetWindowCompositor().ProcessEvent(event);
00271   text_entry->WaitEvent();
00272 }
00273 
00274 TEST_F(TestTextEntry, CutShiftDel)
00275 {
00276   EXPECT_CALL(*text_entry, CutClipboard());
00277   TestEvent event(KEY_MODIFIER_SHIFT, NUX_VK_DELETE);
00278   GetWindowCompositor().ProcessEvent(event);
00279   text_entry->WaitEvent();
00280 }
00281 
00282 TEST_F(TestTextEntry, CtrlA)
00283 {
00284   TestEvent selectall(KEY_MODIFIER_CTRL, NUX_VK_a);
00285   int start, end;
00286   const std::string test_str("Nux");
00287   text_entry->EnterText(test_str.c_str());
00288   EXPECT_FALSE(text_entry->GetSelectionBounds(&start, &end));
00289   ASSERT_EQ(start, end);
00290   ASSERT_EQ(start, test_str.length());
00291 
00292   GetWindowCompositor().ProcessEvent(selectall);
00293   text_entry->WaitEvent();
00294   EXPECT_TRUE(text_entry->GetSelectionBounds(&start, &end));
00295   EXPECT_EQ(start, 0);
00296   EXPECT_EQ(end, test_str.length());
00297 }
00298 
00299 TEST_F(TestTextEntry, MoveKeys)
00300 {
00301   const std::string test_str("Nux");
00302   text_entry->EnterText(test_str.c_str());
00303   ASSERT_EQ(text_entry->GetCursor(), test_str.length());
00304   text_entry->SetCursor(0);
00305   ASSERT_EQ(text_entry->GetCursor(), 0);
00306 
00307   TestEvent right(NUX_VK_RIGHT);
00308   GetWindowCompositor().ProcessEvent(right);
00309   text_entry->WaitEvent();
00310   EXPECT_EQ(text_entry->GetCursor(), 1);
00311 
00312   TestEvent end(NUX_VK_END);
00313   GetWindowCompositor().ProcessEvent(end);
00314   text_entry->WaitEvent();
00315   EXPECT_EQ(text_entry->GetCursor(), test_str.length());
00316 
00317   TestEvent left(NUX_VK_LEFT);
00318   GetWindowCompositor().ProcessEvent(left);
00319   text_entry->WaitEvent();
00320   EXPECT_EQ(text_entry->GetCursor(), 2);
00321 
00322   TestEvent home(NUX_VK_HOME);
00323   GetWindowCompositor().ProcessEvent(home);
00324   text_entry->WaitEvent();
00325   EXPECT_EQ(text_entry->GetCursor(), 0);
00326 }
00327 
00328 TEST_F(TestTextEntry, CtrlMoveKeys)
00329 {
00330   const std::string test_str("Nux Text Entry");
00331   text_entry->EnterText(test_str.c_str());
00332   ASSERT_EQ(text_entry->GetCursor(), test_str.length());
00333   text_entry->SetCursor(0);
00334   ASSERT_EQ(text_entry->GetCursor(), 0);
00335 
00336   TestEvent right(KEY_MODIFIER_CTRL, NUX_VK_RIGHT);
00337   GetWindowCompositor().ProcessEvent(right);
00338   text_entry->WaitEvent();
00339   EXPECT_EQ(text_entry->GetCursor(), 3);
00340 
00341   TestEvent left(KEY_MODIFIER_CTRL, NUX_VK_LEFT);
00342   GetWindowCompositor().ProcessEvent(left);
00343   text_entry->WaitEvent();
00344   EXPECT_EQ(text_entry->GetCursor(), 0);
00345 
00346   TestEvent end(KEY_MODIFIER_CTRL, NUX_VK_END);
00347   GetWindowCompositor().ProcessEvent(end);
00348   text_entry->WaitEvent();
00349   EXPECT_EQ(text_entry->GetCursor(), test_str.length());
00350 
00351   TestEvent home(KEY_MODIFIER_CTRL, NUX_VK_HOME);
00352   GetWindowCompositor().ProcessEvent(home);
00353   text_entry->WaitEvent();
00354   EXPECT_EQ(text_entry->GetCursor(), 0);
00355 }
00356 
00357 TEST_F(TestTextEntry, DeleteKeys)
00358 {
00359   const std::string test_str("Nux");
00360   text_entry->EnterText(test_str.c_str());
00361   text_entry->SetCursor(0);
00362 
00363   TestEvent del(NUX_VK_DELETE);
00364   GetWindowCompositor().ProcessEvent(del);
00365   text_entry->WaitEvent();
00366   EXPECT_EQ(text_entry->GetText(), "ux");
00367 
00368   text_entry->SetCursor(std::string(text_entry->GetText()).length());
00369   TestEvent backspace(NUX_VK_BACKSPACE);
00370   GetWindowCompositor().ProcessEvent(backspace);
00371   text_entry->WaitEvent();
00372   EXPECT_EQ(text_entry->GetText(), "u");
00373 }
00374 
00375 TEST_F(TestTextEntry, CtrlDeleteKeys)
00376 {
00377   const std::string test_str("Nux Text Entry");
00378   text_entry->EnterText(test_str.c_str());
00379   text_entry->SetCursor(0);
00380 
00381   TestEvent del(KEY_MODIFIER_CTRL, NUX_VK_DELETE);
00382   GetWindowCompositor().ProcessEvent(del);
00383   text_entry->WaitEvent();
00384   EXPECT_EQ(text_entry->GetText(), " Text Entry");
00385 
00386   text_entry->SetCursor(std::string(text_entry->GetText()).length());
00387   TestEvent backspace(KEY_MODIFIER_CTRL, NUX_VK_BACKSPACE);
00388   GetWindowCompositor().ProcessEvent(backspace);
00389   text_entry->WaitEvent();
00390   EXPECT_EQ(text_entry->GetText(), " Text ");
00391 }
00392 }