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.TCKTestSetup; 013import org.javamoney.tck.TestUtils; 014import org.javamoney.tck.tests.internal.TestAmount; 015import org.jboss.test.audit.annotations.SpecAssertion; 016import org.jboss.test.audit.annotations.SpecVersion; 017import org.mutabilitydetector.unittesting.MutabilityAssertionError; 018import org.testng.AssertJUnit; 019import org.testng.annotations.Test; 020 021import javax.money.CurrencyUnit; 022import javax.money.Monetary; 023import javax.money.MonetaryAmount; 024import javax.money.MonetaryAmountFactory; 025import javax.money.MonetaryContext; 026import javax.money.MonetaryException; 027import javax.money.MonetaryOperator; 028import javax.money.MonetaryQuery; 029import javax.money.NumberValue; 030import java.math.BigDecimal; 031import java.math.RoundingMode; 032import java.util.ArrayList; 033import java.util.Currency; 034import java.util.List; 035 036 037@SpecVersion(spec = "JSR 354", version = "1.0.0") 038public class ModellingMonetaryAmountsTest { 039 040 private final static String DEFAULT_CURRENCY = "CHF"; 041 042 private final static String ADDITIONAL_CURRENCY = "USD"; 043 044 /** 045 * Ensure at least one MonetaryAmount implementation is registered, 046 * by calling Monetary.getAmountTypes(); 047 */ 048 @SpecAssertion(section = "4.2.2", id = "422-0") 049 @Test(description = "4.2.2 Ensure Monetary.getAmountTypes() is not null and not empty.") 050 public void testEnsureMonetaryAmount() { 051 AssertJUnit.assertNotNull("Section 4.2.2: Monetary.getAmountTypes() must never return null.", 052 Monetary.getAmountTypes()); 053 AssertJUnit.assertTrue( 054 "Section 4.2.2: At least one type must be registered with Monetary (see getAmountTypes()).", 055 !Monetary.getAmountTypes().isEmpty()); 056 } 057 058 /** 059 * For each MonetaryAmount implementation: Ensure getCurrencyCode 060 * returns correct results. 061 */ 062 @SpecAssertion(section = "4.2.2", id = "422-A1") 063 @Test(description = "4.2.2 Ensure amount can be created with all default currencies.") 064 public void testCurrencyCode() { 065 for (Class type : Monetary.getAmountTypes()) { 066 for (Currency jdkCur : Currency.getAvailableCurrencies()) { 067 MonetaryAmount amount = 068 Monetary.getDefaultAmountFactory().setCurrency(jdkCur.getCurrencyCode()).setNumber(10.15) 069 .create(); 070 AssertJUnit.assertNotNull( 071 "Section 4.2.2: Amount factory returned null for new amount type: " + type.getName(), amount); 072 AssertJUnit.assertNotNull( 073 "Section 4.2.2: Amount factory returned new amount with null currency, type: " + type.getName(), 074 amount.getCurrency()); 075 AssertJUnit.assertEquals( 076 "Section 4.2.2: Amount factory returned new amount with invalid currency, type: " + 077 type.getName(), jdkCur.getCurrencyCode(), amount.getCurrency().getCurrencyCode()); 078 } 079 } 080 } 081 082 /** 083 * For each MonetaryAmount implementation: Ensure getNumber() 084 * returns correct results. 085 */ 086 @SpecAssertion(section = "4.2.2", id = "422-A2") 087 @Test(description = "4.2.2 Ensure amounts created return correct getNumber().") 088 public void testGetNumber() { 089 for (Class type : Monetary.getAmountTypes()) { 090 if (type.equals(TestAmount.class)) { 091 continue; 092 } 093 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 094 f.setCurrency("CHF"); 095 MonetaryAmount[] moneys = new MonetaryAmount[]{f.setNumber(100).create(), 096 f.setNumber(new BigDecimal("23123213.435")).create(), 097 f.setNumber(new BigDecimal("-23123213.435")).create(), f.setNumber(-23123213).create(), 098 f.setNumber(0).create()}; 099 BigDecimal[] numbers = new BigDecimal[]{new BigDecimal("100"), new BigDecimal("23123213.435"), 100 new BigDecimal("-23123213.435"), new BigDecimal("-23123213"), BigDecimal.ZERO}; 101 int[] intNums = new int[]{100, 23123213, -23123213, -23123213, 0}; 102 long[] longNums = new long[]{100, 23123213, -23123213, -23123213, 0}; 103 double[] doubleNums = new double[]{100, 23123213.435, -23123213.435, -23123213, 0}; 104 float[] floatNums = new float[]{100f, 23123213.435f, -23123213.435f, -23123213, 0f}; 105 106 for (int i = 0; i < moneys.length; i++) { 107 NumberValue nv = moneys[i].getNumber(); 108 AssertJUnit.assertNotNull("Section 4.2.2: Amount returned returns null for getNumber(), type: " + 109 moneys[i].getClass().getName(), nv); 110 AssertJUnit.assertEquals( 111 "Section 4.2.2: getNumber().numberValue(BigDecimal.class) incorrect for " + type.getName(), 112 numbers[i].stripTrailingZeros(), nv.numberValue(BigDecimal.class).stripTrailingZeros()); 113 AssertJUnit.assertEquals("Section 4.2.2: getNumber().intValue() incorrect for " + type.getName(), 114 intNums[i], nv.intValue()); 115 AssertJUnit.assertEquals("Section 4.2.2: getNumber().longValue() incorrect for " + type.getName(), 116 longNums[i], nv.longValue()); 117 AssertJUnit.assertEquals("Section 4.2.2: getNumber().doubleValue() incorrect for " + type.getName(), 118 doubleNums[i], nv.doubleValue(), 0.0d); 119 AssertJUnit.assertEquals("Section 4.2.2: getNumber().floatValue() incorrect for " + type.getName(), 120 floatNums[i], nv.floatValue(), 0.0d); 121 } 122 } 123 } 124 125 /** 126 * For each MonetaryAmount implementation: Ensure 127 * getContext() returns correct results. 128 */ 129 @SpecAssertion(section = "4.2.2", id = "422-A3") 130 @Test(description = "4.2.2 Ensure amounts created return correct getContext().") 131 public void testGetMonetaryContext() { 132 for (Class type : Monetary.getAmountTypes()) { 133 if (type.equals(TestAmount.class)) { 134 continue; 135 } 136 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 137 f.setCurrency("CHF"); 138 MonetaryContext defCtx = f.getDefaultMonetaryContext(); 139 MonetaryContext maxCtx = f.getMaximalMonetaryContext(); 140 MonetaryContext mc = f.setNumber(1).create().getContext(); 141 AssertJUnit.assertEquals("Section 4.2.2: Invalid MonetaryContext(amountType) for " + type.getName(), 142 mc.getAmountType(), type); 143 if (maxCtx.getPrecision() > 0) { 144 AssertJUnit.assertTrue("Section 4.2.2: Invalid MonetaryContext(precision) for " + type.getName(), 145 mc.getPrecision() <= maxCtx.getPrecision()); 146 } 147 if (maxCtx.getMaxScale() > 0) { 148 AssertJUnit.assertTrue("Section 4.2.2: Invalid MonetaryContext(maxScale) for " + type.getName(), 149 mc.getMaxScale() <= maxCtx.getMaxScale()); 150 } 151 AssertJUnit.assertEquals("Section 4.2.2: Invalid MonetaryContext(amountType) for " + type.getName(), 152 f.setNumber(0.34746d).create().getContext().getAmountType(), type); 153 mc = f.setNumber(0).create().getContext(); 154 AssertJUnit.assertEquals("Section 4.2.2: Invalid MonetaryContext(amountType) for " + type.getName(), 155 mc.getAmountType(), type); 156 if (maxCtx.getPrecision() > 0) { 157 AssertJUnit.assertTrue("Section 4.2.2: Invalid MonetaryContext(precision) for " + type.getName(), 158 mc.getPrecision() <= maxCtx.getPrecision()); 159 } 160 if (maxCtx.getMaxScale() > 0) { 161 AssertJUnit.assertTrue("Section 4.2.2: Invalid MonetaryContext(maxScale) for " + type.getName(), 162 mc.getMaxScale() <= maxCtx.getMaxScale()); 163 } 164 AssertJUnit.assertEquals("Section 4.2.2: Invalid MonetaryContext(amountType) for " + type.getName(), 165 f.setNumber(100034L).create().getContext().getAmountType(), type); 166 mc = f.setNumber(0).create().getContext(); 167 AssertJUnit.assertEquals("Section 4.2.2: Invalid MonetaryContext(amountType) for " + type.getName(), 168 mc.getAmountType(), type); 169 if (maxCtx.getPrecision() > 0) { 170 AssertJUnit.assertTrue("Section 4.2.2: Invalid MonetaryContext(precision) for " + type.getName(), 171 mc.getPrecision() <= maxCtx.getPrecision()); 172 } 173 if (maxCtx.getMaxScale() > 0) { 174 AssertJUnit.assertTrue("Section 4.2.2: Invalid MonetaryContext(maxScale) for " + type.getName(), 175 mc.getMaxScale() <= maxCtx.getMaxScale()); 176 } 177 } 178 } 179 180 /** 181 * For each MonetaryAmount implementation: Ensure isNegative() 182 * returns correct results. 183 */ 184 @SpecAssertion(section = "4.2.2", id = "422-A4") 185 @Test(description = "4.2.2 For each amount class, test isNegative().") 186 public void testIsNegative() { 187 for (Class type : Monetary.getAmountTypes()) { 188 if (type.equals(TestAmount.class)) { 189 continue; 190 } 191 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 192 f.setCurrency("CHF"); 193 MonetaryAmount[] moneys = new MonetaryAmount[]{f.setNumber(0).create(), f.setNumber(0.0).create(), 194 f.setNumber(BigDecimal.ZERO).create(), f.setNumber(new BigDecimal("0.00000000000000000")).create(), 195 f.setNumber(100).create(), f.setNumber(34242344).create(), f.setNumber(23123213.435).create()}; 196 for (MonetaryAmount m : moneys) { 197 AssertJUnit.assertFalse("Section 4.2.2: Invalid isNegative (expected false) for " + type.getName(), 198 m.isNegative()); 199 } 200 moneys = new MonetaryAmount[]{f.setNumber(-100).create(), f.setNumber(-34242344).create(), 201 f.setNumber(-23123213.435).create()}; 202 for (MonetaryAmount m : moneys) { 203 AssertJUnit.assertTrue("Section 4.2.2: Invalid isNegative (expected true) for " + type.getName(), 204 m.isNegative()); 205 } 206 } 207 } 208 209 /** 210 * For each MonetaryAmount implementation: Ensure isPositive() 211 * returns correct results. 212 */ 213 @SpecAssertion(section = "4.2.2", id = "422-A5") 214 @Test(description = "4.2.2 For each amount class, test isPositive().") 215 public void testIsPositive() { 216 for (Class type : Monetary.getAmountTypes()) { 217 if (type.equals(TestAmount.class)) { 218 continue; 219 } 220 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 221 f.setCurrency("CHF"); 222 MonetaryAmount[] moneys = new MonetaryAmount[]{f.setNumber(100).create(), f.setNumber(34242344).create(), 223 f.setNumber(23123213.435).create()}; 224 for (MonetaryAmount m : moneys) { 225 AssertJUnit.assertTrue("Section 4.2.2: Invalid isPositive (expected true) for " + type.getName(), 226 m.isPositive()); 227 } 228 moneys = new MonetaryAmount[]{f.setNumber(0).create(), f.setNumber(0.0).create(), 229 f.setNumber(BigDecimal.ZERO).create(), f.setNumber(new BigDecimal("0.00000000000000000")).create(), 230 f.setNumber(-100).create(), f.setNumber(-34242344).create(), f.setNumber(-23123213.435).create()}; 231 for (MonetaryAmount m : moneys) { 232 AssertJUnit.assertFalse("Section 4.2.2: Invalid isPositive (expected false) for " + type.getName(), 233 m.isPositive()); 234 } 235 } 236 } 237 238 239 /** 240 * For each MonetaryAmount implementation: Ensure isZero() 241 * returns correct results. 242 */ 243 @SpecAssertion(section = "4.2.2", id = "422-A6") 244 @Test(description = "4.2.2 For each amount class, test isZero().") 245 public void testIsZero() { 246 for (Class type : Monetary.getAmountTypes()) { 247 if (type.equals(TestAmount.class)) { 248 continue; 249 } 250 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 251 f.setCurrency("CHF"); 252 MonetaryAmount[] moneys = new MonetaryAmount[]{f.setNumber(100).create(), f.setNumber(34242344).create(), 253 f.setNumber(23123213.435).create(), f.setNumber(-100).create(), 254 f.setNumber(-723527.36532).create()}; 255 for (MonetaryAmount m : moneys) { 256 AssertJUnit.assertFalse("Section 4.2.2: Invalid isZero (expected false) for " + type.getName(), 257 m.isZero()); 258 } 259 moneys = new MonetaryAmount[]{f.setNumber(0).create(), f.setNumber(0.0).create(), 260 f.setNumber(BigDecimal.ZERO).create(), f.setNumber(new BigDecimal("0.00000000000000000")).create()}; 261 for (MonetaryAmount m : moneys) { 262 AssertJUnit 263 .assertTrue("Section 4.2.2: Invalid isZero (expected true) for " + type.getName(), m.isZero()); 264 } 265 } 266 } 267 268 /** 269 * For each MonetaryAmount implementation: Ensure isZero() 270 * returns correct results (-0, +0 == 0). 271 */ 272 @SpecAssertion(section = "4.2.2", id = "422-A6") 273 @Test(description = "4.2.2 For each amount class, test isZero(), advanced.") 274 public void testIsZeroAdvanced() { 275 for (Class type : Monetary.getAmountTypes()) { 276 if (type.equals(TestAmount.class)) { 277 continue; 278 } 279 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 280 f.setCurrency("CHF"); 281 MonetaryAmount[] moneys = 282 new MonetaryAmount[]{f.setNumber(-0).create(), f.setNumber(0).create(), f.setNumber(-0.0f).create(), 283 f.setNumber(0.0f).create(), f.setNumber(-0.0d).create(), f.setNumber(0.0d).create()}; 284 for (MonetaryAmount m : moneys) { 285 AssertJUnit 286 .assertTrue("Section 4.2.2: Invalid isZero (expected true) for " + type.getName(), m.isZero()); 287 } 288 } 289 } 290 291 /** 292 * For each MonetaryAmount implementation: signum() function is 293 * implemented correctly. 294 */ 295 @SpecAssertion(section = "4.2.2", id = "422-A7") 296 @Test(description = "4.2.2 For each amount class, test signum().") 297 public void testSignum() { 298 for (Class type : Monetary.getAmountTypes()) { 299 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 300 f.setCurrency("CHF"); 301 MonetaryAmount m = f.setNumber(100).create(); 302 AssertJUnit.assertEquals("Section 4.2.2: Invalid signum of 100 for " + type.getName(), 1, m.signum()); 303 m = f.setNumber(-100).create(); 304 AssertJUnit.assertEquals("Section 4.2.2: signum of -100 for " + type.getName(), -1, m.signum()); 305 m = f.setNumber(100.3435).create(); 306 AssertJUnit.assertEquals("Section 4.2.2: signum of 100.3435 for " + type.getName(), 1, m.signum()); 307 m = f.setNumber(-100.3435).create(); 308 AssertJUnit.assertEquals("Section 4.2.2: signum of -100.3435 for " + type.getName(), -1, m.signum()); 309 m = f.setNumber(0).create(); 310 AssertJUnit.assertEquals("Section 4.2.2: signum of 0 for " + type.getName(), 0, m.signum()); 311 m = f.setNumber(-0).create(); 312 AssertJUnit.assertEquals("Section 4.2.2: signum of - for " + type.getName(), 0, m.signum()); 313 } 314 } 315 316 /** 317 * For each MonetaryAmount implementation: Ensure isNegativeOrZero() 318 * returns correct results. 319 */ 320 @SpecAssertion(section = "4.2.2", id = "422-A8") 321 @Test(description = "4.2.2 For each amount class, test isNegativeOrZero().") 322 public void testIsNegativeOrZero() { 323 for (Class type : Monetary.getAmountTypes()) { 324 if (type.equals(TestAmount.class)) { 325 continue; 326 } 327 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 328 f.setCurrency("CHF"); 329 MonetaryAmount[] moneys = new MonetaryAmount[]{f.setNumber(100).create(), f.setNumber(34242344).create(), 330 f.setNumber(23123213.435).create()}; 331 for (MonetaryAmount m : moneys) { 332 AssertJUnit.assertFalse("Section 4.2.2: Invalid negativeOrZero (expected false) for " + type.getName(), 333 m.isNegativeOrZero()); 334 } 335 moneys = new MonetaryAmount[]{f.setNumber(0).create(), f.setNumber(0.0).create(), 336 f.setNumber(BigDecimal.ZERO).create(), f.setNumber(new BigDecimal("0.0000")).create(), 337 f.setNumber(-100).create(), f.setNumber(-34242344).create(), f.setNumber(-23123213.435).create()}; 338 for (MonetaryAmount m : moneys) { 339 AssertJUnit.assertTrue("Section 4.2.2: Invalid negativeOrZero (expected true) for " + type.getName(), 340 m.isNegativeOrZero()); 341 } 342 } 343 } 344 345 /** 346 * For each MonetaryAmount implementation: Ensure isPositiveOrZero() 347 * returns correct results. 348 */ 349 @SpecAssertion(section = "4.2.2", id = "422-A9") 350 @Test(description = "4.2.2 For each amount class, test isPositiveOrZero().") 351 public void testIsPositiveOrZero() { 352 for (Class type : Monetary.getAmountTypes()) { 353 if (type.equals(TestAmount.class)) { 354 continue; 355 } 356 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 357 f.setCurrency("CHF"); 358 MonetaryAmount[] moneys = new MonetaryAmount[]{f.setNumber(0).create(), f.setNumber(0.0).create(), 359 f.setNumber(BigDecimal.ZERO).create(), f.setNumber(new BigDecimal("0.00000000000000000")).create(), 360 f.setNumber(100).create(), f.setNumber(34242344).create(), f.setNumber(23123213.435).create()}; 361 for (MonetaryAmount m : moneys) { 362 AssertJUnit.assertTrue("Section 4.2.2: Invalid positiveOrZero (expected true): for " + type.getName(), 363 m.isPositiveOrZero()); 364 } 365 moneys = new MonetaryAmount[]{f.setNumber(-100).create(), f.setNumber(-34242344).create(), 366 f.setNumber(-23123213.435).create()}; 367 for (MonetaryAmount m : moneys) { 368 AssertJUnit 369 .assertFalse("Section 4.2.2: Invalid positiveOrZero (expected false) for " + type.getName() + m, 370 m.isPositiveOrZero()); 371 } 372 } 373 } 374 375 376 // ********************* B. Prototyping Support ***************************** 377 378 /** 379 * Ensure getFactory returns a MonetaryAmountFactory and that 380 * instances created are of the same type. 381 */ 382 @SpecAssertion(section = "4.2.2", id = "422-B1") 383 @Test(description = "4.2.2 For each amount class, access factory and of amounts.") 384 public void testMonetaryAmountFactories() { 385 for (Class type : Monetary.getAmountTypes()) { 386 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 387 AssertJUnit.assertNotNull(f); 388 MonetaryAmount m = f.setCurrency("CHF").setNumber(10).create(); 389 AssertJUnit.assertEquals("Section 4.2.2: Invalid class for created amount, expected: " + type.getName(), 390 m.getClass(), type); 391 m = f.setCurrency("CHF").setNumber(-10).create(); 392 AssertJUnit.assertEquals("Section 4.2.2: Invalid class for created amount, expected: " + type.getName(), 393 m.getClass(), type); 394 m = f.setCurrency("CHF").setNumber(10.3).create(); 395 AssertJUnit.assertEquals("Section 4.2.2: Invalid class for created amount, expected: " + type.getName(), 396 m.getClass(), type); 397 m = f.setCurrency("CHF").setNumber(-10.3).create(); 398 AssertJUnit.assertEquals("Section 4.2.2: Invalid class for created amount, expected: " + type.getName(), 399 m.getClass(), type); 400 m = f.setCurrency("CHF").setNumber(0.0).create(); 401 AssertJUnit.assertEquals("Section 4.2.2: Invalid class for created amount, expected: " + type.getName(), 402 m.getClass(), type); 403 m = f.setCurrency("CHF").setNumber(-0.0).create(); 404 AssertJUnit.assertEquals("Section 4.2.2: Invalid class for created amount, expected: " + type.getName(), 405 m.getClass(), type); 406 } 407 } 408 409 /** 410 * Call getFactory(), of a new MonetaryAmount instance, with 411 * same input. The instances must 412 * be equal (or even be identical!). 413 */ 414 @SpecAssertion(section = "4.2.2", id = "422-B2") 415 @Test(description = "4.2.2 For each amount class, access factory and of amounts, ensure amounts are equal if they" + 416 "should.") 417 public void testMonetaryAmountFactories_InstancesMustBeEqual() { 418 for (Class type : Monetary.getAmountTypes()) { 419 if (type.equals(TestAmount.class)) { 420 continue; 421 } 422 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 423 MonetaryAmount m1 = f.setCurrency("CHF").setNumber(10).create(); 424 f = Monetary.getAmountFactory(type); 425 MonetaryAmount m2 = f.setCurrency("CHF").setNumber(10).create(); 426 AssertJUnit.assertEquals("Section 4.2.2: Expected equal instances for " + type.getName(), m1, m2); 427 } 428 429 for (Class type : Monetary.getAmountTypes()) { 430 if (type.equals(TestAmount.class)) { 431 continue; 432 } 433 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 434 MonetaryAmount m1 = f.setCurrency("CHF").setNumber(10.5d).create(); 435 f = Monetary.getAmountFactory(type); 436 MonetaryAmount m2 = f.setCurrency("CHF").setNumber(10.5d).create(); 437 AssertJUnit 438 .assertEquals("Section 4.2.2: Expected equal types created by same factory for " + type.getName(), 439 m1, m2); 440 } 441 442 for (Class type : Monetary.getAmountTypes()) { 443 if (type.equals(TestAmount.class)) { 444 continue; 445 } 446 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 447 MonetaryAmount m1 = f.setCurrency("CHF").setNumber(new BigDecimal("10.52")).create(); 448 f = Monetary.getAmountFactory(type); 449 MonetaryAmount m2 = f.setCurrency("CHF").setNumber(new BigDecimal("10.52")).create(); 450 AssertJUnit 451 .assertEquals("Section 4.2.2: Expected equal types created by same factory for " + type.getName(), 452 m1, m2); 453 } 454 } 455 456 /** 457 * Call getFactory(), of a new MonetaryAmount instance with a 458 * new number 459 * value. The instances must 460 * be non equal and have the 461 * according 462 * numeric value. 463 */ 464 @SpecAssertion(section = "4.2.2", id = "422-B3") 465 @Test(description = "4.2.2 For each amount class, check new amounts are not equal.") 466 public void testMonetaryAmountFactories_InstantesMustBeNotEqual() { 467 for (Class type : Monetary.getAmountTypes()) { 468 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 469 MonetaryAmount m1 = f.setCurrency("CHF").setNumber(10).create(); 470 f = Monetary.getAmountFactory(type); 471 MonetaryAmount m2 = f.setCurrency("CHF").setNumber(11).create(); 472 AssertJUnit.assertNotSame("Section 4.2.2: Expected non equal instances for " + type.getName(), m1, m2); 473 } 474 475 for (Class type : Monetary.getAmountTypes()) { 476 MonetaryAmountFactory f = Monetary.getAmountFactory(type); 477 MonetaryAmount m1 = f.setCurrency("CHF").setNumber(10.5d).create(); 478 f = Monetary.getAmountFactory(type); 479 MonetaryAmount m2 = f.setCurrency("CHF").setNumber(10.4d).create(); 480 AssertJUnit.assertNotSame("Section 4.2.2: Expected non equal instances for " + type.getName(), m1, m2); 481 } 482 483 for (Class type : Monetary.getAmountTypes()) { 484 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 485 MonetaryAmount m1 = f.setCurrency("CHF").setNumber(new BigDecimal("10.52")).create(); 486 f = Monetary.getAmountFactory(type); 487 MonetaryAmount m2 = f.setCurrency("CHF").setNumber(new BigDecimal("10.11")).create(); 488 AssertJUnit.assertNotSame("Section 4.2.2: Expected non equal instances for " + type.getName(), m1, m2); 489 } 490 } 491 492 /** 493 * Call getFactory(),of a new MonetaryAmount instance 494 * with a new currency value.The instances must 495 * be non equal and have the according currency value .Do this by passing a literal code 496 * and by passing a CurrencyUnit. 497 */ 498 @SpecAssertion(section = "4.2.2", id = "422-B4") 499 @Test(description = "4.2.2 For each amount class, check multiple instances are not equal.") 500 public void testMonetaryAmountFactories_CreateWithCurrencies() { 501 for (Class type : Monetary.getAmountTypes()) { 502 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 503 MonetaryAmount m1 = f.setCurrency("CHF").setNumber(10).create(); 504 f = Monetary.getAmountFactory(type); 505 MonetaryAmount m2 = f.setCurrency("USD").setNumber(10).create(); 506 AssertJUnit.assertNotSame("Section 4.2.2: Expected non equal instances for " + type.getName(), m1, m2); 507 } 508 509 for (Class type : Monetary.getAmountTypes()) { 510 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 511 MonetaryAmount m1 = f.setCurrency("CHF").setNumber(10.5d).create(); 512 f = Monetary.getAmountFactory(type); 513 MonetaryAmount m2 = f.setCurrency("USD").setNumber(10.5d).create(); 514 AssertJUnit.assertNotSame("Section 4.2.2: Expected non equal instances for " + type.getName(), m1, m2); 515 } 516 517 for (Class type : Monetary.getAmountTypes()) { 518 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 519 MonetaryAmount m1 = f.setCurrency("CHF").setNumber(new BigDecimal("10.52")).create(); 520 f = Monetary.getAmountFactory(type); 521 MonetaryAmount m2 = f.setCurrency("USD").setNumber(new BigDecimal("10.52")).create(); 522 AssertJUnit.assertNotSame("Section 4.2.2: Expected non equal instances for " + type.getName(), m1, m2); 523 } 524 } 525 526 /** 527 * Call getFactory(),of a new MonetaryAmount instance 528 * with a new monetary context(if possible-check the max context). The 529 * instances must be non equal and have the same currency and number value. 530 */ 531 @SpecAssertion(section = "4.2.2", id = "422-B5") 532 @Test(description = "4.2.2 For each amount class, check new amounts with explcit MonetaryContext.") 533 public void testMonetaryAmountFactories_CreateWithMonetaryContext() { 534 for (Class type : Monetary.getAmountTypes()) { 535 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 536 MonetaryContext mc1 = f.getDefaultMonetaryContext(); 537 MonetaryContext mc2 = f.getMaximalMonetaryContext(); 538 MonetaryAmount m1; 539 MonetaryAmount m2; 540 if (mc1.equals(mc2)) { 541 // In this cases both amount must be equals 542 m1 = f.setCurrency("CHF").setContext(mc1).setNumber(10).create(); 543 m2 = f.setCurrency("CHF").setContext(mc2).setNumber(10).create(); 544 AssertJUnit.assertNotSame("Section 4.2.2: Expected non equal instances for " + type.getName(), m1, m2); 545 } else { 546 // In this cases both amount must be non equals 547 m1 = f.setCurrency("CHF").setContext(mc1).setNumber(10).create(); 548 m2 = f.setCurrency("CHF").setContext(mc2).setNumber(10).create(); 549 AssertJUnit.assertNotSame("Section 4.2.2: Expected non equal instances for " + type.getName(), m1, m2); 550 } 551 AssertJUnit.assertTrue("Section 4.2.2: Expected equality for " + type.getName(), m1.equals(m1)); 552 AssertJUnit.assertTrue("Section 4.2.2: Expected equality for " + type.getName(), m2.equals(m2)); 553 } 554 } 555 556 /** 557 * Call getFactory(),of a new MonetaryAmount instance with a new monetary context, a 558 * new number and a new currency. The instances must be non equal. 559 */ 560 @SpecAssertion(section = "4.2.2", id = "422-B6") 561 @Test(description = "4.2.2 For each amount class, check new amounts are not equal for different currencies and " + 562 "contexts.") 563 public void testMonetaryAmountFactories_CreateWithMonetaryContextNumberAndCurrency() { 564 for (Class type : Monetary.getAmountTypes()) { 565 if (type.equals(TestAmount.class)) { 566 continue; 567 } 568 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 569 MonetaryContext mc1 = f.getDefaultMonetaryContext(); 570 MonetaryContext mc2 = f.getMaximalMonetaryContext(); 571 MonetaryAmount m1 = f.setCurrency("CHF").setContext(mc1).setNumber(10).create(); 572 MonetaryAmount m2 = f.setCurrency("USD").setContext(mc2).setNumber(11).create(); 573 AssertJUnit.assertNotSame("Section 4.2.2: Expected not same for " + type.getName(), m1, m2); 574 AssertJUnit.assertTrue("Section 4.2.2: Expected isEqualTo==true for " + type.getName(), m1.isEqualTo(m1)); 575 AssertJUnit.assertTrue("Section 4.2.2: Expected isEqualTo==true for " + type.getName(), m2.isEqualTo(m2)); 576 AssertJUnit.assertTrue("Section 4.2.2: Expected equality for " + type.getName(), m1.equals(m1)); 577 AssertJUnit.assertTrue("Section 4.2.2: Expected equality for " + type.getName(), m2.equals(m2)); 578 } 579 } 580 581 // ***************************** C.Comparison Methods ********************************* 582 583 /** 584 * Test isGreaterThan() is implemented correctly for each amount type regardless of trailing zeroes. 585 */ 586 @SpecAssertion(section = "4.2.2", id = "422-C1") 587 @Test(description = "4.2.2 For each amount class, check isGreaterThan().") 588 public void testMonetaryAmount_isGreaterThan() { 589 for (Class type : Monetary.getAmountTypes()) { 590 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 591 f.setCurrency("CHF"); 592 AssertJUnit.assertFalse("Section 4.2.2: isGreaterThan failed for " + type.getName(), 593 f.setNumber(BigDecimal.valueOf(0d)).create() 594 .isGreaterThan(f.setNumber(BigDecimal.valueOf(0)).create())); 595 AssertJUnit.assertTrue("Section 4.2.2: isGreaterThan failed for " + type.getName(), 596 f.setNumber(BigDecimal.valueOf(0.00001d)).create() 597 .isGreaterThan(f.setNumber(BigDecimal.valueOf(0d)).create())); 598 AssertJUnit.assertTrue("Section 4.2.2: isGreaterThan failed for " + type.getName(), 599 f.setNumber(15).create().isGreaterThan(f.setNumber(10).create())); 600 AssertJUnit.assertTrue("Section 4.2.2: isGreaterThan failed for " + type.getName(), 601 f.setNumber(15.546).create().isGreaterThan(f.setNumber(10.34).create())); 602 AssertJUnit.assertFalse("Section 4.2.2: isGreaterThan failed for " + type.getName(), 603 f.setNumber(5).create().isGreaterThan(f.setNumber(10).create())); 604 AssertJUnit.assertFalse("Section 4.2.2: isGreaterThan failed for " + type.getName(), 605 f.setNumber(5.546).create().isGreaterThan(f.setNumber(10.34).create())); 606 } 607 } 608 609 /** 610 * Test isGreaterThanOrEquals() is implemented correctly for each amount type regardless of trailing 611 * zeroes. 612 */ 613 @SpecAssertion(section = "4.2.2", id = "422-C2") 614 @Test(description = "4.2.2 For each amount class, check isGreaterThanOrEquals().") 615 public void testMonetaryAmount_isGreaterThanOrEquals() { 616 for (Class type : Monetary.getAmountTypes()) { 617 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 618 f.setCurrency("CHF"); 619 AssertJUnit.assertTrue("Section 4.2.2: isGreaterThanOrEqualTo failed for " + type.getName(), 620 f.setNumber(BigDecimal.valueOf(0d)).create() 621 .isGreaterThanOrEqualTo(f.setNumber(BigDecimal.valueOf(0)).create())); 622 AssertJUnit.assertTrue("Section 4.2.2: isGreaterThanOrEqualTo failed for " + type.getName(), 623 f.setNumber(BigDecimal.valueOf(0.00001d)).create() 624 .isGreaterThanOrEqualTo(f.setNumber(BigDecimal.valueOf(0d)).create())); 625 AssertJUnit.assertTrue("Section 4.2.2: isGreaterThanOrEqualTo failed for " + type.getName(), 626 f.setNumber(15).create().isGreaterThanOrEqualTo(f.setNumber(10).create())); 627 AssertJUnit.assertTrue("Section 4.2.2: isGreaterThanOrEqualTo failed for " + type.getName(), 628 f.setNumber(15.546).create().isGreaterThanOrEqualTo(f.setNumber(10.34).create())); 629 AssertJUnit.assertFalse("Section 4.2.2: isGreaterThanOrEqualTo failed for " + type.getName(), 630 f.setNumber(5).create().isGreaterThanOrEqualTo(f.setNumber(10).create())); 631 AssertJUnit.assertFalse("Section 4.2.2: isGreaterThanOrEqualTo failed for " + type.getName(), 632 f.setNumber(5.546).create().isGreaterThanOrEqualTo(f.setNumber(10.34).create())); 633 } 634 } 635 636 /** 637 * Test isLessThan() is implemented correctly for each amount type regardless of trailing 638 * zeroes. 639 */ 640 @SpecAssertion(section = "4.2.2", id = "422-C3") 641 @Test(description = "4.2.2 For each amount class, check isLessThan().") 642 public void testMonetaryAmount_isLessThan() { 643 for (Class type : Monetary.getAmountTypes()) { 644 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 645 f.setCurrency("CHF"); 646 AssertJUnit.assertFalse("Section 4.2.2: isLessThan failed for " + type.getName(), 647 f.setNumber(BigDecimal.valueOf(0d)).create() 648 .isLessThan(f.setNumber(BigDecimal.valueOf(0)).create())); 649 AssertJUnit.assertFalse("Section 4.2.2: isLessThan failed for " + type.getName(), 650 f.setNumber(BigDecimal.valueOf(0.00001d)).create() 651 .isLessThan(f.setNumber(BigDecimal.valueOf(0d)).create())); 652 AssertJUnit.assertFalse("Section 4.2.2: isLessThan failed for " + type.getName(), 653 f.setNumber(15).create().isLessThan(f.setNumber(10).create())); 654 AssertJUnit.assertFalse("Section 4.2.2: isLessThan failed for " + type.getName(), 655 f.setNumber(15.546).create().isLessThan(f.setNumber(10.34).create())); 656 AssertJUnit.assertTrue("Section 4.2.2: isLessThan failed for " + type.getName(), 657 f.setNumber(5).create().isLessThan(f.setNumber(10).create())); 658 AssertJUnit.assertTrue("Section 4.2.2: isLessThan failed for " + type.getName(), 659 f.setNumber(5.546).create().isLessThan(f.setNumber(10.34).create())); 660 } 661 } 662 663 /** 664 * Test isLessThanOrEquals() is implemented correctly for each amount type regardless of trailing 665 * zeroes. 666 */ 667 @SpecAssertion(section = "4.2.2", id = "422-C4") 668 @Test(description = "4.2.2 For each amount class, check isLessThanOrEqualTo().") 669 public void testMonetaryAmount_isLessThanOrEqualTo() { 670 for (Class type : Monetary.getAmountTypes()) { 671 if (type.equals(TestAmount.class)) { 672 continue; 673 } 674 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 675 f.setCurrency("CHF"); 676 AssertJUnit.assertTrue("Section 4.2.2: isLessThanOrEqualTo failed for " + type.getName(), 677 f.setNumber(BigDecimal.valueOf(0d)).create() 678 .isLessThanOrEqualTo(f.setNumber(BigDecimal.valueOf(0)).create())); 679 AssertJUnit.assertFalse("Section 4.2.2: isLessThanOrEqualTo failed for " + type.getName(), 680 f.setNumber(BigDecimal.valueOf(0.00001d)).create() 681 .isLessThanOrEqualTo(f.setNumber(BigDecimal.valueOf(0d)).create())); 682 AssertJUnit.assertFalse("Section 4.2.2: isLessThanOrEqualTo failed for " + type.getName(), 683 f.setNumber(15).create().isLessThanOrEqualTo(f.setNumber(10).create())); 684 AssertJUnit.assertFalse("Section 4.2.2: isLessThan failed for " + type.getName(), 685 f.setNumber(15.546).create().isLessThan(f.setNumber(10.34).create())); 686 AssertJUnit.assertTrue("Section 4.2.2: isLessThanOrEqualTo failed for " + type.getName(), 687 f.setNumber(5).create().isLessThanOrEqualTo(f.setNumber(10).create())); 688 AssertJUnit.assertTrue("Section 4.2.2: isLessThanOrEqualTo failed for " + type.getName(), 689 f.setNumber(5.546).create().isLessThanOrEqualTo(f.setNumber(10.34).create())); 690 } 691 } 692 693 /** 694 * Test isEqualTo() is implemented correctly for each amount type regardless of trailing 695 * zeroes. 696 */ 697 @SpecAssertion(section = "4.2.2", id = "422-C5") 698 @Test(description = "4.2.2 For each amount class, check isEqualTo().") 699 public void testMonetaryAmount_isEqualTo() { 700 for (Class type : Monetary.getAmountTypes()) { 701 if (type.equals(TestAmount.class)) { 702 continue; 703 } 704 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 705 f.setCurrency("CHF"); 706 AssertJUnit.assertTrue("Section 4.2.2: isEqualTo failed for " + type.getName(), 707 f.setNumber(BigDecimal.valueOf(0d)).create() 708 .isEqualTo(f.setNumber(BigDecimal.valueOf(0)).create())); 709 AssertJUnit.assertFalse("Section 4.2.2: isEqualTo failed for " + type.getName(), 710 f.setNumber(BigDecimal.valueOf(0.00001d)).create() 711 .isEqualTo(f.setNumber(BigDecimal.valueOf(0d)).create())); 712 AssertJUnit.assertTrue("isEqualTo failed for " + type.getName(), 713 f.setNumber(BigDecimal.valueOf(5d)).create() 714 .isEqualTo(f.setNumber(BigDecimal.valueOf(5)).create())); 715 AssertJUnit.assertTrue("Section 4.2.2: isEqualTo failed for " + type.getName(), 716 f.setNumber(BigDecimal.valueOf(1d)).create() 717 .isEqualTo(f.setNumber(BigDecimal.valueOf(1.00)).create())); 718 AssertJUnit.assertTrue("Section 4.2.2: isEqualTo failed for " + type.getName(), 719 f.setNumber(BigDecimal.valueOf(1d)).create() 720 .isEqualTo(f.setNumber(BigDecimal.ONE).create())); 721 AssertJUnit.assertTrue("Section 4.2.2: isEqualTo failed for " + type.getName(), 722 f.setNumber(BigDecimal.valueOf(1)).create() 723 .isEqualTo(f.setNumber(BigDecimal.ONE).create())); 724 AssertJUnit.assertTrue("Section 4.2.2: isEqualTo failed for " + type.getName(), 725 f.setNumber(new BigDecimal("1.0000")).create() 726 .isEqualTo(f.setNumber(new BigDecimal("1.00")).create())); 727 // Test with different scales, but numeric equal values 728 AssertJUnit.assertTrue("Section 4.2.2: isEqualTo failed for " + type.getName(), 729 f.setNumber(BigDecimal.valueOf(0d)).create() 730 .isEqualTo(f.setNumber(BigDecimal.valueOf(0)).create())); 731 AssertJUnit.assertTrue("Section 4.2.2: isEqualTo failed for " + type.getName(), 732 f.setNumber(BigDecimal.ZERO).create() 733 .isEqualTo(f.setNumber(BigDecimal.valueOf(0)).create())); 734 AssertJUnit.assertTrue("Section 4.2.2: isEqualTo failed for " + type.getName(), 735 f.setNumber(BigDecimal.valueOf(5)).create() 736 .isEqualTo(f.setNumber(new BigDecimal("5.0")).create())); 737 AssertJUnit.assertTrue("Section 4.2.2: isEqualTo failed for " + type.getName(), 738 f.setNumber(BigDecimal.valueOf(5)).create() 739 .isEqualTo(f.setNumber(new BigDecimal("5.00")).create())); 740 AssertJUnit.assertTrue("Section 4.2.2: isEqualTo failed for " + type.getName(), 741 f.setNumber(BigDecimal.valueOf(5)).create() 742 .isEqualTo(f.setNumber(new BigDecimal("5.000")).create())); 743 AssertJUnit.assertTrue("Section 4.2.2: isEqualTo failed for " + type.getName(), 744 f.setNumber(BigDecimal.valueOf(5)).create() 745 .isEqualTo(f.setNumber(new BigDecimal("5.0000")).create())); 746 AssertJUnit.assertTrue("Section 4.2.2: isEqualTo failed for " + type.getName(), 747 f.setNumber(new BigDecimal("-1.23")).create() 748 .isEqualTo(f.setNumber(new BigDecimal("-1.23")).create())); 749 try { 750 AssertJUnit.assertTrue("Section 4.2.2: isEqualTo failed for " + type.getName(), 751 f.setNumber(new BigDecimal("-1.23")).create() 752 .isEqualTo(f.setNumber(new BigDecimal("-1.230")).create())); 753 AssertJUnit.assertTrue("Section 4.2.2: isEqualTo failed for " + type.getName(), 754 f.setNumber(new BigDecimal("-1.23")).create() 755 .isEqualTo(f.setNumber(new BigDecimal("-1.2300")).create())); 756 AssertJUnit.assertTrue("Section 4.2.2: isEqualTo failed for " + type.getName(), 757 f.setNumber(new BigDecimal("-1.23")).create() 758 .isEqualTo(f.setNumber(new BigDecimal("-1.23000")).create())); 759 AssertJUnit.assertTrue("Section 4.2.2: isEqualTo failed for " + type.getName(), 760 f.setNumber(new BigDecimal("-1.23")).create().isEqualTo( 761 f.setNumber(new BigDecimal("-1.230000000000000000000")).create())); 762 } catch (MonetaryException e) { 763 // happens if we exceed the limits... 764 } 765 } 766 } 767 768 /** 769 * For two amounts with same numeric value and currency: 770 * {@code }isEqualTo()} return true, regardless of MonetaryContext. 771 */ 772 @SpecAssertion(section = "4.2.2", id = "422-C6") 773 @Test(description = "4.2.2 For each amount class, check isEqualTo(), regardless different MonetaryContext " + 774 "instances.") 775 public void testMonetaryAmount_isEqualToRegardlessMonetaryContext() { 776 for (Class type : Monetary.getAmountTypes()) { 777 if (type.equals(TestAmount.class)) { 778 continue; 779 } 780 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 781 MonetaryContext mc1 = f.getDefaultMonetaryContext(); 782 MonetaryContext mc2 = f.getMaximalMonetaryContext(); 783 MonetaryAmount m1; 784 MonetaryAmount m2; 785 if (mc1.equals(mc2)) { 786 // In this cases both amount must be equals 787 m1 = f.setCurrency("CHF").setContext(mc1).setNumber(10).create(); 788 m2 = f.setCurrency("CHF").setContext(mc2).setNumber(10).create(); 789 AssertJUnit.assertEquals("Section 4.2.2: m1.equals(m2) must be true for m1=" + m1 + " and m2=" + m2, m1, 790 m2); 791 m1 = f.setCurrency("CHF").setContext(mc1).setNumber(10.5d).create(); 792 m2 = f.setCurrency("CHF").setContext(mc2).setNumber(10.5d).create(); 793 AssertJUnit.assertEquals("Section 4.2.2: m1.equals(m2) must be true for m1=" + m1 + " and m2=" + m2, m1, 794 m2); 795 m1 = f.setCurrency("CHF").setContext(mc1).setNumber(BigDecimal.TEN).create(); 796 m2 = f.setCurrency("CHF").setContext(mc2).setNumber(BigDecimal.TEN).create(); 797 AssertJUnit.assertEquals("Section 4.2.2: m1.equals(m2) must be true for m1=" + m1 + " and m2=" + m2, m1, 798 m2); 799 } else { 800 // In this cases both amount must be non equals 801 m1 = f.setCurrency("CHF").setContext(mc1).setNumber(10).create(); 802 m2 = f.setCurrency("CHF").setContext(mc2).setNumber(10).create(); 803 AssertJUnit 804 .assertNotSame("Section 4.2.2: m1.equals(m2) must be false for m1=" + m1 + " and m2=" + m2, m1, 805 m2); 806 AssertJUnit.assertTrue("Section 4.2.2: m1.isEqualTo(m2) must be true for m1=" + m1 + " and m2=" + m2, 807 m1.isEqualTo(m2)); 808 AssertJUnit.assertTrue("Section 4.2.2: m1.isEqualTo(m2) must be true for m1=" + m2 + " and m2=" + m1, 809 m2.isEqualTo(m1)); 810 m1 = f.setCurrency("CHF").setContext(mc1).setNumber(10.5d).create(); 811 m2 = f.setCurrency("CHF").setContext(mc2).setNumber(10.5d).create(); 812 AssertJUnit 813 .assertNotSame("Section 4.2.2: m1.equals(m2) must be false for m1=" + m1 + " and m2=" + m2, m1, 814 m2); 815 AssertJUnit.assertTrue("Section 4.2.2: m1.isEqualTo(m2) must be true for m1=" + m1 + " and m2=" + m2, 816 m1.isEqualTo(m2)); 817 AssertJUnit.assertTrue("Section 4.2.2: m1.isEqualTo(m2) must be true for m1=" + m2 + " and m2=" + m1, 818 m2.isEqualTo(m1)); 819 m1 = f.setCurrency("CHF").setContext(mc1).setNumber(BigDecimal.TEN).create(); 820 m2 = f.setCurrency("CHF").setContext(mc2).setNumber(BigDecimal.TEN).create(); 821 AssertJUnit 822 .assertNotSame("Section 4.2.2: m1.equals(m2) must be false for m1=" + m1 + " and m2=" + m2, m1, 823 m2); 824 AssertJUnit.assertTrue("Section 4.2.2: m1.isEqualTo(m2) must be true for m1=" + m1 + " and m2=" + m2, 825 m1.isEqualTo(m2)); 826 AssertJUnit.assertTrue("Section 4.2.2: m1.isEqualTo(m2) must be true for m1=" + m2 + " and m2=" + m1, 827 m2.isEqualTo(m1)); 828 } 829 AssertJUnit.assertTrue("Section 4.2.2: m.isEqualTo(m) must be true for " + m1, m1.isEqualTo(m1)); 830 AssertJUnit.assertTrue("Section 4.2.2: m.isEqualTo(m) must be true for " + m2, m2.isEqualTo(m2)); 831 } 832 } 833 834 /** 835 * For two amounts with same numeric value and currency: 836 * {@code }isEqualTo()} return true, regardless of iumplementation type. 837 */ 838 @SpecAssertion(section = "4.2.2", id = "422-C7") 839 @Test(description = "4.2.2 For each amount class, check isEqualTo(), regardless implementation type.") 840 public void testMonetaryAmount_isEqualToRegardlessType() { 841 List<MonetaryAmount> instances = new ArrayList<>(); 842 for (Class type : Monetary.getAmountTypes()) { 843 MonetaryAmountFactory f = Monetary.getAmountFactory(type); 844 f.setCurrency("CHF"); 845 instances.add(f.setNumber(10).create()); 846 instances.add(f.setNumber(10.0d).create()); 847 instances.add(f.setNumber(BigDecimal.TEN).create()); 848 } 849 // compare each other... 850 for (MonetaryAmount mi: instances) { 851 for (MonetaryAmount mj: instances) { 852 AssertJUnit 853 .assertTrue("Section 4.2.2: isEqualTo must be true for " + mi + " and " + mj, mi.isEqualTo(mj)); 854 } 855 } 856 } 857 858 /** 859 * Tests that add() correctly adds two values, using positive integers. 860 */ 861 @SpecAssertion(section = "4.2.2", id = "422-D1") 862 @Test(description = "4.2.2 For each amount class, check m1.add(m2), m1 >0, m2>0.") 863 public void testAddPositiveIntegers() { 864 for (Class type : Monetary.getAmountTypes()) { 865 if (type.equals(TestAmount.class)) { 866 continue; 867 } 868 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 869 MonetaryAmount mAmount2 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(20).create(); 870 MonetaryAmount mActualResult = mAmount1.add(mAmount2); 871 MonetaryAmount mExpectedResult = 872 Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(30).create(); 873 AssertJUnit.assertEquals( 874 "Section 4.2.2: Adding two simple ammounts failed, " + mAmount1 + " + " + mAmount2 + " != " + 875 mExpectedResult, mExpectedResult, mActualResult); 876 } 877 } 878 879 /** 880 * Tests that add() correctly adds two values, using negative integers. 881 */ 882 @SpecAssertion(section = "4.2.2", id = "422-D1") 883 @Test(description = "4.2.2 For each amount class, check m1.add(m2), m1 <0, m2<0.") 884 public void testAddNegativeIntegers() { 885 for (Class type : Monetary.getAmountTypes()) { 886 if (type.equals(TestAmount.class)) { 887 continue; 888 } 889 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(-10).create(); 890 MonetaryAmount mAmount2 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(-20).create(); 891 MonetaryAmount mActualResult = mAmount1.add(mAmount2); 892 MonetaryAmount mExpectedResult = 893 Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(-30).create(); 894 AssertJUnit.assertEquals("Section 4.2.2: Adding two simple ammounts", mExpectedResult, mActualResult); 895 } 896 } 897 898 /** 899 * Tests that add() correctly adds two values, using fractions. 900 */ 901 @SpecAssertion(section = "4.2.2", id = "422-D1") 902 @Test(description = "4.2.2 For each amount class, check m1.add(m2), m2 is fraction.") 903 public void testAddPositiveFractions() { 904 for (Class type : Monetary.getAmountTypes()) { 905 if (type.equals(TestAmount.class)) { 906 continue; 907 } 908 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(1.5).create(); 909 MonetaryAmount mAmount2 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(2.85).create(); 910 MonetaryAmount mActualResult = mAmount1.add(mAmount2); 911 MonetaryAmount mExpectedResult = 912 Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(4.35).create(); 913 AssertJUnit.assertEquals("Section 4.2.2: Adding two simple ammounts", mExpectedResult, mActualResult); 914 } 915 } 916 917 /** 918 * Tests that add() correctly adds two values, using positive and negative integers. 919 */ 920 @SpecAssertion(section = "4.2.2", id = "422-D1") 921 @Test(description = "4.2.2 For each amount class, check m1.add(m2), m1, m2 = mixed ints.") 922 public void testAddMixedIntegers() { 923 for (Class type : Monetary.getAmountTypes()) { 924 if (type.equals(TestAmount.class)) { 925 continue; 926 } 927 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(-10).create(); 928 MonetaryAmount mAmount2 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(20).create(); 929 MonetaryAmount mActualResult = mAmount1.add(mAmount2); 930 MonetaryAmount mExpectedResult = 931 Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 932 AssertJUnit.assertEquals("Section 4.2.2: Adding two simple ammounts", mExpectedResult, mActualResult); 933 } 934 for (Class type : Monetary.getAmountTypes()) { 935 if (type.equals(TestAmount.class)) { 936 continue; 937 } 938 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(-20).create(); 939 MonetaryAmount mAmount2 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 940 MonetaryAmount mActualResult = mAmount1.add(mAmount2); 941 MonetaryAmount mExpectedResult = 942 Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(-10).create(); 943 AssertJUnit.assertEquals("Section 4.2.2: Adding two simple ammounts", mExpectedResult, mActualResult); 944 } 945 for (Class type : Monetary.getAmountTypes()) { 946 if (type.equals(TestAmount.class)) { 947 continue; 948 } 949 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(-10).create(); 950 MonetaryAmount mAmount2 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 951 MonetaryAmount mActualResult = mAmount1.add(mAmount2); 952 MonetaryAmount mExpectedResult = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(0).create(); 953 AssertJUnit.assertEquals("Section 4.2.2: Adding two simple ammounts", mExpectedResult, mActualResult); 954 } 955 } 956 957 /** 958 * Tests that add() correctly adds two values, using positive and negative fractions. 959 */ 960 @SpecAssertion(section = "4.2.2", id = "422-D1") 961 @Test(description = "4.2.2 For each amount class, check m1.add(m2), m1, m2 = mixed fractions.") 962 public void testAddMixedFractions() { 963 for (Class type : Monetary.getAmountTypes()) { 964 if (type.equals(TestAmount.class)) { 965 continue; 966 } 967 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(1.5).create(); 968 MonetaryAmount mAmount2 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(-2.85).create(); 969 MonetaryAmount mActualResult = mAmount1.add(mAmount2); 970 MonetaryAmount mExpectedResult = 971 Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(-1.35).create(); 972 AssertJUnit.assertEquals("Section 4.2.2: Adding two simple ammounts", mExpectedResult, mActualResult); 973 } 974 for (Class type : Monetary.getAmountTypes()) { 975 if (type.equals(TestAmount.class)) { 976 continue; 977 } 978 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(-1.5).create(); 979 MonetaryAmount mAmount2 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(+2.85).create(); 980 MonetaryAmount mActualResult = mAmount1.add(mAmount2); 981 MonetaryAmount mExpectedResult = 982 Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(1.35).create(); 983 AssertJUnit.assertEquals("Section 4.2.2: Adding two simple ammounts", mExpectedResult, mActualResult); 984 } 985 for (Class type : Monetary.getAmountTypes()) { 986 if (type.equals(TestAmount.class)) { 987 continue; 988 } 989 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(-2.85).create(); 990 MonetaryAmount mAmount2 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(+2.85).create(); 991 MonetaryAmount mActualResult = mAmount1.add(mAmount2); 992 MonetaryAmount mExpectedResult = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(0).create(); 993 AssertJUnit.assertEquals("Section 4.2.2: Adding two simple ammounts", mExpectedResult, mActualResult); 994 } 995 } 996 997 /** 998 * Tests that add() with non matching currencies throws a 999 * MonetaryException. 1000 */ 1001 @SpecAssertion(section = "4.2.2", id = "422-D2") 1002 @Test(description = "4.2.2 For each amount class, ensure currency compatibility is working.") 1003 public void testAdd_IncompatibleCurrencies() { 1004 for (Class type : Monetary.getAmountTypes()) { 1005 if (type.equals(TestAmount.class)) { 1006 continue; 1007 } 1008 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1009 MonetaryAmount mAmount2 = Monetary.getAmountFactory(type).setCurrency(ADDITIONAL_CURRENCY).setNumber(20).create(); 1010 try { 1011 mAmount1.add(mAmount2); 1012 AssertJUnit.fail("Section 4.2.2: Exception expected"); 1013 } catch (MonetaryException ex) { 1014 // Expected 1015 } 1016 } 1017 } 1018 1019 /** 1020 * Tests that add(0) should return itself. 1021 */ 1022 @SpecAssertion(section = "4.2.2", id = "422-D3") 1023 @Test(description = "4.2.2 For each amount class, ensure m2 = m1,add(0) -> m1==m2.") 1024 public void testAdd_Zero() { 1025 for (Class type : Monetary.getAmountTypes()) { 1026 if (type.equals(TestAmount.class)) { 1027 continue; 1028 } 1029 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1030 MonetaryAmount mAmount2 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(0).create(); 1031 MonetaryAmount mActualResult = mAmount1.add(mAmount2); 1032 AssertJUnit.assertEquals("Section 4.2.2: Adding zero", mAmount1, mActualResult); 1033 } 1034 } 1035 1036 /** 1037 * Tests that add(), which results in an amount exceeding the max MonetaryContext throws 1038 * a MonetaryException. 1039 */ 1040 @SpecAssertion(section = "4.2.2", id = "422-D4") 1041 @Test(description = "4.2.2 For each amount class, ensure ArithemticException is thrown when adding exceeding " + 1042 "values.") 1043 public void testAdd_ExceedsCapabilities() { 1044 for (Class type : Monetary.getAmountTypes()) { 1045 if (type.equals(TestAmount.class)) { 1046 continue; 1047 } 1048 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 1049 f.setCurrency("CHF"); 1050 MonetaryContext maxCtx = f.getMaximalMonetaryContext(); 1051 if (maxCtx.getPrecision() > 0) { 1052 MonetaryAmount m = f.setNumber(f.getMaxNumber()).create(); 1053 MonetaryAmount ms = m; 1054 try { 1055 for (int i = 0; i < 20; i++) { 1056 ms = ms.add(ms); 1057 } 1058 AssertJUnit.fail("Section 4.2.2: ArithmeticException expected, since adding 20x " + m + " to " + m + 1059 " exceeds capabilities (precision) for " + 1060 type.getName()); 1061 } catch (ArithmeticException ex) { 1062 // Expected 1063 } catch (Exception e) { 1064 AssertJUnit.fail("Section 4.2.2: Addition of amount " + ms + " to " + ms + 1065 " exceeds max monetary context(scale), " + 1066 "but did not throw an ArithmeticException (exception thrown was " + 1067 e.getClass().getName() + "), type was " + 1068 type); 1069 } 1070 } 1071 } 1072 for (Class type : Monetary.getAmountTypes()) { 1073 if (type.equals(TestAmount.class)) { 1074 continue; 1075 } 1076 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 1077 f.setCurrency("CHF"); 1078 MonetaryContext maxCtx = f.getMaximalMonetaryContext(); 1079 if (maxCtx.getMaxScale() >= 0) { 1080 try { 1081 MonetaryAmount m = f.setNumber(1).create(); 1082 MonetaryAmount m2 = 1083 f.setNumber(TestUtils.createNumberWithScale(maxCtx.getMaxScale() + 5)).create(); 1084 m.add(m2); 1085 AssertJUnit.fail("Section 4.2.2: Exception expected, since adding " + m2 + " to " + m + 1086 " exceeds capabilities (scale) for " + 1087 type.getName()); 1088 } catch (ArithmeticException ex) { 1089 // Expected 1090 } 1091 } 1092 } 1093 } 1094 1095 1096 /** 1097 * Tests that add(), which results in an amount exceeding the max MonetaryContext throws 1098 * a MonetaryException. 1099 */ 1100 @SpecAssertion(section = "4.2.2", id = "422-D5") 1101 @Test(description = "4.2.2 For each amount class, ensure NullPointerException is thrown when calling m.add(null).") 1102 public void testAdd_Null() { 1103 for (Class type : Monetary.getAmountTypes()) { 1104 if (type.equals(TestAmount.class)) { 1105 continue; 1106 } 1107 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1108 try { 1109 MonetaryAmount mActualResult = mAmount1.add(null); 1110 AssertJUnit.fail("Section 4.2.2: MonetaryAmount.add(null): NullPointerException expected"); 1111 } catch (NullPointerException ex) { 1112 // Expected 1113 } 1114 } 1115 } 1116 1117 1118 /** 1119 * Tests that subtract() correctly adds two values, using positive integers. 1120 */ 1121 @SpecAssertion(section = "4.2.2", id = "422-D6") 1122 @Test(description = "4.2.2 For each amount class, ensure correct subtraction of positive ints.") 1123 public void testSubtractPositiveIntegers() { 1124 for (Class type : Monetary.getAmountTypes()) { 1125 if (type.equals(TestAmount.class)) { 1126 continue; 1127 } 1128 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1129 MonetaryAmount mAmount2 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(20).create(); 1130 MonetaryAmount mActualResult = mAmount1.subtract(mAmount2); 1131 MonetaryAmount mExpectedResult = 1132 Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(-10).create(); 1133 AssertJUnit.assertEquals("Section 4.2.2: Subtracting two simple ammounts", mExpectedResult, mActualResult); 1134 } 1135 } 1136 1137 /** 1138 * Tests that subtract() correctly adds two values, using negative integers. 1139 */ 1140 @SpecAssertion(section = "4.2.2", id = "422-D6") 1141 @Test(description = "4.2.2 For each amount class, ensure correct subtraction of negative ints.") 1142 public void testSubtractNegativeIntegers() { 1143 for (Class type : Monetary.getAmountTypes()) { 1144 if (type.equals(TestAmount.class)) { 1145 continue; 1146 } 1147 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(-10).create(); 1148 MonetaryAmount mAmount2 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(-20).create(); 1149 MonetaryAmount mActualResult = mAmount1.subtract(mAmount2); 1150 MonetaryAmount mExpectedResult = 1151 Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1152 AssertJUnit.assertEquals("Section 4.2.2: Subtracting two simple ammounts", mExpectedResult, mActualResult); 1153 } 1154 } 1155 1156 /** 1157 * Tests that subtract() correctly adds two values, using fractions. 1158 */ 1159 @SpecAssertion(section = "4.2.2", id = "422-D6") 1160 @Test(description = "4.2.2 For each amount class, ensure correct subtraction of positive fractions.") 1161 public void testSubtractPositiveFractions() { 1162 for (Class type : Monetary.getAmountTypes()) { 1163 if (type.equals(TestAmount.class)) { 1164 continue; 1165 } 1166 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(1.5).create(); 1167 MonetaryAmount mAmount2 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(2.85).create(); 1168 MonetaryAmount mActualResult = mAmount1.subtract(mAmount2); 1169 MonetaryAmount mExpectedResult = 1170 Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(-1.35).create(); 1171 AssertJUnit.assertEquals("Section 4.2.2: Adding two simple ammounts", mExpectedResult, mActualResult); 1172 } 1173 } 1174 1175 /** 1176 * Tests that subtract() correctly adds two values, using positive and negative integers. 1177 */ 1178 @SpecAssertion(section = "4.2.2", id = "422-D6") 1179 @Test(description = "4.2.2 For each amount class, ensure correct subtraction of mixed ints.") 1180 public void testSubtractMixedIntegers() { 1181 for (Class type : Monetary.getAmountTypes()) { 1182 if (type.equals(TestAmount.class)) { 1183 continue; 1184 } 1185 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(20).create(); 1186 MonetaryAmount mAmount2 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1187 MonetaryAmount mActualResult = mAmount1.subtract(mAmount2); 1188 MonetaryAmount mExpectedResult = 1189 Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1190 AssertJUnit.assertEquals("Section 4.2.2: Adding two simple ammounts", mExpectedResult, mActualResult); 1191 } 1192 for (Class type : Monetary.getAmountTypes()) { 1193 if (type.equals(TestAmount.class)) { 1194 continue; 1195 } 1196 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1197 MonetaryAmount mAmount2 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1198 MonetaryAmount mActualResult = mAmount1.subtract(mAmount2); 1199 MonetaryAmount mExpectedResult = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(0).create(); 1200 AssertJUnit.assertEquals("Section 4.2.2: Adding two simple ammounts", mExpectedResult, mActualResult); 1201 } 1202 for (Class type : Monetary.getAmountTypes()) { 1203 if (type.equals(TestAmount.class)) { 1204 continue; 1205 } 1206 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(-10).create(); 1207 MonetaryAmount mAmount2 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1208 MonetaryAmount mActualResult = mAmount1.subtract(mAmount2); 1209 MonetaryAmount mExpectedResult = 1210 Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(-20).create(); 1211 AssertJUnit.assertEquals("Section 4.2.2: Adding two simple ammounts", mExpectedResult, mActualResult); 1212 } 1213 } 1214 1215 /** 1216 * Tests that subtract() correctly adds two values, using positive and negative fractions. 1217 */ 1218 @SpecAssertion(section = "4.2.2", id = "422-D6") 1219 @Test(description = "4.2.2 For each amount class, ensure correct subtraction of mixed fractions.") 1220 public void testSubtractMixedFractions() { 1221 for (Class type : Monetary.getAmountTypes()) { 1222 if (type.equals(TestAmount.class)) { 1223 continue; 1224 } 1225 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(1.5).create(); 1226 MonetaryAmount mAmount2 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(-2.85).create(); 1227 MonetaryAmount mActualResult = mAmount1.subtract(mAmount2); 1228 MonetaryAmount mExpectedResult = 1229 Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(4.35).create(); 1230 AssertJUnit.assertEquals("Section 4.2.2: Adding two simple ammounts", mExpectedResult, mActualResult); 1231 } 1232 for (Class type : Monetary.getAmountTypes()) { 1233 if (type.equals(TestAmount.class)) { 1234 continue; 1235 } 1236 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(-1.5).create(); 1237 MonetaryAmount mAmount2 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(+2.85).create(); 1238 MonetaryAmount mActualResult = mAmount1.subtract(mAmount2); 1239 MonetaryAmount mExpectedResult = 1240 Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(-4.35).create(); 1241 AssertJUnit.assertEquals("Section 4.2.2: Adding two simple ammounts", mExpectedResult, mActualResult); 1242 } 1243 for (Class type : Monetary.getAmountTypes()) { 1244 if (type.equals(TestAmount.class)) { 1245 continue; 1246 } 1247 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(2.85).create(); 1248 MonetaryAmount mAmount2 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(+2.85).create(); 1249 MonetaryAmount mActualResult = mAmount1.subtract(mAmount2); 1250 MonetaryAmount mExpectedResult = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(0).create(); 1251 AssertJUnit.assertEquals("Section 4.2.2: Adding two simple ammounts", mExpectedResult, mActualResult); 1252 } 1253 } 1254 1255 /** 1256 * Tests that subtract() with non matching currencies throws a 1257 * MonetaryException. 1258 */ 1259 @SpecAssertion(section = "4.2.2", id = "422-D8") 1260 @Test(description = "4.2.2 For each amount class, ensure subtraction with invalid currency throws " + 1261 "MonetaryException.") 1262 public void testSubtract_IncompatibleCurrencies() { 1263 for (Class type : Monetary.getAmountTypes()) { 1264 if (type.equals(TestAmount.class)) { 1265 continue; 1266 } 1267 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1268 MonetaryAmount mAmount2 = Monetary.getAmountFactory(type).setCurrency(ADDITIONAL_CURRENCY).setNumber(20).create(); 1269 try { 1270 MonetaryAmount mActualResult = mAmount1.subtract(mAmount2); 1271 AssertJUnit.fail("Section 4.2.2: Exception expected"); 1272 } catch (MonetaryException ex) { 1273 // Expected 1274 } 1275 } 1276 } 1277 1278 /** 1279 * Tests that subtract(0) should return itself. 1280 */ 1281 @SpecAssertion(section = "4.2.2", id = "422-D7") 1282 @Test(description = "4.2.2 For each amount class, ensure subtraction of 0 returns same instance.") 1283 public void testSubtract_Zero() { 1284 for (Class type : Monetary.getAmountTypes()) { 1285 if (type.equals(TestAmount.class)) { 1286 continue; 1287 } 1288 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1289 MonetaryAmount mAmount2 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(0).create(); 1290 MonetaryAmount mActualResult = mAmount1.subtract(mAmount2); 1291 AssertJUnit.assertEquals("Section 4.2.2: Subtract zero", mAmount1, mActualResult); 1292 } 1293 } 1294 1295 /** 1296 * Tests that subtract(), which results in an amount exceeding the max MonetaryContext throws 1297 * a MonetaryException. 1298 */ 1299 @SpecAssertion(section = "4.2.2", id = "422-D9") 1300 @Test(description = "4.2.2 For each amount class, ensure subtraction with exceeding capabilities throws " + 1301 "ArithmeticException.") 1302 public void testSubtract_ExceedsCapabilities() { 1303 for (Class type : Monetary.getAmountTypes()) { 1304 if (type.equals(TestAmount.class)) { 1305 continue; 1306 } 1307 MonetaryAmountFactory f = Monetary.getAmountFactory(type); 1308 f.setCurrency("CHF"); 1309 MonetaryContext maxCtx = f.getMaximalMonetaryContext(); 1310 MonetaryAmount m = null; 1311 if (maxCtx.getPrecision() > 0) { 1312 MonetaryAmount mAmount1 = null; 1313 try { 1314 mAmount1 = f.setNumber(f.getMinNumber()).create().negate(); 1315 m = TestUtils.createAmountWithPrecision(maxCtx.getPrecision() + 1); 1316 mAmount1 = mAmount1.subtract(m); 1317 AssertJUnit.fail("Section 4.2.2: ArithmeticException expected on subtraction that exceeds " + 1318 "capabilities for " + 1319 type.getName()); 1320 } catch (ArithmeticException ex) { 1321 // Expected 1322 } catch (Exception e) { 1323 AssertJUnit.fail("Section 4.2.2: Subtraction of amount " + m + " from " + mAmount1 + 1324 " exceeds max monetary context(scale), " + 1325 "but did not throw an ArithmeticException (exception thrown was " + 1326 e.getClass().getName() + "), type was " + 1327 type); 1328 } 1329 } 1330 } 1331 1332 for (Class type : Monetary.getAmountTypes()) { 1333 if (type.equals(TestAmount.class)) { 1334 continue; 1335 } 1336 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 1337 f.setCurrency("CHF"); 1338 MonetaryAmount mAmount1 = f.setNumber(0).create(); 1339 MonetaryContext maxCtx = f.getMaximalMonetaryContext(); 1340 MonetaryAmount m = null; 1341 if (maxCtx.getMaxScale() >= 0) { 1342 m = TestUtils.createAmountWithScale(maxCtx.getMaxScale() + 1); 1343 } 1344 if (m != null) { 1345 try { 1346 mAmount1.subtract(m); 1347 AssertJUnit.fail("Section 4.2.2: ArithmeticException expected on subtraction that exceeds " + 1348 "capabilities for " + 1349 type.getName()); 1350 } catch (ArithmeticException ex) { 1351 // Expected 1352 } catch (Exception e) { 1353 AssertJUnit.fail("Section 4.2.2: Subtraction of amount " + m + " from " + mAmount1 + 1354 " exceeds max monetary context(scale), " + 1355 "but did not throw an ArithmeticException (exception thrown was " + 1356 e.getClass().getName() + "), type was " + 1357 type); 1358 } 1359 } 1360 } 1361 } 1362 1363 /** 1364 * Tests that subtract(), which results in an amount exceeding the max MonetaryContext throws 1365 * a MonetaryException. 1366 */ 1367 @SpecAssertion(section = "4.2.2", id = "422-D10") 1368 @Test(description = "4.2.2 For each amount class, ensure subtraction with null throws NullPointerException.") 1369 public void testSubtract_Null() { 1370 for (Class type : Monetary.getAmountTypes()) { 1371 if (type.equals(TestAmount.class)) { 1372 continue; 1373 } 1374 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1375 try { 1376 mAmount1.subtract(null); 1377 AssertJUnit.fail("Section 4.2.2: MonetaryAmount.subtract(null): NullPointerException expected"); 1378 } catch (NullPointerException ex) { 1379 // Expected 1380 } 1381 } 1382 } 1383 1384 /** 1385 * Test multiply() allow to multiply numbers. 1386 */ 1387 @SpecAssertion(section = "4.2.2", id = "422-D11") 1388 @Test(description = "4.2.2 For each amount class, ensure correct multiplication of int values.") 1389 public void testMultiply_Integral() { 1390 for (Class type : Monetary.getAmountTypes()) { 1391 if (type.equals(TestAmount.class)) { 1392 continue; 1393 } 1394 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1395 MonetaryAmount mActualResult = mAmount1.multiply(2L); 1396 AssertJUnit.assertTrue( 1397 "Section 4.2.2: Multiplication with 2 does not return correct value for " + type.getName(), 1398 mActualResult.getNumber().longValueExact() == 20); 1399 mActualResult = mAmount1.multiply(Double.valueOf(-3)); 1400 AssertJUnit.assertTrue( 1401 "Section 4.2.2: Multiplication with -3 does not return correct value for " + type.getName(), 1402 mActualResult.getNumber().longValueExact() == -30); 1403 mActualResult = mAmount1.multiply(BigDecimal.ONE); 1404 AssertJUnit.assertTrue( 1405 "Section 4.2.2: Multiplication with 1 does not return correct value for " + type.getName(), 1406 mActualResult.getNumber().longValueExact() == 10); 1407 AssertJUnit.assertTrue( 1408 "Section 4.2.2: Multiplication with 1 does not return identity value for " + type.getName(), 1409 mActualResult == mAmount1); 1410 mActualResult = mAmount1.multiply(BigDecimal.ZERO); 1411 AssertJUnit.assertTrue( 1412 "Section 4.2.2: Multiplication with 0 does not return correct value for " + type.getName(), 1413 mActualResult.getNumber().longValue() == 0); 1414 } 1415 } 1416 1417 /** 1418 * Test multiply() allow to multiply numbers. 1419 */ 1420 @SpecAssertion(section = "4.2.2", id = "422-D11") 1421 @Test(description = "4.2.2 For each amount class, ensure correct multiplication of decimal values.") 1422 public void testMultiply_Decimals() { 1423 for (Class type : Monetary.getAmountTypes()) { 1424 if (type.equals(TestAmount.class)) { 1425 continue; 1426 } 1427 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1428 MonetaryAmount mActualResult = mAmount1.multiply(1.5d); 1429 AssertJUnit.assertTrue( 1430 "Section 4.2.2: Multiplication with 1.5 does not return correct value for " + type.getName(), 1431 mActualResult.getNumber().longValueExact() == 15); 1432 mActualResult = mAmount1.multiply(Double.valueOf(-1.5)); 1433 AssertJUnit.assertTrue( 1434 "Section 4.2.2: Multiplication with -3 does not return correct value for " + type.getName(), 1435 mActualResult.getNumber().longValueExact() == -15); 1436 mActualResult = mAmount1.multiply(0.0); 1437 AssertJUnit.assertTrue( 1438 "Section 4.2.2: Multiplication with 0 does not return correct value for " + type.getName(), 1439 mActualResult.getNumber().longValueExact() == 0); 1440 mActualResult = mAmount1.multiply(1.0); 1441 AssertJUnit.assertTrue( 1442 "Section 4.2.2: Multiplication with 0 does not return correct value for " + type.getName(), 1443 mActualResult.getNumber().longValueExact() == 10); 1444 AssertJUnit.assertTrue( 1445 "Section 4.2.2: Multiplication with 0 does not return identity value for " + type.getName(), 1446 mActualResult == mAmount1); 1447 } 1448 } 1449 1450 /** 1451 * Test multiply(1) returns this. 1452 */ 1453 @SpecAssertion(section = "4.2.2", id = "422-D12") 1454 @Test(description = "4.2.2 For each amount class, ensure multiplication by one returns same instance.") 1455 public void testMultiplyOne() { 1456 for (Class type : Monetary.getAmountTypes()) { 1457 if (type.equals(TestAmount.class)) { 1458 continue; 1459 } 1460 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1461 MonetaryAmount mActualResult = mAmount1.multiply(1); 1462 AssertJUnit.assertTrue( 1463 "Section 4.2.2: Multiplication with 1 does not return identity value for " + type.getName(), 1464 mActualResult == mAmount1); 1465 mActualResult = mAmount1.multiply(1.0); 1466 AssertJUnit.assertTrue( 1467 "Section 4.2.2: Multiplication with 1 does not return identity value for " + type.getName(), 1468 mActualResult == mAmount1); 1469 mActualResult = mAmount1.multiply(BigDecimal.ONE); 1470 AssertJUnit.assertTrue( 1471 "Section 4.2.2: Multiplication with 1 does not return identity value for " + type.getName(), 1472 mActualResult == mAmount1); 1473 } 1474 } 1475 1476 1477 /** 1478 * Test multiply, which results in an amount exceeding the max 1479 * MonetaryContext must throw a 1480 * ArithmeticException. 1481 */ 1482 @SpecAssertion(section = "4.2.2", id = "422-D13") 1483 @Test(description = "4.2.2 For each amount class, ensure multiplication with exceeding values throws " + 1484 "ArithmeticException.") 1485 public void testMultiplyExceedsCapabilities() { 1486 for (Class type : Monetary.getAmountTypes()) { 1487 if (type.equals(TestAmount.class)) { 1488 continue; 1489 } 1490 MonetaryAmountFactory<?> f = Monetary.getAmountFactory(type); 1491 MonetaryContext ctx = f.getMaximalMonetaryContext(); 1492 if (ctx.getMaxScale() >= 0) { 1493 BigDecimal num = TestUtils.createNumberWithScale(ctx.getMaxScale() + 5); 1494 MonetaryAmount m = f.setNumber(10).setCurrency("USD").create(); 1495 try { 1496 m.multiply(num); 1497 } catch (ArithmeticException e) { 1498 // OK! 1499 } catch (Exception e) { 1500 AssertJUnit.fail("Section 4.2.2: Multiplication of amount 10 with " + num + 1501 " exceeds max monetary context(scale), should be rounded, " + 1502 "but did throw an Exception (exception thrown was " + 1503 e.getClass().getName() + "), type was " + 1504 type); 1505 } 1506 } 1507 } 1508 for (Class type : Monetary.getAmountTypes()) { 1509 if (type.equals(TestAmount.class)) { 1510 continue; 1511 } 1512 MonetaryAmountFactory<?> f = Monetary.getAmountFactory(type); 1513 MonetaryContext ctx = f.getMaximalMonetaryContext(); 1514 if (ctx.getPrecision() > 0) { 1515 BigDecimal num = TestUtils.createNumberWithPrecision(ctx.getPrecision() + 5); 1516 MonetaryAmount m = f.setNumber(10).setCurrency("USD").create(); 1517 try { 1518 m.multiply(num); 1519 AssertJUnit.fail("Section 4.2.2: Multiplication of amount " + num + 1520 " with 10000000 exceeds max monetary context(precision), " + 1521 "but did not throw an ArithmeticException, type was " + 1522 type.getName()); 1523 } catch (ArithmeticException e) { 1524 // OK 1525 } catch (Exception e) { 1526 AssertJUnit.fail("Section 4.2.2: Multiplication of amount " + num + 1527 " with 10000000 exceeds max monetary context(precision), " + 1528 "but did not throw an ArithmeticException (exception thrown was " + 1529 e.getClass().getName() + "), type was " + 1530 type.getName()); 1531 } 1532 } 1533 } 1534 } 1535 1536 /** 1537 * Test multiply(null) must throw an NullPointerException. 1538 */ 1539 @SpecAssertion(section = "4.2.2", id = "422-D14") 1540 @Test(description = "4.2.2 For each amount class, ensure multiplication of null throws NullPointerException.") 1541 public void testMultiplyNull() { 1542 for (Class type : Monetary.getAmountTypes()) { 1543 if (type.equals(TestAmount.class)) { 1544 continue; 1545 } 1546 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1547 try { 1548 MonetaryAmount mActualResult = mAmount1.multiply(null); 1549 AssertJUnit 1550 .fail("Section 4.2.2: NullPointerException expected for multiplication with null, type was " + 1551 type.getName()); 1552 } catch (NullPointerException e) { 1553 // expected 1554 } 1555 } 1556 } 1557 1558 /** 1559 * Test multiply(Double.NaN) must throw an ArithmeticException. 1560 */ 1561 @SpecAssertion(section = "4.2.2", id = "422-D14") 1562 @Test(description = "4.2.2 For each amount class, ensure multiplication of Double.NaN throws ArithmeticException.") 1563 public void testMultiply_DoubleNaN() { 1564 for (Class type : Monetary.getAmountTypes()) { 1565 if (type.equals(TestAmount.class)) { 1566 continue; 1567 } 1568 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1569 try { 1570 MonetaryAmount mActualResult = mAmount1.multiply(Double.NaN); 1571 AssertJUnit 1572 .fail("Section 4.2.2: ArithmeticException expected for multiplication with Double.NaN, type was " + 1573 type.getName()); 1574 } catch (ArithmeticException e) { 1575 // expected 1576 } 1577 } 1578 } 1579 1580 /** 1581 * Test multiply(Double.POSITIVE_INFINITY) must throw an ArithmeticException. 1582 */ 1583 @SpecAssertion(section = "4.2.2", id = "422-D14") 1584 @Test(description = "4.2.2 For each amount class, ensure multiplication of Double.POSITIVE_INFINITY throws ArithmeticException.") 1585 public void testMultiply_DoublePOSITIVE_INFINITY() { 1586 for (Class type : Monetary.getAmountTypes()) { 1587 if (type.equals(TestAmount.class)) { 1588 continue; 1589 } 1590 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1591 try { 1592 MonetaryAmount mActualResult = mAmount1.multiply(Double.POSITIVE_INFINITY); 1593 AssertJUnit 1594 .fail("Section 4.2.2: ArithmeticException expected for multiplication with Double.POSITIVE_INFINITY, type was " + 1595 type.getName()); 1596 } catch (ArithmeticException e) { 1597 // expected 1598 } 1599 } 1600 } 1601 1602 /** 1603 * Test multiply(Double.POSITIVE_INFINITY) must throw an ArithmeticException. 1604 */ 1605 @SpecAssertion(section = "4.2.2", id = "422-D14") 1606 @Test(description = "4.2.2 For each amount class, ensure multiplication of Double.NEGATIVE_INFINITY throws ArithmeticException.") 1607 public void testMultiply_DoubleNEGATIVE_INFINITY() { 1608 for (Class type : Monetary.getAmountTypes()) { 1609 if (type.equals(TestAmount.class)) { 1610 continue; 1611 } 1612 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1613 try { 1614 MonetaryAmount mActualResult = mAmount1.multiply(Double.NEGATIVE_INFINITY); 1615 AssertJUnit 1616 .fail("Section 4.2.2: ArithmeticException expected for multiplication with Double.NEGATIVE_INFINITY, type was " + 1617 type.getName()); 1618 } catch (ArithmeticException e) { 1619 // expected 1620 } 1621 } 1622 } 1623 1624 /** 1625 * Test divide() function allow to divide numbers. 1626 */ 1627 @SpecAssertion(section = "4.2.2", id = "422-D15") 1628 @Test(description = "4.2.2 For each amount class, ensure correct division.") 1629 public void testDivide() { 1630 for (Class type : Monetary.getAmountTypes()) { 1631 if (type.equals(TestAmount.class)) { 1632 continue; 1633 } 1634 MonetaryAmount m = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1635 MonetaryAmount m2 = m.divide(10); 1636 AssertJUnit.assertEquals("Section 4.2.2: Currency not equal after division, type was " + type.getName(), 1637 DEFAULT_CURRENCY, m2.getCurrency().getCurrencyCode()); 1638 AssertJUnit.assertEquals("Section 4.2.2: Division result is not correct for " + type.getName(), 1, 1639 m2.getNumber().longValueExact()); 1640 } 1641 } 1642 1643 /** 1644 * Test divideToIntegralValue() function allow to divide numbers. 1645 */ 1646 @SpecAssertion(section = "4.2.2", id = "422-D15") 1647 @Test(description = "4.2.2 For each amount class, ensure correct division with int values.") 1648 public void testDivideToIntegralValue() { 1649 for (Class type : Monetary.getAmountTypes()) { 1650 if (type.equals(TestAmount.class)) { 1651 continue; 1652 } 1653 CurrencyUnit euro = Monetary.getCurrency("EUR"); 1654 MonetaryAmount money1 = Monetary.getAmountFactory(type).setNumber(BigDecimal.ONE).setCurrency(euro).create(); 1655 MonetaryAmount result = money1.divideToIntegralValue(new BigDecimal("0.5001")); 1656 AssertJUnit.assertEquals( 1657 "Section 4.2.2: divideToIntegralValue returned incorrect result for " + type.getName(), 1658 result.getNumber().numberValue(BigDecimal.class).stripTrailingZeros(), 1659 new BigDecimal("1.0").stripTrailingZeros()); 1660 result = money1.divideToIntegralValue(new BigDecimal("0.2001")); 1661 AssertJUnit.assertEquals( 1662 "Section 4.2.2: divideToIntegralValue returned incorrect result for " + type.getName(), 1663 result.getNumber().numberValue(BigDecimal.class).stripTrailingZeros(), 1664 new BigDecimal("4.0").stripTrailingZeros()); 1665 result = money1.divideToIntegralValue(new BigDecimal("5.0")); 1666 AssertJUnit 1667 .assertTrue("Section 4.2.2: divideToIntegralValue returned incorrect result for " + type.getName(), 1668 result.getNumber().numberValue(BigDecimal.class).intValueExact() == 0); 1669 } 1670 } 1671 1672 /** 1673 * Test divide(0) function must throw an ArithmeticException. 1674 */ 1675 @SpecAssertion(section = "4.2.2", id = "422-D16") 1676 @Test(description = "4.2.2 For each amount class, ensure divide(0) throws ArithmeticException.") 1677 public void testDivideZero() { 1678 for (Class type : Monetary.getAmountTypes()) { 1679 if (type.equals(TestAmount.class)) { 1680 continue; 1681 } 1682 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1683 try { 1684 MonetaryAmount mActualResult = mAmount1.divide(0); 1685 AssertJUnit.fail("Section 4.2.2: ArithmeticException expected on division by 0, type was " + 1686 type.getName()); 1687 } catch (ArithmeticException ex) { 1688 // expected 1689 } 1690 } 1691 } 1692 1693 /** 1694 * Test divide(0) function must throw an ArithmeticException. 1695 */ 1696 @SpecAssertion(section = "4.2.2", id = "422-D16") 1697 @Test(description = "4.2.2 For each amount class, ensure divide(Double.NaN) throws ArithmeticException.") 1698 public void testDivideDoubleNaN() { 1699 for (Class type : Monetary.getAmountTypes()) { 1700 if (type.equals(TestAmount.class)) { 1701 continue; 1702 } 1703 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1704 try { 1705 MonetaryAmount mActualResult = mAmount1.divide(Double.NaN); 1706 AssertJUnit.fail("Section 4.2.2: ArithmeticException expected on division by Double.NaN, type was " + 1707 type.getName()); 1708 } catch (ArithmeticException ex) { 1709 // expected 1710 } 1711 } 1712 } 1713 1714 /** 1715 * Test divide(0) function must return ZERO amount. 1716 */ 1717 @SpecAssertion(section = "4.2.2", id = "422-D16") 1718 @Test(description = "4.2.2 For each amount class, ensure divide(Double.POSITIVE_INFINITY) return ZERO amount.") 1719 public void testDivideDoublePOSITIVE_INFINITY() { 1720 for (Class type : Monetary.getAmountTypes()) { 1721 if (type.equals(TestAmount.class)) { 1722 continue; 1723 } 1724 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1725 MonetaryAmount mActualResult = mAmount1.divide(Double.POSITIVE_INFINITY); 1726 AssertJUnit.assertEquals("Section 4.2.2: ZERO amount expected on division by Double.POSITIVE_INFINITY, type was " + 1727 type.getName(), mActualResult, Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(0).create()); 1728 } 1729 } 1730 1731 /** 1732 * Test divide(Double.NEGATIVE_INFINITY) function must return ZERO amount. 1733 */ 1734 @SpecAssertion(section = "4.2.2", id = "422-D16") 1735 @Test(description = "4.2.2 For each amount class, ensure divide(Double.NEGATIVE_INFINITY) return ZERO amount.") 1736 public void testDivideDoubleNEGATIVE_INFINITY() { 1737 for (Class type : Monetary.getAmountTypes()) { 1738 if (type.equals(TestAmount.class)) { 1739 continue; 1740 } 1741 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1742 MonetaryAmount mActualResult = mAmount1.divide(Double.NEGATIVE_INFINITY); 1743 AssertJUnit.assertEquals("Section 4.2.2: ZERO amount expected on division by Double.POSITIVE_INFINITY, type was " + 1744 type.getName(), mActualResult, Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(0).create()); 1745 } 1746 } 1747 1748 /** 1749 * Test divide(1) should return this. 1750 */ 1751 @SpecAssertion(section = "4.2.2", id = "422-D17") 1752 @Test(description = "4.2.2 For each amount class, ensure divide 1 returns same instance.") 1753 public void testDivideOne() { 1754 for (Class type : Monetary.getAmountTypes()) { 1755 if (type.equals(TestAmount.class)) { 1756 continue; 1757 } 1758 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1759 MonetaryAmount mActualResult = mAmount1.divide(1); 1760 AssertJUnit.assertTrue("Section 4.2.2: Division by 1 does not return identity value for " + type.getName(), 1761 mActualResult == mAmount1); 1762 mActualResult = mAmount1.divide(1.0); 1763 AssertJUnit.assertTrue("Section 4.2.2: Division by 1 does not return identity value for " + type.getName(), 1764 mActualResult == mAmount1); 1765 mActualResult = mAmount1.divide(BigDecimal.ONE); 1766 AssertJUnit.assertTrue("Section 4.2.2: Division by 1 does not return identity value for " + type.getName(), 1767 mActualResult == mAmount1); 1768 } 1769 } 1770 1771 /** 1772 * Test divide(null)must throw a NullPointerException. 1773 */ 1774 @SpecAssertion(section = "4.2.2", id = "422-D18") 1775 @Test(description = "4.2.2 For each amount class, ensure divide by null throws NullPointerException.") 1776 public void testDivideNull() { 1777 for (Class type : Monetary.getAmountTypes()) { 1778 if (type.equals(TestAmount.class)) { 1779 continue; 1780 } 1781 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1782 try { 1783 MonetaryAmount mActualResult = mAmount1.divide(null); 1784 AssertJUnit.fail("Section 4.2.2: NullPointerException expected for division by null, type was " + 1785 type.getName()); 1786 } catch (NullPointerException e) { 1787 // expected 1788 } 1789 } 1790 } 1791 1792 /** 1793 * Test remainder()allow to calculate the remainder. 1794 */ 1795 @SpecAssertion(section = "4.2.2", id = "422-D19") 1796 @Test(description = "4.2.2 For each amount class, ensure correct results for remainder.") 1797 public void testRemainder() { 1798 for (Class type : Monetary.getAmountTypes()) { 1799 if (type.equals(TestAmount.class)) { 1800 continue; 1801 } 1802 MonetaryAmountFactory<?> f = Monetary.getAmountFactory(type); 1803 f.setCurrency("CHF"); 1804 MonetaryAmount[] moneys = new MonetaryAmount[]{f.setNumber(100).create(), f.setNumber(34242344).create(), 1805 f.setNumber(23123213.435).create(), f.setNumber(0).create(), f.setNumber(-100).create(), 1806 f.setNumber(-723527.36532).create()}; 1807 for (MonetaryAmount m : moneys) { 1808 AssertJUnit.assertEquals("Section 4.2.2: Invalid remainder of " + 10.50 + " for " + type.getName(), 1809 m.getFactory().setNumber(m.getNumber().numberValue(BigDecimal.class) 1810 .remainder(BigDecimal.valueOf(10.50))) 1811 .create(), m.remainder(10.50)); 1812 AssertJUnit.assertEquals("Section 4.2.2: Invalid remainder of " + -30.20 + " for " + type.getName(), 1813 m.getFactory().setNumber(m.getNumber().numberValue(BigDecimal.class) 1814 .remainder(BigDecimal.valueOf(-30.20))) 1815 .create(), m.remainder(-30.20)); 1816 AssertJUnit.assertEquals("Section 4.2.2: Invalid remainder of " + -3 + " for " + type.getName(), 1817 m.getFactory().setNumber(m.getNumber().numberValue(BigDecimal.class) 1818 .remainder(BigDecimal.valueOf(-3))).create(), 1819 m.remainder(-3)); 1820 AssertJUnit.assertEquals("Section 4.2.2: Invalid remainder of " + 3 + " for " + type.getName(), 1821 m.getFactory().setNumber(m.getNumber().numberValue(BigDecimal.class) 1822 .remainder(BigDecimal.valueOf(3))).create(), 1823 m.remainder(3)); 1824 } 1825 } 1826 } 1827 1828 /** 1829 * Test remainder(0) must throw an ArithmeticException 1830 */ 1831 @SpecAssertion(section = "4.2.2", id = "422-D20") 1832 @Test(description = "4.2.2 For each amount class, ensure remainder(0), double, throws ArithmeticException.") 1833 public void testRemainderZero_Double() { 1834 for (Class type : Monetary.getAmountTypes()) { 1835 if (type.equals(TestAmount.class)) { 1836 continue; 1837 } 1838 MonetaryAmount m = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1839 try { 1840 m.remainder(0.0d); 1841 AssertJUnit 1842 .fail("Section 4.2.2: remainder(0) did not throw an ArithmeticException for " + type.getName()); 1843 } catch (ArithmeticException e) { 1844 // OK, ignore 1845 } catch (Exception e) { 1846 AssertJUnit.fail("Section 4.2.2: remainder(0.0d) did not throw an ArithmeticException for " + 1847 type.getName() + ", but " + 1848 e); 1849 } 1850 } 1851 } 1852 1853 /** 1854 * Test remainder(0) must throw an ArithmeticException 1855 */ 1856 @SpecAssertion(section = "4.2.2", id = "422-D20") 1857 @Test(description = "4.2.2 For each amount class, ensure remainder(0), long, throws ArithmeticException.") 1858 public void testRemainderZero_Long() { 1859 for (Class type : Monetary.getAmountTypes()) { 1860 if (type.equals(TestAmount.class)) { 1861 continue; 1862 } 1863 MonetaryAmount m = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1864 try { 1865 m.remainder(0L); 1866 AssertJUnit.fail("Section 4.2.2: remainder(0L) did not throw an ArithmeticException for " + 1867 type.getName()); 1868 } catch (ArithmeticException e) { 1869 // OK, ignore 1870 } catch (Exception e) { 1871 AssertJUnit.fail("Section 4.2.2: remainder(0L) did not throw an ArithmeticException for " + 1872 type.getName() + ", but " + 1873 e); 1874 } 1875 } 1876 } 1877 1878 /** 1879 * Test remainder(0) must throw an ArithmeticException 1880 */ 1881 @SpecAssertion(section = "4.2.2", id = "422-D20") 1882 @Test(description = "4.2.2 For each amount class, ensure remainder(0), Number, throws ArithmeticException.") 1883 public void testRemainderZero_Number() { 1884 for (Class type : Monetary.getAmountTypes()) { 1885 if (type.equals(TestAmount.class)) { 1886 continue; 1887 } 1888 MonetaryAmount m = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1889 try { 1890 m.remainder(BigDecimal.ZERO); 1891 AssertJUnit.fail("Section 4.2.2: remainder(BigDecimal.ZERO) did not throw an ArithmeticException for " + 1892 type.getName()); 1893 } catch (ArithmeticException e) { 1894 // OK, ignore 1895 } catch (Exception e) { 1896 AssertJUnit.fail("Section 4.2.2: remainder(BigDecimal.ZERO) did not throw an ArithmeticException for " + 1897 type.getName() + 1898 ", but " + e); 1899 } 1900 } 1901 } 1902 1903 /** 1904 * Test remainder(null) must throw a NullPointerException 1905 */ 1906 @SpecAssertion(section = "4.2.2", id = "422-D21") 1907 @Test(description = "4.2.2 For each amount class, ensure remainder(null), throws NullPointerException.") 1908 public void testRemainderNull() { 1909 for (Class type : Monetary.getAmountTypes()) { 1910 if (type.equals(TestAmount.class)) { 1911 continue; 1912 } 1913 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1914 try { 1915 MonetaryAmount mActualResult = mAmount1.remainder(null); 1916 AssertJUnit.fail("Section 4.2.2: NullPointerException expected for remainder with null, type was " + 1917 type.getName()); 1918 } catch (NullPointerException e) { 1919 // expected 1920 } 1921 } 1922 } 1923 1924 /** 1925 * Test remainder(null) must throw a NullPointerException 1926 */ 1927 @SpecAssertion(section = "4.2.2", id = "422-D21") 1928 @Test(description = "4.2.2 For each amount class, ensure remainder(Double.NaN), throws ArithmeticException.") 1929 public void testRemainder_DoubleNaN() { 1930 for (Class type : Monetary.getAmountTypes()) { 1931 if (type.equals(TestAmount.class)) { 1932 continue; 1933 } 1934 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1935 try { 1936 MonetaryAmount mActualResult = mAmount1.remainder(Double.NaN); 1937 AssertJUnit.fail("Section 4.2.2: ArithmeticException expected for remainder(Double.NaN), type was " + 1938 type.getName()); 1939 } catch (ArithmeticException e) { 1940 // expected 1941 } 1942 } 1943 } 1944 1945 /** 1946 * Test remainder(null) must throw a NullPointerException 1947 */ 1948 @SpecAssertion(section = "4.2.2", id = "422-D21") 1949 @Test(description = "4.2.2 For each amount class, ensure remainder(Double.POSITIVE_INFINITY), throws ArithmeticException.") 1950 public void testRemainder_DoublePOSITIVE_INFINITY() { 1951 for (Class type : Monetary.getAmountTypes()) { 1952 if (type.equals(TestAmount.class)) { 1953 continue; 1954 } 1955 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1956 MonetaryAmount mActualResult = mAmount1.remainder(Double.POSITIVE_INFINITY); 1957 AssertJUnit.assertEquals(Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(0).create(), mActualResult); 1958 } 1959 } 1960 1961 /** 1962 * Test remainder(null) must throw a NullPointerException 1963 */ 1964 @SpecAssertion(section = "4.2.2", id = "422-D21") 1965 @Test(description = "4.2.2 For each amount class, ensure remainder(Double.NEGATIVE_INFINITY), throws ArithmeticException.") 1966 public void testRemainder_DoubleNEGATIVE_INFINITY() { 1967 for (Class type : Monetary.getAmountTypes()) { 1968 if (type.equals(TestAmount.class)) { 1969 continue; 1970 } 1971 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 1972 MonetaryAmount mActualResult = mAmount1.remainder(Double.NEGATIVE_INFINITY); 1973 AssertJUnit.assertEquals(Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(0).create(), mActualResult); 1974 } 1975 } 1976 1977 1978 /** 1979 * Test divideAndRemainder()allow to divide/remind numbers. 1980 */ 1981 @SpecAssertion(section = "4.2.2", id = "422-D22") 1982 @Test(description = "4.2.2 For each amount class, ensure correct divideAndRemainder().") 1983 public void testDivideAndRemainder() { 1984 for (Class type : Monetary.getAmountTypes()) { 1985 if (type.equals(TestAmount.class)) { 1986 continue; 1987 } 1988 MonetaryAmountFactory<?> f = Monetary.getAmountFactory(type); 1989 MonetaryAmount money1 = f.setNumber(BigDecimal.ONE).setCurrency("EUR").create(); 1990 if (f.getDefaultMonetaryContext().getMaxScale() < 5) { 1991 MonetaryAmount[] divideAndRemainder = money1.divideAndRemainder(new BigDecimal("0.6")); 1992 AssertJUnit.assertEquals("Section 4.2.2: divideAndRemainder(0.6)[0] failed for " + type.getName(), 1993 divideAndRemainder[0].getNumber().numberValue(BigDecimal.class) 1994 .stripTrailingZeros(), BigDecimal.ONE.stripTrailingZeros()); 1995 AssertJUnit.assertEquals("Section 4.2.2: divideAndRemainder(0.6)[1] failed for " + type.getName(), 1996 divideAndRemainder[1].getNumber().numberValue(BigDecimal.class) 1997 .stripTrailingZeros(), new BigDecimal("0.4").stripTrailingZeros()); 1998 } else { 1999 MonetaryAmount[] divideAndRemainder = money1.divideAndRemainder(new BigDecimal("0.50001")); 2000 AssertJUnit.assertEquals("Section 4.2.2: divideAndRemainder(0.50001)[0] failed for " + type.getName(), 2001 divideAndRemainder[0].getNumber().numberValue(BigDecimal.class) 2002 .stripTrailingZeros(), BigDecimal.ONE.stripTrailingZeros()); 2003 AssertJUnit.assertEquals("Section 4.2.2: divideAndRemainder(0.50001)[1] failed for " + type.getName(), 2004 divideAndRemainder[1].getNumber().numberValue(BigDecimal.class) 2005 .stripTrailingZeros(), new BigDecimal("0.49999").stripTrailingZeros()); 2006 } 2007 } 2008 } 2009 2010 /** 2011 * Test divideAndRemainder(0) throws an ArithmeticException. 2012 */ 2013 @SpecAssertion(section = "4.2.2", id = "422-D23") 2014 @Test(description = "4.2.2 For each amount class, ensure correct divideAndRemainderZero().") 2015 public void testDivideAndRemainderZero() { 2016 for (Class type : Monetary.getAmountTypes()) { 2017 if (type.equals(TestAmount.class)) { 2018 continue; 2019 } 2020 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 2021 try { 2022 mAmount1.divideAndRemainder(BigDecimal.ZERO); 2023 AssertJUnit.fail("Section 4.2.2: divideAndRemainder(0) for " + type.getName() + 2024 ", should throw ArithmeticException!"); 2025 } catch (ArithmeticException e) { 2026 // expected 2027 } catch (Exception e) { 2028 AssertJUnit.fail("Section 4.2.2: Unexpected exception for divideAndRemainder(0) for " + type.getName() + 2029 ", should be ArithmeticException, but was " + e); 2030 } 2031 } 2032 } 2033 2034 /** 2035 * Test divideAndRemainder(null) throws an NullPointerException. 2036 */ 2037 @SpecAssertion(section = "4.2.2", id = "422-D24") 2038 @Test(description = "4.2.2 For each amount class, ensure divideAndRemainder(null) throws a NullPointerException.") 2039 public void testDivideAndRemainderNull() { 2040 for (Class type : Monetary.getAmountTypes()) { 2041 if (type.equals(TestAmount.class)) { 2042 continue; 2043 } 2044 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 2045 try { 2046 MonetaryAmount[] mActualResult = mAmount1.divideAndRemainder(null); 2047 AssertJUnit.fail("Section 4.2.2: NullPointerException expected for divideAndRemainder with null, " + 2048 "type was " + 2049 type.getName()); 2050 } catch (NullPointerException e) { 2051 // expected 2052 } 2053 } 2054 } 2055 2056 /** 2057 * Test divideAndRemainder(null) throws an NullPointerException. 2058 */ 2059 @SpecAssertion(section = "4.2.2", id = "422-D24") 2060 @Test(description = "4.2.2 For each amount class, ensure divideAndRemainder(Double.NaN) throws a ArithmeticException.") 2061 public void testDivideAndRemainderDoubleNaN() { 2062 for (Class type : Monetary.getAmountTypes()) { 2063 if (type.equals(TestAmount.class)) { 2064 continue; 2065 } 2066 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 2067 try { 2068 MonetaryAmount[] mActualResult = mAmount1.divideAndRemainder(Double.NaN); 2069 AssertJUnit.fail("Section 4.2.2: ArithmeticException expected for divideAndRemainder with Double.NaN, " + 2070 "type was " + 2071 type.getName()); 2072 } catch (ArithmeticException e) { 2073 // expected 2074 } 2075 } 2076 } 2077 2078 /** 2079 * Test divideAndRemainder(null) throws an NullPointerException. 2080 */ 2081 @SpecAssertion(section = "4.2.2", id = "422-D24") 2082 @Test(description = "4.2.2 For each amount class, ensure divideAndRemainder(Double.POSITIVE_INFINITY) returns ZERO amount.") 2083 public void testDivideAndRemainderDoublePOSITIVE_INFINITY() { 2084 for (Class type : Monetary.getAmountTypes()) { 2085 if (type.equals(TestAmount.class)) { 2086 continue; 2087 } 2088 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 2089 MonetaryAmount[] mActualResult = mAmount1.divideAndRemainder(Double.POSITIVE_INFINITY); 2090 MonetaryAmount zero = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(0).create(); 2091 AssertJUnit.assertEquals("Section 4.2.2: ZERO amount expected for divideAndRemainder with Double.POSITIVE_INFINITY, " + 2092 "type was " + 2093 type.getName(), zero, 2094 mActualResult[0]); 2095 AssertJUnit.assertEquals("Section 4.2.2: ZERO amount expected for divideAndRemainder with Double.POSITIVE_INFINITY, " + 2096 "type was " + 2097 type.getName(), zero, 2098 mActualResult[1]); 2099 } 2100 } 2101 2102 /** 2103 * Test divideAndRemainder(null) throws an NullPointerException. 2104 */ 2105 @SpecAssertion(section = "4.2.2", id = "422-D24") 2106 @Test(description = "4.2.2 For each amount class, ensure divideAndRemainder(Double.NEGATIVE_INFINITY) returns ZERO amount.") 2107 public void testDivideAndRemainderDoubleNEGATIVE_INFINITY() { 2108 for (Class type : Monetary.getAmountTypes()) { 2109 if (type.equals(TestAmount.class)) { 2110 continue; 2111 } 2112 MonetaryAmount mAmount1 = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(10).create(); 2113 MonetaryAmount[] mActualResult = mAmount1.divideAndRemainder(Double.NEGATIVE_INFINITY); 2114 MonetaryAmount zero = Monetary.getAmountFactory(type).setCurrency(DEFAULT_CURRENCY).setNumber(0).create(); 2115 AssertJUnit.assertEquals("Section 4.2.2: ZERO amount expected for divideAndRemainder with Double.NEGATIVE_INFINITY, " + 2116 "type was " + 2117 type.getName(), zero, 2118 mActualResult[0]); 2119 AssertJUnit.assertEquals("Section 4.2.2: ZERO amount expected for divideAndRemainder with Double.NEGATIVE_INFINITY, " + 2120 "type was " + 2121 type.getName(), zero, 2122 mActualResult[1]); 2123 } 2124 } 2125 2126 2127 /** 2128 * Test divideAndRemainder(1) returns this/ZERO. 2129 */ 2130 @SpecAssertion(section = "4.2.2", id = "422-D25") 2131 @Test(description = "4.2.2 For each amount class, ensure divideAndRemainder(1) returns same instance.") 2132 public void testDivideAndRemainderOne() { 2133 for (Class type : Monetary.getAmountTypes()) { 2134 if (type.equals(TestAmount.class)) { 2135 continue; 2136 } 2137 MonetaryAmountFactory<?> f = Monetary.getAmountFactory(type); 2138 MonetaryAmount m = f.setNumber(100).setCurrency("CHF").create(); 2139 AssertJUnit.assertEquals( 2140 "Section 4.2.2: DivideAndRemainder not returning correct result for type: " + type.getName(), 2141 BigDecimal.valueOf(33), 2142 m.divideAndRemainder(3)[0].getNumber().numberValue(BigDecimal.class).stripTrailingZeros()); 2143 AssertJUnit.assertEquals( 2144 "Section 4.2.2: DivideAndRemainder not returning correct result for type: " + type.getName(), 2145 BigDecimal.valueOf(1), 2146 m.divideAndRemainder(3)[1].getNumber().numberValue(BigDecimal.class).stripTrailingZeros()); 2147 AssertJUnit.assertEquals( 2148 "Section 4.2.2: DivideAndRemainder not returning correct result for type: " + type.getName(), 2149 BigDecimal.ONE, 2150 m.divideAndRemainder(BigDecimal.valueOf(3))[1].getNumber().numberValue(BigDecimal.class) 2151 .stripTrailingZeros()); 2152 } 2153 } 2154 2155 /** 2156 * Test scaleByPowerOfTen()allow to scale by power of 10. 2157 */ 2158 @SpecAssertion(section = "4.2.2", id = "422-D26") 2159 @Test(description = "4.2.2 For each amount class, ensure scaleByPowerOfTen(1) returns correct results.") 2160 public void testScaleByPowerOfTen() { 2161 for (Class type : Monetary.getAmountTypes()) { 2162 if (type.equals(TestAmount.class)) { 2163 continue; 2164 } 2165 MonetaryAmountFactory<?> f = Monetary.getAmountFactory(type); 2166 f.setCurrency("CHF"); 2167 MonetaryAmount[] amounts = new MonetaryAmount[]{f.setNumber(100).create(), f.setNumber(342444).create(), 2168 f.setNumber(2312213.435).create(), f.setNumber(BigDecimal.ZERO).create(), 2169 f.setNumber(-100).create(), f.setNumber(-723527.3653).create()}; 2170 2171 for (MonetaryAmount m : amounts) { 2172 for (int p = -3; p < 3; p++) { 2173 BigDecimal bdExpected = m.scaleByPowerOfTen(p).getNumber().numberValue(BigDecimal.class); 2174 BigDecimal bdCalculated = m.getNumber().numberValue(BigDecimal.class).scaleByPowerOfTen(p); 2175 bdCalculated = bdCalculated.setScale(m.getContext().getMaxScale(), RoundingMode.HALF_EVEN); 2176 if (bdExpected.signum() == 0) { 2177 AssertJUnit.assertTrue("Section 4.2.2: Invalid " + m + " -> scaleByPowerOfTen(" + p + ") for " + 2178 type.getName(), bdCalculated.signum() == 0); 2179 } else { 2180 AssertJUnit 2181 .assertEquals("Section 4.2.2: Invalid " + m + " -> scaleByPowerOfTen(" + p + ") for " + 2182 type.getName(), bdExpected 2183 .setScale(m.getContext().getMaxScale() - 1, 2184 RoundingMode.HALF_EVEN).stripTrailingZeros(), 2185 bdCalculated.setScale(m.getContext().getMaxScale() - 1, 2186 RoundingMode.HALF_EVEN).stripTrailingZeros()); 2187 } 2188 } 2189 } 2190 } 2191 } 2192 2193 /** 2194 * Test abs() for getting the absolute value. 2195 */ 2196 @SpecAssertion(section = "4.2.2", id = "422-D27") 2197 @Test(description = "4.2.2 For each amount class, test absolute().") 2198 public void testAbsolute() { 2199 for (Class type : Monetary.getAmountTypes()) { 2200 if (type.equals(TestAmount.class)) { 2201 continue; 2202 } 2203 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 2204 f.setCurrency("CHF"); 2205 MonetaryAmount m = f.setNumber(10).create(); 2206 AssertJUnit 2207 .assertEquals("Section 4.2.2: abs(m) !equals m, if m > 0 for type: " + type.getName(), m, m.abs()); 2208 AssertJUnit.assertTrue("Section 4.2.2: abs(m) != m, if m > 0 for type: " + type.getName(), m == m.abs()); 2209 m = f.setNumber(0).create(); 2210 AssertJUnit 2211 .assertEquals("Section 4.2.2: abs(m) != equals, if m == 0 for type: " + type.getName(), m, m.abs()); 2212 AssertJUnit.assertTrue("Section 4.2.2: abs(m) != m, if m == 0 for type: " + type.getName(), m == m.abs()); 2213 m = f.setNumber(-10).create(); 2214 AssertJUnit.assertEquals("Section 4.2.2: abs(m) == m, if m < 0 for type: " + type.getName(), m.negate(), 2215 m.abs()); 2216 AssertJUnit.assertTrue("Section 4.2.2: abs(m) == m, if m < 0 for type: " + type.getName(), m != m.abs()); 2217 } 2218 } 2219 2220 /** 2221 * Test negate() for negating a value. 2222 */ 2223 @SpecAssertion(section = "4.2.2", id = "422-D28") 2224 @Test(description = "4.2.2 For each amount class, test negate().") 2225 public void testNegate() { 2226 for (Class type : Monetary.getAmountTypes()) { 2227 if (type.equals(TestAmount.class)) { 2228 continue; 2229 } 2230 MonetaryAmountFactory<MonetaryAmount> f = Monetary.getAmountFactory(type); 2231 f.setCurrency("CHF"); 2232 MonetaryAmount m = f.setNumber(100).create(); 2233 AssertJUnit 2234 .assertEquals("Section 4.2.2: negate(-x) failed for " + type.getName(), f.setNumber(-100).create(), 2235 m.negate()); 2236 m = f.setNumber(-123.234).create(); 2237 AssertJUnit.assertEquals("Section 4.2.2: negate(+x) failed for " + type.getName(), 2238 f.setNumber(123.234).create(), m.negate()); 2239 } 2240 } 2241 2242 /** 2243 * Ensure with(MonetaryOperator) can be called and produces 2244 * amounts of the same type and correct value. 2245 */ 2246 @SpecAssertion(section = "4.2.2", id = "422-E1") 2247 @Test(description = "4.2.2 For each amount class, test with().") 2248 public void testWith() { 2249 MonetaryOperator op = new MonetaryOperator() { 2250 @Override 2251 public MonetaryAmount apply(MonetaryAmount amount) { 2252 return amount; 2253 } 2254 }; 2255 for (Class type : Monetary.getAmountTypes()) { 2256 if (type.equals(TestAmount.class)) { 2257 continue; 2258 } 2259 MonetaryAmount amount = Monetary.getAmountFactory(type).setCurrency("CHF").setNumber(10).create(); 2260 MonetaryAmount amount2 = amount.with(op); 2261 AssertJUnit.assertTrue( 2262 "Section 4.2.2: MonetaryAmount returned from operator is wrapped by implementation of type: " + 2263 type.getName(), amount == amount2); 2264 final MonetaryAmount result = Monetary.getAmountFactory(type).setCurrency("CHF").setNumber(4).create(); 2265 MonetaryOperator op2 = new MonetaryOperator() { 2266 @Override 2267 public MonetaryAmount apply(MonetaryAmount amount) { 2268 return result; 2269 } 2270 }; 2271 amount2 = amount.with(op); 2272 AssertJUnit.assertTrue( 2273 "Section 4.2.2: MonetaryAmount returned from operator is wrapped by implementation of type: " + 2274 type.getName(), amount == amount2); 2275 } 2276 } 2277 2278 /** 2279 * Ensure with(MonetaryOperator) can be called and produces 2280 * amounts of the same type and correct value, testing operators provided by TCKTestSetup. 2281 */ 2282 @SpecAssertion(section = "4.2.2", id = "422-E1") 2283 @Test(description = "4.2.2 For each amount class, test with().") 2284 public void testWith4ProvidedOperators() { 2285 for (MonetaryOperator op : TCKTestSetup.getTestConfiguration().getMonetaryOperators4Test()) { 2286 for (Class type : Monetary.getAmountTypes()) { 2287 if (type.equals(TestAmount.class)) { 2288 continue; 2289 } 2290 MonetaryAmount amount = Monetary.getAmountFactory(type).setCurrency("CHF").setNumber(10).create(); 2291 MonetaryAmount amount2 = amount.with(op); 2292 AssertJUnit.assertTrue( 2293 "Section 4.2.2: MonetaryAmount returned from operator is wrapped by implementation of type: " + 2294 type.getName(), amount.getClass() == amount2.getClass()); 2295 final MonetaryAmount result = Monetary.getAmountFactory(type).setCurrency("CHF").setNumber(4).create(); 2296 MonetaryOperator op2 = new MonetaryOperator() { 2297 @Override 2298 public MonetaryAmount apply(MonetaryAmount amount) { 2299 return amount; 2300 } 2301 }; 2302 amount2 = amount.with(op2); 2303 AssertJUnit.assertTrue( 2304 "Section 4.2.2: MonetaryAmount returned from operator is wrapped by implementation of type: " + 2305 type.getName(), amount == amount2); 2306 } 2307 } 2308 } 2309 2310 /** 2311 * Test with(m) throws a MonetaryException, if m throws any exception. 2312 */ 2313 @SpecAssertion(section = "4.2.2", id = "422-E2") 2314 @Test(description = "4.2.2 Bad case: For each amount class, test with(), operator throws exception.") 2315 public void testWithInvalidOperator() { 2316 MonetaryOperator op = new MonetaryOperator() { 2317 @Override 2318 public MonetaryAmount apply(MonetaryAmount value) { 2319 throw new IllegalStateException(); 2320 } 2321 }; 2322 for (Class type : Monetary.getAmountTypes()) { 2323 if (type.equals(TestAmount.class)) { 2324 continue; 2325 } 2326 MonetaryAmountFactory factory = Monetary.getAmountFactory(type); 2327 MonetaryAmount amount = factory.setCurrency("XXX").setNumber(1).create(); 2328 try { 2329 amount.with(op); 2330 AssertJUnit.fail("Section 4.2.2: MonetaryException expected as operator fails, type was " + 2331 type.getName()); 2332 } catch (MonetaryException e) { 2333 // OK, everything else makes the test fail! 2334 } 2335 } 2336 } 2337 2338 /** 2339 * Test with(null) throws a NullPointerException. 2340 */ 2341 @SpecAssertion(section = "4.2.2", id = "422-E2") 2342 @Test(description = "4.2.2 Bad case: For each amount class, test with(null), expected NullPointerException.") 2343 public void testWithNull() { 2344 for (Class type : Monetary.getAmountTypes()) { 2345 if (type.equals(TestAmount.class)) { 2346 continue; 2347 } 2348 MonetaryAmountFactory factory = Monetary.getAmountFactory(type); 2349 MonetaryAmount amount = factory.setCurrency("XXX").setNumber(1).create(); 2350 try { 2351 amount.with(null); 2352 AssertJUnit.fail("Section 4.2.2: NullPointerException expected as operator applied is null, type was " + 2353 type.getName()); 2354 } catch (NullPointerException e) { 2355 // OK, everything else makes the test fail! 2356 } 2357 } 2358 } 2359 2360 /** 2361 * Test with(null) throws a NullPointerException. 2362 */ 2363 @SpecAssertion(section = "4.2.2", id = "422-E2") 2364 @Test(description = "4.2.2 Bad case: For each amount class, test with(), operator throws exception.") 2365 public void testWithNull4ProvidedOperators() { 2366 for (MonetaryOperator op : TCKTestSetup.getTestConfiguration().getMonetaryOperators4Test()) { 2367 try { 2368 op.apply(null); 2369 AssertJUnit.fail("Section 4.2.2: NullPointerException expected as operator was applied on null, " + 2370 "operator was " + 2371 op.getClass().getName()); 2372 } catch (NullPointerException e) { 2373 // OK, everything else makes the test fail! 2374 } 2375 } 2376 } 2377 2378 /** 2379 * Ensure query(MonetaryQUery) can be called and produces 2380 * valuable results. 2381 */ 2382 @SpecAssertion(section = "4.2.2", id = "422-E3") 2383 @Test(description = "4.2.2 For each amount class, test query().") 2384 public void testQuery() { 2385 MonetaryQuery<Integer> query = new MonetaryQuery<Integer>() { 2386 @Override 2387 public Integer queryFrom(MonetaryAmount amount) { 2388 return amount.getNumber().intValue(); 2389 } 2390 }; 2391 for (Class type : Monetary.getAmountTypes()) { 2392 if (type.equals(TestAmount.class)) { 2393 continue; 2394 } 2395 MonetaryAmount amount = Monetary.getAmountFactory(type).setCurrency("CHF").setNumber(10).create(); 2396 Integer value = amount.query(query); 2397 AssertJUnit.assertTrue( 2398 "Section 4.2.2: Value returned from MonetaryAmount Query is not correct for " + type.getName(), 2399 value == 10); 2400 amount = Monetary.getAmountFactory(type).setCurrency("CHF").setNumber(4.5).create(); 2401 value = amount.query(query); 2402 AssertJUnit.assertTrue( 2403 "Section 4.2.2: Value returned from MonetaryAmount Query is not correct for " + type.getName(), 2404 value == 4); 2405 } 2406 } 2407 2408 /** 2409 * Test query(q) throws a MonetaryException, if q throws any exception. 2410 */ 2411 @SpecAssertion(section = "4.2.2", id = "422-E4") 2412 @Test(description = "4.2.2 For each amount class, test query(), MonetaryQuery throws exception, " + 2413 "MonetaryException expected.") 2414 public void testQueryInvalidQuery() { 2415 MonetaryQuery<Integer> query = new MonetaryQuery<Integer>() { 2416 @Override 2417 public Integer queryFrom(MonetaryAmount amount) { 2418 throw new IllegalStateException(); 2419 } 2420 }; 2421 for (Class type : Monetary.getAmountTypes()) { 2422 if (type.equals(TestAmount.class)) { 2423 continue; 2424 } 2425 TestUtils.testComparable("Section 4.2.2", type); 2426 MonetaryAmountFactory factory = Monetary.getAmountFactory(type); 2427 MonetaryAmount amount = factory.setCurrency("XXX").setNumber(1).create(); 2428 try { 2429 amount.query(query); 2430 AssertJUnit.fail("Section 4.2.2: MonetaryException expected as query applied is failing, type was " + 2431 type.getName()); 2432 } catch (MonetaryException e) { 2433 // OK, everything else makes the test fail! 2434 } 2435 } 2436 } 2437 2438 /** 2439 * Test query(null) throws a NullPointerException. 2440 */ 2441 @SpecAssertion(section = "4.2.2", id = "422-E4") 2442 @Test(description = "4.2.2 For each amount class, test query(null), NullPointerException expected.") 2443 public void testQueryNull() { 2444 for (Class type : Monetary.getAmountTypes()) { 2445 if (type.equals(TestAmount.class)) { 2446 continue; 2447 } 2448 TestUtils.testComparable("Section 4.2.2", type); 2449 MonetaryAmountFactory factory = Monetary.getAmountFactory(type); 2450 MonetaryAmount amount = factory.setCurrency("XXX").setNumber(1).create(); 2451 try { 2452 amount.query(null); 2453 AssertJUnit.fail("Section 4.2.2: NullPointerException expected as query applied is null, type was " + 2454 type.getName()); 2455 } catch (NullPointerException e) { 2456 // OK, everything else makes the test fail! 2457 } 2458 } 2459 } 2460 2461 /** 2462 * Implementations of MonetaryAmount must implement hashCode, 2463 * considering number, currency and implementation type, 2464 * monetary 2465 * context. 2466 */ 2467 @SpecAssertion(section = "4.2.2", id = "422-F1") 2468 @Test(description = "4.2.2 For each amount class, test implements hashCode().") 2469 public void testImplementsHashCode() { 2470 for (Class type : Monetary.getAmountTypes()) { 2471 if (type.equals(TestAmount.class)) { 2472 continue; 2473 } 2474 MonetaryAmount amount = Monetary.getAmountFactory(type).setCurrency("USD").setNumber(0).create(); 2475 TestUtils.testHasPublicMethod("Section 4.2.2", type, type, "hashCode"); 2476 MonetaryAmount amount2 = Monetary.getAmountFactory(type).setCurrency("USD").setNumber(0).create(); 2477 AssertJUnit.assertEquals("Section 4.2.2: hashCode() for equal amounts differ for type " + type.getName(), 2478 amount.hashCode(), amount2.hashCode()); 2479 } 2480 } 2481 2482 /** 2483 * Implementations of MonetaryAmount must implement 2484 * equals, 2485 * considering number, currency and implementation type, 2486 * monetary 2487 * context. 2488 */ 2489 @SpecAssertion(section = "4.2.2", id = "422-F2") 2490 @Test(description = "4.2.2 For each amount class, test implements equals().") 2491 public void testImplementsEquals() { 2492 for (Class type : Monetary.getAmountTypes()) { 2493 if (type.equals(TestAmount.class)) { 2494 continue; 2495 } 2496 MonetaryAmount amount = Monetary.getAmountFactory(type).setCurrency("XXX").setNumber(0).create(); 2497 TestUtils.testHasPublicMethod("Section 4.2.2", type, type, "equals", Object.class); 2498 MonetaryAmount amount2 = Monetary.getAmountFactory(type).setCurrency("XXX").setNumber(0).create(); 2499 AssertJUnit 2500 .assertEquals("Section 4.2.2: equals(Object) for equal amounts returns false for " + type.getName(), 2501 amount, amount2); 2502 } 2503 } 2504 2505 /** 2506 * Implementations of MonetaryAmount must be Comparable. 2507 */ 2508 @SpecAssertion(section = "4.2.2", id = "422-F3") 2509 @Test(description = "4.2.2 For each amount class, test is Comparable.") 2510 public void testImplementComparable() { 2511 for (Class type : Monetary.getAmountTypes()) { 2512 if (type.equals(TestAmount.class)) { 2513 continue; 2514 } 2515 TestUtils.testComparable("Section 4.2.2", type); 2516 MonetaryAmountFactory factory = Monetary.getAmountFactory(type); 2517 MonetaryAmount amount = factory.setCurrency("XXX").setNumber(0).create(); 2518 MonetaryAmount amount2 = factory.setCurrency("XXX").setNumber(0).create(); 2519 MonetaryAmount amount3 = factory.setCurrency("CHF").setNumber(1).create(); 2520 MonetaryAmount amount4 = factory.setCurrency("XXX").setNumber(1).create(); 2521 2522 AssertJUnit.assertTrue("Section 4.2.2: Comparable failed for: " + type.getName(), 2523 ((Comparable) amount).compareTo(amount3) > 0); 2524 2525 AssertJUnit.assertTrue("Section 4.2.2: Comparable failed for: " + type.getName(), 2526 ((Comparable) amount3).compareTo(amount) < 0); 2527 2528 AssertJUnit.assertTrue("Section 4.2.2: Comparable failed for: " + type.getName(), 2529 ((Comparable) amount).compareTo(amount4) < 0); 2530 2531 AssertJUnit.assertTrue("Section 4.2.2: Comparable failed for: " + type.getName(), 2532 ((Comparable) amount4).compareTo(amount) > 0); 2533 } 2534 } 2535 2536 /** 2537 * Implementations of MonetaryAmount must be Serializable. 2538 */ 2539 @SuppressWarnings("UseOfSystemOutOrSystemErr") 2540 @SpecAssertion(section = "4.2.2", id = "422-F4") 2541 @Test(description = "4.2.2 For each amount class, test iis immutable.") 2542 public void testImmutable() { 2543 for (Class type : TCKTestSetup.getTestConfiguration().getAmountClasses()) { 2544 if (type.equals(TestAmount.class)) { 2545 continue; 2546 } 2547 TestUtils.testImmutable("Section 4.2.2", type); 2548 } 2549 for (Class type : Monetary.getAmountTypes()) { 2550 if (type.equals(TestAmount.class)) { 2551 continue; 2552 } 2553 //noinspection ErrorNotRethrown 2554 try { 2555 TestUtils.testImmutable("Section 4.2.2", type); 2556 } catch (MutabilityAssertionError e) { 2557 System.out 2558 .println("Warning: found non immutable MonetaryAmountType: " + type.getName() + ", details: " + 2559 e.getMessage()); 2560 } 2561 } 2562 } 2563 2564 2565}