AryaWu/sqlite
0
1#include "sqliteInt.h"2#include "unity.h"3#include <stdlib.h>4#include <string.h>5#include <stdint.h>6 7/* Forward declaration of the opaque struct type from the SQLite module. */8struct compareInfo;9 10/* Prototype of the provided test wrapper for the static function. */11int test_patternCompare(const u8 *zPattern, const u8 *zString,12 const struct compareInfo *pInfo, u32 matchOther);13 14/* Helpers to construct compareInfo blobs without redefining the struct. */15static void fillCompareInfo(u8 info[4], u8 matchAll, u8 matchOne, u8 matchSet, u8 noCase){16 info[0] = matchAll;17 info[1] = matchOne;18 info[2] = matchSet;19 info[3] = noCase;20}21 22/* Callers for GLOB and LIKE */23static int globCmp(const char *pattern, const char *z, int noCase){24 u8 info[4];25 /* GLOB: matchAll='*', matchOne='?', matchSet='[', noCase as given */26 fillCompareInfo(info, (u8)'*', (u8)'?', (u8)'[', (u8)(noCase?1:0));27 return test_patternCompare((const u8*)pattern, (const u8*)z,28 (const struct compareInfo*)info, (u32)'[');29}30static int likeCmp(const char *pattern, const char *z, int noCase, int esc){31 u8 info[4];32 /* LIKE: matchAll='%', matchOne='_', matchSet=0, noCase as given */33 fillCompareInfo(info, (u8)'%', (u8)'_', (u8)0, (u8)(noCase?1:0));34 return test_patternCompare((const u8*)pattern, (const u8*)z,35 (const struct compareInfo*)info, (u32)(esc & 0xFF));36}37 38/* Unity fixtures */39void setUp(void) {}40void tearDown(void) {}41 42/* Tests */43 44void test_patternCompare_glob_exact_match_and_mismatch(void){45 TEST_ASSERT_EQUAL_INT(SQLITE_MATCH, globCmp("abc", "abc", 0));46 TEST_ASSERT_EQUAL_INT(SQLITE_NOMATCH, globCmp("abc", "abd", 0));47 TEST_ASSERT_EQUAL_INT(SQLITE_NOMATCH, globCmp("abc", "abcd", 0));48 TEST_ASSERT_EQUAL_INT(SQLITE_NOMATCH, globCmp("abcd", "abc", 0));49}50 51void test_patternCompare_glob_star_and_question(void){52 /* '*' matches any sequence; '?' matches exactly one char */53 TEST_ASSERT_EQUAL_INT(SQLITE_MATCH, globCmp("a*bc", "axyzbc", 0));54 TEST_ASSERT_EQUAL_INT(SQLITE_MATCH, globCmp("*", "", 0));55 TEST_ASSERT_EQUAL_INT(SQLITE_MATCH, globCmp("*", "anything", 0));56 /* "*?" requires at least one character */57 TEST_ASSERT_EQUAL_INT(SQLITE_NOWILDCARDMATCH, globCmp("*?", "", 0));58 TEST_ASSERT_EQUAL_INT(SQLITE_MATCH, globCmp("*?", "x", 0));59 /* Multiple '?' each consumes exactly one character */60 TEST_ASSERT_EQUAL_INT(SQLITE_MATCH, globCmp("ab??d", "abXYd", 0));61 TEST_ASSERT_EQUAL_INT(SQLITE_NOMATCH, globCmp("ab??d", "abXd", 0));62}63 64void test_patternCompare_glob_sets_basic_and_negated(void){65 /* Basic set [a-c] */66 TEST_ASSERT_EQUAL_INT(SQLITE_MATCH, globCmp("[a-c]x", "bx", 0));67 TEST_ASSERT_EQUAL_INT(SQLITE_NOMATCH, globCmp("[a-c]x", "dx", 0));68 /* Negated set [^a-c] */69 TEST_ASSERT_EQUAL_INT(SQLITE_MATCH, globCmp("[^a-c]x", "dx", 0));70 TEST_ASSERT_EQUAL_INT(SQLITE_NOMATCH, globCmp("[^a-c]x", "bx", 0));71}72 73void test_patternCompare_glob_sets_including_bracket_and_dash(void){74 /* ']' as a member when first in set */75 TEST_ASSERT_EQUAL_INT(SQLITE_MATCH, globCmp("[]]x", "]x", 0));76 TEST_ASSERT_EQUAL_INT(SQLITE_NOMATCH, globCmp("[]]x", "ax", 0));77 /* Include ']' and 'a' in the set */78 TEST_ASSERT_EQUAL_INT(SQLITE_MATCH, globCmp("[]a]x", "]x", 0));79 TEST_ASSERT_EQUAL_INT(SQLITE_MATCH, globCmp("[]a]x", "ax", 0));80 TEST_ASSERT_EQUAL_INT(SQLITE_NOMATCH, globCmp("[]a]x", "bx", 0));81 /* '-' literal at end of set */82 TEST_ASSERT_EQUAL_INT(SQLITE_MATCH, globCmp("[abc-]", "b", 0));83 TEST_ASSERT_EQUAL_INT(SQLITE_MATCH, globCmp("[abc-]", "-", 0));84 TEST_ASSERT_EQUAL_INT(SQLITE_NOMATCH, globCmp("[abc-]", "d", 0));85}86 87void test_patternCompare_glob_recursive_star_followed_by_set(void){88 /* Pattern "*[0-9]" requires a digit somewhere; recursive search path */89 TEST_ASSERT_EQUAL_INT(SQLITE_NOWILDCARDMATCH, globCmp("*[0-9]", "abc", 0));90 TEST_ASSERT_EQUAL_INT(SQLITE_MATCH, globCmp("*[0-9]", "ab3", 0));91 TEST_ASSERT_EQUAL_INT(SQLITE_MATCH, globCmp("*[0-9]xyz", "zzz5xyz", 0));92}93 94void test_patternCompare_like_percent_and_underscore(void){95 /* Basic LIKE: % and _ */96 TEST_ASSERT_EQUAL_INT(SQLITE_MATCH, likeCmp("a%bc", "axyzbc", 0, 0));97 TEST_ASSERT_EQUAL_INT(SQLITE_MATCH, likeCmp("_b_", "abc", 0, 0));98 TEST_ASSERT_EQUAL_INT(SQLITE_NOMATCH, likeCmp("_b_", "ab", 0, 0));99 TEST_ASSERT_EQUAL_INT(SQLITE_NOMATCH, likeCmp("_b_", "abbc", 0, 0));100}101 102void test_patternCompare_like_escape_of_underscore(void){103 /* Escape '_' so it is matched literally */104 TEST_ASSERT_EQUAL_INT(SQLITE_MATCH, likeCmp("a\\_c", "a_c", 0, '\\'));105 TEST_ASSERT_EQUAL_INT(SQLITE_NOMATCH, likeCmp("a\\_c", "abc", 0, '\\'));106}107 108void test_patternCompare_like_case_insensitive(void){109 /* Case-insensitive LIKE (noCase=1) */110 TEST_ASSERT_EQUAL_INT(SQLITE_MATCH, likeCmp("a%Z", "aBcZ", 1, 0));111 TEST_ASSERT_EQUAL_INT(SQLITE_MATCH, likeCmp("A%z", "abcz", 1, 0));112 /* Case-sensitive should not match different case at fixed positions */113 TEST_ASSERT_EQUAL_INT(SQLITE_NOMATCH, likeCmp("a%Z", "aBcz", 0, 0));114}115 116void test_patternCompare_like_nowildcardmatch_scenarios(void){117 /* "%a" cannot match "bbb" -> NOWILDCARDMATCH */118 TEST_ASSERT_EQUAL_INT(SQLITE_NOWILDCARDMATCH, likeCmp("%a", "bbb", 0, 0));119 /* After '%' then escape at end -> NOWILDCARDMATCH */120 TEST_ASSERT_EQUAL_INT(SQLITE_NOWILDCARDMATCH, likeCmp("%\\", "anything", 0, '\\'));121}122 123void test_patternCompare_utf8_matchOne(void){124 /* Single UTF-8 character should be matched by single '?' in GLOB */125 const char *euro = "\xE2\x82\xAC"; /* U+20AC */126 TEST_ASSERT_EQUAL_INT(SQLITE_MATCH, globCmp("?", euro, 0));127 TEST_ASSERT_EQUAL_INT(SQLITE_NOMATCH, globCmp("??", euro, 0));128}129 130void test_patternCompare_glob_case_insensitive_basic(void){131 /* Case-insensitive GLOB (non-standard, but supported via noCase flag) */132 TEST_ASSERT_EQUAL_INT(SQLITE_MATCH, globCmp("Ab*", "abacus", 1));133 TEST_ASSERT_EQUAL_INT(SQLITE_NOMATCH, globCmp("Ab*", "abacus", 0));134}135 136int main(void){137 UNITY_BEGIN();138 RUN_TEST(test_patternCompare_glob_exact_match_and_mismatch);139 RUN_TEST(test_patternCompare_glob_star_and_question);140 RUN_TEST(test_patternCompare_glob_sets_basic_and_negated);141 RUN_TEST(test_patternCompare_glob_sets_including_bracket_and_dash);142 RUN_TEST(test_patternCompare_glob_recursive_star_followed_by_set);143 RUN_TEST(test_patternCompare_like_percent_and_underscore);144 RUN_TEST(test_patternCompare_like_escape_of_underscore);145 RUN_TEST(test_patternCompare_like_case_insensitive);146 RUN_TEST(test_patternCompare_like_nowildcardmatch_scenarios);147 RUN_TEST(test_patternCompare_utf8_matchOne);148 RUN_TEST(test_patternCompare_glob_case_insensitive_basic);149 return UNITY_END();150}