KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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-2023 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
51#include <erc_settings.h>
52
54{
55public:
59 std::shared_ptr<ERC_ITEM> m_ercItem;
60
62 m_sheet(),
63 m_symbol( "test symbol" ),
64 m_pin( &m_symbol ),
66 {
69 }
70
72 {
73 if( !IsEeschemaType( aType ) )
74 return nullptr;
75
76 if( !IsInstantiableType( aType ) )
77 return nullptr;
78
79 switch( aType )
80 {
81 case SCH_MARKER_T: return new SCH_MARKER( m_ercItem, VECTOR2I( 0, 0 ) );
82 case SCH_JUNCTION_T: return new SCH_JUNCTION();
83 case SCH_NO_CONNECT_T: return new SCH_NO_CONNECT();
85 case SCH_BUS_BUS_ENTRY_T: return new SCH_BUS_BUS_ENTRY();
86 case SCH_LINE_T: return new SCH_LINE();
87 case SCH_SHAPE_T: return new SCH_SHAPE( SHAPE_T::ARC );
88 case SCH_BITMAP_T: return new SCH_BITMAP();
89 case SCH_TEXT_T: return new SCH_TEXT( VECTOR2I( 0, 0 ), "test text" );
90 case SCH_TEXTBOX_T: return new SCH_TEXTBOX( 0, FILL_T::NO_FILL, "test textbox" );
91 case SCH_LABEL_T: return new SCH_LABEL( VECTOR2I( 0, 0 ), "test label" );
92 case SCH_DIRECTIVE_LABEL_T: return new SCH_DIRECTIVE_LABEL( VECTOR2I( 0, 0 ) );
93 case SCH_GLOBAL_LABEL_T: return new SCH_GLOBALLABEL();
94 case SCH_HIER_LABEL_T: return new SCH_HIERLABEL();
95 case SCH_FIELD_T: return new SCH_FIELD( VECTOR2I( 0, 0 ), 0, nullptr );
96 case SCH_SYMBOL_T: return new SCH_SYMBOL();
97
98 case SCH_SHEET_PIN_T:
99 // XXX: m_sheet pins currently have to have their initial positions calculated manually.
100 return new SCH_SHEET_PIN( &m_sheet,
103 "test aPin" );
104
105 case SCH_SHEET_T: return new SCH_SHEET();
106 case LIB_SHAPE_T: return new LIB_SHAPE( &m_symbol, SHAPE_T::ARC );
107 case LIB_TEXT_T: return new LIB_TEXT( &m_symbol );
108 case LIB_TEXTBOX_T: return new LIB_TEXTBOX( &m_symbol, 0, FILL_T::NO_FILL, "test" );
109 case LIB_PIN_T: return new LIB_PIN( &m_symbol );
110 case LIB_FIELD_T: return new LIB_FIELD( &m_symbol );
111
112 case SCHEMATIC_T:
113 case SCH_PIN_T:
114 case LIB_SYMBOL_T: return nullptr;
115
116 default:
117 BOOST_FAIL( wxString::Format(
118 "Unhandled type: %d "
119 "(if you created a new type you need to handle it in this switch statement)",
120 aType ) );
121 return nullptr;
122 }
123 }
124
125 static void CompareItems( EDA_ITEM* aItem, EDA_ITEM* aOriginalItem )
126 {
127 BOOST_CHECK_EQUAL( aItem->GetPosition(), aOriginalItem->GetPosition() );
128 BOOST_CHECK_EQUAL( aItem->GetBoundingBox().GetTop(),
129 aOriginalItem->GetBoundingBox().GetTop() );
130 BOOST_CHECK_EQUAL( aItem->GetBoundingBox().GetLeft(),
131 aOriginalItem->GetBoundingBox().GetLeft() );
132 BOOST_CHECK_EQUAL( aItem->GetBoundingBox().GetBottom(),
133 aOriginalItem->GetBoundingBox().GetBottom() );
134 BOOST_CHECK_EQUAL( aItem->GetBoundingBox().GetRight(),
135 aOriginalItem->GetBoundingBox().GetRight() );
136 }
137};
138
139
140BOOST_FIXTURE_TEST_SUITE( EeItem, TEST_EE_ITEM_FIXTURE )
141
142
144{
145 for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
146 {
147 KICAD_T type = static_cast<KICAD_T>( i );
148
149 auto item = std::unique_ptr<EDA_ITEM>( Instantiate( type ) );
150
151 if( item == nullptr )
152 continue;
153
154 BOOST_TEST_CONTEXT( "Class: " << item->GetClass() )
155 {
156 IterateOverPositionsAndReferences<EDA_ITEM>(
157 item.get(),
158 []( EDA_ITEM* aOriginalItem, VECTOR2I aRef )
159 {
160 auto item = std::unique_ptr<EDA_ITEM>( aOriginalItem->Clone() );
161 VECTOR2I originalPos = item->GetPosition();
162
163 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item.get() );
164 LIB_ITEM* libItem = dynamic_cast<LIB_ITEM*>( item.get() );
165
166 // Move to a point, then go back.
167 // This has to be an identity transformation.
168
169 if( schItem != nullptr )
170 {
171 schItem->Move( aRef );
172 BOOST_CHECK_EQUAL( schItem->GetPosition(), originalPos + aRef );
173
174 schItem->Move( -aRef );
175 }
176
177 if( libItem != nullptr )
178 {
179 libItem->MoveTo( libItem->GetPosition() + aRef );
180 BOOST_CHECK_EQUAL( libItem->GetPosition(), originalPos + aRef );
181
182 libItem->MoveTo( libItem->GetPosition() - aRef );
183 }
184
185 CompareItems( item.get(), aOriginalItem );
186 } );
187 }
188 }
189}
190
191
193{
194 for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
195 {
196 KICAD_T type = static_cast<KICAD_T>( i );
197
198 auto item = std::unique_ptr<EDA_ITEM>( Instantiate( type ) );
199
200 if( item == nullptr )
201 continue;
202
203 BOOST_TEST_CONTEXT( "Class: " << item->GetClass() )
204 {
205 // Four equivalent 90 degree rotations are an identity.
206 // (warning: only for items having no autoplaced fields).
207
208 if( item->GetClass() == "SCH_SHEET_PIN" )
209 {
210 auto newItem = std::unique_ptr<EDA_ITEM>( item->Clone() );
211
212 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( newItem.get() );
213 LIB_ITEM* libItem = dynamic_cast<LIB_ITEM*>( newItem.get() );
214
215 if( schItem != nullptr )
216 {
217 schItem->ClearFieldsAutoplaced();
218 // Only rotating pins around the center of parent sheet works.
219 schItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter() );
220 schItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter() );
221 schItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter() );
222 schItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter() );
223 }
224
225 if( libItem != nullptr )
226 {
227 libItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter() );
228 libItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter() );
229 libItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter() );
230 libItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter() );
231 }
232
233 CompareItems( newItem.get(), item.get() );
234 }
235 else
236 {
237 IterateOverPositionsAndReferences<EDA_ITEM>(
238 item.get(),
239 []( EDA_ITEM* aOriginalItem, VECTOR2I aRef )
240 {
241 auto item = std::unique_ptr<EDA_ITEM>( aOriginalItem->Clone() );
242
243 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item.get() );
244 LIB_ITEM* libItem = dynamic_cast<LIB_ITEM*>( item.get() );
245
246 if( schItem != nullptr )
247 {
248 schItem->ClearFieldsAutoplaced();
249 schItem->Rotate( aRef );
250 schItem->Rotate( aRef );
251 schItem->Rotate( aRef );
252 schItem->Rotate( aRef );
253 }
254
255 if( libItem != nullptr )
256 {
257 libItem->Rotate( aRef );
258 libItem->Rotate( aRef );
259 libItem->Rotate( aRef );
260 libItem->Rotate( aRef );
261 }
262
263 CompareItems( item.get(), aOriginalItem );
264 } );
265 }
266 }
267 }
268}
269
270
271BOOST_AUTO_TEST_CASE( MirrorHorizontally )
272{
273 for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
274 {
275 KICAD_T type = static_cast<KICAD_T>( i );
276
277 auto item = std::unique_ptr<EDA_ITEM>( Instantiate( type ) );
278
279 if( item == nullptr )
280 continue;
281
282 BOOST_TEST_CONTEXT( "Class: " << item->GetClass() )
283 {
284 IterateOverPositionsAndReferences<EDA_ITEM>(
285 item.get(),
286 []( EDA_ITEM* aOriginalItem, VECTOR2I aRef )
287 {
288 auto item = std::unique_ptr<EDA_ITEM>( aOriginalItem->Clone() );
289
290 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item.get() );
291 LIB_ITEM* libItem = dynamic_cast<LIB_ITEM*>( item.get() );
292
293 // Two mirrorings are an identity
294 // (warning: only for text items having no autoplaced fields).
295 if( schItem != nullptr )
296 {
297 schItem->ClearFieldsAutoplaced();
298 schItem->MirrorHorizontally( aRef.x );
299 schItem->MirrorHorizontally( aRef.x );
300 }
301
302 if( libItem != nullptr )
303 {
304 libItem->MirrorHorizontal( aRef );
305 libItem->MirrorHorizontal( aRef );
306 }
307
308 CompareItems( item.get(), aOriginalItem );
309 } );
310 }
311 }
312}
313
314
315BOOST_AUTO_TEST_CASE( MirrorVertically )
316{
317 for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
318 {
319 KICAD_T type = static_cast<KICAD_T>( i );
320
321 auto item = std::unique_ptr<EDA_ITEM>( Instantiate( type ) );
322
323 if( item == nullptr )
324 continue;
325
326 BOOST_TEST_CONTEXT( "Class: " << item->GetClass() )
327 {
328 IterateOverPositionsAndReferences<EDA_ITEM>(
329 item.get(),
330 []( EDA_ITEM* aOriginalItem, VECTOR2I aRef )
331 {
332 auto item = std::unique_ptr<EDA_ITEM>( aOriginalItem->Clone() );
333
334 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item.get() );
335 LIB_ITEM* libItem = dynamic_cast<LIB_ITEM*>( item.get() );
336
337 // Two mirrorings are an identity
338 // (warning only for text items having no autoplaced fields).
339
340 if( schItem != nullptr )
341 {
342 schItem->ClearFieldsAutoplaced();
343 schItem->MirrorVertically( aRef.y );
344 schItem->MirrorVertically( aRef.y );
345 }
346
347 if( libItem != nullptr )
348 {
349 libItem->MirrorVertical( aRef );
350 libItem->MirrorVertical( aRef );
351 }
352
353 CompareItems( item.get(), aOriginalItem );
354 } );
355 }
356 }
357}
358
359BOOST_AUTO_TEST_SUITE_END()
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:111
coord_type GetTop() const
Definition: box2.h:195
coord_type GetRight() const
Definition: box2.h:190
coord_type GetLeft() const
Definition: box2.h:194
coord_type GetBottom() const
Definition: box2.h:191
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:239
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:62
The base class for drawable items used by schematic library symbols.
Definition: lib_item.h:68
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:99
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:52
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:150
void ClearFieldsAutoplaced()
Definition: sch_item.h:446
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:57
void SetSize(const VECTOR2I &aSize)
Definition: sch_sheet.h:113
void SetPosition(const VECTOR2I &aPosition) override
Definition: sch_sheet.cpp:923
VECTOR2I GetPosition() const override
Definition: sch_sheet.h:378
Schematic symbol object.
Definition: sch_symbol.h:81
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
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:145
@ LIB_SYMBOL_T
Definition: typeinfo.h:197
@ SCH_NO_CONNECT_T
Definition: typeinfo.h:142
@ LIB_TEXT_T
Definition: typeinfo.h:199
@ MAX_STRUCT_TYPE_ID
Definition: typeinfo.h:240
@ SCH_SYMBOL_T
Definition: typeinfo.h:155
@ LIB_TEXTBOX_T
Definition: typeinfo.h:200
@ SCH_FIELD_T
Definition: typeinfo.h:154
@ SCH_DIRECTIVE_LABEL_T
Definition: typeinfo.h:153
@ SCH_LABEL_T
Definition: typeinfo.h:150
@ SCH_SHEET_T
Definition: typeinfo.h:157
@ LIB_SHAPE_T
Definition: typeinfo.h:198
@ SCH_MARKER_T
Definition: typeinfo.h:140
@ SCH_SHAPE_T
Definition: typeinfo.h:146
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:152
@ SCH_BUS_BUS_ENTRY_T
Definition: typeinfo.h:144
@ LIB_PIN_T
Definition: typeinfo.h:201
@ SCHEMATIC_T
Definition: typeinfo.h:187
@ SCH_SHEET_PIN_T
Definition: typeinfo.h:156
@ SCH_TEXT_T
Definition: typeinfo.h:149
@ LIB_FIELD_T
Definition: typeinfo.h:207
@ SCH_BUS_WIRE_ENTRY_T
Definition: typeinfo.h:143
@ SCH_BITMAP_T
Definition: typeinfo.h:147
@ SCH_TEXTBOX_T
Definition: typeinfo.h:148
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:151
@ SCH_JUNCTION_T
Definition: typeinfo.h:141
@ SCH_PIN_T
Definition: typeinfo.h:158
constexpr bool IsInstantiableType(const KICAD_T aType)
Definition: typeinfo.h:311
constexpr bool IsEeschemaType(const KICAD_T aType)
Definition: typeinfo.h:370
#define BOOST_TEST_CONTEXT(A)
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588