1 /* 2 * Copyright 2019 Haiku, Inc. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Simon South, simon@simonsouth.net 7 */ 8 9 10 #include <stdio.h> 11 #include <string.h> 12 13 #include <map> 14 15 #include <cppunit/TestCaller.h> 16 #include <cppunit/TestSuite.h> 17 18 #include "KeymapTest.h" 19 20 21 KeymapTest::KeymapTest() 22 { 23 fCurrentKeymap.SetToCurrent(); 24 fDefaultKeymap.SetToDefault(); 25 } 26 27 28 KeymapTest::~KeymapTest() 29 { 30 } 31 32 33 void 34 KeymapTest::TestEquals() 35 { 36 CPPUNIT_ASSERT(fCurrentKeymap == fCurrentKeymap); 37 CPPUNIT_ASSERT(fDefaultKeymap == fDefaultKeymap); 38 39 BKeymap keymap; 40 41 keymap.SetToCurrent(); 42 CPPUNIT_ASSERT(keymap == fCurrentKeymap); 43 44 keymap.SetToDefault(); 45 CPPUNIT_ASSERT(keymap == fDefaultKeymap); 46 } 47 48 49 void 50 KeymapTest::TestAssignment() 51 { 52 BKeymap keymap; 53 54 keymap = fCurrentKeymap; 55 CPPUNIT_ASSERT(keymap == fCurrentKeymap); 56 57 keymap = fDefaultKeymap; 58 CPPUNIT_ASSERT(keymap == fDefaultKeymap); 59 } 60 61 62 void 63 KeymapTest::TestGetChars() 64 { 65 // Get a copy of the currently loaded keymap 66 key_map* keymap; 67 char* charArray; 68 69 get_key_map(&keymap, &charArray); 70 CPPUNIT_ASSERT(keymap != NULL); 71 72 // Test each of the keymap's character tables 73 std::map<uint32, int(*)[128]> tables = { 74 {0, &keymap->normal_map}, 75 {B_SHIFT_KEY, &keymap->shift_map}, 76 {B_CAPS_LOCK, &keymap->caps_map}, 77 {B_CAPS_LOCK | B_SHIFT_KEY, &keymap->caps_shift_map}, 78 {B_CONTROL_KEY, &keymap->control_map}, 79 {B_OPTION_KEY, &keymap->option_map}, 80 {B_OPTION_KEY | B_SHIFT_KEY, &keymap->option_shift_map}, 81 {B_OPTION_KEY | B_CAPS_LOCK, &keymap->option_caps_map}, 82 {B_OPTION_KEY | B_SHIFT_KEY | B_CAPS_LOCK, 83 &keymap->option_caps_shift_map} 84 }; 85 86 for (auto p = tables.begin(); p != tables.end(); p++) { 87 const uint32 modifiers = (*p).first; 88 const int (*table)[128] = (*p).second; 89 90 // Test, for every keycode, that the result from BKeymap::GetChars() 91 // matches what we find in our our own copy of the keymap 92 for (uint32 keycode = 0; keycode < 128; keycode++) { 93 char* mapChars = &charArray[(*table)[keycode]]; 94 95 // If the keycode isn't mapped, try again without the Option key 96 if (*mapChars <= 0 && (modifiers & B_OPTION_KEY) != 0) { 97 int newOffset = (*tables[modifiers & ~B_OPTION_KEY])[keycode]; 98 if (newOffset >= 0) 99 mapChars = &charArray[newOffset]; 100 } 101 102 char* chars; 103 int32 numBytes; 104 fCurrentKeymap.GetChars(keycode, modifiers, 0, &chars, &numBytes); 105 106 CPPUNIT_ASSERT(*mapChars <= 0 || chars != NULL); 107 CPPUNIT_ASSERT_EQUAL(*mapChars, numBytes); 108 CPPUNIT_ASSERT(strncmp(chars, mapChars + 1, numBytes) == 0); 109 } 110 } 111 112 delete keymap; 113 delete[] charArray; 114 } 115 116 117 /* static */ void 118 KeymapTest::AddTests(BTestSuite& parent) 119 { 120 CppUnit::TestSuite& suite = *new CppUnit::TestSuite("KeymapTest"); 121 122 suite.addTest(new CppUnit::TestCaller<KeymapTest>( 123 "KeymapTest::TestEquals", &KeymapTest::TestEquals)); 124 suite.addTest(new CppUnit::TestCaller<KeymapTest>( 125 "KeymapTest::TestAssignment", &KeymapTest::TestAssignment)); 126 suite.addTest(new CppUnit::TestCaller<KeymapTest>( 127 "KeymapTest::TestGetChars", &KeymapTest::TestGetChars)); 128 129 parent.addTest("KeymapTest", &suite); 130 } 131