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