mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-08 06:53:45 +00:00
Merge pull request #43 from hugovdm/getUnitCategory
Add getUnitCategory()
This commit is contained in:
commit
d406b915c4
3 changed files with 63 additions and 0 deletions
|
@ -357,6 +357,29 @@ int32_t getPreferenceMetadataIndex(const MaybeStackVector<UnitPreferenceMetadata
|
|||
|
||||
} // namespace
|
||||
|
||||
CharString U_I18N_API getUnitCategory(const char *baseUnitIdentifier, UErrorCode &status) {
|
||||
CharString result;
|
||||
LocalUResourceBundlePointer unitsBundle(ures_openDirect(NULL, "units", &status));
|
||||
LocalUResourceBundlePointer unitQuantities(
|
||||
ures_getByKey(unitsBundle.getAlias(), "unitQuantities", NULL, &status));
|
||||
int32_t categoryLength;
|
||||
if (U_FAILURE(status)) { return result; }
|
||||
const UChar *uCategory =
|
||||
ures_getStringByKey(unitQuantities.getAlias(), baseUnitIdentifier, &categoryLength, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
// TODO(CLDR-13787,hugovdm): special-casing the consumption-inverse
|
||||
// case. Once CLDR-13787 is clarified, this should be generalised (or
|
||||
// possibly removed):
|
||||
if (uprv_strcmp(baseUnitIdentifier, "meter-per-cubic-meter") == 0) {
|
||||
status = U_ZERO_ERROR;
|
||||
result.append("consumption-inverse", status);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
result.appendInvariantChars(uCategory, categoryLength, status);
|
||||
return result;
|
||||
}
|
||||
|
||||
// TODO: this may be unnecessary. Fold into ConversionRates class? Or move to anonymous namespace?
|
||||
void U_I18N_API getAllConversionRates(MaybeStackVector<ConversionRateInfo> &result, UErrorCode &status) {
|
||||
LocalUResourceBundlePointer unitsBundle(ures_openDirect(NULL, "units", &status));
|
||||
|
|
|
@ -14,6 +14,22 @@
|
|||
|
||||
U_NAMESPACE_BEGIN
|
||||
|
||||
/**
|
||||
* Looks up the unit category of a base unit identifier.
|
||||
*
|
||||
* Only supports base units, other units must be resolved to base units before
|
||||
* passing to this function.
|
||||
*
|
||||
* Categories are found in `unitQuantities` in the `units` resource (see
|
||||
* `units.txt`).
|
||||
*
|
||||
* TODO(hugovdm): if we give unitsdata.cpp access to the functionality of
|
||||
* `extractCompoundBaseUnit` which is currently in unitconverter.cpp, we could
|
||||
* support all units for which there is a category. Does it make sense to move
|
||||
* that function to unitsdata.cpp?
|
||||
*/
|
||||
CharString U_I18N_API getUnitCategory(const char *baseUnitIdentifier, UErrorCode &status);
|
||||
|
||||
/**
|
||||
* Encapsulates "convertUnits" information from units resources, specifying how
|
||||
* to convert from one unit to another.
|
||||
|
|
|
@ -12,6 +12,7 @@ class UnitsDataTest : public IntlTest {
|
|||
|
||||
void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = NULL);
|
||||
|
||||
void testGetUnitCategory();
|
||||
void testGetAllConversionRates();
|
||||
void testGetPreferences();
|
||||
};
|
||||
|
@ -21,11 +22,34 @@ extern IntlTest *createUnitsDataTest() { return new UnitsDataTest(); }
|
|||
void UnitsDataTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char * /*par*/) {
|
||||
if (exec) { logln("TestSuite UnitsDataTest: "); }
|
||||
TESTCASE_AUTO_BEGIN;
|
||||
TESTCASE_AUTO(testGetUnitCategory);
|
||||
TESTCASE_AUTO(testGetAllConversionRates);
|
||||
TESTCASE_AUTO(testGetPreferences);
|
||||
TESTCASE_AUTO_END;
|
||||
}
|
||||
|
||||
void UnitsDataTest::testGetUnitCategory() {
|
||||
struct TestCase {
|
||||
const char *unit;
|
||||
const char *expectedCategory;
|
||||
} testCases[]{
|
||||
{"kilogram-per-cubic-meter", "mass-density"},
|
||||
{"cubic-meter-per-meter", "consumption"},
|
||||
// TODO(CLDR-13787,hugovdm): currently we're treating
|
||||
// consumption-inverse as a separate category. Once consumption
|
||||
// preference handling has been clarified by CLDR-13787, this function
|
||||
// should be fixed.
|
||||
{"meter-per-cubic-meter", "consumption-inverse"},
|
||||
};
|
||||
|
||||
IcuTestErrorCode status(*this, "testGetUnitCategory");
|
||||
for (const auto &t : testCases) {
|
||||
CharString category = getUnitCategory(t.unit, status);
|
||||
status.errIfFailureAndReset("getUnitCategory(%s)", t.unit);
|
||||
assertEquals("category", t.expectedCategory, category.data());
|
||||
}
|
||||
}
|
||||
|
||||
void UnitsDataTest::testGetAllConversionRates() {
|
||||
IcuTestErrorCode status(*this, "testGetAllConversionRates");
|
||||
MaybeStackVector<ConversionRateInfo> conversionInfo;
|
||||
|
|
Loading…
Add table
Reference in a new issue