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
31#include <sch_marker.h>
32#include <sch_junction.h>
33#include <sch_no_connect.h>
34#include <sch_bus_entry.h>
35#include <sch_line.h>
36#include <sch_shape.h>
37#include <sch_bitmap.h>
38#include <sch_text.h>
39#include <sch_textbox.h>
40#include <sch_table.h>
41#include <sch_tablecell.h>
42#include <sch_field.h>
43#include <sch_symbol.h>
44#include <sch_sheet_pin.h>
45#include <sch_sheet.h>
46
47#include <lib_shape.h>
48#include <lib_text.h>
49#include <lib_textbox.h>
50#include <lib_pin.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 {
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, VECTOR2I( 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( VECTOR2I( 0, 0 ), "test text" );
91 case SCH_TEXTBOX_T: return new SCH_TEXTBOX( 0, FILL_T::NO_FILL, "test textbox" );
92 case SCH_TABLECELL_T: return new SCH_TABLECELL();
93 case SCH_TABLE_T:
94 {
95 SCH_TABLE* table = new SCH_TABLE( schIUScale.mmToIU( 0.1 ) );
96
97 table->SetColCount( 2 );
98
99 for( int ii = 0; ii < 4; ++ii )
100 table->InsertCell( ii, new SCH_TABLECELL() );
101
102 return table;
103 }
104 case SCH_LABEL_T: return new SCH_LABEL( VECTOR2I( 0, 0 ), "test label" );
105 case SCH_DIRECTIVE_LABEL_T: return new SCH_DIRECTIVE_LABEL( VECTOR2I( 0, 0 ) );
106 case SCH_GLOBAL_LABEL_T: return new SCH_GLOBALLABEL();
107 case SCH_HIER_LABEL_T: return new SCH_HIERLABEL();
108 case SCH_FIELD_T: return new SCH_FIELD( VECTOR2I( 0, 0 ), 0, nullptr );
109 case SCH_SYMBOL_T: return new SCH_SYMBOL();
110
111 case SCH_SHEET_PIN_T:
112 // XXX: m_sheet pins currently have to have their initial positions calculated manually.
113 return new SCH_SHEET_PIN( &m_sheet,
116 "test aPin" );
117
118 case SCH_SHEET_T: return new SCH_SHEET();
119 case LIB_SHAPE_T: return new LIB_SHAPE( &m_symbol, SHAPE_T::ARC );
120 case LIB_TEXT_T: return new LIB_TEXT( &m_symbol );
121 case LIB_TEXTBOX_T: return new LIB_TEXTBOX( &m_symbol, 0, FILL_T::NO_FILL, "test" );
122 case LIB_PIN_T: return new LIB_PIN( &m_symbol );
123
124 case SCHEMATIC_T:
125 case SCH_PIN_T:
126 case LIB_SYMBOL_T: return nullptr;
127
128 default:
129 BOOST_FAIL( wxString::Format(
130 "Unhandled type: %d "
131 "(if you created a new type you need to handle it in this switch statement)",
132 aType ) );
133 return nullptr;
134 }
135 }
136
137 static void CompareItems( EDA_ITEM* aItem, EDA_ITEM* aOriginalItem )
138 {
139 BOOST_CHECK_EQUAL( aItem->GetPosition(), aOriginalItem->GetPosition() );
140 BOOST_CHECK_EQUAL( aItem->GetBoundingBox().GetTop(),
141 aOriginalItem->GetBoundingBox().GetTop() );
142 BOOST_CHECK_EQUAL( aItem->GetBoundingBox().GetLeft(),
143 aOriginalItem->GetBoundingBox().GetLeft() );
144 BOOST_CHECK_EQUAL( aItem->GetBoundingBox().GetBottom(),
145 aOriginalItem->GetBoundingBox().GetBottom() );
146 BOOST_CHECK_EQUAL( aItem->GetBoundingBox().GetRight(),
147 aOriginalItem->GetBoundingBox().GetRight() );
148 }
149};
150
151
152BOOST_FIXTURE_TEST_SUITE( EeItem, TEST_EE_ITEM_FIXTURE )
153
154
156{
157 for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
158 {
159 KICAD_T type = static_cast<KICAD_T>( i );
160
161 auto item = std::unique_ptr<EDA_ITEM>( Instantiate( type ) );
162
163 if( item == nullptr )
164 continue;
165
166 BOOST_TEST_CONTEXT( "Class: " << item->GetClass() )
167 {
168 IterateOverPositionsAndReferences<EDA_ITEM>(
169 item.get(),
170 []( EDA_ITEM* aOriginalItem, VECTOR2I aRef )
171 {
172 auto item = std::unique_ptr<EDA_ITEM>( aOriginalItem->Clone() );
173 VECTOR2I originalPos = item->GetPosition();
174
175 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item.get() );
176
177 // Move to a point, then go back.
178 // This has to be an identity transformation.
179
180 if( schItem != nullptr )
181 {
182 schItem->Move( aRef );
183 BOOST_CHECK_EQUAL( schItem->GetPosition(), originalPos + aRef );
184
185 schItem->Move( -aRef );
186 }
187
188 CompareItems( item.get(), aOriginalItem );
189 } );
190 }
191 }
192}
193
194
196{
197 for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
198 {
199 KICAD_T type = static_cast<KICAD_T>( i );
200
201 auto item = std::unique_ptr<EDA_ITEM>( Instantiate( type ) );
202
203 if( item == nullptr )
204 continue;
205
206 BOOST_TEST_CONTEXT( "Class: " << item->GetClass() )
207 {
208 // Four equivalent 90 degree rotations are an identity.
209 // (warning: only for items having no autoplaced fields).
210
211 if( item->GetClass() == "SCH_SHEET_PIN" )
212 {
213 auto newItem = std::unique_ptr<EDA_ITEM>( item->Clone() );
214
215 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( newItem.get() );
216
217 if( schItem != nullptr )
218 {
219 schItem->ClearFieldsAutoplaced();
220 // Only rotating pins around the center of parent sheet works.
221 schItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter(), false );
222 schItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter(), false );
223 schItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter(), false );
224 schItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter(), false );
225 }
226
227 CompareItems( newItem.get(), item.get() );
228 }
229 else
230 {
231 IterateOverPositionsAndReferences<EDA_ITEM>(
232 item.get(),
233 []( EDA_ITEM* aOriginalItem, VECTOR2I aRef )
234 {
235 auto item = std::unique_ptr<EDA_ITEM>( aOriginalItem->Clone() );
236
237 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item.get() );
238
239 if( schItem != nullptr )
240 {
241 schItem->ClearFieldsAutoplaced();
242 schItem->Rotate( aRef, false );
243 schItem->Rotate( aRef, false );
244 schItem->Rotate( aRef, false );
245 schItem->Rotate( aRef, false );
246 }
247
248 CompareItems( item.get(), aOriginalItem );
249 } );
250 }
251 }
252 }
253}
254
255
256BOOST_AUTO_TEST_CASE( MirrorHorizontally )
257{
258 for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
259 {
260 KICAD_T type = static_cast<KICAD_T>( i );
261
262 auto item = std::unique_ptr<EDA_ITEM>( Instantiate( type ) );
263
264 if( item == nullptr )
265 continue;
266
267 BOOST_TEST_CONTEXT( "Class: " << item->GetClass() )
268 {
269 IterateOverPositionsAndReferences<EDA_ITEM>(
270 item.get(),
271 []( EDA_ITEM* aOriginalItem, VECTOR2I aRef )
272 {
273 auto item = std::unique_ptr<EDA_ITEM>( aOriginalItem->Clone() );
274
275 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item.get() );
276
277 // Two mirrorings are an identity
278 // (warning: only for text items having no autoplaced fields).
279 if( schItem != nullptr )
280 {
281 schItem->ClearFieldsAutoplaced();
282 schItem->MirrorHorizontally( aRef.x );
283 schItem->MirrorHorizontally( aRef.x );
284 }
285
286 CompareItems( item.get(), aOriginalItem );
287 } );
288 }
289 }
290}
291
292
293BOOST_AUTO_TEST_CASE( MirrorVertically )
294{
295 for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
296 {
297 KICAD_T type = static_cast<KICAD_T>( i );
298
299 auto item = std::unique_ptr<EDA_ITEM>( Instantiate( type ) );
300
301 if( item == nullptr )
302 continue;
303
304 BOOST_TEST_CONTEXT( "Class: " << item->GetClass() )
305 {
306 IterateOverPositionsAndReferences<EDA_ITEM>(
307 item.get(),
308 []( EDA_ITEM* aOriginalItem, VECTOR2I aRef )
309 {
310 auto item = std::unique_ptr<EDA_ITEM>( aOriginalItem->Clone() );
311
312 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item.get() );
313
314 // Two mirrorings are an identity
315 // (warning only for text items having no autoplaced fields).
316
317 if( schItem != nullptr )
318 {
319 schItem->ClearFieldsAutoplaced();
320 schItem->MirrorVertically( aRef.y );
321 schItem->MirrorVertically( aRef.y );
322 }
323
324 CompareItems( item.get(), aOriginalItem );
325 } );
326 }
327 }
328}
329
330BOOST_AUTO_TEST_SUITE_END()
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:110
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:88
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:242
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition: eda_item.cpp:74
Define a library symbol object.
Definition: lib_symbol.h:78
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:51
Base class for any item which can be embedded within the SCHEMATIC container class,...
Definition: sch_item.h:172
void ClearFieldsAutoplaced()
Definition: sch_item.h:557
virtual void Rotate(const VECTOR2I &aCenter, bool aRotateCCW)
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_item.h:365
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:927
VECTOR2I GetPosition() const override
Definition: sch_sheet.h:376
Schematic symbol object.
Definition: sch_symbol.h:108
void SetColCount(int aCount)
Definition: sch_table.h:103
void InsertCell(int aIdx, SCH_TABLECELL *aCell)
Definition: sch_table.h:152
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:63
constexpr int mmToIU(double mm) const
Definition: base_units.h:88
BOOST_AUTO_TEST_CASE(Move)
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition: typeinfo.h:78
@ SCH_TABLE_T
Definition: typeinfo.h:153
@ SCH_LINE_T
Definition: typeinfo.h:148
@ LIB_SYMBOL_T
Definition: typeinfo.h:202
@ SCH_NO_CONNECT_T
Definition: typeinfo.h:145
@ LIB_TEXT_T
Definition: typeinfo.h:204
@ MAX_STRUCT_TYPE_ID
Definition: typeinfo.h:239
@ SCH_SYMBOL_T
Definition: typeinfo.h:160
@ SCH_TABLECELL_T
Definition: typeinfo.h:154
@ LIB_TEXTBOX_T
Definition: typeinfo.h:205
@ SCH_FIELD_T
Definition: typeinfo.h:159
@ SCH_DIRECTIVE_LABEL_T
Definition: typeinfo.h:158
@ SCH_LABEL_T
Definition: typeinfo.h:155
@ SCH_SHEET_T
Definition: typeinfo.h:162
@ LIB_SHAPE_T
Definition: typeinfo.h:203
@ SCH_MARKER_T
Definition: typeinfo.h:143
@ SCH_SHAPE_T
Definition: typeinfo.h:149
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:157
@ SCH_BUS_BUS_ENTRY_T
Definition: typeinfo.h:147
@ LIB_PIN_T
Definition: typeinfo.h:206
@ SCHEMATIC_T
Definition: typeinfo.h:192
@ SCH_SHEET_PIN_T
Definition: typeinfo.h:161
@ SCH_TEXT_T
Definition: typeinfo.h:152
@ SCH_BUS_WIRE_ENTRY_T
Definition: typeinfo.h:146
@ SCH_BITMAP_T
Definition: typeinfo.h:150
@ SCH_TEXTBOX_T
Definition: typeinfo.h:151
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:156
@ SCH_JUNCTION_T
Definition: typeinfo.h:144
@ SCH_PIN_T
Definition: typeinfo.h:163
constexpr bool IsInstantiableType(const KICAD_T aType)
Definition: typeinfo.h:310
constexpr bool IsEeschemaType(const KICAD_T aType)
Definition: typeinfo.h:369
#define BOOST_TEST_CONTEXT(A)
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588