]> granicus.if.org Git - icu/commitdiff
ICU-21935 Add DisplayOptions
authorYounies Mahmoud <younies@chromium.org>
Fri, 20 May 2022 23:42:34 +0000 (23:42 +0000)
committerYounies Mahmoud <younies@chromium.org>
Sat, 21 May 2022 01:20:37 +0000 (03:20 +0200)
See #2061

23 files changed:
icu4c/source/i18n/displayoptions.cpp [new file with mode: 0644]
icu4c/source/i18n/i18n.vcxproj
icu4c/source/i18n/i18n.vcxproj.filters
icu4c/source/i18n/i18n_uwp.vcxproj
icu4c/source/i18n/number_output.cpp
icu4c/source/i18n/sources.txt
icu4c/source/i18n/unicode/displayoptions.h [new file with mode: 0644]
icu4c/source/i18n/unicode/numberformatter.h
icu4c/source/i18n/unicode/udisplayoptions.h [new file with mode: 0644]
icu4c/source/i18n/unicode/unounclass.h [deleted file]
icu4c/source/test/depstest/dependencies.txt
icu4c/source/test/intltest/Makefile.in
icu4c/source/test/intltest/displayoptions_test.cpp [new file with mode: 0644]
icu4c/source/test/intltest/intltest.vcxproj
icu4c/source/test/intltest/intltest.vcxproj.filters
icu4c/source/test/intltest/itformat.cpp
icu4c/source/test/intltest/numbertest_api.cpp
icu4j/main/classes/core/src/com/ibm/icu/number/FormattedNumber.java
icu4j/main/classes/core/src/com/ibm/icu/text/DisplayOptions.java [new file with mode: 0644]
icu4j/main/classes/core/src/com/ibm/icu/util/NounClass.java [deleted file]
icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/text/DisplayOptionsTest.java [new file with mode: 0644]
icu4j/main/tests/core/src/com/ibm/icu/dev/test/util/UtilityTest.java

diff --git a/icu4c/source/i18n/displayoptions.cpp b/icu4c/source/i18n/displayoptions.cpp
new file mode 100644 (file)
index 0000000..e782ed2
--- /dev/null
@@ -0,0 +1,159 @@
+// © 2022 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "cstring.h"
+#include "unicode/displayoptions.h"
+#include "unicode/udisplayoptions.h"
+
+icu::DisplayOptions::Builder icu::DisplayOptions::builder() { return icu::DisplayOptions::Builder(); }
+
+icu::DisplayOptions::Builder icu::DisplayOptions::copyToBuilder() const { return Builder(*this); }
+
+icu::DisplayOptions::DisplayOptions(const Builder &builder) {
+    this->grammaticalCase = builder.grammaticalCase;
+    this->nounClass = builder.nounClass;
+    this->pluralCategory = builder.pluralCategory;
+    this->capitalization = builder.capitalization;
+    this->nameStyle = builder.nameStyle;
+    this->displayLength = builder.displayLength;
+    this->substituteHandling = builder.substituteHandling;
+}
+
+icu::DisplayOptions::Builder::Builder() {
+    // Sets default values.
+    this->grammaticalCase = UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_UNDEFINED;
+    this->nounClass = UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_UNDEFINED;
+    this->pluralCategory = UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_UNDEFINED;
+    this->capitalization = UDisplayOptionsCapitalization::UDISPOPT_CAPITALIZATION_UNDEFINED;
+    this->nameStyle = UDisplayOptionsNameStyle::UDISPOPT_NAME_STYLE_UNDEFINED;
+    this->displayLength = UDisplayOptionsDisplayLength::UDISPOPT_DISPLAY_LENGTH_UNDEFINED;
+    this->substituteHandling = UDisplayOptionsSubstituteHandling::UDISPOPT_SUBSTITUTE_HANDLING_UNDEFINED;
+}
+
+icu::DisplayOptions::Builder::Builder(const DisplayOptions &displayOptions) {
+    this->grammaticalCase = displayOptions.grammaticalCase;
+    this->nounClass = displayOptions.nounClass;
+    this->pluralCategory = displayOptions.pluralCategory;
+    this->capitalization = displayOptions.capitalization;
+    this->nameStyle = displayOptions.nameStyle;
+    this->displayLength = displayOptions.displayLength;
+    this->substituteHandling = displayOptions.substituteHandling;
+}
+
+namespace {
+
+const char *grammaticalCasesIds[] = {
+    "undefined",           // 0
+    "ablative",            // 1
+    "accusative",          // 2
+    "comitative",          // 3
+    "dative",              // 4
+    "ergative",            // 5
+    "genitive",            // 6
+    "instrumental",        // 7
+    "locative",            // 8
+    "locative_copulative", // 9
+    "nominative",          // 10
+    "oblique",             // 11
+    "prepositional",       // 12
+    "sociative",           // 13
+    "vocative",            // 14
+};
+
+const int32_t grammaticalCasesCount = 15;
+
+} // namespace
+
+const char *udispopt_getGrammaticalCaseIdentifier(UDisplayOptionsGrammaticalCase grammaticalCase) {
+    if (grammaticalCase >= 0 && grammaticalCase < grammaticalCasesCount) {
+        return grammaticalCasesIds[grammaticalCase];
+    }
+
+    return grammaticalCasesIds[0];
+}
+
+UDisplayOptionsGrammaticalCase udispopt_fromGrammaticalCaseIdentifier(const char *identifier) {
+    for (int32_t i = 0; i < grammaticalCasesCount; i++) {
+        if (uprv_strcmp(identifier, grammaticalCasesIds[i]) == 0) {
+            return static_cast<UDisplayOptionsGrammaticalCase>(i);
+        }
+    }
+
+    return UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_UNDEFINED;
+}
+
+namespace {
+
+const char *pluralCategoriesIds[] = {
+    "undefined", // 0
+    "zero",      // 1
+    "one",       // 2
+    "two",       // 3
+    "few",       // 4
+    "many",      // 5
+    "other",     // 6
+};
+
+} // namespace
+
+const int32_t pluralCategoriesCount = 7;
+
+const char *udispopt_getPluralCategoryIdentifier(UDisplayOptionsPluralCategory pluralCategory) {
+    if (pluralCategory >= 0 && pluralCategory < pluralCategoriesCount) {
+        return pluralCategoriesIds[pluralCategory];
+    }
+
+    return pluralCategoriesIds[0];
+}
+
+UDisplayOptionsPluralCategory udispopt_fromPluralCategoryIdentifier(const char *identifier) {
+    for (int32_t i = 0; i < pluralCategoriesCount; i++) {
+        if (uprv_strcmp(identifier, pluralCategoriesIds[i]) == 0) {
+            return static_cast<UDisplayOptionsPluralCategory>(i);
+        }
+    }
+
+    return UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_UNDEFINED;
+}
+
+namespace {
+
+const char *nounClassesIds[] = {
+    "undefined", // 0
+    "other",     // 1
+    "neuter",    // 2
+    "feminine",  // 3
+    "masculine", // 4
+    "animate",   // 5
+    "inanimate", // 6
+    "personal",  // 7
+    "common",    // 8
+};
+
+const int32_t nounClassesCount = 9;
+
+} // namespace
+
+const char *udispopt_getNounClassIdentifier(UDisplayOptionsNounClass nounClass) {
+    if (nounClass >= 0 && nounClass < nounClassesCount) {
+        return nounClassesIds[nounClass];
+    }
+
+    return nounClassesIds[0];
+}
+
+UDisplayOptionsNounClass udispopt_fromNounClassIdentifier(const char *identifier) {
+    for (int32_t i = 0; i < nounClassesCount; i++) {
+        if (uprv_strcmp(identifier, nounClassesIds[i]) == 0) {
+            return static_cast<UDisplayOptionsNounClass>(i);
+        }
+    }
+
+    return UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_UNDEFINED;
+}
+
+#endif /* #if !UCONFIG_NO_FORMATTING */
index 04b396c823d5d3bb282f34417619753e060c814c..60bbe0f89ee47a215adbd6f495dd1ea7357133d8 100644 (file)
     <ClCompile Include="units_converter.cpp" />
     <ClCompile Include="units_data.cpp" />
     <ClCompile Include="units_router.cpp" />
+    <ClCompile Include="displayoptions.cpp" />
     <ClCompile Include="unum.cpp" />
     <ClCompile Include="unumsys.cpp" />
     <ClCompile Include="upluralrules.cpp" />
index 2fc88e0606168c9e7249ce85690b4a1ad6468ed2..74fd8c486145408b8496f7ca14918cb867516653 100644 (file)
     <ClCompile Include="units_router.cpp">
       <Filter>formatting</Filter>
     </ClCompile>
+    <ClCompile Include="displayoptions.cpp">
+      <Filter>formatting</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="bocsu.cpp">
index 086d59865720919c62b2ea9fdcd15f7df3241938..7ce4ae64f9695df77917f0c525645c14b6af59ee 100644 (file)
     <ClCompile Include="units_converter.cpp" />
     <ClCompile Include="units_data.cpp" />
     <ClCompile Include="units_router.cpp" />
+    <ClCompile Include="displayoptions.cpp" />
     <ClCompile Include="unum.cpp" />
     <ClCompile Include="unumsys.cpp" />
     <ClCompile Include="upluralrules.cpp" />
index 78006da8c42f0a7cc4e73990a86c9eb480b3a27a..130435d03a2a19c6cbe12ca624cdf956e8463c19 100644 (file)
@@ -39,47 +39,10 @@ MeasureUnit FormattedNumber::getOutputUnit(UErrorCode& status) const {
     return fData->outputUnit;
 }
 
-NounClass FormattedNumber::getNounClass(UErrorCode &status) const {
-    UPRV_FORMATTED_VALUE_METHOD_GUARD(NounClass::OTHER);
+UDisplayOptionsNounClass FormattedNumber::getNounClass(UErrorCode &status) const {
+    UPRV_FORMATTED_VALUE_METHOD_GUARD(UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_UNDEFINED);
     const char *nounClass = fData->gender;
-
-    // if it is not exist, return `OTHER`
-    if (uprv_strcmp(nounClass, "") == 0) {
-        return NounClass::OTHER;
-    }
-
-    if (uprv_strcmp(nounClass, "neuter") == 0) {
-        return NounClass::NEUTER;
-    }
-
-    if (uprv_strcmp(nounClass, "feminine") == 0) {
-        return NounClass::FEMININE;
-    }
-
-    if (uprv_strcmp(nounClass, "masculine") == 0) {
-        return NounClass::MASCULINE;
-    }
-
-    if (uprv_strcmp(nounClass, "animate") == 0) {
-        return NounClass::ANIMATE;
-    }
-
-    if (uprv_strcmp(nounClass, "inanimate") == 0) {
-        return NounClass::INANIMATE;
-    }
-
-    if (uprv_strcmp(nounClass, "personal") == 0) {
-        return NounClass::PERSONAL;
-    }
-
-    if (uprv_strcmp(nounClass, "common") == 0) {
-        return NounClass::COMMON;
-    }
-
-    // In case there is no matching, this means there are noun classes
-    // that are not supported yet.
-    status = U_INTERNAL_PROGRAM_ERROR;
-    return NounClass::OTHER;
+    return udispopt_fromNounClassIdentifier(nounClass);
 }
 
 const char *FormattedNumber::getGender(UErrorCode &status) const {
index b28f34c86fb931b5199c274a3470820abd9db281..b882b0464a9f80a7d280652128cf6586b489e853 100644 (file)
@@ -53,6 +53,7 @@ dcfmtsym.cpp
 decContext.cpp
 decNumber.cpp
 decimfmt.cpp
+displayoptions.cpp
 double-conversion-bignum-dtoa.cpp
 double-conversion-bignum.cpp
 double-conversion-cached-powers.cpp
diff --git a/icu4c/source/i18n/unicode/displayoptions.h b/icu4c/source/i18n/unicode/displayoptions.h
new file mode 100644 (file)
index 0000000..a9402bf
--- /dev/null
@@ -0,0 +1,257 @@
+// © 2022 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+#ifndef __DISPLAYOPTIONS_H__
+#define __DISPLAYOPTIONS_H__
+
+#include "unicode/udisplayoptions.h"
+#include "unicode/utypes.h"
+
+#if U_SHOW_CPLUSPLUS_API
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "unicode/uversion.h"
+
+U_NAMESPACE_BEGIN
+
+#ifndef U_HIDE_DRAFT_API
+
+/**
+ * Represents all the display options that are supported by CLDR such as grammatical case, noun
+ * class, ... etc. It currently supports enums, but may be extended in the future to have other
+ * types of data. It replaces a DisplayContext[] as a method parameter.
+ *
+ * NOTE: this class is Immutable, and uses a Builder interface.
+ *
+ * For example:
+ * ```
+ * DisplayOptions x =
+ *                    DisplayOptions::builder().
+ *                             .setGrammaticalCase(UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_DATIVE)
+ *                             .setPluralCategory(UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_FEW)
+ *                             .build();
+ *```
+ *
+ * @draft ICU 72
+ */
+class U_I18N_API DisplayOptions {
+  public:
+    /**
+     * Responsible for building `DisplayOptions`.
+     *
+     * @draft ICU 72
+     */
+    class U_I18N_API Builder {
+      public:
+        /**
+         * Sets the grammatical case.
+         *
+         * @return Builder
+         * @draft ICU 72
+         */
+        Builder &setGrammaticalCase(UDisplayOptionsGrammaticalCase grammaticalCase) {
+            this->grammaticalCase = grammaticalCase;
+            return *this;
+        }
+
+        /**
+         * Sets the noun class.
+         *
+         * @return Builder
+         * @draft ICU 72
+         */
+        Builder &setNounClass(UDisplayOptionsNounClass nounClass) {
+            this->nounClass = nounClass;
+            return *this;
+        }
+
+        /**
+         * Sets the plural category.
+         *
+         * @return Builder
+         * @draft ICU 72
+         */
+        Builder &setPluralCategory(UDisplayOptionsPluralCategory pluralCategory) {
+            this->pluralCategory = pluralCategory;
+            return *this;
+        }
+
+        /**
+         * Sets the capitalization.
+         *
+         * @return Builder
+         * @draft ICU 72
+         */
+        Builder &setCapitalization(UDisplayOptionsCapitalization capitalization) {
+            this->capitalization = capitalization;
+            return *this;
+        }
+
+        /**
+         * Sets the dialect handling.
+         *
+         * @return Builder
+         * @draft ICU 72
+         */
+        Builder &setNameStyle(UDisplayOptionsNameStyle nameStyle) {
+            this->nameStyle = nameStyle;
+            return *this;
+        }
+
+        /**
+         * Sets the display length.
+         *
+         * @return Builder
+         * @draft ICU 72
+         */
+        Builder &setDisplayLength(UDisplayOptionsDisplayLength displayLength) {
+            this->displayLength = displayLength;
+            return *this;
+        }
+
+        /**
+         * Sets the substitute handling.
+         *
+         * @return Builder
+         * @draft ICU 72
+         */
+        Builder &setSubstituteHandling(UDisplayOptionsSubstituteHandling substituteHandling) {
+            this->substituteHandling = substituteHandling;
+            return *this;
+        }
+
+        /**
+         * Builds the display options.
+         *
+         * @return DisplayOptions
+         * @draft ICU 72
+         */
+        DisplayOptions build() { return DisplayOptions(*this); }
+
+      private:
+        friend DisplayOptions;
+
+        Builder();
+        Builder(const DisplayOptions &displayOptions);
+
+        UDisplayOptionsGrammaticalCase grammaticalCase;
+        UDisplayOptionsNounClass nounClass;
+        UDisplayOptionsPluralCategory pluralCategory;
+        UDisplayOptionsCapitalization capitalization;
+        UDisplayOptionsNameStyle nameStyle;
+        UDisplayOptionsDisplayLength displayLength;
+        UDisplayOptionsSubstituteHandling substituteHandling;
+    };
+
+    /**
+     * Creates a builder with the `UNDEFINED` values for all the parameters.
+     *
+     * @return Builder
+     * @draft ICU 72
+     */
+    static Builder builder();
+    /**
+     * Creates a builder with the same parameters from this object.
+     *
+     * @return Builder
+     * @draft ICU 72
+     */
+    Builder copyToBuilder() const;
+    /**
+     * Gets the grammatical case.
+     *
+     * @return UDisplayOptionsGrammaticalCase
+     * @draft ICU 72
+     */
+    UDisplayOptionsGrammaticalCase getGrammaticalCase() const { return this->grammaticalCase; }
+
+    /**
+     * Gets the noun class.
+     *
+     * @return UDisplayOptionsNounClass
+     * @draft ICU 72
+     */
+    UDisplayOptionsNounClass getNounClass() const { return this->nounClass; }
+
+    /**
+     * Gets the plural category.
+     *
+     * @return UDisplayOptionsPluralCategory
+     * @draft ICU 72
+     */
+    UDisplayOptionsPluralCategory getPluralCategory() const { return this->pluralCategory; }
+
+    /**
+     * Gets the capitalization.
+     *
+     * @return UDisplayOptionsCapitalization
+     * @draft ICU 72
+     */
+    UDisplayOptionsCapitalization getCapitalization() const { return this->capitalization; }
+
+    /**
+     * Gets the dialect handling.
+     *
+     * @return UDisplayOptionsNameStyle
+     * @draft ICU 72
+     */
+    UDisplayOptionsNameStyle getNameStyle() const { return this->nameStyle; }
+
+    /**
+     * Gets the display length.
+     *
+     * @return UDisplayOptionsDisplayLength
+     * @draft ICU 72
+     */
+    UDisplayOptionsDisplayLength getDisplayLength() const { return this->displayLength; }
+
+    /**
+     * Gets the substitute handling.
+     *
+     * @return UDisplayOptionsSubstituteHandling
+     * @draft ICU 72
+     */
+    UDisplayOptionsSubstituteHandling getSubstituteHandling() const { return this->substituteHandling; }
+
+    /**
+     * Copy the DisplayOptions.
+     *
+     * @draft ICU 72
+     */
+    DisplayOptions &operator=(const DisplayOptions &other) = default;
+
+    /**
+     * Moves the DisplayOptions.
+     *
+     * @draft ICU 72
+     */
+    DisplayOptions &operator=(DisplayOptions &&other) noexcept = default;
+
+    /**
+     * Copy the DisplayOptions.
+     *
+     * @draft ICU 72
+     */
+    DisplayOptions(const DisplayOptions &) = default;
+
+  private:
+    DisplayOptions(const Builder &builder);
+    UDisplayOptionsGrammaticalCase grammaticalCase;
+    UDisplayOptionsNounClass nounClass;
+    UDisplayOptionsPluralCategory pluralCategory;
+    UDisplayOptionsCapitalization capitalization;
+    UDisplayOptionsNameStyle nameStyle;
+    UDisplayOptionsDisplayLength displayLength;
+    UDisplayOptionsSubstituteHandling substituteHandling;
+};
+
+#endif // U_HIDE_DRAFT_API
+
+U_NAMESPACE_END
+
+#endif /* #if !UCONFIG_NO_FORMATTING */
+
+#endif /* U_SHOW_CPLUSPLUS_API */
+
+#endif // __DISPLAYOPTIONS_H__
\ No newline at end of file
index 711064ece8dbb3329892ffebde2a48dbc87e417c..2a19de10a1e887298f3fcedf8223b9f33a895996 100644 (file)
@@ -22,7 +22,7 @@
 #include "unicode/parseerr.h"
 #include "unicode/plurrule.h"
 #include "unicode/ucurr.h"
-#include "unicode/unounclass.h"
+#include "unicode/udisplayoptions.h"
 #include "unicode/unum.h"
 #include "unicode/unumberformatter.h"
 #include "unicode/uobject.h"
@@ -2771,13 +2771,13 @@ class U_I18N_API FormattedNumber : public UMemory, public FormattedValue {
 #ifndef U_HIDE_DRAFT_API
 
     /**
-     * Gets the noun class of the formatted output. Returns `OTHER` when the noun class
+     * Gets the noun class of the formatted output. Returns `UNDEFINED` when the noun class
      * is not supported yet.
      *
      * @return `NounClass`
      * @draft ICU 71.
      */
-    NounClass getNounClass(UErrorCode &status) const;
+    UDisplayOptionsNounClass getNounClass(UErrorCode &status) const;
 
 #endif // U_HIDE_DRAFT_API
 
diff --git a/icu4c/source/i18n/unicode/udisplayoptions.h b/icu4c/source/i18n/unicode/udisplayoptions.h
new file mode 100644 (file)
index 0000000..527dd71
--- /dev/null
@@ -0,0 +1,316 @@
+// © 2022 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+#ifndef __UDISPLAYOPTIONS_H__
+#define __UDISPLAYOPTIONS_H__
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "unicode/uversion.h"
+
+#ifndef U_HIDE_DRAFT_API
+
+/**
+ * Represents all the grammatical cases that are supported by CLDR.
+ *
+ *
+ * @draft ICU 72
+ */
+typedef enum UDisplayOptionsGrammaticalCase {
+    /**
+     * A possible setting for GrammaticalCase.
+     * The grammatical case context to be used is unknown (this is the default value).
+     * @draft ICU 72
+     */
+    UDISPOPT_GRAMMATICAL_CASE_UNDEFINED = 0,
+    /** @draft ICU 72 */
+    UDISPOPT_GRAMMATICAL_CASE_ABLATIVE = 1,
+    /** @draft ICU 72 */
+    UDISPOPT_GRAMMATICAL_CASE_ACCUSATIVE = 2,
+    /** @draft ICU 72 */
+    UDISPOPT_GRAMMATICAL_CASE_COMITATIVE = 3,
+    /** @draft ICU 72 */
+    UDISPOPT_GRAMMATICAL_CASE_DATIVE = 4,
+    /** @draft ICU 72 */
+    UDISPOPT_GRAMMATICAL_CASE_ERGATIVE = 5,
+    /** @draft ICU 72 */
+    UDISPOPT_GRAMMATICAL_CASE_GENITIVE = 6,
+    /** @draft ICU 72 */
+    UDISPOPT_GRAMMATICAL_CASE_INSTRUMENTAL = 7,
+    /** @draft ICU 72 */
+    UDISPOPT_GRAMMATICAL_CASE_LOCATIVE = 8,
+    /** @draft ICU 72 */
+    UDISPOPT_GRAMMATICAL_CASE_LOCATIVE_COPULATIVE = 9,
+    /** @draft ICU 72 */
+    UDISPOPT_GRAMMATICAL_CASE_NOMINATIVE = 10,
+    /** @draft ICU 72 */
+    UDISPOPT_GRAMMATICAL_CASE_OBLIQUE = 11,
+    /** @draft ICU 72 */
+    UDISPOPT_GRAMMATICAL_CASE_PREPOSITIONAL = 12,
+    /** @draft ICU 72 */
+    UDISPOPT_GRAMMATICAL_CASE_SOCIATIVE = 13,
+    /** @draft ICU 72 */
+    UDISPOPT_GRAMMATICAL_CASE_VOCATIVE = 14,
+} UDisplayOptionsGrammaticalCase;
+
+/**
+ * @return the lowercase CLDR keyword string for the grammatical case.
+ *
+ * @draft ICU 72
+ */
+U_CAPI const char * U_EXPORT2
+udispopt_getGrammaticalCaseIdentifier(UDisplayOptionsGrammaticalCase grammaticalCase);
+
+/**
+ *
+ * @param identifier in lower case such as "dative" or "nominative"
+ * @return the plural category corresponding to the identifier, or `UDISPOPT_GRAMMATICAL_CASE_UNDEFINED`
+ *
+ * @draft ICU 72
+ */
+U_CAPI UDisplayOptionsGrammaticalCase U_EXPORT2
+udispopt_fromGrammaticalCaseIdentifier(const char *identifier);
+
+/**
+ * Standard CLDR plural form/category constants.
+ * See http://www.unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules
+ *
+ * @draft ICU 72
+ */
+typedef enum UDisplayOptionsPluralCategory {
+
+    /**
+     * A possible setting for PluralCategory.
+     * The plural category case context to be used is unknown (this is the default value).
+     *
+     * @draft ICU 72
+     */
+    UDISPOPT_PLURAL_CATEGORY_UNDEFINED = 0,
+    /** @draft ICU 72 */
+    UDISPOPT_PLURAL_CATEGORY_ZERO = 1,
+    /** @draft ICU 72 */
+    UDISPOPT_PLURAL_CATEGORY_ONE = 2,
+    /** @draft ICU 72 */
+    UDISPOPT_PLURAL_CATEGORY_TWO = 3,
+    /** @draft ICU 72 */
+    UDISPOPT_PLURAL_CATEGORY_FEW = 4,
+    /** @draft ICU 72 */
+    UDISPOPT_PLURAL_CATEGORY_MANY = 5,
+    /** @draft ICU 72 */
+    UDISPOPT_PLURAL_CATEGORY_OTHER = 6,
+} UDisplayOptionsPluralCategory;
+
+/**
+ * @return the lowercase CLDR identifier string for the plural category.
+ *
+ * @draft ICU 72
+ */
+U_CAPI const char * U_EXPORT2
+udispopt_getPluralCategoryIdentifier(UDisplayOptionsPluralCategory pluralCategory);
+
+/**
+ * @param keyword for example "few" or "other"
+ * @return the plural category corresponding to the keyword, or `UDISPOPT_PLURAL_CATEGORY_UNDEFINED`
+ *
+ * @draft ICU 72
+ */
+U_CAPI UDisplayOptionsPluralCategory U_EXPORT2
+udispopt_fromPluralCategoryIdentifier(const char *identifier);
+
+/**
+ * Represents all the grammatical noun classes that are supported by CLDR.
+ *
+ * @draft ICU 71.
+ */
+typedef enum UDisplayOptionsNounClass {
+    /**
+     * A possible setting for NounClass.
+     * The noun class case context to be used is unknown (this is the default value).
+     *
+     * @draft ICU 72
+     */
+    UDISPOPT_NOUN_CLASS_UNDEFINED = 0,
+    /** ICU 72 */
+    UDISPOPT_NOUN_CLASS_OTHER = 1,
+    /** ICU 72 */
+    UDISPOPT_NOUN_CLASS_NEUTER = 2,
+    /** ICU 72 */
+    UDISPOPT_NOUN_CLASS_FEMININE = 3,
+    /** ICU 72 */
+    UDISPOPT_NOUN_CLASS_MASCULINE = 4,
+    /** ICU 72 */
+    UDISPOPT_NOUN_CLASS_ANIMATE = 5,
+    /** ICU 72 */
+    UDISPOPT_NOUN_CLASS_INANIMATE = 6,
+    /** ICU 72 */
+    UDISPOPT_NOUN_CLASS_PERSONAL = 7,
+    /** ICU 72 */
+    UDISPOPT_NOUN_CLASS_COMMON = 8,
+} UDisplayOptionsNounClass;
+
+/**
+ * @return the lowercase CLDR keyword string for the noun class.
+ *
+ * @draft ICU 72
+ */
+U_CAPI const char * U_EXPORT2
+udispopt_getNounClassIdentifier(UDisplayOptionsNounClass nounClass);
+
+/**
+ *
+ * @param identifier in lower case such as "feminine" or "masculine"
+ * @return the plural category corresponding to the identifier, or `UDISPOPT_NOUN_CLASS_UNDEFINED`
+ *
+ * @draft ICU 72
+ */
+U_CAPI UDisplayOptionsNounClass U_EXPORT2
+udispopt_fromNounClassIdentifier(const char *identifier);
+
+/**
+ * Represents all the capitalization options.
+ *
+ * @draft ICU 72
+ */
+typedef enum UDisplayOptionsCapitalization {
+    /**
+     * A possible setting for Capitalization.
+     * The capitalization context to be used is unknown (this is the default value).
+     *
+     * @draft ICU 72
+     */
+    UDISPOPT_CAPITALIZATION_UNDEFINED = 0,
+
+    /**
+     * The capitalization context if a date, date symbol or display name is to be
+     * formatted with capitalization appropriate for the beginning of a sentence.
+     *
+     * @draft ICU 72
+     */
+    UDISPOPT_CAPITALIZATION_BEGINNING_OF_SENTENCE = 1,
+
+    /**
+     * The capitalization context if a date, date symbol or display name is to be
+     * formatted with capitalization appropriate for the middle of a sentence.
+     *
+     * @draft ICU 72
+     */
+    UDISPOPT_CAPITALIZATION_MIDDLE_OF_SENTENCE = 2,
+
+    /**
+     * The capitalization context if a date, date symbol or display name is to be
+     * formatted with capitalization appropriate for stand-alone usage such as an
+     * isolated name on a calendar page.
+     *
+     * @draft ICU 72
+     */
+    UDISPOPT_CAPITALIZATION_STANDALONE = 3,
+
+    /**
+     * The capitalization context if a date, date symbol or display name is to be
+     * formatted with capitalization appropriate for a user-interface list or menu item.
+     *
+     * @draft ICU 72
+     */
+    UDISPOPT_CAPITALIZATION_UI_LIST_OR_MENU = 4,
+} UDisplayOptionsCapitalization;
+
+/**
+ * Represents all the dialect handlings.
+ *
+ * @draft ICU 72
+ */
+typedef enum UDisplayOptionsNameStyle {
+    /**
+     * A possible setting for NameStyle.
+     * The NameStyle context to be used is unknown (this is the default value).
+     *
+     * @draft ICU 72
+     */
+    UDISPOPT_NAME_STYLE_UNDEFINED = 0,
+
+    /**
+     * Use standard names when generating a locale name,
+     * e.g. en_GB displays as 'English (United Kingdom)'.
+     *
+     * @draft ICU 72
+     */
+    UDISPOPT_NAME_STYLE_STANDARD_NAMES = 1,
+
+    /**
+     * Use dialect names, when generating a locale name,
+     * e.g. en_GB displays as 'British English'.
+     *
+     * @draft ICU 72
+     */
+    UDISPOPT_NAME_STYLE_DIALECT_NAMES = 2,
+} UDisplayOptionsNameStyle;
+
+/**
+ * Represents all the display lengths.
+ *
+ * @draft ICU 72
+ */
+typedef enum UDisplayOptionsDisplayLength {
+    /**
+     * A possible setting for DisplayLength.
+     * The DisplayLength context to be used is unknown (this is the default value).
+     *
+     * @draft ICU 72
+     */
+    UDISPOPT_DISPLAY_LENGTH_UNDEFINED = 0,
+
+    /**
+     * Uses full names when generating a locale name,
+     * e.g. "United States" for US.
+     *
+     * @draft ICU 72
+     */
+    UDISPOPT_DISPLAY_LENGTH_FULL = 1,
+
+    /**
+     * Use short names when generating a locale name,
+     * e.g. "U.S." for US.
+     *
+     * @draft ICU 72
+     */
+    UDISPOPT_DISPLAY_LENGTH_SHORT = 2,
+} UDisplayOptionsDisplayLength;
+
+/**
+ * Represents all the substitute handling.
+ *
+ * @draft ICU 72
+ */
+typedef enum UDisplayOptionsSubstituteHandling {
+
+    /**
+     * A possible setting for SubstituteHandling.
+     * The SubstituteHandling context to be used is unknown (this is the default value).
+     *
+     * @draft ICU 72
+     */
+    UDISPOPT_SUBSTITUTE_HANDLING_UNDEFINED = 0,
+
+    /**
+     * Returns a fallback value (e.g., the input code) when no data is available.
+     * This is the default behaviour.
+     *
+     * @draft ICU 72
+     */
+    UDISPOPT_SUBSTITUTE_HANDLING_SUBSTITUTE = 1,
+
+    /**
+     * Returns a null value when no data is available.
+     *
+     * @draft ICU 72
+     */
+    UDISPOPT_SUBSTITUTE_HANDLING_NO_SUBSTITUTE = 2,
+} UDisplayOptionsSubstituteHandling;
+
+#endif // U_HIDE_DRAFT_API
+
+#endif /* #if !UCONFIG_NO_FORMATTING */
+
+#endif // __UDISPLAYOPTIONS_H__
\ No newline at end of file
diff --git a/icu4c/source/i18n/unicode/unounclass.h b/icu4c/source/i18n/unicode/unounclass.h
deleted file mode 100644 (file)
index 1721dbd..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-// © 2022 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-
-#ifndef __UNOUNCLASS_H__
-#define __UNOUNCLASS_H__
-
-#include "unicode/utypes.h"
-
-#if U_SHOW_CPLUSPLUS_API
-
-#if !UCONFIG_NO_FORMATTING
-
-#include "unicode/uversion.h"
-
-U_NAMESPACE_BEGIN
-
-#ifndef U_HIDE_DRAFT_API
-
-/**
- * Represents all the grammatical noun classes that are supported by CLDR.
- *
- * @draft ICU 71.
- */
-enum NounClass {
-    OTHER = 0,
-    NEUTER = 1,
-    FEMININE = 2,
-    MASCULINE = 3,
-    ANIMATE = 4,
-    INANIMATE = 5,
-    PERSONAL = 6,
-    COMMON = 7,
-};
-
-#endif // U_HIDE_DRAFT_API
-
-U_NAMESPACE_END
-
-#endif /* #if !UCONFIG_NO_FORMATTING */
-
-#endif /* U_SHOW_CPLUSPLUS_API */
-
-#endif // __UNOUNCLASS_H__
index 4653afc1c3f34c166baa3f7e208c8663c68cfad8..d0cb8a80a2299bbb565d0dd4ad166794d4bcd96b 100644 (file)
@@ -885,6 +885,7 @@ library: i18n
     units_extra unitsformatter
     universal_time_scale
     uclean_i18n
+    display_options
 
 group: region
     region.o uregion.o
@@ -991,6 +992,7 @@ group: number_output
     number_representation format formatted_value_sbimpl units
     # PluralRules internals:
     unifiedcache
+    display_options
 
 group: numberformatter
     # ICU 60+ NumberFormatter API
@@ -1191,6 +1193,11 @@ group: uclean_i18n
   deps
     platform
 
+group: display_options
+    displayoptions.o
+  deps
+    platform
+
 # ICU io library ------------------------------------------------------------- #
 
 library: io
index 4bb615f1b6e3485eb1ab782ff5f14a6e90c54fd7..c4b5f6097bf446ed7f5444fa6f92311276483ab6 100644 (file)
@@ -69,7 +69,7 @@ string_segment_test.o \
 numbertest_parse.o numbertest_doubleconversion.o numbertest_skeletons.o \
 static_unisets_test.o numfmtdatadriventest.o numbertest_range.o erarulestest.o \
 formattedvaluetest.o formatted_string_builder_test.o numbertest_permutation.o \
-units_data_test.o units_router_test.o units_test.o
+units_data_test.o units_router_test.o units_test.o displayoptions_test.o
 
 DEPS = $(OBJECTS:.o=.d)
 
diff --git a/icu4c/source/test/intltest/displayoptions_test.cpp b/icu4c/source/test/intltest/displayoptions_test.cpp
new file mode 100644 (file)
index 0000000..9036d8b
--- /dev/null
@@ -0,0 +1,370 @@
+// © 2022 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "intltest.h"
+#include "unicode/displayoptions.h"
+#include "unicode/udisplayoptions.h"
+
+class DisplayOptionsTest : public IntlTest {
+  public:
+    void testDisplayOptionsDefault();
+    void testDisplayOptionsEachElement();
+    void testDisplayOptionsUpdating();
+    void testDisplayOptionsGetIdentifier();
+    void testDisplayOptionsFromIdentifier();
+
+    void runIndexedTest(int32_t index, UBool exec, const char *&name, char *par = 0) override;
+};
+
+void DisplayOptionsTest::runIndexedTest(int32_t index, UBool exec, const char *&name, char *) {
+    if (exec) {
+        logln(u"TestSuite DisplayOptionsTest: ");
+    }
+    TESTCASE_AUTO_BEGIN;
+    TESTCASE_AUTO(testDisplayOptionsDefault);
+    TESTCASE_AUTO(testDisplayOptionsEachElement);
+    TESTCASE_AUTO(testDisplayOptionsUpdating);
+    TESTCASE_AUTO(testDisplayOptionsGetIdentifier);
+    TESTCASE_AUTO(testDisplayOptionsFromIdentifier);
+    TESTCASE_AUTO_END;
+}
+
+void DisplayOptionsTest::testDisplayOptionsDefault() {
+    icu::DisplayOptions displayOptions = icu::DisplayOptions::builder().build();
+    assertEquals(u"Test setting parameters", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_UNDEFINED,
+                 displayOptions.getGrammaticalCase());
+    assertEquals(u"Test default values: ", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_UNDEFINED,
+                 displayOptions.getNounClass());
+    assertEquals(u"Test default values: ", UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_UNDEFINED,
+                 displayOptions.getPluralCategory());
+    assertEquals(u"Test default values: ", UDisplayOptionsCapitalization::UDISPOPT_CAPITALIZATION_UNDEFINED,
+                 displayOptions.getCapitalization());
+    assertEquals(u"Test default values: ", UDisplayOptionsNameStyle::UDISPOPT_NAME_STYLE_UNDEFINED,
+                 displayOptions.getNameStyle());
+    assertEquals(u"Test default values: ", UDisplayOptionsDisplayLength::UDISPOPT_DISPLAY_LENGTH_UNDEFINED,
+                 displayOptions.getDisplayLength());
+    assertEquals(u"Test default values: ", UDisplayOptionsSubstituteHandling::UDISPOPT_SUBSTITUTE_HANDLING_UNDEFINED,
+                 displayOptions.getSubstituteHandling());
+}
+
+void DisplayOptionsTest::testDisplayOptionsEachElement() {
+    icu::DisplayOptions displayOptions =
+        icu::DisplayOptions::builder()
+            .setGrammaticalCase(UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_ABLATIVE)
+            .build();
+    assertEquals(u"Test setting parameters: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_ABLATIVE,
+                 displayOptions.getGrammaticalCase());
+
+    displayOptions =
+        icu::DisplayOptions::builder().setNounClass(UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_PERSONAL).build();
+    assertEquals(u"Test setting parameters: ", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_PERSONAL,
+                 displayOptions.getNounClass());
+
+    displayOptions =
+        icu::DisplayOptions::builder().setPluralCategory(UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_FEW).build();
+    assertEquals(u"Test setting parameters: ", UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_FEW,
+                 displayOptions.getPluralCategory());
+
+    displayOptions = icu::DisplayOptions::builder()
+                         .setCapitalization(UDisplayOptionsCapitalization::UDISPOPT_CAPITALIZATION_BEGINNING_OF_SENTENCE)
+                         .build();
+    assertEquals(u"Test setting parameters: ", UDisplayOptionsCapitalization::UDISPOPT_CAPITALIZATION_BEGINNING_OF_SENTENCE,
+                 displayOptions.getCapitalization());
+
+    displayOptions = icu::DisplayOptions::builder()
+                         .setNameStyle(UDisplayOptionsNameStyle::UDISPOPT_NAME_STYLE_STANDARD_NAMES)
+                         .build();
+    assertEquals(u"Test setting parameters: ", UDisplayOptionsNameStyle::UDISPOPT_NAME_STYLE_STANDARD_NAMES,
+                 displayOptions.getNameStyle());
+
+    displayOptions = icu::DisplayOptions::builder()
+                         .setDisplayLength(UDisplayOptionsDisplayLength::UDISPOPT_DISPLAY_LENGTH_FULL)
+                         .build();
+    assertEquals(u"Test setting parameters: ", UDisplayOptionsDisplayLength::UDISPOPT_DISPLAY_LENGTH_FULL,
+                 displayOptions.getDisplayLength());
+
+    displayOptions = icu::DisplayOptions::builder()
+                         .setSubstituteHandling(UDisplayOptionsSubstituteHandling::UDISPOPT_SUBSTITUTE_HANDLING_NO_SUBSTITUTE)
+                         .build();
+    assertEquals(u"Test setting parameters: ", UDisplayOptionsSubstituteHandling::UDISPOPT_SUBSTITUTE_HANDLING_NO_SUBSTITUTE,
+                 displayOptions.getSubstituteHandling());
+}
+
+void DisplayOptionsTest::testDisplayOptionsUpdating() {
+    DisplayOptions displayOptions = DisplayOptions::builder()
+                                        .setGrammaticalCase(UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_ABLATIVE)
+                                        .build();
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_ABLATIVE,
+                 displayOptions.getGrammaticalCase());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_UNDEFINED,
+                 displayOptions.getNounClass());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_UNDEFINED,
+                 displayOptions.getPluralCategory());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsCapitalization::UDISPOPT_CAPITALIZATION_UNDEFINED,
+                 displayOptions.getCapitalization());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsNameStyle::UDISPOPT_NAME_STYLE_UNDEFINED,
+                 displayOptions.getNameStyle());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsDisplayLength::UDISPOPT_DISPLAY_LENGTH_UNDEFINED,
+                 displayOptions.getDisplayLength());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsSubstituteHandling::UDISPOPT_SUBSTITUTE_HANDLING_UNDEFINED,
+                 displayOptions.getSubstituteHandling());
+
+    displayOptions =
+        displayOptions.copyToBuilder().setNounClass(UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_PERSONAL).build();
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_ABLATIVE,
+                 displayOptions.getGrammaticalCase());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_PERSONAL,
+                 displayOptions.getNounClass());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_UNDEFINED,
+                 displayOptions.getPluralCategory());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsCapitalization::UDISPOPT_CAPITALIZATION_UNDEFINED,
+                 displayOptions.getCapitalization());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsNameStyle::UDISPOPT_NAME_STYLE_UNDEFINED,
+                 displayOptions.getNameStyle());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsDisplayLength::UDISPOPT_DISPLAY_LENGTH_UNDEFINED,
+                 displayOptions.getDisplayLength());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsSubstituteHandling::UDISPOPT_SUBSTITUTE_HANDLING_UNDEFINED,
+                 displayOptions.getSubstituteHandling());
+
+    displayOptions =
+        displayOptions.copyToBuilder().setPluralCategory(UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_FEW).build();
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_ABLATIVE,
+                 displayOptions.getGrammaticalCase());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_PERSONAL,
+                 displayOptions.getNounClass());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_FEW,
+                 displayOptions.getPluralCategory());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsCapitalization::UDISPOPT_CAPITALIZATION_UNDEFINED,
+                 displayOptions.getCapitalization());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsNameStyle::UDISPOPT_NAME_STYLE_UNDEFINED,
+                 displayOptions.getNameStyle());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsDisplayLength::UDISPOPT_DISPLAY_LENGTH_UNDEFINED,
+                 displayOptions.getDisplayLength());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsSubstituteHandling::UDISPOPT_SUBSTITUTE_HANDLING_UNDEFINED,
+                 displayOptions.getSubstituteHandling());
+
+    displayOptions = displayOptions.copyToBuilder()
+                         .setCapitalization(UDisplayOptionsCapitalization::UDISPOPT_CAPITALIZATION_BEGINNING_OF_SENTENCE)
+                         .build();
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_ABLATIVE,
+                 displayOptions.getGrammaticalCase());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_PERSONAL,
+                 displayOptions.getNounClass());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_FEW,
+                 displayOptions.getPluralCategory());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsCapitalization::UDISPOPT_CAPITALIZATION_BEGINNING_OF_SENTENCE,
+                 displayOptions.getCapitalization());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsNameStyle::UDISPOPT_NAME_STYLE_UNDEFINED,
+                 displayOptions.getNameStyle());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsDisplayLength::UDISPOPT_DISPLAY_LENGTH_UNDEFINED,
+                 displayOptions.getDisplayLength());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsSubstituteHandling::UDISPOPT_SUBSTITUTE_HANDLING_UNDEFINED,
+                 displayOptions.getSubstituteHandling());
+
+    displayOptions = displayOptions.copyToBuilder()
+                         .setNameStyle(UDisplayOptionsNameStyle::UDISPOPT_NAME_STYLE_STANDARD_NAMES)
+                         .build();
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_ABLATIVE,
+                 displayOptions.getGrammaticalCase());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_PERSONAL,
+                 displayOptions.getNounClass());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_FEW,
+                 displayOptions.getPluralCategory());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsCapitalization::UDISPOPT_CAPITALIZATION_BEGINNING_OF_SENTENCE,
+                 displayOptions.getCapitalization());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsNameStyle::UDISPOPT_NAME_STYLE_STANDARD_NAMES,
+                 displayOptions.getNameStyle());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsDisplayLength::UDISPOPT_DISPLAY_LENGTH_UNDEFINED,
+                 displayOptions.getDisplayLength());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsSubstituteHandling::UDISPOPT_SUBSTITUTE_HANDLING_UNDEFINED,
+                 displayOptions.getSubstituteHandling());
+
+    displayOptions = displayOptions.copyToBuilder()
+                         .setDisplayLength(UDisplayOptionsDisplayLength::UDISPOPT_DISPLAY_LENGTH_FULL)
+                         .build();
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_ABLATIVE,
+                 displayOptions.getGrammaticalCase());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_PERSONAL,
+                 displayOptions.getNounClass());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_FEW,
+                 displayOptions.getPluralCategory());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsCapitalization::UDISPOPT_CAPITALIZATION_BEGINNING_OF_SENTENCE,
+                 displayOptions.getCapitalization());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsNameStyle::UDISPOPT_NAME_STYLE_STANDARD_NAMES,
+                 displayOptions.getNameStyle());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsDisplayLength::UDISPOPT_DISPLAY_LENGTH_FULL,
+                 displayOptions.getDisplayLength());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsSubstituteHandling::UDISPOPT_SUBSTITUTE_HANDLING_UNDEFINED,
+                 displayOptions.getSubstituteHandling());
+
+    displayOptions = displayOptions.copyToBuilder()
+                         .setSubstituteHandling(UDisplayOptionsSubstituteHandling::UDISPOPT_SUBSTITUTE_HANDLING_NO_SUBSTITUTE)
+                         .build();
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_ABLATIVE,
+                 displayOptions.getGrammaticalCase());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_PERSONAL,
+                 displayOptions.getNounClass());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_FEW,
+                 displayOptions.getPluralCategory());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsCapitalization::UDISPOPT_CAPITALIZATION_BEGINNING_OF_SENTENCE,
+                 displayOptions.getCapitalization());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsNameStyle::UDISPOPT_NAME_STYLE_STANDARD_NAMES,
+                 displayOptions.getNameStyle());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsDisplayLength::UDISPOPT_DISPLAY_LENGTH_FULL,
+                 displayOptions.getDisplayLength());
+    assertEquals(u"Test updating parameters: ", UDisplayOptionsSubstituteHandling::UDISPOPT_SUBSTITUTE_HANDLING_NO_SUBSTITUTE,
+                 displayOptions.getSubstituteHandling());
+}
+
+void DisplayOptionsTest::testDisplayOptionsGetIdentifier() {
+
+    assertEquals(u"test get identifier: ", "undefined",
+                 udispopt_getGrammaticalCaseIdentifier(UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_UNDEFINED));
+    assertEquals(u"test get identifier: ", "ablative",
+                 udispopt_getGrammaticalCaseIdentifier(UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_ABLATIVE));
+    assertEquals(u"test get identifier: ", "accusative",
+                 udispopt_getGrammaticalCaseIdentifier(UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_ACCUSATIVE));
+    assertEquals(u"test get identifier: ", "comitative",
+                 udispopt_getGrammaticalCaseIdentifier(UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_COMITATIVE));
+    assertEquals(u"test get identifier: ", "dative",
+                 udispopt_getGrammaticalCaseIdentifier(UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_DATIVE));
+    assertEquals(u"test get identifier: ", "ergative",
+                 udispopt_getGrammaticalCaseIdentifier(UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_ERGATIVE));
+    assertEquals(u"test get identifier: ", "genitive",
+                 udispopt_getGrammaticalCaseIdentifier(UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_GENITIVE));
+    assertEquals(
+        u"test get identifier: ", "instrumental",
+        udispopt_getGrammaticalCaseIdentifier(UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_INSTRUMENTAL));
+    assertEquals(u"test get identifier: ", "locative",
+                 udispopt_getGrammaticalCaseIdentifier(UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_LOCATIVE));
+    assertEquals(
+        u"test get identifier: ", "locative_copulative",
+        udispopt_getGrammaticalCaseIdentifier(UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_LOCATIVE_COPULATIVE));
+    assertEquals(u"test get identifier: ", "nominative",
+                 udispopt_getGrammaticalCaseIdentifier(UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_NOMINATIVE));
+    assertEquals(u"test get identifier: ", "oblique",
+                 udispopt_getGrammaticalCaseIdentifier(UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_OBLIQUE));
+    assertEquals(
+        u"test get identifier: ", "prepositional",
+        udispopt_getGrammaticalCaseIdentifier(UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_PREPOSITIONAL));
+    assertEquals(u"test get identifier: ", "sociative",
+                 udispopt_getGrammaticalCaseIdentifier(UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_SOCIATIVE));
+    assertEquals(u"test get identifier: ", "vocative",
+                 udispopt_getGrammaticalCaseIdentifier(UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_VOCATIVE));
+
+    assertEquals(u"test get identifier: ", "undefined",
+                 udispopt_getPluralCategoryIdentifier(UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_UNDEFINED));
+    assertEquals(u"test get identifier: ", "zero",
+                 udispopt_getPluralCategoryIdentifier(UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_ZERO));
+    assertEquals(u"test get identifier: ", "one",
+                 udispopt_getPluralCategoryIdentifier(UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_ONE));
+    assertEquals(u"test get identifier: ", "two",
+                 udispopt_getPluralCategoryIdentifier(UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_TWO));
+    assertEquals(u"test get identifier: ", "few",
+                 udispopt_getPluralCategoryIdentifier(UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_FEW));
+    assertEquals(u"test get identifier: ", "many",
+                 udispopt_getPluralCategoryIdentifier(UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_MANY));
+    assertEquals(u"test get identifier: ", "other",
+                 udispopt_getPluralCategoryIdentifier(UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_OTHER));
+
+    assertEquals(u"test get identifier: ", "undefined",
+                 udispopt_getNounClassIdentifier(UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_UNDEFINED));
+    assertEquals(u"test get identifier: ", "other",
+                 udispopt_getNounClassIdentifier(UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_OTHER));
+    assertEquals(u"test get identifier: ", "neuter",
+                 udispopt_getNounClassIdentifier(UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_NEUTER));
+    assertEquals(u"test get identifier: ", "feminine",
+                 udispopt_getNounClassIdentifier(UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_FEMININE));
+    assertEquals(u"test get identifier: ", "masculine",
+                 udispopt_getNounClassIdentifier(UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE));
+    assertEquals(u"test get identifier: ", "animate",
+                 udispopt_getNounClassIdentifier(UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_ANIMATE));
+    assertEquals(u"test get identifier: ", "inanimate",
+                 udispopt_getNounClassIdentifier(UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_INANIMATE));
+    assertEquals(u"test get identifier: ", "personal",
+                 udispopt_getNounClassIdentifier(UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_PERSONAL));
+    assertEquals(u"test get identifier: ", "common",
+                 udispopt_getNounClassIdentifier(UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_COMMON));
+}
+
+void DisplayOptionsTest::testDisplayOptionsFromIdentifier() {
+
+    assertEquals(u"test from identifier: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_UNDEFINED,
+                 udispopt_fromGrammaticalCaseIdentifier(""));
+    assertEquals(u"test from identifier: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_UNDEFINED,
+                 udispopt_fromGrammaticalCaseIdentifier("undefined"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_ABLATIVE,
+                 udispopt_fromGrammaticalCaseIdentifier("ablative"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_ACCUSATIVE,
+                 udispopt_fromGrammaticalCaseIdentifier("accusative"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_COMITATIVE,
+                 udispopt_fromGrammaticalCaseIdentifier("comitative"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_DATIVE,
+                 udispopt_fromGrammaticalCaseIdentifier("dative"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_ERGATIVE,
+                 udispopt_fromGrammaticalCaseIdentifier("ergative"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_GENITIVE,
+                 udispopt_fromGrammaticalCaseIdentifier("genitive"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_INSTRUMENTAL,
+                 udispopt_fromGrammaticalCaseIdentifier("instrumental"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_LOCATIVE,
+                 udispopt_fromGrammaticalCaseIdentifier("locative"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_LOCATIVE_COPULATIVE,
+                 udispopt_fromGrammaticalCaseIdentifier("locative_copulative"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_NOMINATIVE,
+                 udispopt_fromGrammaticalCaseIdentifier("nominative"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_OBLIQUE,
+                 udispopt_fromGrammaticalCaseIdentifier("oblique"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_PREPOSITIONAL,
+                 udispopt_fromGrammaticalCaseIdentifier("prepositional"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_SOCIATIVE,
+                 udispopt_fromGrammaticalCaseIdentifier("sociative"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsGrammaticalCase::UDISPOPT_GRAMMATICAL_CASE_VOCATIVE,
+                 udispopt_fromGrammaticalCaseIdentifier("vocative"));
+
+    assertEquals(u"test from identifier: ", UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_UNDEFINED,
+                 udispopt_fromPluralCategoryIdentifier(""));
+    assertEquals(u"test from identifier: ", UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_UNDEFINED,
+                 udispopt_fromPluralCategoryIdentifier("undefined"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_ZERO,
+                 udispopt_fromPluralCategoryIdentifier("zero"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_ONE,
+                 udispopt_fromPluralCategoryIdentifier("one"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_TWO,
+                 udispopt_fromPluralCategoryIdentifier("two"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_FEW,
+                 udispopt_fromPluralCategoryIdentifier("few"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_MANY,
+                 udispopt_fromPluralCategoryIdentifier("many"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsPluralCategory::UDISPOPT_PLURAL_CATEGORY_OTHER,
+                 udispopt_fromPluralCategoryIdentifier("other"));
+
+    assertEquals(u"test from identifier: ", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_UNDEFINED,
+                 udispopt_fromNounClassIdentifier(""));
+    assertEquals(u"test from identifier: ", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_UNDEFINED,
+                 udispopt_fromNounClassIdentifier("undefined"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_OTHER,
+                 udispopt_fromNounClassIdentifier("other"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_NEUTER,
+                 udispopt_fromNounClassIdentifier("neuter"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_FEMININE,
+                 udispopt_fromNounClassIdentifier("feminine"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE,
+                 udispopt_fromNounClassIdentifier("masculine"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_ANIMATE,
+                 udispopt_fromNounClassIdentifier("animate"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_INANIMATE,
+                 udispopt_fromNounClassIdentifier("inanimate"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_PERSONAL,
+                 udispopt_fromNounClassIdentifier("personal"));
+    assertEquals(u"test from identifier: ", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_COMMON,
+                 udispopt_fromNounClassIdentifier("common"));
+}
+
+extern IntlTest *createDisplayOptionsTest() { return new DisplayOptionsTest(); }
+
+#endif /* #if !UCONFIG_NO_FORMATTING */
index e8bdacd5fc9d2bdc0c416338c33d7978f2b35452..dd3cc6f1cbc393133d2d04e99d97dbd08408f92b 100644 (file)
     <ClCompile Include="numbertest_patternstring.cpp" />
     <ClCompile Include="string_segment_test.cpp" />
     <ClCompile Include="numbertest_parse.cpp" />
+    <ClCompile Include="displayoptions_test.cpp" />
     <ClCompile Include="numbertest_doubleconversion.cpp" />
     <ClCompile Include="numbertest_skeletons.cpp" />
     <ClCompile Include="numbertest_range.cpp" />
index 079cbbb1629298ba214182137707bd585f4f49c5..ebf3c7ec2aa3004b2c5aef2d46bec1d3be89d3a2 100644 (file)
     <ClCompile Include="numbertest_parse.cpp">
       <Filter>formatting</Filter>
     </ClCompile>
+    <ClCompile Include="displayoptions_test.cpp">
+      <Filter>formatting</Filter>
+    </ClCompile>
     <ClCompile Include="numbertest_doubleconversion.cpp">
       <Filter>formatting</Filter>
     </ClCompile>
index a2b5ffec67a95702b2cb1de4c7c9a0f6327acf4d..08f725adc1424e34bb1a74fa1f997500f68ce05f 100644 (file)
@@ -77,6 +77,7 @@ extern IntlTest *createStringSegmentTest();
 extern IntlTest *createUnitsDataTest();
 extern IntlTest *createUnitsTest();
 extern IntlTest *createUnitsRouterTest();
+extern IntlTest *createDisplayOptionsTest();
 
 
 #define TESTCLASS(id, TestClass)          \
@@ -277,6 +278,15 @@ void IntlTestFormat::runIndexedTest( int32_t index, UBool exec, const char* &nam
             callTest(*test, par);
           }
           break;
+        case 59:
+          name = "DisplayOptionsTest";
+          if (exec) {
+            logln("DisplayOptionsTest test---");
+            logln((UnicodeString)"");
+            LocalPointer<IntlTest> test(createDisplayOptionsTest());
+            callTest(*test, par);
+          }
+          break;
         default: name = ""; break; //needed to end loop
     }
     if (exec) {
index b477a16e93e7c90b9f5cdd44f4a23626c08187cf..3472e6d3997169c760bc5ecbf681d4f431991172 100644 (file)
@@ -2440,274 +2440,283 @@ void NumberFormatterApiTest::unitInflections() {
     // TODO: look at "↑↑↑" cases: check that inheritance is done right.
 }
 
-using icu::NounClass;
 void NumberFormatterApiTest::unitNounClass() {
     IcuTestErrorCode status(*this, "unitNounClass");
     const struct TestCase {
         const char *locale;
         const char *unitIdentifier;
-        const NounClass expectedNounClass;
+        const UDisplayOptionsNounClass expectedNounClass;
     } cases[] = {
-        {"de", "inch", NounClass::MASCULINE},
-        {"de", "yard", NounClass::NEUTER},
-        {"de", "meter", NounClass::MASCULINE},
-        {"de", "liter", NounClass::MASCULINE},
-        {"de", "second", NounClass::FEMININE},
-        {"de", "minute", NounClass::FEMININE},
-        {"de", "hour", NounClass::FEMININE},
-        {"de", "day", NounClass::MASCULINE},
-        {"de", "year", NounClass::NEUTER},
-        {"de", "gram", NounClass::NEUTER},
-        {"de", "watt", NounClass::NEUTER},
-        {"de", "bit", NounClass::NEUTER},
-        {"de", "byte", NounClass::NEUTER},
-
-        {"fr", "inch", NounClass::MASCULINE},
-        {"fr", "yard", NounClass::MASCULINE},
-        {"fr", "meter", NounClass::MASCULINE},
-        {"fr", "liter", NounClass::MASCULINE},
-        {"fr", "second", NounClass::FEMININE},
-        {"fr", "minute", NounClass::FEMININE},
-        {"fr", "hour", NounClass::FEMININE},
-        {"fr", "day", NounClass::MASCULINE},
-        {"fr", "year", NounClass::MASCULINE},
-        {"fr", "gram", NounClass::MASCULINE},
+        {"de", "inch", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},
+        {"de", "yard", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_NEUTER},
+        {"de", "meter", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},
+        {"de", "liter", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},
+        {"de", "second", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_FEMININE},
+        {"de", "minute", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_FEMININE},
+        {"de", "hour", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_FEMININE},
+        {"de", "day", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},
+        {"de", "year", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_NEUTER},
+        {"de", "gram", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_NEUTER},
+        {"de", "watt", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_NEUTER},
+        {"de", "bit", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_NEUTER},
+        {"de", "byte", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_NEUTER},
+
+        {"fr", "inch", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},
+        {"fr", "yard", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},
+        {"fr", "meter", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},
+        {"fr", "liter", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},
+        {"fr", "second", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_FEMININE},
+        {"fr", "minute", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_FEMININE},
+        {"fr", "hour", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_FEMININE},
+        {"fr", "day", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},
+        {"fr", "year", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},
+        {"fr", "gram", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},
 
         // grammaticalFeatures deriveCompound "per" rule takes the gender of the
         // numerator unit:
-        {"de", "meter-per-hour", NounClass::MASCULINE},
-        {"fr", "meter-per-hour", NounClass::MASCULINE},
-        {"af", "meter-per-hour", NounClass::OTHER}, // ungendered language
+        {"de", "meter-per-hour", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},
+        {"fr", "meter-per-hour", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},
+        {"af", "meter-per-hour",
+         UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_UNDEFINED}, // ungendered language
 
         // French "times" takes gender from first value, German takes the
         // second. Prefix and power does not have impact on gender for these
         // languages:
-        {"de", "square-decimeter-square-second", NounClass::FEMININE},
-        {"fr", "square-decimeter-square-second", NounClass::MASCULINE},
+        {"de", "square-decimeter-square-second", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_FEMININE},
+        {"fr", "square-decimeter-square-second",
+         UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},
 
         // TODO(icu-units#149): percent and permille bypasses LongNameHandler
         // when unitWidth is not FULL_NAME:
         // // Gender of per-second might be that of percent? TODO(icu-units#28)
-        // {"de", "percent", NounClass::NEUTER},
-        // {"fr", "percent", NounClass::MASCULINE},
+        // {"de", "percent", UNounClass::UNOUN_CLASS_NEUTER},
+        // {"fr", "percent", UNounClass::UNOUN_CLASS_MASCULINE},
 
         // Built-in units whose simple units lack gender in the CLDR data file
-        {"de", "kilopascal", NounClass::NEUTER},
-        {"fr", "kilopascal", NounClass::MASCULINE},
-        // {"de", "pascal", NounClass::OTHER},
-        // {"fr", "pascal", NounClass::OTHER},
+        {"de", "kilopascal", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_NEUTER},
+        {"fr", "kilopascal", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},
+        // {"de", "pascal", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "pascal", UNounClass::UNOUN_CLASS_UNDEFINED},
 
         // Built-in units that lack gender in the CLDR data file
-        // {"de", "revolution", NounClass::OTHER},
-        // {"de", "radian", NounClass::OTHER},
-        // {"de", "arc-minute", NounClass::OTHER},
-        // {"de", "arc-second", NounClass::OTHER},
-        {"de", "square-yard", NounClass::NEUTER},    // POWER
-        {"de", "square-inch", NounClass::MASCULINE}, // POWER
-        // {"de", "dunam", NounClass::OTHER},
-        // {"de", "karat", NounClass::OTHER},
-        // {"de", "milligram-ofglucose-per-deciliter", NounClass::OTHER}, // COMPOUND, ofglucose
-        // {"de", "millimole-per-liter", NounClass::OTHER},               // COMPOUND, mole
-        // {"de", "permillion", NounClass::OTHER},
-        // {"de", "permille", NounClass::OTHER},
-        // {"de", "permyriad", NounClass::OTHER},
-        // {"de", "mole", NounClass::OTHER},
-        {"de", "liter-per-kilometer", NounClass::MASCULINE}, // COMPOUND
-        {"de", "petabyte", NounClass::NEUTER},               // PREFIX
-        {"de", "terabit", NounClass::NEUTER},                // PREFIX
-        // {"de", "century", NounClass::OTHER},
-        // {"de", "decade", NounClass::OTHER},
-        {"de", "millisecond", NounClass::FEMININE}, // PREFIX
-        {"de", "microsecond", NounClass::FEMININE}, // PREFIX
-        {"de", "nanosecond", NounClass::FEMININE},  // PREFIX
-        // {"de", "ampere", NounClass::OTHER},
-        // {"de", "milliampere", NounClass::OTHER}, // PREFIX, ampere
-        // {"de", "ohm", NounClass::OTHER},
-        // {"de", "calorie", NounClass::OTHER},
-        // {"de", "kilojoule", NounClass::OTHER}, // PREFIX, joule
-        // {"de", "joule", NounClass::OTHER},
-        {"de", "kilowatt-hour", NounClass::FEMININE}, // COMPOUND
-        // {"de", "electronvolt", NounClass::OTHER},
-        // {"de", "british-thermal-unit", NounClass::OTHER},
-        // {"de", "therm-us", NounClass::OTHER},
-        // {"de", "pound-force", NounClass::OTHER},
-        // {"de", "newton", NounClass::OTHER},
-        // {"de", "gigahertz", NounClass::OTHER}, // PREFIX, hertz
-        // {"de", "megahertz", NounClass::OTHER}, // PREFIX, hertz
-        // {"de", "kilohertz", NounClass::OTHER}, // PREFIX, hertz
-        // {"de", "hertz", NounClass::OTHER},
-        // {"de", "em", NounClass::OTHER},
-        // {"de", "pixel", NounClass::OTHER},
-        // {"de", "megapixel", NounClass::OTHER},
-        // {"de", "pixel-per-centimeter", NounClass::OTHER}, // COMPOUND, pixel
-        // {"de", "pixel-per-inch", NounClass::OTHER},       // COMPOUND, pixel
-        // {"de", "dot-per-centimeter", NounClass::OTHER},   // COMPOUND, dot
-        // {"de", "dot-per-inch", NounClass::OTHER},         // COMPOUND, dot
-        // {"de", "dot", NounClass::OTHER},
-        // {"de", "earth-radius", NounClass::OTHER},
-        {"de", "decimeter", NounClass::MASCULINE},  // PREFIX
-        {"de", "micrometer", NounClass::MASCULINE}, // PREFIX
-        {"de", "nanometer", NounClass::MASCULINE},  // PREFIX
-        // {"de", "light-year", NounClass::OTHER},
-        // {"de", "astronomical-unit", NounClass::OTHER},
-        // {"de", "furlong", NounClass::OTHER},
-        // {"de", "fathom", NounClass::OTHER},
-        // {"de", "nautical-mile", NounClass::OTHER},
-        // {"de", "mile-scandinavian", NounClass::OTHER},
-        // {"de", "point", NounClass::OTHER},
-        // {"de", "lux", NounClass::OTHER},
-        // {"de", "candela", NounClass::OTHER},
-        // {"de", "lumen", NounClass::OTHER},
-        // {"de", "metric-ton", NounClass::OTHER},
-        // {"de", "microgram", NounClass::NEUTER}, // PREFIX
-        // {"de", "ton", NounClass::OTHER},
-        // {"de", "stone", NounClass::OTHER},
-        // {"de", "ounce-troy", NounClass::OTHER},
-        // {"de", "carat", NounClass::OTHER},
-        {"de", "gigawatt", NounClass::NEUTER},  // PREFIX
-        {"de", "milliwatt", NounClass::NEUTER}, // PREFIX
-        // {"de", "horsepower", NounClass::OTHER},
-        // {"de", "millimeter-ofhg", NounClass::OTHER},
-        // {"de", "pound-force-per-square-inch", NounClass::OTHER}, // COMPOUND, pound-force
-        // {"de", "inch-ofhg", NounClass::OTHER},
-        // {"de", "bar", NounClass::OTHER},
-        // {"de", "millibar", NounClass::OTHER}, // PREFIX, bar
-        // {"de", "atmosphere", NounClass::OTHER},
-        // {"de", "pascal", NounClass::OTHER},      // PREFIX, kilopascal? neuter?
-        // {"de", "hectopascal", NounClass::OTHER}, // PREFIX, pascal, neuter?
-        // {"de", "megapascal", NounClass::OTHER},  // PREFIX, pascal, neuter?
-        // {"de", "knot", NounClass::OTHER},
-        {"de", "pound-force-foot", NounClass::MASCULINE}, // COMPOUND
-        {"de", "newton-meter", NounClass::MASCULINE},     // COMPOUND
-        {"de", "cubic-kilometer", NounClass::MASCULINE},  // POWER
-        {"de", "cubic-yard", NounClass::NEUTER},          // POWER
-        {"de", "cubic-inch", NounClass::MASCULINE},       // POWER
-        {"de", "megaliter", NounClass::MASCULINE},        // PREFIX
-        {"de", "hectoliter", NounClass::MASCULINE},       // PREFIX
-        // {"de", "pint-metric", NounClass::OTHER},
-        // {"de", "cup-metric", NounClass::OTHER},
-        {"de", "acre-foot", NounClass::MASCULINE}, // COMPOUND
-        // {"de", "bushel", NounClass::OTHER},
-        // {"de", "barrel", NounClass::OTHER},
+        // {"de", "revolution", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "radian", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "arc-minute", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "arc-second", UNounClass::UNOUN_CLASS_UNDEFINED},
+        {"de", "square-yard", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_NEUTER},    // POWER
+        {"de", "square-inch", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE}, // POWER
+        // {"de", "dunam", UNounClass::UNOUN_CLASS_ UNDEFINED},
+        // {"de", "karat", UNounClass::UNOUN_CLASS_ UNDEFINED},
+        // {"de", "milligram-ofglucose-per-deciliter", UNounClass::UNOUN_CLASS_UNDEFINED}, // COMPOUND,
+        // ofglucose
+        // {"de", "millimole-per-liter", UNounClass::UNOUN_CLASS_UNDEFINED},               // COMPOUND,
+        // mole
+        // {"de", "permillion", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "permille", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "permyriad", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "mole", UNounClass::UNOUN_CLASS_UNDEFINED},
+        {"de", "liter-per-kilometer",
+         UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},                // COMPOUND
+        {"de", "petabyte", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_NEUTER}, // PREFIX
+        {"de", "terabit", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_NEUTER},  // PREFIX
+        // {"de", "century", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "decade", UNounClass::UNOUN_CLASS_UNDEFINED},
+        {"de", "millisecond", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_FEMININE}, // PREFIX
+        {"de", "microsecond", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_FEMININE}, // PREFIX
+        {"de", "nanosecond", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_FEMININE},  // PREFIX
+        // {"de", "ampere", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "milliampere", UNounClass::UNOUN_CLASS_UNDEFINED}, // PREFIX, ampere
+        // {"de", "ohm", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "calorie", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "kilojoule", UNounClass::UNOUN_CLASS_UNDEFINED}, // PREFIX, joule
+        // {"de", "joule", UNounClass::UNOUN_CLASS_ UNDEFINED},
+        {"de", "kilowatt-hour", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_FEMININE}, // COMPOUND
+        // {"de", "electronvolt", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "british-thermal-unit", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "therm-us", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "pound-force", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "newton", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "gigahertz", UNounClass::UNOUN_CLASS_UNDEFINED}, // PREFIX, hertz
+        // {"de", "megahertz", UNounClass::UNOUN_CLASS_UNDEFINED}, // PREFIX, hertz
+        // {"de", "kilohertz", UNounClass::UNOUN_CLASS_UNDEFINED}, // PREFIX, hertz
+        // {"de", "hertz", UNounClass::UNOUN_CLASS_ UNDEFINED},
+        // {"de", "em", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "pixel", UNounClass::UNOUN_CLASS_ UNDEFINED},
+        // {"de", "megapixel", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "pixel-per-centimeter", UNounClass::UNOUN_CLASS_UNDEFINED}, // COMPOUND, pixel
+        // {"de", "pixel-per-inch", UNounClass::UNOUN_CLASS_UNDEFINED},       // COMPOUND, pixel
+        // {"de", "dot-per-centimeter", UNounClass::UNOUN_CLASS_UNDEFINED},   // COMPOUND, dot
+        // {"de", "dot-per-inch", UNounClass::UNOUN_CLASS_UNDEFINED},         // COMPOUND, dot
+        // {"de", "dot", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "earth-radius", UNounClass::UNOUN_CLASS_UNDEFINED},
+        {"de", "decimeter", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},  // PREFIX
+        {"de", "micrometer", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE}, // PREFIX
+        {"de", "nanometer", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},  // PREFIX
+        // {"de", "light-year", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "astronomical-unit", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "furlong", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "fathom", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "nautical-mile", UNounClass::UNOUN_CLASS_ UNDEFINED},
+        // {"de", "mile-scandinavian", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "point", UNounClass::UNOUN_CLASS_ UNDEFINED},
+        // {"de", "lux", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "candela", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "lumen", UNounClass::UNOUN_CLASS_ UNDEFINED},
+        // {"de", "metric-ton", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "microgram", UNounClass::UNOUN_CLASS_NEUTER}, // PREFIX
+        // {"de", "ton", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "stone", UNounClass::UNOUN_CLASS_ UNDEFINED},
+        // {"de", "ounce-troy", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "carat", UNounClass::UNOUN_CLASS_ UNDEFINED},
+        {"de", "gigawatt", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_NEUTER},  // PREFIX
+        {"de", "milliwatt", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_NEUTER}, // PREFIX
+        // {"de", "horsepower", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "millimeter-ofhg", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "pound-force-per-square-inch", UNounClass::UNOUN_CLASS_UNDEFINED}, // COMPOUND,
+        // pound-force
+        // {"de", "inch-ofhg", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "bar", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "millibar", UNounClass::UNOUN_CLASS_UNDEFINED}, // PREFIX, bar
+        // {"de", "atmosphere", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "pascal", UNounClass::UNOUN_CLASS_UNDEFINED},      // PREFIX, kilopascal? neuter?
+        // {"de", "hectopascal", UNounClass::UNOUN_CLASS_UNDEFINED}, // PREFIX, pascal, neuter?
+        // {"de", "megapascal", UNounClass::UNOUN_CLASS_UNDEFINED},  // PREFIX, pascal, neuter?
+        // {"de", "knot", UNounClass::UNOUN_CLASS_UNDEFINED},
+        {"de", "pound-force-foot", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE}, // COMPOUND
+        {"de", "newton-meter", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},     // COMPOUND
+        {"de", "cubic-kilometer", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},  // POWER
+        {"de", "cubic-yard", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_NEUTER},          // POWER
+        {"de", "cubic-inch", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},       // POWER
+        {"de", "megaliter", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},        // PREFIX
+        {"de", "hectoliter", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},       // PREFIX
+        // {"de", "pint-metric", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "cup-metric", UNounClass::UNOUN_CLASS_UNDEFINED},
+        {"de", "acre-foot", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE}, // COMPOUND
+        // {"de", "bushel", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"de", "barrel", UNounClass::UNOUN_CLASS_UNDEFINED},
         // Units missing gender in German also misses gender in French:
-        // {"fr", "revolution", NounClass::OTHER},
-        // {"fr", "radian", NounClass::OTHER},
-        // {"fr", "arc-minute", NounClass::OTHER},
-        // {"fr", "arc-second", NounClass::OTHER},
-        {"fr", "square-yard", NounClass::MASCULINE}, // POWER
-        {"fr", "square-inch", NounClass::MASCULINE}, // POWER
-        // {"fr", "dunam", NounClass::OTHER},
-        // {"fr", "karat", NounClass::OTHER},
-        {"fr", "milligram-ofglucose-per-deciliter", NounClass::MASCULINE}, // COMPOUND
-        // {"fr", "millimole-per-liter", NounClass::OTHER},                        // COMPOUND, mole
-        // {"fr", "permillion", NounClass::OTHER},
-        // {"fr", "permille", NounClass::OTHER},
-        // {"fr", "permyriad", NounClass::OTHER},
-        // {"fr", "mole", NounClass::OTHER},
-        {"fr", "liter-per-kilometer", NounClass::MASCULINE}, // COMPOUND
-        // {"fr", "petabyte", NounClass::OTHER},                     // PREFIX
-        // {"fr", "terabit", NounClass::OTHER},                      // PREFIX
-        // {"fr", "century", NounClass::OTHER},
-        // {"fr", "decade", NounClass::OTHER},
-        {"fr", "millisecond", NounClass::FEMININE}, // PREFIX
-        {"fr", "microsecond", NounClass::FEMININE}, // PREFIX
-        {"fr", "nanosecond", NounClass::FEMININE},  // PREFIX
-        // {"fr", "ampere", NounClass::OTHER},
-        // {"fr", "milliampere", NounClass::OTHER}, // PREFIX, ampere
-        // {"fr", "ohm", NounClass::OTHER},
-        // {"fr", "calorie", NounClass::OTHER},
-        // {"fr", "kilojoule", NounClass::OTHER}, // PREFIX, joule
-        // {"fr", "joule", NounClass::OTHER},
-        // {"fr", "kilowatt-hour", NounClass::OTHER}, // COMPOUND
-        // {"fr", "electronvolt", NounClass::OTHER},
-        // {"fr", "british-thermal-unit", NounClass::OTHER},
-        // {"fr", "therm-us", NounClass::OTHER},
-        // {"fr", "pound-force", NounClass::OTHER},
-        // {"fr", "newton", NounClass::OTHER},
-        // {"fr", "gigahertz", NounClass::OTHER}, // PREFIX, hertz
-        // {"fr", "megahertz", NounClass::OTHER}, // PREFIX, hertz
-        // {"fr", "kilohertz", NounClass::OTHER}, // PREFIX, hertz
-        // {"fr", "hertz", NounClass::OTHER},
-        // {"fr", "em", NounClass::OTHER},
-        // {"fr", "pixel", NounClass::OTHER},
-        // {"fr", "megapixel", NounClass::OTHER},
-        // {"fr", "pixel-per-centimeter", NounClass::OTHER}, // COMPOUND, pixel
-        // {"fr", "pixel-per-inch", NounClass::OTHER},       // COMPOUND, pixel
-        // {"fr", "dot-per-centimeter", NounClass::OTHER},   // COMPOUND, dot
-        // {"fr", "dot-per-inch", NounClass::OTHER},         // COMPOUND, dot
-        // {"fr", "dot", NounClass::OTHER},
-        // {"fr", "earth-radius", NounClass::OTHER},
-        {"fr", "decimeter", NounClass::MASCULINE},  // PREFIX
-        {"fr", "micrometer", NounClass::MASCULINE}, // PREFIX
-        {"fr", "nanometer", NounClass::MASCULINE},  // PREFIX
-        // {"fr", "light-year", NounClass::OTHER},
-        // {"fr", "astronomical-unit", NounClass::OTHER},
-        // {"fr", "furlong", NounClass::OTHER},
-        // {"fr", "fathom", NounClass::OTHER},
-        // {"fr", "nautical-mile", NounClass::OTHER},
-        // {"fr", "mile-scandinavian", NounClass::OTHER},
-        // {"fr", "point", NounClass::OTHER},
-        // {"fr", "lux", NounClass::OTHER},
-        // {"fr", "candela", NounClass::OTHER},
-        // {"fr", "lumen", NounClass::OTHER},
-        // {"fr", "metric-ton", NounClass::OTHER},
-        // {"fr", "microgram", NounClass::MASCULINE}, // PREFIX
-        // {"fr", "ton", NounClass::OTHER},
-        // {"fr", "stone", NounClass::OTHER},
-        // {"fr", "ounce-troy", NounClass::OTHER},
-        // {"fr", "carat", NounClass::OTHER},
-        // {"fr", "gigawatt", NounClass::OTHER}, // PREFIX
-        // {"fr", "milliwatt", NounClass::OTHER},
-        // {"fr", "horsepower", NounClass::OTHER},
-        {"fr", "millimeter-ofhg", NounClass::MASCULINE},
-        // {"fr", "pound-force-per-square-inch", NounClass::OTHER}, // COMPOUND, pound-force
-        {"fr", "inch-ofhg", NounClass::MASCULINE},
-        // {"fr", "bar", NounClass::OTHER},
-        // {"fr", "millibar", NounClass::OTHER}, // PREFIX, bar
-        // {"fr", "atmosphere", NounClass::OTHER},
-        // {"fr", "pascal", NounClass::OTHER},      // PREFIX, kilopascal?
-        // {"fr", "hectopascal", NounClass::OTHER}, // PREFIX, pascal
-        // {"fr", "megapascal", NounClass::OTHER},  // PREFIX, pascal
-        // {"fr", "knot", NounClass::OTHER},
-        // {"fr", "pound-force-foot", NounClass::OTHER},
-        // {"fr", "newton-meter", NounClass::OTHER},
-        {"fr", "cubic-kilometer", NounClass::MASCULINE}, // POWER
-        {"fr", "cubic-yard", NounClass::MASCULINE},      // POWER
-        {"fr", "cubic-inch", NounClass::MASCULINE},      // POWER
-        {"fr", "megaliter", NounClass::MASCULINE},       // PREFIX
-        {"fr", "hectoliter", NounClass::MASCULINE},      // PREFIX
-        // {"fr", "pint-metric", NounClass::OTHER},
-        // {"fr", "cup-metric", NounClass::OTHER},
-        {"fr", "acre-foot", NounClass::FEMININE}, // COMPOUND
-        // {"fr", "bushel", NounClass::OTHER},
-        // {"fr", "barrel", NounClass::OTHER},
+        // {"fr", "revolution", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "radian", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "arc-minute", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "arc-second", UNounClass::UNOUN_CLASS_UNDEFINED},
+        {"fr", "square-yard", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE}, // POWER
+        {"fr", "square-inch", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE}, // POWER
+        // {"fr", "dunam", UNounClass::UNOUN_CLASS_ UNDEFINED},
+        // {"fr", "karat", UNounClass::UNOUN_CLASS_ UNDEFINED},
+        {"fr", "milligram-ofglucose-per-deciliter",
+         UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE}, // COMPOUND
+        // {"fr", "millimole-per-liter", UNounClass::UNOUN_CLASS_UNDEFINED},                        //
+        // COMPOUND, mole
+        // {"fr", "permillion", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "permille", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "permyriad", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "mole", UNounClass::UNOUN_CLASS_UNDEFINED},
+        {"fr", "liter-per-kilometer",
+         UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE}, // COMPOUND
+        // {"fr", "petabyte", UNounClass::UNOUN_CLASS_UNDEFINED},                     // PREFIX
+        // {"fr", "terabit", UNounClass::UNOUN_CLASS_UNDEFINED},                      // PREFIX
+        // {"fr", "century", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "decade", UNounClass::UNOUN_CLASS_UNDEFINED},
+        {"fr", "millisecond", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_FEMININE}, // PREFIX
+        {"fr", "microsecond", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_FEMININE}, // PREFIX
+        {"fr", "nanosecond", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_FEMININE},  // PREFIX
+        // {"fr", "ampere", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "milliampere", UNounClass::UNOUN_CLASS_UNDEFINED}, // PREFIX, ampere
+        // {"fr", "ohm", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "calorie", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "kilojoule", UNounClass::UNOUN_CLASS_UNDEFINED}, // PREFIX, joule
+        // {"fr", "joule", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "kilowatt-hour", UNounClass::UNOUN_CLASS_UNDEFINED}, // COMPOUND
+        // {"fr", "electronvolt", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "british-thermal-unit", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "therm-us", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "pound-force", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "newton", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "gigahertz", UNounClass::UNOUN_CLASS_UNDEFINED}, // PREFIX, hertz
+        // {"fr", "megahertz", UNounClass::UNOUN_CLASS_UNDEFINED}, // PREFIX, hertz
+        // {"fr", "kilohertz", UNounClass::UNOUN_CLASS_UNDEFINED}, // PREFIX, hertz
+        // {"fr", "hertz", UNounClass::UNOUN_CLASS_ UNDEFINED},
+        // {"fr", "em", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "pixel", UNounClass::UNOUN_CLASS_ UNDEFINED},
+        // {"fr", "megapixel", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "pixel-per-centimeter", UNounClass::UNOUN_CLASS_UNDEFINED}, // COMPOUND, pixel
+        // {"fr", "pixel-per-inch", UNounClass::UNOUN_CLASS_UNDEFINED},       // COMPOUND, pixel
+        // {"fr", "dot-per-centimeter", UNounClass::UNOUN_CLASS_UNDEFINED},   // COMPOUND, dot
+        // {"fr", "dot-per-inch", UNounClass::UNOUN_CLASS_UNDEFINED},         // COMPOUND, dot
+        // {"fr", "dot", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "earth-radius", UNounClass::UNOUN_CLASS_UNDEFINED},
+        {"fr", "decimeter", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},  // PREFIX
+        {"fr", "micrometer", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE}, // PREFIX
+        {"fr", "nanometer", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},  // PREFIX
+        // {"fr", "light-year", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "astronomical-unit", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "furlong", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "fathom", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "nautical-mile", UNounClass::UNOUN_CLASS_ UNDEFINED},
+        // {"fr", "mile-scandinavian", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "point", UNounClass::UNOUN_CLASS_ UNDEFINED},
+        // {"fr", "lux", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "candela", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "lumen", UNounClass::UNOUN_CLASS_ UNDEFINED},
+        // {"fr", "metric-ton", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "microgram", UNounClass::UNOUN_CLASS_MASCULINE}, // PREFIX
+        // {"fr", "ton", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "stone", UNounClass::UNOUN_CLASS_ UNDEFINED},
+        // {"fr", "ounce-troy", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "carat", UNounClass::UNOUN_CLASS_ UNDEFINED},
+        // {"fr", "gigawatt", UNounClass::UNOUN_CLASS_UNDEFINED}, // PREFIX
+        // {"fr", "milliwatt", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "horsepower", UNounClass::UNOUN_CLASS_UNDEFINED},
+        {"fr", "millimeter-ofhg", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},
+        // {"fr", "pound-force-per-square-inch", UNounClass::UNOUN_CLASS_UNDEFINED}, // COMPOUND,
+        // pound-force
+        {"fr", "inch-ofhg", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},
+        // {"fr", "bar", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "millibar", UNounClass::UNOUN_CLASS_UNDEFINED}, // PREFIX, bar
+        // {"fr", "atmosphere", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "pascal", UNounClass::UNOUN_CLASS_UNDEFINED},      // PREFIX, kilopascal?
+        // {"fr", "hectopascal", UNounClass::UNOUN_CLASS_UNDEFINED}, // PREFIX, pascal
+        // {"fr", "megapascal", UNounClass::UNOUN_CLASS_UNDEFINED},  // PREFIX, pascal
+        // {"fr", "knot", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "pound-force-foot", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "newton-meter", UNounClass::UNOUN_CLASS_UNDEFINED},
+        {"fr", "cubic-kilometer", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE}, // POWER
+        {"fr", "cubic-yard", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},      // POWER
+        {"fr", "cubic-inch", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},      // POWER
+        {"fr", "megaliter", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},       // PREFIX
+        {"fr", "hectoliter", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},      // PREFIX
+        // {"fr", "pint-metric", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "cup-metric", UNounClass::UNOUN_CLASS_UNDEFINED},
+        {"fr", "acre-foot", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_FEMININE}, // COMPOUND
+        // {"fr", "bushel", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "barrel", UNounClass::UNOUN_CLASS_UNDEFINED},
         // Some more French units missing gender:
-        // {"fr", "degree", NounClass::OTHER},
-        {"fr", "square-meter", NounClass::MASCULINE}, // POWER
-        // {"fr", "terabyte", NounClass::OTHER},              // PREFIX, byte
-        // {"fr", "gigabyte", NounClass::OTHER},              // PREFIX, byte
-        // {"fr", "gigabit", NounClass::OTHER},               // PREFIX, bit
-        // {"fr", "megabyte", NounClass::OTHER},              // PREFIX, byte
-        // {"fr", "megabit", NounClass::OTHER},               // PREFIX, bit
-        // {"fr", "kilobyte", NounClass::OTHER},              // PREFIX, byte
-        // {"fr", "kilobit", NounClass::OTHER},               // PREFIX, bit
-        // {"fr", "byte", NounClass::OTHER},
-        // {"fr", "bit", NounClass::OTHER},
-        // {"fr", "volt", NounClass::OTHER},
-        // {"fr", "watt", NounClass::OTHER},
-        {"fr", "cubic-meter", NounClass::MASCULINE}, // POWER
+        // {"fr", "degree", UNounClass::UNOUN_CLASS_UNDEFINED},
+        {"fr", "square-meter", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE}, // POWER
+        // {"fr", "terabyte", UNounClass::UNOUN_CLASS_UNDEFINED},              // PREFIX, byte
+        // {"fr", "gigabyte", UNounClass::UNOUN_CLASS_UNDEFINED},              // PREFIX, byte
+        // {"fr", "gigabit", UNounClass::UNOUN_CLASS_UNDEFINED},               // PREFIX, bit
+        // {"fr", "megabyte", UNounClass::UNOUN_CLASS_UNDEFINED},              // PREFIX, byte
+        // {"fr", "megabit", UNounClass::UNOUN_CLASS_UNDEFINED},               // PREFIX, bit
+        // {"fr", "kilobyte", UNounClass::UNOUN_CLASS_UNDEFINED},              // PREFIX, byte
+        // {"fr", "kilobit", UNounClass::UNOUN_CLASS_UNDEFINED},               // PREFIX, bit
+        // {"fr", "byte", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "bit", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "volt", UNounClass::UNOUN_CLASS_UNDEFINED},
+        // {"fr", "watt", UNounClass::UNOUN_CLASS_UNDEFINED},
+        {"fr", "cubic-meter", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE}, // POWER
 
         // gender-lacking builtins within compound units
-        {"de", "newton-meter-per-second", NounClass::MASCULINE},
+        {"de", "newton-meter-per-second", UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_MASCULINE},
 
         // TODO(ICU-21494): determine whether list genders behave as follows,
         // and implement proper getListGender support (covering more than just
         // two genders):
         // // gender rule for lists of people: de "neutral", fr "maleTaints"
-        // {"de", "day-and-hour-and-minute", NounClass::NEUTER},
-        // {"de", "hour-and-minute", NounClass::FEMININE},
-        // {"fr", "day-and-hour-and-minute", NounClass::MASCULINE},
-        // {"fr", "hour-and-minute", NounClass::FEMININE},
+        // {"de", "day-and-hour-and-minute", UNounClass::UNOUN_CLASS_NEUTER},
+        // {"de", "hour-and-minute", UNounClass::UNOUN_CLASS_FEMININE},
+        // {"fr", "day-and-hour-and-minute", UNounClass::UNOUN_CLASS_MASCULINE},
+        // {"fr", "hour-and-minute", UNounClass::UNOUN_CLASS_FEMININE},
     };
 
     LocalizedNumberFormatter formatter;
@@ -2737,8 +2746,8 @@ void NumberFormatterApiTest::unitNounClass() {
     formatter = NumberFormatter::with().locale(Locale::getEnglish());
     fn = formatter.formatDouble(1.1, status);
     status.assertSuccess();
-    assertEquals("getNounClasses for a not supported language", NounClass::OTHER,
-                 fn.getNounClass(status));
+    assertEquals("getNounClasses for a not supported language",
+                 UDisplayOptionsNounClass::UDISPOPT_NOUN_CLASS_UNDEFINED, fn.getNounClass(status));
 }
 
 void NumberFormatterApiTest::unitGender() {
index 3782b9af5b52c6e4fd3ea1233beeffd1fac26760..da18f1dd7cd543ebdef10433618d3b63632d56c2 100644 (file)
@@ -13,8 +13,7 @@ import com.ibm.icu.text.ConstrainedFieldPosition;
 import com.ibm.icu.text.FormattedValue;
 import com.ibm.icu.text.PluralRules.IFixedDecimal;
 import com.ibm.icu.util.MeasureUnit;
-import com.ibm.icu.util.NounClass;
-import com.ibm.icu.util.UResourceTypeMismatchException;
+import com.ibm.icu.text.DisplayOptions.NounClass;
 
 /**
  * The result of a number formatting operation. This class allows the result to be exported in several
@@ -139,49 +138,14 @@ public class FormattedNumber implements FormattedValue {
     }
 
     /**
-     * Gets the noun class of the formatted output. Returns `OTHER` when the noun class
-     * is not supported yet.
+     * Gets the noun class of the formatted output. Returns `UNDEFINED` when the noun class is not
+     * supported yet.
      *
-     * @throws UResourceTypeMismatchException
-     * @return `NounClass`
+     * @return NounClass
      * @draft ICU 71.
      */
     public NounClass getNounClass() {
-        // if it is not exist, return `OTHER`
-        if (this.gender == null || this.gender.isEmpty()) {
-            return NounClass.OTHER;
-        }
-
-        if (this.gender.equals("neuter")) {
-            return NounClass.NEUTER;
-        }
-
-        if (this.gender.equals("feminine")) {
-            return NounClass.FEMININE;
-        }
-
-        if (this.gender.equals("masculine")) {
-            return NounClass.MASCULINE;
-        }
-
-        if (this.gender.equals("animate")) {
-            return NounClass.ANIMATE;
-        }
-
-        if (this.gender.equals("inanimate")) {
-            return NounClass.INANIMATE;
-        }
-
-        if (this.gender.equals("personal")) {
-            return NounClass.PERSONAL;
-        }
-
-        if (this.gender.equals("common")) {
-            return NounClass.COMMON;
-        }
-
-        // In case there is no matching.
-        throw new UResourceTypeMismatchException("there are noun classes that are not supported yet");
+        return NounClass.fromIdentifier(this.gender);
     }
 
     /**
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/DisplayOptions.java b/icu4j/main/classes/core/src/com/ibm/icu/text/DisplayOptions.java
new file mode 100644 (file)
index 0000000..ec10bc4
--- /dev/null
@@ -0,0 +1,748 @@
+// © 2022 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+package com.ibm.icu.text;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Represents all the display options that are supported by CLDR such as grammatical case, noun
+ * class, ... etc. It currently supports enums, but may be extended in the future to have other
+ * types of data. It replaces a DisplayContext[] as a method parameter.
+ * <p>
+ * NOTE: this class is Immutable, and uses a Builder interface.
+ * <p>For example:
+ * {@code DisplayOptions x =
+ *                DisplayOptions.builder()
+ *                             .setNounClass(NounClass.DATIVE)
+ *                             .setPluralCategory(PluralCategory.FEW)
+ *                             .build();
+ *                             }
+ *
+ * @draft ICU 72
+ */
+public final class DisplayOptions {
+
+  private final GrammaticalCase grammaticalCase;
+  private final NounClass nounClass;
+  private final PluralCategory pluralCategory;
+  private final Capitalization capitalization;
+  private final NameStyle nameStyle;
+  private final DisplayLength displayLength;
+  private final SubstituteHandling substituteHandling;
+
+  private DisplayOptions(Builder builder) {
+    this.grammaticalCase = builder.grammaticalCase;
+    this.nounClass = builder.nounClass;
+    this.pluralCategory = builder.pluralCategory;
+    this.capitalization = builder.capitalization;
+    this.nameStyle = builder.nameStyle;
+    this.displayLength = builder.displayLength;
+    this.substituteHandling = builder.substituteHandling;
+  }
+
+  /**
+   * Creates a builder with the {@code UNDEFINED} value for all the parameters.
+   *
+   * @return Builder
+   * @draft ICU 72
+   */
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  /**
+   * Creates a builder with the same parameters from this object.
+   *
+   * @return Builder
+   * @draft ICU 72
+   */
+  public Builder copyToBuilder() {
+    return new Builder(this);
+  }
+
+  /**
+   * Gets the grammatical case.
+   *
+   * @return GrammaticalCase
+   * @draft ICU 72
+   */
+  public GrammaticalCase getGrammaticalCase() {
+    return this.grammaticalCase;
+  }
+
+  /**
+   * Gets the noun class.
+   *
+   * @return NounClass
+   * @draft ICU 72
+   */
+  public NounClass getNounClass() {
+    return this.nounClass;
+  }
+
+  /**
+   * Gets the plural category.
+   *
+   * @return PluralCategory
+   * @draft ICU 72
+   */
+  public PluralCategory getPluralCategory() {
+    return this.pluralCategory;
+  }
+
+
+  /**
+   * Gets the capitalization.
+   *
+   * @return Capitalization
+   * @draft ICU 72
+   */
+  public Capitalization getCapitalization() {
+    return this.capitalization;
+  }
+
+
+  /**
+   * Gets the name style.
+   *
+   * @return NameStyle
+   * @draft ICU 72
+   */
+  public NameStyle getNameStyle() {
+    return this.nameStyle;
+  }
+
+
+  /**
+   * Gets the display length.
+   *
+   * @return DisplayLength
+   * @draft ICU 72
+   */
+  public DisplayLength getDisplayLength() {
+    return this.displayLength;
+  }
+
+
+  /**
+   * Gets the substitute handling.
+   *
+   * @return SubstituteHandling
+   * @draft ICU 72
+   */
+  public SubstituteHandling getSubstituteHandling() {
+    return this.substituteHandling;
+  }
+
+  /**
+   * Responsible for building {@code DisplayOptions}.
+   *
+   * @draft ICU 72
+   */
+  public static class Builder {
+
+    private GrammaticalCase grammaticalCase;
+    private NounClass nounClass;
+    private PluralCategory pluralCategory;
+    private Capitalization capitalization;
+    private NameStyle nameStyle;
+    private DisplayLength displayLength;
+    private SubstituteHandling substituteHandling;
+
+    /**
+     * Creates a {@code DisplayOptions.Builder} with the default values.
+     *
+     * @return Builder
+     * @draft ICU 72
+     */
+    private Builder() {
+      this.grammaticalCase = GrammaticalCase.UNDEFINED;
+      this.nounClass = NounClass.UNDEFINED;
+      this.pluralCategory = PluralCategory.UNDEFINED;
+      this.capitalization = Capitalization.UNDEFINED;
+      this.nameStyle = NameStyle.UNDEFINED;
+      this.displayLength = DisplayLength.UNDEFINED;
+      this.substituteHandling = SubstituteHandling.UNDEFINED;
+    }
+
+    /**
+     * Creates a {@code Builder} with all the information from a {@code DisplayOptions}.
+     *
+     * @return Builder
+     * @draft ICU 72
+     */
+    private Builder(DisplayOptions displayOptions) {
+      this.grammaticalCase = displayOptions.grammaticalCase;
+      this.nounClass = displayOptions.nounClass;
+      this.pluralCategory = displayOptions.pluralCategory;
+      this.capitalization = displayOptions.capitalization;
+      this.nameStyle = displayOptions.nameStyle;
+      this.displayLength = displayOptions.displayLength;
+      this.substituteHandling = displayOptions.substituteHandling;
+    }
+
+    /**
+     * Sets the grammatical case.
+     *
+     * @return Builder
+     * @draft ICU 72
+     */
+    public Builder setGrammaticalCase(GrammaticalCase grammaticalCase) {
+      this.grammaticalCase = grammaticalCase;
+      return this;
+    }
+
+    /**
+     * Sets the noun class.
+     *
+     * @return Builder
+     * @draft ICU 72
+     */
+    public Builder setNounClass(NounClass nounClass) {
+      this.nounClass = nounClass;
+      return this;
+    }
+
+    /**
+     * Sets the plural category.
+     *
+     * @return Builder
+     * @draft ICU 72
+     */
+    public Builder setPluralCategory(PluralCategory pluralCategory) {
+      this.pluralCategory = pluralCategory;
+      return this;
+    }
+
+    /**
+     * Sets the capitalization.
+     *
+     * @return Builder
+     * @draft ICU 72
+     */
+    public Builder setCapitalization(Capitalization capitalization) {
+      this.capitalization = capitalization;
+      return this;
+    }
+
+    /**
+     * Sets the name style.
+     *
+     * @return Builder
+     * @draft ICU 72
+     */
+    public Builder setNameStyle(NameStyle nameStyle) {
+      this.nameStyle = nameStyle;
+      return this;
+    }
+
+    /**
+     * Sets the display length.
+     *
+     * @return Builder
+     * @draft ICU 72
+     */
+    public Builder setDisplayLength(DisplayLength displayLength) {
+      this.displayLength = displayLength;
+      return this;
+    }
+
+    /**
+     * Sets the substitute handling.
+     *
+     * @return Builder
+     * @draft ICU 72
+     */
+    public Builder setSubstituteHandling(SubstituteHandling substituteHandling) {
+      this.substituteHandling = substituteHandling;
+      return this;
+    }
+
+    /**
+     * Builds the display options.
+     *
+     * @return DisplayOptions
+     * @draft ICU 72
+     */
+    public DisplayOptions build() {
+      DisplayOptions displayOptions = new DisplayOptions(this);
+      return displayOptions;
+    }
+  }
+
+  /**
+   * Represents all the grammatical noun classes that are supported by CLDR.
+   *
+   * @draft ICU 71
+   */
+  public enum NounClass {
+    /**
+     * A possible setting for NounClass. The noun class context to be used is unknown (this is the
+     * default value).
+     *
+     * @draft ICU 72
+     */
+    UNDEFINED("undefined"),
+    /**
+     * @draft ICU 71
+     */
+    OTHER("other"),
+    /**
+     * @draft ICU 71
+     */
+    NEUTER("neuter"),
+    /**
+     * @draft ICU 71
+     */
+    FEMININE("feminine"),
+    /**
+     * @draft ICU 71
+     */
+    MASCULINE("masculine"),
+    /**
+     * @draft ICU 71
+     */
+    ANIMATE("animate"),
+    /**
+     * @draft ICU 71
+     */
+    INANIMATE("inanimate"),
+    /**
+     * @draft ICU 71
+     */
+    PERSONAL("personal"),
+    /**
+     * @draft ICU 71
+     */
+    COMMON("common");
+
+    private final String identifier;
+
+    private NounClass(String identifier) {
+      this.identifier = identifier;
+    }
+
+
+    /**
+     * Unmodifiable List of all noun classes constants. List version of {@link #values()}.
+     *
+     * @draft ICU 72
+     */
+    public static final List<NounClass> VALUES =
+        Collections.unmodifiableList(Arrays.asList(NounClass.values()));
+
+    /**
+     * @return the lowercase CLDR keyword string for the noun class.
+     * @draft ICU 72
+     */
+    public final String getIdentifier() {
+      return this.identifier;
+    }
+
+    /**
+     * @param identifier in lower case such as "feminine" or "masculine"
+     * @return the plural category corresponding to the identifier, or {@code UNDEFINED}
+     * @draft ICU 72
+     */
+    public static final NounClass fromIdentifier(String identifier) {
+      if (identifier == null) {
+        return NounClass.UNDEFINED;
+      }
+
+      for (NounClass nounClass : VALUES) {
+        if (identifier.equals(nounClass.getIdentifier())) {
+          return nounClass;
+        }
+      }
+
+      return NounClass.UNDEFINED;
+    }
+  }
+
+  /**
+   * Represents all the name styles.
+   *
+   * @draft ICU 72
+   */
+  public enum NameStyle {
+    /**
+     * A possible setting for NameStyle. The NameStyle context to be used is unknown (this is the
+     * default value).
+     *
+     * @draft ICU 72
+     */
+    UNDEFINED,
+    /**
+     * Use standard names when generating a locale name, e.g. en_GB displays as 'English (United
+     * Kingdom)'.
+     *
+     * @draft ICU 72
+     */
+    STANDARD_NAMES,
+
+    /**
+     * Use dialect names, when generating a locale name, e.g. en_GB displays as 'British English'.
+     *
+     * @draft ICU 72
+     */
+    DIALECT_NAMES;
+
+    /**
+     * Unmodifiable List of all name styles constants. List version of {@link #values()}.
+     *
+     * @draft ICU 72
+     */
+    public static final List<NameStyle> VALUES =
+        Collections.unmodifiableList(Arrays.asList(NameStyle.values()));
+  }
+
+  /**
+   * Represents all the substitute handlings.
+   *
+   * @draft ICU 72
+   */
+  public enum SubstituteHandling {
+    /**
+     * A possible setting for SubstituteHandling. The SubstituteHandling context to be used is
+     * unknown (this is the default value).
+     *
+     * @draft ICU 72
+     */
+    UNDEFINED,
+    /**
+     * Returns a fallback value (e.g., the input code) when no data is available. This is the
+     * default behaviour.
+     *
+     * @draft ICU 72
+     */
+    SUBSTITUTE,
+
+    /**
+     * Returns a null value when no data is available.
+     *
+     * @draft ICU 72
+     */
+    NO_SUBSTITUTE;
+
+    /**
+     * Unmodifiable List of all substitute handlings constants. List version of {@link #values()}.
+     *
+     * @draft ICU 72
+     */
+    public static final List<SubstituteHandling> VALUES =
+        Collections.unmodifiableList(Arrays.asList(SubstituteHandling.values()));
+  }
+
+  /**
+   * Represents all the display lengths.
+   *
+   * @draft ICU 72
+   */
+  public enum DisplayLength {
+    /**
+     * A possible setting for DisplayLength. The DisplayLength context to be used is unknown (this
+     * is the default value).
+     *
+     * @draft ICU 72
+     */
+    UNDEFINED,
+    /**
+     * Uses full names when generating a locale name, e.g. "United States" for US.
+     *
+     * @draft ICU 72
+     */
+    LENGTH_FULL,
+
+    /**
+     * Use short names when generating a locale name, e.g. "U.S." for US.
+     *
+     * @draft ICU 72
+     */
+    LENGTH_SHORT;
+
+    /**
+     * Unmodifiable List of all display lengths constants. List version of {@link #values()}.
+     *
+     * @draft ICU 72
+     */
+    public static final List<DisplayLength> VALUES =
+        Collections.unmodifiableList(Arrays.asList(DisplayLength.values()));
+  }
+
+  /**
+   * Represents all the capitalization options.
+   *
+   * @draft ICU 72
+   */
+  public enum Capitalization {
+    /**
+     * A possible setting for Capitalization. The capitalization context to be used is unknown (this
+     * is the default value).
+     *
+     * @draft ICU 72
+     */
+    UNDEFINED,
+
+    /**
+     * The capitalization context if a date, date symbol or display name is to be formatted with
+     * capitalization appropriate for the beginning of a sentence.
+     *
+     * @draft ICU 72
+     */
+    BEGINNING_OF_SENTENCE,
+
+    /**
+     * The capitalization context if a date, date symbol or display name is to be formatted with
+     * capitalization appropriate for the middle of a sentence.
+     *
+     * @draft ICU 72
+     */
+    MIDDLE_OF_SENTENCE,
+
+    /**
+     * The capitalization context if a date, date symbol or display name is to be formatted with
+     * capitalization appropriate for stand-alone usage such as an isolated name on a calendar
+     * page.
+     *
+     * @draft ICU 72
+     */
+    STANDALONE,
+
+    /**
+     * The capitalization context if a date, date symbol or display name is to be formatted with
+     * capitalization appropriate for a user-interface list or menu item.
+     *
+     * @draft ICU 72
+     */
+    UI_LIST_OR_MENU;
+
+
+    /**
+     * Unmodifiable List of all the capitalizations constants. List version of {@link #values()}.
+     *
+     * @draft ICU 72
+     */
+    public static final List<Capitalization> VALUES =
+        Collections.unmodifiableList(Arrays.asList(Capitalization.values()));
+
+  }
+
+  /**
+   * Standard CLDR plural category constants. See http://www.unicode.org/reports/tr35/tr35-numbers.html#Language_Plural_Rules
+   *
+   * @draft ICU 72
+   */
+  public enum PluralCategory {
+
+    /**
+     * A possible setting for PluralCategory. The plural category context to be used is unknown
+     * (this is the default value).
+     *
+     * @draft ICU 72
+     */
+    UNDEFINED("undefined"),
+
+    /**
+     * @draft ICU 72
+     */
+    ZERO("zero"),
+
+    /**
+     * @draft ICU 72
+     */
+    ONE("one"),
+
+    /**
+     * @draft ICU 72
+     */
+    TWO("two"),
+
+    /**
+     * @draft ICU 72
+     */
+    FEW("few"),
+
+    /**
+     * @draft ICU 72
+     */
+    MANY("many"),
+
+    /**
+     * @draft ICU 72
+     */
+    OTHER("other");
+
+    private final String identifier;
+
+    private PluralCategory(String identifier) {
+      this.identifier = identifier;
+    }
+
+
+    /**
+     * Unmodifiable List of all plural categories constants. List version of {@link #values()}.
+     *
+     * @draft ICU 72
+     */
+    public static final List<PluralCategory> VALUES =
+        Collections.unmodifiableList(Arrays.asList(PluralCategory.values()));
+
+    /**
+     * @return the lowercase CLDR keyword string for the plural category
+     * @draft ICU 72
+     */
+    public final String getIdentifier() {
+      return this.identifier;
+    }
+
+    /**
+     * @param identifier in lower case such as "few" or "other"
+     * @return the plural category corresponding to the identifier, or {@code UNDEFINED}
+     * @draft ICU 72
+     */
+    public static final PluralCategory fromIdentifier(String identifier) {
+      if (identifier == null) {
+        return PluralCategory.UNDEFINED;
+      }
+
+      for (PluralCategory pluralCategory : VALUES) {
+        if (identifier.equals(pluralCategory.getIdentifier())) {
+          return pluralCategory;
+        }
+      }
+
+      return PluralCategory.UNDEFINED;
+    }
+  }
+
+  /**
+   * Represents all the grammatical cases that are supported by CLDR.
+   *
+   * @draft ICU 72
+   */
+  public enum GrammaticalCase {
+
+    /**
+     * A possible setting for GrammaticalCase. The grammatical case context to be used is unknown
+     * (this is the default value).
+     *
+     * @draft ICU 72
+     */
+    UNDEFINED("undefined"),
+
+    /**
+     * @draft ICU 72
+     */
+    ABLATIVE("ablative"),
+
+    /**
+     * @draft ICU 72
+     */
+    ACCUSATIVE("accusative"),
+
+    /**
+     * @draft ICU 72
+     */
+    COMITATIVE("comitative"),
+
+    /**
+     * @draft ICU 72
+     */
+    DATIVE("dative"),
+
+    /**
+     * @draft ICU 72
+     */
+    ERGATIVE("ergative"),
+
+    /**
+     * @draft ICU 72
+     */
+    GENITIVE("genitive"),
+
+    /**
+     * @draft ICU 72
+     */
+    INSTRUMENTAL("instrumental"),
+
+    /**
+     * @draft ICU 72
+     */
+    LOCATIVE("locative"),
+
+    /**
+     * @draft ICU 72
+     */
+    LOCATIVE_COPULATIVE("locative_copulative"),
+
+    /**
+     * @draft ICU 72
+     */
+    NOMINATIVE("nominative"),
+
+    /**
+     * @draft ICU 72
+     */
+    OBLIQUE("oblique"),
+
+    /**
+     * @draft ICU 72
+     */
+    PREPOSITIONAL("prepositional"),
+
+    /**
+     * @draft ICU 72
+     */
+    SOCIATIVE("sociative"),
+
+    /**
+     * @draft ICU 72
+     */
+    VOCATIVE("vocative");
+
+    private final String identifier;
+
+    private GrammaticalCase(String identifier) {
+      this.identifier = identifier;
+    }
+
+    /**
+     * Unmodifiable List of all grammatical cases constants. List version of {@link #values()}.
+     *
+     * @draft ICU 72
+     */
+    public static final List<GrammaticalCase> VALUES =
+        Collections.unmodifiableList(Arrays.asList(GrammaticalCase.values()));
+
+
+    /**
+     * @return the lowercase CLDR keyword string for the grammatical case.
+     * @draft ICU 72
+     */
+    public final String getIdentifier() {
+      return this.identifier;
+    }
+
+    /**
+     * @param identifier in lower case such as "dative" or "nominative"
+     * @return the plural category corresponding to the identifier, or {@code UNDEFINED}
+     * @draft ICU 72
+     */
+    public static final GrammaticalCase fromIdentifier(String identifier) {
+      if (identifier == null) {
+        return GrammaticalCase.UNDEFINED;
+      }
+
+      for (GrammaticalCase grammaticalCase : VALUES) {
+        if (identifier.equals(grammaticalCase.getIdentifier())) {
+          return grammaticalCase;
+        }
+      }
+
+      return GrammaticalCase.UNDEFINED;
+    }
+  }
+}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/util/NounClass.java b/icu4j/main/classes/core/src/com/ibm/icu/util/NounClass.java
deleted file mode 100644 (file)
index 1a0a400..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-// © 2022 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-
-package com.ibm.icu.util;
-
-/**
- * Represents all the grammatical noun classes that are supported by CLDR.
- *
- * @draft ICU 71
- */
-public enum NounClass {
-    /**
-     * @draft ICU 71
-     */
-    OTHER,
-    /**
-     * @draft ICU 71
-     */
-    NEUTER,
-    /**
-     * @draft ICU 71
-     */
-    FEMININE,
-    /**
-     * @draft ICU 71
-     */
-    MASCULINE,
-    /**
-     * @draft ICU 71
-     */
-    ANIMATE,
-    /**
-     * @draft ICU 71
-     */
-    INANIMATE,
-    /**
-     * @draft ICU 71
-     */
-    PERSONAL,
-    /**
-     * @draft ICU 71
-     */
-    COMMON,
-}
index 1430dab40f819d95dac80a34f7a26b14196f4d9c..671121e3c43775aa9fd1949f867d69ddb4d3ad91 100644 (file)
@@ -56,7 +56,7 @@ import com.ibm.icu.util.CurrencyAmount;
 import com.ibm.icu.util.Measure;
 import com.ibm.icu.util.MeasureUnit;
 import com.ibm.icu.util.NoUnit;
-import com.ibm.icu.util.NounClass;
+import com.ibm.icu.text.DisplayOptions.NounClass;
 import com.ibm.icu.util.ULocale;
 
 public class NumberFormatterApiTest extends TestFmwk {
@@ -2473,7 +2473,7 @@ public class NumberFormatterApiTest extends TestFmwk {
                 // numerator unit:
                 new TestCase("de", "meter-per-hour", NounClass.MASCULINE),
                 new TestCase("fr", "meter-per-hour", NounClass.MASCULINE),
-                new TestCase("af", "meter-per-hour", NounClass.OTHER), // ungendered language
+                new TestCase("af", "meter-per-hour", NounClass.UNDEFINED), // ungendered language
 
                 // French "times" takes gender from first value, German takes the
                 // second. Prefix and power does not have impact on gender for these
@@ -2490,89 +2490,89 @@ public class NumberFormatterApiTest extends TestFmwk {
                 // Built-in units whose simple units lack gender in the CLDR data file
                 new TestCase("de", "kilopascal", NounClass.NEUTER),    //
                 new TestCase("fr", "kilopascal", NounClass.MASCULINE), //
-                //     new TestCase("de", "pascal", NounClass.OTHER),              //
-                //     new TestCase("fr", "pascal", NounClass.OTHER),              //
+                //     new TestCase("de", "pascal", NounClass.UNDEFINED),              //
+                //     new TestCase("fr", "pascal", NounClass.UNDEFINED),              //
 
                 // Built-in units that lack gender in the CLDR data file
-                //     new TestCase("de", "revolution", NounClass.OTHER),                        //
-                //     new TestCase("de", "radian", NounClass.OTHER),                            //
-                //     new TestCase("de", "arc-minute", NounClass.OTHER),                        //
-                //     new TestCase("de", "arc-second", NounClass.OTHER),                        //
+                //     new TestCase("de", "revolution", NounClass.UNDEFINED),                        //
+                //     new TestCase("de", "radian", NounClass.UNDEFINED),                            //
+                //     new TestCase("de", "arc-minute", NounClass.UNDEFINED),                        //
+                //     new TestCase("de", "arc-second", NounClass.UNDEFINED),                        //
                 new TestCase("de", "square-yard", NounClass.NEUTER),                 // COMPOUND
                 new TestCase("de", "square-inch", NounClass.MASCULINE),              // COMPOUND
-                //     new TestCase("de", "dunam", NounClass.OTHER),                             //
-                //     new TestCase("de", "karat", NounClass.OTHER),                             //
-                //     new TestCase("de", "milligram-ofglucose-per-deciliter", NounClass.OTHER), // COMPOUND, ofglucose
-                //     new TestCase("de", "millimole-per-liter", NounClass.OTHER),               // COMPOUND, mole
-                //     new TestCase("de", "permillion", NounClass.OTHER),                        //
-                //     new TestCase("de", "permille", NounClass.OTHER),                          //
-                //     new TestCase("de", "permyriad", NounClass.OTHER),                         //
-                //     new TestCase("de", "mole", NounClass.OTHER),                              //
+                //     new TestCase("de", "dunam", NounClass.UNDEFINED),                             //
+                //     new TestCase("de", "karat", NounClass.UNDEFINED),                             //
+                //     new TestCase("de", "milligram-ofglucose-per-deciliter", NounClass.UNDEFINED), // COMPOUND, ofglucose
+                //     new TestCase("de", "millimole-per-liter", NounClass.UNDEFINED),               // COMPOUND, mole
+                //     new TestCase("de", "permillion", NounClass.UNDEFINED),                        //
+                //     new TestCase("de", "permille", NounClass.UNDEFINED),                          //
+                //     new TestCase("de", "permyriad", NounClass.UNDEFINED),                         //
+                //     new TestCase("de", "mole", NounClass.UNDEFINED),                              //
                 new TestCase("de", "liter-per-kilometer", NounClass.MASCULINE),      // COMPOUND
                 new TestCase("de", "petabyte", NounClass.NEUTER),                    // PREFIX
                 new TestCase("de", "terabit", NounClass.NEUTER),                     // PREFIX
-                //     new TestCase("de", "century", NounClass.OTHER),                           //
-                //     new TestCase("de", "decade", NounClass.OTHER),                            //
+                //     new TestCase("de", "century", NounClass.UNDEFINED),                           //
+                //     new TestCase("de", "decade", NounClass.UNDEFINED),                            //
                 new TestCase("de", "millisecond", NounClass.FEMININE),               // PREFIX
                 new TestCase("de", "microsecond", NounClass.FEMININE),               // PREFIX
                 new TestCase("de", "nanosecond", NounClass.FEMININE),                // PREFIX
-                //     new TestCase("de", "ampere", NounClass.OTHER),                            //
-                //     new TestCase("de", "milliampere", NounClass.OTHER),                       // PREFIX, ampere
-                //     new TestCase("de", "ohm", NounClass.OTHER),                               //
-                //     new TestCase("de", "calorie", NounClass.OTHER),                           //
-                //     new TestCase("de", "kilojoule", NounClass.OTHER),                         // PREFIX, joule
-                //     new TestCase("de", "joule", NounClass.OTHER),                             //
+                //     new TestCase("de", "ampere", NounClass.UNDEFINED),                            //
+                //     new TestCase("de", "milliampere", NounClass.UNDEFINED),                       // PREFIX, ampere
+                //     new TestCase("de", "ohm", NounClass.UNDEFINED),                               //
+                //     new TestCase("de", "calorie", NounClass.UNDEFINED),                           //
+                //     new TestCase("de", "kilojoule", NounClass.UNDEFINED),                         // PREFIX, joule
+                //     new TestCase("de", "joule", NounClass.UNDEFINED),                             //
                 new TestCase("de", "kilowatt-hour", NounClass.FEMININE),             // COMPOUND
-                //     new TestCase("de", "electronvolt", NounClass.OTHER),                      //
-                //     new TestCase("de", "british-thermal-unit", NounClass.OTHER),              //
-                //     new TestCase("de", "therm-us", NounClass.OTHER),                          //
-                //     new TestCase("de", "pound-force", NounClass.OTHER),                       //
-                //     new TestCase("de", "newton", NounClass.OTHER),                            //
-                //     new TestCase("de", "gigahertz", NounClass.OTHER),                         // PREFIX, hertz
-                //     new TestCase("de", "megahertz", NounClass.OTHER),                         // PREFIX, hertz
-                //     new TestCase("de", "kilohertz", NounClass.OTHER),                         // PREFIX, hertz
-                //     new TestCase("de", "hertz", NounClass.OTHER),                             // PREFIX, hertz
-                //     new TestCase("de", "em", NounClass.OTHER),                                //
-                //     new TestCase("de", "pixel", NounClass.OTHER),                             //
-                //     new TestCase("de", "megapixel", NounClass.OTHER),                         //
-                //     new TestCase("de", "pixel-per-centimeter", NounClass.OTHER),              // COMPOUND, pixel
-                //     new TestCase("de", "pixel-per-inch", NounClass.OTHER),                    // COMPOUND, pixel
-                //     new TestCase("de", "dot-per-centimeter", NounClass.OTHER),                // COMPOUND, dot
-                //     new TestCase("de", "dot-per-inch", NounClass.OTHER),                      // COMPOUND, dot
-                //     new TestCase("de", "dot", NounClass.OTHER),                               //
-                //     new TestCase("de", "earth-radius", NounClass.OTHER),                      //
+                //     new TestCase("de", "electronvolt", NounClass.UNDEFINED),                      //
+                //     new TestCase("de", "british-thermal-unit", NounClass.UNDEFINED),              //
+                //     new TestCase("de", "therm-us", NounClass.UNDEFINED),                          //
+                //     new TestCase("de", "pound-force", NounClass.UNDEFINED),                       //
+                //     new TestCase("de", "newton", NounClass.UNDEFINED),                            //
+                //     new TestCase("de", "gigahertz", NounClass.UNDEFINED),                         // PREFIX, hertz
+                //     new TestCase("de", "megahertz", NounClass.UNDEFINED),                         // PREFIX, hertz
+                //     new TestCase("de", "kilohertz", NounClass.UNDEFINED),                         // PREFIX, hertz
+                //     new TestCase("de", "hertz", NounClass.UNDEFINED),                             // PREFIX, hertz
+                //     new TestCase("de", "em", NounClass.UNDEFINED),                                //
+                //     new TestCase("de", "pixel", NounClass.UNDEFINED),                             //
+                //     new TestCase("de", "megapixel", NounClass.UNDEFINED),                         //
+                //     new TestCase("de", "pixel-per-centimeter", NounClass.UNDEFINED),              // COMPOUND, pixel
+                //     new TestCase("de", "pixel-per-inch", NounClass.UNDEFINED),                    // COMPOUND, pixel
+                //     new TestCase("de", "dot-per-centimeter", NounClass.UNDEFINED),                // COMPOUND, dot
+                //     new TestCase("de", "dot-per-inch", NounClass.UNDEFINED),                      // COMPOUND, dot
+                //     new TestCase("de", "dot", NounClass.UNDEFINED),                               //
+                //     new TestCase("de", "earth-radius", NounClass.UNDEFINED),                      //
                 new TestCase("de", "decimeter", NounClass.MASCULINE),                // PREFIX
                 new TestCase("de", "micrometer", NounClass.MASCULINE),               // PREFIX
                 new TestCase("de", "nanometer", NounClass.MASCULINE),                // PREFIX
-                //     new TestCase("de", "light-year", NounClass.OTHER),                        //
-                //     new TestCase("de", "astronomical-unit", NounClass.OTHER),                 //
-                //     new TestCase("de", "furlong", NounClass.OTHER),                           //
-                //     new TestCase("de", "fathom", NounClass.OTHER),                            //
-                //     new TestCase("de", "nautical-mile", NounClass.OTHER),                     //
-                //     new TestCase("de", "mile-scandinavian", NounClass.OTHER),                 //
-                //     new TestCase("de", "point", NounClass.OTHER),                             //
-                //     new TestCase("de", "lux", NounClass.OTHER),                               //
-                //     new TestCase("de", "candela", NounClass.OTHER),                           //
-                //     new TestCase("de", "lumen", NounClass.OTHER),                             //
-                //     new TestCase("de", "metric-ton", NounClass.OTHER),                        //
+                //     new TestCase("de", "light-year", NounClass.UNDEFINED),                        //
+                //     new TestCase("de", "astronomical-unit", NounClass.UNDEFINED),                 //
+                //     new TestCase("de", "furlong", NounClass.UNDEFINED),                           //
+                //     new TestCase("de", "fathom", NounClass.UNDEFINED),                            //
+                //     new TestCase("de", "nautical-mile", NounClass.UNDEFINED),                     //
+                //     new TestCase("de", "mile-scandinavian", NounClass.UNDEFINED),                 //
+                //     new TestCase("de", "point", NounClass.UNDEFINED),                             //
+                //     new TestCase("de", "lux", NounClass.UNDEFINED),                               //
+                //     new TestCase("de", "candela", NounClass.UNDEFINED),                           //
+                //     new TestCase("de", "lumen", NounClass.UNDEFINED),                             //
+                //     new TestCase("de", "metric-ton", NounClass.UNDEFINED),                        //
                 new TestCase("de", "microgram", NounClass.NEUTER),                   // PREFIX
-                //     new TestCase("de", "ton", NounClass.OTHER),                               //
-                //     new TestCase("de", "stone", NounClass.OTHER),                             //
-                //     new TestCase("de", "ounce-troy", NounClass.OTHER),                        //
-                //     new TestCase("de", "carat", NounClass.OTHER),                             //
+                //     new TestCase("de", "ton", NounClass.UNDEFINED),                               //
+                //     new TestCase("de", "stone", NounClass.UNDEFINED),                             //
+                //     new TestCase("de", "ounce-troy", NounClass.UNDEFINED),                        //
+                //     new TestCase("de", "carat", NounClass.UNDEFINED),                             //
                 new TestCase("de", "gigawatt", NounClass.NEUTER),                    // PREFIX
                 new TestCase("de", "milliwatt", NounClass.NEUTER),                   // PREFIX
-                //     new TestCase("de", "horsepower", NounClass.OTHER),                        //
-                //     new TestCase("de", "millimeter-ofhg", NounClass.OTHER),                   //
-                //     new TestCase("de", "pound-force-per-square-inch", NounClass.OTHER),       // COMPOUND, pound-force
-                //     new TestCase("de", "inch-ofhg", NounClass.OTHER),                         //
-                //     new TestCase("de", "bar", NounClass.OTHER),                               //
-                //     new TestCase("de", "millibar", NounClass.OTHER),                          // PREFIX, bar
-                //     new TestCase("de", "atmosphere", NounClass.OTHER),                        //
-                //     new TestCase("de", "pascal", NounClass.OTHER),                            // PREFIX, kilopascal? neuter?
-                //     new TestCase("de", "hectopascal", NounClass.OTHER),                       // PREFIX, pascal, neuter?
-                //     new TestCase("de", "megapascal", NounClass.OTHER),                        // PREFIX, pascal, neuter?
-                //     new TestCase("de", "knot", NounClass.OTHER),                              //
+                //     new TestCase("de", "horsepower", NounClass.UNDEFINED),                        //
+                //     new TestCase("de", "millimeter-ofhg", NounClass.UNDEFINED),                   //
+                //     new TestCase("de", "pound-force-per-square-inch", NounClass.UNDEFINED),       // COMPOUND, pound-force
+                //     new TestCase("de", "inch-ofhg", NounClass.UNDEFINED),                         //
+                //     new TestCase("de", "bar", NounClass.UNDEFINED),                               //
+                //     new TestCase("de", "millibar", NounClass.UNDEFINED),                          // PREFIX, bar
+                //     new TestCase("de", "atmosphere", NounClass.UNDEFINED),                        //
+                //     new TestCase("de", "pascal", NounClass.UNDEFINED),                            // PREFIX, kilopascal? neuter?
+                //     new TestCase("de", "hectopascal", NounClass.UNDEFINED),                       // PREFIX, pascal, neuter?
+                //     new TestCase("de", "megapascal", NounClass.UNDEFINED),                        // PREFIX, pascal, neuter?
+                //     new TestCase("de", "knot", NounClass.UNDEFINED),                              //
                 new TestCase("de", "pound-force-foot", NounClass.MASCULINE),         // COMPOUND
                 new TestCase("de", "newton-meter", NounClass.MASCULINE),             // COMPOUND
                 new TestCase("de", "cubic-kilometer", NounClass.MASCULINE),          // POWER
@@ -2580,116 +2580,116 @@ public class NumberFormatterApiTest extends TestFmwk {
                 new TestCase("de", "cubic-inch", NounClass.MASCULINE),               // POWER
                 new TestCase("de", "megaliter", NounClass.MASCULINE),                // PREFIX
                 new TestCase("de", "hectoliter", NounClass.MASCULINE),               // PREFIX
-                //     new TestCase("de", "pint-metric", NounClass.OTHER),                       //
-                //     new TestCase("de", "cup-metric", NounClass.OTHER),                        //
+                //     new TestCase("de", "pint-metric", NounClass.UNDEFINED),                       //
+                //     new TestCase("de", "cup-metric", NounClass.UNDEFINED),                        //
                 new TestCase("de", "acre-foot", NounClass.MASCULINE),                // COMPOUND
-                //     new TestCase("de", "bushel", NounClass.OTHER),                            //
-                //     new TestCase("de", "barrel", NounClass.OTHER),                            //
+                //     new TestCase("de", "bushel", NounClass.UNDEFINED),                            //
+                //     new TestCase("de", "barrel", NounClass.UNDEFINED),                            //
                 // Units missing gender in German also misses gender in French:
-                //     new TestCase("fr", "revolution", NounClass.OTHER),                                 //
-                //     new TestCase("fr", "radian", NounClass.OTHER),                                     //
-                //     new TestCase("fr", "arc-minute", NounClass.OTHER),                                 //
-                //     new TestCase("fr", "arc-second", NounClass.OTHER),                                 //
+                //     new TestCase("fr", "revolution", NounClass.UNDEFINED),                                 //
+                //     new TestCase("fr", "radian", NounClass.UNDEFINED),                                     //
+                //     new TestCase("fr", "arc-minute", NounClass.UNDEFINED),                                 //
+                //     new TestCase("fr", "arc-second", NounClass.UNDEFINED),                                 //
                 new TestCase("fr", "square-yard", NounClass.MASCULINE),                       // COMPOUND
                 new TestCase("fr", "square-inch", NounClass.MASCULINE),                       // COMPOUND
-                //     new TestCase("fr", "dunam", NounClass.OTHER),                                      //
-                //     new TestCase("fr", "karat", NounClass.OTHER),                                      //
+                //     new TestCase("fr", "dunam", NounClass.UNDEFINED),                                      //
+                //     new TestCase("fr", "karat", NounClass.UNDEFINED),                                      //
                 new TestCase("fr", "milligram-ofglucose-per-deciliter", NounClass.MASCULINE), // COMPOUND
-                //     new TestCase("fr", "millimole-per-liter", NounClass.OTHER),                        // COMPOUND, mole
-                //     new TestCase("fr", "permillion", NounClass.OTHER),                                 //
-                //     new TestCase("fr", "permille", NounClass.OTHER),                                   //
-                //     new TestCase("fr", "permyriad", NounClass.OTHER),                                  //
-                //     new TestCase("fr", "mole", NounClass.OTHER),                                       //
+                //     new TestCase("fr", "millimole-per-liter", NounClass.UNDEFINED),                        // COMPOUND, mole
+                //     new TestCase("fr", "permillion", NounClass.UNDEFINED),                                 //
+                //     new TestCase("fr", "permille", NounClass.UNDEFINED),                                   //
+                //     new TestCase("fr", "permyriad", NounClass.UNDEFINED),                                  //
+                //     new TestCase("fr", "mole", NounClass.UNDEFINED),                                       //
                 new TestCase("fr", "liter-per-kilometer", NounClass.MASCULINE),               // COMPOUND
-                //     new TestCase("fr", "petabyte", NounClass.OTHER),                                   // PREFIX
-                //     new TestCase("fr", "terabit", NounClass.OTHER),                                    // PREFIX
-                //     new TestCase("fr", "century", NounClass.OTHER),                                    //
-                //     new TestCase("fr", "decade", NounClass.OTHER),                                     //
+                //     new TestCase("fr", "petabyte", NounClass.UNDEFINED),                                   // PREFIX
+                //     new TestCase("fr", "terabit", NounClass.UNDEFINED),                                    // PREFIX
+                //     new TestCase("fr", "century", NounClass.UNDEFINED),                                    //
+                //     new TestCase("fr", "decade", NounClass.UNDEFINED),                                     //
                 new TestCase("fr", "millisecond", NounClass.FEMININE),                        // PREFIX
                 new TestCase("fr", "microsecond", NounClass.FEMININE),                        // PREFIX
                 new TestCase("fr", "nanosecond", NounClass.FEMININE),                         // PREFIX
-                //     new TestCase("fr", "ampere", NounClass.OTHER),                                     //
-                //     new TestCase("fr", "milliampere", NounClass.OTHER),                                // PREFIX, ampere
-                //     new TestCase("fr", "ohm", NounClass.OTHER),                                        //
-                //     new TestCase("fr", "calorie", NounClass.OTHER),                                    //
-                //     new TestCase("fr", "kilojoule", NounClass.OTHER),                                  // PREFIX, joule
-                //     new TestCase("fr", "joule", NounClass.OTHER),                                      //
-                //     new TestCase("fr", "kilowatt-hour", NounClass.OTHER),                              // COMPOUND
-                //     new TestCase("fr", "electronvolt", NounClass.OTHER),                               //
-                //     new TestCase("fr", "british-thermal-unit", NounClass.OTHER),                       //
-                //     new TestCase("fr", "therm-us", NounClass.OTHER),                                   //
-                //     new TestCase("fr", "pound-force", NounClass.OTHER),                                //
-                //     new TestCase("fr", "newton", NounClass.OTHER),                                     //
-                //     new TestCase("fr", "gigahertz", NounClass.OTHER),                                  // PREFIX, hertz
-                //     new TestCase("fr", "megahertz", NounClass.OTHER),                                  // PREFIX, hertz
-                //     new TestCase("fr", "kilohertz", NounClass.OTHER),                                  // PREFIX, hertz
-                //     new TestCase("fr", "hertz", NounClass.OTHER),                                      // PREFIX, hertz
-                //     new TestCase("fr", "em", NounClass.OTHER),                                         //
-                //     new TestCase("fr", "pixel", NounClass.OTHER),                                      //
-                //     new TestCase("fr", "megapixel", NounClass.OTHER),                                  //
-                //     new TestCase("fr", "pixel-per-centimeter", NounClass.OTHER),                       // COMPOUND, pixel
-                //     new TestCase("fr", "pixel-per-inch", NounClass.OTHER),                             // COMPOUND, pixel
-                //     new TestCase("fr", "dot-per-centimeter", NounClass.OTHER),                         // COMPOUND, dot
-                //     new TestCase("fr", "dot-per-inch", NounClass.OTHER),                               // COMPOUND, dot
-                //     new TestCase("fr", "dot", NounClass.OTHER),                                        //
-                //     new TestCase("fr", "earth-radius", NounClass.OTHER),                               //
+                //     new TestCase("fr", "ampere", NounClass.UNDEFINED),                                     //
+                //     new TestCase("fr", "milliampere", NounClass.UNDEFINED),                                // PREFIX, ampere
+                //     new TestCase("fr", "ohm", NounClass.UNDEFINED),                                        //
+                //     new TestCase("fr", "calorie", NounClass.UNDEFINED),                                    //
+                //     new TestCase("fr", "kilojoule", NounClass.UNDEFINED),                                  // PREFIX, joule
+                //     new TestCase("fr", "joule", NounClass.UNDEFINED),                                      //
+                //     new TestCase("fr", "kilowatt-hour", NounClass.UNDEFINED),                              // COMPOUND
+                //     new TestCase("fr", "electronvolt", NounClass.UNDEFINED),                               //
+                //     new TestCase("fr", "british-thermal-unit", NounClass.UNDEFINED),                       //
+                //     new TestCase("fr", "therm-us", NounClass.UNDEFINED),                                   //
+                //     new TestCase("fr", "pound-force", NounClass.UNDEFINED),                                //
+                //     new TestCase("fr", "newton", NounClass.UNDEFINED),                                     //
+                //     new TestCase("fr", "gigahertz", NounClass.UNDEFINED),                                  // PREFIX, hertz
+                //     new TestCase("fr", "megahertz", NounClass.UNDEFINED),                                  // PREFIX, hertz
+                //     new TestCase("fr", "kilohertz", NounClass.UNDEFINED),                                  // PREFIX, hertz
+                //     new TestCase("fr", "hertz", NounClass.UNDEFINED),                                      // PREFIX, hertz
+                //     new TestCase("fr", "em", NounClass.UNDEFINED),                                         //
+                //     new TestCase("fr", "pixel", NounClass.UNDEFINED),                                      //
+                //     new TestCase("fr", "megapixel", NounClass.UNDEFINED),                                  //
+                //     new TestCase("fr", "pixel-per-centimeter", NounClass.UNDEFINED),                       // COMPOUND, pixel
+                //     new TestCase("fr", "pixel-per-inch", NounClass.UNDEFINED),                             // COMPOUND, pixel
+                //     new TestCase("fr", "dot-per-centimeter", NounClass.UNDEFINED),                         // COMPOUND, dot
+                //     new TestCase("fr", "dot-per-inch", NounClass.UNDEFINED),                               // COMPOUND, dot
+                //     new TestCase("fr", "dot", NounClass.UNDEFINED),                                        //
+                //     new TestCase("fr", "earth-radius", NounClass.UNDEFINED),                               //
                 new TestCase("fr", "decimeter", NounClass.MASCULINE),                         // PREFIX
                 new TestCase("fr", "micrometer", NounClass.MASCULINE),                        // PREFIX
                 new TestCase("fr", "nanometer", NounClass.MASCULINE),                         // PREFIX
-                //     new TestCase("fr", "light-year", NounClass.OTHER),                                 //
-                //     new TestCase("fr", "astronomical-unit", NounClass.OTHER),                          //
-                //     new TestCase("fr", "furlong", NounClass.OTHER),                                    //
-                //     new TestCase("fr", "fathom", NounClass.OTHER),                                     //
-                //     new TestCase("fr", "nautical-mile", NounClass.OTHER),                              //
-                //     new TestCase("fr", "mile-scandinavian", NounClass.OTHER),                          //
-                //     new TestCase("fr", "point", NounClass.OTHER),                                      //
-                //     new TestCase("fr", "lux", NounClass.OTHER),                                        //
-                //     new TestCase("fr", "candela", NounClass.OTHER),                                    //
-                //     new TestCase("fr", "lumen", NounClass.OTHER),                                      //
-                //     new TestCase("fr", "metric-ton", NounClass.OTHER),                                 //
+                //     new TestCase("fr", "light-year", NounClass.UNDEFINED),                                 //
+                //     new TestCase("fr", "astronomical-unit", NounClass.UNDEFINED),                          //
+                //     new TestCase("fr", "furlong", NounClass.UNDEFINED),                                    //
+                //     new TestCase("fr", "fathom", NounClass.UNDEFINED),                                     //
+                //     new TestCase("fr", "nautical-mile", NounClass.UNDEFINED),                              //
+                //     new TestCase("fr", "mile-scandinavian", NounClass.UNDEFINED),                          //
+                //     new TestCase("fr", "point", NounClass.UNDEFINED),                                      //
+                //     new TestCase("fr", "lux", NounClass.UNDEFINED),                                        //
+                //     new TestCase("fr", "candela", NounClass.UNDEFINED),                                    //
+                //     new TestCase("fr", "lumen", NounClass.UNDEFINED),                                      //
+                //     new TestCase("fr", "metric-ton", NounClass.UNDEFINED),                                 //
                 new TestCase("fr", "microgram", NounClass.MASCULINE),                         // PREFIX
-                //     new TestCase("fr", "ton", NounClass.OTHER),                                        //
-                //     new TestCase("fr", "stone", NounClass.OTHER),                                      //
-                //     new TestCase("fr", "ounce-troy", NounClass.OTHER),                                 //
-                //     new TestCase("fr", "carat", NounClass.OTHER),                                      //
-                //     new TestCase("fr", "gigawatt", NounClass.OTHER),                                   // PREFIX
-                //     new TestCase("fr", "milliwatt", NounClass.OTHER),                                  //
-                //     new TestCase("fr", "horsepower", NounClass.OTHER),                                 //
+                //     new TestCase("fr", "ton", NounClass.UNDEFINED),                                        //
+                //     new TestCase("fr", "stone", NounClass.UNDEFINED),                                      //
+                //     new TestCase("fr", "ounce-troy", NounClass.UNDEFINED),                                 //
+                //     new TestCase("fr", "carat", NounClass.UNDEFINED),                                      //
+                //     new TestCase("fr", "gigawatt", NounClass.UNDEFINED),                                   // PREFIX
+                //     new TestCase("fr", "milliwatt", NounClass.UNDEFINED),                                  //
+                //     new TestCase("fr", "horsepower", NounClass.UNDEFINED),                                 //
                 new TestCase("fr", "millimeter-ofhg", NounClass.MASCULINE),                   //
-                //     new TestCase("fr", "pound-force-per-square-inch", NounClass.OTHER), // COMPOUND, pound-force
+                //     new TestCase("fr", "pound-force-per-square-inch", NounClass.UNDEFINED), // COMPOUND, pound-force
                 new TestCase("fr", "inch-ofhg", NounClass.MASCULINE),          //
-                //     new TestCase("fr", "bar", NounClass.OTHER),                         //
-                //     new TestCase("fr", "millibar", NounClass.OTHER),                    // PREFIX, bar
-                //     new TestCase("fr", "atmosphere", NounClass.OTHER),                  //
-                //     new TestCase("fr", "pascal", NounClass.OTHER),                      // PREFIX, kilopascal?
-                //     new TestCase("fr", "hectopascal", NounClass.OTHER),                 // PREFIX, pascal
-                //     new TestCase("fr", "megapascal", NounClass.OTHER),                  // PREFIX, pascal
-                //     new TestCase("fr", "knot", NounClass.OTHER),                        //
-                //     new TestCase("fr", "pound-force-foot", NounClass.OTHER),            //
-                //     new TestCase("fr", "newton-meter", NounClass.OTHER),                //
+                //     new TestCase("fr", "bar", NounClass.UNDEFINED),                         //
+                //     new TestCase("fr", "millibar", NounClass.UNDEFINED),                    // PREFIX, bar
+                //     new TestCase("fr", "atmosphere", NounClass.UNDEFINED),                  //
+                //     new TestCase("fr", "pascal", NounClass.UNDEFINED),                      // PREFIX, kilopascal?
+                //     new TestCase("fr", "hectopascal", NounClass.UNDEFINED),                 // PREFIX, pascal
+                //     new TestCase("fr", "megapascal", NounClass.UNDEFINED),                  // PREFIX, pascal
+                //     new TestCase("fr", "knot", NounClass.UNDEFINED),                        //
+                //     new TestCase("fr", "pound-force-foot", NounClass.UNDEFINED),            //
+                //     new TestCase("fr", "newton-meter", NounClass.UNDEFINED),                //
                 new TestCase("fr", "cubic-kilometer", NounClass.MASCULINE),    // POWER
                 new TestCase("fr", "cubic-yard", NounClass.MASCULINE),         // POWER
                 new TestCase("fr", "cubic-inch", NounClass.MASCULINE),         // POWER
                 new TestCase("fr", "megaliter", NounClass.MASCULINE),          // PREFIX
                 new TestCase("fr", "hectoliter", NounClass.MASCULINE),         // PREFIX
-                //     new TestCase("fr", "pint-metric", NounClass.OTHER),                 //
-                //     new TestCase("fr", "cup-metric", NounClass.OTHER),                  //
+                //     new TestCase("fr", "pint-metric", NounClass.UNDEFINED),                 //
+                //     new TestCase("fr", "cup-metric", NounClass.UNDEFINED),                  //
                 new TestCase("fr", "acre-foot", NounClass.FEMININE),           // COMPOUND
-                //     new TestCase("fr", "bushel", NounClass.OTHER),                      //
-                //     new TestCase("fr", "barrel", NounClass.OTHER),                      //
+                //     new TestCase("fr", "bushel", NounClass.UNDEFINED),                      //
+                //     new TestCase("fr", "barrel", NounClass.UNDEFINED),                      //
                 // Some more French units missing gender:
-                //     new TestCase("fr", "degree", NounClass.OTHER),                //
+                //     new TestCase("fr", "degree", NounClass.UNDEFINED),                //
                 new TestCase("fr", "square-meter", NounClass.MASCULINE), // COMPOUND
-                //     new TestCase("fr", "terabyte", NounClass.OTHER),              // PREFIX, byte
-                //     new TestCase("fr", "gigabyte", NounClass.OTHER),              // PREFIX, byte
-                //     new TestCase("fr", "gigabit", NounClass.OTHER),               // PREFIX, bit
-                //     new TestCase("fr", "megabyte", NounClass.OTHER),              // PREFIX, byte
-                //     new TestCase("fr", "megabit", NounClass.OTHER),               // PREFIX, bit
-                //     new TestCase("fr", "kilobyte", NounClass.OTHER),              // PREFIX, byte
-                //     new TestCase("fr", "kilobit", NounClass.OTHER),               // PREFIX, bit
-                //     new TestCase("fr", "byte", NounClass.OTHER),                  //
-                //     new TestCase("fr", "bit", NounClass.OTHER),                   //
-                //     new TestCase("fr", "volt", NounClass.OTHER),                  //
+                //     new TestCase("fr", "terabyte", NounClass.UNDEFINED),              // PREFIX, byte
+                //     new TestCase("fr", "gigabyte", NounClass.UNDEFINED),              // PREFIX, byte
+                //     new TestCase("fr", "gigabit", NounClass.UNDEFINED),               // PREFIX, bit
+                //     new TestCase("fr", "megabyte", NounClass.UNDEFINED),              // PREFIX, byte
+                //     new TestCase("fr", "megabit", NounClass.UNDEFINED),               // PREFIX, bit
+                //     new TestCase("fr", "kilobyte", NounClass.UNDEFINED),              // PREFIX, byte
+                //     new TestCase("fr", "kilobit", NounClass.UNDEFINED),               // PREFIX, bit
+                //     new TestCase("fr", "byte", NounClass.UNDEFINED),                  //
+                //     new TestCase("fr", "bit", NounClass.UNDEFINED),                   //
+                //     new TestCase("fr", "volt", NounClass.UNDEFINED),                  //
                 new TestCase("fr", "cubic-meter", NounClass.MASCULINE),  // POWER
 
                 // gender-lacking builtins within compound units
@@ -2729,7 +2729,7 @@ public class NumberFormatterApiTest extends TestFmwk {
         // Make sure getGender does not return garbage for genderless languages
         formatter = NumberFormatter.with().locale(ULocale.ENGLISH);
         fn = formatter.format(1.1);
-        assertEquals("getNounClass for not supported language", NounClass.OTHER, fn.getNounClass());
+        assertEquals("getNounClass for not supported language", NounClass.UNDEFINED, fn.getNounClass());
 
     }
 
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/text/DisplayOptionsTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/text/DisplayOptionsTest.java
new file mode 100644 (file)
index 0000000..e81dace
--- /dev/null
@@ -0,0 +1,320 @@
+// © 2022 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+package com.ibm.icu.dev.test.text;
+
+
+import com.ibm.icu.text.DisplayOptions;
+import com.ibm.icu.text.DisplayOptions.Capitalization;
+import com.ibm.icu.text.DisplayOptions.DisplayLength;
+import com.ibm.icu.text.DisplayOptions.GrammaticalCase;
+import com.ibm.icu.text.DisplayOptions.NameStyle;
+import com.ibm.icu.text.DisplayOptions.NounClass;
+import com.ibm.icu.text.DisplayOptions.PluralCategory;
+import com.ibm.icu.text.DisplayOptions.SubstituteHandling;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import com.ibm.icu.dev.test.TestFmwk;
+
+
+/**
+ * @test
+ * @summary Test of DisplayOptions Class.
+ */
+@RunWith(JUnit4.class)
+public class DisplayOptionsTest  extends TestFmwk {
+
+  @Test
+  public void TestDisplayOptionsDefault(){
+    DisplayOptions displayOptions = DisplayOptions.builder().build();
+    assertEquals("Test setting parameters", GrammaticalCase.UNDEFINED,
+        displayOptions.getGrammaticalCase());
+    assertEquals("Test default values: ", NounClass.UNDEFINED, displayOptions.getNounClass());
+    assertEquals("Test default values: ", PluralCategory.UNDEFINED,
+        displayOptions.getPluralCategory());
+    assertEquals("Test default values: ", Capitalization.UNDEFINED,
+        displayOptions.getCapitalization());
+    assertEquals("Test default values: ", NameStyle.UNDEFINED, displayOptions.getNameStyle());
+    assertEquals("Test default values: ", DisplayLength.UNDEFINED,
+        displayOptions.getDisplayLength());
+    assertEquals("Test default values: ", SubstituteHandling.UNDEFINED,
+        displayOptions.getSubstituteHandling());
+  }
+
+  @Test
+  public void TestDisplayOptionsEachElement() {
+    DisplayOptions displayOptions = DisplayOptions.builder()
+        .setGrammaticalCase(GrammaticalCase.ABLATIVE).build();
+    assertEquals("Test setting parameters: ", GrammaticalCase.ABLATIVE,
+        displayOptions.getGrammaticalCase());
+
+    displayOptions = DisplayOptions.builder().setNounClass(NounClass.PERSONAL).build();
+    assertEquals("Test setting parameters: ", NounClass.PERSONAL,
+        displayOptions.getNounClass());
+
+    displayOptions = DisplayOptions.builder().setPluralCategory(PluralCategory.FEW).build();
+    assertEquals("Test setting parameters: ", PluralCategory.FEW,
+        displayOptions.getPluralCategory());
+
+    displayOptions = DisplayOptions.builder()
+        .setCapitalization(Capitalization.BEGINNING_OF_SENTENCE).build();
+    assertEquals("Test setting parameters: ", Capitalization.BEGINNING_OF_SENTENCE,
+        displayOptions.getCapitalization());
+
+    displayOptions = DisplayOptions.builder().setNameStyle(NameStyle.STANDARD_NAMES).build();
+    assertEquals("Test setting parameters: ", NameStyle.STANDARD_NAMES,
+        displayOptions.getNameStyle());
+
+    displayOptions = DisplayOptions.builder().setDisplayLength(DisplayLength.LENGTH_FULL)
+        .build();
+    assertEquals("Test setting parameters: ", DisplayLength.LENGTH_FULL,
+        displayOptions.getDisplayLength());
+
+    displayOptions = DisplayOptions.builder()
+        .setSubstituteHandling(SubstituteHandling.NO_SUBSTITUTE).build();
+    assertEquals("Test setting parameters: ", SubstituteHandling.NO_SUBSTITUTE,
+        displayOptions.getSubstituteHandling());
+  }
+
+  @Test
+  public void TestDisplayOptionsUpdating() {
+    DisplayOptions displayOptions = DisplayOptions.builder()
+        .setGrammaticalCase(GrammaticalCase.ABLATIVE).build();
+    assertEquals("Test updating parameters: ", GrammaticalCase.ABLATIVE,
+        displayOptions.getGrammaticalCase());
+    assertEquals("Test updating parameters: ", NounClass.UNDEFINED,
+        displayOptions.getNounClass());
+    assertEquals("Test updating parameters: ", PluralCategory.UNDEFINED,
+        displayOptions.getPluralCategory());
+    assertEquals("Test updating parameters: ", Capitalization.UNDEFINED,
+        displayOptions.getCapitalization());
+    assertEquals("Test updating parameters: ", NameStyle.UNDEFINED,
+        displayOptions.getNameStyle());
+    assertEquals("Test updating parameters: ", DisplayLength.UNDEFINED,
+        displayOptions.getDisplayLength());
+    assertEquals("Test updating parameters: ", SubstituteHandling.UNDEFINED,
+        displayOptions.getSubstituteHandling());
+
+    displayOptions = displayOptions.copyToBuilder().setNounClass(NounClass.PERSONAL).build();
+    assertEquals("Test updating parameters: ", GrammaticalCase.ABLATIVE,
+        displayOptions.getGrammaticalCase());
+    assertEquals("Test updating parameters: ", NounClass.PERSONAL,
+        displayOptions.getNounClass());
+    assertEquals("Test updating parameters: ", PluralCategory.UNDEFINED,
+        displayOptions.getPluralCategory());
+    assertEquals("Test updating parameters: ", Capitalization.UNDEFINED,
+        displayOptions.getCapitalization());
+    assertEquals("Test updating parameters: ", NameStyle.UNDEFINED,
+        displayOptions.getNameStyle());
+    assertEquals("Test updating parameters: ", DisplayLength.UNDEFINED,
+        displayOptions.getDisplayLength());
+    assertEquals("Test updating parameters: ", SubstituteHandling.UNDEFINED,
+        displayOptions.getSubstituteHandling());
+
+    displayOptions = displayOptions.copyToBuilder().setPluralCategory(PluralCategory.FEW)
+        .build();
+    assertEquals("Test updating parameters: ", GrammaticalCase.ABLATIVE,
+        displayOptions.getGrammaticalCase());
+    assertEquals("Test updating parameters: ", NounClass.PERSONAL,
+        displayOptions.getNounClass());
+    assertEquals("Test updating parameters: ", PluralCategory.FEW,
+        displayOptions.getPluralCategory());
+    assertEquals("Test updating parameters: ", Capitalization.UNDEFINED,
+        displayOptions.getCapitalization());
+    assertEquals("Test updating parameters: ", NameStyle.UNDEFINED,
+        displayOptions.getNameStyle());
+    assertEquals("Test updating parameters: ", DisplayLength.UNDEFINED,
+        displayOptions.getDisplayLength());
+    assertEquals("Test updating parameters: ", SubstituteHandling.UNDEFINED,
+        displayOptions.getSubstituteHandling());
+
+    displayOptions = displayOptions.copyToBuilder()
+        .setCapitalization(Capitalization.BEGINNING_OF_SENTENCE).build();
+    assertEquals("Test updating parameters: ", GrammaticalCase.ABLATIVE,
+        displayOptions.getGrammaticalCase());
+    assertEquals("Test updating parameters: ", NounClass.PERSONAL,
+        displayOptions.getNounClass());
+    assertEquals("Test updating parameters: ", PluralCategory.FEW,
+        displayOptions.getPluralCategory());
+    assertEquals("Test updating parameters: ", Capitalization.BEGINNING_OF_SENTENCE,
+        displayOptions.getCapitalization());
+    assertEquals("Test updating parameters: ", NameStyle.UNDEFINED,
+        displayOptions.getNameStyle());
+    assertEquals("Test updating parameters: ", DisplayLength.UNDEFINED,
+        displayOptions.getDisplayLength());
+    assertEquals("Test updating parameters: ", SubstituteHandling.UNDEFINED,
+        displayOptions.getSubstituteHandling());
+
+    displayOptions = displayOptions.copyToBuilder().setNameStyle(NameStyle.STANDARD_NAMES)
+        .build();
+    assertEquals("Test updating parameters: ", GrammaticalCase.ABLATIVE,
+        displayOptions.getGrammaticalCase());
+    assertEquals("Test updating parameters: ", NounClass.PERSONAL,
+        displayOptions.getNounClass());
+    assertEquals("Test updating parameters: ", PluralCategory.FEW,
+        displayOptions.getPluralCategory());
+    assertEquals("Test updating parameters: ", Capitalization.BEGINNING_OF_SENTENCE,
+        displayOptions.getCapitalization());
+    assertEquals("Test updating parameters: ", NameStyle.STANDARD_NAMES,
+        displayOptions.getNameStyle());
+    assertEquals("Test updating parameters: ", DisplayLength.UNDEFINED,
+        displayOptions.getDisplayLength());
+    assertEquals("Test updating parameters: ", SubstituteHandling.UNDEFINED,
+        displayOptions.getSubstituteHandling());
+
+    displayOptions = displayOptions.copyToBuilder().setDisplayLength(DisplayLength.LENGTH_FULL)
+        .build();
+    assertEquals("Test updating parameters: ", GrammaticalCase.ABLATIVE,
+        displayOptions.getGrammaticalCase());
+    assertEquals("Test updating parameters: ", NounClass.PERSONAL,
+        displayOptions.getNounClass());
+    assertEquals("Test updating parameters: ", PluralCategory.FEW,
+        displayOptions.getPluralCategory());
+    assertEquals("Test updating parameters: ", Capitalization.BEGINNING_OF_SENTENCE,
+        displayOptions.getCapitalization());
+    assertEquals("Test updating parameters: ", NameStyle.STANDARD_NAMES,
+        displayOptions.getNameStyle());
+    assertEquals("Test updating parameters: ", DisplayLength.LENGTH_FULL,
+        displayOptions.getDisplayLength());
+    assertEquals("Test updating parameters: ", SubstituteHandling.UNDEFINED,
+        displayOptions.getSubstituteHandling());
+
+    displayOptions = displayOptions.copyToBuilder()
+        .setSubstituteHandling(SubstituteHandling.NO_SUBSTITUTE).build();
+    assertEquals("Test updating parameters: ", GrammaticalCase.ABLATIVE,
+        displayOptions.getGrammaticalCase());
+    assertEquals("Test updating parameters: ", NounClass.PERSONAL,
+        displayOptions.getNounClass());
+    assertEquals("Test updating parameters: ", PluralCategory.FEW,
+        displayOptions.getPluralCategory());
+    assertEquals("Test updating parameters: ", Capitalization.BEGINNING_OF_SENTENCE,
+        displayOptions.getCapitalization());
+    assertEquals("Test updating parameters: ", NameStyle.STANDARD_NAMES,
+        displayOptions.getNameStyle());
+    assertEquals("Test updating parameters: ", DisplayLength.LENGTH_FULL,
+        displayOptions.getDisplayLength());
+    assertEquals("Test updating parameters: ", SubstituteHandling.NO_SUBSTITUTE,
+        displayOptions.getSubstituteHandling());
+  }
+
+  @Test
+  public void TestDisplayOptionsGetIdentifier() {
+    assertEquals("test get identifier: ", "undefined",
+        GrammaticalCase.UNDEFINED.getIdentifier());
+    assertEquals("test get identifier: ", "ablative", GrammaticalCase.ABLATIVE.getIdentifier());
+    assertEquals("test get identifier: ", "accusative",
+        GrammaticalCase.ACCUSATIVE.getIdentifier());
+    assertEquals("test get identifier: ", "comitative",
+        GrammaticalCase.COMITATIVE.getIdentifier());
+    assertEquals("test get identifier: ", "dative", GrammaticalCase.DATIVE.getIdentifier());
+    assertEquals("test get identifier: ", "ergative", GrammaticalCase.ERGATIVE.getIdentifier());
+    assertEquals("test get identifier: ", "genitive", GrammaticalCase.GENITIVE.getIdentifier());
+    assertEquals("test get identifier: ", "instrumental",
+        GrammaticalCase.INSTRUMENTAL.getIdentifier());
+    assertEquals("test get identifier: ", "locative", GrammaticalCase.LOCATIVE.getIdentifier());
+    assertEquals("test get identifier: ", "locative_copulative",
+        GrammaticalCase.LOCATIVE_COPULATIVE.getIdentifier());
+    assertEquals("test get identifier: ", "nominative",
+        GrammaticalCase.NOMINATIVE.getIdentifier());
+    assertEquals("test get identifier: ", "oblique", GrammaticalCase.OBLIQUE.getIdentifier());
+    assertEquals("test get identifier: ", "prepositional",
+        GrammaticalCase.PREPOSITIONAL.getIdentifier());
+    assertEquals("test get identifier: ", "sociative",
+        GrammaticalCase.SOCIATIVE.getIdentifier());
+    assertEquals("test get identifier: ", "vocative", GrammaticalCase.VOCATIVE.getIdentifier());
+
+    assertEquals("test get identifier: ", "undefined",
+        PluralCategory.UNDEFINED.getIdentifier());
+    assertEquals("test get identifier: ", "zero", PluralCategory.ZERO.getIdentifier());
+    assertEquals("test get identifier: ", "one", PluralCategory.ONE.getIdentifier());
+    assertEquals("test get identifier: ", "two", PluralCategory.TWO.getIdentifier());
+    assertEquals("test get identifier: ", "few", PluralCategory.FEW.getIdentifier());
+    assertEquals("test get identifier: ", "many", PluralCategory.MANY.getIdentifier());
+    assertEquals("test get identifier: ", "other", PluralCategory.OTHER.getIdentifier());
+
+    assertEquals("test get identifier: ", "undefined", NounClass.UNDEFINED.getIdentifier());
+    assertEquals("test get identifier: ", "other", NounClass.OTHER.getIdentifier());
+    assertEquals("test get identifier: ", "neuter", NounClass.NEUTER.getIdentifier());
+    assertEquals("test get identifier: ", "feminine", NounClass.FEMININE.getIdentifier());
+    assertEquals("test get identifier: ", "masculine", NounClass.MASCULINE.getIdentifier());
+    assertEquals("test get identifier: ", "animate", NounClass.ANIMATE.getIdentifier());
+    assertEquals("test get identifier: ", "inanimate", NounClass.INANIMATE.getIdentifier());
+    assertEquals("test get identifier: ", "personal", NounClass.PERSONAL.getIdentifier());
+    assertEquals("test get identifier: ", "common", NounClass.COMMON.getIdentifier());
+  }
+
+  @Test
+  public void TestDisplayOptionsFromIdentifier() {
+    assertEquals("test from identifier: ", GrammaticalCase.UNDEFINED,
+        GrammaticalCase.fromIdentifier(""));
+    assertEquals("test from identifier: ", GrammaticalCase.UNDEFINED,
+        GrammaticalCase.fromIdentifier("undefined"));
+    assertEquals("test from identifier: ", GrammaticalCase.ABLATIVE,
+        GrammaticalCase.fromIdentifier("ablative"));
+    assertEquals("test from identifier: ", GrammaticalCase.ACCUSATIVE,
+        GrammaticalCase.fromIdentifier("accusative"));
+    assertEquals("test from identifier: ", GrammaticalCase.COMITATIVE,
+        GrammaticalCase.fromIdentifier("comitative"));
+    assertEquals("test from identifier: ", GrammaticalCase.DATIVE,
+        GrammaticalCase.fromIdentifier("dative"));
+    assertEquals("test from identifier: ", GrammaticalCase.ERGATIVE,
+        GrammaticalCase.fromIdentifier("ergative"));
+    assertEquals("test from identifier: ", GrammaticalCase.GENITIVE,
+        GrammaticalCase.fromIdentifier("genitive"));
+    assertEquals("test from identifier: ", GrammaticalCase.INSTRUMENTAL,
+        GrammaticalCase.fromIdentifier("instrumental"));
+    assertEquals("test from identifier: ", GrammaticalCase.LOCATIVE,
+        GrammaticalCase.fromIdentifier("locative"));
+    assertEquals("test from identifier: ", GrammaticalCase.LOCATIVE_COPULATIVE,
+        GrammaticalCase.fromIdentifier("locative_copulative"));
+    assertEquals("test from identifier: ", GrammaticalCase.NOMINATIVE,
+        GrammaticalCase.fromIdentifier("nominative"));
+    assertEquals("test from identifier: ", GrammaticalCase.OBLIQUE,
+        GrammaticalCase.fromIdentifier("oblique"));
+    assertEquals("test from identifier: ", GrammaticalCase.PREPOSITIONAL,
+        GrammaticalCase.fromIdentifier("prepositional"));
+    assertEquals("test from identifier: ", GrammaticalCase.SOCIATIVE,
+        GrammaticalCase.fromIdentifier("sociative"));
+    assertEquals("test from identifier: ", GrammaticalCase.VOCATIVE,
+        GrammaticalCase.fromIdentifier("vocative"));
+
+    assertEquals("test from identifier: ", PluralCategory.UNDEFINED,
+        PluralCategory.fromIdentifier(""));
+    assertEquals("test from identifier: ", PluralCategory.UNDEFINED,
+        PluralCategory.fromIdentifier("undefined"));
+    assertEquals("test from identifier: ", PluralCategory.ZERO,
+        PluralCategory.fromIdentifier("zero"));
+    assertEquals("test from identifier: ", PluralCategory.ONE,
+        PluralCategory.fromIdentifier("one"));
+    assertEquals("test from identifier: ", PluralCategory.TWO,
+        PluralCategory.fromIdentifier("two"));
+    assertEquals("test from identifier: ", PluralCategory.FEW,
+        PluralCategory.fromIdentifier("few"));
+    assertEquals("test from identifier: ", PluralCategory.MANY,
+        PluralCategory.fromIdentifier("many"));
+    assertEquals("test from identifier: ", PluralCategory.OTHER,
+        PluralCategory.fromIdentifier("other"));
+
+    assertEquals("test from identifier: ", NounClass.UNDEFINED, NounClass.fromIdentifier(""));
+    assertEquals("test from identifier: ", NounClass.UNDEFINED,
+        NounClass.fromIdentifier("undefined"));
+    assertEquals("test from identifier: ", NounClass.OTHER, NounClass.fromIdentifier("other"));
+    assertEquals("test from identifier: ", NounClass.NEUTER,
+        NounClass.fromIdentifier("neuter"));
+    assertEquals("test from identifier: ", NounClass.FEMININE,
+        NounClass.fromIdentifier("feminine"));
+    assertEquals("test from identifier: ", NounClass.MASCULINE,
+        NounClass.fromIdentifier("masculine"));
+    assertEquals("test from identifier: ", NounClass.ANIMATE,
+        NounClass.fromIdentifier("animate"));
+    assertEquals("test from identifier: ", NounClass.INANIMATE,
+        NounClass.fromIdentifier("inanimate"));
+    assertEquals("test from identifier: ", NounClass.PERSONAL,
+        NounClass.fromIdentifier("personal"));
+    assertEquals("test from identifier: ", NounClass.COMMON,
+        NounClass.fromIdentifier("common"));
+  }
+}
index ddc8b0d9aeae07afdc921ef9f2aece14b98a58ad..6be5155234af340a95fc96f545cb69af08bf3318 100644 (file)
@@ -19,6 +19,7 @@ import java.util.List;
 import java.util.Random;
 import java.util.Set;
 
+
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.JUnit4;