1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #if !defined(__has_feature) || !__has_feature(objc_arc) 6 #error "This file requires ARC support." 7 #endif 8 9 #import "remoting/ios/key_input.h" 10 #import "remoting/ios/key_map_us.h" 11 12 #include <vector> 13 14 #import "base/compiler_specific.h" 15 #import "testing/gtest_mac.h" 16 17 @interface KeyInputDelegateTester : NSObject<KeyInputDelegate> { 18 @private 19 std::vector<uint32_t> _keyList; 20 } 21 22 @property(nonatomic, assign) int numKeysDown; 23 @property(nonatomic, assign) BOOL wasDismissed; 24 25 - (std::vector<uint32_t>&)getKeyList; 26 27 @end 28 29 @implementation KeyInputDelegateTester 30 31 - (std::vector<uint32_t>&)getKeyList { 32 return _keyList; 33 } 34 35 - (void)keyboardDismissed { 36 // This can not be tested, because we can not set |keyInput_| as 37 // FirstResponder in this test harness 38 _wasDismissed = true; 39 } 40 41 - (void)keyboardActionKeyCode:(uint32_t)keyPressed isKeyDown:(BOOL)keyDown { 42 if (keyDown) { 43 _keyList.push_back(keyPressed); 44 _numKeysDown++; 45 } else { 46 _numKeysDown--; 47 } 48 } 49 50 @end 51 52 namespace remoting { 53 54 class KeyInputTest : public ::testing::Test { 55 protected: 56 virtual void SetUp() OVERRIDE { 57 keyInput_ = [[KeyInput allocWithZone:nil] init]; 58 delegateTester_ = [[KeyInputDelegateTester alloc] init]; 59 keyInput_.delegate = delegateTester_; 60 } 61 62 KeyInput* keyInput_; 63 KeyInputDelegateTester* delegateTester_; 64 }; 65 66 TEST_F(KeyInputTest, SendKey) { 67 // Empty 68 [keyInput_ insertText:@""]; 69 ASSERT_EQ(0, delegateTester_.numKeysDown); 70 ASSERT_EQ(0, [delegateTester_ getKeyList].size()); 71 72 // Value is out of bounds 73 [keyInput_ insertText:@""]; 74 ASSERT_EQ(0, delegateTester_.numKeysDown); 75 ASSERT_EQ(0, [delegateTester_ getKeyList].size()); 76 77 // Lower case 78 [keyInput_ insertText:@"a"]; 79 ASSERT_EQ(0, delegateTester_.numKeysDown); 80 ASSERT_EQ(1, [delegateTester_ getKeyList].size()); 81 ASSERT_EQ(kKeyCodeUS['a'], [delegateTester_ getKeyList][0]); 82 // Upper Case 83 [delegateTester_ getKeyList].clear(); 84 [keyInput_ insertText:@"A"]; 85 ASSERT_EQ(0, delegateTester_.numKeysDown); 86 ASSERT_EQ(2, [delegateTester_ getKeyList].size()); 87 ASSERT_EQ(kKeyCodeUS[kShiftIndex], [delegateTester_ getKeyList][0]); 88 ASSERT_EQ(kKeyCodeUS['A'], [delegateTester_ getKeyList][1]); 89 90 // Multiple characters and mixed case 91 [delegateTester_ getKeyList].clear(); 92 [keyInput_ insertText:@"ABCabc"]; 93 ASSERT_EQ(0, delegateTester_.numKeysDown); 94 ASSERT_EQ(9, [delegateTester_ getKeyList].size()); 95 ASSERT_EQ(kKeyCodeUS[kShiftIndex], [delegateTester_ getKeyList][0]); 96 ASSERT_EQ(kKeyCodeUS['A'], [delegateTester_ getKeyList][1]); 97 ASSERT_EQ(kKeyCodeUS[kShiftIndex], [delegateTester_ getKeyList][2]); 98 ASSERT_EQ(kKeyCodeUS['B'], [delegateTester_ getKeyList][3]); 99 ASSERT_EQ(kKeyCodeUS[kShiftIndex], [delegateTester_ getKeyList][4]); 100 ASSERT_EQ(kKeyCodeUS['C'], [delegateTester_ getKeyList][5]); 101 ASSERT_EQ(kKeyCodeUS['a'], [delegateTester_ getKeyList][6]); 102 ASSERT_EQ(kKeyCodeUS['b'], [delegateTester_ getKeyList][7]); 103 ASSERT_EQ(kKeyCodeUS['c'], [delegateTester_ getKeyList][8]); 104 } 105 106 TEST_F(KeyInputTest, CtrlAltDel) { 107 [keyInput_ ctrlAltDel]; 108 109 ASSERT_EQ(0, delegateTester_.numKeysDown); 110 ASSERT_EQ(3, [delegateTester_ getKeyList].size()); 111 ASSERT_EQ(kKeyCodeUS[kCtrlIndex], [delegateTester_ getKeyList][0]); 112 ASSERT_EQ(kKeyCodeUS[kAltIndex], [delegateTester_ getKeyList][1]); 113 ASSERT_EQ(kKeyCodeUS[kDelIndex], [delegateTester_ getKeyList][2]); 114 } 115 116 TEST_F(KeyInputTest, Backspace) { 117 [keyInput_ deleteBackward]; 118 119 ASSERT_EQ(0, delegateTester_.numKeysDown); 120 ASSERT_EQ(1, [delegateTester_ getKeyList].size()); 121 ASSERT_EQ(kKeyCodeUS[kBackspaceIndex], [delegateTester_ getKeyList][0]); 122 } 123 124 } // namespace remoting