1 /* Test of ordered set data type implementation.
2 Copyright (C) 2020-2021 Free Software Foundation, Inc.
3 Written by Bruno Haible <bruno@clisp.org>, 2020.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17
18 static void
action(const void * str,void * data)19 action (const void *str, void *data)
20 {
21 ((char *) str)[0] += *(int *)data;
22 }
23
24 static void
test_update(gl_oset_implementation_t implementation)25 test_update (gl_oset_implementation_t implementation)
26 {
27 char A[2] = "A";
28 char B[2] = "B";
29 char C[2] = "C";
30 char D[2] = "D";
31
32 gl_oset_t set1 =
33 gl_oset_nx_create_empty (implementation, (gl_setelement_compar_fn) strcmp, NULL);
34 ASSERT (set1 != NULL);
35
36 /* Fill the set. */
37 ASSERT (gl_oset_nx_add (set1, C) == 1);
38 ASSERT (gl_oset_nx_add (set1, A) == 1);
39 ASSERT (gl_oset_nx_add (set1, B) == 1);
40 ASSERT (gl_oset_nx_add (set1, D) == 1);
41
42 /* Verify that set1 = ["A", "B", "C", "D"]. */
43 {
44 gl_oset_iterator_t iter = gl_oset_iterator (set1);
45 const void *elt;
46
47 ASSERT (gl_oset_iterator_next (&iter, &elt));
48 ASSERT (elt == A);
49 ASSERT (gl_oset_iterator_next (&iter, &elt));
50 ASSERT (elt == B);
51 ASSERT (gl_oset_iterator_next (&iter, &elt));
52 ASSERT (elt == C);
53 ASSERT (gl_oset_iterator_next (&iter, &elt));
54 ASSERT (elt == D);
55 ASSERT (!gl_oset_iterator_next (&iter, &elt));
56 }
57
58 /* Make a side effect on an element in the set, that moves the element. */
59 {
60 int data = 'G' - 'B';
61 ASSERT (gl_oset_update (set1, B, action, &data) == 1);
62 }
63 /* Verify that set1 = ["A", "C", "D", "G"]. */
64 {
65 gl_oset_iterator_t iter = gl_oset_iterator (set1);
66 const void *elt;
67
68 ASSERT (gl_oset_iterator_next (&iter, &elt));
69 ASSERT (elt == A);
70 ASSERT (gl_oset_iterator_next (&iter, &elt));
71 ASSERT (elt == C);
72 ASSERT (gl_oset_iterator_next (&iter, &elt));
73 ASSERT (elt == D);
74 ASSERT (gl_oset_iterator_next (&iter, &elt));
75 ASSERT (elt == B);
76 ASSERT (!gl_oset_iterator_next (&iter, &elt));
77 }
78
79 /* Make a side effect on an element in the set, that does not move the
80 element. */
81 {
82 int data = 'E' - 'D';
83 ASSERT (gl_oset_update (set1, D, action, &data) == 0);
84 }
85 /* Verify that set1 = ["A", "C", "E", "G"]. */
86 {
87 gl_oset_iterator_t iter = gl_oset_iterator (set1);
88 const void *elt;
89
90 ASSERT (gl_oset_iterator_next (&iter, &elt));
91 ASSERT (elt == A);
92 ASSERT (gl_oset_iterator_next (&iter, &elt));
93 ASSERT (elt == C);
94 ASSERT (gl_oset_iterator_next (&iter, &elt));
95 ASSERT (elt == D);
96 ASSERT (gl_oset_iterator_next (&iter, &elt));
97 ASSERT (elt == B);
98 ASSERT (!gl_oset_iterator_next (&iter, &elt));
99 }
100
101 /* Make a side effect on an element in the set, that provokes a
102 collision. */
103 {
104 int data = 'G' - 'A';
105 ASSERT (gl_oset_update (set1, A, action, &data) == -1);
106 }
107 /* Verify that set1 = ["C", "E", "G"]. */
108 {
109 gl_oset_iterator_t iter = gl_oset_iterator (set1);
110 const void *elt;
111
112 ASSERT (gl_oset_iterator_next (&iter, &elt));
113 ASSERT (elt == C);
114 ASSERT (gl_oset_iterator_next (&iter, &elt));
115 ASSERT (elt == D);
116 ASSERT (gl_oset_iterator_next (&iter, &elt));
117 ASSERT (elt == B);
118 ASSERT (!gl_oset_iterator_next (&iter, &elt));
119 }
120
121 /* Make a side effect on an element that is not in the set. */
122 {
123 int data = 'R' - 'G';
124 ASSERT (gl_oset_update (set1, A, action, &data) == 0);
125 }
126 /* Verify that set1 = ["C", "E", "G"]. */
127 {
128 gl_oset_iterator_t iter = gl_oset_iterator (set1);
129 const void *elt;
130
131 ASSERT (gl_oset_iterator_next (&iter, &elt));
132 ASSERT (elt == C);
133 ASSERT (gl_oset_iterator_next (&iter, &elt));
134 ASSERT (elt == D);
135 ASSERT (gl_oset_iterator_next (&iter, &elt));
136 ASSERT (elt == B);
137 ASSERT (!gl_oset_iterator_next (&iter, &elt));
138 }
139
140 gl_oset_free (set1);
141 }
142