50bool textFilesMatch(
const wxString& aGoldenPath,
const wxString& aGeneratedPath,
int aSkipLines )
52 std::ifstream goldenStream( aGoldenPath.ToStdString() );
53 std::ifstream generatedStream( aGeneratedPath.ToStdString() );
55 if( !goldenStream.is_open() )
61 if( !generatedStream.is_open() )
67 std::string goldenLine, generatedLine;
69 for(
int i = 0; i < aSkipLines; ++i )
71 std::getline( goldenStream, goldenLine );
72 std::getline( generatedStream, generatedLine );
75 int lineNum = aSkipLines + 1;
77 while( std::getline( goldenStream, goldenLine ) )
79 if( !std::getline( generatedStream, generatedLine ) )
85 if( goldenLine != generatedLine )
88 <<
" golden: " << goldenLine <<
"\n"
89 <<
" generated: " << generatedLine );
96 if( std::getline( generatedStream, generatedLine ) )
149 BOOST_REQUIRE_MESSAGE( Start(), LastError() );
151 wxString testDataDir =
154 wxFileName boardPath( testDataDir, wxS(
"ZoneFill-4.0.7.kicad_pcb" ) );
156 kiapi::common::types::DocumentSpecifier document;
158 BOOST_REQUIRE_MESSAGE( Client().OpenDocument( boardPath.GetFullPath(), &document ),
159 "OpenDocument failed: " + Client().LastError() );
163 wxFileName outputPath( tempDir.
ChildPathStr(
"plot.svg" ) );
165 kiapi::board::jobs::RunBoardJobExportSvg request;
166 *request.mutable_job_settings()->mutable_document() = document;
167 request.mutable_job_settings()->set_output_path( outputPath.GetFullPath().ToUTF8().data() );
169 request.mutable_plot_settings()->add_layers( kiapi::board::types::BL_F_Cu );
170 request.mutable_plot_settings()->set_black_and_white(
true );
171 request.mutable_plot_settings()->set_plot_drawing_sheet(
false );
172 request.mutable_plot_settings()->set_drill_marks( kiapi::board::jobs::PDM_FULL );
173 request.set_page_mode( kiapi::board::jobs::BJPM_EACH_LAYER_OWN_FILE );
174 request.set_precision( 4 );
176 kiapi::common::types::RunJobResponse response;
177 BOOST_REQUIRE_MESSAGE( Client().RunJob( request, &response ),
"RunJob failed: " + Client().LastError() );
179 BOOST_REQUIRE_MESSAGE( response.status() == kiapi::common::types::JS_SUCCESS,
180 "Job failed: " + wxString::FromUTF8( response.message() ) );
182 BOOST_REQUIRE_MESSAGE( response.output_path_size() > 0,
"Job returned no output paths" );
184 wxString generatedPath = wxString::FromUTF8( response.output_path( 0 ) );
185 BOOST_REQUIRE_MESSAGE( wxFileName::FileExists( generatedPath ),
"Generated SVG does not exist: " + generatedPath );
191 BOOST_REQUIRE_MESSAGE( !svg.empty(),
"Generated SVG is empty or unreadable: " + generatedPath );
192 BOOST_CHECK( svg.find(
"<svg" ) != std::string::npos );
193 BOOST_CHECK( svg.find(
"</svg>" ) != std::string::npos );
196 BOOST_CHECK( svg.find(
"width=\"297.0022mm\" height=\"210.0072mm\"" ) != std::string::npos );
199 BOOST_REQUIRE_MESSAGE( !colours.empty(),
"Plot declares no colours at all" );
201 for(
const std::string& colour : colours )
203 BOOST_CHECK_MESSAGE( colour ==
"#000000" || colour ==
"#FFFFFF",
204 "black_and_white was requested but the plot contains " + colour );
247 BOOST_REQUIRE_MESSAGE( Start(), LastError() );
251 wxFileName schPath( testDataDir, wxS(
"basic_test.kicad_sch" ) );
253 kiapi::common::types::DocumentSpecifier document;
255 BOOST_REQUIRE_MESSAGE(
256 Client().OpenDocument( schPath.GetFullPath(), kiapi::common::types::DOCTYPE_SCHEMATIC, &document ),
257 "OpenDocument failed: " + Client().LastError() );
261 wxString outputDir = tempDir.
CreateChildDirStr(
"all" ) + wxFileName::GetPathSeparator();
264 kiapi::schematic::jobs::RunSchematicJobExportPng request;
265 *request.mutable_job_settings()->mutable_document() = document;
266 request.mutable_job_settings()->set_output_path( outputDir.ToUTF8().data() );
267 request.mutable_plot_settings()->set_sheet_mode( kiapi::schematic::jobs::SJSM_ALL_SHEETS );
268 request.mutable_plot_settings()->set_black_and_white(
true );
269 request.set_dpi( 150 );
271 kiapi::common::types::RunJobResponse response;
272 BOOST_REQUIRE_MESSAGE( Client().RunJob( request, &response ),
273 "RunJob failed: " + Client().LastError() );
275 BOOST_REQUIRE_MESSAGE( response.status() == kiapi::common::types::JS_SUCCESS,
276 "Job failed: " + wxString::FromUTF8( response.message() ) );
277 BOOST_REQUIRE_MESSAGE( response.output_path_size() > 0,
"Job returned no output paths" );
279 wxString generatedPath = wxString::FromUTF8( response.output_path( 0 ) );
280 BOOST_REQUIRE_MESSAGE( wxFileName::FileExists( generatedPath ),
281 "Generated PNG does not exist: " + generatedPath );
284 uint32_t width = 0, height = 0;
285 BOOST_REQUIRE_MESSAGE(
pngDimensions( generatedPath, width, height ),
286 "Generated file is not a valid PNG: " + generatedPath );
287 BOOST_CHECK_MESSAGE( width >= 1750 && width <= 1758,
288 "Unexpected PNG width " << width <<
" for 150dpi A4 landscape" );
289 BOOST_CHECK_MESSAGE( height >= 1236 && height <= 1244,
290 "Unexpected PNG height " << height <<
" for 150dpi A4 landscape" );
294 wxFileName singlePath( tempDir.
ChildPathStr(
"single.png" ) );
297 kiapi::schematic::jobs::RunSchematicJobExportPng request;
298 *request.mutable_job_settings()->mutable_document() = document;
299 request.mutable_job_settings()->set_output_path( singlePath.GetFullPath().ToUTF8().data() );
300 request.mutable_plot_settings()->set_sheet_mode( kiapi::schematic::jobs::SJSM_SINGLE_SHEET );
301 request.mutable_plot_settings()->set_black_and_white(
true );
302 request.set_dpi( 300 );
304 kiapi::common::types::RunJobResponse response;
305 BOOST_REQUIRE_MESSAGE( Client().RunJob( request, &response ),
306 "Single-sheet RunJob failed: " + Client().LastError() );
308 BOOST_REQUIRE_MESSAGE( response.status() == kiapi::common::types::JS_SUCCESS,
309 "Single-sheet job failed: " + wxString::FromUTF8( response.message() ) );
310 BOOST_REQUIRE_MESSAGE( response.output_path_size() > 0,
311 "Single-sheet job returned no output paths" );
313 wxString generatedPath = wxString::FromUTF8( response.output_path( 0 ) );
314 BOOST_REQUIRE_MESSAGE( wxFileName::FileExists( generatedPath ),
315 "Generated PNG does not exist: " + generatedPath );
318 uint32_t width = 0, height = 0;
319 BOOST_REQUIRE_MESSAGE(
pngDimensions( generatedPath, width, height ),
320 "Generated file is not a valid PNG: " + generatedPath );
321 BOOST_CHECK_MESSAGE( width >= 3500 && width <= 3516,
322 "Unexpected PNG width " << width <<
" for 300dpi A4 landscape" );
325 BOOST_CHECK_MESSAGE( generatedPath == singlePath.GetFullPath(),
326 "Single-sheet output path not honored: " + generatedPath );
331 kiapi::schematic::jobs::RunSchematicJobExportPng request;
332 *request.mutable_job_settings()->mutable_document() = document;
333 request.mutable_job_settings()->set_output_path( outputDir.ToUTF8().data() );
334 request.mutable_plot_settings()->set_sheet_mode( kiapi::schematic::jobs::SJSM_ALL_SHEETS );
335 request.set_dpi( 10 );
337 kiapi::common::types::RunJobResponse response;
338 BOOST_CHECK_MESSAGE( !Client().RunJob( request, &response ),
339 "Out-of-range dpi was not rejected" );
344 wxString defaultDir = tempDir.
CreateChildDirStr(
"default" ) + wxFileName::GetPathSeparator();
346 kiapi::schematic::jobs::RunSchematicJobExportPng request;
347 *request.mutable_job_settings()->mutable_document() = document;
348 request.mutable_job_settings()->set_output_path( defaultDir.ToUTF8().data() );
349 request.mutable_plot_settings()->set_sheet_mode( kiapi::schematic::jobs::SJSM_ALL_SHEETS );
351 kiapi::common::types::RunJobResponse response;
352 BOOST_REQUIRE_MESSAGE( Client().RunJob( request, &response ),
353 "Default-dpi RunJob failed: " + Client().LastError() );
354 BOOST_REQUIRE_MESSAGE( response.status() == kiapi::common::types::JS_SUCCESS,
355 "Default-dpi job failed: " + wxString::FromUTF8( response.message() ) );
356 BOOST_REQUIRE_MESSAGE( response.output_path_size() > 0,
357 "Default-dpi job returned no output paths" );
359 uint32_t width = 0, height = 0;
360 wxString generatedPath = wxString::FromUTF8( response.output_path( 0 ) );
361 BOOST_REQUIRE_MESSAGE(
pngDimensions( generatedPath, width, height ),
362 "Generated file is not a valid PNG: " + generatedPath );
363 BOOST_CHECK_MESSAGE( width >= 3500 && width <= 3516,
364 "Default dpi should be 300; got width " << width );
371 BOOST_REQUIRE_MESSAGE( Start(), LastError() );
375 wxFileName boardPath( testDataDir, wxS(
"basic_test.kicad_pcb" ) );
377 kiapi::common::types::DocumentSpecifier document;
379 BOOST_REQUIRE_MESSAGE( Client().OpenDocument( boardPath.GetFullPath(), &document ),
380 "OpenDocument failed: " + Client().LastError() );
383 wxString outputDir = tempDir.
CreateChildDirStr(
"drill" ) + wxFileName::GetPathSeparator();
385 kiapi::board::jobs::RunBoardJobExportDrill request;
386 *request.mutable_job_settings()->mutable_document() = document;
387 request.mutable_job_settings()->set_output_path( outputDir.ToUTF8().data() );
388 request.set_format( kiapi::board::jobs::DF_EXCELLON );
390 kiapi::common::types::RunJobResponse response;
391 BOOST_REQUIRE_MESSAGE( Client().RunJob( request, &response ),
"RunJob failed: " + Client().LastError() );
393 BOOST_REQUIRE_MESSAGE( response.status() == kiapi::common::types::JS_SUCCESS,
394 "Job failed: " + wxString::FromUTF8( response.message() ) );
396 BOOST_REQUIRE_MESSAGE( response.output_path_size() > 0,
"Job returned no output paths" );
397 wxString generatedDrillPath;
399 for(
int i = 0; i < response.output_path_size(); ++i )
401 wxString outputPath = wxString::FromUTF8( response.output_path( i ) );
403 if( outputPath.EndsWith( wxS(
".drl" ) ) )
405 generatedDrillPath = outputPath;
410 BOOST_REQUIRE_MESSAGE( !generatedDrillPath.IsEmpty(),
"No .drl file found in job output" );
411 BOOST_REQUIRE_MESSAGE( wxFileName::FileExists( generatedDrillPath ),
412 "Generated drill file does not exist: " + generatedDrillPath );
414 wxString goldenPath = testDataDir + wxS(
"basic_test_excellon_inches.drl" );
415 BOOST_CHECK_MESSAGE(
textFilesMatch( goldenPath, generatedDrillPath, 5 ),
416 "Drill output does not match golden file" );
422 BOOST_REQUIRE_MESSAGE( Start(), LastError() );
425 wxS(
"issue24735.kicad_pcb" ) );
427 kiapi::common::types::DocumentSpecifier document;
429 BOOST_REQUIRE_MESSAGE( Client().OpenDocument( boardPath.GetFullPath(), &document ),
430 "OpenDocument failed: " + Client().LastError() );
435 kiapi::board::jobs::RunBoardJobExportODB request;
436 *request.mutable_job_settings()->mutable_document() = document;
437 request.mutable_job_settings()->set_output_path( target.GetFullPath().ToUTF8().data() );
438 request.set_units( kiapi::common::types::U_MM );
439 request.set_compression( kiapi::board::jobs::ODBC_NONE );
440 request.add_variant_names(
"var1" );
441 request.add_variant_names(
"var2" );
442 request.set_variant_packaging( kiapi::board::jobs::ODBVP_COMBINED );
444 kiapi::common::types::RunJobResponse response;
445 BOOST_REQUIRE_MESSAGE( Client().RunJob( request, &response ),
"RunJob failed: " + Client().LastError() );
446 BOOST_REQUIRE_MESSAGE( response.status() == kiapi::common::types::JS_SUCCESS,
447 "Job failed: " + wxString::FromUTF8( response.message() ) );
449 auto hasLine = [](
const wxString& aPackage,
const wxString& aDir,
const std::string& aLine )
451 wxFileName file( aPackage + wxFileName::GetPathSeparator() + aDir, wxS(
"attrlist" ) );
452 std::ifstream input(
ToFsPath( file.GetFullPath() ) );
455 while( std::getline( input, line ) )
464 BOOST_REQUIRE_EQUAL( response.output_path_size(), 1 );
465 wxString
combined = wxString::FromUTF8( response.output_path( 0 ) );
466 BOOST_REQUIRE_MESSAGE( wxFileName::DirExists(
combined ),
"Missing reported output " +
combined );
467 BOOST_CHECK_MESSAGE( wxFileName::DirName(
combined ).SameAs( wxFileName::DirName( target.GetFullPath() ) ),
468 "Combined output ignored the requested path: " +
combined );
469 BOOST_CHECK( hasLine(
combined, wxS(
"misc" ),
".variant_list=var1:var2" ) );
470 BOOST_CHECK( hasLine(
combined, wxS(
"steps/pcb" ),
".current_variant=var1" ) );
473 wxFileName separateTarget( tempDir.
CreateChildDirStr(
"odb_separate" ), wxS(
"separate" ) );
474 request.mutable_job_settings()->set_output_path( separateTarget.GetFullPath().ToUTF8().data() );
475 request.set_variant_packaging( kiapi::board::jobs::ODBVP_SEPARATE );
478 BOOST_REQUIRE_MESSAGE( Client().RunJob( request, &response ),
"RunJob failed: " + Client().LastError() );
479 BOOST_REQUIRE_MESSAGE( response.status() == kiapi::common::types::JS_SUCCESS,
480 "Separate job failed: " + wxString::FromUTF8( response.message() ) );
481 BOOST_REQUIRE_EQUAL( response.output_path_size(), 2 );
482 std::set<std::string> currentVariants;
484 for(
int i = 0; i < response.output_path_size(); ++i )
486 wxString
package = wxString::FromUTF8( response.output_path( i ) );
487 BOOST_REQUIRE_MESSAGE( wxFileName::DirExists( package ),
"Missing reported output " + package );
488 BOOST_CHECK_MESSAGE( package.StartsWith( separateTarget.GetFullPath() + wxS(
"-" ) ),
489 "Separate output ignored the requested path: " + package );
491 for(
const std::string variant : {
"var1",
"var2" } )
493 if( hasLine( package, wxS(
"steps/pcb" ),
".current_variant=" + variant ) )
494 currentVariants.insert( variant );
498 BOOST_CHECK( currentVariants == std::set<std::string>( {
"var1",
"var2" } ) );
504 BOOST_REQUIRE_MESSAGE( Start(), LastError() );
506 wxString testDataDir =
509 wxFileName boardPath( testDataDir, wxS(
"ZoneFill-4.0.7.kicad_pcb" ) );
511 kiapi::common::types::DocumentSpecifier document;
513 BOOST_REQUIRE_MESSAGE( Client().OpenDocument( boardPath.GetFullPath(), &document ),
514 "OpenDocument failed: " + Client().LastError() );
520 wxString outputDir = tempDir.
CreateChildDirStr(
"multi" ) + wxFileName::GetPathSeparator();
522 kiapi::board::jobs::RunBoardJobExportPng request;
523 *request.mutable_job_settings()->mutable_document() = document;
524 request.mutable_job_settings()->set_output_path( outputDir.ToUTF8().data() );
525 request.mutable_plot_settings()->add_layers( kiapi::board::types::BL_F_Cu );
526 request.mutable_plot_settings()->set_black_and_white(
true );
527 request.set_page_mode( kiapi::board::jobs::BJPM_EACH_LAYER_OWN_FILE );
528 request.set_dpi( 150 );
530 kiapi::common::types::RunJobResponse response;
531 BOOST_REQUIRE_MESSAGE( Client().RunJob( request, &response ),
532 "RunJob failed: " + Client().LastError() );
534 BOOST_REQUIRE_MESSAGE( response.status() == kiapi::common::types::JS_SUCCESS,
535 "Job failed: " + wxString::FromUTF8( response.message() ) );
536 BOOST_REQUIRE_MESSAGE( response.output_path_size() > 0,
"Job returned no output paths" );
538 wxString generatedPath = wxString::FromUTF8( response.output_path( 0 ) );
539 BOOST_REQUIRE_MESSAGE( wxFileName::FileExists( generatedPath ),
540 "Generated PNG does not exist: " + generatedPath );
542 uint32_t width = 0, height = 0;
543 BOOST_REQUIRE_MESSAGE(
pngDimensions( generatedPath, width, height ),
544 "Generated file is not a valid PNG: " + generatedPath );
545 BOOST_CHECK_MESSAGE( width >= 1750 && width <= 1758,
546 "Unexpected PNG width " << width <<
" for 150dpi A4 landscape" );
551 wxFileName outputPath( tempDir.
ChildPathStr(
"single.png" ) );
553 kiapi::board::jobs::RunBoardJobExportPng request;
554 *request.mutable_job_settings()->mutable_document() = document;
555 request.mutable_job_settings()->set_output_path( outputPath.GetFullPath().ToUTF8().data() );
556 request.mutable_plot_settings()->add_layers( kiapi::board::types::BL_F_Cu );
557 request.mutable_plot_settings()->add_layers( kiapi::board::types::BL_F_SilkS );
558 request.mutable_plot_settings()->set_black_and_white(
true );
559 request.set_page_mode( kiapi::board::jobs::BJPM_ALL_LAYERS_ONE_PAGE );
560 request.set_dpi( 300 );
562 kiapi::common::types::RunJobResponse response;
563 BOOST_REQUIRE_MESSAGE( Client().RunJob( request, &response ),
564 "Single-mode RunJob failed: " + Client().LastError() );
566 BOOST_REQUIRE_MESSAGE( response.status() == kiapi::common::types::JS_SUCCESS,
567 "Single-mode job failed: " + wxString::FromUTF8( response.message() ) );
568 BOOST_REQUIRE_MESSAGE( response.output_path_size() > 0,
569 "Single-mode job returned no output paths" );
571 wxString generatedPath = wxString::FromUTF8( response.output_path( 0 ) );
572 BOOST_REQUIRE_MESSAGE( wxFileName::FileExists( generatedPath ),
573 "Generated PNG does not exist: " + generatedPath );
574 BOOST_CHECK_MESSAGE( generatedPath == outputPath.GetFullPath(),
575 "Single-mode output path not honored: " + generatedPath );
577 uint32_t width = 0, height = 0;
578 BOOST_REQUIRE_MESSAGE(
pngDimensions( generatedPath, width, height ),
579 "Generated file is not a valid PNG: " + generatedPath );
580 BOOST_CHECK_MESSAGE( width >= 3500 && width <= 3516,
581 "Unexpected PNG width " << width <<
" for 300dpi A4 landscape" );
588 BOOST_REQUIRE_MESSAGE( Start(), LastError() );
592 wxFileName schPath( testDataDir, wxS(
"basic_test.kicad_sch" ) );
594 kiapi::common::types::DocumentSpecifier document;
596 BOOST_REQUIRE_MESSAGE(
597 Client().OpenDocument( schPath.GetFullPath(), kiapi::common::types::DOCTYPE_SCHEMATIC, &document ),
598 "OpenDocument failed: " + Client().LastError() );
601 wxFileName outputPath( tempDir.
ChildPathStr(
"netlist.cadstar" ) );
603 kiapi::schematic::jobs::RunSchematicJobExportNetlist request;
604 *request.mutable_job_settings()->mutable_document() = document;
605 request.mutable_job_settings()->set_output_path( outputPath.GetFullPath().ToUTF8().data() );
606 request.set_format( kiapi::schematic::jobs::SNF_CADSTAR );
608 kiapi::common::types::RunJobResponse response;
609 BOOST_REQUIRE_MESSAGE( Client().RunJob( request, &response ),
"RunJob failed: " + Client().LastError() );
611 BOOST_REQUIRE_MESSAGE( response.status() == kiapi::common::types::JS_SUCCESS,
612 "Job failed: " + wxString::FromUTF8( response.message() ) );
614 BOOST_REQUIRE_MESSAGE( response.output_path_size() > 0,
"Job returned no output paths" );
616 wxString generatedPath = wxString::FromUTF8( response.output_path( 0 ) );
617 BOOST_REQUIRE_MESSAGE( wxFileName::FileExists( generatedPath ),
618 "Generated netlist does not exist: " + generatedPath );
621 wxString goldenPath = testDataDir + wxS(
"basic_test.netlist.cadstar" );
622 BOOST_CHECK_MESSAGE(
textFilesMatch( goldenPath, generatedPath, 3 ),
"Netlist output does not match golden file" );
628 BOOST_REQUIRE_MESSAGE( Start(), LastError() );
632 wxFileName schPath( testDataDir, wxS(
"variants.kicad_sch" ) );
634 kiapi::common::types::DocumentSpecifier document;
636 BOOST_REQUIRE_MESSAGE(
637 Client().OpenDocument( schPath.GetFullPath(), kiapi::common::types::DOCTYPE_SCHEMATIC, &document ),
638 "OpenDocument failed: " + Client().LastError() );
641 wxFileName outputPath( tempDir.
ChildPathStr(
"bom.csv" ) );
643 kiapi::schematic::jobs::RunSchematicJobExportBOM request;
644 *request.mutable_job_settings()->mutable_document() = document;
645 request.mutable_job_settings()->set_output_path( outputPath.GetFullPath().ToUTF8().data() );
646 request.set_exclude_dnp(
true );
648 request.mutable_format()->set_preset_name(
"CSV" );
650 auto* refField = request.mutable_fields()->add_fields();
651 refField->set_name(
"Reference" );
652 refField->set_label(
"Refs" );
653 refField->set_group_by(
false );
655 auto* valField = request.mutable_fields()->add_fields();
656 valField->set_name(
"Value" );
657 valField->set_label(
"Value" );
658 valField->set_group_by(
false );
660 kiapi::common::types::RunJobResponse response;
661 BOOST_REQUIRE_MESSAGE( Client().RunJob( request, &response ),
"RunJob failed: " + Client().LastError() );
663 BOOST_REQUIRE_MESSAGE( response.status() == kiapi::common::types::JS_SUCCESS,
664 "Job failed: " + wxString::FromUTF8( response.message() ) );
666 BOOST_REQUIRE_MESSAGE( response.output_path_size() > 0,
"Job returned no output paths" );
668 wxString generatedPath = wxString::FromUTF8( response.output_path( 0 ) );
669 BOOST_REQUIRE_MESSAGE( wxFileName::FileExists( generatedPath ),
"Generated BOM does not exist: " + generatedPath );
671 wxString goldenPath = testDataDir + wxS(
"variants_default.bom.csv" );
672 BOOST_CHECK_MESSAGE(
textFilesMatch( goldenPath, generatedPath, 0 ),
"BOM output does not match golden file" );
674 request.mutable_format()->clear_preset_name();
675 request.mutable_format()->set_field_delimiter(
"," );
676 request.mutable_format()->set_string_delimiter(
"\"" );
677 request.mutable_format()->set_ref_delimiter(
"," );
678 request.mutable_format()->set_ref_range_delimiter(
"" );
679 request.mutable_format()->set_include_byte_order_mark(
true );
682 BOOST_REQUIRE_MESSAGE( Client().RunJob( request, &response ),
683 "BOM job with byte order mark failed: " + Client().LastError() );
685 BOOST_REQUIRE_MESSAGE( response.status() == kiapi::common::types::JS_SUCCESS,
686 "BOM job with byte order mark failed: " + wxString::FromUTF8( response.message() ) );
687 BOOST_REQUIRE_MESSAGE( response.output_path_size() > 0,
"BOM job with byte order mark returned no output paths" );
689 generatedPath = wxString::FromUTF8( response.output_path( 0 ) );
690 std::ifstream generatedStream( generatedPath.ToStdString(), std::ios::binary );
691 std::ifstream goldenStream( goldenPath.ToStdString(), std::ios::binary );
695 std::ostringstream generatedContents;
696 std::ostringstream goldenContents;
697 generatedContents << generatedStream.rdbuf();
698 goldenContents << goldenStream.rdbuf();
700 const std::string utf8ByteOrderMark(
"\xEF\xBB\xBF", 3 );
701 const std::string bom = generatedContents.str();
702 BOOST_REQUIRE_GE( bom.size(), utf8ByteOrderMark.size() );
703 BOOST_CHECK_EQUAL( bom.substr( 0, utf8ByteOrderMark.size() ), utf8ByteOrderMark );
704 BOOST_CHECK_EQUAL( bom.substr( utf8ByteOrderMark.size() ), goldenContents.str() );
706 generatedStream.close();
707 goldenStream.close();
713 BOOST_REQUIRE_MESSAGE( Start(), LastError() );
717 wxFileName boardPath( testDataDir, wxS(
"basic_test.kicad_pcb" ) );
719 kiapi::common::types::DocumentSpecifier document;
721 BOOST_REQUIRE_MESSAGE( Client().OpenDocument( boardPath.GetFullPath(), &document ),
722 "OpenDocument failed: " + Client().LastError() );
725 wxFileName outputPath( tempDir.
ChildPathStr(
"basic_test.dsn" ) );
727 kiapi::board::jobs::RunBoardJobExportSpecctraDsn request;
728 *request.mutable_job_settings()->mutable_document() = document;
729 request.mutable_job_settings()->set_output_path( outputPath.GetFullPath().ToUTF8().data() );
731 kiapi::common::types::RunJobResponse response;
732 BOOST_REQUIRE_MESSAGE( Client().RunJob( request, &response ),
"RunJob failed: " + Client().LastError() );
734 BOOST_REQUIRE_MESSAGE( response.status() == kiapi::common::types::JS_SUCCESS,
735 "Job failed: " + wxString::FromUTF8( response.message() ) );
736 BOOST_REQUIRE_MESSAGE( response.output_path_size() > 0,
"Job returned no output paths" );
738 wxString generatedPath = wxString::FromUTF8( response.output_path( 0 ) );
739 BOOST_REQUIRE_MESSAGE( wxFileName::FileExists( generatedPath ),
"Generated DSN does not exist: " + generatedPath );
740 BOOST_CHECK_MESSAGE( generatedPath == outputPath.GetFullPath(),
"Output path not honored: " + generatedPath );
743 BOOST_CHECK( dsn.find(
"(unit um)" ) != std::string::npos );
744 BOOST_CHECK( dsn.find(
"(network" ) != std::string::npos );
750 BOOST_REQUIRE_MESSAGE( Start(), LastError() );
754 wxFileName boardPath( testDataDir, wxS(
"basic_test.kicad_pcb" ) );
756 kiapi::common::types::DocumentSpecifier document;
758 BOOST_REQUIRE_MESSAGE( Client().OpenDocument( boardPath.GetFullPath(), &document ),
759 "OpenDocument failed: " + Client().LastError() );
763 kiapi::board::commands::ImportSpecctraSession request;
764 *request.mutable_board() = document;
765 request.set_session_path( wxFileName( wxS(
"/nonexistent/missing.ses" ) ).GetFullPath().ToUTF8().data() );
767 kiapi::common::ApiResponse response;
768 BOOST_CHECK_MESSAGE( Client().SendCommand( request, &response ),
769 "SendCommand failed: " + Client().LastError() );
776 wxFileName sesPath( tempDir.
ChildPathStr(
"malformed.ses" ) );
779 BOOST_REQUIRE( badFile.Create( sesPath.GetFullPath(),
true ) );
780 badFile.Write(
"(session test.ses\n (base_design test.dsn)\n", 45 );
783 kiapi::board::commands::ImportSpecctraSession request;
784 *request.mutable_board() = document;
785 request.set_session_path( sesPath.GetFullPath().ToUTF8().data() );
787 kiapi::common::ApiResponse response;
788 BOOST_CHECK_MESSAGE( Client().SendCommand( request, &response ),
"SendCommand failed" );
790 BOOST_CHECK( !response.status().error_message().empty() );
797 BOOST_REQUIRE_MESSAGE( Start(), LastError() );
801 wxFileName boardPath( testDataDir, wxS(
"basic_test.kicad_pcb" ) );
803 kiapi::common::types::DocumentSpecifier document;
805 BOOST_REQUIRE_MESSAGE( Client().OpenDocument( boardPath.GetFullPath(), &document ),
806 "OpenDocument failed: " + Client().LastError() );
809 BOOST_REQUIRE_MESSAGE( Client().GetFootprintByReference( document, wxS(
"J1" ), &footprint ),
810 "GetFootprintByReference failed: " + Client().LastError() );
815 wxS(
"basic_test" ), wxS(
"ses" ) );
817 BOOST_REQUIRE_MESSAGE( wxFileName::FileExists( sesPath.GetFullPath() ),
818 "Session fixture is missing: " + sesPath.GetFullPath() );
820 kiapi::board::commands::ImportSpecctraSession request;
821 *request.mutable_board() = document;
822 request.set_session_path( sesPath.GetFullPath().ToUTF8().data() );
824 kiapi::common::ApiResponse response;
825 BOOST_REQUIRE_MESSAGE( Client().SendCommand( request, &response ),
826 "Session import SendCommand failed: " + Client().LastError() );
829 kiapi::board::commands::ImportSpecctraSessionResponse importResponse;
830 BOOST_REQUIRE_MESSAGE( response.message().UnpackTo( &importResponse ),
831 "Failed to unpack ImportSpecctraSessionResponse" );
833 BOOST_CHECK_MESSAGE( importResponse.report().empty(),
"Unexpected importer report: "
834 + importResponse.report() );
837 int traceCountAfter = 0;
838 BOOST_REQUIRE_MESSAGE( Client().GetItemsCount( document, kiapi::common::types::KOT_PCB_TRACE, &traceCountAfter ),
839 "GetItems (traces after import) failed: " + Client().LastError() );
844 BOOST_REQUIRE_MESSAGE( Client().GetFootprintByReference( document, wxS(
"J1" ), &after ),
845 "GetFootprintByReference after import failed: " + Client().LastError() );
846 BOOST_CHECK( after.
GetPosition() != positionBefore );
BOOST_CHECK_EQUAL(result, "25.4")