20#include <boost/test/unit_test.hpp>
47 std::ostringstream stream;
49 for( uint8_t
byte : aId.
target )
50 stream << std::hex << std::setfill( '0' ) << std::setw( 2 ) << static_cast<int>(
byte );
56std::string resultSignature(
const SNAP_RESULT& aResult )
58 std::ostringstream stream;
64 stream << ':' << static_cast<int>( accepted.
kind ) <<
',' << targetBytes( accepted ) <<
','
68 stream << std::hexfloat;
71 stream <<
':' << residual;
75 stream <<
':' << guide.
start.
x <<
',' << guide.
start.
y <<
',' << guide.
end.
x <<
',' << guide.
end.
y <<
','
76 <<
static_cast<int>( guide.
style );
94 BOOST_CHECK( first == same );
95 BOOST_CHECK( first != differentKind );
136 KIID(
"00000000-0000-0000-0000-000000000002" ).
AsBytes(), 3, 4 };
139 "b1fa72f98d0eaaf396ce1f1030e5f274" );
141 "38ec5cc638db882f25564f708cd908d4" );
144 {
KIID(
"00000000-0000-0000-0000-000000000002" ).
AsBytes(),
145 KIID(
"00000000-0000-0000-0000-000000000001" ).
AsBytes() },
147 "9084556ddbcdd0543f07abd73d7fb746" );
168 BOOST_REQUIRE_EQUAL(
result.accepted.size(), 1 );
169 BOOST_CHECK(
result.accepted.front() ==
id(
"authored" ) );
190 BOOST_CHECK(
result.Accepted(
id(
"angle" ) ) );
191 BOOST_CHECK( !
result.Accepted(
id(
"object" ) ) );
192 BOOST_CHECK(
result.Accepted(
id(
"grid-x" ) ) );
211 BOOST_CHECK(
result.Accepted(
id(
"align-x" ) ) );
212 BOOST_CHECK(
result.Accepted(
id(
"align-y" ) ) );
234 BOOST_CHECK(
result.Accepted(
id(
"grid-x" ) ) );
235 BOOST_CHECK( !
result.Accepted(
id(
"grid-y" ) ) );
249 { 1006370.0, -3755829.0 }, 0.25851349837571413 ) );
252 { 1006358.0, -3755779.0 }, 0.31431204619285724 ) );
258 BOOST_CHECK(
result.Accepted(
id(
"segment-a" ) ) );
259 BOOST_CHECK( !
result.Accepted(
id(
"segment-b" ) ) );
282 BOOST_CHECK(
result.Accepted(
id(
"segment-a" ) ) );
283 BOOST_CHECK(
result.Accepted(
id(
"segment-b" ) ) );
301 BOOST_REQUIRE_EQUAL(
result.accepted.size(), 1 );
302 BOOST_CHECK(
result.accepted.front() == std::min(
id(
"a" ),
id(
"z" ) ) );
308 const std::vector<VECTOR2I> cursorPath = { { 0, 0 }, { 3, 5 }, { 7, 9 }, { 11, 13 } };
310 const auto resolvePath = [&](
bool aReverse )
312 std::vector<std::string> signatures;
316 std::vector<SNAP_CANDIDATE> candidates = {
326 std::reverse( candidates.begin(), candidates.end() );
333 resolver.AddCandidate( std::move( candidate ) );
335 signatures.push_back( resultSignature(
resolver.Resolve( context ) ) );
341 BOOST_CHECK( resolvePath(
false ) == resolvePath(
true ) );
359 resolver.AddCandidate( std::move( fallback ) );
360 resolver.AddCandidate( std::move( preferred ) );
364 BOOST_CHECK(
result.Accepted(
id(
"preferred" ) ) );
365 BOOST_CHECK( !
result.Accepted(
id(
"fallback" ) ) );
383 resolver.AddCandidate( std::move( fallback ) );
384 resolver.AddCandidate( std::move( preferred ) );
394 if( aTrial.back().id ==
id(
"preferred" ) )
407 BOOST_CHECK( !
result.Accepted(
id(
"preferred" ) ) );
408 BOOST_CHECK(
result.Accepted(
id(
"fallback" ) ) );
424 resolver.AddCandidate( std::move( alignment ) );
428 BOOST_REQUIRE_EQUAL(
result.accepted.size(), 1 );
429 BOOST_CHECK(
result.Accepted(
id(
"anchor" ) ) );
430 BOOST_CHECK( !
result.Accepted(
id(
"alignment" ) ) );
448 BOOST_CHECK(
result.Accepted(
id(
"horizontal" ) ) );
449 BOOST_CHECK( !
result.Accepted(
id(
"vertical" ) ) );
478 if( aTrial.back().id ==
id(
"object" ) )
485 result.remainingDof = aTrial.size() == 1 ? 1 : 0;
493 BOOST_CHECK(
result.Accepted(
id(
"angle" ) ) );
494 BOOST_CHECK( !
result.Accepted(
id(
"object" ) ) );
495 BOOST_CHECK(
result.Accepted(
id(
"grid-x" ) ) );
501 using CLOCK = std::chrono::steady_clock;
505 CLOCK::time_point now;
506 int optionalCalls = 0;
514 resolver.SetDeadline( std::chrono::milliseconds( 8 ) );
515 resolver.SetRetainedCandidate(
id(
"retained" ) );
532 if( !aTrial.empty() )
534 now += std::chrono::milliseconds( 3 );
536 if( aTrial.back().id ==
id(
"optional" ) )
547 BOOST_CHECK(
result.Accepted(
id(
"angle-a" ) ) );
548 BOOST_CHECK(
result.Accepted(
id(
"retained" ) ) );
549 BOOST_CHECK(
result.Accepted(
id(
"intrinsic" ) ) );
559 resolver.SetRetainedCandidate(
id(
"horizontal" ) );
567 BOOST_CHECK(
result.Accepted(
id(
"horizontal" ) ) );
568 BOOST_CHECK( !
result.Accepted(
id(
"diagonal" ) ) );
581 resolver.SetStickyCandidates( { id(
"held" ) } );
589 BOOST_CHECK(
result.Accepted(
id(
"held" ) ) );
590 BOOST_CHECK( !
result.Accepted(
id(
"nearer" ) ) );
602 resolver.SetStickyCandidates( { id(
"held" ) } );
610 BOOST_CHECK(
result.Accepted(
id(
"nearer" ) ) );
611 BOOST_CHECK( !
result.Accepted(
id(
"held" ) ) );
619 std::vector<std::string> trace;
623 [&](
const std::string& aMessage )
625 trace.push_back( aMessage );
627 resolver.SetStickyCandidates( { id(
"held" ) } );
630 resolver.AddCandidate( std::move( held ) );
636 const auto contains = [&](
const char* aText )
638 return std::any_of( trace.begin(), trace.end(),
639 [&](
const std::string& aMessage )
641 return aMessage.find( aText ) != std::string::npos;
645 BOOST_CHECK( contains(
"rank index=0" ) );
646 BOOST_CHECK( contains(
"sticky=1" ) );
647 BOOST_CHECK( contains(
"trial id=" ) );
648 BOOST_CHECK( contains(
"accepted=1" ) );
649 BOOST_CHECK( contains(
"result status=SUCCESS position=(0,0) accepted=[" ) );
659 resolver.SetRetainedCandidate(
id(
"retained" ) );
667 BOOST_CHECK(
result.Accepted(
id(
"intrinsic" ) ) );
668 BOOST_CHECK( !
result.Accepted(
id(
"retained" ) ) );
675 using CLOCK = std::chrono::steady_clock;
679 CLOCK::time_point now;
688 resolver.SetDeadline( std::chrono::milliseconds( 8 ) );
701 now += std::chrono::milliseconds( 9 );
710 BOOST_CHECK(
result.Accepted( std::min(
id(
"first" ),
id(
"second" ) ) ) );
711 BOOST_CHECK( !
result.Accepted( std::max(
id(
"first" ),
id(
"second" ) ) ) );
730 resolver.AddCandidate( std::move( rejected ) );
731 resolver.AddCandidate( std::move( accepted ) );
735 BOOST_REQUIRE_EQUAL(
result.guides.size(), 2 );
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
std::array< uint8_t, 16 > AsBytes() const
static KIID FromBytes(const std::array< uint8_t, 16 > &aBytes)
static KIID FromName(const std::string &aName)
Return a KIID derived from a name, the same name always gives the same KIID.
static FILENAME_RESOLVER * resolver
std::chrono::steady_clock CLOCK
SNAP_STABLE_ID MakeIntersectionSnapId(const SNAP_STABLE_ID &aFirst, const SNAP_STABLE_ID &aSecond, int aSolutionBranch)
SNAP_STABLE_ID MakePointSnapId(SNAP_ID_KIND aKind, const VECTOR2I &aPoint, int aFeatureIndex=0)
SNAP_STABLE_ID MakeCompositeSnapId(SNAP_ID_KIND aKind, const std::vector< SNAP_TARGET_ID > &aTargets, int aFeatureIndex=0)
SNAP_STABLE_ID MakeDerivedSnapId(SNAP_ID_KIND aKind, const SNAP_STABLE_ID &aSource, int aFeatureIndex=0, int aSolutionBranch=0)
std::array< uint8_t, 16 > SNAP_TARGET_ID
static SNAP_CANDIDATE Point(SNAP_STABLE_ID aId, SNAP_PRIORITY_TIER aPriority, SNAP_CANDIDATE_SUBTYPE aSubtype, const VECTOR2I &aPoint, double aResidual)
static SNAP_CANDIDATE Line(SNAP_STABLE_ID aId, SNAP_PRIORITY_TIER aPriority, SNAP_CANDIDATE_SUBTYPE aSubtype, const VECTOR2I &aOrigin, const VECTOR2D &aDirection, double aResidual)
static SNAP_CANDIDATE AxisY(SNAP_STABLE_ID aId, SNAP_PRIORITY_TIER aPriority, SNAP_CANDIDATE_SUBTYPE aSubtype, int aCoordinate, double aResidual)
static SNAP_CANDIDATE AxisX(SNAP_STABLE_ID aId, SNAP_PRIORITY_TIER aPriority, SNAP_CANDIDATE_SUBTYPE aSubtype, int aCoordinate, double aResidual)
std::vector< SNAP_GUIDE > guides
std::vector< double > quantizedResiduals
std::vector< SNAP_GUIDE > guides
std::vector< SNAP_STABLE_ID > accepted
SNAP_RESULT_STATUS status
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(StableIdentityUsesTypedKindAndTarget)
wxString result
Test unit parsing edge cases and error handling.
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I