KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_eagle_board_import.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, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19 * or you may search the http://www.gnu.org website for the version 2 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
28
32
34
35#include <board.h>
36#include <footprint.h>
37#include <netinfo.h>
38#include <pcb_text.h>
39#include <pcb_track.h>
40
41#include <map>
42#include <wx/filename.h>
43
44
49
50
51BOOST_FIXTURE_TEST_SUITE( EagleBoardImport, EAGLE_BOARD_IMPORT_FIXTURE )
52
53
54
64BOOST_AUTO_TEST_CASE( ViaNetAssignment )
65{
66 std::string dataPath = KI_TEST::GetPcbnewTestDataDir()
67 + "plugins/eagle/Adafruit-AHT20-PCB/"
68 "Adafruit AHT20 Temperature & Humidity.brd";
69
70 BOOST_REQUIRE_MESSAGE( wxFileName::FileExists( dataPath ),
71 "Test board file not found: " + dataPath );
72
73 PCB_IO_EAGLE eaglePlugin;
74 BOARD* rawBoard = nullptr;
75
76 try
77 {
78 rawBoard = eaglePlugin.LoadBoard( dataPath, nullptr, nullptr );
79 }
80 catch( const IO_ERROR& e )
81 {
82 BOOST_FAIL( "IO_ERROR loading Eagle board: " + e.What().ToStdString() );
83 }
84 catch( const std::exception& e )
85 {
86 BOOST_FAIL( std::string( "Exception loading Eagle board: " ) + e.what() );
87 }
88
89 std::unique_ptr<BOARD> board( rawBoard );
90
91 BOOST_REQUIRE( board );
92
93 // Collect vias grouped by net name
94 std::map<wxString, int> viasPerNet;
95
96 for( PCB_TRACK* track : board->Tracks() )
97 {
98 if( track->Type() == PCB_VIA_T )
99 {
100 NETINFO_ITEM* net = track->GetNet();
101 BOOST_REQUIRE( net );
102
103 wxString netName = net->GetNetname();
104 viasPerNet[netName]++;
105 }
106 }
107
108 // The Eagle board has vias on these nets (verified from the XML source)
109 BOOST_CHECK_GT( viasPerNet[wxT( "SDA" )], 0 );
110 BOOST_CHECK_GT( viasPerNet[wxT( "SCL" )], 0 );
111 BOOST_CHECK_GT( viasPerNet[wxT( "GND" )], 0 );
112 BOOST_CHECK_GT( viasPerNet[wxT( "VCC" )], 0 );
113 BOOST_CHECK_GT( viasPerNet[wxT( "VDD" )], 0 );
114
115 // Verify exact counts from the Eagle XML
116 BOOST_CHECK_EQUAL( viasPerNet[wxT( "SDA" )], 2 );
117 BOOST_CHECK_EQUAL( viasPerNet[wxT( "SCL" )], 2 );
118 BOOST_CHECK_EQUAL( viasPerNet[wxT( "GND" )], 3 );
119 BOOST_CHECK_EQUAL( viasPerNet[wxT( "VCC" )], 2 );
120 BOOST_CHECK_EQUAL( viasPerNet[wxT( "VDD" )], 2 );
121
122 // No via should be unassigned (net code 0)
123 BOOST_CHECK_EQUAL( viasPerNet[wxT( "" )], 0 );
124}
125
126
140BOOST_AUTO_TEST_CASE( TextJustification )
141{
142 std::string dataPath = KI_TEST::GetPcbnewTestDataDir()
143 + "plugins/eagle/test_eagle_23016/test_eagle.brd";
144
145 BOOST_REQUIRE_MESSAGE( wxFileName::FileExists( dataPath ),
146 "Test board file not found: " + dataPath );
147
148 PCB_IO_EAGLE eaglePlugin;
149 BOARD* rawBoard = nullptr;
150
151 try
152 {
153 rawBoard = eaglePlugin.LoadBoard( dataPath, nullptr, nullptr );
154 }
155 catch( const IO_ERROR& e )
156 {
157 BOOST_FAIL( "IO_ERROR loading Eagle board: " + e.What().ToStdString() );
158 }
159 catch( const std::exception& e )
160 {
161 BOOST_FAIL( std::string( "Exception loading Eagle board: " ) + e.what() );
162 }
163
164 std::unique_ptr<BOARD> board( rawBoard );
165
166 BOOST_REQUIRE( board );
167
168 // Board should have 13 elements from the Eagle file
169 BOOST_CHECK_EQUAL( board->Footprints().size(), 13 );
170
171 // Find the I2C connector footprints and verify reference text justification.
172 // I2C0 and I2C1 are smashed but have no NAME attribute, so their Reference text
173 // goes through the non-smashed orientFPText() code path. With the footprint at R90
174 // and the package text at 0 degrees, the combined angle is 180, triggering the
175 // justification flip to RIGHT/TOP. Before the fix, the dead code branch
176 // (abs(degrees) <= -180) would never fire and justification stayed at LEFT/BOTTOM.
177 for( FOOTPRINT* fp : board->Footprints() )
178 {
179 wxString ref = fp->GetReference();
180
181 if( ref == wxT( "I2C0" ) || ref == wxT( "I2C1" ) )
182 {
183 PCB_TEXT& refText = fp->Reference();
184
185 BOOST_CHECK_MESSAGE(
187 ref + " reference horizontal justification should be RIGHT, got "
188 + std::to_string( refText.GetHorizJustify() ) );
189
190 BOOST_CHECK_MESSAGE(
192 ref + " reference vertical justification should be TOP, got "
193 + std::to_string( refText.GetVertJustify() ) );
194 }
195 }
196
197 // Verify the plain text pin labels have correct justification.
198 // "G SDA SCL V+" on F.SilkS (Eagle layer 21) should have LEFT/BOTTOM justification
199 // with 90-degree rotation so the text reads bottom-to-top matching the pin order.
200 int topPinLabelCount = 0;
201
202 for( BOARD_ITEM* item : board->Drawings() )
203 {
204 if( item->Type() != PCB_TEXT_T )
205 continue;
206
207 PCB_TEXT* text = static_cast<PCB_TEXT*>( item );
208
209 if( text->GetText() != wxT( "G SDA SCL V+" ) )
210 continue;
211
212 if( text->GetLayer() != F_SilkS )
213 continue;
214
215 topPinLabelCount++;
216
217 BOOST_CHECK_MESSAGE(
218 text->GetHorizJustify() == GR_TEXT_H_ALIGN_LEFT,
219 "Pin label text horizontal justification should be LEFT" );
220
221 BOOST_CHECK_MESSAGE(
222 text->GetVertJustify() == GR_TEXT_V_ALIGN_BOTTOM,
223 "Pin label text vertical justification should be BOTTOM" );
224
225 BOOST_CHECK_MESSAGE(
226 text->GetTextAngle() == EDA_ANGLE( 90, DEGREES_T ),
227 "Pin label text angle should be 90 degrees" );
228 }
229
230 // Two instances of "G SDA SCL V+" on F.SilkS (one per connector)
231 BOOST_CHECK_EQUAL( topPinLabelCount, 2 );
232}
233
234
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
Information pertinent to a Pcbnew printed circuit board.
Definition board.h:322
GR_TEXT_H_ALIGN_T GetHorizJustify() const
Definition eda_text.h:200
GR_TEXT_V_ALIGN_T GetVertJustify() const
Definition eda_text.h:203
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
virtual const char * what() const override
std::exception interface, returned as UTF-8
Handle the data for a net.
Definition netinfo.h:54
const wxString & GetNetname() const
Definition netinfo.h:112
Works with Eagle 6.x XML board files and footprints to implement the Pcbnew #PLUGIN API or a portion ...
BOARD * LoadBoard(const wxString &aFileName, BOARD *aAppendToMe, const std::map< std::string, UTF8 > *aProperties=nullptr, PROJECT *aProject=nullptr) override
Load information from some input file format that this PCB_IO implementation knows about into either ...
@ DEGREES_T
Definition eda_angle.h:31
@ F_SilkS
Definition layer_ids.h:100
std::string GetPcbnewTestDataDir()
Utility which returns a path to the data directory where the test board files are stored.
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_CASE(ViaNetAssignment)
Verify that vias imported from an Eagle board are assigned to the correct nets.
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
BOOST_CHECK_EQUAL(result, "25.4")
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_TOP
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
Definition typeinfo.h:97
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
Definition typeinfo.h:92