Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2010 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions are
      6  * met:
      7  *
      8  *     * Redistributions of source code must retain the above copyright
      9  * notice, this list of conditions and the following disclaimer.
     10  *     * Redistributions in binary form must reproduce the above
     11  * copyright notice, this list of conditions and the following disclaimer
     12  * in the documentation and/or other materials provided with the
     13  * distribution.
     14  *     * Neither the name of Google Inc. nor the names of its
     15  * contributors may be used to endorse or promote products derived from
     16  * this software without specific prior written permission.
     17  *
     18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     29  */
     30 
     31 #include "config.h"
     32 
     33 #include <gdk/gdk.h>
     34 #include <gdk/gdkkeysyms.h>
     35 #include <gtest/gtest.h>
     36 
     37 #include "WebInputEvent.h"
     38 #include "WebInputEventConversion.h"
     39 #include "WebInputEventFactory.h"
     40 #include "core/dom/KeyboardEvent.h"
     41 
     42 using WebKit::WebInputEvent;
     43 using WebKit::WebKeyboardEvent;
     44 using WebKit::WebMouseEvent;
     45 using WebKit::WebInputEventFactory;
     46 
     47 namespace {
     48 
     49 TEST(WebInputEventFactoryTest, DoubleClick)
     50 {
     51     GdkEventButton firstClick;
     52     firstClick.type = GDK_BUTTON_PRESS;
     53     firstClick.window = static_cast<GdkWindow*>(GINT_TO_POINTER(1));
     54     firstClick.x = firstClick.y = firstClick.x_root = firstClick.y_root = 100;
     55     firstClick.state = 0;
     56     firstClick.time = 0;
     57     firstClick.button = 1;
     58 
     59     // Single click works.
     60     WebMouseEvent firstClickEvent = WebInputEventFactory::mouseEvent(&firstClick);
     61     EXPECT_EQ(1, firstClickEvent.clickCount);
     62 
     63     // Make sure double click works.
     64     GdkEventButton secondClick = firstClick;
     65     secondClick.time = firstClick.time + 100;
     66     WebMouseEvent secondClickEvent = WebInputEventFactory::mouseEvent(&secondClick);
     67     EXPECT_EQ(2, secondClickEvent.clickCount);
     68 
     69     // Reset the click count.
     70     firstClick.time += 10000;
     71     firstClickEvent = WebInputEventFactory::mouseEvent(&firstClick);
     72     EXPECT_EQ(1, firstClickEvent.clickCount);
     73 
     74     // Two clicks with a long gap in between aren't counted as a double click.
     75     secondClick = firstClick;
     76     secondClick.time = firstClick.time + 1000;
     77     secondClickEvent = WebInputEventFactory::mouseEvent(&secondClick);
     78     EXPECT_EQ(1, secondClickEvent.clickCount);
     79 
     80     // Reset the click count.
     81     firstClick.time += 10000;
     82     firstClickEvent = WebInputEventFactory::mouseEvent(&firstClick);
     83     EXPECT_EQ(1, firstClickEvent.clickCount);
     84 
     85     // Two clicks far apart (horizontally) aren't counted as a double click.
     86     secondClick = firstClick;
     87     secondClick.time = firstClick.time + 1;
     88     secondClick.x = firstClick.x + 100;
     89     secondClickEvent = WebInputEventFactory::mouseEvent(&secondClick);
     90     EXPECT_EQ(1, secondClickEvent.clickCount);
     91 
     92     // Reset the click count.
     93     firstClick.time += 10000;
     94     firstClickEvent = WebInputEventFactory::mouseEvent(&firstClick);
     95     EXPECT_EQ(1, firstClickEvent.clickCount);
     96 
     97     // Two clicks far apart (vertically) aren't counted as a double click.
     98     secondClick = firstClick;
     99     secondClick.time = firstClick.time + 1;
    100     secondClick.x = firstClick.y + 100;
    101     secondClickEvent = WebInputEventFactory::mouseEvent(&secondClick);
    102     EXPECT_EQ(1, secondClickEvent.clickCount);
    103 
    104     // Reset the click count.
    105     firstClick.time += 10000;
    106     firstClickEvent = WebInputEventFactory::mouseEvent(&firstClick);
    107     EXPECT_EQ(1, firstClickEvent.clickCount);
    108 
    109     // Two clicks on different windows aren't a double click.
    110     secondClick = firstClick;
    111     secondClick.time = firstClick.time + 1;
    112     secondClick.window = static_cast<GdkWindow*>(GINT_TO_POINTER(2));
    113     secondClickEvent = WebInputEventFactory::mouseEvent(&secondClick);
    114     EXPECT_EQ(1, secondClickEvent.clickCount);
    115 }
    116 
    117 TEST(WebInputEventFactoryTest, MouseUpClickCount)
    118 {
    119     GdkEventButton mouseDown;
    120     memset(&mouseDown, 0, sizeof(mouseDown));
    121     mouseDown.type = GDK_BUTTON_PRESS;
    122     mouseDown.window = static_cast<GdkWindow*>(GINT_TO_POINTER(1));
    123     mouseDown.x = mouseDown.y = mouseDown.x_root = mouseDown.y_root = 100;
    124     mouseDown.time = 0;
    125     mouseDown.button = 1;
    126 
    127     // Properly set the last click time, so that the internal state won't be affected by previous tests.
    128     WebInputEventFactory::mouseEvent(&mouseDown);
    129 
    130     mouseDown.time += 10000;
    131     GdkEventButton mouseUp = mouseDown;
    132     mouseUp.type = GDK_BUTTON_RELEASE;
    133     WebMouseEvent mouseDownEvent;
    134     WebMouseEvent mouseUpEvent;
    135 
    136     // Click for three times.
    137     for (int i = 1; i < 4; ++i) {
    138         mouseDown.time += 100;
    139         mouseDownEvent = WebInputEventFactory::mouseEvent(&mouseDown);
    140         EXPECT_EQ(i, mouseDownEvent.clickCount);
    141 
    142         mouseUp.time = mouseDown.time + 50;
    143         mouseUpEvent = WebInputEventFactory::mouseEvent(&mouseUp);
    144         EXPECT_EQ(i, mouseUpEvent.clickCount);
    145     }
    146 
    147     // Reset the click count.
    148     mouseDown.time += 10000;
    149     mouseDownEvent = WebInputEventFactory::mouseEvent(&mouseDown);
    150     EXPECT_EQ(1, mouseDownEvent.clickCount);
    151 
    152     // Moving the cursor for a significant distance will reset the click count to 0.
    153     GdkEventMotion mouseMove;
    154     memset(&mouseMove, 0, sizeof(mouseMove));
    155     mouseMove.type = GDK_MOTION_NOTIFY;
    156     mouseMove.window = mouseDown.window;
    157     mouseMove.time = mouseDown.time;
    158     mouseMove.x = mouseMove.y = mouseMove.x_root = mouseMove.y_root = mouseDown.x + 100;
    159     WebInputEventFactory::mouseEvent(&mouseMove);
    160 
    161     mouseUp.time = mouseDown.time + 50;
    162     mouseUpEvent = WebInputEventFactory::mouseEvent(&mouseUp);
    163     EXPECT_EQ(0, mouseUpEvent.clickCount);
    164 
    165     // Reset the click count.
    166     mouseDown.time += 10000;
    167     mouseDownEvent = WebInputEventFactory::mouseEvent(&mouseDown);
    168     EXPECT_EQ(1, mouseDownEvent.clickCount);
    169 
    170     // Moving the cursor with a significant delay will reset the click count to 0.
    171     mouseMove.time = mouseDown.time + 1000;
    172     mouseMove.x = mouseMove.y = mouseMove.x_root = mouseMove.y_root = mouseDown.x;
    173     WebInputEventFactory::mouseEvent(&mouseMove);
    174 
    175     mouseUp.time = mouseMove.time + 50;
    176     mouseUpEvent = WebInputEventFactory::mouseEvent(&mouseUp);
    177     EXPECT_EQ(0, mouseUpEvent.clickCount);
    178 }
    179 
    180 TEST(WebInputEventFactoryTest, NumPadConversion)
    181 {
    182     // Construct a GDK input event for the numpad "5" key.
    183     char five[] = "5";
    184     GdkEventKey gdkEvent;
    185     memset(&gdkEvent, 0, sizeof(GdkEventKey));
    186     gdkEvent.type = GDK_KEY_PRESS;
    187     gdkEvent.keyval = GDK_KP_5;
    188     gdkEvent.string = five;
    189 
    190     // Numpad flag should be set on the WebKeyboardEvent.
    191     WebKeyboardEvent webEvent = WebInputEventFactory::keyboardEvent(&gdkEvent);
    192     EXPECT_TRUE(webEvent.modifiers & WebInputEvent::IsKeyPad);
    193 
    194     // Round-trip through the WebCore KeyboardEvent class.
    195     WebKit::PlatformKeyboardEventBuilder platformBuilder(webEvent);
    196     RefPtr<WebCore::KeyboardEvent> keypress = WebCore::KeyboardEvent::create(platformBuilder, 0);
    197     EXPECT_TRUE(keypress->location() == WebCore::KeyboardEvent::DOM_KEY_LOCATION_NUMPAD);
    198 
    199     WebKit::WebKeyboardEventBuilder builder(*keypress);
    200     EXPECT_TRUE(builder.modifiers & WebInputEvent::IsKeyPad);
    201 }
    202 
    203 } // anonymous namespace
    204