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 dataDrivenTests(void); 43 void testAPICustomFunctions(void); 44 // Test custom functions 45 void testCustomFunctions(void); 46 // Test the data model API 47 void testDataModelAPI(void); 48 // Test the formatting API 49 void testFormatterAPI(void); 50 void testAPI(void); 51 void testAPISimple(void); 52 53 private: 54 void jsonTestsFromFiles(IcuTestErrorCode&); 55 56 // Built-in function testing 57 void testNumbers(IcuTestErrorCode&); 58 59 // Custom function testing 60 void testPersonFormatter(IcuTestErrorCode&); 61 void testCustomFunctionsComplexMessage(IcuTestErrorCode&); 62 void testGrammarCasesFormatter(IcuTestErrorCode&); 63 void testListFormatter(IcuTestErrorCode&); 64 void testMessageRefFormatter(IcuTestErrorCode&); 65 66 // Feature tests 67 void testEmptyMessage(message2::TestCase::Builder&, IcuTestErrorCode&); 68 void testPlainText(message2::TestCase::Builder&, IcuTestErrorCode&); 69 void testPlaceholders(message2::TestCase::Builder&, IcuTestErrorCode&); 70 void testArgumentMissing(message2::TestCase::Builder&, IcuTestErrorCode&); 71 void testDefaultLocale(message2::TestCase::Builder&, IcuTestErrorCode&); 72 void testSpecialPluralWithDecimals(message2::TestCase::Builder&, IcuTestErrorCode&); 73 void testDefaultFunctionAndOptions(message2::TestCase::Builder&, IcuTestErrorCode&); 74 void testSimpleSelection(message2::TestCase::Builder&, IcuTestErrorCode&); 75 void testComplexSelection(message2::TestCase::Builder&, IcuTestErrorCode&); 76 void testSimpleLocalVariable(message2::TestCase::Builder&, IcuTestErrorCode&); 77 void testLocalVariableWithSelect(message2::TestCase::Builder&, IcuTestErrorCode&); 78 void testDateFormat(message2::TestCase::Builder&, IcuTestErrorCode&); 79 void testPlural(message2::TestCase::Builder&, IcuTestErrorCode&); 80 81 void testPluralOrdinal(message2::TestCase::Builder&, IcuTestErrorCode&); 82 void testDeclareBeforeUse(message2::TestCase::Builder&, IcuTestErrorCode&); 83 84 // MessageFormat 1 tests 85 void testSample(message2::TestCase::Builder&, IcuTestErrorCode&); 86 void testStaticFormat(message2::TestCase::Builder&, IcuTestErrorCode&); 87 void testSimpleFormat(message2::TestCase::Builder&, IcuTestErrorCode&); 88 void testSelectFormatToPattern(message2::TestCase::Builder&, IcuTestErrorCode&); 89 void testMessageFormatDateTimeSkeleton(message2::TestCase::Builder&, IcuTestErrorCode&); 90 void testMf1Behavior(message2::TestCase::Builder&, IcuTestErrorCode&); 91 92 void testHighLoneSurrogate(void); 93 void testLowLoneSurrogate(void); 94 }; // class TestMessageFormat2 95 96 U_NAMESPACE_BEGIN 97 98 namespace message2 { 99 100 // Custom function classes 101 class PersonNameFormatterFactory : public FormatterFactory { 102 103 public: 104 Formatter* createFormatter(const Locale&, UErrorCode&) override; 105 }; 106 107 class Person : public FormattableObject { 108 public: 109 UnicodeString title; 110 UnicodeString firstName; 111 UnicodeString lastName; Person(UnicodeString t,UnicodeString f,UnicodeString l)112 Person(UnicodeString t, UnicodeString f, UnicodeString l) : title(t), firstName(f), lastName(l), tagName("person") {} 113 ~Person(); tag()114 const UnicodeString& tag() const override { return tagName; } 115 private: 116 const UnicodeString tagName; 117 }; 118 119 class PersonNameFormatter : public Formatter { 120 public: 121 FormattedPlaceholder format(FormattedPlaceholder&&, FunctionOptions&& opts, UErrorCode& errorCode) const override; 122 }; 123 124 class FormattableProperties : public FormattableObject { 125 public: tag()126 const UnicodeString& tag() const override { return tagName; } FormattableProperties(Hashtable * hash)127 FormattableProperties(Hashtable* hash) : properties(hash), tagName("properties") { 128 U_ASSERT(hash != nullptr); 129 } 130 ~FormattableProperties(); 131 LocalPointer<Hashtable> properties; 132 private: 133 const UnicodeString tagName; 134 }; 135 136 class GrammarCasesFormatterFactory : public FormatterFactory { 137 public: 138 Formatter* createFormatter(const Locale&, UErrorCode&) override; 139 }; 140 141 class GrammarCasesFormatter : public Formatter { 142 public: 143 FormattedPlaceholder format(FormattedPlaceholder&&, FunctionOptions&& opts, UErrorCode& errorCode) const override; 144 static MFFunctionRegistry customRegistry(UErrorCode&); 145 private: 146 void getDativeAndGenitive(const UnicodeString&, UnicodeString& result) const; 147 }; 148 149 class ListFormatterFactory : public FormatterFactory { 150 public: 151 Formatter* createFormatter(const Locale&, UErrorCode&) override; 152 }; 153 154 class ListFormatter : public Formatter { 155 public: 156 FormattedPlaceholder format(FormattedPlaceholder&&, FunctionOptions&& opts, UErrorCode& errorCode) const override; 157 static MFFunctionRegistry customRegistry(UErrorCode&); 158 private: 159 friend class ListFormatterFactory; 160 const Locale& locale; ListFormatter(const Locale & loc)161 ListFormatter(const Locale& loc) : locale(loc) {} 162 }; 163 164 class ResourceManagerFactory : public FormatterFactory { 165 public: 166 Formatter* createFormatter(const Locale&, UErrorCode&) override; 167 }; 168 169 class ResourceManager : public Formatter { 170 public: 171 FormattedPlaceholder format(FormattedPlaceholder&&, FunctionOptions&& opts, UErrorCode& errorCode) const override; 172 static MFFunctionRegistry customRegistry(UErrorCode&); 173 static Hashtable* properties(UErrorCode&); 174 static UnicodeString propertiesAsString(const Hashtable&); 175 static Hashtable* parseProperties(const UnicodeString&, UErrorCode&); 176 177 private: 178 friend class ResourceManagerFactory; ResourceManager(const Locale & loc)179 ResourceManager(const Locale& loc) : locale(loc) {} 180 const Locale& locale; 181 }; 182 183 } // namespace message2 184 U_NAMESPACE_END 185 186 #endif /* #if !UCONFIG_NO_MF2 */ 187 188 #endif /* #if !UCONFIG_NO_FORMATTING */ 189 190 #endif 191