xref: /aosp_15_r20/external/icu/icu4c/source/test/intltest/messageformat2test_icu.cpp (revision 0e209d3975ff4a8c132096b14b0e9364a753506e)
1 // © 2024 and later: Unicode, Inc. and others.
2 
3 #include "unicode/utypes.h"
4 
5 #if !UCONFIG_NO_FORMATTING
6 
7 #if !UCONFIG_NO_MF2
8 
9 #include "unicode/gregocal.h"
10 #include "unicode/msgfmt.h"
11 #include "messageformat2test.h"
12 
13 using namespace icu::message2;
14 
15 /*
16   Tests based on ICU4J's Mf2IcuTest.java
17 */
18 
19 /*
20   TODO: Tests need to be unified in a single format that
21   both ICU4C and ICU4J can use, rather than being embedded in code.
22 */
23 
24 /*
25 Tests reflect the syntax specified in
26 
27   https://github.com/unicode-org/message-format-wg/commits/main/spec/message.abnf
28 
29 as of the following commit from 2023-05-09:
30   https://github.com/unicode-org/message-format-wg/commit/194f6efcec5bf396df36a19bd6fa78d1fa2e0867
31 
32 */
33 
testSample(TestCase::Builder & testBuilder,IcuTestErrorCode & errorCode)34 void TestMessageFormat2::testSample(TestCase::Builder& testBuilder, IcuTestErrorCode& errorCode) {
35     TestUtils::runTestCase(*this, testBuilder.setPattern("There are {$count} files on {$where}")
36                                 .setArgument("count", "abc")
37                                 .setArgument("where", "def")
38                                 .setExpected("There are abc files on def")
39                                 .build(), errorCode);
40 }
41 
testStaticFormat(TestCase::Builder & testBuilder,IcuTestErrorCode & errorCode)42 void TestMessageFormat2::testStaticFormat(TestCase::Builder& testBuilder, IcuTestErrorCode& errorCode) {
43     TestUtils::runTestCase(*this, testBuilder.setPattern("At {$when :time style=medium} on {$when :date style=medium}, \
44 there was {$what} on planet {$planet :integer}.")
45                                 .setArgument("planet", (int64_t) 7)
46                                 .setDateArgument("when", (UDate) 871068000000)
47                                 .setArgument("what", "a disturbance in the Force")
48                                 .setExpected(CharsToUnicodeString("At 12:20:00\\u202FPM on Aug 8, 1997, there was a disturbance in the Force on planet 7."))
49                                 .build(), errorCode);
50 }
51 
testSimpleFormat(TestCase::Builder & testBuilder,IcuTestErrorCode & errorCode)52 void TestMessageFormat2::testSimpleFormat(TestCase::Builder& testBuilder, IcuTestErrorCode& errorCode) {
53     testBuilder.setPattern("The disk \"{$diskName}\" contains {$fileCount} file(s).");
54     testBuilder.setArgument("diskName", "MyDisk");
55 
56 
57     TestCase test = testBuilder.setArgument("fileCount", (int64_t) 0)
58         .setExpected("The disk \"MyDisk\" contains 0 file(s).")
59         .build();
60     TestUtils::runTestCase(*this, test, errorCode);
61 
62     test = testBuilder.setArgument("fileCount", (int64_t) 1)
63                       .setExpected("The disk \"MyDisk\" contains 1 file(s).")
64                       .build();
65     TestUtils::runTestCase(*this, test, errorCode);
66 
67     test = testBuilder.setArgument("fileCount", (int64_t) 12)
68                       .setExpected("The disk \"MyDisk\" contains 12 file(s).")
69                       .build();
70     TestUtils::runTestCase(*this, test, errorCode);
71 }
72 
testSelectFormatToPattern(TestCase::Builder & testBuilder,IcuTestErrorCode & errorCode)73 void TestMessageFormat2::testSelectFormatToPattern(TestCase::Builder& testBuilder, IcuTestErrorCode& errorCode) {
74     UnicodeString pattern = CharsToUnicodeString(".match {$userGender :string}\n\
75                  female {{{$userName} est all\\u00E9e \\u00E0 Paris.}}\n\
76                  *     {{{$userName} est all\\u00E9 \\u00E0 Paris.}}");
77 
78     testBuilder.setPattern(pattern);
79 
80     TestCase test = testBuilder.setArgument("userName", "Charlotte")
81                                 .setArgument("userGender", "female")
82                                 .setExpected(CharsToUnicodeString("Charlotte est all\\u00e9e \\u00e0 Paris."))
83                                 .build();
84     TestUtils::runTestCase(*this, test, errorCode);
85 
86     test = testBuilder.setArgument("userName", "Guillaume")
87                                 .setArgument("userGender", "male")
88                                 .setExpected(CharsToUnicodeString("Guillaume est all\\u00e9 \\u00e0 Paris."))
89                                 .build();
90     TestUtils::runTestCase(*this, test, errorCode);
91 
92     test = testBuilder.setArgument("userName", "Dominique")
93                                 .setArgument("userGender", "unknown")
94                                 .setExpected(CharsToUnicodeString("Dominique est all\\u00e9 \\u00e0 Paris."))
95                                 .build();
96     TestUtils::runTestCase(*this, test, errorCode);
97 }
98 
testMf1Behavior(TestCase::Builder & testBuilder,IcuTestErrorCode & errorCode)99 void TestMessageFormat2::testMf1Behavior(TestCase::Builder& testBuilder, IcuTestErrorCode& errorCode) {
100     CHECK_ERROR(errorCode);
101 
102     UDate testDate = UDate(1671782400000); // 2022-12-23
103     UnicodeString user = "John";
104     UnicodeString badArgumentsNames[] = {
105         "userX", "todayX"
106     };
107     UnicodeString goodArgumentsNames[] = {
108         "user", "today"
109     };
110     icu::Formattable oldArgumentsValues[] = {
111         icu::Formattable(user), icu::Formattable(testDate, icu::Formattable::kIsDate)
112     };
113     UnicodeString expectedGood = "Hello John, today is December 23, 2022.";
114 
115     LocalPointer<MessageFormat> mf1(new MessageFormat("Hello {user}, today is {today,date,long}.", errorCode));
116     CHECK_ERROR(errorCode);
117 
118     UnicodeString result;
119     mf1->format(badArgumentsNames, oldArgumentsValues, 2, result, errorCode);
120     assertEquals("testMf1Behavior", (UBool) true, U_SUCCESS(errorCode));
121     assertEquals("old icu test", "Hello {user}, today is {today}.", result);
122     result.remove();
123     mf1->format(goodArgumentsNames, oldArgumentsValues, 2, result, errorCode);
124     assertEquals("testMf1Behavior", (UBool) true, U_SUCCESS(errorCode));
125     assertEquals("old icu test", expectedGood, result);
126 
127     TestCase test = testBuilder.setPattern("Hello {$user}, today is {$today :date style=long}.")
128                                 .setArgument(badArgumentsNames[0], user)
129                                 .setDateArgument(badArgumentsNames[1], testDate)
130                                 .setExpected("Hello {$user}, today is {$today}.")
131                                 .setExpectedError(U_MF_UNRESOLVED_VARIABLE_ERROR)
132                                 .build();
133     TestUtils::runTestCase(*this, test, errorCode);
134 
135     test = testBuilder.clearArguments()
136                       .setExpectSuccess()
137                       .setArgument(goodArgumentsNames[0], user)
138                       .setDateArgument(goodArgumentsNames[1], testDate)
139                       .setExpected(expectedGood)
140                       .build();
141     TestUtils::runTestCase(*this, test, errorCode);
142 }
143 
messageFormat1Tests()144 void TestMessageFormat2::messageFormat1Tests() {
145     IcuTestErrorCode errorCode(*this, "featureTests");
146 
147     TestCase::Builder testBuilder;
148     testBuilder.setName("messageFormat1Tests");
149 
150     testSample(testBuilder, errorCode);
151     testStaticFormat(testBuilder, errorCode);
152     testSimpleFormat(testBuilder, errorCode);
153     testSelectFormatToPattern(testBuilder, errorCode);
154     testMf1Behavior(testBuilder, errorCode);
155 }
156 
157 #endif /* #if !UCONFIG_NO_MF2 */
158 
159 #endif /* #if !UCONFIG_NO_FORMATTING */
160