37 BOOST_CHECK( m_plugin.CanReadSchematicFile( GetTestDataDir() +
"z80_board.dch" ) );
38 BOOST_CHECK( m_plugin.CanReadSchematicFile( GetTestDataDir() +
"power_supply.dch" ) );
39 BOOST_CHECK( m_plugin.CanReadSchematicFile( GetTestDataDir() +
"pppp.dch" ) );
50 const std::string
path = GetTestDataDir() +
"power_supply.dch";
56 BOOST_CHECK_GT( CountItemsOfType(
SCH_LINE_T ), 0 );
58 RemoveGeneratedLibrary(
path );
64 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
65 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_bad_count_" ) );
66 wxRemoveFile( tempBase );
67 wxString tempPath = tempBase + wxS(
".dch" );
72 static constexpr wxFileOffset COMPONENT_COUNT_OFFSET = 0xEE;
73 const uint8_t invalidCount[] = { 0x12, 0x4F, 0x81 };
75 wxFFile file( tempPath, wxS(
"r+b" ) );
78 BOOST_REQUIRE_EQUAL( file.Write( invalidCount,
sizeof( invalidCount ) ),
sizeof( invalidCount ) );
81 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
83 RemoveGeneratedLibrary( tempPath.ToStdString() );
84 wxRemoveFile( tempPath );
90 const std::string
path = GetTestDataDir() +
"z80_board.dch";
95 wxFileName newFilename(
path );
97 rootSheet->
SetFileName( newFilename.GetFullPath() );
98 m_schematic->SetTopLevelSheets( { rootSheet } );
109 RemoveGeneratedLibrary(
path );
119 const std::string
path = GetTestDataDir() +
"z80_board.dch";
121 wxFileName genLib(
path );
122 genLib.SetName( genLib.GetName() + wxT(
"-diptrace-import" ) );
123 genLib.SetExt( wxT(
"kicad_sym" ) );
125 if( genLib.FileExists() )
126 wxRemoveFile( genLib.GetFullPath() );
131 BOOST_CHECK_MESSAGE( !genLib.FileExists(),
"DipTrace import must not create a symbol library file: "
132 << genLib.GetFullPath().ToStdString() );
135 std::set<SCH_SCREEN*> seenScreens;
136 std::vector<SCH_SCREEN*> pendingScreens;
137 bool foundEmbeddedSymbol =
false;
140 pendingScreens.push_back( root->
GetScreen() );
142 while( !pendingScreens.empty() && !foundEmbeddedSymbol )
145 pendingScreens.pop_back();
147 if( !screen || !seenScreens.insert( screen ).second )
154 if(
static_cast<SCH_SYMBOL*
>( item )->GetLibSymbolRef() )
156 foundEmbeddedSymbol =
true;
165 pendingScreens.push_back( subSheet->
GetScreen() );
170 BOOST_CHECK_MESSAGE( foundEmbeddedSymbol,
"Imported schematic must carry embedded symbol definitions." );
172 if( genLib.FileExists() )
173 wxRemoveFile( genLib.GetFullPath() );
184 const std::string
path = GetTestDataDir() +
"z80_board.dch";
193 SCH_SHEET_LIST hierarchy = m_schematic->BuildUnorderedSheetList();
194 BOOST_REQUIRE_GE( hierarchy.size(), 1u );
196 bool contentReachable =
false;
200 if( sheetPath.LastScreen() == root->
GetScreen() )
202 contentReachable =
true;
207 BOOST_CHECK( contentReachable );
209 RemoveGeneratedLibrary(
path );
215 const std::string examplesDir = GetViewerExamplesDir();
216 const std::vector<std::string> paths = {
217 examplesDir +
"/CNC_controller.dch",
218 examplesDir +
"/Schematic_2.dch",
219 examplesDir +
"/Schematic_4.dch",
220 examplesDir +
"/Schematic_6.dch",
223 bool foundAny =
false;
225 for(
const std::string&
path : paths )
227 if( !wxFileExists(
path ) )
235 wxFileName newFilename(
path );
237 rootSheet->
SetFileName( newFilename.GetFullPath() );
238 m_schematic->SetTopLevelSheets( { rootSheet } );
248 path +
": component boundary scan fallback used" );
250 RemoveGeneratedLibrary(
path );
255 BOOST_TEST_MESSAGE(
"Skipping sequential component record check; no viewer examples found at "
263 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
264 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_count_mismatch_" ) );
265 wxRemoveFile( tempBase );
266 wxString tempPath = tempBase + wxS(
".dch" );
271 static constexpr wxFileOffset COMPONENT_COUNT_OFFSET = 0xEE;
272 const uint8_t mismatchedCount[] = { 0x0F, 0x42, 0xC5 };
274 wxFFile file( tempPath, wxS(
"r+b" ) );
277 BOOST_REQUIRE_EQUAL( file.Write( mismatchedCount,
sizeof( mismatchedCount ) ),
sizeof( mismatchedCount ) );
280 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
282 RemoveGeneratedLibrary( tempPath.ToStdString() );
283 wxRemoveFile( tempPath );
289 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
290 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_bad_pin_count_" ) );
291 wxRemoveFile( tempBase );
292 wxString tempPath = tempBase + wxS(
".dch" );
297 static constexpr wxFileOffset FIRST_COMPONENT_PIN_COUNT_OFFSET = 0x20A;
298 const uint8_t invalidPinCount[] = { 0x12, 0x4F, 0x81 };
300 wxFFile file( tempPath, wxS(
"r+b" ) );
302 BOOST_REQUIRE( file.Seek( FIRST_COMPONENT_PIN_COUNT_OFFSET ) );
303 BOOST_REQUIRE_EQUAL( file.Write( invalidPinCount,
sizeof( invalidPinCount ) ),
sizeof( invalidPinCount ) );
306 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
308 RemoveGeneratedLibrary( tempPath.ToStdString() );
309 wxRemoveFile( tempPath );
315 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
316 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_bad_extra_tail_" ) );
317 wxRemoveFile( tempBase );
318 wxString tempPath = tempBase + wxS(
".dch" );
323 static constexpr wxFileOffset FIRST_COMPONENT_EXTRA_TAIL_COUNT_OFFSET = 0x206;
324 const uint8_t invalidExtraTailCount[] = { 0x00, 0x00, 0x27, 0x10 };
326 wxFFile file( tempPath, wxS(
"r+b" ) );
328 BOOST_REQUIRE( file.Seek( FIRST_COMPONENT_EXTRA_TAIL_COUNT_OFFSET ) );
329 BOOST_REQUIRE_EQUAL( file.Write( invalidExtraTailCount,
sizeof( invalidExtraTailCount ) ),
330 sizeof( invalidExtraTailCount ) );
333 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
335 RemoveGeneratedLibrary( tempPath.ToStdString() );
336 wxRemoveFile( tempPath );
342 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
343 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_bad_pin_" ) );
344 wxRemoveFile( tempBase );
345 wxString tempPath = tempBase + wxS(
".dch" );
350 static constexpr wxFileOffset FIRST_COMPONENT_FIRST_PIN_NAME_LEN_OFFSET = 0x226;
351 const uint8_t invalidNameLength[] = { 0xFF, 0xFF };
353 wxFFile file( tempPath, wxS(
"r+b" ) );
355 BOOST_REQUIRE( file.Seek( FIRST_COMPONENT_FIRST_PIN_NAME_LEN_OFFSET ) );
356 BOOST_REQUIRE_EQUAL( file.Write( invalidNameLength,
sizeof( invalidNameLength ) ),
357 sizeof( invalidNameLength ) );
360 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
362 RemoveGeneratedLibrary( tempPath.ToStdString() );
363 wxRemoveFile( tempPath );
369 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
370 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_bad_later_pin_" ) );
371 wxRemoveFile( tempBase );
372 wxString tempPath = tempBase + wxS(
".dch" );
377 static constexpr wxFileOffset FIRST_COMPONENT_SECOND_PIN_NAME_LEN_OFFSET = 0x272;
378 const uint8_t invalidNameLength[] = { 0xFF, 0xFF };
380 wxFFile file( tempPath, wxS(
"r+b" ) );
382 BOOST_REQUIRE( file.Seek( FIRST_COMPONENT_SECOND_PIN_NAME_LEN_OFFSET ) );
383 BOOST_REQUIRE_EQUAL( file.Write( invalidNameLength,
sizeof( invalidNameLength ) ),
384 sizeof( invalidNameLength ) );
387 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
389 RemoveGeneratedLibrary( tempPath.ToStdString() );
390 wxRemoveFile( tempPath );
396 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
397 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_bad_shape_points_" ) );
398 wxRemoveFile( tempBase );
399 wxString tempPath = tempBase + wxS(
".dch" );
404 static constexpr wxFileOffset FIRST_COMPONENT_SHAPE_POINT_COUNT_OFFSET = 0x2C2;
405 const uint8_t invalidPointCount[] = { 0x0F, 0x42, 0xA5 };
407 wxFFile file( tempPath, wxS(
"r+b" ) );
409 BOOST_REQUIRE( file.Seek( FIRST_COMPONENT_SHAPE_POINT_COUNT_OFFSET ) );
410 BOOST_REQUIRE_EQUAL( file.Write( invalidPointCount,
sizeof( invalidPointCount ) ),
411 sizeof( invalidPointCount ) );
414 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
416 RemoveGeneratedLibrary( tempPath.ToStdString() );
417 wxRemoveFile( tempPath );
423 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
424 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_zero_shape_points_" ) );
425 wxRemoveFile( tempBase );
426 wxString tempPath = tempBase + wxS(
".dch" );
431 static constexpr wxFileOffset FIRST_COMPONENT_SHAPE_POINT_COUNT_OFFSET = 0x2C2;
432 const uint8_t zeroPointCount[] = { 0x0F, 0x42, 0x40 };
434 wxFFile file( tempPath, wxS(
"r+b" ) );
436 BOOST_REQUIRE( file.Seek( FIRST_COMPONENT_SHAPE_POINT_COUNT_OFFSET ) );
437 BOOST_REQUIRE_EQUAL( file.Write( zeroPointCount,
sizeof( zeroPointCount ) ),
sizeof( zeroPointCount ) );
440 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
442 RemoveGeneratedLibrary( tempPath.ToStdString() );
443 wxRemoveFile( tempPath );
449 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
450 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_bad_bus_" ) );
451 wxRemoveFile( tempBase );
452 wxString tempPath = tempBase + wxS(
".dch" );
457 static constexpr wxFileOffset FIRST_BUS_TERMINATOR_OFFSET = 0x39484;
458 const uint8_t invalidTerminator[] = { 0x0F, 0x42, 0x40 };
460 wxFFile file( tempPath, wxS(
"r+b" ) );
463 BOOST_REQUIRE_EQUAL( file.Write( invalidTerminator,
sizeof( invalidTerminator ) ),
464 sizeof( invalidTerminator ) );
467 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
469 RemoveGeneratedLibrary( tempPath.ToStdString() );
470 wxRemoveFile( tempPath );
476 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
477 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_bad_bus_count_" ) );
478 wxRemoveFile( tempBase );
479 wxString tempPath = tempBase + wxS(
".dch" );
484 static constexpr wxFileOffset BUS_SECTION_COUNT_OFFSET = 0x3946A;
485 const uint8_t invalidCount[] = { 0x0F, 0x46, 0x29 };
487 wxFFile file( tempPath, wxS(
"r+b" ) );
490 BOOST_REQUIRE_EQUAL( file.Write( invalidCount,
sizeof( invalidCount ) ),
sizeof( invalidCount ) );
493 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
495 RemoveGeneratedLibrary( tempPath.ToStdString() );
496 wxRemoveFile( tempPath );
502 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
503 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_bad_wire_pin_count_" ) );
504 wxRemoveFile( tempBase );
505 wxString tempPath = tempBase + wxS(
".dch" );
510 static constexpr wxFileOffset FIRST_WIRE_NET_PIN_COUNT_OFFSET = 0x3988E;
511 const uint8_t invalidPinCount[] = { 0x0F, 0x51, 0xE9 };
513 wxFFile file( tempPath, wxS(
"r+b" ) );
515 BOOST_REQUIRE( file.Seek( FIRST_WIRE_NET_PIN_COUNT_OFFSET ) );
516 BOOST_REQUIRE_EQUAL( file.Write( invalidPinCount,
sizeof( invalidPinCount ) ),
sizeof( invalidPinCount ) );
519 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
521 RemoveGeneratedLibrary( tempPath.ToStdString() );
522 wxRemoveFile( tempPath );
528 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
529 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_bad_wire_name_" ) );
530 wxRemoveFile( tempBase );
531 wxString tempPath = tempBase + wxS(
".dch" );
536 static constexpr wxFileOffset FIRST_WIRE_NET_NAME_LENGTH_OFFSET = 0x3987A;
537 const uint8_t invalidNameLength[] = { 0xFF, 0xFF };
539 wxFFile file( tempPath, wxS(
"r+b" ) );
541 BOOST_REQUIRE( file.Seek( FIRST_WIRE_NET_NAME_LENGTH_OFFSET ) );
542 BOOST_REQUIRE_EQUAL( file.Write( invalidNameLength,
sizeof( invalidNameLength ) ),
543 sizeof( invalidNameLength ) );
546 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
548 RemoveGeneratedLibrary( tempPath.ToStdString() );
549 wxRemoveFile( tempPath );
555 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
556 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_bad_wire_point_count_" ) );
557 wxRemoveFile( tempBase );
558 wxString tempPath = tempBase + wxS(
".dch" );
563 static constexpr wxFileOffset FIRST_WIRE_POINT_COUNT_OFFSET = 0x39913;
564 const uint8_t invalidPointCount[] = { 0x0F, 0x51, 0xE9 };
566 wxFFile file( tempPath, wxS(
"r+b" ) );
569 BOOST_REQUIRE_EQUAL( file.Write( invalidPointCount,
sizeof( invalidPointCount ) ),
570 sizeof( invalidPointCount ) );
573 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
575 RemoveGeneratedLibrary( tempPath.ToStdString() );
576 wxRemoveFile( tempPath );
591 for(
const char* file : {
"z80_board.dch",
"power_supply.dch",
"pppp.dch" } )
593 const std::string
path = GetTestDataDir() + file;
595 if( !wxFileExists(
path ) )
599 BOOST_REQUIRE_NO_THROW( root = LoadDipTraceSchematic(
path ) );
603 "Import of " << file <<
" reported errors" );
605 "Import of " << file <<
" reported warnings" );
607 RemoveGeneratedLibrary(
path );
614 const std::string examplesDir = GetViewerExamplesDir();
615 const std::string sch2 = examplesDir +
"/Schematic_2.dch";
616 const std::string sch4 = examplesDir +
"/Schematic_4.dch";
618 if( !wxFileExists( sch2 ) || !wxFileExists( sch4 ) )
620 BOOST_TEST_MESSAGE(
"Skipping legacy header check; viewer examples not found at " << examplesDir );
624 BOOST_CHECK( m_plugin.CanReadSchematicFile( sch2 ) );
625 BOOST_CHECK( m_plugin.CanReadSchematicFile( sch4 ) );
631 const std::string examplesDir = GetViewerExamplesDir();
635 const char* fileName;
640 const std::vector<EXPECTED>
expected = {
641 {
"CNC_controller.dch", 100, 3 },
642 {
"Schematic_2.dch", 50, 1 },
643 {
"Schematic_4.dch", 70, 1 },
644 {
"Schematic_6.dch", 120, 1 },
647 bool foundAny =
false;
651 const std::string
path = examplesDir +
"/" + e.fileName;
653 if( !wxFileExists(
path ) )
662 root = LoadDipTraceSchematic(
path );
664 catch(
const std::exception& eex )
666 BOOST_FAIL(
"Failed to load " <<
path <<
": " << eex.what() );
670 BOOST_FAIL(
"Failed to load " <<
path <<
": unknown exception" );
673 BOOST_REQUIRE_MESSAGE( root !=
nullptr,
"Failed to load " <<
path );
679 const int screenCount = CountImportedScreens();
681 BOOST_CHECK_GE( symbolCount, e.minSymbols );
682 BOOST_CHECK_GE( screenCount, e.minScreens );
687 BOOST_TEST_MESSAGE(
"Skipping external example load test; no .dch files found at " << examplesDir );
694 const char* corpusEnv = std::getenv(
"DIPTRACE_EXTERNAL_CORPUS_DIR" );
696 if( !corpusEnv || !*corpusEnv )
698 BOOST_TEST_MESSAGE(
"DIPTRACE_EXTERNAL_CORPUS_DIR not set; skipping external schematic corpus sweep" );
702 std::filesystem::path corpusRoot( corpusEnv );
704 if( !std::filesystem::exists( corpusRoot ) )
706 BOOST_TEST_MESSAGE(
"External corpus path does not exist; skipping external schematic corpus sweep" );
710 std::vector<std::filesystem::path> dchFiles;
712 for(
const auto& entry : std::filesystem::recursive_directory_iterator( corpusRoot ) )
714 if( entry.is_regular_file() && entry.path().extension() ==
".dch" )
715 dchFiles.push_back( entry.path() );
718 std::sort( dchFiles.begin(), dchFiles.end() );
719 BOOST_REQUIRE_MESSAGE( !dchFiles.empty(),
"No .dch files found under: " + corpusRoot.string() );
723 for(
const std::filesystem::path&
path : dchFiles )
729 root = LoadDipTraceSchematic(
path.string() );
731 catch(
const std::exception& e )
733 BOOST_ERROR(
path.string() +
": exception: " + std::string( e.what() ) );
737 BOOST_REQUIRE_MESSAGE( root !=
nullptr,
"Failed to load " +
path.string() );
745 path.string() +
": import reported warnings: "
748 RemoveGeneratedLibrary(
path.string() );
751 BOOST_CHECK_MESSAGE( loaded > 0,
"External schematic corpus sweep loaded zero schematics" );
757 const std::string examplesDir = GetViewerExamplesDir();
762 const char* dchXmlFile;
763 double minPartCoverage;
769 const std::vector<EXPECTED>
expected = {
770 {
"CNC_controller.dch",
"CNC_controller.dchxml", 0.78 },
771 {
"Schematic_2.dch",
"PCB_2.dchxml", 0.95 },
772 {
"Schematic_4.dch",
"PCB_4.dchxml", 0.95 },
773 {
"Schematic_6.dch",
"PCB_6.dchxml", 0.95 },
776 bool foundAny =
false;
780 const std::string dchPath = examplesDir +
"/" + e.dchFile;
781 const std::string xmlPath = examplesDir +
"/" + e.dchXmlFile;
783 if( !wxFileExists( dchPath ) || !wxFileExists( xmlPath ) )
788 DCH_XML_COUNTS xmlCounts;
789 BOOST_REQUIRE_MESSAGE( LoadDchXmlCounts( xmlPath, xmlCounts ),
"Failed to parse " << xmlPath );
790 BOOST_REQUIRE_GT( xmlCounts.partCount, 0 );
791 BOOST_REQUIRE_GT( xmlCounts.sheetCount, 0 );
797 root = LoadDipTraceSchematic( dchPath );
799 catch(
const std::exception& eex )
801 BOOST_FAIL(
"Failed to load " << dchPath <<
": " << eex.what() );
805 BOOST_FAIL(
"Failed to load " << dchPath <<
": unknown exception" );
813 const int importedSymbols = CountItemsOfType(
SCH_SYMBOL_T );
815 const int importedScreens = CountImportedScreens();
816 const int realParts = xmlCounts.partCount - xmlCounts.netPortCount;
817 const int minParts =
static_cast<int>( std::floor( realParts * e.minPartCoverage ) );
820 BOOST_CHECK_LE( importedSymbols, realParts + 2 );
821 BOOST_CHECK_GE( importedSymbols, minParts );
823 if( xmlCounts.netPortCount > 0 )
824 BOOST_CHECK_GE( importedLabels, 1 );
829 BOOST_TEST_MESSAGE(
"Skipping DCH/XML parity test; no matched files found at " << examplesDir );
836 const std::string examplesDir = GetViewerExamplesDir();
837 const std::string cncPath = examplesDir +
"/CNC_controller.dch";
838 const std::string sch6Path = examplesDir +
"/Schematic_6.dch";
840 if( !wxFileExists( cncPath ) || !wxFileExists( sch6Path ) )
842 BOOST_TEST_MESSAGE(
"Skipping pin-count checks; required viewer examples not found at " << examplesDir );
847 SCH_SHEET* root = LoadDipTraceSchematic( cncPath );
854 SCH_SHEET* root = LoadDipTraceSchematic( sch6Path );
866 const std::string examplesDir = GetViewerExamplesDir();
867 const std::string sch6Path = examplesDir +
"/Schematic_6.dch";
869 if( !wxFileExists( sch6Path ) )
871 BOOST_TEST_MESSAGE(
"Skipping footprint field checks; Schematic_6.dch not found at " << examplesDir );
875 SCH_SHEET* root = LoadDipTraceSchematic( sch6Path );
881 BOOST_CHECK_EQUAL( GetFootprintForRefdes( wxT(
"C1" ) ), wxString( wxT(
"CAP_2012_N" ) ) );
882 BOOST_CHECK_EQUAL( GetFootprintForRefdes( wxT(
"R1" ) ), wxString( wxT(
"RES_2012_N" ) ) );
885 BOOST_CHECK_EQUAL( GetFootprintForRefdes( wxT(
"C10" ) ), wxString( wxT(
"CAP_2012_N" ) ) );
886 BOOST_CHECK_EQUAL( GetFootprintForRefdes( wxT(
"R10" ) ), wxString( wxT(
"RES_2012_N" ) ) );
898 const std::string
path = GetTestDataDir() +
"z80_board.dch";
903 SCH_SHEET_LIST sheets = m_schematic->BuildSheetListSortedByPageNumbers();
904 m_schematic->ConnectionGraph()->Recalculate( sheets,
true );
906 const NET_MAP& netMap = m_schematic->ConnectionGraph()->GetNetMap();
908 int multiPinNets = 0;
910 for(
const auto& [key, subgraphs] : netMap )
916 for(
SCH_ITEM* item : sg->GetItems() )
935 BOOST_CHECK_MESSAGE( multiPinNets > 0,
"Import produced no net connecting two or more pins" );
937 RemoveGeneratedLibrary(
path );
949 const std::string
path = GetTestDataDir() +
"z80_board.dch";
955 static constexpr int PAGE_WIDTH_IU = 40640000;
956 static constexpr int PAGE_HEIGHT_IU = 30480000;
959 static constexpr int MARGIN_FACTOR = 4;
960 const int maxX = PAGE_WIDTH_IU * MARGIN_FACTOR;
961 const int maxY = PAGE_HEIGHT_IU * MARGIN_FACTOR;
963 int symbolsChecked = 0;
965 for(
const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
978 "Symbol X extent exceeds page bounds: [" << bbox.
GetLeft() <<
", " << bbox.
GetRight()
981 "Symbol Y extent exceeds page bounds: [" << bbox.
GetTop() <<
", " << bbox.
GetBottom()
988 BOOST_CHECK_GT( symbolsChecked, 0 );
990 RemoveGeneratedLibrary(
path );
1003 const std::string
path = GetTestDataDir() +
"z80_board.dch";
1011 const int maxShapeWidth =
schIUScale.MilsToIU( 100 );
1013 int shapesChecked = 0;
1015 for(
const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
1025 const std::unique_ptr<LIB_SYMBOL>& libSymbol = symbol->
GetLibSymbolRef();
1030 for(
SCH_ITEM& drawItem : libSymbol->GetDrawItems() )
1039 "Symbol graphic width " << width <<
" is far from pin width " << defaultWidth );
1046 BOOST_CHECK_GT( shapesChecked, 0 );
1048 RemoveGeneratedLibrary(
path );
1060 const std::string
path = GetTestDataDir() +
"z80_board.dch";
1066 int diagonalPolylines = 0;
1068 for(
const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
1078 const std::unique_ptr<LIB_SYMBOL>& libSymbol = symbol->
GetLibSymbolRef();
1083 for(
SCH_ITEM& drawItem : libSymbol->GetDrawItems() )
1101 if( pts.size() == 2 && pts[1].x != pts[0].x && pts[1].y != pts[0].y )
1102 diagonalPolylines++;
1107 BOOST_TEST_MESSAGE(
"z80 rectangles=" << rectangles <<
" diagonalPolylines=" << diagonalPolylines );
1112 BOOST_CHECK_GT( diagonalPolylines, 0 );
1114 RemoveGeneratedLibrary(
path );
1125 const std::string
path = GetTestDataDir() +
"z80_board.dch";
1130 std::set<PIN_ORIENTATION> orientations;
1131 int pinsChecked = 0;
1133 for(
const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
1143 const std::unique_ptr<LIB_SYMBOL>& libSymbol = symbol->
GetLibSymbolRef();
1148 for(
SCH_ITEM& drawItem : libSymbol->GetDrawItems() )
1153 orientations.insert(
static_cast<SCH_PIN&
>( drawItem ).GetOrientation() );
1159 BOOST_CHECK_GT( pinsChecked, 0 );
1161 "All imported pins share a single orientation; orientation was not applied" );
1163 RemoveGeneratedLibrary(
path );
1175 const std::string
path = GetTestDataDir() +
"power_supply.dch";
1184 BOOST_CHECK_CLOSE( page.
GetWidthMM(), 297.0, 0.5 );
1185 BOOST_CHECK_CLOSE( page.
GetHeightMM(), 210.0, 0.5 );
1187 RemoveGeneratedLibrary(
path );
1201 const std::string
path = GetTestDataDir() +
"re-arm_pub.dch";
1206 BOOST_CHECK_EQUAL( CountSymbolsForRefdesOnSheet( wxT(
"U3" ), GetSheetNameForRefdes( wxT(
"U3" ) ) ), 1 );
1210 RemoveGeneratedLibrary(
path );
constexpr EDA_IU_SCALE schIUScale
constexpr coord_type GetLeft() const
constexpr coord_type GetRight() const
constexpr coord_type GetTop() const
constexpr coord_type GetBottom() const
A subgraph is a set of items that are electrically connected on a single sheet.
Parser for DipTrace .dch schematic binary files.
void Parse()
Parse the .dch file and populate the schematic with KiCad objects.
int ComponentBoundaryScanCount() const
SHAPE_POLY_SET & GetPolyShape()
virtual int GetWidth() const
EE_TYPE OfType(KICAD_T aType) const
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Describe the page size and margins of a paper page on which to eventually print or plot.
double GetHeightMM() const
double GetWidthMM() const
Each graphical item can have a SCH_CONNECTION describing its logical connection (to a bus or net).
Base class for any item which can be embedded within the SCHEMATIC container class,...
const PAGE_INFO & GetPageSettings() const
EE_RTREE & Items()
Get the full RTree, usually for iterating.
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
void SetFileName(const wxString &aFilename)
SCH_SCREEN * GetScreen() const
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
std::unique_ptr< LIB_SYMBOL > & GetLibSymbolRef()
const std::vector< VECTOR2I > & CPoints() const
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.
std::unordered_map< NET_NAME_CODE_CACHE_KEY, std::vector< CONNECTION_SUBGRAPH * > > NET_MAP
Associate a #NET_CODE_NAME with all the subgraphs in that net.
#define DEFAULT_LINE_WIDTH_MILS
The default wire width in mils. (can be changed in preference menu)
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
static const std::string KiCadSchematicFileExtension
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_CASE(CanReadSchematic)
Test that CanReadSchematicFile correctly identifies DipTrace .dch files by their magic header bytes.
Shared fixture, reporter and helpers for the DipTrace schematic import test suite.
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
VECTOR3I expected(15, 30, 45)
BOOST_CHECK_MESSAGE(totalMismatches==0, std::to_string(totalMismatches)+" board(s) with strategy disagreements")
BOOST_TEST_MESSAGE("\n=== Real-World Polygon PIP Benchmark ===\n"<< formatTable(table))
BOOST_CHECK_EQUAL(result, "25.4")