File size: 4,684 Bytes
7510827 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
#include "sqliteInt.h"
#include "unity.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
/* 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();
} |