ICU-20568 testConversions: test convertibility of unitsTest.txt test cases.
PR: https://github.com/sffc/icu/pull/39
Commit: 3202693e542e300e235096557777d4892548d676
diff --git a/icu4c/source/test/intltest/intltest.cpp b/icu4c/source/test/intltest/intltest.cpp
index cbfb512..c264e09 100644
--- a/icu4c/source/test/intltest/intltest.cpp
+++ b/icu4c/source/test/intltest/intltest.cpp
@@ -2155,6 +2155,23 @@
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 @@
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,
diff --git a/icu4c/source/test/intltest/intltest.h b/icu4c/source/test/intltest/intltest.h
index 4ee9b83..59a7679 100644
--- a/icu4c/source/test/intltest/intltest.h
+++ b/icu4c/source/test/intltest/intltest.h
@@ -306,6 +306,7 @@
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 @@
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 !
diff --git a/icu4c/source/test/intltest/unitstest.cpp b/icu4c/source/test/intltest/unitstest.cpp
index 1f85e88..d3ecf60 100644
--- a/icu4c/source/test/intltest/unitstest.cpp
+++ b/icu4c/source/test/intltest/unitstest.cpp
@@ -67,55 +67,14 @@
const StringPiece target;
const UnitsConvertibilityState expectedState;
} testCases[]{
- {"meter", "foot", CONVERTIBLE}, //
- {"kilometer", "foot", CONVERTIBLE}, //
- {"hectare", "square-foot", CONVERTIBLE}, //
- {"kilometer-per-second", "second-per-meter", RECIPROCAL}, //
- {"square-meter", "square-foot", CONVERTIBLE}, //
- {"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}, //
+ {"meter", "foot", CONVERTIBLE}, //
+ {"kilometer", "foot", CONVERTIBLE}, //
+ {"hectare", "square-foot", CONVERTIBLE}, //
+ {"kilometer-per-second", "second-per-meter", RECIPROCAL}, //
+ {"square-meter", "square-foot", CONVERTIBLE}, //
+ {"kilometer-per-second", "foot-per-second", CONVERTIBLE}, //
+ {"square-hectare", "p4-foot", CONVERTIBLE}, //
+ {"square-kilometer-per-second", "second-per-square-meter", RECIPROCAL}, //
};
for (const auto &testCase : testCases) {
@@ -265,13 +224,24 @@
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 @@
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 @@
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 @@
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;
}
diff --git a/icu4c/source/test/testdata/units/unitsTest.txt b/icu4c/source/test/testdata/units/unitsTest.txt
index 2ab615d..31b0e25 100644
--- a/icu4c/source/test/testdata/units/unitsTest.txt
+++ b/icu4c/source/test/testdata/units/unitsTest.txt
@@ -142,7 +142,7 @@
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