#include #include #include "asdf_arch.h" #include "unity.h" #include "asdf.h" #include "asdf_ascii.h" #include "asdf_modifiers.h" #include "asdf_keymap_table.h" #include "test_asdf_keymap_defs.h" #include "asdf_keymaps.h" #include "test_asdf_lib.h" #define TESTALPHA 'a' #define TESTNUM '2' #define TESTKEYMAP_TAG PLAIN_MATRIX_1 #define NUM_DIPSWITCHES 4 static const FLASH asdf_keycode_t test_PLAIN_matrix[TEST_NUM_ROWS][TEST_NUM_COLS] = ASDF_TEST_PLAIN_MAP; static const FLASH asdf_keycode_t test_SHIFT_matrix[TEST_NUM_ROWS][TEST_NUM_COLS] = ASDF_TEST_SHIFT_MAP; static const FLASH asdf_keycode_t test_CAPS_matrix[TEST_NUM_ROWS][TEST_NUM_COLS] = ASDF_TEST_CAPS_MAP; static const FLASH asdf_keycode_t test_CTRL_matrix[TEST_NUM_ROWS][TEST_NUM_COLS] = ASDF_TEST_CTRL_MAP; static const FLASH asdf_keycode_t test2_PLAIN_matrix[TEST_NUM_ROWS][TEST_NUM_COLS] = ASDF_TEST2_PLAIN_MAP; static const FLASH asdf_keycode_t test2_SHIFT_matrix[TEST_NUM_ROWS][TEST_NUM_COLS] = ASDF_TEST2_SHIFT_MAP; static const FLASH asdf_keycode_t test2_CAPS_matrix[TEST_NUM_ROWS][TEST_NUM_COLS] = ASDF_TEST2_CAPS_MAP; static const FLASH asdf_keycode_t test2_CTRL_matrix[TEST_NUM_ROWS][TEST_NUM_COLS] = ASDF_TEST2_CTRL_MAP; // row: row number // col: column number // keymap_name: id of the file defining the matrix to be used. // defnum: numerical order of the file defining the matrix to be used. // mapindex: matrix of keymaps to be used (contains all modifier maps for the matrix). // modifier_name: name of the modifier to be accessed within the map. #define TESTMAP(row, col, keymap_name, defnum, mapindex, modifier_name) \ do { \ asdf_keymaps_select(ASDF_##mapindex##_MAP_INDEX); \ asdf_keycode_t expected = keymap_name##_##modifier_name##_matrix[(row)][(col)]; \ asdf_keycode_t result = asdf_keymaps_get_code((row), (col), MOD_##modifier_name##_MAP); \ asdf_keycode_t map_id = asdf_keymaps_get_code(0, 0, MOD_##modifier_name##_MAP); \ TEST_ASSERT_EQUAL_INT32((uint32_t) expected, (uint32_t) result); \ TEST_ASSERT_EQUAL_INT32((uint32_t) modifier_name##_MATRIX_##defnum, (uint32_t) map_id); \ } while (0) #define TEST0MAP(row, col, modifier) TESTMAP(row, col, test, 1, TEST_PLAIN, modifier) #define TEST1MAP(row, col, modifier) TESTMAP(row, col, test, 1, TEST_CAPS, modifier) #define TEST2MAP(row, col, modifier) TESTMAP(row, col, test2, 2, TEST2_PLAIN, modifier) #define TEST3MAP(row, col, modifier) TESTMAP(row, col, test2, 2, TEST2_CAPS, modifier) #define TEST_VALID_CODE(position) \ do { \ coord_t pos = position; \ TEST_ASSERT_FALSE(pos.row == -1); \ TEST_ASSERT_FALSE(pos.col == -1); \ } while (0) // check against the "test" keymaps #define TEST0PLAIN(row, col) TEST0MAP((row), (col), PLAIN) #define TEST0SHIFT(row, col) TEST0MAP((row), (col), SHIFT) #define TEST0CAPS(row, col) TEST0MAP((row), (col), CAPS) #define TEST0CTRL(row, col) TEST0MAP((row), (col), CTRL) #define TEST1PLAIN(row, col) TEST1MAP((row), (col), PLAIN) #define TEST1SHIFT(row, col) TEST1MAP((row), (col), SHIFT) #define TEST1CAPS(row, col) TEST1MAP((row), (col), CAPS) #define TEST1CTRL(row, col) TEST1MAP((row), (col), CTRL) // check against the "test2" keymaps #define TEST2PLAIN(row, col) TEST2MAP((row), (col), PLAIN) #define TEST2SHIFT(row, col) TEST2MAP((row), (col), SHIFT) #define TEST2CAPS(row, col) TEST2MAP((row), (col), CAPS) #define TEST2CTRL(row, col) TEST2MAP((row), (col), CTRL) #define TEST3PLAIN(row, col) TEST3MAP((row), (col), PLAIN) #define TEST3SHIFT(row, col) TEST3MAP((row), (col), SHIFT) #define TEST3CAPS(row, col) TEST3MAP((row), (col), CAPS) #define TEST3CTRL(row, col) TEST3MAP((row), (col), CTRL) typedef struct { int32_t row; int32_t col; } coord_t; // The dip switch positions do not need to reflect real hardware. These // positions reflect the organization of the test keymaps, to ensure that tools // used to place the codes are functioning and are being properly used. // keymap coordinates for special functions static coord_t alpha_sample; static coord_t num_sample; static coord_t keymap_tag; coord_t *find_code(asdf_keycode_t code) { uint32_t done = 0; static coord_t location = { .row = -1, .col = -1 }; for (uint32_t row = 0; !done && (row < TEST_NUM_ROWS); row++) { for (uint32_t col = 0; !done && (col < TEST_NUM_COLS); col++) { if (test_PLAIN_matrix[row][col] == code) { done = 1; location.row = row; location.col = col; } } } return &location; } void setUp(void) { coord_t *temp; asdf_keymaps_init(); asdf_keymaps_select(ASDF_TEST_PLAIN_MAP_INDEX); temp = find_code(TESTALPHA); alpha_sample = *temp; temp = find_code(TESTNUM); num_sample = *temp; temp = find_code(TESTKEYMAP_TAG); keymap_tag = *temp; } void tearDown(void) {} // set a keymap using the asdf_keymap dip-switch functions void complicated_set_keymap(uint8_t mapnum) { void (*set_funcs[])(void) = { &asdf_keymaps_map_select_0_set, &asdf_keymaps_map_select_1_set, &asdf_keymaps_map_select_2_set, &asdf_keymaps_map_select_3_set }; void (*clr_funcs[])(void) = { &asdf_keymaps_map_select_0_clear, &asdf_keymaps_map_select_1_clear, &asdf_keymaps_map_select_2_clear, &asdf_keymaps_map_select_3_clear }; for (uint8_t i = 0; i < NUM_DIPSWITCHES; i++) { if (mapnum & 1) { set_funcs[i](); } else { clr_funcs[i](); } mapnum >>= 1; } } // dummy function, to resolve reference in keymap hook initialization. asdf_cols_t asdf_arch_read_row(uint8_t row) { return (asdf_cols_t)(row + 1); } void test_chars_are_in_map(void) { TEST_VALID_CODE(alpha_sample); TEST_VALID_CODE(num_sample); } void keymap0_plain_gives_plain_values(void) { asdf_keymaps_select(ASDF_TEST_PLAIN_MAP_INDEX); TEST0PLAIN(alpha_sample.row, alpha_sample.col); TEST0PLAIN(num_sample.row, num_sample.col); } void keymap0_shift_gives_shift_values(void) { TEST0SHIFT(alpha_sample.row, alpha_sample.col); TEST0SHIFT(num_sample.row, num_sample.col); } void keymap0_caps_gives_caps_values(void) { TEST0CAPS(alpha_sample.row, alpha_sample.col); TEST0CAPS(num_sample.row, num_sample.col); } void keymap0_ctrl_gives_ctrl_values(void) { TEST0CTRL(alpha_sample.row, alpha_sample.col); TEST0CTRL(num_sample.row, num_sample.col); } void keymap2_plain_gives_plain_values(void) { TEST2PLAIN(alpha_sample.row, alpha_sample.col); TEST2PLAIN(num_sample.row, num_sample.col); } void keymap2_shift_gives_shift_values(void) { TEST2SHIFT(alpha_sample.row, alpha_sample.col); TEST2SHIFT(num_sample.row, num_sample.col); } void keymap2_caps_gives_caps_values(void) { TEST2CAPS(alpha_sample.row, alpha_sample.col); TEST2CAPS(num_sample.row, num_sample.col); } void keymap2_ctrl_gives_ctrl_values(void) { TEST2CTRL(alpha_sample.row, alpha_sample.col); TEST2CTRL(num_sample.row, num_sample.col); } void keymap1_capsmap_plain_maps_to_caps(void) { // set bit 0 to select keymap 1 asdf_keymaps_map_select_0_set(); TEST1CAPS(alpha_sample.row, alpha_sample.col); TEST1CAPS(num_sample.row, num_sample.col); } void dip_switch_codes_are_in_last_row_test1_map(void) { coord_t dip_switches[NUM_DIPSWITCHES] = { { .row = (TEST_NUM_ROWS - 1), .col = 0 }, { .row = (TEST_NUM_ROWS - 1), .col = 1 }, { .row = (TEST_NUM_ROWS - 1), .col = 2 }, { .row = (TEST_NUM_ROWS - 1), .col = 3 } }; for (uint8_t i = 0; i < NUM_DIPSWITCHES; i++) { asdf_keycode_t code = asdf_keymaps_get_code(dip_switches[i].row, dip_switches[i].col, ASDF_TEST_PLAIN_MAP_INDEX); TEST_ASSERT_EQUAL_INT32((uint32_t) code, (uint32_t)(ACTION_MAPSEL_0 + i)); } } void dip_switch_codes_are_in_last_row_test2_map(void) { coord_t dip_switches[NUM_DIPSWITCHES] = { { .row = (TEST_NUM_ROWS - 1), .col = 0 }, { .row = (TEST_NUM_ROWS - 1), .col = 1 }, { .row = (TEST_NUM_ROWS - 1), .col = 2 }, { .row = (TEST_NUM_ROWS - 1), .col = 3 } }; for (uint8_t i = 0; i < NUM_DIPSWITCHES; i++) { asdf_keycode_t code = asdf_keymaps_get_code(dip_switches[i].row, dip_switches[i].col, ASDF_TEST2_PLAIN_MAP_INDEX); TEST_ASSERT_EQUAL_INT32((uint32_t) code, (uint32_t)(ACTION_MAPSEL_0 + i)); } } void dip_switch_properly_sets_bits(void) { for (uint8_t i = 0; i < ASDF_NUM_KEYMAPS; i++) { asdf_keycode_t expected; asdf_keycode_t result; asdf_keymaps_select(i); expected = asdf_keymaps_get_code(keymap_tag.row, keymap_tag.col, MOD_PLAIN_MAP); // set all keymap bits to '0' asdf_keymaps_select(0); complicated_set_keymap(i); result = asdf_keymaps_get_code(keymap_tag.row, keymap_tag.col, MOD_PLAIN_MAP); TEST_ASSERT_EQUAL_INT32(expected, result); } } void dip_switch_properly_clears_bits(void) { uint8_t mask = 0; uint8_t next = 1; // calculate word with most 1's less than (or equal to) ASDF_NUM_KEYMAPS while (next < ASDF_NUM_KEYMAPS) { mask = next; next = (next << 1) | 1; } for (uint8_t i = 0; i < ASDF_NUM_KEYMAPS; i++) { asdf_keycode_t expected; asdf_keycode_t result; asdf_keymaps_select(i); expected = asdf_keymaps_get_code(keymap_tag.row, keymap_tag.col, MOD_PLAIN_MAP); // set as many keymap bits to '1' as possible. asdf_keymaps_select(mask); complicated_set_keymap(i); result = asdf_keymaps_get_code(keymap_tag.row, keymap_tag.col, MOD_PLAIN_MAP); TEST_ASSERT_EQUAL_INT32(expected, result); } } void dip_switch_invalid_keymap_has_no_effect(void) { asdf_keycode_t map_id; // First, assert that changing to matrix 2 works: asdf_keymaps_select(ASDF_TEST2_PLAIN_MAP_INDEX); map_id = asdf_keymaps_get_code(keymap_tag.row, keymap_tag.col, MOD_PLAIN_MAP); TEST_ASSERT_EQUAL_INT32(PLAIN_MATRIX_2, map_id); // assert that resetting keymap to 0 works: asdf_keymaps_select(0); map_id = asdf_keymaps_get_code(keymap_tag.row, keymap_tag.col, MOD_PLAIN_MAP); TEST_ASSERT_EQUAL_INT32(PLAIN_MATRIX_1, map_id); // selecting one above the highest keymap should have no effect asdf_keymaps_select(ASDF_NUM_KEYMAPS); map_id = asdf_keymaps_get_code(keymap_tag.row, keymap_tag.col, MOD_PLAIN_MAP); TEST_ASSERT_EQUAL_INT32(PLAIN_MATRIX_1, map_id); // selecting the highest possible keymap should have no effect asdf_keymaps_select(UINT8_MAX); map_id = asdf_keymaps_get_code(keymap_tag.row, keymap_tag.col, MOD_PLAIN_MAP); TEST_ASSERT_EQUAL_INT32(PLAIN_MATRIX_1, map_id); } int main(void) { UNITY_BEGIN(); RUN_TEST(test_chars_are_in_map); RUN_TEST(keymap0_plain_gives_plain_values); RUN_TEST(keymap0_shift_gives_shift_values); RUN_TEST(keymap0_caps_gives_caps_values); RUN_TEST(keymap0_ctrl_gives_ctrl_values); RUN_TEST(keymap2_plain_gives_plain_values); RUN_TEST(keymap2_shift_gives_shift_values); RUN_TEST(keymap2_caps_gives_caps_values); RUN_TEST(keymap2_ctrl_gives_ctrl_values); RUN_TEST(keymap1_capsmap_plain_maps_to_caps); RUN_TEST(dip_switch_codes_are_in_last_row_test1_map); RUN_TEST(dip_switch_codes_are_in_last_row_test2_map); RUN_TEST(dip_switch_properly_clears_bits); RUN_TEST(dip_switch_properly_sets_bits); RUN_TEST(dip_switch_invalid_keymap_has_no_effect); return UNITY_END(); }