/* * Copyright (c) 2012 Ngewi Fet <ngewif@gmail.com> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.gnucash.android.test.unit.model; import org.gnucash.android.BuildConfig; import org.gnucash.android.model.Commodity; import org.gnucash.android.model.Money; import org.gnucash.android.test.unit.testutil.GnucashTestRunner; import org.gnucash.android.test.unit.testutil.ShadowCrashlytics; import org.gnucash.android.test.unit.testutil.ShadowUserVoice; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.annotation.Config; import java.math.BigDecimal; import java.util.Currency; import java.util.Locale; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotSame; @RunWith(GnucashTestRunner.class) @Config(constants = BuildConfig.class, sdk = 21, packageName = "org.gnucash.android", shadows = {ShadowCrashlytics.class, ShadowUserVoice.class}) public class MoneyTest{ private static final String CURRENCY_CODE = "EUR"; private Money mMoneyInEur; private int mHashcode; private String amountString = "15.75"; @Before public void setUp() throws Exception { mMoneyInEur = new Money(new BigDecimal(amountString), Commodity.getInstance(CURRENCY_CODE)); mHashcode = mMoneyInEur.hashCode(); } @Test public void testCreation(){ Locale.setDefault(Locale.US); String amount = "12.25"; Money temp = new Money(amount, CURRENCY_CODE); assertThat("12.25").isEqualTo(temp.toPlainString()); assertThat(temp.getNumerator()).isEqualTo(1225L); assertThat(temp.getDenominator()).isEqualTo(100L); Commodity commodity = Commodity.getInstance(CURRENCY_CODE); temp = new Money(BigDecimal.TEN, commodity); assertEquals("10.00", temp.asBigDecimal().toPlainString()); //decimal places for EUR currency assertEquals(commodity, temp.getCommodity()); assertThat("10").isNotEqualTo(temp.asBigDecimal().toPlainString()); } @Test public void testAddition(){ Money result = mMoneyInEur.add(new Money("5", CURRENCY_CODE)); assertEquals("20.75", result.toPlainString()); assertNotSame(result, mMoneyInEur); validateImmutability(); } @Test(expected = Money.CurrencyMismatchException.class) public void testAdditionWithIncompatibleCurrency(){ Money addend = new Money("4", "USD"); mMoneyInEur.add(addend); } @Test public void testSubtraction(){ Money result = mMoneyInEur.subtract(new Money("2", CURRENCY_CODE)); assertEquals(new BigDecimal("13.75"), result.asBigDecimal()); assertNotSame(result, mMoneyInEur); validateImmutability(); } @Test(expected = Money.CurrencyMismatchException.class) public void testSubtractionWithDifferentCurrency(){ Money addend = new Money("4", "USD"); mMoneyInEur.subtract(addend); } @Test public void testMultiplication(){ Money result = mMoneyInEur.multiply(new Money(BigDecimal.TEN, Commodity.getInstance(CURRENCY_CODE))); assertThat("157.50").isEqualTo(result.toPlainString()); assertThat(result).isNotEqualTo(mMoneyInEur); validateImmutability(); } @Test(expected = Money.CurrencyMismatchException.class) public void testMultiplicationWithDifferentCurrencies(){ Money addend = new Money("4", "USD"); mMoneyInEur.multiply(addend); } @Test public void testDivision(){ Money result = mMoneyInEur.divide(2); assertThat(result.toPlainString()).isEqualTo("7.88"); assertThat(result).isNotEqualTo(mMoneyInEur); validateImmutability(); } @Test(expected = Money.CurrencyMismatchException.class) public void testDivisionWithDifferentCurrency(){ Money addend = new Money("4", "USD"); mMoneyInEur.divide(addend); } @Test public void testNegation(){ Money result = mMoneyInEur.negate(); assertThat(result.toPlainString()).startsWith("-"); validateImmutability(); } @Test public void testFractionParts(){ Money money = new Money("14.15", "USD"); assertThat(money.getNumerator()).isEqualTo(1415L); assertThat(money.getDenominator()).isEqualTo(100L); money = new Money("125", "JPY"); assertThat(money.getNumerator()).isEqualTo(125L); assertThat(money.getDenominator()).isEqualTo(1L); } @Test public void nonMatchingCommodityFraction_shouldThrowException(){ Money money = new Money("12.345", "JPY"); assertThat(money.getNumerator()).isEqualTo(12L); assertThat(money.getDenominator()).isEqualTo(1); } @Test public void testPrinting(){ assertEquals(mMoneyInEur.asString(), mMoneyInEur.toPlainString()); assertEquals(amountString, mMoneyInEur.asString()); // the unicode for Euro symbol is \u20AC String symbol = Currency.getInstance("EUR").getSymbol(Locale.GERMANY); String actualOuputDE = mMoneyInEur.formattedString(Locale.GERMANY); assertThat(actualOuputDE).isEqualTo("15,75 " + symbol); symbol = Currency.getInstance("EUR").getSymbol(Locale.GERMANY); String actualOuputUS = mMoneyInEur.formattedString(Locale.US); assertThat(actualOuputUS).isEqualTo(symbol + "15.75"); //always prints with 2 decimal places only Money some = new Money("9.7469", CURRENCY_CODE); assertEquals("9.75", some.asString()); } public void validateImmutability(){ assertEquals(mHashcode, mMoneyInEur.hashCode()); assertEquals(amountString, mMoneyInEur.toPlainString()); assertEquals(CURRENCY_CODE, mMoneyInEur.getCommodity().getCurrencyCode()); } }