test(txt) initial unit tests and general code cleanup/fixes (#2623)
* test(txt): Add test for identifying empty text when trying to get next line * test(txt): Rename next line empty string handling test * test(txt): Add tests for _lv_txt_is_cmd * test(txt): Add initial tests for _lv_txt_ins * fix(txt): Check for NULL before using strlen Passing NULL to strlen is not defined, so we should avoid it * txt: Update docs Remove docs from source file and add comment about pointers to NULL terminated arrays where necessary * txt: Misc update in encoded_size * test(txt): first tests for _lv_txt_cut * tests: Remove -Wmissing-prototype flag from compilation This will allow us to have cleaner test cases files. * test(txt): Remove test (funtion) prototypes as they're no longer necessary * Update src/misc/lv_txt.h Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com> * Update src/misc/lv_txt.h Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com> * Revert "tests: Remove -Wmissing-prototype flag from compilation" This reverts commit 8b3217de8d9210eb2e6da5e94c0735beb2735be7. * test(txt): Use pragma to disable missing-prototype warning * test: use extended set of compile options for test cases * Revert "test(txt): Use pragma to disable missing-prototype warning" This reverts commit 64909e30ed124ca1e8ca390ca0639479c3e34f44. * test(txt): Add assert to test_txt_cut_len_longer_than_string test * test(txt): Add test for _lv_txt_encoded_next on valid ascii input * test(txt): Add tests for _lv_txt_encoded_next with 2 byte long inputs * test(txt): Add tests for _lv_txt_encoded_next with 3 byte long inputs * test(txt): Add tests for _lv_txt_encoded_next with 4 byte long inputs * cleanup(txt): Add helper macros to identify ASCII and UTF8 codes * cleanup(txt): Add missing LV_ prefix to helper macros Co-authored-by: Gabor Kiss-Vamosi <kisvegabor@gmail.com> Co-authored-by: embeddedt <42941056+embeddedt@users.noreply.github.com>
This commit is contained in:
@@ -233,7 +233,7 @@ else()
|
||||
message(FATAL_ERROR "Must provide an options value.")
|
||||
endif()
|
||||
|
||||
# Options lvgl and all test files are compiled with.
|
||||
# Options lvgl and examples are compiled with.
|
||||
set(COMPILE_OPTIONS
|
||||
-DLV_CONF_PATH=${LVGL_TEST_DIR}/src/lv_test_conf.h
|
||||
-DLV_BUILD_TEST
|
||||
@@ -264,6 +264,12 @@ set(COMPILE_OPTIONS
|
||||
${BUILD_OPTIONS}
|
||||
)
|
||||
|
||||
# Options test cases are compiled with.
|
||||
set(LVGL_TESTFILE_COMPILE_OPTIONS
|
||||
${COMPILE_OPTIONS}
|
||||
-Wno-missing-prototypes
|
||||
)
|
||||
|
||||
get_filename_component(LVGL_DIR ${LVGL_TEST_DIR} DIRECTORY)
|
||||
|
||||
# Include lvgl project file.
|
||||
@@ -289,7 +295,7 @@ add_library(test_common
|
||||
unity/unity.c
|
||||
)
|
||||
target_include_directories(test_common PUBLIC ${TEST_INCLUDE_DIRS})
|
||||
target_compile_options(test_common PUBLIC ${COMPILE_OPTIONS})
|
||||
target_compile_options(test_common PUBLIC ${LVGL_TESTFILE_COMPILE_OPTIONS})
|
||||
|
||||
# Some examples `#include "lvgl/lvgl.h"` - which is a path which is not
|
||||
# in this source repository. If this repo is in a directory names 'lvgl'
|
||||
@@ -316,7 +322,7 @@ foreach( test_case_fname ${TEST_CASE_FILES} )
|
||||
)
|
||||
target_link_libraries(${test_name} test_common lvgl_examples lvgl png ${TEST_LIBS})
|
||||
target_include_directories(${test_name} PUBLIC ${TEST_INCLUDE_DIRS})
|
||||
target_compile_options(${test_name} PUBLIC ${COMPILE_OPTIONS})
|
||||
target_compile_options(${test_name} PUBLIC ${LVGL_TESTFILE_COMPILE_OPTIONS})
|
||||
|
||||
add_test(
|
||||
NAME ${test_name}
|
||||
|
||||
207
tests/src/test_cases/test_txt.c
Normal file
207
tests/src/test_cases/test_txt.c
Normal file
@@ -0,0 +1,207 @@
|
||||
#if LV_BUILD_TEST
|
||||
#include "../lvgl.h"
|
||||
|
||||
#include "unity/unity.h"
|
||||
|
||||
static const char color_cmd = LV_TXT_COLOR_CMD[0];
|
||||
|
||||
void test_txt_should_identify_valid_start_of_command(void)
|
||||
{
|
||||
uint32_t character = color_cmd;
|
||||
lv_text_cmd_state_t state = LV_TEXT_CMD_STATE_WAIT;
|
||||
|
||||
bool is_cmd = _lv_txt_is_cmd(&state, character);
|
||||
|
||||
TEST_ASSERT_TRUE(is_cmd);
|
||||
TEST_ASSERT_EQUAL_UINT8(state, LV_TEXT_CMD_STATE_PAR);
|
||||
}
|
||||
|
||||
void test_txt_should_identify_invalid_start_of_command(void)
|
||||
{
|
||||
uint32_t character = '$';
|
||||
lv_text_cmd_state_t state = LV_TEXT_CMD_STATE_WAIT;
|
||||
|
||||
bool is_cmd = _lv_txt_is_cmd(&state, character);
|
||||
|
||||
TEST_ASSERT_FALSE(is_cmd);
|
||||
TEST_ASSERT_EQUAL_UINT8(state, LV_TEXT_CMD_STATE_WAIT);
|
||||
}
|
||||
|
||||
void test_txt_should_identify_scaped_command_in_parameter(void)
|
||||
{
|
||||
uint32_t character = color_cmd;
|
||||
lv_text_cmd_state_t state = LV_TEXT_CMD_STATE_PAR;
|
||||
|
||||
bool is_cmd = _lv_txt_is_cmd(&state, character);
|
||||
|
||||
TEST_ASSERT_FALSE(is_cmd);
|
||||
TEST_ASSERT_EQUAL_UINT8(state, LV_TEXT_CMD_STATE_WAIT);
|
||||
}
|
||||
|
||||
void test_txt_should_skip_color_parameter_in_parameter(void)
|
||||
{
|
||||
uint32_t character = '$';
|
||||
lv_text_cmd_state_t state = LV_TEXT_CMD_STATE_PAR;
|
||||
|
||||
bool is_cmd = _lv_txt_is_cmd(&state, character);
|
||||
|
||||
TEST_ASSERT_TRUE(is_cmd);
|
||||
TEST_ASSERT_EQUAL_UINT8(state, LV_TEXT_CMD_STATE_PAR);
|
||||
}
|
||||
|
||||
void test_txt_should_reset_state_when_receiving_color_cmd_while_processing_commands(void)
|
||||
{
|
||||
uint32_t character = color_cmd;
|
||||
lv_text_cmd_state_t state = LV_TEXT_CMD_STATE_IN;
|
||||
|
||||
bool is_cmd = _lv_txt_is_cmd(&state, character);
|
||||
|
||||
TEST_ASSERT_TRUE(is_cmd);
|
||||
TEST_ASSERT_EQUAL_UINT8(state, LV_TEXT_CMD_STATE_WAIT);
|
||||
}
|
||||
|
||||
void test_txt_should_identify_space_after_parameter(void)
|
||||
{
|
||||
uint32_t character = ' ';
|
||||
lv_text_cmd_state_t state = LV_TEXT_CMD_STATE_PAR;
|
||||
|
||||
bool is_cmd = _lv_txt_is_cmd(&state, character);
|
||||
|
||||
TEST_ASSERT_TRUE(is_cmd);
|
||||
TEST_ASSERT_EQUAL_UINT8(state, LV_TEXT_CMD_STATE_IN);
|
||||
}
|
||||
|
||||
void test_txt_should_insert_string_into_another(void)
|
||||
{
|
||||
const char *msg = "Hello ";
|
||||
const char *suffix = "World";
|
||||
char target[20] = {0};
|
||||
size_t msg_len = strlen(msg);
|
||||
|
||||
strcpy(target, msg);
|
||||
|
||||
_lv_txt_ins(target, msg_len, suffix);
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING("Hello World", target);
|
||||
}
|
||||
|
||||
void test_txt_should_handle_null_pointers_when_inserting(void)
|
||||
{
|
||||
const char *msg = "Hello ";
|
||||
char target[20] = {0};
|
||||
size_t msg_len = strlen(msg);
|
||||
|
||||
strcpy(target, msg);
|
||||
|
||||
_lv_txt_ins(target, msg_len, NULL);
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING("Hello ", target);
|
||||
}
|
||||
|
||||
void test_txt_cut_should_handle_null_pointer_to_txt(void)
|
||||
{
|
||||
_lv_txt_cut(NULL, 0, 6);
|
||||
}
|
||||
|
||||
void test_txt_cut_happy_path(void)
|
||||
{
|
||||
char msg[] = "Hello World";
|
||||
|
||||
_lv_txt_cut(msg, 0, 6);
|
||||
|
||||
TEST_ASSERT_EQUAL_STRING("World", msg);
|
||||
}
|
||||
|
||||
void test_txt_cut_should_handle_len_longer_than_string_length(void)
|
||||
{
|
||||
char msg[] = "Hello World";
|
||||
|
||||
_lv_txt_cut(msg, 0, 30);
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT8(msg[0], 0x00);
|
||||
}
|
||||
|
||||
void test_txt_get_encoded_next_should_decode_valid_ascii(void)
|
||||
{
|
||||
char msg[] = "Hello World!";
|
||||
uint32_t result = 0;
|
||||
|
||||
result = _lv_txt_encoded_next(msg, NULL);
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT32((uint32_t) 'H', result);
|
||||
}
|
||||
|
||||
void test_txt_get_encoded_next_detect_valid_2_byte_input(void)
|
||||
{
|
||||
char msg[] = "\xc3\xb1";
|
||||
uint32_t result = 0;
|
||||
|
||||
result = _lv_txt_encoded_next(msg, NULL);
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT32(241, result);
|
||||
}
|
||||
|
||||
void test_txt_get_encoded_next_detect_invalid_2_byte_input(void)
|
||||
{
|
||||
char msg[] = "\xc3\x28";
|
||||
uint32_t result = 0;
|
||||
|
||||
result = _lv_txt_encoded_next(msg, NULL);
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT32(0, result);
|
||||
}
|
||||
|
||||
void test_txt_get_encoded_next_detect_valid_3_byte_input(void)
|
||||
{
|
||||
char msg[] = "\xe2\x82\xa1";
|
||||
uint32_t result = 0;
|
||||
|
||||
result = _lv_txt_encoded_next(msg, NULL);
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT32(8353, result);
|
||||
}
|
||||
|
||||
void test_txt_get_encoded_next_detect_invalid_3_byte_input(void)
|
||||
{
|
||||
char msg[] = "\xe2\x28\xa1";
|
||||
uint32_t result = 0;
|
||||
|
||||
result = _lv_txt_encoded_next(msg, NULL);
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT32(0, result);
|
||||
}
|
||||
|
||||
void test_txt_get_encoded_next_detect_valid_4_byte_input(void)
|
||||
{
|
||||
char msg[] = "\xf0\x90\x8c\xbc";
|
||||
uint32_t result = 0;
|
||||
|
||||
result = _lv_txt_encoded_next(msg, NULL);
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT32(66364, result);
|
||||
}
|
||||
|
||||
void test_txt_get_encoded_next_detect_invalid_4_byte_input(void)
|
||||
{
|
||||
char msg[] = "\xf0\x28\x8c\x28";
|
||||
uint32_t result = 0;
|
||||
|
||||
result = _lv_txt_encoded_next(msg, NULL);
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT32(0, result);
|
||||
}
|
||||
|
||||
/* See #2615 for more information */
|
||||
void test_txt_next_line_should_handle_empty_string(void)
|
||||
{
|
||||
const lv_font_t *font_ptr = NULL;
|
||||
lv_coord_t letter_space = 0;
|
||||
lv_coord_t max_width = 0;
|
||||
lv_text_flag_t flag = LV_TEXT_FLAG_NONE;
|
||||
|
||||
uint32_t next_line = _lv_txt_get_next_line("", font_ptr, letter_space, max_width, flag);
|
||||
|
||||
TEST_ASSERT_EQUAL_UINT32(0, next_line);
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user