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  // Include in BOM support tests.
342  testPart.SetIncludeInBom( false );
343  BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
344  testPart.SetIncludeInBom( true );
345  m_part_no_data.SetIncludeInBom( false );
346  BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
347  m_part_no_data.SetIncludeInBom( true );
348 
349  // Include on board support tests.
350  testPart.SetIncludeOnBoard( false );
351  BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
352  testPart.SetIncludeOnBoard( true );
353  m_part_no_data.SetIncludeOnBoard( false );
354  BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
355  m_part_no_data.SetIncludeOnBoard( true );
356 
357  // Show pin names flag comparison tests.
358  m_part_no_data.SetShowPinNames( false );
359  BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
360  m_part_no_data.SetShowPinNames( true );
361  testPart.SetShowPinNames( false );
362  BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
363  testPart.SetShowPinNames( true );
364 
365  // Show pin numbers flag comparison tests.
366  m_part_no_data.SetShowPinNumbers( false );
367  BOOST_CHECK( m_part_no_data.Compare( testPart ) < 0 );
368  m_part_no_data.SetShowPinNumbers( true );
369  testPart.SetShowPinNumbers( false );
370  BOOST_CHECK( m_part_no_data.Compare( testPart ) > 0 );
371  testPart.SetShowPinNumbers( true );
372 
373  // Time stamp comparison tests.
374 }
375 
376 
380 BOOST_AUTO_TEST_CASE( GetUnitItems )
381 {
382  // There are no unit draw items in the empty LIB_PART object.
383  BOOST_CHECK( m_part_no_data.GetUnitItems( 1, 1 ).size() == 0 );
384 
385  // A single unique unit with 1 pin common to all units and all body styles.
386  LIB_PIN* pin1 = new LIB_PIN( &m_part_no_data );
387  m_part_no_data.AddDrawItem( pin1 );
388  BOOST_CHECK( m_part_no_data.GetUnitItems( 0, 0 ).size() == 1 );
389 
390  // A single unique unit with 1 pin in unit 1 and common to all body styles.
391  pin1->SetUnit( 1 );
392  BOOST_CHECK( m_part_no_data.GetUnitItems( 1, 0 ).size() == 1 );
393 
394  // A single unique unit with 1 pin in unit 1 and body style 1.
395  pin1->SetConvert( 1 );
396  BOOST_CHECK( m_part_no_data.GetUnitItems( 1, 1 ).size() == 1 );
397 
398  // Two unique units with pin 1 assigned to unit 1 and body style 1 and pin 2 assinged to
399  // unit 2 and body style 1.
400  LIB_PIN* pin2 = new LIB_PIN( &m_part_no_data );
401  m_part_no_data.SetUnitCount( 2 );
402  pin2->SetUnit( 2 );
403  pin2->SetConvert( 2 );
404  pin2->SetNumber( "4" );
405  m_part_no_data.AddDrawItem( pin2 );
406  BOOST_CHECK( m_part_no_data.GetUnitItems( 2, 2 ).size() == 1 );
407 
408  // Make pin 1 body style common to all units.
409  pin1->SetConvert( 0 );
410  BOOST_CHECK( m_part_no_data.GetUnitItems( 1, 1 ).size() == 0 );
411  BOOST_CHECK( m_part_no_data.GetUnitItems( 2, 1 ).size() == 1 );
412 
413  m_part_no_data.RemoveDrawItem( pin2 );
414  m_part_no_data.RemoveDrawItem( pin1 );
415  m_part_no_data.RemoveDrawItem( m_part_no_data.GetNextDrawItem() );
416 }
417 
418 
422 BOOST_AUTO_TEST_CASE( GetUnitDrawItems )
423 {
424  // There are no unit draw items in the empty LIB_PART object.
425  BOOST_CHECK( m_part_no_data.GetUnitDrawItems().size() == 0 );
426 
427  // A single unique unit with 1 pin common to all units and all body styles.
428  LIB_PIN* pin1 = new LIB_PIN( &m_part_no_data );
429  pin1->SetNumber( "1" );
430  m_part_no_data.AddDrawItem( pin1 );
431  std::vector<struct PART_UNITS> units = m_part_no_data.GetUnitDrawItems();
432  BOOST_CHECK( units.size() == 1 );
433  BOOST_CHECK( units[0].m_unit == 0 );
434  BOOST_CHECK( units[0].m_convert == 0 );
435  BOOST_CHECK( units[0].m_items[0] == pin1 );
436 }
437 
438 
442 BOOST_AUTO_TEST_CASE( Inheritance )
443 {
444  std::unique_ptr<LIB_PART> parent = std::make_unique<LIB_PART>( "parent" );
445  BOOST_CHECK( parent->IsRoot() );
446  std::unique_ptr<LIB_PART> child1 = std::make_unique<LIB_PART>( "child1", parent.get() );
447  BOOST_CHECK( child1->IsAlias() );
448  PART_SPTR parentRef = child1->GetParent().lock();
449  BOOST_CHECK( parentRef );
450  BOOST_CHECK( parentRef == parent->SharedPtr() );
451  BOOST_CHECK_EQUAL( parent->SharedPtr().use_count(), 3 );
452  BOOST_CHECK_EQUAL( child1->GetUnitCount(), 1 );
453  parent->SetUnitCount( 4 );
454  BOOST_CHECK_EQUAL( child1->GetUnitCount(), 4 );
455  child1->SetParent();
456  BOOST_CHECK_EQUAL( child1->GetUnitCount(), 1 );
457  parentRef.reset();
458  BOOST_CHECK_EQUAL( parent->SharedPtr().use_count(), 2 );
459 }
460 
461 
465 BOOST_AUTO_TEST_CASE( CopyConstructor )
466 {
467  std::shared_ptr<LIB_PART> copy = std::make_shared<LIB_PART>( m_part_no_data );
468  BOOST_CHECK( m_part_no_data == *copy.get() );
469 }
470 
471 
472 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
void SetIncludeInBom(bool aIncludeInBom)
Set or clear the include in schematic bill of materials flag.
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:62
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.
void SetIncludeOnBoard(bool aIncludeOnBoard)
Set or clear include in board netlist flag.
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()