UFO
test/ufo/RecursiveSplitter.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 2019 Met Office UK
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  */
7 
8 #ifndef TEST_UFO_RECURSIVESPLITTER_H_
9 #define TEST_UFO_RECURSIVESPLITTER_H_
10 
11 #include <iomanip>
12 #include <memory>
13 #include <set>
14 #include <string>
15 #include <vector>
16 
17 #include "eckit/testing/Test.h"
18 #include "oops/runs/Test.h"
19 #include "oops/util/Expect.h"
21 
22 namespace ufo {
23 namespace test {
24 
25 typedef std::set<size_t> Group;
26 typedef std::set<Group> Groups;
27 
29  Groups groups;
30  for (const auto &g : splitter.groups()) {
31  Group group;
32  for (auto index : g)
33  group.insert(index);
34  groups.insert(group);
35  }
36  return groups;
37 }
38 
40  Groups groups;
41  for (const auto &g : splitter.multiElementGroups()) {
42  Group group;
43  for (auto index : g)
44  group.insert(index);
45  groups.insert(group);
46  }
47  return groups;
48 }
49 
50 CASE("ufo/RecursiveSplitter/ZeroIds") {
51  RecursiveSplitter splitter(0);
52  {
53  Groups expectedGroups;
54  Groups groups = getGroups(splitter);
55  EXPECT_EQUAL(groups, expectedGroups);
56 
57  Groups expectedMultiElementGroups;
58  Groups multiElementGroups = getMultiElementGroups(splitter);
59  EXPECT_EQUAL(multiElementGroups, expectedMultiElementGroups);
60  }
61 
62  {
63  std::vector<size_t> categories;
64  splitter.groupBy(categories);
65 
66  Groups expectedGroups;
67  Groups groups = getGroups(splitter);
68  EXPECT_EQUAL(groups, expectedGroups);
69 
70  Groups expectedMultiElementGroups;
71  Groups multiElementGroups = getMultiElementGroups(splitter);
72  EXPECT_EQUAL(multiElementGroups, expectedMultiElementGroups);
73  }
74 }
75 
76 CASE("ufo/RecursiveSplitter/OneId") {
77  RecursiveSplitter splitter(1);
78  {
79  Groups expectedGroups{{0}};
80  Groups groups = getGroups(splitter);
81  EXPECT_EQUAL(groups, expectedGroups);
82 
83  Groups expectedMultiElementGroups;
84  Groups multiElementGroups = getMultiElementGroups(splitter);
85  EXPECT_EQUAL(multiElementGroups, expectedMultiElementGroups);
86  }
87 
88  {
89  std::vector<size_t> categories{1};
90  splitter.groupBy(categories);
91 
92  Groups expectedGroups{{0}};
93  Groups groups = getGroups(splitter);
94  EXPECT_EQUAL(groups, expectedGroups);
95 
96  Groups expectedMultiElementGroups;
97  Groups multiElementGroups = getMultiElementGroups(splitter);
98  EXPECT_EQUAL(multiElementGroups, expectedMultiElementGroups);
99  }
100 }
101 
102 CASE("ufo/RecursiveSplitter/TenIds") {
103  RecursiveSplitter splitter(10);
104  {
105  Groups expectedGroups{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}};
106  Groups groups = getGroups(splitter);
107  EXPECT_EQUAL(groups, expectedGroups);
108 
109  Groups expectedMultiElementGroups{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}};
110  Groups multiElementGroups = getMultiElementGroups(splitter);
111  EXPECT_EQUAL(multiElementGroups, expectedMultiElementGroups);
112  }
113 
114  {
115  std::vector<size_t> categories{1, 2, 1, 2, 1, 2, 1, 2, 1, 2};
116  splitter.groupBy(categories);
117 
118  Groups expectedGroups{{0, 2, 4, 6, 8}, {1, 3, 5, 7, 9}};
119  Groups groups = getGroups(splitter);
120  EXPECT_EQUAL(groups, expectedGroups);
121 
122  Groups expectedMultiElementGroups{{0, 2, 4, 6, 8}, {1, 3, 5, 7, 9}};
123  Groups multiElementGroups = getMultiElementGroups(splitter);
124  EXPECT_EQUAL(multiElementGroups, expectedMultiElementGroups);
125  }
126 
127  {
128  // The first and last category in the first group have only a single element
129  std::vector<size_t> categories{3, 2, 1, 2, 3, 2, 4, 2, 3, 2};
130  splitter.groupBy(categories);
131 
132  Groups expectedGroups{{2}, {0, 4, 8}, {6}, {1, 3, 5, 7, 9}};
133  Groups groups = getGroups(splitter);
134  EXPECT_EQUAL(groups, expectedGroups);
135 
136  Groups expectedMultiElementGroups{{0, 4, 8}, {1, 3, 5, 7, 9}};
137  Groups multiElementGroups = getMultiElementGroups(splitter);
138  EXPECT_EQUAL(multiElementGroups, expectedMultiElementGroups);
139  }
140 
141  {
142  // Two multiple-element categories in the second group.
143  // Categories shared by multiple groups.
144  std::vector<size_t> categories{1, 3, 1, 3, 1, 2, 1, 1, 1, 1};
145  splitter.groupBy(categories);
146 
147  Groups expectedGroups{{2}, {0, 4, 8}, {6}, {1, 3}, {5}, {7, 9}};
148  Groups groups = getGroups(splitter);
149  EXPECT_EQUAL(groups, expectedGroups);
150 
151  Groups expectedMultiElementGroups{{0, 4, 8}, {7, 9}, {1, 3}};
152  Groups multiElementGroups = getMultiElementGroups(splitter);
153  EXPECT_EQUAL(multiElementGroups, expectedMultiElementGroups);
154  }
155 }
156 
157 CASE("ufo/RecursiveSplitter/IntCategories") {
158  RecursiveSplitter splitter(10);
159 
160  {
161  std::vector<int> categories{1, 2, 1, 2, 1, 2, 1, 2, 1, 2};
162  splitter.groupBy(categories);
163 
164  Groups expectedGroups{{0, 2, 4, 6, 8}, {1, 3, 5, 7, 9}};
165  Groups groups = getGroups(splitter);
166  EXPECT_EQUAL(groups, expectedGroups);
167 
168  Groups expectedMultiElementGroups{{0, 2, 4, 6, 8}, {1, 3, 5, 7, 9}};
169  Groups multiElementGroups = getMultiElementGroups(splitter);
170  EXPECT_EQUAL(multiElementGroups, expectedMultiElementGroups);
171  }
172 }
173 
174 CASE("ufo/RecursiveSplitter/StringCategories") {
175  RecursiveSplitter splitter(10);
176 
177  {
178  std::vector<std::string> categories{"abc", "def", "abc", "def",
179  "abc", "def", "abc", "def",
180  "abc", "def"};
181  splitter.groupBy(categories);
182 
183  Groups expectedGroups{{0, 2, 4, 6, 8}, {1, 3, 5, 7, 9}};
184  Groups groups = getGroups(splitter);
185  EXPECT_EQUAL(groups, expectedGroups);
186 
187  Groups expectedMultiElementGroups{{0, 2, 4, 6, 8}, {1, 3, 5, 7, 9}};
188  Groups multiElementGroups = getMultiElementGroups(splitter);
189  EXPECT_EQUAL(multiElementGroups, expectedMultiElementGroups);
190  }
191 }
192 
193 class RecursiveSplitter : public oops::Test {
194  public:
196 
197  private:
198  std::string testid() const override {return "ufo::test::RecursiveSplitter";}
199 
200  void register_tests() const override {}
201 
202  void clear() const override {}
203 };
204 
205 } // namespace test
206 } // namespace ufo
207 
208 #endif // TEST_UFO_RECURSIVESPLITTER_H_
ufo::test::RecursiveSplitter::register_tests
void register_tests() const override
Definition: test/ufo/RecursiveSplitter.h:200
ufo::test::getGroups
Groups getGroups(const RecursiveSplitter &splitter)
Definition: test/ufo/RecursiveSplitter.h:28
ufo::test::CASE
CASE("ufo/MetOfficeBuddyPairFinder/" "Duplicates, constraints on buddy counts, legacy pair collector")
Definition: test/ufo/MetOfficeBuddyPairFinder.h:171
ufo::test::RecursiveSplitter::testid
std::string testid() const override
Definition: test/ufo/RecursiveSplitter.h:198
ufo::test::Group
std::set< size_t > Group
Definition: test/ufo/RecursiveSplitter.h:25
ufo
Definition: RunCRTM.h:27
ufo::test::getMultiElementGroups
Groups getMultiElementGroups(const RecursiveSplitter &splitter)
Definition: test/ufo/RecursiveSplitter.h:39
ufo::test::RecursiveSplitter::clear
void clear() const override
Definition: test/ufo/RecursiveSplitter.h:202
ufo::test::RecursiveSplitter::RecursiveSplitter
RecursiveSplitter()
Definition: test/ufo/RecursiveSplitter.h:195
ufo::test::RecursiveSplitter
Definition: test/ufo/RecursiveSplitter.h:193
ufo::test::Groups
std::set< Group > Groups
Definition: test/ufo/RecursiveSplitter.h:26
RecursiveSplitter.h