- Add ty to dev deps; - Add some tests covering previously uncovered cases; - Fix some bugs; - Introduce argfield for nicer argparse interface for things that can't be expressed via the type system; - Fix line length.
127 lines
3.3 KiB
Python
127 lines
3.3 KiB
Python
# type: ignore[ty:unresolved-attribute]
|
|
# type: ignore[ty:unknown-argument]
|
|
import unittest
|
|
from enum import Enum
|
|
|
|
from argclass import argclass, argfield
|
|
|
|
|
|
class TestArgClass(unittest.TestCase):
|
|
def test__required_argument(self):
|
|
@argclass
|
|
class A:
|
|
arg1: str
|
|
|
|
assert A.parse_args(["--arg1", "hello"]) == A(arg1="hello")
|
|
self.assertRaises(SystemExit, A.parse_args, [])
|
|
self.assertRaises(SystemExit, A.parse_args, ["--arg2", "hello"])
|
|
|
|
def test__optional_argument_missing(self):
|
|
@argclass
|
|
class A:
|
|
arg2: str = "world"
|
|
|
|
assert A.parse_args([]) == A(arg2="world")
|
|
assert A.parse_args(["--arg2", "welt"]) == A(arg2="welt")
|
|
self.assertRaises(SystemExit, A.parse_args, ["--arg3", "welt"])
|
|
|
|
def test__str_enum_choices(self):
|
|
|
|
class MyEnum(str, Enum):
|
|
hello = "hello"
|
|
world = "world"
|
|
|
|
@argclass
|
|
class A:
|
|
arg3: MyEnum
|
|
|
|
assert A.parse_args(["--arg3", "hello"]) == A(arg3=MyEnum.hello)
|
|
self.assertRaises(SystemExit, A.parse_args, ["--arg3", "foo"])
|
|
|
|
def test__str_enum_default(self):
|
|
|
|
class MyEnum(str, Enum):
|
|
hello = "hello"
|
|
world = "world"
|
|
|
|
@argclass
|
|
class A:
|
|
arg3: MyEnum = MyEnum.hello
|
|
|
|
assert A.parse_args([]) == A(arg3=MyEnum.hello)
|
|
assert A.parse_args(["--arg3", "world"]) == A(arg3=MyEnum.world)
|
|
|
|
def test__boolean(self):
|
|
@argclass
|
|
class A:
|
|
arg3: bool
|
|
|
|
assert A.parse_args(["--arg3"]) == A(arg3=True)
|
|
assert A.parse_args(["--no-arg3"]) == A(arg3=False)
|
|
|
|
def test__boolean_default_true(self):
|
|
@argclass
|
|
class A:
|
|
arg3: bool = True
|
|
|
|
assert A.parse_args([]) == A(arg3=True)
|
|
assert A.parse_args(["--arg3"]) == A(arg3=True)
|
|
assert A.parse_args(["--no-arg3"]) == A(arg3=False)
|
|
|
|
def test__int(self):
|
|
@argclass
|
|
class A:
|
|
arg4: int
|
|
|
|
assert A.parse_args(["--arg4", "42"]) == A(arg4=42)
|
|
self.assertRaises(SystemExit, A.parse_args, ["--arg4", "4e2"])
|
|
|
|
def test__list_str(self):
|
|
@argclass
|
|
class A:
|
|
arg5: list[str]
|
|
|
|
assert A.parse_args(["--arg5", "hello", "world"]) == A(
|
|
arg5=["hello", "world"]
|
|
)
|
|
|
|
def test__list_int(self):
|
|
@argclass
|
|
class A:
|
|
arg5: list[int]
|
|
|
|
assert A.parse_args(["--arg5", "23", "42"]) == A(arg5=[23, 42])
|
|
|
|
def test__list_empty(self):
|
|
@argclass
|
|
class A:
|
|
arg5: list[str] = argfield(allow_empty=True)
|
|
|
|
assert A.parse_args(["--arg5"]) == A(arg5=[])
|
|
|
|
def test__shortoptions(self):
|
|
@argclass
|
|
class A:
|
|
world: str = argfield(shortopt="w")
|
|
|
|
assert A.parse_args(["-w", "hello"]) == A(world="hello")
|
|
|
|
def test__choices_str_valid(self):
|
|
@argclass
|
|
class A:
|
|
world: str = argfield(choices=["hello", "goodbye"])
|
|
|
|
assert A.parse_args(["--world", "hello"]) == A(world="hello")
|
|
self.assertRaises(SystemExit, A.parse_args, ["--world", "foo"])
|
|
|
|
def test__choices_int(self):
|
|
@argclass
|
|
class A:
|
|
number: int = argfield(choices=[4, 5, 6])
|
|
|
|
assert A.parse_args(["--number", "5"]) == A(number=5)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|