1 /*
   2  * Copyright (c) 2012, 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 7050528
  26  * @summary Test java.text.DecimalFormat fast-path for format(double...)
  27  * @author Olivier Lagneau
  28  * @run main RoundingAndPropertyTest
  29  *
  30  */
  31 
  32 /* -----------------------------------------------------------------------------
  33  * Note :
  34  *  Since fast-path algorithm   does not modify  any feature  of DecimalFormat,
  35  *  some tests or  values in this program  may have to be adapted/added/removed
  36  *  when any change has been done in the fast-path source  code, because the
  37  *  conditions for exercising fast-path may change.
  38  *
  39  *  This is specially true if the set of constraints to fall in the fast-path
  40  *  case is relaxed in any manner.
  41  *
  42  * Usage :
  43  *  - Run main without any argument to test against a set of golden values and
  44  *    associated results hard-coded in the source code. That will do the tests
  45  *    described below
  46  *    See below comment section named "Description".
  47  *
  48  *  or
  49  *
  50  *  - Run main with string argument "-gengold" to output source code of
  51  *    GoldenFormattedValues.java class file with the jdk version used while
  52  *    generating the code.
  53  *    See below comment section named : "Modifying Golden Values".
  54  *
  55  *  In case of error while running the test, a Runtime exception is generated
  56  *  providing the numbers of errors detected (format of golden values checks and
  57  *  property changes checks), and the program exit.
  58  *
  59  * Description :
  60  *
  61  *  This test first checks that localization of digits is done correctly when
  62  *  calling DecimalFormat.format() on the array of values DecimalLocalizationValues
  63  *  found in GoldenDoubleValues, using the locale FullLocalizationTestLocale
  64  *  (from GoldenDoubleValues) that implies localization of digits. it checks the
  65  *  the results against expected returned string. In case of formatting error,
  66  *  it provides a message informing which value was wrongly formatted.
  67  *
  68  *  Then it checks the results of  calling NumberFormat.format(double) on a set
  69  *  of  predefined golden values and  checks results against expected returned
  70  *  string.  It does this both for the  decimal case, with an instance returned
  71  *  NumberFormat.getInstance() call and for the currency case, with an instance
  72  *  returned by NumberFormat.getCurrencyInstance(). Almost all the tested  double
  73  *  values satisfy the constraints assumed by the fast-path algorithm for
  74  *  format(double ...). Some  are voluntarily outside the scope of fast-path to
  75  *  check that the algorithm correctly eliminate them. In case of formatting
  76  *  error a message provides information on the golden value raising the error
  77  *  (value, exact decimal value (using BidDecimal), expected result, formatted result).
  78  *
  79  *  Last  the test checks the status and  behavior of a DecimalFormat instance
  80  *  when changing  properties that  make this  instance  satisfy/invalidate its
  81  *  fast-path status, depending on the predefined  set of fast-path constraints.
  82  *
  83  *  The golden  results are predefined arrays  of  int[] containing the unicode
  84  *  ints of the chars  in  the expected  formatted  string, when  using  locale
  85  *  provided in  GoldenDoubleValues class. The   results are those obtained  by
  86  *  using a reference jdk  version (for example  one that does not contains the
  87  *  DecimalFormat fast-path algorithm, like jdk80-b25).
  88  *
  89  *  The double values from which we get golden results are stored inside two
  90  *  arrays of double values:
  91  *  - DecimalGoldenValues  for testing NumberFormat.getInstance().
  92  *  - CurrencyGoldenValues for testing NumberFormat.getCurrencyInstance().
  93  *  These arrays are located in GoldenDoubleValues.java source file.
  94  *
  95  *  For each double value in the arrays above, there is an associated golden
  96  *  result. These results are stored in arrays of int[]:
  97  *  - DecimalGoldenFormattedValues  for expected decimal golden results.
  98  *  - CurrencyGoldenFormattedValues for expected currency golden results.
  99  *  - DecimalDigitsLocalizedFormattedValues for expected localized digit results.
 100  *
 101  *  We store the results in int[] arrays containing the expected unicode values
 102  *  because the  compiler that will compile the  containing java file may use a
 103  *  different locale than the one registered in GoldenDoubleValues.java.  These
 104  *  arrays are  located in  a  separate GoldenFormattedValues.java  source file
 105  *  that is generated  by  RoundingAndPropertyTest using  "-gengold"  parameter.
 106  *  See below "Modifying Golden Values".
 107  *
 108  *  The golden value arrays can be expanded, modified ... to test additional
 109  *  or different double values. In that case, the source file of class
 110  *  GoldenFormattedValues must be regenerated to replace the existing one..
 111  *
 112  * Modifying Golden Values :
 113  *
 114  *  In order to ease further modification of the list of double values checked
 115  *  and associated golden results, the test includes the method
 116  *  generatesGoldenFormattedValuesClass() that writes on standard output stream
 117  *  the source code for GoldenFormattedValues class that includes the expected
 118  *  results arrays.
 119  *
 120  *  Here are the steps to follow for updating/modifying golden values and results:
 121  *   1- Edit GoldenDoubleValues.java to add/remove/modify golden or localization
 122  *      values.
 123  *   2- Run main with "-gengold" string argument with a target jdk.
 124  *      (at the creation of this test file, the target jdk used was jdk1.8.0-ea).
 125  *   2- Copy this java code that has been writen on standard output and replace
 126  *      GoldenFormattedValues.java contents by the generated output.
 127  *   3- Check that this updated code compiles.
 128  *  [4]- If needed replaces existing GoldenDoubleValues and GoldenFormattedValues
 129  *      files in jdk/test section, respectively by the one modified at step 1 and
 130  *      generated at step 2.
 131  * -----------------------------------------------------------------------------
 132  */
 133 
 134 import java.util.*;
 135 import java.text.NumberFormat;
 136 import java.text.DecimalFormat;
 137 import java.text.DecimalFormatSymbols;
 138 import java.math.RoundingMode;
 139 import java.math.BigDecimal;
 140 
 141 
 142 public class RoundingAndPropertyTest {
 143 
 144 
 145     // Prints on standard output stream the unicode values of chars as a
 146     // comma-separated list of int values
 147     private static void printUnicodeValuesArray(char[] chars) {
 148         for (int i = 0; i < chars.length; i++) {
 149             System.out.print((int) chars[i]);
 150             if (i != (chars.length - 1))
 151                 System.out.print(", ");
 152         }
 153     }
 154 
 155     // Converts given array of unicode values as an array of chars.
 156     // Returns this converted array.
 157     private static char[] getCharsFromUnicodeArray(int[] unicodeValues) {
 158         char[] chars = new char[unicodeValues.length];
 159 
 160         for (int i = 0; i < unicodeValues.length; i++) {
 161             chars[i] = (char) unicodeValues[i];
 162         }
 163         return chars;
 164     }
 165 
 166     /* Prints on standard output stream the java code of resulting
 167      * GoldenFormattedValues class for the golden values found in
 168      * class GoldenDoubleValues.
 169      */
 170     private static void generatesGoldenFormattedValuesClass() {
 171 
 172         String fourWhiteSpaces    = "    ";
 173         String eightWhiteSpaces   = "        ";
 174 
 175         // Prints header without Copyright header.
 176         System.out.println("/* This is a machine generated file - Please DO NOT EDIT !");
 177         System.out.println(" * Change RoundingAndPropertyTest instead,");
 178         System.out.println(" * and run with \"-gengold\" argument to regenerate (without copyright header).");
 179         System.out.println(" */");
 180         System.out.println();
 181 
 182         System.out.println("/* This file contains the set of result Strings expected from calling inside");
 183         System.out.println(" * RoundingAndPropertyTest the method NumberFormat.format() upon the set of");
 184         System.out.println(" * double values provided in GoldenDoubleValues.java. It contains three arrays,");
 185         System.out.println(" * each containing arrays of unicode values representing the expected string");
 186         System.out.println(" * result when calling format() on the corresponding (i.e. same index) double");
 187         System.out.println(" * value found in GoldenDoubleValues arrays :");
 188         System.out.println(" * - DecimalDigitsLocalizedFormattedValues corresponds to DecimalLocalizationValues,");
 189         System.out.println(" *   when using FullLocalizationTestLocale to format.");
 190         System.out.println(" * - DecimalGoldenFormattedValues corresponds to DecimalGoldenValues, when used");
 191         System.out.println(" *   in the decimal pattern case together with TestLocale.");
 192         System.out.println(" * - CurrencyGoldenFormattedValues corresponds to CurrencyGoldenValues. when used");
 193         System.out.println(" *   in the currency pattern case together with TestLocale.");
 194         System.out.println(" * Please see documentation in RoundingAndPropertyTest.java for more details.");
 195         System.out.println(" *");
 196         System.out.println(" * This file generated by running RoundingAndPropertyTest with \"-gengold\" argument.");
 197         System.out.println(" */");
 198         System.out.println();
 199 
 200         // Prints beginning of class GoldenFormattedValues.
 201         System.out.println("class GoldenFormattedValues {");
 202         System.out.println();
 203         System.out.println(
 204             fourWhiteSpaces +
 205             "// The formatted values below were generated from golden values");
 206         System.out.print(
 207             fourWhiteSpaces +
 208             "// listed in GoldenDoubleValues.java,");
 209         System.out.println(" using the following jvm version :");
 210         System.out.println(
 211             fourWhiteSpaces + "//   " +
 212             System.getProperty("java.vendor") +
 213             " " +
 214             System.getProperty("java.vm.name") +
 215             " " +
 216             System.getProperty("java.version"));
 217         System.out.println(
 218             fourWhiteSpaces +
 219             "//   locale for golden double values : " + GoldenDoubleValues.TestLocale);
 220         System.out.println(
 221             fourWhiteSpaces +
 222             "//   locale for testing digit localization : " + GoldenDoubleValues.FullLocalizationTestLocale);
 223         System.out.println();
 224 
 225         // Prints the expected results when digit localization happens
 226         System.out.println(
 227             fourWhiteSpaces +
 228             "// The array of int[] unicode values storing the expected results");
 229         System.out.print(
 230             fourWhiteSpaces +
 231             "// when experiencing full localization of digits");
 232         System.out.println(" on DecimalLocalizationValues.");
 233         System.out.println(
 234             fourWhiteSpaces +
 235             "static int[][] DecimalDigitsLocalizedFormattedValues = {");
 236         NumberFormat df =
 237             NumberFormat.getInstance(GoldenDoubleValues.FullLocalizationTestLocale);
 238         for (int i = 0;
 239              i < GoldenDoubleValues.DecimalLocalizationValues.length;
 240              i++) {
 241             double d = GoldenDoubleValues.DecimalLocalizationValues[i];
 242             String formatted = df.format(d);
 243             char[] decFmtChars = formatted.toCharArray();
 244 
 245             System.out.print(eightWhiteSpaces + "{ ");
 246             printUnicodeValuesArray(decFmtChars);
 247             System.out.println(" },");
 248         }
 249         System.out.println(fourWhiteSpaces + "};");
 250         System.out.println();
 251 
 252         // Prints the golden expected results for the decimal pattern case
 253         System.out.println(
 254             fourWhiteSpaces +
 255             "// The array of int[] unicode values storing the expected results");
 256         System.out.print(
 257             fourWhiteSpaces +
 258             "// when calling Decimal.format(double)");
 259         System.out.println(" on the decimal GoldenDoubleValues.");
 260         System.out.println(
 261             fourWhiteSpaces +
 262             "static int[][] DecimalGoldenFormattedValues = {");
 263         df = NumberFormat.getInstance(GoldenDoubleValues.TestLocale);
 264         for (int i = 0;
 265              i < GoldenDoubleValues.DecimalGoldenValues.length;
 266              i++) {
 267             double d = GoldenDoubleValues.DecimalGoldenValues[i];
 268             String formatted = df.format(d);
 269             char[] decFmtChars = formatted.toCharArray();
 270 
 271             System.out.print(eightWhiteSpaces + "{ ");
 272             printUnicodeValuesArray(decFmtChars);
 273             System.out.println(" },");
 274         }
 275         System.out.println(fourWhiteSpaces + "};");
 276         System.out.println();
 277 
 278         // Prints the golden expected results for the currency pattern case
 279         System.out.println(
 280             fourWhiteSpaces +
 281             "// The array of int[] unicode values storing the expected results");
 282         System.out.print(
 283             fourWhiteSpaces +
 284             "// when calling Decimal.format(double)");
 285         System.out.println(" on the currency GoldenDoubleValues.");
 286         System.out.println(
 287             fourWhiteSpaces +
 288             "static int[][] CurrencyGoldenFormattedValues = {");
 289         NumberFormat cf =
 290             NumberFormat.getCurrencyInstance(GoldenDoubleValues.TestLocale);
 291         for (int i = 0;
 292              i < GoldenDoubleValues.CurrencyGoldenValues.length;
 293              i++) {
 294             double d = GoldenDoubleValues.CurrencyGoldenValues[i];
 295             String formatted = cf.format(d);
 296             char[] decFmtChars = formatted.toCharArray();
 297 
 298             System.out.print(eightWhiteSpaces + "{ ");
 299             printUnicodeValuesArray(decFmtChars);
 300             System.out.println(" },");
 301         }
 302         System.out.println(fourWhiteSpaces + "};");
 303         System.out.println();
 304 
 305         // Prints end of GoldenFormattedValues class.
 306         System.out.println("}");
 307     }
 308 
 309     private static int testLocalizationValues() {
 310 
 311         DecimalFormat df = (DecimalFormat)
 312             NumberFormat.getInstance(GoldenDoubleValues.FullLocalizationTestLocale);
 313 
 314         double[] localizationValues = GoldenDoubleValues.DecimalLocalizationValues;
 315         int size = localizationValues.length;
 316         int successCounter = 0;
 317         int failureCounter = 0;
 318         for (int i = 0; i < size; i++) {
 319 
 320             double d = localizationValues[i];
 321             String formatted = df.format(d);
 322 
 323             char[] expectedUnicodeArray =
 324                 getCharsFromUnicodeArray(
 325                     GoldenFormattedValues.DecimalDigitsLocalizedFormattedValues[i]);
 326             String expected = new String(expectedUnicodeArray);
 327 
 328             if (!formatted.equals(expected)) {
 329                 failureCounter++;
 330                 System.out.println(
 331                     "--- Localization error for value d = " + d +
 332                     ". Exact value = " + new BigDecimal(d).toString() +
 333                     ". Expected result = " + expected +
 334                     ". Output result = " + formatted);
 335             } else successCounter++;
 336         }
 337         System.out.println("Checked positively " + successCounter +
 338                            " golden decimal values out of " + size +
 339                            " tests. There were " + failureCounter +
 340                            " format failure");
 341 
 342         return failureCounter;
 343     }
 344 
 345     private static int testGoldenValues(java.text.DecimalFormat df,
 346                                         java.text.DecimalFormat cf) {
 347 
 348         double[] goldenDecimalValues = GoldenDoubleValues.DecimalGoldenValues;
 349         int decimalSize = goldenDecimalValues.length;
 350         int decimalSuccessCounter = 0;
 351         int decimalFailureCounter = 0;
 352         for (int i = 0; i < decimalSize; i++) {
 353 
 354             double d = goldenDecimalValues[i];
 355             String formatted = df.format(d);
 356 
 357             char[] expectedUnicodeArray =
 358                 getCharsFromUnicodeArray(
 359                     GoldenFormattedValues.DecimalGoldenFormattedValues[i]);
 360             String expected = new String(expectedUnicodeArray);
 361 
 362             if (!formatted.equals(expected)) {
 363                 decimalFailureCounter++;
 364                 System.out.println(
 365                     "--- Error for golden value d = " + d +
 366                     ". Exact value = " + new BigDecimal(d).toString() +
 367                     ". Expected result = " + expected +
 368                     ". Output result = " + formatted);
 369             } else decimalSuccessCounter++;
 370         }
 371         System.out.println("Checked positively " + decimalSuccessCounter +
 372                            " golden decimal values out of " + decimalSize +
 373                            " tests. There were " + decimalFailureCounter +
 374                            " format failure");
 375 
 376         double[] goldenCurrencyValues = GoldenDoubleValues.CurrencyGoldenValues;
 377         int currencySize = goldenCurrencyValues.length;
 378         int currencySuccessCounter = 0;
 379         int currencyFailureCounter = 0;
 380         for (int i = 0; i < currencySize; i++) {
 381             double d = goldenCurrencyValues[i];
 382             String formatted = cf.format(d);
 383 
 384             char[] expectedUnicodeArray =
 385                 getCharsFromUnicodeArray(
 386                     GoldenFormattedValues.CurrencyGoldenFormattedValues[i]);
 387             String expected = new String(expectedUnicodeArray);
 388 
 389             if (!formatted.equals(expected)) {
 390                 currencyFailureCounter++;
 391                 System.out.println(
 392                     "--- Error for golden value d = " + d +
 393                     ". Exact value = " + new BigDecimal(d).toString() +
 394                     ". Expected result = " + expected +
 395                     ". Output result = " + formatted);
 396             } else currencySuccessCounter++;
 397         }
 398         System.out.println("Checked positively " + currencySuccessCounter +
 399                            " golden currency values out of " + currencySize +
 400                            " tests. There were " + currencyFailureCounter +
 401                            " format failure");
 402 
 403         return (decimalFailureCounter + currencyFailureCounter);
 404     }
 405 
 406     // Checks that the two passed s1 and s2 string are equal, and prints
 407     // out message in case of error.
 408     private static boolean resultsEqual(String propertyName,
 409                                         String s1,
 410                                         String s2) {
 411 
 412         boolean equality = s1.equals(s2);
 413         if (!equality)
 414             System.out.println(
 415                 "\n*** Error while reverting to default " +
 416                 propertyName + " property.\n" +
 417                 "    initial output = " + s1 +
 418                 ". reverted output = " + s2 + ".");
 419         else System.out.println(" Test passed.");
 420 
 421         return equality;
 422 
 423     }
 424 
 425     /* This methods checks the behaviour of the management of properties
 426      * of a DecimalFormat instance that satisfies fast-path constraints.
 427      *
 428      * It does this by comparing the results of the format(double) output
 429      * obtained from initial fast-path state with the output provided by
 430      * the same instance that has been pushed and exercised outside
 431      * fast-path rules and finally "reverted" to its initial fast-path state.
 432      *
 433      * The schema of actions is this :
 434      *  - Call format(double) on a known DecimalFormat fast-path instance,
 435      *    and store this result.
 436      *  - Record the current state of a given property.
 437      *  - Change the property to invalidate the fast-path state.
 438      *  - Call again format(double) on the instance.
 439      *  - Revert state of property to validate again fast-path context.
 440      *  - Call format(double) again.
 441      *  - Check that first and last call to format(double) provide same result
 442      *  - Record failure if any.
 443      *  - Do the same for another property with the same instance.
 444      * So all the property changes are chained one after the other on only the
 445      * same instance.
 446      *
 447      * Some properties that currently do not influence the fast-path state
 448      * are also tested. This is not useful with current fast-path source
 449      * but is here for testing the whole set of properties. This is the case
 450      * for prefixes and suffixes, and parseBigDecimal properties.
 451      */
 452     private static int testSettersAndFastPath(DecimalFormat df,
 453                                                boolean isCurrency) {
 454 
 455         final double d1 = GoldenDoubleValues.PROPERTY_CHECK_POSITIVE_VALUE;
 456         final double d2 = GoldenDoubleValues.PROPERTY_CHECK_NEGATIVE_VALUE;
 457 
 458         int errors = 0;
 459         boolean testSucceeded = false;
 460         String firstFormatResult;
 461         String secondFormatResult;
 462         String propertyName;
 463 
 464         // ---- positivePrefix property test ----
 465         testSucceeded = false;
 466         propertyName = "positivePrefix";
 467         System.out.print("Checking " + propertyName + " property.");
 468         String initialPrefix = df.getPositivePrefix();
 469         firstFormatResult = df.format(d1);
 470         df.setPositivePrefix("positivePrefix:");
 471         df.format(d1);
 472         df.setPositivePrefix(initialPrefix);
 473         secondFormatResult = df.format(d1);
 474         testSucceeded =
 475             resultsEqual(propertyName, firstFormatResult, secondFormatResult);
 476         if (!testSucceeded)
 477             errors++;
 478 
 479         // ---- positiveSuffix property test ----
 480         testSucceeded = false;
 481         propertyName = "positiveSuffix";
 482         System.out.print("Checking " + propertyName + " property.");
 483         String initialSuffix = df.getPositiveSuffix();
 484         firstFormatResult = df.format(d1);
 485         df.setPositiveSuffix("positiveSuffix:");
 486         df.format(d1);
 487         df.setPositiveSuffix(initialSuffix);
 488         secondFormatResult = df.format(d1);
 489         testSucceeded =
 490             resultsEqual(propertyName,firstFormatResult, secondFormatResult);
 491         if (!testSucceeded)
 492             errors++;
 493 
 494         // ---- negativePrefix property test ----
 495         testSucceeded = false;
 496         propertyName = "negativePrefix";
 497         System.out.print("Checking " + propertyName + " property.");
 498         initialPrefix = df.getNegativePrefix();
 499         firstFormatResult = df.format(d1);
 500         df.setNegativePrefix("negativePrefix:");
 501         df.format(d1);
 502         df.setNegativePrefix(initialPrefix);
 503         secondFormatResult = df.format(d1);
 504         testSucceeded =
 505             resultsEqual(propertyName, firstFormatResult, secondFormatResult);
 506         if (!testSucceeded)
 507             errors++;
 508 
 509         // ---- negativeSuffix property test ----
 510         testSucceeded = false;
 511         propertyName = "negativeSuffix";
 512         System.out.print("Checking " + propertyName + " property.");
 513         initialSuffix = df.getNegativeSuffix();
 514         firstFormatResult = df.format(d1);
 515         df.setNegativeSuffix("negativeSuffix:");
 516         df.format(d1);
 517         df.setNegativeSuffix(initialSuffix);
 518         secondFormatResult = df.format(d1);
 519         testSucceeded =
 520             resultsEqual(propertyName, firstFormatResult, secondFormatResult);
 521         if (!testSucceeded)
 522             errors++;
 523 
 524         // ---- multiplier property test ----
 525         testSucceeded = false;
 526         propertyName = "multiplier";
 527         System.out.print("Checking " + propertyName + " property.");
 528         int initialMultiplier = df.getMultiplier();
 529         firstFormatResult = df.format(d1);
 530         df.setMultiplier(10);
 531         df.format(d1);
 532         df.setMultiplier(initialMultiplier);
 533         secondFormatResult = df.format(d1);
 534         testSucceeded =
 535             resultsEqual(propertyName, firstFormatResult, secondFormatResult);
 536         if (!testSucceeded)
 537             errors++;
 538 
 539         // ---- groupingUsed property test ----
 540         testSucceeded = false;
 541         propertyName = "groupingUsed";
 542         System.out.print("Checking " + propertyName + " property.");
 543         boolean initialGroupingUsed = df.isGroupingUsed();
 544         firstFormatResult = df.format(d1);
 545         df.setGroupingUsed(!initialGroupingUsed);
 546         df.format(d1);
 547         df.setGroupingUsed(initialGroupingUsed);
 548         secondFormatResult = df.format(d1);
 549         testSucceeded =
 550             resultsEqual(propertyName, firstFormatResult, secondFormatResult);
 551         if (!testSucceeded)
 552             errors++;
 553 
 554         // ---- groupingSize property test ----
 555         testSucceeded = false;
 556         propertyName = "groupingSize";
 557         System.out.print("Checking " + propertyName + " property.");
 558         int initialGroupingSize = df.getGroupingSize();
 559         firstFormatResult = df.format(d1);
 560         df.setGroupingSize(initialGroupingSize + 1);
 561         df.format(d1);
 562         df.setGroupingSize(initialGroupingSize);
 563         secondFormatResult = df.format(d1);
 564         testSucceeded =
 565             resultsEqual(propertyName, firstFormatResult, secondFormatResult);
 566         if (!testSucceeded)
 567             errors++;
 568 
 569         // ---- decimalSeparatorAlwaysShown property test ----
 570         testSucceeded = false;
 571         propertyName = "decimalSeparatorAlwaysShown";
 572         System.out.print("Checking " + propertyName + " property.");
 573         boolean initialDSShown = df.isDecimalSeparatorAlwaysShown();
 574         firstFormatResult = df.format(d1);
 575         df.setDecimalSeparatorAlwaysShown(!initialDSShown);
 576         df.format(d1);
 577         df.setDecimalSeparatorAlwaysShown(initialDSShown);
 578         secondFormatResult = df.format(d1);
 579         testSucceeded =
 580             resultsEqual(propertyName, firstFormatResult, secondFormatResult);
 581         if (!testSucceeded)
 582             errors++;
 583 
 584         // ---- parseBigDecimal property test ----
 585         testSucceeded = false;
 586         propertyName = "parseBigDecimal";
 587         System.out.print("Checking " + propertyName + " property.");
 588         boolean initialParseBigdecimal = df.isParseBigDecimal();
 589         firstFormatResult = df.format(d1);
 590         df.setParseBigDecimal(!initialParseBigdecimal);
 591         df.format(d1);
 592         df.setParseBigDecimal(initialParseBigdecimal);
 593         secondFormatResult = df.format(d1);
 594         testSucceeded =
 595             resultsEqual(propertyName, firstFormatResult, secondFormatResult);
 596         if (!testSucceeded)
 597             errors++;
 598 
 599         // ---- maximumIntegerDigits property test ----
 600         testSucceeded = false;
 601         propertyName = "maximumIntegerDigits";
 602         System.out.print("Checking " + propertyName + " property.");
 603         int initialMaxIDs = df.getMaximumIntegerDigits();
 604         firstFormatResult = df.format(d1);
 605         df.setMaximumIntegerDigits(8);
 606         df.format(d1);
 607         df.setMaximumIntegerDigits(initialMaxIDs);
 608         secondFormatResult = df.format(d1);
 609         testSucceeded =
 610             resultsEqual(propertyName, firstFormatResult, secondFormatResult);
 611         if (!testSucceeded)
 612             errors++;
 613 
 614         // ---- minimumIntegerDigits property test ----
 615         testSucceeded = false;
 616         propertyName = "minimumIntegerDigits";
 617         System.out.print("Checking " + propertyName + " property.");
 618         int initialMinIDs = df.getMinimumIntegerDigits();
 619         firstFormatResult = df.format(d1);
 620         df.setMinimumIntegerDigits(2);
 621         df.format(d1);
 622         df.setMinimumIntegerDigits(initialMinIDs);
 623         secondFormatResult = df.format(d1);
 624         testSucceeded =
 625             resultsEqual(propertyName, firstFormatResult, secondFormatResult);
 626         if (!testSucceeded)
 627             errors++;
 628 
 629         // ---- maximumFractionDigits property test ----
 630         testSucceeded = false;
 631         propertyName = "maximumFractionDigits";
 632         System.out.print("Checking " + propertyName + " property.");
 633         firstFormatResult = df.format(d1);
 634         df.setMaximumFractionDigits(8);
 635         df.format(d1);
 636         if (isCurrency) {
 637             df.setMinimumFractionDigits(2);
 638             df.setMaximumFractionDigits(2);
 639         } else {
 640             df.setMinimumFractionDigits(0);
 641             df.setMaximumFractionDigits(3);
 642         }
 643         secondFormatResult = df.format(d1);
 644         testSucceeded =
 645             resultsEqual(propertyName, firstFormatResult, secondFormatResult);
 646         if (!testSucceeded)
 647             errors++;
 648 
 649         // ---- minimumFractionDigits property test ----
 650         testSucceeded = false;
 651         propertyName = "minimumFractionDigits";
 652         System.out.print("Checking " + propertyName + " property.");
 653         firstFormatResult = df.format(d1);
 654         df.setMinimumFractionDigits(1);
 655         df.format(d1);
 656         if (isCurrency) {
 657             df.setMinimumFractionDigits(2);
 658             df.setMaximumFractionDigits(2);
 659         } else {
 660             df.setMinimumFractionDigits(0);
 661             df.setMaximumFractionDigits(3);
 662         }
 663         secondFormatResult = df.format(d1);
 664         testSucceeded =
 665             resultsEqual(propertyName, firstFormatResult, secondFormatResult);
 666         if (!testSucceeded)
 667             errors++;
 668 
 669         // ---- currency property test ----
 670         testSucceeded = false;
 671         propertyName = "currency";
 672         System.out.print("Checking " + propertyName + " property.");
 673         Currency initialCurrency = df.getCurrency();
 674         Currency japanCur = java.util.Currency.getInstance(Locale.JAPAN);
 675         firstFormatResult = df.format(d1);
 676         df.setCurrency(japanCur);
 677         df.format(d1);
 678         df.setCurrency(initialCurrency);
 679         secondFormatResult = df.format(d1);
 680         testSucceeded =
 681             resultsEqual(propertyName, firstFormatResult, secondFormatResult);
 682         if (!testSucceeded)
 683             errors++;
 684 
 685         // ---- roundingMode property test ----
 686         testSucceeded = false;
 687         propertyName = "roundingMode";
 688         System.out.print("Checking " + propertyName + " property.");
 689         RoundingMode initialRMode = df.getRoundingMode();
 690         firstFormatResult = df.format(d1);
 691         df.setRoundingMode(RoundingMode.HALF_UP);
 692         df.format(d1);
 693         df.setRoundingMode(RoundingMode.HALF_EVEN);
 694         secondFormatResult = df.format(d1);
 695         testSucceeded =
 696             resultsEqual(propertyName, firstFormatResult, secondFormatResult);
 697         if (!testSucceeded)
 698             errors++;
 699 
 700         // ---- decimalFormatSymbols property test ----
 701         testSucceeded = false;
 702         propertyName = "decimalFormatSymbols";
 703         System.out.print("Checking " + propertyName + " property.");
 704         DecimalFormatSymbols initialDecimalFormatSymbols = df.getDecimalFormatSymbols();
 705         firstFormatResult = df.format(d1);
 706         Locale bizarreLocale = new Locale("fr", "FR");
 707         DecimalFormatSymbols unusualSymbols = new DecimalFormatSymbols(bizarreLocale);
 708         unusualSymbols.setDecimalSeparator('@');
 709         unusualSymbols.setGroupingSeparator('|');
 710         df.setDecimalFormatSymbols(unusualSymbols);
 711         df.format(d1);
 712         df.setDecimalFormatSymbols(initialDecimalFormatSymbols);
 713         secondFormatResult = df.format(d1);
 714         testSucceeded =
 715             resultsEqual(propertyName, firstFormatResult, secondFormatResult);
 716         if (!testSucceeded)
 717             errors++;
 718 
 719         testSucceeded = false;
 720         System.out.print("Checking " + propertyName + " property.");
 721         initialDecimalFormatSymbols = df.getDecimalFormatSymbols();
 722         firstFormatResult = df.format(d1);
 723         Locale japanLocale = Locale.JAPAN;
 724         unusualSymbols = new DecimalFormatSymbols(japanLocale);
 725         unusualSymbols.setDecimalSeparator('9');
 726         unusualSymbols.setGroupingSeparator('0');
 727         df.setDecimalFormatSymbols(unusualSymbols);
 728         df.format(d1);
 729         df.setDecimalFormatSymbols(initialDecimalFormatSymbols);
 730         secondFormatResult = df.format(d1);
 731         testSucceeded =
 732             resultsEqual(propertyName, firstFormatResult, secondFormatResult);
 733         if (!testSucceeded)
 734             errors++;
 735 
 736         return errors;
 737     }
 738 
 739     // Main for RoundingAndPropertyTest. We test first the golden values,
 740     // and then the property setters and getters.
 741     public static void main(String[] args) {
 742 
 743         if ((args.length >= 1) &&
 744             (args[0].equals("-gengold")))
 745             generatesGoldenFormattedValuesClass();
 746         else {
 747             System.out.println("\nChecking correctness of formatting with digit localization.");
 748             System.out.println("=============================================================");
 749             int localizationErrors = testLocalizationValues();
 750             if (localizationErrors != 0)
 751                 System.out.println("*** Failure in localization tests : " +
 752                                    localizationErrors + " errors detected ");
 753             else System.out.println(" Tests for full localization of digits all passed.");
 754 
 755             DecimalFormat df = (DecimalFormat)
 756                 NumberFormat.getInstance(GoldenDoubleValues.TestLocale);
 757             DecimalFormat cf = (DecimalFormat)
 758                 NumberFormat.getCurrencyInstance(GoldenDoubleValues.TestLocale);
 759 
 760             System.out.println("\nChecking correctness of formating for golden values.");
 761             System.out.println("=============================================================");
 762             int goldenValuesErrors = testGoldenValues(df,cf);
 763             if (goldenValuesErrors != 0)
 764                 System.out.println("*** Failure in goldenValues tests : " +
 765                                    goldenValuesErrors + " errors detected ");
 766             else System.out.println(" Tests for golden values all passed.");
 767 
 768             System.out.println("\nChecking behavior of property changes for decimal case.");
 769             System.out.println("=============================================================");
 770             int decimalTestsErrors = testSettersAndFastPath(df, false);
 771             if (decimalTestsErrors != 0)
 772                 System.out.println("*** Failure in decimal property changes tests : " +
 773                                    decimalTestsErrors + " errors detected ");
 774             else System.out.println(" Tests for decimal property changes all passed.");
 775 
 776             System.out.println("\nChecking behavior of property changes for currency case.");
 777             System.out.println("=============================================================");
 778             int currencyTestsErrors = testSettersAndFastPath(cf, true);
 779             if (currencyTestsErrors != 0)
 780                 System.out.println("*** Failure in currency property changes tests : " +
 781                                    currencyTestsErrors + " errors detected ");
 782             else System.out.println(" Tests for currency property chamges all passed.");
 783 
 784             if ((localizationErrors > 0) ||
 785                 (goldenValuesErrors > 0) ||
 786                 (decimalTestsErrors > 0) ||
 787                 (currencyTestsErrors > 0))
 788                 throw new RuntimeException(
 789                     "Failed with " +
 790                     (localizationErrors + goldenValuesErrors +
 791                      decimalTestsErrors + currencyTestsErrors) +
 792                     " error(s).");
 793         }
 794     }
 795 }