Skip to content

Commit

Permalink
feat: add test for text -> currency value
Browse files Browse the repository at this point in the history
  • Loading branch information
tdgrunenwald committed Dec 5, 2024
1 parent fc7655d commit f513d33
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 5 deletions.
18 changes: 18 additions & 0 deletions features/currency.feature
Original file line number Diff line number Diff line change
Expand Up @@ -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 <repr>
When currency text representation is parsed
Then the resulting currency object has value <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 |
15 changes: 15 additions & 0 deletions features/steps/currency.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}"
31 changes: 26 additions & 5 deletions src/ddd_sample/domain/currency.py
Original file line number Diff line number Diff line change
@@ -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:
Expand All @@ -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)

0 comments on commit f513d33

Please sign in to comment.