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