boxes/utest/bxstring_test.c
2023-05-04 21:30:47 +02:00

1019 lines
29 KiB
C

/*
* boxes - Command line filter to draw/remove ASCII boxes around text
* Copyright (c) 1999-2023 Thomas Jensen and the boxes contributors
*
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
* License, version 3, as published by the Free Software Foundation.
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
* details.
* You should have received a copy of the GNU General Public License along with this program.
* If not, see <https://www.gnu.org/licenses/>.
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
/*
* Unit tests of the 'bxstring' module
*/
#include "config.h"
#include <setjmp.h>
#include <stdarg.h>
#include <stddef.h>
#include <cmocka.h>
#include <string.h>
#include "boxes.h"
#include "bxstring.h"
#include "bxstring_test.h"
#include "global_mock.h"
#include "tools.h"
#include "unicode.h"
#include "utest_tools.h"
void test_ascii_simple(void **state)
{
UNUSED(state);
bxstr_t *actual = bxs_from_ascii("foo");
assert_non_null(actual);
assert_non_null(actual->memory);
assert_string_equal("foo", actual->ascii);
assert_int_equal(0, (int) actual->indent);
assert_int_equal(3, (int) actual->num_columns);
assert_int_equal(3, (int) actual->num_chars);
assert_int_equal(3, (int) actual->num_chars_visible);
assert_int_equal(0, (int) actual->num_chars_invisible);
assert_int_equal(0, (int) actual->trailing);
int expected_indexes[] = {0, 1, 2};
assert_array_equal(expected_indexes, actual->first_char, 3);
assert_array_equal(expected_indexes, actual->visible_char, 3);
bxs_free(actual);
}
void test_ascii_illegalchar(void **state)
{
UNUSED(state);
bxstr_t *actual = bxs_from_ascii("illegal \b backspace");
assert_null(actual);
assert_int_equal(1, collect_err_size);
assert_string_equal("boxes: illegal character '\b' (0x00000008) encountered in string\n", collect_err[0]);
}
void test_ascii_null(void **state)
{
UNUSED(state);
bxstr_t *actual = bxs_from_ascii(NULL);
assert_null(actual);
assert_int_equal(1, collect_err_size);
assert_string_equal("boxes: internal error: from_ascii() called with NULL\n", collect_err[0]);
}
void test_ansi_unicode_book(void **state)
{
UNUSED(state);
uint32_t *ustr32 = u32_strconv_from_arg(
"\x1b[38;5;203m \x1b[0m \x1b[38;5;198m x\x1b[0mxx\x1b[38;5;208m\xc3\xa4\x1b[0m\x1b[38;5;203mb\x1b[0m ",
"UTF-8");
assert_non_null(ustr32);
bxstr_t *actual = bxs_from_unicode(ustr32);
assert_non_null(actual);
assert_non_null(actual->memory);
assert_string_equal(" xxxxb ", actual->ascii); // 'ä' replaced by 'x'
assert_int_equal(4, (int) actual->indent);
assert_int_equal(10, (int) actual->num_columns);
assert_int_equal(70, (int) actual->num_chars);
assert_int_equal(10, (int) actual->num_chars_visible);
assert_int_equal(60, (int) actual->num_chars_invisible);
assert_int_equal(1, (int) actual->trailing);
int expected_firstchar_idx[] = {0, 16, 17, 18, 30, 35, 36, 37, 53, 69, 70};
assert_array_equal(expected_firstchar_idx, actual->first_char, 11);
int expected_vischar_idx[] = {11, 16, 17, 29, 30, 35, 36, 48, 64, 69, 70};
assert_array_equal(expected_vischar_idx, actual->visible_char, 11);
BFREE(ustr32);
bxs_free(actual);
}
void test_ansi_unicode_space_kinds(void **state)
{
UNUSED(state);
uint32_t *ustr32 = u32_strconv_from_arg("\xe2\x80\x83\xe2\x80\x82 X", /* em-space, en-space, space, x */
"UTF-8");
assert_non_null(ustr32);
bxstr_t *actual = bxs_from_unicode(ustr32);
assert_non_null(actual);
assert_non_null(actual->memory);
assert_string_equal(" X", actual->ascii);
assert_int_equal(3, (int) actual->indent);
assert_int_equal(4, (int) actual->num_columns);
assert_int_equal(4, (int) actual->num_chars);
assert_int_equal(4, (int) actual->num_chars_visible);
assert_int_equal(0, (int) actual->num_chars_invisible);
assert_int_equal(0, (int) actual->trailing);
int expected_firstchar_idx[] = {0, 1, 2, 3};
assert_array_equal(expected_firstchar_idx, actual->first_char, 4);
int expected_vischar_idx[] = {0, 1, 2, 3};
assert_array_equal(expected_vischar_idx, actual->visible_char, 4);
BFREE(ustr32);
bxs_free(actual);
}
void test_ansi_unicode_chinese(void **state)
{
UNUSED(state);
uint32_t *ustr32 = u32_strconv_from_arg(
"\xe5\x85\xac\xe7\x88\xb8\xe8\xa6\x81\xe9\x81\x93\xef\xbc\x81", /* 公爸要道! */
"UTF-8");
assert_non_null(ustr32);
bxstr_t *actual = bxs_from_unicode(ustr32);
assert_non_null(actual);
assert_non_null(actual->memory);
assert_string_equal("xxxxxxxxxx", actual->ascii);
assert_int_equal(0, (int) actual->indent);
assert_int_equal(10, (int) actual->num_columns);
assert_int_equal(5, (int) actual->num_chars);
assert_int_equal(5, (int) actual->num_chars_visible);
assert_int_equal(0, (int) actual->num_chars_invisible);
assert_int_equal(0, (int) actual->trailing);
int expected_firstchar_idx[] = {0, 1, 2, 3, 4};
assert_array_equal(expected_firstchar_idx, actual->first_char, 5);
int expected_vischar_idx[] = {0, 1, 2, 3, 4};
assert_array_equal(expected_vischar_idx, actual->visible_char, 5);
BFREE(ustr32);
bxs_free(actual);
}
void test_ansi_unicode_empty(void **state)
{
UNUSED(state);
uint32_t *ustr32 = u32_strconv_from_arg("", "UTF-8");
assert_non_null(ustr32);
bxstr_t *actual = bxs_from_unicode(ustr32);
assert_non_null(actual);
assert_non_null(actual->memory);
assert_string_equal("", actual->ascii);
assert_int_equal(0, (int) actual->indent);
assert_int_equal(0, (int) actual->num_columns);
assert_int_equal(0, (int) actual->num_chars);
assert_int_equal(0, (int) actual->num_chars_visible);
assert_int_equal(0, (int) actual->num_chars_invisible);
assert_int_equal(0, (int) actual->trailing);
int expected_firstchar_idx[] = {};
assert_array_equal(expected_firstchar_idx, actual->first_char, 0);
int expected_vischar_idx[] = {};
assert_array_equal(expected_vischar_idx, actual->visible_char, 0);
BFREE(ustr32);
bxs_free(actual);
}
void test_ansi_unicode_blanks(void **state)
{
UNUSED(state);
uint32_t *ustr32 = u32_strconv_from_arg(" ", "UTF-8");
assert_non_null(ustr32);
bxstr_t *actual = bxs_from_unicode(ustr32);
assert_non_null(actual);
assert_non_null(actual->memory);
assert_string_equal(" ", actual->ascii);
assert_int_equal(4, (int) actual->indent);
assert_int_equal(4, (int) actual->num_columns);
assert_int_equal(4, (int) actual->num_chars);
assert_int_equal(4, (int) actual->num_chars_visible);
assert_int_equal(0, (int) actual->num_chars_invisible);
assert_int_equal(0, (int) actual->trailing);
int expected_firstchar_idx[] = {0, 1, 2, 3};
assert_array_equal(expected_firstchar_idx, actual->first_char, 0);
int expected_vischar_idx[] = {0, 1, 2, 3};
assert_array_equal(expected_vischar_idx, actual->visible_char, 0);
BFREE(ustr32);
bxs_free(actual);
}
void test_ansi_unicode_invisible_only(void **state)
{
UNUSED(state);
uint32_t *ustr32 = u32_strconv_from_arg("\x1b[38;5;203m\x1b[0m\x1b[38;5;198m\x1b[m", "UTF-8");
assert_non_null(ustr32);
bxstr_t *actual = bxs_from_unicode(ustr32);
assert_non_null(actual);
assert_non_null(actual->memory);
assert_string_equal("", actual->ascii);
assert_int_equal(0, (int) actual->indent);
assert_int_equal(0, (int) actual->num_columns);
assert_int_equal(29, (int) actual->num_chars);
assert_int_equal(0, (int) actual->num_chars_visible);
assert_int_equal(29, (int) actual->num_chars_invisible);
assert_int_equal(0, (int) actual->trailing);
int expected_firstchar_idx[] = {29};
assert_array_equal(expected_firstchar_idx, actual->first_char, 1);
int expected_vischar_idx[] = {29};
assert_array_equal(expected_vischar_idx, actual->visible_char, 1);
BFREE(ustr32);
bxs_free(actual);
}
void test_ansi_unicode_illegalchar(void **state)
{
UNUSED(state);
uint32_t *ustr32 = u32_strconv_from_arg("illegal \b backspace", "UTF-8");
assert_non_null(ustr32);
bxstr_t *actual = bxs_from_unicode(ustr32);
BFREE(ustr32);
assert_null(actual);
assert_int_equal(1, collect_err_size);
assert_string_equal("boxes: illegal character '\b' (0x00000008) encountered in string\n", collect_err[0]);
}
void test_ansi_unicode_tabs(void **state)
{
UNUSED(state);
uint32_t *ustr32 = u32_strconv_from_arg(" \t", "ASCII");
assert_non_null(ustr32);
bxstr_t *actual = bxs_from_unicode(ustr32);
assert_non_null(actual);
assert_non_null(actual->memory);
assert_string_equal(" ", actual->ascii); /* tab converted to space in ascii representation */
assert_int_equal(2, (int) actual->indent);
assert_int_equal(2, (int) actual->num_columns);
assert_int_equal(2, (int) actual->num_chars);
assert_int_equal(2, (int) actual->num_chars_visible);
assert_int_equal(0, (int) actual->num_chars_invisible);
assert_int_equal(0, (int) actual->trailing);
int expected_firstchar_idx[] = {0, 1, 2};
assert_array_equal(expected_firstchar_idx, actual->first_char, 3);
int expected_vischar_idx[] = {0, 1, 2};
assert_array_equal(expected_vischar_idx, actual->visible_char, 3);
BFREE(ustr32);
bxs_free(actual);
}
void test_ansi_unicode_broken_escapes(void **state)
{
UNUSED(state);
/* "\x1b[38;5;203 X" is the first escape sequence, followed by
* "X " (visible) and
* "\x1b[0m" (regular escape sequence) and
* "__" (visible)
* "\x1b[38;5;203m" (regular, invisible)
* "b" (visible)
* "\x1b[" (broken, counts as invisible, and belonging to the previous 'b')
*/
uint32_t *ustr32 = u32_strconv_from_arg("\x1b[38;5;203 XX \x1b[0m__\x1b[38;5;203mb\x1b[", "ASCII");
fprintf(stderr, "BOO\n");
assert_non_null(ustr32);
bxstr_t *actual = bxs_from_unicode(ustr32);
fprintf(stderr, "BAA\n");
assert_non_null(actual);
assert_non_null(actual->memory);
assert_string_equal("X __b", actual->ascii);
assert_int_equal(0, (int) actual->indent);
assert_int_equal(5, (int) actual->num_columns);
assert_int_equal(34, (int) actual->num_chars);
assert_int_equal(5, (int) actual->num_chars_visible);
assert_int_equal(29, (int) actual->num_chars_invisible);
assert_int_equal(0, (int) actual->trailing);
int expected_firstchar_idx[] = {0, 13, 18, 19, 20, 34};
assert_array_equal(expected_firstchar_idx, actual->first_char, 6);
int expected_vischar_idx[] = {12, 13, 18, 19, 31, 34};
assert_array_equal(expected_vischar_idx, actual->visible_char, 6);
BFREE(ustr32);
bxs_free(actual);
}
void test_ansi_unicode_null(void **state)
{
UNUSED(state);
bxstr_t *actual = bxs_from_unicode(NULL);
assert_null(actual);
assert_int_equal(1, collect_err_size);
assert_string_equal("boxes: internal error: bxs_from_unicode() called with NULL\n", collect_err[0]);
}
void test_bxs_strdup(void **state)
{
UNUSED(state);
bxstr_t *actual = bxs_strdup(NULL);
assert_null(actual);
uint32_t *ustr32 = u32_strconv_from_arg(" x\x1b[38;5;203mc\x1b[0m\x1b[38;5;198mc\x1b[0mx ", "UTF-8");
assert_non_null(ustr32);
bxstr_t *bxstr = bxs_from_unicode(ustr32);
actual = bxs_strdup(bxstr);
assert_non_null(actual);
assert_non_null(actual->memory);
assert_string_equal(" xccx ", actual->ascii);
assert_int_equal(1, (int) actual->indent);
assert_int_equal(7, (int) actual->num_columns);
assert_int_equal(37, (int) actual->num_chars);
assert_int_equal(7, (int) actual->num_chars_visible);
assert_int_equal(30, (int) actual->num_chars_invisible);
assert_int_equal(2, (int) actual->trailing);
int expected_firstchar_idx[] = {0, 1, 2, 18, 34, 35, 36, 37};
assert_array_equal(expected_firstchar_idx, actual->first_char, 8);
int expected_vischar_idx[] = {0, 1, 13, 29, 34, 35, 36, 37};
assert_array_equal(expected_vischar_idx, actual->visible_char, 8);
BFREE(ustr32);
bxs_free(actual);
bxs_free(bxstr);
}
void test_bxs_trimdup_null(void **state)
{
UNUSED(state);
bxstr_t *actual = bxs_trimdup(NULL, 0, 0);
assert_null(actual);
assert_int_equal(0, collect_err_size);
}
void test_bxs_trimdup_invalid_startidx(void **state)
{
UNUSED(state);
bxstr_t *input = bxs_from_ascii("foo");
bxstr_t *actual = bxs_trimdup(input, 1000, 1000);
assert_null(actual);
assert_int_equal(1, collect_err_size);
assert_string_equal("boxes: internal error: start_idx out of bounds in bxs_trimdup()\n", collect_err[0]);
bxs_free(input);
}
void test_bxs_trimdup_invalid_endidx(void **state)
{
UNUSED(state);
bxstr_t *input = bxs_from_ascii("foo");
bxstr_t *actual = bxs_trimdup(input, 0, 1000);
assert_null(actual);
assert_int_equal(1, collect_err_size);
assert_string_equal("boxes: internal error: end_idx out of bounds in bxs_trimdup()\n", collect_err[0]);
bxs_free(input);
}
void test_bxs_trimdup_invalid_endidx2(void **state)
{
UNUSED(state);
bxstr_t *input = bxs_from_ascii("foo");
bxstr_t *actual = bxs_trimdup(input, 2, 1);
assert_null(actual);
assert_int_equal(1, collect_err_size);
assert_string_equal("boxes: internal error: end_idx before start_idx in bxs_trimdup()\n", collect_err[0]);
bxs_free(input);
}
void test_bxs_trimdup_normal(void **state)
{
UNUSED(state);
bxstr_t *input = bxs_from_ascii("A, foo, B");
bxstr_t *actual = bxs_trimdup(input, 2, 6);
assert_non_null(actual);
assert_string_equal("foo", actual->ascii);
assert_int_equal(3, actual->num_chars);
bxs_free(input);
bxs_free(actual);
}
void test_bxs_trimdup_vanish(void **state)
{
UNUSED(state);
bxstr_t *input = bxs_from_ascii("A, , B");
bxstr_t *actual = bxs_trimdup(input, 2, 6);
assert_non_null(actual);
assert_string_equal("", actual->ascii);
assert_int_equal(0, actual->num_chars);
bxs_free(input);
bxs_free(actual);
}
void test_bxs_trimdup_ansi(void **state)
{
UNUSED(state);
uint32_t *ustr32 = u32_strconv_from_arg("\x1b[38;5;203m \x1b[0m \x1b[38;5;203m \x1b[0m"
"\x1b[38;5;203mX\x1b[0m\x1b[38;5;203mX\x1b[0m\x1b[38;5;198m \x1b[0m ", "UTF-8");
assert_non_null(ustr32);
bxstr_t *input = bxs_from_unicode(ustr32);
assert_int_equal(7, input->num_chars_visible);
assert_int_equal(3, input->indent);
assert_int_equal(2, input->trailing);
bxstr_t *actual = bxs_trimdup(input, 0, input->num_chars_visible);
assert_non_null(actual);
assert_string_equal("XX", actual->ascii);
assert_int_equal(32, actual->num_chars);
assert_int_equal(30, actual->num_chars_invisible);
assert_int_equal(2, actual->num_chars_visible);
assert_int_equal(2, actual->num_columns);
assert_int_equal(0, actual->indent);
BFREE(ustr32);
bxs_free(input);
bxs_free(actual);
}
void test_bxs_trimdup_ansi_same(void **state)
{
UNUSED(state);
uint32_t *ustr32 = u32_strconv_from_arg("X \x1b[38;5;203mX\x1b[0m\x1b[38;5;198m \x1b[0mX", "UTF-8");
assert_non_null(ustr32);
bxstr_t *input = bxs_from_unicode(ustr32);
assert_int_equal(5, input->num_chars_visible);
assert_int_equal(0, input->indent);
assert_int_equal(0, input->trailing);
bxstr_t *actual = bxs_trimdup(input, 0, input->num_chars_visible);
assert_non_null(actual);
assert_string_equal("X X X", actual->ascii);
assert_int_equal(input->indent, actual->indent);
assert_int_equal(input->num_columns, actual->num_columns);
assert_int_equal(input->num_chars, actual->num_chars);
assert_int_equal(input->num_chars_visible, actual->num_chars_visible);
assert_int_equal(input->num_chars_invisible, actual->num_chars_invisible);
assert_int_equal(input->trailing, actual->trailing);
assert_memory_equal(input->memory, actual->memory, input->num_chars * sizeof(ucs4_t));
assert_memory_equal(input->ascii, actual->ascii, input->num_columns * sizeof(char));
assert_memory_equal(input->first_char, actual->first_char, input->num_chars_visible * sizeof(size_t));
assert_memory_equal(input->visible_char, actual->visible_char, input->num_chars_visible * sizeof(size_t));
BFREE(ustr32);
bxs_free(input);
bxs_free(actual);
}
void test_bxs_strcat_empty(void **state)
{
UNUSED(state);
uint32_t *ustr32 = u32_strconv_from_arg("x", "UTF-8");
assert_non_null(ustr32);
bxstr_t *bxstr = bxs_from_unicode(ustr32);
bxstr_t *actual = bxs_strcat(NULL, ustr32);
assert_non_null(actual);
assert_string_equal("x", actual->ascii);
bxs_free(actual);
actual = bxs_strcat(bxstr, NULL);
assert_non_null(actual);
assert_string_equal("x", actual->ascii);
bxs_free(actual);
BFREE(ustr32);
bxs_free(bxstr);
}
void test_bxs_strcat_empty2(void **state)
{
UNUSED(state);
uint32_t *ustr32_x = u32_strconv_from_arg("x", "UTF-8");
uint32_t *ustr32_empty = u32_strconv_from_arg("", "UTF-8");
assert_non_null(ustr32_x);
assert_non_null(ustr32_empty);
bxstr_t *bxstr = bxs_from_unicode(ustr32_x);
bxstr_t *actual = bxs_strcat(bxstr, ustr32_empty);
assert_non_null(actual);
assert_string_equal("x", actual->ascii);
BFREE(ustr32_x);
BFREE(ustr32_empty);
bxs_free(actual);
bxs_free(bxstr);
}
void test_bxs_strcat_empty3(void **state)
{
UNUSED(state);
uint32_t *ustr32_empty = u32_strconv_from_arg("", "UTF-8");
uint32_t *ustr32_x = u32_strconv_from_arg("x", "UTF-8");
assert_non_null(ustr32_empty);
assert_non_null(ustr32_x);
bxstr_t *bxstr = bxs_from_unicode(ustr32_empty);
bxstr_t *actual = bxs_strcat(bxstr, ustr32_x);
assert_non_null(actual);
assert_string_equal("x", actual->ascii);
BFREE(ustr32_empty);
BFREE(ustr32_x);
bxs_free(actual);
bxs_free(bxstr);
}
void test_bxs_strcat(void **state)
{
UNUSED(state);
uint32_t *ustr32_1 = u32_strconv_from_arg("\x1b[38;5;203mA\x1b[0m\x1b[38;5;198mB\x1b[0m", "UTF-8");
uint32_t *ustr32_2 = u32_strconv_from_arg("-\x1b[38;5;203ma\x1b[0m\x1b[38;5;198mb\x1b[0m", "UTF-8");
assert_non_null(ustr32_1);
assert_non_null(ustr32_2);
bxstr_t *bxstr = bxs_from_unicode(ustr32_1);
bxstr_t *actual = bxs_strcat(bxstr, ustr32_2);
assert_non_null(actual);
assert_non_null(actual->memory);
assert_string_equal("AB-ab", actual->ascii);
assert_int_equal(0, (int) actual->indent);
assert_int_equal(5, (int) actual->num_columns);
assert_int_equal(65, (int) actual->num_chars);
assert_int_equal(5, (int) actual->num_chars_visible);
assert_int_equal(60, (int) actual->num_chars_invisible);
assert_int_equal(0, (int) actual->trailing);
int expected_firstchar_idx[] = {0, 16, 32, 33, 49, 65};
assert_array_equal(expected_firstchar_idx, actual->first_char, 6);
int expected_vischar_idx[] = {11, 27, 32, 44, 60, 65};
assert_array_equal(expected_vischar_idx, actual->visible_char, 6);
BFREE(ustr32_1);
BFREE(ustr32_2);
bxs_free(actual);
bxs_free(bxstr);
}
void test_bxs_strchr(void **state)
{
UNUSED(state);
uint32_t *ustr32 = u32_strconv_from_arg("\x1b[38;5;203ma\x1b[0m\x1b[38;5;198mb\x1b[0m", "UTF-8");
assert_non_null(ustr32);
bxstr_t *bxstr = bxs_from_unicode(ustr32);
ucs4_t char_a = 0x00000061;
ucs4_t char_m = 0x0000006D;
uint32_t *found = bxs_strchr(bxstr, char_a, NULL);
assert_int_equal(11, found - bxstr->memory);
found = bxs_strchr(bxstr, char_m, NULL);
assert_null(found);
found = bxs_strchr(NULL, char_a, NULL);
assert_null(found);
BFREE(ustr32);
bxs_free(bxstr);
}
void test_bxs_strchr_empty(void **state)
{
UNUSED(state);
uint32_t *ustr32 = u32_strconv_from_arg("\x1b[38;5;203m\x1b[0m", "UTF-8");
assert_non_null(ustr32);
bxstr_t *bxstr = bxs_from_unicode(ustr32);
ucs4_t char_m = 0x0000006D;
uint32_t *found = bxs_strchr(bxstr, char_m, NULL);
assert_null(found);
BFREE(ustr32);
bxs_free(bxstr);
}
void test_bxs_strchr_cursor(void **state)
{
UNUSED(state);
uint32_t *ustr32 = u32_strconv_from_arg("foo, \x1b[38;5;203mBAR\x1b[0m, \x1b[38;5;198mBAZ\x1b[0m", "UTF-8");
assert_non_null(ustr32);
bxstr_t *bxstr = bxs_from_unicode(ustr32);
ucs4_t char_comma = 0x0000002C; /* ',' */
int cursor = -1;
uint32_t *found = bxs_strchr(bxstr, char_comma, &cursor);
assert_non_null(found);
assert_int_equal(3, cursor);
assert_memory_equal(&char_comma, found, sizeof(ucs4_t));
found = bxs_strchr(bxstr, char_comma, &cursor);
assert_non_null(found);
assert_int_equal(8, cursor);
assert_memory_equal(&char_comma, found, sizeof(ucs4_t));
found = bxs_strchr(bxstr, char_comma, &cursor);
assert_null(found);
assert_int_equal(8, cursor);
BFREE(ustr32);
bxs_free(bxstr);
}
void test_bxs_trim(void **state)
{
UNUSED(state);
uint32_t *ustr32 = /* em-space */
u32_strconv_from_arg("\xe2\x80\x83 \x1b[38;5;203m \x1b[0mtrimmed\x1b[38;5;198m \x1b[0m ", "UTF-8");
bxstr_t *bxstr = bxs_from_unicode(ustr32);
assert_int_equal(3, (int) bxstr->indent);
bxstr_t *actual = bxs_trim(bxstr);
assert_non_null(actual);
assert_non_null(actual->memory);
assert_string_equal("trimmed", actual->ascii);
assert_int_equal(0, (int) actual->indent);
assert_int_equal(7, (int) actual->num_columns);
assert_int_equal(7, (int) actual->num_chars);
assert_int_equal(7, (int) actual->num_chars_visible);
assert_int_equal(0, (int) actual->num_chars_invisible);
assert_int_equal(0, (int) actual->trailing);
int expected_firstchar_idx[] = {0, 1, 2, 3, 4, 5, 6, 7};
assert_array_equal(expected_firstchar_idx, actual->first_char, 8);
int expected_vischar_idx[] = {0, 1, 2, 3, 4, 5, 6, 7};
assert_array_equal(expected_vischar_idx, actual->visible_char, 8);
BFREE(ustr32);
bxs_free(actual);
bxs_free(bxstr);
}
void test_bxs_trim_blanks(void **state)
{
UNUSED(state);
/* em-space */
uint32_t *ustr32 = u32_strconv_from_arg(" \xe2\x80\x83\x1b[38;5;203m \x1b[0m \x1b[38;5;198m \x1b[0m ", "UTF-8");
bxstr_t *bxstr = bxs_from_unicode(ustr32);
assert_int_equal(7, (int) bxstr->indent);
assert_int_equal(0, (int) bxstr->trailing);
bxstr_t *actual = bxs_trim(bxstr);
assert_non_null(actual);
assert_non_null(actual->memory);
assert_string_equal("", actual->ascii);
assert_int_equal(0, (int) actual->indent);
assert_int_equal(0, (int) actual->num_columns);
assert_int_equal(0, (int) actual->num_chars);
assert_int_equal(0, (int) actual->num_chars_visible);
assert_int_equal(0, (int) actual->num_chars_invisible);
assert_int_equal(0, (int) actual->trailing);
int expected_firstchar_idx[] = {0};
assert_array_equal(expected_firstchar_idx, actual->first_char, 1);
int expected_vischar_idx[] = {0};
assert_array_equal(expected_vischar_idx, actual->visible_char, 1);
BFREE(ustr32);
bxs_free(actual);
bxs_free(bxstr);
}
void test_bxs_trim_none(void **state)
{
UNUSED(state);
bxstr_t *actual = bxs_trim(NULL);
assert_null(actual);
uint32_t *ustr32 = u32_strconv_from_arg("\x1b[38;5;203mX\x1b[0mX\x1b[38;5;198mX\x1b[0mX", "ASCII");
bxstr_t *bxstr = bxs_from_unicode(ustr32);
actual = bxs_trim(bxstr);
assert_non_null(actual);
assert_non_null(actual->memory);
assert_string_equal("XXXX", actual->ascii);
assert_int_equal(0, (int) actual->indent);
assert_int_equal(4, (int) actual->num_columns);
assert_int_equal(34, (int) actual->num_chars);
assert_int_equal(4, (int) actual->num_chars_visible);
assert_int_equal(30, (int) actual->num_chars_invisible);
assert_int_equal(0, (int) actual->trailing);
int expected_firstchar_idx[] = {0, 16, 17, 33, 34};
assert_array_equal(expected_firstchar_idx, actual->first_char, 5);
int expected_vischar_idx[] = {11, 16, 28, 33, 34};
assert_array_equal(expected_vischar_idx, actual->visible_char, 5);
BFREE(ustr32);
bxs_free(actual);
bxs_free(bxstr);
}
void test_bxs_rtrim(void **state)
{
UNUSED(state);
uint32_t *ustr32 = u32_strconv_from_arg("xx\x1b[38;5;203m \x1b[0m \x1b[38;5;198m \x1b[0m ", "UTF-8");
assert_non_null(ustr32);
bxstr_t *bxstr = bxs_from_unicode(ustr32);
bxstr_t *actual = bxs_rtrim(bxstr);
assert_non_null(actual);
assert_non_null(actual->memory);
assert_string_equal("xx", actual->ascii);
assert_int_equal(0, (int) actual->indent);
assert_int_equal(2, (int) actual->num_columns);
assert_int_equal(2, (int) actual->num_chars);
assert_int_equal(2, (int) actual->num_chars_visible);
assert_int_equal(0, (int) actual->num_chars_invisible);
assert_int_equal(0, (int) actual->trailing);
int expected_firstchar_idx[] = {0, 1, 2};
assert_array_equal(expected_firstchar_idx, actual->first_char, 3);
int expected_vischar_idx[] = {0, 1, 2};
assert_array_equal(expected_vischar_idx, actual->visible_char, 3);
BFREE(ustr32);
bxs_free(actual);
bxs_free(bxstr);
}
void test_bxs_rtrim_empty(void **state)
{
UNUSED(state);
bxstr_t *actual = bxs_rtrim(NULL);
assert_null(actual);
uint32_t *ustr32 = u32_strconv_from_arg("X\x1b[38;5;203m \x1b[0mX", "UTF-8");
assert_non_null(ustr32);
bxstr_t *bxstr = bxs_from_unicode(ustr32);
actual = bxs_rtrim(bxstr);
assert_non_null(actual);
assert_non_null(actual->memory);
assert_string_equal("X X", actual->ascii);
assert_int_equal(0, (int) actual->indent);
assert_int_equal(3, (int) actual->num_columns);
assert_int_equal(18, (int) actual->num_chars);
assert_int_equal(3, (int) actual->num_chars_visible);
assert_int_equal(15, (int) actual->num_chars_invisible);
assert_int_equal(0, (int) actual->trailing);
int expected_firstchar_idx[] = {0, 1, 17, 18};
assert_array_equal(expected_firstchar_idx, actual->first_char, 4);
int expected_vischar_idx[] = {0, 12, 17, 18};
assert_array_equal(expected_vischar_idx, actual->visible_char, 4);
BFREE(ustr32);
bxs_free(actual);
bxs_free(bxstr);
}
void test_bxs_to_output(void **state)
{
UNUSED(state);
char *actual = bxs_to_output(NULL);
assert_string_equal("NULL", actual);
BFREE(actual);
bxstr_t *bxstr = bxs_from_ascii("foobar");
actual = bxs_to_output(bxstr);
assert_string_equal("foobar", actual);
BFREE(actual);
bxs_free(bxstr);
}
void test_bxs_is_empty_null(void **state)
{
UNUSED(state);
int actual = bxs_is_empty(NULL);
assert_int_equal(1, actual);
}
void test_bxs_is_visible_char(void **state)
{
UNUSED(state);
uint32_t *ustr32 = u32_strconv_from_arg("\x1b[38;5;203mX\x1b[0m \x1b[38;5;203mY\x1b[0m", "ASCII");
assert_non_null(ustr32);
bxstr_t *input = bxs_from_unicode(ustr32);
assert_int_equal(0, bxs_is_visible_char(NULL, 4));
assert_int_equal(0, bxs_is_visible_char(input, 1000));
assert_int_equal(0, bxs_is_visible_char(input, 0));
assert_int_equal(0, bxs_is_visible_char(input, 1));
assert_int_equal(0, bxs_is_visible_char(input, 31));
assert_int_equal(0, bxs_is_visible_char(input, 32));
assert_int_equal(0, bxs_is_visible_char(input, 33));
assert_int_equal(1, bxs_is_visible_char(input, 11));
assert_int_equal(1, bxs_is_visible_char(input, 16));
assert_int_equal(1, bxs_is_visible_char(input, 28));
BFREE(ustr32);
bxs_free(input);
}
void test_bxs_strcmp(void **state)
{
UNUSED(state);
int actual = bxs_strcmp(NULL, NULL);
assert_int_equal(0, actual);
bxstr_t *bxstr1 = bxs_from_ascii("alice");
bxstr_t *bxstr2 = bxs_from_ascii("bob");
actual = bxs_strcmp(NULL, bxstr1);
assert_int_equal(1, actual);
actual = bxs_strcmp(bxstr1, NULL);
assert_int_equal(-1, actual);
actual = bxs_strcmp(bxstr1, bxstr2);
assert_int_equal(-1, actual);
actual = bxs_strcmp(bxstr2, bxstr1);
assert_int_equal(1, actual);
bxs_free(bxstr1);
bxs_free(bxstr2);
}
void test_bxs_valid_anywhere_error(void **state)
{
UNUSED(state);
size_t error_pos = 42;
assert_int_equal(0, bxs_valid_anywhere(NULL, NULL));
assert_int_equal(0, bxs_valid_anywhere(NULL, &error_pos));
assert_int_equal(0, (int) error_pos);
bxstr_t *bxstr = bxs_from_ascii("illegal X backspace");
ucs4_t char_backspace = 0x00000008;
bxstr->memory[8] = char_backspace;
assert_int_equal(0, bxs_valid_anywhere(bxstr, NULL));
bxs_free(bxstr);
}
void test_bxs_valid_in_filename_error(void **state)
{
UNUSED(state);
uint32_t *ustr32 = u32_strconv_from_arg("\x1b[38;5;203m\x1b[0m", "ASCII");
bxstr_t *bxstr_no_vis = bxs_from_unicode(ustr32);
BFREE(ustr32);
ustr32 = u32_strconv_from_arg("\x1b[38;5;203m_VISIBLE_\x1b[0m", "ASCII");
bxstr_t *bxstr_vis_invis = bxs_from_unicode(ustr32);
assert_int_equal(0, bxs_valid_in_filename(bxstr_no_vis, NULL));
assert_int_equal(0, bxs_valid_in_filename(bxstr_vis_invis, NULL));
BFREE(ustr32);
bxs_free(bxstr_no_vis);
bxs_free(bxstr_vis_invis);
}
void test_bxs_free_null(void **state)
{
UNUSED(state);
bxstr_t *bstr = (bxstr_t *) calloc(1, sizeof(bxstr_t));
bstr->ascii = NULL;
bstr->memory = NULL;
bstr->first_char = NULL;
bstr->visible_char = NULL;
bxs_free(bstr);
bxs_free(NULL);
}
/* vim: set cindent sw=4: */