@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("AXE -1,00", built.format(COIN.multiply(-1)));
    built = BtcFormat.builder().pattern("¤¤##,###.#").scale(3).locale(US).build();
    assertEquals("mAXE1,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("D\u20e6").locale(US).build();
    assertEquals("D⃦1.00", built.format(COIN));
    built = BtcFormat.builder().style(CODE).code("XDC").locale(US).build();
    assertEquals("XDC 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("D\u20e6").locale(US).build();
    assertEquals("₥D⃦1.00", built.format(COIN.divide(1000)));
    built = BtcFormat.builder().style(CODE).code("XDC").locale(US).build();
    assertEquals("mXDC 1.00", built.format(COIN.divide(1000)));
    built = BtcFormat.builder().style(SYMBOL).symbol("D\u20e6").locale(US).build();
    assertEquals("µD⃦1.00", built.format(valueOf(100)));
    built = BtcFormat.builder().style(CODE).code("XDC").locale(US).build();
    assertEquals("µXDC 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());
}