KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_issue25074_odb_knockout_textbox.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, see <https://www.gnu.org/licenses/>.
18 */
19
20#include <filesystem>
21#include <fstream>
22#include <memory>
23
26#include <boost/test/unit_test.hpp>
27
28#include <base_units.h>
29#include <board.h>
30#include <kiid.h>
31#include <pcb_shape.h>
32#include <pcb_textbox.h>
35#include <core/utf8.h>
36
37namespace fs = std::filesystem;
38
39
40// A knockout reaches the feature file as filled polygons, so surface records prove it was emitted.
41static int countSurfaceRecords( const fs::path& aFeaturesFile )
42{
43 int count = 0;
44 std::ifstream stream( aFeaturesFile );
45 std::string line;
46
47 while( std::getline( stream, line ) )
48 {
49 if( line.rfind( "S ", 0 ) == 0 )
50 count++;
51 }
52
53 return count;
54}
55
56
57// A knockout text box was cast to PCB_TEXT before being turned into polygons. The two share no
58// base below EDA_TEXT, so the export read the wrong subobject and died.
59BOOST_AUTO_TEST_CASE( OdbKnockoutTextboxExport )
60{
61 SETTINGS_MANAGER settingsManager;
62 std::unique_ptr<BOARD> board = KI_TEST::ReadBoardFromFileOrStream(
63 KI_TEST::GetPcbnewTestDataDir() + "issue25074/knockout_textbox.kicad_pcb" );
64
65 BOOST_REQUIRE( board );
66
67 // The crash needed a knockout text box specifically, so fail loudly if the
68 // fixture ever loses the flag.
69 const PCB_TEXTBOX* textbox = nullptr;
70
71 for( const BOARD_ITEM* item : board->Drawings() )
72 {
73 if( item->Type() == PCB_TEXTBOX_T )
74 textbox = static_cast<const PCB_TEXTBOX*>( item );
75 }
76
77 BOOST_REQUIRE( textbox );
78 BOOST_REQUIRE( textbox->IsKnockout() );
79
80 const fs::path outDir =
81 fs::temp_directory_path() / ( "kicad_qa_odb_knockout_25074_" + KIID().AsString().ToStdString() );
82
83 BOOST_REQUIRE( fs::create_directory( outDir ) );
84
85 PCB_IO_ODBPP odbExporter;
86 std::map<std::string, UTF8> props;
87 props["units"] = "mm";
88 props["sigfig"] = "6";
89
90 BOOST_REQUIRE_NO_THROW( odbExporter.SaveBoard( outDir.string(), *board, &props ) );
91
92 const fs::path features = outDir / "steps" / "pcb" / "layers" / "b.silkscreen" / "features";
93
94 BOOST_REQUIRE_MESSAGE( fs::exists( features ), "ODB++ export produced no back silkscreen features file" );
95
96 BOOST_CHECK_MESSAGE( countSurfaceRecords( features ) > 0,
97 "Knockout text box produced no surface features on the back silkscreen" );
98
99 fs::remove_all( outDir );
100}
General utilities for PCB file IO for QA programs.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
Definition board_item.h:84
virtual bool IsKnockout() const
Definition board_item.h:413
Definition kiid.h:46
wxString AsString() const
Definition kiid.cpp:264
void SaveBoard(const wxString &aFileName, BOARD &aBoard, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Write aBoard to a storage file in a format that this PCB_IO implementation knows about or it can be u...
std::string GetPcbnewTestDataDir()
Utility which returns a path to the data directory where the test board files are stored.
std::unique_ptr< BOARD > ReadBoardFromFileOrStream(const std::string &aFilename, std::istream &aFallback)
Read a board from a file, or another stream, as appropriate.
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_CASE(OdbKnockoutTextboxExport)
static int countSurfaceRecords(const fs::path &aFeaturesFile)
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
Definition typeinfo.h:85