QA: Make a separate unit test utils library, COLOR4D tests
This includes: * Linkage against the Boost unit test libs * Configuration of the Boost libs * A place for common generics "extras" for unit test harnesses including * A simple way to allow "expected-failure" tests (without breaking Boost < 1.58, e.g. Ubuntu LTS) * Moving some simple numeric predicates from the geom tests to the utils library. Expand unit test docs to describe the expected failures macro. Add a few COLOR4D tests, including one with expected failures due to a pre-existing bug. This will be fixed in a follow-up commit.
This commit is contained in:
parent
0980f7232c
commit
ee819216e2
|
@ -70,6 +70,50 @@ messages inside tested functions (i.e. where you don't have access to the Boost
|
||||||
unit test headers). These will always be printed, so take care
|
unit test headers). These will always be printed, so take care
|
||||||
to remove them before committing, or they'll show up when KiCad runs normally!
|
to remove them before committing, or they'll show up when KiCad runs normally!
|
||||||
|
|
||||||
|
### Expected failures {#expected-failures}
|
||||||
|
|
||||||
|
Sometimes, it is helpful to check in tests that do not pass. However, it is bad
|
||||||
|
practise to intentionally check in commits that break builds (which is what
|
||||||
|
happens if you cause `make test` to fail).
|
||||||
|
|
||||||
|
Boost provides a method of declaring that some specific tests are allowed to fail.
|
||||||
|
This syntax is not consistently available in all supported Boost versions, so you
|
||||||
|
should use the following construct:
|
||||||
|
|
||||||
|
```
|
||||||
|
#include <unit_test_utils/unit_test_utils.h>
|
||||||
|
|
||||||
|
// On platforms with older boosts, the test will be excluded entirely
|
||||||
|
#ifdef HAVE_EXPECTED_FAILURES
|
||||||
|
|
||||||
|
// Declare a test case with 1 "allowed" failure (out of 2, in this case)
|
||||||
|
BOOST_AUTO_TEST_CASE( SomeTest, *boost::unit_test::expected_failures( 1 ) )
|
||||||
|
{
|
||||||
|
BOOST_CHECK_EQUAL( 1, 1 );
|
||||||
|
|
||||||
|
// This check fails, but does not cause a test suite failure
|
||||||
|
BOOST_CHECK_EQUAL( 1, 2 );
|
||||||
|
|
||||||
|
// Further failures *would* be a test suit failure
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
```
|
||||||
|
|
||||||
|
When run, this produces output somewhat like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
qa/common/test_mytest.cpp(123): error: in "MyTests/SomeTest": check 1 == 2 has failed [1 != 2
|
||||||
|
*** No errors detected
|
||||||
|
```
|
||||||
|
|
||||||
|
And the unit test executable returns `0` (success).
|
||||||
|
|
||||||
|
Checking in a failing test is a strictly temporary situation, used to illustrate
|
||||||
|
the triggering of a bug prior to fixing it. This is advantageous, not only from
|
||||||
|
a "project history" perspective, but also to ensure that the test you write to
|
||||||
|
catch the bug in question does, in fact, catch the bug in the first place.
|
||||||
|
|
||||||
## Python modules {#python-tests}
|
## Python modules {#python-tests}
|
||||||
|
|
||||||
The Pcbnew Python modules have some test programs in the `qa` directory.
|
The Pcbnew Python modules have some test programs in the `qa` directory.
|
||||||
|
|
|
@ -14,6 +14,7 @@ endif()
|
||||||
|
|
||||||
# common QA helpers
|
# common QA helpers
|
||||||
add_subdirectory( qa_utils )
|
add_subdirectory( qa_utils )
|
||||||
|
add_subdirectory( unit_test_utils )
|
||||||
|
|
||||||
add_subdirectory( common )
|
add_subdirectory( common )
|
||||||
add_subdirectory( shape_poly_set_refactor )
|
add_subdirectory( shape_poly_set_refactor )
|
||||||
|
|
|
@ -19,12 +19,8 @@
|
||||||
# or you may write to the Free Software Foundation, Inc.,
|
# or you may write to the Free Software Foundation, Inc.,
|
||||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
|
||||||
find_package(Boost COMPONENTS unit_test_framework REQUIRED)
|
|
||||||
find_package( wxWidgets 3.0.0 COMPONENTS gl aui adv html core net base xml stc REQUIRED )
|
find_package( wxWidgets 3.0.0 COMPONENTS gl aui adv html core net base xml stc REQUIRED )
|
||||||
|
|
||||||
|
|
||||||
add_definitions(-DBOOST_TEST_DYN_LINK)
|
|
||||||
|
|
||||||
add_executable( qa_common
|
add_executable( qa_common
|
||||||
# This is needed for the global mock objects
|
# This is needed for the global mock objects
|
||||||
common_mocks.cpp
|
common_mocks.cpp
|
||||||
|
@ -39,6 +35,7 @@ add_executable( qa_common
|
||||||
../../common/colors.cpp
|
../../common/colors.cpp
|
||||||
../../common/observable.cpp
|
../../common/observable.cpp
|
||||||
|
|
||||||
|
test_color4d.cpp
|
||||||
test_hotkey_store.cpp
|
test_hotkey_store.cpp
|
||||||
test_title_block.cpp
|
test_title_block.cpp
|
||||||
test_utf8.cpp
|
test_utf8.cpp
|
||||||
|
@ -50,7 +47,6 @@ include_directories(
|
||||||
${CMAKE_SOURCE_DIR}
|
${CMAKE_SOURCE_DIR}
|
||||||
${CMAKE_SOURCE_DIR}/include
|
${CMAKE_SOURCE_DIR}/include
|
||||||
${CMAKE_SOURCE_DIR}/polygon
|
${CMAKE_SOURCE_DIR}/polygon
|
||||||
${Boost_INCLUDE_DIR}
|
|
||||||
${INC_AFTER}
|
${INC_AFTER}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -60,7 +56,8 @@ target_link_libraries( qa_common
|
||||||
polygon
|
polygon
|
||||||
bitmaps
|
bitmaps
|
||||||
gal
|
gal
|
||||||
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
|
qa_utils
|
||||||
|
unit_test_utils
|
||||||
${wxWidgets_LIBRARIES}
|
${wxWidgets_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -26,55 +26,18 @@
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
#include <geometry/seg.h>
|
||||||
|
#include <geometry/shape_line_chain.h>
|
||||||
|
#include <geometry/shape_poly_set.h>
|
||||||
|
|
||||||
|
#include <unit_test_utils/numeric.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Utility functions for testing geometry functions.
|
* @brief Utility functions for testing geometry functions.
|
||||||
*/
|
*/
|
||||||
namespace GEOM_TEST
|
namespace GEOM_TEST
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check if a value is within a tolerance of a nominal value
|
|
||||||
*
|
|
||||||
* @return value is in [aNominal - aError, aNominal + aError]
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
bool IsWithin( T aValue, T aNominal, T aError )
|
|
||||||
{
|
|
||||||
return ( aValue >= aNominal - aError )
|
|
||||||
&& ( aValue <= aNominal + aError );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Check if a value is within a tolerance of a nominal value,
|
|
||||||
* with different allowances for errors above and below.
|
|
||||||
*
|
|
||||||
* @return value is in [aNominal - aErrorBelow, aNominal + aErrorAbove]
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
bool IsWithin( T aValue, T aNominal, T aErrorAbove, T aErrorBelow )
|
|
||||||
{
|
|
||||||
return ( aValue >= aNominal - aErrorBelow )
|
|
||||||
&& ( aValue <= aNominal + aErrorAbove );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief value is in range [aNominal - aErrorBelow, aNominal]
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
bool IsWithinAndBelow( T aValue, T aNominal, T aErrorBelow )
|
|
||||||
{
|
|
||||||
return IsWithin( aValue, aNominal, 0, aErrorBelow );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief value is in range [aNominal, aNominal + aErrorAbove]
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
bool IsWithinAndAbove( T aValue, T aNominal, T aErrorAbove )
|
|
||||||
{
|
|
||||||
return IsWithin( aValue, aNominal, aErrorAbove, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Geometric quadrants, from top-right, anti-clockwise
|
* @brief Geometric quadrants, from top-right, anti-clockwise
|
||||||
*
|
*
|
||||||
|
@ -163,7 +126,7 @@ bool ArePerpendicular( const VECTOR2<T>& a, const VECTOR2<T>& b, double aToleran
|
||||||
angle -= M_PI;
|
angle -= M_PI;
|
||||||
}
|
}
|
||||||
|
|
||||||
return IsWithin( angle, M_PI / 2.0, aTolerance );
|
return KI_TEST::IsWithin( angle, M_PI / 2.0, aTolerance );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#include <boost/test/unit_test.hpp>
|
#include <boost/test/unit_test.hpp>
|
||||||
#include <boost/test/test_case_template.hpp>
|
#include <boost/test/test_case_template.hpp>
|
||||||
|
|
||||||
|
#include <unit_test_utils/unit_test_utils.h>
|
||||||
|
|
||||||
#include <geometry/shape_poly_set.h>
|
#include <geometry/shape_poly_set.h>
|
||||||
#include <geometry/shape_line_chain.h>
|
#include <geometry/shape_line_chain.h>
|
||||||
|
|
||||||
|
@ -51,26 +53,24 @@ BOOST_FIXTURE_TEST_SUITE( Fillet, FilletFixture )
|
||||||
void TestFilletSegmentConstraints( const SEG& aSeg, VECTOR2I aRadCentre,
|
void TestFilletSegmentConstraints( const SEG& aSeg, VECTOR2I aRadCentre,
|
||||||
int aRadius, int aError )
|
int aRadius, int aError )
|
||||||
{
|
{
|
||||||
using namespace GEOM_TEST;
|
|
||||||
|
|
||||||
const auto diffA = aRadCentre - aSeg.A;
|
const auto diffA = aRadCentre - aSeg.A;
|
||||||
const auto diffB = aRadCentre - aSeg.B;
|
const auto diffB = aRadCentre - aSeg.B;
|
||||||
const auto diffC = aRadCentre - aSeg.Center();
|
const auto diffC = aRadCentre - aSeg.Center();
|
||||||
|
|
||||||
// Check 1: radii (error of 1 for rounding)
|
// Check 1: radii (error of 1 for rounding)
|
||||||
BOOST_CHECK_PREDICATE( IsWithinAndBelow<int>,
|
BOOST_CHECK_PREDICATE(
|
||||||
( diffA.EuclideanNorm() )( aRadius )( 1 ) );
|
KI_TEST::IsWithinAndBelow<int>, ( diffA.EuclideanNorm() )( aRadius )( 1 ) );
|
||||||
BOOST_CHECK_PREDICATE( IsWithinAndBelow<int>,
|
BOOST_CHECK_PREDICATE(
|
||||||
( diffB.EuclideanNorm() )( aRadius )( 1 ) );
|
KI_TEST::IsWithinAndBelow<int>, ( diffB.EuclideanNorm() )( aRadius )( 1 ) );
|
||||||
|
|
||||||
// Check 2: Mid-point error
|
// Check 2: Mid-point error
|
||||||
BOOST_CHECK_PREDICATE( IsWithinAndBelow<int>,
|
BOOST_CHECK_PREDICATE(
|
||||||
( diffC.EuclideanNorm() )( aRadius )( aError + 1 ) );
|
KI_TEST::IsWithinAndBelow<int>, ( diffC.EuclideanNorm() )( aRadius )( aError + 1 ) );
|
||||||
|
|
||||||
// Check 3: Mid-point -> radius centre perpendicular
|
// Check 3: Mid-point -> radius centre perpendicular
|
||||||
const auto perpendularityMaxError = ( M_PI / 2 ) / 10;
|
const auto perpendularityMaxError = ( M_PI / 2 ) / 10;
|
||||||
BOOST_CHECK_PREDICATE( ArePerpendicular<int>,
|
BOOST_CHECK_PREDICATE( GEOM_TEST::ArePerpendicular<int>,
|
||||||
( diffC )( aSeg.A - aSeg.B )( perpendularityMaxError ) );
|
( diffC )( aSeg.A - aSeg.B )( perpendularityMaxError ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,289 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018 KiCad Developers, see CHANGELOG.TXT for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <boost/test/test_case_template.hpp>
|
||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
#include <unit_test_utils/numeric.h>
|
||||||
|
#include <unit_test_utils/unit_test_utils.h>
|
||||||
|
|
||||||
|
#include <gal/color4d.h>
|
||||||
|
|
||||||
|
#ifdef WX_COMPATIBILITY
|
||||||
|
#include <wx/colour.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// All these tests are of a class in KIGFX
|
||||||
|
using namespace KIGFX;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a COLOR4D is close enough to another
|
||||||
|
*/
|
||||||
|
bool pred_colour_is_near( const COLOR4D& aCol, const COLOR4D aOther, double aTol )
|
||||||
|
{
|
||||||
|
return KI_TEST::IsWithin<double>( aCol.r, aOther.r, aTol )
|
||||||
|
&& KI_TEST::IsWithin<double>( aCol.g, aOther.g, aTol )
|
||||||
|
&& KI_TEST::IsWithin<double>( aCol.b, aOther.b, aTol )
|
||||||
|
&& KI_TEST::IsWithin<double>( aCol.a, aOther.a, aTol );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a COLOR4D is close enough to a given RGB char value
|
||||||
|
*/
|
||||||
|
bool pred_colour_is_near_hex(
|
||||||
|
const COLOR4D& aCol, unsigned char r, unsigned char g, unsigned char b, unsigned char a )
|
||||||
|
{
|
||||||
|
const double tol = 0.5 / 255.0; // One bit of quantised error
|
||||||
|
|
||||||
|
return KI_TEST::IsWithin<double>( aCol.r, r / 255.0, tol )
|
||||||
|
&& KI_TEST::IsWithin<double>( aCol.g, g / 255.0, tol )
|
||||||
|
&& KI_TEST::IsWithin<double>( aCol.b, b / 255.0, tol )
|
||||||
|
&& KI_TEST::IsWithin<double>( aCol.a, a / 255.0, tol );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declares a struct as the Boost test fixture.
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_SUITE( Color4D )
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check basic setting and getting of values
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_CASE( BasicOps )
|
||||||
|
{
|
||||||
|
const auto c = COLOR4D{ 0.4, 0.5, 0.6, 0.7 };
|
||||||
|
|
||||||
|
BOOST_CHECK_EQUAL( c.r, 0.4 );
|
||||||
|
BOOST_CHECK_EQUAL( c.g, 0.5 );
|
||||||
|
BOOST_CHECK_EQUAL( c.b, 0.6 );
|
||||||
|
BOOST_CHECK_EQUAL( c.a, 0.7 );
|
||||||
|
|
||||||
|
const auto copied = c;
|
||||||
|
|
||||||
|
// Test equality
|
||||||
|
BOOST_CHECK_EQUAL( c, copied );
|
||||||
|
|
||||||
|
const auto c2 = COLOR4D{ 0.1, 0.2, 0.3, 0.4 };
|
||||||
|
|
||||||
|
// Test inequality
|
||||||
|
BOOST_CHECK_NE( c, c2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test case data for a test that takes a colour and a scalar factor
|
||||||
|
* and returns a result.
|
||||||
|
*/
|
||||||
|
struct COLOR_SCALAR_CASE
|
||||||
|
{
|
||||||
|
COLOR4D start;
|
||||||
|
double factor;
|
||||||
|
COLOR4D expected;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check inversion
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_CASE( Invert )
|
||||||
|
{
|
||||||
|
// Inverts RGB, A is the same
|
||||||
|
static const std::vector<COLOR_SCALAR_CASE> cases = {
|
||||||
|
{ { 0.0, 0.25, 1.0, 1.0 }, 0.0, { 1.0, 0.75, 0.0, 1.0 } },
|
||||||
|
};
|
||||||
|
|
||||||
|
for( const auto& c : cases )
|
||||||
|
{
|
||||||
|
auto col = c.start;
|
||||||
|
|
||||||
|
const auto inverted = col.Inverted();
|
||||||
|
BOOST_CHECK_EQUAL( inverted, c.expected );
|
||||||
|
|
||||||
|
// Test in-place function
|
||||||
|
col.Invert();
|
||||||
|
BOOST_CHECK_EQUAL( col, c.expected );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check inversion
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_CASE( Brighten )
|
||||||
|
{
|
||||||
|
static const std::vector<COLOR_SCALAR_CASE> cases = {
|
||||||
|
{ { 0.0, 0.0, 0.0, 1.0 }, 0.5, { 0.5, 0.5, 0.5, 1.0 } },
|
||||||
|
{ { 0.0, 0.5, 1.0, 1.0 }, 0.5, { 0.5, 0.75, 1.0, 1.0 } },
|
||||||
|
};
|
||||||
|
|
||||||
|
for( const auto& c : cases )
|
||||||
|
{
|
||||||
|
auto col = c.start;
|
||||||
|
|
||||||
|
const auto brightened = col.Brightened( c.factor );
|
||||||
|
BOOST_CHECK_EQUAL( brightened, c.expected );
|
||||||
|
|
||||||
|
// Test in-place function
|
||||||
|
col.Brighten( c.factor );
|
||||||
|
BOOST_CHECK_EQUAL( col, c.expected );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check darken
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_CASE( Darken )
|
||||||
|
{
|
||||||
|
static const std::vector<COLOR_SCALAR_CASE> cases = {
|
||||||
|
{ { 0.0, 0.0, 0.0, 1.0 }, 0.5, { 0.0, 0.0, 0.0, 1.0 } },
|
||||||
|
{ { 1.0, 1.0, 1.0, 1.0 }, 0.5, { 0.5, 0.5, 0.5, 1.0 } },
|
||||||
|
};
|
||||||
|
|
||||||
|
for( const auto& c : cases )
|
||||||
|
{
|
||||||
|
auto col = c.start;
|
||||||
|
|
||||||
|
const auto brightened = col.Darkened( c.factor );
|
||||||
|
BOOST_CHECK_EQUAL( brightened, c.expected );
|
||||||
|
|
||||||
|
// Test in-place function
|
||||||
|
col.Darken( c.factor );
|
||||||
|
BOOST_CHECK_EQUAL( col, c.expected );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check alpha setting
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_CASE( WithAlpha )
|
||||||
|
{
|
||||||
|
static const std::vector<COLOR_SCALAR_CASE> cases = {
|
||||||
|
{ { 0.0, 0.0, 0.0, 1.0 }, 0.5, { 0.0, 0.0, 0.0, 0.5 } },
|
||||||
|
{ { 0.0, 0.5, 1.0, 1.0 }, 0.5, { 0.0, 0.5, 1.0, 0.5 } },
|
||||||
|
};
|
||||||
|
|
||||||
|
for( const auto& c : cases )
|
||||||
|
{
|
||||||
|
auto col = c.start;
|
||||||
|
|
||||||
|
const auto with_alpha = col.WithAlpha( c.factor );
|
||||||
|
BOOST_CHECK_EQUAL( with_alpha, c.expected );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: If COLOR4D::WithAlpha raised an exception, we could check
|
||||||
|
// the bounds-checking with BOOST_REQUIRE_THROW,
|
||||||
|
// but it assert()s, so we can't.
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FROM_HSV_TO_HEX_CASE
|
||||||
|
{
|
||||||
|
double h;
|
||||||
|
double s;
|
||||||
|
double v;
|
||||||
|
unsigned char r;
|
||||||
|
unsigned char g;
|
||||||
|
unsigned char b;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check FromHSV
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_CASE( FromHsv )
|
||||||
|
{
|
||||||
|
static const std::vector<FROM_HSV_TO_HEX_CASE> cases = {
|
||||||
|
{ 90.0, 0.5, 0.5, 96, 128, 64 },
|
||||||
|
};
|
||||||
|
|
||||||
|
for( const auto& c : cases )
|
||||||
|
{
|
||||||
|
auto col = COLOR4D{};
|
||||||
|
col.FromHSV( c.h, c.s, c.v );
|
||||||
|
const unsigned char alpha = 0xFF;
|
||||||
|
|
||||||
|
BOOST_CHECK_PREDICATE( pred_colour_is_near_hex, ( col )( c.r )( c.g )( c.b )( alpha ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WX_COMPATIBILITY
|
||||||
|
|
||||||
|
struct WX_CONV_CASE
|
||||||
|
{
|
||||||
|
wxColour wx;
|
||||||
|
COLOR4D c4d;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static std::vector<WX_CONV_CASE> wx_conv_cases = {
|
||||||
|
{ { 0x00, 0x00, 0x00, 0x00 }, { 0.0, 0.0, 0.0, 0.0 } },
|
||||||
|
{ { 0x66, 0x80, 0x99, 0xB3 }, { 0.4, 0.5, 0.6, 0.7 } },
|
||||||
|
{ { 0xFF, 0xFF, 0xFF, 0xFF }, { 1.0, 1.0, 1.0, 1.0 } },
|
||||||
|
{ { 0xFF, 0x00, 0x00, 0xFF }, { 0.999, 0.001, 0.0, 1.0 } },
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef HAVE_EXPECTED_FAILURES
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check conversion to WxColour
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_CASE( ToWx, *boost::unit_test::expected_failures( 3 ) )
|
||||||
|
{
|
||||||
|
for( const auto& c : wx_conv_cases )
|
||||||
|
{
|
||||||
|
wxColour wx_col = c.c4d.ToColour();
|
||||||
|
|
||||||
|
// A hack, but avoids having to define a custom operator<<
|
||||||
|
BOOST_CHECK_EQUAL( wx_col.Red(), c.wx.Red() );
|
||||||
|
BOOST_CHECK_EQUAL( wx_col.Green(), c.wx.Green() );
|
||||||
|
BOOST_CHECK_EQUAL( wx_col.Blue(), c.wx.Blue() );
|
||||||
|
BOOST_CHECK_EQUAL( wx_col.Alpha(), c.wx.Alpha() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // HAVE_EXPECTED_FAILURES
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check conversion from WxColour
|
||||||
|
*/
|
||||||
|
BOOST_AUTO_TEST_CASE( FromWx )
|
||||||
|
{
|
||||||
|
const double tol = 0.5 / 255.0; // One bit of quantised error
|
||||||
|
|
||||||
|
for( const auto& c : wx_conv_cases )
|
||||||
|
{
|
||||||
|
const auto col = COLOR4D{ c.wx };
|
||||||
|
|
||||||
|
BOOST_CHECK_PREDICATE( pred_colour_is_near, ( col )( c.c4d )( tol ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // WX_COMPATIBILITY
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_SUITE_END()
|
|
@ -0,0 +1,47 @@
|
||||||
|
# This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
#
|
||||||
|
# Copyright (C) 2018 KiCad Developers, see CHANGELOG.TXT for contributors.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or
|
||||||
|
# modify it under the terms of the GNU General Public License
|
||||||
|
# as published by the Free Software Foundation; either version 2
|
||||||
|
# of the License, or (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, you may find one here:
|
||||||
|
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
# or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
# or you may write to the Free Software Foundation, Inc.,
|
||||||
|
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
|
||||||
|
# The unit_test_utils library is a simple helper library to collate
|
||||||
|
# utilities that are generically useful for unit test executables.
|
||||||
|
#
|
||||||
|
# Code that is useful for QA purposes outside of the unit-testing context
|
||||||
|
# belongs in qa_utils.
|
||||||
|
|
||||||
|
find_package(Boost COMPONENTS unit_test_framework REQUIRED)
|
||||||
|
|
||||||
|
set(SRCS
|
||||||
|
unit_test_utils.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
add_library( unit_test_utils STATIC ${SRCS} )
|
||||||
|
|
||||||
|
target_link_libraries( unit_test_utils PUBLIC
|
||||||
|
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories( unit_test_utils PUBLIC
|
||||||
|
include
|
||||||
|
${Boost_INCLUDE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_definitions( unit_test_utils PUBLIC
|
||||||
|
BOOST_TEST_DYN_LINK
|
||||||
|
)
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file numeric.h
|
||||||
|
* Numerical test predicates.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NUMERIC__H
|
||||||
|
#define NUMERIC__H
|
||||||
|
|
||||||
|
namespace KI_TEST
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a value is within a tolerance of a nominal value
|
||||||
|
*
|
||||||
|
* @return value is in [aNominal - aError, aNominal + aError]
|
||||||
|
*/
|
||||||
|
template <typename T> bool IsWithin( T aValue, T aNominal, T aError )
|
||||||
|
{
|
||||||
|
return ( aValue >= aNominal - aError ) && ( aValue <= aNominal + aError );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a value is within a tolerance of a nominal value,
|
||||||
|
* with different allowances for errors above and below.
|
||||||
|
*
|
||||||
|
* @return value is in [aNominal - aErrorBelow, aNominal + aErrorAbove]
|
||||||
|
*/
|
||||||
|
template <typename T> bool IsWithinBounds( T aValue, T aNominal, T aErrorAbove, T aErrorBelow )
|
||||||
|
{
|
||||||
|
return ( aValue >= aNominal - aErrorBelow ) && ( aValue <= aNominal + aErrorAbove );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* value is in range [aNominal - aErrorBelow, aNominal]
|
||||||
|
*/
|
||||||
|
template <typename T> bool IsWithinAndBelow( T aValue, T aNominal, T aErrorBelow )
|
||||||
|
{
|
||||||
|
return IsWithinBounds( aValue, aNominal, 0, aErrorBelow );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* value is in range [aNominal, aNominal + aErrorAbove]
|
||||||
|
*/
|
||||||
|
template <typename T> bool IsWithinAndAbove( T aValue, T aNominal, T aErrorAbove )
|
||||||
|
{
|
||||||
|
return IsWithinBounds( aValue, aNominal, aErrorAbove, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace KI_TEST
|
||||||
|
|
||||||
|
#endif // NUMERIC__H
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2018 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UNIT_TEST_UTILS__H
|
||||||
|
#define UNIT_TEST_UTILS__H
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If HAVE_EXPECTED_FAILURES is defined, this means that
|
||||||
|
* boost::unit_test::expected_failures is available.
|
||||||
|
*
|
||||||
|
* Wrap expected-to-fail tests with this to prevent them being compiled
|
||||||
|
* on platforms with older (<1.59) Boost versions.
|
||||||
|
*
|
||||||
|
* This can be removed when our minimum boost version is 1.59 or higher.
|
||||||
|
*/
|
||||||
|
#if BOOST_VERSION >= 105900
|
||||||
|
#define HAVE_EXPECTED_FAILURES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BOOST_TEST, while extremely handy, is not available in Boost < 1.59.
|
||||||
|
* Undef it here to prevent use. Using it can cause older packaging like
|
||||||
|
* Ubuntu LTS (which is on Boost 1.58) to fail.
|
||||||
|
*
|
||||||
|
* Use BOOST_CHECK_{EQUAL,NE,etc} instead.
|
||||||
|
*
|
||||||
|
* This can be removed when our minimum boost version is 1.59 or higher.
|
||||||
|
*/
|
||||||
|
#undef BOOST_TEST
|
||||||
|
|
||||||
|
#endif // UNIT_TEST_UTILS__H
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||||
|
*
|
||||||
|
* Copyright (C) 1992-2018 KiCad Developers, see AUTHORS.txt for contributors.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, you may find one here:
|
||||||
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||||
|
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||||
|
* or you may write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Nothing here yet, but CMake requires *something*.
|
||||||
|
*/
|
Loading…
Reference in New Issue