#define mu_assert(message, test) \ do { \ if (!(test)) { \ return message; \ } \ } while (0) #define RED "\033[0;31m" #define GREEN "\033[0;32m" #define NC "\033[0m" enum ASSERT_TYPES { UINT, INT }; #define BUFF_SIZE 1024 char buffer[BUFF_SIZE]; #define ASSERT_EQ(type, actual, expected) \ do { \ if (actual != expected) { \ switch (type) { \ case UINT: \ snprintf(buffer, BUFF_SIZE, "\nline %d\nvar %s\nactual = %u\nexpected = %u\n", __LINE__, #actual, actual, expected); \ break; \ case INT: \ snprintf(buffer, BUFF_SIZE, "\nline %d\nvar %s\nactual = %d\nexpected = %d\n", __LINE__, #actual, actual, expected); \ break; \ default: \ snprintf(buffer, BUFF_SIZE, "\nline %d\nunsupported ASSERT_EQ type\n", __LINE__); \ break; \ } \ printf("%s\n", buffer); \ passed = false; \ all_passed = false; \ } \ } while (0) #include <stdio.h> #include <stdint.h> #include <stddef.h> #include <stdbool.h> #include <string.h> #define MATRIX_ROWS 2 #define MATRIX_COLS 10 #define LAYOUT_test( \ k09, k08, k07, k06, k05, k04, k03, k02, k01, k00, \ k19, k18, k17, k16, k15, k14, k13, k12, k11, k10 \ ) { \ { k00, k01, k02, k03, k04, k05, k06, k07, k08, k09}, \ { k10, k11, k12, k13, k14, k15, k16, k17, k18, k19}, \ } #define PROGMEM #define memcpy_P memcpy const struct Chord* pgm_read_word(const struct Chord* const* chord) {return *chord;} typedef struct { uint8_t col; uint8_t row; } keypos_t; typedef struct { keypos_t key; bool pressed; uint16_t time; } keyevent_t; typedef struct { bool interrupted :1; bool reserved2 :1; bool reserved1 :1; bool reserved0 :1; uint8_t count :4; } tap_t; typedef struct { keyevent_t event; tap_t tap; } keyrecord_t; keyrecord_t pressed = {{{0,0},true,0}, {0,0,0,0,0}}; keyrecord_t depressed = {{{0,0},false,0}, {0,0,0,0,0}}; enum keycodes { KC_NO, KC_TILDE, KC_GRAVE, KC_EXCLAIM, KC_1, KC_AT, KC_2, KC_HASH, KC_3, KC_DOLLAR, KC_4, KC_PERCENT, KC_5, KC_CIRCUMFLEX, KC_6, KC_AMPERSAND, KC_7, KC_ASTERISK, KC_8, KC_LEFT_PAREN, KC_9, KC_RIGHT_PAREN, KC_0, KC_UNDERSCORE, KC_MINUS, KC_PLUS, KC_EQUAL, KC_LEFT_CURLY_BRACE, KC_LBRACKET, KC_RIGHT_CURLY_BRACE, KC_RBRACKET, KC_PIPE, KC_BSLASH, KC_COLON, KC_SCOLON, KC_DOUBLE_QUOTE, KC_QUOTE, KC_LEFT_ANGLE_BRACKET, KC_COMMA, KC_RIGHT_ANGLE_BRACKET, KC_DOT, KC_QUESTION, KC_SLASH, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_ESC, KC_LSFT, KC_LCTL, KC_LGUI, KC_LALT, KC_RALT, KC_RCTL, KC_RGUI, KC_RSFT, KC_TAB, KC_DEL, KC_INS, KC_BSPC, KC_ENTER, KC_SPACE, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT, SAFE_RANGE }; #define HISTORY 20 int16_t current_time; uint8_t keyboard_history[HISTORY][SAFE_RANGE-1]; int16_t time_history[HISTORY]; uint8_t history_index; void register_code(int16_t keycode) { history_index++; for (int j = 0; j < SAFE_RANGE-1; j++) { keyboard_history[history_index][j] = keyboard_history[history_index-1][j]; } keyboard_history[history_index][keycode] = 1; time_history[history_index] = current_time; }; void unregister_code(int16_t keycode) { history_index++; for (int j = 0; j < SAFE_RANGE-1; j++) { keyboard_history[history_index][j] = keyboard_history[history_index-1][j]; } keyboard_history[history_index][keycode] = 0; time_history[history_index] = current_time; }; void send_keyboard_report(void) { /*still don't know what this does*/ }; void matrix_scan_user (void); void wait_ms(uint16_t ms) { current_time += ms; }; uint16_t timer_read(void) { uint16_t result = current_time; return result; }; uint16_t timer_elapsed(uint16_t timer) { uint16_t result = current_time - timer; return result; }; void layer_move(int16_t layer) { /*ignoring for now*/ }; void clear_keyboard(void) { history_index++; for (int j = 0; j < SAFE_RANGE-1; j++) { keyboard_history[history_index][j] = 0; } time_history[history_index] = current_time; }; void reset_keyboard(void) { /*ignoring for now*/ }; void pause_ms(uint16_t ms) { for (int i = 0; i < ms; i++) { current_time++; matrix_scan_user(); } }; #define TEST(name) \ do { \ printf("%s\n", name); \ passed = true; \ do { \ uint8_t clear_state = ACTIVATED; \ struct Chord clear_chord PROGMEM = {0, QWERTY, &clear_state, NULL, 0, 0, clear}; \ clear_chord.function(&clear_chord); \ } while (0); \ current_time = 0; \ history_index = 0; \ for (int j = 0; j < SAFE_RANGE-1; j++) { \ keyboard_history[0][j] = 0; \ } \ time_history[0] = 0; \ for (int i = 1; i < HISTORY; i++) { \ for (int j = 0; j < SAFE_RANGE-1; j++) { \ keyboard_history[i][j] = -1; \ } \ time_history[i] = -1; \ } #define END_TEST \ if (passed) { \ printf(GREEN"PASSED"NC"\n"); \ } else { \ printf(RED"FAILED"NC"\n"); \ } \ } while(0); #define MAIN \ int main(int argc, char **argv) { \ bool passed = true; \ bool all_passed = true; #define END \ printf("\n"); \ if (all_passed) { \ printf(GREEN"ALL TESTS PASSED"NC"\n"); \ } else { \ printf(RED"TESTS FAILED"NC"\n"); \ } \ return 1 - all_passed; \ }