1 #include <stic.h>
2 
3 #include <limits.h> /* INT_MAX */
4 #include <string.h> /* strcpy() */
5 
6 #include <test-utils.h>
7 
8 #include "../../src/cfg/config.h"
9 #include "../../src/ui/color_scheme.h"
10 #include "../../src/ui/statusbar.h"
11 #include "../../src/ui/ui.h"
12 #include "../../src/utils/matchers.h"
13 #include "../../src/cmd_core.h"
14 #include "../../src/filelist.h"
15 #include "../../src/status.h"
16 
SETUP_ONCE()17 SETUP_ONCE()
18 {
19 	init_commands();
20 	cs_reset(&cfg.cs);
21 	lwin.list_rows = 0;
22 	rwin.list_rows = 0;
23 
24 	curr_view = &lwin;
25 }
26 
SETUP()27 SETUP()
28 {
29 	cs_reset(&cfg.cs);
30 	curr_stats.cs = &cfg.cs;
31 }
32 
TEARDOWN()33 TEARDOWN()
34 {
35 	cs_reset(&cfg.cs);
36 	curr_stats.cs = NULL;
37 }
38 
39 /* Attributes. */
40 
TEST(wrong_attribute_causes_error)41 TEST(wrong_attribute_causes_error)
42 {
43 	assert_failure(exec_commands("hi Win cterm=bad", &lwin, CIT_COMMAND));
44 }
45 
TEST(various_attributes_are_parsed)46 TEST(various_attributes_are_parsed)
47 {
48 #ifdef HAVE_A_ITALIC_DECL
49 	const unsigned int italic_attr = A_ITALIC;
50 #else
51 	/* If A_ITALIC is missing (it's an extension), use A_REVERSE instead. */
52 	const unsigned int italic_attr = A_REVERSE;
53 #endif
54 
55 	curr_stats.cs->color[WIN_COLOR].attr = 0;
56 	assert_success(exec_commands("hi Win cterm=bold,italic", &lwin, CIT_COMMAND));
57 	assert_int_equal(A_BOLD | italic_attr, curr_stats.cs->color[WIN_COLOR].attr);
58 	assert_success(exec_commands("hi Win cterm=underline,reverse", &lwin,
59 				CIT_COMMAND));
60 	assert_int_equal(A_UNDERLINE | A_REVERSE,
61 			curr_stats.cs->color[WIN_COLOR].attr);
62 	assert_success(exec_commands("hi Win cterm=standout", &lwin, CIT_COMMAND));
63 	assert_int_equal(A_STANDOUT, curr_stats.cs->color[WIN_COLOR].attr);
64 }
65 
TEST(attributes_are_printed_back_correctly)66 TEST(attributes_are_printed_back_correctly)
67 {
68 	ui_sb_msg("");
69 	assert_failure(exec_commands("highlight AuxWin", &lwin, CIT_COMMAND));
70 	assert_string_equal("AuxWin     cterm=none ctermfg=default ctermbg=default",
71 			ui_sb_last());
72 
73 	assert_success(exec_commands("highlight Win cterm=underline,inverse", &lwin,
74 				CIT_COMMAND));
75 
76 	ui_sb_msg("");
77 	assert_failure(exec_commands("highlight Win", &lwin, CIT_COMMAND));
78 	assert_string_equal(
79 			"Win        cterm=underline,reverse ctermfg=white   ctermbg=black  ",
80 			ui_sb_last());
81 
82 	assert_success(exec_commands("highlight Win cterm=italic,standout,bold",
83 				&lwin, CIT_COMMAND));
84 
85 	ui_sb_msg("");
86 	assert_failure(exec_commands("highlight Win", &lwin, CIT_COMMAND));
87 #ifdef HAVE_A_ITALIC_DECL
88 	assert_string_equal(
89 			"Win        cterm=bold,standout,italic ctermfg=white   ctermbg=black  ",
90 			ui_sb_last());
91 #else
92 	assert_string_equal(
93 			"Win        cterm=bold,reverse,standout ctermfg=white   ctermbg=black  ",
94 			ui_sb_last());
95 #endif
96 }
97 
98 /* Generic groups. */
99 
TEST(color_is_set)100 TEST(color_is_set)
101 {
102 	const char *const COMMANDS = "hi Win ctermfg=red ctermbg=red cterm=bold";
103 
104 	curr_stats.cs->color[WIN_COLOR].fg = COLOR_BLUE;
105 	curr_stats.cs->color[WIN_COLOR].bg = COLOR_BLUE;
106 	curr_stats.cs->color[WIN_COLOR].attr = 0;
107 	assert_success(exec_commands(COMMANDS, &lwin, CIT_COMMAND));
108 	assert_int_equal(COLOR_RED, curr_stats.cs->color[WIN_COLOR].fg);
109 	assert_int_equal(COLOR_RED, curr_stats.cs->color[WIN_COLOR].bg);
110 	assert_int_equal(A_BOLD, curr_stats.cs->color[WIN_COLOR].attr);
111 }
112 
TEST(original_color_is_unchanged_on_parsing_error)113 TEST(original_color_is_unchanged_on_parsing_error)
114 {
115 	const char *const COMMANDS = "highlight Win ctermfg=red ctersmbg=red";
116 
117 	curr_stats.cs->color[WIN_COLOR].fg = COLOR_BLUE;
118 	assert_failure(exec_commands(COMMANDS, &lwin, CIT_COMMAND));
119 	assert_int_equal(COLOR_BLUE, curr_stats.cs->color[WIN_COLOR].fg);
120 }
121 
122 /* File-specific highlight. */
123 
TEST(empty_curly_braces)124 TEST(empty_curly_braces)
125 {
126 	const char *const COMMANDS = "highlight {} ctermfg=red";
127 
128 	assert_false(exec_commands(COMMANDS, &lwin, CIT_COMMAND) == 0);
129 }
130 
TEST(curly_braces_pattern_transform)131 TEST(curly_braces_pattern_transform)
132 {
133 	const char *const COMMANDS = "highlight {*.sh}<inode/directory> ctermfg=red";
134 
135 	assert_int_equal(0, exec_commands(COMMANDS, &lwin, CIT_COMMAND));
136 	assert_string_equal("{*.sh}<inode/directory>",
137 			matchers_get_expr(cfg.cs.file_hi[0].matchers));
138 }
139 
TEST(curly_braces_no_flags_allowed)140 TEST(curly_braces_no_flags_allowed)
141 {
142 	const char *const COMMANDS = "highlight {*.sh}i ctermfg=red";
143 
144 	assert_false(exec_commands(COMMANDS, &lwin, CIT_COMMAND) == 0);
145 }
146 
TEST(empty_re_without_flags)147 TEST(empty_re_without_flags)
148 {
149 	const char *const COMMANDS = "highlight // ctermfg=red";
150 
151 	assert_false(exec_commands(COMMANDS, &lwin, CIT_COMMAND) == 0);
152 }
153 
TEST(empty_re_with_flags)154 TEST(empty_re_with_flags)
155 {
156 	const char *const COMMANDS = "highlight //i ctermfg=red";
157 
158 	assert_false(exec_commands(COMMANDS, &lwin, CIT_COMMAND) == 0);
159 }
160 
TEST(pattern_is_not_unescaped)161 TEST(pattern_is_not_unescaped)
162 {
163 	const char *const COMMANDS = "highlight /^\\./ ctermfg=red";
164 
165 	assert_int_equal(0, exec_commands(COMMANDS, &lwin, CIT_COMMAND));
166 	assert_string_equal("/^\\./", matchers_get_expr(cfg.cs.file_hi[0].matchers));
167 }
168 
TEST(pattern_length_is_not_limited)169 TEST(pattern_length_is_not_limited)
170 {
171 	const char *const COMMANDS = "highlight /\\.(7z|Z|a|ace|alz|apkg|arc|arj|bz"
172 		"|bz2|cab|cpio|deb|gz|jar|lha|lrz|lz|lzma|lzo|rar|rpm|rz|t7z|tZ|tar|tbz"
173 		"|tbz2|tgz|tlz|txz|tzo|war|xz|zip)$/ ctermfg=red";
174 
175 	assert_int_equal(0, exec_commands(COMMANDS, &lwin, CIT_COMMAND));
176 	assert_string_equal("/\\.(7z|Z|a|ace|alz|apkg|arc|arj|bz"
177 		"|bz2|cab|cpio|deb|gz|jar|lha|lrz|lz|lzma|lzo|rar|rpm|rz|t7z|tZ|tar|tbz"
178 		"|tbz2|tgz|tlz|txz|tzo|war|xz|zip)$/",
179 		matchers_get_expr(cfg.cs.file_hi[0].matchers));
180 }
181 
TEST(i_flag)182 TEST(i_flag)
183 {
184 	const char *const COMMANDS = "highlight /^\\./i ctermfg=red";
185 
186 	assert_int_equal(0, exec_commands(COMMANDS, &lwin, CIT_COMMAND));
187 	assert_string_equal("/^\\./i", matchers_get_expr(cfg.cs.file_hi[0].matchers));
188 }
189 
TEST(I_flag)190 TEST(I_flag)
191 {
192 	const char *const COMMANDS = "highlight /^\\./I ctermfg=red";
193 
194 	assert_int_equal(0, exec_commands(COMMANDS, &lwin, CIT_COMMAND));
195 	assert_string_equal("/^\\./I", matchers_get_expr(cfg.cs.file_hi[0].matchers));
196 }
197 
TEST(wrong_flag)198 TEST(wrong_flag)
199 {
200 	const char *const COMMANDS = "highlight /^\\./x ctermfg=red";
201 
202 	assert_int_equal(1, exec_commands(COMMANDS, &lwin, CIT_COMMAND));
203 }
204 
TEST(negation)205 TEST(negation)
206 {
207 	const char *const COMMANDS = "highlight !/^\\./i ctermfg=red";
208 
209 	assert_success(exec_commands(COMMANDS, &lwin, CIT_COMMAND));
210 	assert_string_equal("!/^\\./i",
211 			matchers_get_expr(cfg.cs.file_hi[0].matchers));
212 }
213 
TEST(highlighting_is_printed_back_correctly)214 TEST(highlighting_is_printed_back_correctly)
215 {
216 	const char *const COMMANDS = "highlight {*.jpg} ctermfg=red";
217 	assert_success(exec_commands(COMMANDS, &lwin, CIT_COMMAND));
218 
219 	ui_sb_msg("");
220 	assert_failure(exec_commands("highlight {*.jpg}", &lwin, CIT_COMMAND));
221 	assert_string_equal("{*.jpg}    cterm=none ctermfg=red     ctermbg=default",
222 			ui_sb_last());
223 }
224 
TEST(existing_records_are_updated)225 TEST(existing_records_are_updated)
226 {
227 	const char *const COMMANDS1 = "highlight {*.jpg} ctermfg=red";
228 	const char *const COMMANDS2 = "highlight {*.jpg} ctermfg=blue";
229 
230 	assert_success(exec_commands(COMMANDS1, &lwin, CIT_COMMAND));
231 	assert_success(exec_commands(COMMANDS2, &lwin, CIT_COMMAND));
232 	assert_int_equal(1, cfg.cs.file_hi_count);
233 
234 	assert_int_equal(COLOR_BLUE, cfg.cs.file_hi[0].hi.fg);
235 }
236 
TEST(all_records_can_be_removed)237 TEST(all_records_can_be_removed)
238 {
239 	const char *const COMMANDS1 = "highlight {*.jpg} ctermfg=red";
240 	const char *const COMMANDS2 = "highlight {*.avi} cterm=bold";
241 	const char *const COMMANDS3 = "highlight clear";
242 
243 	assert_success(exec_commands(COMMANDS1, &lwin, CIT_COMMAND));
244 	assert_success(exec_commands(COMMANDS2, &lwin, CIT_COMMAND));
245 	assert_int_equal(2, cfg.cs.file_hi_count);
246 	assert_success(exec_commands(COMMANDS3, &lwin, CIT_COMMAND));
247 	assert_int_equal(0, cfg.cs.file_hi_count);
248 }
249 
TEST(records_can_be_removed)250 TEST(records_can_be_removed)
251 {
252 	const char *const COMMANDS1 = "highlight {*.jpg} ctermfg=red";
253 	const char *const COMMANDS2 = "highlight clear {*.avi}";
254 	const char *const COMMANDS3 = "highlight clear {*.jpg}";
255 
256 	assert_success(exec_commands(COMMANDS1, &lwin, CIT_COMMAND));
257 	assert_int_equal(1, cfg.cs.file_hi_count);
258 	assert_failure(exec_commands(COMMANDS2, &lwin, CIT_COMMAND));
259 	assert_int_equal(1, cfg.cs.file_hi_count);
260 	assert_success(exec_commands(COMMANDS3, &lwin, CIT_COMMAND));
261 	assert_int_equal(0, cfg.cs.file_hi_count);
262 }
263 
TEST(incorrect_highlight_groups_are_not_added)264 TEST(incorrect_highlight_groups_are_not_added)
265 {
266 	const char *const COMMANDS = "highlight {*.jpg} ctersmfg=red";
267 	assert_failure(exec_commands(COMMANDS, &lwin, CIT_COMMAND));
268 	assert_int_equal(0, cfg.cs.file_hi_count);
269 }
270 
TEST(can_color_uncolored_file)271 TEST(can_color_uncolored_file)
272 {
273 	view_setup(&lwin);
274 	make_abs_path(lwin.curr_dir, sizeof(lwin.curr_dir), TEST_DATA_PATH,
275 			"color-schemes", NULL);
276 
277 	assert_success(populate_dir_list(&lwin, 0));
278 
279 	curr_stats.cs = &cfg.cs;
280 	curr_stats.load_stage = 2;
281 
282 	assert_null(cs_get_file_hi(curr_stats.cs, "some.vifm",
283 				&lwin.dir_entry[0].hi_num));
284 	assert_int_equal(INT_MAX, lwin.dir_entry[0].hi_num);
285 
286 	assert_success(exec_commands("highlight {*.vifm} cterm=bold", &lwin,
287 				CIT_COMMAND));
288 	assert_non_null(cs_get_file_hi(curr_stats.cs, "some.vifm",
289 				&lwin.dir_entry[0].hi_num));
290 	assert_int_equal(0, lwin.dir_entry[0].hi_num);
291 
292 	view_teardown(&lwin);
293 	curr_stats.load_stage = 0;
294 }
295 
TEST(tabs_are_allowed)296 TEST(tabs_are_allowed)
297 {
298 	const char *const COMMANDS1 = "highlight\t{*.jpg} ctermfg=red\tctermbg=blue";
299 	const char *const COMMANDS2 = "highlight {*.avi}\tctermfg=red";
300 	const char *const COMMANDS3 = "highlight\t{*.mp3}\tctermfg=red";
301 
302 	assert_success(exec_commands(COMMANDS1, &lwin, CIT_COMMAND));
303 	assert_int_equal(1, cfg.cs.file_hi_count);
304 	assert_success(exec_commands(COMMANDS2, &lwin, CIT_COMMAND));
305 	assert_int_equal(2, cfg.cs.file_hi_count);
306 	assert_success(exec_commands(COMMANDS3, &lwin, CIT_COMMAND));
307 	assert_int_equal(3, cfg.cs.file_hi_count);
308 
309 	if(cfg.cs.file_hi_count > 0)
310 	{
311 		assert_string_equal("{*.jpg}",
312 				matchers_get_expr(cfg.cs.file_hi[0].matchers));
313 	}
314 	if(cfg.cs.file_hi_count > 1)
315 	{
316 		assert_string_equal("{*.avi}",
317 				matchers_get_expr(cfg.cs.file_hi[1].matchers));
318 	}
319 	if(cfg.cs.file_hi_count > 2)
320 	{
321 		assert_string_equal("{*.mp3}",
322 				matchers_get_expr(cfg.cs.file_hi[2].matchers));
323 	}
324 }
325 
326 /* vim: set tabstop=2 softtabstop=2 shiftwidth=2 noexpandtab cinoptions-=(0 : */
327 /* vim: set cinoptions+=t0 filetype=c : */
328