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 )
182 plan.actions.push_back( r );
183 plan.unresolved.push_back(
id );
199 std::vector<std::size_t> conflictIdx = { 0, 1 };
200 std::map<wxString, ITEM_RES> autoMap = {
211 BOOST_CHECK(
plan.unresolved.empty() );
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;
267 plan.actions.push_back( a );
268 plan.actions.push_back( b );
269 plan.unresolved.push_back( idB );
271 std::vector<std::size_t> conflictIdx = { 0, 1 };
279 BOOST_CHECK(
plan.unresolved.empty() );
297 plan.actions.push_back( a );
298 plan.actions.push_back( b );
299 plan.actions.push_back( c );
300 plan.unresolved.push_back( idB );
301 plan.unresolved.push_back( idC );
304 BOOST_REQUIRE_EQUAL( entries.size(), 2u );
306 BOOST_CHECK( entries[0].
id == idB );
308 BOOST_CHECK( entries[1].
id == idC );
319 const wxString longSegmentString = wxS(
"/" ) + a.
AsString() + wxS(
"/" )
322 const KIID_PATH longPath( longSegmentString );
328 plan.actions.push_back( r );
329 plan.unresolved.push_back( longPath );
332 BOOST_REQUIRE_EQUAL( entries.size(), 1u );
334 BOOST_CHECK( entries[0].label.StartsWith( wxS(
"…" ) ) );
336 BOOST_CHECK( entries[0].label.EndsWith( longPath.
AsString().Right( 39 ) ) );
342 const KIID_PATH shortPath = MakePath( 2200 );
348 plan.actions.push_back( r );
349 plan.unresolved.push_back( shortPath );
352 BOOST_REQUIRE_EQUAL( entries.size(), 1u );
353 BOOST_CHECK( entries[0].label == shortPath.
AsString() );
377 plan.actions.push_back( a );
378 plan.actions.push_back( b );
381 BOOST_REQUIRE_EQUAL( entries.size(), 1u );
383 BOOST_CHECK( entries[0].
id == idA );
397 plan.actions.push_back( a );
398 plan.actions.push_back( b );
410 plan.actions.push_back( a );
413 BOOST_REQUIRE_EQUAL( unresolved.size(), 1u );
414 BOOST_CHECK( unresolved[0] == idA );
424 plan.actions.push_back( a );
440 plan.actions.push_back( a );
443 BOOST_REQUIRE_EQUAL( unresolved.size(), 1u );
455 plan.actions.push_back( a );
459 BOOST_REQUIRE_EQUAL( unresolved.size(), 1u );
460 BOOST_CHECK( unresolved[0] == idA );
475 std::vector<std::size_t> conflictIdx = { 0, 99 };
476 std::map<wxString, ITEM_RES> autoMap = {
500 std::vector<std::size_t> conflictIdx = { 99 };
501 std::map<wxString, ITEM_RES> autoMap = {
521 plan.actions.push_back( a );
522 plan.actions.push_back( b );
523 plan.actions.push_back( c );
526 BOOST_REQUIRE_EQUAL( unresolved.size(), 1u );
527 BOOST_CHECK( unresolved[0] == idB );
549 std::map<KIID_PATH, BOX2I> primary = { { id, VALID_PRIMARY } };
550 std::map<KIID_PATH, BOX2I> ours = { { id, VALID_OURS } };
551 std::map<KIID_PATH, BOX2I> theirs = { { id, VALID_THEIRS } };
552 std::map<KIID_PATH, BOX2I> ancestor = { { id, VALID_ANCESTOR } };
556 BOOST_CHECK( *bbox == VALID_PRIMARY );
566 std::map<KIID_PATH, BOX2I> ours = { { id, VALID_OURS } };
567 std::map<KIID_PATH, BOX2I> theirs = { { id, VALID_THEIRS } };
568 std::map<KIID_PATH, BOX2I> ancestor = { { id, VALID_ANCESTOR } };
570 auto bbox =
ResolveConflictBBox(
id, std::map<KIID_PATH, BOX2I>{}, ours, theirs, ancestor );
572 BOOST_CHECK( *bbox == VALID_OURS );
580 std::map<KIID_PATH, BOX2I> primary;
581 std::map<KIID_PATH, BOX2I> ours;
582 std::map<KIID_PATH, BOX2I> theirs = { { id, VALID_THEIRS } };
583 std::map<KIID_PATH, BOX2I> ancestor = { { id, VALID_ANCESTOR } };
587 BOOST_CHECK( *bbox == VALID_THEIRS );
595 std::map<KIID_PATH, BOX2I> primary;
596 std::map<KIID_PATH, BOX2I> ours;
597 std::map<KIID_PATH, BOX2I> theirs;
598 std::map<KIID_PATH, BOX2I> ancestor = { { id, VALID_ANCESTOR } };
602 BOOST_CHECK( *bbox == VALID_ANCESTOR );
612 std::map<KIID_PATH, BOX2I> primary = { { id,
DEGENERATE } };
613 std::map<KIID_PATH, BOX2I> ours = { { id, VALID_OURS } };
614 std::map<KIID_PATH, BOX2I> theirs;
615 std::map<KIID_PATH, BOX2I> ancestor;
619 BOOST_CHECK( *bbox == VALID_OURS );
626 std::map<KIID_PATH, BOX2I>
empty;
629 BOOST_CHECK( !bbox.has_value() );
641 std::map<KIID_PATH, BOX2I> ours = { { id,
DEGENERATE } };
642 std::map<KIID_PATH, BOX2I> theirs = { { id, VALID_THEIRS } };
643 std::map<KIID_PATH, BOX2I> ancestor = { { id, VALID_ANCESTOR } };
645 auto bbox =
ResolveConflictBBox(
id, std::map<KIID_PATH, BOX2I>{}, ours, theirs, ancestor );
647 BOOST_CHECK( *bbox == VALID_THEIRS );
656 r.
id = MakePath( 4100 );
668 BOOST_CHECK(
text.Contains(
_(
"Take ours" ) ) );
669 BOOST_CHECK( !
text.Contains(
_(
"Property-level merge" ) ) );
670 BOOST_CHECK( !
text.Contains(
_(
"Keep (default)" ) ) );
677 r.
id = MakePath( 4101 );
684 BOOST_CHECK(
text.Contains( wxS(
"2" ) ) );
705 const wxString expectedCountLine = wxString::Format(
706 _(
"%zu property edit(s) in this resolution.\n" ),
707 static_cast<std::size_t
>( 0 ) );
712 r.
id = MakePath( 4200 );
716 BOOST_CHECK_MESSAGE(
text.Length() > 30,
717 "Detail text too short for kind "
718 <<
static_cast<int>( kind ) );
719 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)
static std::vector< PENDING_PROPERTY > plan(const EDA_ITEM &aSource, const EDA_ITEM &aTarget, const std::set< wxString > &aEnabledKeys)
Target properties to write, paired with values read off the source.
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 conflict actions that still have no decision.
_OUT_STRING AsString(const std::string &aString)
std::vector< PROPERTY_RESOLUTION > props
Result of planning a 3-way merge.
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()
wxString result
Test unit parsing edge cases and error handling.
BOOST_CHECK_EQUAL(result, "25.4")
VECTOR2< int32_t > VECTOR2I