+UnicodeString TestMessageFormat::GetPatternAndSkipSyntax(const MessagePattern& pattern) {
+ UnicodeString us(pattern.getPatternString());
+ int count = pattern.countParts();
+ for (int i = count; i > 0;) {
+ const MessagePattern::Part& part = pattern.getPart(--i);
+ if (part.getType() == UMSGPAT_PART_TYPE_SKIP_SYNTAX) {
+ us.remove(part.getIndex(), part.getLimit() - part.getIndex());
+ }
+ }
+ return us;
+}
+
+void TestMessageFormat::TestApostropheMode() {
+ UErrorCode status = U_ZERO_ERROR;
+ MessagePattern *ado_mp = new MessagePattern(UMSGPAT_APOS_DOUBLE_OPTIONAL, status);
+ MessagePattern *adr_mp = new MessagePattern(UMSGPAT_APOS_DOUBLE_REQUIRED, status);
+ if (ado_mp->getApostropheMode() != UMSGPAT_APOS_DOUBLE_OPTIONAL) {
+ errln("wrong value from ado_mp->getApostropheMode().");
+ }
+ if (adr_mp->getApostropheMode() != UMSGPAT_APOS_DOUBLE_REQUIRED) {
+ errln("wrong value from adr_mp->getApostropheMode().");
+ }
+
+
+ UnicodeString tuples[] = {
+ // Desired output
+ // DOUBLE_OPTIONAL pattern
+ // DOUBLE_REQUIRED pattern (empty=same as DOUBLE_OPTIONAL)
+ "I see {many}", "I see '{many}'", "",
+ "I said {'Wow!'}", "I said '{''Wow!''}'", "",
+ "I dont know", "I dont know", "I don't know",
+ "I don't know", "I don't know", "I don''t know",
+ "I don't know", "I don''t know", "I don''t know"
+ };
+ int32_t tuples_count = LENGTHOF(tuples);
+
+ for (int i = 0; i < tuples_count; i += 3) {
+ UnicodeString& desired = tuples[i];
+ UnicodeString& ado_pattern = tuples[i + 1];
+ UErrorCode status = U_ZERO_ERROR;
+ assertEquals("DOUBLE_OPTIONAL failure",
+ desired,
+ GetPatternAndSkipSyntax(ado_mp->parse(ado_pattern, NULL, status)));
+ UnicodeString& adr_pattern = tuples[i + 2].isEmpty() ? ado_pattern : tuples[i + 2];
+ assertEquals("DOUBLE_REQUIRED failure", desired,
+ GetPatternAndSkipSyntax(adr_mp->parse(adr_pattern, NULL, status)));
+ }
+ delete adr_mp;
+ delete ado_mp;
+}
+
+
+// Compare behavior of DOUBLE_OPTIONAL (new default) and DOUBLE_REQUIRED JDK-compatibility mode.
+void TestMessageFormat::TestCompatibleApostrophe() {
+ // Message with choice argument which does not contain another argument.
+ // The JDK performs only one apostrophe-quoting pass on this pattern.
+ UnicodeString pattern = "ab{0,choice,0#1'2''3'''4''''.}yz";
+
+ UErrorCode ec = U_ZERO_ERROR;
+ MessageFormat compMsg("", Locale::getUS(), ec);
+ compMsg.applyPattern(pattern, UMSGPAT_APOS_DOUBLE_REQUIRED, NULL, ec);
+ if (compMsg.getApostropheMode() != UMSGPAT_APOS_DOUBLE_REQUIRED) {
+ errln("wrong value from compMsg.getApostropheMode().");
+ }
+
+ MessageFormat icuMsg("", Locale::getUS(), ec);
+ icuMsg.applyPattern(pattern, UMSGPAT_APOS_DOUBLE_OPTIONAL, NULL, ec);
+ if (icuMsg.getApostropheMode() != UMSGPAT_APOS_DOUBLE_OPTIONAL) {
+ errln("wrong value from icuMsg.getApostropheMode().");
+ }
+
+ Formattable zero0[] = { (int32_t)0 };
+ FieldPosition fieldpos(0);
+ UnicodeString buffer1, buffer2;
+ assertEquals("incompatible ICU MessageFormat compatibility-apostrophe behavior",
+ "ab12'3'4''.yz",
+ compMsg.format(zero0, 1, buffer1, fieldpos, ec));
+ assertEquals("unexpected ICU MessageFormat double-apostrophe-optional behavior",
+ "ab1'2'3''4''.yz",
+ icuMsg.format(zero0, 1, buffer2, fieldpos, ec));
+
+ // Message with choice argument which contains a nested simple argument.
+ // The DOUBLE_REQUIRED version performs two apostrophe-quoting passes.
+ buffer1.remove();
+ buffer2.remove();
+ pattern = "ab{0,choice,0#1'2''3'''4''''.{0,number,'#x'}}yz";
+ compMsg.applyPattern(pattern, ec);
+ icuMsg.applyPattern(pattern, ec);
+ if (U_FAILURE(ec)) {
+ dataerrln("Unable to applyPattern - %s", u_errorName(ec));
+ } else {
+ assertEquals("incompatible ICU MessageFormat compatibility-apostrophe behavior",
+ "ab1234'.0xyz",
+ compMsg.format(zero0, 1, buffer1, fieldpos, ec));
+ assertEquals("unexpected ICU MessageFormat double-apostrophe-optional behavior",
+ "ab1'2'3''4''.#x0yz",
+ icuMsg.format(zero0, 1, buffer2, fieldpos, ec));
+ }
+
+ // This part is copied over from Java tests but cannot be properly tested here
+ // because we do not have a live reference implementation with JDK behavior.
+ // The JDK ChoiceFormat itself always performs one apostrophe-quoting pass.
+ /*
+ ChoiceFormat choice = new ChoiceFormat("0#1'2''3'''4''''.");
+ assertEquals("unexpected JDK ChoiceFormat apostrophe behavior",
+ "12'3'4''.",
+ choice.format(0));
+ choice.applyPattern("0#1'2''3'''4''''.{0,number,'#x'}");
+ assertEquals("unexpected JDK ChoiceFormat apostrophe behavior",
+ "12'3'4''.{0,number,#x}",
+ choice.format(0));
+ */
+}
+