undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
|
|
@ -0,0 +1,796 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 7050528
|
||||
* @summary Test java.text.DecimalFormat fast-path for format(double...)
|
||||
* @author Olivier Lagneau
|
||||
* @build GoldenDoubleValues GoldenFormattedValues
|
||||
* @run main RoundingAndPropertyTest
|
||||
*
|
||||
*/
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
* Note :
|
||||
* Since fast-path algorithm does not modify any feature of DecimalFormat,
|
||||
* some tests or values in this program may have to be adapted/added/removed
|
||||
* when any change has been done in the fast-path source code, because the
|
||||
* conditions for exercising fast-path may change.
|
||||
*
|
||||
* This is specially true if the set of constraints to fall in the fast-path
|
||||
* case is relaxed in any manner.
|
||||
*
|
||||
* Usage :
|
||||
* - Run main without any argument to test against a set of golden values and
|
||||
* associated results hard-coded in the source code. That will do the tests
|
||||
* described below
|
||||
* See below comment section named "Description".
|
||||
*
|
||||
* or
|
||||
*
|
||||
* - Run main with string argument "-gengold" to output source code of
|
||||
* GoldenFormattedValues.java class file with the jdk version used while
|
||||
* generating the code.
|
||||
* See below comment section named : "Modifying Golden Values".
|
||||
*
|
||||
* In case of error while running the test, a Runtime exception is generated
|
||||
* providing the numbers of errors detected (format of golden values checks and
|
||||
* property changes checks), and the program exit.
|
||||
*
|
||||
* Description :
|
||||
*
|
||||
* This test first checks that localization of digits is done correctly when
|
||||
* calling DecimalFormat.format() on the array of values DecimalLocalizationValues
|
||||
* found in GoldenDoubleValues, using the locale FullLocalizationTestLocale
|
||||
* (from GoldenDoubleValues) that implies localization of digits. it checks the
|
||||
* the results against expected returned string. In case of formatting error,
|
||||
* it provides a message informing which value was wrongly formatted.
|
||||
*
|
||||
* Then it checks the results of calling NumberFormat.format(double) on a set
|
||||
* of predefined golden values and checks results against expected returned
|
||||
* string. It does this both for the decimal case, with an instance returned
|
||||
* NumberFormat.getInstance() call and for the currency case, with an instance
|
||||
* returned by NumberFormat.getCurrencyInstance(). Almost all the tested double
|
||||
* values satisfy the constraints assumed by the fast-path algorithm for
|
||||
* format(double ...). Some are voluntarily outside the scope of fast-path to
|
||||
* check that the algorithm correctly eliminate them. In case of formatting
|
||||
* error a message provides information on the golden value raising the error
|
||||
* (value, exact decimal value (using BidDecimal), expected result, formatted result).
|
||||
*
|
||||
* Last the test checks the status and behavior of a DecimalFormat instance
|
||||
* when changing properties that make this instance satisfy/invalidate its
|
||||
* fast-path status, depending on the predefined set of fast-path constraints.
|
||||
*
|
||||
* The golden results are predefined arrays of int[] containing the unicode
|
||||
* ints of the chars in the expected formatted string, when using locale
|
||||
* provided in GoldenDoubleValues class. The results are those obtained by
|
||||
* using a reference jdk version (for example one that does not contains the
|
||||
* DecimalFormat fast-path algorithm, like jdk80-b25).
|
||||
*
|
||||
* The double values from which we get golden results are stored inside two
|
||||
* arrays of double values:
|
||||
* - DecimalGoldenValues for testing NumberFormat.getInstance().
|
||||
* - CurrencyGoldenValues for testing NumberFormat.getCurrencyInstance().
|
||||
* These arrays are located in GoldenDoubleValues.java source file.
|
||||
*
|
||||
* For each double value in the arrays above, there is an associated golden
|
||||
* result. These results are stored in arrays of int[]:
|
||||
* - DecimalGoldenFormattedValues for expected decimal golden results.
|
||||
* - CurrencyGoldenFormattedValues for expected currency golden results.
|
||||
* - DecimalDigitsLocalizedFormattedValues for expected localized digit results.
|
||||
*
|
||||
* We store the results in int[] arrays containing the expected unicode values
|
||||
* because the compiler that will compile the containing java file may use a
|
||||
* different locale than the one registered in GoldenDoubleValues.java. These
|
||||
* arrays are located in a separate GoldenFormattedValues.java source file
|
||||
* that is generated by RoundingAndPropertyTest using "-gengold" parameter.
|
||||
* See below "Modifying Golden Values".
|
||||
*
|
||||
* The golden value arrays can be expanded, modified ... to test additional
|
||||
* or different double values. In that case, the source file of class
|
||||
* GoldenFormattedValues must be regenerated to replace the existing one..
|
||||
*
|
||||
* Modifying Golden Values :
|
||||
*
|
||||
* In order to ease further modification of the list of double values checked
|
||||
* and associated golden results, the test includes the method
|
||||
* generatesGoldenFormattedValuesClass() that writes on standard output stream
|
||||
* the source code for GoldenFormattedValues class that includes the expected
|
||||
* results arrays.
|
||||
*
|
||||
* Here are the steps to follow for updating/modifying golden values and results:
|
||||
* 1- Edit GoldenDoubleValues.java to add/remove/modify golden or localization
|
||||
* values.
|
||||
* 2- Run main with "-gengold" string argument with a target jdk.
|
||||
* (at the creation of this test file, the target jdk used was jdk1.8.0-ea).
|
||||
* 2- Copy this java code that has been writen on standard output and replace
|
||||
* GoldenFormattedValues.java contents by the generated output.
|
||||
* 3- Check that this updated code compiles.
|
||||
* [4]- If needed replaces existing GoldenDoubleValues and GoldenFormattedValues
|
||||
* files in jdk/test section, respectively by the one modified at step 1 and
|
||||
* generated at step 2.
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
import java.util.*;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.DecimalFormatSymbols;
|
||||
import java.math.RoundingMode;
|
||||
import java.math.BigDecimal;
|
||||
|
||||
|
||||
public class RoundingAndPropertyTest {
|
||||
|
||||
|
||||
// Prints on standard output stream the unicode values of chars as a
|
||||
// comma-separated list of int values
|
||||
private static void printUnicodeValuesArray(char[] chars) {
|
||||
for (int i = 0; i < chars.length; i++) {
|
||||
System.out.print((int) chars[i]);
|
||||
if (i != (chars.length - 1))
|
||||
System.out.print(", ");
|
||||
}
|
||||
}
|
||||
|
||||
// Converts given array of unicode values as an array of chars.
|
||||
// Returns this converted array.
|
||||
private static char[] getCharsFromUnicodeArray(int[] unicodeValues) {
|
||||
char[] chars = new char[unicodeValues.length];
|
||||
|
||||
for (int i = 0; i < unicodeValues.length; i++) {
|
||||
chars[i] = (char) unicodeValues[i];
|
||||
}
|
||||
return chars;
|
||||
}
|
||||
|
||||
/* Prints on standard output stream the java code of resulting
|
||||
* GoldenFormattedValues class for the golden values found in
|
||||
* class GoldenDoubleValues.
|
||||
*/
|
||||
private static void generatesGoldenFormattedValuesClass() {
|
||||
|
||||
String fourWhiteSpaces = " ";
|
||||
String eightWhiteSpaces = " ";
|
||||
|
||||
// Prints header without Copyright header.
|
||||
System.out.println("/* This is a machine generated file - Please DO NOT EDIT !");
|
||||
System.out.println(" * Change RoundingAndPropertyTest instead,");
|
||||
System.out.println(" * and run with \"-gengold\" argument to regenerate (without copyright header).");
|
||||
System.out.println(" */");
|
||||
System.out.println();
|
||||
|
||||
System.out.println("/* This file contains the set of result Strings expected from calling inside");
|
||||
System.out.println(" * RoundingAndPropertyTest the method NumberFormat.format() upon the set of");
|
||||
System.out.println(" * double values provided in GoldenDoubleValues.java. It contains three arrays,");
|
||||
System.out.println(" * each containing arrays of unicode values representing the expected string");
|
||||
System.out.println(" * result when calling format() on the corresponding (i.e. same index) double");
|
||||
System.out.println(" * value found in GoldenDoubleValues arrays :");
|
||||
System.out.println(" * - DecimalDigitsLocalizedFormattedValues corresponds to DecimalLocalizationValues,");
|
||||
System.out.println(" * when using FullLocalizationTestLocale to format.");
|
||||
System.out.println(" * - DecimalGoldenFormattedValues corresponds to DecimalGoldenValues, when used");
|
||||
System.out.println(" * in the decimal pattern case together with TestLocale.");
|
||||
System.out.println(" * - CurrencyGoldenFormattedValues corresponds to CurrencyGoldenValues. when used");
|
||||
System.out.println(" * in the currency pattern case together with TestLocale.");
|
||||
System.out.println(" * Please see documentation in RoundingAndPropertyTest.java for more details.");
|
||||
System.out.println(" *");
|
||||
System.out.println(" * This file generated by running RoundingAndPropertyTest with \"-gengold\" argument.");
|
||||
System.out.println(" */");
|
||||
System.out.println();
|
||||
|
||||
// Prints beginning of class GoldenFormattedValues.
|
||||
System.out.println("class GoldenFormattedValues {");
|
||||
System.out.println();
|
||||
System.out.println(
|
||||
fourWhiteSpaces +
|
||||
"// The formatted values below were generated from golden values");
|
||||
System.out.print(
|
||||
fourWhiteSpaces +
|
||||
"// listed in GoldenDoubleValues.java,");
|
||||
System.out.println(" using the following jvm version :");
|
||||
System.out.println(
|
||||
fourWhiteSpaces + "// " +
|
||||
System.getProperty("java.vendor") +
|
||||
" " +
|
||||
System.getProperty("java.vm.name") +
|
||||
" " +
|
||||
System.getProperty("java.version"));
|
||||
System.out.println(
|
||||
fourWhiteSpaces +
|
||||
"// locale for golden double values : " + GoldenDoubleValues.TestLocale);
|
||||
System.out.println(
|
||||
fourWhiteSpaces +
|
||||
"// locale for testing digit localization : " + GoldenDoubleValues.FullLocalizationTestLocale);
|
||||
System.out.println();
|
||||
|
||||
// Prints the expected results when digit localization happens
|
||||
System.out.println(
|
||||
fourWhiteSpaces +
|
||||
"// The array of int[] unicode values storing the expected results");
|
||||
System.out.print(
|
||||
fourWhiteSpaces +
|
||||
"// when experiencing full localization of digits");
|
||||
System.out.println(" on DecimalLocalizationValues.");
|
||||
System.out.println(
|
||||
fourWhiteSpaces +
|
||||
"static int[][] DecimalDigitsLocalizedFormattedValues = {");
|
||||
NumberFormat df =
|
||||
NumberFormat.getInstance(GoldenDoubleValues.FullLocalizationTestLocale);
|
||||
for (int i = 0;
|
||||
i < GoldenDoubleValues.DecimalLocalizationValues.length;
|
||||
i++) {
|
||||
double d = GoldenDoubleValues.DecimalLocalizationValues[i];
|
||||
String formatted = df.format(d);
|
||||
char[] decFmtChars = formatted.toCharArray();
|
||||
|
||||
System.out.print(eightWhiteSpaces + "{ ");
|
||||
printUnicodeValuesArray(decFmtChars);
|
||||
System.out.println(" },");
|
||||
}
|
||||
System.out.println(fourWhiteSpaces + "};");
|
||||
System.out.println();
|
||||
|
||||
// Prints the golden expected results for the decimal pattern case
|
||||
System.out.println(
|
||||
fourWhiteSpaces +
|
||||
"// The array of int[] unicode values storing the expected results");
|
||||
System.out.print(
|
||||
fourWhiteSpaces +
|
||||
"// when calling Decimal.format(double)");
|
||||
System.out.println(" on the decimal GoldenDoubleValues.");
|
||||
System.out.println(
|
||||
fourWhiteSpaces +
|
||||
"static int[][] DecimalGoldenFormattedValues = {");
|
||||
df = NumberFormat.getInstance(GoldenDoubleValues.TestLocale);
|
||||
for (int i = 0;
|
||||
i < GoldenDoubleValues.DecimalGoldenValues.length;
|
||||
i++) {
|
||||
double d = GoldenDoubleValues.DecimalGoldenValues[i];
|
||||
String formatted = df.format(d);
|
||||
char[] decFmtChars = formatted.toCharArray();
|
||||
|
||||
System.out.print(eightWhiteSpaces + "{ ");
|
||||
printUnicodeValuesArray(decFmtChars);
|
||||
System.out.println(" },");
|
||||
}
|
||||
System.out.println(fourWhiteSpaces + "};");
|
||||
System.out.println();
|
||||
|
||||
// Prints the golden expected results for the currency pattern case
|
||||
System.out.println(
|
||||
fourWhiteSpaces +
|
||||
"// The array of int[] unicode values storing the expected results");
|
||||
System.out.print(
|
||||
fourWhiteSpaces +
|
||||
"// when calling Decimal.format(double)");
|
||||
System.out.println(" on the currency GoldenDoubleValues.");
|
||||
System.out.println(
|
||||
fourWhiteSpaces +
|
||||
"static int[][] CurrencyGoldenFormattedValues = {");
|
||||
NumberFormat cf =
|
||||
NumberFormat.getCurrencyInstance(GoldenDoubleValues.TestLocale);
|
||||
for (int i = 0;
|
||||
i < GoldenDoubleValues.CurrencyGoldenValues.length;
|
||||
i++) {
|
||||
double d = GoldenDoubleValues.CurrencyGoldenValues[i];
|
||||
String formatted = cf.format(d);
|
||||
char[] decFmtChars = formatted.toCharArray();
|
||||
|
||||
System.out.print(eightWhiteSpaces + "{ ");
|
||||
printUnicodeValuesArray(decFmtChars);
|
||||
System.out.println(" },");
|
||||
}
|
||||
System.out.println(fourWhiteSpaces + "};");
|
||||
System.out.println();
|
||||
|
||||
// Prints end of GoldenFormattedValues class.
|
||||
System.out.println("}");
|
||||
}
|
||||
|
||||
private static int testLocalizationValues() {
|
||||
|
||||
DecimalFormat df = (DecimalFormat)
|
||||
NumberFormat.getInstance(GoldenDoubleValues.FullLocalizationTestLocale);
|
||||
|
||||
double[] localizationValues = GoldenDoubleValues.DecimalLocalizationValues;
|
||||
int size = localizationValues.length;
|
||||
int successCounter = 0;
|
||||
int failureCounter = 0;
|
||||
for (int i = 0; i < size; i++) {
|
||||
|
||||
double d = localizationValues[i];
|
||||
String formatted = df.format(d);
|
||||
|
||||
char[] expectedUnicodeArray =
|
||||
getCharsFromUnicodeArray(
|
||||
GoldenFormattedValues.DecimalDigitsLocalizedFormattedValues[i]);
|
||||
String expected = new String(expectedUnicodeArray);
|
||||
|
||||
if (!formatted.equals(expected)) {
|
||||
failureCounter++;
|
||||
System.out.println(
|
||||
"--- Localization error for value d = " + d +
|
||||
". Exact value = " + new BigDecimal(d).toString() +
|
||||
". Expected result = " + expected +
|
||||
". Output result = " + formatted);
|
||||
} else successCounter++;
|
||||
}
|
||||
System.out.println("Checked positively " + successCounter +
|
||||
" golden decimal values out of " + size +
|
||||
" tests. There were " + failureCounter +
|
||||
" format failure");
|
||||
|
||||
return failureCounter;
|
||||
}
|
||||
|
||||
private static int testGoldenValues(java.text.DecimalFormat df,
|
||||
java.text.DecimalFormat cf) {
|
||||
|
||||
double[] goldenDecimalValues = GoldenDoubleValues.DecimalGoldenValues;
|
||||
int decimalSize = goldenDecimalValues.length;
|
||||
int decimalSuccessCounter = 0;
|
||||
int decimalFailureCounter = 0;
|
||||
for (int i = 0; i < decimalSize; i++) {
|
||||
|
||||
double d = goldenDecimalValues[i];
|
||||
String formatted = df.format(d);
|
||||
|
||||
char[] expectedUnicodeArray =
|
||||
getCharsFromUnicodeArray(
|
||||
GoldenFormattedValues.DecimalGoldenFormattedValues[i]);
|
||||
String expected = new String(expectedUnicodeArray);
|
||||
|
||||
if (!formatted.equals(expected)) {
|
||||
decimalFailureCounter++;
|
||||
System.out.println(
|
||||
"--- Error for golden value d = " + d +
|
||||
". Exact value = " + new BigDecimal(d).toString() +
|
||||
". Expected result = " + expected +
|
||||
". Output result = " + formatted);
|
||||
} else decimalSuccessCounter++;
|
||||
}
|
||||
System.out.println("Checked positively " + decimalSuccessCounter +
|
||||
" golden decimal values out of " + decimalSize +
|
||||
" tests. There were " + decimalFailureCounter +
|
||||
" format failure");
|
||||
|
||||
double[] goldenCurrencyValues = GoldenDoubleValues.CurrencyGoldenValues;
|
||||
int currencySize = goldenCurrencyValues.length;
|
||||
int currencySuccessCounter = 0;
|
||||
int currencyFailureCounter = 0;
|
||||
for (int i = 0; i < currencySize; i++) {
|
||||
double d = goldenCurrencyValues[i];
|
||||
String formatted = cf.format(d);
|
||||
|
||||
char[] expectedUnicodeArray =
|
||||
getCharsFromUnicodeArray(
|
||||
GoldenFormattedValues.CurrencyGoldenFormattedValues[i]);
|
||||
String expected = new String(expectedUnicodeArray);
|
||||
|
||||
if (!formatted.equals(expected)) {
|
||||
currencyFailureCounter++;
|
||||
System.out.println(
|
||||
"--- Error for golden value d = " + d +
|
||||
". Exact value = " + new BigDecimal(d).toString() +
|
||||
". Expected result = " + expected +
|
||||
". Output result = " + formatted);
|
||||
} else currencySuccessCounter++;
|
||||
}
|
||||
System.out.println("Checked positively " + currencySuccessCounter +
|
||||
" golden currency values out of " + currencySize +
|
||||
" tests. There were " + currencyFailureCounter +
|
||||
" format failure");
|
||||
|
||||
return (decimalFailureCounter + currencyFailureCounter);
|
||||
}
|
||||
|
||||
// Checks that the two passed s1 and s2 string are equal, and prints
|
||||
// out message in case of error.
|
||||
private static boolean resultsEqual(String propertyName,
|
||||
String s1,
|
||||
String s2) {
|
||||
|
||||
boolean equality = s1.equals(s2);
|
||||
if (!equality)
|
||||
System.out.println(
|
||||
"\n*** Error while reverting to default " +
|
||||
propertyName + " property.\n" +
|
||||
" initial output = " + s1 +
|
||||
". reverted output = " + s2 + ".");
|
||||
else System.out.println(" Test passed.");
|
||||
|
||||
return equality;
|
||||
|
||||
}
|
||||
|
||||
/* This methods checks the behaviour of the management of properties
|
||||
* of a DecimalFormat instance that satisfies fast-path constraints.
|
||||
*
|
||||
* It does this by comparing the results of the format(double) output
|
||||
* obtained from initial fast-path state with the output provided by
|
||||
* the same instance that has been pushed and exercised outside
|
||||
* fast-path rules and finally "reverted" to its initial fast-path state.
|
||||
*
|
||||
* The schema of actions is this :
|
||||
* - Call format(double) on a known DecimalFormat fast-path instance,
|
||||
* and store this result.
|
||||
* - Record the current state of a given property.
|
||||
* - Change the property to invalidate the fast-path state.
|
||||
* - Call again format(double) on the instance.
|
||||
* - Revert state of property to validate again fast-path context.
|
||||
* - Call format(double) again.
|
||||
* - Check that first and last call to format(double) provide same result
|
||||
* - Record failure if any.
|
||||
* - Do the same for another property with the same instance.
|
||||
* So all the property changes are chained one after the other on only the
|
||||
* same instance.
|
||||
*
|
||||
* Some properties that currently do not influence the fast-path state
|
||||
* are also tested. This is not useful with current fast-path source
|
||||
* but is here for testing the whole set of properties. This is the case
|
||||
* for prefixes and suffixes, and parseBigDecimal properties.
|
||||
*/
|
||||
private static int testSettersAndFastPath(DecimalFormat df,
|
||||
boolean isCurrency) {
|
||||
|
||||
final double d1 = GoldenDoubleValues.PROPERTY_CHECK_POSITIVE_VALUE;
|
||||
final double d2 = GoldenDoubleValues.PROPERTY_CHECK_NEGATIVE_VALUE;
|
||||
|
||||
int errors = 0;
|
||||
boolean testSucceeded = false;
|
||||
String firstFormatResult;
|
||||
String secondFormatResult;
|
||||
String propertyName;
|
||||
|
||||
// ---- positivePrefix property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "positivePrefix";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
String initialPrefix = df.getPositivePrefix();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setPositivePrefix("positivePrefix:");
|
||||
df.format(d1);
|
||||
df.setPositivePrefix(initialPrefix);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- positiveSuffix property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "positiveSuffix";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
String initialSuffix = df.getPositiveSuffix();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setPositiveSuffix("positiveSuffix:");
|
||||
df.format(d1);
|
||||
df.setPositiveSuffix(initialSuffix);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName,firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- negativePrefix property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "negativePrefix";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
initialPrefix = df.getNegativePrefix();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setNegativePrefix("negativePrefix:");
|
||||
df.format(d1);
|
||||
df.setNegativePrefix(initialPrefix);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- negativeSuffix property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "negativeSuffix";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
initialSuffix = df.getNegativeSuffix();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setNegativeSuffix("negativeSuffix:");
|
||||
df.format(d1);
|
||||
df.setNegativeSuffix(initialSuffix);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- multiplier property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "multiplier";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
int initialMultiplier = df.getMultiplier();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setMultiplier(10);
|
||||
df.format(d1);
|
||||
df.setMultiplier(initialMultiplier);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- groupingUsed property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "groupingUsed";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
boolean initialGroupingUsed = df.isGroupingUsed();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setGroupingUsed(!initialGroupingUsed);
|
||||
df.format(d1);
|
||||
df.setGroupingUsed(initialGroupingUsed);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- groupingSize property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "groupingSize";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
int initialGroupingSize = df.getGroupingSize();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setGroupingSize(initialGroupingSize + 1);
|
||||
df.format(d1);
|
||||
df.setGroupingSize(initialGroupingSize);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- decimalSeparatorAlwaysShown property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "decimalSeparatorAlwaysShown";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
boolean initialDSShown = df.isDecimalSeparatorAlwaysShown();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setDecimalSeparatorAlwaysShown(!initialDSShown);
|
||||
df.format(d1);
|
||||
df.setDecimalSeparatorAlwaysShown(initialDSShown);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- parseBigDecimal property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "parseBigDecimal";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
boolean initialParseBigdecimal = df.isParseBigDecimal();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setParseBigDecimal(!initialParseBigdecimal);
|
||||
df.format(d1);
|
||||
df.setParseBigDecimal(initialParseBigdecimal);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- maximumIntegerDigits property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "maximumIntegerDigits";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
int initialMaxIDs = df.getMaximumIntegerDigits();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setMaximumIntegerDigits(8);
|
||||
df.format(d1);
|
||||
df.setMaximumIntegerDigits(initialMaxIDs);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- minimumIntegerDigits property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "minimumIntegerDigits";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
int initialMinIDs = df.getMinimumIntegerDigits();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setMinimumIntegerDigits(2);
|
||||
df.format(d1);
|
||||
df.setMinimumIntegerDigits(initialMinIDs);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- maximumFractionDigits property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "maximumFractionDigits";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setMaximumFractionDigits(8);
|
||||
df.format(d1);
|
||||
if (isCurrency) {
|
||||
df.setMinimumFractionDigits(2);
|
||||
df.setMaximumFractionDigits(2);
|
||||
} else {
|
||||
df.setMinimumFractionDigits(0);
|
||||
df.setMaximumFractionDigits(3);
|
||||
}
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- minimumFractionDigits property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "minimumFractionDigits";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setMinimumFractionDigits(1);
|
||||
df.format(d1);
|
||||
if (isCurrency) {
|
||||
df.setMinimumFractionDigits(2);
|
||||
df.setMaximumFractionDigits(2);
|
||||
} else {
|
||||
df.setMinimumFractionDigits(0);
|
||||
df.setMaximumFractionDigits(3);
|
||||
}
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- currency property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "currency";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
Currency initialCurrency = df.getCurrency();
|
||||
Currency japanCur = java.util.Currency.getInstance(Locale.JAPAN);
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setCurrency(japanCur);
|
||||
df.format(d1);
|
||||
df.setCurrency(initialCurrency);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- roundingMode property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "roundingMode";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
RoundingMode initialRMode = df.getRoundingMode();
|
||||
firstFormatResult = df.format(d1);
|
||||
df.setRoundingMode(RoundingMode.HALF_UP);
|
||||
df.format(d1);
|
||||
df.setRoundingMode(RoundingMode.HALF_EVEN);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
// ---- decimalFormatSymbols property test ----
|
||||
testSucceeded = false;
|
||||
propertyName = "decimalFormatSymbols";
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
DecimalFormatSymbols initialDecimalFormatSymbols = df.getDecimalFormatSymbols();
|
||||
firstFormatResult = df.format(d1);
|
||||
Locale bizarreLocale = Locale.FRANCE;
|
||||
DecimalFormatSymbols unusualSymbols = new DecimalFormatSymbols(bizarreLocale);
|
||||
unusualSymbols.setDecimalSeparator('@');
|
||||
unusualSymbols.setGroupingSeparator('|');
|
||||
df.setDecimalFormatSymbols(unusualSymbols);
|
||||
df.format(d1);
|
||||
df.setDecimalFormatSymbols(initialDecimalFormatSymbols);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
testSucceeded = false;
|
||||
System.out.print("Checking " + propertyName + " property.");
|
||||
initialDecimalFormatSymbols = df.getDecimalFormatSymbols();
|
||||
firstFormatResult = df.format(d1);
|
||||
Locale japanLocale = Locale.JAPAN;
|
||||
unusualSymbols = new DecimalFormatSymbols(japanLocale);
|
||||
unusualSymbols.setDecimalSeparator('9');
|
||||
unusualSymbols.setGroupingSeparator('0');
|
||||
df.setDecimalFormatSymbols(unusualSymbols);
|
||||
df.format(d1);
|
||||
df.setDecimalFormatSymbols(initialDecimalFormatSymbols);
|
||||
secondFormatResult = df.format(d1);
|
||||
testSucceeded =
|
||||
resultsEqual(propertyName, firstFormatResult, secondFormatResult);
|
||||
if (!testSucceeded)
|
||||
errors++;
|
||||
|
||||
return errors;
|
||||
}
|
||||
|
||||
// Main for RoundingAndPropertyTest. We test first the golden values,
|
||||
// and then the property setters and getters.
|
||||
public static void main(String[] args) {
|
||||
|
||||
if ((args.length >= 1) &&
|
||||
(args[0].equals("-gengold")))
|
||||
generatesGoldenFormattedValuesClass();
|
||||
else {
|
||||
System.out.println("\nChecking correctness of formatting with digit localization.");
|
||||
System.out.println("=============================================================");
|
||||
int localizationErrors = testLocalizationValues();
|
||||
if (localizationErrors != 0)
|
||||
System.out.println("*** Failure in localization tests : " +
|
||||
localizationErrors + " errors detected ");
|
||||
else System.out.println(" Tests for full localization of digits all passed.");
|
||||
|
||||
DecimalFormat df = (DecimalFormat)
|
||||
NumberFormat.getInstance(GoldenDoubleValues.TestLocale);
|
||||
DecimalFormat cf = (DecimalFormat)
|
||||
NumberFormat.getCurrencyInstance(GoldenDoubleValues.TestLocale);
|
||||
|
||||
System.out.println("\nChecking correctness of formating for golden values.");
|
||||
System.out.println("=============================================================");
|
||||
int goldenValuesErrors = testGoldenValues(df,cf);
|
||||
if (goldenValuesErrors != 0)
|
||||
System.out.println("*** Failure in goldenValues tests : " +
|
||||
goldenValuesErrors + " errors detected ");
|
||||
else System.out.println(" Tests for golden values all passed.");
|
||||
|
||||
System.out.println("\nChecking behavior of property changes for decimal case.");
|
||||
System.out.println("=============================================================");
|
||||
int decimalTestsErrors = testSettersAndFastPath(df, false);
|
||||
if (decimalTestsErrors != 0)
|
||||
System.out.println("*** Failure in decimal property changes tests : " +
|
||||
decimalTestsErrors + " errors detected ");
|
||||
else System.out.println(" Tests for decimal property changes all passed.");
|
||||
|
||||
System.out.println("\nChecking behavior of property changes for currency case.");
|
||||
System.out.println("=============================================================");
|
||||
int currencyTestsErrors = testSettersAndFastPath(cf, true);
|
||||
if (currencyTestsErrors != 0)
|
||||
System.out.println("*** Failure in currency property changes tests : " +
|
||||
currencyTestsErrors + " errors detected ");
|
||||
else System.out.println(" Tests for currency property chamges all passed.");
|
||||
|
||||
if ((localizationErrors > 0) ||
|
||||
(goldenValuesErrors > 0) ||
|
||||
(decimalTestsErrors > 0) ||
|
||||
(currencyTestsErrors > 0))
|
||||
throw new RuntimeException(
|
||||
"Failed with " +
|
||||
(localizationErrors + goldenValuesErrors +
|
||||
decimalTestsErrors + currencyTestsErrors) +
|
||||
" error(s).");
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue