1 | /** \file |
2 | * \brief Generic tests for all array classes |
3 | * |
4 | * \author Stephan Beyer, Mirko Wagner, Tilo Wiedera |
5 | * |
6 | * \par License: |
7 | * This file is part of the Open Graph Drawing Framework (OGDF). |
8 | * |
9 | * \par |
10 | * Copyright (C)<br> |
11 | * See README.md in the OGDF root directory for details. |
12 | * |
13 | * \par |
14 | * This program is free software; you can redistribute it and/or |
15 | * modify it under the terms of the GNU General Public License |
16 | * Version 2 or 3 as published by the Free Software Foundation; |
17 | * see the file LICENSE.txt included in the packaging of this file |
18 | * for details. |
19 | * |
20 | * \par |
21 | * This program is distributed in the hope that it will be useful, |
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
24 | * GNU General Public License for more details. |
25 | * |
26 | * \par |
27 | * You should have received a copy of the GNU General Public |
28 | * License along with this program; if not, see |
29 | * http://www.gnu.org/copyleft/gpl.html |
30 | */ |
31 | |
32 | #pragma once |
33 | |
34 | #include <ogdf/basic/graph_generators.h> |
35 | #include <testing.h> |
36 | |
37 | /** |
38 | * Perform basic tests for a map of graph elements to values. |
39 | * @tparam ArrayType the type of array to be tested |
40 | * @tparam KeyType the type of key graph element |
41 | * @tparam ElementType the value type |
42 | * |
43 | * @param title the title of the top-level bandit::describe |
44 | * @param fillElement an arbitrary instance of \a ElementType |
45 | * @param secondElement a second instance of \a ElementType, must differ from \p fillElement |
46 | * @param chooseKey a function to choose an arbitrary key element from the graph |
47 | * @param getAllKeys a function to generate a list of all keys |
48 | * @param createKey a function to create a new key element in the graph |
49 | */ |
50 | template<template<typename> class ArrayType, typename KeyType, typename ElementType> |
51 | void describeArray( |
52 | const std::string &title, |
53 | const ElementType &fillElement, |
54 | const ElementType &secondElement, |
55 | std::function<KeyType (const Graph&)> chooseKey, |
56 | std::function<void (const Graph&, List<KeyType>&)> getAllKeys, |
57 | std::function<KeyType (Graph&)> createKey) |
58 | { |
59 | using MyArrayType = ArrayType<ElementType>; |
60 | using const_iterator = typename MyArrayType::const_iterator; |
61 | using iterator = typename MyArrayType::iterator; |
62 | |
63 | describe(title.c_str(), [&]() { |
64 | std::unique_ptr<MyArrayType> array; |
65 | Graph graph; |
66 | randomGraph(graph, 42, 168); |
67 | |
68 | before_each([&]() { |
69 | array.reset(new MyArrayType()); |
70 | }); |
71 | |
72 | it("handles nested arrays well" , [&]() { |
73 | Graph G; |
74 | G.newEdge(G.newNode(), G.newNode()); |
75 | |
76 | List<KeyType> keys; |
77 | getAllKeys(G, keys); |
78 | |
79 | ArrayType<MyArrayType> nestedArray(G); |
80 | for (KeyType k : keys) { |
81 | nestedArray[k].init(G, fillElement); |
82 | } |
83 | }); |
84 | |
85 | describe("init" , [&]() { |
86 | it("initializes w/o a graph" , [&]() { |
87 | AssertThat(array->graphOf(), IsNull()); |
88 | AssertThat(array->valid(), IsFalse()); |
89 | array->init(); |
90 | AssertThat(array->graphOf(), IsNull()); |
91 | AssertThat(array->valid(), IsFalse()); |
92 | }); |
93 | |
94 | it("initializes w a graph" , [&]() { |
95 | array->init(graph); |
96 | AssertThat(array->graphOf(), Equals(&graph)); |
97 | AssertThat(array->valid(), IsTrue()); |
98 | }); |
99 | |
100 | it("initializes w a graph and filled" , [&]() { |
101 | array->init(graph, fillElement); |
102 | AssertThat(array->graphOf(), Equals(&graph)); |
103 | AssertThat(array->valid(), IsTrue()); |
104 | AssertThat((*array)[chooseKey(graph)], Equals(fillElement)); |
105 | }); |
106 | |
107 | it("is constructed w a graph" , [&]() { |
108 | array.reset(new MyArrayType(graph)); |
109 | AssertThat(array->graphOf(), Equals(&graph)); |
110 | AssertThat(array->valid(), IsTrue()); |
111 | }); |
112 | |
113 | it("is constructed w a graph and filled" , [&]() { |
114 | array.reset(new MyArrayType(graph, fillElement)); |
115 | AssertThat(array->graphOf(), Equals(&graph)); |
116 | AssertThat(array->valid(), IsTrue()); |
117 | AssertThat((*array)[chooseKey(graph)], Equals(fillElement)); |
118 | }); |
119 | |
120 | it("supports copy-construction" , [&]() { |
121 | array->init(graph, fillElement); |
122 | MyArrayType copiedArray(*array); |
123 | AssertThat(copiedArray.graphOf(), Equals(array->graphOf())); |
124 | AssertThat(array->valid(), IsTrue()); |
125 | AssertThat((*array)[chooseKey(graph)], Equals(fillElement)); |
126 | AssertThat(copiedArray.valid(), IsTrue()); |
127 | AssertThat(copiedArray[chooseKey(graph)], Equals(fillElement)); |
128 | }); |
129 | |
130 | it("implements the assignment-operator" , [&]() { |
131 | array->init(graph, fillElement); |
132 | MyArrayType copiedArray = *array; |
133 | AssertThat(copiedArray.graphOf(), Equals(array->graphOf())); |
134 | AssertThat(copiedArray.valid(), IsTrue()); |
135 | AssertThat(copiedArray[chooseKey(graph)], Equals(fillElement)); |
136 | }); |
137 | |
138 | it("supports move-construction" , [&]() { |
139 | array->init(graph, fillElement); |
140 | MyArrayType copiedArray = std::move(*array); |
141 | AssertThat(copiedArray.graphOf(), Equals(&graph)); |
142 | AssertThat(array->graphOf(), IsNull()); |
143 | AssertThat(array->valid(), IsFalse()); |
144 | AssertThat(copiedArray.valid(), IsTrue()); |
145 | AssertThat(copiedArray[chooseKey(graph)], Equals(fillElement)); |
146 | }); |
147 | |
148 | it("moves an array using the assignment operator" , [&]() { |
149 | array->init(graph, fillElement); |
150 | MyArrayType copiedArray; |
151 | copiedArray = (std::move(*array)); |
152 | AssertThat(&(*copiedArray.graphOf()), Equals(&graph)); |
153 | AssertThat(array->graphOf(), IsNull()); |
154 | AssertThat(array->valid(), IsFalse()); |
155 | AssertThat(copiedArray.valid(), IsTrue()); |
156 | AssertThat(copiedArray[chooseKey(graph)], Equals(fillElement)); |
157 | }); |
158 | |
159 | it("assigns the default value to a newly created key" , [&]() { |
160 | array->init(graph, fillElement); |
161 | KeyType key = createKey(graph); |
162 | AssertThat((*array)[key], Equals(fillElement)); |
163 | }); |
164 | }); |
165 | |
166 | describe("access" , [&]() { |
167 | it("distinguishes between a valid and an invalid array" , [&]() { |
168 | AssertThat(array->valid(), IsFalse()); |
169 | array->init(graph); |
170 | AssertThat(array->valid(), IsTrue()); |
171 | }); |
172 | |
173 | it("knows its graph" , [&]() { |
174 | array->init(graph); |
175 | AssertThat(array->graphOf(), Equals(&graph)); |
176 | }); |
177 | |
178 | it("allows access with the subscript operator" , [&]() { |
179 | array->init(graph, fillElement); |
180 | KeyType k = chooseKey(graph); |
181 | AssertThat((*array)[k], Equals(fillElement)); |
182 | AssertThat((*array)[k] = secondElement, Equals(secondElement)); |
183 | |
184 | array->init(graph, fillElement); |
185 | const MyArrayType cAccessArray(*array); |
186 | AssertThat(cAccessArray[k], Equals(fillElement)); |
187 | }); |
188 | |
189 | it("allows access with the () operator" , [&]() { |
190 | array->init(graph, fillElement); |
191 | KeyType k = chooseKey(graph); |
192 | AssertThat((*array)(k), Equals(fillElement)); |
193 | AssertThat((*array)(k) = secondElement, Equals(secondElement)); |
194 | |
195 | array->init(graph, fillElement); |
196 | const MyArrayType cAccessArray(*array); |
197 | AssertThat(cAccessArray(k), Equals(fillElement)); |
198 | }); |
199 | }); |
200 | |
201 | describe("iterators" , [&]() { |
202 | before_each([&]() { |
203 | array->init(graph, fillElement); |
204 | }); |
205 | |
206 | it("iterates over the array" , [&]() { |
207 | List<KeyType> list; |
208 | getAllKeys(graph, list); |
209 | |
210 | const MyArrayType cArray(*array); |
211 | int counter = 0; |
212 | for(const_iterator it = cArray.begin(); it != cArray.end(); it++){ |
213 | counter++; |
214 | } |
215 | AssertThat(counter, Equals(list.size())); |
216 | |
217 | counter = 0; |
218 | for(iterator it = array->begin(); it != array->end(); it++){ |
219 | counter++; |
220 | } |
221 | AssertThat(counter, Equals(list.size())); |
222 | |
223 | counter = 0; |
224 | for(const_iterator it = cArray.cbegin(); it != cArray.cend(); it++){ |
225 | counter++; |
226 | } |
227 | AssertThat(counter, Equals(list.size())); |
228 | }); |
229 | }); |
230 | }); |
231 | } |
232 | |