TestMerge.cxx
Go to the documentation of this file.
1 /*===========================================================================================================
2  *
3  * HUC - Hurna Core
4  *
5  * Copyright (c) Michael Jeulin-Lagarrigue
6  *
7  * Licensed under the MIT License, you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * https://github.com/Hurna/Hurna-Core/blob/master/LICENSE
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License is
13  * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and limitations under the License.
15  *
16  * The above copyright notice and this permission notice shall be included in all copies or
17  * substantial portions of the Software.
18  *
19  *=========================================================================================================*/
20 #include <gtest/gtest.h>
21 #include <merge.hxx>
22 
23 // STD includes
24 #include <functional>
25 #include <vector>
26 #include <string>
27 
28 // Testing namespace
29 using namespace huc::sort;
30 
31 #ifndef DOXYGEN_SKIP
32 namespace {
33  typedef std::vector<int> Container;
34  typedef Container::iterator IT;
35  typedef MergeWithBuffer<std::string::iterator> Aggregator_Str;
36 
37  const Container ArraySort = {-3, -2, 0, 2, 8, 15, 36, 212, 366}; // Sorted with neg values
38  const Container ArraySortWithRot = {-3, 2, 7, 20, 0, 2, 8, 15, 36}; // Sorted with a rotation
39  const Container ArraySortU = {0, 2, 8, 15, 36, 212, 366, 15478}; // Sorted positive values
40  const Container ArrayRand = {4, 3, 5, 2, -18, 3, 2, 3, 4, 5, -5}; // Random with neg values
41  const Container ArrayRandU = {4520, 30, 500, 20, 3, 2, 3, 4, 5, 15}; // Random positive values
42 
43  const std::string StrRand = "xacvgeze";
44  // String with pivot at end = begin() + 4 : Left sorted part [e,k,n,x] - Right sorted part [a,s,u,w]
45  const std::string StrRandPivot = "eknxasuw";
46 }
47 #endif /* DOXYGEN_SKIP */
48 
49 // Basic MergeInPlace tests
50 TEST(TestMerge, MergeInPlaces)
51 {
52  // Normal Run - All elements should be sorted in order
53  {
54  Container vector(ArraySortWithRot);
55  MergeInPlace<IT>()(vector.begin(), vector.begin() + 4, vector.end());
56 
57  // All elements of the final array are sorted
58  for (auto it = vector.begin(); it < vector.end() - 1; ++it)
59  EXPECT_LE(*it, *(it + 1));
60  }
61 
62  // Already SortArray - Array should not be affected
63  {
64  Container vector(ArraySortU);
65  MergeInPlace<IT>()(vector.begin(), vector.begin() + 5, vector.end());
66 
67  // All elements are still sorted
68  for (auto it = vector.begin(); it < vector.end() - 1; ++it)
69  EXPECT_LE(*it, *(it + 1));
70  }
71 
72  // Inverse iterator order - Array should not be affected
73  {
74  Container vector(ArrayRandU);
75  MergeInPlace<IT>()(vector.end(), vector.begin() + 3, vector.begin());
76 
77  int i = 0;
78  for (auto it = vector.begin(); it < vector.end(); ++it, ++i)
79  EXPECT_EQ(ArrayRandU[i], *it);
80  }
81 
82  // No error empty array
83  {
84  Container emptyArray;
85  MergeInPlace<IT>()(emptyArray.begin(), emptyArray.begin(), emptyArray.end());
86  }
87 
88  // Unique value array - Array should not be affected
89  {
90  Container uniqueValueArray(1, 511);
91  MergeInPlace<IT>()(uniqueValueArray.begin(), uniqueValueArray.end(), uniqueValueArray.end());
92  EXPECT_EQ(511, uniqueValueArray[0]);
93  }
94 
95  // Double values array - Order should be made
96  {
97  Container doubleValues(1, 511);
98  doubleValues.push_back(66);
99 
100  MergeInPlace<IT>()(doubleValues.begin(), doubleValues.begin() + 1, doubleValues.end());
101 
102  EXPECT_EQ(66, doubleValues[0]);
103  EXPECT_EQ(511, doubleValues[1]);
104  }
105 
106  // String Collection - All elements should be sorted in order
107  {
108  std::string str = StrRandPivot;
109  MergeInPlace<std::string::iterator>()(str.begin(), str.begin() + 4, str.end());
110 
111  // All elements of the final array are sorted
112  for (auto it = str.begin(); it < str.end() - 1; ++it)
113  EXPECT_LE(*it, *(it + 1));
114  }
115 }
116 
117 
118 // Basic MergeWithBuffer tests
119 TEST(TestMerge, MergeWithBuffers)
120 {
121  // Normal Run - All elements should be sorted in order
122  {
123  Container vector(ArraySortWithRot);
124  MergeWithBuffer<IT>()(vector.begin(), vector.begin() + 4, vector.end());
125 
126  // All elements of the final array are sorted
127  for (auto it = vector.begin(); it < vector.end() - 1; ++it)
128  EXPECT_LE(*it, *(it + 1));
129  }
130 
131  // Already SortArray - Array should not be affected
132  {
133  Container vector(ArraySortU);
134  MergeWithBuffer<IT>()(vector.begin(), vector.begin() + 5, vector.end());
135 
136  // All elements are still sorted
137  for (auto it = vector.begin(); it < vector.end() - 1; ++it)
138  EXPECT_LE(*it, *(it + 1));
139  }
140 
141  // Inverse iterator order - Array should not be affected
142  {
143  Container vector(ArrayRandU);
144  MergeWithBuffer<IT>()(vector.end(), vector.begin() + 3, vector.begin());
145 
146  int i = 0;
147  for (auto it = vector.begin(); it < vector.end(); ++it, ++i)
148  EXPECT_EQ(ArrayRandU[i], *it);
149  }
150 
151  // No error empty array
152  {
153  Container emptyArray;
154  MergeWithBuffer<IT>()(emptyArray.begin(), emptyArray.begin(), emptyArray.end());
155  }
156 
157  // Unique value array - Array should not be affected
158  {
159  Container uniqueValueArray(1, 511);
160  MergeWithBuffer<IT>()(uniqueValueArray.begin(), uniqueValueArray.end(), uniqueValueArray.end());
161  EXPECT_EQ(511, uniqueValueArray[0]);
162  }
163 
164  // Double values array - Order should be made
165  {
166  Container doubleValuesArray(1, 511);
167  doubleValuesArray.push_back(66);
168 
169  MergeWithBuffer<IT>()(doubleValuesArray.begin(), doubleValuesArray.begin() + 1, doubleValuesArray.end());
170 
171  EXPECT_EQ(66, doubleValuesArray[0]);
172  EXPECT_EQ(511, doubleValuesArray[1]);
173  }
174 
175  // String Collection - All elements should be sorted in order
176  {
177  std::string stringToMerge = "eknxasuw"; // Left sorted part [e,k,n,x] - Right sorted part [a,s,u,w]
179  (stringToMerge.begin(), stringToMerge.begin() + 4, stringToMerge.end());
180 
181  // All elements of the final array are sorted
182  for (std::string::iterator it = stringToMerge.begin(); it < stringToMerge.end() - 1; ++it)
183  EXPECT_LE(*it, *(it + 1));
184  }
185 }
186 
187 // Basic Merge-Sort tests - Uses the merge with buffer (computation optimized)
188 TEST(TestMerge, MergeSorts)
189 {
190  // Normal Run - all elements should be sorter in order
191  {
192  Container vector(ArrayRand);
193  MergeSort<IT>(vector.begin(), vector.end());
194 
195  // All elements are sorted
196  for (auto it = vector.begin(); it < vector.end() - 1; ++it)
197  EXPECT_LE(*it, *(it + 1));
198  }
199 
200  // Already SortArray - Array should not be affected
201  {
202  Container vector(ArraySort);
203  MergeSort<IT>(vector.begin(), vector.end());
204 
205  // All elements are still sorted
206  for (auto it = vector.begin(); it < vector.end() - 1; ++it)
207  EXPECT_LE(*it, *(it + 1));
208  }
209 
210  // Inverse iterator order - Array should not be affected
211  {
212  Container vector(ArrayRand);
213  MergeSort<IT>(vector.end(), vector.begin());
214 
215  int i = 0;
216  for (auto it = vector.begin(); it < vector.end(); ++it, ++i)
217  EXPECT_EQ(ArrayRand[i], *it);
218  }
219 
220  // No error empty array
221  {
222  Container emptyArray;
223  MergeSort<IT>(emptyArray.begin(), emptyArray.end());
224  }
225 
226  // Unique value array - Array should not be affected
227  {
228  Container uniqueValueArray(1, 511);
229  MergeSort<IT>(uniqueValueArray.begin(), uniqueValueArray.end());
230  EXPECT_EQ(511, uniqueValueArray[0]);
231  }
232 
233  // String collection - all elements should be sorter in order
234  {
235  std::string str = StrRand;
236  MergeSort<std::string::iterator, Aggregator_Str>(str.begin(), str.end());
237 
238  // All elements are sorted
239  for (auto it = str.begin(); it < str.end() - 1; ++it)
240  EXPECT_LE(*it, *(it + 1));
241  }
242 }
TEST(TestMerge, MergeInPlaces)
Definition: TestMerge.cxx:50