From 15d5182e101f9d9b5ac8185d568e51770a1c3e99 Mon Sep 17 00:00:00 2001 From: Aneta Szumowska <85861945+aszumowska@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:03:25 +0100 Subject: [PATCH] #99 | add longConverter for Dutch (#170) Co-authored-by: Julia Glaszka <85160468+jglaszka@users.noreply.github.com> --- .../tradukisto/LongValueConverters.java | 4 +- .../tradukisto/internal/Container.java | 16 ++-- .../dutch/DutchLongToWordsConverter.java | 81 +++++++++++++++++++ .../internal/languages/dutch/DutchValues.java | 7 +- .../languages/dutch/DutchValuesTest.groovy | 25 +++--- 5 files changed, 114 insertions(+), 19 deletions(-) create mode 100644 src/main/java/pl/allegro/finance/tradukisto/internal/languages/dutch/DutchLongToWordsConverter.java diff --git a/src/main/java/pl/allegro/finance/tradukisto/LongValueConverters.java b/src/main/java/pl/allegro/finance/tradukisto/LongValueConverters.java index c154e8de..9e3a6f7b 100644 --- a/src/main/java/pl/allegro/finance/tradukisto/LongValueConverters.java +++ b/src/main/java/pl/allegro/finance/tradukisto/LongValueConverters.java @@ -4,6 +4,7 @@ import java.util.Objects; import static pl.allegro.finance.tradukisto.internal.Container.croatianContainer; +import static pl.allegro.finance.tradukisto.internal.Container.dutchContainer; import static pl.allegro.finance.tradukisto.internal.Container.englishContainer; import static pl.allegro.finance.tradukisto.internal.Container.hindiContainer; import static pl.allegro.finance.tradukisto.internal.Container.japaneseKanjiContainer; @@ -19,7 +20,8 @@ public enum LongValueConverters { POLISH_LONG(polishContainer().getLongConverter()), HINDI_LONG(hindiContainer().getLongConverter()), SWEDISH_LONG(swedishContainer().getLongConverter()), - JAPANESE_KANJI_LONG(japaneseKanjiContainer().getLongConverter()); + JAPANESE_KANJI_LONG(japaneseKanjiContainer().getLongConverter()), + DUTCH_LONG(dutchContainer().getLongConverter()); private final LongToStringConverter converter; diff --git a/src/main/java/pl/allegro/finance/tradukisto/internal/Container.java b/src/main/java/pl/allegro/finance/tradukisto/internal/Container.java index 57c14a5a..d82acd7a 100644 --- a/src/main/java/pl/allegro/finance/tradukisto/internal/Container.java +++ b/src/main/java/pl/allegro/finance/tradukisto/internal/Container.java @@ -10,6 +10,7 @@ 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.dutch.DutchIntegerToWordsConverter; +import pl.allegro.finance.tradukisto.internal.languages.dutch.DutchLongToWordsConverter; import pl.allegro.finance.tradukisto.internal.languages.dutch.DutchThousandToWordsConverter; import pl.allegro.finance.tradukisto.internal.languages.dutch.DutchValues; import pl.allegro.finance.tradukisto.internal.languages.english.AmericanEnglishValues; @@ -103,12 +104,12 @@ public static Container sloveneContainer() { SloveneValues values = new SloveneValues(); SloveneThousandToWordsConverter sloveneThousandToWordsConverter = new SloveneThousandToWordsConverter( - values.baseNumbers()); + values.baseNumbers()); IntegerToStringConverter converter = new NumberToWordsConverter(sloveneThousandToWordsConverter, values.pluralForms()); BigDecimalToStringConverter bigDecimalBankingMoneyValueConverter = new BigDecimalToBankingMoneyConverter( - converter, values.currency()); + converter, values.currency()); return new Container(converter, null, bigDecimalBankingMoneyValueConverter); } @@ -189,21 +190,26 @@ public static Container germanContainer() { } public static Container dutchContainer() { - DutchValues values = new DutchValues(); DutchThousandToWordsConverter dutchThousandToWordsConverter = new DutchThousandToWordsConverter(values.baseNumbers()); IntegerToStringConverter converter = new DutchIntegerToWordsConverter( - new NumberToWordsConverter(dutchThousandToWordsConverter, values.pluralForms()), values.exceptions(), + new NumberToWordsConverter(dutchThousandToWordsConverter, values.pluralForms()), + values.exceptions(), dutchThousandToWordsConverter ); + LongToStringConverter dutchLongToWordsConverter = new DutchLongToWordsConverter( + dutchThousandToWordsConverter, + values.pluralForms() + ); + BigDecimalToStringConverter bigDecimalBankingMoneyValueConverter = new BigDecimalToBankingMoneyConverter(converter, values.currency()); - return new Container(converter, null, bigDecimalBankingMoneyValueConverter); + return new Container(converter, dutchLongToWordsConverter, bigDecimalBankingMoneyValueConverter); } public static Container italianContainer() { diff --git a/src/main/java/pl/allegro/finance/tradukisto/internal/languages/dutch/DutchLongToWordsConverter.java b/src/main/java/pl/allegro/finance/tradukisto/internal/languages/dutch/DutchLongToWordsConverter.java new file mode 100644 index 00000000..a1911686 --- /dev/null +++ b/src/main/java/pl/allegro/finance/tradukisto/internal/languages/dutch/DutchLongToWordsConverter.java @@ -0,0 +1,81 @@ +package pl.allegro.finance.tradukisto.internal.languages.dutch; + +import pl.allegro.finance.tradukisto.internal.GenderAwareIntegerToStringConverter; +import pl.allegro.finance.tradukisto.internal.LongToStringConverter; +import pl.allegro.finance.tradukisto.internal.languages.GenderType; +import pl.allegro.finance.tradukisto.internal.languages.PluralForms; +import pl.allegro.finance.tradukisto.internal.support.Assert; +import pl.allegro.finance.tradukisto.internal.support.NumberChunking; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import static java.util.Collections.reverse; + +public class DutchLongToWordsConverter implements LongToStringConverter { + + private final NumberChunking numberChunking = new NumberChunking(); + + private final GenderAwareIntegerToStringConverter hundredsToWordsConverter; + private final List pluralForms; + + public DutchLongToWordsConverter( + GenderAwareIntegerToStringConverter hundredsToWordsConverter, + List pluralForms + ) { + this.hundredsToWordsConverter = hundredsToWordsConverter; + this.pluralForms = pluralForms; + } + + @Override + public String asWords(Long value) { + Assert.isTrue(value >= 0, () -> String.format("can't convert negative numbers for value %d", value)); + + List result = new ArrayList<>(); + + long bigNumber = value / 1000000; + long smallNumber = value % 1000000; + + if (bigNumber > 0) { + List valueChunks = numberChunking.chunk(bigNumber); + List formsToUse = getRequiredFormsInReversedOrder(valueChunks.size()); + result.add(joinValueChunksWithForms(valueChunks.iterator(), formsToUse.iterator())); + } + + if (smallNumber > 0) { + result.add(hundredsToWordsConverter.asWords((int) smallNumber, GenderType.NON_APPLICABLE)); + } + + return joinParts(result); + } + + protected List getRequiredFormsInReversedOrder(int chunks) { + List formsToUse = new ArrayList<>(pluralForms.subList(0, chunks)); + reverse(formsToUse); + return formsToUse; + } + + protected String joinValueChunksWithForms(Iterator chunks, Iterator formsToUse) { + List result = new ArrayList<>(); + + while (chunks.hasNext() && formsToUse.hasNext()) { + Integer currentChunkValue = chunks.next(); + PluralForms currentForms = formsToUse.next(); + + if (currentChunkValue > 0) { + String words = hundredsToWordsConverter.asWords(currentChunkValue, currentForms.genderType()); + result.add(words); + result.add(currentForms.formFor(currentChunkValue)); + } + } + + return joinParts(result); + } + + protected String joinParts(List result) { + return result.isEmpty() + ? hundredsToWordsConverter.asWords(0, pluralForms.get(0).genderType()) + : String.join(" ", result).trim(); + } +} diff --git a/src/main/java/pl/allegro/finance/tradukisto/internal/languages/dutch/DutchValues.java b/src/main/java/pl/allegro/finance/tradukisto/internal/languages/dutch/DutchValues.java index 3e5a7c7d..e340f3a8 100644 --- a/src/main/java/pl/allegro/finance/tradukisto/internal/languages/dutch/DutchValues.java +++ b/src/main/java/pl/allegro/finance/tradukisto/internal/languages/dutch/DutchValues.java @@ -7,7 +7,9 @@ import java.util.Map; import pl.allegro.finance.tradukisto.internal.languages.GenderForms; +import pl.allegro.finance.tradukisto.internal.languages.GenderType; import pl.allegro.finance.tradukisto.internal.languages.PluralForms; +import pl.allegro.finance.tradukisto.internal.languages.RegularPluralForms; import static java.util.Collections.singletonMap; @@ -63,7 +65,10 @@ public Map exceptions() { public List pluralForms() { return Arrays.asList( new DutchPluralForms("miljoen"), - new DutchPluralForms("miljard") + new DutchPluralForms("miljard"), + new DutchPluralForms("biljoen"), + new DutchPluralForms("biljard"), + new DutchPluralForms("triljoen") ); } diff --git a/src/test/groovy/pl/allegro/finance/tradukisto/internal/languages/dutch/DutchValuesTest.groovy b/src/test/groovy/pl/allegro/finance/tradukisto/internal/languages/dutch/DutchValuesTest.groovy index ce6690d9..66a8762e 100644 --- a/src/test/groovy/pl/allegro/finance/tradukisto/internal/languages/dutch/DutchValuesTest.groovy +++ b/src/test/groovy/pl/allegro/finance/tradukisto/internal/languages/dutch/DutchValuesTest.groovy @@ -1,6 +1,6 @@ package pl.allegro.finance.tradukisto.internal.languages.dutch -import spock.lang.Ignore + import spock.lang.Specification import spock.lang.Unroll @@ -109,7 +109,6 @@ class DutchValuesTest extends Specification { 2147483647 | "twee miljard honderdzevenenveertig miljoen vierhonderddrieëntachtigduizendzeshonderdzevenenveertig" } - @Ignore("Needs Dutch long converter and values for trillion, quadrillion, quintillion") @Unroll def "should convert long #value to '#words' in Dutch"() { expect: @@ -117,18 +116,20 @@ class DutchValuesTest extends Specification { where: value | words - 5_000_000_000 | "" + 5_000_000_000 | "vijf miljard" - 1_000_000_000_000 | "" - 2_000_000_000_000 | "" - 5_000_000_000_000 | "" + 1_000_000_000_000 | "één biljoen" + 2_000_000_000_000 | "twee biljoen" + 5_000_000_000_000 | "vijf biljoen" - 1_000_000_000_000_000 | "" - 2_000_000_000_000_000 | "" - 5_000_000_000_000_000 | "" + 1_000_000_000_000_000 | "één biljard" + 2_000_000_000_000_000 | "twee biljard" + 5_000_000_000_000_000 | "vijf biljard" - 1_000_000_000_000_000_000 | "" - 2_000_000_000_000_000_000 | "" - Long.MAX_VALUE | "" + 1_000_000_000_000_000_000 | "één triljoen" + 2_000_000_000_000_000_000 | "twee triljoen" + Long.MAX_VALUE | "negen triljoen tweehonderddrieëntwintig biljard " + + "driehonderdtweeënzeventig biljoen zesendertig miljard " + + "achthonderdvierenvijftig miljoen zevenhonderdvijfenzeventigduizendachthonderdzeven" } }