}
}
+// The input unit needs to be simple, but can have dimensionality != 1.
void processSingleUnit(const MeasureUnit &unit, const UResourceBundle *convertUnitsBundle,
ConversionRateDataSink &convertSink, MeasureUnit *baseSingleUnit,
UErrorCode &status) {
ures_getAllItemsWithFallback(convertUnitsBundle, simple.getIdentifier(), convertSink, status);
if (baseSingleUnit != NULL) {
- *baseSingleUnit = convertSink.getLastBaseUnit(status).withDimensionality(dimensionality, status);
+ MeasureUnit baseUnit = convertSink.getLastBaseUnit(status);
+
+ if (dimensionality == 1) {
+ *baseSingleUnit = baseUnit;
+ } else if (baseUnit.getComplexity(status) == UMEASURE_UNIT_SINGLE) {
+ // TODO(hugovdm): find examples where we're converting a *-per-* to
+ // a square-*? Does one ever square frequency? What about
+ // squared-speed in the case of mv^2? Or F=ma^2?
+ //
+ // baseUnit might also have dimensionality, e.g. cubic-meter -
+ // retain this instead of overriding with input unit dimensionality:
+ dimensionality *= baseUnit.getDimensionality(status);
+ *baseSingleUnit = baseUnit.withDimensionality(dimensionality, status);
+ } else {
+ // We only support higher dimensionality input units if they map to
+ // simple base units, such that that base unit can have the
+ // dimensionality easily applied.
+ //
+ // TODO(hugovdm): produce succeeding examples of simple input unit
+ // mapped to a different simple target/base unit.
+ //
+ // TODO(hugovdm): produce failing examples of higher-dimensionality
+ // or inverted input units that map to compound output units.
+ status = U_ILLEGAL_ARGUMENT_ERROR;
+ return;
+ }
}
}
}
}
if (baseCompoundUnit != NULL) {
- fprintf(stderr, "source base: %s\n", baseCompoundUnit->getIdentifier());
*baseCompoundUnit = MeasureUnit();
}
for (int i = 0; i < targetUnitsLength; i++) {
{"centimeter-per-square-milligram",
"inch-per-square-ounce",
{"pound", "stone", "ton"},
- "kilogram"},
+ "meter-per-square-kilogram"},
{"liter", "gallon", {"liter", "gallon", NULL}, "cubic-meter"},
{"stone-and-pound", "ton", {"pound", "stone", "ton"}, "kilogram"},
{"mile-per-hour", "dekameter-per-hour", {"mile", "hour", "meter"}, "meter-per-second"},
+ {"kilovolt-ampere",
+ "horsepower",
+ {"volt", "ampere", "horsepower"},
+ "kilogram-square-meter-per-cubic-second"}, // watt
+ // TODO: include capacitance test case with base unit:
+ // pow4-second-square-ampere-per-kilogram-square-meter;
};
for (const auto &t : testCases) {
logln("---testing: source=\"%s\", target=\"%s\", expectedBaseUnit=\"%s\"", t.sourceUnit,
MeasureUnit targetUnit = MeasureUnit::forIdentifier(t.targetUnit, status);
MaybeStackVector<ConversionRateInfo> conversionInfo =
getConversionRatesInfo(sourceUnit, targetUnit, &baseCompoundUnit, status);
+ if (status.errIfFailureAndReset("getConversionRatesInfo(<%s>, <%s>, ...)",
+ sourceUnit.getIdentifier(), targetUnit.getIdentifier())) {
+ continue;
+ }
- logln("---found BaseUnit=\"%s\"", baseCompoundUnit.getIdentifier());
+ assertEquals("baseCompoundUnit returned by getConversionRatesInfo", t.baseUnit,
+ baseCompoundUnit.getIdentifier());
for (int i = 0; i < conversionInfo.length(); i++) {
ConversionRateInfo *cri;
cri = conversionInfo[i];