ICU-20568 testConversions: test convertibility of unitsTest.txt test cases.

PR: https://github.com/sffc/icu/pull/39
Commit: 3202693e542e300e235096557777d4892548d676
This commit is contained in:
Hugo van der Merwe 2020-04-28 21:48:28 +02:00
parent c49cb73509
commit 4d07e3b10f
4 changed files with 73 additions and 83 deletions

View File

@ -2155,6 +2155,23 @@ UBool IntlTest::assertEquals(const char* message,
return TRUE;
}
UBool IntlTest::assertNotEquals(const char* message,
int32_t expectedNot,
int32_t actual) {
if (expectedNot == actual) {
errln((UnicodeString)("FAIL: ") + message + "; got " + actual + "=0x" + toHex(actual) +
"; expected != " + expectedNot);
return FALSE;
}
#ifdef VERBOSE_ASSERTIONS
else {
logln((UnicodeString)("Ok: ") + message + "; got " + actual + "=0x" + toHex(actual) +
" != " + expectedNot);
}
#endif
return TRUE;
}
static char ASSERT_BUF[256];
static const char* extractToAssertBuf(const UnicodeString& message) {
@ -2224,6 +2241,11 @@ UBool IntlTest::assertEquals(const UnicodeString& message,
const std::vector<std::string>& actual) {
return assertEquals(extractToAssertBuf(message), expected, actual);
}
UBool IntlTest::assertNotEquals(const UnicodeString &message,
int32_t expectedNot,
int32_t actual) {
return assertNotEquals(extractToAssertBuf(message), expectedNot, actual);
}
#if !UCONFIG_NO_FORMATTING
UBool IntlTest::assertEquals(const UnicodeString& message,

View File

@ -306,6 +306,7 @@ public:
UBool assertEquals(const UnicodeString& message, const Formattable& expected,
const Formattable& actual);
#endif
UBool assertNotEquals(const char* message, int32_t expectedNot, int32_t actual);
UBool assertTrue(const UnicodeString& message, UBool condition, UBool quiet=FALSE, UBool possibleDataError=FALSE);
UBool assertFalse(const UnicodeString& message, UBool condition, UBool quiet=FALSE, UBool possibleDataError=FALSE);
UBool assertSuccess(const UnicodeString& message, UErrorCode ec);
@ -320,6 +321,7 @@ public:
UBool assertEquals(const UnicodeString& message, const UnicodeSet& expected, const UnicodeSet& actual);
UBool assertEquals(const UnicodeString& message,
const std::vector<std::string>& expected, const std::vector<std::string>& actual);
UBool assertNotEquals(const UnicodeString& message, int32_t expectedNot, int32_t actual);
virtual void runIndexedTest( int32_t index, UBool exec, const char* &name, char* par = NULL ); // overide !

View File

@ -75,47 +75,6 @@ void UnitsTest::testConversionCapability() {
{"kilometer-per-second", "foot-per-second", CONVERTIBLE}, //
{"square-hectare", "p4-foot", CONVERTIBLE}, //
{"square-kilometer-per-second", "second-per-square-meter", RECIPROCAL}, //
// TODO: Remove the following test cases after hocking up unitsTest.txt.
{"g-force", "meter-per-square-second", CONVERTIBLE}, //
{"ohm", "kilogram-square-meter-per-cubic-second-square-ampere", CONVERTIBLE}, //
{"electronvolt", "kilogram-square-meter-per-square-second", CONVERTIBLE}, //
{"dalton", "kilogram-square-meter-per-square-second", CONVERTIBLE}, //
{"joule", "kilogram-square-meter-per-square-second", CONVERTIBLE}, //
{"meter-newton", "kilogram-square-meter-per-square-second", CONVERTIBLE}, //
{"foot-pound-force", "kilogram-square-meter-per-square-second", CONVERTIBLE}, //
{"calorie", "kilogram-square-meter-per-square-second", CONVERTIBLE}, //
{"kilojoule", "kilogram-square-meter-per-square-second", CONVERTIBLE}, //
{"british-thermal-unit", "kilogram-square-meter-per-square-second", CONVERTIBLE}, //
{"foodcalorie", "kilogram-square-meter-per-square-second", CONVERTIBLE}, //
{"kilocalorie", "kilogram-square-meter-per-square-second", CONVERTIBLE}, //
{"hour-kilowatt", "kilogram-square-meter-second-per-cubic-second", CONVERTIBLE}, //
{"therm-us", "kilogram-square-meter-per-square-second", CONVERTIBLE}, //
{"newton", "kilogram-meter-per-square-second", CONVERTIBLE}, //
{"pound-force", "kilogram-meter-per-square-second", CONVERTIBLE}, //
{"hertz", "revolution-per-second", CONVERTIBLE}, //
{"kilohertz", "revolution-per-second", CONVERTIBLE}, //
{"megahertz", "revolution-per-second", CONVERTIBLE}, //
{"gigahertz", "revolution-per-second", CONVERTIBLE}, //
{"lux", "candela-square-meter-per-square-meter", CONVERTIBLE}, //
{"milliwatt", "kilogram-square-meter-per-cubic-second", CONVERTIBLE}, //
{"watt", "kilogram-square-meter-per-cubic-second", CONVERTIBLE}, //
{"horsepower", "kilogram-square-meter-per-cubic-second", CONVERTIBLE}, //
{"kilowatt", "kilogram-square-meter-per-cubic-second", CONVERTIBLE}, //
{"megawatt", "kilogram-square-meter-per-cubic-second", CONVERTIBLE}, //
{"gigawatt", "kilogram-square-meter-per-cubic-second", CONVERTIBLE}, //
{"solar-luminosity", "kilogram-square-meter-per-cubic-second", CONVERTIBLE}, //
{"pascal", "kilogram-per-meter-square-second", CONVERTIBLE}, //
{"hectopascal", "kilogram-per-meter-square-second", CONVERTIBLE}, //
{"millibar", "kilogram-per-meter-square-second", CONVERTIBLE}, //
{"millimeter-ofhg", "kilogram-meter-per-square-meter-square-second", CONVERTIBLE}, //
{"kilopascal", "kilogram-per-meter-square-second", CONVERTIBLE}, //
{"inch-ofhg", "kilogram-meter-per-square-meter-square-second", CONVERTIBLE}, //
{"bar", "kilogram-per-meter-square-second", CONVERTIBLE}, //
{"atmosphere", "kilogram-per-meter-square-second", CONVERTIBLE}, //
{"megapascal", "kilogram-per-meter-square-second", CONVERTIBLE}, //
{"ofhg", "kilogram-per-square-meter-square-second", CONVERTIBLE}, //
{"knot", "meter-per-second", CONVERTIBLE}, //
{"volt", "kilogram-square-meter-per-cubic-second-ampere", CONVERTIBLE}, //
};
for (const auto &testCase : testCases) {
@ -265,13 +224,24 @@ StringPiece trimField(char *(&field)[2]) {
return StringPiece(start, length);
}
// Used for passing context to unitsTestDataLineFn via u_parseDelimitedFile.
struct UnitsTestContext {
// Provides access to UnitsTest methods like logln.
UnitsTest *unitsTest;
// Conversion rates: does not take ownership.
ConversionRates *conversionRates;
};
/**
* Deals with a single data-driven unit test for unit conversions. This
* UParseLineFn for use by u_parseDelimitedFile is intended for "unitsTest.txt".
* WIP(hugovdm): deals with a single data-driven unit test for unit conversions.
* This is a UParseLineFn as required by u_parseDelimitedFile.
*
* context must point at a UnitsTestContext struct.
*/
void unitsTestDataLineFn(void *context, char *fields[][2], int32_t fieldCount, UErrorCode *pErrorCode) {
if (U_FAILURE(*pErrorCode)) return;
UnitsTest* unitsTest = (UnitsTest*)context;
if (U_FAILURE(*pErrorCode)) { return; }
UnitsTestContext *ctx = (UnitsTestContext *)context;
UnitsTest* unitsTest = ctx->unitsTest;
(void)fieldCount; // unused UParseLineFn variable
IcuTestErrorCode status(*unitsTest, "unitsTestDatalineFn");
@ -287,10 +257,10 @@ void unitsTestDataLineFn(void *context, char *fields[][2], int32_t fieldCount, U
unum_close(nf);
MeasureUnit sourceUnit = MeasureUnit::forIdentifier(x, status);
if (status.errIfFailureAndReset("forIdentifier(\"%.*s\")", x.length(), x.data())) return;
if (status.errIfFailureAndReset("forIdentifier(\"%.*s\")", x.length(), x.data())) { return; }
MeasureUnit targetUnit = MeasureUnit::forIdentifier(y, status);
if (status.errIfFailureAndReset("forIdentifier(\"%.*s\")", y.length(), y.data())) return;
if (status.errIfFailureAndReset("forIdentifier(\"%.*s\")", y.length(), y.data())) { return; }
unitsTest->logln("Quantity (Category): \"%.*s\", "
"Expected value of \"1000 %.*s in %.*s\": %f, "
@ -298,35 +268,29 @@ void unitsTestDataLineFn(void *context, char *fields[][2], int32_t fieldCount, U
quantity.length(), quantity.data(), x.length(), x.data(), y.length(), y.data(),
expected, commentConversionFormula.length(), commentConversionFormula.data());
// WIP(hugovdm): hook this up to actual tests.
// Convertibility:
auto convertibility = checkConvertibility(sourceUnit, targetUnit, *ctx->conversionRates, status);
if (status.errIfFailureAndReset("checkConvertibility(<%s>, <%s>, ...)", sourceUnit.getIdentifier(),
targetUnit.getIdentifier())) {
return;
}
CharString msg;
msg.append("convertible: ", status)
.append(sourceUnit.getIdentifier(), status)
.append(" -> ", status)
.append(targetUnit.getIdentifier(), status);
if (status.errIfFailureAndReset("msg construction")) { return; }
unitsTest->assertNotEquals(msg.data(), UNCONVERTIBLE, convertibility);
// // Convertibility:
// MaybeStackVector<MeasureUnit> units;
// units.emplaceBack(sourceUnit);
// units.emplaceBack(targetUnit);
// const auto &conversionRateInfoList = getConversionRatesInfo(units, status);
// if (status.errIfFailureAndReset("getConversionRatesInfo(...)")) return;
// auto actualState = checkUnitsState(sourceUnit, targetUnit, conversionRateInfoList, status);
// if (status.errIfFailureAndReset("checkUnitsState(<%s>, <%s>, ...)", sourceUnit.getIdentifier(),
// targetUnit.getIdentifier())) {
// TODO(hugovdm,younies): the following code can be uncommented (and
// fixed) once merged with a UnitConverter branch:
// UnitConverter converter(sourceUnit, targetUnit, unitsTest->conversionRates_, status);
// if (status.errIfFailureAndReset("constructor: UnitConverter(<%s>, <%s>, status)",
// sourceUnit.getIdentifier(), targetUnit.getIdentifier())) {
// return;
// }
// CharString msg;
// msg.append("convertible: ", status)
// .append(sourceUnit.getIdentifier(), status)
// .append(" -> ", status)
// .append(targetUnit.getIdentifier(), status);
// if (status.errIfFailureAndReset("msg construction")) return;
// unitsTest->assertTrue(msg.data(), actualState != UNCONVERTIBLE);
// TODO(hugovdm,younies): add conversion testing in unitsTestDataLineFn:
//
// UnitConverter converter(sourceUnit, targetUnit, status);
// double got = converter.convert(1000, status);
// unitsTest->assertEqualsNear(quantity.data(), expected, got, 0.0001);
// double got = converter.convert(1000);
// unitsTest->assertEqualsNear(fields[0][0], expected, got, 0.0001);
}
/**
@ -349,7 +313,9 @@ void UnitsTest::testConversions() {
path.appendPathPart("units", errorCode);
path.appendPathPart(filename, errorCode);
u_parseDelimitedFile(path.data(), ';', fields, kNumFields, unitsTestDataLineFn, this, errorCode);
ConversionRates rates(errorCode);
UnitsTestContext ctx = {this, &rates};
u_parseDelimitedFile(path.data(), ';', fields, kNumFields, unitsTestDataLineFn, &ctx, errorCode);
if (errorCode.errIfFailureAndReset("error parsing %s: %s\n", path.data(), u_errorName(errorCode))) {
return;
}

View File

@ -142,7 +142,7 @@ pressure ; millibar ; kilogram-per-meter-square-second ; 100 * x
pressure ; millimeter-ofhg ; kilogram-meter-per-square-meter-square-second ; 133.322387415 * x ; 133322.4
pressure ; kilopascal ; kilogram-per-meter-square-second ; 1,000 * x ; 1000000.0
pressure ; inch-ofhg ; kilogram-meter-per-square-meter-square-second ; 3,386.388640341 * x ; 3386389.0
#WIP(MeasureUnit parsing bug)#pressure ; pound-force-per-square-inch ; kilogram-meter-per-square-meter-square-second ; 111,205,540.3815125/16,129 * x ; 6894757.0
pressure ; pound-force-per-square-inch ; kilogram-meter-per-square-meter-square-second ; 111,205,540.3815125/16,129 * x ; 6894757.0
pressure ; bar ; kilogram-per-meter-square-second ; 100,000 * x ; 1.0E8
pressure ; atmosphere ; kilogram-per-meter-square-second ; 101,325 * x ; 1.01325E8
pressure ; megapascal ; kilogram-per-meter-square-second ; 1,000,000 * x ; 1.0E9