21#include <boost/test/results_collector.hpp>
31#define MAX_DEFAULT_REL_ERROR 2e-2
47 *
m_log << aText <<
"\n";
58 std::shared_ptr<wxString>
m_log;
64 m_log(
std::make_shared<wxString>() ),
72 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 );
84 if( !results.passed() )
93 fn.AppendDir(
"spice_netlists" );
94 fn.AppendDir( aBaseName );
95 fn.SetName( aBaseName );
103 wxFileName netFile =
m_schematic->Project().GetProjectFullName();
106 netFile.SetName( netFile.GetName() +
"_test" );
108 netFile.SetExt(
"spice" );
109 return netFile.GetFullPath();
115 BOOST_TEST_CHECKPOINT(
"Comparing netlist " << netlistPath );
125 wxFFile file( netlistPath,
"rt" );
132 ngspice->
Command(
"set ngbehavior=ps" );
133 ngspice->
Command(
"setseed 1" );
158 bool mif_error =
m_log->Find( wxT(
"MIF-ERROR" ) ) != wxNOT_FOUND;
160 BOOST_TEST_INFO(
"Cannot run ngspice. test skipped. Missing code model files?" );
161 BOOST_CHECK( !mif_error );
163 bool err_found =
m_log->Find( wxT(
"Error: circuit not parsed" ) ) != wxNOT_FOUND;
171 BOOST_CHECK( !err_found );
173 if( mif_error || err_found )
178 *
m_log <<
"Original Netlist\n";
179 *
m_log <<
"----------------\n";
186 ngspice->
Command(
"linearize" );
193 ngspice->
Command(
"echo Available Vectors" );
194 ngspice->
Command(
"echo -----------------" );
199 *
m_log <<
"Original Netlist\n";
200 *
m_log <<
"----------------\n";
204 ngspice->
Command(
"echo Expanded Netlist" );
205 ngspice->
Command(
"echo ----------------" );
206 ngspice->
Command(
"listing runnable" );
209 void TestOpPoint(
double aRefValue,
const std::string& aVectorName,
216 std::vector<double> vector = ngspice->
GetRealVector( aVectorName );
218 BOOST_REQUIRE_EQUAL( vector.size(), 1 );
220 double maxError = abs( aRefValue * aMaxRelError );
221 BOOST_CHECK_LE( abs( vector[0] - aRefValue ), aMaxRelError );
225 void TestPoint(
const std::string& aXVectorName,
double aXValue,
226 const std::map<const std::string, double> aTestVectorsAndValues,
237 std::vector<double> xVector = ngspice->
GetRealVector( aXVectorName );
240 for(; i < xVector.size(); ++i )
242 double inf = std::numeric_limits<double>::infinity();
244 double leftDelta = ( aXValue - ( i >= 1 ? xVector[i - 1] : -inf ) );
245 double middleDelta = ( aXValue - xVector[i] );
246 double rightDelta = ( aXValue - ( i < xVector.size() - 1 ? xVector[i + 1] : inf ) );
249 if( abs( middleDelta ) <= abs( leftDelta )
250 && abs( middleDelta ) <= abs( rightDelta ) )
256 BOOST_REQUIRE_LT( i, xVector.size() );
258 for(
auto& [vectorName, refValue] : aTestVectorsAndValues )
260 std::vector<double> yVector = ngspice->
GetGainVector( vectorName );
262 BOOST_REQUIRE_GE( yVector.size(), i + 1 );
265 <<
", Ref value: " << refValue
266 <<
", Actual value: " << yVector[i] )
268 double maxError = abs( refValue * aMaxRelError );
273 maxError = aMaxRelError;
276 BOOST_CHECK_LE( abs( yVector[i] - refValue ), maxError );
283 const std::map<const std::string, double> aTestVectorsAndValues,
286 TestPoint(
"time", aTime, aTestVectorsAndValues, aMaxRelError );
290 const std::map<const std::string, double> aTestVectorsAndValues,
293 TestPoint(
"frequency", aFrequency, aTestVectorsAndValues, aMaxRelError );
299 netlistPath.SetExt(
"csv" );
301 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
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.
Interface to receive simulation updates from SPICE_SIMULATOR class.
virtual void SetReporter(SIMULATOR_REPORTER *aReporter)
Set a SIMULATOR_REPORTER object to receive the simulation log.
bool HasMessage() const override
Returns true if any messages were reported.
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
virtual ~TEST_NETLIST_EXPORTER_SPICE_FIXTURE()
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)
wxFileName SchematicQAPath(const wxString &aBaseName) override
unsigned GetNetlistOptions() override
TEST_NETLIST_EXPORTER_SPICE_FIXTURE()
wxString GetResultsPath(bool aTest=false)
void TestTranPoint(double aTime, const std::map< const std::string, double > aTestVectorsAndValues, double aMaxRelError=MAX_DEFAULT_REL_ERROR)
std::shared_ptr< wxString > m_log
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())
BOOST_TEST_INFO("Two-port Series .op current = "<< iDevice)
#define MAX_DEFAULT_REL_ERROR
BOOST_TEST_MESSAGE("\n=== Real-World Polygon PIP Benchmark ===\n"<< formatTable(table))
BOOST_TEST_CONTEXT("Test Clearance")