Support conversion of linkshere
[dueringa_WikiWalker.git] / test / CollectionMergeTests.cpp
blobfb09fcb5a787352ca822cc7cc22f566c1cc4aba6
1 #include <memory>
3 #include <UnitTest++/UnitTest++.h>
5 #include "Article.h"
6 #include "ArticleCollection.h"
7 #include "WalkerException.h"
9 SUITE(CollectionMergeTests)
11 using namespace WikiWalker;
12 using namespace WikiWalker::CollectionUtils;
14 /*!
15 * Create test data of the following structure:
16 * dragon -> treasure
17 * -> fire
18 * -> flying
19 * cat -> -
20 * apple -> fruit
21 * window -> outside
23 void createArticlesAndFillFirst(ArticleCollection & ac)
25 auto a1 = std::make_shared<Article>("Dragon");
26 auto a2 = std::make_shared<Article>("Treasure");
27 auto a3 = std::make_shared<Article>("Fire");
28 auto a4 = std::make_shared<Article>("Flying");
29 a1->addLink(a2);
30 a1->addLink(a3);
31 a1->addLink(a4);
33 auto a5 = std::make_shared<Article>("Cat");
35 auto a6 = std::make_shared<Article>("Apple");
36 auto a7 = std::make_shared<Article>("Fruit");
37 a6->addLink(a7);
39 auto a8 = std::make_shared<Article>("Window");
40 auto a9 = std::make_shared<Article>("Outside");
41 a8->addLink(a9);
43 CollectionUtils::add(ac, a1);
44 CollectionUtils::add(ac, a2);
45 CollectionUtils::add(ac, a3);
46 CollectionUtils::add(ac, a4);
47 CollectionUtils::add(ac, a5);
48 CollectionUtils::add(ac, a6);
49 CollectionUtils::add(ac, a7);
50 CollectionUtils::add(ac, a8);
51 CollectionUtils::add(ac, a9);
54 /*!
55 * Create test data of the following structure:
57 * dragon -> -
58 * cat -> milk
59 * -> lazy
60 * wood -> house
61 * window -> glass
62 * -> cleaning
64 void createArticlesAndFillSecond(ArticleCollection & ac)
66 auto b1 = std::make_shared<Article>("Dragon");
68 auto b2 = std::make_shared<Article>("Cat");
69 auto b9 = std::make_shared<Article>("Milk");
70 auto b3 = std::make_shared<Article>("Lazy");
71 b2->addLink(b3);
72 b2->addLink(b9);
74 auto b4 = std::make_shared<Article>("Wood");
75 auto b5 = std::make_shared<Article>("House");
76 b4->addLink(b5);
78 auto b6 = std::make_shared<Article>("Window");
79 auto b7 = std::make_shared<Article>("Glass");
80 auto b8 = std::make_shared<Article>("Cleaning");
81 b6->addLink(b7);
82 b6->addLink(b8);
84 CollectionUtils::add(ac, b1);
85 CollectionUtils::add(ac, b2);
86 CollectionUtils::add(ac, b3);
87 CollectionUtils::add(ac, b4);
88 CollectionUtils::add(ac, b5);
89 CollectionUtils::add(ac, b6);
90 CollectionUtils::add(ac, b7);
91 CollectionUtils::add(ac, b8);
92 CollectionUtils::add(ac, b9);
95 /*! check whether data from first set is preferred
97 * Overview of the combined structure-
99 * dragon -> treasure | dragon -> -
100 * -> fire |
101 * -> flying |
103 * cat -> - | cat -> milk
104 * | -> lazy
106 * apple -> fruit |
108 * | wood -> house
110 * window -> outside | window -> glass
111 * | -> cleaning
114 * So we have 15 articles in total, and either side of the links may exist
116 void checkConflicts_DataFromFirstSetPreferred(ArticleCollection & c1)
118 // 15 articles in total, no matter what
119 CHECK_EQUAL(15, c1.size());
121 // data from createArticlesAndFillFirst won
122 auto ptr = CollectionUtils::get(c1, "Dragon");
123 CHECK(ptr != nullptr);
124 CHECK_EQUAL(3, ptr->countLinks());
126 ptr = CollectionUtils::get(c1, "Cat");
127 CHECK(ptr != nullptr);
128 CHECK_THROW(ptr->countLinks(), WalkerException);
130 ptr = CollectionUtils::get(c1, "Window");
131 CHECK(ptr != nullptr);
132 CHECK_EQUAL(1, ptr->countLinks());
136 * see #checkConflicts_DataFromFirstSetPreferred, only for the second set
138 void checkConflicts_DataFromSecondSetPreferred(ArticleCollection & c2)
140 CHECK_EQUAL(15, c2.size());
142 // data from createArticlesAndFillSecond won
143 auto ptr = CollectionUtils::get(c2, "Dragon");
144 CHECK(ptr != nullptr);
145 CHECK_THROW(ptr->countLinks(), WalkerException);
147 ptr = CollectionUtils::get(c2, "Cat");
148 CHECK(ptr != nullptr);
149 CHECK_EQUAL(2, ptr->countLinks());
151 ptr = CollectionUtils::get(c2, "Window");
152 CHECK(ptr != nullptr);
153 CHECK_EQUAL(2, ptr->countLinks());
157 * see #checkConflicts_DataFromFirstSetPreferred, only for non-conflicting
158 * items
160 void checkNonConflictingItems(ArticleCollection & c)
162 // check non-conflicting items, too
163 auto ptr = CollectionUtils::get(c, "Apple");
164 CHECK(ptr != nullptr);
165 CHECK_EQUAL(1, ptr->countLinks());
167 ptr = CollectionUtils::get(c, "Wood");
168 CHECK(ptr != nullptr);
169 CHECK_EQUAL(1, ptr->countLinks());
172 TEST(ArticleCollection_TestMergeIgnore)
175 ArticleCollection a1, a2;
176 createArticlesAndFillFirst(a1);
177 createArticlesAndFillSecond(a2);
178 CollectionUtils::merge(
179 a1, a2, CollectionUtils::MergeStrategy::IgnoreDuplicates);
180 checkConflicts_DataFromFirstSetPreferred(a1);
181 checkNonConflictingItems(a1);
184 ArticleCollection a1, a2;
185 createArticlesAndFillFirst(a1);
186 createArticlesAndFillSecond(a2);
187 // reverse merge
188 CollectionUtils::merge(
189 a2, a1, CollectionUtils::MergeStrategy::IgnoreDuplicates);
190 checkConflicts_DataFromSecondSetPreferred(a2);
191 checkNonConflictingItems(a2);
195 // overwrite behaves "exactly the opposite" of ignore
196 TEST(ArticleCollection_TestMergeOverwrite)
199 ArticleCollection a1, a2;
200 createArticlesAndFillFirst(a1);
201 createArticlesAndFillSecond(a2);
202 CollectionUtils::merge(
203 a1, a2, CollectionUtils::MergeStrategy::AlwaysOverwrite);
204 checkConflicts_DataFromSecondSetPreferred(a1);
205 checkNonConflictingItems(a1);
208 ArticleCollection a1, a2;
209 createArticlesAndFillFirst(a1);
210 createArticlesAndFillSecond(a2);
211 // reverse merge
212 CollectionUtils::merge(
213 a2, a1, CollectionUtils::MergeStrategy::AlwaysOverwrite);
214 checkConflicts_DataFromFirstSetPreferred(a2);
215 checkNonConflictingItems(a2);
220 * see #checkConflicts_DataFromFirstSetPreferred, only for items with most
221 * links
223 void checkConflicts_DataWithMoreLinksPreferred(ArticleCollection & ac)
225 auto ptr = CollectionUtils::get(ac, "Dragon");
226 CHECK(ptr != nullptr);
227 CHECK_EQUAL(3, ptr->countLinks());
229 ptr = CollectionUtils::get(ac, "Cat");
230 CHECK(ptr != nullptr);
231 CHECK_EQUAL(2, ptr->countLinks());
233 ptr = CollectionUtils::get(ac, "Window");
234 CHECK(ptr != nullptr);
235 CHECK_EQUAL(2, ptr->countLinks());
238 TEST(ArticleCollection_TestMergeMoreLinks)
241 ArticleCollection a1, a2;
242 createArticlesAndFillFirst(a1);
243 createArticlesAndFillSecond(a2);
244 CollectionUtils::merge(
245 a1, a2, CollectionUtils::MergeStrategy::UseArticleWithMoreLinks);
246 CHECK_EQUAL(15, a1.size());
248 checkConflicts_DataWithMoreLinksPreferred(a1);
249 checkNonConflictingItems(a1);
252 ArticleCollection a1, a2;
253 createArticlesAndFillFirst(a1);
254 createArticlesAndFillSecond(a2);
255 // reverse merge
256 CollectionUtils::merge(
257 a2, a1, CollectionUtils::MergeStrategy::UseArticleWithMoreLinks);
258 CHECK_EQUAL(15, a2.size());
260 checkConflicts_DataWithMoreLinksPreferred(a2);
261 checkNonConflictingItems(a2);
265 TEST(ArticleCollection_TestMerge)
267 ArticleCollection ac1;
268 CollectionUtils::add(ac1, std::make_shared<Article>("ManaMana"));
269 CollectionUtils::add(ac1, std::make_shared<Article>("Dragon"));
270 CollectionUtils::add(ac1, std::make_shared<Article>("Cereals"));
273 ArticleCollection ac2;
274 CollectionUtils::add(ac2, std::make_shared<Article>("Dragon"));
275 CollectionUtils::add(ac2, std::make_shared<Article>("Git"));
276 CollectionUtils::add(ac2, std::make_shared<Article>("Stroustrup"));
277 CollectionUtils::merge(
278 ac1, ac2, CollectionUtils::MergeStrategy::IgnoreDuplicates);
280 CHECK_EQUAL(5, ac1.size());
281 CHECK_EQUAL(3, ac2.size());
283 // check again after scope is left
284 CHECK_EQUAL(5, ac1.size());