/* * Copyright 2014 Adam Mackler * * 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.bitcoinj.utils; import org.bitcoinj.core.Coin; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import java.math.BigDecimal; import java.text.*; import java.text.AttributedCharacterIterator.Attribute; import java.util.HashSet; import java.util.Locale; import java.util.Set; import static org.bitcoinj.core.Coin.*; import static org.bitcoinj.core.NetworkParameters.MAX_MONEY; import static org.bitcoinj.utils.BtcAutoFormat.Style.CODE; import static org.bitcoinj.utils.BtcAutoFormat.Style.SYMBOL; import static org.bitcoinj.utils.BtcFixedFormat.REPEATING_DOUBLETS; import static org.bitcoinj.utils.BtcFixedFormat.REPEATING_TRIPLETS; import static java.text.NumberFormat.Field.DECIMAL_SEPARATOR; import static java.util.Locale.*; import static org.junit.Assert.*; @RunWith(Parameterized.class) public class BtcFormatTest { @Parameters public static Set<Locale[]> data() { Set<Locale[]> localeSet = new HashSet<Locale[]>(); for (Locale locale : Locale.getAvailableLocales()) { localeSet.add(new Locale[]{locale}); } return localeSet; } public BtcFormatTest(Locale defaultLocale) { Locale.setDefault(defaultLocale); } @Test public void prefixTest() { // prefix b/c symbol is prefixed BtcFormat usFormat = BtcFormat.getSymbolInstance(Locale.US); assertEquals("฿1.00", usFormat.format(COIN)); assertEquals("฿1.01", usFormat.format(101000000)); assertEquals("₥฿0.01", usFormat.format(1000)); assertEquals("₥฿1,011.00", usFormat.format(101100000)); assertEquals("₥฿1,000.01", usFormat.format(100001000)); assertEquals("µ฿1,000,001.00", usFormat.format(100000100)); assertEquals("µ฿1,000,000.10", usFormat.format(100000010)); assertEquals("µ฿1,000,000.01", usFormat.format(100000001)); assertEquals("µ฿1.00", usFormat.format(100)); assertEquals("µ฿0.10", usFormat.format(10)); assertEquals("µ฿0.01", usFormat.format(1)); } @Test public void suffixTest() { BtcFormat deFormat = BtcFormat.getSymbolInstance(Locale.GERMANY); // int assertEquals("1,00 ฿", deFormat.format(100000000)); assertEquals("1,01 ฿", deFormat.format(101000000)); assertEquals("1.011,00 ₥฿", deFormat.format(101100000)); assertEquals("1.000,01 ₥฿", deFormat.format(100001000)); assertEquals("1.000.001,00 µ฿", deFormat.format(100000100)); assertEquals("1.000.000,10 µ฿", deFormat.format(100000010)); assertEquals("1.000.000,01 µ฿", deFormat.format(100000001)); } @Test public void defaultLocaleTest() { assertEquals( "Default Locale is " + Locale.getDefault().toString(), BtcFormat.getInstance().pattern(), BtcFormat.getInstance(Locale.getDefault()).pattern() ); assertEquals( "Default Locale is " + Locale.getDefault().toString(), BtcFormat.getCodeInstance().pattern(), BtcFormat.getCodeInstance(Locale.getDefault()).pattern() ); } @Test public void symbolCollisionTest() { Locale[] locales = BtcFormat.getAvailableLocales(); for (int i = 0; i < locales.length; ++i) { String cs = ((DecimalFormat)NumberFormat.getCurrencyInstance(locales[i])). getDecimalFormatSymbols().getCurrencySymbol(); if (cs.contains("฿")) { BtcFormat bf = BtcFormat.getSymbolInstance(locales[i]); String coin = bf.format(COIN); assertTrue(coin.contains("Ƀ")); assertFalse(coin.contains("฿")); String milli = bf.format(valueOf(10000)); assertTrue(milli.contains("₥Ƀ")); assertFalse(milli.contains("฿")); String micro = bf.format(valueOf(100)); assertTrue(micro.contains("µɃ")); assertFalse(micro.contains("฿")); BtcFormat ff = BtcFormat.builder().scale(0).locale(locales[i]).pattern("¤#.#").build(); assertEquals("Ƀ", ((BtcFixedFormat)ff).symbol()); assertEquals("Ƀ", ff.coinSymbol()); coin = ff.format(COIN); assertTrue(coin.contains("Ƀ")); assertFalse(coin.contains("฿")); BtcFormat mlff = BtcFormat.builder().scale(3).locale(locales[i]).pattern("¤#.#").build(); assertEquals("₥Ƀ", ((BtcFixedFormat)mlff).symbol()); assertEquals("Ƀ", mlff.coinSymbol()); milli = mlff.format(valueOf(10000)); assertTrue(milli.contains("₥Ƀ")); assertFalse(milli.contains("฿")); BtcFormat mcff = BtcFormat.builder().scale(6).locale(locales[i]).pattern("¤#.#").build(); assertEquals("µɃ", ((BtcFixedFormat)mcff).symbol()); assertEquals("Ƀ", mcff.coinSymbol()); micro = mcff.format(valueOf(100)); assertTrue(micro.contains("µɃ")); assertFalse(micro.contains("฿")); } if (cs.contains("Ƀ")) { // NB: We don't know of any such existing locale, but check anyway. BtcFormat bf = BtcFormat.getInstance(locales[i]); String coin = bf.format(COIN); assertTrue(coin.contains("฿")); assertFalse(coin.contains("Ƀ")); String milli = bf.format(valueOf(10000)); assertTrue(milli.contains("₥฿")); assertFalse(milli.contains("Ƀ")); String micro = bf.format(valueOf(100)); assertTrue(micro.contains("µ฿")); assertFalse(micro.contains("Ƀ")); } } } @Test public void argumentTypeTest() { BtcFormat usFormat = BtcFormat.getSymbolInstance(Locale.US); // longs are tested above // Coin assertEquals("µ฿1,000,000.01", usFormat.format(COIN.add(valueOf(1)))); // Integer assertEquals("µ฿21,474,836.47" ,usFormat.format(Integer.MAX_VALUE)); assertEquals("(µ฿21,474,836.48)" ,usFormat.format(Integer.MIN_VALUE)); // Long assertEquals("µ฿92,233,720,368,547,758.07" ,usFormat.format(Long.MAX_VALUE)); assertEquals("(µ฿92,233,720,368,547,758.08)" ,usFormat.format(Long.MIN_VALUE)); // BigInteger assertEquals("µ฿0.10" ,usFormat.format(java.math.BigInteger.TEN)); assertEquals("฿0.00" ,usFormat.format(java.math.BigInteger.ZERO)); // BigDecimal assertEquals("฿1.00" ,usFormat.format(java.math.BigDecimal.ONE)); assertEquals("฿0.00" ,usFormat.format(java.math.BigDecimal.ZERO)); // use of Double not encouraged but no way to stop user from converting one to BigDecimal assertEquals( "฿179,769,313,486,231,570,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000,000.00", usFormat.format(java.math.BigDecimal.valueOf(Double.MAX_VALUE))); assertEquals("฿0.00", usFormat.format(java.math.BigDecimal.valueOf(Double.MIN_VALUE))); assertEquals( "฿340,282,346,638,528,860,000,000,000,000,000,000,000.00", usFormat.format(java.math.BigDecimal.valueOf(Float.MAX_VALUE))); // Bad type try { usFormat.format("1"); fail("should not have tried to format a String"); } catch (IllegalArgumentException e) { } } @Test public void columnAlignmentTest() { BtcFormat germany = BtcFormat.getCoinInstance(2,BtcFixedFormat.REPEATING_PLACES); char separator = germany.symbols().getDecimalSeparator(); Coin[] rows = {MAX_MONEY, MAX_MONEY.subtract(SATOSHI), Coin.parseCoin("1234"), COIN, COIN.add(SATOSHI), COIN.subtract(SATOSHI), COIN.divide(1000).add(SATOSHI), COIN.divide(1000), COIN.divide(1000).subtract(SATOSHI), valueOf(100), valueOf(1000), valueOf(10000), SATOSHI}; FieldPosition fp = new FieldPosition(DECIMAL_SEPARATOR); String[] output = new String[rows.length]; int[] indexes = new int[rows.length]; int maxIndex = 0; for (int i = 0; i < rows.length; i++) { output[i] = germany.format(rows[i], new StringBuffer(), fp).toString(); indexes[i] = fp.getBeginIndex(); if (indexes[i] > maxIndex) maxIndex = indexes[i]; } for (int i = 0; i < output.length; i++) { // uncomment to watch printout // System.out.println(repeat(" ", (maxIndex - indexes[i])) + output[i]); assertEquals(output[i].indexOf(separator), indexes[i]); } } @Test public void repeatingPlaceTest() { BtcFormat mega = BtcFormat.getInstance(-6, US); Coin value = MAX_MONEY.subtract(SATOSHI); assertEquals("20.99999999999999", mega.format(value, 0, BtcFixedFormat.REPEATING_PLACES)); assertEquals("20.99999999999999", mega.format(value, 0, BtcFixedFormat.REPEATING_PLACES)); assertEquals("20.99999999999999", mega.format(value, 1, BtcFixedFormat.REPEATING_PLACES)); assertEquals("20.99999999999999", mega.format(value, 2, BtcFixedFormat.REPEATING_PLACES)); assertEquals("20.99999999999999", mega.format(value, 3, BtcFixedFormat.REPEATING_PLACES)); assertEquals("20.99999999999999", mega.format(value, 0, BtcFixedFormat.REPEATING_DOUBLETS)); assertEquals("20.99999999999999", mega.format(value, 1, BtcFixedFormat.REPEATING_DOUBLETS)); assertEquals("20.99999999999999", mega.format(value, 2, BtcFixedFormat.REPEATING_DOUBLETS)); assertEquals("20.99999999999999", mega.format(value, 3, BtcFixedFormat.REPEATING_DOUBLETS)); assertEquals("20.99999999999999", mega.format(value, 0, BtcFixedFormat.REPEATING_TRIPLETS)); assertEquals("20.99999999999999", mega.format(value, 1, BtcFixedFormat.REPEATING_TRIPLETS)); assertEquals("20.99999999999999", mega.format(value, 2, BtcFixedFormat.REPEATING_TRIPLETS)); assertEquals("20.99999999999999", mega.format(value, 3, BtcFixedFormat.REPEATING_TRIPLETS)); assertEquals("1.00000005", BtcFormat.getCoinInstance(US). format(COIN.add(Coin.valueOf(5)), 0, BtcFixedFormat.REPEATING_PLACES)); } @Test public void characterIteratorTest() { BtcFormat usFormat = BtcFormat.getInstance(Locale.US); AttributedCharacterIterator i = usFormat.formatToCharacterIterator(parseCoin("1234.5")); java.util.Set<Attribute> a = i.getAllAttributeKeys(); assertTrue("Missing currency attribute", a.contains(NumberFormat.Field.CURRENCY)); assertTrue("Missing integer attribute", a.contains(NumberFormat.Field.INTEGER)); assertTrue("Missing fraction attribute", a.contains(NumberFormat.Field.FRACTION)); assertTrue("Missing decimal separator attribute", a.contains(NumberFormat.Field.DECIMAL_SEPARATOR)); assertTrue("Missing grouping separator attribute", a.contains(NumberFormat.Field.GROUPING_SEPARATOR)); assertTrue("Missing currency attribute", a.contains(NumberFormat.Field.CURRENCY)); char c; i = BtcFormat.getCodeInstance(Locale.US).formatToCharacterIterator(new BigDecimal("0.19246362747414458")); // formatted as "µBTC 192,463.63" assertEquals(0, i.getBeginIndex()); assertEquals(15, i.getEndIndex()); int n = 0; for(c = i.first(); i.getAttribute(NumberFormat.Field.CURRENCY) != null; c = i.next()) { n++; } assertEquals(4, n); n = 0; for(i.next(); i.getAttribute(NumberFormat.Field.INTEGER) != null && i.getAttribute(NumberFormat.Field.GROUPING_SEPARATOR) != NumberFormat.Field.GROUPING_SEPARATOR; c = i.next()) { n++; } assertEquals(3, n); assertEquals(NumberFormat.Field.INTEGER, i.getAttribute(NumberFormat.Field.INTEGER)); n = 0; for(c = i.next(); i.getAttribute(NumberFormat.Field.INTEGER) != null; c = i.next()) { n++; } assertEquals(3, n); assertEquals(NumberFormat.Field.DECIMAL_SEPARATOR, i.getAttribute(NumberFormat.Field.DECIMAL_SEPARATOR)); n = 0; for(c = i.next(); c != CharacterIterator.DONE; c = i.next()) { n++; assertNotNull(i.getAttribute(NumberFormat.Field.FRACTION)); } assertEquals(2,n); // immutability check BtcFormat fa = BtcFormat.getSymbolInstance(US); BtcFormat fb = BtcFormat.getSymbolInstance(US); assertEquals(fa, fb); assertEquals(fa.hashCode(), fb.hashCode()); fa.formatToCharacterIterator(COIN.multiply(1000000)); assertEquals(fa, fb); assertEquals(fa.hashCode(), fb.hashCode()); fb.formatToCharacterIterator(COIN.divide(1000000)); assertEquals(fa, fb); assertEquals(fa.hashCode(), fb.hashCode()); } @Test public void parseTest() throws java.text.ParseException { BtcFormat us = BtcFormat.getSymbolInstance(Locale.US); BtcFormat usCoded = BtcFormat.getCodeInstance(Locale.US); // Coins assertEquals(valueOf(200000000), us.parseObject("BTC2")); assertEquals(valueOf(200000000), us.parseObject("XBT2")); assertEquals(valueOf(200000000), us.parseObject("฿2")); assertEquals(valueOf(200000000), us.parseObject("Ƀ2")); assertEquals(valueOf(200000000), us.parseObject("2")); assertEquals(valueOf(200000000), usCoded.parseObject("BTC 2")); assertEquals(valueOf(200000000), usCoded.parseObject("XBT 2")); assertEquals(valueOf(200000000), us.parseObject("฿2.0")); assertEquals(valueOf(200000000), us.parseObject("Ƀ2.0")); assertEquals(valueOf(200000000), us.parseObject("2.0")); assertEquals(valueOf(200000000), us.parseObject("BTC2.0")); assertEquals(valueOf(200000000), us.parseObject("XBT2.0")); assertEquals(valueOf(200000000), usCoded.parseObject("฿ 2")); assertEquals(valueOf(200000000), usCoded.parseObject("Ƀ 2")); assertEquals(valueOf(200000000), usCoded.parseObject(" 2")); assertEquals(valueOf(200000000), usCoded.parseObject("BTC 2")); assertEquals(valueOf(200000000), usCoded.parseObject("XBT 2")); assertEquals(valueOf(202222420000000L), us.parseObject("2,022,224.20")); assertEquals(valueOf(202222420000000L), us.parseObject("฿2,022,224.20")); assertEquals(valueOf(202222420000000L), us.parseObject("Ƀ2,022,224.20")); assertEquals(valueOf(202222420000000L), us.parseObject("BTC2,022,224.20")); assertEquals(valueOf(202222420000000L), us.parseObject("XBT2,022,224.20")); assertEquals(valueOf(220200000000L), us.parseObject("2,202.0")); assertEquals(valueOf(2100000000000000L), us.parseObject("21000000.00000000")); // MilliCoins assertEquals(valueOf(200000), usCoded.parseObject("mBTC 2")); assertEquals(valueOf(200000), usCoded.parseObject("mXBT 2")); assertEquals(valueOf(200000), usCoded.parseObject("m฿ 2")); assertEquals(valueOf(200000), usCoded.parseObject("mɃ 2")); assertEquals(valueOf(200000), us.parseObject("mBTC2")); assertEquals(valueOf(200000), us.parseObject("mXBT2")); assertEquals(valueOf(200000), us.parseObject("₥฿2")); assertEquals(valueOf(200000), us.parseObject("₥Ƀ2")); assertEquals(valueOf(200000), us.parseObject("₥2")); assertEquals(valueOf(200000), usCoded.parseObject("₥BTC 2.00")); assertEquals(valueOf(200000), usCoded.parseObject("₥XBT 2.00")); assertEquals(valueOf(200000), usCoded.parseObject("₥BTC 2")); assertEquals(valueOf(200000), usCoded.parseObject("₥XBT 2")); assertEquals(valueOf(200000), usCoded.parseObject("₥฿ 2")); assertEquals(valueOf(200000), usCoded.parseObject("₥Ƀ 2")); assertEquals(valueOf(200000), usCoded.parseObject("₥ 2")); assertEquals(valueOf(202222400000L), us.parseObject("₥฿2,022,224")); assertEquals(valueOf(202222420000L), us.parseObject("₥Ƀ2,022,224.20")); assertEquals(valueOf(202222400000L), us.parseObject("m฿2,022,224")); assertEquals(valueOf(202222420000L), us.parseObject("mɃ2,022,224.20")); assertEquals(valueOf(202222400000L), us.parseObject("₥BTC2,022,224")); assertEquals(valueOf(202222400000L), us.parseObject("₥XBT2,022,224")); assertEquals(valueOf(202222400000L), us.parseObject("mBTC2,022,224")); assertEquals(valueOf(202222400000L), us.parseObject("mXBT2,022,224")); assertEquals(valueOf(202222420000L), us.parseObject("₥2,022,224.20")); assertEquals(valueOf(202222400000L), usCoded.parseObject("₥฿ 2,022,224")); assertEquals(valueOf(202222420000L), usCoded.parseObject("₥Ƀ 2,022,224.20")); assertEquals(valueOf(202222400000L), usCoded.parseObject("m฿ 2,022,224")); assertEquals(valueOf(202222420000L), usCoded.parseObject("mɃ 2,022,224.20")); assertEquals(valueOf(202222400000L), usCoded.parseObject("₥BTC 2,022,224")); assertEquals(valueOf(202222400000L), usCoded.parseObject("₥XBT 2,022,224")); assertEquals(valueOf(202222400000L), usCoded.parseObject("mBTC 2,022,224")); assertEquals(valueOf(202222400000L), usCoded.parseObject("mXBT 2,022,224")); assertEquals(valueOf(202222420000L), usCoded.parseObject("₥ 2,022,224.20")); // Microcoins assertEquals(valueOf(435), us.parseObject("µ฿4.35")); assertEquals(valueOf(435), us.parseObject("uɃ4.35")); assertEquals(valueOf(435), us.parseObject("u฿4.35")); assertEquals(valueOf(435), us.parseObject("µɃ4.35")); assertEquals(valueOf(435), us.parseObject("uBTC4.35")); assertEquals(valueOf(435), us.parseObject("uXBT4.35")); assertEquals(valueOf(435), us.parseObject("µBTC4.35")); assertEquals(valueOf(435), us.parseObject("µXBT4.35")); assertEquals(valueOf(435), usCoded.parseObject("uBTC 4.35")); assertEquals(valueOf(435), usCoded.parseObject("uXBT 4.35")); assertEquals(valueOf(435), usCoded.parseObject("µBTC 4.35")); assertEquals(valueOf(435), usCoded.parseObject("µXBT 4.35")); // fractional satoshi; round up assertEquals(valueOf(435), us.parseObject("uBTC4.345")); assertEquals(valueOf(435), us.parseObject("uXBT4.345")); // negative with mu symbol assertEquals(valueOf(-1), usCoded.parseObject("(µ฿ 0.01)")); assertEquals(valueOf(-10), us.parseObject("(µBTC0.100)")); assertEquals(valueOf(-10), us.parseObject("(µXBT0.100)")); // Same thing with addition of custom code, symbol us = BtcFormat.builder().locale(US).style(SYMBOL).symbol("£").code("XYZ").build(); usCoded = BtcFormat.builder().locale(US).scale(0).symbol("£").code("XYZ"). pattern("¤ #,##0.00").build(); // Coins assertEquals(valueOf(200000000), us.parseObject("XYZ2")); assertEquals(valueOf(200000000), us.parseObject("BTC2")); assertEquals(valueOf(200000000), us.parseObject("XBT2")); assertEquals(valueOf(200000000), us.parseObject("£2")); assertEquals(valueOf(200000000), us.parseObject("฿2")); assertEquals(valueOf(200000000), us.parseObject("Ƀ2")); assertEquals(valueOf(200000000), us.parseObject("2")); assertEquals(valueOf(200000000), usCoded.parseObject("XYZ 2")); assertEquals(valueOf(200000000), usCoded.parseObject("BTC 2")); assertEquals(valueOf(200000000), usCoded.parseObject("XBT 2")); assertEquals(valueOf(200000000), us.parseObject("£2.0")); assertEquals(valueOf(200000000), us.parseObject("฿2.0")); assertEquals(valueOf(200000000), us.parseObject("Ƀ2.0")); assertEquals(valueOf(200000000), us.parseObject("2.0")); assertEquals(valueOf(200000000), us.parseObject("XYZ2.0")); assertEquals(valueOf(200000000), us.parseObject("BTC2.0")); assertEquals(valueOf(200000000), us.parseObject("XBT2.0")); assertEquals(valueOf(200000000), usCoded.parseObject("£ 2")); assertEquals(valueOf(200000000), usCoded.parseObject("฿ 2")); assertEquals(valueOf(200000000), usCoded.parseObject("Ƀ 2")); assertEquals(valueOf(200000000), usCoded.parseObject(" 2")); assertEquals(valueOf(200000000), usCoded.parseObject("XYZ 2")); assertEquals(valueOf(200000000), usCoded.parseObject("BTC 2")); assertEquals(valueOf(200000000), usCoded.parseObject("XBT 2")); assertEquals(valueOf(202222420000000L), us.parseObject("2,022,224.20")); assertEquals(valueOf(202222420000000L), us.parseObject("£2,022,224.20")); assertEquals(valueOf(202222420000000L), us.parseObject("฿2,022,224.20")); assertEquals(valueOf(202222420000000L), us.parseObject("Ƀ2,022,224.20")); assertEquals(valueOf(202222420000000L), us.parseObject("XYZ2,022,224.20")); assertEquals(valueOf(202222420000000L), us.parseObject("BTC2,022,224.20")); assertEquals(valueOf(202222420000000L), us.parseObject("XBT2,022,224.20")); assertEquals(valueOf(220200000000L), us.parseObject("2,202.0")); assertEquals(valueOf(2100000000000000L), us.parseObject("21000000.00000000")); // MilliCoins assertEquals(valueOf(200000), usCoded.parseObject("mXYZ 2")); assertEquals(valueOf(200000), usCoded.parseObject("mBTC 2")); assertEquals(valueOf(200000), usCoded.parseObject("mXBT 2")); assertEquals(valueOf(200000), usCoded.parseObject("m£ 2")); assertEquals(valueOf(200000), usCoded.parseObject("m฿ 2")); assertEquals(valueOf(200000), usCoded.parseObject("mɃ 2")); assertEquals(valueOf(200000), us.parseObject("mXYZ2")); assertEquals(valueOf(200000), us.parseObject("mBTC2")); assertEquals(valueOf(200000), us.parseObject("mXBT2")); assertEquals(valueOf(200000), us.parseObject("₥£2")); assertEquals(valueOf(200000), us.parseObject("₥฿2")); assertEquals(valueOf(200000), us.parseObject("₥Ƀ2")); assertEquals(valueOf(200000), us.parseObject("₥2")); assertEquals(valueOf(200000), usCoded.parseObject("₥XYZ 2.00")); assertEquals(valueOf(200000), usCoded.parseObject("₥BTC 2.00")); assertEquals(valueOf(200000), usCoded.parseObject("₥XBT 2.00")); assertEquals(valueOf(200000), usCoded.parseObject("₥XYZ 2")); assertEquals(valueOf(200000), usCoded.parseObject("₥BTC 2")); assertEquals(valueOf(200000), usCoded.parseObject("₥XBT 2")); assertEquals(valueOf(200000), usCoded.parseObject("₥£ 2")); assertEquals(valueOf(200000), usCoded.parseObject("₥฿ 2")); assertEquals(valueOf(200000), usCoded.parseObject("₥Ƀ 2")); assertEquals(valueOf(200000), usCoded.parseObject("₥ 2")); assertEquals(valueOf(202222400000L), us.parseObject("₥£2,022,224")); assertEquals(valueOf(202222400000L), us.parseObject("₥฿2,022,224")); assertEquals(valueOf(202222420000L), us.parseObject("₥Ƀ2,022,224.20")); assertEquals(valueOf(202222400000L), us.parseObject("m£2,022,224")); assertEquals(valueOf(202222400000L), us.parseObject("m฿2,022,224")); assertEquals(valueOf(202222420000L), us.parseObject("mɃ2,022,224.20")); assertEquals(valueOf(202222400000L), us.parseObject("₥XYZ2,022,224")); assertEquals(valueOf(202222400000L), us.parseObject("₥BTC2,022,224")); assertEquals(valueOf(202222400000L), us.parseObject("₥XBT2,022,224")); assertEquals(valueOf(202222400000L), us.parseObject("mXYZ2,022,224")); assertEquals(valueOf(202222400000L), us.parseObject("mBTC2,022,224")); assertEquals(valueOf(202222400000L), us.parseObject("mXBT2,022,224")); assertEquals(valueOf(202222420000L), us.parseObject("₥2,022,224.20")); assertEquals(valueOf(202222400000L), usCoded.parseObject("₥£ 2,022,224")); assertEquals(valueOf(202222400000L), usCoded.parseObject("₥฿ 2,022,224")); assertEquals(valueOf(202222420000L), usCoded.parseObject("₥Ƀ 2,022,224.20")); assertEquals(valueOf(202222400000L), usCoded.parseObject("m£ 2,022,224")); assertEquals(valueOf(202222400000L), usCoded.parseObject("m฿ 2,022,224")); assertEquals(valueOf(202222420000L), usCoded.parseObject("mɃ 2,022,224.20")); assertEquals(valueOf(202222400000L), usCoded.parseObject("₥XYZ 2,022,224")); assertEquals(valueOf(202222400000L), usCoded.parseObject("₥BTC 2,022,224")); assertEquals(valueOf(202222400000L), usCoded.parseObject("₥XBT 2,022,224")); assertEquals(valueOf(202222400000L), usCoded.parseObject("mXYZ 2,022,224")); assertEquals(valueOf(202222400000L), usCoded.parseObject("mBTC 2,022,224")); assertEquals(valueOf(202222400000L), usCoded.parseObject("mXBT 2,022,224")); assertEquals(valueOf(202222420000L), usCoded.parseObject("₥ 2,022,224.20")); // Microcoins assertEquals(valueOf(435), us.parseObject("µ£4.35")); assertEquals(valueOf(435), us.parseObject("µ฿4.35")); assertEquals(valueOf(435), us.parseObject("uɃ4.35")); assertEquals(valueOf(435), us.parseObject("u£4.35")); assertEquals(valueOf(435), us.parseObject("u฿4.35")); assertEquals(valueOf(435), us.parseObject("µɃ4.35")); assertEquals(valueOf(435), us.parseObject("uXYZ4.35")); assertEquals(valueOf(435), us.parseObject("uBTC4.35")); assertEquals(valueOf(435), us.parseObject("uXBT4.35")); assertEquals(valueOf(435), us.parseObject("µXYZ4.35")); assertEquals(valueOf(435), us.parseObject("µBTC4.35")); assertEquals(valueOf(435), us.parseObject("µXBT4.35")); assertEquals(valueOf(435), usCoded.parseObject("uXYZ 4.35")); assertEquals(valueOf(435), usCoded.parseObject("uBTC 4.35")); assertEquals(valueOf(435), usCoded.parseObject("uXBT 4.35")); assertEquals(valueOf(435), usCoded.parseObject("µXYZ 4.35")); assertEquals(valueOf(435), usCoded.parseObject("µBTC 4.35")); assertEquals(valueOf(435), usCoded.parseObject("µXBT 4.35")); // fractional satoshi; round up assertEquals(valueOf(435), us.parseObject("uXYZ4.345")); assertEquals(valueOf(435), us.parseObject("uBTC4.345")); assertEquals(valueOf(435), us.parseObject("uXBT4.345")); // negative with mu symbol assertEquals(valueOf(-1), usCoded.parseObject("µ£ -0.01")); assertEquals(valueOf(-1), usCoded.parseObject("µ฿ -0.01")); assertEquals(valueOf(-10), us.parseObject("(µXYZ0.100)")); assertEquals(valueOf(-10), us.parseObject("(µBTC0.100)")); assertEquals(valueOf(-10), us.parseObject("(µXBT0.100)")); // parse() method as opposed to parseObject try { BtcFormat.getInstance().parse("abc"); fail("bad parse must raise exception"); } catch (ParseException e) {} } @Test public void parseMetricTest() throws ParseException { BtcFormat cp = BtcFormat.getCodeInstance(Locale.US); BtcFormat sp = BtcFormat.getSymbolInstance(Locale.US); // coin assertEquals(parseCoin("1"), cp.parseObject("BTC 1.00")); assertEquals(parseCoin("1"), sp.parseObject("BTC1.00")); assertEquals(parseCoin("1"), cp.parseObject("฿ 1.00")); assertEquals(parseCoin("1"), sp.parseObject("฿1.00")); assertEquals(parseCoin("1"), cp.parseObject("B⃦ 1.00")); assertEquals(parseCoin("1"), sp.parseObject("B⃦1.00")); assertEquals(parseCoin("1"), cp.parseObject("Ƀ 1.00")); assertEquals(parseCoin("1"), sp.parseObject("Ƀ1.00")); // milli assertEquals(parseCoin("0.001"), cp.parseObject("mBTC 1.00")); assertEquals(parseCoin("0.001"), sp.parseObject("mBTC1.00")); assertEquals(parseCoin("0.001"), cp.parseObject("m฿ 1.00")); assertEquals(parseCoin("0.001"), sp.parseObject("m฿1.00")); assertEquals(parseCoin("0.001"), cp.parseObject("mB⃦ 1.00")); assertEquals(parseCoin("0.001"), sp.parseObject("mB⃦1.00")); assertEquals(parseCoin("0.001"), cp.parseObject("mɃ 1.00")); assertEquals(parseCoin("0.001"), sp.parseObject("mɃ1.00")); assertEquals(parseCoin("0.001"), cp.parseObject("₥BTC 1.00")); assertEquals(parseCoin("0.001"), sp.parseObject("₥BTC1.00")); assertEquals(parseCoin("0.001"), cp.parseObject("₥฿ 1.00")); assertEquals(parseCoin("0.001"), sp.parseObject("₥฿1.00")); assertEquals(parseCoin("0.001"), cp.parseObject("₥B⃦ 1.00")); assertEquals(parseCoin("0.001"), sp.parseObject("₥B⃦1.00")); assertEquals(parseCoin("0.001"), cp.parseObject("₥Ƀ 1.00")); assertEquals(parseCoin("0.001"), sp.parseObject("₥Ƀ1.00")); // micro assertEquals(parseCoin("0.000001"), cp.parseObject("uBTC 1.00")); assertEquals(parseCoin("0.000001"), sp.parseObject("uBTC1.00")); assertEquals(parseCoin("0.000001"), cp.parseObject("u฿ 1.00")); assertEquals(parseCoin("0.000001"), sp.parseObject("u฿1.00")); assertEquals(parseCoin("0.000001"), cp.parseObject("uB⃦ 1.00")); assertEquals(parseCoin("0.000001"), sp.parseObject("uB⃦1.00")); assertEquals(parseCoin("0.000001"), cp.parseObject("uɃ 1.00")); assertEquals(parseCoin("0.000001"), sp.parseObject("uɃ1.00")); assertEquals(parseCoin("0.000001"), cp.parseObject("µBTC 1.00")); assertEquals(parseCoin("0.000001"), sp.parseObject("µBTC1.00")); assertEquals(parseCoin("0.000001"), cp.parseObject("µ฿ 1.00")); assertEquals(parseCoin("0.000001"), sp.parseObject("µ฿1.00")); assertEquals(parseCoin("0.000001"), cp.parseObject("µB⃦ 1.00")); assertEquals(parseCoin("0.000001"), sp.parseObject("µB⃦1.00")); assertEquals(parseCoin("0.000001"), cp.parseObject("µɃ 1.00")); assertEquals(parseCoin("0.000001"), sp.parseObject("µɃ1.00")); // satoshi assertEquals(parseCoin("0.00000001"), cp.parseObject("uBTC 0.01")); assertEquals(parseCoin("0.00000001"), sp.parseObject("uBTC0.01")); assertEquals(parseCoin("0.00000001"), cp.parseObject("u฿ 0.01")); assertEquals(parseCoin("0.00000001"), sp.parseObject("u฿0.01")); assertEquals(parseCoin("0.00000001"), cp.parseObject("uB⃦ 0.01")); assertEquals(parseCoin("0.00000001"), sp.parseObject("uB⃦0.01")); assertEquals(parseCoin("0.00000001"), cp.parseObject("uɃ 0.01")); assertEquals(parseCoin("0.00000001"), sp.parseObject("uɃ0.01")); assertEquals(parseCoin("0.00000001"), cp.parseObject("µBTC 0.01")); assertEquals(parseCoin("0.00000001"), sp.parseObject("µBTC0.01")); assertEquals(parseCoin("0.00000001"), cp.parseObject("µ฿ 0.01")); assertEquals(parseCoin("0.00000001"), sp.parseObject("µ฿0.01")); assertEquals(parseCoin("0.00000001"), cp.parseObject("µB⃦ 0.01")); assertEquals(parseCoin("0.00000001"), sp.parseObject("µB⃦0.01")); assertEquals(parseCoin("0.00000001"), cp.parseObject("µɃ 0.01")); assertEquals(parseCoin("0.00000001"), sp.parseObject("µɃ0.01")); // cents assertEquals(parseCoin("0.01234567"), cp.parseObject("cBTC 1.234567")); assertEquals(parseCoin("0.01234567"), sp.parseObject("cBTC1.234567")); assertEquals(parseCoin("0.01234567"), cp.parseObject("c฿ 1.234567")); assertEquals(parseCoin("0.01234567"), sp.parseObject("c฿1.234567")); assertEquals(parseCoin("0.01234567"), cp.parseObject("cB⃦ 1.234567")); assertEquals(parseCoin("0.01234567"), sp.parseObject("cB⃦1.234567")); assertEquals(parseCoin("0.01234567"), cp.parseObject("cɃ 1.234567")); assertEquals(parseCoin("0.01234567"), sp.parseObject("cɃ1.234567")); assertEquals(parseCoin("0.01234567"), cp.parseObject("¢BTC 1.234567")); assertEquals(parseCoin("0.01234567"), sp.parseObject("¢BTC1.234567")); assertEquals(parseCoin("0.01234567"), cp.parseObject("¢฿ 1.234567")); assertEquals(parseCoin("0.01234567"), sp.parseObject("¢฿1.234567")); assertEquals(parseCoin("0.01234567"), cp.parseObject("¢B⃦ 1.234567")); assertEquals(parseCoin("0.01234567"), sp.parseObject("¢B⃦1.234567")); assertEquals(parseCoin("0.01234567"), cp.parseObject("¢Ƀ 1.234567")); assertEquals(parseCoin("0.01234567"), sp.parseObject("¢Ƀ1.234567")); // dekacoins assertEquals(parseCoin("12.34567"), cp.parseObject("daBTC 1.234567")); assertEquals(parseCoin("12.34567"), sp.parseObject("daBTC1.234567")); assertEquals(parseCoin("12.34567"), cp.parseObject("da฿ 1.234567")); assertEquals(parseCoin("12.34567"), sp.parseObject("da฿1.234567")); assertEquals(parseCoin("12.34567"), cp.parseObject("daB⃦ 1.234567")); assertEquals(parseCoin("12.34567"), sp.parseObject("daB⃦1.234567")); assertEquals(parseCoin("12.34567"), cp.parseObject("daɃ 1.234567")); assertEquals(parseCoin("12.34567"), sp.parseObject("daɃ1.234567")); // hectocoins assertEquals(parseCoin("123.4567"), cp.parseObject("hBTC 1.234567")); assertEquals(parseCoin("123.4567"), sp.parseObject("hBTC1.234567")); assertEquals(parseCoin("123.4567"), cp.parseObject("h฿ 1.234567")); assertEquals(parseCoin("123.4567"), sp.parseObject("h฿1.234567")); assertEquals(parseCoin("123.4567"), cp.parseObject("hB⃦ 1.234567")); assertEquals(parseCoin("123.4567"), sp.parseObject("hB⃦1.234567")); assertEquals(parseCoin("123.4567"), cp.parseObject("hɃ 1.234567")); assertEquals(parseCoin("123.4567"), sp.parseObject("hɃ1.234567")); // kilocoins assertEquals(parseCoin("1234.567"), cp.parseObject("kBTC 1.234567")); assertEquals(parseCoin("1234.567"), sp.parseObject("kBTC1.234567")); assertEquals(parseCoin("1234.567"), cp.parseObject("k฿ 1.234567")); assertEquals(parseCoin("1234.567"), sp.parseObject("k฿1.234567")); assertEquals(parseCoin("1234.567"), cp.parseObject("kB⃦ 1.234567")); assertEquals(parseCoin("1234.567"), sp.parseObject("kB⃦1.234567")); assertEquals(parseCoin("1234.567"), cp.parseObject("kɃ 1.234567")); assertEquals(parseCoin("1234.567"), sp.parseObject("kɃ1.234567")); // megacoins assertEquals(parseCoin("1234567"), cp.parseObject("MBTC 1.234567")); assertEquals(parseCoin("1234567"), sp.parseObject("MBTC1.234567")); assertEquals(parseCoin("1234567"), cp.parseObject("M฿ 1.234567")); assertEquals(parseCoin("1234567"), sp.parseObject("M฿1.234567")); assertEquals(parseCoin("1234567"), cp.parseObject("MB⃦ 1.234567")); assertEquals(parseCoin("1234567"), sp.parseObject("MB⃦1.234567")); assertEquals(parseCoin("1234567"), cp.parseObject("MɃ 1.234567")); assertEquals(parseCoin("1234567"), sp.parseObject("MɃ1.234567")); } @Test public void parsePositionTest() { BtcFormat usCoded = BtcFormat.getCodeInstance(Locale.US); // Test the field constants FieldPosition intField = new FieldPosition(NumberFormat.Field.INTEGER); assertEquals( "987,654,321", usCoded.format(valueOf(98765432123L), new StringBuffer(), intField). substring(intField.getBeginIndex(), intField.getEndIndex()) ); FieldPosition fracField = new FieldPosition(NumberFormat.Field.FRACTION); assertEquals( "23", usCoded.format(valueOf(98765432123L), new StringBuffer(), fracField). substring(fracField.getBeginIndex(), fracField.getEndIndex()) ); // for currency we use a locale that puts the units at the end BtcFormat de = BtcFormat.getSymbolInstance(Locale.GERMANY); BtcFormat deCoded = BtcFormat.getCodeInstance(Locale.GERMANY); FieldPosition currField = new FieldPosition(NumberFormat.Field.CURRENCY); assertEquals( "µ฿", de.format(valueOf(98765432123L), new StringBuffer(), currField). substring(currField.getBeginIndex(), currField.getEndIndex()) ); assertEquals( "µBTC", deCoded.format(valueOf(98765432123L), new StringBuffer(), currField). substring(currField.getBeginIndex(), currField.getEndIndex()) ); assertEquals( "₥฿", de.format(valueOf(98765432000L), new StringBuffer(), currField). substring(currField.getBeginIndex(), currField.getEndIndex()) ); assertEquals( "mBTC", deCoded.format(valueOf(98765432000L), new StringBuffer(), currField). substring(currField.getBeginIndex(), currField.getEndIndex()) ); assertEquals( "฿", de.format(valueOf(98765000000L), new StringBuffer(), currField). substring(currField.getBeginIndex(), currField.getEndIndex()) ); assertEquals( "BTC", deCoded.format(valueOf(98765000000L), new StringBuffer(), currField). substring(currField.getBeginIndex(), currField.getEndIndex()) ); } @Test public void currencyCodeTest() { /* Insert needed space AFTER currency-code */ BtcFormat usCoded = BtcFormat.getCodeInstance(Locale.US); assertEquals("µBTC 0.01", usCoded.format(1)); assertEquals("BTC 1.00", usCoded.format(COIN)); /* Do not insert unneeded space BEFORE currency-code */ BtcFormat frCoded = BtcFormat.getCodeInstance(Locale.FRANCE); assertEquals("0,01 µBTC", frCoded.format(1)); assertEquals("1,00 BTC", frCoded.format(COIN)); /* Insert needed space BEFORE currency-code: no known currency pattern does this? */ /* Do not insert unneeded space AFTER currency-code */ BtcFormat deCoded = BtcFormat.getCodeInstance(Locale.ITALY); assertEquals("µBTC 0,01", deCoded.format(1)); assertEquals("BTC 1,00", deCoded.format(COIN)); } @Test public void coinScaleTest() throws Exception { BtcFormat coinFormat = BtcFormat.getCoinInstance(Locale.US); assertEquals("1.00", coinFormat.format(Coin.COIN)); assertEquals("-1.00", coinFormat.format(Coin.COIN.negate())); assertEquals(Coin.parseCoin("1"), coinFormat.parseObject("1.00")); assertEquals(valueOf(1000000), coinFormat.parseObject("0.01")); assertEquals(Coin.parseCoin("1000"), coinFormat.parseObject("1,000.00")); assertEquals(Coin.parseCoin("1000"), coinFormat.parseObject("1000")); } @Test public void millicoinScaleTest() throws Exception { BtcFormat coinFormat = BtcFormat.getMilliInstance(Locale.US); assertEquals("1,000.00", coinFormat.format(Coin.COIN)); assertEquals("-1,000.00", coinFormat.format(Coin.COIN.negate())); assertEquals(Coin.parseCoin("0.001"), coinFormat.parseObject("1.00")); assertEquals(valueOf(1000), coinFormat.parseObject("0.01")); assertEquals(Coin.parseCoin("1"), coinFormat.parseObject("1,000.00")); assertEquals(Coin.parseCoin("1"), coinFormat.parseObject("1000")); } @Test public void microcoinScaleTest() throws Exception { BtcFormat coinFormat = BtcFormat.getMicroInstance(Locale.US); assertEquals("1,000,000.00", coinFormat.format(Coin.COIN)); assertEquals("-1,000,000.00", coinFormat.format(Coin.COIN.negate())); assertEquals("1,000,000.10", coinFormat.format(Coin.COIN.add(valueOf(10)))); assertEquals(Coin.parseCoin("0.000001"), coinFormat.parseObject("1.00")); assertEquals(valueOf(1), coinFormat.parseObject("0.01")); assertEquals(Coin.parseCoin("0.001"), coinFormat.parseObject("1,000.00")); assertEquals(Coin.parseCoin("0.001"), coinFormat.parseObject("1000")); } @Test public void testGrouping() throws Exception { BtcFormat usCoin = BtcFormat.getInstance(0, Locale.US, 1, 2, 3); assertEquals("0.1", usCoin.format(Coin.parseCoin("0.1"))); assertEquals("0.010", usCoin.format(Coin.parseCoin("0.01"))); assertEquals("0.001", usCoin.format(Coin.parseCoin("0.001"))); assertEquals("0.000100", usCoin.format(Coin.parseCoin("0.0001"))); assertEquals("0.000010", usCoin.format(Coin.parseCoin("0.00001"))); assertEquals("0.000001", usCoin.format(Coin.parseCoin("0.000001"))); // no more than two fractional decimal places for the default coin-denomination assertEquals("0.01", BtcFormat.getCoinInstance(Locale.US).format(Coin.parseCoin("0.005"))); BtcFormat usMilli = BtcFormat.getInstance(3, Locale.US, 1, 2, 3); assertEquals("0.1", usMilli.format(Coin.parseCoin("0.0001"))); assertEquals("0.010", usMilli.format(Coin.parseCoin("0.00001"))); assertEquals("0.001", usMilli.format(Coin.parseCoin("0.000001"))); // even though last group is 3, that would result in fractional satoshis, which we don't do assertEquals("0.00010", usMilli.format(Coin.valueOf(10))); assertEquals("0.00001", usMilli.format(Coin.valueOf(1))); BtcFormat usMicro = BtcFormat.getInstance(6, Locale.US, 1, 2, 3); assertEquals("0.1", usMicro.format(Coin.valueOf(10))); // even though second group is 2, that would result in fractional satoshis, which we don't do assertEquals("0.01", usMicro.format(Coin.valueOf(1))); } /* These just make sure factory methods don't raise exceptions. * Other tests inspect their return values. */ @Test public void factoryTest() { BtcFormat coded = BtcFormat.getInstance(0, 1, 2, 3); BtcFormat.getInstance(BtcAutoFormat.Style.CODE); BtcAutoFormat symbolic = (BtcAutoFormat)BtcFormat.getInstance(BtcAutoFormat.Style.SYMBOL); assertEquals(2, symbolic.fractionPlaces()); BtcFormat.getInstance(BtcAutoFormat.Style.CODE, 3); assertEquals(3, ((BtcAutoFormat)BtcFormat.getInstance(BtcAutoFormat.Style.SYMBOL, 3)).fractionPlaces()); BtcFormat.getInstance(BtcAutoFormat.Style.SYMBOL, Locale.US, 3); BtcFormat.getInstance(BtcAutoFormat.Style.CODE, Locale.US); BtcFormat.getInstance(BtcAutoFormat.Style.SYMBOL, Locale.US); BtcFormat.getCoinInstance(2, BtcFixedFormat.REPEATING_PLACES); BtcFormat.getMilliInstance(1, 2, 3); BtcFormat.getInstance(2); BtcFormat.getInstance(2, Locale.US); BtcFormat.getCodeInstance(3); BtcFormat.getSymbolInstance(3); BtcFormat.getCodeInstance(Locale.US, 3); BtcFormat.getSymbolInstance(Locale.US, 3); try { BtcFormat.getInstance(SMALLEST_UNIT_EXPONENT + 1); fail("should not have constructed an instance with denomination less than satoshi"); } catch (IllegalArgumentException e) {} } @Test public void factoryArgumentsTest() { Locale locale; if (Locale.getDefault().equals(GERMANY)) locale = FRANCE; else locale = GERMANY; assertEquals(BtcFormat.getInstance(), BtcFormat.getCodeInstance()); assertEquals(BtcFormat.getInstance(locale), BtcFormat.getCodeInstance(locale)); assertEquals(BtcFormat.getInstance(BtcAutoFormat.Style.CODE), BtcFormat.getCodeInstance()); assertEquals(BtcFormat.getInstance(BtcAutoFormat.Style.SYMBOL), BtcFormat.getSymbolInstance()); assertEquals(BtcFormat.getInstance(BtcAutoFormat.Style.CODE,3), BtcFormat.getCodeInstance(3)); assertEquals(BtcFormat.getInstance(BtcAutoFormat.Style.SYMBOL,3), BtcFormat.getSymbolInstance(3)); assertEquals(BtcFormat.getInstance(BtcAutoFormat.Style.CODE,locale), BtcFormat.getCodeInstance(locale)); assertEquals(BtcFormat.getInstance(BtcAutoFormat.Style.SYMBOL,locale), BtcFormat.getSymbolInstance(locale)); assertEquals(BtcFormat.getInstance(BtcAutoFormat.Style.CODE,locale,3), BtcFormat.getCodeInstance(locale,3)); assertEquals(BtcFormat.getInstance(BtcAutoFormat.Style.SYMBOL,locale,3), BtcFormat.getSymbolInstance(locale,3)); assertEquals(BtcFormat.getCoinInstance(), BtcFormat.getInstance(0)); assertEquals(BtcFormat.getMilliInstance(), BtcFormat.getInstance(3)); assertEquals(BtcFormat.getMicroInstance(), BtcFormat.getInstance(6)); assertEquals(BtcFormat.getCoinInstance(3), BtcFormat.getInstance(0,3)); assertEquals(BtcFormat.getMilliInstance(3), BtcFormat.getInstance(3,3)); assertEquals(BtcFormat.getMicroInstance(3), BtcFormat.getInstance(6,3)); assertEquals(BtcFormat.getCoinInstance(3,4,5), BtcFormat.getInstance(0,3,4,5)); assertEquals(BtcFormat.getMilliInstance(3,4,5), BtcFormat.getInstance(3,3,4,5)); assertEquals(BtcFormat.getMicroInstance(3,4,5), BtcFormat.getInstance(6,3,4,5)); assertEquals(BtcFormat.getCoinInstance(locale), BtcFormat.getInstance(0,locale)); assertEquals(BtcFormat.getMilliInstance(locale), BtcFormat.getInstance(3,locale)); assertEquals(BtcFormat.getMicroInstance(locale), BtcFormat.getInstance(6,locale)); assertEquals(BtcFormat.getCoinInstance(locale,4,5), BtcFormat.getInstance(0,locale,4,5)); assertEquals(BtcFormat.getMilliInstance(locale,4,5), BtcFormat.getInstance(3,locale,4,5)); assertEquals(BtcFormat.getMicroInstance(locale,4,5), BtcFormat.getInstance(6,locale,4,5)); } @Test public void autoDecimalTest() { BtcFormat codedZero = BtcFormat.getCodeInstance(Locale.US, 0); BtcFormat symbolZero = BtcFormat.getSymbolInstance(Locale.US, 0); assertEquals("฿1", symbolZero.format(COIN)); assertEquals("BTC 1", codedZero.format(COIN)); assertEquals("µ฿1,000,000", symbolZero.format(COIN.subtract(SATOSHI))); assertEquals("µBTC 1,000,000", codedZero.format(COIN.subtract(SATOSHI))); assertEquals("µ฿1,000,000", symbolZero.format(COIN.subtract(Coin.valueOf(50)))); assertEquals("µBTC 1,000,000", codedZero.format(COIN.subtract(Coin.valueOf(50)))); assertEquals("µ฿999,999", symbolZero.format(COIN.subtract(Coin.valueOf(51)))); assertEquals("µBTC 999,999", codedZero.format(COIN.subtract(Coin.valueOf(51)))); assertEquals("฿1,000", symbolZero.format(COIN.multiply(1000))); assertEquals("BTC 1,000", codedZero.format(COIN.multiply(1000))); assertEquals("µ฿1", symbolZero.format(Coin.valueOf(100))); assertEquals("µBTC 1", codedZero.format(Coin.valueOf(100))); assertEquals("µ฿1", symbolZero.format(Coin.valueOf(50))); assertEquals("µBTC 1", codedZero.format(Coin.valueOf(50))); assertEquals("µ฿0", symbolZero.format(Coin.valueOf(49))); assertEquals("µBTC 0", codedZero.format(Coin.valueOf(49))); assertEquals("µ฿0", symbolZero.format(Coin.valueOf(1))); assertEquals("µBTC 0", codedZero.format(Coin.valueOf(1))); assertEquals("µ฿500,000", symbolZero.format(Coin.valueOf(49999999))); assertEquals("µBTC 500,000", codedZero.format(Coin.valueOf(49999999))); assertEquals("µ฿499,500", symbolZero.format(Coin.valueOf(49950000))); assertEquals("µBTC 499,500", codedZero.format(Coin.valueOf(49950000))); assertEquals("µ฿499,500", symbolZero.format(Coin.valueOf(49949999))); assertEquals("µBTC 499,500", codedZero.format(Coin.valueOf(49949999))); assertEquals("µ฿500,490", symbolZero.format(Coin.valueOf(50049000))); assertEquals("µBTC 500,490", codedZero.format(Coin.valueOf(50049000))); assertEquals("µ฿500,490", symbolZero.format(Coin.valueOf(50049001))); assertEquals("µBTC 500,490", codedZero.format(Coin.valueOf(50049001))); assertEquals("µ฿500,000", symbolZero.format(Coin.valueOf(49999950))); assertEquals("µBTC 500,000", codedZero.format(Coin.valueOf(49999950))); assertEquals("µ฿499,999", symbolZero.format(Coin.valueOf(49999949))); assertEquals("µBTC 499,999", codedZero.format(Coin.valueOf(49999949))); assertEquals("µ฿500,000", symbolZero.format(Coin.valueOf(50000049))); assertEquals("µBTC 500,000", codedZero.format(Coin.valueOf(50000049))); assertEquals("µ฿500,001", symbolZero.format(Coin.valueOf(50000050))); assertEquals("µBTC 500,001", codedZero.format(Coin.valueOf(50000050))); BtcFormat codedTwo = BtcFormat.getCodeInstance(Locale.US, 2); BtcFormat symbolTwo = BtcFormat.getSymbolInstance(Locale.US, 2); assertEquals("฿1.00", symbolTwo.format(COIN)); assertEquals("BTC 1.00", codedTwo.format(COIN)); assertEquals("µ฿999,999.99", symbolTwo.format(COIN.subtract(SATOSHI))); assertEquals("µBTC 999,999.99", codedTwo.format(COIN.subtract(SATOSHI))); assertEquals("฿1,000.00", symbolTwo.format(COIN.multiply(1000))); assertEquals("BTC 1,000.00", codedTwo.format(COIN.multiply(1000))); assertEquals("µ฿1.00", symbolTwo.format(Coin.valueOf(100))); assertEquals("µBTC 1.00", codedTwo.format(Coin.valueOf(100))); assertEquals("µ฿0.50", symbolTwo.format(Coin.valueOf(50))); assertEquals("µBTC 0.50", codedTwo.format(Coin.valueOf(50))); assertEquals("µ฿0.49", symbolTwo.format(Coin.valueOf(49))); assertEquals("µBTC 0.49", codedTwo.format(Coin.valueOf(49))); assertEquals("µ฿0.01", symbolTwo.format(Coin.valueOf(1))); assertEquals("µBTC 0.01", codedTwo.format(Coin.valueOf(1))); BtcFormat codedThree = BtcFormat.getCodeInstance(Locale.US, 3); BtcFormat symbolThree = BtcFormat.getSymbolInstance(Locale.US, 3); assertEquals("฿1.000", symbolThree.format(COIN)); assertEquals("BTC 1.000", codedThree.format(COIN)); assertEquals("µ฿999,999.99", symbolThree.format(COIN.subtract(SATOSHI))); assertEquals("µBTC 999,999.99", codedThree.format(COIN.subtract(SATOSHI))); assertEquals("฿1,000.000", symbolThree.format(COIN.multiply(1000))); assertEquals("BTC 1,000.000", codedThree.format(COIN.multiply(1000))); assertEquals("₥฿0.001", symbolThree.format(Coin.valueOf(100))); assertEquals("mBTC 0.001", codedThree.format(Coin.valueOf(100))); assertEquals("µ฿0.50", symbolThree.format(Coin.valueOf(50))); assertEquals("µBTC 0.50", codedThree.format(Coin.valueOf(50))); assertEquals("µ฿0.49", symbolThree.format(Coin.valueOf(49))); assertEquals("µBTC 0.49", codedThree.format(Coin.valueOf(49))); assertEquals("µ฿0.01", symbolThree.format(Coin.valueOf(1))); assertEquals("µBTC 0.01", codedThree.format(Coin.valueOf(1))); } @Test public void symbolsCodesTest() { BtcFixedFormat coin = (BtcFixedFormat)BtcFormat.getCoinInstance(US); assertEquals("BTC", coin.code()); assertEquals("฿", coin.symbol()); BtcFixedFormat cent = (BtcFixedFormat)BtcFormat.getInstance(2, US); assertEquals("cBTC", cent.code()); assertEquals("¢฿", cent.symbol()); BtcFixedFormat milli = (BtcFixedFormat)BtcFormat.getInstance(3, US); assertEquals("mBTC", milli.code()); assertEquals("₥฿", milli.symbol()); BtcFixedFormat micro = (BtcFixedFormat)BtcFormat.getInstance(6, US); assertEquals("µBTC", micro.code()); assertEquals("µ฿", micro.symbol()); BtcFixedFormat deka = (BtcFixedFormat)BtcFormat.getInstance(-1, US); assertEquals("daBTC", deka.code()); assertEquals("da฿", deka.symbol()); BtcFixedFormat hecto = (BtcFixedFormat)BtcFormat.getInstance(-2, US); assertEquals("hBTC", hecto.code()); assertEquals("h฿", hecto.symbol()); BtcFixedFormat kilo = (BtcFixedFormat)BtcFormat.getInstance(-3, US); assertEquals("kBTC", kilo.code()); assertEquals("k฿", kilo.symbol()); BtcFixedFormat mega = (BtcFixedFormat)BtcFormat.getInstance(-6, US); assertEquals("MBTC", mega.code()); assertEquals("M฿", mega.symbol()); BtcFixedFormat noSymbol = (BtcFixedFormat)BtcFormat.getInstance(4, US); try { noSymbol.symbol(); fail("non-standard denomination has no symbol()"); } catch (IllegalStateException e) {} try { noSymbol.code(); fail("non-standard denomination has no code()"); } catch (IllegalStateException e) {} BtcFixedFormat symbolCoin = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(0). symbol("B\u20e6").build(); assertEquals("BTC", symbolCoin.code()); assertEquals("B⃦", symbolCoin.symbol()); BtcFixedFormat symbolCent = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(2). symbol("B\u20e6").build(); assertEquals("cBTC", symbolCent.code()); assertEquals("¢B⃦", symbolCent.symbol()); BtcFixedFormat symbolMilli = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(3). symbol("B\u20e6").build(); assertEquals("mBTC", symbolMilli.code()); assertEquals("₥B⃦", symbolMilli.symbol()); BtcFixedFormat symbolMicro = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(6). symbol("B\u20e6").build(); assertEquals("µBTC", symbolMicro.code()); assertEquals("µB⃦", symbolMicro.symbol()); BtcFixedFormat symbolDeka = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(-1). symbol("B\u20e6").build(); assertEquals("daBTC", symbolDeka.code()); assertEquals("daB⃦", symbolDeka.symbol()); BtcFixedFormat symbolHecto = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(-2). symbol("B\u20e6").build(); assertEquals("hBTC", symbolHecto.code()); assertEquals("hB⃦", symbolHecto.symbol()); BtcFixedFormat symbolKilo = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(-3). symbol("B\u20e6").build(); assertEquals("kBTC", symbolKilo.code()); assertEquals("kB⃦", symbolKilo.symbol()); BtcFixedFormat symbolMega = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(-6). symbol("B\u20e6").build(); assertEquals("MBTC", symbolMega.code()); assertEquals("MB⃦", symbolMega.symbol()); BtcFixedFormat codeCoin = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(0). code("XBT").build(); assertEquals("XBT", codeCoin.code()); assertEquals("฿", codeCoin.symbol()); BtcFixedFormat codeCent = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(2). code("XBT").build(); assertEquals("cXBT", codeCent.code()); assertEquals("¢฿", codeCent.symbol()); BtcFixedFormat codeMilli = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(3). code("XBT").build(); assertEquals("mXBT", codeMilli.code()); assertEquals("₥฿", codeMilli.symbol()); BtcFixedFormat codeMicro = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(6). code("XBT").build(); assertEquals("µXBT", codeMicro.code()); assertEquals("µ฿", codeMicro.symbol()); BtcFixedFormat codeDeka = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(-1). code("XBT").build(); assertEquals("daXBT", codeDeka.code()); assertEquals("da฿", codeDeka.symbol()); BtcFixedFormat codeHecto = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(-2). code("XBT").build(); assertEquals("hXBT", codeHecto.code()); assertEquals("h฿", codeHecto.symbol()); BtcFixedFormat codeKilo = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(-3). code("XBT").build(); assertEquals("kXBT", codeKilo.code()); assertEquals("k฿", codeKilo.symbol()); BtcFixedFormat codeMega = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(-6). code("XBT").build(); assertEquals("MXBT", codeMega.code()); assertEquals("M฿", codeMega.symbol()); BtcFixedFormat symbolCodeCoin = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(0). symbol("B\u20e6").code("XBT").build(); assertEquals("XBT", symbolCodeCoin.code()); assertEquals("B⃦", symbolCodeCoin.symbol()); BtcFixedFormat symbolCodeCent = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(2). symbol("B\u20e6").code("XBT").build(); assertEquals("cXBT", symbolCodeCent.code()); assertEquals("¢B⃦", symbolCodeCent.symbol()); BtcFixedFormat symbolCodeMilli = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(3). symbol("B\u20e6").code("XBT").build(); assertEquals("mXBT", symbolCodeMilli.code()); assertEquals("₥B⃦", symbolCodeMilli.symbol()); BtcFixedFormat symbolCodeMicro = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(6). symbol("B\u20e6").code("XBT").build(); assertEquals("µXBT", symbolCodeMicro.code()); assertEquals("µB⃦", symbolCodeMicro.symbol()); BtcFixedFormat symbolCodeDeka = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(-1). symbol("B\u20e6").code("XBT").build(); assertEquals("daXBT", symbolCodeDeka.code()); assertEquals("daB⃦", symbolCodeDeka.symbol()); BtcFixedFormat symbolCodeHecto = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(-2). symbol("B\u20e6").code("XBT").build(); assertEquals("hXBT", symbolCodeHecto.code()); assertEquals("hB⃦", symbolCodeHecto.symbol()); BtcFixedFormat symbolCodeKilo = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(-3). symbol("B\u20e6").code("XBT").build(); assertEquals("kXBT", symbolCodeKilo.code()); assertEquals("kB⃦", symbolCodeKilo.symbol()); BtcFixedFormat symbolCodeMega = (BtcFixedFormat)BtcFormat.builder().locale(US).scale(-6). symbol("B\u20e6").code("XBT").build(); assertEquals("MXBT", symbolCodeMega.code()); assertEquals("MB⃦", symbolCodeMega.symbol()); } /* copied from CoinFormatTest.java and modified */ @Test public void parse() throws Exception { BtcFormat coin = BtcFormat.getCoinInstance(Locale.US); assertEquals(Coin.COIN, coin.parseObject("1")); assertEquals(Coin.COIN, coin.parseObject("1.")); assertEquals(Coin.COIN, coin.parseObject("1.0")); assertEquals(Coin.COIN, BtcFormat.getCoinInstance(Locale.GERMANY).parseObject("1,0")); assertEquals(Coin.COIN, coin.parseObject("01.0000000000")); // TODO work with express positive sign // assertEquals(Coin.COIN, coin.parseObject("+1.0")); assertEquals(Coin.COIN.negate(), coin.parseObject("-1")); assertEquals(Coin.COIN.negate(), coin.parseObject("-1.0")); assertEquals(Coin.CENT, coin.parseObject(".01")); BtcFormat milli = BtcFormat.getMilliInstance(Locale.US); assertEquals(Coin.MILLICOIN, milli.parseObject("1")); assertEquals(Coin.MILLICOIN, milli.parseObject("1.0")); assertEquals(Coin.MILLICOIN, milli.parseObject("01.0000000000")); // TODO work with express positive sign //assertEquals(Coin.MILLICOIN, milli.parseObject("+1.0")); assertEquals(Coin.MILLICOIN.negate(), milli.parseObject("-1")); assertEquals(Coin.MILLICOIN.negate(), milli.parseObject("-1.0")); BtcFormat micro = BtcFormat.getMicroInstance(Locale.US); assertEquals(Coin.MICROCOIN, micro.parseObject("1")); assertEquals(Coin.MICROCOIN, micro.parseObject("1.0")); assertEquals(Coin.MICROCOIN, micro.parseObject("01.0000000000")); // TODO work with express positive sign // assertEquals(Coin.MICROCOIN, micro.parseObject("+1.0")); assertEquals(Coin.MICROCOIN.negate(), micro.parseObject("-1")); assertEquals(Coin.MICROCOIN.negate(), micro.parseObject("-1.0")); } /* Copied (and modified) from CoinFormatTest.java */ @Test public void btcRounding() throws Exception { BtcFormat coinFormat = BtcFormat.getCoinInstance(Locale.US); assertEquals("0", BtcFormat.getCoinInstance(Locale.US, 0).format(ZERO)); assertEquals("0", coinFormat.format(ZERO, 0)); assertEquals("0.00", BtcFormat.getCoinInstance(Locale.US, 2).format(ZERO)); assertEquals("0.00", coinFormat.format(ZERO, 2)); assertEquals("1", BtcFormat.getCoinInstance(Locale.US, 0).format(COIN)); assertEquals("1", coinFormat.format(COIN, 0)); assertEquals("1.0", BtcFormat.getCoinInstance(Locale.US, 1).format(COIN)); assertEquals("1.0", coinFormat.format(COIN, 1)); assertEquals("1.00", BtcFormat.getCoinInstance(Locale.US, 2, 2).format(COIN)); assertEquals("1.00", coinFormat.format(COIN, 2, 2)); assertEquals("1.00", BtcFormat.getCoinInstance(Locale.US, 2, 2, 2).format(COIN)); assertEquals("1.00", coinFormat.format(COIN, 2, 2, 2)); assertEquals("1.00", BtcFormat.getCoinInstance(Locale.US, 2, 2, 2, 2).format(COIN)); assertEquals("1.00", coinFormat.format(COIN, 2, 2, 2, 2)); assertEquals("1.000", BtcFormat.getCoinInstance(Locale.US, 3).format(COIN)); assertEquals("1.000", coinFormat.format(COIN, 3)); assertEquals("1.0000", BtcFormat.getCoinInstance(US, 4).format(COIN)); assertEquals("1.0000", coinFormat.format(COIN, 4)); final Coin justNot = COIN.subtract(SATOSHI); assertEquals("1", BtcFormat.getCoinInstance(US, 0).format(justNot)); assertEquals("1", coinFormat.format(justNot, 0)); assertEquals("1.0", BtcFormat.getCoinInstance(US, 1).format(justNot)); assertEquals("1.0", coinFormat.format(justNot, 1)); final Coin justNotUnder = Coin.valueOf(99995000); assertEquals("1.00", BtcFormat.getCoinInstance(US, 2, 2).format(justNot)); assertEquals("1.00", coinFormat.format(justNot, 2, 2)); assertEquals("1.00", BtcFormat.getCoinInstance(US, 2, 2).format(justNotUnder)); assertEquals("1.00", coinFormat.format(justNotUnder, 2, 2)); assertEquals("1.00", BtcFormat.getCoinInstance(US, 2, 2, 2).format(justNot)); assertEquals("1.00", coinFormat.format(justNot, 2, 2, 2)); assertEquals("0.999950", BtcFormat.getCoinInstance(US, 2, 2, 2).format(justNotUnder)); assertEquals("0.999950", coinFormat.format(justNotUnder, 2, 2, 2)); assertEquals("0.99999999", BtcFormat.getCoinInstance(US, 2, 2, 2, 2).format(justNot)); assertEquals("0.99999999", coinFormat.format(justNot, 2, 2, 2, 2)); assertEquals("0.99999999", BtcFormat.getCoinInstance(US, 2, REPEATING_DOUBLETS).format(justNot)); assertEquals("0.99999999", coinFormat.format(justNot, 2, REPEATING_DOUBLETS)); assertEquals("0.999950", BtcFormat.getCoinInstance(US, 2, 2, 2, 2).format(justNotUnder)); assertEquals("0.999950", coinFormat.format(justNotUnder, 2, 2, 2, 2)); assertEquals("0.999950", BtcFormat.getCoinInstance(US, 2, REPEATING_DOUBLETS).format(justNotUnder)); assertEquals("0.999950", coinFormat.format(justNotUnder, 2, REPEATING_DOUBLETS)); assertEquals("1.000", BtcFormat.getCoinInstance(US, 3).format(justNot)); assertEquals("1.000", coinFormat.format(justNot, 3)); assertEquals("1.0000", BtcFormat.getCoinInstance(US, 4).format(justNot)); assertEquals("1.0000", coinFormat.format(justNot, 4)); final Coin slightlyMore = COIN.add(SATOSHI); assertEquals("1", BtcFormat.getCoinInstance(US, 0).format(slightlyMore)); assertEquals("1", coinFormat.format(slightlyMore, 0)); assertEquals("1.0", BtcFormat.getCoinInstance(US, 1).format(slightlyMore)); assertEquals("1.0", coinFormat.format(slightlyMore, 1)); assertEquals("1.00", BtcFormat.getCoinInstance(US, 2, 2).format(slightlyMore)); assertEquals("1.00", coinFormat.format(slightlyMore, 2, 2)); assertEquals("1.00", BtcFormat.getCoinInstance(US, 2, 2, 2).format(slightlyMore)); assertEquals("1.00", coinFormat.format(slightlyMore, 2, 2, 2)); assertEquals("1.00000001", BtcFormat.getCoinInstance(US, 2, 2, 2, 2).format(slightlyMore)); assertEquals("1.00000001", coinFormat.format(slightlyMore, 2, 2, 2, 2)); assertEquals("1.00000001", BtcFormat.getCoinInstance(US, 2, REPEATING_DOUBLETS).format(slightlyMore)); assertEquals("1.00000001", coinFormat.format(slightlyMore, 2, REPEATING_DOUBLETS)); assertEquals("1.000", BtcFormat.getCoinInstance(US, 3).format(slightlyMore)); assertEquals("1.000", coinFormat.format(slightlyMore, 3)); assertEquals("1.0000", BtcFormat.getCoinInstance(US, 4).format(slightlyMore)); assertEquals("1.0000", coinFormat.format(slightlyMore, 4)); final Coin pivot = COIN.add(SATOSHI.multiply(5)); assertEquals("1.00000005", BtcFormat.getCoinInstance(US, 8).format(pivot)); assertEquals("1.00000005", coinFormat.format(pivot, 8)); assertEquals("1.00000005", BtcFormat.getCoinInstance(US, 7, 1).format(pivot)); assertEquals("1.00000005", coinFormat.format(pivot, 7, 1)); assertEquals("1.0000001", BtcFormat.getCoinInstance(US, 7).format(pivot)); assertEquals("1.0000001", coinFormat.format(pivot, 7)); final Coin value = Coin.valueOf(1122334455667788l); assertEquals("11,223,345", BtcFormat.getCoinInstance(US, 0).format(value)); assertEquals("11,223,345", coinFormat.format(value, 0)); assertEquals("11,223,344.6", BtcFormat.getCoinInstance(US, 1).format(value)); assertEquals("11,223,344.6", coinFormat.format(value, 1)); assertEquals("11,223,344.5567", BtcFormat.getCoinInstance(US, 2, 2).format(value)); assertEquals("11,223,344.5567", coinFormat.format(value, 2, 2)); assertEquals("11,223,344.556678", BtcFormat.getCoinInstance(US, 2, 2, 2).format(value)); assertEquals("11,223,344.556678", coinFormat.format(value, 2, 2, 2)); assertEquals("11,223,344.55667788", BtcFormat.getCoinInstance(US, 2, 2, 2, 2).format(value)); assertEquals("11,223,344.55667788", coinFormat.format(value, 2, 2, 2, 2)); assertEquals("11,223,344.55667788", BtcFormat.getCoinInstance(US, 2, REPEATING_DOUBLETS).format(value)); assertEquals("11,223,344.55667788", coinFormat.format(value, 2, REPEATING_DOUBLETS)); assertEquals("11,223,344.557", BtcFormat.getCoinInstance(US, 3).format(value)); assertEquals("11,223,344.557", coinFormat.format(value, 3)); assertEquals("11,223,344.5567", BtcFormat.getCoinInstance(US, 4).format(value)); assertEquals("11,223,344.5567", coinFormat.format(value, 4)); BtcFormat megaFormat = BtcFormat.getInstance(-6, US); assertEquals("21.00", megaFormat.format(MAX_MONEY)); assertEquals("21", megaFormat.format(MAX_MONEY, 0)); assertEquals("11.22334455667788", megaFormat.format(value, 0, REPEATING_DOUBLETS)); assertEquals("11.223344556677", megaFormat.format(Coin.valueOf(1122334455667700l), 0, REPEATING_DOUBLETS)); assertEquals("11.22334455667788", megaFormat.format(value, 0, REPEATING_TRIPLETS)); assertEquals("11.223344556677", megaFormat.format(Coin.valueOf(1122334455667700l), 0, REPEATING_TRIPLETS)); } @Test public void negativeTest() throws Exception { assertEquals("-1,00 BTC", BtcFormat.getInstance(FRANCE).format(COIN.multiply(-1))); assertEquals("BTC -1,00", BtcFormat.getInstance(ITALY).format(COIN.multiply(-1))); assertEquals("฿ -1,00", BtcFormat.getSymbolInstance(ITALY).format(COIN.multiply(-1))); assertEquals("BTC -1.00", BtcFormat.getInstance(JAPAN).format(COIN.multiply(-1))); assertEquals("฿-1.00", BtcFormat.getSymbolInstance(JAPAN).format(COIN.multiply(-1))); assertEquals("(BTC 1.00)", BtcFormat.getInstance(US).format(COIN.multiply(-1))); assertEquals("(฿1.00)", BtcFormat.getSymbolInstance(US).format(COIN.multiply(-1))); // assertEquals("BTC -१.००", BtcFormat.getInstance(Locale.forLanguageTag("hi-IN")).format(COIN.multiply(-1))); assertEquals("BTC -๑.๐๐", BtcFormat.getInstance(new Locale("th","TH","TH")).format(COIN.multiply(-1))); assertEquals("Ƀ-๑.๐๐", BtcFormat.getSymbolInstance(new Locale("th","TH","TH")).format(COIN.multiply(-1))); } /* Warning: these tests assume the state of Locale data extant on the platform on which * they were written: openjdk 7u21-2.3.9-5 */ @Test public void equalityTest() throws Exception { // First, autodenominator assertEquals(BtcFormat.getInstance(), BtcFormat.getInstance()); assertEquals(BtcFormat.getInstance().hashCode(), BtcFormat.getInstance().hashCode()); assertNotEquals(BtcFormat.getCodeInstance(), BtcFormat.getSymbolInstance()); assertNotEquals(BtcFormat.getCodeInstance().hashCode(), BtcFormat.getSymbolInstance().hashCode()); assertEquals(BtcFormat.getSymbolInstance(5), BtcFormat.getSymbolInstance(5)); assertEquals(BtcFormat.getSymbolInstance(5).hashCode(), BtcFormat.getSymbolInstance(5).hashCode()); assertNotEquals(BtcFormat.getSymbolInstance(5), BtcFormat.getSymbolInstance(4)); assertNotEquals(BtcFormat.getSymbolInstance(5).hashCode(), BtcFormat.getSymbolInstance(4).hashCode()); /* The underlying formatter is mutable, and its currency code * and symbol may be reset each time a number is * formatted or parsed. Here we check to make sure that state is * ignored when comparing for equality */ // when formatting BtcAutoFormat a = (BtcAutoFormat)BtcFormat.getSymbolInstance(US); BtcAutoFormat b = (BtcAutoFormat)BtcFormat.getSymbolInstance(US); assertEquals(a, b); assertEquals(a.hashCode(), b.hashCode()); a.format(COIN.multiply(1000000)); assertEquals(a, b); assertEquals(a.hashCode(), b.hashCode()); b.format(COIN.divide(1000000)); assertEquals(a, b); assertEquals(a.hashCode(), b.hashCode()); // when parsing a = (BtcAutoFormat)BtcFormat.getSymbolInstance(US); b = (BtcAutoFormat)BtcFormat.getSymbolInstance(US); assertEquals(a, b); assertEquals(a.hashCode(), b.hashCode()); a.parseObject("mBTC2"); assertEquals(a, b); assertEquals(a.hashCode(), b.hashCode()); b.parseObject("µ฿4.35"); assertEquals(a, b); assertEquals(a.hashCode(), b.hashCode()); // FRANCE and GERMANY have different pattterns assertNotEquals(BtcFormat.getInstance(FRANCE).hashCode(), BtcFormat.getInstance(GERMANY).hashCode()); // TAIWAN and CHINA differ only in the Locale and Currency, i.e. the patterns and symbols are // all the same (after setting the currency symbols to bitcoins) assertNotEquals(BtcFormat.getInstance(TAIWAN), BtcFormat.getInstance(CHINA)); // but they hash the same because of the DecimalFormatSymbols.hashCode() implementation assertEquals(BtcFormat.getSymbolInstance(4), BtcFormat.getSymbolInstance(4)); assertEquals(BtcFormat.getSymbolInstance(4).hashCode(), BtcFormat.getSymbolInstance(4).hashCode()); assertNotEquals(BtcFormat.getSymbolInstance(4), BtcFormat.getSymbolInstance(5)); assertNotEquals(BtcFormat.getSymbolInstance(4).hashCode(), BtcFormat.getSymbolInstance(5).hashCode()); // Fixed-denomination assertEquals(BtcFormat.getCoinInstance(), BtcFormat.getCoinInstance()); assertEquals(BtcFormat.getCoinInstance().hashCode(), BtcFormat.getCoinInstance().hashCode()); assertEquals(BtcFormat.getMilliInstance(), BtcFormat.getMilliInstance()); assertEquals(BtcFormat.getMilliInstance().hashCode(), BtcFormat.getMilliInstance().hashCode()); assertEquals(BtcFormat.getMicroInstance(), BtcFormat.getMicroInstance()); assertEquals(BtcFormat.getMicroInstance().hashCode(), BtcFormat.getMicroInstance().hashCode()); assertEquals(BtcFormat.getInstance(-6), BtcFormat.getInstance(-6)); assertEquals(BtcFormat.getInstance(-6).hashCode(), BtcFormat.getInstance(-6).hashCode()); assertNotEquals(BtcFormat.getCoinInstance(), BtcFormat.getMilliInstance()); assertNotEquals(BtcFormat.getCoinInstance().hashCode(), BtcFormat.getMilliInstance().hashCode()); assertNotEquals(BtcFormat.getCoinInstance(), BtcFormat.getMicroInstance()); assertNotEquals(BtcFormat.getCoinInstance().hashCode(), BtcFormat.getMicroInstance().hashCode()); assertNotEquals(BtcFormat.getMilliInstance(), BtcFormat.getMicroInstance()); assertNotEquals(BtcFormat.getMilliInstance().hashCode(), BtcFormat.getMicroInstance().hashCode()); assertNotEquals(BtcFormat.getInstance(SMALLEST_UNIT_EXPONENT), BtcFormat.getInstance(SMALLEST_UNIT_EXPONENT - 1)); assertNotEquals(BtcFormat.getInstance(SMALLEST_UNIT_EXPONENT).hashCode(), BtcFormat.getInstance(SMALLEST_UNIT_EXPONENT - 1).hashCode()); assertNotEquals(BtcFormat.getCoinInstance(TAIWAN), BtcFormat.getCoinInstance(CHINA)); assertNotEquals(BtcFormat.getCoinInstance(2,3), BtcFormat.getCoinInstance(2,4)); assertNotEquals(BtcFormat.getCoinInstance(2,3).hashCode(), BtcFormat.getCoinInstance(2,4).hashCode()); assertNotEquals(BtcFormat.getCoinInstance(2,3), BtcFormat.getCoinInstance(2,3,3)); assertNotEquals(BtcFormat.getCoinInstance(2,3).hashCode(), BtcFormat.getCoinInstance(2,3,3).hashCode()); } @Test public void attributeTest() throws Exception { String codePat = BtcFormat.getCodeInstance(Locale.US).pattern(); assertTrue(codePat.contains("BTC") && ! codePat.contains("(^|[^฿])฿([^฿]|$)") && ! codePat.contains("(^|[^¤])¤([^¤]|$)")); String symPat = BtcFormat.getSymbolInstance(Locale.US).pattern(); assertTrue(symPat.contains("฿") && !symPat.contains("BTC") && !symPat.contains("¤¤")); assertEquals("BTC #,##0.00;(BTC #,##0.00)", BtcFormat.getCodeInstance(Locale.US).pattern()); assertEquals("฿#,##0.00;(฿#,##0.00)", BtcFormat.getSymbolInstance(Locale.US).pattern()); assertEquals('0', BtcFormat.getInstance(Locale.US).symbols().getZeroDigit()); // assertEquals('०', BtcFormat.getInstance(Locale.forLanguageTag("hi-IN")).symbols().getZeroDigit()); // TODO will this next line work with other JREs? assertEquals('๐', BtcFormat.getInstance(new Locale("th","TH","TH")).symbols().getZeroDigit()); } @Test public void toStringTest() { assertEquals("Auto-format ฿#,##0.00;(฿#,##0.00)", BtcFormat.getSymbolInstance(Locale.US).toString()); assertEquals("Auto-format ฿#,##0.0000;(฿#,##0.0000)", BtcFormat.getSymbolInstance(Locale.US, 4).toString()); assertEquals("Auto-format BTC #,##0.00;(BTC #,##0.00)", BtcFormat.getCodeInstance(Locale.US).toString()); assertEquals("Auto-format BTC #,##0.0000;(BTC #,##0.0000)", BtcFormat.getCodeInstance(Locale.US, 4).toString()); assertEquals("Coin-format #,##0.00", BtcFormat.getCoinInstance(Locale.US).toString()); assertEquals("Millicoin-format #,##0.00", BtcFormat.getMilliInstance(Locale.US).toString()); assertEquals("Microcoin-format #,##0.00", BtcFormat.getMicroInstance(Locale.US).toString()); assertEquals("Coin-format #,##0.000", BtcFormat.getCoinInstance(Locale.US,3).toString()); assertEquals("Coin-format #,##0.000(####)(#######)", BtcFormat.getCoinInstance(Locale.US,3,4,7).toString()); assertEquals("Kilocoin-format #,##0.000", BtcFormat.getInstance(-3,Locale.US,3).toString()); assertEquals("Kilocoin-format #,##0.000(####)(#######)", BtcFormat.getInstance(-3,Locale.US,3,4,7).toString()); assertEquals("Decicoin-format #,##0.000", BtcFormat.getInstance(1,Locale.US,3).toString()); assertEquals("Decicoin-format #,##0.000(####)(#######)", BtcFormat.getInstance(1,Locale.US,3,4,7).toString()); assertEquals("Dekacoin-format #,##0.000", BtcFormat.getInstance(-1,Locale.US,3).toString()); assertEquals("Dekacoin-format #,##0.000(####)(#######)", BtcFormat.getInstance(-1,Locale.US,3,4,7).toString()); assertEquals("Hectocoin-format #,##0.000", BtcFormat.getInstance(-2,Locale.US,3).toString()); assertEquals("Hectocoin-format #,##0.000(####)(#######)", BtcFormat.getInstance(-2,Locale.US,3,4,7).toString()); assertEquals("Megacoin-format #,##0.000", BtcFormat.getInstance(-6,Locale.US,3).toString()); assertEquals("Megacoin-format #,##0.000(####)(#######)", BtcFormat.getInstance(-6,Locale.US,3,4,7).toString()); assertEquals("Fixed (-4) format #,##0.000", BtcFormat.getInstance(-4,Locale.US,3).toString()); assertEquals("Fixed (-4) format #,##0.000(####)", BtcFormat.getInstance(-4,Locale.US,3,4).toString()); assertEquals("Fixed (-4) format #,##0.000(####)(#######)", BtcFormat.getInstance(-4, Locale.US, 3, 4, 7).toString()); assertEquals("Auto-format ฿#,##0.00;(฿#,##0.00)", BtcFormat.builder().style(SYMBOL).code("USD").locale(US).build().toString()); assertEquals("Auto-format #.##0,00 $", BtcFormat.builder().style(SYMBOL).symbol("$").locale(GERMANY).build().toString()); assertEquals("Auto-format #.##0,0000 $", BtcFormat.builder().style(SYMBOL).symbol("$").fractionDigits(4).locale(GERMANY).build().toString()); assertEquals("Auto-format BTC#,00฿;BTC-#,00฿", BtcFormat.builder().style(SYMBOL).locale(GERMANY).pattern("¤¤#¤").build().toString()); assertEquals("Coin-format BTC#,00฿;BTC-#,00฿", BtcFormat.builder().scale(0).locale(GERMANY).pattern("¤¤#¤").build().toString()); assertEquals("Millicoin-format BTC#.00฿;BTC-#.00฿", BtcFormat.builder().scale(3).locale(US).pattern("¤¤#¤").build().toString()); } @Test public void patternDecimalPlaces() { /* The pattern format provided by DecimalFormat includes specification of fractional digits, * but we ignore that because we have alternative mechanism for specifying that.. */ BtcFormat f = BtcFormat.builder().locale(US).scale(3).pattern("¤¤ #.0").fractionDigits(3).build(); assertEquals("Millicoin-format BTC #.000;BTC -#.000", f.toString()); assertEquals("mBTC 1000.000", f.format(COIN)); } @Test public void builderTest() { Locale locale; if (Locale.getDefault().equals(GERMANY)) locale = FRANCE; else locale = GERMANY; assertEquals(BtcFormat.builder().build(), BtcFormat.getCoinInstance()); try { BtcFormat.builder().scale(0).style(CODE); fail("Invoking both scale() and style() on a Builder should raise exception"); } catch (IllegalStateException e) {} try { BtcFormat.builder().style(CODE).scale(0); fail("Invoking both style() and scale() on a Builder should raise exception"); } catch (IllegalStateException e) {} BtcFormat built = BtcFormat.builder().style(BtcAutoFormat.Style.CODE).fractionDigits(4).build(); assertEquals(built, BtcFormat.getCodeInstance(4)); built = BtcFormat.builder().style(BtcAutoFormat.Style.SYMBOL).fractionDigits(4).build(); assertEquals(built, BtcFormat.getSymbolInstance(4)); built = BtcFormat.builder().scale(0).build(); assertEquals(built, BtcFormat.getCoinInstance()); built = BtcFormat.builder().scale(3).build(); assertEquals(built, BtcFormat.getMilliInstance()); built = BtcFormat.builder().scale(6).build(); assertEquals(built, BtcFormat.getMicroInstance()); built = BtcFormat.builder().locale(locale).scale(0).build(); assertEquals(built, BtcFormat.getCoinInstance(locale)); built = BtcFormat.builder().locale(locale).scale(3).build(); assertEquals(built, BtcFormat.getMilliInstance(locale)); built = BtcFormat.builder().locale(locale).scale(6).build(); assertEquals(built, BtcFormat.getMicroInstance(locale)); built = BtcFormat.builder().minimumFractionDigits(3).scale(0).build(); assertEquals(built, BtcFormat.getCoinInstance(3)); built = BtcFormat.builder().minimumFractionDigits(3).scale(3).build(); assertEquals(built, BtcFormat.getMilliInstance(3)); built = BtcFormat.builder().minimumFractionDigits(3).scale(6).build(); assertEquals(built, BtcFormat.getMicroInstance(3)); built = BtcFormat.builder().fractionGroups(3,4).scale(0).build(); assertEquals(built, BtcFormat.getCoinInstance(2,3,4)); built = BtcFormat.builder().fractionGroups(3,4).scale(3).build(); assertEquals(built, BtcFormat.getMilliInstance(2,3,4)); built = BtcFormat.builder().fractionGroups(3,4).scale(6).build(); assertEquals(built, BtcFormat.getMicroInstance(2,3,4)); built = BtcFormat.builder().pattern("#,####.#").scale(6).locale(GERMANY).build(); assertEquals("100.0000,00", built.format(COIN)); built = BtcFormat.builder().pattern("#,####.#").scale(6).locale(GERMANY).build(); assertEquals("-100.0000,00", built.format(COIN.multiply(-1))); built = BtcFormat.builder().localizedPattern("#.####,#").scale(6).locale(GERMANY).build(); assertEquals("100.0000,00", built.format(COIN)); built = BtcFormat.builder().pattern("¤#,####.#").style(CODE).locale(GERMANY).build(); assertEquals("฿-1,00", built.format(COIN.multiply(-1))); built = BtcFormat.builder().pattern("¤¤ #,####.#").style(SYMBOL).locale(GERMANY).build(); assertEquals("BTC -1,00", built.format(COIN.multiply(-1))); built = BtcFormat.builder().pattern("¤¤##,###.#").scale(3).locale(US).build(); assertEquals("mBTC1,000.00", built.format(COIN)); built = BtcFormat.builder().pattern("¤ ##,###.#").scale(3).locale(US).build(); assertEquals("₥฿ 1,000.00", built.format(COIN)); try { BtcFormat.builder().pattern("¤¤##,###.#").scale(4).locale(US).build().format(COIN); fail("Pattern with currency sign and non-standard denomination should raise exception"); } catch (IllegalStateException e) {} try { BtcFormat.builder().localizedPattern("¤¤##,###.#").scale(4).locale(US).build().format(COIN); fail("Localized pattern with currency sign and non-standard denomination should raise exception"); } catch (IllegalStateException e) {} built = BtcFormat.builder().style(SYMBOL).symbol("B\u20e6").locale(US).build(); assertEquals("B⃦1.00", built.format(COIN)); built = BtcFormat.builder().style(CODE).code("XBT").locale(US).build(); assertEquals("XBT 1.00", built.format(COIN)); built = BtcFormat.builder().style(SYMBOL).symbol("$").locale(GERMANY).build(); assertEquals("1,00 $", built.format(COIN)); // Setting the currency code on a DecimalFormatSymbols object can affect the currency symbol. built = BtcFormat.builder().style(SYMBOL).code("USD").locale(US).build(); assertEquals("฿1.00", built.format(COIN)); built = BtcFormat.builder().style(SYMBOL).symbol("B\u20e6").locale(US).build(); assertEquals("₥B⃦1.00", built.format(COIN.divide(1000))); built = BtcFormat.builder().style(CODE).code("XBT").locale(US).build(); assertEquals("mXBT 1.00", built.format(COIN.divide(1000))); built = BtcFormat.builder().style(SYMBOL).symbol("B\u20e6").locale(US).build(); assertEquals("µB⃦1.00", built.format(valueOf(100))); built = BtcFormat.builder().style(CODE).code("XBT").locale(US).build(); assertEquals("µXBT 1.00", built.format(valueOf(100))); /* The prefix of a pattern can have number symbols in quotes. * Make sure our custom negative-subpattern creator handles this. */ built = BtcFormat.builder().pattern("'#'¤#0").scale(0).locale(US).build(); assertEquals("#฿-1.00", built.format(COIN.multiply(-1))); built = BtcFormat.builder().pattern("'#0'¤#0").scale(0).locale(US).build(); assertEquals("#0฿-1.00", built.format(COIN.multiply(-1))); // this is an escaped quote between two hash marks in one set of quotes, not // two adjacent quote-enclosed hash-marks: built = BtcFormat.builder().pattern("'#''#'¤#0").scale(0).locale(US).build(); assertEquals("#'#฿-1.00", built.format(COIN.multiply(-1))); built = BtcFormat.builder().pattern("'#0''#'¤#0").scale(0).locale(US).build(); assertEquals("#0'#฿-1.00", built.format(COIN.multiply(-1))); built = BtcFormat.builder().pattern("'#0#'¤#0").scale(0).locale(US).build(); assertEquals("#0#฿-1.00", built.format(COIN.multiply(-1))); built = BtcFormat.builder().pattern("'#0'E'#'¤#0").scale(0).locale(US).build(); assertEquals("#0E#฿-1.00", built.format(COIN.multiply(-1))); built = BtcFormat.builder().pattern("E'#0''#'¤#0").scale(0).locale(US).build(); assertEquals("E#0'#฿-1.00", built.format(COIN.multiply(-1))); built = BtcFormat.builder().pattern("E'#0#'¤#0").scale(0).locale(US).build(); assertEquals("E#0#฿-1.00", built.format(COIN.multiply(-1))); built = BtcFormat.builder().pattern("E'#0''''#'¤#0").scale(0).locale(US).build(); assertEquals("E#0''#฿-1.00", built.format(COIN.multiply(-1))); built = BtcFormat.builder().pattern("''#0").scale(0).locale(US).build(); assertEquals("'-1.00", built.format(COIN.multiply(-1))); // immutability check for fixed-denomination formatters, w/ & w/o custom pattern BtcFormat a = BtcFormat.builder().scale(3).build(); BtcFormat b = BtcFormat.builder().scale(3).build(); assertEquals(a, b); assertEquals(a.hashCode(), b.hashCode()); a.format(COIN.multiply(1000000)); assertEquals(a, b); assertEquals(a.hashCode(), b.hashCode()); b.format(COIN.divide(1000000)); assertEquals(a, b); assertEquals(a.hashCode(), b.hashCode()); a = BtcFormat.builder().scale(3).pattern("¤#.#").build(); b = BtcFormat.builder().scale(3).pattern("¤#.#").build(); assertEquals(a, b); assertEquals(a.hashCode(), b.hashCode()); a.format(COIN.multiply(1000000)); assertEquals(a, b); assertEquals(a.hashCode(), b.hashCode()); b.format(COIN.divide(1000000)); assertEquals(a, b); assertEquals(a.hashCode(), b.hashCode()); } }