| // Copyright 2010-2015, Google Inc. |
| // All rights reserved. |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions are |
| // met: |
| // |
| // * Redistributions of source code must retain the above copyright |
| // notice, this list of conditions and the following disclaimer. |
| // * Redistributions in binary form must reproduce the above |
| // copyright notice, this list of conditions and the following disclaimer |
| // in the documentation and/or other materials provided with the |
| // distribution. |
| // * Neither the name of Google Inc. nor the names of its |
| // contributors may be used to endorse or promote products derived from |
| // this software without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| #include "renderer/unix/window_manager.h" |
| |
| #include "testing/base/public/gunit.h" |
| #include "testing/base/public/gmock.h" |
| #include "renderer/unix/gtk_window_mock.h" |
| #include "renderer/unix/gtk_wrapper_mock.h" |
| |
| using ::testing::Expectation; |
| using ::testing::NotNull; |
| using ::testing::Return; |
| using ::testing::SetArgPointee; |
| using ::testing::StrEq; |
| using ::testing::StrictMock; |
| using ::testing::_; |
| |
| namespace mozc { |
| namespace renderer { |
| namespace gtk { |
| |
| namespace { |
| MATCHER_P(PointEq, expected_point, "The expected point does not match") { |
| return (arg.x == expected_point.x) && (arg.y == expected_point.y); |
| } |
| } // namespace |
| |
| TEST(WindowManagerTest, InitializeTest) { |
| GtkWindowMock *candidate_window_mock = new GtkWindowMock(); |
| GtkWindowMock *infolist_window_mock = new GtkWindowMock(); |
| GtkWrapperMock *gtk_mock = new GtkWrapperMock(); |
| |
| Expectation candidate_show |
| = EXPECT_CALL(*candidate_window_mock, ShowWindow()); |
| EXPECT_CALL(*candidate_window_mock, HideWindow()).After(candidate_show); |
| EXPECT_CALL(*candidate_window_mock, Initialize()).After(candidate_show); |
| |
| Expectation infolist_show = EXPECT_CALL(*infolist_window_mock, ShowWindow()); |
| EXPECT_CALL(*infolist_window_mock, HideWindow()).After(candidate_show); |
| EXPECT_CALL(*infolist_window_mock, Initialize()).After(candidate_show); |
| |
| WindowManager manager(candidate_window_mock, infolist_window_mock, gtk_mock); |
| |
| manager.Initialize(); |
| } |
| |
| TEST(WindowManagerTest, HideAllWindowsTest) { |
| GtkWindowMock *candidate_window_mock = new GtkWindowMock(); |
| GtkWindowMock *infolist_window_mock = new GtkWindowMock(); |
| GtkWrapperMock *gtk_mock = new GtkWrapperMock(); |
| |
| EXPECT_CALL(*candidate_window_mock, HideWindow()); |
| EXPECT_CALL(*infolist_window_mock, HideWindow()); |
| |
| WindowManager manager(candidate_window_mock, infolist_window_mock, gtk_mock); |
| |
| manager.HideAllWindows(); |
| } |
| |
| TEST(WindowManagerTest, ShowAllWindowsTest) { |
| GtkWindowMock *candidate_window_mock = new GtkWindowMock(); |
| GtkWindowMock *infolist_window_mock = new GtkWindowMock(); |
| GtkWrapperMock *gtk_mock = new GtkWrapperMock(); |
| |
| EXPECT_CALL(*candidate_window_mock, ShowWindow()); |
| EXPECT_CALL(*infolist_window_mock, ShowWindow()); |
| |
| WindowManager manager(candidate_window_mock, infolist_window_mock, gtk_mock); |
| |
| manager.ShowAllWindows(); |
| } |
| |
| TEST(WindowManagerTest, UpdateLayoutTest) { |
| { |
| SCOPED_TRACE("Empty candidates should hide window, and do nothing."); |
| commands::RendererCommand command; |
| |
| GtkWindowMock *candidate_window_mock = new StrictMock<GtkWindowMock>(); |
| GtkWindowMock *infolist_window_mock = new StrictMock<GtkWindowMock>(); |
| GtkWrapperMock *gtk_mock = new StrictMock<GtkWrapperMock>(); |
| |
| EXPECT_CALL(*candidate_window_mock, HideWindow()); |
| EXPECT_CALL(*infolist_window_mock, HideWindow()); |
| |
| WindowManager manager(candidate_window_mock, infolist_window_mock, |
| gtk_mock); |
| |
| manager.UpdateLayout(command); |
| } |
| { |
| // Other case of UpdateLayout test is break-downed as UpdateCandidateWindow |
| // and UpdateInfolistWindow. |
| } |
| } |
| |
| TEST(WindowManagerTest, ActivateTest) { |
| // TODO(nona): Implement activate. |
| } |
| |
| TEST(WindowManagerTest, IsAvailable) { |
| // TODO(nona): Implement IsAvailable. |
| } |
| |
| TEST(WindowManagerTest, SetSendCommandInterfaceTest) { |
| GtkWindowMock *candidate_window_mock = new GtkWindowMock(); |
| GtkWindowMock *infolist_window_mock = new GtkWindowMock(); |
| GtkWrapperMock *gtk_mock = new GtkWrapperMock(); |
| |
| client::SendCommandInterface *send_command_interface |
| = reinterpret_cast<client::SendCommandInterface *>(0x12345678); |
| |
| WindowManager manager(candidate_window_mock, infolist_window_mock, gtk_mock); |
| manager.SetSendCommandInterface(send_command_interface); |
| |
| EXPECT_EQ(send_command_interface, manager.send_command_interface_); |
| } |
| |
| TEST(WindowManagerTest, SetWindowPosTest) { |
| GtkWindowMock *candidate_window_mock = new GtkWindowMock(); |
| GtkWindowMock *infolist_window_mock = new GtkWindowMock(); |
| GtkWrapperMock *gtk_mock = new GtkWrapperMock(); |
| |
| const Point direction(10, 20); |
| EXPECT_CALL(*candidate_window_mock, Move(PointEq(direction))); |
| |
| WindowManager manager(candidate_window_mock, infolist_window_mock, gtk_mock); |
| manager.SetWindowPos(direction.x, direction.y); |
| } |
| |
| TEST(WindowManagerTest, ShouldShowCandidateWindowTest) { |
| { |
| SCOPED_TRACE("If it is not visible, return false."); |
| commands::RendererCommand command; |
| command.set_visible(false); |
| command.mutable_output()->mutable_candidates(); |
| |
| WindowManager manager(NULL, NULL, NULL); |
| EXPECT_FALSE(manager.ShouldShowCandidateWindow(command)); |
| } |
| { |
| SCOPED_TRACE("If there is no Candidates message, return false."); |
| commands::RendererCommand command; |
| command.set_visible(true); |
| command.mutable_output(); |
| |
| WindowManager manager(NULL, NULL, NULL); |
| EXPECT_FALSE(manager.ShouldShowCandidateWindow(command)); |
| } |
| { |
| SCOPED_TRACE("If there are no candidates, return false."); |
| commands::RendererCommand command; |
| command.set_visible(true); |
| command.mutable_output()->mutable_candidates(); |
| |
| WindowManager manager(NULL, NULL, NULL); |
| EXPECT_FALSE(manager.ShouldShowCandidateWindow(command)); |
| } |
| { |
| commands::RendererCommand command; |
| command.set_visible(true); |
| commands::Candidates *candidates |
| = command.mutable_output()->mutable_candidates(); |
| candidates->add_candidate(); |
| |
| WindowManager manager(NULL, NULL, NULL); |
| EXPECT_TRUE(manager.ShouldShowCandidateWindow(command)); |
| } |
| } |
| |
| TEST(WindowManagerTest, ShouldShowInfolistWindowTest) { |
| { |
| SCOPED_TRACE("If it is not visible, return false."); |
| commands::RendererCommand command; |
| command.set_visible(false); |
| command.mutable_output()->mutable_candidates(); |
| |
| WindowManager manager(NULL, NULL, NULL); |
| EXPECT_FALSE(manager.ShouldShowInfolistWindow(command)); |
| } |
| { |
| SCOPED_TRACE("If there is no Candidates message, return false."); |
| commands::RendererCommand command; |
| command.set_visible(true); |
| command.mutable_output(); |
| |
| WindowManager manager(NULL, NULL, NULL); |
| EXPECT_FALSE(manager.ShouldShowInfolistWindow(command)); |
| } |
| { |
| SCOPED_TRACE("If there are no candidates, return false."); |
| commands::RendererCommand command; |
| command.set_visible(true); |
| command.mutable_output()->mutable_candidates(); |
| |
| WindowManager manager(NULL, NULL, NULL); |
| EXPECT_FALSE(manager.ShouldShowInfolistWindow(command)); |
| } |
| { |
| SCOPED_TRACE("If there is no usages message, return false"); |
| commands::RendererCommand command; |
| command.set_visible(true); |
| commands::Candidates *candidates |
| = command.mutable_output()->mutable_candidates(); |
| candidates->add_candidate(); |
| |
| WindowManager manager(NULL, NULL, NULL); |
| EXPECT_FALSE(manager.ShouldShowInfolistWindow(command)); |
| } |
| { |
| SCOPED_TRACE("If there is no Information List message, return false"); |
| commands::RendererCommand command; |
| command.set_visible(true); |
| commands::Candidates *candidates |
| = command.mutable_output()->mutable_candidates(); |
| candidates->add_candidate(); |
| |
| WindowManager manager(NULL, NULL, NULL); |
| EXPECT_FALSE(manager.ShouldShowInfolistWindow(command)); |
| } |
| { |
| SCOPED_TRACE("If there are no information, return false"); |
| commands::RendererCommand command; |
| command.set_visible(true); |
| commands::Candidates *candidates |
| = command.mutable_output()->mutable_candidates(); |
| candidates->add_candidate(); |
| commands::InformationList *usage = candidates->mutable_usages(); |
| usage->add_information(); |
| |
| WindowManager manager(NULL, NULL, NULL); |
| EXPECT_FALSE(manager.ShouldShowInfolistWindow(command)); |
| } |
| { |
| SCOPED_TRACE("If focused index is out of range, return false"); |
| commands::RendererCommand command; |
| command.set_visible(true); |
| commands::Candidates *candidates |
| = command.mutable_output()->mutable_candidates(); |
| candidates->add_candidate(); |
| commands::InformationList *usage = candidates->mutable_usages(); |
| usage->add_information(); |
| |
| candidates->set_focused_index(3); |
| |
| WindowManager manager(NULL, NULL, NULL); |
| EXPECT_FALSE(manager.ShouldShowInfolistWindow(command)); |
| } |
| { |
| SCOPED_TRACE("If focused candidate has no information, return false"); |
| commands::RendererCommand command; |
| command.set_visible(true); |
| commands::Candidates *candidates |
| = command.mutable_output()->mutable_candidates(); |
| commands::Candidates_Candidate *candidate = candidates->add_candidate(); |
| commands::InformationList *usage = candidates->mutable_usages(); |
| usage->add_information(); |
| |
| candidates->set_focused_index(0); |
| candidate->set_index(0); |
| |
| WindowManager manager(NULL, NULL, NULL); |
| EXPECT_FALSE(manager.ShouldShowInfolistWindow(command)); |
| } |
| { |
| commands::RendererCommand command; |
| command.set_visible(true); |
| commands::Candidates *candidates |
| = command.mutable_output()->mutable_candidates(); |
| commands::Candidates_Candidate *candidate = candidates->add_candidate(); |
| |
| commands::InformationList *usage = candidates->mutable_usages(); |
| usage->add_information(); |
| |
| candidates->set_focused_index(0); |
| candidate->set_information_id(0); |
| |
| WindowManager manager(NULL, NULL, NULL); |
| EXPECT_TRUE(manager.ShouldShowInfolistWindow(command)); |
| } |
| } |
| |
| TEST(WindowManagerTest, UpdateCandidateWindowTest) { |
| // TODO(nona): Cleanup redundant codes. |
| { |
| SCOPED_TRACE("Use caret location"); |
| GtkWindowMock *candidate_window_mock = new GtkWindowMock(); |
| GtkWindowMock *infolist_window_mock = new GtkWindowMock(); |
| GtkWrapperMock *gtk_mock = new GtkWrapperMock(); |
| |
| commands::RendererCommand command; |
| command.set_visible(true); |
| commands::Candidates *candidates |
| = command.mutable_output()->mutable_candidates(); |
| candidates->set_focused_index(0); |
| |
| commands::Candidates_Candidate *candidate = candidates->add_candidate(); |
| candidate->set_information_id(0); |
| |
| commands::InformationList *usage = candidates->mutable_usages(); |
| usage->add_information(); |
| |
| const Rect client_cord_rect(10, 20, 30, 40); |
| const Point window_position(15, 25); |
| const Size window_size(35, 45); |
| const gint monitor = 0x7777; |
| |
| candidates->set_window_location(commands::Candidates::CARET); |
| const Rect caret_rect(16, 26, 2, 13); |
| commands::Rectangle *rectangle = candidates->mutable_caret_rectangle(); |
| rectangle->set_x(caret_rect.Left()); |
| rectangle->set_y(caret_rect.Top()); |
| rectangle->set_width(caret_rect.Width()); |
| rectangle->set_height(caret_rect.Height()); |
| const Point expected_window_position( |
| caret_rect.Left() - client_cord_rect.Left(), |
| caret_rect.Top() + caret_rect.Height()); |
| |
| EXPECT_CALL(*candidate_window_mock, Update(_)) |
| .WillOnce(Return(window_size)); |
| EXPECT_CALL(*candidate_window_mock, GetCandidateColumnInClientCord()) |
| .WillOnce(Return(client_cord_rect)); |
| EXPECT_CALL(*candidate_window_mock, GetWindowPos()) |
| .WillOnce(Return(window_position)); |
| EXPECT_CALL(*candidate_window_mock, |
| Move(PointEq(expected_window_position))); |
| EXPECT_CALL(*candidate_window_mock, ShowWindow()); |
| |
| GtkWidget *toplevel_widget = reinterpret_cast<GtkWidget*>(0x12345678); |
| GdkScreen *toplevel_screen = reinterpret_cast<GdkScreen*>(0x87654321); |
| const GdkRectangle monitor_rect = {0, 0, 4000, 4000}; |
| EXPECT_CALL(*gtk_mock, GtkWindowNew(GTK_WINDOW_TOPLEVEL)) |
| .WillOnce(Return(toplevel_widget)); |
| EXPECT_CALL(*gtk_mock, GtkWindowGetScreen(toplevel_widget)) |
| .WillOnce(Return(toplevel_screen)); |
| EXPECT_CALL(*gtk_mock, GdkScreenGetMonitorAtPoint(toplevel_screen, |
| caret_rect.Left(), |
| caret_rect.Bottom())) |
| .WillOnce(Return(monitor)); |
| EXPECT_CALL(*gtk_mock, GdkScreenGetMonitorGeometry(toplevel_screen, |
| monitor, |
| NotNull())) |
| .WillOnce(SetArgPointee<2>(monitor_rect)); |
| |
| WindowManager manager(candidate_window_mock, infolist_window_mock, |
| gtk_mock); |
| const Rect actual_rect = manager.UpdateCandidateWindow(command); |
| |
| EXPECT_EQ(actual_rect.origin.x, expected_window_position.x); |
| EXPECT_EQ(actual_rect.origin.y, expected_window_position.y); |
| EXPECT_EQ(actual_rect.size.width, window_size.width); |
| EXPECT_EQ(actual_rect.size.height, window_size.height); |
| } |
| { |
| SCOPED_TRACE("Use composition rectangle"); |
| GtkWindowMock *candidate_window_mock = new GtkWindowMock(); |
| GtkWindowMock *infolist_window_mock = new GtkWindowMock(); |
| GtkWrapperMock *gtk_mock = new GtkWrapperMock(); |
| |
| commands::RendererCommand command; |
| command.set_visible(true); |
| commands::Candidates *candidates |
| = command.mutable_output()->mutable_candidates(); |
| candidates->set_focused_index(0); |
| |
| commands::Candidates_Candidate *candidate = candidates->add_candidate(); |
| candidate->set_information_id(0); |
| |
| commands::InformationList *usage = candidates->mutable_usages(); |
| usage->add_information(); |
| |
| const Rect client_cord_rect(10, 20, 30, 40); |
| const Point window_position(15, 25); |
| const Size window_size(35, 45); |
| const gint monitor = 0x7777; |
| |
| candidates->set_window_location(commands::Candidates::COMPOSITION); |
| const Rect comp_rect(16, 26, 2, 13); |
| commands::Rectangle *rectangle |
| = candidates->mutable_composition_rectangle(); |
| rectangle->set_x(comp_rect.Left()); |
| rectangle->set_y(comp_rect.Top()); |
| rectangle->set_width(comp_rect.Width()); |
| rectangle->set_height(comp_rect.Height()); |
| const Point expected_window_position( |
| comp_rect.Left() - client_cord_rect.Left(), |
| comp_rect.Top() + comp_rect.Height()); |
| |
| EXPECT_CALL(*candidate_window_mock, Update(_)) |
| .WillOnce(Return(window_size)); |
| EXPECT_CALL(*candidate_window_mock, GetCandidateColumnInClientCord()) |
| .WillOnce(Return(client_cord_rect)); |
| EXPECT_CALL(*candidate_window_mock, GetWindowPos()) |
| .WillOnce(Return(window_position)); |
| EXPECT_CALL(*candidate_window_mock, |
| Move(PointEq(expected_window_position))); |
| EXPECT_CALL(*candidate_window_mock, ShowWindow()); |
| |
| GtkWidget *toplevel_widget = reinterpret_cast<GtkWidget*>(0x12345678); |
| GdkScreen *toplevel_screen = reinterpret_cast<GdkScreen*>(0x87654321); |
| const GdkRectangle monitor_rect = {0, 0, 4000, 4000}; |
| EXPECT_CALL(*gtk_mock, GtkWindowNew(GTK_WINDOW_TOPLEVEL)) |
| .WillOnce(Return(toplevel_widget)); |
| EXPECT_CALL(*gtk_mock, GtkWindowGetScreen(toplevel_widget)) |
| .WillOnce(Return(toplevel_screen)); |
| EXPECT_CALL(*gtk_mock, GdkScreenGetMonitorAtPoint(toplevel_screen, |
| comp_rect.Left(), |
| comp_rect.Bottom())) |
| .WillOnce(Return(monitor)); |
| EXPECT_CALL(*gtk_mock, GdkScreenGetMonitorGeometry(toplevel_screen, |
| monitor, |
| NotNull())) |
| .WillOnce(SetArgPointee<2>(monitor_rect)); |
| |
| WindowManager manager(candidate_window_mock, infolist_window_mock, |
| gtk_mock); |
| const Rect actual_rect = manager.UpdateCandidateWindow(command); |
| |
| EXPECT_EQ(actual_rect.origin.x, expected_window_position.x); |
| EXPECT_EQ(actual_rect.origin.y, expected_window_position.y); |
| EXPECT_EQ(actual_rect.size.width, window_size.width); |
| EXPECT_EQ(actual_rect.size.height, window_size.height); |
| } |
| { |
| SCOPED_TRACE("Edge fixing"); |
| GtkWindowMock *candidate_window_mock = new GtkWindowMock(); |
| GtkWindowMock *infolist_window_mock = new GtkWindowMock(); |
| GtkWrapperMock *gtk_mock = new GtkWrapperMock(); |
| |
| commands::RendererCommand command; |
| commands::Candidates *candidates |
| = command.mutable_output()->mutable_candidates(); |
| candidates->add_candidate(); |
| |
| GtkWidget *toplevel_widget = reinterpret_cast<GtkWidget*>(0x12345678); |
| GdkScreen *toplevel_screen = reinterpret_cast<GdkScreen*>(0x87654321); |
| const Rect client_cord_rect(0, 0, 30, 40); |
| const Point window_position(1000, 1000); |
| const Size window_size(300, 400); |
| const GdkRectangle monitor_rect = {0, 0, 1200, 1200}; |
| const gint monitor = 0x7777; |
| |
| EXPECT_CALL(*candidate_window_mock, Update(_)) |
| .WillOnce(Return(window_size)); |
| EXPECT_CALL(*candidate_window_mock, GetCandidateColumnInClientCord()) |
| .WillOnce(Return(client_cord_rect)); |
| EXPECT_CALL(*candidate_window_mock, GetWindowPos()) |
| .WillOnce(Return(window_position)); |
| EXPECT_CALL(*candidate_window_mock, Move(_)); |
| EXPECT_CALL(*candidate_window_mock, ShowWindow()); |
| |
| EXPECT_CALL(*gtk_mock, GtkWindowNew(GTK_WINDOW_TOPLEVEL)) |
| .WillOnce(Return(toplevel_widget)); |
| EXPECT_CALL(*gtk_mock, GtkWindowGetScreen(toplevel_widget)) |
| .WillOnce(Return(toplevel_screen)); |
| EXPECT_CALL(*gtk_mock, GdkScreenGetMonitorAtPoint(toplevel_screen, |
| window_position.x, |
| window_position.y)) |
| .WillOnce(Return(monitor)); |
| EXPECT_CALL(*gtk_mock, GdkScreenGetMonitorGeometry(toplevel_screen, |
| monitor, |
| NotNull())) |
| .WillOnce(SetArgPointee<2>(monitor_rect)); |
| |
| WindowManager manager(candidate_window_mock, infolist_window_mock, |
| gtk_mock); |
| const Rect actual_rect = manager.UpdateCandidateWindow(command); |
| |
| EXPECT_GE(actual_rect.Left(), monitor_rect.x); |
| EXPECT_GE(actual_rect.Top(), monitor_rect.y); |
| EXPECT_LE(actual_rect.Right(), monitor_rect.x + monitor_rect.width); |
| EXPECT_LE(actual_rect.Bottom(), monitor_rect.y + monitor_rect.height); |
| } |
| } |
| |
| TEST(WindowManagerTest, UpdateInfolistWindowTest) { |
| { |
| SCOPED_TRACE("If there are no information, should hide and do nothing"); |
| GtkWindowMock *candidate_window_mock = new StrictMock<GtkWindowMock>(); |
| GtkWindowMock *infolist_window_mock = new StrictMock<GtkWindowMock>(); |
| GtkWrapperMock *gtk_mock = new StrictMock<GtkWrapperMock>(); |
| |
| commands::RendererCommand command; |
| command.set_visible(false); |
| |
| EXPECT_CALL(*infolist_window_mock, HideWindow()); |
| const Rect candidate_window_rect(10, 20, 30, 40); |
| |
| WindowManager manager(candidate_window_mock, infolist_window_mock, |
| gtk_mock); |
| manager.UpdateInfolistWindow(command, candidate_window_rect); |
| } |
| { |
| GtkWindowMock *candidate_window_mock = new GtkWindowMock(); |
| GtkWindowMock *infolist_window_mock = new GtkWindowMock(); |
| GtkWrapperMock *gtk_mock = new GtkWrapperMock(); |
| |
| commands::RendererCommand command; |
| command.set_visible(true); |
| commands::Candidates *candidates |
| = command.mutable_output()->mutable_candidates(); |
| commands::Candidates_Candidate *candidate = candidates->add_candidate(); |
| |
| commands::InformationList *usage = candidates->mutable_usages(); |
| usage->add_information(); |
| |
| candidates->set_focused_index(0); |
| candidate->set_information_id(0); |
| |
| GtkWidget *toplevel_widget = reinterpret_cast<GtkWidget*>(0x12345678); |
| GdkScreen *toplevel_screen = reinterpret_cast<GdkScreen*>(0x87654321); |
| const GdkRectangle monitor_rect = {15, 25, 35, 45}; |
| const gint monitor = 0x7777; |
| const Rect cand_window_rect(10, 20, 30, 40); |
| |
| EXPECT_CALL(*gtk_mock, GtkWindowNew(GTK_WINDOW_TOPLEVEL)) |
| .WillOnce(Return(toplevel_widget)); |
| EXPECT_CALL(*gtk_mock, GtkWindowGetScreen(toplevel_widget)) |
| .WillOnce(Return(toplevel_screen)); |
| EXPECT_CALL(*gtk_mock, GdkScreenGetMonitorAtPoint(toplevel_screen, |
| cand_window_rect.Left(), |
| cand_window_rect.Top())) |
| .WillOnce(Return(monitor)); |
| EXPECT_CALL(*gtk_mock, GdkScreenGetMonitorGeometry(toplevel_screen, |
| monitor, |
| NotNull())) |
| .WillOnce(SetArgPointee<2>(monitor_rect)); |
| |
| |
| // TODO(nona): Make precise expectation. |
| const Size infolist_window_size(10, 20); |
| EXPECT_CALL(*infolist_window_mock, Move(_)); |
| EXPECT_CALL(*infolist_window_mock, ShowWindow()); |
| EXPECT_CALL(*infolist_window_mock, HideWindow()).Times(0); |
| EXPECT_CALL(*infolist_window_mock, Update(_)) |
| .WillOnce(Return(infolist_window_size)); |
| |
| WindowManager manager(candidate_window_mock, infolist_window_mock, |
| gtk_mock); |
| |
| EXPECT_TRUE(manager.ShouldShowInfolistWindow(command)); |
| manager.UpdateInfolistWindow(command, cand_window_rect); |
| } |
| } |
| |
| TEST(WindowManagerTest, GetMonitorRectTest) { |
| GtkWindowMock *candidate_window_mock = new GtkWindowMock(); |
| GtkWindowMock *infolist_window_mock = new GtkWindowMock(); |
| GtkWrapperMock *gtk_mock = new GtkWrapperMock(); |
| GtkWidget *toplevel_widget = reinterpret_cast<GtkWidget*>(0x12345678); |
| GdkScreen *toplevel_screen = reinterpret_cast<GdkScreen*>(0x87654321); |
| const gint monitor = 0x7777; |
| const Point cursor(123, 456); |
| |
| const GdkRectangle monitor_rect = {10, 20, 35, 45}; |
| EXPECT_CALL(*gtk_mock, GtkWindowNew(GTK_WINDOW_TOPLEVEL)) |
| .WillOnce(Return(toplevel_widget)); |
| EXPECT_CALL(*gtk_mock, GtkWindowGetScreen(toplevel_widget)) |
| .WillOnce(Return(toplevel_screen)); |
| EXPECT_CALL(*gtk_mock, GdkScreenGetMonitorAtPoint(toplevel_screen, |
| cursor.x, |
| cursor.y)) |
| .WillOnce(Return(monitor)); |
| EXPECT_CALL(*gtk_mock, GdkScreenGetMonitorGeometry(toplevel_screen, |
| monitor, |
| NotNull())) |
| .WillOnce(SetArgPointee<2>(monitor_rect)); |
| |
| WindowManager manager(candidate_window_mock, infolist_window_mock, gtk_mock); |
| |
| const Rect &actual_monitor_rect = manager.GetMonitorRect(cursor.x, cursor.y); |
| EXPECT_EQ(monitor_rect.x, actual_monitor_rect.origin.x); |
| EXPECT_EQ(monitor_rect.y, actual_monitor_rect.origin.y); |
| EXPECT_EQ(monitor_rect.width, actual_monitor_rect.size.width); |
| EXPECT_EQ(monitor_rect.height, actual_monitor_rect.size.height); |
| } |
| |
| class FontUpdateTestableWindowManager : public WindowManager { |
| public: |
| FontUpdateTestableWindowManager(GtkWindowInterface *main_window, |
| GtkWindowInterface *infolist_window, |
| GtkWrapperInterface *gtk) |
| : WindowManager(main_window, infolist_window, gtk) {} |
| virtual ~FontUpdateTestableWindowManager() {} |
| |
| MOCK_METHOD1(ShouldShowCandidateWindow, |
| bool(const commands::RendererCommand &command)); |
| MOCK_METHOD1(ShouldShowInfolistWindow, |
| bool(const commands::RendererCommand &command)); |
| MOCK_METHOD1(UpdateCandidateWindow, |
| Rect(const commands::RendererCommand &command)); |
| MOCK_METHOD2(UpdateInfolistWindow, |
| void(const commands::RendererCommand &command, |
| const Rect &candidate_window_rect)); |
| }; |
| |
| TEST(WindowManagerTest, FontReloadTest) { |
| { |
| GtkWindowMock *candidate_window_mock = new GtkWindowMock(); |
| GtkWindowMock *infolist_window_mock = new GtkWindowMock(); |
| GtkWrapperMock *gtk_mock = new GtkWrapperMock(); |
| |
| const Rect kDummyRect(0, 0, 0, 0); |
| const char kDummyFontDescription[] = "Foo,Bar,Baz"; |
| |
| FontUpdateTestableWindowManager window_manager( |
| candidate_window_mock, infolist_window_mock, gtk_mock); |
| EXPECT_CALL(window_manager, ShouldShowCandidateWindow(_)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(*candidate_window_mock, |
| ReloadFontConfig(StrEq(kDummyFontDescription))); |
| EXPECT_CALL(*infolist_window_mock, |
| ReloadFontConfig(StrEq(kDummyFontDescription))); |
| EXPECT_CALL(window_manager, UpdateCandidateWindow(_)) |
| .WillOnce(Return(kDummyRect)); |
| |
| EXPECT_CALL(window_manager, UpdateInfolistWindow(_, _)); |
| |
| commands::RendererCommand command; |
| |
| commands::RendererCommand::ApplicationInfo *app_info = |
| command.mutable_application_info(); |
| app_info->set_pango_font_description(kDummyFontDescription); |
| |
| window_manager.UpdateLayout(command); |
| } |
| { |
| SCOPED_TRACE("Does not call reload function when the custom font setting " |
| "is not available"); |
| GtkWindowMock *candidate_window_mock = new GtkWindowMock(); |
| GtkWindowMock *infolist_window_mock = new GtkWindowMock(); |
| GtkWrapperMock *gtk_mock = new GtkWrapperMock(); |
| |
| const Rect kDummyRect(0, 0, 0, 0); |
| |
| FontUpdateTestableWindowManager window_manager( |
| candidate_window_mock, infolist_window_mock, gtk_mock); |
| EXPECT_CALL(window_manager, ShouldShowCandidateWindow(_)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(*candidate_window_mock, ReloadFontConfig(_)).Times(0); |
| EXPECT_CALL(*infolist_window_mock, ReloadFontConfig(_)).Times(0); |
| EXPECT_CALL(window_manager, UpdateCandidateWindow(_)) |
| .WillOnce(Return(kDummyRect)); |
| |
| EXPECT_CALL(window_manager, UpdateInfolistWindow(_, _)); |
| |
| commands::RendererCommand command; |
| command.mutable_application_info(); |
| |
| window_manager.UpdateLayout(command); |
| } |
| { |
| SCOPED_TRACE("Does not call reload function if previously loaded font" |
| "description is same as requested one."); |
| GtkWindowMock *candidate_window_mock = new GtkWindowMock(); |
| GtkWindowMock *infolist_window_mock = new GtkWindowMock(); |
| GtkWrapperMock *gtk_mock = new GtkWrapperMock(); |
| |
| const Rect kDummyRect(0, 0, 0, 0); |
| const char kDummyFontDescription[] = "Foo,Bar,Baz"; |
| |
| FontUpdateTestableWindowManager window_manager( |
| candidate_window_mock, infolist_window_mock, gtk_mock); |
| EXPECT_CALL(window_manager, ShouldShowCandidateWindow(_)) |
| .Times(2) |
| .WillRepeatedly(Return(true)); |
| EXPECT_CALL(*candidate_window_mock, |
| ReloadFontConfig(StrEq(kDummyFontDescription))); |
| EXPECT_CALL(*infolist_window_mock, |
| ReloadFontConfig(StrEq(kDummyFontDescription))); |
| EXPECT_CALL(window_manager, UpdateCandidateWindow(_)) |
| .Times(2) |
| .WillRepeatedly(Return(kDummyRect)); |
| |
| EXPECT_CALL(window_manager, UpdateInfolistWindow(_, _)).Times(2); |
| |
| commands::RendererCommand command; |
| |
| commands::RendererCommand::ApplicationInfo *app_info = |
| command.mutable_application_info(); |
| app_info->set_pango_font_description(kDummyFontDescription); |
| |
| window_manager.UpdateLayout(command); |
| |
| // Call again with same font description. |
| window_manager.UpdateLayout(command); |
| } |
| { |
| SCOPED_TRACE("Call reload function if previously loaded font description" |
| " is different from requested one."); |
| GtkWindowMock *candidate_window_mock = new GtkWindowMock(); |
| GtkWindowMock *infolist_window_mock = new GtkWindowMock(); |
| GtkWrapperMock *gtk_mock = new GtkWrapperMock(); |
| |
| const Rect kDummyRect(0, 0, 0, 0); |
| const char kDummyFontDescription[] = "Foo,Bar,Baz"; |
| const char kDummyFontDescription2[] = "Foo,Bar"; |
| |
| FontUpdateTestableWindowManager window_manager( |
| candidate_window_mock, infolist_window_mock, gtk_mock); |
| EXPECT_CALL(window_manager, ShouldShowCandidateWindow(_)) |
| .Times(2) |
| .WillRepeatedly(Return(true)); |
| EXPECT_CALL(*candidate_window_mock, |
| ReloadFontConfig(StrEq(kDummyFontDescription))); |
| EXPECT_CALL(*infolist_window_mock, |
| ReloadFontConfig(StrEq(kDummyFontDescription))); |
| EXPECT_CALL(*candidate_window_mock, |
| ReloadFontConfig(StrEq(kDummyFontDescription2))); |
| EXPECT_CALL(*infolist_window_mock, |
| ReloadFontConfig(StrEq(kDummyFontDescription2))); |
| EXPECT_CALL(window_manager, UpdateCandidateWindow(_)) |
| .Times(2) |
| .WillRepeatedly(Return(kDummyRect)); |
| |
| EXPECT_CALL(window_manager, UpdateInfolistWindow(_, _)).Times(2); |
| |
| commands::RendererCommand command; |
| |
| commands::RendererCommand::ApplicationInfo *app_info = |
| command.mutable_application_info(); |
| app_info->set_pango_font_description(kDummyFontDescription); |
| |
| window_manager.UpdateLayout(command); |
| |
| app_info->set_pango_font_description(kDummyFontDescription2); |
| // Call again with different font description. |
| window_manager.UpdateLayout(command); |
| } |
| } |
| } // namespace gtk |
| } // namespace renderer |
| } // namespace mozc |