Skip to content

Commit

Permalink
using expected actual wording (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
bdsoha authored Dec 2, 2022
1 parent aa1ee90 commit 69e4a3d
Show file tree
Hide file tree
Showing 6 changed files with 171 additions and 159 deletions.
6 changes: 3 additions & 3 deletions src/expycted/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ def function(cls, function: Callable):
return Function(function)

@classmethod
def value(cls, value: Any):
def value(cls, expected: Any):
"""Expect a value to be something
Args:
value (Any): Value to check for some sort of condition
expected (Any): Value to check for some sort of condition
"""
return cls(value)
return cls(expected)

@classmethod
def folder(cls, path: Union[str, Path]):
Expand Down
19 changes: 14 additions & 5 deletions src/expycted/internals/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,24 @@
class BaseExpectation:
_ASSERTION_MESSAGES = {}

def __init__(self, value: Any, negate=False):
self.value = value
def __init__(self, expected: Any, negate=False):
self.expected = expected
self.negate = negate

def _message(self, method: str, actual: Any = _SENTINEL) -> str:
placeholders = dict(value1=self.value)
def _message(
self,
method: str,
actual: Any = _SENTINEL,
expected: Any = None,
**kwargs
) -> str:
placeholders = dict(
expected=self.expected if expected is None else expected,
**kwargs
)

if actual is not _SENTINEL:
placeholders['value2'] = actual
placeholders["actual"] = actual

return self._ASSERTION_MESSAGES[method].format(**placeholders)

Expand Down
32 changes: 16 additions & 16 deletions src/expycted/internals/filesystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ class Folder:

class Directory(BaseExpectation):
_ASSERTION_MESSAGES = {
"contain": "Expected {value1} to contain {value2}",
"contain_file": "Expected {value1} to contain file {value2}",
"contain_folder": "Expected {value1} to contain folder {value2}",
"exist": "Expected {value1} to exist",
"be_empty": "Expected {value1} to be empty",
"contain": "Expected {expected} to contain {actual}",
"contain_file": "Expected {expected} to contain file {actual}",
"contain_folder": "Expected {expected} to contain folder {actual}",
"exist": "Expected {expected} to exist",
"be_empty": "Expected {expected} to be empty",
}

def __init__(self, value: Union[str, Path]):
super().__init__(self._normalize(value))
def __init__(self, expected: Union[str, Path]):
super().__init__(self._normalize(expected))

@staticmethod
def _normalize(value: Union[str, Path]) -> Path:
Expand All @@ -34,10 +34,10 @@ def _normalize(value: Union[str, Path]) -> Path:

def _internal_contain(
self,
name: str,
actual: str,
type_: Union[Type[File], Type[Folder], None, str] = None
) -> Tuple[bool, str]:
name = self.value.joinpath(self._normalize(name))
name = self.expected.joinpath(self._normalize(actual))

if type_ == File or str(type_).lower() == "file":
return name.is_file(), self._message("contain_file", name)
Expand All @@ -48,34 +48,34 @@ def _internal_contain(
return name.exists(), self._message("contain", name)

def _internal_exist(self) -> Tuple[bool, str]:
return self.value.exists(), self._message("exist")
return self.expected.exists(), self._message("exist")

def _internal_be_empty(self) -> Tuple[bool, str]:
return not any(self.value.iterdir()), self._message("be_empty")
return not any(self.expected.iterdir()), self._message("be_empty")

@assertion
def contain(
self,
name: str,
actual: str,
type_: Union[Type[File], Type[Folder], None, str] = None
) -> None:
"""
Check if folder contains something with given name
"""

@hidetraceback
def contain_file(self, name: str) -> None:
def contain_file(self, actual: str) -> None:
"""
Check if folder contains file with given name
"""
return self.contain(name, type_=File)
return self.contain(actual, type_=File)

@hidetraceback
def contain_folder(self, name: str) -> None:
def contain_folder(self, actual: str) -> None:
"""
Check if folder contains folder with given name
"""
return self.contain(name, type_=Folder)
return self.contain(actual, type_=Folder)

@assertion
def exist(self) -> None:
Expand Down
99 changes: 58 additions & 41 deletions src/expycted/internals/function.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
from typing import Any, Callable, Type

from expycted.internals.base import BaseExpectation
from expycted.internals.utils import hidetraceback

assertion_texts = {
"to_raise": "Expected function `{function}` to raise {exc} when called with: {arguments}",
"to_return": "Expected function {function} to return {value} when called with: {arguments}",
"to_return_type": "Expected value ({value}) returned by function {function} to be of type {type} when called with: {arguments}",
}


class Function:
def __init__(self, function: Callable):
self.function = function
def __init__(self, expected: Callable):
self.expected = expected

def to_raise(self, exception: Type[Exception] = Exception):
def to_raise(self, exception: Type[Exception] = None):
"""Check if the function raises the exception
Args:
exception (Exception): Exception to expect
"""
return ToRaise(exception=exception, function=self.function)
return ToRaise(
expected=self.expected,
exception=exception if exception else Exception,
)

def to_return(self, value: Any = None, type_of_value: type = None):
"""Check if the function returns provided value or type
Expand All @@ -35,10 +33,13 @@ def to_return(self, value: Any = None, type_of_value: type = None):
raise ValueError(
"You must specify either value or type_of_value in to_return function"
)
else:
return ToReturn(
value=value, type_of_value=type_of_value, function=self.function
)

return ToReturn(
expected=self.expected,
value=value,
type_of_value=type_of_value,
)


def format_args_kwargs(args: Any, kwargs: Any) -> str:
"""Format arguments and keyword arguments to string
Expand All @@ -52,16 +53,19 @@ def format_args_kwargs(args: Any, kwargs: Any) -> str:
"""
args_str = ", ".join(map(str, args))
kwargs_str = ", ".join(
map(lambda x: "{}={}".format(x[0], x[1]), kwargs.items())
map(lambda x: f"{x[0]}={x[1]}", kwargs.items())
)

return f"\n\t- arguments: {args_str} \n\t- keyword arguments: {kwargs_str}"

class ToRaise:
function: Callable
exception: Type[Exception]

def __init__(self, exception: Type[Exception], function: Callable):
self.function = function
class ToRaise(BaseExpectation):
_ASSERTION_MESSAGES = {
"to_raise": "Expected function `{expected}` to raise {actual} when called with: {arguments}",
}

def __init__(self, expected: Callable, exception: Type[Exception]):
super().__init__(expected)
self.exception = exception

@hidetraceback
Expand All @@ -72,12 +76,17 @@ def when_called_with(self, *args, **kwargs):
AssertionError: When function doesn't raise the expected exception AssertionError is raised
"""
try:
self.function(*args, **kwargs)
self.expected(*args, **kwargs)
except Exception as e:
assert issubclass(type(e), self.exception), assertion_texts["to_raise"].format(
function=self.function.__name__,
exc=self.exception,
arguments=format_args_kwargs(args, kwargs))
self._assert(
issubclass(type(e), self.exception),
self._message(
"to_raise",
self.exception,
expected=self.expected.__name__,
arguments=format_args_kwargs(args, kwargs)
)
)
else:
raise AssertionError(
f"Expected '{self.exception}' to be raised, but nothing was raised"
Expand All @@ -86,13 +95,14 @@ def when_called_with(self, *args, **kwargs):
when_called_with_args = when_called_with_arguments = when_called_with


class ToReturn:
function: Callable
value: Any
type_of_value: type
class ToReturn(BaseExpectation):
_ASSERTION_MESSAGES = {
"to_return": "Expected function {expected} to return {actual} when called with: {arguments}",
"to_return_type": "Expected value ({actual}) returned by function {expected} to be of type {type} when called with: {arguments}",
}

def __init__(self, function: Callable, value, type_of_value):
self.function = function
def __init__(self, expected: Callable, value, type_of_value):
super().__init__(expected)
self.value = value
self.type_of_value = type_of_value

Expand All @@ -103,17 +113,24 @@ def when_called_with(self, *args, **kwargs):
Raises:
AssertionError: When function value or type_of_value is not matched AssertionError is raised
"""
ret = self.function(*args, **kwargs)
ret = self.expected(*args, **kwargs)

substitutions = dict(
actual=self.value,
expected=self.expected.__name__,
arguments=format_args_kwargs(args, kwargs)
)

if self.value is not None:
assert ret == self.value, assertion_texts["to_return"].format(
function=self.function.__name__,
value=self.value,
arguments=format_args_kwargs(args, kwargs))
self._assert(
ret == self.value,
self._message("to_return", **substitutions)
)

if self.type_of_value is not None:
assert type(ret) == self.type_of_value, assertion_texts["to_return_type"].format(
function=self.function.__name__,
value=self.value,
arguments=format_args_kwargs(args, kwargs),
type=self.type_of_value)
self._assert(
type(ret) == self.type_of_value,
self._message("to_return", type=self.type_of_value, **substitutions)
)

when_called_with_args = when_called_with_arguments = when_called_with
Loading

0 comments on commit 69e4a3d

Please sign in to comment.