KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_pin_map_roundtrip.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 The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
21
22#include <memory>
23
24#include <pin_map.h>
25#include <lib_symbol.h>
26#include <richio.h>
30
31
32namespace
33{
34LIB_ID makeFp( const wxString& aLibNick, const wxString& aName )
35{
36 LIB_ID id;
37 id.SetLibNickname( aLibNick );
38 id.SetLibItemName( aName );
39 return id;
40}
41
42
44std::string format( LIB_SYMBOL& aSymbol )
45{
46 STRING_FORMATTER formatter;
47 SCH_IO_KICAD_SEXPR::FormatLibSymbol( &aSymbol, formatter );
48 return formatter.GetString();
49}
50
51
53std::unique_ptr<LIB_SYMBOL> roundTrip( LIB_SYMBOL& aSymbol )
54{
55 std::string text = format( aSymbol );
56 std::vector<LIB_SYMBOL*> loaded = SCH_IO_KICAD_SEXPR::ParseLibSymbols( text, "pin map test" );
57
58 BOOST_REQUIRE_EQUAL( loaded.size(), 1u );
59 return std::unique_ptr<LIB_SYMBOL>( loaded.front() );
60}
61} // namespace
62
63
64BOOST_AUTO_TEST_SUITE( PinMapRoundTrip )
65
66
67BOOST_AUTO_TEST_CASE( RootSymbolWithStackedAndSharedMaps )
68{
69 LIB_SYMBOL sym( wxS( "LM358" ) );
70
71 PIN_MAP std8( wxS( "STD-8" ) );
72
73 for( int i = 1; i <= 8; ++i )
74 std8.SetEntry( wxString::Format( wxS( "%d" ), i ), wxString::Format( wxS( "%d" ), i ) );
75
76 PIN_MAP dfn( wxS( "DFN-8-EP" ) );
77 dfn.SetEntry( wxS( "4" ), wxS( "[4,9]" ) ); // V- on pad 4 AND the exposed pad
78
79 sym.PinMaps().AddOrReplace( std8 );
80 sym.PinMaps().AddOrReplace( dfn );
81
82 // STD-8 is shared between two footprints; DFN uses its own map.
84 { makeFp( wxS( "Package_SO" ), wxS( "SOIC-8" ) ), wxS( "STD-8" ) },
85 { makeFp( wxS( "Package_DFN_QFN" ), wxS( "DFN-8-1EP" ) ), wxS( "DFN-8-EP" ) },
86 { makeFp( wxS( "Package_SO" ), wxS( "VSSOP-8" ) ), wxS( "STD-8" ) },
87 } );
88
89 std::unique_ptr<LIB_SYMBOL> reloaded = roundTrip( sym );
90
91 BOOST_CHECK( reloaded->GetPinMaps() == sym.GetPinMaps() );
92 BOOST_CHECK( reloaded->GetAssociatedFootprints() == sym.GetAssociatedFootprints() );
93
94 // The bracketed stacked pad survives verbatim.
95 const PIN_MAP* reDfn = reloaded->GetPinMaps().FindByName( wxS( "DFN-8-EP" ) );
96 BOOST_REQUIRE( reDfn );
97 BOOST_CHECK_EQUAL( reDfn->GetPadNumber( wxS( "4" ) ), wxS( "[4,9]" ) );
98
99 // STD-8 is written once and reused by both associations.
100 BOOST_CHECK_EQUAL( reloaded->GetAssociatedFootprints()[0].m_MapName, wxS( "STD-8" ) );
101 BOOST_CHECK_EQUAL( reloaded->GetAssociatedFootprints()[2].m_MapName, wxS( "STD-8" ) );
102}
103
104
105BOOST_AUTO_TEST_CASE( EmptyStateProducesNoTokens )
106{
107 LIB_SYMBOL sym( wxS( "Plain" ) );
108
109 std::string text = format( sym );
110
111 BOOST_CHECK( text.find( "pin_maps" ) == std::string::npos );
112 BOOST_CHECK( text.find( "associated_footprints" ) == std::string::npos );
113}
114
115
116BOOST_AUTO_TEST_CASE( DerivedEmitsOnlyOwnSets )
117{
118 LIB_SYMBOL root( wxS( "root" ) );
119 root.PinMaps().AddOrReplace( PIN_MAP( wxS( "ROOT-MAP" ) ) );
120 root.SetAssociatedFootprints( { { makeFp( wxS( "L" ), wxS( "F" ) ), wxS( "ROOT-MAP" ) } } );
121
122 // A derived symbol that inherits the bundle writes nothing of its own.
123 LIB_SYMBOL inheritor( wxS( "inheritor" ) );
124 inheritor.SetParent( &root );
125
126 std::string inheritedText = format( inheritor );
127 BOOST_CHECK( inheritedText.find( "pin_maps" ) == std::string::npos );
128 BOOST_CHECK( inheritedText.find( "associated_footprints" ) == std::string::npos );
129
130 // A derived symbol that overrides the bundle writes only its own sets.
131 LIB_SYMBOL overrider( wxS( "overrider" ) );
132 overrider.SetParent( &root );
133 overrider.PinMaps().AddOrReplace( PIN_MAP( wxS( "CHILD-MAP" ) ) );
134
135 std::string ownText = format( overrider );
136 BOOST_CHECK( ownText.find( "CHILD-MAP" ) != std::string::npos );
137 BOOST_CHECK( ownText.find( "ROOT-MAP" ) == std::string::npos );
138}
139
140
141BOOST_AUTO_TEST_CASE( MalformedInputIsRejected )
142{
143 // An entry missing its pad number must be rejected, not silently accepted.
144 std::string bad = "(symbol \"Bad\" (pin_maps (pin_map \"M\" (entry \"1\"))))";
145
146 BOOST_CHECK_THROW( SCH_IO_KICAD_SEXPR::ParseLibSymbols( bad, "bad" ), IO_ERROR );
147}
148
149
150BOOST_AUTO_TEST_CASE( NewerFormatVersionIsRefused )
151{
152 // The format-version bump means an older reader must refuse a newer file. Prove the gate with
153 // a version far above the supported maximum (issue #2282, plan verification step 4).
154 std::string text =
155 "(kicad_symbol_lib (version 99999999) (generator \"test\") (generator_version \"1\"))";
156
157 STRING_LINE_READER reader( text, "future" );
158 SCH_IO_KICAD_SEXPR_PARSER parser( &reader );
159 LIB_SYMBOL_MAP map;
160
161 BOOST_CHECK_THROW( parser.ParseLib( map ), IO_ERROR );
162}
163
164
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
int SetLibNickname(const UTF8 &aLibNickname)
Override the logical library name portion of the LIB_ID to aLibNickname.
Definition lib_id.cpp:113
Define a library symbol object.
Definition lib_symbol.h:80
void SetAssociatedFootprints(std::vector< ASSOCIATED_FOOTPRINT > aList)
Definition lib_symbol.h:228
void SetParent(LIB_SYMBOL *aParent=nullptr)
const PIN_MAP_SET & GetPinMaps() const
Pin-to-pad mapping (issue #2282).
Definition lib_symbol.h:222
PIN_MAP_SET & PinMaps()
Definition lib_symbol.h:223
const std::vector< ASSOCIATED_FOOTPRINT > & GetAssociatedFootprints() const
Definition lib_symbol.h:226
void AddOrReplace(PIN_MAP aMap)
Insert aMap, replacing any existing entry with the same name.
Definition pin_map.cpp:113
A named pin map.
Definition pin_map.h:64
const wxString & GetPadNumber(const wxString &aPinNumber) const
Definition pin_map.cpp:85
void SetEntry(const wxString &aPinNumber, const wxString &aPadNumber)
Set the pad number for a symbol pin.
Definition pin_map.cpp:59
Object to parser s-expression symbol library and schematic file formats.
void ParseLib(LIB_SYMBOL_MAP &aSymbolLibMap)
static void FormatLibSymbol(LIB_SYMBOL *aPart, OUTPUTFORMATTER &aFormatter)
static std::vector< LIB_SYMBOL * > ParseLibSymbols(std::string &aSymbolText, std::string aSource, int aFileVersion=SEXPR_SCHEMATIC_FILE_VERSION)
Implement an OUTPUTFORMATTER to a memory buffer.
Definition richio.h:418
const std::string & GetString()
Definition richio.h:441
Is a LINE_READER that reads from a multiline 8 bit wide std::string.
Definition richio.h:222
std::map< wxString, LIB_SYMBOL *, LibSymbolMapSort > LIB_SYMBOL_MAP
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
static void roundTrip(const DIFF_VALUE &aValue)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_CASE(RootSymbolWithStackedAndSharedMaps)
BOOST_CHECK_EQUAL(result, "25.4")