KiCad PCB EDA Suite
test_lib_part.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) 2019-2020 KiCad Developers, see CHANGELOG.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 
30 
31 // Code under test
32 #include <class_libentry.h>
33 #include <lib_rectangle.h>
34 #include <lib_arc.h>
35 #include <lib_pin.h>
36 
37 #include "lib_field_test_utils.h"
38 
40 {
41 public:
43  m_part_no_data( "part_name", nullptr )
44  {
45  }
46 
49 };
50 
51 
55 BOOST_FIXTURE_TEST_SUITE( LibPart, TEST_LIB_PART_FIXTURE )
56 
57 
58 
61 BOOST_AUTO_TEST_CASE( DefaultProperties )
62 {
63  BOOST_CHECK_EQUAL( m_part_no_data.GetName(), "part_name" );
64 
65  // Didn't set a library, so this is empty
66  BOOST_CHECK_EQUAL( m_part_no_data.GetLibraryName(), "" );
67  BOOST_CHECK_EQUAL( m_part_no_data.GetLib(), nullptr );
68 
69  // only get the root
70  BOOST_CHECK_EQUAL( m_part_no_data.IsRoot(), true );
71  BOOST_CHECK_EQUAL( m_part_no_data.IsAlias(), false );
72  BOOST_CHECK_EQUAL( m_part_no_data.SharedPtr().use_count(), 2 );
73 
74  // no sub units
75  BOOST_CHECK_EQUAL( m_part_no_data.GetUnitCount(), 1 );
76  BOOST_CHECK_EQUAL( m_part_no_data.IsMulti(), false );
77 
78  // no conversion
79  BOOST_CHECK_EQUAL( m_part_no_data.HasConversion(), false );
80 }
81 
82 
86 BOOST_AUTO_TEST_CASE( DefaultDrawings )
87 {
88  // default drawings exist
89  BOOST_CHECK_EQUAL( m_part_no_data.GetDrawItems().size(), 4 );
90  BOOST_CHECK_EQUAL( m_part_no_data.GetNextDrawItem( NULL, LIB_PIN_T ), (LIB_ITEM*)NULL );
91 }
92 
93 
97 BOOST_AUTO_TEST_CASE( DefaultFields )
98 {
99  LIB_FIELDS fields;
100  m_part_no_data.GetFields( fields );
101 
102  // Should get the 4 default fields
103  BOOST_CHECK_PREDICATE( KI_TEST::AreDefaultFieldsCorrect, ( fields ) );
104 
105  // but no more (we didn't set them)
106  BOOST_CHECK_EQUAL( fields.size(), NumFieldType::MANDATORY_FIELDS );
107 
108  // also check the default field accessors
109  BOOST_CHECK_PREDICATE( KI_TEST::FieldNameIdMatches,
110  ( m_part_no_data.GetReferenceField() )( "Reference" )( NumFieldType::REFERENCE ) );
111  BOOST_CHECK_PREDICATE( KI_TEST::FieldNameIdMatches,
112  ( m_part_no_data.GetValueField() )( "Value" )( NumFieldType::VALUE ) );
113  BOOST_CHECK_PREDICATE( KI_TEST::FieldNameIdMatches,
114  ( m_part_no_data.GetFootprintField() )( "Footprint" )( NumFieldType::FOOTPRINT ) );
115 }
116 
117 
121 BOOST_AUTO_TEST_CASE( AddedFields )
122 {
123  LIB_FIELDS fields;
124  m_part_no_data.GetFields( fields );
125 
126  // Ctor takes non-const ref (?!)
127  const std::string newFieldName = "new_field";
128  wxString nonConstNewFieldName = newFieldName;
129  fields.push_back( LIB_FIELD( 42, nonConstNewFieldName ) );
130 
131  // fairly roundabout way to add a field, but it is what it is
132  m_part_no_data.SetFields( fields );
133 
134  // Should get the 4 default fields
135  BOOST_CHECK_PREDICATE( KI_TEST::AreDefaultFieldsCorrect, ( fields ) );
136 
137  // and our new one
138  BOOST_REQUIRE_EQUAL( fields.size(), NumFieldType::MANDATORY_FIELDS + 1 );
139 
140  BOOST_CHECK_PREDICATE( KI_TEST::FieldNameIdMatches,
141  ( fields[NumFieldType::MANDATORY_FIELDS] )( newFieldName )( 42 ) );
142 
143  // Check by-id lookup
144 
145  LIB_FIELD* gotNewField = m_part_no_data.GetField( 42 );
146 
147  BOOST_REQUIRE_NE( gotNewField, nullptr );
148 
149  BOOST_CHECK_PREDICATE( KI_TEST::FieldNameIdMatches, ( *gotNewField )( newFieldName )( 42 ) );
150 
151  // Check by-name lookup
152 
153  gotNewField = m_part_no_data.FindField( newFieldName );
154 
155  BOOST_REQUIRE_NE( gotNewField, nullptr );
156  BOOST_CHECK_PREDICATE( KI_TEST::FieldNameIdMatches, ( *gotNewField )( newFieldName )( 42 ) );
157 }
158 
159 
163 BOOST_AUTO_TEST_CASE( AddedDrawItems )
164 {
165 }
166 
167 
169 {
170  int m_index;
171  bool m_addSep;
172  std::string m_expSubRef;
173 };
174 
175 
179 BOOST_AUTO_TEST_CASE( SubReference )
180 {
181  const std::vector<TEST_LIB_PART_SUBREF_CASE> cases = {
182  {
183  1,
184  false,
185  "A",
186  },
187  {
188  2,
189  false,
190  "B",
191  },
192  {
193  26,
194  false,
195  "Z",
196  },
197  {
198  27,
199  false,
200  "AA",
201  },
202  { // haven't configured a separator, so should be nothing
203  1,
204  true,
205  "A",
206  },
207  };
208 
209  for( const auto& c : cases )
210  {
212  "Subref: " << c.m_index << ", " << c.m_addSep << " -> '" << c.m_expSubRef << "'" )
213  {
214  const auto subref = m_part_no_data.SubReference( c.m_index, c.m_addSep );
215  BOOST_CHECK_EQUAL( subref, c.m_expSubRef );
216  }
217  }
218 }
219 
220 
225 {
226  // Identical root part to m_part_no_data sans time stamp.
227  LIB_PART testPart( "part_name" );
228 
229  // Self comparison test.
230  BOOST_CHECK_EQUAL( m_part_no_data.Compare( m_part_no_data ), 0 );
231 
232  // Test for identical LIB_PART.
233  BOOST_CHECK_EQUAL( m_part_no_data.Compare( testPart ), 0 );
234 
235  // Test name.
236  testPart.SetName( "tart_name" );
237  BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
238  testPart.SetName( "cart_name" );
239  BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
240  testPart.SetName( "part_name" );
241 
242  // LIB_ID comparison tests.
243  LIB_ID id = testPart.GetLibId();
244  id.SetLibItemName( "tart_name" );
245  testPart.SetLibId( id );
246  BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
247  id.SetLibItemName( "cart_name" );
248  testPart.SetLibId( id );
249  BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
250  id.SetLibItemName( "part_name" );
251  testPart.SetLibId( id );
252 
253  // Unit count comparison tests.
254  testPart.SetUnitCount( 2 );
255  BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
256  testPart.SetUnitCount( 1 );
257  m_part_no_data.SetUnitCount( 2 );
258  BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
259  m_part_no_data.SetUnitCount( 1 );
260 
261  // Options flag comparison tests.
262  testPart.SetPower();
263  BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
264  testPart.SetNormal();
265  m_part_no_data.SetPower();
266  BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
267  m_part_no_data.SetNormal();
268 
269  // Draw item list size comparison tests.
270  testPart.AddDrawItem( new LIB_RECTANGLE( &testPart ) );
271  m_part_no_data.AddDrawItem( new LIB_RECTANGLE( &m_part_no_data ) );
272  BOOST_CHECK_EQUAL( m_part_no_data.Compare( testPart ), 0 );
273  m_part_no_data.RemoveDrawItem( m_part_no_data.GetNextDrawItem( nullptr, LIB_RECTANGLE_T ) );
274  BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
275  testPart.RemoveDrawItem( testPart.GetNextDrawItem( nullptr, LIB_RECTANGLE_T ) );
276  m_part_no_data.AddDrawItem( new LIB_RECTANGLE( &m_part_no_data ) );
277  BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
278  m_part_no_data.RemoveDrawItem( m_part_no_data.GetNextDrawItem( nullptr, LIB_RECTANGLE_T ) );
279 
280  // Draw item list contents comparison tests.
281  testPart.AddDrawItem( new LIB_RECTANGLE( &testPart ) );
282  m_part_no_data.AddDrawItem( new LIB_ARC( &m_part_no_data ) );
283  BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
284  m_part_no_data.RemoveDrawItem( m_part_no_data.GetNextDrawItem( nullptr, LIB_ARC_T ) );
285  m_part_no_data.AddDrawItem( new LIB_PIN( &m_part_no_data ) );
286  BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
287  m_part_no_data.RemoveDrawItem( m_part_no_data.GetNextDrawItem( nullptr, LIB_PIN_T ) );
288  testPart.RemoveDrawItem( testPart.GetNextDrawItem( nullptr, LIB_RECTANGLE_T ) );
289 
290  // Footprint filter array comparison tests.
291  wxArrayString footPrintFilters;
292  BOOST_CHECK( m_part_no_data.GetFootprints() == footPrintFilters );
293  footPrintFilters.Add( "b" );
294  testPart.SetFootprintFilters( footPrintFilters );
295  BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
296  m_part_no_data.SetFootprintFilters( footPrintFilters );
297  footPrintFilters.Clear();
298  testPart.SetFootprintFilters( footPrintFilters );
299  BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
300  footPrintFilters.Clear();
301  m_part_no_data.SetFootprintFilters( footPrintFilters );
302  testPart.SetFootprintFilters( footPrintFilters );
303 
304  // Description string tests.
305  m_part_no_data.SetDescription( "b" );
306  testPart.SetDescription( "b" );
307  BOOST_CHECK_EQUAL( m_part_no_data.Compare( testPart ), 0 );
308  m_part_no_data.SetDescription( "a" );
309  BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
310  m_part_no_data.SetDescription( "c" );
311  BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
312  m_part_no_data.SetDescription( wxEmptyString );
313  testPart.SetDescription( wxEmptyString );
314 
315  // Key word string tests.
316  m_part_no_data.SetKeyWords( "b" );
317  testPart.SetKeyWords( "b" );
318  BOOST_CHECK_EQUAL( m_part_no_data.Compare( testPart ), 0 );
319  m_part_no_data.SetKeyWords( "a" );
320  BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
321  m_part_no_data.SetKeyWords( "c" );
322  BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
323  m_part_no_data.SetKeyWords( wxEmptyString );
324  testPart.SetKeyWords( wxEmptyString );
325 
326  // Pin name offset comparison tests.
327  testPart.SetPinNameOffset( testPart.GetPinNameOffset() + 1 );
328  BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
329  testPart.SetPinNameOffset( testPart.GetPinNameOffset() - 2 );
330  BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
331  testPart.SetPinNameOffset( testPart.GetPinNameOffset() + 1 );
332 
333  // Units locked flag comparision tests.
334  testPart.LockUnits( true );
335  BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
336  testPart.LockUnits( false );
337  m_part_no_data.LockUnits( true );
338  BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
339  m_part_no_data.LockUnits( false );
340 
341  // Show pin names flag comparison tests.
342  m_part_no_data.SetShowPinNames( false );
343  BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
344  m_part_no_data.SetShowPinNames( true );
345  testPart.SetShowPinNames( false );
346  BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
347  testPart.SetShowPinNames( true );
348 
349  // Show pin numbers flag comparison tests.
350  m_part_no_data.SetShowPinNumbers( false );
351  BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
352  m_part_no_data.SetShowPinNumbers( true );
353  testPart.SetShowPinNumbers( false );
354  BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
355  testPart.SetShowPinNumbers( true );
356 
357  // Time stamp comparison tests.
358 }
359 
360 
364 BOOST_AUTO_TEST_CASE( GetUnitItems )
365 {
366  // There are no unit draw items in the empty LIB_PART object.
367  BOOST_CHECK( m_part_no_data.GetUnitItems( 1, 1 ).size() == 0 );
368 
369  // A single unique unit with 1 pin common to all units and all body styles.
370  LIB_PIN* pin1 = new LIB_PIN( &m_part_no_data );
371  m_part_no_data.AddDrawItem( pin1 );
372  BOOST_CHECK( m_part_no_data.GetUnitItems( 0, 0 ).size() == 1 );
373 
374  // A single unique unit with 1 pin in unit 1 and common to all body styles.
375  pin1->SetUnit( 1 );
376  BOOST_CHECK( m_part_no_data.GetUnitItems( 1, 0 ).size() == 1 );
377 
378  // A single unique unit with 1 pin in unit 1 and body style 1.
379  pin1->SetConvert( 1 );
380  BOOST_CHECK( m_part_no_data.GetUnitItems( 1, 1 ).size() == 1 );
381 
382  // Two unique units with pin 1 assigned to unit 1 and body style 1 and pin 2 assinged to
383  // unit 2 and body style 1.
384  LIB_PIN* pin2 = new LIB_PIN( &m_part_no_data );
385  m_part_no_data.SetUnitCount( 2 );
386  pin2->SetUnit( 2 );
387  pin2->SetConvert( 2 );
388  pin2->SetNumber( "4" );
389  m_part_no_data.AddDrawItem( pin2 );
390  BOOST_CHECK( m_part_no_data.GetUnitItems( 2, 2 ).size() == 1 );
391 
392  // Make pin 1 body style common to all units.
393  pin1->SetConvert( 0 );
394  BOOST_CHECK( m_part_no_data.GetUnitItems( 1, 1 ).size() == 0 );
395  BOOST_CHECK( m_part_no_data.GetUnitItems( 2, 1 ).size() == 1 );
396 
397  m_part_no_data.RemoveDrawItem( pin2 );
398  m_part_no_data.RemoveDrawItem( pin1 );
399  m_part_no_data.RemoveDrawItem( m_part_no_data.GetNextDrawItem() );
400 }
401 
402 
406 BOOST_AUTO_TEST_CASE( GetUnitDrawItems )
407 {
408  // There are no unit draw items in the empty LIB_PART object.
409  BOOST_CHECK( m_part_no_data.GetUnitDrawItems().size() == 0 );
410 
411  // A single unique unit with 1 pin common to all units and all body styles.
412  LIB_PIN* pin1 = new LIB_PIN( &m_part_no_data );
413  pin1->SetNumber( "1" );
414  m_part_no_data.AddDrawItem( pin1 );
415  std::vector<struct PART_UNITS> units = m_part_no_data.GetUnitDrawItems();
416  BOOST_CHECK( units.size() == 1 );
417  BOOST_CHECK( units[0].m_unit == 0 );
418  BOOST_CHECK( units[0].m_convert == 0 );
419  BOOST_CHECK( units[0].m_items[0] == pin1 );
420 }
421 
422 
426 BOOST_AUTO_TEST_CASE( Inheritance )
427 {
428  std::unique_ptr< LIB_PART > parent( new LIB_PART( "parent" ) );
429  BOOST_CHECK( parent->IsRoot() );
430  std::unique_ptr< LIB_PART > child1( new LIB_PART( "child1", parent.get() ) );
431  BOOST_CHECK( child1->IsAlias() );
432  PART_SPTR parentRef = child1->GetParent().lock();
433  BOOST_CHECK( parentRef );
434  BOOST_CHECK( parentRef == parent->SharedPtr() );
435  BOOST_CHECK_EQUAL( parent->SharedPtr().use_count(), 3 );
436  BOOST_CHECK_EQUAL( child1->GetUnitCount(), 1 );
437  parent->SetUnitCount( 4 );
438  BOOST_CHECK_EQUAL( child1->GetUnitCount(), 4 );
439  child1->SetParent();
440  BOOST_CHECK_EQUAL( child1->GetUnitCount(), 1 );
441  parentRef.reset();
442  BOOST_CHECK_EQUAL( parent->SharedPtr().use_count(), 2 );
443 }
444 
445 
449 BOOST_AUTO_TEST_CASE( CopyConstructor )
450 {
451  std::shared_ptr< LIB_PART > copy( new LIB_PART( m_part_no_data ) );
452  BOOST_CHECK( m_part_no_data == *copy.get() );
453 }
454 
455 
456 BOOST_AUTO_TEST_SUITE_END()
void SetPower()
LIB_ID GetLibId() const override
int GetPinNameOffset()
LIB_ITEM * GetNextDrawItem(LIB_ITEM *aItem=NULL, KICAD_T aType=TYPE_NOT_INIT)
Return the next draw object pointer.
The first 4 are mandatory, and must be instantiated in SCH_COMPONENT and LIB_PART constructors.
Field object used in symbol libraries.
Definition: lib_field.h:59
void SetUnitCount(int aCount, bool aDuplicateDrawItems=true)
Set the units per part count.
void SetFootprintFilters(const wxArrayString &aFootprintFilters)
bool AreDefaultFieldsCorrect(const LIB_FIELDS &aFields)
Predicate to check that the mandatory fields in a LIB_FIELDS object look sensible.
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:51
Field Name Module PCB, i.e. "16DIP300".
Field Reference of part, i.e. "IC21".
The base class for drawable items used by schematic library components.
Definition: lib_item.h:61
void AddDrawItem(LIB_ITEM *aItem)
Add a new draw aItem to the draw object list.
#define NULL
std::shared_ptr< LIB_PART > PART_SPTR
shared pointer to LIB_PART
void SetDescription(const wxString &aDescription)
Define a library symbol object.
#define BOOST_TEST_CONTEXT(A)
int SetLibItemName(const UTF8 &aLibItemName, bool aTestForRev=true)
Override the library item name portion of the LIB_ID to aLibItemName.
Definition: lib_id.cpp:206
Field Value of part, i.e. "3.3K".
void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
std::vector< LIB_FIELD > LIB_FIELDS
Definition: lib_field.h:218
void SetKeyWords(const wxString &aKeyWords)
LIB_PART m_part_no_data
Part with no extra data set
virtual void SetName(const wxString &aName)
BOOST_AUTO_TEST_CASE(DefaultProperties)
Declare the test suite.
Test utils (e.g.
void SetShowPinNames(bool aShow)
Set or clear the pin name visibility flag.
void SetPinNameOffset(int aOffset)
Set the offset in mils of the pin name text from the pin symbol.
void SetLibId(const LIB_ID &aLibId)
bool FieldNameIdMatches(const LIB_FIELD &aField, const std::string &aExpectedName, int aExpectedId)
Predicate to check a field name is as expected.
void LockUnits(bool aLockUnits)
Set interchangeable the property for part units.
void RemoveDrawItem(LIB_ITEM *aItem)
Remove draw aItem from list.
void SetNormal()