1/* GENERATED SOURCE. DO NOT MODIFY. */ 2// © 2017 and later: Unicode, Inc. and others. 3// License & terms of use: http://www.unicode.org/copyright.html#License 4package android.icu.dev.test.number; 5 6import static org.junit.Assert.assertEquals; 7import static org.junit.Assert.assertTrue; 8 9import org.junit.Test; 10 11import android.icu.impl.SimpleFormatterImpl; 12import android.icu.impl.number.ConstantAffixModifier; 13import android.icu.impl.number.ConstantMultiFieldModifier; 14import android.icu.impl.number.CurrencySpacingEnabledModifier; 15import android.icu.impl.number.Modifier; 16import android.icu.impl.number.NumberStringBuilder; 17import android.icu.impl.number.SimpleModifier; 18import android.icu.text.DecimalFormatSymbols; 19import android.icu.text.NumberFormat; 20import android.icu.util.ULocale; 21import android.icu.testsharding.MainTestShard; 22 23@MainTestShard 24public class ModifierTest { 25 @Test 26 public void testConstantAffixModifier() { 27 assertModifierEquals(ConstantAffixModifier.EMPTY, 0, false, "|", "n"); 28 29 Modifier mod1 = new ConstantAffixModifier("a", "b", NumberFormat.Field.PERCENT, true); 30 assertModifierEquals(mod1, 3, true, "a|b", "%%%n%"); 31 } 32 33 @Test 34 public void testConstantMultiFieldModifier() { 35 NumberStringBuilder prefix = new NumberStringBuilder(); 36 NumberStringBuilder suffix = new NumberStringBuilder(); 37 Modifier mod1 = new ConstantMultiFieldModifier(prefix, suffix, true); 38 assertModifierEquals(mod1, 0, true, "|", "n"); 39 40 prefix.append("a", NumberFormat.Field.PERCENT); 41 suffix.append("b", NumberFormat.Field.CURRENCY); 42 Modifier mod2 = new ConstantMultiFieldModifier(prefix, suffix, true); 43 assertModifierEquals(mod2, 3, true, "a|b", "%%%n$"); 44 45 // Make sure the first modifier is still the same (that it stayed constant) 46 assertModifierEquals(mod1, 0, true, "|", "n"); 47 } 48 49 @Test 50 public void testSimpleModifier() { 51 String[] patterns = { "{0}", "X{0}Y", "XX{0}YYY", "{0}YY", "XXXX{0}" }; 52 Object[][] outputs = { { "", 0, 0 }, { "abcde", 0, 0 }, { "abcde", 4, 4 }, { "abcde", 3, 5 } }; 53 int[] prefixLens = { 0, 1, 2, 0, 6 }; 54 String[][] expectedCharFields = { { "|", "n" }, { "X|Y", "%n%" }, { "XX|YYY", "%%n%%%" }, { "|YY", "n%%" }, 55 { "XXXX|", "%%%%%%n" } }; 56 String[][] expecteds = { { "", "XY", "XXYYY", "YY", "XXXX" }, 57 { "abcde", "XYabcde", "XXYYYabcde", "YYabcde", "XXXXabcde" }, 58 { "abcde", "abXYcde", "abXXYYYcde", "abYYcde", "abXXXXcde" }, 59 { "abcde", "aXbcYde", "aXXbcYYYde", "abcYYde", "aXXXXbcde" } }; 60 for (int i = 0; i < patterns.length; i++) { 61 String pattern = patterns[i]; 62 String compiledPattern = SimpleFormatterImpl 63 .compileToStringMinMaxArguments(pattern, new StringBuilder(), 1, 1); 64 Modifier mod = new SimpleModifier(compiledPattern, NumberFormat.Field.PERCENT, false); 65 assertModifierEquals(mod, prefixLens[i], false, expectedCharFields[i][0], expectedCharFields[i][1]); 66 67 // Test strange insertion positions 68 for (int j = 0; j < outputs.length; j++) { 69 NumberStringBuilder output = new NumberStringBuilder(); 70 output.append((String) outputs[j][0], null); 71 mod.apply(output, (Integer) outputs[j][1], (Integer) outputs[j][2]); 72 String expected = expecteds[j][i]; 73 String actual = output.toString(); 74 assertEquals(expected, actual); 75 } 76 } 77 } 78 79 @Test 80 public void testCurrencySpacingEnabledModifier() { 81 DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(ULocale.ENGLISH); 82 NumberStringBuilder prefix = new NumberStringBuilder(); 83 NumberStringBuilder suffix = new NumberStringBuilder(); 84 Modifier mod1 = new CurrencySpacingEnabledModifier(prefix, suffix, true, symbols); 85 assertModifierEquals(mod1, 0, true, "|", "n"); 86 87 prefix.append("USD", NumberFormat.Field.CURRENCY); 88 Modifier mod2 = new CurrencySpacingEnabledModifier(prefix, suffix, true, symbols); 89 assertModifierEquals(mod2, 3, true, "USD|", "$$$n"); 90 91 // Test the default currency spacing rules 92 NumberStringBuilder sb = new NumberStringBuilder(); 93 sb.append("123", NumberFormat.Field.INTEGER); 94 NumberStringBuilder sb1 = new NumberStringBuilder(sb); 95 assertModifierEquals(mod2, sb1, 3, true, "USD\u00A0123", "$$$niii"); 96 97 // Compare with the unsafe code path 98 NumberStringBuilder sb2 = new NumberStringBuilder(sb); 99 sb2.insert(0, "USD", NumberFormat.Field.CURRENCY); 100 CurrencySpacingEnabledModifier.applyCurrencySpacing(sb2, 0, 3, 6, 0, symbols); 101 assertTrue(sb1.toDebugString() + " vs " + sb2.toDebugString(), sb1.contentEquals(sb2)); 102 103 // Test custom patterns 104 // The following line means that the last char of the number should be a | (rather than a digit) 105 symbols.setPatternForCurrencySpacing(DecimalFormatSymbols.CURRENCY_SPC_SURROUNDING_MATCH, true, "[|]"); 106 suffix.append("XYZ", NumberFormat.Field.CURRENCY); 107 Modifier mod3 = new CurrencySpacingEnabledModifier(prefix, suffix, true, symbols); 108 assertModifierEquals(mod3, 3, true, "USD|\u00A0XYZ", "$$$nn$$$"); 109 } 110 111 @Test 112 public void testCurrencySpacingPatternStability() { 113 // This test checks for stability of the currency spacing patterns in CLDR. 114 // For efficiency, ICU caches the most common currency spacing UnicodeSets. 115 // If this test starts failing, please update the method #getUnicodeSet() in 116 // BOTH CurrencySpacingEnabledModifier.java AND in C++. 117 DecimalFormatSymbols dfs = DecimalFormatSymbols.getInstance(new ULocale("en-US")); 118 assertEquals( 119 "[:^S:]", 120 dfs.getPatternForCurrencySpacing(DecimalFormatSymbols.CURRENCY_SPC_CURRENCY_MATCH, true)); 121 assertEquals( 122 "[:^S:]", 123 dfs.getPatternForCurrencySpacing(DecimalFormatSymbols.CURRENCY_SPC_CURRENCY_MATCH, false)); 124 assertEquals( 125 "[:digit:]", 126 dfs.getPatternForCurrencySpacing(DecimalFormatSymbols.CURRENCY_SPC_SURROUNDING_MATCH, true)); 127 assertEquals( 128 "[:digit:]", 129 dfs.getPatternForCurrencySpacing(DecimalFormatSymbols.CURRENCY_SPC_SURROUNDING_MATCH, false)); 130 } 131 132 private void assertModifierEquals( 133 Modifier mod, 134 int expectedPrefixLength, 135 boolean expectedStrong, 136 String expectedChars, 137 String expectedFields) { 138 NumberStringBuilder sb = new NumberStringBuilder(); 139 sb.appendCodePoint('|', null); 140 assertModifierEquals(mod, sb, expectedPrefixLength, expectedStrong, expectedChars, expectedFields); 141 } 142 143 private void assertModifierEquals( 144 Modifier mod, 145 NumberStringBuilder sb, 146 int expectedPrefixLength, 147 boolean expectedStrong, 148 String expectedChars, 149 String expectedFields) { 150 int oldCount = sb.codePointCount(); 151 mod.apply(sb, 0, oldCount); 152 assertEquals("Prefix length on " + sb, expectedPrefixLength, mod.getPrefixLength()); 153 assertEquals("Strong on " + sb, expectedStrong, mod.isStrong()); 154 if (!(mod instanceof CurrencySpacingEnabledModifier)) { 155 assertEquals("Code point count equals actual code point count", 156 sb.codePointCount() - oldCount, mod.getCodePointCount()); 157 } 158 assertEquals("<NumberStringBuilder [" + expectedChars + "] [" + expectedFields + "]>", sb.toDebugString()); 159 } 160} 161