#include "term_api.h" #include #include #include /* A feed that returns false must not move the cursor or change a cell. */ static void expect_unchanged(struct term *t, int x, int y, uint32_t cp) { assert(tt_cursor_x(t) == x); assert(tt_cursor_y(t) == y); assert(tt_cell(t, 0, 0)->text == cp); } static void test_feed_unknown_flag(void) { struct term *t = tt_new(10, 3); assert(t); assert(term_feed(t, "abc", 3, 0)); expect_unchanged(t, 3, 0, 'a'); assert(!term_feed(t, "xy", 2, 1u << 1)); expect_unchanged(t, 3, 0, 'a'); assert(!term_feed(t, "xy", 2, TERM_FEED_ONLCR | (1u << 4))); expect_unchanged(t, 3, 0, 'a'); assert(!term_feed(t, "xy", 2, 1u << 31)); expect_unchanged(t, 3, 0, 'a'); /* Unknown bits are rejected even when there are no bytes. */ assert(!term_feed(t, "", 0, 1u << 1)); assert(term_feed(t, "\nz", 2, TERM_FEED_ONLCR)); assert(tt_cursor_x(t) == 1); assert(tt_cursor_y(t) == 1); term_free(t); } static void test_feed_null_buffer(void) { struct term *t = tt_new(10, 3); assert(t); assert(term_feed(t, "abc", 3, 0)); assert(!term_feed(t, NULL, 1, 0)); expect_unchanged(t, 3, 0, 'a'); assert(!term_feed(t, NULL, 4096, TERM_FEED_ONLCR)); expect_unchanged(t, 3, 0, 'a'); /* A zero length is a no-op, so a NULL buffer is fine. */ assert(term_feed(t, NULL, 0, 0)); assert(term_feed(t, "", 0, TERM_FEED_ONLCR)); expect_unchanged(t, 3, 0, 'a'); assert(!term_feed(NULL, "a", 1, 0)); assert(!term_feed(NULL, NULL, 0, 0)); term_free(t); } static void test_new_rejects_bad_options(void) { struct term_options opt; memset(&opt, 0, sizeof(opt)); opt.size.x = -1; assert(!term_new(&opt)); memset(&opt, 0, sizeof(opt)); opt.size.y = -1; assert(!term_new(&opt)); memset(&opt, 0, sizeof(opt)); opt.size.x = TERM_MAX_COLS + 1; assert(!term_new(&opt)); memset(&opt, 0, sizeof(opt)); opt.scrollback = -1; assert(!term_new(&opt)); memset(&opt, 0, sizeof(opt)); opt.cursor_style = (enum term_cursor_style)3; assert(!term_new(&opt)); memset(&opt, 0, sizeof(opt)); opt.cursor_style = (enum term_cursor_style)-1; assert(!term_new(&opt)); } static void test_new_accepts_defaults(void) { struct term_options opt; memset(&opt, 0, sizeof(opt)); struct term *t = term_new(&opt); assert(t); assert(tt_cols(t) == 80); assert(tt_rows(t) == 24); assert(term_cursor(t).style == TERM_CURSOR_BLOCK); term_free(t); memset(&opt, 0, sizeof(opt)); opt.size.x = TERM_MAX_COLS; opt.size.y = 1; opt.cursor_style = TERM_CURSOR_BAR; t = term_new(&opt); assert(t); assert(tt_cols(t) == TERM_MAX_COLS); assert(tt_rows(t) == 1); assert(term_cursor(t).style == TERM_CURSOR_BAR); term_free(t); } static void test_resize_rejects_too_wide(void) { struct term *t = tt_new(10, 3); assert(t); assert(term_feed(t, "abc", 3, 0)); assert(!tt_resize(t, TERM_MAX_COLS + 1, 3)); assert(tt_cols(t) == 10); assert(tt_rows(t) == 3); expect_unchanged(t, 3, 0, 'a'); assert(!tt_resize(t, 10, 0)); assert(!tt_resize(t, 0, 3)); assert(tt_cols(t) == 10); assert(tt_rows(t) == 3); assert(tt_resize(t, TERM_MAX_COLS, 3)); assert(tt_cols(t) == TERM_MAX_COLS); assert(tt_rows(t) == 3); term_free(t); } int main(void) { test_feed_unknown_flag(); test_feed_null_buffer(); test_new_rejects_bad_options(); test_new_accepts_defaults(); test_resize_rejects_too_wide(); return 0; }