KiCad PCB EDA Suite
Loading...
Searching...
No Matches
test_netlist_exporter_xml_chain_gating.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
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
22
23#include <connection_graph.h>
25#include <sch_netchain.h>
26#include <schematic.h>
28#include <locale_io.h>
29
30#include <wx/filename.h>
31#include <wx/xml/xml.h>
32
33
34// Verifies that the KiCad-internal <net_chains> element is gated behind GNL_OPT_KICAD.
35// External XML netlist consumers (KiCost, custom BOM scripts, schema validators) must
36// not see this extension under the public netlist version "E".
37
45
46
47static wxXmlNode* find_child( wxXmlNode* parent, const wxString& name )
48{
49 for( wxXmlNode* child = parent->GetChildren(); child; child = child->GetNext() )
50 {
51 if( child->GetName() == name )
52 return child;
53 }
54
55 return nullptr;
56}
57
58
59static bool writeAndLoad( SCHEMATIC* aSch, const wxString& aSuffix, unsigned aOptions,
60 wxXmlDocument& aDoc )
61{
62 wxFileName netFile = aSch->Project().GetProjectFullName();
63 netFile.SetName( netFile.GetName() + aSuffix );
64 netFile.SetExt( wxT( "xml" ) );
65
66 if( wxFileExists( netFile.GetFullPath() ) )
67 wxRemoveFile( netFile.GetFullPath() );
68
70 std::unique_ptr<NETLIST_EXPORTER_XML> exporter =
71 std::make_unique<NETLIST_EXPORTER_XML>( aSch );
72
73 bool ok = exporter->WriteNetlist( netFile.GetFullPath(), aOptions, reporter )
74 && reporter.GetMessages().IsEmpty();
75
76 if( !ok )
77 return false;
78
79 bool loaded = aDoc.Load( netFile.GetFullPath() );
80 wxRemoveFile( netFile.GetFullPath() );
81 return loaded;
82}
83
84
85BOOST_FIXTURE_TEST_CASE( NetlistExporterXML_NetChainsAbsentForGenericFormat,
87{
88 // Schematic with committed chains; generic-XML export must NOT include <net_chains>.
90 KI_TEST::LoadSchematic( m_settingsManager, wxT( "net_chains_four_nets" ), m_schematic );
91
92 SCH_SHEET_LIST sheets = m_schematic->BuildSheetListSortedByPageNumbers();
93 CONNECTION_GRAPH* graph = m_schematic->ConnectionGraph();
94 graph->Recalculate( sheets, /*aUnconditional=*/true );
95
96 SCH_NETCHAIN* candidate = nullptr;
97
98 for( const auto& sig : graph->GetPotentialNetChains() )
99 {
100 if( sig && sig->GetNets().size() == 4 )
101 {
102 candidate = sig.get();
103 break;
104 }
105 }
106
107 BOOST_REQUIRE_MESSAGE( candidate, "fixture must produce a 4-net potential chain" );
108 BOOST_REQUIRE( graph->CreateNetChainFromPotential( candidate, wxT( "SIG_GATING" ) ) );
109
110 // Generic XML (no GNL_OPT_KICAD) must not emit <net_chains>.
111 {
112 wxXmlDocument xdoc;
113 BOOST_REQUIRE( writeAndLoad( m_schematic.get(), wxT( "_generic" ), 0, xdoc ) );
114 BOOST_REQUIRE( xdoc.GetRoot() );
115 BOOST_CHECK_MESSAGE( find_child( xdoc.GetRoot(), wxT( "net_chains" ) ) == nullptr,
116 "Generic XML export must not contain <net_chains>" );
117 }
118
119 // KiCad-internal export must emit <net_chains> with the committed chain.
120 {
121 wxXmlDocument xdoc;
122 BOOST_REQUIRE( writeAndLoad( m_schematic.get(), wxT( "_kicad" ), GNL_OPT_KICAD, xdoc ) );
123 BOOST_REQUIRE( xdoc.GetRoot() );
124
125 wxXmlNode* netChains = find_child( xdoc.GetRoot(), wxT( "net_chains" ) );
126 BOOST_REQUIRE_MESSAGE( netChains,
127 "KiCad-internal export must contain <net_chains>" );
128
129 bool foundCommitted = false;
130
131 for( wxXmlNode* xchain = netChains->GetChildren(); xchain; xchain = xchain->GetNext() )
132 {
133 if( xchain->GetName() != wxT( "net_chain" ) )
134 continue;
135
136 if( xchain->GetAttribute( wxT( "name" ), wxEmptyString ) == wxT( "SIG_GATING" ) )
137 {
138 foundCommitted = true;
139 break;
140 }
141 }
142
143 BOOST_CHECK_MESSAGE( foundCommitted,
144 "KiCad-internal export must list the committed chain" );
145 }
146}
147
148
149BOOST_FIXTURE_TEST_CASE( NetlistExporterXML_NoNetChainsElementWhenEmpty,
151{
152 // A schematic with no committed chains must not emit a stray <net_chains/> wrapper,
153 // even under the KiCad-internal flag.
155 KI_TEST::LoadSchematic( m_settingsManager, wxT( "net_chains_four_nets" ), m_schematic );
156
157 SCH_SHEET_LIST sheets = m_schematic->BuildSheetListSortedByPageNumbers();
158 CONNECTION_GRAPH* graph = m_schematic->ConnectionGraph();
159 graph->Recalculate( sheets, /*aUnconditional=*/true );
160
161 BOOST_REQUIRE_MESSAGE( graph->GetCommittedNetChains().empty(),
162 "fresh fixture must have no committed chains" );
163
164 wxXmlDocument xdocGeneric;
165 BOOST_REQUIRE( writeAndLoad( m_schematic.get(), wxT( "_empty_generic" ), 0, xdocGeneric ) );
166 BOOST_REQUIRE( xdocGeneric.GetRoot() );
167 BOOST_CHECK( find_child( xdocGeneric.GetRoot(), wxT( "net_chains" ) ) == nullptr );
168
169 wxXmlDocument xdocKicad;
170 BOOST_REQUIRE( writeAndLoad( m_schematic.get(), wxT( "_empty_kicad" ),
171 GNL_OPT_KICAD, xdocKicad ) );
172 BOOST_REQUIRE( xdocKicad.GetRoot() );
173 BOOST_CHECK_MESSAGE( find_child( xdocKicad.GetRoot(), wxT( "net_chains" ) ) == nullptr,
174 "Empty chain set must not produce a stray <net_chains/> element" );
175}
const char * name
Calculate the connectivity of a schematic and generates netlists.
SCH_NETCHAIN * CreateNetChainFromPotential(SCH_NETCHAIN *aPotential, const wxString &aName)
Promote a potential net chain to an actual user net chain with the provided name.
void Recalculate(const SCH_SHEET_LIST &aSheetList, bool aUnconditional=false, std::function< void(SCH_ITEM *)> *aChangedItemHandler=nullptr, PROGRESS_REPORTER *aProgressReporter=nullptr)
Update the connection graph for the given list of sheets.
const std::vector< std::unique_ptr< SCH_NETCHAIN > > & GetPotentialNetChains() const
Potential net chains are inferred groupings produced by RebuildNetChains() but not yet user-committed...
const std::vector< std::unique_ptr< SCH_NETCHAIN > > & GetCommittedNetChains() const
Return user-created (committed) net chains (legacy accessor retained under net-chain API).
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition locale_io.h:37
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
Definition project.cpp:177
Holds all the data relating to one schematic.
Definition schematic.h:90
PROJECT & Project() const
Return a reference to the project this schematic is part of.
Definition schematic.h:105
A net chain is a collection of nets that are connected together through passive components.
A container for handling SCH_SHEET_PATH objects in a flattened hierarchy.
A wrapper for reporting to a wxString object.
Definition reporter.h:189
void LoadSchematic(SETTINGS_MANAGER &aSettingsManager, const wxString &aRelPath, std::unique_ptr< SCHEMATIC > &aSchematic)
@ GNL_OPT_KICAD
std::vector< FAB_LAYER_COLOR > dummy
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
IbisParser parser & reporter
static wxXmlNode * find_child(wxXmlNode *parent, const wxString &name)
static bool writeAndLoad(SCHEMATIC *aSch, const wxString &aSuffix, unsigned aOptions, wxXmlDocument &aDoc)
BOOST_FIXTURE_TEST_CASE(NetlistExporterXML_NetChainsAbsentForGenericFormat, XML_NETCHAIN_GATING_FIXTURE)
BOOST_CHECK_MESSAGE(totalMismatches==0, std::to_string(totalMismatches)+" board(s) with strategy disagreements")