Adds some plumbing to allow MutablePatternModifier to set fields, and otherwise builds upon the infrastructure from the previous commit to add the MEASURE_UNIT field.
int32_t
AffixUtils::unescape(const UnicodeString &affixPattern, NumberStringBuilder &output, int32_t position,
- const SymbolProvider &provider, UErrorCode &status) {
+ const SymbolProvider &provider, Field field, UErrorCode &status) {
int32_t length = 0;
AffixTag tag;
while (hasNext(tag, affixPattern)) {
length += output.insert(
position + length, provider.getSymbol(tag.type), getFieldForType(tag.type), status);
} else {
- length += output.insertCodePoint(position + length, tag.codePoint, UNUM_FIELD_COUNT, status);
+ length += output.insertCodePoint(position + length, tag.codePoint, field, status);
}
}
return length;
* @param provider An object to generate locale symbols.
*/
static int32_t unescape(const UnicodeString& affixPattern, NumberStringBuilder& output,
- int32_t position, const SymbolProvider& provider, UErrorCode& status);
+ int32_t position, const SymbolProvider& provider, Field field,
+ UErrorCode& status);
/**
* Sames as {@link #unescape}, but only calculates the code point count. More efficient than {@link #unescape}
ParsedPatternInfo patternInfo;
PatternParser::parseToPatternInfo(UnicodeString(patternString), patternInfo, status);
if (U_FAILURE(status)) { return; }
- buildReference.setPatternInfo(&patternInfo);
+ buildReference.setPatternInfo(&patternInfo, UNUM_COMPACT_FIELD);
info.mod = buildReference.createImmutable(status);
if (U_FAILURE(status)) { return; }
info.patternString = patternString;
ParsedPatternInfo &patternInfo = const_cast<CompactHandler *>(this)->unsafePatternInfo;
PatternParser::parseToPatternInfo(UnicodeString(patternString), patternInfo, status);
static_cast<MutablePatternModifier*>(const_cast<Modifier*>(micros.modMiddle))
- ->setPatternInfo(&patternInfo);
+ ->setPatternInfo(&patternInfo, UNUM_COMPACT_FIELD);
}
// We already performed rounding. Do not perform it again.
fPatternModifier.adoptInstead(patternModifier);
patternModifier->setPatternInfo(
macros.affixProvider != nullptr ? macros.affixProvider
- : static_cast<const AffixPatternProvider*>(fPatternInfo.getAlias()));
+ : static_cast<const AffixPatternProvider*>(fPatternInfo.getAlias()),
+ UNUM_FIELD_COUNT);
patternModifier->setPatternAttributes(fMicros.sign, isPermille);
if (patternModifier->needsPlurals()) {
patternModifier->setSymbols(
MutablePatternModifier::MutablePatternModifier(bool isStrong)
: fStrong(isStrong) {}
-void MutablePatternModifier::setPatternInfo(const AffixPatternProvider* patternInfo) {
+void MutablePatternModifier::setPatternInfo(const AffixPatternProvider* patternInfo, Field field) {
fPatternInfo = patternInfo;
+ fField = field;
}
void MutablePatternModifier::setPatternAttributes(UNumberSignDisplay signDisplay, bool perMille) {
fSignDisplay = signDisplay;
- this->perMilleReplacesPercent = perMille;
+ fPerMilleReplacesPercent = perMille;
}
void MutablePatternModifier::setSymbols(const DecimalFormatSymbols* symbols,
int32_t MutablePatternModifier::insertPrefix(NumberStringBuilder& sb, int position, UErrorCode& status) {
prepareAffix(true);
- int length = AffixUtils::unescape(currentAffix, sb, position, *this, status);
+ int32_t length = AffixUtils::unescape(currentAffix, sb, position, *this, fField, status);
return length;
}
int32_t MutablePatternModifier::insertSuffix(NumberStringBuilder& sb, int position, UErrorCode& status) {
prepareAffix(false);
- int length = AffixUtils::unescape(currentAffix, sb, position, *this, status);
+ int32_t length = AffixUtils::unescape(currentAffix, sb, position, *this, fField, status);
return length;
}
/** This method contains the heart of the logic for rendering LDML affix strings. */
void MutablePatternModifier::prepareAffix(bool isPrefix) {
PatternStringUtils::patternInfoToStringBuilder(
- *fPatternInfo, isPrefix, fSignum, fSignDisplay, fPlural, perMilleReplacesPercent, currentAffix);
+ *fPatternInfo, isPrefix, fSignum, fSignDisplay, fPlural, fPerMilleReplacesPercent, currentAffix);
}
UnicodeString MutablePatternModifier::getSymbol(AffixPatternType type) const {
* Sets a reference to the parsed decimal format pattern, usually obtained from
* {@link PatternStringParser#parseToPatternInfo(String)}, but any implementation of {@link AffixPatternProvider} is
* accepted.
+ *
+ * @param field
+ * Which field to use for literal characters in the pattern.
*/
- void setPatternInfo(const AffixPatternProvider *patternInfo);
+ void setPatternInfo(const AffixPatternProvider *patternInfo, Field field);
/**
* Sets attributes that imply changes to the literal interpretation of the pattern string affixes.
// Pattern details (initialized in setPatternInfo and setPatternAttributes)
const AffixPatternProvider *fPatternInfo;
+ Field fField;
UNumberSignDisplay fSignDisplay;
- bool perMilleReplacesPercent;
+ bool fPerMilleReplacesPercent;
// Symbol details (initialized in setSymbols)
const DecimalFormatSymbols *fSymbols;
kSignField = UNUM_SIGN_FIELD,
/** @draft ICU 64 */
kMeasureUnitField = UNUM_MEASURE_UNIT_FIELD,
+ /** @draft ICU 64 */
+ kCompactField = UNUM_COMPACT_FIELD,
/**
* These constants are provided for backwards compatibility only.
UNUM_SIGN_FIELD,
/** @draft ICU 64 */
UNUM_MEASURE_UNIT_FIELD,
+ /** @draft ICU 64 */
+ UNUM_COMPACT_FIELD,
+
#ifndef U_HIDE_DEPRECATED_API
/**
* One more than the highest normal UNumberFormatFields value.
UnicodeString input(cas[0]);
UnicodeString expected(cas[1]);
sb.clear();
- AffixUtils::unescape(input, sb, 0, provider, status);
+ AffixUtils::unescape(input, sb, 0, provider, UNUM_FIELD_COUNT, status);
assertSuccess("Spot 1", status);
assertEquals(input, expected, sb.toUnicodeString());
assertEquals(input, expected, sb.toTempUnicodeString());
sb.clear();
sb.append(u"abcdefg", UNUM_FIELD_COUNT, status);
assertSuccess("Spot 2", status);
- AffixUtils::unescape(u"-+%", sb, 4, provider, status);
+ AffixUtils::unescape(u"-+%", sb, 4, provider, UNUM_FIELD_COUNT, status);
assertSuccess("Spot 3", status);
assertEquals(u"Symbol provider into middle", u"abcd123efg", sb.toUnicodeString());
}
UnicodeString AffixUtilsTest::unescapeWithDefaults(const SymbolProvider &defaultProvider,
UnicodeString input, UErrorCode &status) {
NumberStringBuilder nsb;
- int32_t length = AffixUtils::unescape(input, nsb, 0, defaultProvider, status);
+ int32_t length = AffixUtils::unescape(input, nsb, 0, defaultProvider, UNUM_FIELD_COUNT, status);
assertEquals("Return value of unescape", nsb.length(), length);
return nsb.toUnicodeString();
}
expectedFieldPositions,
sizeof(expectedFieldPositions)/sizeof(*expectedFieldPositions));
}
+
+ {
+ const char16_t* message = u"Compact field basic";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ u"compact-short",
+ NumberFormatter::with().notation(Notation::compactShort()),
+ Locale::getUS(),
+ 65000,
+ u"65K");
+ static const UFieldPosition expectedFieldPositions[] = {
+ // field, begin index, end index
+ {UNUM_INTEGER_FIELD, 0, 2},
+ {UNUM_COMPACT_FIELD, 2, 3}};
+ assertFieldPositions(
+ message,
+ result,
+ expectedFieldPositions,
+ sizeof(expectedFieldPositions)/sizeof(*expectedFieldPositions));
+ }
+
+ {
+ const char16_t* message = u"Compact field with spaces";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ u"compact-long",
+ NumberFormatter::with().notation(Notation::compactLong()),
+ Locale::getUS(),
+ 65000,
+ u"65 thousand");
+ static const UFieldPosition expectedFieldPositions[] = {
+ // field, begin index, end index
+ {UNUM_INTEGER_FIELD, 0, 2},
+ {UNUM_COMPACT_FIELD, 3, 11}};
+ assertFieldPositions(
+ message,
+ result,
+ expectedFieldPositions,
+ sizeof(expectedFieldPositions)/sizeof(*expectedFieldPositions));
+ }
+
+ {
+ const char16_t* message = u"Compact field with inner space";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ u"compact-long",
+ NumberFormatter::with().notation(Notation::compactLong()),
+ "fil", // locale with interesting data
+ 6000,
+ u"6 na libo");
+ static const UFieldPosition expectedFieldPositions[] = {
+ // field, begin index, end index
+ {UNUM_INTEGER_FIELD, 0, 1},
+ {UNUM_COMPACT_FIELD, 2, 9}};
+ assertFieldPositions(
+ message,
+ result,
+ expectedFieldPositions,
+ sizeof(expectedFieldPositions)/sizeof(*expectedFieldPositions));
+ }
+
+ {
+ const char16_t* message = u"Compact field with bidi mark";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ u"compact-long",
+ NumberFormatter::with().notation(Notation::compactLong()),
+ "he", // locale with interesting data
+ 6000,
+ u"\u200F6 אלף");
+ static const UFieldPosition expectedFieldPositions[] = {
+ // field, begin index, end index
+ {UNUM_INTEGER_FIELD, 1, 2},
+ {UNUM_COMPACT_FIELD, 3, 6}};
+ assertFieldPositions(
+ message,
+ result,
+ expectedFieldPositions,
+ sizeof(expectedFieldPositions)/sizeof(*expectedFieldPositions));
+ }
+
+ {
+ const char16_t* message = u"Compact with currency fields";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ u"compact-short currency/USD",
+ NumberFormatter::with().notation(Notation::compactShort()).unit(USD),
+ "sr_Latn", // locale with interesting data
+ 65000,
+ u"65 hilj. US$");
+ static const UFieldPosition expectedFieldPositions[] = {
+ // field, begin index, end index
+ {UNUM_INTEGER_FIELD, 0, 2},
+ {UNUM_COMPACT_FIELD, 3, 8},
+ {UNUM_CURRENCY_FIELD, 9, 12}};
+ assertFieldPositions(
+ message,
+ result,
+ expectedFieldPositions,
+ sizeof(expectedFieldPositions)/sizeof(*expectedFieldPositions));
+ }
+
+ {
+ const char16_t* message = u"Compact with measure unit fields";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ u"compact-long measure-unit/length-meter unit-width-full-name",
+ NumberFormatter::with().notation(Notation::compactLong())
+ .unit(METER)
+ .unitWidth(UNUM_UNIT_WIDTH_FULL_NAME),
+ Locale::getUS(),
+ 65000,
+ u"65 thousand meters");
+ static const UFieldPosition expectedFieldPositions[] = {
+ // field, begin index, end index
+ {UNUM_INTEGER_FIELD, 0, 2},
+ {UNUM_COMPACT_FIELD, 3, 11},
+ {UNUM_MEASURE_UNIT_FIELD, 12, 18}};
+ assertFieldPositions(
+ message,
+ result,
+ expectedFieldPositions,
+ sizeof(expectedFieldPositions)/sizeof(*expectedFieldPositions));
+ }
}
void NumberFormatterApiTest::toFormat() {
ParsedPatternInfo patternInfo;
PatternParser::parseToPatternInfo(u"a0b", patternInfo, status);
assertSuccess("Spot 1", status);
- mod.setPatternInfo(&patternInfo);
+ mod.setPatternInfo(&patternInfo, UNUM_FIELD_COUNT);
mod.setPatternAttributes(UNUM_SIGN_AUTO, false);
DecimalFormatSymbols symbols(Locale::getEnglish(), status);
CurrencySymbols currencySymbols({u"USD", status}, "en", status);
ParsedPatternInfo patternInfo2;
PatternParser::parseToPatternInfo(u"a0b;c-0d", patternInfo2, status);
assertSuccess("Spot 4", status);
- mod.setPatternInfo(&patternInfo2);
+ mod.setPatternInfo(&patternInfo2, UNUM_FIELD_COUNT);
mod.setPatternAttributes(UNUM_SIGN_AUTO, false);
mod.setNumberProperties(1, StandardPlural::Form::COUNT);
assertEquals("Pattern a0b;c-0d", u"a", getPrefix(mod, status));
ParsedPatternInfo patternInfo;
PatternParser::parseToPatternInfo(u"abc", patternInfo, status);
assertSuccess("Spot 1", status);
- mod.setPatternInfo(&patternInfo);
+ mod.setPatternInfo(&patternInfo, UNUM_FIELD_COUNT);
mod.setPatternAttributes(UNUM_SIGN_AUTO, false);
DecimalFormatSymbols symbols(Locale::getEnglish(), status);
CurrencySymbols currencySymbols({u"USD", status}, "en", status);
ParsedPatternInfo patternInfo;
PatternParser::parseToPatternInfo("a0b;c-0d", patternInfo, status);
assertSuccess("Spot 1", status);
- mod.setPatternInfo(&patternInfo);
+ mod.setPatternInfo(&patternInfo, UNUM_FIELD_COUNT);
mod.setPatternAttributes(UNUM_SIGN_AUTO, false);
DecimalFormatSymbols symbols(Locale::getEnglish(), status);
CurrencySymbols currencySymbols({u"USD", status}, "en", status);
CharSequence affixPattern,
NumberStringBuilder output,
int position,
- SymbolProvider provider) {
+ SymbolProvider provider,
+ NumberFormat.Field field) {
assert affixPattern != null;
int length = 0;
long tag = 0L;
provider.getSymbol(typeOrCp),
getFieldForType(typeOrCp));
} else {
- length += output.insertCodePoint(position + length, typeOrCp, null);
+ length += output.insertCodePoint(position + length, typeOrCp, field);
}
}
return length;
// Pattern details
AffixPatternProvider patternInfo;
+ Field field;
SignDisplay signDisplay;
boolean perMilleReplacesPercent;
* Sets a reference to the parsed decimal format pattern, usually obtained from
* {@link PatternStringParser#parseToPatternInfo(String)}, but any implementation of
* {@link AffixPatternProvider} is accepted.
+ *
+ * @param field
+ * Which field to use for literal characters in the pattern.
*/
- public void setPatternInfo(AffixPatternProvider patternInfo) {
+ public void setPatternInfo(AffixPatternProvider patternInfo, Field field) {
this.patternInfo = patternInfo;
+ this.field = field;
}
/**
private int insertPrefix(NumberStringBuilder sb, int position) {
prepareAffix(true);
- int length = AffixUtils.unescape(currentAffix, sb, position, this);
+ int length = AffixUtils.unescape(currentAffix, sb, position, this, field);
return length;
}
private int insertSuffix(NumberStringBuilder sb, int position) {
prepareAffix(false);
- int length = AffixUtils.unescape(currentAffix, sb, position, this);
+ int length = AffixUtils.unescape(currentAffix, sb, position, this, field);
return length;
}
import com.ibm.icu.impl.number.PatternStringParser;
import com.ibm.icu.impl.number.PatternStringParser.ParsedPatternInfo;
import com.ibm.icu.text.CompactDecimalFormat.CompactStyle;
+import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.text.PluralRules;
import com.ibm.icu.util.ULocale;
}
if (buildReference != null) {
// Safe code path
- precomputedMods = new HashMap<String, ImmutablePatternModifier>();
+ precomputedMods = new HashMap<>();
precomputeAllModifiers(buildReference);
} else {
// Unsafe code path
/** Used by the safe code path */
private void precomputeAllModifiers(MutablePatternModifier buildReference) {
- Set<String> allPatterns = new HashSet<String>();
+ Set<String> allPatterns = new HashSet<>();
data.getUniquePatterns(allPatterns);
for (String patternString : allPatterns) {
ParsedPatternInfo patternInfo = PatternStringParser.parseToPatternInfo(patternString);
- buildReference.setPatternInfo(patternInfo);
+ buildReference.setPatternInfo(patternInfo, NumberFormat.Field.COMPACT);
precomputedMods.put(patternString, buildReference.createImmutable());
}
}
// Overwrite the PatternInfo in the existing modMiddle.
assert micros.modMiddle instanceof MutablePatternModifier;
ParsedPatternInfo patternInfo = PatternStringParser.parseToPatternInfo(patternString);
- ((MutablePatternModifier) micros.modMiddle).setPatternInfo(patternInfo);
+ ((MutablePatternModifier) micros.modMiddle).setPatternInfo(patternInfo, NumberFormat.Field.COMPACT);
}
// We already performed rounding. Do not perform it again.
// Middle modifier (patterns, positive/negative, currency symbols, percent)
// The default middle modifier is weak (thus the false argument).
MutablePatternModifier patternMod = new MutablePatternModifier(false);
- patternMod.setPatternInfo((macros.affixProvider != null) ? macros.affixProvider : patternInfo);
+ patternMod.setPatternInfo((macros.affixProvider != null) ? macros.affixProvider : patternInfo, null);
patternMod.setPatternAttributes(micros.sign, isPermille);
if (patternMod.needsPlurals()) {
if (rules == null) {
*/
public static final Field MEASURE_UNIT = new Field("measure unit");
+ /**
+ * @draft ICU 64
+ */
+ public static final Field COMPACT = new Field("compact");
+
/**
* Constructs a new instance of NumberFormat.Field with the given field
* name.
String input = cas[0];
String expected = cas[1];
sb.clear();
- AffixUtils.unescape(input, sb, 0, provider);
+ AffixUtils.unescape(input, sb, 0, provider, null);
assertEquals("With symbol provider on <" + input + ">", expected, sb.toString());
}
// Test insertion position
sb.clear();
sb.append("abcdefg", null);
- AffixUtils.unescape("-+%", sb, 4, provider);
+ AffixUtils.unescape("-+%", sb, 4, provider, null);
assertEquals("Symbol provider into middle", "abcd123efg", sb.toString());
}
private static String unescapeWithDefaults(String input) {
NumberStringBuilder nsb = new NumberStringBuilder();
- int length = AffixUtils.unescape(input, nsb, 0, DEFAULT_SYMBOL_PROVIDER);
+ int length = AffixUtils.unescape(input, nsb, 0, DEFAULT_SYMBOL_PROVIDER, null);
assertEquals("Return value of unescape", nsb.length(), length);
return nsb.toString();
}
@Test
public void basic() {
MutablePatternModifier mod = new MutablePatternModifier(false);
- mod.setPatternInfo(PatternStringParser.parseToPatternInfo("a0b"));
+ mod.setPatternInfo(PatternStringParser.parseToPatternInfo("a0b"), null);
mod.setPatternAttributes(SignDisplay.AUTO, false);
mod.setSymbols(DecimalFormatSymbols.getInstance(ULocale.ENGLISH),
Currency.getInstance("USD"),
assertEquals("a", getPrefix(mod));
assertEquals("b", getSuffix(mod));
- mod.setPatternInfo(PatternStringParser.parseToPatternInfo("a0b;c-0d"));
+ mod.setPatternInfo(PatternStringParser.parseToPatternInfo("a0b;c-0d"), null);
mod.setPatternAttributes(SignDisplay.AUTO, false);
mod.setNumberProperties(1, null);
assertEquals("a", getPrefix(mod));
@Test
public void mutableEqualsImmutable() {
MutablePatternModifier mod = new MutablePatternModifier(false);
- mod.setPatternInfo(PatternStringParser.parseToPatternInfo("a0b;c-0d"));
+ mod.setPatternInfo(PatternStringParser.parseToPatternInfo("a0b;c-0d"), null);
mod.setPatternAttributes(SignDisplay.AUTO, false);
mod.setSymbols(DecimalFormatSymbols.getInstance(ULocale.ENGLISH), null, UnitWidth.SHORT, null);
DecimalQuantity fq = new DecimalQuantity_DualStorageBCD(1);
@Test
public void patternWithNoPlaceholder() {
MutablePatternModifier mod = new MutablePatternModifier(false);
- mod.setPatternInfo(PatternStringParser.parseToPatternInfo("abc"));
+ mod.setPatternInfo(PatternStringParser.parseToPatternInfo("abc"), null);
mod.setPatternAttributes(SignDisplay.AUTO, false);
mod.setSymbols(DecimalFormatSymbols.getInstance(ULocale.ENGLISH),
Currency.getInstance("USD"),
result,
expectedFieldPositions);
}
+
+ {
+ String message = "Compact field basic";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ "compact-short",
+ NumberFormatter.with().notation(Notation.compactShort()),
+ ULocale.US,
+ 65000,
+ "65K");
+ Object[][] expectedFieldPositions = new Object[][] {
+ // field, begin index, end index
+ {NumberFormat.Field.INTEGER, 0, 2},
+ {NumberFormat.Field.COMPACT, 2, 3}};
+ assertFieldPositions(
+ message,
+ result,
+ expectedFieldPositions);
+ }
+
+ {
+ String message = "Compact field with spaces";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ "compact-long",
+ NumberFormatter.with().notation(Notation.compactLong()),
+ ULocale.US,
+ 65000,
+ "65 thousand");
+ Object[][] expectedFieldPositions = new Object[][] {
+ // field, begin index, end index
+ {NumberFormat.Field.INTEGER, 0, 2},
+ {NumberFormat.Field.COMPACT, 3, 11}};
+ assertFieldPositions(
+ message,
+ result,
+ expectedFieldPositions);
+ }
+
+ {
+ String message = "Compact field with inner space";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ "compact-long",
+ NumberFormatter.with().notation(Notation.compactLong()),
+ new ULocale("fil"), // locale with interesting data
+ 6000,
+ "6 na libo");
+ Object[][] expectedFieldPositions = new Object[][] {
+ // field, begin index, end index
+ {NumberFormat.Field.INTEGER, 0, 1},
+ {NumberFormat.Field.COMPACT, 2, 9}};
+ assertFieldPositions(
+ message,
+ result,
+ expectedFieldPositions);
+ }
+
+ {
+ String message = "Compact field with bidi mark";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ "compact-long",
+ NumberFormatter.with().notation(Notation.compactLong()),
+ new ULocale("he"), // locale with interesting data
+ 6000,
+ "\u200F6 אלף");
+ Object[][] expectedFieldPositions = new Object[][] {
+ // field, begin index, end index
+ {NumberFormat.Field.INTEGER, 1, 2},
+ {NumberFormat.Field.COMPACT, 3, 6}};
+ assertFieldPositions(
+ message,
+ result,
+ expectedFieldPositions);
+ }
+
+ {
+ String message = "Compact with currency fields";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ "compact-short currency/USD",
+ NumberFormatter.with().notation(Notation.compactShort()).unit(USD),
+ new ULocale("sr_Latn"), // locale with interesting data
+ 65000,
+ "65 hilj. US$");
+ Object[][] expectedFieldPositions = new Object[][] {
+ // field, begin index, end index
+ {NumberFormat.Field.INTEGER, 0, 2},
+ {NumberFormat.Field.COMPACT, 3, 8},
+ {NumberFormat.Field.CURRENCY, 9, 12}};
+ assertFieldPositions(
+ message,
+ result,
+ expectedFieldPositions);
+ }
+
+ {
+ String message = "Compact with measure unit fields";
+ FormattedNumber result = assertFormatSingle(
+ message,
+ "compact-long measure-unit/length-meter unit-width-full-name",
+ NumberFormatter.with().notation(Notation.compactLong())
+ .unit(MeasureUnit.METER)
+ .unitWidth(UnitWidth.FULL_NAME),
+ ULocale.US,
+ 65000,
+ "65 thousand meters");
+ Object[][] expectedFieldPositions = new Object[][] {
+ // field, begin index, end index
+ {NumberFormat.Field.INTEGER, 0, 2},
+ {NumberFormat.Field.COMPACT, 3, 11},
+ {NumberFormat.Field.MEASURE_UNIT, 12, 18}};
+ assertFieldPositions(
+ message,
+ result,
+ expectedFieldPositions);
+ }
}
/** Handler for serialization compatibility test suite. */