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