26#include <boost/test/results_collector.hpp>
36#define MAX_DEFAULT_REL_ERROR 2e-2
52 *
m_log << aText <<
"\n";
63 std::shared_ptr<wxString>
m_log;
69 m_log(
std::make_shared<wxString>() ),
77 using namespace boost::unit_test;
79 test_case::id_t
id = framework::current_test_case().p_id;
80 test_results results = results_collector.results(
id );
83 BOOST_CHECK_MESSAGE( results.passed(),
"\nNGSPICE LOG\n===========\n" << *
m_log );
89 fn.AppendDir(
"spice_netlists" );
90 fn.AppendDir( aBaseName );
91 fn.SetName( aBaseName );
92 fn.SetExt( KiCadSchematicFileExtension );
102 netFile.SetName( netFile.GetName() +
"_test" );
104 netFile.SetExt(
"spice" );
105 return netFile.GetFullPath();
114 BOOST_REQUIRE( ngspice );
124 ngspice->
Command(
"set ngbehavior=ps" );
125 ngspice->
Command(
"setseed 1" );
127 BOOST_REQUIRE( ngspice->
Run() );
132 bool err_found =
m_log->Find( wxT(
"Error: circuit not parsed" ) ) != wxNOT_FOUND
133 ||
m_log->Find( wxT(
"MIF-ERROR" ) ) != wxNOT_FOUND;
137 if(
m_log->Find( wxT(
"MIF-ERROR" ) ) != wxNOT_FOUND )
138 wxLogWarning( wxT(
"Cannot run ngspice. test skipped. Missing code model files?" ) );
140 wxLogWarning( wxT(
"Cannot run ngspice. test skipped. Install error?" ) );
145 *
m_log <<
"Original Netlist\n";
146 *
m_log <<
"----------------\n";
153 ngspice->
Command(
"linearize" );
160 ngspice->
Command(
"echo Available Vectors" );
161 ngspice->
Command(
"echo -----------------" );
166 *
m_log <<
"Original Netlist\n";
167 *
m_log <<
"----------------\n";
171 ngspice->
Command(
"echo Expanded Netlist" );
172 ngspice->
Command(
"echo ----------------" );
173 ngspice->
Command(
"listing runnable" );
176 void TestOpPoint(
double aRefValue,
const std::string& aVectorName,
179 BOOST_TEST_CONTEXT(
"Vector name: " << aVectorName )
183 std::vector<double> vector = ngspice->GetRealPlot( aVectorName );
185 BOOST_REQUIRE_EQUAL( vector.size(), 1 );
187 double maxError = abs( aRefValue * aMaxRelError );
188 BOOST_CHECK_LE( abs( vector[0] - aRefValue ), aMaxRelError );
192 void TestPoint(
const std::string& aXVectorName,
double aXValue,
193 const std::map<const std::string, double> aTestVectorsAndValues,
200 BOOST_TEST_CONTEXT(
"X vector name: " << aXVectorName <<
", X value: " << aXValue )
204 std::vector<double> xVector = ngspice->GetRealPlot( aXVectorName );
207 for(; i < xVector.size(); ++i )
209 double inf = std::numeric_limits<double>::infinity();
211 double leftDelta = ( aXValue - ( i >= 1 ? xVector[i - 1] : -inf ) );
212 double middleDelta = ( aXValue - xVector[i] );
213 double rightDelta = ( aXValue - ( i < xVector.size() - 1 ? xVector[i + 1] : inf ) );
216 if( abs( middleDelta ) <= abs( leftDelta )
217 && abs( middleDelta ) <= abs( rightDelta ) )
223 BOOST_REQUIRE_LT( i, xVector.size() );
225 for(
auto& [vectorName, refValue] : aTestVectorsAndValues )
227 std::vector<double> yVector = ngspice->GetMagPlot( vectorName );
229 BOOST_REQUIRE_GE( yVector.size(), i + 1 );
231 BOOST_TEST_CONTEXT(
"Y vector name: " << vectorName
232 <<
", Ref value: " << refValue
233 <<
", Actual value: " << yVector[i] )
235 double maxError = abs( refValue * aMaxRelError );
240 maxError = aMaxRelError;
243 BOOST_CHECK_LE( abs( yVector[i] - refValue ), maxError );
250 const std::map<const std::string, double> aTestVectorsAndValues,
253 TestPoint(
"time", aTime, aTestVectorsAndValues, aMaxRelError );
257 const std::map<const std::string, double> aTestVectorsAndValues,
260 TestPoint(
"frequency", aFrequency, aTestVectorsAndValues, aMaxRelError );
266 netlistPath.SetExt(
"csv" );
268 return netlistPath.GetFullPath();
@ OPTION_SAVE_ALL_CURRENTS
@ OPTION_SAVE_ALL_VOLTAGES
@ OPTION_SAVE_ALL_DISSIPATIONS
@ OPTION_ADJUST_INCLUDE_PATHS
bool Command(const std::string &aCmd) override final
Set a SIMULATOR_REPORTER object to receive the simulation log.
bool Run() override final
Halt the simulation.
bool LoadNetlist(const std::string &aNetlist) override final
Execute the simulation with currently loaded netlist.
virtual const wxString GetProjectFullName() const
Return the full path and name of the project.
A pure virtual class used to derive REPORTER objects from.
PROJECT & Prj() const override
Return a reference to the project this schematic is part of.
virtual void SetReporter(SIMULATOR_REPORTER *aReporter)
void OnSimStateChange(SPICE_SIMULATOR *aObject, SIM_STATE aNewState) override
bool HasMessage() const override
Returns true if the reporter client is non-empty.
std::shared_ptr< wxString > m_log
SPICE_TEST_REPORTER(std::shared_ptr< wxString > aLog)
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
std::unique_ptr< SPICE_TEST_REPORTER > m_reporter
std::shared_ptr< SPICE_SIMULATOR > m_simulator
void TestOpPoint(double aRefValue, const std::string &aVectorName, double aMaxRelError=MAX_DEFAULT_REL_ERROR)
void TestPoint(const std::string &aXVectorName, double aXValue, const std::map< const std::string, double > aTestVectorsAndValues, double aMaxRelError=MAX_DEFAULT_REL_ERROR)
unsigned GetNetlistOptions() override
TEST_NETLIST_EXPORTER_SPICE_FIXTURE()
wxString GetResultsPath(bool aTest=false)
wxFileName GetSchematicPath(const wxString &aBaseName) override
void TestTranPoint(double aTime, const std::map< const std::string, double > aTestVectorsAndValues, double aMaxRelError=MAX_DEFAULT_REL_ERROR)
std::shared_ptr< wxString > m_log
~TEST_NETLIST_EXPORTER_SPICE_FIXTURE()
void TestACPoint(double aFrequency, const std::map< const std::string, double > aTestVectorsAndValues, double aMaxRelError=MAX_DEFAULT_REL_ERROR)
wxString GetNetlistPath(bool aTest=false) override
void CompareNetlists() override
std::string GetEeschemaTestDataDir()
Get the configured location of Eeschema test data.
#define MAX_DEFAULT_REL_ERROR