41 BOOST_CHECK( m_plugin.CanReadSchematicFile( GetTestDataDir() +
"z80_board.dch" ) );
42 BOOST_CHECK( m_plugin.CanReadSchematicFile( GetTestDataDir() +
"power_supply.dch" ) );
43 BOOST_CHECK( m_plugin.CanReadSchematicFile( GetTestDataDir() +
"pppp.dch" ) );
54 const std::string
path = GetTestDataDir() +
"power_supply.dch";
60 BOOST_CHECK_GT( CountItemsOfType(
SCH_LINE_T ), 0 );
62 RemoveGeneratedLibrary(
path );
68 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
69 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_bad_count_" ) );
70 wxRemoveFile( tempBase );
71 wxString tempPath = tempBase + wxS(
".dch" );
76 static constexpr wxFileOffset COMPONENT_COUNT_OFFSET = 0xEE;
77 const uint8_t invalidCount[] = { 0x12, 0x4F, 0x81 };
79 wxFFile file( tempPath, wxS(
"r+b" ) );
82 BOOST_REQUIRE_EQUAL( file.Write( invalidCount,
sizeof( invalidCount ) ),
sizeof( invalidCount ) );
85 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
87 RemoveGeneratedLibrary( tempPath.ToStdString() );
88 wxRemoveFile( tempPath );
94 const std::string
path = GetTestDataDir() +
"z80_board.dch";
99 wxFileName newFilename(
path );
101 rootSheet->
SetFileName( newFilename.GetFullPath() );
102 m_schematic->SetTopLevelSheets( { rootSheet } );
113 RemoveGeneratedLibrary(
path );
123 const std::string
path = GetTestDataDir() +
"z80_board.dch";
125 wxFileName genLib(
path );
126 genLib.SetName( genLib.GetName() + wxT(
"-diptrace-import" ) );
127 genLib.SetExt( wxT(
"kicad_sym" ) );
129 if( genLib.FileExists() )
130 wxRemoveFile( genLib.GetFullPath() );
135 BOOST_CHECK_MESSAGE( !genLib.FileExists(),
"DipTrace import must not create a symbol library file: "
136 << genLib.GetFullPath().ToStdString() );
139 std::set<SCH_SCREEN*> seenScreens;
140 std::vector<SCH_SCREEN*> pendingScreens;
141 bool foundEmbeddedSymbol =
false;
144 pendingScreens.push_back( root->
GetScreen() );
146 while( !pendingScreens.empty() && !foundEmbeddedSymbol )
149 pendingScreens.pop_back();
151 if( !screen || !seenScreens.insert( screen ).second )
158 if(
static_cast<SCH_SYMBOL*
>( item )->GetLibSymbolRef() )
160 foundEmbeddedSymbol =
true;
169 pendingScreens.push_back( subSheet->
GetScreen() );
174 BOOST_CHECK_MESSAGE( foundEmbeddedSymbol,
"Imported schematic must carry embedded symbol definitions." );
176 if( genLib.FileExists() )
177 wxRemoveFile( genLib.GetFullPath() );
188 const std::string
path = GetTestDataDir() +
"z80_board.dch";
197 SCH_SHEET_LIST hierarchy = m_schematic->BuildUnorderedSheetList();
198 BOOST_REQUIRE_GE( hierarchy.size(), 1u );
200 bool contentReachable =
false;
204 if( sheetPath.LastScreen() == root->
GetScreen() )
206 contentReachable =
true;
211 BOOST_CHECK( contentReachable );
213 RemoveGeneratedLibrary(
path );
219 const std::string examplesDir = GetViewerExamplesDir();
220 const std::vector<std::string> paths = {
221 examplesDir +
"/CNC_controller.dch",
222 examplesDir +
"/Schematic_2.dch",
223 examplesDir +
"/Schematic_4.dch",
224 examplesDir +
"/Schematic_6.dch",
227 bool foundAny =
false;
229 for(
const std::string&
path : paths )
231 if( !wxFileExists(
path ) )
239 wxFileName newFilename(
path );
241 rootSheet->
SetFileName( newFilename.GetFullPath() );
242 m_schematic->SetTopLevelSheets( { rootSheet } );
252 path +
": component boundary scan fallback used" );
254 RemoveGeneratedLibrary(
path );
259 BOOST_TEST_MESSAGE(
"Skipping sequential component record check; no viewer examples found at "
267 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
268 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_count_mismatch_" ) );
269 wxRemoveFile( tempBase );
270 wxString tempPath = tempBase + wxS(
".dch" );
275 static constexpr wxFileOffset COMPONENT_COUNT_OFFSET = 0xEE;
276 const uint8_t mismatchedCount[] = { 0x0F, 0x42, 0xC5 };
278 wxFFile file( tempPath, wxS(
"r+b" ) );
281 BOOST_REQUIRE_EQUAL( file.Write( mismatchedCount,
sizeof( mismatchedCount ) ),
sizeof( mismatchedCount ) );
284 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
286 RemoveGeneratedLibrary( tempPath.ToStdString() );
287 wxRemoveFile( tempPath );
293 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
294 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_bad_pin_count_" ) );
295 wxRemoveFile( tempBase );
296 wxString tempPath = tempBase + wxS(
".dch" );
301 static constexpr wxFileOffset FIRST_COMPONENT_PIN_COUNT_OFFSET = 0x20A;
302 const uint8_t invalidPinCount[] = { 0x12, 0x4F, 0x81 };
304 wxFFile file( tempPath, wxS(
"r+b" ) );
306 BOOST_REQUIRE( file.Seek( FIRST_COMPONENT_PIN_COUNT_OFFSET ) );
307 BOOST_REQUIRE_EQUAL( file.Write( invalidPinCount,
sizeof( invalidPinCount ) ),
sizeof( invalidPinCount ) );
310 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
312 RemoveGeneratedLibrary( tempPath.ToStdString() );
313 wxRemoveFile( tempPath );
319 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
320 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_bad_extra_tail_" ) );
321 wxRemoveFile( tempBase );
322 wxString tempPath = tempBase + wxS(
".dch" );
327 static constexpr wxFileOffset FIRST_COMPONENT_EXTRA_TAIL_COUNT_OFFSET = 0x206;
328 const uint8_t invalidExtraTailCount[] = { 0x00, 0x00, 0x27, 0x10 };
330 wxFFile file( tempPath, wxS(
"r+b" ) );
332 BOOST_REQUIRE( file.Seek( FIRST_COMPONENT_EXTRA_TAIL_COUNT_OFFSET ) );
333 BOOST_REQUIRE_EQUAL( file.Write( invalidExtraTailCount,
sizeof( invalidExtraTailCount ) ),
334 sizeof( invalidExtraTailCount ) );
337 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
339 RemoveGeneratedLibrary( tempPath.ToStdString() );
340 wxRemoveFile( tempPath );
346 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
347 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_bad_pin_" ) );
348 wxRemoveFile( tempBase );
349 wxString tempPath = tempBase + wxS(
".dch" );
354 static constexpr wxFileOffset FIRST_COMPONENT_FIRST_PIN_NAME_LEN_OFFSET = 0x226;
355 const uint8_t invalidNameLength[] = { 0xFF, 0xFF };
357 wxFFile file( tempPath, wxS(
"r+b" ) );
359 BOOST_REQUIRE( file.Seek( FIRST_COMPONENT_FIRST_PIN_NAME_LEN_OFFSET ) );
360 BOOST_REQUIRE_EQUAL( file.Write( invalidNameLength,
sizeof( invalidNameLength ) ),
361 sizeof( invalidNameLength ) );
364 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
366 RemoveGeneratedLibrary( tempPath.ToStdString() );
367 wxRemoveFile( tempPath );
373 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
374 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_bad_later_pin_" ) );
375 wxRemoveFile( tempBase );
376 wxString tempPath = tempBase + wxS(
".dch" );
381 static constexpr wxFileOffset FIRST_COMPONENT_SECOND_PIN_NAME_LEN_OFFSET = 0x272;
382 const uint8_t invalidNameLength[] = { 0xFF, 0xFF };
384 wxFFile file( tempPath, wxS(
"r+b" ) );
386 BOOST_REQUIRE( file.Seek( FIRST_COMPONENT_SECOND_PIN_NAME_LEN_OFFSET ) );
387 BOOST_REQUIRE_EQUAL( file.Write( invalidNameLength,
sizeof( invalidNameLength ) ),
388 sizeof( invalidNameLength ) );
391 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
393 RemoveGeneratedLibrary( tempPath.ToStdString() );
394 wxRemoveFile( tempPath );
400 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
401 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_bad_shape_points_" ) );
402 wxRemoveFile( tempBase );
403 wxString tempPath = tempBase + wxS(
".dch" );
408 static constexpr wxFileOffset FIRST_COMPONENT_SHAPE_POINT_COUNT_OFFSET = 0x2C2;
409 const uint8_t invalidPointCount[] = { 0x0F, 0x42, 0xA5 };
411 wxFFile file( tempPath, wxS(
"r+b" ) );
413 BOOST_REQUIRE( file.Seek( FIRST_COMPONENT_SHAPE_POINT_COUNT_OFFSET ) );
414 BOOST_REQUIRE_EQUAL( file.Write( invalidPointCount,
sizeof( invalidPointCount ) ),
415 sizeof( invalidPointCount ) );
418 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
420 RemoveGeneratedLibrary( tempPath.ToStdString() );
421 wxRemoveFile( tempPath );
427 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
428 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_zero_shape_points_" ) );
429 wxRemoveFile( tempBase );
430 wxString tempPath = tempBase + wxS(
".dch" );
435 static constexpr wxFileOffset FIRST_COMPONENT_SHAPE_POINT_COUNT_OFFSET = 0x2C2;
436 const uint8_t zeroPointCount[] = { 0x0F, 0x42, 0x40 };
438 wxFFile file( tempPath, wxS(
"r+b" ) );
440 BOOST_REQUIRE( file.Seek( FIRST_COMPONENT_SHAPE_POINT_COUNT_OFFSET ) );
441 BOOST_REQUIRE_EQUAL( file.Write( zeroPointCount,
sizeof( zeroPointCount ) ),
sizeof( zeroPointCount ) );
444 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
446 RemoveGeneratedLibrary( tempPath.ToStdString() );
447 wxRemoveFile( tempPath );
453 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
454 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_bad_bus_" ) );
455 wxRemoveFile( tempBase );
456 wxString tempPath = tempBase + wxS(
".dch" );
461 static constexpr wxFileOffset FIRST_BUS_TERMINATOR_OFFSET = 0x39484;
462 const uint8_t invalidTerminator[] = { 0x0F, 0x42, 0x40 };
464 wxFFile file( tempPath, wxS(
"r+b" ) );
467 BOOST_REQUIRE_EQUAL( file.Write( invalidTerminator,
sizeof( invalidTerminator ) ),
468 sizeof( invalidTerminator ) );
471 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
473 RemoveGeneratedLibrary( tempPath.ToStdString() );
474 wxRemoveFile( tempPath );
480 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
481 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_bad_bus_count_" ) );
482 wxRemoveFile( tempBase );
483 wxString tempPath = tempBase + wxS(
".dch" );
488 static constexpr wxFileOffset BUS_SECTION_COUNT_OFFSET = 0x3946A;
489 const uint8_t invalidCount[] = { 0x0F, 0x46, 0x29 };
491 wxFFile file( tempPath, wxS(
"r+b" ) );
494 BOOST_REQUIRE_EQUAL( file.Write( invalidCount,
sizeof( invalidCount ) ),
sizeof( invalidCount ) );
497 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
499 RemoveGeneratedLibrary( tempPath.ToStdString() );
500 wxRemoveFile( tempPath );
506 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
507 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_bad_wire_pin_count_" ) );
508 wxRemoveFile( tempBase );
509 wxString tempPath = tempBase + wxS(
".dch" );
514 static constexpr wxFileOffset FIRST_WIRE_NET_PIN_COUNT_OFFSET = 0x3988E;
515 const uint8_t invalidPinCount[] = { 0x0F, 0x51, 0xE9 };
517 wxFFile file( tempPath, wxS(
"r+b" ) );
519 BOOST_REQUIRE( file.Seek( FIRST_WIRE_NET_PIN_COUNT_OFFSET ) );
520 BOOST_REQUIRE_EQUAL( file.Write( invalidPinCount,
sizeof( invalidPinCount ) ),
sizeof( invalidPinCount ) );
523 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
525 RemoveGeneratedLibrary( tempPath.ToStdString() );
526 wxRemoveFile( tempPath );
532 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
533 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_bad_wire_name_" ) );
534 wxRemoveFile( tempBase );
535 wxString tempPath = tempBase + wxS(
".dch" );
540 static constexpr wxFileOffset FIRST_WIRE_NET_NAME_LENGTH_OFFSET = 0x3987A;
541 const uint8_t invalidNameLength[] = { 0xFF, 0xFF };
543 wxFFile file( tempPath, wxS(
"r+b" ) );
545 BOOST_REQUIRE( file.Seek( FIRST_WIRE_NET_NAME_LENGTH_OFFSET ) );
546 BOOST_REQUIRE_EQUAL( file.Write( invalidNameLength,
sizeof( invalidNameLength ) ),
547 sizeof( invalidNameLength ) );
550 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
552 RemoveGeneratedLibrary( tempPath.ToStdString() );
553 wxRemoveFile( tempPath );
559 const std::string sourcePath = GetTestDataDir() +
"z80_board.dch";
560 wxString tempBase = wxFileName::CreateTempFileName( wxS(
"kicad_diptrace_bad_wire_point_count_" ) );
561 wxRemoveFile( tempBase );
562 wxString tempPath = tempBase + wxS(
".dch" );
567 static constexpr wxFileOffset FIRST_WIRE_POINT_COUNT_OFFSET = 0x39913;
568 const uint8_t invalidPointCount[] = { 0x0F, 0x51, 0xE9 };
570 wxFFile file( tempPath, wxS(
"r+b" ) );
573 BOOST_REQUIRE_EQUAL( file.Write( invalidPointCount,
sizeof( invalidPointCount ) ),
574 sizeof( invalidPointCount ) );
577 BOOST_CHECK_THROW( LoadDipTraceSchematic( tempPath.ToStdString() ),
IO_ERROR );
579 RemoveGeneratedLibrary( tempPath.ToStdString() );
580 wxRemoveFile( tempPath );
595 for(
const char* file : {
"z80_board.dch",
"power_supply.dch",
"pppp.dch" } )
597 const std::string
path = GetTestDataDir() + file;
599 if( !wxFileExists(
path ) )
603 BOOST_REQUIRE_NO_THROW( root = LoadDipTraceSchematic(
path ) );
607 "Import of " << file <<
" reported errors" );
609 "Import of " << file <<
" reported warnings" );
611 RemoveGeneratedLibrary(
path );
618 const std::string examplesDir = GetViewerExamplesDir();
619 const std::string sch2 = examplesDir +
"/Schematic_2.dch";
620 const std::string sch4 = examplesDir +
"/Schematic_4.dch";
622 if( !wxFileExists( sch2 ) || !wxFileExists( sch4 ) )
624 BOOST_TEST_MESSAGE(
"Skipping legacy header check; viewer examples not found at " << examplesDir );
628 BOOST_CHECK( m_plugin.CanReadSchematicFile( sch2 ) );
629 BOOST_CHECK( m_plugin.CanReadSchematicFile( sch4 ) );
635 const std::string examplesDir = GetViewerExamplesDir();
639 const char* fileName;
644 const std::vector<EXPECTED>
expected = {
645 {
"CNC_controller.dch", 100, 3 },
646 {
"Schematic_2.dch", 50, 1 },
647 {
"Schematic_4.dch", 70, 1 },
648 {
"Schematic_6.dch", 120, 1 },
651 bool foundAny =
false;
655 const std::string
path = examplesDir +
"/" + e.fileName;
657 if( !wxFileExists(
path ) )
666 root = LoadDipTraceSchematic(
path );
668 catch(
const std::exception& eex )
670 BOOST_FAIL(
"Failed to load " <<
path <<
": " << eex.what() );
674 BOOST_FAIL(
"Failed to load " <<
path <<
": unknown exception" );
677 BOOST_REQUIRE_MESSAGE( root !=
nullptr,
"Failed to load " <<
path );
683 const int screenCount = CountImportedScreens();
685 BOOST_CHECK_GE( symbolCount, e.minSymbols );
686 BOOST_CHECK_GE( screenCount, e.minScreens );
691 BOOST_TEST_MESSAGE(
"Skipping external example load test; no .dch files found at " << examplesDir );
698 const char* corpusEnv = std::getenv(
"DIPTRACE_EXTERNAL_CORPUS_DIR" );
700 if( !corpusEnv || !*corpusEnv )
702 BOOST_TEST_MESSAGE(
"DIPTRACE_EXTERNAL_CORPUS_DIR not set; skipping external schematic corpus sweep" );
706 std::filesystem::path corpusRoot( corpusEnv );
708 if( !std::filesystem::exists( corpusRoot ) )
710 BOOST_TEST_MESSAGE(
"External corpus path does not exist; skipping external schematic corpus sweep" );
714 std::vector<std::filesystem::path> dchFiles;
716 for(
const auto& entry : std::filesystem::recursive_directory_iterator( corpusRoot ) )
718 if( entry.is_regular_file() && entry.path().extension() ==
".dch" )
719 dchFiles.push_back( entry.path() );
722 std::sort( dchFiles.begin(), dchFiles.end() );
723 BOOST_REQUIRE_MESSAGE( !dchFiles.empty(),
"No .dch files found under: " + corpusRoot.string() );
727 for(
const std::filesystem::path&
path : dchFiles )
733 root = LoadDipTraceSchematic(
path.string() );
735 catch(
const std::exception& e )
737 BOOST_ERROR(
path.string() +
": exception: " + std::string( e.what() ) );
741 BOOST_REQUIRE_MESSAGE( root !=
nullptr,
"Failed to load " +
path.string() );
749 path.string() +
": import reported warnings: "
752 RemoveGeneratedLibrary(
path.string() );
755 BOOST_CHECK_MESSAGE( loaded > 0,
"External schematic corpus sweep loaded zero schematics" );
761 const std::string examplesDir = GetViewerExamplesDir();
766 const char* dchXmlFile;
767 double minPartCoverage;
773 const std::vector<EXPECTED>
expected = {
774 {
"CNC_controller.dch",
"CNC_controller.dchxml", 0.78 },
775 {
"Schematic_2.dch",
"PCB_2.dchxml", 0.95 },
776 {
"Schematic_4.dch",
"PCB_4.dchxml", 0.95 },
777 {
"Schematic_6.dch",
"PCB_6.dchxml", 0.95 },
780 bool foundAny =
false;
784 const std::string dchPath = examplesDir +
"/" + e.dchFile;
785 const std::string xmlPath = examplesDir +
"/" + e.dchXmlFile;
787 if( !wxFileExists( dchPath ) || !wxFileExists( xmlPath ) )
792 DCH_XML_COUNTS xmlCounts;
793 BOOST_REQUIRE_MESSAGE( LoadDchXmlCounts( xmlPath, xmlCounts ),
"Failed to parse " << xmlPath );
794 BOOST_REQUIRE_GT( xmlCounts.partCount, 0 );
795 BOOST_REQUIRE_GT( xmlCounts.sheetCount, 0 );
801 root = LoadDipTraceSchematic( dchPath );
803 catch(
const std::exception& eex )
805 BOOST_FAIL(
"Failed to load " << dchPath <<
": " << eex.what() );
809 BOOST_FAIL(
"Failed to load " << dchPath <<
": unknown exception" );
817 const int importedSymbols = CountItemsOfType(
SCH_SYMBOL_T );
819 const int importedScreens = CountImportedScreens();
820 const int realParts = xmlCounts.partCount - xmlCounts.netPortCount;
821 const int minParts =
static_cast<int>( std::floor( realParts * e.minPartCoverage ) );
824 BOOST_CHECK_LE( importedSymbols, realParts + 2 );
825 BOOST_CHECK_GE( importedSymbols, minParts );
827 if( xmlCounts.netPortCount > 0 )
828 BOOST_CHECK_GE( importedLabels, 1 );
833 BOOST_TEST_MESSAGE(
"Skipping DCH/XML parity test; no matched files found at " << examplesDir );
840 const std::string examplesDir = GetViewerExamplesDir();
841 const std::string cncPath = examplesDir +
"/CNC_controller.dch";
842 const std::string sch6Path = examplesDir +
"/Schematic_6.dch";
844 if( !wxFileExists( cncPath ) || !wxFileExists( sch6Path ) )
846 BOOST_TEST_MESSAGE(
"Skipping pin-count checks; required viewer examples not found at " << examplesDir );
851 SCH_SHEET* root = LoadDipTraceSchematic( cncPath );
858 SCH_SHEET* root = LoadDipTraceSchematic( sch6Path );
870 const std::string examplesDir = GetViewerExamplesDir();
871 const std::string sch6Path = examplesDir +
"/Schematic_6.dch";
873 if( !wxFileExists( sch6Path ) )
875 BOOST_TEST_MESSAGE(
"Skipping footprint field checks; Schematic_6.dch not found at " << examplesDir );
879 SCH_SHEET* root = LoadDipTraceSchematic( sch6Path );
885 BOOST_CHECK_EQUAL( GetFootprintForRefdes( wxT(
"C1" ) ), wxString( wxT(
"CAP_2012_N" ) ) );
886 BOOST_CHECK_EQUAL( GetFootprintForRefdes( wxT(
"R1" ) ), wxString( wxT(
"RES_2012_N" ) ) );
889 BOOST_CHECK_EQUAL( GetFootprintForRefdes( wxT(
"C10" ) ), wxString( wxT(
"CAP_2012_N" ) ) );
890 BOOST_CHECK_EQUAL( GetFootprintForRefdes( wxT(
"R10" ) ), wxString( wxT(
"RES_2012_N" ) ) );
902 const std::string
path = GetTestDataDir() +
"z80_board.dch";
907 SCH_SHEET_LIST sheets = m_schematic->BuildSheetListSortedByPageNumbers();
908 m_schematic->ConnectionGraph()->Recalculate( sheets,
true );
910 const NET_MAP& netMap = m_schematic->ConnectionGraph()->GetNetMap();
912 int multiPinNets = 0;
914 for(
const auto& [key, subgraphs] : netMap )
920 for(
SCH_ITEM* item : sg->GetItems() )
939 BOOST_CHECK_MESSAGE( multiPinNets > 0,
"Import produced no net connecting two or more pins" );
941 RemoveGeneratedLibrary(
path );
953 const std::string
path = GetTestDataDir() +
"z80_board.dch";
959 static constexpr int PAGE_WIDTH_IU = 40640000;
960 static constexpr int PAGE_HEIGHT_IU = 30480000;
963 static constexpr int MARGIN_FACTOR = 4;
964 const int maxX = PAGE_WIDTH_IU * MARGIN_FACTOR;
965 const int maxY = PAGE_HEIGHT_IU * MARGIN_FACTOR;
967 int symbolsChecked = 0;
969 for(
const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
982 "Symbol X extent exceeds page bounds: [" << bbox.
GetLeft() <<
", " << bbox.
GetRight()
985 "Symbol Y extent exceeds page bounds: [" << bbox.
GetTop() <<
", " << bbox.
GetBottom()
992 BOOST_CHECK_GT( symbolsChecked, 0 );
994 RemoveGeneratedLibrary(
path );
1007 const std::string
path = GetTestDataDir() +
"z80_board.dch";
1015 const int maxShapeWidth =
schIUScale.MilsToIU( 100 );
1017 int shapesChecked = 0;
1019 for(
const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
1029 const std::unique_ptr<LIB_SYMBOL>& libSymbol = symbol->
GetLibSymbolRef();
1034 for(
SCH_ITEM& drawItem : libSymbol->GetDrawItems() )
1043 "Symbol graphic width " << width <<
" is far from pin width " << defaultWidth );
1050 BOOST_CHECK_GT( shapesChecked, 0 );
1052 RemoveGeneratedLibrary(
path );
1064 const std::string
path = GetTestDataDir() +
"z80_board.dch";
1070 int diagonalPolylines = 0;
1072 for(
const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
1082 const std::unique_ptr<LIB_SYMBOL>& libSymbol = symbol->
GetLibSymbolRef();
1087 for(
SCH_ITEM& drawItem : libSymbol->GetDrawItems() )
1105 if( pts.size() == 2 && pts[1].x != pts[0].x && pts[1].y != pts[0].y )
1106 diagonalPolylines++;
1111 BOOST_TEST_MESSAGE(
"z80 rectangles=" << rectangles <<
" diagonalPolylines=" << diagonalPolylines );
1116 BOOST_CHECK_GT( diagonalPolylines, 0 );
1118 RemoveGeneratedLibrary(
path );
1129 const std::string
path = GetTestDataDir() +
"z80_board.dch";
1134 std::set<PIN_ORIENTATION> orientations;
1135 int pinsChecked = 0;
1137 for(
const SCH_SHEET_PATH& sheetPath : m_schematic->BuildUnorderedSheetList() )
1147 const std::unique_ptr<LIB_SYMBOL>& libSymbol = symbol->
GetLibSymbolRef();
1152 for(
SCH_ITEM& drawItem : libSymbol->GetDrawItems() )
1157 orientations.insert(
static_cast<SCH_PIN&
>( drawItem ).GetOrientation() );
1163 BOOST_CHECK_GT( pinsChecked, 0 );
1165 "All imported pins share a single orientation; orientation was not applied" );
1167 RemoveGeneratedLibrary(
path );
1179 const std::string
path = GetTestDataDir() +
"power_supply.dch";
1188 BOOST_CHECK_CLOSE( page.
GetWidthMM(), 297.0, 0.5 );
1189 BOOST_CHECK_CLOSE( page.
GetHeightMM(), 210.0, 0.5 );
1191 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")