163 lines
6.9 KiB
C++
163 lines
6.9 KiB
C++
// © 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) override;
|
|
|
|
void testGetUnitCategory();
|
|
// This is a sanity check that only exists in ICU4C.
|
|
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"},
|
|
{"second-per-meter", "speed"},
|
|
// TODO: add this test cases once the `getUnitCategory` accepts any `MeasureUnit` and not only
|
|
// base units.
|
|
// Tests are:
|
|
// {"liter-per-100-kilometer", "consumption"},
|
|
// {"mile-per-gallon", "consumption"},
|
|
{"cubic-meter-per-meter", "consumption"},
|
|
{"meter-per-cubic-meter", "consumption"},
|
|
{"kilogram-meter-per-square-meter-square-second", "pressure"},
|
|
};
|
|
|
|
IcuTestErrorCode status(*this, "testGetUnitCategory");
|
|
for (const auto &t : testCases) {
|
|
CharString category = getUnitQuantity(MeasureUnitImpl::forIdentifier(t.unit, status), 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 */
|