KiCad PCB EDA Suite
Loading...
Searching...
No Matches
unit_test_utils.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2018 KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#ifndef UNIT_TEST_UTILS__H
25#define UNIT_TEST_UTILS__H
26
27#define BOOST_NO_AUTO_PTR
28
29#include <boost/test/unit_test.hpp>
30#include <turtle/mock.hpp>
31
33
34#include <functional>
35#include <optional>
36#include <set>
37
38#include <wx/gdicmn.h>
39
40
41
42template<class T>
44{
45 PRINTABLE_OPT( const std::optional<T>& aOpt ) : m_Opt( aOpt ){};
46 PRINTABLE_OPT( const T& aVal ) : m_Opt( aVal ){};
47
48 std::optional<T> m_Opt;
49};
50
51
55#define KI_CHECK_OPT_EQUAL( lhs, rhs ) \
56 BOOST_CHECK_EQUAL( PRINTABLE_OPT( lhs ), PRINTABLE_OPT( rhs ) )
57
58
59template <class T>
60inline std::ostream& operator<<( std::ostream& aOs, const PRINTABLE_OPT<T>& aOptional )
61{
62 if( aOptional.m_Opt.has_value() )
63 aOs << *aOptional.m_Opt;
64 else
65 aOs << "nullopt";
66
67 return aOs;
68}
69
70
71template <class L, class R>
72inline bool operator==( const PRINTABLE_OPT<L>& aLhs, const PRINTABLE_OPT<R>& aRhs )
73{
74 if( !aLhs.m_Opt.has_value() && !aRhs.m_Opt.has_value() )
75 return true; // both nullopt
76
77 return aLhs.m_Opt.has_value() && aRhs.m_Opt.has_value() && *aLhs.m_Opt == *aRhs.m_Opt;
78}
79
80
81template <class L, class R>
82inline bool operator!=( const PRINTABLE_OPT<L>& aLhs, const PRINTABLE_OPT<R>& aRhs )
83{
84 return !( aLhs == aRhs );
85}
86
87
88// boost_test_print_type has to be in the same namespace as the printed type
89namespace std
90{
91
95template <typename T>
96std::ostream& boost_test_print_type( std::ostream& os, std::vector<T> const& aVec )
97{
98 os << "std::vector size " << aVec.size() << " [";
99
100 for( const auto& i : aVec )
101 {
102 os << "\n " << i;
103 }
104
105 os << "]";
106 return os;
107}
108
112template <typename K, typename V>
113std::ostream& boost_test_print_type( std::ostream& os, std::map<K, V> const& aMap )
114{
115 os << "std::map size " << aMap.size() << " [";
116
117 for( const auto& [key, value] : aMap )
118 {
119 os << "\n " << key << " = " << value;
120 }
121
122 os << "]";
123 return os;
124}
125
129template <typename K, typename V>
130std::ostream& boost_test_print_type( std::ostream& os, std::pair<K, V> const& aPair )
131{
132 os << "[" << aPair.first << ", " << aPair.second << "]";
133 return os;
134}
135
136} // namespace std
137
138
143std::ostream& boost_test_print_type( std::ostream& os, wxPoint const& aVec );
144
145
146namespace KI_TEST
147{
148
149template <typename EXP_CONT> using EXP_OBJ = typename EXP_CONT::value_type;
150template <typename FOUND_CONT> using FOUND_OBJ = typename FOUND_CONT::value_type;
151
168template <typename EXP_OBJ, typename FOUND_OBJ>
169using MATCH_PRED = std::function<bool( const EXP_OBJ&, const FOUND_OBJ& )>;
170
205template <typename EXP_CONT, typename FOUND_CONT, typename MATCH_PRED>
206void CheckUnorderedMatches( const EXP_CONT& aExpected, const FOUND_CONT& aFound,
207 MATCH_PRED aMatchPredicate )
208{
209 using EXP_OBJ = typename EXP_CONT::value_type;
210
211 // set of object we've already found
212 std::set<const EXP_OBJ*> matched;
213
214 // fill the set of object that match
215 for( const auto& found : aFound )
216 {
217 for( const auto& expected : aExpected )
218 {
219 if( aMatchPredicate( expected, found ) )
220 {
221 matched.insert( &expected );
222 break;
223 }
224 }
225 }
226
227 // first check every expected object was "found"
228 for( const EXP_OBJ& exp : aExpected )
229 {
230 BOOST_CHECK_MESSAGE( matched.count( &exp ) > 0, "Expected item was not found. Expected: \n"
231 << exp );
232 }
233
234 // check every "found" object was expected
235 for( const EXP_OBJ* found : matched )
236 {
237 const bool was_expected = std::find_if( aExpected.begin(), aExpected.end(),
238 [found]( const EXP_OBJ& aObj )
239 {
240 return &aObj == found;
241 } ) != aExpected.end();
242
243 BOOST_CHECK_MESSAGE( was_expected, "Found item was not expected. Found: \n" << *found );
244 }
245}
246
247
251template <typename T>
252bool CollectionHasNoDuplicates( const T& aCollection )
253{
254 T sorted = aCollection;
255 std::sort( sorted.begin(), sorted.end() );
256
257 return std::adjacent_find( sorted.begin(), sorted.end() ) == sorted.end();
258}
259
260
267#ifdef DEBUG
268#define CHECK_WX_ASSERT( STATEMENT ) BOOST_CHECK_THROW( STATEMENT, KI_TEST::WX_ASSERT_ERROR );
269#else
270#define CHECK_WX_ASSERT( STATEMENT )
271#endif
272
281std::string GetEeschemaTestDataDir();
282
283} // namespace KI_TEST
284
285#endif // UNIT_TEST_UTILS__H
std::ostream & operator<<(std::ostream &aStream, const EDA_TEXT &aText)
Definition: eda_text.cpp:1306
void CheckUnorderedMatches(const EXP_CONT &aExpected, const FOUND_CONT &aFound, MATCH_PRED aMatchPredicate)
Check that a container of "found" objects matches a container of "expected" objects.
std::string GetEeschemaTestDataDir()
Get the configured location of Eeschema test data.
bool CollectionHasNoDuplicates(const T &aCollection)
Predicate to check a collection has no duplicate elements.
std::function< bool(const EXP_OBJ &, const FOUND_OBJ &)> MATCH_PRED
A match predicate: check that a "found" object is equivalent to or represents an "expected" object,...
typename FOUND_CONT::value_type FOUND_OBJ
typename EXP_CONT::value_type EXP_OBJ
STL namespace.
std::ostream & boost_test_print_type(std::ostream &os, std::vector< T > const &aVec)
Boost print helper for generic vectors.
std::optional< T > m_Opt
PRINTABLE_OPT(const T &aVal)
PRINTABLE_OPT(const std::optional< T > &aOpt)
VECTOR3I expected(15, 30, 45)
bool operator!=(const PRINTABLE_OPT< L > &aLhs, const PRINTABLE_OPT< R > &aRhs)
bool operator==(const PRINTABLE_OPT< L > &aLhs, const PRINTABLE_OPT< R > &aRhs)
std::ostream & boost_test_print_type(std::ostream &os, wxPoint const &aVec)
Boost print helper for wxPoint.