25#include <boost/test/results_collector.hpp>
35#define MAX_DEFAULT_REL_ERROR 2e-2
51 *
m_log << aText <<
"\n";
62 std::shared_ptr<wxString>
m_log;
68 m_log(
std::make_shared<wxString>() ),
76 using namespace boost::unit_test;
78 test_case::id_t
id = framework::current_test_case().p_id;
79 test_results results = results_collector.results(
id );
83 if( !results.passed() )
92 fn.AppendDir(
"spice_netlists" );
93 fn.AppendDir( aBaseName );
94 fn.SetName( aBaseName );
102 wxFileName netFile =
m_schematic->Prj().GetProjectFullName();
105 netFile.SetName( netFile.GetName() +
"_test" );
107 netFile.SetExt(
"spice" );
108 return netFile.GetFullPath();
114 BOOST_TEST_CHECKPOINT(
"Comparing netlist " << netlistPath );
124 wxFFile file( netlistPath,
"rt" );
131 ngspice->
Command(
"set ngbehavior=ps" );
132 ngspice->
Command(
"setseed 1" );
151 bool mif_error =
m_log->Find( wxT(
"MIF-ERROR" ) ) != wxNOT_FOUND;
153 BOOST_TEST_INFO(
"Cannot run ngspice. test skipped. Missing code model files?" );
154 BOOST_CHECK( !mif_error );
156 bool err_found =
m_log->Find( wxT(
"Error: circuit not parsed" ) ) != wxNOT_FOUND;
158 BOOST_TEST_INFO(
"Cannot run ngspice. test skipped. Install error?" );
159 BOOST_CHECK( !err_found );
161 if( mif_error || err_found )
166 *
m_log <<
"Original Netlist\n";
167 *
m_log <<
"----------------\n";
174 ngspice->
Command(
"linearize" );
181 ngspice->
Command(
"echo Available Vectors" );
182 ngspice->
Command(
"echo -----------------" );
187 *
m_log <<
"Original Netlist\n";
188 *
m_log <<
"----------------\n";
192 ngspice->
Command(
"echo Expanded Netlist" );
193 ngspice->
Command(
"echo ----------------" );
194 ngspice->
Command(
"listing runnable" );
197 void TestOpPoint(
double aRefValue,
const std::string& aVectorName,
204 std::vector<double> vector = ngspice->
GetRealVector( aVectorName );
206 BOOST_REQUIRE_EQUAL( vector.size(), 1 );
208 double maxError = abs( aRefValue * aMaxRelError );
209 BOOST_CHECK_LE( abs( vector[0] - aRefValue ), aMaxRelError );
213 void TestPoint(
const std::string& aXVectorName,
double aXValue,
214 const std::map<const std::string, double> aTestVectorsAndValues,
225 std::vector<double> xVector = ngspice->
GetRealVector( aXVectorName );
228 for(; i < xVector.size(); ++i )
230 double inf = std::numeric_limits<double>::infinity();
232 double leftDelta = ( aXValue - ( i >= 1 ? xVector[i - 1] : -inf ) );
233 double middleDelta = ( aXValue - xVector[i] );
234 double rightDelta = ( aXValue - ( i < xVector.size() - 1 ? xVector[i + 1] : inf ) );
237 if( abs( middleDelta ) <= abs( leftDelta )
238 && abs( middleDelta ) <= abs( rightDelta ) )
244 BOOST_REQUIRE_LT( i, xVector.size() );
246 for(
auto& [vectorName, refValue] : aTestVectorsAndValues )
248 std::vector<double> yVector = ngspice->
GetGainVector( vectorName );
250 BOOST_REQUIRE_GE( yVector.size(), i + 1 );
253 <<
", Ref value: " << refValue
254 <<
", Actual value: " << yVector[i] )
256 double maxError = abs( refValue * aMaxRelError );
261 maxError = aMaxRelError;
264 BOOST_CHECK_LE( abs( yVector[i] - refValue ), maxError );
271 const std::map<const std::string, double> aTestVectorsAndValues,
274 TestPoint(
"time", aTime, aTestVectorsAndValues, aMaxRelError );
278 const std::map<const std::string, double> aTestVectorsAndValues,
281 TestPoint(
"frequency", aFrequency, aTestVectorsAndValues, aMaxRelError );
287 netlistPath.SetExt(
"csv" );
289 return netlistPath.GetFullPath();
std::unique_ptr< SCHEMATIC > m_schematic
@ 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 IsRunning() override final
Execute a Spice command as if it was typed into console.
bool Run() override final
Halt the simulation.
bool LoadNetlist(const std::string &aNetlist) override final
Execute the simulation with currently loaded netlist.
std::vector< double > GetGainVector(const std::string &aName, int aMaxLen=-1) override final
Return a requested vector with phase values.
std::vector< double > GetRealVector(const std::string &aName, int aMaxLen=-1) override final
Return a requested vector with imaginary values.
A pure virtual class used to derive REPORTER objects from.
Interface to receive simulation updates from SPICE_SIMULATOR class.
virtual void SetReporter(SIMULATOR_REPORTER *aReporter)
bool HasMessage() const override
Returns true if the reporter client is non-empty.
SPICE_TEST_REPORTER(std::shared_ptr< wxString > aLog)
void OnSimStateChange(SIMULATOR *aObject, SIM_STATE aNewState) override
REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED) override
Report a string with a given severity.
std::shared_ptr< wxString > m_log
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::unique_ptr< SPICE_TEST_REPORTER > m_reporter
static const std::string KiCadSchematicFileExtension
std::string GetEeschemaTestDataDir()
Get the configured location of Eeschema test data.
BOOST_REQUIRE(intersection.has_value()==c.ExpectedIntersection.has_value())
#define MAX_DEFAULT_REL_ERROR
BOOST_TEST_CONTEXT("Test Clearance")
BOOST_TEST_MESSAGE("Polyline has "<< chain.PointCount()<< " points")