File size: 4,284 Bytes
78d2150
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
140
141
142
143
144
145
#include "../../unity/unity.h"
#include <stdlib.h>
#include <stdint.h>

/* 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();
}