Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,14 @@ public void parse(ParseContext context)
break;
case SYMBOL:
if (token.startsWith("$")) {
throw new MonetaryParseException("$ is not a unique currency symbol.", token,
context.getErrorIndex());
CurrencyUnit fixed = this.context.get(CurrencyUnit.class);
String symbol = fixed == null ? "" : getCurrencySymbol(fixed);
if (symbol.isEmpty() || !token.startsWith(symbol)) {
throw new MonetaryParseException("$ is not a unique currency symbol.", token,
context.getErrorIndex());
}
cur = fixed;
context.consume(symbol);
} else if (token.startsWith("€")) {
cur = Monetary.getCurrency("EUR", providers);
context.consume('€');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,11 @@

import org.javamoney.moneta.CurrencyUnitBuilder;
import org.javamoney.moneta.FastMoney;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import javax.money.CurrencyUnit;
import javax.money.Monetary;
import javax.money.format.AmountFormatContextBuilder;
import javax.money.format.MonetaryParseException;
import java.io.IOException;
Expand Down Expand Up @@ -92,6 +94,65 @@ public void testParse_SYMBOL_ambiguous_dollar() {
assertEquals(context.getErrorMessage(), "$ is not a unique currency symbol.");
}

@DataProvider
public Object[][] explicitDollarCurrencies() {
return new Object[][] {
{US, Monetary.getCurrency("USD"), "$", "$"},
{US, Monetary.getCurrency("USD"), "$1000.00", "$"},
{CANADA, Monetary.getCurrency("CAD"), "$1000.00", "$"},
{new Locale("en", "AU"), Monetary.getCurrency("AUD"), "$1000.00", "$"},
{FRANCE, Monetary.getCurrency("USD"), "$US1000,00", "$US"},
{US, CurrencyUnitBuilder.of("USD", "configured").build(), "$1000.00", "$"}
};
}

@Test(dataProvider = "explicitDollarCurrencies")
public void testParse_SYMBOL_explicit_dollar(Locale locale, CurrencyUnit currency, String input, String symbol) {
CurrencyToken token = new CurrencyToken(SYMBOL,
AmountFormatContextBuilder.of(locale).set(CurrencyUnit.class, currency).build());
ParseContext context = new ParseContext(input);
token.parse(context);
assertSame(context.getParsedCurrency(), currency);
assertEquals(context.getIndex(), symbol.length());
assertFalse(context.hasError());
assertEquals(context.isFullyParsed(), input.equals(symbol));
if (!context.isFullyParsed()) {
assertEquals(context.lookupNextToken(), input.substring(symbol.length()));
}
}

@DataProvider
public Object[][] ambiguousDollarCurrencies() {
return new Object[][] {
{US, null, "$1000.00"},
{US, Monetary.getCurrency("EUR"), "$1000.00"},
{FRANCE, Monetary.getCurrency("USD"), "$1000,00"},
{FRANCE, Monetary.getCurrency("USD"), "$U1000,00"}
};
}

@Test(dataProvider = "ambiguousDollarCurrencies")
public void testParse_SYMBOL_dollar_requires_matching_currency(Locale locale, CurrencyUnit currency, String input) {
AmountFormatContextBuilder builder = AmountFormatContextBuilder.of(locale);
if (currency != null) {
builder.set(CurrencyUnit.class, currency);
}
CurrencyToken token = new CurrencyToken(SYMBOL, builder.build());
ParseContext context = new ParseContext(input);
try {
token.parse(context);
fail("Expected ambiguous dollar input to be rejected");
} catch (MonetaryParseException e) {
assertEquals(e.getInput(), input);
assertEquals(e.getErrorIndex(), -1);
assertEquals(e.getMessage(), "$ is not a unique currency symbol.");
}
assertEquals(context.getIndex(), 0);
assertFalse(context.isComplete());
assertTrue(context.hasError());
assertEquals(context.getErrorMessage(), "$ is not a unique currency symbol.");
}

@Test
public void testParse_NUMERIC_CODE() {
CurrencyToken token = new CurrencyToken(NUMERIC_CODE, AmountFormatContextBuilder.of(FRANCE).build());
Expand Down Expand Up @@ -311,4 +372,4 @@ public void testToString() {
CurrencyToken token = new CurrencyToken(CODE, AmountFormatContextBuilder.of(FRANCE).build());
assertEquals(token.toString(), "CurrencyToken [locale=fr_FR, style=CODE]");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
package org.javamoney.moneta.spi.format;

import org.javamoney.moneta.FastMoney;
import org.javamoney.moneta.format.CurrencyStyle;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import javax.money.*;
Expand Down Expand Up @@ -87,6 +89,54 @@ public void testParse() {
assertEquals(parsedAmount.toString(), "USD 1000.42");
}

@DataProvider
public Object[][] explicitDollarAmounts() {
return new Object[][] {
{US, "USD", "$1000", 1000D},
{US, "USD", "$1000.00", 1000D},
{US, "USD", "$0.01", 0.01D},
{US, "USD", "$-1000.00", -1000D},
{Locale.CANADA, "CAD", "$1000.00", 1000D},
{new Locale("en", "AU"), "AUD", "$1000.00", 1000D}
};
}

@Test(dataProvider = "explicitDollarAmounts")
public void testParse_with_explicit_dollar_currency(Locale locale, String code, String input, double number) {
CurrencyUnit currency = Monetary.getCurrency(code);
MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(AmountFormatQueryBuilder.of(locale)
.set(CurrencyStyle.SYMBOL).set(CurrencyUnit.class, currency).build());
MonetaryAmount parsedAmount = format.parse(input);
assertSame(parsedAmount.getCurrency(), currency);
assertEquals(parsedAmount.getNumber().doubleValueExact(), number);
}

@Test
public void testParse_with_localised_explicit_dollar_currency() {
CurrencyUnit usd = Monetary.getCurrency("USD");
MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(AmountFormatQueryBuilder.of(Locale.FRANCE)
.set(CurrencyStyle.SYMBOL).set(CurrencyUnit.class, usd).set("pattern", "¤#,##0.00").build());
MonetaryAmount parsedAmount = format.parse("$US1000,00");
assertSame(parsedAmount.getCurrency(), usd);
assertEquals(parsedAmount.getNumber().doubleValueExact(), 1000D);
}

@Test
public void testParse_explicit_currency_remains_a_fallback() {
MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(AmountFormatQueryBuilder.of(US)
.set(CurrencyStyle.SYMBOL).set(CurrencyUnit.class, Monetary.getCurrency("USD")).build());
MonetaryAmount parsedAmount = format.parse("€1000.00");
assertEquals(parsedAmount.getCurrency().getCurrencyCode(), "EUR");
assertEquals(parsedAmount.getNumber().doubleValueExact(), 1000D);
}

@Test(expectedExceptions = MonetaryParseException.class)
public void testParse_dollar_without_explicit_currency() {
MonetaryAmountFormat format = MonetaryFormats.getAmountFormat(AmountFormatQueryBuilder.of(US)
.set(CurrencyStyle.SYMBOL).build());
format.parse("$1000.00");
}

@Test
public void testParse_with_custom_pattern() {
AmountFormatContextBuilder builder = AmountFormatContextBuilder.of(US);
Expand Down Expand Up @@ -206,4 +256,4 @@ public void testParseDifferentStyles() {
}
}
}
}
}