KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_pcad_sch_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, see <https://www.gnu.org/licenses/>.
18 */
19
24
26
27#include <lib_id.h>
28#include <wx/arrstr.h>
29
30
31BOOST_FIXTURE_TEST_SUITE( PcadSchImport, PCAD_SCH_IMPORT_FIXTURE )
32
33
34// P-CAD saves are extension-agnostic and boards share the ACCEL_ASCII
35// container, so detection is by content.
36BOOST_AUTO_TEST_CASE( CanReadSchematic )
37{
38 BOOST_CHECK( m_plugin.CanReadSchematicFile( GetTestDataDir() + "pcad_feature_test.sch" ) );
39
40 // library-only ACCEL file without a schematicDesign section
41 BOOST_CHECK( !m_plugin.CanReadSchematicFile( GetTestDataDir() + "pcad_library_test.lia" ) );
42
43 // ACCEL board file
44 BOOST_CHECK( !m_plugin.CanReadSchematicFile( GetTestDataDir() + "pcad_board_reject.pcb" ) );
45
46 // pre-ACCEL vintage P-CAD format
47 BOOST_CHECK( !m_plugin.CanReadSchematicFile( GetTestDataDir() + "pcad_vintage_reject.sch" ) );
48}
49
50
51BOOST_AUTO_TEST_CASE( FeatureTestCounts )
52{
53 LoadSchematic( "pcad_feature_test.sch" );
54
55 // "Main" lands on the content root and "IO" becomes a subsheet
56 BOOST_CHECK_EQUAL( CountImportedScreens(), 2 );
57 BOOST_CHECK_EQUAL( CountItemsOfType( SCH_SHEET_T ), 1 );
58
59 // U1 unit 1, U1 unit 2, GND1 and U2
60 BOOST_CHECK_EQUAL( CountItemsOfType( SCH_SYMBOL_T ), 4 );
61
62 // Main has DATA0 (1 seg + 2-seg polyline), SENSE_NET (2) and DB0 (1); IO has MM_NET (1)
63 BOOST_CHECK_EQUAL( CountWires(), 7 );
64
65 BOOST_CHECK_EQUAL( CountBusSegments(), 2 );
66 BOOST_CHECK_EQUAL( CountItemsOfType( SCH_BUS_WIRE_ENTRY_T ), 2 );
67
68 // each entry's slant must be chosen so its far end lands on its bus; the
69 // Right entry disambiguates the vertical slant, the Up entry the horizontal
70 forEachItemOfType( SCH_BUS_WIRE_ENTRY_T,
71 []( SCH_ITEM* item, const SCH_SHEET_PATH& )
72 {
73 auto* entry = static_cast<SCH_BUS_WIRE_ENTRY*>( item );
74
75 if( entry->GetPosition().x == schIUScale.MilsToIU( 6300 ) )
76 {
77 BOOST_CHECK_EQUAL( entry->GetEnd().x, schIUScale.MilsToIU( 6400 ) );
78 BOOST_CHECK_EQUAL( entry->GetEnd().y, schIUScale.MilsToIU( 3900 ) );
79 }
80 else
81 {
82 BOOST_CHECK_EQUAL( entry->GetPosition().x, schIUScale.MilsToIU( 8600 ) );
83 BOOST_CHECK_EQUAL( entry->GetEnd().x, schIUScale.MilsToIU( 8500 ) );
84 BOOST_CHECK_EQUAL( entry->GetEnd().y, schIUScale.MilsToIU( 2000 ) );
85 }
86 } );
87 BOOST_CHECK_EQUAL( CountItemsOfType( SCH_JUNCTION_T ), 3 );
88
89 // displayed net names DATA0 and MM_NET, undisplayed named net SENSE_NET,
90 // bus names DBUS and HBUS
91 BOOST_CHECK_EQUAL( CountItemsOfType( SCH_LABEL_T ), 5 );
92 BOOST_CHECK( HasLabel( wxT( "DATA0" ) ) );
93 BOOST_CHECK( HasLabel( wxT( "SENSE_NET" ) ) );
94 BOOST_CHECK( HasLabel( wxT( "DBUS" ) ) );
95
96 // ports become global labels
97 BOOST_CHECK_EQUAL( CountItemsOfType( SCH_GLOBAL_LABEL_T ), 3 );
98 BOOST_CHECK( HasLabel( wxT( "VCC" ), SCH_GLOBAL_LABEL_T ) );
99 BOOST_CHECK( HasLabel( wxT( "DATA0" ), SCH_GLOBAL_LABEL_T ) );
100 BOOST_CHECK( HasLabel( wxT( "MM_NET" ), SCH_GLOBAL_LABEL_T ) );
101
102 // two free texts and the placed Title field on Main
103 BOOST_CHECK_EQUAL( CountItemsOfType( SCH_TEXT_T ), 3 );
104
105 // dotted polyline, two arcs, filled triangle and the IEEE Generator polyline
106 BOOST_CHECK_EQUAL( CountItemsOfType( SCH_SHAPE_T ), 5 );
107 BOOST_CHECK_EQUAL( CountShapesWithStyle( LINE_STYLE::DOT ), 1 );
108}
109
110
111BOOST_AUTO_TEST_CASE( MultiUnitComponent )
112{
113 LoadSchematic( "pcad_feature_test.sch" );
114
115 SCH_SYMBOL* unit1 = SymbolForRefdesUnit( wxT( "U1" ), 1 );
116 SCH_SYMBOL* unit2 = SymbolForRefdesUnit( wxT( "U1" ), 2 );
117
118 BOOST_REQUIRE( unit1 && unit2 );
119
120 LIB_SYMBOL* libSym = LibSymbolForRefdes( wxT( "U1" ) );
121 BOOST_REQUIRE( libSym );
122 BOOST_CHECK_EQUAL( libSym->GetUnitCount(), 2 );
123
124 // symbol pin ordinals resolve to pad designators through the compPin mapping
125 SCH_PIN* pin1 = LibPin( libSym, wxT( "1" ) );
126 SCH_PIN* pin2 = LibPin( libSym, wxT( "2" ) );
127 SCH_PIN* pin3 = LibPin( libSym, wxT( "3" ) );
128 SCH_PIN* pin4 = LibPin( libSym, wxT( "4" ) );
129
130 BOOST_REQUIRE( pin1 && pin2 && pin3 && pin4 );
131
132 BOOST_CHECK( pin1->GetType() == ELECTRICAL_PINTYPE::PT_INPUT );
133 BOOST_CHECK( pin2->GetType() == ELECTRICAL_PINTYPE::PT_OUTPUT );
134 BOOST_CHECK( pin3->GetType() == ELECTRICAL_PINTYPE::PT_PASSIVE );
135 BOOST_CHECK( pin4->GetType() == ELECTRICAL_PINTYPE::PT_TRISTATE );
136
137 BOOST_CHECK_EQUAL( pin1->GetUnit(), 1 );
138 BOOST_CHECK_EQUAL( pin3->GetUnit(), 2 );
139
140 // outsideEdgeStyle Dot and insideEdgeStyle Clock
141 BOOST_CHECK( pin1->GetShape() == GRAPHIC_PINSHAPE::INVERTED );
142 BOOST_CHECK( pin2->GetShape() == GRAPHIC_PINSHAPE::CLOCK );
143
144 BOOST_CHECK_EQUAL( libSym->GetFootprintField().GetText(), wxT( "DIP4" ) );
145 BOOST_CHECK_EQUAL( libSym->GetDescription(), wxT( "Dual QA test gate" ) );
146}
147
148
149BOOST_AUTO_TEST_CASE( ComponentAlias )
150{
151 LoadSchematic( "pcad_feature_test.sch" );
152
153 // U2 references compAlias GATE_ALIAS, which resolves to compDef GATE
154 SCH_SYMBOL* u2 = SymbolForRefdesUnit( wxT( "U2" ), 1 );
155
156 BOOST_REQUIRE( u2 );
157 BOOST_CHECK_EQUAL( u2->GetField( FIELD_T::VALUE )->GetText(), wxT( "74HC02" ) );
158 BOOST_CHECK_EQUAL( u2->GetLibId().GetLibItemName().wx_str(), wxT( "GATE" ) );
159}
160
161
163{
164 LoadSchematic( "pcad_feature_test.sch" );
165
166 LIB_SYMBOL* gnd = LibSymbolForRefdes( wxT( "#PWR" ) );
167
168 // compType Power maps to a KiCad power symbol with an invisible reference
169 if( !gnd )
170 gnd = LibSymbolForRefdes( wxT( "GND1" ) );
171
172 BOOST_REQUIRE( gnd );
173 BOOST_CHECK( gnd->IsPower() );
174
175 SCH_PIN* pin = LibPin( gnd, wxT( "1" ) );
177 BOOST_CHECK( pin->GetType() == ELECTRICAL_PINTYPE::PT_POWER_IN );
178 BOOST_CHECK( !pin->IsVisible() );
179}
180
181
183{
184 LoadSchematic( "pcad_feature_test.sch" );
185
186 const TITLE_BLOCK& tb = m_loadedRoot->GetScreen()->GetTitleBlock();
187
188 BOOST_CHECK_EQUAL( tb.GetTitle(), wxT( "P-CAD import feature fixture" ) );
189 BOOST_CHECK_EQUAL( tb.GetRevision(), wxT( "A" ) );
190 BOOST_CHECK_EQUAL( tb.GetDate(), wxT( "2026-07-03" ) );
191 BOOST_CHECK_EQUAL( tb.GetCompany(), wxT( "KiCad Project QA" ) );
192}
193
194
195BOOST_AUTO_TEST_CASE( TextFormatting )
196{
197 LoadSchematic( "pcad_feature_test.sch" );
198
199 // TrueType style with fontWeight 700 and fontItalic, rotated 90 degrees
200 SCH_TEXT* bold = FindText( wxT( "Bold TTF note" ) );
201
202 BOOST_REQUIRE( bold );
203 BOOST_CHECK( bold->IsBold() );
204 BOOST_CHECK( bold->IsItalic() );
205 BOOST_CHECK( bold->GetTextAngle() == EDA_ANGLE( 90.0, DEGREES_T ) );
206
207 SCH_TEXT* stroke = FindText( wxT( "Stroke note" ) );
208
209 BOOST_REQUIRE( stroke );
210 BOOST_CHECK( !stroke->IsBold() );
211
212 // placed title-block field renders with the fieldSet value
213 BOOST_CHECK( FindText( wxT( "P-CAD import feature fixture" ) ) );
214}
215
216
218{
219 LoadSchematic( "pcad_feature_test.sch" );
220
221 // The IO sheet junction sits at (25.4mm, 127mm) in a mil-unit file; with
222 // the 11000 mil page the KiCad position is (1000, 6000) mils.
223 bool found = false;
224
225 forEachItemOfType( SCH_JUNCTION_T,
226 [&]( SCH_ITEM* item, const SCH_SHEET_PATH& )
227 {
228 if( item->GetPosition() == VECTOR2I( schIUScale.MilsToIU( 1000 ),
229 schIUScale.MilsToIU( 6000 ) ) )
230 found = true;
231 } );
232
233 BOOST_CHECK( found );
234}
235
236
237BOOST_AUTO_TEST_CASE( EnumerateLibrary )
238{
239 wxArrayString names;
240
241 m_plugin.EnumerateSymbolLib( names, GetTestDataDir() + "pcad_library_test.lia" );
242
243 BOOST_REQUIRE_EQUAL( names.size(), 1 );
244 BOOST_CHECK_EQUAL( names[0], wxT( "RES_QA" ) );
245
246 // LoadSymbol returns a plugin-cache-owned pointer
247 LIB_SYMBOL* sym = m_plugin.LoadSymbol( GetTestDataDir() + "pcad_library_test.lia",
248 wxT( "RES_QA" ) );
249
250 BOOST_REQUIRE( sym );
251
252 // repeated loads must serve the identical cached object
253 BOOST_CHECK_EQUAL( sym, m_plugin.LoadSymbol( GetTestDataDir() + "pcad_library_test.lia",
254 wxT( "RES_QA" ) ) );
255 BOOST_CHECK_EQUAL( sym->GetPins().size(), 2 );
256 BOOST_CHECK_EQUAL( sym->GetReferenceField().GetText(), wxT( "R" ) );
257 BOOST_CHECK_EQUAL( sym->GetFootprintField().GetText(), wxT( "RES0805" ) );
258
259 // in the metric file the 15.24mm wide body spans 600 mils
260 SCH_PIN* pin1 = LibPin( sym, wxT( "1" ) );
261 SCH_PIN* pin2 = LibPin( sym, wxT( "2" ) );
262
263 BOOST_REQUIRE( pin1 && pin2 );
264
265 int span = std::abs( pin2->GetPosition().x - pin1->GetPosition().x );
266
267 // pins extend 5.08mm (200 mil) past each body end, so 600 + 2*200 mils
268 BOOST_CHECK_EQUAL( span, schIUScale.MilsToIU( 1000 ) );
269}
270
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:123
virtual VECTOR2I GetPosition() const
Definition eda_item.h:282
bool IsItalic() const
Definition eda_text.h:190
virtual EDA_ANGLE GetTextAngle() const
Definition eda_text.h:168
bool IsBold() const
Definition eda_text.h:205
const UTF8 & GetLibItemName() const
Definition lib_id.h:98
Define a library symbol object.
Definition lib_symbol.h:80
wxString GetDescription() const override
Definition lib_symbol.h:161
bool IsPower() const override
SCH_FIELD & GetFootprintField()
Return reference to the footprint field.
Definition lib_symbol.h:386
std::vector< SCH_PIN * > GetPins() const override
int GetUnitCount() const override
SCH_FIELD & GetReferenceField()
Return reference to the reference designator field.
Definition lib_symbol.h:382
Class for a wire to bus entry.
virtual const wxString & GetText() const override
Return the string associated with the text object.
Definition sch_field.h:128
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition sch_item.h:162
VECTOR2I GetPosition() const override
Definition sch_pin.cpp:350
GRAPHIC_PINSHAPE GetShape() const
Definition sch_pin.cpp:372
ELECTRICAL_PINTYPE GetType() const
Definition sch_pin.cpp:407
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Schematic symbol object.
Definition sch_symbol.h:69
const LIB_ID & GetLibId() const override
Definition sch_symbol.h:158
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
Hold the information shown in the lower right corner of a plot, printout, or editing view.
Definition title_block.h:37
const wxString & GetCompany() const
Definition title_block.h:92
const wxString & GetRevision() const
Definition title_block.h:82
const wxString & GetDate() const
Definition title_block.h:72
const wxString & GetTitle() const
Definition title_block.h:59
wxString wx_str() const
Definition utf8.cpp:41
@ DEGREES_T
Definition eda_angle.h:31
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition eda_angle.h:400
@ PT_INPUT
usual pin input: must be connected
Definition pin_type.h:33
@ PT_OUTPUT
usual output
Definition pin_type.h:34
@ PT_TRISTATE
tri state bus pin
Definition pin_type.h:36
@ PT_POWER_IN
power input (GND, VCC for ICs). Must be connected to a power output.
Definition pin_type.h:42
@ PT_PASSIVE
pin for passive symbols: must be connected, and can be connected to any pin.
Definition pin_type.h:39
static void LoadSchematic(SCHEMATIC *aSchematic, SCH_SHEET *aRootSheet, const wxString &aFileName)
@ VALUE
Field Value of part, i.e. "3.3K".
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
KIBIS_PIN * pin3
KIBIS_PIN * pin1
KIBIS_PIN * pin
BOOST_AUTO_TEST_CASE(CanReadSchematic)
Shared fixture and helpers for the P-CAD schematic import test suite.
BOOST_CHECK_EQUAL(result, "25.4")
@ SCH_SYMBOL_T
Definition typeinfo.h:169
@ SCH_LABEL_T
Definition typeinfo.h:164
@ SCH_SHEET_T
Definition typeinfo.h:172
@ SCH_SHAPE_T
Definition typeinfo.h:146
@ SCH_TEXT_T
Definition typeinfo.h:148
@ SCH_BUS_WIRE_ENTRY_T
Definition typeinfo.h:158
@ SCH_GLOBAL_LABEL_T
Definition typeinfo.h:165
@ SCH_JUNCTION_T
Definition typeinfo.h:156
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:683