@@ -334,8 +334,107 @@ static void test_inline_comments(void)
334334}
335335
336336/**
337- * @brief Main entry point for test application
337+ * @brief Test: Active section restriction
338338 */
339+ static void test_active_section (void )
340+ {
341+ TEST_START ("Active section restriction" );
342+
343+ const char * ini_data =
344+ "global_key=global_value\n"
345+ "\n"
346+ "[driver1]\n"
347+ "param=hello\n"
348+ "\n"
349+ "[driver2]\n"
350+ "param=world\n" ;
351+
352+ /* --- unprotected context (token 0) --- */
353+ dmini_context_t ctx = dmini_create ();
354+ TEST_ASSERT (ctx != NULL , "Failed to create context" );
355+
356+ int result = dmini_parse_string (ctx , ini_data );
357+ TEST_ASSERT (result == DMINI_OK , "Failed to parse string" );
358+
359+ /* Restrict to driver1 */
360+ result = dmini_set_active_section (ctx , "driver1" , 0 );
361+ TEST_ASSERT (result == DMINI_OK , "Failed to set active section" );
362+
363+ /* NULL maps to active section */
364+ const char * val = dmini_get_string (ctx , NULL , "param" , "" );
365+ TEST_ASSERT (strcmp (val , "hello" ) == 0 , "NULL should map to active section" );
366+
367+ /* Active section is also accessible by name */
368+ val = dmini_get_string (ctx , "driver1" , "param" , "" );
369+ TEST_ASSERT (strcmp (val , "hello" ) == 0 , "Active section should be accessible by name" );
370+
371+ /* Other sections are not visible */
372+ val = dmini_get_string (ctx , "driver2" , "param" , "not_found" );
373+ TEST_ASSERT (strcmp (val , "not_found" ) == 0 , "Other section should not be visible" );
374+
375+ TEST_ASSERT (dmini_has_section (ctx , "driver2" ) == 0 , "driver2 should not be visible" );
376+ TEST_ASSERT (dmini_has_key (ctx , "driver2" , "param" ) == 0 , "key in hidden section invisible" );
377+
378+ /* Clear restriction */
379+ result = dmini_clear_active_section (ctx , 0 );
380+ TEST_ASSERT (result == DMINI_OK , "Failed to clear active section" );
381+
382+ /* After clearing, all sections visible again */
383+ val = dmini_get_string (ctx , "driver2" , "param" , "" );
384+ TEST_ASSERT (strcmp (val , "world" ) == 0 , "driver2 should be visible after clearing" );
385+
386+ dmini_destroy (ctx );
387+
388+ /* --- token-protected context --- */
389+ const unsigned int test_token = 0xCAFEBABEu ;
390+ ctx = dmini_create_with_token (test_token );
391+ TEST_ASSERT (ctx != NULL , "Failed to create context with token" );
392+
393+ result = dmini_parse_string (ctx , ini_data );
394+ TEST_ASSERT (result == DMINI_OK , "Failed to parse string" );
395+
396+ /* Wrong token must be rejected */
397+ result = dmini_set_active_section (ctx , "driver1" , test_token + 1 );
398+ TEST_ASSERT (result == DMINI_ERR_LOCKED , "Wrong token should be rejected" );
399+
400+ /* Correct token must succeed */
401+ result = dmini_set_active_section (ctx , "driver1" , test_token );
402+ TEST_ASSERT (result == DMINI_OK , "Correct token should succeed" );
403+
404+ val = dmini_get_string (ctx , NULL , "param" , "" );
405+ TEST_ASSERT (strcmp (val , "hello" ) == 0 , "Active section accessible via NULL" );
406+
407+ /* Wrong token must not clear restriction */
408+ result = dmini_clear_active_section (ctx , test_token + 1 );
409+ TEST_ASSERT (result == DMINI_ERR_LOCKED , "Wrong token should not clear restriction" );
410+
411+ /* Section is still restricted after failed clear */
412+ val = dmini_get_string (ctx , "driver2" , "param" , "not_found" );
413+ TEST_ASSERT (strcmp (val , "not_found" ) == 0 , "Restriction should still be active" );
414+
415+ /* Correct token clears restriction */
416+ result = dmini_clear_active_section (ctx , test_token );
417+ TEST_ASSERT (result == DMINI_OK , "Correct token should clear restriction" );
418+
419+ val = dmini_get_string (ctx , "driver2" , "param" , "" );
420+ TEST_ASSERT (strcmp (val , "world" ) == 0 , "All sections visible after clear" );
421+
422+ /* Active section set to NULL (global section) */
423+ result = dmini_set_active_section (ctx , NULL , test_token );
424+ TEST_ASSERT (result == DMINI_OK , "Setting active section to NULL (global) should succeed" );
425+
426+ val = dmini_get_string (ctx , NULL , "global_key" , "" );
427+ TEST_ASSERT (strcmp (val , "global_value" ) == 0 , "Global section visible via NULL active section" );
428+
429+ val = dmini_get_string (ctx , "driver1" , "param" , "not_found" );
430+ TEST_ASSERT (strcmp (val , "not_found" ) == 0 , "Named sections hidden when global is active" );
431+
432+ dmini_clear_active_section (ctx , test_token );
433+ dmini_destroy (ctx );
434+ TEST_PASS ();
435+ }
436+
437+
339438int main (int argc , char * * argv )
340439{
341440 DMOD_LOG_INFO ("=== DMINI Functionality Tests ===\n\n" );
@@ -353,6 +452,7 @@ int main(int argc, char** argv)
353452 test_file_io ();
354453 test_comments_whitespace ();
355454 test_inline_comments ();
455+ test_active_section ();
356456
357457 // Print summary
358458 Dmod_Printf ("\n=== Test Summary ===\n" );
0 commit comments