xref: /aosp_15_r20/external/icu/icu4c/source/test/intltest/messageformat2test.h (revision 0e209d3975ff4a8c132096b14b0e9364a753506e)
1 // © 2024 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 
4 #ifndef _TESTMESSAGEFORMAT2
5 #define _TESTMESSAGEFORMAT2
6 
7 #include "unicode/rep.h"
8 #include "unicode/utypes.h"
9 
10 #if !UCONFIG_NO_FORMATTING
11 
12 #if !UCONFIG_NO_MF2
13 
14 #include "messageformat2test_utils.h"
15 #include "unicode/unistr.h"
16 #include "unicode/messageformat2_formattable.h"
17 #include "unicode/parseerr.h"
18 #include "intltest.h"
19 
20 /**
21  * TestMessageFormat2 tests MessageFormat2
22  */
23 
24 struct TestResult {
25     const UnicodeString pattern;
26     const UnicodeString output;
27 };
28 
29 struct TestResultError {
30     const UnicodeString pattern;
31     const UnicodeString output;
32     UErrorCode expected;
33 };
34 
35 class TestMessageFormat2: public IntlTest {
36 public:
37     void runIndexedTest( int32_t index, UBool exec, const char* &name, char* par = NULL ) override;
38 
39     /**
40      * test MessageFormat2 with various given patterns
41      **/
42     void testVariousPatterns(void);
43     void featureTests(void);
44     void messageFormat1Tests(void);
45     void testAPICustomFunctions(void);
46     // Test custom functions
47     void testCustomFunctions(void);
48     // Test standard functions
49     void testBuiltInFunctions(void);
50     void testDataModelErrors(void);
51     void testResolutionErrors(void);
52     // Test the data model API
53     void testDataModelAPI(void);
54     void testAPI(void);
55     void testInvalidPatterns(void);
56     void testAPISimple(void);
57 
58 private:
59 
60     void testSemanticallyInvalidPattern(uint32_t, const UnicodeString&, UErrorCode);
61     void testRuntimeErrorPattern(uint32_t, const UnicodeString&, UErrorCode);
62     void testRuntimeWarningPattern(uint32_t, const UnicodeString&, const UnicodeString&, UErrorCode);
63     void testInvalidPattern(uint32_t, const UnicodeString&);
64     void testInvalidPattern(uint32_t, const UnicodeString&, uint32_t);
65     void testInvalidPattern(uint32_t, const UnicodeString&, uint32_t, uint32_t);
66     void testValidPatterns(const TestResult*, int32_t, IcuTestErrorCode&);
67     void testResolutionErrors(IcuTestErrorCode&);
68     void testNoSyntaxErrors(const UnicodeString*, int32_t, IcuTestErrorCode&);
69     void jsonTests(IcuTestErrorCode&);
70     void specTests();
71     void runSpecTests(IcuTestErrorCode&);
72 
73     // Built-in function testing
74     void testDateTime(IcuTestErrorCode&);
75     void testNumbers(IcuTestErrorCode&);
76 
77     // Custom function testing
78     void testPersonFormatter(IcuTestErrorCode&);
79     void testCustomFunctionsComplexMessage(IcuTestErrorCode&);
80     void testGrammarCasesFormatter(IcuTestErrorCode&);
81     void testListFormatter(IcuTestErrorCode&);
82     void testMessageRefFormatter(IcuTestErrorCode&);
83 
84     // Feature tests
85     void testEmptyMessage(message2::TestCase::Builder&, IcuTestErrorCode&);
86     void testPlainText(message2::TestCase::Builder&, IcuTestErrorCode&);
87     void testPlaceholders(message2::TestCase::Builder&, IcuTestErrorCode&);
88     void testArgumentMissing(message2::TestCase::Builder&, IcuTestErrorCode&);
89     void testDefaultLocale(message2::TestCase::Builder&, IcuTestErrorCode&);
90     void testSpecialPluralWithDecimals(message2::TestCase::Builder&, IcuTestErrorCode&);
91     void testDefaultFunctionAndOptions(message2::TestCase::Builder&, IcuTestErrorCode&);
92     void testSimpleSelection(message2::TestCase::Builder&, IcuTestErrorCode&);
93     void testComplexSelection(message2::TestCase::Builder&, IcuTestErrorCode&);
94     void testSimpleLocalVariable(message2::TestCase::Builder&, IcuTestErrorCode&);
95     void testLocalVariableWithSelect(message2::TestCase::Builder&, IcuTestErrorCode&);
96     void testDateFormat(message2::TestCase::Builder&, IcuTestErrorCode&);
97     void testPlural(message2::TestCase::Builder&, IcuTestErrorCode&);
98 
99     void testPluralOrdinal(message2::TestCase::Builder&, IcuTestErrorCode&);
100     void testDeclareBeforeUse(message2::TestCase::Builder&, IcuTestErrorCode&);
101 
102     // MessageFormat 1 tests
103     void testSample(message2::TestCase::Builder&, IcuTestErrorCode&);
104     void testStaticFormat(message2::TestCase::Builder&, IcuTestErrorCode&);
105     void testSimpleFormat(message2::TestCase::Builder&, IcuTestErrorCode&);
106     void testSelectFormatToPattern(message2::TestCase::Builder&, IcuTestErrorCode&);
107     void testMessageFormatDateTimeSkeleton(message2::TestCase::Builder&, IcuTestErrorCode&);
108     void testMf1Behavior(message2::TestCase::Builder&, IcuTestErrorCode&);
109 
110 }; // class TestMessageFormat2
111 
112 U_NAMESPACE_BEGIN
113 
114 namespace message2 {
115 
116 // Custom function classes
117 class PersonNameFormatterFactory : public FormatterFactory {
118 
119     public:
120     Formatter* createFormatter(const Locale&, UErrorCode&) override;
121 };
122 
123 class Person : public FormattableObject {
124     public:
125     UnicodeString title;
126     UnicodeString firstName;
127     UnicodeString lastName;
Person(UnicodeString t,UnicodeString f,UnicodeString l)128     Person(UnicodeString t, UnicodeString f, UnicodeString l) : title(t), firstName(f), lastName(l), tagName("person") {}
129     ~Person();
tag()130     const UnicodeString& tag() const override { return tagName; }
131     private:
132     const UnicodeString tagName;
133 };
134 
135 class PersonNameFormatter : public Formatter {
136     public:
137     FormattedPlaceholder format(FormattedPlaceholder&&, FunctionOptions&& opts, UErrorCode& errorCode) const override;
138 };
139 
140 class FormattableProperties : public FormattableObject {
141     public:
tag()142     const UnicodeString& tag() const override { return tagName; }
FormattableProperties(Hashtable * hash)143     FormattableProperties(Hashtable* hash) : properties(hash), tagName("properties") {
144         U_ASSERT(hash != nullptr);
145     }
146     ~FormattableProperties();
147     LocalPointer<Hashtable> properties;
148 private:
149     const UnicodeString tagName;
150 };
151 
152 class GrammarCasesFormatterFactory : public FormatterFactory {
153     public:
154     Formatter* createFormatter(const Locale&, UErrorCode&) override;
155 };
156 
157 class GrammarCasesFormatter : public Formatter {
158     public:
159     FormattedPlaceholder format(FormattedPlaceholder&&, FunctionOptions&& opts, UErrorCode& errorCode) const override;
160     static MFFunctionRegistry customRegistry(UErrorCode&);
161     private:
162     void getDativeAndGenitive(const UnicodeString&, UnicodeString& result) const;
163 };
164 
165 class ListFormatterFactory : public FormatterFactory {
166     public:
167     Formatter* createFormatter(const Locale&, UErrorCode&) override;
168 };
169 
170 class ListFormatter : public Formatter {
171     public:
172     FormattedPlaceholder format(FormattedPlaceholder&&, FunctionOptions&& opts, UErrorCode& errorCode) const override;
173     static MFFunctionRegistry customRegistry(UErrorCode&);
174     private:
175     friend class ListFormatterFactory;
176     const Locale& locale;
ListFormatter(const Locale & loc)177     ListFormatter(const Locale& loc) : locale(loc) {}
178 };
179 
180 class ResourceManagerFactory : public FormatterFactory {
181     public:
182     Formatter* createFormatter(const Locale&, UErrorCode&) override;
183 };
184 
185 class ResourceManager : public Formatter {
186     public:
187     FormattedPlaceholder format(FormattedPlaceholder&&, FunctionOptions&& opts, UErrorCode& errorCode) const override;
188     static MFFunctionRegistry customRegistry(UErrorCode&);
189     static Hashtable* properties(UErrorCode&);
190     static UnicodeString propertiesAsString(const Hashtable&);
191     static Hashtable* parseProperties(const UnicodeString&, UErrorCode&);
192 
193     private:
194     friend class ResourceManagerFactory;
ResourceManager(const Locale & loc)195     ResourceManager(const Locale& loc) : locale(loc) {}
196     const Locale& locale;
197 };
198 
199 } // namespace message2
200 U_NAMESPACE_END
201 
202 #endif /* #if !UCONFIG_NO_MF2 */
203 
204 #endif /* #if !UCONFIG_NO_FORMATTING */
205 
206 #endif
207