TestPartition.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 <partition.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 std::greater_equal<IT::value_type> GE_Compare;
36 
37  const Container ArraySort = {-3, -2, 0, 2, 8, 15, 36, 212, 366}; // Sorted with neg values
38  const Container ArrayInvSort = {366, 212, 36, 15, 8, 2, 0, -2, -3}; // Inverse Sorted with neg values
39  const Container ArrayRand = {4, 3, 5, 2, -18, 3, 2, 3, 4, 5, -5}; // Random sequence
40  const std::string StrRand = "xacvgeze";
41 
42 
43 
44  template<typename IT>
45  void CheckPartition (const IT& begin, const IT& end, const IT& newPivot,
46  typename std::iterator_traits<IT>::value_type pivotVal, bool inOrder = true)
47  {
48  // Value of the pivot not changed
49  EXPECT_EQ(pivotVal, *newPivot);
50 
51  // All elements before the pivot are smaller or equal
52  if (inOrder)
53  for (auto it = begin; it < newPivot; ++it)
54  EXPECT_GE(pivotVal, *it);
55  else
56  for (auto it = begin; it < newPivot; ++it)
57  EXPECT_LE(pivotVal, *it);
58 
59  // All elements before the pivot are bigger or equal
60  if (inOrder)
61  for (auto it = newPivot; it < end; ++it)
62  EXPECT_LE(pivotVal, *it);
63  else
64  for (auto it = newPivot; it < end; ++it)
65  EXPECT_GE(pivotVal, *it);
66  }
67 }
68 #endif /* DOXYGEN_SKIP */
69 
70 // Basic Partition tests
71 TEST(TestPartition, Partitions)
72 {
73  // Normal Run - Random Array
74  {
75  Container vector(ArrayRand);
76  auto pivot = vector.begin() + 5;
77  auto pivotVal = *pivot;
78 
79  // Run partition - Should result in: max[begin, pivot[ <= pivot <= min]pivot, end]
80  auto newPivot = Partition<IT>(vector.begin(), pivot, vector.end());
81  CheckPartition<IT>(vector.begin(), vector.end(), newPivot, pivotVal);
82  }
83 
84  // Already sortedArray - Array should not be affected
85  {
86  Container vector(ArraySort);
87  auto pivot = vector.begin() + 5;
88 
89  Partition<IT>(vector.begin(), pivot, vector.end());
90 
91  int i = 0;
92  for (auto it = vector.begin(); it < vector.end(); ++it, ++i)
93  EXPECT_EQ(ArraySort[i], *it);
94  }
95 
96  // Begin and End inversed - Array should not be affected
97  {
98  Container vector(ArrayRand);
99  auto pivot = vector.begin() + 5;
100 
101  Partition<IT>(vector.end(), pivot, vector.begin());
102 
103  int i = 0;
104  for (auto it = vector.begin(); it < vector.end(); ++it, ++i)
105  EXPECT_EQ(ArrayRand[i], *it);
106  }
107 }
108 
109 // String collection - Should result in: max[begin, pivot[ <= pivot <= min]pivot, end]
110 TEST(TestPartition, PartitionString)
111 {
112  std::string str = StrRand;
113  auto pivot = str.begin() + 5;
114  auto pivotVal = *pivot;
115 
116  auto newPivot = Partition<std::string::iterator>(str.begin(), pivot, str.end());
117  CheckPartition<std::string::iterator>(str.begin(), str.end(), newPivot, pivotVal);
118 }
119 
120 // Extreme Pivot Partition tests
121 TEST(TestPartition, PartitionBoudaryPivots)
122 {
123  // Pivot choose as begin
124  {
125  Container vector(ArrayRand);
126  auto pivot = vector.begin();
127  const int pivotVal = *pivot;
128 
129  // Run partition
130  auto newPivot = Partition<IT>(vector.begin(), pivot, vector.end());
131  CheckPartition<IT>(vector.begin(), vector.end(), newPivot, pivotVal);
132 
133  }
134 
135  // Pivot choose as last element
136  {
137  Container vector(ArrayRand);
138  auto pivot = vector.end() - 1;
139  const int pivotVal = *pivot;
140 
141  // Run partition
142  auto newPivot = Partition<IT>(vector.begin(), pivot, vector.end());
143  CheckPartition<IT>(vector.begin(), vector.end(), newPivot, pivotVal);
144  }
145 
146  // Pivot choose as end - cannot process
147  {
148  Container vector(ArrayRand);
149  auto pivot = vector.end();
150 
151  // Run partition
152  Partition<IT>(vector.begin(), pivot, vector.end());
153 
154  int i = 0;
155  for (auto it = vector.begin(); it < vector.end(); ++it, ++i)
156  EXPECT_EQ(ArrayRand[i], *it);
157  }
158 }
159 
160 // Basic Partition tests - Greater element in the left partition
161 TEST(TestPartition, PartitionGreaterComparator)
162 {
163  // Normal Run - Should result in: min[begin, pivot[ >= pivot >= max]pivot, end]
164  {
165  Container vector(ArrayRand);
166  auto pivot = vector.begin() + 5;
167  const auto pivotVal = *pivot;
168 
169  // Run partition
170  auto newPivot = Partition<IT, GE_Compare>(vector.begin(), pivot, vector.end());
171  CheckPartition<IT>(vector.begin(), vector.end(), newPivot, pivotVal, false);
172  }
173 
174  // Already InverseSortedArray - Array should not be affected
175  {
176  Container invSortedArray(ArrayInvSort);
177  auto pivot = invSortedArray.begin() + 5;
178 
179  Partition<IT, GE_Compare>(invSortedArray.begin(), pivot, invSortedArray.end());
180 
181  int i = 0;
182  for (auto it = invSortedArray.begin(); it < invSortedArray.end(); ++it, ++i)
183  EXPECT_EQ(invSortedArray[i], *it);
184  }
185 
186  // String collection - Should result in: min[begin, pivot[ >= pivot >= max]pivot, end]
187  {
188  std::string str = StrRand;
189  auto pivot = str.begin() + 5;
190  const auto pivotVal = *pivot;
191 
192  // Run partition
193  auto newPivot =
194  Partition<std::string::iterator, std::greater_equal<char>>(str.begin(), pivot, str.end());
195  CheckPartition<std::string::iterator>(str.begin(), str.end(), newPivot, pivotVal, false);
196  }
197 }
TEST(TestPartition, Partitions)