shell/platform/windows/keyboard_key_handler_unittests.cc
TEST(KeyboardKeyHandlerTest, WithSlowFrameworkResponse) {
  std::list<MockKeyHandlerDelegate::KeyboardHookCall> hook_history;

  // Capture the scancode of the last redispatched event
  int redispatch_scancode = 0;
  bool delegate_handled = false;
  TestKeyboardKeyHandler handler([&redispatch_scancode](UINT cInputs,
                                                        LPINPUT pInputs,
                                                        int cbSize) -> UINT {
    EXPECT_TRUE(cbSize > 0);
    redispatch_scancode = pInputs->ki.wScan;
    return 1;
  });

  auto delegate1 = std::make_unique<MockKeyHandlerDelegate>(1, &hook_history);
  CallbackHandler& delegate1_handler = delegate1->callback_handler;
  handler.AddDelegate(std::move(delegate1));

  // The first native event.
  EXPECT_EQ(
      handler.KeyboardHook(64, kHandledScanCode, WM_KEYDOWN, L'a', false, true),
      true);

  // The second identical native event, received between the first and its
  // framework response.
  EXPECT_EQ(
      handler.KeyboardHook(64, kHandledScanCode, WM_KEYDOWN, L'a', false, true),
      true);
  EXPECT_EQ(redispatch_scancode, 0);
  EXPECT_EQ(hook_history.size(), 2);

  EXPECT_EQ(handler.HasRedispatched(), false);

  // The first response.
  hook_history.front().callback(false);
  EXPECT_EQ(redispatch_scancode, kHandledScanCode);
  EXPECT_EQ(handler.HasRedispatched(), true);

  // Redispatch the first event.
  EXPECT_EQ(handler.KeyboardHook(64, kHandledScanCode, WM_KEYDOWN, L'a', false,
                                 false),
            false);
  EXPECT_EQ(handler.HasRedispatched(), false);
  redispatch_scancode = 0;

  // The second response.
  hook_history.back().callback(false);
  EXPECT_EQ(redispatch_scancode, kHandledScanCode);
  EXPECT_EQ(handler.HasRedispatched(), true);

  // Redispatch the second event.
  EXPECT_EQ(handler.KeyboardHook(64, kHandledScanCode, WM_KEYDOWN, L'a', false,
                                 false),
            false);

  EXPECT_EQ(handler.HasRedispatched(), false);
  redispatch_scancode = 0;
  hook_history.clear();
}
// Regression test for a crash in an earlier implementation.
//
// In real life, the framework responds slowly. The next real event might
// arrive earlier than the framework response, and if the 2nd event is identical
// to the one waiting for response, an earlier implementation will crash upon
// the response.
Regression test for a crash in an earlier implementation.
In real life, the framework responds slowly. The next real event might
arrive earlier than the framework response, and if the 2nd event is identical
to the one waiting for response, an earlier implementation will crash upon
the response.
Regression test for a crash in an earlier implementation . In real life the framework responds slowly . The next real event might arrive earlier than the framework response and if the 2nd event is identical to the one waiting for response an earlier implementation will crash upon the response .
TEST(KeyboardKeyHandlerTest, WithSlowFrameworkResponse) {
  std::list<MockKeyHandlerDelegate::KeyboardHookCall> hook_history;
  int redispatch_scancode = 0;
  bool delegate_handled = false;
  TestKeyboardKeyHandler handler([&redispatch_scancode](UINT cInputs,
                                                        LPINPUT pInputs,
                                                        int cbSize) -> UINT {
    EXPECT_TRUE(cbSize > 0);
    redispatch_scancode = pInputs->ki.wScan;
    return 1;
  });
  auto delegate1 = std::make_unique<MockKeyHandlerDelegate>(1, &hook_history);
  CallbackHandler& delegate1_handler = delegate1->callback_handler;
  handler.AddDelegate(std::move(delegate1));
  EXPECT_EQ(
      handler.KeyboardHook(64, kHandledScanCode, WM_KEYDOWN, L'a', false, true),
      true);
  EXPECT_EQ(
      handler.KeyboardHook(64, kHandledScanCode, WM_KEYDOWN, L'a', false, true),
      true);
  EXPECT_EQ(redispatch_scancode, 0);
  EXPECT_EQ(hook_history.size(), 2);
  EXPECT_EQ(handler.HasRedispatched(), false);
  hook_history.front().callback(false);
  EXPECT_EQ(redispatch_scancode, kHandledScanCode);
  EXPECT_EQ(handler.HasRedispatched(), true);
  EXPECT_EQ(handler.KeyboardHook(64, kHandledScanCode, WM_KEYDOWN, L'a', false,
                                 false),
            false);
  EXPECT_EQ(handler.HasRedispatched(), false);
  redispatch_scancode = 0;
  hook_history.back().callback(false);
  EXPECT_EQ(redispatch_scancode, kHandledScanCode);
  EXPECT_EQ(handler.HasRedispatched(), true);
  EXPECT_EQ(handler.KeyboardHook(64, kHandledScanCode, WM_KEYDOWN, L'a', false,
                                 false),
            false);
  EXPECT_EQ(handler.HasRedispatched(), false);
  redispatch_scancode = 0;
  hook_history.clear();
}
TEST ( KeyboardKeyHandlerTest , WithSlowFrameworkResponse ) { std :: list < MockKeyHandlerDelegate :: KeyboardHookCall > hook_history ; int redispatch_scancode = 0 ; bool delegate_handled = false ; TestKeyboardKeyHandler handler ( [ & redispatch_scancode ] ( UINT cInputs , LPINPUT pInputs , int cbSize ) -> UINT { EXPECT_TRUE ( cbSize > 0 ) ; redispatch_scancode = pInputs -> ki . wScan ; return 1 ; } ) ; auto delegate1 = std :: make_unique < MockKeyHandlerDelegate > ( 1 , & hook_history ) ; CallbackHandler & delegate1_handler = delegate1 -> callback_handler ; handler . AddDelegate ( std :: move ( delegate1 ) ) ; EXPECT_EQ ( handler . KeyboardHook ( 64 , kHandledScanCode , WM_KEYDOWN , L' ' , false , true ) , true ) ; EXPECT_EQ ( handler . KeyboardHook ( 64 , kHandledScanCode , WM_KEYDOWN , L' ' , false , true ) , true ) ; EXPECT_EQ ( redispatch_scancode , 0 ) ; EXPECT_EQ ( hook_history . size ( ) , 2 ) ; EXPECT_EQ ( handler . HasRedispatched ( ) , false ) ; hook_history . front ( ) . callback ( false ) ; EXPECT_EQ ( redispatch_scancode , kHandledScanCode ) ; EXPECT_EQ ( handler . HasRedispatched ( ) , true ) ; EXPECT_EQ ( handler . KeyboardHook ( 64 , kHandledScanCode , WM_KEYDOWN , L' ' , false , false ) , false ) ; EXPECT_EQ ( handler . HasRedispatched ( ) , false ) ; redispatch_scancode = 0 ; hook_history . back ( ) . callback ( false ) ; EXPECT_EQ ( redispatch_scancode , kHandledScanCode ) ; EXPECT_EQ ( handler . HasRedispatched ( ) , true ) ; EXPECT_EQ ( handler . KeyboardHook ( 64 , kHandledScanCode , WM_KEYDOWN , L' ' , false , false ) , false ) ; EXPECT_EQ ( handler . HasRedispatched ( ) , false ) ; redispatch_scancode = 0 ; hook_history . clear ( ) ; }
Regression test for a crash in an earlier implementation.
Regression test for a crash in an earlier implementation .
// Capture the scancode of the last redispatched event // The first native event. // The second identical native event, received between the first and its // framework response. // The first response. // Redispatch the first event. // The second response. // Redispatch the second event.