#include "sqliteInt.h" #include "unity.h" #include #include #include /* Wrapper for the static function under test (provided by the build as per instructions) */ extern int test_getConstraintToken(const u8 *z, int *piToken); void setUp(void) { /* No global setup required */ } void tearDown(void) { /* No global teardown required */ } /* Helper: return index of first occurrence of character c in s, or -1 if not found */ static int idx_of_char(const char *s, char c){ const char *p = strchr(s, c); if( !p ) return -1; return (int)(p - s); } /* Helper: return index immediately after the first occurrence of substring sub in s, or -1 if not found */ static int idx_after_sub(const char *s, const char *sub){ const char *p = strstr(s, sub); if( !p ) return -1; return (int)((p - s) + (int)strlen(sub)); } /* 1) Simple identifier with no leading whitespace/comments */ void test_getConstraintToken_simple_identifier(void) { const char *z = "abc def"; int t = 0; int n = test_getConstraintToken((const u8*)z, &t); TEST_ASSERT_EQUAL_INT(TK_ID, t); TEST_ASSERT_EQUAL_INT(3, n); /* "abc" length */ } /* 2) Skips leading spaces and comments, then identifies "abc" */ void test_getConstraintToken_skips_space_and_comments_before_id(void) { const char *z = " /* comment */\n-- line comment\nabc def"; int expected = idx_after_sub(z, "abc"); /* position immediately after "abc" */ TEST_ASSERT_TRUE_MESSAGE(expected > 0, "Did not find 'abc' in test string"); int t = 0; int n = test_getConstraintToken((const u8*)z, &t); TEST_ASSERT_EQUAL_INT(TK_ID, t); TEST_ASSERT_EQUAL_INT(expected, n); } /* 3) Minimal parenthesis token "()" followed by sentinel 'X' */ void test_getConstraintToken_minimal_parentheses(void) { const char *z = "()X"; int expected = idx_of_char(z, 'X'); TEST_ASSERT_TRUE_MESSAGE(expected >= 0, "Sentinel 'X' not found"); int t = 0; int n = test_getConstraintToken((const u8*)z, &t); TEST_ASSERT_EQUAL_INT(TK_LP, t); TEST_ASSERT_EQUAL_INT(expected, n); } /* 4) Parenthesis token with inner tokens and leading spaces; should consume up to the matching ')' */ void test_getConstraintToken_parentheses_with_inner_tokens(void) { const char *z = " (two three)X"; int expected = idx_of_char(z, 'X'); TEST_ASSERT_TRUE_MESSAGE(expected >= 0, "Sentinel 'X' not found"); int t = 0; int n = test_getConstraintToken((const u8*)z, &t); TEST_ASSERT_EQUAL_INT(TK_LP, t); TEST_ASSERT_EQUAL_INT(expected, n); } /* 5) Nested parentheses: (a(b)c)X -> should consume exactly up to the ')' before X */ void test_getConstraintToken_nested_parentheses(void) { const char *z = "(a(b)c)X"; int expected = idx_of_char(z, 'X'); TEST_ASSERT_TRUE_MESSAGE(expected >= 0, "Sentinel 'X' not found"); int t = 0; int n = test_getConstraintToken((const u8*)z, &t); TEST_ASSERT_EQUAL_INT(TK_LP, t); TEST_ASSERT_EQUAL_INT(expected, n); } /* 6) Unclosed parenthesis at end-of-input: expect TK_ILLEGAL and only the '(' consumed */ void test_getConstraintToken_unclosed_parenthesis_hits_illegal(void) { const char *z = "(abc"; int t = 0; int n = test_getConstraintToken((const u8*)z, &t); TEST_ASSERT_EQUAL_INT(TK_ILLEGAL, t); /* Expect at least the leading '(' to be consumed; tokenizer should return 0-length illegal at EOF */ TEST_ASSERT_EQUAL_INT(1, n); } /* 7) Unterminated string literal inside parentheses should trigger TK_ILLEGAL */ void test_getConstraintToken_unterminated_string_inside_parentheses(void) { const char *z = "('unterminated"; int t = 0; int n = test_getConstraintToken((const u8*)z, &t); TEST_ASSERT_EQUAL_INT(TK_ILLEGAL, t); /* Should have consumed the '(' plus at least part of the string token */ TEST_ASSERT_TRUE(n > 1); TEST_ASSERT_TRUE(n <= (int)strlen(z)); } /* 8) Non-parenthesis keyword token (SELECT) */ void test_getConstraintToken_keyword_token(void) { const char *z = "SELECT rest"; int t = 0; int n = test_getConstraintToken((const u8*)z, &t); TEST_ASSERT_EQUAL_INT(TK_SELECT, t); TEST_ASSERT_EQUAL_INT(6, n); /* "SELECT" length */ } int main(void) { UNITY_BEGIN(); RUN_TEST(test_getConstraintToken_simple_identifier); RUN_TEST(test_getConstraintToken_skips_space_and_comments_before_id); RUN_TEST(test_getConstraintToken_minimal_parentheses); RUN_TEST(test_getConstraintToken_parentheses_with_inner_tokens); RUN_TEST(test_getConstraintToken_nested_parentheses); RUN_TEST(test_getConstraintToken_unclosed_parenthesis_hits_illegal); RUN_TEST(test_getConstraintToken_unterminated_string_inside_parentheses); RUN_TEST(test_getConstraintToken_keyword_token); return UNITY_END(); }