40bool textFilesMatch(
const wxString& aGoldenPath,
const wxString& aGeneratedPath,
int aSkipLines )
42 std::ifstream goldenStream( aGoldenPath.ToStdString() );
43 std::ifstream generatedStream( aGeneratedPath.ToStdString() );
45 if( !goldenStream.is_open() )
51 if( !generatedStream.is_open() )
57 std::string goldenLine, generatedLine;
59 for(
int i = 0; i < aSkipLines; ++i )
61 std::getline( goldenStream, goldenLine );
62 std::getline( generatedStream, generatedLine );
65 int lineNum = aSkipLines + 1;
67 while( std::getline( goldenStream, goldenLine ) )
69 if( !std::getline( generatedStream, generatedLine ) )
75 if( goldenLine != generatedLine )
78 <<
" golden: " << goldenLine <<
"\n"
79 <<
" generated: " << generatedLine );
86 if( std::getline( generatedStream, generatedLine ) )
101 BOOST_REQUIRE_MESSAGE( Start(), LastError() );
103 wxString testDataDir =
106 wxFileName boardPath( testDataDir, wxS(
"ZoneFill-4.0.7.kicad_pcb" ) );
108 kiapi::common::types::DocumentSpecifier document;
110 BOOST_REQUIRE_MESSAGE( Client().OpenDocument( boardPath.GetFullPath(), &document ),
111 "OpenDocument failed: " + Client().LastError() );
113 wxFileName outputPath = wxFileName::CreateTempFileName( wxS(
"api_job_svg_" ) );
114 outputPath.SetExt( wxS(
"svg" ) );
116 kiapi::board::jobs::RunBoardJobExportSvg request;
117 *request.mutable_job_settings()->mutable_document() = document;
118 request.mutable_job_settings()->set_output_path( outputPath.GetFullPath().ToUTF8().data() );
120 request.mutable_plot_settings()->add_layers( kiapi::board::types::BL_F_Cu );
121 request.mutable_plot_settings()->set_black_and_white(
true );
122 request.mutable_plot_settings()->set_plot_drawing_sheet(
false );
123 request.mutable_plot_settings()->set_drill_marks( kiapi::board::jobs::PDM_FULL );
124 request.set_page_mode( kiapi::board::jobs::BJPM_EACH_LAYER_OWN_FILE );
126 kiapi::common::types::RunJobResponse response;
127 BOOST_REQUIRE_MESSAGE( Client().RunJob( request, &response ),
"RunJob failed: " + Client().LastError() );
129 BOOST_REQUIRE_MESSAGE( response.status() == kiapi::common::types::JS_SUCCESS,
130 "Job failed: " + wxString::FromUTF8( response.message() ) );
132 BOOST_REQUIRE_MESSAGE( response.output_path_size() > 0,
"Job returned no output paths" );
134 wxString generatedPath = wxString::FromUTF8( response.output_path( 0 ) );
135 BOOST_REQUIRE_MESSAGE( wxFileName::FileExists( generatedPath ),
"Generated SVG does not exist: " + generatedPath );
138 constexpr long target_size = 41839;
139 wxFileName generatedFn( generatedPath );
140 BOOST_CHECK_LT(
std::abs( target_size -
static_cast<long>( generatedFn.GetSize().GetValue() ) ), 10 );
142 if( wxFileName::FileExists( generatedPath ) )
143 wxRemoveFile( generatedPath );
145 if( wxFileName::FileExists( outputPath.GetFullPath() ) )
146 wxRemoveFile( outputPath.GetFullPath() );
152 BOOST_REQUIRE_MESSAGE( Start(), LastError() );
156 wxFileName boardPath( testDataDir, wxS(
"basic_test.kicad_pcb" ) );
158 kiapi::common::types::DocumentSpecifier document;
160 BOOST_REQUIRE_MESSAGE( Client().OpenDocument( boardPath.GetFullPath(), &document ),
161 "OpenDocument failed: " + Client().LastError() );
163 wxString outputDir = wxFileName::GetTempDir() + wxFileName::GetPathSeparator() + wxS(
"api_job_drill_" )
164 + wxString::Format(
"%ld", wxGetProcessId() ) + wxFileName::GetPathSeparator();
165 wxFileName::Mkdir( outputDir, wxS_DIR_DEFAULT, wxPATH_MKDIR_FULL );
167 kiapi::board::jobs::RunBoardJobExportDrill request;
168 *request.mutable_job_settings()->mutable_document() = document;
169 request.mutable_job_settings()->set_output_path( outputDir.ToUTF8().data() );
170 request.set_format( kiapi::board::jobs::DF_EXCELLON );
172 kiapi::common::types::RunJobResponse response;
173 BOOST_REQUIRE_MESSAGE( Client().RunJob( request, &response ),
"RunJob failed: " + Client().LastError() );
175 BOOST_REQUIRE_MESSAGE( response.status() == kiapi::common::types::JS_SUCCESS,
176 "Job failed: " + wxString::FromUTF8( response.message() ) );
178 BOOST_REQUIRE_MESSAGE( response.output_path_size() > 0,
"Job returned no output paths" );
182 wxString generatedOutputDir = wxString::FromUTF8( response.output_path( 0 ) );
183 wxString generatedDrillPath;
185 if( !generatedOutputDir.IsEmpty() )
187 wxDir dir( generatedOutputDir );
190 if( dir.IsOpened() && dir.GetFirst( &filename, wxS(
"*.drl" ), wxDIR_FILES ) )
192 wxFileName fn( generatedOutputDir, filename );
193 generatedDrillPath = fn.GetFullPath();
197 BOOST_REQUIRE_MESSAGE( !generatedDrillPath.IsEmpty(),
"No .drl file found in job output" );
198 BOOST_REQUIRE_MESSAGE( wxFileName::FileExists( generatedDrillPath ),
199 "Generated drill file does not exist: " + generatedDrillPath );
201 wxString goldenPath = testDataDir + wxS(
"basic_test_excellon_inches.drl" );
202 BOOST_CHECK_MESSAGE(
textFilesMatch( goldenPath, generatedDrillPath, 5 ),
203 "Drill output does not match golden file" );
205 wxFileName::Rmdir( outputDir, wxPATH_RMDIR_RECURSIVE );
211 BOOST_REQUIRE_MESSAGE( Start(), LastError() );
215 wxFileName schPath( testDataDir, wxS(
"basic_test.kicad_sch" ) );
217 kiapi::common::types::DocumentSpecifier document;
219 BOOST_REQUIRE_MESSAGE(
220 Client().OpenDocument( schPath.GetFullPath(), kiapi::common::types::DOCTYPE_SCHEMATIC, &document ),
221 "OpenDocument failed: " + Client().LastError() );
223 wxFileName outputPath = wxFileName::CreateTempFileName( wxS(
"api_job_netlist_" ) );
224 outputPath.SetExt( wxS(
"cadstar" ) );
226 kiapi::schematic::jobs::RunSchematicJobExportNetlist request;
227 *request.mutable_job_settings()->mutable_document() = document;
228 request.mutable_job_settings()->set_output_path( outputPath.GetFullPath().ToUTF8().data() );
229 request.set_format( kiapi::schematic::jobs::SNF_CADSTAR );
231 kiapi::common::types::RunJobResponse response;
232 BOOST_REQUIRE_MESSAGE( Client().RunJob( request, &response ),
"RunJob failed: " + Client().LastError() );
234 BOOST_REQUIRE_MESSAGE( response.status() == kiapi::common::types::JS_SUCCESS,
235 "Job failed: " + wxString::FromUTF8( response.message() ) );
237 BOOST_REQUIRE_MESSAGE( response.output_path_size() > 0,
"Job returned no output paths" );
239 wxString generatedPath = wxString::FromUTF8( response.output_path( 0 ) );
240 BOOST_REQUIRE_MESSAGE( wxFileName::FileExists( generatedPath ),
241 "Generated netlist does not exist: " + generatedPath );
244 wxString goldenPath = testDataDir + wxS(
"basic_test.netlist.cadstar" );
245 BOOST_CHECK_MESSAGE(
textFilesMatch( goldenPath, generatedPath, 3 ),
"Netlist output does not match golden file" );
248 if( wxFileName::FileExists( generatedPath ) )
249 wxRemoveFile( generatedPath );
251 if( wxFileName::FileExists( outputPath.GetFullPath() ) )
252 wxRemoveFile( outputPath.GetFullPath() );
258 BOOST_REQUIRE_MESSAGE( Start(), LastError() );
262 wxFileName schPath( testDataDir, wxS(
"variants.kicad_sch" ) );
264 kiapi::common::types::DocumentSpecifier document;
266 BOOST_REQUIRE_MESSAGE(
267 Client().OpenDocument( schPath.GetFullPath(), kiapi::common::types::DOCTYPE_SCHEMATIC, &document ),
268 "OpenDocument failed: " + Client().LastError() );
270 wxFileName outputPath = wxFileName::CreateTempFileName( wxS(
"api_job_bom_" ) );
271 outputPath.SetExt( wxS(
"csv" ) );
273 kiapi::schematic::jobs::RunSchematicJobExportBOM request;
274 *request.mutable_job_settings()->mutable_document() = document;
275 request.mutable_job_settings()->set_output_path( outputPath.GetFullPath().ToUTF8().data() );
276 request.set_exclude_dnp(
true );
278 request.mutable_format()->set_preset_name(
"CSV" );
280 auto* refField = request.mutable_fields()->add_fields();
281 refField->set_name(
"Reference" );
282 refField->set_label(
"Refs" );
283 refField->set_group_by(
false );
285 auto* valField = request.mutable_fields()->add_fields();
286 valField->set_name(
"Value" );
287 valField->set_label(
"Value" );
288 valField->set_group_by(
false );
290 kiapi::common::types::RunJobResponse response;
291 BOOST_REQUIRE_MESSAGE( Client().RunJob( request, &response ),
"RunJob failed: " + Client().LastError() );
293 BOOST_REQUIRE_MESSAGE( response.status() == kiapi::common::types::JS_SUCCESS,
294 "Job failed: " + wxString::FromUTF8( response.message() ) );
296 BOOST_REQUIRE_MESSAGE( response.output_path_size() > 0,
"Job returned no output paths" );
298 wxString generatedPath = wxString::FromUTF8( response.output_path( 0 ) );
299 BOOST_REQUIRE_MESSAGE( wxFileName::FileExists( generatedPath ),
"Generated BOM does not exist: " + generatedPath );
301 wxString goldenPath = testDataDir + wxS(
"variants_default.bom.csv" );
302 BOOST_CHECK_MESSAGE(
textFilesMatch( goldenPath, generatedPath, 0 ),
"BOM output does not match golden file" );
304 request.mutable_format()->clear_preset_name();
305 request.mutable_format()->set_field_delimiter(
"," );
306 request.mutable_format()->set_string_delimiter(
"\"" );
307 request.mutable_format()->set_ref_delimiter(
"," );
308 request.mutable_format()->set_ref_range_delimiter(
"" );
309 request.mutable_format()->set_include_byte_order_mark(
true );
312 BOOST_REQUIRE_MESSAGE( Client().RunJob( request, &response ),
313 "BOM job with byte order mark failed: " + Client().LastError() );
315 BOOST_REQUIRE_MESSAGE( response.status() == kiapi::common::types::JS_SUCCESS,
316 "BOM job with byte order mark failed: " + wxString::FromUTF8( response.message() ) );
317 BOOST_REQUIRE_MESSAGE( response.output_path_size() > 0,
"BOM job with byte order mark returned no output paths" );
319 generatedPath = wxString::FromUTF8( response.output_path( 0 ) );
320 std::ifstream generatedStream( generatedPath.ToStdString(), std::ios::binary );
321 std::ifstream goldenStream( goldenPath.ToStdString(), std::ios::binary );
325 std::ostringstream generatedContents;
326 std::ostringstream goldenContents;
327 generatedContents << generatedStream.rdbuf();
328 goldenContents << goldenStream.rdbuf();
330 const std::string utf8ByteOrderMark(
"\xEF\xBB\xBF", 3 );
331 const std::string bom = generatedContents.str();
332 BOOST_REQUIRE_GE( bom.size(), utf8ByteOrderMark.size() );
333 BOOST_CHECK_EQUAL( bom.substr( 0, utf8ByteOrderMark.size() ), utf8ByteOrderMark );
334 BOOST_CHECK_EQUAL( bom.substr( utf8ByteOrderMark.size() ), goldenContents.str() );
336 generatedStream.close();
337 goldenStream.close();
339 if( wxFileName::FileExists( generatedPath ) )
340 wxRemoveFile( generatedPath );
342 if( wxFileName::FileExists( outputPath.GetFullPath() ) )
343 wxRemoveFile( outputPath.GetFullPath() );
BOOST_CHECK_EQUAL(result, "25.4")