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