View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.validator.routines;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  import static org.junit.jupiter.api.Assertions.assertFalse;
21  import static org.junit.jupiter.api.Assertions.assertNull;
22  
23  import java.math.BigDecimal;
24  import java.text.DecimalFormatSymbols;
25  import java.text.NumberFormat;
26  import java.util.Locale;
27  
28  import org.junit.jupiter.api.BeforeEach;
29  import org.junit.jupiter.api.Test;
30  import org.junitpioneer.jupiter.DefaultLocale;
31  
32  /**
33   * Test Case for CurrencyValidator.
34   */
35  class CurrencyValidatorTest {
36  
37      private static final char CURRENCY_SYMBOL = '\u00A4';
38  
39      private String usDollar;
40      private String ukPound;
41  
42      @BeforeEach
43      protected void setUp() {
44          usDollar = new DecimalFormatSymbols(Locale.US).getCurrencySymbol();
45          ukPound = new DecimalFormatSymbols(Locale.UK).getCurrencySymbol();
46      }
47  
48      /**
49       * Test Format Type
50       */
51      @Test
52      void testFormatType() {
53          assertEquals(1, CurrencyValidator.getInstance().getFormatType(), "Format Type A");
54          assertEquals(AbstractNumberValidator.CURRENCY_FORMAT, CurrencyValidator.getInstance().getFormatType(), "Format Type B");
55      }
56  
57      /**
58       * Test Invalid integer (non decimal) currency values
59       */
60      @Test
61      void testIntegerInvalid() {
62          final CurrencyValidator validator = new CurrencyValidator(true, false);
63  
64          // Invalid UK - has decimals
65          assertFalse(validator.isValid(ukPound + "1,234.56", Locale.UK), "UK positive");
66          assertFalse(validator.isValid("-" + ukPound + "1,234.56", Locale.UK), "UK negative");
67  
68          // Invalid US - has decimals
69          assertFalse(validator.isValid(usDollar + "1,234.56", Locale.US), "US positive");
70          assertFalse(validator.isValid("(" + usDollar + "1,234.56)", Locale.US), "US negative");
71      }
72  
73      /**
74       * Test Valid integer (non-decimal) currency values
75       */
76      @Test
77      @DefaultLocale("en-GB")
78      void testIntegerValid() {
79          final CurrencyValidator validator = new CurrencyValidator();
80          final BigDecimal expected = new BigDecimal("1234.00");
81          final BigDecimal negative = new BigDecimal("-1234.00");
82          // Generate the exected strings, as these vary between JVMs
83          final String ukPlus = NumberFormat.getCurrencyInstance(Locale.UK).format(1234);
84          final String ukMinus = NumberFormat.getCurrencyInstance(Locale.UK).format(-1234);
85          final String usPlus = NumberFormat.getCurrencyInstance(Locale.US).format(1234);
86          final String usMinus = NumberFormat.getCurrencyInstance(Locale.US).format(-1234);
87  
88          assertEquals(expected, validator.validate(ukPlus), "Default locale");
89  
90          assertEquals(expected, validator.validate(ukPlus, Locale.UK), "UK locale");
91          assertEquals(negative, validator.validate(ukMinus, Locale.UK), "UK negative");
92  
93          assertEquals(expected, validator.validate(usPlus, Locale.US), "US locale");
94          assertEquals(negative, validator.validate(usMinus, Locale.US), "US negative");
95      }
96  
97      /**
98       * Test Invalid currency values
99       */
100     @Test
101     void testInvalid() {
102         final BigDecimalValidator validator = CurrencyValidator.getInstance();
103 
104         final String ukPlus = NumberFormat.getCurrencyInstance(Locale.UK).format(1234.56);
105         final String usPlus = NumberFormat.getCurrencyInstance(Locale.US).format(1234.56);
106         final String ukMinus = NumberFormat.getCurrencyInstance(Locale.UK).format(-1234.56);
107         final String usMinus = NumberFormat.getCurrencyInstance(Locale.US).format(-1234.56);
108 
109         // Invalid Missing
110         assertFalse(validator.isValid(null), "isValid() Null Value");
111         assertFalse(validator.isValid(""), "isValid() Empty Value");
112         assertNull(validator.validate(null), "validate() Null Value");
113         assertNull(validator.validate(""), "validate() Empty Value");
114 
115         // Invalid UK
116         assertFalse(validator.isValid(usPlus, Locale.UK), "UK wrong symbol: " + usPlus);
117         if (ukMinus.startsWith("-")) {
118             assertFalse(validator.isValid("(" + ukPound + "1,234.56)", Locale.UK), "UK wrong negative: " + ukMinus);
119         } else {
120             assertFalse(validator.isValid("-" + ukPound + "1,234.56", Locale.UK), "UK wrong negative: " + ukMinus);
121         }
122 
123         // Invalid US
124         assertFalse(validator.isValid(ukPlus, Locale.US), "US wrong symbol: " + ukPlus);
125         if (usMinus.startsWith("-")) {
126             assertFalse(validator.isValid("(" + usDollar + "1,234.56)", Locale.US), "UK wrong negative: " + usMinus);
127         } else {
128             assertFalse(validator.isValid("-" + usDollar + "1,234.56", Locale.US), "UK wrong negative: " + usMinus);
129         }
130     }
131 
132     /**
133      * Test currency values with a pattern
134      */
135     @Test
136     @DefaultLocale("en-GB")
137     void testPattern() {
138         final BigDecimalValidator validator = CurrencyValidator.getInstance();
139         final String basicPattern = CURRENCY_SYMBOL + "#,##0.000";
140         final String pattern = basicPattern + ";[" + basicPattern + "]";
141         final BigDecimal expected = new BigDecimal("1234.567");
142         final BigDecimal negative = new BigDecimal("-1234.567");
143 
144         // Test Pattern
145         assertEquals(expected, validator.validate(ukPound + "1,234.567", pattern), "default");
146         assertEquals(negative, validator.validate("[" + ukPound + "1,234.567]", pattern), "negative");
147         assertEquals(expected, validator.validate("1,234.567", pattern), "no symbol +ve");
148         assertEquals(negative, validator.validate("[1,234.567]", pattern), "no symbol -ve");
149 
150         // Test Pattern & Locale
151         assertEquals(expected, validator.validate(usDollar + "1,234.567", pattern, Locale.US), "default");
152         assertEquals(negative, validator.validate("[" + usDollar + "1,234.567]", pattern, Locale.US), "negative");
153         assertEquals(expected, validator.validate("1,234.567", pattern, Locale.US), "no symbol +ve");
154         assertEquals(negative, validator.validate("[1,234.567]", pattern, Locale.US), "no symbol -ve");
155 
156         // invalid
157         assertFalse(validator.isValid(usDollar + "1,234.567", pattern), "invalid symbol");
158         assertFalse(validator.isValid(ukPound + "1,234.567", pattern, Locale.US), "invalid symbol");
159     }
160 
161     /**
162      * Test Valid currency values
163      */
164     @Test
165     @DefaultLocale("en-GB")
166     void testValid() {
167         final BigDecimalValidator validator = CurrencyValidator.getInstance();
168         final BigDecimal expected = new BigDecimal("1234.56");
169         final BigDecimal negative = new BigDecimal("-1234.56");
170         final BigDecimal noDecimal = new BigDecimal("1234.00");
171         final BigDecimal oneDecimal = new BigDecimal("1234.50");
172 
173         // Generate the exected strings, as these vary between JVMs
174         final String ukPlus = NumberFormat.getCurrencyInstance(Locale.UK).format(1234.56);
175         final String ukPlus0Decimal = NumberFormat.getCurrencyInstance(Locale.UK).format(1234);
176         final String ukPlus1Decimal = NumberFormat.getCurrencyInstance(Locale.UK).format(1234.5);
177         // Note that NumberFormat may perform rounding up or truncation, so we cheat
178         final String ukPlus3Decimal = NumberFormat.getCurrencyInstance(Locale.UK).format(1234.56) + "7";
179         final String ukMinus = NumberFormat.getCurrencyInstance(Locale.UK).format(-1234.56);
180         final String usPlus = NumberFormat.getCurrencyInstance(Locale.US).format(1234.56);
181         final String usPlus0Decimal = NumberFormat.getCurrencyInstance(Locale.US).format(1234);
182         final String usPlus1Decimal = NumberFormat.getCurrencyInstance(Locale.US).format(1234.5);
183         // Note that NumberFormat may perform rounding up or truncation, so we cheat
184         final String usPlus3Decimal = NumberFormat.getCurrencyInstance(Locale.US).format(1234.56) + "7";
185         final String usMinus = NumberFormat.getCurrencyInstance(Locale.US).format(-1234.56);
186 
187         assertEquals(expected, validator.validate(ukPlus), "Default locale");
188 
189         assertEquals(expected, validator.validate(ukPlus, Locale.UK), "UK locale");
190         assertEquals(negative, validator.validate(ukMinus, Locale.UK), "UK negative");
191         assertEquals(noDecimal, validator.validate(ukPlus0Decimal, Locale.UK), "UK no decimal");
192         assertEquals(oneDecimal, validator.validate(ukPlus1Decimal, Locale.UK), "UK 1 decimal");
193         assertEquals(expected, validator.validate(ukPlus3Decimal, Locale.UK), "UK 3 decimal: " + ukPlus3Decimal);
194         // TODO: The following expects the value to be truncated, rather than rounded up - is that correct?
195         assertEquals(expected, validator.validate(ukPlus3Decimal, Locale.UK), "UK 3 decimal: " + ukPlus3Decimal);
196         assertEquals(expected, validator.validate("1,234.56", Locale.UK), "UK no symbol");
197 
198         assertEquals(expected, validator.validate(usPlus, Locale.US), "US locale");
199         assertEquals(negative, validator.validate(usMinus, Locale.US), "US negative");
200         assertEquals(noDecimal, validator.validate(usPlus0Decimal, Locale.US), "US no decimal");
201         assertEquals(oneDecimal, validator.validate(usPlus1Decimal, Locale.US), "US 1 decimal");
202         // TODO: The following expects the value to be truncated, rather than rounded up - is that correct?
203         assertEquals(expected, validator.validate(usPlus3Decimal, Locale.US), "US 3 decimal: " + usPlus3Decimal);
204         assertEquals(expected, validator.validate("1,234.56", Locale.US), "US no symbol");
205     }
206 }