U_NAMESPACE_BEGIN
namespace {
-
-const ConversionRateInfo *
-extractConversionInfo(StringPiece source,
- const MaybeStackVector<ConversionRateInfo> &conversionRateInfoList,
- UErrorCode &status) {
- for (size_t i = 0, n = conversionRateInfoList.length(); i < n; ++i) {
- if (conversionRateInfoList[i]->sourceUnit.toStringPiece() == source)
- return conversionRateInfoList[i];
- }
-
- status = U_INTERNAL_PROGRAM_ERROR;
- return nullptr;
-}
-
/**
* Extracts the compound base unit of a compound unit (`source`). For example, if the source unit is
* `square-mile-per-hour`, the compound base unit will be `square-meter-per-second`
*/
-MeasureUnit extractCompoundBaseUnit(const MeasureUnit &source,
- const MaybeStackVector<ConversionRateInfo> &conversionRateInfoList,
+MeasureUnit extractCompoundBaseUnit(const MeasureUnit &source, const ConversionRates &conversionRates,
UErrorCode &status) {
MeasureUnit result;
int32_t count;
// Extract `ConversionRateInfo` using the absolute unit. For example: in case of `square-meter`,
// we will use `meter`
const auto singleUnitImpl = SingleUnitImpl::forMeasureUnit(singleUnit, status);
- const auto rateInfo =
- extractConversionInfo(singleUnitImpl.identifier, conversionRateInfoList, status);
+ const auto rateInfo = conversionRates.extractConversionInfo(singleUnitImpl.identifier, status);
if (U_FAILURE(status)) return result;
if (rateInfo == nullptr) {
status = U_INTERNAL_PROGRAM_ERROR;
int32_t baseUnitsCount;
auto baseUnits = compoundBaseUnit.splitToSingleUnits(baseUnitsCount, status);
for (int j = 0; j < baseUnitsCount; j++) {
- result =
- result.product(baseUnits[j].withDimensionality(baseUnits[j].getDimensionality(status) *
- singleUnit.getDimensionality(status),
- status),
- status);
+ int8_t newDimensionality =
+ baseUnits[j].getDimensionality(status) * singleUnit.getDimensionality(status);
+ result = result.product(baseUnits[j].withDimensionality(newDimensionality, status), status);
+
+ if (U_FAILURE(status)) { return result; }
}
}
} // namespace
-UnitsConvertibilityState U_I18N_API checkConvertibility(
- const MeasureUnit &source, const MeasureUnit &target,
- const MaybeStackVector<ConversionRateInfo> &conversionRateInfoList, UErrorCode &status) {
- auto sourceBaseUnit = extractCompoundBaseUnit(source, conversionRateInfoList, status);
- auto targetBaseUnit = extractCompoundBaseUnit(target, conversionRateInfoList, status);
+UnitsConvertibilityState U_I18N_API checkConvertibility(const MeasureUnit &source,
+ const MeasureUnit &target,
+ const ConversionRates &conversionRates,
+ UErrorCode &status) {
+ auto sourceBaseUnit = extractCompoundBaseUnit(source, conversionRates, status);
+ auto targetBaseUnit = extractCompoundBaseUnit(target, conversionRates, status);
if (U_FAILURE(status)) return UNCONVERTIBLE;
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = NULL);
void testConversionCapability();
- // void testConversions(); // TODO(hugo): it doesnot pass.
+ void testConversions();
void testPreferences();
// void testBasic();
// void testSiPrefixes();
{"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}, //
MeasureUnit source = MeasureUnit::forIdentifier(testCase.source, status);
MeasureUnit target = MeasureUnit::forIdentifier(testCase.target, status);
- MaybeStackVector<MeasureUnit> units;
- units.emplaceBack(source);
- units.emplaceBack(target);
-
- const auto &conversionRateInfoList = getConversionRatesInfo(units, status);
- auto convertibility = checkConvertibility(source, target, conversionRateInfoList, status);
+ ConversionRates conversionRates(status);
+ auto convertibility = checkConvertibility(source, target, conversionRates, status);
assertEquals("Conversion Capability", testCase.expectedState, convertibility);
}
*/
void unitsTestDataLineFn(void *context, char *fields[][2], int32_t fieldCount, UErrorCode *pErrorCode) {
if (U_FAILURE(*pErrorCode)) return;
- UnitsTest *unitsTest = (UnitsTest *)context;
+ UnitsTest* unitsTest = (UnitsTest*)context;
(void)fieldCount; // unused UParseLineFn variable
IcuTestErrorCode status(*unitsTest, "unitsTestDatalineFn");
quantity.length(), quantity.data(), x.length(), x.data(), y.length(), y.data(),
expected, commentConversionFormula.length(), commentConversionFormula.data());
- // Convertibility:
- MaybeStackVector<MeasureUnit> units;
- units.emplaceBack(sourceUnit);
- units.emplaceBack(targetUnit);
- const auto &conversionRateInfoList = getConversionRatesInfo(units, status);
- if (status.errIfFailureAndReset("getConversionRatesInfo(...)")) return;
+ // WIP(hugovdm): hook this up to actual tests.
+
+ // // Convertibility:
+ // MaybeStackVector<MeasureUnit> units;
+ // units.emplaceBack(sourceUnit);
+ // units.emplaceBack(targetUnit);
+ // const auto &conversionRateInfoList = getConversionRatesInfo(units, status);
+ // if (status.errIfFailureAndReset("getConversionRatesInfo(...)")) return;
- auto actualState = checkConvertibility(sourceUnit, targetUnit, conversionRateInfoList, status);
- if (status.errIfFailureAndReset("checkConvertibility(<%s>, <%s>, ...)", sourceUnit.getIdentifier(),
- targetUnit.getIdentifier())) {
- return;
- }
+ // auto actualState = checkUnitsState(sourceUnit, targetUnit, conversionRateInfoList, status);
+ // if (status.errIfFailureAndReset("checkUnitsState(<%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;
+ // 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);
+ // unitsTest->assertTrue(msg.data(), actualState != UNCONVERTIBLE);
// Unit conversion... untested:
// UnitConverter converter(sourceUnit, targetUnit, status);
// unitsTest->assertEqualsNear(quantity.data(), expected, got, 0.0001);
}
-// /**
-// * Runs data-driven unit tests for unit conversion. It looks for the test cases
-// * in source/test/testdata/units/unitsTest.txt, which originates in CLDR.
-// */
-// void UnitsTest::testConversions() {
-// const char *filename = "unitsTest.txt";
-// const int32_t kNumFields = 5;
-// char *fields[kNumFields][2];
-
-// IcuTestErrorCode errorCode(*this, "UnitsTest::testConversions");
-// const char *sourceTestDataPath = getSourceTestData(errorCode);
-// if (errorCode.errIfFailureAndReset("unable to find the source/test/testdata "
-// "folder (getSourceTestData())")) {
-// return;
-// }
+/**
+ * Runs data-driven unit tests for unit conversion. It looks for the test cases
+ * in source/test/testdata/units/unitsTest.txt, which originates in CLDR.
+ */
+void UnitsTest::testConversions() {
+ const char *filename = "unitsTest.txt";
+ const int32_t kNumFields = 5;
+ char *fields[kNumFields][2];
+
+ IcuTestErrorCode errorCode(*this, "UnitsTest::testConversions");
+ const char *sourceTestDataPath = getSourceTestData(errorCode);
+ if (errorCode.errIfFailureAndReset("unable to find the source/test/testdata "
+ "folder (getSourceTestData())")) {
+ return;
+ }
-// CharString path(sourceTestDataPath, errorCode);
-// path.appendPathPart("units", errorCode);
-// path.appendPathPart(filename, errorCode);
+ CharString path(sourceTestDataPath, errorCode);
+ path.appendPathPart("units", errorCode);
+ path.appendPathPart(filename, errorCode);
-// u_parseDelimitedFile(path.data(), ';', fields, kNumFields, unitsTestDataLineFn, this, errorCode);
-// if (errorCode.errIfFailureAndReset("error parsing %s: %s\n", path.data(), u_errorName(errorCode)))
-// {
-// return;
-// }
-// }
+ u_parseDelimitedFile(path.data(), ';', fields, kNumFields, unitsTestDataLineFn, this, errorCode);
+ if (errorCode.errIfFailureAndReset("error parsing %s: %s\n", path.data(), u_errorName(errorCode))) {
+ return;
+ }
+}
/**
* This class represents the output fields from unitPreferencesTest.txt. Please