mirror of
https://github.com/yavook/kiwi-scp.git
synced 2024-11-22 04:43:00 +00:00
pytest shells
This commit is contained in:
parent
8a28730954
commit
243fee3f23
2 changed files with 150 additions and 28 deletions
|
@ -48,7 +48,7 @@ class _Project(BaseModel):
|
||||||
|
|
||||||
@root_validator(pre=True)
|
@root_validator(pre=True)
|
||||||
@classmethod
|
@classmethod
|
||||||
def unify_project(cls, values):
|
def unify_project(cls, values) -> Dict[str, Any]:
|
||||||
"""parse different project notations"""
|
"""parse different project notations"""
|
||||||
|
|
||||||
if "name" in values:
|
if "name" in values:
|
||||||
|
@ -91,7 +91,7 @@ class Config(BaseModel):
|
||||||
|
|
||||||
version: constr(regex=RE_SEMVER) = "0.2.0"
|
version: constr(regex=RE_SEMVER) = "0.2.0"
|
||||||
|
|
||||||
shells: Optional[List[Path]] = [
|
shells: List[Path] = [
|
||||||
Path("/bin/bash"),
|
Path("/bin/bash"),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -152,9 +152,32 @@ class Config(BaseModel):
|
||||||
|
|
||||||
return yml_string
|
return yml_string
|
||||||
|
|
||||||
|
@validator("shells", pre=True)
|
||||||
|
@classmethod
|
||||||
|
def unify_shells(cls, value) -> List[str]:
|
||||||
|
"""parse different shells notations"""
|
||||||
|
|
||||||
|
if value is None:
|
||||||
|
return []
|
||||||
|
|
||||||
|
elif isinstance(value, list):
|
||||||
|
return value
|
||||||
|
|
||||||
|
elif isinstance(value, dict):
|
||||||
|
return list(value)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# any other format (try to coerce to str first)
|
||||||
|
try:
|
||||||
|
return [str(value)]
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
# undefined format
|
||||||
|
raise ValueError("Invalid Shells Format")
|
||||||
|
|
||||||
@validator("projects", pre=True)
|
@validator("projects", pre=True)
|
||||||
@classmethod
|
@classmethod
|
||||||
def unify_projects(cls, value):
|
def unify_projects(cls, value) -> List[Dict[str, str]]:
|
||||||
"""parse different projects notations"""
|
"""parse different projects notations"""
|
||||||
|
|
||||||
if value is None:
|
if value is None:
|
||||||
|
@ -173,9 +196,14 @@ class Config(BaseModel):
|
||||||
result.append(entry)
|
result.append(entry)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
try:
|
||||||
# handle single project name
|
# handle single project name
|
||||||
result.append({"name": str(entry)})
|
result.append({"name": str(entry)})
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
# undefined format
|
||||||
|
raise ValueError("Invalid Projects Format")
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
elif isinstance(value, dict):
|
elif isinstance(value, dict):
|
||||||
|
@ -183,9 +211,15 @@ class Config(BaseModel):
|
||||||
return [value]
|
return [value]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# handle single project name
|
# any other format (try to coerce to str first)
|
||||||
|
try:
|
||||||
|
# handle as a single project name
|
||||||
return [{"name": str(value)}]
|
return [{"name": str(value)}]
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
# undefined format
|
||||||
|
raise ValueError("Invalid Projects Format")
|
||||||
|
|
||||||
@validator("environment", pre=True)
|
@validator("environment", pre=True)
|
||||||
@classmethod
|
@classmethod
|
||||||
def unify_environment(cls, value) -> Dict[str, Optional[str]]:
|
def unify_environment(cls, value) -> Dict[str, Optional[str]]:
|
||||||
|
@ -215,20 +249,20 @@ class Config(BaseModel):
|
||||||
|
|
||||||
result: Dict[str, Optional[str]] = {}
|
result: Dict[str, Optional[str]] = {}
|
||||||
for item in value:
|
for item in value:
|
||||||
|
try:
|
||||||
key, value = parse_str(str(item))
|
key, value = parse_str(str(item))
|
||||||
result[key] = value
|
result[key] = value
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
# undefined format
|
||||||
|
raise ValueError("Invalid Environment Format")
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
elif isinstance(value, str):
|
|
||||||
# string format (single variable):
|
|
||||||
# "<var>=<value>"
|
|
||||||
|
|
||||||
key, value = parse_str(value)
|
|
||||||
return {key: value}
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# any other format (try to coerce to str first)
|
# any other format (try to coerce to str first)
|
||||||
|
# string format (single variable):
|
||||||
|
# "<var>=<value>"
|
||||||
try:
|
try:
|
||||||
key, value = parse_str(str(value))
|
key, value = parse_str(str(value))
|
||||||
return {key: value}
|
return {key: value}
|
||||||
|
|
|
@ -8,6 +8,12 @@ from pydantic import ValidationError
|
||||||
from kiwi_scp.config import Config
|
from kiwi_scp.config import Config
|
||||||
|
|
||||||
|
|
||||||
|
class UnCoercible:
|
||||||
|
"""A class that doesn't have a string representation"""
|
||||||
|
def __str__(self):
|
||||||
|
raise ValueError
|
||||||
|
|
||||||
|
|
||||||
def test_default():
|
def test_default():
|
||||||
c = Config()
|
c = Config()
|
||||||
version = toml.load("./pyproject.toml")["tool"]["poetry"]["version"]
|
version = toml.load("./pyproject.toml")["tool"]["poetry"]["version"]
|
||||||
|
@ -22,6 +28,70 @@ def test_default():
|
||||||
assert c.network.cidr == IPv4Network("10.22.46.0/24")
|
assert c.network.cidr == IPv4Network("10.22.46.0/24")
|
||||||
|
|
||||||
|
|
||||||
|
########
|
||||||
|
# SHELLS
|
||||||
|
########
|
||||||
|
|
||||||
|
def test_shells_empty():
|
||||||
|
c = Config(shells=None)
|
||||||
|
|
||||||
|
assert c == Config(shells=[])
|
||||||
|
|
||||||
|
assert c.shells == []
|
||||||
|
|
||||||
|
|
||||||
|
def test_shells_list():
|
||||||
|
c = Config(shells=["/bin/sh", "sh"])
|
||||||
|
|
||||||
|
assert len(c.shells) == 2
|
||||||
|
assert c.shells[0] == Path("/bin/sh")
|
||||||
|
assert c.shells[1] == Path("sh")
|
||||||
|
|
||||||
|
c = Config(shells=["/bin/bash"])
|
||||||
|
|
||||||
|
assert len(c.shells) == 1
|
||||||
|
assert c.shells[0] == Path("/bin/bash")
|
||||||
|
|
||||||
|
|
||||||
|
def test_shells_dict():
|
||||||
|
c = Config(shells={"/bin/bash": None})
|
||||||
|
|
||||||
|
assert len(c.shells) == 1
|
||||||
|
assert c.shells[0] == Path("/bin/bash")
|
||||||
|
|
||||||
|
|
||||||
|
def test_shells_coercible():
|
||||||
|
c = Config(shells="/bin/bash")
|
||||||
|
|
||||||
|
assert c == Config(shells=Path("/bin/bash"))
|
||||||
|
|
||||||
|
assert len(c.shells) == 1
|
||||||
|
assert c.shells[0] == Path("/bin/bash")
|
||||||
|
|
||||||
|
c = Config(shells=123)
|
||||||
|
|
||||||
|
assert len(c.shells) == 1
|
||||||
|
assert c.shells[0] == Path("123")
|
||||||
|
|
||||||
|
|
||||||
|
def test_shells_uncoercible():
|
||||||
|
with pytest.raises(ValidationError) as exc_info:
|
||||||
|
Config(shells=UnCoercible())
|
||||||
|
|
||||||
|
assert len(exc_info.value.errors()) == 1
|
||||||
|
error = exc_info.value.errors()[0]
|
||||||
|
assert error["msg"] == "Invalid Shells Format"
|
||||||
|
assert error["type"] == "value_error"
|
||||||
|
|
||||||
|
with pytest.raises(ValidationError) as exc_info:
|
||||||
|
Config(shells=["/bin/bash", UnCoercible()])
|
||||||
|
|
||||||
|
assert len(exc_info.value.errors()) == 1
|
||||||
|
error = exc_info.value.errors()[0]
|
||||||
|
assert error["msg"] == "value is not a valid path"
|
||||||
|
assert error["type"] == "type_error.path"
|
||||||
|
|
||||||
|
|
||||||
##########
|
##########
|
||||||
# PROJECTS
|
# PROJECTS
|
||||||
##########
|
##########
|
||||||
|
@ -29,9 +99,7 @@ def test_default():
|
||||||
def test_proj_empty():
|
def test_proj_empty():
|
||||||
c = Config(projects=None)
|
c = Config(projects=None)
|
||||||
|
|
||||||
assert c.projects == []
|
assert c == Config(projects=[])
|
||||||
|
|
||||||
c = Config(projects=[])
|
|
||||||
|
|
||||||
assert c.projects == []
|
assert c.projects == []
|
||||||
|
|
||||||
|
@ -75,7 +143,7 @@ def test_proj_dict():
|
||||||
assert p.override_storage is None
|
assert p.override_storage is None
|
||||||
|
|
||||||
|
|
||||||
def test_proj_name():
|
def test_proj_coercible():
|
||||||
c = Config(projects="project")
|
c = Config(projects="project")
|
||||||
|
|
||||||
assert c == Config(projects=["project"])
|
assert c == Config(projects=["project"])
|
||||||
|
@ -87,6 +155,24 @@ def test_proj_name():
|
||||||
assert p.override_storage is None
|
assert p.override_storage is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_proj_uncoercible():
|
||||||
|
with pytest.raises(ValidationError) as exc_info:
|
||||||
|
Config(projects=["valid", UnCoercible()])
|
||||||
|
|
||||||
|
assert len(exc_info.value.errors()) == 1
|
||||||
|
error = exc_info.value.errors()[0]
|
||||||
|
assert error["msg"] == "Invalid Projects Format"
|
||||||
|
assert error["type"] == "value_error"
|
||||||
|
|
||||||
|
with pytest.raises(ValidationError) as exc_info:
|
||||||
|
Config(projects=UnCoercible())
|
||||||
|
|
||||||
|
assert len(exc_info.value.errors()) == 1
|
||||||
|
error = exc_info.value.errors()[0]
|
||||||
|
assert error["msg"] == "Invalid Projects Format"
|
||||||
|
assert error["type"] == "value_error"
|
||||||
|
|
||||||
|
|
||||||
#############
|
#############
|
||||||
# ENVIRONMENT
|
# ENVIRONMENT
|
||||||
#############
|
#############
|
||||||
|
@ -139,7 +225,7 @@ def test_env_list():
|
||||||
assert c.environment["123"] is None
|
assert c.environment["123"] is None
|
||||||
|
|
||||||
|
|
||||||
def test_env_str():
|
def test_env_coercible():
|
||||||
c = Config(environment="variable=value")
|
c = Config(environment="variable=value")
|
||||||
|
|
||||||
assert len(c.environment) == 1
|
assert len(c.environment) == 1
|
||||||
|
@ -152,8 +238,6 @@ def test_env_str():
|
||||||
assert "variable" in c.environment
|
assert "variable" in c.environment
|
||||||
assert c.environment["variable"] is None
|
assert c.environment["variable"] is None
|
||||||
|
|
||||||
|
|
||||||
def test_env_coercible():
|
|
||||||
c = Config(environment=123)
|
c = Config(environment=123)
|
||||||
|
|
||||||
assert len(c.environment) == 1
|
assert len(c.environment) == 1
|
||||||
|
@ -167,11 +251,7 @@ def test_env_coercible():
|
||||||
assert c.environment["123.4"] is None
|
assert c.environment["123.4"] is None
|
||||||
|
|
||||||
|
|
||||||
def test_env_undef():
|
def test_env_uncoercible():
|
||||||
class UnCoercible:
|
|
||||||
def __str__(self):
|
|
||||||
raise ValueError
|
|
||||||
|
|
||||||
with pytest.raises(ValidationError) as exc_info:
|
with pytest.raises(ValidationError) as exc_info:
|
||||||
Config(environment=UnCoercible())
|
Config(environment=UnCoercible())
|
||||||
|
|
||||||
|
@ -179,3 +259,11 @@ def test_env_undef():
|
||||||
error = exc_info.value.errors()[0]
|
error = exc_info.value.errors()[0]
|
||||||
assert error["msg"] == "Invalid Environment Format"
|
assert error["msg"] == "Invalid Environment Format"
|
||||||
assert error["type"] == "value_error"
|
assert error["type"] == "value_error"
|
||||||
|
|
||||||
|
with pytest.raises(ValidationError) as exc_info:
|
||||||
|
Config(environment=["valid", UnCoercible()])
|
||||||
|
|
||||||
|
assert len(exc_info.value.errors()) == 1
|
||||||
|
error = exc_info.value.errors()[0]
|
||||||
|
assert error["msg"] == "Invalid Environment Format"
|
||||||
|
assert error["type"] == "value_error"
|
||||||
|
|
Loading…
Reference in a new issue