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" ) ) );
252 BOOST_REQUIRE_EQUAL(
result.accepted.size(), 1 );
253 BOOST_CHECK(
result.accepted.front() == std::min(
id(
"a" ),
id(
"z" ) ) );
259 const std::vector<VECTOR2I> cursorPath = { { 0, 0 }, { 3, 5 }, { 7, 9 }, { 11, 13 } };
261 const auto resolvePath = [&](
bool aReverse )
263 std::vector<std::string> signatures;
267 std::vector<SNAP_CANDIDATE> candidates = {
277 std::reverse( candidates.begin(), candidates.end() );
284 resolver.AddCandidate( std::move( candidate ) );
286 signatures.push_back( resultSignature(
resolver.Resolve( context ) ) );
292 BOOST_CHECK( resolvePath(
false ) == resolvePath(
true ) );
310 resolver.AddCandidate( std::move( fallback ) );
311 resolver.AddCandidate( std::move( preferred ) );
315 BOOST_CHECK(
result.Accepted(
id(
"preferred" ) ) );
316 BOOST_CHECK( !
result.Accepted(
id(
"fallback" ) ) );
334 resolver.AddCandidate( std::move( fallback ) );
335 resolver.AddCandidate( std::move( preferred ) );
345 if( aTrial.back().id ==
id(
"preferred" ) )
358 BOOST_CHECK( !
result.Accepted(
id(
"preferred" ) ) );
359 BOOST_CHECK(
result.Accepted(
id(
"fallback" ) ) );
375 resolver.AddCandidate( std::move( alignment ) );
379 BOOST_REQUIRE_EQUAL(
result.accepted.size(), 1 );
380 BOOST_CHECK(
result.Accepted(
id(
"anchor" ) ) );
381 BOOST_CHECK( !
result.Accepted(
id(
"alignment" ) ) );
399 BOOST_CHECK(
result.Accepted(
id(
"horizontal" ) ) );
400 BOOST_CHECK( !
result.Accepted(
id(
"vertical" ) ) );
429 if( aTrial.back().id ==
id(
"object" ) )
436 result.remainingDof = aTrial.size() == 1 ? 1 : 0;
444 BOOST_CHECK(
result.Accepted(
id(
"angle" ) ) );
445 BOOST_CHECK( !
result.Accepted(
id(
"object" ) ) );
446 BOOST_CHECK(
result.Accepted(
id(
"grid-x" ) ) );
452 using CLOCK = std::chrono::steady_clock;
456 CLOCK::time_point now;
457 int optionalCalls = 0;
465 resolver.SetDeadline( std::chrono::milliseconds( 8 ) );
466 resolver.SetRetainedCandidate(
id(
"retained" ) );
483 if( !aTrial.empty() )
485 now += std::chrono::milliseconds( 3 );
487 if( aTrial.back().id ==
id(
"optional" ) )
498 BOOST_CHECK(
result.Accepted(
id(
"angle-a" ) ) );
499 BOOST_CHECK(
result.Accepted(
id(
"retained" ) ) );
500 BOOST_CHECK(
result.Accepted(
id(
"intrinsic" ) ) );
510 resolver.SetRetainedCandidate(
id(
"horizontal" ) );
518 BOOST_CHECK(
result.Accepted(
id(
"horizontal" ) ) );
519 BOOST_CHECK( !
result.Accepted(
id(
"diagonal" ) ) );
532 resolver.SetStickyCandidates( { id(
"held" ) } );
540 BOOST_CHECK(
result.Accepted(
id(
"held" ) ) );
541 BOOST_CHECK( !
result.Accepted(
id(
"nearer" ) ) );
553 resolver.SetStickyCandidates( { id(
"held" ) } );
561 BOOST_CHECK(
result.Accepted(
id(
"nearer" ) ) );
562 BOOST_CHECK( !
result.Accepted(
id(
"held" ) ) );
570 std::vector<std::string> trace;
574 [&](
const std::string& aMessage )
576 trace.push_back( aMessage );
578 resolver.SetStickyCandidates( { id(
"held" ) } );
581 resolver.AddCandidate( std::move( held ) );
587 const auto contains = [&](
const char* aText )
589 return std::any_of( trace.begin(), trace.end(),
590 [&](
const std::string& aMessage )
592 return aMessage.find( aText ) != std::string::npos;
596 BOOST_CHECK( contains(
"rank index=0" ) );
597 BOOST_CHECK( contains(
"sticky=1" ) );
598 BOOST_CHECK( contains(
"trial id=" ) );
599 BOOST_CHECK( contains(
"accepted=1" ) );
600 BOOST_CHECK( contains(
"result status=SUCCESS position=(0,0) accepted=[" ) );
610 resolver.SetRetainedCandidate(
id(
"retained" ) );
618 BOOST_CHECK(
result.Accepted(
id(
"intrinsic" ) ) );
619 BOOST_CHECK( !
result.Accepted(
id(
"retained" ) ) );
626 using CLOCK = std::chrono::steady_clock;
630 CLOCK::time_point now;
639 resolver.SetDeadline( std::chrono::milliseconds( 8 ) );
652 now += std::chrono::milliseconds( 9 );
661 BOOST_CHECK(
result.Accepted( std::min(
id(
"first" ),
id(
"second" ) ) ) );
662 BOOST_CHECK( !
result.Accepted( std::max(
id(
"first" ),
id(
"second" ) ) ) );
681 resolver.AddCandidate( std::move( rejected ) );
682 resolver.AddCandidate( std::move( accepted ) );
686 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