xref: /haiku/src/tests/kits/shared/KeymapTest.cpp (revision 3d4c153e172c6e3c6fc3c94213dc5fb040dbb122)
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