#include <stic.h> #include <limits.h> /* INT_MAX */ #include <stdio.h> /* snprintf() */ #include <string.h> /* strcpy() */ #include <test-utils.h> #include "../../src/cfg/config.h" #include "../../src/lua/vlua.h" #include "../../src/ui/color_scheme.h" #include "../../src/ui/statusbar.h" #include "../../src/ui/ui.h" #include "../../src/utils/matchers.h" #include "../../src/cmd_core.h" #include "../../src/filelist.h" #include "../../src/status.h" SETUP_ONCE() { cmds_init(); cs_reset(&cfg.cs); lwin.list_rows = 0; rwin.list_rows = 0; curr_view = &lwin; } SETUP() { cs_reset(&cfg.cs); curr_stats.cs = &cfg.cs; } TEARDOWN() { cs_reset(&cfg.cs); curr_stats.cs = NULL; } /* General behaviour. */ TEST(all_groups_are_printed) { /* On PDCurses A_STANDOUT == (A_REVERSE | A_BOLD). */ #if __PDCURSES__ # define ATTR ",standout" #else # define ATTR "" #endif const char *expected = "Win cterm=none ctermfg=white ctermbg=black\n" "Directory cterm=bold ctermfg=cyan ctermbg=default\n" "Link cterm=bold ctermfg=yellow ctermbg=default\n" "BrokenLink cterm=bold ctermfg=red ctermbg=default\n" "HardLink cterm=none ctermfg=yellow ctermbg=default\n" "Socket cterm=bold ctermfg=magenta ctermbg=default\n" "Device cterm=bold ctermfg=red ctermbg=default\n" "Fifo cterm=bold ctermfg=cyan ctermbg=default\n" "Executable cterm=bold ctermfg=green ctermbg=default\n" "Selected cterm=bold ctermfg=magenta ctermbg=default\n" "CurrLine cterm=bold,reverse" ATTR " ctermfg=default ctermbg=default\n" "TopLine cterm=none ctermfg=black ctermbg=white\n" "TopLineSel cterm=bold ctermfg=black ctermbg=default\n" "StatusLine cterm=bold ctermfg=black ctermbg=white\n" "WildBox cterm=none ctermfg=default ctermbg=default\n" "WildMenu cterm=underline,reverse ctermfg=white ctermbg=black\n" "CmdLine cterm=none ctermfg=white ctermbg=black\n" "ErrorMsg cterm=none ctermfg=red ctermbg=black\n" "Border cterm=none ctermfg=black ctermbg=white\n" "OtherLine cterm=none ctermfg=default ctermbg=default\n" "JobLine cterm=bold,reverse" ATTR " ctermfg=black ctermbg=white\n" "SuggestBox cterm=bold ctermfg=default ctermbg=default\n" "CmpMismatch cterm=bold ctermfg=white ctermbg=red\n" "CmpUnmatched cterm=bold ctermfg=white ctermbg=green\n" "CmpBlank cterm=none ctermfg=default ctermbg=default\n" "AuxWin cterm=none ctermfg=default ctermbg=default\n" "TabLine cterm=none ctermfg=white ctermbg=black\n" "TabLineSel cterm=bold,reverse" ATTR " ctermfg=default ctermbg=default\n" "User1 cterm=none ctermfg=default ctermbg=default\n" "User2 cterm=none ctermfg=default ctermbg=default\n" "User3 cterm=none ctermfg=default ctermbg=default\n" "User4 cterm=none ctermfg=default ctermbg=default\n" "User5 cterm=none ctermfg=default ctermbg=default\n" "User6 cterm=none ctermfg=default ctermbg=default\n" "User7 cterm=none ctermfg=default ctermbg=default\n" "User8 cterm=none ctermfg=default ctermbg=default\n" "User9 cterm=none ctermfg=default ctermbg=default\n" "User10 cterm=none ctermfg=default ctermbg=default\n" "User11 cterm=none ctermfg=default ctermbg=default\n" "User12 cterm=none ctermfg=default ctermbg=default\n" "User13 cterm=none ctermfg=default ctermbg=default\n" "User14 cterm=none ctermfg=default ctermbg=default\n" "User15 cterm=none ctermfg=default ctermbg=default\n" "User16 cterm=none ctermfg=default ctermbg=default\n" "User17 cterm=none ctermfg=default ctermbg=default\n" "User18 cterm=none ctermfg=default ctermbg=default\n" "User19 cterm=none ctermfg=default ctermbg=default\n" "User20 cterm=none ctermfg=default ctermbg=default\n" "OtherWin cterm=none ctermfg=default ctermbg=default\n" "LineNr cterm=none ctermfg=default ctermbg=default\n" "OddLine cterm=none ctermfg=default ctermbg=default\n" "\n" "column:size cterm=bold ctermfg=red ctermbg=red\n" "\n" "{*.jpg} cterm=none ctermfg=red ctermbg=blue"; assert_success(cmds_dispatch("highlight {*.jpg} ctermfg=red\tctermbg=blue", &lwin, CIT_COMMAND)); assert_success(cmds_dispatch( "highlight column:size ctermfg=red ctermbg=red cterm=bold", &lwin, CIT_COMMAND)); ui_sb_msg(""); assert_failure(cmds_dispatch("hi", &lwin, CIT_COMMAND)); assert_string_equal(expected, ui_sb_last()); } /* Colors. */ TEST(all_xterm_colors_are_printed) { size_t i; for(i = 0U; i < ARRAY_LEN(XTERM256_COLOR_NAMES); ++i) { cfg.cs.color[WIN_COLOR].bg = i; cfg.cs.color[WIN_COLOR].fg = i; char expected[128]; snprintf(expected, sizeof(expected), "Win cterm=none ctermfg=%-7s ctermbg=%s", XTERM256_COLOR_NAMES[i], XTERM256_COLOR_NAMES[i]); ui_sb_msg(""); assert_failure(cmds_dispatch("hi Win", &lwin, CIT_COMMAND)); assert_string_equal(expected, ui_sb_last()); } } TEST(wrong_gui_color_causes_error) { ui_sb_msg(""); assert_failure(cmds_dispatch("hi Win guifg=#1234", &lwin, CIT_COMMAND)); assert_string_equal("Unrecognized color value format: #1234", ui_sb_last()); ui_sb_msg(""); assert_failure(cmds_dispatch("hi Win guibg=#1234", &lwin, CIT_COMMAND)); assert_string_equal("Unrecognized color value format: #1234", ui_sb_last()); } TEST(gui_colors_are_parsed) { assert_success(cmds_dispatch("hi Win guifg=#1234fe guibg=red gui=reverse", &lwin, CIT_COMMAND)); assert_true(curr_stats.cs->color[WIN_COLOR].gui_set); assert_int_equal(0x1234fe, curr_stats.cs->color[WIN_COLOR].gui_fg); assert_int_equal(COLOR_RED, curr_stats.cs->color[WIN_COLOR].gui_bg); assert_int_equal(A_REVERSE, curr_stats.cs->color[WIN_COLOR].gui_attr); assert_success(cmds_dispatch("hi Win guifg=default", &lwin, CIT_COMMAND)); assert_true(curr_stats.cs->color[WIN_COLOR].gui_set); assert_int_equal(-1, curr_stats.cs->color[WIN_COLOR].gui_fg); assert_int_equal(COLOR_RED, curr_stats.cs->color[WIN_COLOR].gui_bg); assert_int_equal(A_REVERSE, curr_stats.cs->color[WIN_COLOR].gui_attr); } TEST(gui_colors_are_printed) { ui_sb_msg(""); assert_success(cmds_dispatch("hi Win guifg=#1234fe guibg=red", &lwin, CIT_COMMAND)); assert_failure(cmds_dispatch("hi Win", &lwin, CIT_COMMAND)); assert_string_equal( "Win cterm=none ctermfg=white ctermbg=black\n" " gui=none guifg=#1234fe guibg=red", ui_sb_last()); } /* Attributes. */ TEST(wrong_attribute_causes_error) { assert_failure(cmds_dispatch("hi Win cterm=bad", &lwin, CIT_COMMAND)); } TEST(various_attributes_are_parsed) { #ifdef HAVE_A_ITALIC_DECL const unsigned int italic_attr = A_ITALIC; #else /* If A_ITALIC is missing (it's an extension), use A_REVERSE instead. */ const unsigned int italic_attr = A_REVERSE; #endif curr_stats.cs->color[WIN_COLOR].attr = 0; assert_success(cmds_dispatch("hi Win cterm=bold,italic", &lwin, CIT_COMMAND)); assert_int_equal(A_BOLD | italic_attr, curr_stats.cs->color[WIN_COLOR].attr); assert_success(cmds_dispatch("hi Win cterm=underline,reverse", &lwin, CIT_COMMAND)); assert_int_equal(A_UNDERLINE | A_REVERSE, curr_stats.cs->color[WIN_COLOR].attr); assert_success(cmds_dispatch("hi Win cterm=standout,combine", &lwin, CIT_COMMAND)); assert_int_equal(A_STANDOUT, curr_stats.cs->color[WIN_COLOR].attr); assert_true(curr_stats.cs->color[WIN_COLOR].combine_attrs); } TEST(attributes_are_printed_back_correctly) { ui_sb_msg(""); assert_failure(cmds_dispatch("highlight AuxWin", &lwin, CIT_COMMAND)); assert_string_equal("AuxWin cterm=none ctermfg=default ctermbg=default", ui_sb_last()); assert_success(cmds_dispatch("highlight Win cterm=underline,inverse", &lwin, CIT_COMMAND)); ui_sb_msg(""); assert_success(cmds_dispatch("highlight AuxWin cterm=combine", &lwin, CIT_COMMAND)); assert_failure(cmds_dispatch("highlight AuxWin", &lwin, CIT_COMMAND)); assert_string_equal( "AuxWin cterm=combine ctermfg=default ctermbg=default", ui_sb_last()); assert_success(cmds_dispatch("highlight Win cterm=underline,inverse", &lwin, CIT_COMMAND)); ui_sb_msg(""); assert_failure(cmds_dispatch("highlight Win", &lwin, CIT_COMMAND)); assert_string_equal( "Win cterm=underline,reverse ctermfg=white ctermbg=black", ui_sb_last()); assert_success(cmds_dispatch("highlight Win cterm=italic,standout,bold", &lwin, CIT_COMMAND)); ui_sb_msg(""); assert_failure(cmds_dispatch("highlight Win", &lwin, CIT_COMMAND)); #ifdef HAVE_A_ITALIC_DECL assert_string_equal( "Win cterm=bold,standout,italic ctermfg=white ctermbg=black", ui_sb_last()); #else assert_string_equal( "Win cterm=bold,reverse,standout ctermfg=white ctermbg=black", ui_sb_last()); #endif } /* Generic groups. */ TEST(color_is_set) { const char *const COMMANDS = "hi Win ctermfg=red ctermbg=red cterm=bold"; curr_stats.cs->color[WIN_COLOR].fg = COLOR_BLUE; curr_stats.cs->color[WIN_COLOR].bg = COLOR_BLUE; curr_stats.cs->color[WIN_COLOR].attr = 0; assert_success(cmds_dispatch(COMMANDS, &lwin, CIT_COMMAND)); assert_int_equal(COLOR_RED, curr_stats.cs->color[WIN_COLOR].fg); assert_int_equal(COLOR_RED, curr_stats.cs->color[WIN_COLOR].bg); assert_int_equal(A_BOLD, curr_stats.cs->color[WIN_COLOR].attr); } TEST(original_color_is_unchanged_on_parsing_error) { const char *const COMMANDS = "highlight Win ctermfg=red ctersmbg=red"; curr_stats.cs->color[WIN_COLOR].fg = COLOR_BLUE; assert_failure(cmds_dispatch(COMMANDS, &lwin, CIT_COMMAND)); assert_int_equal(COLOR_BLUE, curr_stats.cs->color[WIN_COLOR].fg); } /* Column highlighting. */ TEST(column_name_is_wrong) { curr_stats.vlua = vlua_init(); ui_sb_msg(""); assert_failure(cmds_dispatch("hi column:badone ctermfg=red", &lwin, CIT_COMMAND)); assert_string_equal("No such column: badone", ui_sb_last()); vlua_finish(curr_stats.vlua); curr_stats.vlua = NULL; } TEST(column_color_is_not_set) { assert_null(cs_get_column_hi(curr_stats.cs, SK_BY_SIZE)); assert_failure(cmds_dispatch("hi column:size ctermfg=bad", &lwin, CIT_COMMAND)); assert_null(cs_get_column_hi(curr_stats.cs, SK_BY_SIZE)); } TEST(column_color_is_set) { assert_null(cs_get_column_hi(curr_stats.cs, SK_BY_SIZE)); assert_success(cmds_dispatch( "hi column:size ctermfg=red ctermbg=red cterm=bold", &lwin, CIT_COMMAND)); const col_attr_t *hi = cs_get_column_hi(curr_stats.cs, SK_BY_SIZE); assert_int_equal(COLOR_RED, hi->fg); assert_int_equal(COLOR_RED, hi->bg); assert_int_equal(A_BOLD, hi->attr); } TEST(skipped_column_color_is_not_set) { assert_null(cs_get_column_hi(curr_stats.cs, SK_BY_NAME)); assert_success(cmds_dispatch( "hi column:size ctermfg=red ctermbg=red cterm=bold", &lwin, CIT_COMMAND)); assert_null(cs_get_column_hi(curr_stats.cs, SK_BY_NAME)); } TEST(column_color_not_removed) { curr_stats.vlua = vlua_init(); ui_sb_msg(""); assert_failure(cmds_dispatch("hi clear column:bad", &lwin, CIT_COMMAND)); assert_string_equal("No such column: bad", ui_sb_last()); vlua_finish(curr_stats.vlua); curr_stats.vlua = NULL; } TEST(column_color_is_removed) { /* Nothing to remove yet. */ ui_sb_msg(""); assert_failure(cmds_dispatch("hi clear column:size", &lwin, CIT_COMMAND)); assert_string_equal("No such group: column:size", ui_sb_last()); assert_success(cmds_dispatch("hi column:size ctermfg=red cterm=bold", &lwin, CIT_COMMAND)); assert_non_null(cs_get_column_hi(curr_stats.cs, SK_BY_SIZE)); assert_success(cmds_dispatch("hi clear column:size", &lwin, CIT_COMMAND)); assert_null(cs_get_column_hi(curr_stats.cs, SK_BY_SIZE)); } TEST(column_color_is_printed) { ui_sb_msg(""); assert_success(cmds_dispatch("hi column:size", &lwin, CIT_COMMAND)); assert_string_equal("", ui_sb_last()); assert_success(cmds_dispatch("hi column:size ctermfg=red cterm=bold", &lwin, CIT_COMMAND)); assert_non_null(cs_get_column_hi(curr_stats.cs, SK_BY_SIZE)); ui_sb_msg(""); assert_failure(cmds_dispatch("hi column:size", &lwin, CIT_COMMAND)); assert_string_equal("column:size cterm=bold ctermfg=red ctermbg=default", ui_sb_last()); } /* File-specific highlight. */ TEST(empty_curly_braces) { const char *const COMMANDS = "highlight {} ctermfg=red"; assert_false(cmds_dispatch(COMMANDS, &lwin, CIT_COMMAND) == 0); } TEST(curly_braces_pattern_transform) { const char *const COMMANDS = "highlight {*.sh}<inode/directory> ctermfg=red"; assert_int_equal(0, cmds_dispatch(COMMANDS, &lwin, CIT_COMMAND)); assert_string_equal("{*.sh}<inode/directory>", matchers_get_expr(cfg.cs.file_hi[0].matchers)); } TEST(curly_braces_no_flags_allowed) { const char *const COMMANDS = "highlight {*.sh}i ctermfg=red"; assert_false(cmds_dispatch(COMMANDS, &lwin, CIT_COMMAND) == 0); } TEST(empty_re_without_flags) { const char *const COMMANDS = "highlight // ctermfg=red"; assert_false(cmds_dispatch(COMMANDS, &lwin, CIT_COMMAND) == 0); } TEST(empty_re_with_flags) { const char *const COMMANDS = "highlight //i ctermfg=red"; assert_false(cmds_dispatch(COMMANDS, &lwin, CIT_COMMAND) == 0); } TEST(pattern_is_not_unescaped) { const char *const COMMANDS = "highlight /^\\./ ctermfg=red"; assert_int_equal(0, cmds_dispatch(COMMANDS, &lwin, CIT_COMMAND)); assert_string_equal("/^\\./", matchers_get_expr(cfg.cs.file_hi[0].matchers)); } TEST(pattern_length_is_not_limited) { const char *const COMMANDS = "highlight /\\.(7z|Z|a|ace|alz|apkg|arc|arj|bz" "|bz2|cab|cpio|deb|gz|jar|lha|lrz|lz|lzma|lzo|rar|rpm|rz|t7z|tZ|tar|tbz" "|tbz2|tgz|tlz|txz|tzo|war|xz|zip)$/ ctermfg=red"; assert_int_equal(0, cmds_dispatch(COMMANDS, &lwin, CIT_COMMAND)); assert_string_equal("/\\.(7z|Z|a|ace|alz|apkg|arc|arj|bz" "|bz2|cab|cpio|deb|gz|jar|lha|lrz|lz|lzma|lzo|rar|rpm|rz|t7z|tZ|tar|tbz" "|tbz2|tgz|tlz|txz|tzo|war|xz|zip)$/", matchers_get_expr(cfg.cs.file_hi[0].matchers)); } TEST(i_flag) { const char *const COMMANDS = "highlight /^\\./i ctermfg=red"; assert_int_equal(0, cmds_dispatch(COMMANDS, &lwin, CIT_COMMAND)); assert_string_equal("/^\\./i", matchers_get_expr(cfg.cs.file_hi[0].matchers)); } TEST(I_flag) { const char *const COMMANDS = "highlight /^\\./I ctermfg=red"; assert_int_equal(0, cmds_dispatch(COMMANDS, &lwin, CIT_COMMAND)); assert_string_equal("/^\\./I", matchers_get_expr(cfg.cs.file_hi[0].matchers)); } TEST(wrong_flag) { const char *const COMMANDS = "highlight /^\\./x ctermfg=red"; assert_int_equal(-1, cmds_dispatch(COMMANDS, &lwin, CIT_COMMAND)); } TEST(negation) { const char *const COMMANDS = "highlight !/^\\./i ctermfg=red"; assert_success(cmds_dispatch(COMMANDS, &lwin, CIT_COMMAND)); assert_string_equal("!/^\\./i", matchers_get_expr(cfg.cs.file_hi[0].matchers)); } TEST(highlighting_is_printed_back_correctly) { const char *const COMMANDS = "highlight {*.jpg} ctermfg=red"; assert_success(cmds_dispatch(COMMANDS, &lwin, CIT_COMMAND)); ui_sb_msg(""); assert_failure(cmds_dispatch("highlight {*.jpg}", &lwin, CIT_COMMAND)); assert_string_equal("{*.jpg} cterm=none ctermfg=red ctermbg=default", ui_sb_last()); } TEST(existing_records_are_updated) { const char *const COMMANDS1 = "highlight {*.jpg} ctermfg=red"; const char *const COMMANDS2 = "highlight {*.jpg} ctermfg=blue"; assert_success(cmds_dispatch(COMMANDS1, &lwin, CIT_COMMAND)); assert_success(cmds_dispatch(COMMANDS2, &lwin, CIT_COMMAND)); assert_int_equal(1, cfg.cs.file_hi_count); assert_int_equal(COLOR_BLUE, cfg.cs.file_hi[0].hi.fg); } TEST(all_records_can_be_removed) { const char *const COMMANDS1 = "highlight {*.jpg} ctermfg=red"; const char *const COMMANDS2 = "highlight {*.avi} cterm=bold"; const char *const COMMANDS3 = "highlight clear"; assert_success(cmds_dispatch(COMMANDS1, &lwin, CIT_COMMAND)); assert_success(cmds_dispatch(COMMANDS2, &lwin, CIT_COMMAND)); assert_int_equal(2, cfg.cs.file_hi_count); assert_success(cmds_dispatch(COMMANDS3, &lwin, CIT_COMMAND)); assert_int_equal(0, cfg.cs.file_hi_count); } TEST(records_can_be_removed) { const char *const COMMANDS1 = "highlight {*.jpg} ctermfg=red"; const char *const COMMANDS2 = "highlight clear {*.avi}"; const char *const COMMANDS3 = "highlight clear {*.jpg}"; assert_success(cmds_dispatch(COMMANDS1, &lwin, CIT_COMMAND)); assert_int_equal(1, cfg.cs.file_hi_count); assert_failure(cmds_dispatch(COMMANDS2, &lwin, CIT_COMMAND)); assert_int_equal(1, cfg.cs.file_hi_count); assert_success(cmds_dispatch(COMMANDS3, &lwin, CIT_COMMAND)); assert_int_equal(0, cfg.cs.file_hi_count); } TEST(incorrect_highlight_groups_are_not_added) { const char *const COMMANDS = "highlight {*.jpg} ctersmfg=red"; assert_failure(cmds_dispatch(COMMANDS, &lwin, CIT_COMMAND)); assert_int_equal(0, cfg.cs.file_hi_count); } TEST(can_color_uncolored_file) { view_setup(&lwin); make_abs_path(lwin.curr_dir, sizeof(lwin.curr_dir), TEST_DATA_PATH, "color-schemes", NULL); assert_success(populate_dir_list(&lwin, 0)); curr_stats.cs = &cfg.cs; curr_stats.load_stage = 2; assert_null(cs_get_file_hi(curr_stats.cs, "some.vifm", &lwin.dir_entry[0].hi_num)); assert_int_equal(INT_MAX, lwin.dir_entry[0].hi_num); assert_success(cmds_dispatch("highlight {*.vifm} cterm=bold", &lwin, CIT_COMMAND)); assert_non_null(cs_get_file_hi(curr_stats.cs, "some.vifm", &lwin.dir_entry[0].hi_num)); assert_int_equal(0, lwin.dir_entry[0].hi_num); view_teardown(&lwin); curr_stats.load_stage = 0; } TEST(tabs_are_allowed) { const char *const COMMANDS1 = "highlight\t{*.jpg} ctermfg=red\tctermbg=blue"; const char *const COMMANDS2 = "highlight {*.avi}\tctermfg=red"; const char *const COMMANDS3 = "highlight\t{*.mp3}\tctermfg=red"; assert_success(cmds_dispatch(COMMANDS1, &lwin, CIT_COMMAND)); assert_int_equal(1, cfg.cs.file_hi_count); assert_success(cmds_dispatch(COMMANDS2, &lwin, CIT_COMMAND)); assert_int_equal(2, cfg.cs.file_hi_count); assert_success(cmds_dispatch(COMMANDS3, &lwin, CIT_COMMAND)); assert_int_equal(3, cfg.cs.file_hi_count); if(cfg.cs.file_hi_count > 0) { assert_string_equal("{*.jpg}", matchers_get_expr(cfg.cs.file_hi[0].matchers)); } if(cfg.cs.file_hi_count > 1) { assert_string_equal("{*.avi}", matchers_get_expr(cfg.cs.file_hi[1].matchers)); } if(cfg.cs.file_hi_count > 2) { assert_string_equal("{*.mp3}", matchers_get_expr(cfg.cs.file_hi[2].matchers)); } } /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */ /* vim: set cinoptions+=t0 filetype=c : */