001/* 002 * Copyright (c) 2012, 2013, Werner Keil, Credit Suisse (Anatole Tresch). Licensed under the Apache 003 * License, Version 2.0 (the "License"); you may not use this file except in compliance with the 004 * License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 005 * Unless required by applicable law or agreed to in writing, software distributed under the License 006 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 007 * or implied. See the License for the specific language governing permissions and limitations under 008 * the License. Contributors: Anatole Tresch - initial version. 009 */ 010package org.javamoney.tck.tests.format; 011 012import org.javamoney.tck.tests.internal.TestAmount; 013import org.javamoney.tck.tests.internal.TestMonetaryAmountBuilder; 014import org.jboss.test.audit.annotations.SpecAssertion; 015import org.jboss.test.audit.annotations.SpecVersion; 016import org.testng.AssertJUnit; 017import org.testng.annotations.Test; 018 019import javax.money.*; 020import javax.money.format.AmountFormatQuery; 021import javax.money.format.AmountFormatQueryBuilder; 022import javax.money.format.MonetaryAmountFormat; 023import javax.money.format.MonetaryFormats; 024import java.text.DecimalFormat; 025import java.util.HashSet; 026import java.util.Locale; 027import java.util.Set; 028 029import static org.testng.Assert.assertFalse; 030import static org.testng.Assert.assertNotNull; 031import static org.testng.Assert.assertEquals; 032import static org.testng.AssertJUnit.fail; 033 034@SpecVersion(spec = "JSR 354", version = "1.0.0") 035public class FormattingMonetaryAmountsTest { 036 037 /** 038 * Format several amounts, created using the default factory, 039 * but 040 * also a test instance, provided by the TCK, to ensure no 041 * implementation 042 * dependencies on the implementation. 043 */ 044 @SpecAssertion(section = "4.4.1", id = "441-A1") 045 @Test(description = "4.4.1 Ensures the system.s default locale is supported for MonetaryAmountFormat.") 046 public void testNoDepOnAmountImplementation() { 047 final Locale defaultLocale = Locale.getDefault(); 048 MonetaryAmountFormat amountFormat = MonetaryFormats.getAmountFormat(defaultLocale); 049 final Number[] values = new Number[]{100, 10000000000000L};// TODO 050 // other 051 // values 052 // and 053 // currencies 054 for (CurrencyUnit currency : MonetaryCurrencies.getCurrencies()) { 055 for (Number value : values) { 056 MonetaryAmount amount = 057 MonetaryAmounts.getDefaultAmountFactory().setCurrency(currency.getCurrencyCode()) 058 .setNumber(value).create(); 059 String formattedAmount = amountFormat.format(amount); 060 MonetaryAmount amountMock = TestMonetaryAmountBuilder.getAmount(value, currency); 061 String formattedAmountMock = amountFormat.format(amountMock); 062 AssertJUnit.assertNotNull(formattedAmountMock); 063 assertEquals(formattedAmountMock, formattedAmount); 064 } 065 } 066 } 067 068 /** 069 * Print several amounts, created using the default factory, but 070 * also a test instance, provided by the TCK, to ensure no 071 * implementation 072 * dependencies on the implementation. 073 */ 074 @SpecAssertion(section = "4.4.1", id = "441-A2") 075 @Test(description = "4.4.1 Formats amounts using all available locales.") 076 public void testFormattingIsIndependentOfImplementation() { 077 for (Locale locale : MonetaryFormats.getAvailableLocales()) { 078 MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(locale); 079 Set<String> formatsProcuced = new HashSet<>(); 080 for (MonetaryAmountFactory fact : MonetaryAmounts.getAmountFactories()) { 081 if (fact.getAmountType().equals(TestAmount.class)) { 082 continue; 083 } 084 MonetaryAmount amt = fact.setCurrency("USD").setNumber(10.5).create(); 085 String formatProduced = format.format(amt); 086 assertNotNull(formatProduced, "No MonetaryAmountFormat returned from MonetaryFormats." + 087 "getMonetaryFormat(Locale,String...) with supported Locale: " + locale); 088 assertFalse(formatProduced.isEmpty(), "MonetaryAmountFormat returned empty String for " + amt); 089 formatsProcuced.add(formatProduced); 090 } 091 assertFalse(formatsProcuced.isEmpty(), "No formatted amount available. Are there no amount?"); 092 assertFalse(formatsProcuced.size() > 1, 093 "Formatter produces different output for different amount classes(+" + 094 format.getClass() + "): " + formatsProcuced); 095 } 096 } 097 098 /** 099 * Parse back several amounts, input created using the 100 * formatting 101 * from 'Format_formatAmounts'. 102 */ 103 @SpecAssertion(section = "4.4.1", id = "441-A3") 104 @Test(description = "4.4.1 Test formats and parses (round-trip) any supported amount type for each supported " + 105 "Locale.") 106 public void testParseIsIndependentOfImplementation() { 107 for (Locale locale : MonetaryFormats.getAvailableLocales()) { 108 MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(locale); 109 for (MonetaryAmountFactory fact : MonetaryAmounts.getAmountFactories()) { 110 if (fact.getAmountType().equals(TestAmount.class)) { 111 continue; 112 } 113 MonetaryAmount amt = fact.setCurrency("USD").setNumber(10.5).create(); 114 String formatProduced = format.format(amt); 115 assertNotNull(formatProduced, "No MonetaryAmountFormat returned from MonetaryFormats." + 116 "getMonetaryFormat(Locale,String...) with supported Locale: " + locale); 117 assertFalse(formatProduced.isEmpty(), "MonetaryAmountFormat returned empty String for " + amt); 118 try { 119 MonetaryAmount amtParsed = format.parse(formatProduced); 120 assertNotNull(amtParsed, "Reverse-parsing of MonetaryAmount failed for '" + formatProduced + 121 "' using MonetaryAmountFormat: " + format); 122 } catch (MonetaryException e) { 123 fail("Reverse-parsing of MonetaryAmount failed for '" + formatProduced + 124 "' using MonetaryAmountFormat: " + format.getClass().getName() + " for Locale: " + locale); 125 } 126 } 127 } 128 } 129 130 /** 131 * Get/set different amount styles (especially patterns, group 132 * sizes, group characters) and compare results with results as from 133 * RI. 134 * Also apply patterns without currency invovled. 135 */ 136 @SpecAssertion(section = "4.4.2", id = "442-A1") 137 @Test(description = 138 "4.4.2 Test formats and parses (round-trip) any supported amount type for each supported Locale, " + 139 "using different format queries.") 140 public void testParseDifferentStyles() { 141 for (Locale locale : MonetaryFormats.getAvailableLocales()) { 142 for (Class clazz : MonetaryAmounts.getAmountTypes()) { 143 if (clazz.equals(TestAmount.class)) { 144 continue; 145 } 146 MonetaryAmountFactory fact = MonetaryAmounts.getAmountFactory(clazz); 147 AmountFormatQuery query = AmountFormatQueryBuilder.of(locale).setMonetaryAmountFactory(fact).build(); 148 if (fact.getAmountType().equals(TestAmount.class)) { 149 continue; 150 } 151 MonetaryAmount amt = fact.setCurrency("USD").setNumber(10.5).create(); 152 MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(query); 153 String formatProduced = format.format(amt); 154 assertNotNull(formatProduced, "No MonetaryAmountFormat returned from MonetaryFormats." + 155 "getMonetaryFormat(Locale,String...) with supported Locale: " + locale); 156 assertFalse(formatProduced.isEmpty(), "MonetaryAmountFormat returned empty String for " + amt); 157 try { 158 MonetaryAmount amtParsed = format.parse(formatProduced); 159 assertNotNull(amtParsed, "Reverse-parsing of MonetaryAmount failed for '" + formatProduced + 160 "' using MonetaryAmountFormat: " + format); 161 assertEquals(amtParsed.getClass(), clazz, 162 "Reverse-parsing of MonetaryAmount failed for '" + formatProduced + 163 "' using MonetaryAmountFormat(invalid type " + 164 amtParsed.getClass().getName() + ") for format: " + format); 165 } catch (MonetaryException e) { 166 fail("Reverse-parsing of MonetaryAmount failed for '" + formatProduced + 167 "' using MonetaryAmountFormat: " + format.getClass().getName() + " for Locale: " + locale); 168 } 169 } 170 } 171 } 172 173 174 /** 175 * Get/set default currency, try to parse patterns without 176 * currency information. 177 */ 178 @SpecAssertion(section = "4.4.1", id = "441-A4") 179 @Test(description = 180 "4.4.1 Test formats and parses (round-trip) any supported amount type for each supported Locale," + 181 " checks results for different currencies") 182 public void testParseWithDifferentCurrencies() { 183 for (Locale locale : MonetaryFormats.getAvailableLocales()) { 184 MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(locale); 185 for (MonetaryAmountFactory fact : MonetaryAmounts.getAmountFactories()) { 186 if (fact.getAmountType().equals(TestAmount.class)) { 187 continue; 188 } 189 for (String currency : new String[]{"CHF", "USD", "GBP", "EUR"}) { 190 MonetaryAmount amt = fact.setCurrency(currency).setNumber(10.5).create(); 191 String formatProduced = format.format(amt); 192 assertNotNull(formatProduced, "No MonetaryAmountFormat returned from MonetaryFormats." + 193 "getMonetaryFormat(Locale,String...) with supported Locale: " + locale); 194 assertFalse(formatProduced.isEmpty(), "MonetaryAmountFormat returned empty String for " + amt); 195 try { 196 MonetaryAmount amtParsed = format.parse(formatProduced); 197 assertNotNull(amtParsed, "Reverse-parsing of MonetaryAmount failed for '" + formatProduced + 198 "' using MonetaryAmountFormat: " + format); 199 assertEquals(amtParsed.getCurrency().getCurrencyCode(), currency, 200 "Reverse-parsing of MonetaryAmount failed for '" + formatProduced + 201 "' using MonetaryAmountFormat(invalid currency " + 202 amtParsed.getCurrency().getCurrencyCode() + "): " + format); 203 } catch (MonetaryException e) { 204 fail("Reverse-parsing of MonetaryAmount failed for '" + formatProduced + 205 "' using MonetaryAmountFormat: " + format.getClass().getName() + " for Locale: " + locale); 206 } 207 } 208 } 209 } 210 } 211 212 213 /** 214 * AccessingMonetaryAmountFormat using 215 * MonetaryFormats.getAmountFormat(Locale locale), all locales 216 * available also from java.text.DecimalFormat must be supported. 217 */ 218 @SpecAssertion(section = "4.4.3", id = "443-A1") 219 @Test(description = "4.4.3 Ensures all Locales defined by DecimalFormat.getAvailableLocales() are available for " + 220 "monetary formatting.") 221 public void testLocalesSupported() { 222 Locale[] jdkDecimalFormatLocales = DecimalFormat.getAvailableLocales(); 223 for (Locale jdkDecimalFormatLocale : jdkDecimalFormatLocales) { 224 MonetaryAmountFormat amountFormat = MonetaryFormats.getAmountFormat(jdkDecimalFormatLocale); 225 AssertJUnit.assertNotNull(amountFormat); 226 assertEquals(jdkDecimalFormatLocale, amountFormat.getContext().getLocale()); 227 } 228 } 229 230 /** 231 * AccessingMonetaryAmountFormat using 232 * MonetaryFormats.getAmountFormat(AmountFormatContext style), all locales 233 * available also from java.text.DecimalFormat must be supported 234 * (using AmountFormatContext.of(Locale)). 235 */ 236 @Test(description = "4.4.3 Ensures for each locale defined by DecimalFormat.getAvailableLocales() a " + 237 "MonetaryAmountFormat instance is provided.") 238 @SpecAssertion(section = "4.4.3", id = "443-A2") 239 public void testGetAmountFormat() { 240 for (Locale locale : DecimalFormat.getAvailableLocales()) { 241 AssertJUnit.assertNotNull(MonetaryFormats.getAmountFormat(AmountFormatQuery.of(locale))); 242 } 243 } 244 245 /** 246 * Test MonetaryFormats.getAvailableLocales, all locales available also from java.text.DecimalFormat must be 247 * supported (using AmountFormatContext.of(Locale)), more locales are possible. 248 */ 249 @Test(description = "4.4.3 Ensures for each locale defined by DecimalFormat.getAvailableLocales() a " + 250 "MonetaryFormats.isAvailable(Locale) is true.") 251 @SpecAssertion(section = "4.4.3", id = "443-A3") 252 public void testGetAvailableLocales() { 253 Set<Locale> locales = MonetaryFormats.getAvailableLocales(); 254 for (Locale locale : DecimalFormat.getAvailableLocales()) { 255 if (Locale.ROOT.equals(locale)) { 256 continue; 257 } 258 AssertJUnit.assertTrue( 259 "MonetaryFormats.getAvailableLocales(); Locale supported by JDKs DecimalFormat is not available: " + 260 locale, locales.contains(locale)); 261 } 262 } 263 264 /** 265 * Test MonetaryFormats.getAvailableLocales, all locales available also from java.text.DecimalFormat must be 266 * supported (using AmountFormatContext.of(Locale)), more locales are possible. 267 */ 268 @Test(description = "4.4.3 Ensures for each locale defined by DecimalFormat.getAvailableLocales() a " + 269 "MonetaryFormats.getAmountFormat(AmountFormatQuery) returns a formatter.") 270 @SpecAssertion(section = "4.4.3", id = "443-A3") 271 public void testAmountStyleOf() { 272 for (Locale locale : DecimalFormat.getAvailableLocales()) { 273 AssertJUnit.assertNotNull(MonetaryFormats.getAmountFormat(AmountFormatQuery.of(locale))); 274 } 275 } 276}