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