summaryrefslogtreecommitdiff
path: root/test/keyboard.c
diff options
context:
space:
mode:
authorAlbert Cervin <albert@acervin.com>2023-01-26 13:07:07 +0100
committerAlbert Cervin <albert@acervin.com>2023-01-26 13:07:07 +0100
commite65158a0326108d1fc724ee683b7fa900ef2671a (patch)
tree9bad30b377a326e0d0e3101c4f96228ae7a41673 /test/keyboard.c
parent9a2b138a03e27d0f04101fe6ae3977d79518c513 (diff)
downloaddged-e65158a0326108d1fc724ee683b7fa900ef2671a.tar.gz
dged-e65158a0326108d1fc724ee683b7fa900ef2671a.tar.xz
dged-e65158a0326108d1fc724ee683b7fa900ef2671a.zip
More tests and documentation
Also, split out platform-specific parts and add mocks for tests.
Diffstat (limited to 'test/keyboard.c')
-rw-r--r--test/keyboard.c208
1 files changed, 208 insertions, 0 deletions
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 <stdlib.h>
+#include <string.h>
+
+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);
+}