From e65158a0326108d1fc724ee683b7fa900ef2671a Mon Sep 17 00:00:00 2001 From: Albert Cervin Date: Thu, 26 Jan 2023 13:07:07 +0100 Subject: More tests and documentation Also, split out platform-specific parts and add mocks for tests. --- test/keyboard.c | 208 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 208 insertions(+) create mode 100644 test/keyboard.c (limited to 'test/keyboard.c') diff --git a/test/keyboard.c b/test/keyboard.c new file mode 100644 index 0000000..b85c4ad --- /dev/null +++ b/test/keyboard.c @@ -0,0 +1,208 @@ +#include "assert.h" +#include "fake-reactor.h" +#include "test.h" + +#include "keyboard.h" +#include "unistd.h" +#include +#include + +struct call_count { + uint32_t poll; + uint32_t reg; + uint32_t unreg; +}; + +bool fake_poll(void *userdata, uint32_t ev_id) { + if (userdata != NULL) { + struct call_count *cc = (struct call_count *)userdata; + ++cc->poll; + } + return true; +} +uint32_t fake_register_interest(void *userdata, int fd, + enum interest interest) { + if (userdata != NULL) { + struct call_count *cc = (struct call_count *)userdata; + ++cc->reg; + } + return 0; +} + +void fake_unregister_interest(void *userdata, uint32_t ev_id) { + if (userdata != NULL) { + struct call_count *cc = (struct call_count *)userdata; + ++cc->unreg; + } +} + +struct fake_keyboard { + struct keyboard inner; + struct reactor *reactor; + int writefd; +}; + +struct fake_keyboard create_fake_keyboard(struct fake_reactor_impl *reactor) { + struct reactor *r = fake_reactor_create(reactor); + + int pipefd[2]; + int res = pipe(pipefd); + ASSERT(res == 0, "Failed to create a pipe?"); + + struct keyboard k = keyboard_create_fd(r, pipefd[0]); + + return (struct fake_keyboard){ + .inner = k, + .reactor = r, + .writefd = pipefd[1], + }; +} + +void fake_keyboard_write(struct fake_keyboard *kbd, const char *s) { + write(kbd->writefd, s, strlen(s)); +} + +void fake_keyboard_close_write(struct fake_keyboard *kbd) { + close(kbd->writefd); +} + +void fake_keyboard_destroy(struct fake_keyboard *kbd) { + fake_keyboard_close_write(kbd); +} + +void simple_key() { + struct call_count cc = {0}; + struct fake_reactor_impl fake = { + .poll_event = fake_poll, + .register_interest = fake_register_interest, + .unregister_interest = fake_unregister_interest, + .userdata = &cc, + }; + struct fake_keyboard k = create_fake_keyboard(&fake); + ASSERT(cc.reg == 1, "Expected keyboard to register read interest"); + + fake_keyboard_write(&k, "q"); + fake_keyboard_close_write(&k); + + struct keyboard_update upd = keyboard_update(&k.inner, k.reactor, malloc); + + ASSERT(upd.nkeys == 1, "Expected to get 1 key from update"); + ASSERT(cc.poll, "Expected keyboard update to call reactor poll"); + + fake_keyboard_destroy(&k); + free(upd.keys); + free(upd.raw); +} + +void ctrl_key() { + struct fake_reactor_impl fake = { + .poll_event = fake_poll, + .register_interest = fake_register_interest, + .unregister_interest = fake_unregister_interest, + .userdata = NULL, + }; + struct fake_keyboard k = create_fake_keyboard(&fake); + fake_keyboard_write(&k, ""); + fake_keyboard_close_write(&k); + + struct keyboard_update upd = keyboard_update(&k.inner, k.reactor, malloc); + ASSERT(upd.nkeys == 2, "Expected to get 2 keys from update"); + ASSERT(upd.keys[0].mod == Ctrl && upd.keys[0].key == 'H', + "Expected first key to be c-h"); + ASSERT(upd.keys[1].mod == Ctrl && upd.keys[1].key == 'P', + "Expected first key to be c-p"); + + fake_keyboard_destroy(&k); + free(upd.keys); + free(upd.raw); +} + +void meta_key() { + struct fake_reactor_impl fake = { + .poll_event = fake_poll, + .register_interest = fake_register_interest, + .unregister_interest = fake_unregister_interest, + .userdata = NULL, + }; + struct fake_keyboard k = create_fake_keyboard(&fake); + fake_keyboard_write(&k, "d[x"); + fake_keyboard_close_write(&k); + + struct keyboard_update upd = keyboard_update(&k.inner, k.reactor, malloc); + ASSERT(upd.nkeys == 3, "Expected to get 3 keys from update"); + ASSERT(upd.keys[0].mod == Meta && upd.keys[0].key == 'd', + "Expected first key to be m-d"); + ASSERT(upd.keys[1].mod == Meta && upd.keys[1].key == '[', + "Expected second key to be m-["); + ASSERT(upd.keys[2].mod == Meta && upd.keys[2].key == 'x', + "Expected third key to be m-x"); + + fake_keyboard_destroy(&k); + free(upd.keys); + free(upd.raw); +} + +void spec_key() { + struct fake_reactor_impl fake = { + .poll_event = fake_poll, + .register_interest = fake_register_interest, + .unregister_interest = fake_unregister_interest, + .userdata = NULL, + }; + struct fake_keyboard k = create_fake_keyboard(&fake); + fake_keyboard_write(&k, "[6~"); + fake_keyboard_close_write(&k); + + struct keyboard_update upd = keyboard_update(&k.inner, k.reactor, malloc); + ASSERT(upd.nkeys == 2, "Expected to get 2 keys from update"); + ASSERT(upd.keys[0].mod == Spec && upd.keys[0].key == 'A', + "Expected first key to be up arrow"); + ASSERT(upd.keys[1].mod == Spec && upd.keys[1].key == '6', + "Expected second key to be PgDn"); + + fake_keyboard_destroy(&k); + free(upd.keys); + free(upd.raw); +} + +void test_utf8() { + struct fake_reactor_impl fake = { + .poll_event = fake_poll, + .register_interest = fake_register_interest, + .unregister_interest = fake_unregister_interest, + .userdata = NULL, + }; + struct fake_keyboard k = create_fake_keyboard(&fake); + fake_keyboard_write(&k, "🎠"); + fake_keyboard_close_write(&k); + + struct keyboard_update upd = keyboard_update(&k.inner, k.reactor, malloc); + ASSERT(upd.nbytes == 4, "Expected there to be four bytes of raw input"); + ASSERT(upd.nkeys == 1, "Expected to get 1 key from update"); + ASSERT(upd.keys[0].start == 0 && upd.keys[0].end == 4, + "Expected first key to be 4 bytes"); + + fake_keyboard_destroy(&k); + free(upd.keys); + free(upd.raw); +} + +void test_key_equal() { + struct key k1 = {.mod = Ctrl, .key = 'A'}; + ASSERT(key_equal(&k1, &k1), "Expected key to be equal to itself"); + ASSERT(key_equal_char(&k1, Ctrl, 'A'), "Expected key to be c-a"); + + struct key k2 = {.mod = None, .key = 'A'}; + ASSERT(!key_equal(&k1, &k2), "Expected key to not be equal to different key"); + ASSERT(!key_equal_char(&k2, Spec, 'A'), + "Expected yet another different key to not be the same"); +} + +void run_keyboard_tests() { + run_test(simple_key); + run_test(ctrl_key); + run_test(meta_key); + run_test(spec_key); + run_test(test_utf8); + run_test(test_key_equal); +} -- cgit v1.2.3