KiCad PCB EDA Suite
test_ee_item.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 (C) 2022 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
25#include <eda_item_test_utils.h>
26#include <core/typeinfo.h>
27
28#include <eda_item.h>
29#include <sch_item.h>
30#include <lib_item.h>
31
32#include <sch_marker.h>
33#include <sch_junction.h>
34#include <sch_no_connect.h>
35#include <sch_bus_entry.h>
36#include <sch_line.h>
37#include <sch_shape.h>
38#include <sch_bitmap.h>
39#include <sch_text.h>
40#include <sch_textbox.h>
41#include <sch_field.h>
42#include <sch_symbol.h>
43#include <sch_sheet_pin.h>
44#include <sch_sheet.h>
45
46#include <lib_shape.h>
47#include <lib_text.h>
48#include <lib_textbox.h>
49#include <lib_pin.h>
50#include <lib_field.h>
51
52#include <erc_settings.h>
53
55{
56public:
60 std::shared_ptr<ERC_ITEM> m_ercItem;
61
63 m_sheet(),
64 m_symbol( "test symbol" ),
65 m_pin( &m_symbol ),
67 {
68 m_sheet.SetPosition( wxPoint( schIUScale.mmToIU( 5 ), schIUScale.mmToIU( 10 ) ) );
69 m_sheet.SetSize( wxSize( schIUScale.mmToIU( 50 ), schIUScale.mmToIU( 100 ) ) );
70 }
71
73 {
74 if( !IsEeschemaType( aType ) )
75 return nullptr;
76
77 if( !IsInstantiableType( aType ) )
78 return nullptr;
79
80 switch( aType )
81 {
82 case SCH_MARKER_T: return new SCH_MARKER( m_ercItem, wxPoint( 0, 0 ) );
83 case SCH_JUNCTION_T: return new SCH_JUNCTION();
84 case SCH_NO_CONNECT_T: return new SCH_NO_CONNECT();
86 case SCH_BUS_BUS_ENTRY_T: return new SCH_BUS_BUS_ENTRY();
87 case SCH_LINE_T: return new SCH_LINE();
88 case SCH_SHAPE_T: return new SCH_SHAPE( SHAPE_T::ARC );
89 case SCH_BITMAP_T: return new SCH_BITMAP();
90 case SCH_TEXT_T: return new SCH_TEXT( wxPoint( 0, 0 ), "test text" );
91 case SCH_TEXTBOX_T: return new SCH_TEXTBOX( 0, FILL_T::NO_FILL, "test textbox" );
92 case SCH_LABEL_T: return new SCH_LABEL( wxPoint( 0, 0 ), "test label" );
93 case SCH_DIRECTIVE_LABEL_T: return new SCH_DIRECTIVE_LABEL( wxPoint( 0, 0 ) );
94 case SCH_GLOBAL_LABEL_T: return new SCH_GLOBALLABEL();
95 case SCH_HIER_LABEL_T: return new SCH_HIERLABEL();
96 case SCH_FIELD_T: return new SCH_FIELD( wxPoint( 0, 0 ), 0, nullptr );
97 case SCH_SYMBOL_T: return new SCH_SYMBOL();
98
99 case SCH_SHEET_PIN_T:
100 // XXX: m_sheet pins currently have to have their initial positions calculated manually.
101 return new SCH_SHEET_PIN( &m_sheet,
102 wxPoint( m_sheet.GetPosition().x,
104 "test aPin" );
105
106 case SCH_SHEET_T: return new SCH_SHEET();
107 case LIB_SHAPE_T: return new LIB_SHAPE( &m_symbol, SHAPE_T::ARC );
108 case LIB_TEXT_T: return new LIB_TEXT( &m_symbol );
109 case LIB_TEXTBOX_T: return new LIB_TEXTBOX( &m_symbol, 0, FILL_T::NO_FILL, "test" );
110 case LIB_PIN_T: return new LIB_PIN( &m_symbol );
111 case LIB_FIELD_T: return new LIB_FIELD( &m_symbol );
112
113 case SCHEMATIC_T:
114 case SCH_PIN_T:
115 case LIB_SYMBOL_T: return nullptr;
116
117 default:
118 BOOST_FAIL( wxString::Format(
119 "Unhandled type: %d "
120 "(if you created a new type you need to handle it in this switch statement)",
121 aType ) );
122 return nullptr;
123 }
124 }
125
126 static void CompareItems( EDA_ITEM* aItem, EDA_ITEM* aOriginalItem )
127 {
128 BOOST_CHECK_EQUAL( aItem->GetPosition(), aOriginalItem->GetPosition() );
129 BOOST_CHECK_EQUAL( aItem->GetBoundingBox().GetTop(),
130 aOriginalItem->GetBoundingBox().GetTop() );
131 BOOST_CHECK_EQUAL( aItem->GetBoundingBox().GetLeft(),
132 aOriginalItem->GetBoundingBox().GetLeft() );
133 BOOST_CHECK_EQUAL( aItem->GetBoundingBox().GetBottom(),
134 aOriginalItem->GetBoundingBox().GetBottom() );
135 BOOST_CHECK_EQUAL( aItem->GetBoundingBox().GetRight(),
136 aOriginalItem->GetBoundingBox().GetRight() );
137 }
138};
139
140
141BOOST_FIXTURE_TEST_SUITE( EeItem, TEST_EE_ITEM_FIXTURE )
142
143
145{
146 for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
147 {
148 KICAD_T type = static_cast<KICAD_T>( i );
149
150 auto item = std::unique_ptr<EDA_ITEM>( Instantiate( type ) );
151
152 if( item == nullptr )
153 continue;
154
155 BOOST_TEST_CONTEXT( "Class: " << item->GetClass() )
156 {
157 IterateOverPositionsAndReferences<EDA_ITEM>(
158 item.get(),
159 []( EDA_ITEM* aOriginalItem, wxPoint aRef )
160 {
161 auto item = std::unique_ptr<EDA_ITEM>( aOriginalItem->Clone() );
162 VECTOR2I originalPos = item->GetPosition();
163
164 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item.get() );
165 LIB_ITEM* libItem = dynamic_cast<LIB_ITEM*>( item.get() );
166
167 // Move to a point, then go back.
168 // This has to be an identity transformation.
169
170 if( schItem != nullptr )
171 {
172 schItem->Move( aRef );
173 BOOST_CHECK_EQUAL( schItem->GetPosition(), originalPos + aRef );
174
175 schItem->Move( -aRef );
176 }
177
178 if( libItem != nullptr )
179 {
180 libItem->MoveTo( libItem->GetPosition() + aRef );
181 BOOST_CHECK_EQUAL( libItem->GetPosition(), originalPos + aRef );
182
183 libItem->MoveTo( libItem->GetPosition() - aRef );
184 }
185
186 CompareItems( item.get(), aOriginalItem );
187 } );
188 }
189 }
190}
191
192
194{
195 for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
196 {
197 KICAD_T type = static_cast<KICAD_T>( i );
198
199 auto item = std::unique_ptr<EDA_ITEM>( Instantiate( type ) );
200
201 if( item == nullptr )
202 continue;
203
204 BOOST_TEST_CONTEXT( "Class: " << item->GetClass() )
205 {
206 // Four equivalent 90 degree rotations are an identity.
207 // (warning: only for items having no autoplaced fields).
208
209 if( item->GetClass() == "SCH_SHEET_PIN" )
210 {
211 auto newItem = std::unique_ptr<EDA_ITEM>( item->Clone() );
212
213 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( newItem.get() );
214 LIB_ITEM* libItem = dynamic_cast<LIB_ITEM*>( newItem.get() );
215
216 if( schItem != nullptr )
217 {
218 schItem->ClearFieldsAutoplaced();
219 // Only rotating pins around the center of parent sheet works.
220 schItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter() );
221 schItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter() );
222 schItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter() );
223 schItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter() );
224 }
225
226 if( libItem != nullptr )
227 {
228 libItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter() );
229 libItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter() );
230 libItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter() );
231 libItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter() );
232 }
233
234 CompareItems( newItem.get(), item.get() );
235 }
236 else
237 {
238 IterateOverPositionsAndReferences<EDA_ITEM>(
239 item.get(),
240 []( EDA_ITEM* aOriginalItem, wxPoint aRef )
241 {
242 auto item = std::unique_ptr<EDA_ITEM>( aOriginalItem->Clone() );
243
244 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item.get() );
245 LIB_ITEM* libItem = dynamic_cast<LIB_ITEM*>( item.get() );
246
247 if( schItem != nullptr )
248 {
249 schItem->ClearFieldsAutoplaced();
250 schItem->Rotate( aRef );
251 schItem->Rotate( aRef );
252 schItem->Rotate( aRef );
253 schItem->Rotate( aRef );
254 }
255
256 if( libItem != nullptr )
257 {
258 libItem->Rotate( aRef );
259 libItem->Rotate( aRef );
260 libItem->Rotate( aRef );
261 libItem->Rotate( aRef );
262 }
263
264 CompareItems( item.get(), aOriginalItem );
265 } );
266 }
267 }
268 }
269}
270
271
272BOOST_AUTO_TEST_CASE( MirrorHorizontally )
273{
274 for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
275 {
276 KICAD_T type = static_cast<KICAD_T>( i );
277
278 auto item = std::unique_ptr<EDA_ITEM>( Instantiate( type ) );
279
280 if( item == nullptr )
281 continue;
282
283 BOOST_TEST_CONTEXT( "Class: " << item->GetClass() )
284 {
285 IterateOverPositionsAndReferences<EDA_ITEM>(
286 item.get(),
287 []( EDA_ITEM* aOriginalItem, wxPoint aRef )
288 {
289 auto item = std::unique_ptr<EDA_ITEM>( aOriginalItem->Clone() );
290
291 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item.get() );
292 LIB_ITEM* libItem = dynamic_cast<LIB_ITEM*>( item.get() );
293
294 // Two mirrorings are an identity
295 // (warning: only for text items having no autoplaced fields).
296 if( schItem != nullptr )
297 {
298 schItem->ClearFieldsAutoplaced();
299 schItem->MirrorHorizontally( aRef.x );
300 schItem->MirrorHorizontally( aRef.x );
301 }
302
303 if( libItem != nullptr )
304 {
305 libItem->MirrorHorizontal( aRef );
306 libItem->MirrorHorizontal( aRef );
307 }
308
309 CompareItems( item.get(), aOriginalItem );
310 } );
311 }
312 }
313}
314
315
316BOOST_AUTO_TEST_CASE( MirrorVertically )
317{
318 for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
319 {
320 KICAD_T type = static_cast<KICAD_T>( i );
321
322 auto item = std::unique_ptr<EDA_ITEM>( Instantiate( type ) );
323
324 if( item == nullptr )
325 continue;
326
327 BOOST_TEST_CONTEXT( "Class: " << item->GetClass() )
328 {
329 IterateOverPositionsAndReferences<EDA_ITEM>(
330 item.get(),
331 []( EDA_ITEM* aOriginalItem, wxPoint aRef )
332 {
333 auto item = std::unique_ptr<EDA_ITEM>( aOriginalItem->Clone() );
334
335 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item.get() );
336 LIB_ITEM* libItem = dynamic_cast<LIB_ITEM*>( item.get() );
337
338 // Two mirrorings are an identity
339 // (warning only for text items having no autoplaced fields).
340
341 if( schItem != nullptr )
342 {
343 schItem->ClearFieldsAutoplaced();
344 schItem->MirrorVertically( aRef.y );
345 schItem->MirrorVertically( aRef.y );
346 }
347
348 if( libItem != nullptr )
349 {
350 libItem->MirrorVertical( aRef );
351 libItem->MirrorVertical( aRef );
352 }
353
354 CompareItems( item.get(), aOriginalItem );
355 } );
356 }
357 }
358}
359
360BOOST_AUTO_TEST_SUITE_END()
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:111
coord_type GetTop() const
Definition: box2.h:194
coord_type GetRight() const
Definition: box2.h:189
coord_type GetLeft() const
Definition: box2.h:193
coord_type GetBottom() const
Definition: box2.h:190
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:85
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:251
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition: eda_item.cpp:74
Field object used in symbol libraries.
Definition: lib_field.h:60
The base class for drawable items used by schematic library symbols.
Definition: lib_item.h:61
virtual void Rotate(const VECTOR2I &aCenter, bool aRotateCCW=true)=0
Rotate the object about aCenter point.
Define a library symbol object.
Definition: lib_symbol.h:98
Define a symbol library graphical text item.
Definition: lib_text.h:40
Object to handle a bitmap image that can be inserted in a schematic.
Definition: sch_bitmap.h:41
Class for a bus to bus entry.
Class for a wire to bus entry.
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:50
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:147
void ClearFieldsAutoplaced()
Definition: sch_item.h:427
virtual void Rotate(const VECTOR2I &aCenter)=0
Rotate the item around aCenter 90 degrees in the clockwise direction.
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:40
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Definition: sch_sheet_pin.h:66
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
Definition: sch_sheet.h:55
void SetSize(const wxSize &aSize)
Definition: sch_sheet.h:107
void SetPosition(const VECTOR2I &aPosition) override
Definition: sch_sheet.cpp:891
VECTOR2I GetPosition() const override
Definition: sch_sheet.h:366
Schematic symbol object.
Definition: sch_symbol.h:80
EDA_ITEM * Instantiate(KICAD_T aType)
static void CompareItems(EDA_ITEM *aItem, EDA_ITEM *aOriginalItem)
std::shared_ptr< ERC_ITEM > m_ercItem
@ ERCE_DRIVER_CONFLICT
Conflicting drivers (labels, etc) on a subgraph.
Definition: erc_settings.h:61
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
constexpr int mmToIU(double mm) const
Definition: base_units.h:89
BOOST_AUTO_TEST_CASE(Move)
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ SCH_LINE_T
Definition: typeinfo.h:146
@ LIB_SYMBOL_T
Definition: typeinfo.h:198
@ SCH_NO_CONNECT_T
Definition: typeinfo.h:143
@ LIB_TEXT_T
Definition: typeinfo.h:200
@ MAX_STRUCT_TYPE_ID
Definition: typeinfo.h:241
@ SCH_SYMBOL_T
Definition: typeinfo.h:156
@ LIB_TEXTBOX_T
Definition: typeinfo.h:201
@ SCH_FIELD_T
Definition: typeinfo.h:155
@ SCH_DIRECTIVE_LABEL_T
Definition: typeinfo.h:154
@ SCH_LABEL_T
Definition: typeinfo.h:151
@ SCH_SHEET_T
Definition: typeinfo.h:158
@ LIB_SHAPE_T
Definition: typeinfo.h:199
@ SCH_MARKER_T
Definition: typeinfo.h:141
@ SCH_SHAPE_T
Definition: typeinfo.h:147
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:153
@ SCH_BUS_BUS_ENTRY_T
Definition: typeinfo.h:145
@ LIB_PIN_T
Definition: typeinfo.h:202
@ SCHEMATIC_T
Definition: typeinfo.h:188
@ SCH_SHEET_PIN_T
Definition: typeinfo.h:157
@ SCH_TEXT_T
Definition: typeinfo.h:150
@ LIB_FIELD_T
Definition: typeinfo.h:208
@ SCH_BUS_WIRE_ENTRY_T
Definition: typeinfo.h:144
@ SCH_BITMAP_T
Definition: typeinfo.h:148
@ SCH_TEXTBOX_T
Definition: typeinfo.h:149
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:152
@ SCH_JUNCTION_T
Definition: typeinfo.h:142
@ SCH_PIN_T
Definition: typeinfo.h:159
constexpr bool IsInstantiableType(const KICAD_T aType)
Definition: typeinfo.h:311
constexpr bool IsEeschemaType(const KICAD_T aType)
Definition: typeinfo.h:366
#define BOOST_TEST_CONTEXT(A)