"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "source/test/intltest/measfmttest.cpp" between
icu4c-67rc-src.tgz and icu4c-67_1-src.tgz

About: ICU (International Components for Unicode) is a set of C/C++ and Java libraries providing Unicode and Globalization support for software applications on a wide variety of platforms.

measfmttest.cpp  (icu4c-67rc-src.tgz):measfmttest.cpp  (icu4c-67_1-src.tgz)
skipping to change at line 82 skipping to change at line 82
void TestFieldPositionMultiple(); void TestFieldPositionMultiple();
void TestBadArg(); void TestBadArg();
void TestEquality(); void TestEquality();
void TestGroupingSeparator(); void TestGroupingSeparator();
void TestDoubleZero(); void TestDoubleZero();
void TestUnitPerUnitResolution(); void TestUnitPerUnitResolution();
void TestIndividualPluralFallback(); void TestIndividualPluralFallback();
void Test20332_PersonUnits(); void Test20332_PersonUnits();
void TestNumericTime(); void TestNumericTime();
void TestNumericTimeSomeSpecialFormats(); void TestNumericTimeSomeSpecialFormats();
void TestIdentifiers();
void TestInvalidIdentifiers(); void TestInvalidIdentifiers();
void TestCompoundUnitOperations(); void TestCompoundUnitOperations();
void TestIdentifiers(); void TestDimensionlessBehaviour();
void Test21060_AddressSanitizerProblem();
void verifyFormat( void verifyFormat(
const char *description, const char *description,
const MeasureFormat &fmt, const MeasureFormat &fmt,
const Measure *measures, const Measure *measures,
int32_t measureCount, int32_t measureCount,
const char *expected); const char *expected);
void verifyFormatWithPrefix( void verifyFormatWithPrefix(
const char *description, const char *description,
const MeasureFormat &fmt, const MeasureFormat &fmt,
skipping to change at line 204 skipping to change at line 206
TESTCASE_AUTO(TestFieldPositionMultiple); TESTCASE_AUTO(TestFieldPositionMultiple);
TESTCASE_AUTO(TestBadArg); TESTCASE_AUTO(TestBadArg);
TESTCASE_AUTO(TestEquality); TESTCASE_AUTO(TestEquality);
TESTCASE_AUTO(TestGroupingSeparator); TESTCASE_AUTO(TestGroupingSeparator);
TESTCASE_AUTO(TestDoubleZero); TESTCASE_AUTO(TestDoubleZero);
TESTCASE_AUTO(TestUnitPerUnitResolution); TESTCASE_AUTO(TestUnitPerUnitResolution);
TESTCASE_AUTO(TestIndividualPluralFallback); TESTCASE_AUTO(TestIndividualPluralFallback);
TESTCASE_AUTO(Test20332_PersonUnits); TESTCASE_AUTO(Test20332_PersonUnits);
TESTCASE_AUTO(TestNumericTime); TESTCASE_AUTO(TestNumericTime);
TESTCASE_AUTO(TestNumericTimeSomeSpecialFormats); TESTCASE_AUTO(TestNumericTimeSomeSpecialFormats);
TESTCASE_AUTO(TestIdentifiers);
TESTCASE_AUTO(TestInvalidIdentifiers); TESTCASE_AUTO(TestInvalidIdentifiers);
TESTCASE_AUTO(TestCompoundUnitOperations); TESTCASE_AUTO(TestCompoundUnitOperations);
TESTCASE_AUTO(TestIdentifiers); TESTCASE_AUTO(TestDimensionlessBehaviour);
TESTCASE_AUTO(Test21060_AddressSanitizerProblem);
TESTCASE_AUTO_END; TESTCASE_AUTO_END;
} }
void MeasureFormatTest::TestCompatible53() { void MeasureFormatTest::TestCompatible53() {
UErrorCode status = U_ZERO_ERROR; UErrorCode status = U_ZERO_ERROR;
LocalPointer<MeasureUnit> measureUnit; LocalPointer<MeasureUnit> measureUnit;
measureUnit.adoptInstead(MeasureUnit::createGForce(status)); measureUnit.adoptInstead(MeasureUnit::createGForce(status));
measureUnit.adoptInstead(MeasureUnit::createArcMinute(status)); measureUnit.adoptInstead(MeasureUnit::createArcMinute(status));
measureUnit.adoptInstead(MeasureUnit::createArcSecond(status)); measureUnit.adoptInstead(MeasureUnit::createArcSecond(status));
measureUnit.adoptInstead(MeasureUnit::createDegree(status)); measureUnit.adoptInstead(MeasureUnit::createDegree(status));
skipping to change at line 3240 skipping to change at line 3244
// Latvian is one of the very few locales 0-padding the hour // Latvian is one of the very few locales 0-padding the hour
MeasureFormat fmtLt("lt", UMEASFMT_WIDTH_NUMERIC, status); MeasureFormat fmtLt("lt", UMEASFMT_WIDTH_NUMERIC, status);
if (status.errDataIfFailureAndReset(WHERE)) return; if (status.errDataIfFailureAndReset(WHERE)) return;
verifyFormat("Latvian fhoursFminutes", fmtLt, fhoursFminutes, 2, "02:03,877" ); verifyFormat("Latvian fhoursFminutes", fmtLt, fhoursFminutes, 2, "02:03,877" );
// Danish is one of the very few locales using '.' as separator // Danish is one of the very few locales using '.' as separator
MeasureFormat fmtDa("da", UMEASFMT_WIDTH_NUMERIC, status); MeasureFormat fmtDa("da", UMEASFMT_WIDTH_NUMERIC, status);
verifyFormat("Danish fhoursFminutes", fmtDa, fhoursFminutes, 2, "2.03,877"); verifyFormat("Danish fhoursFminutes", fmtDa, fhoursFminutes, 2, "2.03,877");
} }
void MeasureFormatTest::TestIdentifiers() {
IcuTestErrorCode status(*this, "TestIdentifiers");
struct TestCase {
const char* id;
const char* normalized;
} cases[] = {
// Correctly normalized identifiers should not change
{"", ""},
{"square-meter-per-square-meter", "square-meter-per-square-meter"},
{"kilogram-meter-per-square-meter-square-second",
"kilogram-meter-per-square-meter-square-second"},
{"square-mile-and-square-foot", "square-mile-and-square-foot"},
{"square-foot-and-square-mile", "square-foot-and-square-mile"},
{"per-cubic-centimeter", "per-cubic-centimeter"},
{"per-kilometer", "per-kilometer"},
// Normalization of power and per
{"p2-foot-and-p2-mile", "square-foot-and-square-mile"},
{"gram-square-gram-per-dekagram", "cubic-gram-per-dekagram"},
{"kilogram-per-meter-per-second", "kilogram-per-meter-second"},
// TODO(ICU-20920): Add more test cases once the proper ranking is avail
able.
};
for (const auto &cas : cases) {
status.setScope(cas.id);
MeasureUnit unit = MeasureUnit::forIdentifier(cas.id, status);
status.errIfFailureAndReset();
const char* actual = unit.getIdentifier();
assertEquals(cas.id, cas.normalized, actual);
status.errIfFailureAndReset();
}
}
void MeasureFormatTest::TestInvalidIdentifiers() { void MeasureFormatTest::TestInvalidIdentifiers() {
IcuTestErrorCode status(*this, "TestInvalidIdentifiers"); IcuTestErrorCode status(*this, "TestInvalidIdentifiers");
const char* const inputs[] = { const char *const inputs[] = {
"kilo", "kilo",
"kilokilo", "kilokilo",
"onekilo", "onekilo",
"meterkilo", "meterkilo",
"meter-kilo", "meter-kilo",
"k", "k",
"meter-", "meter-",
"meter+", "meter+",
"-meter", "-meter",
"+meter", "+meter",
"-kilometer", "-kilometer",
"+kilometer", "+kilometer",
"-p2-meter", "-p2-meter",
"+p2-meter", "+p2-meter",
"+", "+",
"-" "-",
"-mile",
"-and-mile",
"-per-mile",
"one",
"one-one",
"one-per-mile",
"one-per-cubic-centimeter",
"square--per-meter",
"metersecond", // Must have compound part in between single units
// Negative powers not supported in mixed units yet. TODO(CLDR-13701).
"per-hour-and-hertz",
"hertz-and-per-hour",
// Compound units not supported in mixed units yet. TODO(CLDR-13700).
"kilonewton-meter-and-newton-meter",
}; };
for (const auto& input : inputs) { for (const auto& input : inputs) {
status.setScope(input); status.setScope(input);
MeasureUnit::forIdentifier(input, status); MeasureUnit::forIdentifier(input, status);
status.expectErrorAndReset(U_ILLEGAL_ARGUMENT_ERROR); status.expectErrorAndReset(U_ILLEGAL_ARGUMENT_ERROR);
} }
} }
void MeasureFormatTest::TestCompoundUnitOperations() { void MeasureFormatTest::TestCompoundUnitOperations() {
skipping to change at line 3296 skipping to change at line 3349
assertTrue("centimeter equality", centimeter1 == centimeter2); assertTrue("centimeter equality", centimeter1 == centimeter2);
assertTrue("kilometer inequality", centimeter1 != kilometer); assertTrue("kilometer inequality", centimeter1 != kilometer);
MeasureUnit squareMeter = meter.withDimensionality(2, status); MeasureUnit squareMeter = meter.withDimensionality(2, status);
MeasureUnit overCubicCentimeter = centimeter1.withDimensionality(-3, status) ; MeasureUnit overCubicCentimeter = centimeter1.withDimensionality(-3, status) ;
MeasureUnit quarticKilometer = kilometer.withDimensionality(4, status); MeasureUnit quarticKilometer = kilometer.withDimensionality(4, status);
MeasureUnit overQuarticKilometer1 = kilometer.withDimensionality(-4, status) ; MeasureUnit overQuarticKilometer1 = kilometer.withDimensionality(-4, status) ;
verifySingleUnit(squareMeter, UMEASURE_SI_PREFIX_ONE, 2, "square-meter"); verifySingleUnit(squareMeter, UMEASURE_SI_PREFIX_ONE, 2, "square-meter");
verifySingleUnit(overCubicCentimeter, UMEASURE_SI_PREFIX_CENTI, -3, "one-per -cubic-centimeter"); verifySingleUnit(overCubicCentimeter, UMEASURE_SI_PREFIX_CENTI, -3, "per-cub ic-centimeter");
verifySingleUnit(quarticKilometer, UMEASURE_SI_PREFIX_KILO, 4, "p4-kilometer "); verifySingleUnit(quarticKilometer, UMEASURE_SI_PREFIX_KILO, 4, "p4-kilometer ");
verifySingleUnit(overQuarticKilometer1, UMEASURE_SI_PREFIX_KILO, -4, "one-pe r-p4-kilometer"); verifySingleUnit(overQuarticKilometer1, UMEASURE_SI_PREFIX_KILO, -4, "per-p4 -kilometer");
assertTrue("power inequality", quarticKilometer != overQuarticKilometer1); assertTrue("power inequality", quarticKilometer != overQuarticKilometer1);
MeasureUnit overQuarticKilometer2 = quarticKilometer.reciprocal(status); MeasureUnit overQuarticKilometer2 = quarticKilometer.reciprocal(status);
MeasureUnit overQuarticKilometer3 = kilometer.product(kilometer, status) MeasureUnit overQuarticKilometer3 = kilometer.product(kilometer, status)
.product(kilometer, status) .product(kilometer, status)
.product(kilometer, status) .product(kilometer, status)
.reciprocal(status); .reciprocal(status);
MeasureUnit overQuarticKilometer4 = meter.withDimensionality(4, status) MeasureUnit overQuarticKilometer4 = meter.withDimensionality(4, status)
.reciprocal(status) .reciprocal(status)
.withSIPrefix(UMEASURE_SI_PREFIX_KILO, status); .withSIPrefix(UMEASURE_SI_PREFIX_KILO, status);
verifySingleUnit(overQuarticKilometer2, UMEASURE_SI_PREFIX_KILO, -4, "one-pe verifySingleUnit(overQuarticKilometer2, UMEASURE_SI_PREFIX_KILO, -4, "per-p4
r-p4-kilometer"); -kilometer");
verifySingleUnit(overQuarticKilometer3, UMEASURE_SI_PREFIX_KILO, -4, "one-pe verifySingleUnit(overQuarticKilometer3, UMEASURE_SI_PREFIX_KILO, -4, "per-p4
r-p4-kilometer"); -kilometer");
verifySingleUnit(overQuarticKilometer4, UMEASURE_SI_PREFIX_KILO, -4, "one-pe verifySingleUnit(overQuarticKilometer4, UMEASURE_SI_PREFIX_KILO, -4, "per-p4
r-p4-kilometer"); -kilometer");
assertTrue("reciprocal equality", overQuarticKilometer1 == overQuarticKilome ter2); assertTrue("reciprocal equality", overQuarticKilometer1 == overQuarticKilome ter2);
assertTrue("reciprocal equality", overQuarticKilometer1 == overQuarticKilome ter3); assertTrue("reciprocal equality", overQuarticKilometer1 == overQuarticKilome ter3);
assertTrue("reciprocal equality", overQuarticKilometer1 == overQuarticKilome ter4); assertTrue("reciprocal equality", overQuarticKilometer1 == overQuarticKilome ter4);
MeasureUnit kiloSquareSecond = MeasureUnit::getSecond() MeasureUnit kiloSquareSecond = MeasureUnit::getSecond()
.withDimensionality(2, status).withSIPrefix(UMEASURE_SI_PREFIX_KILO, sta tus); .withDimensionality(2, status).withSIPrefix(UMEASURE_SI_PREFIX_KILO, sta tus);
MeasureUnit meterSecond = meter.product(kiloSquareSecond, status); MeasureUnit meterSecond = meter.product(kiloSquareSecond, status);
MeasureUnit cubicMeterSecond1 = meter.withDimensionality(3, status).product( kiloSquareSecond, status); MeasureUnit cubicMeterSecond1 = meter.withDimensionality(3, status).product( kiloSquareSecond, status);
MeasureUnit centimeterSecond1 = meter.withSIPrefix(UMEASURE_SI_PREFIX_CENTI, status).product(kiloSquareSecond, status); MeasureUnit centimeterSecond1 = meter.withSIPrefix(UMEASURE_SI_PREFIX_CENTI, status).product(kiloSquareSecond, status);
skipping to change at line 3344 skipping to change at line 3397
cubicMeterSecond1Sub, UPRV_LENGTHOF(cubicMeterSecond1Sub)); cubicMeterSecond1Sub, UPRV_LENGTHOF(cubicMeterSecond1Sub));
const char* centimeterSecond1Sub[] = {"centimeter", "square-kilosecond"}; const char* centimeterSecond1Sub[] = {"centimeter", "square-kilosecond"};
verifyCompoundUnit(centimeterSecond1, "centimeter-square-kilosecond", verifyCompoundUnit(centimeterSecond1, "centimeter-square-kilosecond",
centimeterSecond1Sub, UPRV_LENGTHOF(centimeterSecond1Sub)); centimeterSecond1Sub, UPRV_LENGTHOF(centimeterSecond1Sub));
const char* secondCubicMeterSub[] = {"cubic-meter", "square-kilosecond"}; const char* secondCubicMeterSub[] = {"cubic-meter", "square-kilosecond"};
verifyCompoundUnit(secondCubicMeter, "cubic-meter-square-kilosecond", verifyCompoundUnit(secondCubicMeter, "cubic-meter-square-kilosecond",
secondCubicMeterSub, UPRV_LENGTHOF(secondCubicMeterSub)); secondCubicMeterSub, UPRV_LENGTHOF(secondCubicMeterSub));
const char* secondCentimeterSub[] = {"centimeter", "square-kilosecond"}; const char* secondCentimeterSub[] = {"centimeter", "square-kilosecond"};
verifyCompoundUnit(secondCentimeter, "centimeter-square-kilosecond", verifyCompoundUnit(secondCentimeter, "centimeter-square-kilosecond",
secondCentimeterSub, UPRV_LENGTHOF(secondCentimeterSub)); secondCentimeterSub, UPRV_LENGTHOF(secondCentimeterSub));
const char* secondCentimeterPerKilometerSub[] = {"centimeter", "square-kilos econd", "one-per-kilometer"}; const char* secondCentimeterPerKilometerSub[] = {"centimeter", "square-kilos econd", "per-kilometer"};
verifyCompoundUnit(secondCentimeterPerKilometer, "centimeter-square-kiloseco nd-per-kilometer", verifyCompoundUnit(secondCentimeterPerKilometer, "centimeter-square-kiloseco nd-per-kilometer",
secondCentimeterPerKilometerSub, UPRV_LENGTHOF(secondCentimeterPerKilome terSub)); secondCentimeterPerKilometerSub, UPRV_LENGTHOF(secondCentimeterPerKilome terSub));
assertTrue("reordering equality", cubicMeterSecond1 == secondCubicMeter); assertTrue("reordering equality", cubicMeterSecond1 == secondCubicMeter);
assertTrue("additional simple units inequality", secondCubicMeter != secondC entimeter); assertTrue("additional simple units inequality", secondCubicMeter != secondC entimeter);
// Don't allow get/set power or SI prefix on compound units // Don't allow get/set power or SI prefix on compound units
status.errIfFailureAndReset(); status.errIfFailureAndReset();
meterSecond.getDimensionality(status); meterSecond.getDimensionality(status);
status.expectErrorAndReset(U_ILLEGAL_ARGUMENT_ERROR); status.expectErrorAndReset(U_ILLEGAL_ARGUMENT_ERROR);
skipping to change at line 3379 skipping to change at line 3432
const char* footInchSub[] = {"foot", "inch"}; const char* footInchSub[] = {"foot", "inch"};
verifyMixedUnit(footInch, "foot-and-inch", verifyMixedUnit(footInch, "foot-and-inch",
footInchSub, UPRV_LENGTHOF(footInchSub)); footInchSub, UPRV_LENGTHOF(footInchSub));
const char* inchFootSub[] = {"inch", "foot"}; const char* inchFootSub[] = {"inch", "foot"};
verifyMixedUnit(inchFoot, "inch-and-foot", verifyMixedUnit(inchFoot, "inch-and-foot",
inchFootSub, UPRV_LENGTHOF(inchFootSub)); inchFootSub, UPRV_LENGTHOF(inchFootSub));
assertTrue("order matters inequality", footInch != inchFoot); assertTrue("order matters inequality", footInch != inchFoot);
MeasureUnit one1; MeasureUnit dimensionless;
MeasureUnit one2 = MeasureUnit::forIdentifier("one", status); MeasureUnit dimensionless2 = MeasureUnit::forIdentifier("", status);
MeasureUnit one3 = MeasureUnit::forIdentifier("", status); status.errIfFailureAndReset("Dimensionless MeasureUnit.");
MeasureUnit squareOne = one2.withDimensionality(2, status); assertTrue("dimensionless equality", dimensionless == dimensionless2);
MeasureUnit onePerOne = one2.reciprocal(status);
MeasureUnit squareKiloOne = squareOne.withSIPrefix(UMEASURE_SI_PREFIX_KILO, // We support starting from an "identity" MeasureUnit and then combining it
status); // with others via product:
MeasureUnit onePerSquareKiloOne = squareKiloOne.reciprocal(status); MeasureUnit kilometer2 = dimensionless.product(kilometer, status);
MeasureUnit oneOne = MeasureUnit::forIdentifier("one-one", status); status.errIfFailureAndReset("dimensionless.product(kilometer, status)");
MeasureUnit onePlusOne = MeasureUnit::forIdentifier("one-and-one", status);
MeasureUnit kilometer2 = one2.product(kilometer, status);
verifySingleUnit(one1, UMEASURE_SI_PREFIX_ONE, 1, "one");
verifySingleUnit(one2, UMEASURE_SI_PREFIX_ONE, 1, "one");
verifySingleUnit(one3, UMEASURE_SI_PREFIX_ONE, 1, "one");
verifySingleUnit(squareOne, UMEASURE_SI_PREFIX_ONE, 1, "one");
verifySingleUnit(onePerOne, UMEASURE_SI_PREFIX_ONE, 1, "one");
verifySingleUnit(squareKiloOne, UMEASURE_SI_PREFIX_ONE, 1, "one");
verifySingleUnit(onePerSquareKiloOne, UMEASURE_SI_PREFIX_ONE, 1, "one");
verifySingleUnit(oneOne, UMEASURE_SI_PREFIX_ONE, 1, "one");
verifySingleUnit(onePlusOne, UMEASURE_SI_PREFIX_ONE, 1, "one");
verifySingleUnit(kilometer2, UMEASURE_SI_PREFIX_KILO, 1, "kilometer"); verifySingleUnit(kilometer2, UMEASURE_SI_PREFIX_KILO, 1, "kilometer");
assertTrue("one equality", one1 == one2);
assertTrue("one equality", one2 == one3);
assertTrue("one-per-one equality", onePerOne == onePerSquareKiloOne);
assertTrue("kilometer equality", kilometer == kilometer2); assertTrue("kilometer equality", kilometer == kilometer2);
// Test out-of-range powers // Test out-of-range powers
MeasureUnit power15 = MeasureUnit::forIdentifier("p15-kilometer", status); MeasureUnit power15 = MeasureUnit::forIdentifier("p15-kilometer", status);
verifySingleUnit(power15, UMEASURE_SI_PREFIX_KILO, 15, "p15-kilometer"); verifySingleUnit(power15, UMEASURE_SI_PREFIX_KILO, 15, "p15-kilometer");
status.errIfFailureAndReset(); status.errIfFailureAndReset();
MeasureUnit power16a = MeasureUnit::forIdentifier("p16-kilometer", status); MeasureUnit power16a = MeasureUnit::forIdentifier("p16-kilometer", status);
status.expectErrorAndReset(U_ILLEGAL_ARGUMENT_ERROR); status.expectErrorAndReset(U_ILLEGAL_ARGUMENT_ERROR);
MeasureUnit power16b = power15.product(kilometer, status); MeasureUnit power16b = power15.product(kilometer, status);
status.expectErrorAndReset(U_ILLEGAL_ARGUMENT_ERROR); status.expectErrorAndReset(U_ILLEGAL_ARGUMENT_ERROR);
MeasureUnit powerN15 = MeasureUnit::forIdentifier("one-per-p15-kilometer", s MeasureUnit powerN15 = MeasureUnit::forIdentifier("per-p15-kilometer", statu
tatus); s);
verifySingleUnit(powerN15, UMEASURE_SI_PREFIX_KILO, -15, "one-per-p15-kilome verifySingleUnit(powerN15, UMEASURE_SI_PREFIX_KILO, -15, "per-p15-kilometer"
ter"); );
status.errIfFailureAndReset(); status.errIfFailureAndReset();
MeasureUnit powerN16a = MeasureUnit::forIdentifier("one-per-p16-kilometer", status); MeasureUnit powerN16a = MeasureUnit::forIdentifier("per-p16-kilometer", stat us);
status.expectErrorAndReset(U_ILLEGAL_ARGUMENT_ERROR); status.expectErrorAndReset(U_ILLEGAL_ARGUMENT_ERROR);
MeasureUnit powerN16b = powerN15.product(overQuarticKilometer1, status); MeasureUnit powerN16b = powerN15.product(overQuarticKilometer1, status);
status.expectErrorAndReset(U_ILLEGAL_ARGUMENT_ERROR); status.expectErrorAndReset(U_ILLEGAL_ARGUMENT_ERROR);
} }
void MeasureFormatTest::TestIdentifiers() { void MeasureFormatTest::TestDimensionlessBehaviour() {
IcuTestErrorCode status(*this, "TestIdentifiers"); IcuTestErrorCode status(*this, "TestDimensionlessBehaviour");
struct TestCase { MeasureUnit dimensionless;
bool valid; MeasureUnit modified;
const char* id;
const char* normalized; // At the time of writing, each of the seven groups below caused
} cases[] = { // Parser::from("") to be called:
{ true, "square-meter-per-square-meter", "square-meter-per-square-meter"
}, // splitToSingleUnits
// TODO(ICU-20920): Add more test cases once the proper ranking is avail int32_t count;
able. LocalArray<MeasureUnit> singles = dimensionless.splitToSingleUnits(count, st
}; atus);
for (const auto& cas : cases) { status.errIfFailureAndReset("dimensionless.splitToSingleUnits(...)");
status.setScope(cas.id); assertEquals("no singles in dimensionless", 0, count);
MeasureUnit unit = MeasureUnit::forIdentifier(cas.id, status);
if (!cas.valid) { // product(dimensionless)
status.expectErrorAndReset(U_ILLEGAL_ARGUMENT_ERROR); MeasureUnit mile = MeasureUnit::getMile();
continue; mile = mile.product(dimensionless, status);
} status.errIfFailureAndReset("mile.product(dimensionless, ...)");
const char* actual = unit.getIdentifier(); verifySingleUnit(mile, UMEASURE_SI_PREFIX_ONE, 1, "mile");
assertEquals(cas.id, cas.normalized, actual);
status.errIfFailureAndReset(); // dimensionless.getSIPrefix()
} UMeasureSIPrefix siPrefix = dimensionless.getSIPrefix(status);
status.errIfFailureAndReset("dimensionless.getSIPrefix(...)");
assertEquals("dimensionless SIPrefix", UMEASURE_SI_PREFIX_ONE, siPrefix);
// dimensionless.withSIPrefix()
modified = dimensionless.withSIPrefix(UMEASURE_SI_PREFIX_KILO, status);
status.errIfFailureAndReset("dimensionless.withSIPrefix(...)");
singles = modified.splitToSingleUnits(count, status);
assertEquals("no singles in modified", 0, count);
siPrefix = modified.getSIPrefix(status);
status.errIfFailureAndReset("modified.getSIPrefix(...)");
assertEquals("modified SIPrefix", UMEASURE_SI_PREFIX_ONE, siPrefix);
// dimensionless.getComplexity()
UMeasureUnitComplexity complexity = dimensionless.getComplexity(status);
status.errIfFailureAndReset("dimensionless.getComplexity(...)");
assertEquals("dimensionless complexity", UMEASURE_UNIT_SINGLE, complexity);
// Dimensionality is mostly meaningless for dimensionless units, but it's
// still considered a SINGLE unit, so this code doesn't throw errors:
// dimensionless.getDimensionality()
int32_t dimensionality = dimensionless.getDimensionality(status);
status.errIfFailureAndReset("dimensionless.getDimensionality(...)");
assertEquals("dimensionless dimensionality", 0, dimensionality);
// dimensionless.withDimensionality()
dimensionless.withDimensionality(-1, status);
status.errIfFailureAndReset("dimensionless.withDimensionality(...)");
dimensionality = dimensionless.getDimensionality(status);
status.errIfFailureAndReset("dimensionless.getDimensionality(...)");
assertEquals("dimensionless dimensionality", 0, dimensionality);
}
// ICU-21060
void MeasureFormatTest::Test21060_AddressSanitizerProblem() {
IcuTestErrorCode status(*this, "Test21060_AddressSanitizerProblem");
MeasureUnit first = MeasureUnit::forIdentifier("", status);
status.errIfFailureAndReset();
// Experimentally, a compound unit like "kilogram-meter" failed. A single
// unit like "kilogram" or "meter" did not fail, did not trigger the
// problem.
MeasureUnit crux = MeasureUnit::forIdentifier("per-meter", status);
// Heap allocation of a new CharString for first.identifier happens here:
first = first.product(crux, status);
// Constructing second from first's identifier resulted in a failure later,
// as second held a reference to a substring of first's identifier:
MeasureUnit second = MeasureUnit::forIdentifier(first.getIdentifier(), statu
s);
// Heap is freed here, as an old first.identifier CharString is deallocated
// and a new CharString is allocated:
first = first.product(crux, status);
// Proving we've had no failure yet:
status.errIfFailureAndReset();
// heap-use-after-free failure happened here, since a SingleUnitImpl had
// held onto a StringPiece pointing at a substring of an identifier that was
// freed above:
second = second.product(crux, status);
status.errIfFailureAndReset();
} }
void MeasureFormatTest::verifyFieldPosition( void MeasureFormatTest::verifyFieldPosition(
const char *description, const char *description,
const MeasureFormat &fmt, const MeasureFormat &fmt,
const UnicodeString &prefix, const UnicodeString &prefix,
const Measure *measures, const Measure *measures,
int32_t measureCount, int32_t measureCount,
NumberFormat::EAlignmentFields field, NumberFormat::EAlignmentFields field,
int32_t start, int32_t start,
 End of changes. 16 change blocks. 
66 lines changed or deleted 170 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)