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, you may find one at
18 * http://www.gnu.org/licenses/
19 */
20
23
24#include <connection_graph.h>
26#include <sch_netchain.h>
27#include <schematic.h>
29#include <locale_io.h>
30
31#include <wx/filename.h>
32#include <wx/xml/xml.h>
33
34
35// Verifies that the KiCad-internal <net_chains> element is gated behind GNL_OPT_KICAD.
36// External XML netlist consumers (KiCost, custom BOM scripts, schema validators) must
37// not see this extension under the public netlist version "E".
38
46
47
48static wxXmlNode* find_child( wxXmlNode* parent, const wxString& name )
49{
50 for( wxXmlNode* child = parent->GetChildren(); child; child = child->GetNext() )
51 {
52 if( child->GetName() == name )
53 return child;
54 }
55
56 return nullptr;
57}
58
59
60static bool writeAndLoad( SCHEMATIC* aSch, const wxString& aSuffix, unsigned aOptions,
61 wxXmlDocument& aDoc )
62{
63 wxFileName netFile = aSch->Project().GetProjectFullName();
64 netFile.SetName( netFile.GetName() + aSuffix );
65 netFile.SetExt( wxT( "xml" ) );
66
67 if( wxFileExists( netFile.GetFullPath() ) )
68 wxRemoveFile( netFile.GetFullPath() );
69
70 WX_STRING_REPORTER reporter;
71 std::unique_ptr<NETLIST_EXPORTER_XML> exporter =
72 std::make_unique<NETLIST_EXPORTER_XML>( aSch );
73
74 bool ok = exporter->WriteNetlist( netFile.GetFullPath(), aOptions, reporter )
75 && reporter.GetMessages().IsEmpty();
76
77 if( !ok )
78 return false;
79
80 bool loaded = aDoc.Load( netFile.GetFullPath() );
81 wxRemoveFile( netFile.GetFullPath() );
82 return loaded;
83}
84
85
86BOOST_FIXTURE_TEST_CASE( NetlistExporterXML_NetChainsAbsentForGenericFormat,
88{
89 // Schematic with committed chains; generic-XML export must NOT include <net_chains>.
91 KI_TEST::LoadSchematic( m_settingsManager, wxT( "net_chains_four_nets" ), m_schematic );
92
93 SCH_SHEET_LIST sheets = m_schematic->BuildSheetListSortedByPageNumbers();
94 CONNECTION_GRAPH* graph = m_schematic->ConnectionGraph();
95 graph->Recalculate( sheets, /*aUnconditional=*/true );
96
97 SCH_NETCHAIN* candidate = nullptr;
98
99 for( const auto& sig : graph->GetPotentialNetChains() )
100 {
101 if( sig && sig->GetNets().size() == 4 )
102 {
103 candidate = sig.get();
104 break;
105 }
106 }
107
108 BOOST_REQUIRE_MESSAGE( candidate, "fixture must produce a 4-net potential chain" );
109 BOOST_REQUIRE( graph->CreateNetChainFromPotential( candidate, wxT( "SIG_GATING" ) ) );
110
111 // Generic XML (no GNL_OPT_KICAD) must not emit <net_chains>.
112 {
113 wxXmlDocument xdoc;
114 BOOST_REQUIRE( writeAndLoad( m_schematic.get(), wxT( "_generic" ), 0, xdoc ) );
115 BOOST_REQUIRE( xdoc.GetRoot() );
116 BOOST_CHECK_MESSAGE( find_child( xdoc.GetRoot(), wxT( "net_chains" ) ) == nullptr,
117 "Generic XML export must not contain <net_chains>" );
118 }
119
120 // KiCad-internal export must emit <net_chains> with the committed chain.
121 {
122 wxXmlDocument xdoc;
123 BOOST_REQUIRE( writeAndLoad( m_schematic.get(), wxT( "_kicad" ), GNL_OPT_KICAD, xdoc ) );
124 BOOST_REQUIRE( xdoc.GetRoot() );
125
126 wxXmlNode* netChains = find_child( xdoc.GetRoot(), wxT( "net_chains" ) );
127 BOOST_REQUIRE_MESSAGE( netChains,
128 "KiCad-internal export must contain <net_chains>" );
129
130 bool foundCommitted = false;
131
132 for( wxXmlNode* xchain = netChains->GetChildren(); xchain; xchain = xchain->GetNext() )
133 {
134 if( xchain->GetName() != wxT( "net_chain" ) )
135 continue;
136
137 if( xchain->GetAttribute( wxT( "name" ), wxEmptyString ) == wxT( "SIG_GATING" ) )
138 {
139 foundCommitted = true;
140 break;
141 }
142 }
143
144 BOOST_CHECK_MESSAGE( foundCommitted,
145 "KiCad-internal export must list the committed chain" );
146 }
147}
148
149
150BOOST_FIXTURE_TEST_CASE( NetlistExporterXML_NoNetChainsElementWhenEmpty,
152{
153 // A schematic with no committed chains must not emit a stray <net_chains/> wrapper,
154 // even under the KiCad-internal flag.
156 KI_TEST::LoadSchematic( m_settingsManager, wxT( "net_chains_four_nets" ), m_schematic );
157
158 SCH_SHEET_LIST sheets = m_schematic->BuildSheetListSortedByPageNumbers();
159 CONNECTION_GRAPH* graph = m_schematic->ConnectionGraph();
160 graph->Recalculate( sheets, /*aUnconditional=*/true );
161
162 BOOST_REQUIRE_MESSAGE( graph->GetCommittedNetChains().empty(),
163 "fresh fixture must have no committed chains" );
164
165 wxXmlDocument xdocGeneric;
166 BOOST_REQUIRE( writeAndLoad( m_schematic.get(), wxT( "_empty_generic" ), 0, xdocGeneric ) );
167 BOOST_REQUIRE( xdocGeneric.GetRoot() );
168 BOOST_CHECK( find_child( xdocGeneric.GetRoot(), wxT( "net_chains" ) ) == nullptr );
169
170 wxXmlDocument xdocKicad;
171 BOOST_REQUIRE( writeAndLoad( m_schematic.get(), wxT( "_empty_kicad" ),
172 GNL_OPT_KICAD, xdocKicad ) );
173 BOOST_REQUIRE( xdocKicad.GetRoot() );
174 BOOST_CHECK_MESSAGE( find_child( xdocKicad.GetRoot(), wxT( "net_chains" ) ) == nullptr,
175 "Empty chain set must not produce a stray <net_chains/> element" );
176}
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:41
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
Definition project.cpp:181
Holds all the data relating to one schematic.
Definition schematic.h:89
PROJECT & Project() const
Return a reference to the project this schematic is part of.
Definition schematic.h:104
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:193
const wxString & GetMessages() const
Definition reporter.cpp:105
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())
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")