Skip to content

Commit

Permalink
LiteralInt and LiteratInt_test (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
nedtwigg authored Mar 15, 2024
2 parents a9c17e8 + f2afb64 commit 6e1e5fe
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
30 changes: 30 additions & 0 deletions python/selfie-lib/selfie_lib/Literals.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from typing import Protocol, TypeVar
from abc import abstractmethod
from .EscapeLeadingWhitespace import EscapeLeadingWhitespace
import io

T = TypeVar("T")

Expand Down Expand Up @@ -41,6 +42,35 @@ def parse(self, string: str, language: Language) -> T:
PADDING_SIZE = len(str(MAX_RAW_NUMBER)) - 1


class LiteralInt(LiteralFormat[int]):
def _encode_underscores(
self, buffer: io.StringIO, value: int, language: Language
) -> io.StringIO:
if value >= MAX_RAW_NUMBER:
mod = value % MAX_RAW_NUMBER
left_padding = PADDING_SIZE - len(str(mod))
self._encode_underscores(buffer, value // MAX_RAW_NUMBER, language)
buffer.write("_")
buffer.write("0" * left_padding)
buffer.write(str(mod))
return buffer
elif value < 0:
buffer.write("-")
self._encode_underscores(buffer, abs(value), language)
return buffer
else:
buffer.write(str(value))
return buffer

def encode(
self, value: int, language: Language, encoding_policy: EscapeLeadingWhitespace
) -> str:
return self._encode_underscores(io.StringIO(), value, language).getvalue()

def parse(self, string: str, language: Language) -> int:
return int(string.replace("_", ""))


class LiteralBoolean(LiteralFormat[bool]):
def encode(
self, value: bool, language: Language, encoding_policy: EscapeLeadingWhitespace
Expand Down
52 changes: 52 additions & 0 deletions python/selfie-lib/tests/LiteralInt_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from selfie_lib.Literals import LiteralInt, Language
from selfie_lib.EscapeLeadingWhitespace import EscapeLeadingWhitespace


def _encode(value: int, expected: str):
literal_int = LiteralInt()
actual = literal_int.encode(value, Language.PYTHON, EscapeLeadingWhitespace.NEVER)
assert actual == expected, f"Expected '{expected}', but got '{actual}'"


def _decode(value: str, expected: int):
literal_int = LiteralInt()
actual = literal_int.parse(value, Language.PYTHON)
assert actual == expected, f"Expected '{expected}', but got '{actual}'"


class TestLiteralInt:
def test_encode(self):
test_cases = [
(0, "0"),
(1, "1"),
(-1, "-1"),
(999, "999"),
(-999, "-999"),
(1_000, "1_000"),
(-1_000, "-1_000"),
(1_000_000, "1_000_000"),
(-1_000_000, "-1_000_000"),
(2400500, "2_400_500"),
(2400501, "2_400_501"),
(200, "200"),
(1001, "1_001"),
(1010, "1_010"),
(10010, "10_010"),
]
for value, expected in test_cases:
_encode(value, expected)

def test_decode(self):
test_cases = [
("0", 0),
("1", 1),
("-1", -1),
("999", 999),
("9_99", 999),
("9_9_9", 999),
("-999", -999),
("-9_99", -999),
("-9_9_9", -999),
]
for value, expected in test_cases:
_decode(value, expected)

0 comments on commit 6e1e5fe

Please sign in to comment.