88// cmokca needs to be explicitly included last
99#include <cmocka.h>
1010
11- static int open_db (void * * state ) {
12- sqlite3 * db = NULL ;
13- int rc = sqlite3_open (":memory:" , & db );
14- assert_int_equal (rc , SQLITE_OK );
15- * state = db ;
16- return 0 ;
17- }
18-
1911static int close_db (void * * state ) {
2012 sqlite3 * db = * (sqlite3 * * ) state ;
2113 sqlite3_close (db );
@@ -31,6 +23,17 @@ static void exec_ok(sqlite3 *db, const char *sql) {
3123 sqlite3_free (errmsg );
3224}
3325
26+ static int open_db (void * * state ) {
27+ sqlite3 * db = NULL ;
28+ int rc = sqlite3_open (":memory:" , & db );
29+ assert_int_equal (rc , SQLITE_OK );
30+ * state = db ;
31+ rc = sqlite3_enable_load_extension (db , 1 );
32+ assert_int_equal (rc , SQLITE_OK );
33+ exec_ok (db , "SELECT load_extension('sqlite_bignum.dll')" );
34+ return 0 ;
35+ }
36+
3437static sqlite3_stmt * prepare (sqlite3 * db , const char * sql ) {
3538 sqlite3_stmt * stmt = NULL ;
3639 int rc = sqlite3_prepare_v2 (db , sql , -1 , & stmt , NULL );
@@ -155,9 +158,6 @@ static void test_text_ordering_fails_without_collation(void **state) {
155158
156159static void test_u64_edgecases (void * * state ) {
157160 sqlite3 * db = * (sqlite3 * * ) state ;
158- int rc = sqlite3_enable_load_extension (db , 1 );
159- assert_int_equal (rc , SQLITE_OK );
160- exec_ok (db , "SELECT load_extension('sqlite_bignum.dll')" );
161161 exec_ok (db , "CREATE TABLE t(n TEXT COLLATE U64TEXT);" );
162162
163163 exec_ok (db ,
@@ -190,9 +190,99 @@ static void test_u64_edgecases(void **state) {
190190 sqlite3_finalize (stmt );
191191}
192192
193+ static void test_u64text_display_function (void * * state ) {
194+ sqlite3 * db = * (sqlite3 * * ) state ;
195+
196+ struct {
197+ const char * input ;
198+ const char * expected ;
199+ const char * description ;
200+ } test_cases [] = {
201+ // Basic zero removal
202+ {"00000000000000000042" , "42" , "Simple number with leading zeros" },
203+ {"00000000000000000001" , "1" , "Single digit with leading zeros" },
204+ {"00000000000000000000" , "0" , "All zeros should display as single zero" },
205+
206+ // Edge cases
207+ {"18446744073709551615" , "18446744073709551615" , "UINT64_MAX (no leading zeros)" },
208+ {"09223372036854775807" , "9223372036854775807" , "INT64_MAX with one leading zero" },
209+ {"00009007199254740992" , "9007199254740992" , "2^53 with leading zeros" },
210+
211+ // Maximum leading zeros
212+ {"00000000000000000123" , "123" , "Many leading zeros" },
213+ {"01234567890123456789" , "1234567890123456789" , "19 digits with one leading zero" },
214+
215+ // All digits from 1-19 length results
216+ {"00000000000000000001" , "1" , "1 digit result" },
217+ {"00000000000000000012" , "12" , "2 digit result" },
218+ {"00000000000000000123" , "123" , "3 digit result" },
219+ {"00000000000001234567" , "1234567" , "7 digit result" },
220+ {"00000012345678901234" , "12345678901234" , "14 digit result" },
221+ {"12345678901234567890" , "12345678901234567890" , "20 digit result (no leading zeros)" },
222+ };
223+
224+ for (size_t i = 0 ; i < sizeof (test_cases ) / sizeof (test_cases [0 ]); i ++ ) {
225+ char sql [256 ];
226+ snprintf (sql , sizeof (sql ), "SELECT u64text_display('%s')" , test_cases [i ].input );
227+
228+ sqlite3_stmt * stmt = prepare (db , sql );
229+ assert_int_equal (sqlite3_step (stmt ), SQLITE_ROW );
230+
231+ const char * result = (const char * ) sqlite3_column_text (stmt , 0 );
232+ printf ("Test %zu: %s\n" , i + 1 , test_cases [i ].description );
233+ printf (" Input: '%s'\n" , test_cases [i ].input );
234+ printf (" Expected: '%s'\n" , test_cases [i ].expected );
235+ printf (" Got: '%s'\n" , result );
236+
237+ assert_string_equal (result , test_cases [i ].expected );
238+ sqlite3_finalize (stmt );
239+ }
240+
241+ printf ("\nTesting error/edge cases:\n" );
242+
243+ // NULL input
244+ sqlite3_stmt * stmt = prepare (db , "SELECT u64text_display(NULL)" );
245+ assert_int_equal (sqlite3_step (stmt ), SQLITE_ROW );
246+ assert_int_equal (sqlite3_column_type (stmt , 0 ), SQLITE_NULL );
247+ sqlite3_finalize (stmt );
248+ printf (" NULL input -> NULL result: ✓\n" );
249+
250+ // non-TEXT input (should return NULL)
251+ stmt = prepare (db , "SELECT u64text_display(42)" );
252+ assert_int_equal (sqlite3_step (stmt ), SQLITE_ROW );
253+ assert_int_equal (sqlite3_column_type (stmt , 0 ), SQLITE_NULL );
254+ sqlite3_finalize (stmt );
255+ printf (" INTEGER input -> NULL result: ✓\n" );
256+
257+ // invalid u64text format (should return original string)
258+ stmt = prepare (db , "SELECT u64text_display('invalid_format')" );
259+ assert_int_equal (sqlite3_step (stmt ), SQLITE_ROW );
260+ const char * result = (const char * ) sqlite3_column_text (stmt , 0 );
261+ assert_string_equal (result , "invalid_format" );
262+ sqlite3_finalize (stmt );
263+ printf (" Invalid format -> original string: ✓\n" );
264+
265+ // wrong length (should return original string)
266+ stmt = prepare (db , "SELECT u64text_display('123456789')" );
267+ assert_int_equal (sqlite3_step (stmt ), SQLITE_ROW );
268+ result = (const char * ) sqlite3_column_text (stmt , 0 );
269+ assert_string_equal (result , "123456789" );
270+ sqlite3_finalize (stmt );
271+ printf (" Wrong length -> original string: ✓\n" );
272+
273+ // non-numeric characters (should return original string)
274+ stmt = prepare (db , "SELECT u64text_display('1234567890abcdef1234')" );
275+ assert_int_equal (sqlite3_step (stmt ), SQLITE_ROW );
276+ result = (const char * ) sqlite3_column_text (stmt , 0 );
277+ assert_string_equal (result , "1234567890abcdef1234" );
278+ sqlite3_finalize (stmt );
279+ printf (" Non-numeric characters -> original string: ✓\n" );
280+ }
281+
193282int main (void ) {
194283 const struct CMUnitTest tests [] = {cmocka_unit_test_setup_teardown (test_wrong_ordering_on_u64 , open_db , close_db ),
195284 cmocka_unit_test_setup_teardown (test_text_ordering_fails_without_collation , open_db , close_db ),
196- cmocka_unit_test_setup_teardown (test_u64_edgecases , open_db , close_db )};
285+ cmocka_unit_test_setup_teardown (test_u64_edgecases , open_db , close_db ),
286+ cmocka_unit_test_setup_teardown (test_u64text_display_function , open_db , close_db )};
197287 return cmocka_run_group_tests (tests , NULL , NULL );
198288}
0 commit comments