1 #include "tests.h"
2 #include "test_utils.h"
3 #include <wchar.h>
4 #include "fort.h"
5 
test_bug_fixes(void)6 void test_bug_fixes(void)
7 {
8 #ifdef FT_HAVE_WCHAR
9     SCENARIO("Bug 1") {
10         ft_table_t *table = ft_create_table();
11         ft_table_t *table_tmp_1 = ft_create_table();
12 
13 //        ft_set_border_style(table_tmp_1, FT_EMPTY_STYLE);
14         ft_set_cell_prop(table_tmp_1, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
15         ft_wwrite_ln(table_tmp_1, L"Rank", L"Title", L"Year", L"Rating");
16         ft_wwrite_ln(table_tmp_1, L"1", L"The Shawshank Redemption", L"3");
17 
18         const wchar_t *str = ft_to_wstring(table_tmp_1);
19         (void)str;
20         ft_wprintf_ln(table, str);
21 
22         ft_destroy_table(table_tmp_1);
23         ft_destroy_table(table);
24     }
25 #endif
26 
27 
28     SCENARIO("Bug 2") {
29         ft_table_t *table = ft_create_table();
30         assert_true(table != NULL);
31         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
32 
33         ft_set_border_style(table, FT_BASIC_STYLE);
34 
35         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
36         ft_set_cell_prop(table, FT_ANY_ROW, FT_ANY_COLUMN, FT_CPROP_EMPTY_STR_HEIGHT, 1);
37         ft_set_cell_prop(table, FT_ANY_ROW, FT_ANY_COLUMN, FT_CPROP_TOP_PADDING, 0);
38         ft_set_cell_prop(table, FT_ANY_ROW, FT_ANY_COLUMN, FT_CPROP_BOTTOM_PADDING, 0);
39         assert_true(FT_IS_SUCCESS(ft_write(table, "3")));
40         assert_true(FT_IS_SUCCESS(ft_write(table, "c")));
41         assert_true(FT_IS_SUCCESS(ft_write(table, "234")));
42         assert_true(FT_IS_SUCCESS(ft_write_ln(table, "3.140000")));
43         ft_ln(table);
44         ft_ln(table);
45 
46         assert_true(FT_IS_SUCCESS(ft_write(table, "3")));
47         assert_true(FT_IS_SUCCESS(ft_write(table, "c")));
48         assert_true(FT_IS_SUCCESS(ft_write(table, "234")));
49         assert_true(FT_IS_SUCCESS(ft_write_ln(table, "3.140000")));
50         ft_ln(table);
51         ft_ln(table);
52 
53         assert_true(FT_IS_SUCCESS(ft_write(table, "3")));
54         assert_true(FT_IS_SUCCESS(ft_write(table, "c")));
55         assert_true(FT_IS_SUCCESS(ft_write(table, "234")));
56         assert_true(FT_IS_SUCCESS(ft_write_ln(table, "3.140000")));
57 
58         const char *table_str = ft_to_string(table);
59         assert_true(table_str != NULL);
60         const char *table_str_etalon =
61             "+---+---+-----+----------+\n"
62             "| 3 | c | 234 | 3.140000 |\n"
63             "+---+---+-----+----------+\n"
64             "|   |   |     |          |\n"
65             "|   |   |     |          |\n"
66             "| 3 | c | 234 | 3.140000 |\n"
67             "|   |   |     |          |\n"
68             "|   |   |     |          |\n"
69             "| 3 | c | 234 | 3.140000 |\n"
70             "+---+---+-----+----------+\n";
71         assert_str_equal(table_str, table_str_etalon);
72 
73 
74         ft_set_cell_prop(table, FT_ANY_ROW, FT_ANY_COLUMN, FT_CPROP_EMPTY_STR_HEIGHT, 0);
75         table_str = ft_to_string(table);
76         assert_true(table_str != NULL);
77         table_str_etalon =
78             "+---+---+-----+----------+\n"
79             "| 3 | c | 234 | 3.140000 |\n"
80             "+---+---+-----+----------+\n"
81             "| 3 | c | 234 | 3.140000 |\n"
82             "| 3 | c | 234 | 3.140000 |\n"
83             "+---+---+-----+----------+\n";
84         assert_str_equal(table_str, table_str_etalon);
85 
86         ft_destroy_table(table);
87     }
88 
89     SCENARIO("Issue 11 - https://github.com/seleznevae/libfort/issues/11") {
90         ft_table_t *table = ft_create_table();
91         ft_set_border_style(table, FT_PLAIN_STYLE);
92 
93         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
94         ft_write_ln(table, "1", "2");
95         ft_write_ln(table, "3", "4");
96 
97         const char *table_str = ft_to_string(table);
98         assert_true(table_str != NULL);
99         const char *table_str_etalon =
100             "-------\n"
101             " 1   2 \n"
102             "-------\n"
103             " 3   4 \n";
104         assert_str_equal(table_str, table_str_etalon);
105         ft_destroy_table(table);
106     }
107 
108 #ifdef FT_HAVE_WCHAR
109     SCENARIO("Issue 11 - https://github.com/seleznevae/libfort/issues/11 (wchar case)") {
110         ft_table_t *table = ft_create_table();
111         ft_set_border_style(table, FT_PLAIN_STYLE);
112 
113         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
114         ft_wwrite_ln(table, L"1", L"2");
115         ft_wwrite_ln(table, L"3", L"4");
116 
117         const wchar_t *table_str = ft_to_wstring(table);
118         assert_true(table_str != NULL);
119         const wchar_t *table_str_etalon =
120             L"-------\n"
121             L" 1   2 \n"
122             L"-------\n"
123             L" 3   4 \n";
124         assert_wcs_equal(table_str, table_str_etalon);
125         ft_destroy_table(table);
126     }
127 #endif
128 
129 #ifdef FT_HAVE_UTF8
130     SCENARIO("Issue 11 - https://github.com/seleznevae/libfort/issues/11 (utf-8 case)") {
131         ft_table_t *table = ft_create_table();
132         ft_set_border_style(table, FT_PLAIN_STYLE);
133 
134         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
135         ft_u8write_ln(table, "1", "2");
136         ft_u8write_ln(table, "3", "4");
137 
138         const char *table_str = ft_to_u8string(table);
139         assert_true(table_str != NULL);
140         const char *table_str_etalon =
141             "-------\n"
142             " 1   2 \n"
143             "-------\n"
144             " 3   4 \n";
145         assert_str_equal(table_str, table_str_etalon);
146         ft_destroy_table(table);
147     }
148 #endif /* FT_HAVE_UTF8 */
149 
150 #ifdef FT_HAVE_UTF8
151     SCENARIO("Issue 15 - https://github.com/seleznevae/libfort/issues/15") {
152         ft_table_t *table = ft_create_table();
153         ft_set_border_style(table, FT_NICE_STYLE);
154 
155         ft_u8write_ln(table, "視野無限廣");
156         const char *table_str = ft_to_u8string(table);
157         assert_true(table_str != NULL);
158         const char *table_str_etalon =
159             "╔════════════╗\n"
160             "║ 視野無限廣 ║\n"
161             "╚════════════╝\n";
162         assert_str_equal(table_str, table_str_etalon);
163         ft_destroy_table(table);
164     }
165 #endif /* FT_HAVE_UTF8 */
166 
167 
168 #ifdef FT_HAVE_UTF8
169     SCENARIO("Issue 16 - https://github.com/seleznevae/libfort/issues/16") {
170         ft_table_t *table = ft_create_table();
171         ft_set_border_style(table, FT_DOUBLE2_STYLE);
172         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
173 
174         ft_u8write_ln(table, "cm³", "cm²");
175         ft_u8write_ln(table, "123", "123");
176         ft_u8write_ln(table, "yxₙ", "yx₌");
177         const char *table_str = ft_to_u8string(table);
178         assert_true(table_str != NULL);
179         const char *table_str_etalon =
180             "╔═════╤═════╗\n"
181             "║ cm³ │ cm² ║\n"
182             "╠═════╪═════╣\n"
183             "║ 123 │ 123 ║\n"
184             "╟─────┼─────╢\n"
185             "║ yxₙ │ yx₌ ║\n"
186             "╚═════╧═════╝\n";
187         assert_str_equal(table_str, table_str_etalon);
188         ft_destroy_table(table);
189     }
190 #endif /* FT_HAVE_UTF8 */
191 
192     SCENARIO("Issue 37 - https://github.com/seleznevae/libfort/issues/37") {
193         ft_table_t *table = ft_create_table();
194         ft_set_border_style(table, FT_BASIC_STYLE);
195         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
196         ft_write_ln(table, "xxx");
197         ft_write_ln(table,
198                     "1\n2\n3\n4\n5\n6\n7\n8\n9\n0\n1\n2\n3\n4\n5\n6\n7\n8");
199         ft_set_cell_prop(table, 1, 0, FT_CPROP_CONT_FG_COLOR, FT_COLOR_RED);
200 
201         const char *table_str = ft_to_string(table);
202         assert_true(table_str != NULL);
203         const char *table_str_etalon =
204             "+-----+\n"
205             "| xxx |\n"
206             "+-----+\n"
207             "| \033[31m1\033[0m   |\n"
208             "| \033[31m2\033[0m   |\n"
209             "| \033[31m3\033[0m   |\n"
210             "| \033[31m4\033[0m   |\n"
211             "| \033[31m5\033[0m   |\n"
212             "| \033[31m6\033[0m   |\n"
213             "| \033[31m7\033[0m   |\n"
214             "| \033[31m8\033[0m   |\n"
215             "| \033[31m9\033[0m   |\n"
216             "| \033[31m0\033[0m   |\n"
217             "| \033[31m1\033[0m   |\n"
218             "| \033[31m2\033[0m   |\n"
219             "| \033[31m3\033[0m   |\n"
220             "| \033[31m4\033[0m   |\n"
221             "| \033[31m5\033[0m   |\n"
222             "| \033[31m6\033[0m   |\n"
223             "| \033[31m7\033[0m   |\n"
224             "| \033[31m8\033[0m   |\n"
225             "+-----+\n";
226         assert_str_equal(table_str, table_str_etalon);
227 
228         ft_destroy_table(table);
229     }
230 
231     SCENARIO("Issue 37 - https://github.com/seleznevae/libfort/issues/37") {
232         ft_table_t *table = ft_create_table();
233         ft_set_border_style(table, FT_BASIC_STYLE);
234         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
235 
236         ft_write_ln(table, "hdr1", "hdr2", "xxx");
237         ft_write_ln(table, "3", "",
238                     "||||||||||||||||||||||||||||||\n"
239                     "||||||||||||||||||||||||||||||\n"
240                     "||||||||||||||||||||||||||||||\n"
241                     "||||||||||||||||||||||||||||||\n"
242                     "||||||||||||||||||||||||||||||\n"
243                     "||||||||||||||||||||||||||||||\n"
244                     "||||||||||||||||||||||||||||||\n"
245                     "||||||||||||||||||||||||||||||\n"
246                     "||||||||||||||||||||||||||||||\n"
247                     "||||||||||||||||||||||||||||||\n"
248                     "||||||||||||||||||||||||||||||\n"
249                     "||||||||||||||||||||||||||||||\n"
250                     "||||||||||||||||||||||||||||||\n"
251                     "||||||||||||||||||||||||||||||\n"
252                     "||||||||||||||||||||||||||||||\n"
253                     "||||||||||||||||||||||||||||||\n"
254                     "||||||||||||||||||||||||||||||\n"
255                     "||||||||||||||||||||||||||||||\n"
256                     "||||||||||||||||||||||||||||||\n"
257                     "||||||||||||||||||||||||||||||\n"
258                     "||||||||||||||||||||||||||||||\n"
259                     "||||||||||||||||||||||||||||||\n"
260                     "||||||||||||||||||||||||||||||\n"
261                     "||||||");
262 
263         ft_set_cell_prop(table, 1, FT_ANY_COLUMN, FT_CPROP_CONT_FG_COLOR, FT_COLOR_RED);
264         const char *table_str = ft_to_string(table);
265         assert_true(table_str != NULL);
266 
267         const char *table_str_etalon =
268             "+------+------+--------------------------------+\n"
269             "| hdr1 | hdr2 | xxx                            |\n"
270             "+------+------+--------------------------------+\n"
271             "| \033[31m3\033[0m    |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
272             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
273             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
274             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
275             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
276             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
277             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
278             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
279             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
280             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
281             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
282             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
283             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
284             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
285             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
286             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
287             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
288             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
289             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
290             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
291             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
292             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
293             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||||||||||||||||||||||||||\033[0m |\n"
294             "|\033[31m\033[0m      |\033[31m\033[0m      | \033[31m||||||\033[0m                         |\n"
295             "+------+------+--------------------------------+\n";
296         assert_str_equal(table_str, table_str_etalon);
297         ft_destroy_table(table);
298     }
299 
300     SCENARIO("Issue 58 - https://github.com/seleznevae/libfort/issues/58") {
301         {
302             ft_table_t *table = ft_create_table();
303             ft_printf_ln(table, "00|01");
304             ft_printf_ln(table, "10|11");
305             ft_set_cur_cell(table, 0, 5);
306             ft_printf_ln(table, "05");
307 
308             const char *table_str = ft_to_string(table);
309             assert_true(table_str != NULL);
310             const char *table_str_etalon =
311                 "+----+----+--+--+--+----+\n"
312                 "| 00 | 01 |  |  |  | 05 |\n"
313                 "| 10 | 11 |  |  |  |    |\n"
314                 "+----+----+--+--+--+----+\n";
315             assert_str_equal(table_str, table_str_etalon);
316             ft_destroy_table(table);
317         }
318         {
319             ft_table_t *table = ft_create_table();
320             ft_printf_ln(table, "00|01|02|03|04|05");
321             ft_printf_ln(table, "10|11|12|13|14|15");
322             ft_set_cur_cell(table, 0, 4);
323             ft_printf_ln(table, "24|25|26|27|28|29|30");
324 
325             const char *table_str = ft_to_string(table);
326             assert_true(table_str != NULL);
327             const char *table_str_etalon =
328                 "+----+----+----+----+----+----+----+----+----+----+----+\n"
329                 "| 00 | 01 | 02 | 03 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |\n"
330                 "| 10 | 11 | 12 | 13 | 14 | 15 |    |    |    |    |    |\n"
331                 "+----+----+----+----+----+----+----+----+----+----+----+\n";
332             assert_str_equal(table_str, table_str_etalon);
333             ft_destroy_table(table);
334         }
335     }
336 }
337 
test_table_basic(void)338 void test_table_basic(void)
339 {
340     ft_table_t *table = NULL;
341 
342     WHEN("Empty table") {
343         table = ft_create_table();
344         assert_true(table != NULL);
345         assert_true(ft_is_empty(table) == 1);
346         assert_true(ft_row_count(table) == 0);
347 
348         const char *table_str = ft_to_string(table);
349         assert_true(table_str != NULL);
350         const char *table_str_etalon = "";
351         assert_str_equal(table_str, table_str_etalon);
352 #ifdef FT_HAVE_WCHAR
353         const wchar_t *table_wstr = ft_to_wstring(table);
354         assert_true(table_wstr != NULL);
355         const wchar_t *table_wstr_etalon = L"";
356         assert_wcs_equal(table_wstr, table_wstr_etalon);
357 #endif
358 #ifdef FT_HAVE_UTF8
359         table_str = ft_to_u8string(table);
360         assert_true(table_str != NULL);
361         assert_str_equal(table_str, table_str_etalon);
362 #endif /* FT_HAVE_UTF8 */
363 
364         ft_set_cur_cell(table, 5, 6);
365         assert_true(ft_is_empty(table) == 1);
366         assert_true(ft_row_count(table) == 0);
367         ft_destroy_table(table);
368     }
369 
370     WHEN("Empty string content") {
371         table = ft_create_table();
372         assert_true(table != NULL);
373         assert_true(ft_is_empty(table) == 1);
374         assert_true(ft_write_ln(table, "") == FT_SUCCESS);
375         assert_true(ft_is_empty(table) == 0);
376         assert_true(ft_row_count(table) == 1);
377 
378         const char *table_str = ft_to_string(table);
379         const char *table_str_etalon =
380             "+--+\n"
381             "|  |\n"
382             "+--+\n";
383         assert_str_equal(table_str, table_str_etalon);
384 
385         ft_destroy_table(table);
386     }
387 
388     WHEN("All columns are equal and not empty") {
389         table = ft_create_table();
390         assert_true(table != NULL);
391         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
392 
393         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
394         assert_true(ft_write_ln(table, "3", "c", "234", "3.140000") == FT_SUCCESS);
395         assert_true(ft_write_ln(table, "3", "c", "234", "3.140000") == FT_SUCCESS);
396         assert_true(ft_write_ln(table, "3", "c", "234", "3.140000") == FT_SUCCESS);
397         assert_true(ft_is_empty(table) == 0);
398         assert_true(ft_row_count(table) == 3);
399 
400         const char *table_str = ft_to_string(table);
401         assert_true(table_str != NULL);
402         const char *table_str_etalon =
403             "+---+---+-----+----------+\n"
404             "|   |   |     |          |\n"
405             "| 3 | c | 234 | 3.140000 |\n"
406             "|   |   |     |          |\n"
407             "+---+---+-----+----------+\n"
408             "|   |   |     |          |\n"
409             "| 3 | c | 234 | 3.140000 |\n"
410             "|   |   |     |          |\n"
411             "+---+---+-----+----------+\n"
412             "|   |   |     |          |\n"
413             "| 3 | c | 234 | 3.140000 |\n"
414             "|   |   |     |          |\n"
415             "+---+---+-----+----------+\n";
416         assert_str_equal(table_str, table_str_etalon);
417         ft_destroy_table(table);
418     }
419 
420 #ifdef FT_HAVE_WCHAR
421     WHEN("All columns are equal and not empty (wide strings)") {
422         table = ft_create_table();
423         assert_true(table != NULL);
424         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
425 
426         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
427         assert_true(ft_wwrite_ln(table, L"3", L"c", L"234", L"3.140000") == FT_SUCCESS);
428         assert_true(ft_wwrite_ln(table, L"3", L"c", L"234", L"3.140000") == FT_SUCCESS);
429         assert_true(ft_wwrite_ln(table, L"3", L"c", L"234", L"3.140000") == FT_SUCCESS);
430 
431         const wchar_t *table_str = ft_to_wstring(table);
432         assert_true(table_str != NULL);
433         const wchar_t *table_str_etalon =
434             L"+---+---+-----+----------+\n"
435             L"|   |   |     |          |\n"
436             L"| 3 | c | 234 | 3.140000 |\n"
437             L"|   |   |     |          |\n"
438             L"+---+---+-----+----------+\n"
439             L"|   |   |     |          |\n"
440             L"| 3 | c | 234 | 3.140000 |\n"
441             L"|   |   |     |          |\n"
442             L"+---+---+-----+----------+\n"
443             L"|   |   |     |          |\n"
444             L"| 3 | c | 234 | 3.140000 |\n"
445             L"|   |   |     |          |\n"
446             L"+---+---+-----+----------+\n";
447         assert_wcs_equal(table_str, table_str_etalon);
448         ft_destroy_table(table);
449     }
450 #endif
451 
452 #ifdef FT_HAVE_UTF8
453     WHEN("All columns are equal and not empty (utf8 strings)") {
454         table = ft_create_table();
455         assert_true(table != NULL);
456         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
457 
458         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
459         assert_true(ft_u8write_ln(table, "3", "c", "234", "3.140000") == FT_SUCCESS);
460         assert_true(ft_u8write_ln(table, "3", "c", "234", "3.140000") == FT_SUCCESS);
461         assert_true(ft_u8write_ln(table, "3", "c", "234", "3.140000") == FT_SUCCESS);
462 
463         const char *table_str = ft_to_u8string(table);
464         assert_true(table_str != NULL);
465 
466         const char *table_str_etalon =
467             "+---+---+-----+----------+\n"
468             "|   |   |     |          |\n"
469             "| 3 | c | 234 | 3.140000 |\n"
470             "|   |   |     |          |\n"
471             "+---+---+-----+----------+\n"
472             "|   |   |     |          |\n"
473             "| 3 | c | 234 | 3.140000 |\n"
474             "|   |   |     |          |\n"
475             "+---+---+-----+----------+\n"
476             "|   |   |     |          |\n"
477             "| 3 | c | 234 | 3.140000 |\n"
478             "|   |   |     |          |\n"
479             "+---+---+-----+----------+\n";
480         assert_str_equal(table_str, table_str_etalon);
481         ft_destroy_table(table);
482     }
483 #endif /* FT_HAVE_UTF8 */
484 
485     WHEN("All columns are not equal and not empty") {
486         table = ft_create_table();
487         assert_true(table != NULL);
488         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
489 
490         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
491         assert_true(ft_write_ln(table, "3", "c", "234", "3.140000") == FT_SUCCESS);
492         assert_true(ft_write_ln(table, "c", "234", "3.140000", "3") == FT_SUCCESS);
493         assert_true(ft_write_ln(table, "234", "3.140000", "3", "c") == FT_SUCCESS);
494 
495         const char *table_str = ft_to_string(table);
496         assert_true(table_str != NULL);
497         const char *table_str_etalon =
498             "+-----+----------+----------+----------+\n"
499             "|     |          |          |          |\n"
500             "| 3   | c        | 234      | 3.140000 |\n"
501             "|     |          |          |          |\n"
502             "+-----+----------+----------+----------+\n"
503             "|     |          |          |          |\n"
504             "| c   | 234      | 3.140000 | 3        |\n"
505             "|     |          |          |          |\n"
506             "+-----+----------+----------+----------+\n"
507             "|     |          |          |          |\n"
508             "| 234 | 3.140000 | 3        | c        |\n"
509             "|     |          |          |          |\n"
510             "+-----+----------+----------+----------+\n";
511         assert_str_equal(table_str, table_str_etalon);
512         ft_destroy_table(table);
513     }
514 
515 #ifdef FT_HAVE_WCHAR
516     WHEN("All columns are not equal and not empty (wide strings)") {
517         table = ft_create_table();
518         assert_true(table != NULL);
519         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
520 
521         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
522         assert_true(ft_wwrite_ln(table, L"3", L"c", L"234", L"3.140000") == FT_SUCCESS);
523         assert_true(ft_wwrite_ln(table, L"c", L"234", L"3.140000", L"3") == FT_SUCCESS);
524         assert_true(ft_wwrite_ln(table, L"234", L"3.140000", L"3", L"c") == FT_SUCCESS);
525 
526         const wchar_t *table_str = ft_to_wstring(table);
527         assert_true(table_str != NULL);
528         const wchar_t *table_str_etalon =
529             L"+-----+----------+----------+----------+\n"
530             L"|     |          |          |          |\n"
531             L"| 3   | c        | 234      | 3.140000 |\n"
532             L"|     |          |          |          |\n"
533             L"+-----+----------+----------+----------+\n"
534             L"|     |          |          |          |\n"
535             L"| c   | 234      | 3.140000 | 3        |\n"
536             L"|     |          |          |          |\n"
537             L"+-----+----------+----------+----------+\n"
538             L"|     |          |          |          |\n"
539             L"| 234 | 3.140000 | 3        | c        |\n"
540             L"|     |          |          |          |\n"
541             L"+-----+----------+----------+----------+\n";
542         assert_wcs_equal(table_str, table_str_etalon);
543         ft_destroy_table(table);
544     }
545 #endif
546 
547 #ifdef FT_HAVE_UTF8
548     WHEN("All columns are not equal and not empty") {
549         table = ft_create_table();
550         assert_true(table != NULL);
551         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
552 
553         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
554         assert_true(ft_u8write_ln(table, "3", "c", "234", "3.140000") == FT_SUCCESS);
555         assert_true(ft_u8write_ln(table, "c", "234", "3.140000", "3") == FT_SUCCESS);
556         assert_true(ft_u8write_ln(table, "234", "3.140000", "3", "c") == FT_SUCCESS);
557 
558         const char *table_str = ft_to_u8string(table);
559         assert_true(table_str != NULL);
560         const char *table_str_etalon =
561             "+-----+----------+----------+----------+\n"
562             "|     |          |          |          |\n"
563             "| 3   | c        | 234      | 3.140000 |\n"
564             "|     |          |          |          |\n"
565             "+-----+----------+----------+----------+\n"
566             "|     |          |          |          |\n"
567             "| c   | 234      | 3.140000 | 3        |\n"
568             "|     |          |          |          |\n"
569             "+-----+----------+----------+----------+\n"
570             "|     |          |          |          |\n"
571             "| 234 | 3.140000 | 3        | c        |\n"
572             "|     |          |          |          |\n"
573             "+-----+----------+----------+----------+\n";
574         assert_str_equal(table_str, table_str_etalon);
575         ft_destroy_table(table);
576     }
577 #endif /* FT_HAVE_UTF8 */
578 
579     WHEN("All columns are not equal and some cells are empty") {
580         table = ft_create_table();
581         assert_true(table != NULL);
582         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
583 
584         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
585         assert_true(ft_write_ln(table, "", "", "234", "3.140000") == FT_SUCCESS);
586         assert_true(ft_write_ln(table, "c", "234", "3.140000", "") == FT_SUCCESS);
587         assert_true(ft_write_ln(table, "234", "3.140000", "", "") == FT_SUCCESS);
588 
589         const char *table_str = ft_to_string(table);
590         assert_true(table_str != NULL);
591         const char *table_str_etalon =
592             "+-----+----------+----------+----------+\n"
593             "|     |          |          |          |\n"
594             "|     |          | 234      | 3.140000 |\n"
595             "|     |          |          |          |\n"
596             "+-----+----------+----------+----------+\n"
597             "|     |          |          |          |\n"
598             "| c   | 234      | 3.140000 |          |\n"
599             "|     |          |          |          |\n"
600             "+-----+----------+----------+----------+\n"
601             "|     |          |          |          |\n"
602             "| 234 | 3.140000 |          |          |\n"
603             "|     |          |          |          |\n"
604             "+-----+----------+----------+----------+\n";
605         assert_str_equal(table_str, table_str_etalon);
606         ft_destroy_table(table);
607     }
608 
609 #ifdef FT_HAVE_WCHAR
610     WHEN("All columns are not equal and some cells are empty (wide strings)") {
611         table = ft_create_table();
612         assert_true(table != NULL);
613         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
614 
615         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
616         assert_true(ft_wwrite_ln(table, L"", L"", L"234", L"3.140000") == FT_SUCCESS);
617         assert_true(ft_wwrite_ln(table, L"c", L"234", L"3.140000", L"") == FT_SUCCESS);
618         assert_true(ft_wwrite_ln(table, L"234", L"3.140000", L"", L"") == FT_SUCCESS);
619 
620         const wchar_t *table_str = ft_to_wstring(table);
621         assert_true(table_str != NULL);
622         const wchar_t *table_str_etalon =
623             L"+-----+----------+----------+----------+\n"
624             L"|     |          |          |          |\n"
625             L"|     |          | 234      | 3.140000 |\n"
626             L"|     |          |          |          |\n"
627             L"+-----+----------+----------+----------+\n"
628             L"|     |          |          |          |\n"
629             L"| c   | 234      | 3.140000 |          |\n"
630             L"|     |          |          |          |\n"
631             L"+-----+----------+----------+----------+\n"
632             L"|     |          |          |          |\n"
633             L"| 234 | 3.140000 |          |          |\n"
634             L"|     |          |          |          |\n"
635             L"+-----+----------+----------+----------+\n";
636         assert_wcs_equal(table_str, table_str_etalon);
637         ft_destroy_table(table);
638     }
639 #endif
640 
641 #ifdef FT_HAVE_UTF8
642     WHEN("All columns are not equal and some cells are empty (utf-8 strings)") {
643         table = ft_create_table();
644         assert_true(table != NULL);
645         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
646 
647         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
648         assert_true(ft_u8write_ln(table, "", "", "234", "3.140000") == FT_SUCCESS);
649         assert_true(ft_u8write_ln(table, "c", "234", "3.140000", "") == FT_SUCCESS);
650         assert_true(ft_u8write_ln(table, "234", "3.140000", "", "") == FT_SUCCESS);
651 
652         const char *table_str = ft_to_u8string(table);
653         assert_true(table_str != NULL);
654         const char *table_str_etalon =
655             "+-----+----------+----------+----------+\n"
656             "|     |          |          |          |\n"
657             "|     |          | 234      | 3.140000 |\n"
658             "|     |          |          |          |\n"
659             "+-----+----------+----------+----------+\n"
660             "|     |          |          |          |\n"
661             "| c   | 234      | 3.140000 |          |\n"
662             "|     |          |          |          |\n"
663             "+-----+----------+----------+----------+\n"
664             "|     |          |          |          |\n"
665             "| 234 | 3.140000 |          |          |\n"
666             "|     |          |          |          |\n"
667             "+-----+----------+----------+----------+\n";
668         assert_str_equal(table_str, table_str_etalon);
669         ft_destroy_table(table);
670     }
671 #endif /* FT_HAVE_UTF8 */
672 
673     WHEN("All cells are empty") {
674         table = ft_create_table();
675         assert_true(table != NULL);
676         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
677 
678         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
679         assert_true(ft_write_ln(table, "", "", "", "") == FT_SUCCESS);
680         assert_true(ft_write_ln(table, "", "", "", "") == FT_SUCCESS);
681         assert_true(ft_write_ln(table, "", "", "", "") == FT_SUCCESS);
682 
683         const char *table_str = ft_to_string(table);
684         assert_true(table_str != NULL);
685         const char *table_str_etalon =
686             "+--+--+--+--+\n"
687             "|  |  |  |  |\n"
688             "|  |  |  |  |\n"
689             "|  |  |  |  |\n"
690             "+--+--+--+--+\n"
691             "|  |  |  |  |\n"
692             "|  |  |  |  |\n"
693             "|  |  |  |  |\n"
694             "+--+--+--+--+\n"
695             "|  |  |  |  |\n"
696             "|  |  |  |  |\n"
697             "|  |  |  |  |\n"
698             "+--+--+--+--+\n";
699         assert_str_equal(table_str, table_str_etalon);
700         ft_destroy_table(table);
701     }
702 
703 #ifdef FT_HAVE_WCHAR
704     WHEN("All cells are empty (wide strings)") {
705         table = ft_create_table();
706         assert_true(table != NULL);
707         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
708 
709         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
710         assert_true(ft_wwrite_ln(table, L"", L"", L"", L"") == FT_SUCCESS);
711         assert_true(ft_wwrite_ln(table, L"", L"", L"", L"") == FT_SUCCESS);
712         assert_true(ft_wwrite_ln(table, L"", L"", L"", L"") == FT_SUCCESS);
713 
714         const wchar_t *table_str = ft_to_wstring(table);
715         assert_true(table_str != NULL);
716         const wchar_t *table_str_etalon =
717             L"+--+--+--+--+\n"
718             L"|  |  |  |  |\n"
719             L"|  |  |  |  |\n"
720             L"|  |  |  |  |\n"
721             L"+--+--+--+--+\n"
722             L"|  |  |  |  |\n"
723             L"|  |  |  |  |\n"
724             L"|  |  |  |  |\n"
725             L"+--+--+--+--+\n"
726             L"|  |  |  |  |\n"
727             L"|  |  |  |  |\n"
728             L"|  |  |  |  |\n"
729             L"+--+--+--+--+\n";
730         assert_wcs_equal(table_str, table_str_etalon);
731         ft_destroy_table(table);
732     }
733 #endif
734 
735     WHEN("Multiline conten") {
736         table = ft_create_table();
737         assert_true(table != NULL);
738         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
739 
740         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
741         assert_true(ft_write_ln(table, "3", "c", "234\n2", "3.140000") == FT_SUCCESS);
742         assert_true(ft_write_ln(table, "3", "c", "234", "3.140000\n123") == FT_SUCCESS);
743         assert_true(ft_write_ln(table, "3", "c", "234", "x") == FT_SUCCESS);
744 
745         ft_set_cell_prop(table, FT_ANY_ROW, 3, FT_CPROP_TEXT_ALIGN, FT_ALIGNED_RIGHT);
746 
747         const char *table_str = ft_to_string(table);
748         assert_true(table_str != NULL);
749         const char *table_str_etalon =
750             "+---+---+-----+----------+\n"
751             "|   |   |     |          |\n"
752             "| 3 | c | 234 | 3.140000 |\n"
753             "|   |   | 2   |          |\n"
754             "|   |   |     |          |\n"
755             "+---+---+-----+----------+\n"
756             "|   |   |     |          |\n"
757             "| 3 | c | 234 | 3.140000 |\n"
758             "|   |   |     | 123      |\n"             /* todo: Fix strange alignment for multiline cells */
759             "|   |   |     |          |\n"
760             "+---+---+-----+----------+\n"
761             "|   |   |     |          |\n"
762             "| 3 | c | 234 |        x |\n"
763             "|   |   |     |          |\n"
764             "+---+---+-----+----------+\n";
765         assert_str_equal(table_str, table_str_etalon);
766         ft_destroy_table(table);
767     }
768 }
769 
770 
771 
772 #ifdef FT_HAVE_WCHAR
test_wcs_table_boundaries(void)773 void test_wcs_table_boundaries(void)
774 {
775     ft_table_t *table = NULL;
776 
777     WHEN("All columns are not equal and not empty (wide strings)") {
778         table = ft_create_table();
779         assert_true(table != NULL);
780         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
781 
782         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
783         assert_true(ft_wwrite_ln(table, L"3", L"12345\x8888\x8888", L"c") == FT_SUCCESS);   /* \x8888,\x8888  - occupy 2 columns each */
784         assert_true(ft_wwrite_ln(table, L"c", L"12345678\x500", L"c") == FT_SUCCESS);  /* \x500  - occupies 1 column */
785         assert_true(ft_wwrite_ln(table, L"234", L"123456789", L"c") == FT_SUCCESS);
786 
787         const wchar_t *table_str = ft_to_wstring(table);
788         assert_true(table_str != NULL);
789         const wchar_t *table_str_etalon =
790             L"+-----+-----------+---+\n"
791             L"|     |           |   |\n"
792             L"| 3   | 12345\x8888\x8888 | c |\n"
793             L"|     |           |   |\n"
794             L"+-----+-----------+---+\n"
795             L"|     |           |   |\n"
796             L"| c   | 12345678\x500 | c |\n"
797             L"|     |           |   |\n"
798             L"+-----+-----------+---+\n"
799             L"|     |           |   |\n"
800             L"| 234 | 123456789 | c |\n"
801             L"|     |           |   |\n"
802             L"+-----+-----------+---+\n";
803         assert_wcs_equal(table_str, table_str_etalon);
804         ft_destroy_table(table);
805     }
806 }
807 #endif
808 
809 #ifdef FT_HAVE_UTF8
test_utf8_table(void)810 void test_utf8_table(void)
811 {
812     ft_table_t *table = NULL;
813 
814 #define TEST_UTF8_SIMPLE(content) \
815     { \
816             table = ft_create_table(); \
817             assert_true(table != NULL); \
818             assert(ft_set_border_style(table, FT_EMPTY_STYLE) == 0); \
819             assert_true(ft_u8write_ln(table, content) == FT_SUCCESS); \
820             const char *table_str = ft_to_u8string(table); \
821             assert_true(table_str != NULL); \
822             char table_str_etalon[1024] = {'\0'}; \
823             snprintf(table_str_etalon, 1024," %s \n", content); \
824             assert_str_equal(table_str, table_str_etalon); \
825             ft_destroy_table(table); \
826     }
827     TEST_UTF8_SIMPLE("");
828     TEST_UTF8_SIMPLE("1");
829     TEST_UTF8_SIMPLE("foo");
830     TEST_UTF8_SIMPLE("1234567890");
831     TEST_UTF8_SIMPLE("Xylophmsik");
832     TEST_UTF8_SIMPLE("ψημένηζειθ");
833     TEST_UTF8_SIMPLE("D’ḟuascail");
834     TEST_UTF8_SIMPLE("Pójdźżełąć");
835     TEST_UTF8_SIMPLE("«braçõeshá");
836     TEST_UTF8_SIMPLE("французких");
837     TEST_UTF8_SIMPLE("Benjamínúñ");
838     TEST_UTF8_SIMPLE("görmüştüçğ");
839     TEST_UTF8_SIMPLE("視野無限廣窗外有藍天");
840     TEST_UTF8_SIMPLE("いろはにほへとちりぬ");
841     TEST_UTF8_SIMPLE("��������������������");
842 #undef TEST_UTF8_SIMPLE
843 
844 #define TEST_UTF8_SIMPLE_STYLE(content) \
845     { \
846             table = ft_create_table(); \
847             assert_true(table != NULL); \
848             assert(ft_set_border_style(table, FT_EMPTY_STYLE) == 0); \
849             assert_true(ft_u8write_ln(table, content) == FT_SUCCESS); \
850             assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CONT_FG_COLOR, FT_COLOR_YELLOW) == FT_SUCCESS); \
851             assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CELL_BG_COLOR, FT_COLOR_RED) == FT_SUCCESS); \
852             assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CONT_TEXT_STYLE, FT_TSTYLE_UNDERLINED) == FT_SUCCESS); \
853             const char *table_str = ft_to_u8string(table); \
854             assert_true(table_str != NULL); \
855             char table_str_etalon[1024] = {'\0'}; \
856             snprintf(table_str_etalon, 1024, \
857                 "\033[41m \033[4m\033[33m%s\033[0m\033[41m \033[0m\n", content); \
858             assert_str_equal(table_str, table_str_etalon); \
859             ft_destroy_table(table); \
860     }
861     TEST_UTF8_SIMPLE_STYLE("1234567890");
862     TEST_UTF8_SIMPLE_STYLE("Xylophmsik");
863     TEST_UTF8_SIMPLE_STYLE("ψημένηζειθ");
864     TEST_UTF8_SIMPLE_STYLE("D’ḟuascail");
865     TEST_UTF8_SIMPLE_STYLE("Pójdźżełąć");
866     TEST_UTF8_SIMPLE_STYLE("«braçõeshá");
867     TEST_UTF8_SIMPLE_STYLE("французких");
868     TEST_UTF8_SIMPLE_STYLE("Benjamínúñ");
869     TEST_UTF8_SIMPLE_STYLE("görmüştüçğ");
870     TEST_UTF8_SIMPLE_STYLE("視野無限廣窗外有藍天");
871     TEST_UTF8_SIMPLE_STYLE("いろはにほへとちりぬ");
872     TEST_UTF8_SIMPLE_STYLE("��������������������");
873 #undef TEST_UTF8_SIMPLE_STYLE
874 
875 #define TEST_UTF8_BORDER(content) \
876     { \
877             table = ft_create_table(); \
878             assert_true(table != NULL); \
879             assert(ft_set_border_style(table, FT_BASIC_STYLE) == 0); \
880             assert_true(ft_u8write_ln(table, content) == FT_SUCCESS); \
881             const char *table_str = ft_to_u8string(table); \
882             assert_true(table_str != NULL); \
883             char table_str_etalon[1024] = {'\0'}; \
884             snprintf(table_str_etalon, 1024, \
885                 "+------------+\n"  \
886                 "| %s |\n" \
887                 "+------------+\n", content); \
888             assert_str_equal(table_str, table_str_etalon); \
889             ft_destroy_table(table); \
890     }
891 
892 #define TEST_UTF8_BORDER_WIDE(content) \
893     { \
894             table = ft_create_table(); \
895             assert_true(table != NULL); \
896             assert(ft_set_border_style(table, FT_BASIC_STYLE) == 0); \
897             assert_true(ft_u8write_ln(table, content) == FT_SUCCESS); \
898             const char *table_str = ft_to_u8string(table); \
899             assert_true(table_str != NULL); \
900             char table_str_etalon[1024] = {'\0'}; \
901             snprintf(table_str_etalon, 1024, \
902                 "+----------------------+\n"  \
903                 "| %s |\n" \
904                 "+----------------------+\n", content); \
905             assert_str_equal(table_str, table_str_etalon); \
906             ft_destroy_table(table); \
907     }
908 
909     TEST_UTF8_BORDER("1234567890");
910     TEST_UTF8_BORDER("Xylophmsik");
911     TEST_UTF8_BORDER("ψημένηζειθ");
912     TEST_UTF8_BORDER("D’ḟuascail");
913     TEST_UTF8_BORDER("Pójdźżełąć");
914     TEST_UTF8_BORDER("«braçõeshá");
915     TEST_UTF8_BORDER("французких");
916     TEST_UTF8_BORDER("Benjamínúñ");
917     TEST_UTF8_BORDER("görmüştüçğ");
918     TEST_UTF8_BORDER_WIDE("視野無限廣窗外有藍天");
919     TEST_UTF8_BORDER_WIDE("いろはにほへとちりぬ");
920     TEST_UTF8_BORDER_WIDE("��������������������");
921 #undef TEST_UTF8_BORDER
922 #undef TEST_UTF8_BORDER_WIDE
923 
924 #define TEST_UTF8_STYLE(content) \
925     { \
926             table = ft_create_table(); \
927             assert_true(table != NULL); \
928             assert(ft_set_border_style(table, FT_BASIC_STYLE) == 0); \
929             assert_true(ft_u8write_ln(table, content) == FT_SUCCESS); \
930             assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CONT_FG_COLOR, FT_COLOR_YELLOW) == FT_SUCCESS); \
931             assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CELL_BG_COLOR, FT_COLOR_RED) == FT_SUCCESS); \
932             assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CONT_TEXT_STYLE, FT_TSTYLE_UNDERLINED) == FT_SUCCESS); \
933             const char *table_str = ft_to_u8string(table); \
934             assert_true(table_str != NULL); \
935             char table_str_etalon[1024] = {'\0'}; \
936             snprintf(table_str_etalon, 1024, \
937                 "+------------+\n"  \
938                 "|\033[41m \033[4m\033[33m%s\033[0m\033[41m \033[0m|\n" \
939                 "+------------+\n", content); \
940             assert_str_equal(table_str, table_str_etalon); \
941             ft_destroy_table(table); \
942     }
943 #define TEST_UTF8_STYLE_WIDE(content) \
944     { \
945             table = ft_create_table(); \
946             assert_true(table != NULL); \
947             assert(ft_set_border_style(table, FT_BASIC_STYLE) == 0); \
948             assert_true(ft_u8write_ln(table, content) == FT_SUCCESS); \
949             assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CONT_FG_COLOR, FT_COLOR_YELLOW) == FT_SUCCESS); \
950             assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CELL_BG_COLOR, FT_COLOR_RED) == FT_SUCCESS); \
951             assert(ft_set_cell_prop(table, 0, 0, FT_CPROP_CONT_TEXT_STYLE, FT_TSTYLE_UNDERLINED) == FT_SUCCESS); \
952             const char *table_str = ft_to_u8string(table); \
953             assert_true(table_str != NULL); \
954             char table_str_etalon[1024] = {'\0'}; \
955             snprintf(table_str_etalon, 1024, \
956                 "+----------------------+\n"  \
957                 "|\033[41m \033[4m\033[33m%s\033[0m\033[41m \033[0m|\n" \
958                 "+----------------------+\n", content); \
959             assert_str_equal(table_str, table_str_etalon); \
960             ft_destroy_table(table); \
961     }
962     TEST_UTF8_STYLE("1234567890");
963     TEST_UTF8_STYLE("Xylophmsik");
964     TEST_UTF8_STYLE("ψημένηζειθ");
965     TEST_UTF8_STYLE("D’ḟuascail");
966     TEST_UTF8_STYLE("Pójdźżełąć");
967     TEST_UTF8_STYLE("«braçõeshá");
968     TEST_UTF8_STYLE("французких");
969     TEST_UTF8_STYLE("Benjamínúñ");
970     TEST_UTF8_STYLE("görmüştüçğ");
971     TEST_UTF8_STYLE_WIDE("視野無限廣窗外有藍天");
972     TEST_UTF8_STYLE_WIDE("いろはにほへとちりぬ");
973     TEST_UTF8_STYLE_WIDE("��������������������");
974 #undef TEST_UTF8_STYLE
975 #undef TEST_UTF8_STYLE_WIDE
976 
977 }
978 #endif /* FT_HAVE_UTF8 */
979 
test_table_write(void)980 void test_table_write(void)
981 {
982     ft_table_t *table = NULL;
983 
984     SCENARIO("Test write functions") {
985         table = ft_create_table();
986         assert_true(table != NULL);
987         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
988 
989         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
990         assert_true(FT_IS_SUCCESS(ft_write(table, "3")));
991         assert_true(FT_IS_SUCCESS(ft_write(table, "c")));
992         assert_true(FT_IS_SUCCESS(ft_write(table, "234")));
993         assert_true(FT_IS_SUCCESS(ft_write(table, "3.140000")));
994         ft_ln(table);
995         assert_true(FT_IS_SUCCESS(ft_write(table, "c")));
996         assert_true(FT_IS_SUCCESS(ft_write(table, "235")));
997         assert_true(FT_IS_SUCCESS(ft_write(table, "3.150000")));
998         assert_true(FT_IS_SUCCESS(ft_write_ln(table, "5")));
999 
1000         assert_true(FT_IS_SUCCESS(ft_write(table, "234")));
1001         assert_true(FT_IS_SUCCESS(ft_write(table, "3.140000")));
1002         assert_true(FT_IS_SUCCESS(ft_write(table, "3")));
1003         assert_true(FT_IS_SUCCESS(ft_write_ln(table, "c")));
1004 
1005         /* Replace old values */
1006         ft_set_cur_cell(table, 1, 1);
1007         assert_true(FT_IS_SUCCESS(ft_write(table, "234")));
1008         assert_true(FT_IS_SUCCESS(ft_write(table, "3.140000")));
1009         assert_true(FT_IS_SUCCESS(ft_write_ln(table, "3")));
1010 
1011         const char *table_str = ft_to_string(table);
1012         assert_true(table_str != NULL);
1013         const char *table_str_etalon =
1014             "+-----+----------+----------+----------+\n"
1015             "|     |          |          |          |\n"
1016             "| 3   | c        | 234      | 3.140000 |\n"
1017             "|     |          |          |          |\n"
1018             "+-----+----------+----------+----------+\n"
1019             "|     |          |          |          |\n"
1020             "| c   | 234      | 3.140000 | 3        |\n"
1021             "|     |          |          |          |\n"
1022             "+-----+----------+----------+----------+\n"
1023             "|     |          |          |          |\n"
1024             "| 234 | 3.140000 | 3        | c        |\n"
1025             "|     |          |          |          |\n"
1026             "+-----+----------+----------+----------+\n";
1027         assert_str_equal(table_str, table_str_etalon);
1028         ft_destroy_table(table);
1029     }
1030 
1031 #ifdef FT_HAVE_WCHAR
1032     SCENARIO("Test wwrite functions(wide strings)") {
1033         table = ft_create_table();
1034         assert_true(table != NULL);
1035         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
1036 
1037         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
1038         assert_true(FT_IS_SUCCESS(ft_wwrite(table, L"3")));
1039         assert_true(FT_IS_SUCCESS(ft_wwrite(table, L"c")));
1040         assert_true(FT_IS_SUCCESS(ft_wwrite(table, L"234")));
1041         assert_true(FT_IS_SUCCESS(ft_wwrite(table, L"3.140000")));
1042         ft_ln(table);
1043         assert_true(FT_IS_SUCCESS(ft_wwrite(table, L"c")));
1044         assert_true(FT_IS_SUCCESS(ft_wwrite(table, L"235")));
1045         assert_true(FT_IS_SUCCESS(ft_wwrite(table, L"3.150000")));
1046         assert_true(FT_IS_SUCCESS(ft_wwrite_ln(table, L"5")));
1047 
1048         assert_true(FT_IS_SUCCESS(ft_wwrite(table, L"234")));
1049         assert_true(FT_IS_SUCCESS(ft_wwrite(table, L"3.140000")));
1050         assert_true(FT_IS_SUCCESS(ft_wwrite(table, L"3")));
1051         assert_true(FT_IS_SUCCESS(ft_wwrite_ln(table, L"c")));
1052 
1053         /* Replace old values */
1054         ft_set_cur_cell(table, 1, 1);
1055         assert_true(FT_IS_SUCCESS(ft_wwrite(table, L"234")));
1056         assert_true(FT_IS_SUCCESS(ft_wwrite(table, L"3.140000")));
1057         assert_true(FT_IS_SUCCESS(ft_wwrite_ln(table, L"3")));
1058 
1059         const wchar_t *table_str = ft_to_wstring(table);
1060         assert_true(table_str != NULL);
1061         const wchar_t *table_str_etalon =
1062             L"+-----+----------+----------+----------+\n"
1063             L"|     |          |          |          |\n"
1064             L"| 3   | c        | 234      | 3.140000 |\n"
1065             L"|     |          |          |          |\n"
1066             L"+-----+----------+----------+----------+\n"
1067             L"|     |          |          |          |\n"
1068             L"| c   | 234      | 3.140000 | 3        |\n"
1069             L"|     |          |          |          |\n"
1070             L"+-----+----------+----------+----------+\n"
1071             L"|     |          |          |          |\n"
1072             L"| 234 | 3.140000 | 3        | c        |\n"
1073             L"|     |          |          |          |\n"
1074             L"+-----+----------+----------+----------+\n";
1075         assert_wcs_equal(table_str, table_str_etalon);
1076         ft_destroy_table(table);
1077     }
1078 #endif
1079 
1080 #ifdef FT_HAVE_UTF8
1081     SCENARIO("Test wwrite functions(utf8 strings)") {
1082         table = ft_create_table();
1083         assert_true(table != NULL);
1084         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
1085 
1086         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
1087         assert_true(FT_IS_SUCCESS(ft_u8write(table, "3")));
1088         assert_true(FT_IS_SUCCESS(ft_u8write(table, "c")));
1089         assert_true(FT_IS_SUCCESS(ft_u8write(table, "234")));
1090         assert_true(FT_IS_SUCCESS(ft_u8write(table, "3.140000")));
1091         ft_ln(table);
1092         assert_true(FT_IS_SUCCESS(ft_u8write(table, "c")));
1093         assert_true(FT_IS_SUCCESS(ft_u8write(table, "235")));
1094         assert_true(FT_IS_SUCCESS(ft_u8write(table, "3.150000")));
1095         assert_true(FT_IS_SUCCESS(ft_u8write_ln(table, "5")));
1096 
1097         assert_true(FT_IS_SUCCESS(ft_u8write(table, "234")));
1098         assert_true(FT_IS_SUCCESS(ft_u8write(table, "3.140000")));
1099         assert_true(FT_IS_SUCCESS(ft_u8write(table, "3")));
1100         assert_true(FT_IS_SUCCESS(ft_u8write_ln(table, "c")));
1101 
1102         /* Replace old values */
1103         ft_set_cur_cell(table, 1, 1);
1104         assert_true(FT_IS_SUCCESS(ft_u8write(table, "234")));
1105         assert_true(FT_IS_SUCCESS(ft_u8write(table, "3.140000")));
1106         assert_true(FT_IS_SUCCESS(ft_u8write_ln(table, "3")));
1107 
1108         const char *table_str = ft_to_u8string(table);
1109         assert_true(table_str != NULL);
1110         const char *table_str_etalon =
1111             "+-----+----------+----------+----------+\n"
1112             "|     |          |          |          |\n"
1113             "| 3   | c        | 234      | 3.140000 |\n"
1114             "|     |          |          |          |\n"
1115             "+-----+----------+----------+----------+\n"
1116             "|     |          |          |          |\n"
1117             "| c   | 234      | 3.140000 | 3        |\n"
1118             "|     |          |          |          |\n"
1119             "+-----+----------+----------+----------+\n"
1120             "|     |          |          |          |\n"
1121             "| 234 | 3.140000 | 3        | c        |\n"
1122             "|     |          |          |          |\n"
1123             "+-----+----------+----------+----------+\n";
1124         assert_str_equal(table_str, table_str_etalon);
1125         ft_destroy_table(table);
1126     }
1127 #endif
1128 
1129     SCENARIO("Test nwrite functions") {
1130         table = ft_create_table();
1131         assert_true(table != NULL);
1132         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
1133 
1134         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
1135         assert_true(ft_nwrite(table, 4, "3", "c", "234", "3.140000") == FT_SUCCESS);
1136         ft_ln(table);
1137         assert_true(ft_nwrite_ln(table, 4, "c", "235", "3.150000", "5") == FT_SUCCESS);
1138         assert_true(ft_nwrite_ln(table, 4, "234", "3.140000", "3", "c") == FT_SUCCESS);
1139 
1140         /* Replace old values */
1141         ft_set_cur_cell(table, 1, 1);
1142         assert_true(ft_nwrite_ln(table, 3, "234", "3.140000", "3") == FT_SUCCESS);
1143 
1144         const char *table_str = ft_to_string(table);
1145         assert_true(table_str != NULL);
1146         const char *table_str_etalon =
1147             "+-----+----------+----------+----------+\n"
1148             "|     |          |          |          |\n"
1149             "| 3   | c        | 234      | 3.140000 |\n"
1150             "|     |          |          |          |\n"
1151             "+-----+----------+----------+----------+\n"
1152             "|     |          |          |          |\n"
1153             "| c   | 234      | 3.140000 | 3        |\n"
1154             "|     |          |          |          |\n"
1155             "+-----+----------+----------+----------+\n"
1156             "|     |          |          |          |\n"
1157             "| 234 | 3.140000 | 3        | c        |\n"
1158             "|     |          |          |          |\n"
1159             "+-----+----------+----------+----------+\n";
1160         assert_str_equal(table_str, table_str_etalon);
1161         ft_destroy_table(table);
1162     }
1163 
1164 #ifdef FT_HAVE_WCHAR
1165     SCENARIO("Test nwwrite functions(wide strings)") {
1166         table = ft_create_table();
1167         assert_true(table != NULL);
1168         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
1169 
1170         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
1171         assert_true(ft_nwwrite(table, 4, L"3", L"c", L"234", L"3.140000") == FT_SUCCESS);
1172         ft_ln(table);
1173         assert_true(ft_nwwrite_ln(table, 4, L"c", L"235", L"3.150000", L"5") == FT_SUCCESS);
1174         assert_true(ft_nwwrite_ln(table, 4, L"234", L"3.140000", L"3", L"c") == FT_SUCCESS);
1175 
1176         /* Replace old values */
1177         ft_set_cur_cell(table, 1, 1);
1178         assert_true(ft_nwwrite_ln(table, 3, L"234", L"3.140000", L"3") == FT_SUCCESS);
1179 
1180         const wchar_t *table_str = ft_to_wstring(table);
1181         assert_true(table_str != NULL);
1182         const wchar_t *table_str_etalon =
1183             L"+-----+----------+----------+----------+\n"
1184             L"|     |          |          |          |\n"
1185             L"| 3   | c        | 234      | 3.140000 |\n"
1186             L"|     |          |          |          |\n"
1187             L"+-----+----------+----------+----------+\n"
1188             L"|     |          |          |          |\n"
1189             L"| c   | 234      | 3.140000 | 3        |\n"
1190             L"|     |          |          |          |\n"
1191             L"+-----+----------+----------+----------+\n"
1192             L"|     |          |          |          |\n"
1193             L"| 234 | 3.140000 | 3        | c        |\n"
1194             L"|     |          |          |          |\n"
1195             L"+-----+----------+----------+----------+\n";
1196         assert_wcs_equal(table_str, table_str_etalon);
1197         ft_destroy_table(table);
1198     }
1199 #endif
1200 
1201 #ifdef FT_HAVE_UTF8
1202     SCENARIO("Test nwwrite functions(utf8 strings)") {
1203         table = ft_create_table();
1204         assert_true(table != NULL);
1205         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
1206 
1207         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
1208         assert_true(ft_u8nwrite(table, 4, "3", "c", "234", "3.140000") == FT_SUCCESS);
1209         ft_ln(table);
1210         assert_true(ft_u8nwrite_ln(table, 4, "c", "235", "3.150000", "5") == FT_SUCCESS);
1211         assert_true(ft_u8nwrite_ln(table, 4, "234", "3.140000", "3", "c") == FT_SUCCESS);
1212 
1213         /* Replace old values */
1214         ft_set_cur_cell(table, 1, 1);
1215         assert_true(ft_u8nwrite_ln(table, 3, "234", "3.140000", "3") == FT_SUCCESS);
1216 
1217         const char *table_str = ft_to_u8string(table);
1218         assert_true(table_str != NULL);
1219         const char *table_str_etalon =
1220             "+-----+----------+----------+----------+\n"
1221             "|     |          |          |          |\n"
1222             "| 3   | c        | 234      | 3.140000 |\n"
1223             "|     |          |          |          |\n"
1224             "+-----+----------+----------+----------+\n"
1225             "|     |          |          |          |\n"
1226             "| c   | 234      | 3.140000 | 3        |\n"
1227             "|     |          |          |          |\n"
1228             "+-----+----------+----------+----------+\n"
1229             "|     |          |          |          |\n"
1230             "| 234 | 3.140000 | 3        | c        |\n"
1231             "|     |          |          |          |\n"
1232             "+-----+----------+----------+----------+\n";
1233         assert_str_equal(table_str, table_str_etalon);
1234         ft_destroy_table(table);
1235     }
1236 #endif /* FT_HAVE_UTF8 */
1237 
1238     SCENARIO("Test row_write functions") {
1239         table = ft_create_table();
1240         assert_true(table != NULL);
1241         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
1242 
1243         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
1244         const char *row_0[4] = {"3", "c", "234", "3.140000"};
1245         const char *row_1[4] = {"c", "235", "3.150000", "5"};
1246         const char *row_2[4] = {"234", "3.140000", "3", "c"};
1247         assert_true(ft_row_write_ln(table, 4, row_0) == FT_SUCCESS);
1248         assert_true(ft_row_write(table, 4, row_1) == FT_SUCCESS);
1249         ft_ln(table);
1250         assert_true(ft_row_write_ln(table, 4, row_2) == FT_SUCCESS);
1251 
1252         /* Replace old values */
1253         ft_set_cur_cell(table, 1, 1);
1254         const char *row_11[3] = {"234", "3.140000", "3"};
1255         assert_true(ft_row_write(table, 3, row_11) == FT_SUCCESS);
1256         ft_ln(table);
1257 
1258         const char *table_str = ft_to_string(table);
1259         assert_true(table_str != NULL);
1260         const char *table_str_etalon =
1261             "+-----+----------+----------+----------+\n"
1262             "|     |          |          |          |\n"
1263             "| 3   | c        | 234      | 3.140000 |\n"
1264             "|     |          |          |          |\n"
1265             "+-----+----------+----------+----------+\n"
1266             "|     |          |          |          |\n"
1267             "| c   | 234      | 3.140000 | 3        |\n"
1268             "|     |          |          |          |\n"
1269             "+-----+----------+----------+----------+\n"
1270             "|     |          |          |          |\n"
1271             "| 234 | 3.140000 | 3        | c        |\n"
1272             "|     |          |          |          |\n"
1273             "+-----+----------+----------+----------+\n";
1274         assert_str_equal(table_str, table_str_etalon);
1275         ft_destroy_table(table);
1276     }
1277 
1278 #ifdef FT_HAVE_WCHAR
1279     SCENARIO("Test row_write functions(wide strings)") {
1280         table = ft_create_table();
1281         assert_true(table != NULL);
1282         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
1283 
1284         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
1285         const wchar_t *row_0[4] = {L"3", L"c", L"234", L"3.140000"};
1286         const wchar_t *row_1[4] = {L"c", L"235", L"3.150000", L"5"};
1287         const wchar_t *row_2[4] = {L"234", L"3.140000", L"3", L"c"};
1288         assert_true(ft_row_wwrite_ln(table, 4, row_0) == FT_SUCCESS);
1289         assert_true(ft_row_wwrite(table, 4, row_1) == FT_SUCCESS);
1290         ft_ln(table);
1291         assert_true(ft_row_wwrite_ln(table, 4, row_2) == FT_SUCCESS);
1292 
1293         /* Replace old values */
1294         ft_set_cur_cell(table, 1, 1);
1295         const wchar_t *row_11[3] = {L"234", L"3.140000", L"3"};
1296         assert_true(ft_row_wwrite(table, 3, row_11) == FT_SUCCESS);
1297         ft_ln(table);
1298 
1299         const wchar_t *table_str = ft_to_wstring(table);
1300         assert_true(table_str != NULL);
1301         const wchar_t *table_str_etalon =
1302             L"+-----+----------+----------+----------+\n"
1303             L"|     |          |          |          |\n"
1304             L"| 3   | c        | 234      | 3.140000 |\n"
1305             L"|     |          |          |          |\n"
1306             L"+-----+----------+----------+----------+\n"
1307             L"|     |          |          |          |\n"
1308             L"| c   | 234      | 3.140000 | 3        |\n"
1309             L"|     |          |          |          |\n"
1310             L"+-----+----------+----------+----------+\n"
1311             L"|     |          |          |          |\n"
1312             L"| 234 | 3.140000 | 3        | c        |\n"
1313             L"|     |          |          |          |\n"
1314             L"+-----+----------+----------+----------+\n";
1315         assert_wcs_equal(table_str, table_str_etalon);
1316         ft_destroy_table(table);
1317     }
1318 #endif
1319 
1320     SCENARIO("Test table_write functions") {
1321         table = ft_create_table();
1322         assert_true(table != NULL);
1323         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
1324 
1325         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
1326         const char *table_cont[3][4] = {
1327             {"3", "c", "234", "3.140000"},
1328             {"c", "234", "3.140000", "3"},
1329             {"234", "3.140000", "3", "c"}
1330         };
1331         assert_true(ft_table_write_ln(table, 3, 4, (const char **)table_cont) == FT_SUCCESS);
1332 
1333         const char *table_str = ft_to_string(table);
1334         assert_true(table_str != NULL);
1335         const char *table_str_etalon =
1336             "+-----+----------+----------+----------+\n"
1337             "|     |          |          |          |\n"
1338             "| 3   | c        | 234      | 3.140000 |\n"
1339             "|     |          |          |          |\n"
1340             "+-----+----------+----------+----------+\n"
1341             "|     |          |          |          |\n"
1342             "| c   | 234      | 3.140000 | 3        |\n"
1343             "|     |          |          |          |\n"
1344             "+-----+----------+----------+----------+\n"
1345             "|     |          |          |          |\n"
1346             "| 234 | 3.140000 | 3        | c        |\n"
1347             "|     |          |          |          |\n"
1348             "+-----+----------+----------+----------+\n";
1349         assert_str_equal(table_str, table_str_etalon);
1350         ft_destroy_table(table);
1351     }
1352 
1353 #ifdef FT_HAVE_WCHAR
1354     SCENARIO("Test table_write functions(wide strings)") {
1355         table = ft_create_table();
1356         assert_true(table != NULL);
1357         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
1358 
1359         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
1360         const wchar_t *table_cont[3][4] = {
1361             {L"3", L"c", L"234", L"3.140000"},
1362             {L"c", L"234", L"3.140000", L"3"},
1363             {L"234", L"3.140000", L"3", L"c"}
1364         };
1365         assert_true(ft_table_wwrite_ln(table, 3, 4, (const wchar_t **)table_cont) == FT_SUCCESS);
1366 
1367         const wchar_t *table_str = ft_to_wstring(table);
1368         assert_true(table_str != NULL);
1369         const wchar_t *table_str_etalon =
1370             L"+-----+----------+----------+----------+\n"
1371             L"|     |          |          |          |\n"
1372             L"| 3   | c        | 234      | 3.140000 |\n"
1373             L"|     |          |          |          |\n"
1374             L"+-----+----------+----------+----------+\n"
1375             L"|     |          |          |          |\n"
1376             L"| c   | 234      | 3.140000 | 3        |\n"
1377             L"|     |          |          |          |\n"
1378             L"+-----+----------+----------+----------+\n"
1379             L"|     |          |          |          |\n"
1380             L"| 234 | 3.140000 | 3        | c        |\n"
1381             L"|     |          |          |          |\n"
1382             L"+-----+----------+----------+----------+\n";
1383         assert_wcs_equal(table_str, table_str_etalon);
1384         ft_destroy_table(table);
1385     }
1386 #endif
1387 
1388     SCENARIO("Test printf functions") {
1389         table = ft_create_table();
1390         assert_true(table != NULL);
1391         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
1392 
1393         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
1394         int n = ft_printf_ln(table, "%d|%c|%s|%f", 3, 'c', "234", 3.14);
1395         assert_true(n == 4);
1396         n = ft_printf(table, "%c|%s|%f|%d", 'c', "235", 3.15, 5);
1397         assert_true(n == 4);
1398         ft_ln(table);
1399         n = ft_printf_ln(table, "%s|%f|%d|%c", "234", 3.14,  3, 'c');
1400         assert_true(n == 4);
1401 
1402         /* Replace old values */
1403         ft_set_cur_cell(table, 1, 1);
1404         n = ft_printf(table, "%s|%f|%d", "234", 3.14, 3);
1405         assert_true(n == 3);
1406 
1407         const char *table_str = ft_to_string(table);
1408         assert_true(table_str != NULL);
1409         const char *table_str_etalon =
1410             "+-----+----------+----------+----------+\n"
1411             "|     |          |          |          |\n"
1412             "| 3   | c        | 234      | 3.140000 |\n"
1413             "|     |          |          |          |\n"
1414             "+-----+----------+----------+----------+\n"
1415             "|     |          |          |          |\n"
1416             "| c   | 234      | 3.140000 | 3        |\n"
1417             "|     |          |          |          |\n"
1418             "+-----+----------+----------+----------+\n"
1419             "|     |          |          |          |\n"
1420             "| 234 | 3.140000 | 3        | c        |\n"
1421             "|     |          |          |          |\n"
1422             "+-----+----------+----------+----------+\n";
1423         assert_str_equal(table_str, table_str_etalon);
1424         ft_destroy_table(table);
1425     }
1426 
1427 #ifdef FT_HAVE_WCHAR
1428     SCENARIO("Test printf functions(wide strings)") {
1429         table = ft_create_table();
1430         assert_true(table != NULL);
1431         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
1432 
1433         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
1434         int n = ft_wprintf_ln(table, L"%d|%c|%ls|%f", 3, 'c', L"234", 3.14);
1435         assert_true(n == 4);
1436         n = ft_wprintf(table, L"%c|%ls|%f|%d", 'c', L"235", 3.15, 5);
1437         assert_true(n == 4);
1438         ft_ln(table);
1439         n = ft_wprintf_ln(table, L"%ls|%f|%d|%c", L"234", 3.14,  3, 'c');
1440         assert_true(n == 4);
1441 
1442         /* Replace old values */
1443         ft_set_cur_cell(table, 1, 1);
1444         n = ft_wprintf_ln(table, L"%ls|%f|%d", L"234", 3.14, 3);
1445         assert_true(n == 3);
1446 
1447         const wchar_t *table_str = ft_to_wstring(table);
1448         assert_true(table_str != NULL);
1449         const wchar_t *table_str_etalon =
1450             L"+-----+----------+----------+----------+\n"
1451             L"|     |          |          |          |\n"
1452             L"| 3   | c        | 234      | 3.140000 |\n"
1453             L"|     |          |          |          |\n"
1454             L"+-----+----------+----------+----------+\n"
1455             L"|     |          |          |          |\n"
1456             L"| c   | 234      | 3.140000 | 3        |\n"
1457             L"|     |          |          |          |\n"
1458             L"+-----+----------+----------+----------+\n"
1459             L"|     |          |          |          |\n"
1460             L"| 234 | 3.140000 | 3        | c        |\n"
1461             L"|     |          |          |          |\n"
1462             L"+-----+----------+----------+----------+\n";
1463         assert_wcs_equal(table_str, table_str_etalon);
1464         ft_destroy_table(table);
1465     }
1466 #endif
1467 
1468 #ifdef FT_HAVE_UTF8
1469     SCENARIO("Test printf functions(utf8 strings)") {
1470         table = ft_create_table();
1471         assert_true(table != NULL);
1472         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
1473 
1474         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
1475         int n = ft_u8printf_ln(table, "%d|%c|%s|%f", 3, 'c', "234", 3.14);
1476         assert_true(n == 4);
1477         n = ft_u8printf(table, "%c|%s|%f|%d", 'c', "235", 3.15, 5);
1478         assert_true(n == 4);
1479         ft_ln(table);
1480         n = ft_u8printf_ln(table, "%s|%f|%d|%c", "234", 3.14,  3, 'c');
1481         assert_true(n == 4);
1482 
1483         /* Replace old values */
1484         ft_set_cur_cell(table, 1, 1);
1485         n = ft_u8printf(table, "%s|%f|%d", "234", 3.14, 3);
1486         assert_true(n == 3);
1487 
1488         const char *table_str = ft_to_u8string(table);
1489         assert_true(table_str != NULL);
1490         const char *table_str_etalon =
1491             "+-----+----------+----------+----------+\n"
1492             "|     |          |          |          |\n"
1493             "| 3   | c        | 234      | 3.140000 |\n"
1494             "|     |          |          |          |\n"
1495             "+-----+----------+----------+----------+\n"
1496             "|     |          |          |          |\n"
1497             "| c   | 234      | 3.140000 | 3        |\n"
1498             "|     |          |          |          |\n"
1499             "+-----+----------+----------+----------+\n"
1500             "|     |          |          |          |\n"
1501             "| 234 | 3.140000 | 3        | c        |\n"
1502             "|     |          |          |          |\n"
1503             "+-----+----------+----------+----------+\n";
1504         assert_str_equal(table_str, table_str_etalon);
1505         ft_destroy_table(table);
1506     }
1507 #endif
1508 
1509     SCENARIO("Test printf functions with strings with separators inside them") {
1510         table = ft_create_table();
1511         assert_true(table != NULL);
1512         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
1513 
1514         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
1515         int n = ft_printf_ln(table, "%d|%c|%s|%f", 3, 'c', "234", 3.14);
1516         assert_true(n == 4);
1517         n = ft_printf(table, "%c", 'c');
1518         assert_true(n == 1);
1519         n = ft_printf(table, "%s", "234");
1520         assert_true(n == 1);
1521         n = ft_printf(table, "%s", "string|with separator");
1522         assert_true(n == 1);
1523         n = ft_printf(table, "3");
1524         assert_true(n == 1);
1525         ft_ln(table);
1526         n = ft_printf_ln(table, "%s|%f|%d|%c", "234", 3.14,  3, 'c');
1527         assert_true(n == 4);
1528 
1529         const char *table_str = ft_to_string(table);
1530         assert_true(table_str != NULL);
1531         const char *table_str_etalon =
1532             "+-----+----------+-----------------------+----------+\n"
1533             "|     |          |                       |          |\n"
1534             "| 3   | c        | 234                   | 3.140000 |\n"
1535             "|     |          |                       |          |\n"
1536             "+-----+----------+-----------------------+----------+\n"
1537             "|     |          |                       |          |\n"
1538             "| c   | 234      | string|with separator | 3        |\n"
1539             "|     |          |                       |          |\n"
1540             "+-----+----------+-----------------------+----------+\n"
1541             "|     |          |                       |          |\n"
1542             "| 234 | 3.140000 | 3                     | c        |\n"
1543             "|     |          |                       |          |\n"
1544             "+-----+----------+-----------------------+----------+\n";
1545         assert_str_equal(table_str, table_str_etalon);
1546         ft_destroy_table(table);
1547     }
1548 
1549 #ifdef FT_HAVE_WCHAR
1550     SCENARIO("Test printf functions with strings with separators inside them") {
1551         table = ft_create_table();
1552         assert_true(table != NULL);
1553         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
1554 
1555         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
1556         int n = ft_wprintf_ln(table, L"%d|%c|%ls|%f", 3, 'c', L"234", 3.14);
1557         assert_true(n == 4);
1558         n = ft_wprintf(table, L"%c", 'c');
1559         assert_true(n == 1);
1560         n = ft_wprintf(table, L"%ls", L"234");
1561         assert_true(n == 1);
1562         n = ft_wprintf(table, L"%ls", L"string|with separator");
1563         assert_true(n == 1);
1564         n = ft_wprintf(table, L"3");
1565         assert_true(n == 1);
1566         ft_ln(table);
1567         n = ft_wprintf_ln(table, L"%ls|%f|%d|%c", L"234", 3.14,  3, 'c');
1568         assert_true(n == 4);
1569 
1570         const wchar_t *table_str = ft_to_wstring(table);
1571         assert_true(table_str != NULL);
1572         const wchar_t *table_str_etalon =
1573             L"+-----+----------+-----------------------+----------+\n"
1574             L"|     |          |                       |          |\n"
1575             L"| 3   | c        | 234                   | 3.140000 |\n"
1576             L"|     |          |                       |          |\n"
1577             L"+-----+----------+-----------------------+----------+\n"
1578             L"|     |          |                       |          |\n"
1579             L"| c   | 234      | string|with separator | 3        |\n"
1580             L"|     |          |                       |          |\n"
1581             L"+-----+----------+-----------------------+----------+\n"
1582             L"|     |          |                       |          |\n"
1583             L"| 234 | 3.140000 | 3                     | c        |\n"
1584             L"|     |          |                       |          |\n"
1585             L"+-----+----------+-----------------------+----------+\n";
1586         assert_wcs_equal(table_str, table_str_etalon);
1587         ft_destroy_table(table);
1588     }
1589 #endif
1590 
1591 #ifdef FT_HAVE_UTF8
1592     SCENARIO("Test printf functions with strings with separators inside them") {
1593         table = ft_create_table();
1594         assert_true(table != NULL);
1595         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
1596 
1597         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
1598         int n = ft_u8printf_ln(table, "%d|%c|%s|%f", 3, 'c', "234", 3.14);
1599         assert_true(n == 4);
1600         n = ft_u8printf(table, "%c", 'c');
1601         assert_true(n == 1);
1602         n = ft_u8printf(table, "%s", "234");
1603         assert_true(n == 1);
1604         n = ft_u8printf(table, "%s", "string|with separator");
1605         assert_true(n == 1);
1606         n = ft_u8printf(table, "3");
1607         assert_true(n == 1);
1608         ft_ln(table);
1609         n = ft_u8printf_ln(table, "%s|%f|%d|%c", "234", 3.14,  3, 'c');
1610         assert_true(n == 4);
1611 
1612         const char *table_str = ft_to_u8string(table);
1613         assert_true(table_str != NULL);
1614         const char *table_str_etalon =
1615             "+-----+----------+-----------------------+----------+\n"
1616             "|     |          |                       |          |\n"
1617             "| 3   | c        | 234                   | 3.140000 |\n"
1618             "|     |          |                       |          |\n"
1619             "+-----+----------+-----------------------+----------+\n"
1620             "|     |          |                       |          |\n"
1621             "| c   | 234      | string|with separator | 3        |\n"
1622             "|     |          |                       |          |\n"
1623             "+-----+----------+-----------------------+----------+\n"
1624             "|     |          |                       |          |\n"
1625             "| 234 | 3.140000 | 3                     | c        |\n"
1626             "|     |          |                       |          |\n"
1627             "+-----+----------+-----------------------+----------+\n";
1628         assert_str_equal(table_str, table_str_etalon);
1629         ft_destroy_table(table);
1630     }
1631 #endif
1632 
1633     SCENARIO("Test printf functions with custom separator") {
1634         ft_set_default_printf_field_separator('$');
1635         table = ft_create_table();
1636         assert_true(table != NULL);
1637         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
1638 
1639         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
1640         int n = ft_printf_ln(table, "%d$%c$%s$%f", 3, 'c', "234", 3.14);
1641         assert_true(n == 4);
1642         n = ft_printf(table, "%c$%s$%f$%d", 'c', "235", 3.15, 5);
1643         assert_true(n == 4);
1644         ft_ln(table);
1645         n = ft_printf_ln(table, "%s$%f$%d$%c", "234", 3.14,  3, 'c');
1646         assert_true(n == 4);
1647 
1648         /* Replace old values */
1649         ft_set_cur_cell(table, 1, 1);
1650         n = ft_printf(table, "%s$%f$%d", "234", 3.14, 3);
1651         assert_true(n == 3);
1652 
1653         const char *table_str = ft_to_string(table);
1654         assert_true(table_str != NULL);
1655         const char *table_str_etalon =
1656             "+-----+----------+----------+----------+\n"
1657             "|     |          |          |          |\n"
1658             "| 3   | c        | 234      | 3.140000 |\n"
1659             "|     |          |          |          |\n"
1660             "+-----+----------+----------+----------+\n"
1661             "|     |          |          |          |\n"
1662             "| c   | 234      | 3.140000 | 3        |\n"
1663             "|     |          |          |          |\n"
1664             "+-----+----------+----------+----------+\n"
1665             "|     |          |          |          |\n"
1666             "| 234 | 3.140000 | 3        | c        |\n"
1667             "|     |          |          |          |\n"
1668             "+-----+----------+----------+----------+\n";
1669         assert_str_equal(table_str, table_str_etalon);
1670         ft_destroy_table(table);
1671         ft_set_default_printf_field_separator('|');
1672     }
1673 
1674 #ifdef FT_HAVE_WCHAR
1675     SCENARIO("Test printf functions(wide strings)  with custom separator") {
1676         ft_set_default_printf_field_separator('$');
1677         table = ft_create_table();
1678         assert_true(table != NULL);
1679         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
1680 
1681         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
1682         int n = ft_wprintf_ln(table, L"%d$%c$%ls$%f", 3, 'c', L"234", 3.14);
1683         assert_true(n == 4);
1684         n = ft_wprintf(table, L"%c$%ls$%f$%d", 'c', L"235", 3.15, 5);
1685         assert_true(n == 4);
1686         ft_ln(table);
1687         n = ft_wprintf_ln(table, L"%ls$%f$%d$%c", L"234", 3.14,  3, 'c');
1688         assert_true(n == 4);
1689 
1690         /* Replace old values */
1691         ft_set_cur_cell(table, 1, 1);
1692         n = ft_wprintf_ln(table, L"%ls$%f$%d", L"234", 3.14, 3);
1693         assert_true(n == 3);
1694 
1695         const wchar_t *table_str = ft_to_wstring(table);
1696         assert_true(table_str != NULL);
1697         const wchar_t *table_str_etalon =
1698             L"+-----+----------+----------+----------+\n"
1699             L"|     |          |          |          |\n"
1700             L"| 3   | c        | 234      | 3.140000 |\n"
1701             L"|     |          |          |          |\n"
1702             L"+-----+----------+----------+----------+\n"
1703             L"|     |          |          |          |\n"
1704             L"| c   | 234      | 3.140000 | 3        |\n"
1705             L"|     |          |          |          |\n"
1706             L"+-----+----------+----------+----------+\n"
1707             L"|     |          |          |          |\n"
1708             L"| 234 | 3.140000 | 3        | c        |\n"
1709             L"|     |          |          |          |\n"
1710             L"+-----+----------+----------+----------+\n";
1711         assert_wcs_equal(table_str, table_str_etalon);
1712         ft_destroy_table(table);
1713         ft_set_default_printf_field_separator('|');
1714     }
1715 #endif
1716 
1717 #ifdef FT_HAVE_UTF8
1718     SCENARIO("Test printf functions(utf8 strings)  with custom separator") {
1719         ft_set_default_printf_field_separator('$');
1720         table = ft_create_table();
1721         assert_true(table != NULL);
1722         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
1723 
1724         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
1725         int n = ft_u8printf_ln(table, "%d$%c$%s$%f", 3, 'c', "234", 3.14);
1726         assert_true(n == 4);
1727         n = ft_u8printf(table, "%c$%s$%f$%d", 'c', "235", 3.15, 5);
1728         assert_true(n == 4);
1729         ft_ln(table);
1730         n = ft_u8printf_ln(table, "%s$%f$%d$%c", "234", 3.14,  3, 'c');
1731         assert_true(n == 4);
1732 
1733         /* Replace old values */
1734         ft_set_cur_cell(table, 1, 1);
1735         n = ft_u8printf(table, "%s$%f$%d", "234", 3.14, 3);
1736         assert_true(n == 3);
1737 
1738         const char *table_str = ft_to_u8string(table);
1739         assert_true(table_str != NULL);
1740         const char *table_str_etalon =
1741             "+-----+----------+----------+----------+\n"
1742             "|     |          |          |          |\n"
1743             "| 3   | c        | 234      | 3.140000 |\n"
1744             "|     |          |          |          |\n"
1745             "+-----+----------+----------+----------+\n"
1746             "|     |          |          |          |\n"
1747             "| c   | 234      | 3.140000 | 3        |\n"
1748             "|     |          |          |          |\n"
1749             "+-----+----------+----------+----------+\n"
1750             "|     |          |          |          |\n"
1751             "| 234 | 3.140000 | 3        | c        |\n"
1752             "|     |          |          |          |\n"
1753             "+-----+----------+----------+----------+\n";
1754         assert_str_equal(table_str, table_str_etalon);
1755         ft_destroy_table(table);
1756         ft_set_default_printf_field_separator('|');
1757     }
1758 #endif
1759 
1760     SCENARIO("Test write and printf functions simultaneously") {
1761         table = ft_create_table();
1762         assert_true(table != NULL);
1763         assert_true(FT_IS_SUCCESS(ft_write(table, "0", "1")));
1764         assert_true(FT_IS_SUCCESS(ft_printf(table, "2|3")));
1765         assert_true(FT_IS_SUCCESS(ft_write(table, "5", "6")));
1766 
1767         const char *table_str = ft_to_string(table);
1768         assert_true(table_str != NULL);
1769         const char *table_str_etalon =
1770             "+---+---+---+---+---+---+\n"
1771             "| 0 | 1 | 2 | 3 | 5 | 6 |\n"
1772             "+---+---+---+---+---+---+\n";
1773         assert_str_equal(table_str, table_str_etalon);
1774 
1775         ft_destroy_table(table);
1776     }
1777 }
1778 
test_table_insert_strategy(void)1779 void test_table_insert_strategy(void)
1780 {
1781     SCENARIO("Test ft_ln") {
1782         ft_table_t *table = ft_create_table();
1783         assert_true(table != NULL);
1784         ft_set_tbl_prop(table, FT_TPROP_ADDING_STRATEGY, FT_STRATEGY_INSERT);
1785         assert_true(FT_IS_SUCCESS(ft_write_ln(table, "0", "1", "2")));
1786         ft_set_cur_cell(table, 0, 2);
1787         assert_true(FT_IS_SUCCESS(ft_ln(table)));
1788         ft_set_cur_cell(table, 1, 1);
1789         assert_true(FT_IS_SUCCESS(ft_write(table, "3")));
1790 
1791         const char *table_str = ft_to_string(table);
1792         assert_true(table_str != NULL);
1793         const char *table_str_etalon =
1794             "+---+---+\n"
1795             "| 0 | 1 |\n"
1796             "| 2 | 3 |\n"
1797             "+---+---+\n";
1798         assert_str_equal(table_str, table_str_etalon);
1799 
1800         ft_destroy_table(table);
1801     }
1802 
1803     SCENARIO("Test write functions") {
1804         ft_table_t *table = ft_create_table();
1805         assert_true(table != NULL);
1806         ft_set_tbl_prop(table, FT_TPROP_ADDING_STRATEGY, FT_STRATEGY_INSERT);
1807         assert_true(FT_IS_SUCCESS(ft_write_ln(table, "0", "1", "2", "4", "5")));
1808         ft_set_cur_cell(table, 0, 2);
1809         assert_true(FT_IS_SUCCESS(ft_ln(table)));
1810         ft_set_cur_cell(table, 1, 1);
1811         assert_true(FT_IS_SUCCESS(ft_write_ln(table, "3")));
1812 
1813         const char *table_str = ft_to_string(table);
1814         assert_true(table_str != NULL);
1815         const char *table_str_etalon =
1816             "+---+---+\n"
1817             "| 0 | 1 |\n"
1818             "| 2 | 3 |\n"
1819             "| 4 | 5 |\n"
1820             "+---+---+\n";
1821         assert_str_equal(table_str, table_str_etalon);
1822 
1823         ft_destroy_table(table);
1824     }
1825 
1826     SCENARIO("Test printf functions") {
1827         ft_table_t *table = ft_create_table();
1828         assert_true(table != NULL);
1829         ft_set_tbl_prop(table, FT_TPROP_ADDING_STRATEGY, FT_STRATEGY_INSERT);
1830         assert_true(FT_IS_SUCCESS(ft_write_ln(table, "0", "1", "2", "5", "6")));
1831         ft_set_cur_cell(table, 0, 2);
1832         assert_true(FT_IS_SUCCESS(ft_ln(table)));
1833         ft_set_cur_cell(table, 1, 1);
1834         assert_true(FT_IS_SUCCESS(ft_printf_ln(table, "3|4")));
1835 
1836         const char *table_str = ft_to_string(table);
1837         assert_true(table_str != NULL);
1838         const char *table_str_etalon =
1839             "+---+---+---+\n"
1840             "| 0 | 1 |   |\n"
1841             "| 2 | 3 | 4 |\n"
1842             "| 5 | 6 |   |\n"
1843             "+---+---+---+\n";
1844         assert_str_equal(table_str, table_str_etalon);
1845 
1846         ft_destroy_table(table);
1847     }
1848 }
1849 
test_table_copy(void)1850 void test_table_copy(void)
1851 {
1852     ft_table_t *table = NULL;
1853 
1854     WHEN("Test table copy") {
1855         table = ft_create_table();
1856         assert_true(table != NULL);
1857 
1858         assert_true(ft_set_cell_prop(table, FT_ANY_ROW, FT_ANY_COLUMN, FT_CPROP_BOTTOM_PADDING, 1) == FT_SUCCESS);
1859         assert_true(ft_set_cell_prop(table, FT_ANY_ROW, FT_ANY_COLUMN, FT_CPROP_TOP_PADDING, 1) == FT_SUCCESS);
1860         assert_true(ft_set_cell_prop(table, FT_ANY_ROW, FT_ANY_COLUMN, FT_CPROP_LEFT_PADDING, 2) == FT_SUCCESS);
1861         assert_true(ft_set_cell_prop(table, FT_ANY_ROW, FT_ANY_COLUMN, FT_CPROP_RIGHT_PADDING, 2) == FT_SUCCESS);
1862 
1863 
1864         ft_set_border_style(table, FT_DOUBLE2_STYLE);
1865 
1866         /* Set "header" type for the first row */
1867         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
1868         ft_write_ln(table, "Movie title", "Director", "Year", "Rating");
1869 
1870         ft_write_ln(table, "The Shawshank Redemption", "Frank Darabont", "1994", "9.5");
1871         ft_write_ln(table, "The Godfather", "Francis Ford Coppola", "1972", "9.2");
1872         ft_add_separator(table);
1873 
1874         ft_write_ln(table, "2001: A Space Odyssey", "Stanley Kubrick", "1968", "8.5");
1875 
1876         /* Set center alignment for the 1st and 3rd columns */
1877         ft_set_cell_prop(table, FT_ANY_ROW, 1, FT_CPROP_TEXT_ALIGN, FT_ALIGNED_CENTER);
1878         ft_set_cell_prop(table, FT_ANY_ROW, 3, FT_CPROP_TEXT_ALIGN, FT_ALIGNED_CENTER);
1879 
1880 
1881         ft_table_t *table_copy = ft_copy_table(table);
1882 
1883         assert_true(table != NULL);
1884         const char *table_str = ft_to_string(table_copy);
1885         assert_true(table_str != NULL);
1886         const char *table_str_etalon =
1887             "╔════════════════════════════╤════════════════════════╤════════╤══════════╗\n"
1888             "║                            │                        │        │          ║\n"
1889             "║  Movie title               │        Director        │  Year  │  Rating  ║\n"
1890             "║                            │                        │        │          ║\n"
1891             "╠════════════════════════════╪════════════════════════╪════════╪══════════╣\n"
1892             "║                            │                        │        │          ║\n"
1893             "║  The Shawshank Redemption  │     Frank Darabont     │  1994  │   9.5    ║\n"
1894             "║                            │                        │        │          ║\n"
1895             "╟────────────────────────────┼────────────────────────┼────────┼──────────╢\n"
1896             "║                            │                        │        │          ║\n"
1897             "║  The Godfather             │  Francis Ford Coppola  │  1972  │   9.2    ║\n"
1898             "║                            │                        │        │          ║\n"
1899             "╠════════════════════════════╪════════════════════════╪════════╪══════════╣\n"
1900             "║                            │                        │        │          ║\n"
1901             "║  2001: A Space Odyssey     │    Stanley Kubrick     │  1968  │   8.5    ║\n"
1902             "║                            │                        │        │          ║\n"
1903             "╚════════════════════════════╧════════════════════════╧════════╧══════════╝\n";
1904         assert_str_equal(table_str, table_str_etalon);
1905         ft_destroy_table(table);
1906         ft_destroy_table(table_copy);
1907     }
1908 }
1909 
1910 
1911 
test_table_changing_cell(void)1912 void test_table_changing_cell(void)
1913 {
1914     ft_table_t *table = NULL;
1915 
1916     WHEN("All columns are equal and not empty") {
1917         table = ft_create_table();
1918         assert_true(table != NULL);
1919         assert_true(set_test_props_for_table(table) == FT_SUCCESS);
1920 
1921         ft_set_cell_prop(table, 0, FT_ANY_COLUMN, FT_CPROP_ROW_TYPE, FT_ROW_HEADER);
1922         assert_true(ft_write_ln(table, "3", "c", "234", "3.140000") == FT_SUCCESS);
1923         assert_true(ft_write_ln(table, "3", "c", "234", "3.140000") == FT_SUCCESS);
1924         assert_true(ft_write_ln(table, "3", "c", "234", "3.140000") == FT_SUCCESS);
1925 
1926         assert_true(ft_cur_row(table) == 3);
1927         assert_true(ft_cur_col(table) == 0);
1928 
1929         ft_set_cur_cell(table, 1, 1);
1930         assert_true(ft_cur_row(table) == 1);
1931         assert_true(ft_cur_col(table) == 1);
1932         assert_true(ft_write(table, "A") == FT_SUCCESS);
1933         assert_true(ft_cur_row(table) == 1);
1934         assert_true(ft_cur_col(table) == 2);
1935 
1936         const char *table_str = ft_to_string(table);
1937         assert_true(table_str != NULL);
1938         const char *table_str_etalon =
1939             "+---+---+-----+----------+\n"
1940             "|   |   |     |          |\n"
1941             "| 3 | c | 234 | 3.140000 |\n"
1942             "|   |   |     |          |\n"
1943             "+---+---+-----+----------+\n"
1944             "|   |   |     |          |\n"
1945             "| 3 | A | 234 | 3.140000 |\n"
1946             "|   |   |     |          |\n"
1947             "+---+---+-----+----------+\n"
1948             "|   |   |     |          |\n"
1949             "| 3 | c | 234 | 3.140000 |\n"
1950             "|   |   |     |          |\n"
1951             "+---+---+-----+----------+\n";
1952         assert_str_equal(table_str, table_str_etalon);
1953         ft_destroy_table(table);
1954     }
1955 }
1956 
create_test_table()1957 static struct ft_table *create_test_table()
1958 {
1959     ft_table_t *table = ft_create_table();
1960     assert_true(table != NULL);
1961     ft_set_cell_prop(table, FT_ANY_ROW, FT_ANY_COLUMN, FT_CPROP_BOTTOM_PADDING, 0);
1962     ft_set_cell_prop(table, FT_ANY_ROW, FT_ANY_COLUMN, FT_CPROP_TOP_PADDING, 0);
1963 
1964     ft_write_ln(table, "00", "01", "02");
1965     ft_write_ln(table, "10", "11", "12");
1966     ft_write_ln(table, "20", "21", "22");
1967 
1968     return table;
1969 }
1970 
test_table_erase(void)1971 void test_table_erase(void)
1972 {
1973     WHEN("Invalid arguments") {
1974         ft_table_t *table = create_test_table();
1975 
1976         // invalid rows
1977         assert_true(ft_erase_range(table, 1, 1, 0, 2) == FT_EINVAL);
1978 
1979         // invalid colums
1980         assert_true(ft_erase_range(table, 1, 1, 2, 0) == FT_EINVAL);
1981 
1982         ft_destroy_table(table);
1983     }
1984 
1985     WHEN("Erase one cell") {
1986         ft_table_t *table = create_test_table();
1987         assert_true(FT_IS_SUCCESS(ft_erase_range(table, 1, 1, 1, 1)));
1988 
1989         const char *table_str = ft_to_string(table);
1990         assert_true(table_str != NULL);
1991         const char *table_str_etalon =
1992             "+----+----+----+\n"
1993             "| 00 | 01 | 02 |\n"
1994             "| 10 | 12 |    |\n"
1995             "| 20 | 21 | 22 |\n"
1996             "+----+----+----+\n";
1997         assert_str_equal(table_str, table_str_etalon);
1998         ft_destroy_table(table);
1999     }
2000 
2001     WHEN("Erase one last cell") {
2002         ft_table_t *table = create_test_table();
2003         ft_write_ln(table, "30");
2004         assert_true(FT_IS_SUCCESS(ft_erase_range(table, 3, 0, 3, 0)));
2005 
2006         const char *table_str = ft_to_string(table);
2007         assert_true(table_str != NULL);
2008         const char *table_str_etalon =
2009             "+----+----+----+\n"
2010             "| 00 | 01 | 02 |\n"
2011             "| 10 | 11 | 12 |\n"
2012             "| 20 | 21 | 22 |\n"
2013             "+----+----+----+\n";
2014         assert_str_equal(table_str, table_str_etalon);
2015         ft_destroy_table(table);
2016     }
2017 
2018     WHEN("Erase row") {
2019         ft_table_t *table = create_test_table();
2020         assert_true(FT_IS_SUCCESS(ft_erase_range(table, 1, 0, 1, 999)));
2021 
2022         const char *table_str = ft_to_string(table);
2023         assert_true(table_str != NULL);
2024         const char *table_str_etalon =
2025             "+----+----+----+\n"
2026             "| 00 | 01 | 02 |\n"
2027             "| 20 | 21 | 22 |\n"
2028             "+----+----+----+\n";
2029         assert_str_equal(table_str, table_str_etalon);
2030         ft_destroy_table(table);
2031     }
2032 
2033     WHEN("Erase last row") {
2034         ft_table_t *table = create_test_table();
2035         assert_true(FT_IS_SUCCESS(ft_erase_range(table, 2, 0, 2, 999)));
2036 
2037         const char *table_str = ft_to_string(table);
2038         assert_true(table_str != NULL);
2039         const char *table_str_etalon =
2040             "+----+----+----+\n"
2041             "| 00 | 01 | 02 |\n"
2042             "| 10 | 11 | 12 |\n"
2043             "+----+----+----+\n";
2044         assert_str_equal(table_str, table_str_etalon);
2045         ft_destroy_table(table);
2046     }
2047 
2048     WHEN("Erase column") {
2049         ft_table_t *table = create_test_table();
2050         assert_true(FT_IS_SUCCESS(ft_erase_range(table, 0, 1, 999, 1)));
2051 
2052         const char *table_str = ft_to_string(table);
2053         assert_true(table_str != NULL);
2054         const char *table_str_etalon =
2055             "+----+----+\n"
2056             "| 00 | 02 |\n"
2057             "| 10 | 12 |\n"
2058             "| 20 | 22 |\n"
2059             "+----+----+\n";
2060         assert_str_equal(table_str, table_str_etalon);
2061         ft_destroy_table(table);
2062     }
2063 
2064     WHEN("Erase last column") {
2065         ft_table_t *table = create_test_table();
2066         assert_true(FT_IS_SUCCESS(ft_erase_range(table, 0, 2, 999, 2)));
2067 
2068         const char *table_str = ft_to_string(table);
2069         assert_true(table_str != NULL);
2070         const char *table_str_etalon =
2071             "+----+----+\n"
2072             "| 00 | 01 |\n"
2073             "| 10 | 11 |\n"
2074             "| 20 | 21 |\n"
2075             "+----+----+\n";
2076         assert_str_equal(table_str, table_str_etalon);
2077         ft_destroy_table(table);
2078     }
2079 
2080     WHEN("Erasion lines with separators") {
2081         ft_table_t *table = ft_create_table();
2082         assert_true(table != NULL);
2083         ft_set_cell_prop(table, FT_ANY_ROW, FT_ANY_COLUMN, FT_CPROP_BOTTOM_PADDING, 0);
2084         ft_set_cell_prop(table, FT_ANY_ROW, FT_ANY_COLUMN, FT_CPROP_TOP_PADDING, 0);
2085 
2086         ft_write_ln(table, "00", "01", "02");
2087         ft_write_ln(table, "10", "11", "12");
2088         ft_add_separator(table);
2089         ft_write_ln(table, "20", "21", "22");
2090         ft_write_ln(table, "30", "31", "32");
2091         ft_add_separator(table);
2092         ft_write_ln(table, "40", "41", "42");
2093 
2094         assert_true(FT_IS_SUCCESS(ft_erase_range(table, 1, 0, 2, 9999)));
2095 
2096         const char *table_str = ft_to_string(table);
2097         assert_true(table_str != NULL);
2098         const char *table_str_etalon =
2099             "+----+----+----+\n"
2100             "| 00 | 01 | 02 |\n"
2101             "| 30 | 31 | 32 |\n"
2102             "+----+----+----+\n"
2103             "| 40 | 41 | 42 |\n"
2104             "+----+----+----+\n";
2105         assert_str_equal(table_str, table_str_etalon);
2106         ft_destroy_table(table);
2107     }
2108 
2109 
2110 }
2111