24#include <boost/test/unit_test.hpp>
41 const std::string
json =
42 R
"({"/abc": "take_ours", "/def": "take_theirs", "/ghi": "take_ancestor"})";
46 BOOST_REQUIRE_EQUAL( r.resolutions.size(), 3u );
57 BOOST_CHECK( r.resolutions.empty() );
65 BOOST_CHECK( !r.errorContext.IsEmpty() );
95 BOOST_CHECK( r.errorContext == wxS( "/def" ) );
103 BOOST_CHECK( r.errorContext == wxS( "/abc" ) );
111 BOOST_CHECK( r.errorContext == wxS( "/abc" ) );
135 R
"({"/abc": "take_ours", "/def": "not_a_kind"})" );
137 BOOST_CHECK( r.resolutions.empty() );
140 R
"({"/abc": "take_ours", "/def": "keep"})" );
142 BOOST_CHECK( r2.resolutions.empty() );
145 R
"({"/abc": "take_ours", "/def": 42})" );
147 BOOST_CHECK( r3.resolutions.empty() );
157 BOOST_CHECK( r.resolutions.count( wxString::FromUTF8(
"/élément" ) ) == 1 );
173MERGE_PLAN MakePlanWithConflicts(
const std::vector<KIID_PATH>& aConflictIds )
177 for(
const KIID_PATH&
id : aConflictIds )
197 MERGE_PLAN plan = MakePlanWithConflicts( { idA, idB } );
199 std::vector<std::size_t> conflictIdx = { 0, 1 };
200 std::map<wxString, ITEM_RES> autoMap = {
223 MERGE_PLAN plan = MakePlanWithConflicts( { idA, idB } );
225 std::vector<std::size_t> conflictIdx = { 0, 1 };
226 std::map<wxString, ITEM_RES> autoMap = {
234 BOOST_CHECK(
result.firstMissingId == idB );
245 std::vector<std::size_t> conflictIdx;
246 std::map<wxString, ITEM_RES> autoMap;
275 BOOST_REQUIRE_EQUAL( entries.size(), 2u );
277 BOOST_CHECK( entries[0].
id == idB );
279 BOOST_CHECK( entries[1].
id == idC );
290 const wxString longSegmentString = wxS(
"/" ) + a.
AsString() + wxS(
"/" )
293 const KIID_PATH longPath( longSegmentString );
303 BOOST_REQUIRE_EQUAL( entries.size(), 1u );
305 BOOST_CHECK( entries[0].label.StartsWith( wxS(
"…" ) ) );
307 BOOST_CHECK( entries[0].label.EndsWith( longPath.
AsString().Right( 39 ) ) );
313 const KIID_PATH shortPath = MakePath( 2200 );
323 BOOST_REQUIRE_EQUAL( entries.size(), 1u );
324 BOOST_CHECK( entries[0].label == shortPath.
AsString() );
361 BOOST_REQUIRE_EQUAL( unresolved.size(), 1u );
362 BOOST_CHECK( unresolved[0] == idA );
375 BOOST_REQUIRE_EQUAL( unresolved.size(), 1u );
376 BOOST_CHECK( unresolved[0] == idA );
393 BOOST_REQUIRE_EQUAL( unresolved.size(), 1u );
409 BOOST_REQUIRE_EQUAL( unresolved.size(), 1u );
410 BOOST_CHECK( unresolved[0] == idA );
423 MERGE_PLAN plan = MakePlanWithConflicts( { idA, idB } );
425 std::vector<std::size_t> conflictIdx = { 0, 99 };
426 std::map<wxString, ITEM_RES> autoMap = {
447 MERGE_PLAN plan = MakePlanWithConflicts( { idA } );
450 std::vector<std::size_t> conflictIdx = { 99 };
451 std::map<wxString, ITEM_RES> autoMap = {
476 BOOST_REQUIRE_EQUAL( unresolved.size(), 1u );
477 BOOST_CHECK( unresolved[0] == idB );
499 std::map<KIID_PATH, BOX2I> primary = { { id, VALID_PRIMARY } };
500 std::map<KIID_PATH, BOX2I> ours = { { id, VALID_OURS } };
501 std::map<KIID_PATH, BOX2I> theirs = { { id, VALID_THEIRS } };
502 std::map<KIID_PATH, BOX2I> ancestor = { { id, VALID_ANCESTOR } };
506 BOOST_CHECK( *bbox == VALID_PRIMARY );
516 std::map<KIID_PATH, BOX2I> ours = { { id, VALID_OURS } };
517 std::map<KIID_PATH, BOX2I> theirs = { { id, VALID_THEIRS } };
518 std::map<KIID_PATH, BOX2I> ancestor = { { id, VALID_ANCESTOR } };
520 auto bbox =
ResolveConflictBBox(
id, std::map<KIID_PATH, BOX2I>{}, ours, theirs, ancestor );
522 BOOST_CHECK( *bbox == VALID_OURS );
530 std::map<KIID_PATH, BOX2I> primary;
531 std::map<KIID_PATH, BOX2I> ours;
532 std::map<KIID_PATH, BOX2I> theirs = { { id, VALID_THEIRS } };
533 std::map<KIID_PATH, BOX2I> ancestor = { { id, VALID_ANCESTOR } };
537 BOOST_CHECK( *bbox == VALID_THEIRS );
545 std::map<KIID_PATH, BOX2I> primary;
546 std::map<KIID_PATH, BOX2I> ours;
547 std::map<KIID_PATH, BOX2I> theirs;
548 std::map<KIID_PATH, BOX2I> ancestor = { { id, VALID_ANCESTOR } };
552 BOOST_CHECK( *bbox == VALID_ANCESTOR );
562 std::map<KIID_PATH, BOX2I> primary = { { id, DEGENERATE } };
563 std::map<KIID_PATH, BOX2I> ours = { { id, VALID_OURS } };
564 std::map<KIID_PATH, BOX2I> theirs;
565 std::map<KIID_PATH, BOX2I> ancestor;
569 BOOST_CHECK( *bbox == VALID_OURS );
576 std::map<KIID_PATH, BOX2I>
empty;
579 BOOST_CHECK( !bbox.has_value() );
591 std::map<KIID_PATH, BOX2I> ours = { { id, DEGENERATE } };
592 std::map<KIID_PATH, BOX2I> theirs = { { id, VALID_THEIRS } };
593 std::map<KIID_PATH, BOX2I> ancestor = { { id, VALID_ANCESTOR } };
595 auto bbox =
ResolveConflictBBox(
id, std::map<KIID_PATH, BOX2I>{}, ours, theirs, ancestor );
597 BOOST_CHECK( *bbox == VALID_THEIRS );
606 r.
id = MakePath( 4100 );
618 BOOST_CHECK(
text.Contains(
_(
"Take ours" ) ) );
619 BOOST_CHECK( !
text.Contains(
_(
"Property-level merge" ) ) );
620 BOOST_CHECK( !
text.Contains(
_(
"Keep (default)" ) ) );
627 r.
id = MakePath( 4101 );
634 BOOST_CHECK(
text.Contains( wxS(
"2" ) ) );
655 const wxString expectedCountLine = wxString::Format(
656 _(
"%zu property edit(s) in this resolution.\n" ),
657 static_cast<std::size_t
>( 0 ) );
662 r.
id = MakePath( 4200 );
667 "Detail text too short for kind "
668 <<
static_cast<int>( kind ) );
669 BOOST_CHECK(
text.Contains( expectedCountLine ) );
wxString AsString() const
static void SeedGenerator(unsigned int aSeed)
Re-initialize the UUID generator with a given seed (for testing or QA purposes)
wxString AsString() const
static bool empty(const wxTextEntryBase *aCtrl)
wxString BuildConflictDetailText(const ITEM_RESOLUTION &aResolution)
Build the human-readable detail text shown in the merge dialog's resolution panel for a given ITEM_RE...
AUTO_RESOLUTION_PARSE_RESULT ParseAutoResolutionJson(const std::string &aJsonContent)
Parse a KICAD_MERGETOOL_AUTO-format JSON object mapping item IDs (KIID_PATH strings) to ITEM_RES spel...
@ BAD_VALUE
at least one entry's value wasn't a string
@ NOT_OBJECT
JSON parsed but the root was not an object.
@ INVALID_JSON
input could not be parsed as JSON
@ UNKNOWN_KIND
at least one entry's string wasn't a known ITEM_RES
@ OK
parsed cleanly; resolutions is populated
@ ENGINE_INTERNAL_KIND
at least one entry asked for an engine-internal kind (KEEP / DELETE / MERGE_PROPS); only the TAKE_* f...
ITEM_RES
Resolution kind for a whole item.
std::vector< CONFLICT_LIST_ENTRY > BuildConflictList(const MERGE_PLAN &aPlan)
std::optional< BOX2I > ResolveConflictBBox(const KIID_PATH &aId, const std::map< KIID_PATH, BOX2I > &aPrimary, const std::map< KIID_PATH, BOX2I > &aOurs, const std::map< KIID_PATH, BOX2I > &aTheirs, const std::map< KIID_PATH, BOX2I > &aAncestor)
Resolve the best bounding box for a conflicted item across the three sides of a 3-way merge.
APPLY_AUTO_RESOLUTIONS_RESULT ApplyAutoResolutions(MERGE_PLAN &aPlan, const std::vector< std::size_t > &aConflictActionIndices, const std::map< wxString, ITEM_RES > &aResolutions)
Apply a parsed auto-resolution map to a MERGE_PLAN's conflicts.
std::vector< KIID_PATH > CollectUnresolvedConflicts(const MERGE_PLAN &aPlan, const std::vector< std::size_t > &aConflictActionIndices)
Return the subset of conflict actions whose kind is NOT one of the concrete TAKE_OURS / TAKE_THEIRS /...
_OUT_STRING AsString(const std::string &aString)
std::vector< PROPERTY_RESOLUTION > props
Result of planning a 3-way merge.
std::vector< ITEM_RESOLUTION > actions
std::vector< KIID_PATH > unresolved
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_CASE(Parse_ValidObject)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
BOOST_CHECK_MESSAGE(totalMismatches==0, std::to_string(totalMismatches)+" board(s) with strategy disagreements")
wxString result
Test unit parsing edge cases and error handling.
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I