1 #include <test.h>
2 
3 #include <variable.h>
4 #include <rlist.h>
5 
6 struct Variable_
7 {
8     VarRef *ref;
9     Rval rval;
10     DataType type;
11     StringSet *tags;
12     char *comment;
13     const Promise *promise; // The promise that set the present value
14 };
15 
PutVar(VariableTable * table,char * var_str)16 static bool PutVar(VariableTable *table, char *var_str)
17 {
18     VarRef *ref = VarRefParse(var_str);
19     Rval rval = (Rval) { var_str, RVAL_TYPE_SCALAR };
20     bool ret = VariableTablePut(table, ref, &rval, CF_DATA_TYPE_STRING, NULL, NULL, NULL);
21     VarRefDestroy(ref);
22     return ret;
23 }
24 
ReferenceTable(void)25 static VariableTable *ReferenceTable(void)
26 {
27     VariableTable *t = VariableTableNew();
28 
29     assert_false(PutVar(t, "scope1.lval1"));
30     assert_false(PutVar(t, "scope1.lval2"));
31     assert_false(PutVar(t, "scope2.lval1"));
32     {
33         VarRef *ref = VarRefParse("scope1.array[one]");
34         Rval rval = (Rval) { "scope1.array[one]", RVAL_TYPE_SCALAR };
35         assert_false(VariableTablePut(t, ref, &rval, CF_DATA_TYPE_STRING, NULL, NULL, NULL));
36         VarRefDestroy(ref);
37     }
38     {
39         VarRef *ref = VarRefParse("scope1.array[two]");
40         Rval rval = (Rval) { "scope1.array[two]", RVAL_TYPE_SCALAR };
41         assert_false(VariableTablePut(t, ref, &rval, CF_DATA_TYPE_STRING, NULL, NULL, NULL));
42         VarRefDestroy(ref);
43     }
44     {
45         VarRef *ref = VarRefParse("scope1.array[two][three]");
46         Rval rval = (Rval) { "scope1.array[two][three]", RVAL_TYPE_SCALAR };
47         assert_false(VariableTablePut(t, ref, &rval, CF_DATA_TYPE_STRING, NULL, NULL, NULL));
48         VarRefDestroy(ref);
49     }
50     {
51         VarRef *ref = VarRefParse("scope1.array[two][four]");
52         Rval rval = (Rval) { "scope1.array[two][four]", RVAL_TYPE_SCALAR };
53         assert_false(VariableTablePut(t, ref, &rval, CF_DATA_TYPE_STRING, NULL, NULL, NULL));
54         VarRefDestroy(ref);
55     }
56 
57     {
58         VarRef *ref = VarRefParse("scope3.array[te][st]");
59         Rval rval = (Rval) { "scope3.array[te][st]", RVAL_TYPE_SCALAR };
60         assert_false(VariableTablePut(t, ref, &rval, CF_DATA_TYPE_STRING, NULL, NULL, NULL));
61         VarRefDestroy(ref);
62     }
63     {
64         VarRef *ref = VarRefParse("scope3.array[t][e][s][t]");
65         Rval rval = (Rval) { "scope3.array[t][e][s][t]", RVAL_TYPE_SCALAR };
66         assert_false(VariableTablePut(t, ref, &rval, CF_DATA_TYPE_STRING, NULL, NULL, NULL));
67         VarRefDestroy(ref);
68     }
69 
70     assert_false(PutVar(t, "ns1:scope1.lval1"));
71     assert_false(PutVar(t, "ns1:scope1.lval2"));
72     assert_false(PutVar(t, "ns1:scope2.lval1"));
73 
74     return t;
75 }
76 
TestGet(VariableTable * t,const char * ref_str)77 static void TestGet(VariableTable *t, const char *ref_str)
78 {
79     VarRef *ref = VarRefParse(ref_str);
80     Variable *v = VariableTableGet(t, ref);
81     assert_true(v != NULL);
82     assert_int_equal(0, VarRefCompare(ref, v->ref));
83     assert_string_equal(ref_str, RvalScalarValue(v->rval));
84     VarRefDestroy(ref);
85 }
86 
test_get_in_default_namespace(void)87 static void test_get_in_default_namespace(void)
88 {
89     VariableTable *t = ReferenceTable();
90 
91     TestGet(t, "scope1.lval1");
92     TestGet(t, "scope1.lval2");
93     TestGet(t, "scope2.lval1");
94 
95     VariableTableDestroy(t);
96 }
97 
98 // Redmine 6674
test_multi_index_array_conflation(void)99 static void test_multi_index_array_conflation(void)
100 {
101     VariableTable *t = ReferenceTable();
102 
103     TestGet(t, "scope3.array[te][st]");
104     TestGet(t, "scope3.array[t][e][s][t]");
105 
106     VariableTableDestroy(t);
107 }
108 
test_get_different_namespaces(void)109 static void test_get_different_namespaces(void)
110 {
111     VariableTable *t = ReferenceTable();
112 
113     TestGet(t, "scope1.lval1");
114     TestGet(t, "ns1:scope1.lval1");
115 
116     VariableTableDestroy(t);
117 }
118 
test_get_indices(void)119 static void test_get_indices(void)
120 {
121     VariableTable *t = ReferenceTable();
122 
123     TestGet(t, "scope1.array[one]");
124     TestGet(t, "scope1.array[two]");
125 
126     VariableTableDestroy(t);
127 }
128 
test_replace(void)129 static void test_replace(void)
130 {
131     VariableTable *t = ReferenceTable();
132 
133     VarRef *ref = VarRefParse("scope1.lval1");
134     TestGet(t, "scope1.lval1");
135 
136     Rval rval = (Rval) { "foo", RVAL_TYPE_SCALAR };
137     assert_true(VariableTablePut(t, ref, &rval, CF_DATA_TYPE_STRING, NULL, NULL, NULL));
138 
139     Variable *v = VariableTableGet(t, ref);
140     assert_true(v != NULL);
141     assert_string_equal("foo", RvalScalarValue(v->rval));
142 
143     VarRefDestroy(ref);
144 
145     VariableTableDestroy(t);
146 }
147 
test_remove(void)148 static void test_remove(void)
149 {
150     VariableTable *t = ReferenceTable();
151 
152     {
153         VarRef *ref = VarRefParse("scope1.array[one]");
154         assert_true(VariableTableRemove(t, ref));
155         assert_true(VariableTableGet(t, ref) == NULL);
156         assert_false(VariableTableRemove(t, ref));
157 
158         assert_int_equal(11, VariableTableCount(t, NULL, NULL, NULL));
159 
160         VarRefDestroy(ref);
161     }
162 
163     {
164         VarRef *ref = VarRefParse("ns1:scope1.lval1");
165         assert_true(VariableTableRemove(t, ref));
166         assert_true(VariableTableGet(t, ref) == NULL);
167         assert_false(VariableTableRemove(t, ref));
168 
169         assert_int_equal(10, VariableTableCount(t, NULL, NULL, NULL));
170 
171         VarRefDestroy(ref);
172     }
173 
174     VariableTableDestroy(t);
175 }
176 
test_clear(void)177 static void test_clear(void)
178 {
179     {
180         VariableTable *t = ReferenceTable();
181         assert_false(VariableTableClear(t, "xxx", NULL, NULL));
182         assert_false(VariableTableClear(t, NULL, "xxx", NULL));
183         assert_false(VariableTableClear(t, NULL, NULL, "xxx"));
184         assert_int_equal(12, VariableTableCount(t, NULL, NULL, NULL));
185         VariableTableDestroy(t);
186     }
187 
188     {
189         VariableTable *t = ReferenceTable();
190         assert_true(VariableTableClear(t, NULL, NULL, NULL));
191         assert_int_equal(0, VariableTableCount(t, NULL, NULL, NULL));
192         VariableTableDestroy(t);
193     }
194 
195     {
196         VariableTable *t = ReferenceTable();
197         assert_true(VariableTableClear(t, "default", NULL, NULL));
198         assert_int_equal(3, VariableTableCount(t, NULL, NULL, NULL));
199         VariableTableDestroy(t);
200     }
201 
202     {
203         VariableTable *t = ReferenceTable();
204         assert_true(VariableTableClear(t, "default", "scope1", NULL));
205         assert_int_equal(6, VariableTableCount(t, NULL, NULL, NULL));
206         VariableTableDestroy(t);
207     }
208 
209     {
210         VariableTable *t = ReferenceTable();
211         assert_true(VariableTableClear(t, "default", NULL, "array"));
212         assert_int_equal(6, VariableTableCount(t, NULL, NULL, NULL));
213         VariableTableDestroy(t);
214     }
215 
216     {
217         VariableTable *t = ReferenceTable();
218         assert_true(VariableTableClear(t, "ns1", NULL, NULL));
219         assert_int_equal(9, VariableTableCount(t, NULL, NULL, NULL));
220         VariableTableDestroy(t);
221     }
222 
223     {
224         VariableTable *t = ReferenceTable();
225         assert_true(VariableTableClear(t, "ns1", "scope2", NULL));
226         assert_int_equal(11, VariableTableCount(t, NULL, NULL, NULL));
227         VariableTableDestroy(t);
228     }
229 
230     {
231         VariableTable *t = ReferenceTable();
232         assert_true(VariableTableClear(t, "default", "scope1", "lval1"));
233         assert_int_equal(11, VariableTableCount(t, NULL, NULL, NULL));
234         VariableTableDestroy(t);
235     }
236 
237     {
238         VariableTable *t = ReferenceTable();
239         assert_true(VariableTableClear(t, "default", "scope1", "lval1"));
240         assert_int_equal(11, VariableTableCount(t, NULL, NULL, NULL));
241         VariableTableDestroy(t);
242     }
243 }
244 
test_counting(void)245 static void test_counting(void)
246 {
247     VariableTable *t = ReferenceTable();
248 
249     assert_int_equal(12, VariableTableCount(t, NULL, NULL, NULL));
250     assert_int_equal(9, VariableTableCount(t, "default", NULL, NULL));
251     assert_int_equal(8, VariableTableCount(t, NULL, "scope1", NULL));
252     assert_int_equal(6, VariableTableCount(t, "default", "scope1", NULL));
253     assert_int_equal(4, VariableTableCount(t, NULL, NULL, "lval1"));
254     assert_int_equal(3, VariableTableCount(t, "ns1", NULL, NULL));
255     assert_int_equal(2, VariableTableCount(t, "ns1", "scope1", NULL));
256     assert_int_equal(6, VariableTableCount(t, NULL, NULL, "array"));
257     assert_int_equal(1, VariableTableCount(t, "default", "scope1", "lval1"));
258 
259     VariableTableDestroy(t);
260 }
261 
test_iterate_indices(void)262 static void test_iterate_indices(void)
263 {
264     VariableTable *t = ReferenceTable();
265 
266     {
267         VarRef *ref = VarRefParse("default:scope1.array");
268         VariableTableIterator *iter = VariableTableIteratorNewFromVarRef(t, ref);
269 
270         unsigned short number_of_entries = 0;
271         while (VariableTableIteratorNext(iter))
272         {
273             number_of_entries++;
274         }
275         assert_int_equal(4, number_of_entries);
276 
277         VariableTableIteratorDestroy(iter);
278         VarRefDestroy(ref);
279     }
280 
281     {
282         VarRef *ref = VarRefParse("default:scope1.array[two]");
283         VariableTableIterator *iter = VariableTableIteratorNewFromVarRef(t, ref);
284 
285         unsigned short number_of_entries = 0;
286         while (VariableTableIteratorNext(iter))
287         {
288             number_of_entries++;
289         }
290 
291         assert_int_equal(3, number_of_entries);
292 
293         VariableTableIteratorDestroy(iter);
294         VarRefDestroy(ref);
295     }
296 
297     VariableTableDestroy(t);
298 }
299 
300 // Below test relies on the ordering items in RB tree which is strongly
301 // related to the hash function used.
302 /* No more relevant, RBTree has been replaced with Map. */
303 #if 0
304 static void test_iterate_indices_ordering_related(void)
305 {
306     VariableTable *t = ReferenceTable();
307 
308     {
309         VarRef *ref = VarRefParse("default:scope1.array");
310         VariableTableIterator *iter = VariableTableIteratorNewFromVarRef(t, ref);
311 
312         Variable *v = VariableTableIteratorNext(iter);
313         assert_true(v != NULL);
314         assert_int_equal(1, v->ref->num_indices);
315         assert_string_equal("two", v->ref->indices[0]);
316 
317         v = VariableTableIteratorNext(iter);
318         assert_true(v != NULL);
319         assert_int_equal(2, v->ref->num_indices);
320         assert_string_equal("two", v->ref->indices[0]);
321         assert_string_equal("three", v->ref->indices[1]);
322 
323         v = VariableTableIteratorNext(iter);
324         assert_true(v != NULL);
325         assert_int_equal(2, v->ref->num_indices);
326         assert_string_equal("two", v->ref->indices[0]);
327         assert_string_equal("four", v->ref->indices[1]);
328 
329         v = VariableTableIteratorNext(iter);
330         assert_true(v != NULL);
331         assert_int_equal(1, v->ref->num_indices);
332         assert_string_equal("one", v->ref->indices[0]);
333 
334         assert_false(VariableTableIteratorNext(iter) != NULL);
335 
336         VariableTableIteratorDestroy(iter);
337         VarRefDestroy(ref);
338     }
339 
340     {
341         VarRef *ref = VarRefParse("default:scope1.array[two]");
342         VariableTableIterator *iter = VariableTableIteratorNewFromVarRef(t, ref);
343 
344         Variable *v = VariableTableIteratorNext(iter);
345         assert_true(v != NULL);
346         assert_int_equal(1, v->ref->num_indices);
347         assert_string_equal("two", v->ref->indices[0]);
348 
349         v = VariableTableIteratorNext(iter);
350         assert_true(v != NULL);
351         assert_int_equal(2, v->ref->num_indices);
352         assert_string_equal("two", v->ref->indices[0]);
353         assert_string_equal("three", v->ref->indices[1]);
354 
355         v = VariableTableIteratorNext(iter);
356         assert_true(v != NULL);
357         assert_int_equal(2, v->ref->num_indices);
358         assert_string_equal("two", v->ref->indices[0]);
359         assert_string_equal("four", v->ref->indices[1]);
360 
361         assert_false(VariableTableIteratorNext(iter) != NULL);
362 
363         VariableTableIteratorDestroy(iter);
364         VarRefDestroy(ref);
365     }
366 
367     VariableTableDestroy(t);
368 }
369 #endif
370 
main()371 int main()
372 {
373     PRINT_TEST_BANNER();
374     const UnitTest tests[] =
375     {
376         unit_test(test_get_in_default_namespace),
377         unit_test(test_get_different_namespaces),
378         unit_test(test_get_indices),
379 //        unit_test(test_iterate_indices_ordering_related),
380         unit_test(test_multi_index_array_conflation),
381         unit_test(test_replace),
382         unit_test(test_remove),
383         unit_test(test_clear),
384         unit_test(test_counting),
385         unit_test(test_iterate_indices),
386     };
387 
388     return run_tests(tests);
389 }
390