mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-30 11:55:35 +08:00
Unit tests for temperature, virtual method for value conversion
This commit is contained in:
@@ -54,7 +54,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
CTemperature t1;
|
||||
CTemperature t2(20, CTemperatureUnit::C());
|
||||
qDebug() << t1 << t2;
|
||||
CTemperature t3(1, CTemperatureUnit::F());
|
||||
qDebug() << t1 << t2 << t2.convertedSiValueRoundedWithUnit();
|
||||
qDebug() << t3 << t3.valueRoundedWithUnit(CTemperatureUnit::C());
|
||||
|
||||
// some logging wit CLogMessage
|
||||
bDebug << p1;
|
||||
|
||||
9
src/blackcore/blackcore.h
Normal file
9
src/blackcore/blackcore.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef BLACKCORE_H
|
||||
#define BLACKCORE_H
|
||||
|
||||
/**
|
||||
* @namespace BlackCore
|
||||
* To be written
|
||||
*/
|
||||
|
||||
#endif // BLACKCORE_H
|
||||
@@ -31,7 +31,8 @@ HEADERS += \
|
||||
plane.h \
|
||||
simulator.h \
|
||||
vector_3d.h \
|
||||
vector_geo.h
|
||||
vector_geo.h \
|
||||
blackcore.h
|
||||
|
||||
SOURCES += \
|
||||
ecef.cpp \
|
||||
|
||||
@@ -179,7 +179,7 @@ private:
|
||||
QString _type; //!< type,such as distance. Somehow redundant, but simplifies unit comparisons
|
||||
bool _isSIUnit; //!< is this a SI unit?
|
||||
bool _isSIBaseUnit; //!< SI base unit?
|
||||
double _conversionFactorToSIConversionUnit; //!< factor to convert to SI
|
||||
double _conversionFactorToSIConversionUnit; //!< factor to convert to SI, set to 0 if not applicable (rare cases, e.g. temperature)
|
||||
double _epsilon; //!< values with differences below epsilon are the equal
|
||||
qint32 _displayDigits; //!< standard rounding dor string conversions
|
||||
CMeasurementPrefix _multiplier; //!< multiplier
|
||||
@@ -278,7 +278,7 @@ public:
|
||||
* \param to
|
||||
* \return
|
||||
*/
|
||||
virtual double conversionFactor(const CMeasurementUnit &to) const;
|
||||
double conversionFactor(const CMeasurementUnit &to) const;
|
||||
/*!
|
||||
* \brief Factor to convert between given units
|
||||
* \param from
|
||||
|
||||
@@ -244,14 +244,13 @@ bool CPhysicalQuantity::operator <=(const CPhysicalQuantity &otherQuantity) cons
|
||||
/**
|
||||
* Switch to another unit
|
||||
*/
|
||||
bool CPhysicalQuantity::switchUnit(const CMeasurementUnit &unit)
|
||||
bool CPhysicalQuantity::switchUnit(const CMeasurementUnit &newUnit)
|
||||
{
|
||||
if (this->_unit == unit) return true;
|
||||
if (this->_unit.getType() != unit.getType()) return false; // not possible
|
||||
|
||||
double cf = this->_unit.conversionFactor(unit);
|
||||
this->_unit =unit;
|
||||
this->setUnitValue(cf * this->_unitValueD);
|
||||
if (this->_unit == newUnit) return true;
|
||||
if (this->_unit.getType() != newUnit.getType()) return false; // not possible
|
||||
double cf = this->calculateValueInOtherUnit(newUnit);
|
||||
this->_unit = newUnit;
|
||||
this->setUnitValue(cf);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -275,19 +274,23 @@ void CPhysicalQuantity::setUnitValue(double baseValue)
|
||||
this->_unitValueI = qRound(baseValue);
|
||||
this->_isIntegerBaseValue = false;
|
||||
this->setConversionSiUnitValue();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief set SI value
|
||||
* Set SI value
|
||||
*/
|
||||
void CPhysicalQuantity::setConversionSiUnitValue() {
|
||||
if (this->_unit == CMeasurementUnit::None()) {
|
||||
this->_convertedSiUnitValueD=0.0;
|
||||
} else {
|
||||
double f = this->_unit.conversionFactor(this->_conversionSiUnit);
|
||||
this->_convertedSiUnitValueD =f * this->_unitValueD;
|
||||
}
|
||||
this->_convertedSiUnitValueD = this->calculateValueInOtherUnit(this->_conversionSiUnit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard conversion by factor, used in most cases,in some cases overridden (e.g.CTemperature)
|
||||
*/
|
||||
double CPhysicalQuantity::calculateValueInOtherUnit(const CMeasurementUnit &otherUnit) const {
|
||||
if (this->_unit == CMeasurementUnit::None() || this->_unitValueD == 0.0) return 0.0;
|
||||
if (this->_unit == otherUnit) return this->_unitValueD;
|
||||
double f = this->_unit.conversionFactor(otherUnit);
|
||||
return f * this->_unitValueD;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -368,13 +371,8 @@ double CPhysicalQuantity::valueRounded(const CMeasurementUnit &unit, int digits)
|
||||
*/
|
||||
double CPhysicalQuantity::value(const CMeasurementUnit &unit) const
|
||||
{
|
||||
double v;
|
||||
if (unit == this->_unit)
|
||||
v = this->_unitValueD;
|
||||
else if (unit == this->_conversionSiUnit)
|
||||
v = this->_convertedSiUnitValueD;
|
||||
else
|
||||
v = (this->_unit.conversionFactor(unit)) * (this->_unitValueD);
|
||||
if (unit == this->_conversionSiUnit) return this->_convertedSiUnitValueD;
|
||||
double v = this->calculateValueInOtherUnit(unit);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,14 @@ protected:
|
||||
* \brief Set the SI value
|
||||
*/
|
||||
void setConversionSiUnitValue();
|
||||
/*!
|
||||
* Convert value in another unit, normally just by a factor, but in some cases
|
||||
* (e.g. CTemperature)overridden because arbitrary conversion is required
|
||||
* \sa CMeasurementUnit::conversionFactor(CMeasurementUnit)
|
||||
* \param otherUnit
|
||||
* \return
|
||||
*/
|
||||
virtual double calculateValueInOtherUnit(const CMeasurementUnit &otherUnit) const;
|
||||
|
||||
public:
|
||||
/*!
|
||||
@@ -79,10 +87,10 @@ public:
|
||||
CPhysicalQuantity(const CPhysicalQuantity &otherQuantity);
|
||||
/*!
|
||||
* \brief Switch unit, e.g. feet meter
|
||||
* \param unit
|
||||
* \param newUnit
|
||||
* \return
|
||||
*/
|
||||
bool switchUnit(const CMeasurementUnit &unit);
|
||||
bool switchUnit(const CMeasurementUnit &newUnit);
|
||||
/*!
|
||||
* \brief Value in SI base unit? Meter is an SI base unit, hertz not!
|
||||
* \return
|
||||
@@ -116,7 +124,7 @@ public:
|
||||
* \param digits
|
||||
* @return
|
||||
*/
|
||||
double valueRounded(const CMeasurementUnit &unit, int digits) const;
|
||||
double valueRounded(const CMeasurementUnit &unit, int digits = -1) const;
|
||||
/*!
|
||||
* \brief Value to QString with unit, e.g. "5.00m"
|
||||
* \param unit
|
||||
@@ -143,7 +151,7 @@ public:
|
||||
* \brief SI value to double
|
||||
* @return
|
||||
*/
|
||||
qint32 siBaseUnitValueToDouble() const { return this->_convertedSiUnitValueD;}
|
||||
double siBaseUnitValueToDouble() const { return this->_convertedSiUnitValueD;}
|
||||
/*!
|
||||
* \brief Rounded value by n digits
|
||||
* \param digits
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace BlackMisc {
|
||||
*/
|
||||
CTemperature::CTemperature(): CPhysicalQuantity(0, CTemperatureUnit::K(),CTemperatureUnit::K())
|
||||
{
|
||||
//void
|
||||
this->setUnitValue(this->unitValueToDouble()); // I have to recall, since virtual method overriding does not work in constructor
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -15,7 +15,7 @@ CTemperature::CTemperature(): CPhysicalQuantity(0, CTemperatureUnit::K(),CTemper
|
||||
*/
|
||||
CTemperature::CTemperature(const CPhysicalQuantity &temperature): CPhysicalQuantity(temperature)
|
||||
{
|
||||
//void
|
||||
this->setUnitValue(this->unitValueToDouble()); // I have to recall, since virtual method overriding does not work in constructor
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -23,7 +23,7 @@ CTemperature::CTemperature(const CPhysicalQuantity &temperature): CPhysicalQuant
|
||||
*/
|
||||
CTemperature::CTemperature(qint32 value, const CTemperatureUnit &unit) : CPhysicalQuantity(value, unit, CTemperatureUnit::K())
|
||||
{
|
||||
// void
|
||||
this->setUnitValue(value); // I have to recall, since virtual method overriding does not work in constructor
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -31,7 +31,41 @@ CTemperature::CTemperature(qint32 value, const CTemperatureUnit &unit) : CPhysic
|
||||
*/
|
||||
CTemperature::CTemperature(double value, const CTemperatureUnit &unit) : CPhysicalQuantity(value, unit, CTemperatureUnit::K())
|
||||
{
|
||||
// void
|
||||
this->setUnitValue(value); // I have to recall, since virtual method overriding does not work in constructor
|
||||
}
|
||||
|
||||
/**
|
||||
* Overriden specializedmethodfortemperture
|
||||
*/
|
||||
double CTemperature::calculateValueInOtherUnit(const CMeasurementUnit &otherUnit) const
|
||||
{
|
||||
if (this->getUnit()==otherUnit) return this->siBaseUnitValueToDouble();
|
||||
|
||||
double siValue;
|
||||
// I always convert via SI Unit, other I would need too many conversions
|
||||
if(otherUnit == this->_conversionSiUnit) {
|
||||
// here I expect a conversion to SI is required and not done yet
|
||||
if(this->_unit == CTemperatureUnit::C()) {
|
||||
siValue = this->unitValueToDouble() + 273.15;
|
||||
} else if(this->_unit == CTemperatureUnit::F()) {
|
||||
siValue = (this->unitValueToDouble() + 459.67) *5.0 / 9.0;
|
||||
} else{
|
||||
// TODO: EXCEPTION
|
||||
}
|
||||
} else {
|
||||
// here I expect the SI value is already set
|
||||
siValue = this->siBaseUnitValueToDouble();
|
||||
}
|
||||
|
||||
// from SI
|
||||
if (otherUnit == this->_conversionSiUnit) return siValue;
|
||||
if(otherUnit == CTemperatureUnit::C()) {
|
||||
return siValue - 273.15;
|
||||
} else if(this->_unit == CTemperatureUnit::F()) {
|
||||
return (siValue * 9.0 / 5.0) - 459.67;
|
||||
}
|
||||
// TODO: Exception
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace BlackCore
|
||||
|
||||
@@ -30,15 +30,20 @@ public:
|
||||
*/
|
||||
CTemperatureUnit(const CMeasurementUnit &otherUnit) : CMeasurementUnit(otherUnit) {}
|
||||
/*!
|
||||
* \brief Meter m
|
||||
* \brief Kelvin
|
||||
* \return
|
||||
*/
|
||||
static CTemperatureUnit& K() { static CTemperatureUnit K("Kelvin", "K", true, true); return K;}
|
||||
/*!
|
||||
* \brief Nautical miles NM
|
||||
* \brief Centigrade C
|
||||
* \return
|
||||
*/
|
||||
static CTemperatureUnit& C() { static CTemperatureUnit C("centigrade", "°C", false, false);return C;}
|
||||
/*!
|
||||
* \brief Fahrenheit F
|
||||
* \return
|
||||
*/
|
||||
static CTemperatureUnit& F() { static CTemperatureUnit F("Fahrenheit", "°F", false, false, 5.0/9.0);return F;}
|
||||
};
|
||||
|
||||
/*!
|
||||
@@ -47,6 +52,14 @@ public:
|
||||
*/
|
||||
class CTemperature : public CPhysicalQuantity
|
||||
{
|
||||
protected:
|
||||
/*!
|
||||
* Specific method for temperature, a normal factor conversion is not sufficient.
|
||||
* \param otherUnit
|
||||
* \return
|
||||
*/
|
||||
virtual double calculateValueInOtherUnit(const CMeasurementUnit &otherUnit) const;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \brief Default constructor
|
||||
|
||||
11
tests/blackmisc/blackmisctest.h
Normal file
11
tests/blackmisc/blackmisctest.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef BLACKMISCTEST_H
|
||||
#define BLACKMISCTEST_H
|
||||
|
||||
/**
|
||||
* @namespace BlackMiscTest
|
||||
* Unit test for BlackMisc. Unit test do have their own namespace, so
|
||||
* the regular namespace BlackMiscis completely free of unit tests.
|
||||
* Add any new tests to TestMain::unitMain as shown there in the pattern.
|
||||
*/
|
||||
|
||||
#endif // BLACKMISCTEST_H
|
||||
@@ -10,7 +10,8 @@ CONFIG -= app_bundle
|
||||
DEPENDPATH += . ../../src
|
||||
INCLUDEPATH += . ../../src
|
||||
SOURCES += main.cpp testmain.cpp testphysicalquantitiesbase.cpp
|
||||
HEADERS += testmain.h testphysicalquantitiesbase.h
|
||||
HEADERS += testmain.h testphysicalquantitiesbase.h \
|
||||
blackmisctest.h
|
||||
|
||||
win32-msvc* {
|
||||
PRE_TARGETDEPS += ../../lib/blackmisc.lib
|
||||
|
||||
@@ -70,8 +70,8 @@ void TestPhysicalQuantitiesBase::speedBasics()
|
||||
{
|
||||
CSpeed s1(100, CSpeedUnit::km_h());
|
||||
CSpeed s2(1000, CSpeedUnit::ft_min());
|
||||
QVERIFY2(s1.valueRounded(CSpeedUnit::NM_h(),0) == 54, "100km/h is 54NM/h");
|
||||
QVERIFY2(s2.valueRounded(CSpeedUnit::m_s(),1) == 5.1, "1000ft/min is 5.1m/s");
|
||||
QVERIFY2(s1.valueRounded(CSpeedUnit::NM_h(),0) == 54, qPrintable(QString("100km/h is not %1 NM/h").arg(s1.valueRounded(CSpeedUnit::NM_h(),0))));
|
||||
QVERIFY2(s2.valueRounded(CSpeedUnit::m_s(),1) == 5.1, qPrintable(QString("1000ft/min is not %1 m/s").arg(s2.valueRounded(CSpeedUnit::m_s(),1))));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,8 +94,8 @@ void TestPhysicalQuantitiesBase::angleTests()
|
||||
CAngle a1(180, CAngleUnit::deg());
|
||||
CAngle a2(1.5 * CAngle::pi());
|
||||
a2.switchUnit(CAngleUnit::deg());
|
||||
QVERIFY2(a2.unitValueToInteger() == 270, "1.5Pi should be 270deg");
|
||||
QVERIFY2(a1.piFactor() == 1, "Pi should be 180deg");
|
||||
QVERIFY2(a2.unitValueToInteger() == 270, qPrintable(QString("1.5Pi should be 270deg, not %1 deg").arg(a2.unitValueToInteger())));
|
||||
QVERIFY2(a1.piFactor() == 1, qPrintable(QString("Pi should be 1PI,not %1").arg(a1.piFactor())));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -129,6 +129,20 @@ void TestPhysicalQuantitiesBase::pressureTests()
|
||||
QVERIFY2(p1.unitValueToDouble() == p4.unitValueToDouble(), "mbar/hPa test");
|
||||
}
|
||||
|
||||
/**
|
||||
* Temperature tests
|
||||
*/
|
||||
void TestPhysicalQuantitiesBase::temperatureTests()
|
||||
{
|
||||
CTemperature t1(0, CTemperatureUnit::C()); // 0C
|
||||
CTemperature t2(1, CTemperatureUnit::F()); // 1F
|
||||
CTemperature t3(220.15, CTemperatureUnit::F());
|
||||
QVERIFY2(t1.convertedSiValueToDoubleRounded() == 273.15, qPrintable(QString("0C shall be 273.15K, not %1 K").arg(t1.convertedSiValueToDoubleRounded())));
|
||||
QVERIFY2(t2.valueRounded(CTemperatureUnit::C()) == -17.22, qPrintable(QString("1F shall be -17.22C, not %1 C").arg(t2.valueRounded(CTemperatureUnit::C()))));
|
||||
QVERIFY2(t3.valueRounded(CTemperatureUnit::C()) == 104.53, qPrintable(QString("220.15F shall be 104.53C, not %1 C").arg(t3.valueRounded(CTemperatureUnit::C()))));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Just tesing obvious memory create / destruct flaws
|
||||
*/
|
||||
|
||||
@@ -48,6 +48,10 @@ private slots:
|
||||
* \brief Testing pressure
|
||||
*/
|
||||
void pressureTests();
|
||||
/*!
|
||||
* \brief Testing temperature
|
||||
*/
|
||||
void temperatureTests();
|
||||
/*!
|
||||
* \brief testing construction / destruction in memory
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user