| // © 2020 and later: Unicode, Inc. and others. |
| // License & terms of use: http://www.unicode.org/copyright.html#License |
| |
| #include "unicode/utypes.h" |
| |
| #if !UCONFIG_NO_FORMATTING |
| |
| #include "measunit_impl.h" |
| #include "units_data.h" |
| |
| #include "intltest.h" |
| |
| using namespace ::icu::units; |
| |
| // These test are no in ICU4J. TODO: consider porting them to Java? |
| class UnitsDataTest : public IntlTest { |
| public: |
| UnitsDataTest() {} |
| |
| void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = NULL); |
| |
| void testGetUnitCategory(); |
| void testGetAllConversionRates(); |
| void testGetPreferencesFor(); |
| }; |
| |
| 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(testGetPreferencesFor); |
| TESTCASE_AUTO_END; |
| } |
| |
| void UnitsDataTest::testGetUnitCategory() { |
| struct TestCase { |
| const char *unit; |
| const char *expectedCategory; |
| } testCases[]{ |
| {"kilogram-per-cubic-meter", "mass-density"}, |
| {"cubic-meter-per-kilogram", "specific-volume"}, |
| {"meter-per-second", "speed"}, |
| // TODO(icu-units#130): inverse-speed |
| // {"second-per-meter", "speed"}, |
| // Consumption specifically supports inverse units (mile-per-galon, |
| // liter-per-100-kilometer): |
| {"cubic-meter-per-meter", "consumption"}, |
| {"meter-per-cubic-meter", "consumption"}, |
| }; |
| |
| IcuTestErrorCode status(*this, "testGetUnitCategory"); |
| for (const auto &t : testCases) { |
| CharString category = getUnitQuantity(t.unit, status); |
| if (!status.errIfFailureAndReset("getUnitCategory(%s)", t.unit)) { |
| assertEquals("category", t.expectedCategory, category.data()); |
| } |
| } |
| } |
| |
| void UnitsDataTest::testGetAllConversionRates() { |
| IcuTestErrorCode status(*this, "testGetAllConversionRates"); |
| MaybeStackVector<ConversionRateInfo> conversionInfo; |
| getAllConversionRates(conversionInfo, status); |
| |
| // Convenience output for debugging |
| for (int i = 0; i < conversionInfo.length(); i++) { |
| ConversionRateInfo *cri = conversionInfo[i]; |
| logln("* conversionInfo %d: source=\"%s\", baseUnit=\"%s\", factor=\"%s\", offset=\"%s\"", i, |
| cri->sourceUnit.data(), cri->baseUnit.data(), cri->factor.data(), cri->offset.data()); |
| assertTrue("sourceUnit", cri->sourceUnit.length() > 0); |
| assertTrue("baseUnit", cri->baseUnit.length() > 0); |
| assertTrue("factor", cri->factor.length() > 0); |
| } |
| } |
| |
| class UnitPreferencesOpenedUp : public UnitPreferences { |
| public: |
| UnitPreferencesOpenedUp(UErrorCode &status) : UnitPreferences(status) {} |
| const MaybeStackVector<UnitPreferenceMetadata> *getInternalMetadata() const { return &metadata_; } |
| const MaybeStackVector<UnitPreference> *getInternalUnitPrefs() const { return &unitPrefs_; } |
| }; |
| |
| /** |
| * This test is dependent upon CLDR Data: when the preferences change, the test |
| * may fail: see the constants for expected Max/Min unit identifiers, for US and |
| * World, and for Roads and default lengths. |
| */ |
| void UnitsDataTest::testGetPreferencesFor() { |
| const char* USRoadMax = "mile"; |
| const char* USRoadMin = "foot"; |
| const char* USLenMax = "mile"; |
| const char* USLenMin = "inch"; |
| const char* WorldRoadMax = "kilometer"; |
| const char* WorldRoadMin = "meter"; |
| const char* WorldLenMax = "kilometer"; |
| const char* WorldLenMin = "centimeter"; |
| struct TestCase { |
| const char *name; |
| const char *category; |
| const char *usage; |
| const char *region; |
| const char *expectedBiggest; |
| const char *expectedSmallest; |
| } testCases[]{ |
| {"US road", "length", "road", "US", USRoadMax, USRoadMin}, |
| {"001 road", "length", "road", "001", WorldRoadMax, WorldRoadMin}, |
| {"US lengths", "length", "default", "US", USLenMax, USLenMin}, |
| {"001 lengths", "length", "default", "001", WorldLenMax, WorldLenMin}, |
| {"XX road falls back to 001", "length", "road", "XX", WorldRoadMax, WorldRoadMin}, |
| {"XX default falls back to 001", "length", "default", "XX", WorldLenMax, WorldLenMin}, |
| {"Unknown usage US", "length", "foobar", "US", USLenMax, USLenMin}, |
| {"Unknown usage 001", "length", "foobar", "XX", WorldLenMax, WorldLenMin}, |
| {"Fallback", "length", "person-height-xyzzy", "DE", "centimeter", "centimeter"}, |
| {"Fallback twice", "length", "person-height-xyzzy-foo", "DE", "centimeter", |
| "centimeter"}, |
| // Confirming results for some unitPreferencesTest.txt test cases |
| {"001 area", "area", "default", "001", "square-kilometer", "square-centimeter"}, |
| {"GB area", "area", "default", "GB", "square-mile", "square-inch"}, |
| {"001 area geograph", "area", "geograph", "001", "square-kilometer", "square-kilometer"}, |
| {"GB area geograph", "area", "geograph", "GB", "square-mile", "square-mile"}, |
| {"CA person-height", "length", "person-height", "CA", "foot-and-inch", "inch"}, |
| {"AT person-height", "length", "person-height", "AT", "meter-and-centimeter", |
| "meter-and-centimeter"}, |
| }; |
| IcuTestErrorCode status(*this, "testGetPreferencesFor"); |
| UnitPreferencesOpenedUp preferences(status); |
| auto *metadata = preferences.getInternalMetadata(); |
| auto *unitPrefs = preferences.getInternalUnitPrefs(); |
| assertTrue(UnicodeString("Metadata count: ") + metadata->length() + " > 200", |
| metadata->length() > 200); |
| assertTrue(UnicodeString("Preferences count: ") + unitPrefs->length() + " > 250", |
| unitPrefs->length() > 250); |
| |
| for (const auto &t : testCases) { |
| logln(t.name); |
| const UnitPreference *const *prefs; |
| int32_t prefsCount; |
| preferences.getPreferencesFor(t.category, t.usage, t.region, prefs, prefsCount, status); |
| if (status.errIfFailureAndReset("getPreferencesFor(\"%s\", \"%s\", \"%s\", ...", t.category, |
| t.usage, t.region)) { |
| continue; |
| } |
| if (prefsCount > 0) { |
| assertEquals(UnicodeString(t.name) + " - max unit", t.expectedBiggest, |
| prefs[0]->unit.data()); |
| assertEquals(UnicodeString(t.name) + " - min unit", t.expectedSmallest, |
| prefs[prefsCount - 1]->unit.data()); |
| } else { |
| errln(UnicodeString(t.name) + ": failed to find preferences"); |
| } |
| status.errIfFailureAndReset("testCase '%s'", t.name); |
| } |
| } |
| |
| #endif /* #if !UCONFIG_NO_FORMATTING */ |