#include <stic.h> #include <ctype.h> /* isspace() */ #include <stddef.h> /* NULL */ #include <stdlib.h> /* free() */ #include <string.h> /* memset() strcpy() strdup() */ #include <test-utils.h> #include "../../src/cfg/config.h" #include "../../src/compat/curses.h" #include "../../src/compat/fs_limits.h" #include "../../src/compat/os.h" #include "../../src/engine/abbrevs.h" #include "../../src/engine/keys.h" #include "../../src/engine/mode.h" #include "../../src/modes/cmdline.h" #include "../../src/modes/modes.h" #include "../../src/modes/wk.h" #include "../../src/ui/ui.h" #include "../../src/utils/dynarray.h" #include "../../src/utils/fs.h" #include "../../src/utils/matcher.h" #include "../../src/utils/str.h" #include "../../src/filelist.h" #include "../../src/status.h" static int have_ext_keys(void); static line_stats_t *stats; SETUP_ONCE() { stats = get_line_stats(); try_enable_utf8_locale(); } SETUP() { modes_init(); modcline_enter(CLS_COMMAND, ""); curr_view = &lwin; view_setup(&lwin); char *error; matcher_free(curr_view->manual_filter); assert_non_null(curr_view->manual_filter = matcher_alloc("{filt}", 0, 0, "", &error)); assert_success(filter_set(&curr_view->auto_filter, "auto-filter")); assert_success(filter_set(&curr_view->local_filter.filter, "local-filter")); lwin.list_pos = 0; lwin.list_rows = 2; lwin.dir_entry = dynarray_cextend(NULL, lwin.list_rows*sizeof(*lwin.dir_entry)); lwin.dir_entry[0].name = strdup("\265"); lwin.dir_entry[0].origin = &lwin.curr_dir[0]; lwin.dir_entry[1].name = strdup("root.ext"); lwin.dir_entry[1].origin = &lwin.curr_dir[0]; strcpy(lwin.curr_dir, "tests/fake/tail"); other_view = &rwin; view_setup(&rwin); rwin.list_pos = 0; rwin.list_rows = 1; rwin.dir_entry = dynarray_cextend(NULL, rwin.list_rows*sizeof(*rwin.dir_entry)); rwin.dir_entry[0].name = strdup("otherroot.otherext"); rwin.dir_entry[0].origin = &rwin.curr_dir[0]; strcpy(rwin.curr_dir, "other/dir/othertail"); opt_handlers_setup(); } TEARDOWN() { view_teardown(&lwin); view_teardown(&rwin); (void)vle_keys_exec_timed_out(WK_C_c); vle_keys_reset(); opt_handlers_teardown(); } TEST(backspace_exit) { assert_true(vle_mode_is(CMDLINE_MODE)); assert_wstring_equal(L"", stats->line); (void)vle_keys_exec_timed_out(WK_C_h); assert_true(vle_mode_is(NORMAL_MODE)); assert_wstring_equal(NULL, stats->line); } TEST(backspace_eol) { (void)vle_keys_exec_timed_out(L"abc"); assert_wstring_equal(L"abc", stats->line); (void)vle_keys_exec_timed_out(WK_C_h); assert_wstring_equal(L"ab", stats->line); (void)vle_keys_exec_timed_out(WK_C_h); assert_wstring_equal(L"a", stats->line); (void)vle_keys_exec_timed_out(WK_C_h); assert_wstring_equal(L"", stats->line); } TEST(backspace_not_eol) { (void)vle_keys_exec_timed_out(L"abc"); assert_wstring_equal(L"abc", stats->line); (void)vle_keys_exec_timed_out(WK_C_b); assert_wstring_equal(L"abc", stats->line); (void)vle_keys_exec_timed_out(WK_C_h); assert_wstring_equal(L"ac", stats->line); (void)vle_keys_exec_timed_out(WK_C_h); assert_wstring_equal(L"c", stats->line); (void)vle_keys_exec_timed_out(WK_C_h); assert_wstring_equal(L"c", stats->line); } TEST(right_kill) { (void)vle_keys_exec_timed_out(L"abc"); assert_wstring_equal(L"abc", stats->line); (void)vle_keys_exec_timed_out(WK_C_k); assert_wstring_equal(L"abc", stats->line); (void)vle_keys_exec_timed_out(WK_C_h); (void)vle_keys_exec_timed_out(WK_C_k); assert_wstring_equal(L"ab", stats->line); (void)vle_keys_exec_timed_out(WK_C_a); (void)vle_keys_exec_timed_out(WK_C_k); assert_wstring_equal(L"", stats->line); (void)vle_keys_exec_timed_out(WK_C_k); assert_wstring_equal(L"", stats->line); } TEST(left_kill) { (void)vle_keys_exec_timed_out(L"abc"); assert_wstring_equal(L"abc", stats->line); (void)vle_keys_exec_timed_out(WK_C_b); (void)vle_keys_exec_timed_out(WK_C_b); assert_wstring_equal(L"abc", stats->line); (void)vle_keys_exec_timed_out(WK_C_u); assert_wstring_equal(L"bc", stats->line); (void)vle_keys_exec_timed_out(WK_C_f); (void)vle_keys_exec_timed_out(WK_C_u); assert_wstring_equal(L"c", stats->line); (void)vle_keys_exec_timed_out(WK_C_f); (void)vle_keys_exec_timed_out(WK_C_u); assert_wstring_equal(L"", stats->line); (void)vle_keys_exec_timed_out(WK_C_u); assert_wstring_equal(L"", stats->line); } TEST(moving_cursor) { (void)vle_keys_exec_timed_out(L"abc"); assert_wstring_equal(L"abc", stats->line); (void)vle_keys_exec_timed_out(WK_C_b); assert_int_equal(2, stats->index); (void)vle_keys_exec_timed_out(WK_C_f); assert_int_equal(3, stats->index); (void)vle_keys_exec_timed_out(WK_C_a); assert_int_equal(0, stats->index); (void)vle_keys_exec_timed_out(WK_C_e); assert_int_equal(3, stats->index); #ifdef ENABLE_EXTENDED_KEYS wchar_t keys[2] = { }; keys[0] = K(KEY_LEFT); (void)vle_keys_exec_timed_out(keys); assert_int_equal(2, stats->index); keys[0] = K(KEY_RIGHT); (void)vle_keys_exec_timed_out(keys); assert_int_equal(3, stats->index); keys[0] = K(KEY_HOME); (void)vle_keys_exec_timed_out(keys); assert_int_equal(0, stats->index); keys[0] = K(KEY_END); (void)vle_keys_exec_timed_out(keys); assert_int_equal(3, stats->index); #endif } TEST(word_operations) { (void)vle_keys_exec_timed_out(L"aa bb cc"); assert_wstring_equal(L"aa bb cc", stats->line); /* Fill cfg.word_chars as if it was initialized from isspace() function. */ memset(&cfg.word_chars, 1, sizeof(cfg.word_chars)); cfg.word_chars['\x00'] = 0; cfg.word_chars['\x09'] = 0; cfg.word_chars['\x0a'] = 0; cfg.word_chars['\x0b'] = 0; cfg.word_chars['\x0c'] = 0; cfg.word_chars['\x0d'] = 0; cfg.word_chars['\x20'] = 0; #ifndef __PDCURSES__ (void)vle_keys_exec_timed_out(WK_ESC WK_b); assert_int_equal(6, stats->index); (void)vle_keys_exec_timed_out(WK_ESC WK_b); assert_int_equal(3, stats->index); (void)vle_keys_exec_timed_out(WK_ESC WK_b); assert_int_equal(0, stats->index); (void)vle_keys_exec_timed_out(WK_ESC WK_f); assert_int_equal(2, stats->index); (void)vle_keys_exec_timed_out(WK_ESC WK_f); assert_int_equal(5, stats->index); (void)vle_keys_exec_timed_out(WK_ESC WK_b); assert_int_equal(3, stats->index); (void)vle_keys_exec_timed_out(WK_ESC WK_d); assert_int_equal(3, stats->index); assert_wstring_equal(L"aa cc", stats->line); #else wchar_t keys[2] = { }; keys[0] = K(ALT_B); (void)vle_keys_exec_timed_out(keys); assert_int_equal(6, stats->index); keys[0] = K(ALT_B); (void)vle_keys_exec_timed_out(keys); assert_int_equal(3, stats->index); keys[0] = K(ALT_B); (void)vle_keys_exec_timed_out(keys); assert_int_equal(0, stats->index); keys[0] = K(ALT_F); (void)vle_keys_exec_timed_out(keys); assert_int_equal(2, stats->index); keys[0] = K(ALT_F); (void)vle_keys_exec_timed_out(keys); assert_int_equal(5, stats->index); keys[0] = K(ALT_B); (void)vle_keys_exec_timed_out(keys); assert_int_equal(3, stats->index); keys[0] = K(ALT_D); (void)vle_keys_exec_timed_out(keys); assert_int_equal(3, stats->index); assert_wstring_equal(L"aa cc", stats->line); #endif } TEST(history) { cfg.history_len = 4; assert_success(stats_init(&cfg)); (void)vle_keys_exec_timed_out(L"first"); assert_wstring_equal(L"first", stats->line); (void)vle_keys_exec_timed_out(WK_ESC); (void)vle_keys_exec_timed_out(L":second"); assert_wstring_equal(L"second", stats->line); (void)vle_keys_exec_timed_out(WK_ESC); (void)vle_keys_exec_timed_out(L":third" WK_C_p); assert_wstring_equal(L"second", stats->line); (void)vle_keys_exec_timed_out(WK_C_p); assert_wstring_equal(L"first", stats->line); (void)vle_keys_exec_timed_out(WK_C_p); assert_wstring_equal(L"first", stats->line); (void)vle_keys_exec_timed_out(WK_C_n); assert_wstring_equal(L"second", stats->line); (void)vle_keys_exec_timed_out(WK_C_n); assert_wstring_equal(L"third", stats->line); (void)vle_keys_exec_timed_out(WK_C_n); assert_wstring_equal(L"third", stats->line); hists_resize(0); cfg.history_len = 0; assert_success(stats_reset(&cfg)); } TEST(prefix_history, IF(have_ext_keys)) { const wchar_t up[] = {K(KEY_UP), 0}; const wchar_t down[] = {K(KEY_DOWN), 0}; cfg.history_len = 4; assert_success(stats_init(&cfg)); (void)vle_keys_exec_timed_out(L"first"); assert_wstring_equal(L"first", stats->line); (void)vle_keys_exec_timed_out(WK_ESC); (void)vle_keys_exec_timed_out(L":second"); assert_wstring_equal(L"second", stats->line); (void)vle_keys_exec_timed_out(WK_ESC); (void)vle_keys_exec_timed_out(L":finish"); assert_wstring_equal(L"finish", stats->line); (void)vle_keys_exec_timed_out(WK_ESC); (void)vle_keys_exec_timed_out(L":fi"); assert_wstring_equal(L"fi", stats->line); (void)vle_keys_exec_timed_out(up); assert_wstring_equal(L"finish", stats->line); (void)vle_keys_exec_timed_out(up); assert_wstring_equal(L"first", stats->line); (void)vle_keys_exec_timed_out(down); assert_wstring_equal(L"finish", stats->line); (void)vle_keys_exec_timed_out(down); assert_wstring_equal(L"fi", stats->line); (void)vle_keys_exec_timed_out(down); assert_wstring_equal(L"fi", stats->line); hists_resize(0); cfg.history_len = 0; assert_success(stats_reset(&cfg)); } TEST(value_of_manual_filter_is_pasted) { (void)vle_keys_exec_timed_out(WK_C_x WK_m); assert_wstring_equal(L"filt", stats->line); } TEST(value_of_automatic_filter_is_pasted) { (void)vle_keys_exec_timed_out(WK_C_x WK_a); assert_wstring_equal(L"auto-filter", stats->line); } TEST(value_of_local_filter_is_pasted) { (void)vle_keys_exec_timed_out(WK_C_x WK_EQUALS); assert_wstring_equal(L"local-filter", stats->line); } TEST(last_search_pattern_is_pasted) { /* Emulate proper history initialization (must happen after view * initialization). */ cfg_resize_histories(5); cfg_resize_histories(0); cfg_resize_histories(5); hists_search_save("search-pattern"); (void)vle_keys_exec_timed_out(WK_C_x WK_SLASH); assert_wstring_equal(L"search-pattern", stats->line); cfg_resize_histories(0); } TEST(name_of_current_file_is_pasted) { lwin.list_pos = 1; (void)vle_keys_exec_timed_out(WK_C_x WK_c); assert_wstring_equal(L"root.ext", stats->line); (void)vle_keys_exec_timed_out(WK_SPACE); (void)vle_keys_exec_timed_out(WK_C_x WK_C_x WK_c); assert_wstring_equal(L"root.ext otherroot.otherext", stats->line); } TEST(short_path_of_current_file_is_pasted_in_cv) { char cwd[PATH_MAX + 1]; assert_non_null(get_cwd(cwd, sizeof(cwd))); make_abs_path(lwin.curr_dir, sizeof(lwin.curr_dir), TEST_DATA_PATH, "", cwd); char path[PATH_MAX + 1]; flist_custom_start(&lwin, "test"); make_abs_path(path, sizeof(path), TEST_DATA_PATH, "existing-files/a", cwd); flist_custom_add(&lwin, path); make_abs_path(path, sizeof(path), TEST_DATA_PATH, "existing-files/b", cwd); flist_custom_add(&lwin, path); assert_true(flist_custom_finish(&lwin, CV_REGULAR, 0) == 0); (void)vle_keys_exec_timed_out(WK_C_x WK_c); assert_wstring_equal(L"existing-files/a", stats->line); } TEST(root_is_pasted) { lwin.list_pos = 1; (void)vle_keys_exec_timed_out(WK_C_x WK_r); assert_wstring_equal(L"root", stats->line); (void)vle_keys_exec_timed_out(WK_SPACE); (void)vle_keys_exec_timed_out(WK_C_x WK_C_x WK_r); assert_wstring_equal(L"root otherroot", stats->line); } TEST(extension_is_pasted) { lwin.list_pos = 1; (void)vle_keys_exec_timed_out(WK_C_x WK_e); assert_wstring_equal(L"ext", stats->line); (void)vle_keys_exec_timed_out(WK_SPACE); (void)vle_keys_exec_timed_out(WK_C_x WK_C_x WK_e); assert_wstring_equal(L"ext otherext", stats->line); } TEST(directory_is_pasted) { (void)vle_keys_exec_timed_out(WK_C_x WK_d); assert_wstring_equal(L"tests/fake/tail", stats->line); (void)vle_keys_exec_timed_out(WK_SPACE); (void)vle_keys_exec_timed_out(WK_C_x WK_C_x WK_d); assert_wstring_equal(L"tests/fake/tail other/dir/othertail", stats->line); } TEST(tail_of_current_directory_is_pasted) { (void)vle_keys_exec_timed_out(WK_C_x WK_t); assert_wstring_equal(L"tail", stats->line); (void)vle_keys_exec_timed_out(WK_SPACE); (void)vle_keys_exec_timed_out(WK_C_x WK_C_x WK_t); assert_wstring_equal(L"tail othertail", stats->line); } TEST(broken_utf8_name, IF(utf8_locale)) { (void)vle_keys_exec_timed_out(WK_C_x WK_c); assert_true(stats->line != NULL && stats->line[0] != L'\0'); } TEST(last_argument_is_inserted) { #ifndef __PDCURSES__ const wchar_t meta_dot[] = WK_ESC WK_DOT; #else const wchar_t meta_dot[] = { K(ALT_PERIOD), L'\0' }; #endif /* Emulate proper history initialization (must happen after view * initialization). */ cfg_resize_histories(5); cfg_resize_histories(0); cfg_resize_histories(5); hists_commands_save("a1"); hists_commands_save("b1 b2"); hists_commands_save("c1 c2 c3"); hists_commands_save("d1 d2 d3 d4"); (void)vle_keys_exec_timed_out(meta_dot); assert_wstring_equal(L"d4", stats->line); (void)vle_keys_exec_timed_out(meta_dot); assert_wstring_equal(L"c3", stats->line); (void)vle_keys_exec_timed_out(meta_dot); assert_wstring_equal(L"b2", stats->line); (void)vle_keys_exec_timed_out(meta_dot); assert_wstring_equal(L"a1", stats->line); (void)vle_keys_exec_timed_out(meta_dot); assert_wstring_equal(L"", stats->line); (void)vle_keys_exec_timed_out(meta_dot); assert_wstring_equal(L"", stats->line); (void)vle_keys_exec_timed_out(WK_SPACE); assert_wstring_equal(L" ", stats->line); (void)vle_keys_exec_timed_out(meta_dot); assert_wstring_equal(L" d4", stats->line); cfg_resize_histories(0); } TEST(abbrevs_are_expanded) { int i; for(i = 0; i < 255; ++i) { cfg.word_chars[i] = !isspace(i); } assert_success(vle_abbr_add(L"lhs", L"rhs")); (void)vle_keys_exec_timed_out(L"lhs"); assert_wstring_equal(L"lhs", stats->line); (void)vle_keys_exec_timed_out(L" "); assert_wstring_equal(L"rhs ", stats->line); /* Abbrevs that leave cmdline mode. */ assert_success(vle_abbr_add(L"lhs2", L"rhs2" WK_C_c)); (void)vle_keys_exec_timed_out(L"lhs2" WK_C_RB); assert_false(vle_mode_is(CMDLINE_MODE)); assert_null(stats->line); modcline_enter(CLS_COMMAND, ""); (void)vle_keys_exec_timed_out(L"lhs2 "); assert_false(vle_mode_is(CMDLINE_MODE)); assert_null(stats->line); modcline_enter(CLS_COMMAND, ""); (void)vle_keys_exec_timed_out(L"lhs2" WK_CR); assert_false(vle_mode_is(CMDLINE_MODE)); assert_null(stats->line); vle_abbr_reset(); memset(cfg.word_chars, 0, sizeof(cfg.word_chars)); } TEST(expr_reg_good_expr) { (void)vle_keys_exec_timed_out(L"ad" WK_C_b); (void)vle_keys_exec_timed_out(WK_C_r WK_EQUALS); (void)vle_keys_exec_timed_out(L"'bc'" WK_CR); assert_wstring_equal(L"abcd", stats->line); } TEST(expr_reg_bad_expr) { (void)vle_keys_exec_timed_out(L"ad" WK_C_b); (void)vle_keys_exec_timed_out(WK_C_r WK_EQUALS); (void)vle_keys_exec_timed_out(L"bc" WK_CR); assert_wstring_equal(L"ad", stats->line); } TEST(ext_edited_prompt_is_saved_to_history, IF(not_windows)) { FILE *fp; char path[PATH_MAX + 1]; char *const saved_cwd = save_cwd(); assert_success(os_chdir(SANDBOX_PATH)); /* Emulate proper history initialization (must happen after view * initialization). */ cfg_resize_histories(10); cfg_resize_histories(0); cfg_resize_histories(10); update_string(&cfg.shell, "/bin/sh"); stats_update_shell_type(cfg.shell); fp = fopen("./script", "w"); fputs("#!/bin/sh\n", fp); fputs("echo \\'ext-edit\\' > $3\n", fp); fclose(fp); assert_success(os_chmod("script", 0777)); curr_stats.exec_env_type = EET_EMULATOR; make_abs_path(path, sizeof(path), SANDBOX_PATH, "script", saved_cwd); update_string(&cfg.vi_command, path); (void)vle_keys_exec_timed_out(WK_C_r WK_EQUALS); (void)vle_keys_exec_timed_out(WK_C_g); assert_wstring_equal(L"ext-edit", stats->line); update_string(&cfg.vi_command, NULL); update_string(&cfg.shell, NULL); assert_success(unlink(path)); restore_cwd(saved_cwd); assert_int_equal(1, curr_stats.exprreg_hist.size); assert_string_equal("'ext-edit'", curr_stats.exprreg_hist.items[0].text); cfg_resize_histories(0); } static int have_ext_keys(void) { #ifdef ENABLE_EXTENDED_KEYS return 1; #else return 0; #endif } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */ /* vim: set cinoptions+=t0 filetype=c : */