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; 011 012import org.javamoney.tck.TestUtils; 013import org.javamoney.tck.tests.internal.TestAmount; 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 java.math.BigDecimal; 021import java.util.Collection; 022import java.util.Currency; 023 024import static org.testng.AssertJUnit.assertNotNull; 025import static org.testng.AssertJUnit.assertTrue; 026 027/** 028 * Created by Anatole on 10.03.14. 029 */ 030@SpecVersion(spec = "JSR 354", version = "1.0.0") 031public class CreatingMonetaryAmountsTest { 032 033 // ************************ A. Accessing MonetaryAmount Factories ************************ 034 035 /** 036 * Access a MonetaryAmountFactory for each registered type. 037 */ 038 @Test(description = "4.2.6 Ensure MonetaryAmountFactory instances are accessible for all amount types under test.") 039 @SpecAssertion(section = "4.2.6", id = "426-A1") 040 public void testAccessToMonetaryAmountFactory() { 041 for (Class type : MonetaryAmounts.getAmountTypes()) { 042 assertNotNull("Section 4.2.6: No MonetaryAmountFactory available for " + type.getName(), 043 MonetaryAmounts.getAmountFactory(type)); 044 } 045 } 046 047 /** 048 * For each MonetaryAmountFactory: Check if getAmountType returns the correct type. 049 */ 050 @Test(description = 051 "4.2.6 Ensure MonetaryAmountFactory instances accessible for all amount types under test return " + 052 "correct amount type.") 053 @SpecAssertion(section = "4.2.6", id = "426-A2") 054 public void testMonetaryAmountFactoryReturnsCorrectType() { 055 for (Class type : MonetaryAmounts.getAmountTypes()) { 056 AssertJUnit.assertEquals( 057 "Section 4.2.6: MonetaryAmountFactory declares invalid amount type for " + type.getName(), type, 058 MonetaryAmounts.getAmountFactory(type).getAmountType()); 059 } 060 } 061 062 /** 063 * For each MonetaryAmountFactory: Check if capabilities of default MonetaryContext are less, or equal 064 * than Max 065 * MonetaryContext. 066 */ 067 @Test(description = 068 "4.2.6 Ensure MonetaryAmountFactory instances accessible for all amount types under test return " + 069 "correct min/max MonetaryContext.") 070 @SpecAssertion(section = "4.2.6", id = "426-A3") 071 public void testMonetaryAmountFactoryMinMaxCapabilities() { 072 for (Class type : MonetaryAmounts.getAmountTypes()) { 073 MonetaryAmountFactory<?> f = MonetaryAmounts.getAmountFactory(type); 074 MonetaryContext defCtx = f.getDefaultMonetaryContext(); 075 MonetaryContext maxCts = f.getMaximalMonetaryContext(); 076 assertTrue("Section 4.2.6: MonetaryAmountFactory default/max declares invalid precisions for " + 077 type.getName(), 078 maxCts.getPrecision() == 0 || defCtx.getPrecision() <= maxCts.getPrecision()); 079 assertTrue( 080 "Section 4.2.6: MonetaryAmountFactory default/max declares invalid scales for " + type.getName(), 081 maxCts.getMaxScale() == -1 || defCtx.getMaxScale() <= maxCts.getMaxScale()); 082 } 083 } 084 085 /** 086 * Checks if capabilities of default MonetaryContext are less than Max MonetaryContext. 087 */ 088 @Test(description = 089 "4.2.6 Ensure MonetaryAmountFactory instances accessible for all amount types under test return " + 090 "correct min/max MonetaryContext (min <= max).") 091 @SpecAssertion(section = "4.2.6", id = "426-A4") 092 public void testMonetaryAmountFactoryMinMaxCapabilities_Compare() { 093 for (Class type : MonetaryAmounts.getAmountTypes()) { 094 MonetaryAmountFactory<?> f = MonetaryAmounts.getAmountFactory(type); 095 MonetaryContext defCtx = f.getDefaultMonetaryContext(); 096 MonetaryContext maxCtx = f.getMaximalMonetaryContext(); 097 if (f.getDefaultMonetaryContext().getMaxScale() > -1) { 098 assertTrue( 099 "Section 4.2.6: MonetaryAmountFactory maximal MonetaryContext cannot be less capable than the" + 100 " default " + 101 "(maxScale default/max=" + 102 f.getDefaultMonetaryContext().getMaxScale() + '/' + 103 f.getMaximalMonetaryContext().getMaxScale() + " for " + type.getName(), 104 maxCtx.getMaxScale() == -1 || defCtx.getMaxScale() <= maxCtx.getMaxScale()); 105 } 106 if (f.getDefaultMonetaryContext().getMaxScale() == -1) { 107 assertTrue( 108 "Section 4.2.6: MonetaryAmountFactory maximal MonetaryContext cannot be less capable than the" + 109 " default " + 110 "(maxScale default/max=" + 111 f.getDefaultMonetaryContext().getMaxScale() + '/' + 112 f.getMaximalMonetaryContext().getMaxScale() + " for " + type.getName(), 113 maxCtx.getMaxScale() == -1); 114 } 115 if (f.getDefaultMonetaryContext().getPrecision() > 0) { 116 assertTrue( 117 "Section 4.2.6: MonetaryAmountFactory maximal MonetaryContext cannot be less capable than the" + 118 " default " + 119 "(precision default/max=" + 120 f.getDefaultMonetaryContext().getPrecision() + '/' + 121 f.getMaximalMonetaryContext().getPrecision() + " for " + type.getName(), 122 maxCtx.getPrecision() == 0 || defCtx.getPrecision() <= maxCtx.getPrecision()); 123 } 124 if (f.getDefaultMonetaryContext().getPrecision() == 0) { 125 assertTrue( 126 "Section 4.2.6: MonetaryAmountFactory maximal MonetaryContext cannot be less capable than the" + 127 " default " + 128 "(precision default/max=" + 129 f.getDefaultMonetaryContext().getPrecision() + '/' + 130 f.getMaximalMonetaryContext().getPrecision() + " for " + type.getName(), 131 maxCtx.getPrecision() == 0); 132 } 133 } 134 } 135 136 // **************** B. Testing Creation of Amounts with zero values ****************** 137 138 /** 139 * For each MonetaryAmountFactory: Create zero amounts from a 140 * factory with currencies. 141 */ 142 @Test(description = "4.2.6 Ensure MonetaryAmountFactory instances support creation of 0 amounts.") 143 @SpecAssertion(section = "4.2.6", id = "426-B1") 144 public void testMonetaryAmountFactoryCreateZeroAmountsWithDiffCurrencies() { 145 for (Class type : MonetaryAmounts.getAmountTypes()) { 146 if (type.equals(TestAmount.class)) { 147 continue; 148 } 149 for (Currency cur : Currency.getAvailableCurrencies()) { 150 CurrencyUnit cu = MonetaryCurrencies.getCurrency(cur.getCurrencyCode()); 151 MonetaryAmountFactory<?> f = MonetaryAmounts.getAmountFactory(type); 152 f.setCurrency(cu); 153 f.setNumber(0); 154 MonetaryAmount m = f.create(); 155 AssertJUnit.assertEquals( 156 "Section 4.2.6: Amount created with factory has invalid currency for " + type.getName(), cu, 157 m.getCurrency()); 158 AssertJUnit.assertEquals( 159 "Section 4.2.6: Amount created with factory returns invalid amount type " + type.getName(), 160 type, m.getClass()); 161 assertTrue( 162 "Section 4.2.6: Amount created with factory has invalid value for " + type.getName(), 163 m.isZero()); 164 assertTrue("Amount created with factory has invalid value for " + type.getName(), 165 m.signum() == 0); 166 assertTrue( 167 "Section 4.2.6: Amount created with factory has invalid value for " + type.getName(), 168 m.getNumber().intValueExact() == 0); 169 } 170 } 171 } 172 173 /** 174 * For each MonetaryAmount Factory: Create zero amounts from a 175 * factory with monetary contexts. 176 */ 177 @Test(description = "4.2.6 Ensure MonetaryAmountFactory instances support creation of 0 amounts, with explicit " + 178 "MonetaryContext.") 179 @SpecAssertion(section = "4.2.6", id = "426-B2") 180 public void testMonetaryAmountFactoryCreateZeroAmountsWithDiffContexts() { 181 for (Class type : MonetaryAmounts.getAmountTypes()) { 182 if (type.equals(TestAmount.class)) { 183 continue; 184 } 185 MonetaryAmountFactory<?> f = MonetaryAmounts.getAmountFactory(type); 186 f.setCurrency("GBP"); 187 f.setNumber(0); 188 MonetaryContext maxCtx = f.getMaximalMonetaryContext(); 189 if (maxCtx.getPrecision() != 0) { 190 for (int p = maxCtx.getPrecision(); p > 0; p--) { 191 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setPrecision(p).build()); 192 MonetaryAmount m = f.create(); 193 assertTrue( 194 "Section 4.2.6: Factory did not honor the precision set on the context for " + 195 type.getName(), 196 m.getContext().getPrecision() == 0 || m.getContext().getPrecision() >= p); 197 } 198 } else { 199 for (int p = 0; p < 100; p += 10) { 200 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setPrecision(p).build()); 201 MonetaryAmount m = f.create(); 202 assertTrue( 203 "Section 4.2.6: Factory did not honor the precision set on the context for " + 204 type.getName(), 205 m.getContext().getPrecision() == 0 || m.getContext().getPrecision() >= p); 206 } 207 } 208 if (maxCtx.getMaxScale() != -1) { 209 for (int s = maxCtx.getMaxScale(); s >= 0; s--) { 210 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setMaxScale(s).build()); 211 MonetaryAmount m = f.create(); 212 assertTrue( 213 "Section 4.2.6: Factory did not honor the scale set on the context for " + type.getName(), 214 m.getContext().getMaxScale() == -1 || m.getContext().getMaxScale() >= s); 215 } 216 } else { 217 for (int s = 0; s < 100; s += 10) { 218 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setMaxScale(s).build()); 219 MonetaryAmount m = f.create(); 220 assertTrue( 221 "Section 4.2.6: Factory did not honor the precision set on the context for " + 222 type.getName(), 223 m.getContext().getMaxScale() == -1 || m.getContext().getMaxScale() >= s); 224 } 225 } 226 } 227 } 228 229 /** 230 * For each MonetaryAmount Factory: Create zero amounts from a 231 * factory with monetary contexts. 232 */ 233 @Test(description = "4.2.6 Ensure MonetaryAmountFactory instances support creation of 0 amounts, with different " + 234 "explicit MonetaryContext.") 235 @SpecAssertion(section = "4.2.6", id = "426-B2") 236 public void testMonetaryAmountFactoryCreateZeroAmountsWithDiffContexts2() { 237 for (Class type : MonetaryAmounts.getAmountTypes()) { 238 if (type.equals(TestAmount.class)) { 239 continue; 240 } 241 MonetaryAmountFactory<?> f = MonetaryAmounts.getAmountFactory(type); 242 f.setCurrency("GBP"); 243 f.setNumber(0.0d); 244 MonetaryContext maxCtx = f.getMaximalMonetaryContext(); 245 if (maxCtx.getPrecision() != 0) { 246 for (int p = maxCtx.getPrecision(); p > 0; p--) { 247 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setPrecision(p).build()); 248 MonetaryAmount m = f.create(); 249 assertTrue( 250 "Section 4.2.6: Factory did not honor the precision set on the context for " + 251 type.getName(), 252 m.getContext().getPrecision() == 0 || m.getContext().getPrecision() >= p); 253 } 254 } else { 255 for (int p = 0; p < 100; p += 10) { 256 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setPrecision(p).build()); 257 MonetaryAmount m = f.create(); 258 assertTrue( 259 "Section 4.2.6: Factory did not honor the precision set on the context for " + 260 type.getName(), 261 m.getContext().getPrecision() == 0 || m.getContext().getPrecision() >= p); 262 } 263 } 264 if (maxCtx.getMaxScale() != -1) { 265 for (int s = maxCtx.getMaxScale(); s >= 0; s--) { 266 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setMaxScale(s).build()); 267 MonetaryAmount m = f.create(); 268 assertTrue( 269 "Section 4.2.6: Factory did not honor the scale set on the context for " + type.getName(), 270 m.getContext().getMaxScale() == -1 || m.getContext().getMaxScale() >= s); 271 } 272 } else { 273 for (int s = 0; s < 100; s += 10) { 274 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setMaxScale(s).build()); 275 MonetaryAmount m = f.create(); 276 assertTrue( 277 "Section 4.2.6: Factory did not honor the precision set on the context for " + 278 type.getName(), 279 m.getContext().getMaxScale() == -1 || m.getContext().getMaxScale() >= s); 280 } 281 } 282 } 283 } 284 285 /** 286 * For each MonetaryAmount Factory: Create zero amounts from a 287 * factory with monetary contexts. 288 */ 289 @Test(description = "4.2.6 Ensure MonetaryAmountFactory instances support creation of 0 amounts, with different " + 290 "explicit MonetaryContext (precision, scale).") 291 @SpecAssertion(section = "4.2.6", id = "426-B2") 292 public void testMonetaryAmountFactoryCreateZeroAmountsWithDiffContexts3() { 293 for (Class type : MonetaryAmounts.getAmountTypes()) { 294 if (type.equals(TestAmount.class)) { 295 continue; 296 } 297 MonetaryAmountFactory<?> f = MonetaryAmounts.getAmountFactory(type); 298 f.setCurrency("GBP"); 299 f.setNumber(BigDecimal.ZERO); 300 MonetaryContext maxCtx = f.getMaximalMonetaryContext(); 301 if (maxCtx.getPrecision() != 0) { 302 for (int p = maxCtx.getPrecision(); p > 0; p--) { 303 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setPrecision(p).build()); 304 MonetaryAmount m = f.create(); 305 assertTrue( 306 "Section 4.2.6: Factory did not honor the precision set on the context for " + 307 type.getName(), 308 m.getContext().getPrecision() == 0 || m.getContext().getPrecision() >= p); 309 } 310 } else { 311 for (int p = 0; p < 100; p += 10) { 312 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setPrecision(p).build()); 313 MonetaryAmount m = f.create(); 314 assertTrue( 315 "Section 4.2.6: Factory did not honor the precision set on the context for " + 316 type.getName(), 317 m.getContext().getPrecision() == 0 || m.getContext().getPrecision() >= p); 318 } 319 } 320 if (maxCtx.getMaxScale() != -1) { 321 for (int s = maxCtx.getMaxScale(); s >= 0; s--) { 322 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setMaxScale(s).build()); 323 MonetaryAmount m = f.create(); 324 assertTrue( 325 "Section 4.2.6: Factory did not honor the scale set on the context for " + type.getName(), 326 m.getContext().getMaxScale() == -1 || m.getContext().getMaxScale() >= s); 327 } 328 } else { 329 for (int s = 0; s < 100; s += 10) { 330 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setMaxScale(s).build()); 331 MonetaryAmount m = f.create(); 332 assertTrue( 333 "Section 4.2.6: Factory did not honor the precision set on the context for " + 334 type.getName(), 335 m.getContext().getMaxScale() == -1 || m.getContext().getMaxScale() >= s); 336 } 337 } 338 } 339 } 340 341 342 /** 343 * For each MonetaryAmount Factory: Bad Case: Create zero amounts 344 * from a factory with an invalid currency. 345 */ 346 @Test(description = "4.2.6 Bad case: For each MonetaryAmount Factory: Create zero amounts" + 347 " from a factory with an invalid currency.") 348 @SpecAssertion(section = "4.2.6", id = "426-B3") 349 public void testMonetaryAmountFactoryCreateAmountsWithInvalidCurrency() { 350 for (Class type : MonetaryAmounts.getAmountTypes()) { 351 if (type.equals(TestAmount.class)) { 352 continue; 353 } 354 for (Currency cur : Currency.getAvailableCurrencies()) { 355 MonetaryCurrencies.getCurrency(cur.getCurrencyCode()); 356 MonetaryAmountFactory<?> f = MonetaryAmounts.getAmountFactory(type); 357 try { 358 f.setCurrency("shjgssgsjgsj"); 359 AssertJUnit 360 .fail("Section 4.2.6: Factory should throw UnknownCurrencyException for invalid currency," + 361 " type was " + 362 type.getName()); 363 } catch (UnknownCurrencyException e) { 364 // OK 365 } 366 } 367 } 368 } 369 370 /** 371 * For each MonetaryAmount Factory: Bad Case: Create zero amounts 372 * from a factory with an invalid contexts. 373 */ 374 @Test(description = "4.2.6 Bad case: For each MonetaryAmount Factory: Create zero amounts" + 375 " from a factory with an invalid MonetaryContext.") 376 @SpecAssertion(section = "4.2.6", id = "426-B4") 377 public void testMonetaryAmountFactoryCreateAmountsWithInvalidMonetaryContext() { 378 for (Class type : MonetaryAmounts.getAmountTypes()) { 379 if (type.equals(TestAmount.class)) { 380 continue; 381 } 382 MonetaryAmountFactory<?> f = MonetaryAmounts.getAmountFactory(type); 383 try { 384 f.setCurrency("USD"); 385 MonetaryContext maxCtx = f.getMaximalMonetaryContext(); 386 if (maxCtx.getPrecision() != 0) { 387 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setPrecision(maxCtx.getPrecision() + 1) 388 .build()); 389 AssertJUnit.fail("Section 4.2.6: Factory should throw MonetaryException for invalid context " + 390 "(exceeding precision), " + 391 "type was " + 392 type.getName()); 393 } 394 if (maxCtx.getMaxScale() != -1) { 395 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setMaxScale(maxCtx.getMaxScale() + 1) 396 .build()); 397 AssertJUnit.fail("Section 4.2.6: Factory should throw MonetaryException for invalid context " + 398 "(exceeding scale), " + 399 "type was " + 400 type.getName()); 401 } 402 } catch (MonetaryException e) { 403 // OK 404 } 405 } 406 } 407 408 409 // ********************* C. Testing Creation of Amounts with positive values ************** 410 411 /** 412 * For each MonetaryAmount Factory: Create positive amounts from 413 * a factory with currencies. 414 */ 415 @Test(description = "4.2.6 For each MonetaryAmount Factory: Create positive amounts.") 416 @SpecAssertion(section = "4.2.6", id = "426-C1") 417 public void testMonetaryAmountFactoryCreatePositiveAmountsWitCurrencies() { 418 for (Class type : MonetaryAmounts.getAmountTypes()) { 419 if (type.equals(TestAmount.class)) { 420 continue; 421 } 422 for (Currency cur : Currency.getAvailableCurrencies()) { 423 CurrencyUnit cu = MonetaryCurrencies.getCurrency(cur.getCurrencyCode()); 424 MonetaryAmountFactory<?> f = MonetaryAmounts.getAmountFactory(type); 425 f.setCurrency(cu); 426 f.setNumber(1); 427 MonetaryAmount m = f.create(); 428 AssertJUnit.assertEquals( 429 "Section 4.2.6: Amount created with factory has invalid currency for " + type.getName(), cu, 430 m.getCurrency()); 431 AssertJUnit.assertEquals( 432 "Section 4.2.6: Amount created with factory returns invalid amount type " + type.getName(), 433 type, m.getClass()); 434 assertTrue( 435 "Section 4.2.6: Amount created with factory has invalid value for " + type.getName(), 436 m.isPositive()); 437 assertTrue( 438 "Section 4.2.6: Amount created with factory has invalid value for " + type.getName(), 439 m.signum() == 1); 440 assertTrue( 441 "Section 4.2.6: Amount created with factory has invalid value for " + type.getName(), 442 m.getNumber().intValueExact() == 1); 443 } 444 } 445 } 446 447 /** 448 * For each MonetaryAmount Factory: Create positive amounts from 449 * a factory with monetary contexts. 450 */ 451 @Test(description = "4.2.6 For each MonetaryAmount Factory: Create positive amounts with explicit MonetaryContext.") 452 @SpecAssertion(section = "4.2.6", id = "426-C2") 453 public void testMonetaryAmountFactoryCreatePositiveAmountsWithContexts() { 454 for (Class type : MonetaryAmounts.getAmountTypes()) { 455 if (type.equals(TestAmount.class)) { 456 continue; 457 } 458 MonetaryAmountFactory<?> f = MonetaryAmounts.getAmountFactory(type); 459 f.setCurrency("GBP"); 460 f.setNumber(1); 461 MonetaryContext maxCtx = f.getMaximalMonetaryContext(); 462 if (maxCtx.getPrecision() != 0) { 463 for (int p = maxCtx.getPrecision(); p > 0; p--) { 464 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setPrecision(p).build()); 465 MonetaryAmount m = f.create(); 466 assertTrue( 467 "Section 4.2.6: Factory did not honor the precision set on the context for " + 468 type.getName(), 469 m.getContext().getPrecision() == 0 || m.getContext().getPrecision() >= p); 470 } 471 } else { 472 for (int p = 0; p < 100; p += 10) { 473 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setPrecision(p).build()); 474 MonetaryAmount m = f.create(); 475 assertTrue( 476 "Section 4.2.6: Factory did not honor the precision set on the context for " + 477 type.getName(), 478 m.getContext().getPrecision() == 0 || m.getContext().getPrecision() >= p); 479 } 480 } 481 if (maxCtx.getMaxScale() != -1) { 482 for (int s = maxCtx.getMaxScale(); s >= 0; s--) { 483 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setMaxScale(s).build()); 484 MonetaryAmount m = f.create(); 485 assertTrue( 486 "Section 4.2.6: Factory did not honor the scale set on the context for " + type.getName(), 487 m.getContext().getMaxScale() == -1 || m.getContext().getMaxScale() >= s); 488 } 489 } else { 490 for (int s = 0; s < 100; s += 10) { 491 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setMaxScale(s).build()); 492 MonetaryAmount m = f.create(); 493 assertTrue( 494 "Section 4.2.6: Factory did not honor the precision set on the context for " + 495 type.getName(), 496 m.getContext().getMaxScale() == -1 || m.getContext().getMaxScale() >= s); 497 } 498 } 499 } 500 } 501 502 /** 503 * For each MonetaryAmount Factory: Create positive amounts from 504 * a factory with monetary contexts. 505 */ 506 @Test(description = 507 "4.2.6 For each MonetaryAmount Factory: Create positive amounts using doubles with explicit " + 508 "MonetaryContext " + 509 "(precision/scale).") 510 @SpecAssertion(section = "4.2.6", id = "426-C2") 511 public void testMonetaryAmountFactoryCreatePositiveAmountsWithContexts2() { 512 for (Class type : MonetaryAmounts.getAmountTypes()) { 513 if (type.equals(TestAmount.class)) { 514 continue; 515 } 516 MonetaryAmountFactory<?> f = MonetaryAmounts.getAmountFactory(type); 517 f.setCurrency("GBP"); 518 f.setNumber(1.0d); 519 MonetaryContext maxCtx = f.getMaximalMonetaryContext(); 520 if (maxCtx.getPrecision() != 0) { 521 for (int p = maxCtx.getPrecision(); p > 0; p--) { 522 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setPrecision(p).build()); 523 MonetaryAmount m = f.create(); 524 assertTrue( 525 "Section 4.2.6: Factory did not honor the precision set on the context for " + 526 type.getName(), 527 m.getContext().getPrecision() == 0 || m.getContext().getPrecision() >= p); 528 } 529 } else { 530 for (int p = 0; p < 100; p += 10) { 531 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setPrecision(p).build()); 532 MonetaryAmount m = f.create(); 533 assertTrue( 534 "Section 4.2.6: Factory did not honor the precision set on the context for " + 535 type.getName(), 536 m.getContext().getPrecision() == 0 || m.getContext().getPrecision() >= p); 537 } 538 } 539 if (maxCtx.getMaxScale() != -1) { 540 for (int s = maxCtx.getMaxScale(); s >= 0; s--) { 541 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setMaxScale(s).build()); 542 MonetaryAmount m = f.create(); 543 assertTrue( 544 "Section 4.2.6: Factory did not honor the scale set on the context for " + type.getName(), 545 m.getContext().getMaxScale() == -1 || m.getContext().getMaxScale() >= s); 546 } 547 } else { 548 for (int s = 0; s < 100; s += 10) { 549 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setMaxScale(s).build()); 550 MonetaryAmount m = f.create(); 551 assertTrue( 552 "Section 4.2.6: Factory did not honor the precision set on the context for " + 553 type.getName(), 554 m.getContext().getMaxScale() == -1 || m.getContext().getMaxScale() >= s); 555 } 556 } 557 } 558 } 559 560 /** 561 * For each MonetaryAmount Factory: Create positive amounts from 562 * a factory with monetary contexts. 563 */ 564 @Test(description = 565 "4.2.6 For each MonetaryAmount Factory: Create positive amounts using BigDecimal with explicit " + 566 "MonetaryContext " + 567 "(precision/scale).") 568 @SpecAssertion(section = "4.2.6", id = "426-C2") 569 public void testMonetaryAmountFactoryCreatePositiveAmountsWithContexts3() { 570 for (Class type : MonetaryAmounts.getAmountTypes()) { 571 if (type.equals(TestAmount.class)) { 572 continue; 573 } 574 MonetaryAmountFactory<?> f = MonetaryAmounts.getAmountFactory(type); 575 f.setCurrency("GBP"); 576 f.setNumber(BigDecimal.ONE); 577 MonetaryContext maxCtx = f.getMaximalMonetaryContext(); 578 if (maxCtx.getPrecision() != 0) { 579 for (int p = maxCtx.getPrecision(); p > 0; p--) { 580 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setPrecision(p).build()); 581 MonetaryAmount m = f.create(); 582 assertTrue( 583 "Section 4.2.6: Factory did not honor the precision set on the context for " + 584 type.getName(), 585 m.getContext().getPrecision() == 0 || m.getContext().getPrecision() >= p); 586 } 587 } else { 588 for (int p = 0; p < 100; p += 10) { 589 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setPrecision(p).build()); 590 MonetaryAmount m = f.create(); 591 assertTrue( 592 "Section 4.2.6: Factory did not honor the precision set on the context for " + 593 type.getName(), 594 m.getContext().getPrecision() == 0 || m.getContext().getPrecision() >= p); 595 } 596 } 597 if (maxCtx.getMaxScale() != -1) { 598 for (int s = maxCtx.getMaxScale(); s >= 0; s--) { 599 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setMaxScale(s).build()); 600 MonetaryAmount m = f.create(); 601 assertTrue( 602 "Section 4.2.6: Factory did not honor the scale set on the context for " + type.getName(), 603 m.getContext().getMaxScale() == -1 || m.getContext().getMaxScale() >= s); 604 } 605 } else { 606 for (int s = 0; s < 100; s += 10) { 607 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setMaxScale(s).build()); 608 MonetaryAmount m = f.create(); 609 assertTrue( 610 "Section 4.2.6: Factory did not honor the precision set on the context for " + 611 type.getName(), 612 m.getContext().getMaxScale() == -1 || m.getContext().getMaxScale() >= s); 613 } 614 } 615 } 616 } 617 618 /** 619 * For each MonetaryAmount Factory: Bad Case: Create positive 620 * amounts from a factory with an invalid numeric value (exceeding max 621 * MonetaryContext). 622 */ 623 @Test(description = 624 "4.2.6 Bad case: For each MonetaryAmount Factory: Create positive amounts using invalid numbers," + 625 " expecting ArithemticException thrown.") 626 @SpecAssertion(section = "4.2.6", id = "426-C3") 627 public void testMonetaryAmountFactoryCreatePositiveAmountsWithInvalidNumber() { 628 for (Class type : MonetaryAmounts.getAmountTypes()) { 629 if (type.equals(TestAmount.class)) { 630 continue; 631 } 632 MonetaryAmountFactory f = MonetaryAmounts.getAmountFactory(type); 633 f.setCurrency("INR"); 634 MonetaryContext ctx = f.getMaximalMonetaryContext(); 635 if (ctx.getPrecision() != 0) { 636 try { 637 f.setNumber(TestUtils.createNumberWithPrecision(f, ctx.getPrecision() + 5)); 638 f.create(); 639 AssertJUnit.fail("Section 4.2.6: MonetaryAmountFactory must throw an ArithmeticException, " + 640 "when an amount with exceeding precision is " + 641 "tried" + 642 643 " being created, type: " + 644 type.getName()); 645 } catch (ArithmeticException e) { 646 // OK 647 } 648 } 649 if (ctx.getMaxScale() != -1) { 650 try { 651 f.setNumber(TestUtils.createNumberWithScale(f, ctx.getMaxScale() + 5)); 652 f.create(); 653 AssertJUnit.fail("Section 4.2.6: MonetaryAmountFactory must throw an ArithmeticException, " + 654 "when an amount with exceeding scale is tried" + 655 " being created, type: " + 656 type.getName()); 657 } catch (ArithmeticException e) { 658 // OK 659 } 660 } 661 } 662 } 663 664 /** 665 * For each MonetaryAmount Factory: Bad Case: Create negative amounts from a factory with an no currency. 666 */ 667 @Test(description = "4.2.6 Bad case: For each MonetaryAmount Factory: Create negative amounts without currency," + 668 " expecting MonetaryException thrown.") 669 @SpecAssertion(section = "4.2.6", id = "426-C4") 670 public void testMonetaryAmountFactoryCreatePositiveNoCurrency_BadCase() { 671 for (Class type : MonetaryAmounts.getAmountTypes()) { 672 if (type.equals(TestAmount.class)) { 673 continue; 674 } 675 MonetaryAmountFactory f = MonetaryAmounts.getAmountFactory(type); 676 try { 677 if (f.getDefaultMonetaryContext().getPrecision() == 0) { 678 f.setNumber(TestUtils.createNumberWithPrecision(f, 5)); 679 } else { 680 f.setNumber(TestUtils.createNumberWithPrecision(f, f.getDefaultMonetaryContext().getPrecision())); 681 } 682 f.create(); 683 AssertJUnit.fail("Section 4.2.6: MonetaryAmountFactory must throw a MonetaryException, " + 684 "when a positive amount without a currency" + 685 " is" + 686 " tried to be created, type: " + 687 type.getName()); 688 } catch (MonetaryException e) { 689 // OK 690 } catch (Exception e) { 691 AssertJUnit.fail("Section 4.2.6: MonetaryAmountFactory must throw a MonetaryException, " + 692 "when a positive amount without a currency" + 693 " is" + 694 " tried to be created, but threw " + e.getClass() + " type: " + 695 type.getName()); 696 } 697 } 698 } 699 700 /** 701 * For each MonetaryAmount Factory: Bad Case: Create negative amounts from a factory with an invalid currency. 702 */ 703 @Test(description = 704 "4.2.6 Bad case: For each MonetaryAmount Factory: Create negative amounts with an invalid currency," + 705 " expecting MonetaryException thrown.") 706 @SpecAssertion(section = "4.2.6", id = "426-C4") 707 public void testMonetaryAmountFactoryCreatePositiveInvalidCurrency_BadCase() { 708 for (Class type : MonetaryAmounts.getAmountTypes()) { 709 if (type.equals(TestAmount.class)) { 710 continue; 711 } 712 MonetaryAmountFactory f = MonetaryAmounts.getAmountFactory(type); 713 try { 714 if (f.getDefaultMonetaryContext().getPrecision() == 0) { 715 f.setNumber(TestUtils.createNumberWithPrecision(f, 5)); 716 } else { 717 f.setNumber(TestUtils.createNumberWithPrecision(f, f.getDefaultMonetaryContext().getPrecision())); 718 } 719 f.setCurrency("FooBar_foobar_fOobAr_foObaR"); 720 f.create(); 721 AssertJUnit.fail("Section 4.2.6: MonetaryAmountFactory must throw a MonetaryException, " + 722 "when a positive amount with an invalid " + 723 "currency" + 724 " is" + 725 " tried to be created, type: " + 726 type.getName()); 727 } catch (MonetaryException e) { 728 // OK 729 } 730 } 731 } 732 733 /** 734 * For each MonetaryAmount Factory: Bad Case: Create negative amounts from a factory with an invalid currency. 735 */ 736 @Test(description = 737 "4.2.6 Bad case: For each MonetaryAmount Factory: Create negative amounts with an invalid currency," + 738 " expecting MonetaryException thrown.") 739 @SpecAssertion(section = "4.2.6", id = "426-C5") 740 public void testMonetaryAmountFactoryCreatePositiveInvalidContext_BadCase() { 741 for (Class type : MonetaryAmounts.getAmountTypes()) { 742 if (type.equals(TestAmount.class)) { 743 continue; 744 } 745 MonetaryAmountFactory f = MonetaryAmounts.getAmountFactory(type); 746 MonetaryContext mc = f.getMaximalMonetaryContext(); 747 try { 748 MonetaryContextBuilder b = mc.toBuilder(); 749 boolean runTest = false; // only run check, if we are able to construct an exceeding MonetaryContext 750 if (mc.getMaxScale() != -1) { 751 b.setMaxScale(mc.getMaxScale() + 10); 752 runTest = true; 753 } 754 if (mc.getPrecision() != -0) { 755 b.setPrecision(mc.getPrecision() + 10); 756 runTest = true; 757 } 758 if (runTest) { 759 f.setNumber(TestUtils.createNumberWithPrecision(f, f.getDefaultMonetaryContext().getPrecision())); 760 f.setCurrency("FooBar_foobar_fOobAr_foObaR"); 761 f.create(); 762 AssertJUnit.fail("Section 4.2.6: MonetaryAmountFactory must throw a MonetaryException, " + 763 "when a positive amount without an " + 764 "invalid MonetaryContext is" + 765 " tried to be created, type: " + 766 type.getName()); 767 } 768 } catch (MonetaryException e) { 769 // OK 770 } 771 } 772 } 773 774 775 // ************** D. Testing Creation of Amounts with negative values ******************* 776 777 /** 778 * For each MonetaryAmount Factory: Create negative amounts from 779 * a factory with currencies. 780 */ 781 @Test(description = "4.2.6 For each MonetaryAmount Factory: Create negative amounts.") 782 @SpecAssertion(section = "4.2.6", id = "426-D1") 783 public void testMonetaryAmountFactoryNegativePositiveAmountsWitCurrencies() { 784 for (Class type : MonetaryAmounts.getAmountTypes()) { 785 if (type.equals(TestAmount.class)) { 786 continue; 787 } 788 for (Currency cur : Currency.getAvailableCurrencies()) { 789 CurrencyUnit cu = MonetaryCurrencies.getCurrency(cur.getCurrencyCode()); 790 MonetaryAmountFactory<?> f = MonetaryAmounts.getAmountFactory(type); 791 f.setCurrency(cu); 792 f.setNumber(-3); 793 MonetaryAmount m = f.create(); 794 AssertJUnit.assertEquals( 795 "Section 4.2.6: Amount created with factory has invalid currency for " + type.getName(), cu, 796 m.getCurrency()); 797 AssertJUnit.assertEquals( 798 "Section 4.2.6: Amount created with factory returns invalid amount type " + type.getName(), 799 type, m.getClass()); 800 assertTrue( 801 "Section 4.2.6: Amount created with factory has invalid value for " + type.getName(), 802 m.isNegative()); 803 assertTrue( 804 "Section 4.2.6: Amount created with factory has invalid value for " + type.getName(), 805 m.signum() == -1); 806 assertTrue( 807 "Section 4.2.6: Amount created with factory has invalid value for " + type.getName(), 808 m.getNumber().intValueExact() == -3); 809 } 810 } 811 } 812 813 /** 814 * For each MonetaryAmount Factory: Create negative amounts from 815 * a factory with monetary contexts. 816 */ 817 @Test(description = "4.2.6 For each MonetaryAmount Factory: Create negative amounts, with explicit" + 818 " MonetaryContext.") 819 @SpecAssertion(section = "4.2.6", id = "426-D2") 820 public void testMonetaryAmountFactoryNegativePositiveAmountsWithContexts() { 821 for (Class type : MonetaryAmounts.getAmountTypes()) { 822 if (type.equals(TestAmount.class)) { 823 continue; 824 } 825 MonetaryAmountFactory<?> f = MonetaryAmounts.getAmountFactory(type); 826 f.setCurrency("GBP"); 827 f.setNumber(1); 828 MonetaryContext maxCtx = f.getMaximalMonetaryContext(); 829 if (maxCtx.getPrecision() != 0) { 830 for (int p = maxCtx.getPrecision(); p > 0; p--) { 831 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setPrecision(p).build()); 832 MonetaryAmount m = f.create(); 833 assertTrue( 834 "Section 4.2.6: Factory did not honor the precision set on the context for " + 835 type.getName(), 836 m.getContext().getPrecision() == 0 || m.getContext().getPrecision() >= p); 837 } 838 } else { 839 for (int p = 0; p < 100; p += 10) { 840 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setPrecision(p).build()); 841 MonetaryAmount m = f.create(); 842 assertTrue( 843 "Section 4.2.6: Factory did not honor the precision set on the context for " + 844 type.getName(), 845 m.getContext().getPrecision() == 0 || m.getContext().getPrecision() >= p); 846 } 847 } 848 if (maxCtx.getMaxScale() != -1) { 849 for (int s = maxCtx.getMaxScale(); s >= 0; s--) { 850 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setMaxScale(s).build()); 851 MonetaryAmount m = f.create(); 852 assertTrue( 853 "Section 4.2.6: Factory did not honor the scale set on the context for " + type.getName(), 854 m.getContext().getMaxScale() == -1 || m.getContext().getMaxScale() >= s); 855 } 856 } else { 857 for (int s = 0; s < 100; s += 10) { 858 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setMaxScale(s).build()); 859 MonetaryAmount m = f.create(); 860 assertTrue( 861 "Section 4.2.6: Factory did not honor the precision set on the context for " + 862 type.getName(), 863 m.getContext().getMaxScale() == -1 || m.getContext().getMaxScale() >= s); 864 } 865 } 866 } 867 } 868 869 /** 870 * For each MonetaryAmount Factory: Create negative amounts from 871 * a factory with monetary contexts. 872 */ 873 @Test(description = "4.2.6 For each MonetaryAmount Factory: Create negative amounts, with explicit " + 874 "MonetaryContext.") 875 @SpecAssertion(section = "4.2.6", id = "426-D2") 876 public void testMonetaryAmountFactoryNegativePositiveAmountsWithContexts2() { 877 for (Class type : MonetaryAmounts.getAmountTypes()) { 878 if (type.equals(TestAmount.class)) { 879 continue; 880 } 881 MonetaryAmountFactory<?> f = MonetaryAmounts.getAmountFactory(type); 882 f.setCurrency("GBP"); 883 f.setNumber(11.2); 884 MonetaryContext maxCtx = f.getMaximalMonetaryContext(); 885 if (maxCtx.getPrecision() != 0) { 886 for (int p = maxCtx.getPrecision(); p > 0; p--) { 887 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setPrecision(p).build()); 888 MonetaryAmount m = f.create(); 889 assertTrue( 890 "Section 4.2.6: Factory did not honor the precision set on the context for " + 891 type.getName(), 892 m.getContext().getPrecision() == 0 || m.getContext().getPrecision() >= p); 893 } 894 } else { 895 for (int p = 0; p < 100; p += 10) { 896 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setPrecision(p).build()); 897 MonetaryAmount m = f.create(); 898 assertTrue( 899 "Section 4.2.6: Factory did not honor the precision set on the context for " + 900 type.getName(), 901 m.getContext().getPrecision() == 0 || m.getContext().getPrecision() >= p); 902 } 903 } 904 if (maxCtx.getMaxScale() != -1) { 905 for (int s = maxCtx.getMaxScale(); s >= 0; s--) { 906 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setMaxScale(s).build()); 907 MonetaryAmount m = f.create(); 908 assertTrue( 909 "Section 4.2.6: Factory did not honor the scale set on the context for " + type.getName(), 910 m.getContext().getMaxScale() == -1 || m.getContext().getMaxScale() >= s); 911 } 912 } else { 913 for (int s = 0; s < 100; s += 10) { 914 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setMaxScale(s).build()); 915 MonetaryAmount m = f.create(); 916 assertTrue( 917 "Section 4.2.6: Factory did not honor the precision set on the context for " + 918 type.getName(), 919 m.getContext().getMaxScale() == -1 || m.getContext().getMaxScale() >= s); 920 } 921 } 922 } 923 } 924 925 /** 926 * For each MonetaryAmount Factory: Create negative amounts from 927 * a factory with monetary contexts. 928 */ 929 @Test(description = "4.2.6 For each MonetaryAmount Factory: Create negative amounts, with explicit " + 930 "MonetaryContext.") 931 @SpecAssertion(section = "4.2.6", id = "426-D2") 932 public void testMonetaryAmountFactoryNegativePositiveAmountsWithContexts3() { 933 for (Class type : MonetaryAmounts.getAmountTypes()) { 934 if (type.equals(TestAmount.class)) { 935 continue; 936 } 937 MonetaryAmountFactory<?> f = MonetaryAmounts.getAmountFactory(type); 938 f.setCurrency("GBP"); 939 f.setNumber(BigDecimal.TEN); 940 MonetaryContext maxCtx = f.getMaximalMonetaryContext(); 941 if (maxCtx.getPrecision() != 0) { 942 for (int p = maxCtx.getPrecision(); p > 0; p--) { 943 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setPrecision(p).build()); 944 MonetaryAmount m = f.create(); 945 assertTrue( 946 "Section 4.2.6: Factory did not honor the precision set on the context for " + 947 type.getName(), 948 m.getContext().getPrecision() == 0 || m.getContext().getPrecision() >= p); 949 } 950 } else { 951 for (int p = 0; p < 100; p += 10) { 952 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setPrecision(p).build()); 953 MonetaryAmount m = f.create(); 954 assertTrue( 955 "Section 4.2.6: Factory did not honor the precision set on the context for " + 956 type.getName(), 957 m.getContext().getPrecision() == 0 || m.getContext().getPrecision() >= p); 958 } 959 } 960 if (maxCtx.getMaxScale() != -1) { 961 for (int s = maxCtx.getMaxScale(); s >= 0; s--) { 962 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setMaxScale(s).build()); 963 MonetaryAmount m = f.create(); 964 assertTrue( 965 "Section 4.2.6: Factory did not honor the scale set on the context for " + type.getName(), 966 m.getContext().getMaxScale() == -1 || m.getContext().getMaxScale() >= s); 967 } 968 } else { 969 for (int s = 0; s < 100; s += 10) { 970 f.setContext(MonetaryContextBuilder.of(MonetaryAmount.class).setMaxScale(s).build()); 971 MonetaryAmount m = f.create(); 972 assertTrue( 973 "Section 4.2.6: Factory did not honor the precision set on the context for " + 974 type.getName(), 975 m.getContext().getMaxScale() == -1 || m.getContext().getMaxScale() >= s); 976 } 977 } 978 } 979 } 980 981 /** 982 * For each MonetaryAmount Factory: Bad Case: Create negative 983 * amounts from a factory with an invalid numeric value (exceeding max 984 * MonetaryContext). 985 */ 986 @Test(description = "4.2.6 Bad case: For each MonetaryAmount Factory: Create negative amounts, with invalid " + 987 "numeric value, expect ArithmeticException.") 988 @SpecAssertion(section = "4.2.6", id = "426-D3") 989 public void testMonetaryAmountFactoryNegativePositiveAmountsWithInvalidNumber() { 990 for (Class type : MonetaryAmounts.getAmountTypes()) { 991 if (type.equals(TestAmount.class)) { 992 continue; 993 } 994 MonetaryAmountFactory f = MonetaryAmounts.getAmountFactory(type); 995 f.setCurrency("INR"); 996 MonetaryContext ctx = f.getMaximalMonetaryContext(); 997 if (ctx.getPrecision() != 0) { 998 try { 999 f.setNumber(TestUtils.createNumberWithPrecision(f, ctx.getPrecision() + 5).negate()); 1000 f.create(); 1001 AssertJUnit.fail("Section 4.2.6: MonetaryAmountFactory must throw an ArithmeticException, " + 1002 "when an amount with exceeding precision is " + 1003 "tried" + 1004 1005 " being created, type: " + 1006 type.getName()); 1007 } catch (ArithmeticException e) { 1008 // OK 1009 } 1010 } 1011 if (ctx.getMaxScale() != -1) { 1012 try { 1013 f.setNumber(TestUtils.createNumberWithScale(f, ctx.getMaxScale() + 5).negate()); 1014 f.create(); 1015 AssertJUnit.fail("Section 4.2.6: MonetaryAmountFactory must throw an ArithmeticException, " + 1016 "when an amount with exceeding scale is tried" + 1017 " being created, type: " + 1018 type.getName()); 1019 } catch (ArithmeticException e) { 1020 // OK 1021 } 1022 } 1023 } 1024 } 1025 1026 /** 1027 * For each MonetaryAmount Factory: Bad Case: Create negative amounts from a factory with an no currency. 1028 */ 1029 @Test(description = "4.2.6 Bad case: For each MonetaryAmount Factory: Create negative amounts, with no " + 1030 "currency, expect MonetaryException.") 1031 @SpecAssertion(section = "4.2.6", id = "426-D4") 1032 public void testMonetaryAmountFactoryCreateNegativeNoCurrency_BadCase() { 1033 for (Class type : MonetaryAmounts.getAmountTypes()) { 1034 if (type.equals(TestAmount.class)) { 1035 continue; 1036 } 1037 MonetaryAmountFactory f = MonetaryAmounts.getAmountFactory(type); 1038 try { 1039 if (f.getDefaultMonetaryContext().getPrecision() == 0) { 1040 f.setNumber(TestUtils.createNumberWithPrecision(f, 5).negate()); 1041 } else { 1042 f.setNumber(TestUtils.createNumberWithPrecision(f, f.getDefaultMonetaryContext().getPrecision()) 1043 .negate()); 1044 } 1045 f.create(); 1046 AssertJUnit.fail("Section 4.2.6: MonetaryAmountFactory must throw a MonetaryException, " + 1047 "when an amount without a currency is" + 1048 " tried to be created, type: " + 1049 type.getName()); 1050 } catch (MonetaryException e) { 1051 // OK 1052 } catch (Exception e) { 1053 AssertJUnit.fail("Section 4.2.6: MonetaryAmountFactory must throw a MonetaryException, " + 1054 "when an amount without a currency is" + 1055 " tried to be created, but threw " + e.getClass() + " type: " + 1056 type.getName()); 1057 } 1058 } 1059 } 1060 1061 /** 1062 * For each MonetaryAmount Factory: Bad Case: Create negative amounts from a factory with an invalid currency. 1063 */ 1064 @Test(description = "4.2.6 Bad case: For each MonetaryAmount Factory: Create negative amounts, with invalid " + 1065 "currency, expect MonetaryException.") 1066 @SpecAssertion(section = "4.2.6", id = "426-D4") 1067 public void testMonetaryAmountFactoryCreateNegativeInvalidCurrency_BadCase() { 1068 for (Class type : MonetaryAmounts.getAmountTypes()) { 1069 if (type.equals(TestAmount.class)) { 1070 continue; 1071 } 1072 MonetaryAmountFactory f = MonetaryAmounts.getAmountFactory(type); 1073 try { 1074 if (f.getDefaultMonetaryContext().getPrecision() == 0) { 1075 f.setNumber(TestUtils.createNumberWithPrecision(f, 5).negate()); 1076 } else { 1077 f.setNumber(TestUtils.createNumberWithPrecision(f, f.getDefaultMonetaryContext().getPrecision()) 1078 .negate()); 1079 } 1080 f.setCurrency("Section 4.2.6: FooBar_foobar_fOobAr_foObaR"); 1081 f.create(); 1082 AssertJUnit.fail("Section 4.2.6: MonetaryAmountFactory must throw a MonetaryException, " + 1083 "when an amount with an invalid " + 1084 "currency is tried to be created, type: " + 1085 type.getName()); 1086 } catch (MonetaryException e) { 1087 // OK 1088 } 1089 } 1090 } 1091 1092 /** 1093 * For each MonetaryAmount Factory: Bad Case: Create negative amounts from a factory with an invalid currency. 1094 */ 1095 @Test(description = "4.2.6 Bad case: For each MonetaryAmount Factory: Create negative amounts, with no " + 1096 "currency, expect MonetaryException.") 1097 @SpecAssertion(section = "4.2.6", id = "426-D5") 1098 public void testMonetaryAmountFactoryCreateNegativeInvalidContext_BadCase() { 1099 for (Class type : MonetaryAmounts.getAmountTypes()) { 1100 if (type.equals(TestAmount.class)) { 1101 continue; 1102 } 1103 MonetaryAmountFactory f = MonetaryAmounts.getAmountFactory(type); 1104 MonetaryContext mc = f.getMaximalMonetaryContext(); 1105 try { 1106 MonetaryContextBuilder b = mc.toBuilder(); 1107 boolean runTest = false; // only run check, if we are able to construct an exceeding MonetaryContext 1108 if (mc.getMaxScale() != -1) { 1109 b.setMaxScale(mc.getMaxScale() + 10); 1110 runTest = true; 1111 } 1112 if (mc.getPrecision() != -0) { 1113 b.setPrecision(mc.getPrecision() + 10); 1114 runTest = true; 1115 } 1116 if (runTest) { 1117 if (f.getDefaultMonetaryContext().getPrecision() == 0) { 1118 f.setNumber(TestUtils.createNumberWithPrecision(f, 5).negate()); 1119 } else { 1120 f.setNumber(TestUtils.createNumberWithPrecision(f, f.getDefaultMonetaryContext().getPrecision()) 1121 .negate()); 1122 } 1123 f.setCurrency("FooBar_foobar_fOobAr_foObaR"); 1124 f.create(); 1125 AssertJUnit.fail("Section 4.2.6: MonetaryAmountFactory must throw a MonetaryException, " + 1126 "when an amount with an invalid " + 1127 "MonetaryContext is tried to be created, type: " + 1128 type.getName()); 1129 } 1130 } catch (MonetaryException e) { 1131 // OK 1132 } 1133 } 1134 } 1135 1136 /** 1137 * For each MonetaryAmount Factory: Bad Case: Create negative amounts from a factory with an invalid currency. 1138 */ 1139 @Test(description = "4.2.7 Ensure the types available, must be at least one type.") 1140 @SpecAssertion(section = "4.2.7", id = "427-B1") 1141 public void testMonetaryAmountTypes_Available() { 1142 Collection<Class<? extends MonetaryAmount>> types = MonetaryAmounts.getAmountTypes(); 1143 assertNotNull("Section 4.2.6: MonetaryAmounts returns null for amount implementations.", types); 1144 assertTrue("Section 4.2.6: MonetaryAmounts does not provide any amount implementations.", types.size() > 0); 1145 } 1146 1147}