#include "../../unity/unity.h" #include #include #include /* Use the in-translation-unit symbols: - static enum { COUNT_COLUMNS, COUNT_BYTES, COUNT_CHARACTERS } counting_mode; - static int last_character_width; - static size_t adjust_column (size_t column, mcel_t g); - #define TAB_WIDTH 8 These are defined earlier in fold.c and are visible here because this file is included at the end of that translation unit. */ static mcel_t make_mcel(uint32_t ch, int len) { mcel_t g; /* Zero-initialize in case mcel_t has other fields. */ memset(&g, 0, sizeof(g)); g.ch = ch; g.len = len; return g; } void setUp(void) { /* Reset to predictable defaults before each test. */ counting_mode = COUNT_COLUMNS; last_character_width = 0; } void tearDown(void) { /* Nothing to cleanup. */ } /* COUNT_COLUMNS: ordinary printable character should add its display width (1). */ void test_adjust_column_columns_regular_char_increments_and_sets_last_width(void) { size_t start = 0; mcel_t g = make_mcel('a', 1); size_t col = adjust_column(start, g); TEST_ASSERT_EQUAL_UINT64(1, col); TEST_ASSERT_EQUAL_INT(1, last_character_width); } /* COUNT_COLUMNS: backspace subtracts last_character_width if column > 0. */ void test_adjust_column_backspace_decrements_by_last_width_when_column_gt0(void) { size_t start = 5; last_character_width = 3; /* Simulate previous wide character */ mcel_t g = make_mcel('\b', 1); size_t col = adjust_column(start, g); TEST_ASSERT_EQUAL_UINT64(2, col); /* last_character_width unchanged in this branch */ TEST_ASSERT_EQUAL_INT(3, last_character_width); } /* COUNT_COLUMNS: backspace at column 0 must not underflow. */ void test_adjust_column_backspace_no_effect_when_column_zero(void) { size_t start = 0; last_character_width = 4; mcel_t g = make_mcel('\b', 1); size_t col = adjust_column(start, g); TEST_ASSERT_EQUAL_UINT64(0, col); TEST_ASSERT_EQUAL_INT(4, last_character_width); } /* COUNT_COLUMNS: carriage return resets column to 0. */ void test_adjust_column_carriage_return_resets_column(void) { size_t start = 10; mcel_t g = make_mcel('\r', 1); size_t col = adjust_column(start, g); TEST_ASSERT_EQUAL_UINT64(0, col); } /* COUNT_COLUMNS: tab advances to next tab stop from 0 (-> 8). */ void test_adjust_column_tab_from_zero_advances_to_8(void) { size_t start = 0; mcel_t g = make_mcel('\t', 1); size_t col = adjust_column(start, g); TEST_ASSERT_EQUAL_UINT64(TAB_WIDTH, col); } /* COUNT_COLUMNS: tab advances to next tab stop from 7 (-> 8). */ void test_adjust_column_tab_from_7_advances_to_8(void) { size_t start = 7; mcel_t g = make_mcel('\t', 1); size_t col = adjust_column(start, g); TEST_ASSERT_EQUAL_UINT64(8, col); } /* COUNT_COLUMNS: tab advances to next tab stop from 8 (-> 16). */ void test_adjust_column_tab_from_8_advances_to_16(void) { size_t start = 8; mcel_t g = make_mcel('\t', 1); size_t col = adjust_column(start, g); TEST_ASSERT_EQUAL_UINT64(16, col); } /* COUNT_CHARACTERS: regardless of the character, counts as 1 and sets last_character_width=1. */ void test_adjust_column_characters_mode_counts_one_and_sets_last_width(void) { counting_mode = COUNT_CHARACTERS; size_t start = 3; /* Use any code point; here 'X'. */ mcel_t g = make_mcel('X', 1); size_t col = adjust_column(start, g); TEST_ASSERT_EQUAL_UINT64(4, col); TEST_ASSERT_EQUAL_INT(1, last_character_width); } /* COUNT_BYTES: counts len, ignores control semantics; last_character_width preserved. */ void test_adjust_column_bytes_mode_counts_len_and_preserves_last_width(void) { counting_mode = COUNT_BYTES; last_character_width = 4; /* Should remain unchanged by COUNT_BYTES path */ size_t start = 5; /* '\t' with len=1 should just add 1 in byte mode. */ mcel_t g = make_mcel('\t', 1); size_t col = adjust_column(start, g); TEST_ASSERT_EQUAL_UINT64(6, col); TEST_ASSERT_EQUAL_INT(4, last_character_width); } /* COUNT_BYTES: multi-byte len added to column. */ void test_adjust_column_bytes_mode_multibyte_len(void) { counting_mode = COUNT_BYTES; size_t start = 2; mcel_t g = make_mcel('x', 4); size_t col = adjust_column(start, g); TEST_ASSERT_EQUAL_UINT64(6, col); } /* COUNT_COLUMNS: invalid code point (surrogate) should fall back to width 1. */ void test_adjust_column_invalid_codepoint_defaults_to_one(void) { counting_mode = COUNT_COLUMNS; size_t start = 10; /* Surrogate range; invalid Unicode scalar -> c32width typically returns <0 */ mcel_t g = make_mcel(0xD800u, 3); size_t col = adjust_column(start, g); TEST_ASSERT_EQUAL_UINT64(11, col); TEST_ASSERT_EQUAL_INT(1, last_character_width); } int main(void) { UNITY_BEGIN(); RUN_TEST(test_adjust_column_columns_regular_char_increments_and_sets_last_width); RUN_TEST(test_adjust_column_backspace_decrements_by_last_width_when_column_gt0); RUN_TEST(test_adjust_column_backspace_no_effect_when_column_zero); RUN_TEST(test_adjust_column_carriage_return_resets_column); RUN_TEST(test_adjust_column_tab_from_zero_advances_to_8); RUN_TEST(test_adjust_column_tab_from_7_advances_to_8); RUN_TEST(test_adjust_column_tab_from_8_advances_to_16); RUN_TEST(test_adjust_column_characters_mode_counts_one_and_sets_last_width); RUN_TEST(test_adjust_column_bytes_mode_counts_len_and_preserves_last_width); RUN_TEST(test_adjust_column_bytes_mode_multibyte_len); RUN_TEST(test_adjust_column_invalid_codepoint_defaults_to_one); return UNITY_END(); }