37#include <wx/filename.h>
56 std::unique_ptr<LIB_SYMBOL> symbol = std::make_unique<LIB_SYMBOL>( wxS(
"Symbol" ) );
57 std::unique_ptr<SCH_SCREEN> screen = std::make_unique<SCH_SCREEN>();
61 SYMBOL_BUFFER buffer( std::move( symbol ), std::move( screen ) );
64 BOOST_CHECK( &buffer.
GetSymbol() == &symbolRef );
70 std::unique_ptr<LIB_SYMBOL> originalSymbol =
71 std::make_unique<LIB_SYMBOL>( wxS(
"OriginalSymbol" ) );
72 LIB_SYMBOL& originalSymbolRef = *originalSymbol;
76 BOOST_CHECK( &buffer.
GetOriginal() == &originalSymbolRef );
77 BOOST_CHECK( buffer.
GetOriginal() == originalSymbolRef );
87 wxArrayString symbolNames;
93 auto parentSymbol1 = std::make_unique<LIB_SYMBOL>( wxS(
"Parent1" ) );
100 parentSymbol1->GetValueField().SetText( parentSymbol1->GetName() );
101 libBuffer.
CreateBuffer( std::move( parentSymbol1 ), std::make_unique<SCH_SCREEN>() );
102 BOOST_CHECK( libBuffer.
GetSymbol( parentSymbol1Ref.
GetName() ) == &parentSymbol1Ref );
119 auto childSymbol1 = std::make_unique<LIB_SYMBOL>( wxS(
"Child1" ) );
122 childSymbol1->
SetParent( &parentSymbol1Ref );
123 childSymbol1->GetValueField().SetText( childSymbol1->GetName() );
124 libBuffer.
CreateBuffer( std::move( childSymbol1 ), std::make_unique<SCH_SCREEN>() );
125 BOOST_CHECK( libBuffer.
GetSymbol( childSymbol1Ref.
GetName() ) == &childSymbol1Ref );
146 std::shared_ptr<SYMBOL_BUFFER> buf = libBuffer.
GetBuffer( parentSymbol1Ref.
GetName() );
156 BOOST_CHECK( deletedOk );
157 BOOST_CHECK( libBuffer.
GetBuffers().empty() );
168 props.
name = wxS(
"Standalone" );
181 std::unique_ptr<LIB_SYMBOL> standalone =
186 BOOST_CHECK( standalone->GetPinNameOffset() > 0 );
188 auto parent = std::make_unique<LIB_SYMBOL>( wxS(
"Parent" ) );
189 parent->GetValueField().SetText( parent->GetName() );
192 parent->AddField( user );
194 props.
name = wxS(
"Child" );
201 std::unique_ptr<LIB_SYMBOL> child =
204 BOOST_CHECK( child->GetParent().lock().get() == parent.get() );
205 BOOST_CHECK( child->GetFootprintField().GetText().IsEmpty() );
206 BOOST_CHECK( child->GetDatasheetField().GetText().IsEmpty() );
208 std::vector<SCH_FIELD*> childFields;
209 child->GetFields( childFields );
218 BOOST_CHECK( field->GetText().IsEmpty() );
222 BOOST_CHECK( found );
235 props.
name = wxS(
"+5V" );
266 wxString tempDir = wxFileName::CreateTempFileName( wxS(
"kicad_test_" ) );
267 wxRemoveFile( tempDir );
268 wxFileName::Mkdir( tempDir );
269 wxString libPath = wxFileName( tempDir, wxS(
"test_lib.kicad_sym" ) ).GetFullPath();
274 plugin->CreateLibrary( libPath );
277 std::unique_ptr<LIB_SYMBOL> parentSymbol = std::make_unique<LIB_SYMBOL>( wxS(
"Parent" ) );
278 parentSymbol->GetValueField().SetText( wxS(
"Parent" ) );
279 parentSymbol->GetReferenceField().SetText( wxS(
"U" ) );
282 plugin->SaveSymbol( libPath, std::make_unique<LIB_SYMBOL>( *parentSymbol ) );
285 std::unique_ptr<LIB_SYMBOL> derivedSymbol = std::make_unique<LIB_SYMBOL>( wxS(
"Derived" ) );
286 derivedSymbol->GetValueField().SetText( wxS(
"Derived" ) );
287 derivedSymbol->SetParent( parentPtr );
289 plugin->SaveSymbol( libPath, std::make_unique<LIB_SYMBOL>( *derivedSymbol ) );
290 plugin->SaveLibrary( libPath );
296 LIB_SYMBOL* parent = plugin->LoadSymbol( libPath, wxS(
"Parent" ) );
297 LIB_SYMBOL* derived = plugin->LoadSymbol( libPath, wxS(
"Derived" ) );
309 LIB_SYMBOL* loadedParent = plugin->LoadSymbol( libPath, wxS(
"Parent" ) );
310 LIB_SYMBOL* loadedDerived = plugin->LoadSymbol( libPath, wxS(
"Derived" ) );
316 loadedDerived->
SetParent( loadedParent );
319 libBuffer.
CreateBuffer( std::make_unique<LIB_SYMBOL>( *loadedParent ),
320 std::make_unique<SCH_SCREEN>() );
322 std::unique_ptr<LIB_SYMBOL> derivedCopy = std::make_unique<LIB_SYMBOL>( *loadedDerived );
323 derivedCopy->SetParent( libBuffer.
GetSymbol( wxS(
"Parent" ) ) );
324 libBuffer.
CreateBuffer( std::move( derivedCopy ), std::make_unique<SCH_SCREEN>() );
329 BOOST_CHECK( libBuffer.
GetSymbol( wxS(
"Parent" ) ) !=
nullptr );
330 BOOST_CHECK( libBuffer.
GetSymbol( wxS(
"Derived" ) ) !=
nullptr );
333 std::shared_ptr<SYMBOL_BUFFER> derivedBuf = libBuffer.
GetBuffer( wxS(
"Derived" ) );
336 bool deleteResult = libBuffer.
DeleteBuffer( *derivedBuf );
337 BOOST_CHECK( deleteResult );
341 BOOST_CHECK( libBuffer.
GetSymbol( wxS(
"Parent" ) ) !=
nullptr );
342 BOOST_CHECK( libBuffer.
GetSymbol( wxS(
"Derived" ) ) ==
nullptr );
347 std::map<std::string, UTF8> properties;
351 for(
const std::shared_ptr<SYMBOL_BUFFER>& symbolBuf : libBuffer.
GetBuffers() )
353 libBuffer.
SaveBuffer( *symbolBuf, libPath, &*plugin,
true );
357 for(
const std::shared_ptr<SYMBOL_BUFFER>& deletedBuf : libBuffer.
GetDeletedBuffers() )
359 const wxString& originalName = deletedBuf->GetOriginal().GetName();
361 if( plugin->LoadSymbol( libPath, originalName ) )
362 plugin->DeleteSymbol( libPath, originalName, &properties );
365 plugin->SaveLibrary( libPath );
373 LIB_SYMBOL* parent = plugin->LoadSymbol( libPath, wxS(
"Parent" ) );
374 LIB_SYMBOL* derived = plugin->LoadSymbol( libPath, wxS(
"Derived" ) );
376 BOOST_CHECK( parent !=
nullptr );
378 BOOST_CHECK_MESSAGE( derived ==
nullptr,
379 "Derived symbol should have been deleted from the library file" );
383 if( wxFileName::DirExists( tempDir ) )
385 wxFileName::Rmdir( tempDir, wxPATH_RMDIR_RECURSIVE );
403 wxString tempDir = wxFileName::CreateTempFileName( wxS(
"kicad_test_" ) );
404 wxRemoveFile( tempDir );
405 wxFileName::Mkdir( tempDir );
407 wxString srcPath = wxFileName( tempDir, wxS(
"source.kicad_sym" ) ).GetFullPath();
408 wxString dstPath = wxFileName( tempDir, wxS(
"destination.kicad_sym" ) ).GetFullPath();
413 plugin->CreateLibrary( srcPath );
415 auto parent = std::make_unique<LIB_SYMBOL>( wxS(
"Parent" ) );
416 parent->GetValueField().SetText( wxS(
"Parent" ) );
417 parent->GetReferenceField().SetText( wxS(
"U" ) );
420 plugin->SaveSymbol( srcPath, std::make_unique<LIB_SYMBOL>( *parent ) );
422 auto derived = std::make_unique<LIB_SYMBOL>( wxS(
"Derived" ) );
423 derived->GetValueField().SetText( wxS(
"Derived" ) );
424 derived->SetParent( parentPtr );
426 plugin->SaveSymbol( srcPath, std::make_unique<LIB_SYMBOL>( *derived ) );
427 plugin->SaveLibrary( srcPath );
435 std::map<std::string, UTF8> properties;
438 LIB_SYMBOL* loadedParent = srcPlugin->LoadSymbol( srcPath, wxS(
"Parent" ) );
439 LIB_SYMBOL* loadedDerived = srcPlugin->LoadSymbol( srcPath, wxS(
"Derived" ) );
445 BOOST_CHECK_NO_THROW(
446 dstPlugin->SaveSymbol( dstPath, std::make_unique<LIB_SYMBOL>( *loadedParent ),
449 auto newDerived = std::make_unique<LIB_SYMBOL>( *loadedDerived );
450 LIB_SYMBOL* dstParent = dstPlugin->LoadSymbol( dstPath, wxS(
"Parent" ), &properties );
452 newDerived->SetParent( dstParent );
454 BOOST_CHECK_NO_THROW(
455 dstPlugin->SaveSymbol( dstPath, std::move( newDerived ), &properties ) );
457 BOOST_CHECK_NO_THROW( dstPlugin->SaveLibrary( dstPath ) );
464 LIB_SYMBOL* parent = plugin->LoadSymbol( dstPath, wxS(
"Parent" ) );
465 LIB_SYMBOL* derived = plugin->LoadSymbol( dstPath, wxS(
"Derived" ) );
467 BOOST_CHECK_MESSAGE( parent !=
nullptr,
468 "Parent symbol should exist in the saved-as library" );
469 BOOST_CHECK_MESSAGE( derived !=
nullptr,
470 "Derived symbol should exist in the saved-as library" );
476 if( wxFileName::DirExists( tempDir ) )
477 wxFileName::Rmdir( tempDir, wxPATH_RMDIR_RECURSIVE );
492 auto parent = std::make_unique<LIB_SYMBOL>( wxS(
"BaseSymbol" ) );
523 auto parent = std::make_unique<LIB_SYMBOL>( wxS(
"BaseSymbol" ) );
524 parent->GetValueField().SetText( wxS(
"BaseSymbol" ) );
525 parent->GetReferenceField().SetText( wxS(
"U" ) );
539 BOOST_REQUIRE_NO_THROW(
542 const std::string out = formatter.
GetString();
544 BOOST_CHECK_MESSAGE( out.find(
"(extends \"RecordedParent\")" ) != std::string::npos,
545 "Derived symbol should serialize (extends ...) using the recorded parent name" );
557 wxString tempDir = wxFileName::CreateTempFileName( wxS(
"kicad_test_" ) );
558 wxRemoveFile( tempDir );
559 wxFileName::Mkdir( tempDir );
561 wxString dstPath = wxFileName( tempDir, wxS(
"copy_target.kicad_sym" ) ).GetFullPath();
564 auto parent = std::make_unique<LIB_SYMBOL>( wxS(
"BaseSymbol" ) );
565 parent->GetValueField().SetText( wxS(
"BaseSymbol" ) );
566 parent->GetReferenceField().SetText( wxS(
"U" ) );
568 auto derived = std::make_unique<LIB_SYMBOL>( wxS(
"DerivedSymbol" ) );
569 derived->SetParent( parent.get() );
570 derived->SetParentName( parent->GetName() );
571 derived->GetValueField().SetText( wxS(
"DerivedSymbol" ) );
576 std::map<std::string, UTF8> properties;
579 BOOST_CHECK_NO_THROW(
580 plugin->SaveSymbol( dstPath, std::make_unique<LIB_SYMBOL>( *parent ), &properties ) );
582 LIB_SYMBOL* dstParent = plugin->LoadSymbol( dstPath, wxS(
"BaseSymbol" ), &properties );
585 auto newChild = std::make_unique<LIB_SYMBOL>( *derived );
586 newChild->SetParent( dstParent );
587 newChild->SetParentName( dstParent->
GetName() );
589 BOOST_CHECK_NO_THROW( plugin->SaveSymbol( dstPath, std::move( newChild ), &properties ) );
590 BOOST_CHECK_NO_THROW( plugin->SaveLibrary( dstPath ) );
597 LIB_SYMBOL* reloadedParent = plugin->LoadSymbol( dstPath, wxS(
"BaseSymbol" ) );
598 LIB_SYMBOL* reloadedChild = plugin->LoadSymbol( dstPath, wxS(
"DerivedSymbol" ) );
600 BOOST_CHECK( reloadedParent !=
nullptr );
602 BOOST_CHECK( reloadedChild->
IsDerived() );
606 if( wxFileName::DirExists( tempDir ) )
607 wxFileName::Rmdir( tempDir, wxPATH_RMDIR_RECURSIVE );
623 auto parent = std::make_unique<LIB_SYMBOL>( wxS(
"Parent" ) );
626 libBuffer.
CreateBuffer( std::move( parent ), std::make_unique<SCH_SCREEN>() );
628 auto child = std::make_unique<LIB_SYMBOL>( wxS(
"Child" ) );
629 child->SetParent( &parentRef );
630 libBuffer.
CreateBuffer( std::move( child ), std::make_unique<SCH_SCREEN>() );
635 BOOST_CHECK( names.IsEmpty() );
639 std::shared_ptr<SYMBOL_BUFFER> parentBuf = libBuffer.
GetBuffer( wxS(
"Parent" ) );
642 BOOST_CHECK( libBuffer.
GetSymbol( wxS(
"Parent" ) ) ==
nullptr );
646 BOOST_CHECK( names.IsEmpty() );
661 auto originalRoot = std::make_unique<LIB_SYMBOL>( wxS(
"Root" ) );
662 auto originalMid = std::make_unique<LIB_SYMBOL>( wxS(
"Mid" ) );
663 auto originalLeaf = std::make_unique<LIB_SYMBOL>( wxS(
"Leaf" ) );
665 originalMid->SetParent( originalRoot.get() );
666 originalLeaf->SetParent( originalMid.get() );
672 auto midCopy = std::make_unique<LIB_SYMBOL>( *originalMid );
675 libBuffer.
CreateBuffer( std::move( midCopy ), std::make_unique<SCH_SCREEN>() );
677 auto leafCopy = std::make_unique<LIB_SYMBOL>( *originalLeaf );
678 leafCopy->SetParent( midCopyPtr );
679 libBuffer.
CreateBuffer( std::move( leafCopy ), std::make_unique<SCH_SCREEN>() );
681 auto rootCopy = std::make_unique<LIB_SYMBOL>( *originalRoot );
684 libBuffer.
CreateBuffer( std::move( rootCopy ), std::make_unique<SCH_SCREEN>() );
688 auto midDuplicate = std::make_unique<LIB_SYMBOL>( *originalMid );
689 midDuplicate->SetParent( rootCopyPtr );
690 libBuffer.
CreateBuffer( std::move( midDuplicate ), std::make_unique<SCH_SCREEN>() );
695 BOOST_CHECK( names.Index( wxS(
"Mid" ) ) != wxNOT_FOUND );
696 BOOST_CHECK( names.Index( wxS(
"Leaf" ) ) != wxNOT_FOUND );
716 auto originalA = std::make_unique<LIB_SYMBOL>( wxS(
"A" ) );
717 auto originalB = std::make_unique<LIB_SYMBOL>( wxS(
"B" ) );
721 auto symbolA = std::make_unique<LIB_SYMBOL>( wxS(
"A" ) );
722 symbolA->SetParent( originalB.get() );
723 libBuffer.
CreateBuffer( std::move( symbolA ), std::make_unique<SCH_SCREEN>() );
725 auto symbolB = std::make_unique<LIB_SYMBOL>( wxS(
"B" ) );
726 symbolB->SetParent( originalA.get() );
727 libBuffer.
CreateBuffer( std::move( symbolB ), std::make_unique<SCH_SCREEN>() );
732 BOOST_REQUIRE_EQUAL( names.GetCount(), 1 );
735 std::shared_ptr<SYMBOL_BUFFER> bufferA = libBuffer.
GetBuffer( wxS(
"A" ) );
738 BOOST_CHECK( libBuffer.
GetBuffers().empty() );
void SetContentModified(bool aModified=true)
Store a working copy of a library.
bool CreateBuffer(std::unique_ptr< LIB_SYMBOL > aCopy, std::unique_ptr< SCH_SCREEN > aScreen, bool aNew=false)
Create a new buffer to store a symbol. LIB_BUFFER takes ownership of aCopy.
bool DeleteBuffer(const SYMBOL_BUFFER &aSymbolBuf)
Delete the given symbol buffer from the library buffer.
void ClearDeletedBuffer()
void GetSymbolNames(wxArrayString &aSymbolNames, SYMBOL_NAME_FILTER aFilter=SYMBOL_NAME_FILTER::ALL)
Fetch a list of root symbols names from the library buffer.
const std::deque< std::shared_ptr< SYMBOL_BUFFER > > & GetDeletedBuffers() const
Return the deleted symbol buffers that need to be removed from the library file.
size_t GetDerivedSymbolNames(const wxString &aSymbolName, wxArrayString &aList) const
Fetch all of the symbols derived from a aSymbolName into aList.
bool SaveBuffer(SYMBOL_BUFFER &aSymbolBuf, const wxString &aFileName, SCH_IO *aPlugin, bool aBuffer)
Save stored modifications using a plugin.
const std::deque< std::shared_ptr< SYMBOL_BUFFER > > & GetBuffers() const
Return all buffered symbols.
std::shared_ptr< SYMBOL_BUFFER > GetBuffer(const wxString &aAlias) const
Return a symbol buffer with LIB_SYMBOL holding a symbolic alias.
LIB_SYMBOL * GetSymbol(const wxString &aAlias) const
Return the working copy of a LIB_SYMBOL root object with specified alias.
bool HasDerivedSymbols(const wxString &aParentName) const
Check to see any symbols in the buffer are derived from a parent named aParentName.
bool UpdateBuffer(SYMBOL_BUFFER &aSymbolBuf, const LIB_SYMBOL &aCopy)
Update the buffered symbol with the contents of aCopy.
static std::unique_ptr< LIB_SYMBOL > CreateSymbol(const NEW_SYMBOL_PROPERTIES &aProps, LIB_SYMBOL *aParent)
Define a library symbol object.
SCH_FIELD & GetDescriptionField()
std::weak_ptr< LIB_SYMBOL > & GetParent()
void SetParent(LIB_SYMBOL *aParent=nullptr)
wxString GetName() const override
SCH_FIELD & GetValueField()
const wxString & GetParentName() const
void SetParentName(const wxString &aParentName)
void SetText(const wxString &aText) override
static void SaveSymbol(LIB_SYMBOL *aSymbol, OUTPUTFORMATTER &aFormatter, const wxString &aLibName=wxEmptyString, bool aIncludeData=true)
static const char * PropBuffering
The property used internally by the plugin to enable cache buffering which prevents the library file ...
LIB_SYMBOL & GetSymbol() const
SCH_SCREEN * GetScreen() const
LIB_SYMBOL & GetOriginal() const
void SetOriginal(std::unique_ptr< LIB_SYMBOL > aSymbol)
SYMBOL_LIBRARY_MANAGER_TEST_FIXTURE()
std::unique_ptr< T > IO_RELEASER
Helper to hold and release an IO_BASE object when exceptions are thrown.
wxString parentSymbolName
bool keepContentUserFields
bool unitsInterchangeable
@ USER
The field ID hasn't been set yet; field is invalid.
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(SymbolBuffer)
Test the SYMBOL_BUFFER object.
BOOST_CHECK_EQUAL(result, "25.4")