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
KeymapTest()21 KeymapTest::KeymapTest()
22 {
23 fCurrentKeymap.SetToCurrent();
24 fDefaultKeymap.SetToDefault();
25 }
26
27
~KeymapTest()28 KeymapTest::~KeymapTest()
29 {
30 }
31
32
33 void
TestEquals()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
TestAssignment()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
TestGetChars()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 typedef std::map<uint32, int32(*)[128]> table_map_t;
74 table_map_t tables;
75 tables[0] = &keymap->normal_map;
76 tables[B_SHIFT_KEY] = &keymap->shift_map;
77 tables[B_CAPS_LOCK] = &keymap->caps_map;
78 tables[B_CAPS_LOCK | B_SHIFT_KEY] = &keymap->caps_shift_map;
79 tables[B_CONTROL_KEY] = &keymap->control_map;
80 tables[B_OPTION_KEY] = &keymap->option_map;
81 tables[B_OPTION_KEY | B_SHIFT_KEY] = &keymap->option_shift_map;
82 tables[B_OPTION_KEY | B_CAPS_LOCK] = &keymap->option_caps_map;
83 tables[B_OPTION_KEY | B_SHIFT_KEY | B_CAPS_LOCK] =
84 &keymap->option_caps_shift_map;
85
86 for (table_map_t::const_iterator p = tables.begin();
87 p != tables.end(); p++) {
88 const uint32 modifiers = (*p).first;
89 const int32(*table)[128] = (*p).second;
90
91 // Test, for every keycode, that the result from BKeymap::GetChars()
92 // matches what we find in our our own copy of the keymap
93 for (uint32 keycode = 0; keycode < 128; keycode++) {
94 char* mapChars = &charArray[(*table)[keycode]];
95
96 // If the keycode isn't mapped, try again without the Option key
97 if (*mapChars <= 0 && (modifiers & B_OPTION_KEY) != 0) {
98 int newOffset = (*tables[modifiers & ~B_OPTION_KEY])[keycode];
99 if (newOffset >= 0)
100 mapChars = &charArray[newOffset];
101 }
102
103 char* chars;
104 int32 numBytes;
105 fCurrentKeymap.GetChars(keycode, modifiers, 0, &chars, &numBytes);
106
107 CPPUNIT_ASSERT(*mapChars <= 0 || chars != NULL);
108 CPPUNIT_ASSERT_EQUAL(*mapChars, numBytes);
109 CPPUNIT_ASSERT(strncmp(chars, mapChars + 1, numBytes) == 0);
110 }
111 }
112
113 delete keymap;
114 delete[] charArray;
115 }
116
117
118 /* static */ void
AddTests(BTestSuite & parent)119 KeymapTest::AddTests(BTestSuite& parent)
120 {
121 CppUnit::TestSuite& suite = *new CppUnit::TestSuite("KeymapTest");
122
123 suite.addTest(new CppUnit::TestCaller<KeymapTest>(
124 "KeymapTest::TestEquals", &KeymapTest::TestEquals));
125 suite.addTest(new CppUnit::TestCaller<KeymapTest>(
126 "KeymapTest::TestAssignment", &KeymapTest::TestAssignment));
127 suite.addTest(new CppUnit::TestCaller<KeymapTest>(
128 "KeymapTest::TestGetChars", &KeymapTest::TestGetChars));
129
130 parent.addTest("KeymapTest", &suite);
131 }
132