KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_netlist_group_instances.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
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 3
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, see <https://www.gnu.org/licenses/>.
18 */
19
20/*
21 * Group members in the netlist are instance paths. Two instances of the same sheet file
22 * contain the same symbol uuids, only the path tells them apart, so path matching must
23 * assign each instance to its own group.
24 */
25
28#include <richio.h>
29#include <lib_id.h>
31
32
33namespace
34{
35
36// Two sheet instances of one file, one symbol, one group per instance
37const char* TWO_INSTANCE_NETLIST =
38 "(export (version \"E\")\n"
39 " (components\n"
40 " (comp (ref \"Q1\")\n"
41 " (value \"BC817\")\n"
42 " (footprint \"TestLib:SOT-23\")\n"
43 " (sheetpath (names \"/Amp 1/\") (tstamps \"/aaaaaaaa-1111-4aaa-8aaa-aaaaaaaaaaaa/\"))\n"
44 " (tstamps \"55555555-5555-4555-8555-555555555555\"))\n"
45 " (comp (ref \"Q2\")\n"
46 " (value \"BC817\")\n"
47 " (footprint \"TestLib:SOT-23\")\n"
48 " (sheetpath (names \"/Amp 2/\") (tstamps \"/bbbbbbbb-2222-4bbb-8bbb-bbbbbbbbbbbb/\"))\n"
49 " (tstamps \"55555555-5555-4555-8555-555555555555\")))\n"
50 " (groups\n"
51 " (group (name \"Amp (Amp 1)\")\n"
52 " (uuid \"/aaaaaaaa-1111-4aaa-8aaa-aaaaaaaaaaaa/99999999-9999-4999-8999-999999999999\")\n"
53 " (lib_id \"MyBlocks:Amp\")\n"
54 " (members\n"
55 " (member (uuid \"/aaaaaaaa-1111-4aaa-8aaa-aaaaaaaaaaaa/55555555-5555-4555-8555-555555555555\"))))\n"
56 " (group (name \"Amp (Amp 2)\")\n"
57 " (uuid \"/bbbbbbbb-2222-4bbb-8bbb-bbbbbbbbbbbb/99999999-9999-4999-8999-999999999999\")\n"
58 " (lib_id \"MyBlocks:Amp\")\n"
59 " (members\n"
60 " (member (uuid \"/bbbbbbbb-2222-4bbb-8bbb-bbbbbbbbbbbb/55555555-5555-4555-8555-555555555555\"))))))\n";
61
62
63void loadNetlist( NETLIST& aNetlist, const char* aText )
64{
65 try
66 {
67 // The netlist reader owns and deletes the line reader
68 KICAD_NETLIST_READER netlistReader( new STRING_LINE_READER( aText, wxS( "test netlist" ) ), &aNetlist );
69 netlistReader.LoadNetlist();
70 }
71 catch( const IO_ERROR& ioe )
72 {
73 BOOST_FAIL( "netlist parse failed: " + ioe.What().ToStdString() );
74 }
75}
76
77} // namespace
78
79
80BOOST_AUTO_TEST_SUITE( NetlistGroupInstances )
81
82
83BOOST_AUTO_TEST_CASE( InstancePathMembersResolvePerInstance )
84{
86 loadNetlist( netlist, TWO_INSTANCE_NETLIST );
87
88 BOOST_REQUIRE_EQUAL( netlist.GetCount(), 2 );
89
90 COMPONENT* q1 = netlist.GetComponentByReference( wxS( "Q1" ) );
91 COMPONENT* q2 = netlist.GetComponentByReference( wxS( "Q2" ) );
92
93 BOOST_REQUIRE( q1 && q2 );
94 BOOST_REQUIRE_MESSAGE( q1->GetGroup(), "Q1 was not assigned to a group" );
95 BOOST_REQUIRE_MESSAGE( q2->GetGroup(), "Q2 was not assigned to a group" );
96
97 // Each instance must land in its own group, not both in the last one parsed
98 BOOST_CHECK_EQUAL( q1->GetGroup()->name, wxString( wxS( "Amp (Amp 1)" ) ) );
99 BOOST_CHECK_EQUAL( q2->GetGroup()->name, wxString( wxS( "Amp (Amp 2)" ) ) );
100 BOOST_CHECK( q1->GetGroup() != q2->GetGroup() );
101 BOOST_CHECK( q1->GetGroup()->uuid != q2->GetGroup()->uuid );
102}
103
104
105BOOST_AUTO_TEST_CASE( GroupUuidsAreDeterministic )
106{
107 NETLIST netlistA;
108 NETLIST netlistB;
109 loadNetlist( netlistA, TWO_INSTANCE_NETLIST );
110 loadNetlist( netlistB, TWO_INSTANCE_NETLIST );
111
112 COMPONENT* a1 = netlistA.GetComponentByReference( wxS( "Q1" ) );
113 COMPONENT* b1 = netlistB.GetComponentByReference( wxS( "Q1" ) );
114
115 BOOST_REQUIRE( a1 && b1 && a1->GetGroup() && b1->GetGroup() );
116
117 // Update PCB must find the same board group on every run
118 BOOST_CHECK( a1->GetGroup()->uuid == b1->GetGroup()->uuid );
119}
120
121
122BOOST_AUTO_TEST_CASE( BareUuidMembersStillResolve )
123{
125
126 LIB_ID fpid;
127 fpid.Parse( wxS( "TestLib:SOT-23" ) );
128
129 KIID symbolUuid;
130 netlist.AddComponent(
131 new COMPONENT( fpid, wxS( "Q1" ), wxS( "BC817" ), KIID_PATH(), std::vector<KIID>{ symbolUuid } ) );
132
133 KIID_PATH member;
134 member.push_back( symbolUuid );
135
136 KIID groupUuid;
137 netlist.AddGroup( new NETLIST_GROUP{ wxS( "Amp" ), groupUuid, LIB_ID(), std::vector<KIID_PATH>{ member } } );
138
139 netlist.ApplyGroupMembership();
140
141 COMPONENT* q1 = netlist.GetComponentByReference( wxS( "Q1" ) );
142
143 BOOST_REQUIRE( q1 );
144 BOOST_REQUIRE_MESSAGE( q1->GetGroup(), "bare uuid member was not resolved" );
145 BOOST_CHECK_EQUAL( q1->GetGroup()->name, wxString( wxS( "Amp" ) ) );
146}
147
148
Store all of the related component information found in a netlist.
NETLIST_GROUP * GetGroup() const
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
virtual const wxString What() const
A composite of Problem() and Where()
Read the new s-expression based KiCad netlist format.
Definition kiid.h:46
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:45
int Parse(const UTF8 &aId, bool aFix=false)
Parse LIB_ID with the information from aId.
Definition lib_id.cpp:65
Store information read from a netlist along with the flags used to update the NETLIST in the BOARD.
COMPONENT * GetComponentByReference(const wxString &aReference)
Return a COMPONENT by aReference.
Is a LINE_READER that reads from a multiline 8 bit wide std::string.
Definition richio.h:222
BOOST_AUTO_TEST_CASE(HorizontalAlignment)
BOOST_AUTO_TEST_SUITE(CadstarPartParser)
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
BOOST_AUTO_TEST_SUITE_END()
std::string netlist
BOOST_AUTO_TEST_CASE(InstancePathMembersResolvePerInstance)
BOOST_CHECK_EQUAL(result, "25.4")