diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/command.c | 22 | ||||
| -rw-r--r-- | test/fake-reactor.c | 47 | ||||
| -rw-r--r-- | test/fake-reactor.h | 13 | ||||
| -rw-r--r-- | test/keyboard.c | 208 | ||||
| -rw-r--r-- | test/main.c | 17 | ||||
| -rw-r--r-- | test/test.h | 1 |
6 files changed, 307 insertions, 1 deletions
diff --git a/test/command.c b/test/command.c index 738f5f9..be5fffc 100644 --- a/test/command.c +++ b/test/command.c @@ -72,8 +72,30 @@ void test_lookup_command() { "Expected the found function to have the correct name"); } +int32_t failing_command(struct command_ctx ctx, int argc, const char *argv[]) { + return 100; +} + +void test_execute_command() { + struct commands cmds = single_fake_command("fake"); + struct command *cmd = lookup_command(&cmds, "fake"); + + int32_t res = execute_command(cmd, &cmds, NULL, NULL, 0, NULL); + ASSERT(res == 0, "Expected to be able to execute command successfully"); + + register_command(&cmds, (struct command){ + .fn = failing_command, + .name = "fejl", + .userdata = NULL, + }); + struct command *fail_cmd = lookup_command(&cmds, "fejl"); + int32_t res2 = execute_command(fail_cmd, &cmds, NULL, NULL, 0, NULL); + ASSERT(res2 != 0, "Expected failing command to fail"); +} + void run_command_tests() { run_test(test_command_registry_create); run_test(test_register_command); run_test(test_lookup_command); + run_test(test_execute_command); } diff --git a/test/fake-reactor.c b/test/fake-reactor.c new file mode 100644 index 0000000..aafe8a3 --- /dev/null +++ b/test/fake-reactor.c @@ -0,0 +1,47 @@ +#include "fake-reactor.h" +#include <stdlib.h> + +struct reactor { + struct fake_reactor_impl *impl; +}; + +struct reactor *reactor_create() { + return (struct reactor *)calloc(1, sizeof(struct reactor)); +} + +void reactor_destroy(struct reactor *reactor) { free(reactor); } + +void reactor_update(struct reactor *reactor) {} +bool reactor_poll_event(struct reactor *reactor, uint32_t ev_id) { + if (reactor->impl != NULL) { + return reactor->impl->poll_event(reactor->impl->userdata, ev_id); + } else { + return false; + } +} + +uint32_t reactor_register_interest(struct reactor *reactor, int fd, + enum interest interest) { + if (reactor->impl != NULL) { + return reactor->impl->register_interest(reactor->impl->userdata, fd, + interest); + } else { + return 0; + } +} + +void reactor_unregister_interest(struct reactor *reactor, uint32_t ev_id) { + if (reactor->impl != NULL) { + return reactor->impl->unregister_interest(reactor->impl->userdata, ev_id); + } +} + +struct reactor *fake_reactor_create(struct fake_reactor_impl *impl) { + struct reactor *r = reactor_create(); + set_reactor_impl(r, impl); + return r; +} + +void set_reactor_impl(struct reactor *reactor, struct fake_reactor_impl *impl) { + reactor->impl = impl; +} diff --git a/test/fake-reactor.h b/test/fake-reactor.h new file mode 100644 index 0000000..04d8306 --- /dev/null +++ b/test/fake-reactor.h @@ -0,0 +1,13 @@ +#include "reactor.h" +#include <stdbool.h> +#include <stdint.h> + +struct fake_reactor_impl { + bool (*poll_event)(void *userdata, uint32_t ev_id); + uint32_t (*register_interest)(void *userdata, int fd, enum interest interest); + void (*unregister_interest)(void *userdata, uint32_t ev_id); + void *userdata; +}; + +struct reactor *fake_reactor_create(struct fake_reactor_impl *impl); +void set_reactor_impl(struct reactor *reactor, struct fake_reactor_impl *impl); 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, "[A[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); +} diff --git a/test/main.c b/test/main.c index 8102a58..68241f9 100644 --- a/test/main.c +++ b/test/main.c @@ -1,7 +1,10 @@ #include <locale.h> #include <signal.h> +#include <stdint.h> #include <stdlib.h> +#include <time.h> +#include "bits/time.h" #include "test.h" void handle_abort() { exit(1); } @@ -10,6 +13,9 @@ int main() { setlocale(LC_ALL, ""); signal(SIGABRT, handle_abort); + struct timespec test_begin; + clock_gettime(CLOCK_MONOTONIC, &test_begin); + printf("\nš \x1b[1;36mRunning utf8 tests...\x1b[0m\n"); run_utf8_tests(); @@ -22,6 +28,15 @@ int main() { printf("\nš \x1b[1;36mRunning command tests...\x1b[0m\n"); run_command_tests(); - printf("\nš \x1b[1;32mDone! All tests successful!\x1b[0m\n"); + printf("\nš \x1b[1;36mRunning keyboard tests...\x1b[0m\n"); + run_keyboard_tests(); + + struct timespec elapsed; + clock_gettime(CLOCK_MONOTONIC, &elapsed); + uint64_t elapsed_nanos = + ((uint64_t)elapsed.tv_sec * 1e9 + (uint64_t)elapsed.tv_nsec) - + ((uint64_t)test_begin.tv_sec * 1e9 + (uint64_t)test_begin.tv_nsec); + printf("\nš \x1b[1;32mDone! All tests successful in %.2f ms!\x1b[0m\n", + (double)elapsed_nanos / 1e6); return 0; } diff --git a/test/test.h b/test/test.h index 3fdcd0d..2d9d8af 100644 --- a/test/test.h +++ b/test/test.h @@ -10,3 +10,4 @@ void run_buffer_tests(); void run_utf8_tests(); void run_text_tests(); void run_command_tests(); +void run_keyboard_tests(); |
