KiCad PCB EDA Suite
Loading...
Searching...
No Matches
board_test_utils.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
25
26#include <iostream>
27#include <filesystem>
28
29#include <wx/filename.h>
30
31#include <boost/test/unit_test.hpp>
32
33#include <board.h>
34#include <board_commit.h>
36#include <footprint.h>
37#include <kiid.h>
38#include <pad.h>
39#include <pcb_shape.h>
40#include <pcb_track.h>
41#include <zone.h>
42#include <zone_filler.h>
47#include <tool/tool_manager.h>
48
49#define CHECK_ENUM_CLASS_EQUAL( L, R ) \
50 BOOST_CHECK_EQUAL( static_cast<int>( L ), static_cast<int>( R ) )
51
52
53std::ostream& boost_test_print_type( std::ostream& os, const VIATYPE& aViaType )
54{
55 // clang-format off
56 switch( aViaType )
57 {
58 case VIATYPE::THROUGH: os << "THROUGH"; break;
59 case VIATYPE::BLIND: os << "BLIND"; break;
60 case VIATYPE::BURIED: os << "BURIED"; break;
61 case VIATYPE::MICROVIA: os << "MICROVIA"; break;
62 default:
63 os << "UNKNOWN_VIA_TYPE(" << static_cast<int>( aViaType ) << ")";
64 }
65 // clang-format on
66 return os;
67}
68
69
70namespace KI_TEST
71{
72
77
78
79void BOARD_DUMPER::DumpBoardToFile( BOARD& aBoard, const std::string& aName ) const
80{
81 if( !m_dump_boards )
82 return;
83
84 auto path = std::filesystem::temp_directory_path() / aName;
85 path += ".kicad_pcb";
86
87 BOOST_TEST_MESSAGE( "Dumping board file: " << path.string() );
88 ::KI_TEST::DumpBoardToFile( aBoard, path.string() );
89}
90
91
92void LoadBoard( SETTINGS_MANAGER& aSettingsManager, const wxString& aRelPath,
93 std::unique_ptr<BOARD>& aBoard )
94{
95 if( aBoard )
96 {
97 aBoard->SetProject( nullptr );
98 aBoard = nullptr;
99 }
100
101 std::string absPath = GetPcbnewTestDataDir() + aRelPath.ToStdString();
102 wxFileName projectFile( absPath + ".kicad_pro" );
103 wxFileName legacyProject( absPath + ".pro" );
104 std::string boardPath = absPath + ".kicad_pcb";
105 wxFileName rulesFile( absPath + ".kicad_dru" );
106
107 if( projectFile.Exists() )
108 {
109 aSettingsManager.LoadProject( projectFile.GetFullPath() );
110 BOOST_TEST_MESSAGE( "Loading project file: " << projectFile.GetFullPath() );
111 }
112 else if( legacyProject.Exists() )
113 {
114 aSettingsManager.LoadProject( legacyProject.GetFullPath() );
115 BOOST_TEST_MESSAGE( "Loading project file: " << projectFile.GetFullPath() );
116 }
117 else
118 BOOST_TEST_MESSAGE( "Could not load project: " << projectFile.GetFullPath() );
119
120 BOOST_TEST_MESSAGE( "Loading board file: " << boardPath );
121
122 try {
123 aBoard = ReadBoardFromFileOrStream( boardPath );
124 }
125 catch( const IO_ERROR& ioe )
126 {
127 BOOST_TEST_ERROR( ioe.What() );
128 }
129
130 BOOST_REQUIRE_MESSAGE( aBoard, "aBoard is null or invalid" );
131
132 if( projectFile.Exists() || legacyProject.Exists() )
133 aBoard->SetProject( &aSettingsManager.Prj() );
134
135 auto m_DRCEngine = std::make_shared<DRC_ENGINE>( aBoard.get(), &aBoard->GetDesignSettings() );
136
137 BOOST_TEST_CHECKPOINT( "Init drc engine" );
138
139 if( rulesFile.Exists() )
140 m_DRCEngine->InitEngine( rulesFile );
141 else
142 m_DRCEngine->InitEngine( wxFileName() );
143
144 aBoard->GetDesignSettings().m_DRCEngine = m_DRCEngine;
145
146 BOOST_TEST_CHECKPOINT( "Build list of nets" );
147 try
148 {
149 aBoard->BuildListOfNets();
150 }
151 catch( const std::exception& e )
152 {
153 BOOST_TEST_ERROR( "Exception in BuildListOfNets: " << e.what() );
154 return;
155 }
156
157 BOOST_TEST_CHECKPOINT( "Build connectivity" );
158 try
159 {
160 aBoard->BuildConnectivity();
161 }
162 catch( const std::exception& e )
163 {
164 BOOST_TEST_ERROR( "Exception in BuildConnectivity: " << e.what() );
165 return;
166 }
167
168 BOOST_TEST_CHECKPOINT( "Synchronize Tuning Profile Properties" );
169 try
170 {
171 aBoard->GetLengthCalculation()->SynchronizeTuningProfileProperties();
172 }
173 catch( const std::exception& e )
174 {
175 BOOST_TEST_ERROR( "Exception in SynchronizeTimeDomainProperties: " << e.what() );
176 return;
177 }
178
179 if( aBoard->GetProject() )
180 {
181 std::unordered_set<wxString> dummy;
182 BOOST_TEST_CHECKPOINT( "Synchronize Component Classes" );
183 try
184 {
185 aBoard->SynchronizeComponentClasses( dummy );
186 }
187 catch( const std::exception& e )
188 {
189 BOOST_TEST_ERROR( "Exception in SynchronizeComponentClasses: " << e.what() );
190 return;
191 }
192
193 BOOST_TEST_CHECKPOINT( "Run DRC cache generator" );
194 try
195 {
196 DRC_CACHE_GENERATOR cacheGenerator;
197 cacheGenerator.SetDRCEngine( m_DRCEngine.get() );
198 cacheGenerator.Run();
199 }
200 catch( const std::exception& e )
201 {
202 BOOST_TEST_ERROR( "Exception in DRC cache generator: " << e.what() );
203 return;
204 }
205 }
206}
207
208
209BOARD_ITEM& RequireBoardItemWithTypeAndId( const BOARD& aBoard, KICAD_T aItemType, const KIID& aID )
210{
211 BOARD_ITEM* item = aBoard.ResolveItem( aID, true );
212
213 BOOST_REQUIRE( item );
214 BOOST_REQUIRE_EQUAL( item->Type(), aItemType );
215
216 return *item;
217}
218
219
224{
225public:
230 TEMPORARY_DIRECTORY( const std::string& aNamePrefix, const std::string aSuffix )
231 {
232 int i = 0;
233
234 // Find a unique directory name
235 while( true )
236 {
237 m_path = std::filesystem::temp_directory_path()
238 / ( aNamePrefix + std::to_string( i ) + aSuffix );
239
240 if( !std::filesystem::exists( m_path ) )
241 break;
242
243 i++;
244 }
245
246 wxASSERT( !std::filesystem::exists( m_path ) );
247 std::filesystem::create_directories( m_path );
248 }
249
250 ~TEMPORARY_DIRECTORY() { std::filesystem::remove_all( m_path ); }
251
252 const std::filesystem::path& GetPath() const { return m_path; }
253
254private:
255 std::filesystem::path m_path;
256};
257
258
259void LoadAndTestBoardFile( const wxString aRelativePath, bool aRoundtrip,
260 std::function<void( BOARD& )> aBoardTestFunction,
261 std::optional<int> aExpectedBoardVersion )
262{
263 const std::string absBoardPath =
264 KI_TEST::GetPcbnewTestDataDir() + aRelativePath.ToStdString() + ".kicad_pcb";
265
266 BOOST_TEST_MESSAGE( "Loading board to test: " << absBoardPath );
267 std::unique_ptr<BOARD> board1 = KI_TEST::ReadBoardFromFileOrStream( absBoardPath );
268
269 // Should load - if it doesn't we're done for
270 BOOST_REQUIRE( board1 );
271
272 BOOST_TEST_MESSAGE( "Testing loaded board" );
273 aBoardTestFunction( *board1 );
274
275 // If we care about the board version, check it now - but not after a roundtrip
276 // (as the version will be updated to the current version)
277 if( aExpectedBoardVersion )
278 {
279 BOOST_CHECK_EQUAL( board1->GetFileFormatVersionAtLoad(), *aExpectedBoardVersion );
280 }
281
282 if( aRoundtrip )
283 {
284 TEMPORARY_DIRECTORY tempLib( "kicad_qa_brd_roundtrip", "" );
285
286 const auto savePath = tempLib.GetPath() / ( aRelativePath.ToStdString() + ".kicad_pcb" );
287 KI_TEST::DumpBoardToFile( *board1, savePath.string() );
288
289 std::unique_ptr<BOARD> board2 = KI_TEST::ReadBoardFromFileOrStream( savePath.string() );
290
291 // Should load again
292 BOOST_REQUIRE( board2 );
293
294 BOOST_TEST_MESSAGE( "Testing roundtripped (saved/reloaded) file" );
295 aBoardTestFunction( *board2 );
296 }
297}
298
299
300void LoadAndTestFootprintFile( const wxString& aLibRelativePath, const wxString& aFpName,
301 bool aRoundtrip,
302 std::function<void( FOOTPRINT& )> aFootprintTestFunction,
303 std::optional<int> aExpectedFootprintVersion )
304{
305 const std::string absFootprintPath = KI_TEST::GetPcbnewTestDataDir()
306 + aLibRelativePath.ToStdString() + "/"
307 + aFpName.ToStdString() + ".kicad_mod";
308
309 BOOST_TEST_MESSAGE( "Loading footprint to test: " << absFootprintPath );
310 std::unique_ptr<FOOTPRINT> fp1 = KI_TEST::ReadFootprintFromFileOrStream( absFootprintPath );
311
312 // Should load - if it doesn't we're done for
313 BOOST_REQUIRE( fp1 );
314
315 BOOST_TEST_MESSAGE( "Testing loaded footprint (value: " << fp1->GetValue() << ")" );
316 aFootprintTestFunction( *fp1 );
317
318 // If we care about the board version, check it now - but not after a roundtrip
319 // (as the version will be updated to the current version)
320 if( aExpectedFootprintVersion )
321 {
322 BOOST_CHECK_EQUAL( fp1->GetFileFormatVersionAtLoad(), *aExpectedFootprintVersion );
323 }
324
325 if( aRoundtrip )
326 {
332 TEMPORARY_DIRECTORY tempLib( "kicad_qa_fp_roundtrip", ".pretty" );
333 const wxString fpFilename = fp1->GetFPID().GetLibItemName() + wxString( ".kicad_mod" );
334
335 BOOST_TEST_MESSAGE( "Resaving footprint: " << fpFilename << " in " << tempLib.GetPath() );
336
337 KI_TEST::DumpFootprintToFile( *fp1, tempLib.GetPath().string() );
338
339 const auto fp2Path = tempLib.GetPath() / fpFilename.ToStdString();
340
341 BOOST_TEST_MESSAGE( "Re-reading footprint: " << fpFilename << " in " << tempLib.GetPath() );
342
343 std::unique_ptr<FOOTPRINT> fp2 = KI_TEST::ReadFootprintFromFileOrStream( fp2Path.string() );
344
345 // Should load again
346 BOOST_REQUIRE( fp2 );
347
348 BOOST_TEST_MESSAGE( "Testing roundtripped (saved/reloaded) file" );
349 aFootprintTestFunction( *fp2 );
350 }
351}
352
353
354void FillZones( BOARD* m_board )
355{
356 BOOST_TEST_CHECKPOINT( "Filling zones" );
357
358 TOOL_MANAGER toolMgr;
359 toolMgr.SetEnvironment( m_board, nullptr, nullptr, nullptr, nullptr );
360
361 KI_TEST::DUMMY_TOOL* dummyTool = new KI_TEST::DUMMY_TOOL();
362 toolMgr.RegisterTool( dummyTool );
363
364 BOARD_COMMIT commit( dummyTool );
365 ZONE_FILLER filler( m_board, &commit );
366 std::vector<ZONE*> toFill;
367
368 for( ZONE* zone : m_board->Zones() )
369 toFill.push_back( zone );
370
371 if( filler.Fill( toFill, false, nullptr ) )
372 commit.Push( _( "Fill Zone(s)" ), SKIP_UNDO | SKIP_SET_DIRTY | ZONE_FILL_OP | SKIP_CONNECTIVITY );
373
374 BOOST_TEST_CHECKPOINT( "Building connectivity (after zone fill)" );
375 m_board->BuildConnectivity();
376}
377
378
379#define TEST( a, b ) \
380 { \
381 if( a != b ) \
382 return a < b; \
383 }
384#define TEST_PT( a, b ) \
385 { \
386 if( a.x != b.x ) \
387 return a.x < b.x; \
388 if( a.y != b.y ) \
389 return a.y < b.y; \
390 }
391
392
394{
396
397 bool operator()( const BOARD_ITEM* itemA, const BOARD_ITEM* itemB ) const
398 {
399 TEST( itemA->Type(), itemB->Type() );
400
401 if( itemA->GetLayerSet() != itemB->GetLayerSet() )
402 return itemA->GetLayerSet().Seq() < itemB->GetLayerSet().Seq();
403
404 if( itemA->Type() == PCB_TEXT_T )
405 {
406 const PCB_TEXT* textA = static_cast<const PCB_TEXT*>( itemA );
407 const PCB_TEXT* textB = static_cast<const PCB_TEXT*>( itemB );
408
409 TEST_PT( textA->GetPosition(), textB->GetPosition() );
410 TEST( textA->GetTextAngle(), textB->GetTextAngle() );
411 }
412
413 return fp_comp( itemA, itemB );
414 }
415};
416
417
419{
420 CHECK_ENUM_CLASS_EQUAL( expected->Type(), fp->Type() );
421
422 // TODO: validate those informations match the importer
423 BOOST_CHECK_EQUAL( expected->GetPosition(), fp->GetPosition() );
424 BOOST_CHECK_EQUAL( expected->GetOrientation(), fp->GetOrientation() );
425
426 BOOST_CHECK_EQUAL( expected->GetReference(), fp->GetReference() );
427 BOOST_CHECK_EQUAL( expected->GetValue(), fp->GetValue() );
428 BOOST_CHECK_EQUAL( expected->GetLibDescription(), fp->GetLibDescription() );
429 BOOST_CHECK_EQUAL( expected->GetKeywords(), fp->GetKeywords() );
430 BOOST_CHECK_EQUAL( expected->GetAttributes(), fp->GetAttributes() );
431 BOOST_CHECK_EQUAL( expected->GetFlag(), fp->GetFlag() );
432 //BOOST_CHECK_EQUAL( expected->GetProperties(), fp->GetProperties() );
433 BOOST_CHECK_EQUAL( expected->GetTypeName(), fp->GetTypeName() );
434
435 // simple test if count matches
436 BOOST_CHECK_EQUAL( expected->GetFields().size(), fp->GetFields().size() );
437 BOOST_CHECK_EQUAL( expected->Pads().size(), fp->Pads().size() );
438 BOOST_CHECK_EQUAL( expected->GraphicalItems().size(), fp->GraphicalItems().size() );
439 BOOST_CHECK_EQUAL( expected->Zones().size(), fp->Zones().size() );
440 BOOST_CHECK_EQUAL( expected->Groups().size(), fp->Groups().size() );
441 BOOST_CHECK_EQUAL( expected->Models().size(), fp->Models().size() );
442
443 std::set<PAD*, FOOTPRINT::cmp_pads> expectedPads( expected->Pads().begin(),
444 expected->Pads().end() );
445 std::set<PAD*, FOOTPRINT::cmp_pads> fpPads( fp->Pads().begin(), fp->Pads().end() );
446
447 for( auto itExpected = expectedPads.begin(), itFp = fpPads.begin();
448 itExpected != expectedPads.end() && itFp != fpPads.end(); itExpected++, itFp++ )
449 {
450 CheckFpPad( *itExpected, *itFp );
451 }
452
453 std::set<BOARD_ITEM*, kitest_cmp_drawings> expectedGraphicalItems( expected->GraphicalItems().begin(),
454 expected->GraphicalItems().end() );
455 std::set<BOARD_ITEM*, kitest_cmp_drawings> fpGraphicalItems( fp->GraphicalItems().begin(),
456 fp->GraphicalItems().end() );
457
458 for( auto itExpected = expectedGraphicalItems.begin(), itFp = fpGraphicalItems.begin();
459 itExpected != expectedGraphicalItems.end() && itFp != fpGraphicalItems.end();
460 itExpected++, itFp++ )
461 {
462 BOOST_CHECK_EQUAL( ( *itExpected )->Type(), ( *itFp )->Type() );
463
464 switch( ( *itExpected )->Type() )
465 {
466 case PCB_TEXT_T:
467 {
468 const PCB_TEXT* expectedText = static_cast<const PCB_TEXT*>( *itExpected );
469 const PCB_TEXT* text = static_cast<const PCB_TEXT*>( *itFp );
470
471 CheckFpText( expectedText, text );
472 break;
473 }
474
475 case PCB_SHAPE_T:
476 {
477 const PCB_SHAPE* expectedShape = static_cast<const PCB_SHAPE*>( *itExpected );
478 const PCB_SHAPE* shape = static_cast<const PCB_SHAPE*>( *itFp );
479
480 CheckFpShape( expectedShape, shape );
481 break;
482 }
483
485 case PCB_DIM_LEADER_T:
486 case PCB_DIM_CENTER_T:
487 case PCB_DIM_RADIAL_T:
489 // TODO
490 break;
491
492 case PCB_BARCODE_T:
493 // TODO
494 break;
495
496 default:
497 BOOST_ERROR( "KICAD_T not known" );
498 break;
499 }
500 }
501
502 std::set<ZONE*, FOOTPRINT::cmp_zones> expectedZones( expected->Zones().begin(),
503 expected->Zones().end() );
504 std::set<ZONE*, FOOTPRINT::cmp_zones> fpZones( fp->Zones().begin(), fp->Zones().end() );
505
506 for( auto itExpected = expectedZones.begin(), itFp = fpZones.begin();
507 itExpected != expectedZones.end() && itFp != fpZones.end(); itExpected++, itFp++ )
508 {
509 CheckFpZone( *itExpected, *itFp );
510 }
511
512 // TODO: Groups
513
514 // Use FootprintNeedsUpdate as sanity check (which should do many of the same checks as above,
515 // but neither is guaranteed to be complete).
516 WX_STRING_REPORTER reporter;
517
518 if( const_cast<FOOTPRINT*>(expected)->FootprintNeedsUpdate(fp, BOARD_ITEM::COMPARE_FLAGS::DRC, &reporter) )
519 BOOST_REQUIRE_MESSAGE( false, reporter.GetMessages() );
520}
521
522
523void CheckFpPad( const PAD* expected, const PAD* pad )
524{
525 // TODO(JE) padstacks
526 BOOST_TEST_CONTEXT( "Assert PAD with KIID=" << expected->m_Uuid.AsString() )
527 {
528 CHECK_ENUM_CLASS_EQUAL( expected->Type(), pad->Type() );
529
530 BOOST_CHECK_EQUAL( expected->GetNumber(), pad->GetNumber() );
531 CHECK_ENUM_CLASS_EQUAL( expected->GetAttribute(), pad->GetAttribute() );
532 CHECK_ENUM_CLASS_EQUAL( expected->GetProperty(), pad->GetProperty() );
534 pad->GetShape( PADSTACK::ALL_LAYERS ) );
535
536 BOOST_CHECK_EQUAL( expected->IsLocked(), pad->IsLocked() );
537
538 BOOST_CHECK_EQUAL( expected->GetPosition(), pad->GetPosition() );
540 pad->GetSize( PADSTACK::ALL_LAYERS ) );
541 BOOST_CHECK_EQUAL( expected->GetOrientation(), pad->GetOrientation() );
543 pad->GetDelta( PADSTACK::ALL_LAYERS ) );
545 pad->GetOffset( PADSTACK::ALL_LAYERS ) );
546 BOOST_CHECK_EQUAL( expected->GetDrillSize(), pad->GetDrillSize() );
547 CHECK_ENUM_CLASS_EQUAL( expected->GetDrillShape(), pad->GetDrillShape() );
548
549 BOOST_CHECK_EQUAL( expected->GetLayerSet(), pad->GetLayerSet() );
550
551 BOOST_CHECK_EQUAL( expected->GetNetCode(), pad->GetNetCode() );
552 BOOST_CHECK_EQUAL( expected->GetPinFunction(), pad->GetPinFunction() );
553 BOOST_CHECK_EQUAL( expected->GetPinType(), pad->GetPinType() );
554 BOOST_CHECK_EQUAL( expected->GetPadToDieLength(), pad->GetPadToDieLength() );
555 BOOST_CHECK_EQUAL( expected->GetPadToDieDelay(), pad->GetPadToDieDelay() );
556 BOOST_CHECK_EQUAL( expected->GetLocalSolderMaskMargin().value_or( 0 ),
557 pad->GetLocalSolderMaskMargin().value_or( 0 ) );
558 BOOST_CHECK_EQUAL( expected->GetLocalSolderPasteMargin().value_or( 0 ),
559 pad->GetLocalSolderPasteMargin().value_or( 0 ) );
560 BOOST_CHECK_EQUAL( expected->GetLocalSolderPasteMarginRatio().value_or( 0 ),
561 pad->GetLocalSolderPasteMarginRatio().value_or( 0 ) );
562 BOOST_CHECK_EQUAL( expected->GetLocalClearance().value_or( 0 ),
563 pad->GetLocalClearance().value_or( 0 ) );
564 CHECK_ENUM_CLASS_EQUAL( expected->GetLocalZoneConnection(), pad->GetLocalZoneConnection() );
565 BOOST_CHECK_EQUAL( expected->GetLocalThermalSpokeWidthOverride().value_or( 0 ),
566 pad->GetLocalThermalSpokeWidthOverride().value_or( 0 ) );
567 BOOST_CHECK_EQUAL( expected->GetThermalSpokeAngle(), pad->GetThermalSpokeAngle() );
568 BOOST_CHECK_EQUAL( expected->GetThermalGap(), pad->GetThermalGap() );
569 BOOST_CHECK_EQUAL( expected->GetRoundRectRadiusRatio( PADSTACK::ALL_LAYERS ),
570 pad->GetRoundRectRadiusRatio( PADSTACK::ALL_LAYERS ) );
571 BOOST_CHECK_EQUAL( expected->GetChamferRectRatio( PADSTACK::ALL_LAYERS ),
572 pad->GetChamferRectRatio( PADSTACK::ALL_LAYERS ) );
573 BOOST_CHECK_EQUAL( expected->GetChamferPositions( PADSTACK::ALL_LAYERS ),
574 pad->GetChamferPositions( PADSTACK::ALL_LAYERS ) );
575 BOOST_CHECK_EQUAL( expected->GetRemoveUnconnected(), pad->GetRemoveUnconnected() );
576 BOOST_CHECK_EQUAL( expected->GetKeepTopBottom(), pad->GetKeepTopBottom() );
577
578 // TODO: did we check everything for complex pad shapes?
580 pad->GetAnchorPadShape( PADSTACK::ALL_LAYERS ) );
581 CHECK_ENUM_CLASS_EQUAL( expected->GetCustomShapeInZoneOpt(),
582 pad->GetCustomShapeInZoneOpt() );
583
584 BOOST_CHECK_EQUAL( expected->GetPrimitives( PADSTACK::ALL_LAYERS ).size(),
585 pad->GetPrimitives( PADSTACK::ALL_LAYERS ).size() );
586
587 if( expected->GetPrimitives( PADSTACK::ALL_LAYERS ).size()
588 == pad->GetPrimitives( PADSTACK::ALL_LAYERS ).size() )
589 {
590 for( size_t i = 0; i < expected->GetPrimitives( PADSTACK::ALL_LAYERS ).size(); ++i )
591 {
592 CheckFpShape( expected->GetPrimitives( PADSTACK::ALL_LAYERS ).at( i ).get(),
593 pad->GetPrimitives( PADSTACK::ALL_LAYERS ).at( i ).get() );
594 }
595 }
596 }
597}
598
599
601{
602 BOOST_TEST_CONTEXT( "Assert PCB_TEXT with KIID=" << expected->m_Uuid.AsString() )
603 {
604 CHECK_ENUM_CLASS_EQUAL( expected->Type(), text->Type() );
605
606 BOOST_CHECK_EQUAL( expected->IsLocked(), text->IsLocked() );
607
608 BOOST_CHECK_EQUAL( expected->GetText(), text->GetText() );
609 BOOST_CHECK_EQUAL( expected->GetPosition(), text->GetPosition() );
610 BOOST_CHECK_EQUAL( expected->GetTextAngle(), text->GetTextAngle() );
611 BOOST_CHECK_EQUAL( expected->IsKeepUpright(), text->IsKeepUpright() );
612
613 BOOST_CHECK_EQUAL( expected->GetLayerSet(), text->GetLayerSet() );
614 BOOST_CHECK_EQUAL( expected->IsVisible(), text->IsVisible() );
615
616 BOOST_CHECK_EQUAL( expected->GetTextSize(), text->GetTextSize() );
617 BOOST_CHECK_EQUAL( expected->GetLineSpacing(), text->GetLineSpacing() );
618 BOOST_CHECK_EQUAL( expected->GetTextThickness(), text->GetTextThickness() );
619 BOOST_CHECK_EQUAL( expected->IsBold(), text->IsBold() );
620 BOOST_CHECK_EQUAL( expected->IsItalic(), text->IsItalic() );
621 BOOST_CHECK_EQUAL( expected->GetHorizJustify(), text->GetHorizJustify() );
622 BOOST_CHECK_EQUAL( expected->GetVertJustify(), text->GetVertJustify() );
623 BOOST_CHECK_EQUAL( expected->IsMirrored(), text->IsMirrored() );
624 BOOST_CHECK_EQUAL( expected->GetFontName(), text->GetFontName() );
625
626 // TODO: render cache?
627 }
628}
629
630
631void CheckFpShape( const PCB_SHAPE* expected, const PCB_SHAPE* shape )
632{
633 BOOST_TEST_CONTEXT( "Assert PCB_SHAPE with KIID=" << expected->m_Uuid.AsString() )
634 {
635 CHECK_ENUM_CLASS_EQUAL( expected->Type(), shape->Type() );
636
637 CHECK_ENUM_CLASS_EQUAL( expected->GetShape(), shape->GetShape() );
638
639 BOOST_CHECK_EQUAL( expected->IsLocked(), shape->IsLocked() );
640
641 BOOST_CHECK_EQUAL( expected->GetStart(), shape->GetStart() );
642 BOOST_CHECK_EQUAL( expected->GetEnd(), shape->GetEnd() );
643
644 if( expected->GetShape() == SHAPE_T::ARC )
645 {
646 // center and position might differ as they are calculated from start/mid/end -> compare mid instead
647 BOOST_CHECK_EQUAL( expected->GetArcMid(), shape->GetArcMid() );
648 }
649 else
650 {
651 BOOST_CHECK_EQUAL( expected->GetCenter(), shape->GetCenter() );
652 BOOST_CHECK_EQUAL( expected->GetPosition(), shape->GetPosition() );
653 }
654
655 BOOST_CHECK_EQUAL( expected->GetBezierC1(), shape->GetBezierC1() );
656 BOOST_CHECK_EQUAL( expected->GetBezierC2(), shape->GetBezierC2() );
657
658 CheckShapePolySet( &expected->GetPolyShape(), &shape->GetPolyShape() );
659
660 BOOST_CHECK_EQUAL( expected->GetLayerSet(), shape->GetLayerSet() );
661
662 BOOST_CHECK_EQUAL( expected->GetStroke().GetWidth(), shape->GetStroke().GetWidth() );
663 CHECK_ENUM_CLASS_EQUAL( expected->GetStroke().GetLineStyle(),
664 shape->GetStroke().GetLineStyle() );
665 CHECK_ENUM_CLASS_EQUAL( expected->GetFillMode(), shape->GetFillMode() );
666 }
667}
668
669
670void CheckFpZone( const ZONE* expected, const ZONE* zone )
671{
672 BOOST_TEST_CONTEXT( "Assert ZONE with KIID=" << expected->m_Uuid.AsString() )
673 {
674 CHECK_ENUM_CLASS_EQUAL( expected->Type(), zone->Type() );
675
676 BOOST_CHECK_EQUAL( expected->IsLocked(), zone->IsLocked() );
677
678 BOOST_CHECK_EQUAL( expected->GetNetCode(), zone->GetNetCode() );
679 BOOST_CHECK_EQUAL( expected->GetAssignedPriority(), zone->GetAssignedPriority() );
680 CHECK_ENUM_CLASS_EQUAL( expected->GetPadConnection(), zone->GetPadConnection() );
681 BOOST_CHECK_EQUAL( expected->GetLocalClearance().value_or( 0 ),
682 zone->GetLocalClearance().value_or( 0 ) );
683 BOOST_CHECK_EQUAL( expected->GetMinThickness(), zone->GetMinThickness() );
684
685 BOOST_CHECK_EQUAL( expected->GetLayerSet(), zone->GetLayerSet() );
686
687 BOOST_CHECK_EQUAL( expected->IsFilled(), zone->IsFilled() );
688 CHECK_ENUM_CLASS_EQUAL( expected->GetFillMode(), zone->GetFillMode() );
689 BOOST_CHECK_EQUAL( expected->GetHatchThickness(), zone->GetHatchThickness() );
690 BOOST_CHECK_EQUAL( expected->GetHatchGap(), zone->GetHatchGap() );
691 BOOST_CHECK_EQUAL( expected->GetHatchOrientation(), zone->GetHatchOrientation() );
692 BOOST_CHECK_EQUAL( expected->GetHatchSmoothingLevel(), zone->GetHatchSmoothingLevel() );
693 BOOST_CHECK_EQUAL( expected->GetHatchSmoothingValue(), zone->GetHatchSmoothingValue() );
694 BOOST_CHECK_EQUAL( expected->GetHatchBorderAlgorithm(), zone->GetHatchBorderAlgorithm() );
695 BOOST_CHECK_EQUAL( expected->GetHatchHoleMinArea(), zone->GetHatchHoleMinArea() );
696 BOOST_CHECK_EQUAL( expected->GetThermalReliefGap(), zone->GetThermalReliefGap() );
697 BOOST_CHECK_EQUAL( expected->GetThermalReliefSpokeWidth(),
699 BOOST_CHECK_EQUAL( expected->GetCornerSmoothingType(), zone->GetCornerSmoothingType() );
700 BOOST_CHECK_EQUAL( expected->GetCornerRadius(), zone->GetCornerRadius() );
701 CHECK_ENUM_CLASS_EQUAL( expected->GetIslandRemovalMode(), zone->GetIslandRemovalMode() );
702 BOOST_CHECK_EQUAL( expected->GetMinIslandArea(), zone->GetMinIslandArea() );
703
704 BOOST_CHECK_EQUAL( expected->GetIsRuleArea(), zone->GetIsRuleArea() );
705 BOOST_CHECK_EQUAL( expected->GetDoNotAllowZoneFills(), zone->GetDoNotAllowZoneFills() );
706 BOOST_CHECK_EQUAL( expected->GetDoNotAllowVias(), zone->GetDoNotAllowVias() );
707 BOOST_CHECK_EQUAL( expected->GetDoNotAllowTracks(), zone->GetDoNotAllowTracks() );
708 BOOST_CHECK_EQUAL( expected->GetDoNotAllowPads(), zone->GetDoNotAllowPads() );
709 BOOST_CHECK_EQUAL( expected->GetDoNotAllowFootprints(), zone->GetDoNotAllowFootprints() );
710
711 BOOST_CHECK_EQUAL( expected->GetZoneName(), zone->GetZoneName() );
712 CHECK_ENUM_CLASS_EQUAL( expected->GetTeardropAreaType(), zone->GetTeardropAreaType() );
713 BOOST_CHECK_EQUAL( expected->GetZoneName(), zone->GetZoneName() );
714
715 CheckShapePolySet( expected->Outline(), zone->Outline() );
716 // TODO: filled zones
717 }
718}
719
720
722{
723 BOOST_TEST_CONTEXT( "Assert SHAPE_POLY_SET" )
724 {
725 BOOST_CHECK_EQUAL( expected->OutlineCount(), polyset->OutlineCount() );
726 BOOST_CHECK_EQUAL( expected->TotalVertices(), polyset->TotalVertices() );
727
728 if( expected->OutlineCount() != polyset->OutlineCount() )
729 return; // don't check the rest
730
731 if( expected->TotalVertices() != polyset->TotalVertices() )
732 return; // don't check the rest
733
734 // TODO: check all outlines and holes (just checking outlines for now)
735 for( int i = 0; i < expected->OutlineCount(); ++i )
736 {
737 BOOST_TEST_CONTEXT( "Outline " << i )
738 {
739 BOOST_CHECK_EQUAL( expected->Outline( i ).ArcCount(),
740 polyset->Outline( i ).ArcCount() );
741 BOOST_CHECK_EQUAL( expected->Outline( i ).PointCount(),
742 polyset->Outline( i ).PointCount() );
743
744
745 if( expected->Outline( i ).PointCount() != polyset->Outline( i ).PointCount() )
746 return; // don't check the rest
747
748 for( int j = 0; j < expected->Outline( i ).PointCount(); ++j )
749 {
750 BOOST_CHECK_EQUAL( expected->Outline( i ).GetPoint( j ),
751 polyset->Outline( i ).GetPoint( j ) );
752 }
753 }
754 }
755 }
756}
757
758
759void PrintBoardStats( const BOARD* aBoard, const std::string& aBoardName )
760{
761 if( !aBoard )
762 {
763 BOOST_TEST_MESSAGE( aBoardName << ": FAILED TO LOAD" );
764 return;
765 }
766
767 int trackCount = 0;
768 int viaCount = 0;
769 int arcCount = 0;
770
771 for( PCB_TRACK* track : aBoard->Tracks() )
772 {
773 switch( track->Type() )
774 {
775 case PCB_TRACE_T: trackCount++; break;
776 case PCB_VIA_T: viaCount++; break;
777 case PCB_ARC_T: arcCount++; break;
778 default: break;
779 }
780 }
781
782 int smdPadCount = 0;
783 int thPadCount = 0;
784
785 for( FOOTPRINT* fp : aBoard->Footprints() )
786 {
787 for( PAD* pad : fp->Pads() )
788 {
789 if( pad->GetAttribute() == PAD_ATTRIB::SMD )
790 smdPadCount++;
791 else
792 thPadCount++;
793 }
794 }
795
796 std::ostringstream ss;
797 ss << "\n=== Board Statistics: " << aBoardName << " ===\n"
798 << " Layers: " << aBoard->GetCopperLayerCount() << "\n"
799 << " Nets: " << aBoard->GetNetCount() << "\n"
800 << " Footprints: " << aBoard->Footprints().size() << "\n"
801 << " Tracks: " << trackCount << "\n"
802 << " Vias: " << viaCount << "\n"
803 << " Arcs: " << arcCount << "\n"
804 << " SMD Pads: " << smdPadCount << "\n"
805 << " TH Pads: " << thPadCount << "\n"
806 << " Zones: " << aBoard->Zones().size();
807
808 BOOST_TEST_MESSAGE( ss.str() );
809}
810
811
812REPORTER& CAPTURING_REPORTER::Report( const wxString& aText, SEVERITY aSeverity )
813{
814 MESSAGE msg;
815 msg.text = aText;
816 msg.severity = aSeverity;
817 m_messages.push_back( msg );
818
819 switch( aSeverity )
820 {
821 case RPT_SEVERITY_ERROR: m_errorCount++; break;
824 case RPT_SEVERITY_ACTION: m_infoCount++; break;
825 default: break;
826 }
827
828 return *this;
829}
830
831
832void CAPTURING_REPORTER::PrintAllMessages( const std::string& aContext ) const
833{
834 if( m_messages.empty() )
835 {
836 BOOST_TEST_MESSAGE( aContext << ": No messages" );
837 return;
838 }
839
840 BOOST_TEST_MESSAGE( aContext << ": " << m_messages.size() << " messages (" << m_errorCount << " errors, "
841 << m_warningCount << " warnings)" );
842
843 for( const MESSAGE& msg : m_messages )
844 {
845 const char* severityStr = "???";
846
847 switch( msg.severity )
848 {
849 case RPT_SEVERITY_ERROR: severityStr = "ERROR"; break;
850 case RPT_SEVERITY_WARNING: severityStr = "WARN "; break;
851 case RPT_SEVERITY_INFO: severityStr = "INFO "; break;
852 case RPT_SEVERITY_ACTION: severityStr = "ACT "; break;
853 case RPT_SEVERITY_DEBUG: severityStr = "DEBUG"; break;
854 default: severityStr = " "; break;
855 }
856
857 BOOST_TEST_MESSAGE( " [" << severityStr << "] " << msg.text );
858 }
859}
860
861
862std::unique_ptr<BOARD> LoadBoardWithCapture( PCB_IO& aIoPlugin, const std::string& aFilePath, REPORTER* aReporter )
863{
864 std::unique_ptr<BOARD> board = std::make_unique<BOARD>();
865
866 if( aReporter )
867 aIoPlugin.SetReporter( aReporter );
868
869 try
870 {
871 aIoPlugin.LoadBoard( aFilePath, board.get(), nullptr, nullptr );
872 return board;
873 }
874 catch( const IO_ERROR& e )
875 {
876 if( aReporter )
877 aReporter->Report( wxString::Format( "IO_ERROR: %s", e.What() ), RPT_SEVERITY_ERROR );
878 return nullptr;
879 }
880 catch( const std::exception& e )
881 {
882 if( aReporter )
883 aReporter->Report( wxString::Format( "Exception: %s", e.what() ), RPT_SEVERITY_ERROR );
884 return nullptr;
885 }
886 catch( ... )
887 {
888 if( aReporter )
889 aReporter->Report( "Unknown exception during load", RPT_SEVERITY_ERROR );
890 return nullptr;
891 }
892}
893
894
895BOARD* CACHED_BOARD_LOADER::GetCachedBoard( const std::string& aFilePath )
896{
897 return getCachedBoard( aFilePath, false, nullptr );
898}
899
900
901BOARD* CACHED_BOARD_LOADER::LoadAndCache( const std::string& aFilePath, REPORTER* aReporter )
902{
903 return getCachedBoard( aFilePath, true, aReporter );
904}
905
906
907BOARD* CACHED_BOARD_LOADER::getCachedBoard( PCB_IO& aIoPlugin, const std::string& aFilePath, bool aForceReload,
908 REPORTER* aReporter )
909{
910 auto it = m_boardCache.find( aFilePath );
911
912 if( it != m_boardCache.end() && !aForceReload )
913 return it->second.get();
914
915 auto board = KI_TEST::LoadBoardWithCapture( aIoPlugin, aFilePath, aReporter );
916 BOARD* raw = board.get();
917 m_boardCache[aFilePath] = std::move( board );
918 return raw;
919}
920
921
922} // namespace KI_TEST
#define SKIP_CONNECTIVITY
#define ZONE_FILL_OP
General utilities for PCB file IO for QA programs.
std::ostream & boost_test_print_type(std::ostream &os, const VIATYPE &aViaType)
#define CHECK_ENUM_CLASS_EQUAL(L, R)
virtual void Push(const wxString &aMessage=wxEmptyString, int aCommitFlags=0) override
Execute the changes.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:84
bool IsLocked() const override
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
Definition board_item.h:257
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:322
const ZONES & Zones() const
Definition board.h:367
bool BuildConnectivity(PROGRESS_REPORTER *aReporter=nullptr)
Build or rebuild the board connectivity database for the board, especially the list of connected item...
Definition board.cpp:191
int GetCopperLayerCount() const
Definition board.cpp:920
const FOOTPRINTS & Footprints() const
Definition board.h:363
const TRACKS & Tracks() const
Definition board.h:361
unsigned GetNetCount() const
Definition board.h:1027
BOARD_ITEM * ResolveItem(const KIID &aID, bool aAllowNullptrReturn=false) const
Definition board.cpp:1780
virtual bool Run() override
Run this provider against the given PCB with configured options (if any).
void SetDRCEngine(DRC_ENGINE *engine)
KICAD_T Type() const
Returns the type of object.
Definition eda_item.h:111
const VECTOR2I & GetBezierC2() const
Definition eda_shape.h:259
FILL_T GetFillMode() const
Definition eda_shape.h:142
SHAPE_POLY_SET & GetPolyShape()
Definition eda_shape.h:337
SHAPE_T GetShape() const
Definition eda_shape.h:169
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
Definition eda_shape.h:216
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
Definition eda_shape.h:174
const VECTOR2I & GetBezierC1() const
Definition eda_shape.h:256
VECTOR2I GetArcMid() const
const EDA_ANGLE & GetTextAngle() const
Definition eda_text.h:147
wxString GetLibDescription() const
Definition footprint.h:368
EDA_ANGLE GetOrientation() const
Definition footprint.h:330
ZONES & Zones()
Definition footprint.h:312
std::deque< PAD * > & Pads()
Definition footprint.h:306
int GetAttributes() const
Definition footprint.h:417
wxString GetTypeName() const
Get the type of footprint.
GROUPS & Groups()
Definition footprint.h:315
void GetFields(std::vector< PCB_FIELD * > &aVector, bool aVisibleOnly) const
Populate a std::vector with PCB_TEXTs.
std::vector< FP_3DMODEL > & Models()
Definition footprint.h:323
const wxString & GetValue() const
Definition footprint.h:773
const wxString & GetReference() const
Definition footprint.h:751
int GetFlag() const
Definition footprint.h:428
wxString GetKeywords() const
Definition footprint.h:371
VECTOR2I GetPosition() const override
Definition footprint.h:327
DRAWINGS & GraphicalItems()
Definition footprint.h:309
virtual void SetReporter(REPORTER *aReporter)
Set an optional reporter for warnings/errors.
Definition io_base.h:89
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
virtual const char * what() const override
std::exception interface, returned as UTF-8
Definition kiid.h:49
void DumpBoardToFile(BOARD &aBoard, const std::string &aName) const
std::map< std::string, std::unique_ptr< BOARD > > m_boardCache
BOARD * getCachedBoard(PCB_IO &aIoPlugin, const std::string &aFilePath, bool aForceReload, REPORTER *aReporter)
BOARD * LoadAndCache(const std::string &aFilePath, REPORTER *aReporter)
Load (or reload) board for the given file path and send the load messages to the given reporter.
BOARD * GetCachedBoard(const std::string &aFilePath)
Get a cached board for the given file path, or load it if not already cached, without forcing a reloa...
void PrintAllMessages(const std::string &aContext) const
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
std::vector< MESSAGE > m_messages
A temporary directory that will be deleted when it goes out of scope.
const std::filesystem::path & GetPath() const
TEMPORARY_DIRECTORY(const std::string &aNamePrefix, const std::string aSuffix)
Create a temporary directory with a given prefix and suffix.
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
Definition lset.cpp:313
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
Definition padstack.h:177
Definition pad.h:55
A base class that BOARD loading and saving plugins should derive from.
Definition pcb_io.h:70
virtual BOARD * LoadBoard(const wxString &aFileName, BOARD *aAppendToMe, const std::map< std::string, UTF8 > *aProperties=nullptr, PROJECT *aProject=nullptr)
Load information from some input file format that this PCB_IO implementation knows about into either ...
Definition pcb_io.cpp:74
VECTOR2I GetCenter() const override
This defaults to the center of the bounding box if not overridden.
Definition pcb_shape.h:81
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
STROKE_PARAMS GetStroke() const override
Definition pcb_shape.h:91
VECTOR2I GetPosition() const override
Definition pcb_shape.h:79
virtual VECTOR2I GetPosition() const override
Definition pcb_text.h:82
A pure virtual class used to derive REPORTER objects from.
Definition reporter.h:73
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
Definition reporter.h:102
REPORTER()
Definition reporter.h:75
bool LoadProject(const wxString &aFullPath, bool aSetActive=true)
Load a project or sets up a new project with a specified path.
PROJECT & Prj() const
A helper while we are not MDI-capable – return the one and only project.
virtual const VECTOR2I GetPoint(int aIndex) const override
int PointCount() const
Return the number of points (vertices) in this line chain.
size_t ArcCount() const
Represent a set of closed polygons.
int TotalVertices() const
Return total number of vertices stored in the set.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int OutlineCount() const
Return the number of outlines in the set.
int GetWidth() const
LINE_STYLE GetLineStyle() const
Master controller class:
void RegisterTool(TOOL_BASE *aTool)
Add a tool to the manager set and sets it up.
void SetEnvironment(EDA_ITEM *aModel, KIGFX::VIEW *aView, KIGFX::VIEW_CONTROLS *aViewControls, APP_SETTINGS_BASE *aSettings, TOOLS_HOLDER *aFrame)
Set the work environment (model, view, view controls and the parent window).
A wrapper for reporting to a wxString object.
Definition reporter.h:191
const wxString & GetMessages() const
Definition reporter.cpp:78
bool Fill(const std::vector< ZONE * > &aZones, bool aCheck=false, wxWindow *aParent=nullptr)
Fills the given list of zones.
Handle a list of polygons defining a copper zone.
Definition zone.h:73
int GetHatchBorderAlgorithm() const
Definition zone.h:333
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
Definition zone.h:719
std::optional< int > GetLocalClearance() const override
Definition zone.cpp:846
bool GetDoNotAllowVias() const
Definition zone.h:730
bool GetDoNotAllowPads() const
Definition zone.h:732
bool GetDoNotAllowTracks() const
Definition zone.h:731
bool IsFilled() const
Definition zone.h:297
ISLAND_REMOVAL_MODE GetIslandRemovalMode() const
Definition zone.h:741
SHAPE_POLY_SET * Outline()
Definition zone.h:340
long long int GetMinIslandArea() const
Definition zone.h:744
const wxString & GetZoneName() const
Definition zone.h:163
int GetMinThickness() const
Definition zone.h:306
ZONE_CONNECTION GetPadConnection() const
Definition zone.h:303
int GetHatchThickness() const
Definition zone.h:315
double GetHatchHoleMinArea() const
Definition zone.h:330
int GetThermalReliefSpokeWidth() const
Definition zone.h:245
EDA_ANGLE GetHatchOrientation() const
Definition zone.h:321
bool GetDoNotAllowFootprints() const
Definition zone.h:733
ZONE_FILL_MODE GetFillMode() const
Definition zone.h:224
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition zone.h:136
int GetHatchGap() const
Definition zone.h:318
TEARDROP_TYPE GetTeardropAreaType() const
Definition zone.h:705
double GetHatchSmoothingValue() const
Definition zone.h:327
bool GetDoNotAllowZoneFills() const
Definition zone.h:729
int GetHatchSmoothingLevel() const
Definition zone.h:324
unsigned int GetCornerRadius() const
Definition zone.h:664
int GetCornerSmoothingType() const
Definition zone.h:660
int GetThermalReliefGap() const
Definition zone.h:234
unsigned GetAssignedPriority() const
Definition zone.h:125
#define _(s)
#define TEST_PT(a, b)
#define TEST(a, b)
std::string GetPcbnewTestDataDir()
Utility which returns a path to the data directory where the test board files are stored.
void LoadBoard(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< BOARD > &aBoard)
void CheckFootprint(const FOOTPRINT *expected, const FOOTPRINT *fp)
Helper method to check if two footprints are semantically the same.
void PrintBoardStats(const BOARD *aBoard, const std::string &aBoardName)
Print detailed board statistics for debugging using test-framework logging.
void FillZones(BOARD *m_board)
std::unique_ptr< BOARD > LoadBoardWithCapture(PCB_IO &aIoPlugin, const std::string &aFilePath, REPORTER *aReporter)
Attempt to load an board with a given IO plugin, capturing all reporter messages.
std::unique_ptr< BOARD > ReadBoardFromFileOrStream(const std::string &aFilename, std::istream &aFallback)
Read a board from a file, or another stream, as appropriate.
void CheckFpShape(const PCB_SHAPE *expected, const PCB_SHAPE *shape)
std::unique_ptr< FOOTPRINT > ReadFootprintFromFileOrStream(const std::string &aFilename, std::istream &aFallback)
void LoadAndTestFootprintFile(const wxString &aLibRelativePath, const wxString &aFpName, bool aRoundtrip, std::function< void(FOOTPRINT &)> aFootprintTestFunction, std::optional< int > aExpectedFootprintVersion)
Same as LoadAndTestBoardFile, but for footprints.
void DumpBoardToFile(BOARD &board, const std::string &aFilename)
Utility function to simply write a Board out to a file.
void CheckFpPad(const PAD *expected, const PAD *pad)
void CheckFpZone(const ZONE *expected, const ZONE *zone)
void CheckFpText(const PCB_TEXT *expected, const PCB_TEXT *text)
void DumpFootprintToFile(const FOOTPRINT &aFootprint, const std::string &aLibraryPath)
Same as DumpBoardToFile, but for footprints.
void LoadAndTestBoardFile(const wxString aRelativePath, bool aRoundtrip, std::function< void(BOARD &)> aBoardTestFunction, std::optional< int > aExpectedBoardVersion)
Perform "some test" on a board file loaded from the path, then optionally save and reload and run the...
void CheckShapePolySet(const SHAPE_POLY_SET *expected, const SHAPE_POLY_SET *polyset)
BOARD_ITEM & RequireBoardItemWithTypeAndId(const BOARD &aBoard, KICAD_T aItemType, const KIID &aID)
Get an item from the given board with a certain type and UUID.
@ SMD
Smd pad, appears on the solder paste layer (default)
Definition padstack.h:99
VIATYPE
SEVERITY
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_DEBUG
@ RPT_SEVERITY_INFO
@ RPT_SEVERITY_ACTION
#define SKIP_SET_DIRTY
Definition sch_commit.h:42
#define SKIP_UNDO
Definition sch_commit.h:40
std::vector< FAB_LAYER_COLOR > dummy
FOOTPRINT::cmp_drawings fp_comp
bool operator()(const BOARD_ITEM *itemA, const BOARD_ITEM *itemB) const
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
std::string path
VECTOR3I expected(15, 30, 45)
BOOST_TEST_CONTEXT("Test Clearance")
BOOST_TEST_MESSAGE("Polyline has "<< chain.PointCount()<< " points")
BOOST_CHECK_EQUAL(result, "25.4")
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition typeinfo.h:78
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
Definition typeinfo.h:88
@ PCB_DIM_ORTHOGONAL_T
class PCB_DIM_ORTHOGONAL, a linear dimension constrained to x/y
Definition typeinfo.h:106
@ PCB_DIM_LEADER_T
class PCB_DIM_LEADER, a leader dimension (graphic item)
Definition typeinfo.h:103
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition typeinfo.h:97
@ PCB_DIM_CENTER_T
class PCB_DIM_CENTER, a center point marking (graphic item)
Definition typeinfo.h:104
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition typeinfo.h:92
@ PCB_BARCODE_T
class PCB_BARCODE, a barcode (graphic item)
Definition typeinfo.h:101
@ PCB_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
Definition typeinfo.h:102
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
Definition typeinfo.h:98
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
Definition typeinfo.h:96
@ PCB_DIM_RADIAL_T
class PCB_DIM_RADIAL, a radius or diameter dimension
Definition typeinfo.h:105