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_rule_area.h>
37#include <sch_shape.h>
38#include <sch_bitmap.h>
39#include <sch_text.h>
40#include <sch_textbox.h>
41#include <sch_table.h>
42#include <sch_tablecell.h>
43#include <sch_field.h>
44#include <sch_symbol.h>
45#include <sch_sheet_pin.h>
46#include <sch_sheet.h>
47#include <sch_pin.h>
48
49#include <erc/erc_settings.h>
50
52{
53public:
57 std::shared_ptr<ERC_ITEM> m_ercItem;
58
60 m_sheet(),
61 m_symbol( "test symbol" ),
62 m_pin( &m_symbol ),
64 {
67 }
68
70 {
71 if( !IsEeschemaType( aType ) )
72 return nullptr;
73
74 if( !IsInstantiableType( aType ) )
75 return nullptr;
76
77 switch( aType )
78 {
79 case SCH_MARKER_T: return new SCH_MARKER( m_ercItem, VECTOR2I( 0, 0 ) );
80 case SCH_JUNCTION_T: return new SCH_JUNCTION();
81 case SCH_NO_CONNECT_T: return new SCH_NO_CONNECT();
83 case SCH_BUS_BUS_ENTRY_T: return new SCH_BUS_BUS_ENTRY();
84 case SCH_LINE_T: return new SCH_LINE();
85 case SCH_RULE_AREA_T:
86 {
87 SHAPE_POLY_SET ruleShape;
88
89 ruleShape.NewOutline();
90 auto& outline = ruleShape.Outline( 0 );
91 outline.Append( VECTOR2I( 20000, 20000) );
92 outline.Append( VECTOR2I( 22000, 20000) );
93 outline.Append( VECTOR2I( 22000, 22000) );
94 outline.Append( VECTOR2I( 20000, 22000) );
95 outline.SetClosed( true );
96 outline.Simplify( true );
97
98 SCH_RULE_AREA* ruleArea = new SCH_RULE_AREA();
99 ruleArea->SetPolyShape( ruleShape );
100
101 return ruleArea;
102 }
103 case SCH_SHAPE_T: return new SCH_SHAPE( SHAPE_T::ARC, LAYER_NOTES );
104 case SCH_BITMAP_T: return new SCH_BITMAP();
105 case SCH_TEXT_T: return new SCH_TEXT( VECTOR2I( 0, 0 ), "test text" );
106 case SCH_TEXTBOX_T: return new SCH_TEXTBOX( LAYER_NOTES, 0, FILL_T::NO_FILL, "test textbox" );
107 case SCH_TABLECELL_T: return new SCH_TABLECELL();
108 case SCH_TABLE_T:
109 {
110 SCH_TABLE* table = new SCH_TABLE( schIUScale.mmToIU( 0.1 ) );
111
112 table->SetColCount( 2 );
113
114 for( int ii = 0; ii < 4; ++ii )
115 table->InsertCell( ii, new SCH_TABLECELL() );
116
117 return table;
118 }
119 case SCH_LABEL_T: return new SCH_LABEL( VECTOR2I( 0, 0 ), "test label" );
120 case SCH_DIRECTIVE_LABEL_T: return new SCH_DIRECTIVE_LABEL( VECTOR2I( 0, 0 ) );
121 case SCH_GLOBAL_LABEL_T: return new SCH_GLOBALLABEL();
122 case SCH_HIER_LABEL_T: return new SCH_HIERLABEL();
123 case SCH_FIELD_T: return new SCH_FIELD( VECTOR2I( 0, 0 ), 0, nullptr );
124 case SCH_SYMBOL_T: return new SCH_SYMBOL();
125
126 case SCH_SHEET_PIN_T:
127 // XXX: m_sheet pins currently have to have their initial positions calculated manually.
128 return new SCH_SHEET_PIN( &m_sheet,
131 "test aPin" );
132
133 case SCH_SHEET_T: return new SCH_SHEET();
134 case SCH_PIN_T: return new SCH_PIN( &m_symbol );
135
136 case SCHEMATIC_T:
137 case LIB_SYMBOL_T: return nullptr;
138
139 default:
140 BOOST_FAIL( wxString::Format(
141 "Unhandled type: %d "
142 "(if you created a new type you need to handle it in this switch statement)",
143 aType ) );
144 return nullptr;
145 }
146 }
147
148 static void CompareItems( EDA_ITEM* aItem, EDA_ITEM* aOriginalItem )
149 {
150 BOOST_CHECK_EQUAL( aItem->GetPosition(), aOriginalItem->GetPosition() );
151 BOOST_CHECK_EQUAL( aItem->GetBoundingBox().GetTop(),
152 aOriginalItem->GetBoundingBox().GetTop() );
153 BOOST_CHECK_EQUAL( aItem->GetBoundingBox().GetLeft(),
154 aOriginalItem->GetBoundingBox().GetLeft() );
155 BOOST_CHECK_EQUAL( aItem->GetBoundingBox().GetBottom(),
156 aOriginalItem->GetBoundingBox().GetBottom() );
157 BOOST_CHECK_EQUAL( aItem->GetBoundingBox().GetRight(),
158 aOriginalItem->GetBoundingBox().GetRight() );
159 }
160};
161
162
163BOOST_FIXTURE_TEST_SUITE( EeItem, TEST_EE_ITEM_FIXTURE )
164
165
167{
168 for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
169 {
170 KICAD_T type = static_cast<KICAD_T>( i );
171
172 auto item = std::unique_ptr<EDA_ITEM>( Instantiate( type ) );
173
174 if( item == nullptr )
175 continue;
176
177 BOOST_TEST_CONTEXT( "Class: " << item->GetClass() )
178 {
179 IterateOverPositionsAndReferences<EDA_ITEM>(
180 item.get(),
181 []( EDA_ITEM* aOriginalItem, VECTOR2I aRef )
182 {
183 auto item = std::unique_ptr<EDA_ITEM>( aOriginalItem->Clone() );
184 VECTOR2I originalPos = item->GetPosition();
185
186 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item.get() );
187
188 // Move to a point, then go back.
189 // This has to be an identity transformation.
190
191 if( schItem != nullptr )
192 {
193 schItem->Move( aRef );
194 BOOST_CHECK_EQUAL( schItem->GetPosition(), originalPos + aRef );
195
196 schItem->Move( -aRef );
197 }
198
199 CompareItems( item.get(), aOriginalItem );
200 } );
201 }
202 }
203}
204
205
207{
208 for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
209 {
210 KICAD_T type = static_cast<KICAD_T>( i );
211
212 auto item = std::unique_ptr<EDA_ITEM>( Instantiate( type ) );
213
214 if( item == nullptr )
215 continue;
216
217 BOOST_TEST_CONTEXT( "Class: " << item->GetClass() )
218 {
219 // Four equivalent 90 degree rotations are an identity.
220 // (warning: only for items having no autoplaced fields).
221
222 if( item->GetClass() == "SCH_SHEET_PIN" )
223 {
224 auto newItem = std::unique_ptr<EDA_ITEM>( item->Clone() );
225
226 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( newItem.get() );
227
228 if( schItem != nullptr )
229 {
230 schItem->ClearFieldsAutoplaced();
231 // Only rotating pins around the center of parent sheet works.
232 schItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter(), false );
233 schItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter(), false );
234 schItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter(), false );
235 schItem->Rotate( m_sheet.GetBodyBoundingBox().GetCenter(), false );
236 }
237
238 CompareItems( newItem.get(), item.get() );
239 }
240 else
241 {
242 IterateOverPositionsAndReferences<EDA_ITEM>(
243 item.get(),
244 []( EDA_ITEM* aOriginalItem, VECTOR2I aRef )
245 {
246 auto item = std::unique_ptr<EDA_ITEM>( aOriginalItem->Clone() );
247
248 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item.get() );
249
250 if( schItem != nullptr )
251 {
252 schItem->ClearFieldsAutoplaced();
253 schItem->Rotate( aRef, false );
254 schItem->Rotate( aRef, false );
255 schItem->Rotate( aRef, false );
256 schItem->Rotate( aRef, false );
257 }
258
259 CompareItems( item.get(), aOriginalItem );
260 } );
261 }
262 }
263 }
264}
265
266
267BOOST_AUTO_TEST_CASE( MirrorHorizontally )
268{
269 for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
270 {
271 KICAD_T type = static_cast<KICAD_T>( i );
272
273 auto item = std::unique_ptr<EDA_ITEM>( Instantiate( type ) );
274
275 if( item == nullptr )
276 continue;
277
278 BOOST_TEST_CONTEXT( "Class: " << item->GetClass() )
279 {
280 IterateOverPositionsAndReferences<EDA_ITEM>(
281 item.get(),
282 []( EDA_ITEM* aOriginalItem, VECTOR2I aRef )
283 {
284 auto item = std::unique_ptr<EDA_ITEM>( aOriginalItem->Clone() );
285
286 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item.get() );
287
288 // Two mirrorings are an identity
289 // (warning: only for text items having no autoplaced fields).
290 if( schItem != nullptr )
291 {
292 schItem->ClearFieldsAutoplaced();
293 schItem->MirrorHorizontally( aRef.x );
294 schItem->MirrorHorizontally( aRef.x );
295 }
296
297 CompareItems( item.get(), aOriginalItem );
298 } );
299 }
300 }
301}
302
303
304BOOST_AUTO_TEST_CASE( MirrorVertically )
305{
306 for( int i = 0; i < MAX_STRUCT_TYPE_ID; i++ )
307 {
308 KICAD_T type = static_cast<KICAD_T>( i );
309
310 auto item = std::unique_ptr<EDA_ITEM>( Instantiate( type ) );
311
312 if( item == nullptr )
313 continue;
314
315 BOOST_TEST_CONTEXT( "Class: " << item->GetClass() )
316 {
317 IterateOverPositionsAndReferences<EDA_ITEM>(
318 item.get(),
319 []( EDA_ITEM* aOriginalItem, VECTOR2I aRef )
320 {
321 auto item = std::unique_ptr<EDA_ITEM>( aOriginalItem->Clone() );
322
323 SCH_ITEM* schItem = dynamic_cast<SCH_ITEM*>( item.get() );
324
325 // Two mirrorings are an identity
326 // (warning only for text items having no autoplaced fields).
327
328 if( schItem != nullptr )
329 {
330 schItem->ClearFieldsAutoplaced();
331 schItem->MirrorVertically( aRef.y );
332 schItem->MirrorVertically( aRef.y );
333 }
334
335 CompareItems( item.get(), aOriginalItem );
336 } );
337 }
338 }
339}
340
341BOOST_AUTO_TEST_SUITE_END()
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:110
coord_type GetTop() const
Definition: box2.h:219
coord_type GetRight() const
Definition: box2.h:207
coord_type GetLeft() const
Definition: box2.h:218
coord_type GetBottom() const
Definition: box2.h:212
A base class for most all the KiCad significant classes used in schematics and boards.
Definition: eda_item.h:89
virtual VECTOR2I GetPosition() const
Definition: eda_item.h:243
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
Definition: eda_item.cpp:74
void SetPolyShape(const SHAPE_POLY_SET &aShape)
Definition: eda_shape.h:287
Define a library symbol object.
Definition: lib_symbol.h:78
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:166
void ClearFieldsAutoplaced()
Definition: sch_item.h:551
virtual void Rotate(const VECTOR2I &aCenter, bool aRotateCCW)
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_item.h:359
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:41
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:1002
VECTOR2I GetPosition() const override
Definition: sch_sheet.h:400
Schematic symbol object.
Definition: sch_symbol.h:106
void SetColCount(int aCount)
Definition: sch_table.h:103
void InsertCell(int aIdx, SCH_TABLECELL *aCell)
Definition: sch_table.h:152
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
Represent a set of closed polygons.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int NewOutline()
Creates a new empty polygon in the set and returns its index.
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:66
@ LAYER_NOTES
Definition: layer_ids.h:372
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:165
@ SCH_LINE_T
Definition: typeinfo.h:163
@ LIB_SYMBOL_T
Definition: typeinfo.h:148
@ SCH_NO_CONNECT_T
Definition: typeinfo.h:160
@ MAX_STRUCT_TYPE_ID
Definition: typeinfo.h:236
@ SCH_SYMBOL_T
Definition: typeinfo.h:172
@ SCH_TABLECELL_T
Definition: typeinfo.h:166
@ SCH_FIELD_T
Definition: typeinfo.h:150
@ SCH_DIRECTIVE_LABEL_T
Definition: typeinfo.h:171
@ SCH_LABEL_T
Definition: typeinfo.h:167
@ SCH_SHEET_T
Definition: typeinfo.h:174
@ SCH_MARKER_T
Definition: typeinfo.h:158
@ SCH_SHAPE_T
Definition: typeinfo.h:149
@ SCH_RULE_AREA_T
Definition: typeinfo.h:170
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:169
@ SCH_BUS_BUS_ENTRY_T
Definition: typeinfo.h:162
@ SCHEMATIC_T
Definition: typeinfo.h:203
@ SCH_SHEET_PIN_T
Definition: typeinfo.h:173
@ SCH_TEXT_T
Definition: typeinfo.h:151
@ SCH_BUS_WIRE_ENTRY_T
Definition: typeinfo.h:161
@ SCH_BITMAP_T
Definition: typeinfo.h:164
@ SCH_TEXTBOX_T
Definition: typeinfo.h:152
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:168
@ SCH_JUNCTION_T
Definition: typeinfo.h:159
@ SCH_PIN_T
Definition: typeinfo.h:153
constexpr bool IsInstantiableType(const KICAD_T aType)
Definition: typeinfo.h:307
constexpr bool IsEeschemaType(const KICAD_T aType)
Definition: typeinfo.h:366
#define BOOST_TEST_CONTEXT(A)
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:673