TESTCASE_AUTO(testGetAllKeywordValues);
TESTCASE_AUTO(testScientificPluralKeyword);
TESTCASE_AUTO(testCompactDecimalPluralKeyword);
+ TESTCASE_AUTO(testDoubleValue);
+ TESTCASE_AUTO(testLongValue);
TESTCASE_AUTO(testOrdinal);
TESTCASE_AUTO(testSelect);
TESTCASE_AUTO(testSelectRange);
}
}
+void
+PluralRulesTest::testDoubleValue() {
+ IcuTestErrorCode errorCode(*this, "testDoubleValue");
+
+ struct IntTestCase {
+ const int64_t inputNum;
+ const double expVal;
+ } intCases[] = {
+ {-101, -101.0},
+ {-100, -100.0},
+ {-1, -1.0},
+ {0, 0.0},
+ {1, 1.0},
+ {100, 100.0}
+ };
+ for (const auto& cas : intCases) {
+ const int64_t inputNum = cas.inputNum;
+ const double expVal = cas.expVal;
+
+ FixedDecimal fd(inputNum);
+ UnicodeString message(u"FixedDecimal::doubleValue() for" + Int64ToUnicodeString(inputNum));
+ assertEquals(message, expVal, fd.doubleValue());
+ }
+
+ struct DoubleTestCase {
+ const double inputNum;
+ const double expVal;
+ } dblCases[] = {
+ {-0.0, -0.0},
+ {0.1, 0.1},
+ {1.999, 1.999},
+ {2.0, 2.0},
+ {100.001, 100.001}
+ };
+ for (const auto & cas : dblCases) {
+ const double inputNum = cas.inputNum;
+ const double expVal = cas.expVal;
+
+ FixedDecimal fd(inputNum);
+ UnicodeString message(u"FixedDecimal::doubleValue() for" + DoubleToUnicodeString(inputNum));
+ assertEquals(message, expVal, fd.doubleValue());
+ }
+}
+
+void
+PluralRulesTest::testLongValue() {
+ IcuTestErrorCode errorCode(*this, "testLongValue");
+
+ struct IntTestCase {
+ const int64_t inputNum;
+ const int64_t expVal;
+ } intCases[] = {
+ {-101, 101},
+ {-100, 100},
+ {-1, 1},
+ {0, 0},
+ {1, 1},
+ {100, 100}
+ };
+ for (const auto& cas : intCases) {
+ const int64_t inputNum = cas.inputNum;
+ const int64_t expVal = cas.expVal;
+
+ FixedDecimal fd(inputNum);
+ UnicodeString message(u"FixedDecimal::longValue() for" + Int64ToUnicodeString(inputNum));
+ assertEquals(message, expVal, fd.longValue());
+ }
+
+ struct DoubleTestCase {
+ const double inputNum;
+ const int64_t expVal;
+ } dblCases[] = {
+ {-0.0, 0},
+ {0.1, 0},
+ {1.999, 1},
+ {2.0, 2},
+ {100.001, 100}
+ };
+ for (const auto & cas : dblCases) {
+ const double inputNum = cas.inputNum;
+ const int64_t expVal = cas.expVal;
+
+ FixedDecimal fd(inputNum);
+ UnicodeString message(u"FixedDecimal::longValue() for" + DoubleToUnicodeString(inputNum));
+ assertEquals(message, expVal, fd.longValue());
+ }
+}
+
UnicodeString PluralRulesTest::getPluralKeyword(const LocalPointer<PluralRules> &rules, Locale locale, double number, const char16_t* skeleton) {
IcuTestErrorCode errorCode(*this, "getPluralKeyword");
UnlocalizedNumberFormatter ulnf = NumberFormatter::forSkeleton(skeleton, errorCode);
source = isNegative ? -n : n;
visibleDecimalDigitCount = v;
decimalDigits = f;
- integerValue = n > MAX
- ? MAX
- : (long)n;
+ integerValue = n > MAX ? MAX : (long) source;
int initExpVal = e;
if (initExpVal == 0) {
initExpVal = c;
@Deprecated
public double getPluralOperand(Operand operand) {
switch(operand) {
- case n: return source;
- case i: return integerValue;
+ case n: return (exponent == 0 ? source : source * Math.pow(10, exponent));
+ case i: return intValue();
case f: return decimalDigits;
case t: return decimalDigitsWithoutTrailingZeros;
case v: return visibleDecimalDigitCount;
case w: return visibleDecimalDigitCountWithoutTrailingZeros;
case e: return exponent;
case c: return exponent;
- default: return source;
+ default: return doubleValue();
}
}
@Deprecated
public long getShiftedValue() {
if (exponent != 0 && visibleDecimalDigitCount == 0 && decimalDigits == 0) {
- // Need to taxe exponent into account if we have it
+ // Need to take exponent into account if we have it
return (long)(source * Math.pow(10, exponent));
}
return integerValue * baseFactor + decimalDigits;
}
public void checkValue(String title1, PluralRules rules, String expected, String value) {
- double number = Double.parseDouble(value);
- int decimalPos = value.indexOf('.') + 1;
- int countVisibleFractionDigits;
- int fractionaldigits;
- if (decimalPos == 0) {
- countVisibleFractionDigits = fractionaldigits = 0;
- } else {
- countVisibleFractionDigits = value.length() - decimalPos;
- fractionaldigits = Integer.parseInt(value.substring(decimalPos));
- }
- String result = rules.select(number, countVisibleFractionDigits, fractionaldigits);
+ FixedDecimal fdNum = new FixedDecimal(value);
+
+ String result = rules.select(fdNum);
ULocale locale = null;
assertEquals(getAssertMessage(title1, locale, rules, expected) + "; value: " + value, expected, result);
}
+ /**
+ * Check the testing helper method checkValue(), which parses a plural
+ * rule's sample string as a {@link FormattedNumber} in order to call
+ * {@code PluralRules.select(FormattedNumber)}, which in turn can support
+ * the exponent in plural sample numbers like 1e6 and 2.8c3.
+ */
+ @Test
+ public void testCheckValue() {
+ String ruleString =
+ "many: e = 0 and i != 0 and i % 1000000 = 0 and v = 0 or e != 0..5"
+ + " @integer 1000000, 1e6, 2e6, 3e6, 4e6, 5e6, 6e6, …"
+ + " @decimal 1.0000001e6, 1.1e6, 2.0000001e6, 2.1e6, 3.0000001e6, 3.1e6, …; "
+ + "one: i = 1 and v = 0"
+ + " @integer 1; "
+ + "other: "
+ + " @integer 0, 2~16, 100, 1000, 10000, 100000, 1e3, 2e3, 3e3, 4e3, 5e3, 6e3, …"
+ + " @decimal 0.0~1.5, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 1.0001e3, 1.1e3, 2.0001e3, 2.1e3, 3.0001e3, 3.1e3, …";
+ PluralRules rules = PluralRules.createRules(ruleString);
+
+ Object[][] casesData = {
+ // expected category, value string
+ {"many", "1000000"},
+ {"many", "1e6"},
+ {"many", "1.1e6"},
+ {"one", "1"},
+ {"other", "0"},
+ {"other", "1e5"},
+ {"other", "100000"},
+ {"other", "0.0"},
+ {"other", "100000.0"},
+ {"other", "1000000.0"}
+ };
+
+ for (Object[] caseDatum : casesData) {
+ String expCategory = (String) caseDatum[0];
+ String inputValueStr = (String) caseDatum[1];
+
+ String msg = "checkValue(" + inputValueStr + ")";
+
+ checkValue(msg, rules, expCategory, inputValueStr);
+ }
+ }
+
private static String[][] equalityTestData = {
// once we add fractions, we had to retract the "test all possibilities" for equality,
// so we only have a limited set of equality tests now.
return pluralKeyword;
}
+ @Test
+ public void testDoubleValue() {
+ Object[][] intCasesData = {
+ // source number, expected double value
+ {-101, -101.0},
+ {-100, -100.0},
+ {-1, -1.0},
+ {0, 0.0},
+ {1, 1.0},
+ {100, 100.0}
+ };
+
+ for (Object[] caseDatum : intCasesData) {
+ double inputNum = (int) caseDatum[0];
+ double expVal = (double) caseDatum[1];
+ FixedDecimal fd = new FixedDecimal(inputNum);
+ assertEquals("FixedDecimal.doubleValue() for " + inputNum, expVal, fd.doubleValue());
+ }
+
+ Object[][] doubleCasesData = {
+ // source number, expected double value
+ {-0.0, -0.0},
+ {0.1, 0.1},
+ {1.999, 1.999},
+ {2.0, 2.0},
+ {100.001, 100.001}
+ };
+
+ for (Object[] caseDatum : doubleCasesData) {
+ double inputNum = (double) caseDatum[0];
+ double expVal = (double) caseDatum[1];
+ FixedDecimal fd = new FixedDecimal(inputNum);
+ assertEquals("FixedDecimal.doubleValue() for " + inputNum, expVal, fd.doubleValue());
+ }
+ }
+
+ @Test
+ public void testLongValue() {
+ Object[][] intCasesData = {
+ // source number, expected double value
+ {-101, 101},
+ {-100, 100},
+ {-1, 1},
+ {0, 0},
+ {1, 1},
+ {100, 100}
+ };
+
+ for (Object[] caseDatum : intCasesData) {
+ long inputNum = (int) caseDatum[0];
+ long expVal = (int) caseDatum[1];
+ FixedDecimal fd = new FixedDecimal(inputNum);
+ assertEquals("FixedDecimal.longValue() for " + inputNum, expVal, fd.longValue());
+ }
+
+ Object[][] doubleCasesData = {
+ // source number, expected double value
+ {-0.0, 0},
+ {0.1, 0},
+ {1.999, 1},
+ {2.0, 2},
+ {100.001, 100}
+ };
+
+ for (Object[] caseDatum : doubleCasesData) {
+ double inputNum = (double) caseDatum[0];
+ long expVal = (int) caseDatum[1];
+ FixedDecimal fd = new FixedDecimal(inputNum);
+ assertEquals("FixedDecimal.longValue() for " + inputNum, expVal, fd.longValue());
+ }
+ }
+
enum StandardPluralCategories {
zero, one, two, few, many, other;
/**