diff --git a/features/currency.feature b/features/currency.feature index c050f86..e6e8ef9 100644 --- a/features/currency.feature +++ b/features/currency.feature @@ -15,3 +15,21 @@ Feature: Represent real currency | USD-cents | 10071 | $100.71 | | USD-cents | 110071 | $1,100.71 | | USD-cents | 500110071 | $5,001,100.71 | + + Scenario Outline: Parse text to currency + Given currency text representation + When currency text representation is parsed + Then the resulting currency object has value + + Examples: USD + | repr | value | + | $1.00 | 100 | + | $1.0 | 100 | + | $1. | 100 | + | $1 | 100 | + | $.5 | 50 | + | $0.5 | 50 | + | $0.50 | 50 | + | $100 | 10000 | + | $1000 | 100000 | + | $1,000 | 100000 | diff --git a/features/steps/currency.py b/features/steps/currency.py index 2f90f05..f3c7ebe 100644 --- a/features/steps/currency.py +++ b/features/steps/currency.py @@ -21,3 +21,18 @@ def _(context): @then('it matches {pattern}') def _(context, pattern: str): assert context.string == pattern, f"'{context.string}' != '{pattern}'" + + +@given("currency text representation {repr}") +def _(context, repr: str): + context.repr = repr + + +@when("currency text representation is parsed") +def _(context): + context.currency = Currency(value=USD.toValue(context.repr), format=USD) + + +@then("the resulting currency object has value {value}") +def _(context, value: int): + assert context.currency.value == value, f"{context.currency.value} != {value}" diff --git a/src/ddd_sample/domain/currency.py b/src/ddd_sample/domain/currency.py index a3632a2..45bfdb4 100644 --- a/src/ddd_sample/domain/currency.py +++ b/src/ddd_sample/domain/currency.py @@ -1,11 +1,32 @@ -from typing import Callable +import re +from abc import ABC, abstractclassmethod -CurrencyFormatMixin = Callable[[int], str] +class CurrencyFormatMixin(ABC): + @abstractclassmethod + def toValue(cls, repr: str) -> int: + pass + @abstractclassmethod + def toString(cls, value: int) -> str: + pass -def USD(value: int) -> str: - return "${:,}.{:02d}".format(value // 100, value % 100) + +class USD(CurrencyFormatMixin): + @abstractclassmethod + def toValue(cls, repr: str) -> int: + repr = repr.strip() + repr = repr.replace(",", "") + match = re.search(r"^\$(\d*)\.?(\d?\d?)$", repr) + print(match.groups()) +# dollars = int(match.group(1)) +# cents = int(match.group(2)) + + return 0#dollars * 100 + cents + + @abstractclassmethod + def toString(cls, value: int) -> str: + return "${:,}.{:02d}".format(value // 100, value % 100) class Currency: @@ -15,4 +36,4 @@ def __init__(self, value: int, format: CurrencyFormatMixin): self.format = format def __str__(self) -> str: - return self.format(self.value) + return self.format.toString(self.value)