#include "../../unity/unity.h" #include #include /* We rely on set-fields.h already being included by the program source, which defines: struct field_range_pair { uintmax_t lo, hi; }; extern struct field_range_pair *frp; and include_field being visible (static within this translation unit). */ /* Keep track of any allocation we make so we can free it in tearDown. */ static struct field_range_pair *owned_frp = NULL; /* Save/restore the previous global frp around each test. */ static struct field_range_pair *saved_frp = NULL; static struct field_range_pair *alloc_frp(size_t n_pairs) { /* Allocate n_pairs entries + 1 sentinel. */ size_t n = n_pairs + 1; struct field_range_pair *arr = (struct field_range_pair *)malloc(n * sizeof(*arr)); TEST_ASSERT_NOT_NULL(arr); /* Ensure sentinel at the end. */ arr[n_pairs].lo = UINTMAX_MAX; arr[n_pairs].hi = 0; return arr; } void setUp(void) { /* Save current frp and reset to NULL by default for each test. */ saved_frp = frp; frp = NULL; owned_frp = NULL; } void tearDown(void) { /* Restore original frp and free any allocation we made. */ if (owned_frp) { free(owned_frp); owned_frp = NULL; } frp = saved_frp; } /* Test: when frp == NULL, only field 1 is included. */ void test_include_field_default_frp_null(void) { frp = NULL; TEST_ASSERT_TRUE(include_field(1)); TEST_ASSERT_FALSE(include_field(0)); TEST_ASSERT_FALSE(include_field(2)); TEST_ASSERT_FALSE(include_field(10)); } /* Test: single inclusive range [3,5]. */ void test_include_field_single_range_inclusive(void) { owned_frp = alloc_frp(1); owned_frp[0].lo = 3; owned_frp[0].hi = 5; frp = owned_frp; TEST_ASSERT_FALSE(include_field(2)); TEST_ASSERT_TRUE(include_field(3)); TEST_ASSERT_TRUE(include_field(4)); TEST_ASSERT_TRUE(include_field(5)); TEST_ASSERT_FALSE(include_field(6)); } /* Test: multiple ranges: [2,2] and [4, UINTMAX_MAX]. */ void test_include_field_multiple_ranges(void) { owned_frp = alloc_frp(2); owned_frp[0].lo = 2; owned_frp[0].hi = 2; owned_frp[1].lo = 4; owned_frp[1].hi = UINTMAX_MAX; frp = owned_frp; TEST_ASSERT_FALSE(include_field(1)); TEST_ASSERT_TRUE(include_field(2)); TEST_ASSERT_FALSE(include_field(3)); TEST_ASSERT_TRUE(include_field(4)); TEST_ASSERT_TRUE(include_field(1000000)); TEST_ASSERT_TRUE(include_field(UINTMAX_MAX)); } /* Test: all fields range [1, UINTMAX_MAX]. */ void test_include_field_all_fields_range(void) { owned_frp = alloc_frp(1); owned_frp[0].lo = 1; owned_frp[0].hi = UINTMAX_MAX; frp = owned_frp; TEST_ASSERT_TRUE(include_field(1)); TEST_ASSERT_TRUE(include_field(123456)); TEST_ASSERT_TRUE(include_field(UINTMAX_MAX)); TEST_ASSERT_FALSE(include_field(0)); /* Field indices are 1-based. */ } /* Test: an invalid range with lo > hi should not match, but another valid range should still work. */ void test_include_field_invalid_range_ignored(void) { owned_frp = alloc_frp(2); owned_frp[0].lo = 5; owned_frp[0].hi = 3; /* lo > hi: should never match */ owned_frp[1].lo = 10; owned_frp[1].hi = 12; frp = owned_frp; TEST_ASSERT_FALSE(include_field(4)); TEST_ASSERT_FALSE(include_field(5)); TEST_ASSERT_FALSE(include_field(3)); TEST_ASSERT_TRUE(include_field(10)); TEST_ASSERT_TRUE(include_field(11)); TEST_ASSERT_TRUE(include_field(12)); TEST_ASSERT_FALSE(include_field(13)); } /* Test: empty list (only sentinel) means include no fields. */ void test_include_field_empty_list_means_none(void) { owned_frp = alloc_frp(0); /* Just a sentinel. */ frp = owned_frp; TEST_ASSERT_FALSE(include_field(1)); TEST_ASSERT_FALSE(include_field(2)); TEST_ASSERT_FALSE(include_field(UINTMAX_MAX)); } int main(void) { UNITY_BEGIN(); RUN_TEST(test_include_field_default_frp_null); RUN_TEST(test_include_field_single_range_inclusive); RUN_TEST(test_include_field_multiple_ranges); RUN_TEST(test_include_field_all_fields_range); RUN_TEST(test_include_field_invalid_range_ignored); RUN_TEST(test_include_field_empty_list_means_none); return UNITY_END(); }