Skip to content

Commit

Permalink
Merge pull request #6 from allegro/feature/english-support
Browse files Browse the repository at this point in the history
Feature/english support
  • Loading branch information
dorians committed Jul 14, 2015
2 parents 44e8b40 + 88db5f4 commit 2a14bd6
Show file tree
Hide file tree
Showing 19 changed files with 311 additions and 31 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Expand Up @@ -11,4 +11,10 @@ First release. Added support for:

Added support for:

- Czech
- Czech

## 0.3.0 (2015-07-14)

Added support for:

- Czech
11 changes: 6 additions & 5 deletions README.md
Expand Up @@ -20,6 +20,7 @@ Features
Supported languages
-------------------

* English
* Polish
* Czech

Expand All @@ -34,24 +35,24 @@ repositories {
}
dependencies {
compile 'pl.allegro.finance:tradukisto:0.2.0'
compile 'pl.allegro.finance:tradukisto:0.3.0'
}
```

and use it:

```java
ValueConverter converter = ValueConverters.POLISH_INTEGER;
ValueConverter converter = ValueConverters.ENGLISH_INTEGER;
String valueAsWords = converter.asWords(1_234);

assertEquals("jeden tysiąc dwieście trzydzieści cztery", valueAsWords);
assertEquals("one thousand two hundred thirty-four", valueAsWords);
```

```java
MoneyConverter converter = MoneyConverters.POLISH_BANKING_MONEY_VALUE;
MoneyConverter converter = MoneyConverters.ENGLISH_BANKING_MONEY_VALUE;
String moneyAsWords = converter.asWords(new BigDecimal("1234.56"));

assertEquals("jeden tysiąc dwieście trzydzieści cztery PLN 56/100", moneyAsWords);
assertEquals("one thousand two hundred thirty-four £ 56/100", moneyAsWords);
```

Tradukisto can handle only values with no more than two digits after the decimal point. Otherwise
Expand Down
Expand Up @@ -6,12 +6,14 @@

import static com.google.common.base.Verify.verifyNotNull;
import static pl.allegro.finance.tradukisto.internal.Container.czechContainer;
import static pl.allegro.finance.tradukisto.internal.Container.englishContainer;
import static pl.allegro.finance.tradukisto.internal.Container.polishContainer;

public enum MoneyConverters {

POLISH_BANKING_MONEY_VALUE(polishContainer().getBankingMoneyConverter()),
CZECH_BANKING_MONEY_VALUE(czechContainer().getBankingMoneyConverter());
CZECH_BANKING_MONEY_VALUE(czechContainer().getBankingMoneyConverter()),
ENGLISH_BANKING_MONEY_VALUE(englishContainer().getBankingMoneyConverter());

private BigDecimalToStringConverter converter;

Expand Down
Expand Up @@ -4,12 +4,14 @@

import static com.google.common.base.Verify.verifyNotNull;
import static pl.allegro.finance.tradukisto.internal.Container.czechContainer;
import static pl.allegro.finance.tradukisto.internal.Container.englishContainer;
import static pl.allegro.finance.tradukisto.internal.Container.polishContainer;

public enum ValueConverters {

POLISH_INTEGER(polishContainer().getNumbersConverter()),
CZECH_INTEGER(czechContainer().getNumbersConverter());
CZECH_INTEGER(czechContainer().getNumbersConverter()),
ENGLISH_INTEGER(englishContainer().getNumbersConverter());

private IntegerToStringConverter converter;

Expand Down
Expand Up @@ -13,4 +13,6 @@ public interface BaseValues {
List<PluralForms> pluralForms();

String currency();

char twoDigitsNumberSeparator();
}
Expand Up @@ -6,6 +6,7 @@
import pl.allegro.finance.tradukisto.internal.languages.czech.CzechIntegerToWordsConverter;
import pl.allegro.finance.tradukisto.internal.languages.czech.CzechValues;
import pl.allegro.finance.tradukisto.internal.languages.czech.CzechValuesForSmallNumbers;
import pl.allegro.finance.tradukisto.internal.languages.english.EnglishValues;
import pl.allegro.finance.tradukisto.internal.languages.polish.PolishValues;

public class Container {
Expand All @@ -29,12 +30,16 @@ public static Container czechContainer() {
return new Container(integerConverter, bigDecimalBankingMoneyValueConverter);
}

private final IntegerToStringConverter integerConverter;
public static Container englishContainer() {
return new Container(new EnglishValues());
}

private final IntegerToStringConverter integerConverter;
private final BigDecimalToStringConverter bigDecimalConverter;

public Container(BaseValues baseValues) {
HundredsToWordsConverter hundredsToStringConverter = new HundredsToWordsConverter(baseValues.baseNumbers());
HundredsToWordsConverter hundredsToStringConverter = new HundredsToWordsConverter(baseValues.baseNumbers(),
baseValues.twoDigitsNumberSeparator());

integerConverter = new IntegerToWordsConverter(
hundredsToStringConverter,
Expand Down
Expand Up @@ -12,9 +12,11 @@
public class HundredsToWordsConverter implements GenderAwareIntegerToStringConverter {

private final Map<Integer, GenderForms> baseValues;
private char twoDigitsNumberSeparator;

public HundredsToWordsConverter(Map<Integer, GenderForms> baseValues) {
public HundredsToWordsConverter(Map<Integer, GenderForms> baseValues, char twoDigitsNumberSeparator) {
this.baseValues = baseValues;
this.twoDigitsNumberSeparator = twoDigitsNumberSeparator;
}

@Override
Expand All @@ -33,7 +35,7 @@ public String asWords(Integer value, GenderType genderType) {
private String twoDigitsNumberAsString(Integer value, GenderType genderType) {
Integer units = value % 10;
Integer tens = value - units;
return format("%s %s", asWords(tens, genderType), asWords(units, genderType));
return format("%s%c%s", asWords(tens, genderType), twoDigitsNumberSeparator, asWords(units, genderType));
}

private String threeDigitsNumberAsString(Integer value, GenderType genderType) {
Expand Down
Expand Up @@ -69,4 +69,9 @@ public List<PluralForms> pluralForms() {
public String currency() {
return "Kč";
}

@Override
public char twoDigitsNumberSeparator() {
return ' ';
}
}
Expand Up @@ -32,4 +32,9 @@ public List<PluralForms> pluralForms() {
public String currency() {
return originalValues.currency();
}

@Override
public char twoDigitsNumberSeparator() {
return ' ';
}
}
@@ -0,0 +1,23 @@
package pl.allegro.finance.tradukisto.internal.languages.english;

import pl.allegro.finance.tradukisto.internal.languages.GenderType;
import pl.allegro.finance.tradukisto.internal.languages.PluralForms;

public class EnglishPluralForms implements PluralForms {

private final String form;

public EnglishPluralForms(String form) {
this.form = form;
}

@Override
public String formFor(Integer value) {
return form;
}

@Override
public GenderType genderType() {
return GenderType.NON_APPLICABLE;
}
}
@@ -0,0 +1,76 @@
package pl.allegro.finance.tradukisto.internal.languages.english;

import pl.allegro.finance.tradukisto.internal.BaseValues;
import pl.allegro.finance.tradukisto.internal.languages.GenderForms;
import pl.allegro.finance.tradukisto.internal.languages.PluralForms;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

import static pl.allegro.finance.tradukisto.internal.support.BaseNumbersBuilder.baseNumbersBuilder;

public class EnglishValues implements BaseValues {

@Override
public Map<Integer, GenderForms> baseNumbers() {
return baseNumbersBuilder()
.put(0, "zero")
.put(1, "one")
.put(2, "two")
.put(3, "three")
.put(4, "four")
.put(5, "five")
.put(6, "six")
.put(7, "seven")
.put(8, "eight")
.put(9, "nine")
.put(10, "ten")
.put(11, "eleven")
.put(12, "twelve")
.put(13, "thirteen")
.put(14, "fourteen")
.put(15, "fifteen")
.put(16, "sixteen")
.put(17, "seventeen")
.put(18, "eighteen")
.put(19, "nineteen")
.put(20, "twenty")
.put(30, "thirty")
.put(40, "forty")
.put(50, "fifty")
.put(60, "sixty")
.put(70, "seventy")
.put(80, "eighty")
.put(90, "ninety")
.put(100, "one hundred")
.put(200, "two hundred")
.put(300, "three hundred")
.put(400, "four hundred")
.put(500, "five hundred")
.put(600, "six hundred")
.put(700, "seven hundred")
.put(800, "eight hundred")
.put(900, "nine hundred")
.build();
}

@Override
public List<PluralForms> pluralForms() {
return Arrays.<PluralForms>asList(
new EnglishPluralForms(""),
new EnglishPluralForms("thousand"),
new EnglishPluralForms("million"),
new EnglishPluralForms("billion"));
}

@Override
public String currency() {
return "£";
}

@Override
public char twoDigitsNumberSeparator() {
return '-';
}
}
Expand Up @@ -68,4 +68,9 @@ public List<PluralForms> pluralForms() {
public String currency() {
return "PLN";
}

@Override
public char twoDigitsNumberSeparator() {
return ' ';
}
}
Expand Up @@ -4,6 +4,7 @@ import com.google.common.base.VerifyException
import spock.lang.Specification

import static pl.allegro.finance.tradukisto.MoneyConverters.CZECH_BANKING_MONEY_VALUE
import static pl.allegro.finance.tradukisto.MoneyConverters.ENGLISH_BANKING_MONEY_VALUE
import static pl.allegro.finance.tradukisto.MoneyConverters.POLISH_BANKING_MONEY_VALUE

class MoneyConvertersTest extends Specification {
Expand All @@ -18,6 +19,11 @@ class MoneyConvertersTest extends Specification {
CZECH_BANKING_MONEY_VALUE.asWords(1_234.56) == "jeden tisíc dvě stě třicet čtyři Kč 56/100"
}

def "should convert money in English"() {
expect:
ENGLISH_BANKING_MONEY_VALUE.asWords(1_234.56) == "one thousand two hundred thirty-four £ 56/100"
}

def "should throw exception when null given"() {
when:
POLISH_BANKING_MONEY_VALUE.asWords(null)
Expand Down
Expand Up @@ -4,6 +4,7 @@ import com.google.common.base.VerifyException
import spock.lang.Specification

import static pl.allegro.finance.tradukisto.ValueConverters.CZECH_INTEGER
import static pl.allegro.finance.tradukisto.ValueConverters.ENGLISH_INTEGER
import static pl.allegro.finance.tradukisto.ValueConverters.POLISH_INTEGER

class ValueConvertersTest extends Specification {
Expand All @@ -18,6 +19,11 @@ class ValueConvertersTest extends Specification {
CZECH_INTEGER.asWords(1_234) == "jeden tisíc dvě stě třicet čtyři"
}

def "should convert numbers in English"() {
expect:
ENGLISH_INTEGER.asWords(1_234) == "one thousand two hundred thirty-four"
}

def "should throw exception when null given"() {
when:
POLISH_INTEGER.asWords(null)
Expand Down
Expand Up @@ -5,25 +5,25 @@ import spock.lang.Specification
class BigDecimalToBankingMoneyConverterTest extends Specification {

def integerToStringConverter = Stub(IntegerToStringConverter)
def converter = new BigDecimalToBankingMoneyConverter(integerToStringConverter, "PLN")
def converter = new BigDecimalToBankingMoneyConverter(integerToStringConverter, "£")

def "setup"() {
integerToStringConverter.asWords(123) >> "sto dwadzieścia trzy"
integerToStringConverter.asWords(123) >> "one hundred twenty-three"
}

def "should convert whole numbers"() {
expect:
converter.asWords(123) == "sto dwadzieścia trzy PLN 00/100"
converter.asWords(123) == "one hundred twenty-three £ 00/100"
}

def "should convert value with one digit after decimal point"() {
expect:
converter.asWords(123.4) == "sto dwadzieścia trzy PLN 40/100"
converter.asWords(123.4) == "one hundred twenty-three £ 40/100"
}

def "should convert value with two digits after decimal point"() {
expect:
converter.asWords(123.4) == "sto dwadzieścia trzy PLN 40/100"
converter.asWords(123.4) == "one hundred twenty-three £ 40/100"
}

def "should not support thousands part of value"() {
Expand Down
Expand Up @@ -7,33 +7,35 @@ import static pl.allegro.finance.tradukisto.internal.languages.GenderForms.gende

class HundredsToWordsConverterTest extends Specification {

char separator = '-'

def "should convert value from list of base values"() {
given:
def converter = new HundredsToWordsConverter([1: genderForm("jeden")])
def converter = new HundredsToWordsConverter([1: genderForm("one")], separator)

expect:
converter.asWords(1, GenderType.NON_APPLICABLE) == "jeden"
converter.asWords(1, GenderType.NON_APPLICABLE) == "one"
}

def "should convert two digits number"() {
given:
def converter = new HundredsToWordsConverter([20: genderForm("dwadzieścia"), 1: genderForm("jeden")])
def converter = new HundredsToWordsConverter([20: genderForm("twenty"), 1: genderForm("one")], separator)

expect:
converter.asWords(21, GenderType.NON_APPLICABLE) == "dwadzieścia jeden"
converter.asWords(21, GenderType.NON_APPLICABLE) == "twenty-one"
}

def "should convert three digits number"() {
given:
def converter = new HundredsToWordsConverter([600: genderForm("sześćset"), 60: genderForm("sześćdziesiąt"), 6: genderForm("sześć")])
def converter = new HundredsToWordsConverter([600: genderForm("six hundred"), 60: genderForm("sixty"), 6: genderForm("six")], separator)

expect:
converter.asWords(666, GenderType.NON_APPLICABLE) =="sześćset sześćdziesiąt sześć"
converter.asWords(666, GenderType.NON_APPLICABLE) =="six hundred sixty-six"
}

def "should throw IllegalArgumentException when given number is not supported"() {
given:
def converter = new HundredsToWordsConverter([1: genderForm("jeden")])
def converter = new HundredsToWordsConverter([1: genderForm("one")], separator)

when:
converter.asWords(2, GenderType.NON_APPLICABLE)
Expand Down

0 comments on commit 2a14bd6

Please sign in to comment.