KiCad PCB EDA Suite
test_drc_courtyard_overlap.cpp File Reference

Go to the source code of this file.

Classes

struct  RECT_DEFINITION
 Simple definition of a rectangle, can be rounded. More...
 
struct  COURTYARD_TEST_MODULE
 
struct  COURTYARD_COLLISION
 
struct  COURTYARD_OVERLAP_TEST_CASE
 A complete courtyard overlap test case: a name, the board modules list and the expected collisions. More...
 
struct  COURTYARD_TEST_FIXTURE
 

Functions

std::ostream & operator<< (std::ostream &os, const COURTYARD_COLLISION &aColl)
 
void AddRectCourtyard (MODULE &aMod, const RECT_DEFINITION &aRect)
 Add a rectangular courtyard outline to a module. More...
 
std::unique_ptr< MODULEMakeCourtyardTestModule (BOARD &aBoard, const COURTYARD_TEST_MODULE &aMod)
 Construct a MODULE to use in a courtyard test from a COURTYARD_TEST_MODULE definition. More...
 
std::unique_ptr< BOARDMakeBoard (const std::vector< COURTYARD_TEST_MODULE > &aMods)
 Make a board for courtyard testing. More...
 
static bool CollisionMatchesExpected (BOARD &aBoard, const MARKER_PCB &aMarker, const COURTYARD_COLLISION &aCollision)
 Check if a MARKER_PCB is described by a particular COURTYARD_COLLISION object. More...
 
static void CheckCollisionsMatchExpected (BOARD &aBoard, const std::vector< std::unique_ptr< MARKER_PCB >> &aMarkers, const std::vector< COURTYARD_COLLISION > &aExpCollisions)
 Check that the produced markers match the expected. More...
 
static void DoCourtyardOverlapTest (const COURTYARD_OVERLAP_TEST_CASE &aCase, const KI_TEST::BOARD_DUMPER &aDumper)
 Run a single courtyard overlap testcase. More...
 
 BOOST_AUTO_TEST_CASE (OverlapCases)
 

Variables

static std::vector< COURTYARD_OVERLAP_TEST_CASEcourtyard_cases
 

Function Documentation

◆ AddRectCourtyard()

void AddRectCourtyard ( MODULE aMod,
const RECT_DEFINITION aRect 
)

Add a rectangular courtyard outline to a module.

Definition at line 101 of file test_drc_courtyard_overlap.cpp.

102 {
103  const PCB_LAYER_ID layer = aRect.m_front ? F_CrtYd : B_CrtYd;
104 
105  const int width = Millimeter2iu( 0.1 );
106 
107  KI_TEST::DrawRect( aMod, aRect.m_centre, aRect.m_size, aRect.m_corner_rad, width, layer );
108 }
PCB_LAYER_ID
A quick note on layer IDs:
void DrawRect(MODULE &aMod, const VECTOR2I &aPos, const VECTOR2I &aSize, int aRadius, int aWidth, PCB_LAYER_ID aLayer)
Draw a rectangle on a module.
static constexpr int Millimeter2iu(double mm)

References B_CrtYd, KI_TEST::DrawRect(), F_CrtYd, RECT_DEFINITION::m_centre, RECT_DEFINITION::m_corner_rad, RECT_DEFINITION::m_front, RECT_DEFINITION::m_size, and Millimeter2iu().

Referenced by MakeCourtyardTestModule().

◆ BOOST_AUTO_TEST_CASE()

BOOST_AUTO_TEST_CASE ( OverlapCases  )

Definition at line 487 of file test_drc_courtyard_overlap.cpp.

488 {
489  for( const auto& c : courtyard_cases )
490  {
491  BOOST_TEST_CONTEXT( c.m_case_name )
492  {
493  DoCourtyardOverlapTest( c, m_dumper );
494  }
495  }
496 }
static std::vector< COURTYARD_OVERLAP_TEST_CASE > courtyard_cases
#define BOOST_TEST_CONTEXT(A)
static void DoCourtyardOverlapTest(const COURTYARD_OVERLAP_TEST_CASE &aCase, const KI_TEST::BOARD_DUMPER &aDumper)
Run a single courtyard overlap testcase.

References BOOST_TEST_CONTEXT, courtyard_cases, and DoCourtyardOverlapTest().

◆ CheckCollisionsMatchExpected()

static void CheckCollisionsMatchExpected ( BOARD aBoard,
const std::vector< std::unique_ptr< MARKER_PCB >> &  aMarkers,
const std::vector< COURTYARD_COLLISION > &  aExpCollisions 
)
static

Check that the produced markers match the expected.

This does NOT check ordering, as that is not part of the contract of the DRC function.

Parameters
aMarkerslist of markers produced by the DRC
aCollisionslist of expected collisions

Definition at line 426 of file test_drc_courtyard_overlap.cpp.

429 {
430  for( const auto& marker : aMarkers )
431  {
432  BOOST_CHECK_PREDICATE(
434  }
435 
436  KI_TEST::CheckUnorderedMatches( aExpCollisions, aMarkers,
437  [&]( const COURTYARD_COLLISION& aColl, const std::unique_ptr<MARKER_PCB>& aMarker )
438  {
439  return CollisionMatchesExpected( aBoard, *aMarker, aColl );
440  } );
441 }
bool IsDrcMarkerOfType(const MARKER_PCB &aMarker, int aErrorCode)
Predicate for testing the type of a DRC marker.
void CheckUnorderedMatches(const EXP_CONT &aExpected, const FOUND_CONT &aFound, MATCH_PRED aMatchPredicate)
Check that a container of "found" objects matches a container of "expected" objects.
static bool CollisionMatchesExpected(BOARD &aBoard, const MARKER_PCB &aMarker, const COURTYARD_COLLISION &aCollision)
Check if a MARKER_PCB is described by a particular COURTYARD_COLLISION object.

References KI_TEST::CheckUnorderedMatches(), CollisionMatchesExpected(), DRCE_OVERLAPPING_FOOTPRINTS, and KI_TEST::IsDrcMarkerOfType().

Referenced by DoCourtyardOverlapTest().

◆ CollisionMatchesExpected()

static bool CollisionMatchesExpected ( BOARD aBoard,
const MARKER_PCB aMarker,
const COURTYARD_COLLISION aCollision 
)
static

Check if a MARKER_PCB is described by a particular COURTYARD_COLLISION object.

Definition at line 396 of file test_drc_courtyard_overlap.cpp.

398 {
399  auto reporter = std::static_pointer_cast<DRC_ITEM>( aMarker.GetRCItem() );
400 
401  const MODULE* item_a = dynamic_cast<MODULE*>( aBoard.GetItem( reporter->GetMainItemID() ) );
402  const MODULE* item_b = dynamic_cast<MODULE*>( aBoard.GetItem( reporter->GetAuxItemID() ) );
403 
404  // cant' find the items!
405  if( !item_a || !item_b )
406  return false;
407 
408  const bool ref_match_aa_bb = ( item_a->GetReference() == aCollision.m_refdes_a )
409  && ( item_b->GetReference() == aCollision.m_refdes_b );
410 
411  const bool ref_match_ab_ba = ( item_a->GetReference() == aCollision.m_refdes_b )
412  && ( item_b->GetReference() == aCollision.m_refdes_a );
413 
414  // Doesn't matter which way around it is, but both have to match somehow
415  return ref_match_aa_bb || ref_match_ab_ba;
416 }
BOARD_ITEM * GetItem(const KIID &aID)
const wxString GetReference() const
Function GetReference.
Definition: class_module.h:451
std::shared_ptr< RC_ITEM > GetRCItem() const
Function GetReporter returns the DRC_ITEM held within this MARKER so that its interface may be used.
Definition: marker_base.h:120

References BOARD::GetItem(), MARKER_BASE::GetRCItem(), MODULE::GetReference(), COURTYARD_COLLISION::m_refdes_a, and COURTYARD_COLLISION::m_refdes_b.

Referenced by CheckCollisionsMatchExpected().

◆ DoCourtyardOverlapTest()

static void DoCourtyardOverlapTest ( const COURTYARD_OVERLAP_TEST_CASE aCase,
const KI_TEST::BOARD_DUMPER aDumper 
)
static

Run a single courtyard overlap testcase.

Parameters
aCaseThe testcase to run.

Definition at line 448 of file test_drc_courtyard_overlap.cpp.

450 {
451  auto board = MakeBoard( aCase.m_mods );
452 
453  // Dump if env var set
454  aDumper.DumpBoardToFile( *board, aCase.m_case_name );
455 
456  BOARD_DESIGN_SETTINGS& bds = board->GetDesignSettings();
457 
459 
460  // we might not always have courtyards - that's a separate test
462 
463  // list of markers to collect
464  std::vector<std::unique_ptr<MARKER_PCB>> markers;
465 
466  DRC_ENGINE drcEngine( board.get(), &board->GetDesignSettings() );
467 
468  drcEngine.InitEngine( wxFileName() );
469 
470  drcEngine.SetViolationHandler(
471  [&]( const std::shared_ptr<DRC_ITEM>& aItem, wxPoint aPos )
472  {
473  if( aItem->GetErrorCode() == DRCE_OVERLAPPING_FOOTPRINTS
474  || aItem->GetErrorCode() == DRCE_MALFORMED_COURTYARD
475  || aItem->GetErrorCode() == DRCE_MISSING_COURTYARD )
476  {
477  markers.push_back( std::make_unique<MARKER_PCB>( aItem, aPos ) );
478  }
479  } );
480 
481  drcEngine.RunTests();
482 
483  CheckCollisionsMatchExpected( *board, markers, aCase.m_collisions );
484 }
Design Rule Checker object that performs all the DRC tests.
Definition: drc_engine.h:81
std::vector< COURTYARD_COLLISION > m_collisions
void DumpBoardToFile(BOARD &aBoard, const std::string &aName) const
std::vector< COURTYARD_TEST_MODULE > m_mods
static void CheckCollisionsMatchExpected(BOARD &aBoard, const std::vector< std::unique_ptr< MARKER_PCB >> &aMarkers, const std::vector< COURTYARD_COLLISION > &aExpCollisions)
Check that the produced markers match the expected.
std::map< int, int > m_DRCSeverities
void InitEngine(const wxFileName &aRulePath)
Initializes the DRC engine.
Definition: drc_engine.cpp:368
std::unique_ptr< BOARD > MakeBoard(const std::vector< COURTYARD_TEST_MODULE > &aMods)
Make a board for courtyard testing.
BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.

References CheckCollisionsMatchExpected(), DRCE_MALFORMED_COURTYARD, DRCE_MISSING_COURTYARD, DRCE_OVERLAPPING_FOOTPRINTS, KI_TEST::BOARD_DUMPER::DumpBoardToFile(), DRC_ENGINE::InitEngine(), COURTYARD_OVERLAP_TEST_CASE::m_case_name, COURTYARD_OVERLAP_TEST_CASE::m_collisions, BOARD_DESIGN_SETTINGS::m_DRCSeverities, COURTYARD_OVERLAP_TEST_CASE::m_mods, MakeBoard(), RPT_SEVERITY_ERROR, and RPT_SEVERITY_IGNORE.

Referenced by BOOST_AUTO_TEST_CASE().

◆ MakeBoard()

std::unique_ptr<BOARD> MakeBoard ( const std::vector< COURTYARD_TEST_MODULE > &  aMods)

Make a board for courtyard testing.

Parameters
aModsthe list of module definitions to add to the board

Definition at line 138 of file test_drc_courtyard_overlap.cpp.

139 {
140  auto board = std::make_unique<BOARD>();
141 
142  for( const auto& mod : aMods )
143  {
144  auto module = MakeCourtyardTestModule( *board, mod );
145 
146  board->Add( module.release() );
147  }
148 
149  return board;
150 }
std::unique_ptr< MODULE > MakeCourtyardTestModule(BOARD &aBoard, const COURTYARD_TEST_MODULE &aMod)
Construct a MODULE to use in a courtyard test from a COURTYARD_TEST_MODULE definition.

References MakeCourtyardTestModule().

Referenced by DoCourtyardOverlapTest().

◆ MakeCourtyardTestModule()

std::unique_ptr<MODULE> MakeCourtyardTestModule ( BOARD aBoard,
const COURTYARD_TEST_MODULE aMod 
)

Construct a MODULE to use in a courtyard test from a COURTYARD_TEST_MODULE definition.

Definition at line 115 of file test_drc_courtyard_overlap.cpp.

116 {
117  auto module = std::make_unique<MODULE>( &aBoard );
118 
119  for( const auto& rect : aMod.m_rects )
120  {
121  AddRectCourtyard( *module, rect );
122  }
123 
124  module->SetReference( aMod.m_refdes );
125 
126  // As of 2019-01-17, this has to go after adding the courtyards,
127  // or all the poly sets are empty when DRC'd
128  module->SetPosition( (wxPoint) aMod.m_pos );
129 
130  return module;
131 }
std::vector< RECT_DEFINITION > m_rects
void AddRectCourtyard(MODULE &aMod, const RECT_DEFINITION &aRect)
Add a rectangular courtyard outline to a module.

References AddRectCourtyard(), COURTYARD_TEST_MODULE::m_pos, COURTYARD_TEST_MODULE::m_rects, and COURTYARD_TEST_MODULE::m_refdes.

Referenced by MakeBoard().

◆ operator<<()

std::ostream& operator<< ( std::ostream &  os,
const COURTYARD_COLLISION aColl 
)

Definition at line 75 of file test_drc_courtyard_overlap.cpp.

76 {
77  os << "COURTYARD_COLLISION[ " << aColl.m_refdes_a << " -> " << aColl.m_refdes_b << "]";
78  return os;
79 }

References COURTYARD_COLLISION::m_refdes_a, and COURTYARD_COLLISION::m_refdes_b.

Variable Documentation

◆ courtyard_cases

std::vector<COURTYARD_OVERLAP_TEST_CASE> courtyard_cases
static

Definition at line 162 of file test_drc_courtyard_overlap.cpp.

Referenced by BOOST_AUTO_TEST_CASE().