1 /*
   2  * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 /*
  24  * @test
  25  * @bug 8177552
  26  * @summary Checks the equals and hashCode method of CompactNumberFormat
  27  * @modules jdk.localedata
  28  * @run testng/othervm TestEquality
  29  *
  30  */
  31 
  32 import java.text.CompactNumberFormat;
  33 import java.text.DecimalFormatSymbols;
  34 import java.text.NumberFormat;
  35 import java.util.Locale;
  36 import org.testng.annotations.Test;
  37 
  38 public class TestEquality {
  39 
  40     @Test
  41     public void testEquality() {
  42         CompactNumberFormat cnf1 = (CompactNumberFormat) NumberFormat
  43                 .getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
  44 
  45         CompactNumberFormat cnf2 = (CompactNumberFormat) NumberFormat
  46                 .getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
  47 
  48         // A custom compact instance with the same state as
  49         // compact number instance of "en_US" locale with SHORT style
  50         String decimalPattern = "#,##0.###";
  51         String[] compactPatterns = new String[]{"", "", "", "0K", "00K", "000K", "0M", "00M", "000M", "0B", "00B", "000B", "0T", "00T", "000T"};
  52         DecimalFormatSymbols symbols = DecimalFormatSymbols.getInstance(Locale.US);
  53         CompactNumberFormat cnf3 = new CompactNumberFormat(decimalPattern, symbols, compactPatterns);
  54 
  55         // A compact instance created with different decimalPattern than cnf3
  56         CompactNumberFormat cnf4 = new CompactNumberFormat("#,#0.0#", symbols, compactPatterns);
  57 
  58         // A compact instance created with different format symbols than cnf3
  59         CompactNumberFormat cnf5 = new CompactNumberFormat(decimalPattern,
  60                 DecimalFormatSymbols.getInstance(Locale.JAPAN), compactPatterns);
  61 
  62         // A compact instance created with different compact patterns than cnf3
  63         CompactNumberFormat cnf6 = new CompactNumberFormat(decimalPattern,
  64                 symbols, new String[]{"", "", "", "0K", "00K", "000K"});
  65 
  66         // Checking reflexivity
  67         if (!cnf1.equals(cnf1)) {
  68             throw new RuntimeException("[testEquality() reflexivity FAILED: The compared"
  69                     + " objects must be equal]");
  70         }
  71 
  72         // Checking symmetry, checking equality of two same objects
  73         if (!cnf1.equals(cnf2) || !cnf2.equals(cnf1)) {
  74             throw new RuntimeException("[testEquality() symmetry FAILED: The compared"
  75                     + " objects must be equal]");
  76         }
  77 
  78         // Checking transitivity, three objects must be equal
  79         if (!cnf1.equals(cnf2) || !cnf2.equals(cnf3) || !cnf1.equals(cnf3)) {
  80             throw new RuntimeException("[testEquality() transitivity FAILED: The compared"
  81                     + " objects must be equal]");
  82         }
  83 
  84         // Objects must not be equal as the decimalPattern is different
  85         checkEquals(cnf3, cnf4, false, "1st", "different decimal pattern");
  86 
  87         // Objects must not be equal as the format symbols instance is different
  88         checkEquals(cnf3, cnf5, false, "2nd", "different format symbols");
  89 
  90         // Objects must not be equal as the compact patters are different
  91         checkEquals(cnf3, cnf6, false, "3rd", "different compact patterns");
  92 
  93         // Changing the min integer digits of first object; objects must not
  94         // be equal
  95         cnf1.setMinimumIntegerDigits(5);
  96         checkEquals(cnf1, cnf2, false, "4th", "different min integer digits");
  97 
  98         // Changing the min integer digits of second object; objects must
  99         // be equal
 100         cnf2.setMinimumIntegerDigits(5);
 101         checkEquals(cnf1, cnf2, true, "5th", "");
 102 
 103         // Changing the grouping size of first object; objects must not
 104         // be equal
 105         cnf1.setGroupingSize(4);
 106         checkEquals(cnf1, cnf2, false, "6th", "different grouping size");
 107 
 108         // Changing the grouping size if second object; objects must be equal
 109         cnf2.setGroupingSize(4);
 110         checkEquals(cnf1, cnf2, true, "7th", "");
 111 
 112         // Changing the parseBigDecimal of first object; objects must not
 113         // be equal
 114         cnf1.setParseBigDecimal(true);
 115         checkEquals(cnf1, cnf2, false, "8th", "different parse big decimal");
 116 
 117     }
 118 
 119     private void checkEquals(CompactNumberFormat cnf1, CompactNumberFormat cnf2,
 120             boolean mustEqual, String nthComparison, String message) {
 121         if (cnf1.equals(cnf2) != mustEqual) {
 122             if (mustEqual) {
 123                 throw new RuntimeException("[testEquality() " + nthComparison
 124                         + " comparison FAILED: The compared objects must be equal]");
 125             } else {
 126                 throw new RuntimeException("[testEquality() " + nthComparison
 127                         + " comparison FAILED: The compared objects must"
 128                         + " not be equal because of " + message + "]");
 129             }
 130         }
 131     }
 132 
 133     @Test
 134     public void testHashCode() {
 135         NumberFormat cnf1 = NumberFormat
 136                 .getCompactNumberInstance(Locale.JAPAN, NumberFormat.Style.SHORT);
 137         NumberFormat cnf2 = NumberFormat
 138                 .getCompactNumberInstance(Locale.JAPAN, NumberFormat.Style.SHORT);
 139 
 140         if (cnf1.hashCode() != cnf2.hashCode()) {
 141             throw new RuntimeException("[testHashCode() FAILED: hashCode of the"
 142                     + " compared objects must match]");
 143         }
 144     }
 145 
 146     // Test the property of equals and hashCode i.e. two equal object must
 147     // always have the same hashCode
 148     @Test
 149     public void testEqualsAndHashCode() {
 150         NumberFormat cnf1 = NumberFormat
 151                 .getCompactNumberInstance(new Locale("hi", "IN"), NumberFormat.Style.SHORT);
 152         cnf1.setMinimumIntegerDigits(5);
 153         NumberFormat cnf2 = NumberFormat
 154                 .getCompactNumberInstance(new Locale("hi", "IN"), NumberFormat.Style.SHORT);
 155         cnf2.setMinimumIntegerDigits(5);
 156         if (cnf1.equals(cnf2)) {
 157             if (cnf1.hashCode() != cnf2.hashCode()) {
 158                 throw new RuntimeException("[testEqualsAndHashCode() FAILED: two"
 159                         + " equal objects must have same hashCode]");
 160             }
 161         } else {
 162             throw new RuntimeException("[testEqualsAndHashCode() FAILED: The"
 163                     + " compared objects must be equal]");
 164         }
 165     }
 166 
 167 }