Skip to content

Commit

Permalink
presents general improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
gabrielfalcao committed Jan 1, 2024
1 parent ff0cfe1 commit 97eb021
Show file tree
Hide file tree
Showing 9 changed files with 396 additions and 599 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ docs: html-docs
$(OPEN_COMMAND) docs/build/html/index.html

test tests: clean | $(VENV)/bin/pytest # $(VENV)/bin/nosetests # @$(VENV)/bin/nosetests --rednose --immediate -vv --with-coverage --cover-package=sure
@$(VENV)/bin/pytest -vv --cov=sure --ignore tests/crashes tests
@$(VENV)/bin/pytest --cov=sure --ignore tests/crashes tests
$(MAIN_CLI_PATH) --special-syntax --with-coverage --cover-branches --cover-module=sure --immediate tests/

# run main command-line tool
Expand Down
4 changes: 2 additions & 2 deletions docs/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ This project adheres to `Semantic Versioning <http://semver.org/>`__.
--------

- Presents better documentation
- Drops support to Python 2
- Drops support to Python 2 obliterates the ``sure.compat`` module
- Introduces the modules ``sure.doubles``, ``sure.doubles.fakes`` and
``sure.doubles.stubs``
- Moves the class ``sure.compat.FakeOrderedDict`` into the module

``sure.doubles.fakes``
- Sure’s featured synctactic-sugar of injecting/monkey-patching
``.should``, ``.should_not``, et cetera methods into
Expand Down
19 changes: 9 additions & 10 deletions sure/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
from sure.core import DeepExplanation
from sure.core import _get_file_name
from sure.core import _get_line_number
from sure.core import safe_repr
from sure.errors import SpecialSyntaxDisabledError
from sure.errors import InternalRuntimeError
from sure.doubles.dummies import anything
Expand Down Expand Up @@ -84,7 +83,7 @@ def __getattr__(self, attr):
not_here_error
% (
attr,
safe_repr(self.__varnames__),
repr(self.__varnames__),
)
)

Expand Down Expand Up @@ -413,8 +412,8 @@ def wrapper(self, *args, **kw):

msg = "{0}({1}) failed".format(
func.__name__,
", ".join(map(safe_repr, args)),
", ".join(["{0}={1}".format(k, safe_repr(kw[k])) for k in kw]),
", ".join(map(repr, args)),
", ".join(["{0}={1}".format(k, repr(kw[k])) for k in kw]),
)
assert value, msg
return value
Expand Down Expand Up @@ -559,10 +558,10 @@ def callable(self):
if self.negative:
assert not callable(
self.obj
), "expected `{0}` to not be callable but it is".format(safe_repr(self.obj))
), "expected `{0}` to not be callable but it is".format(repr(self.obj))
else:
assert callable(self.obj), "expected {0} to be callable".format(
safe_repr(self.obj)
repr(self.obj)
)

return True
Expand Down Expand Up @@ -641,7 +640,7 @@ def key(self, name):
@assertionproperty
def empty(self):
obj = self.obj
representation = safe_repr(obj)
representation = repr(obj)
length = len(obj)
if self.negative:
assert length > 0, "expected `{0}` to not be empty".format(representation)
Expand Down Expand Up @@ -784,8 +783,8 @@ def equal(self, what, epsilon=None):
if error:
return True

msg = "%s should differ from %s, but is the same thing"
raise AssertionError(msg % (safe_repr(obj), safe_repr(what)))
msg = "%s should differ from %s"
raise AssertionError(msg % (repr(obj), repr(what)))

else:
if not error:
Expand Down Expand Up @@ -1220,7 +1219,7 @@ def _new_dir(*obj):

if len(obj) > 1:
raise TypeError(
"dir expected at most 1 arguments, got {0}".format(len(obj))
"builtins.dir expected at most 1 arguments, got {0}".format(len(obj))
)
patched = []
try:
Expand Down
47 changes: 1 addition & 46 deletions sure/compat.py
Original file line number Diff line number Diff line change
@@ -1,49 +1,4 @@
# -*- coding: utf-8 -*-
import six

try:
from collections.abc import Iterable
except ImportError:
from collections import Iterable

from collections.abc import Iterable
from sure.terminal import red, green, yellow


def compat_repr(object_repr):
return object_repr


def _obj_with_safe_repr(obj):
if isinstance(obj, dict):
ret = {}
try:
keys = sorted(obj.keys())
except TypeError: # happens for obj types which are not orderable, like ``Enum``
keys = obj.keys()
for key in keys:
ret[_obj_with_safe_repr(key)] = _obj_with_safe_repr(obj[key])
elif isinstance(obj, list):
ret = []
for x in obj:
if isinstance(x, dict):
ret.append(_obj_with_safe_repr(x))
else:
ret.append(x)
else:
ret = obj
return ret


def safe_repr(val):
try:
if isinstance(val, dict):
# We special case dicts to have a sorted __repr__. This makes testing
# significantly easier
val = _obj_with_safe_repr(val)
ret = repr(val)
except UnicodeEncodeError:
ret = red('a %r that cannot be represented' % type(val))
else:
ret = green(ret)

return ret
39 changes: 16 additions & 23 deletions sure/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,12 @@
from unittest.mock import _CallList

from sure.terminal import red, green, yellow
from sure.compat import safe_repr
from sure.doubles.dummies import Anything


class DeepExplanation(text_type):
def get_header(self, X, Y, suffix):
header = f"given\nX = {safe_repr(X)}\n and\nY = {safe_repr(Y)}\n{text_type(suffix)}"
header = f"X = {repr(X)}\n and\nY = {repr(Y)}\n{text_type(suffix)}"
return yellow(header).strip()

def get_assertion(self, X, Y):
Expand All @@ -49,10 +48,10 @@ class DeepComparison(object):
def __init__(self, X, Y, epsilon=None, parent=None):
self.complex_cmp_funcs = {
float: self.compare_floats,
dict: self.compare_dicts,
dict: self.compare_ordered_dicts,
list: self.compare_iterables,
tuple: self.compare_iterables,
OrderedDict: self.compare_ordereddict
OrderedDict: self.compare_ordered_dicts
}

self.operands = X, Y
Expand All @@ -76,8 +75,8 @@ def compare_generic(self, X, Y, msg_format='X{0} != Y{1}'):
if X == Y:
return True
else:
m = msg_format.format(red(c.current_X_keys), green(c.current_Y_keys))
return DeepExplanation(m)
msg = msg_format.format(red(c.current_X_keys), green(c.current_Y_keys))
return DeepExplanation(msg)

def compare_floats(self, X, Y):
c = self.get_context()
Expand All @@ -87,11 +86,14 @@ def compare_floats(self, X, Y):
if abs(X - Y) <= self.epsilon:
return True
else:
m = 'X{0}±{1} != Y{2}±{3}'.format(
red(c.current_X_keys), self.epsilon, green(c.current_Y_keys), self.epsilon)
return DeepExplanation(m)
msg = 'X{0}±{1} != Y{2}±{3}'.format(
red(c.current_X_keys),
self.epsilon, green(c.current_Y_keys),
self.epsilon
)
return DeepExplanation(msg)

def compare_dicts(self, X, Y):
def compare_ordered_dicts(self, X, Y):
c = self.get_context()

x_keys = list(X.keys())
Expand All @@ -102,15 +104,15 @@ def compare_dicts(self, X, Y):
if diff_x:
msg = "X{0} has the key {1!r} whereas Y{2} does not".format(
red(c.current_X_keys),
safe_repr(diff_x[0]),
repr(diff_x[0]),
green(c.current_Y_keys),
)
return DeepExplanation(msg)

elif diff_y:
msg = "X{0} does not have the key {1!r} whereas Y{2} has it".format(
red(c.current_X_keys),
safe_repr(diff_y[0]),
repr(diff_y[0]),
green(c.current_Y_keys)
)
return DeepExplanation(msg)
Expand All @@ -133,19 +135,10 @@ def compare_dicts(self, X, Y):
if isinstance(instance, DeepExplanation):
return instance

def compare_ordereddict(self, X, Y):
"""Compares two instances of an OrderedDict."""

# check if OrderedDict instances have the same keys and values
instance = self.compare_dicts(X, Y)
if isinstance(instance, DeepExplanation):
return instance

# check if the order of the keys is the same
for i, j in zip(X.items(), Y.items()):
if i[0] != j[0]:
c = self.get_context()
msg = "X{0} and Y{1} are in a different order".format(
msg = "X{0} and Y{1} appear have keys in different order".format(
red(c.current_X_keys), green(c.current_Y_keys)
)
return DeepExplanation(msg)
Expand All @@ -168,7 +161,7 @@ def get_keys(i):
if not i:
return ''

return '[{0}]'.format(']['.join(map(safe_repr, i)))
return '[{0}]'.format(']['.join(map(repr, i)))

class ComparisonContext:
current_X_keys = get_keys(X_keys)
Expand Down
4 changes: 2 additions & 2 deletions sure/original.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from pprint import pformat
from functools import wraps
from typing import Union
from collections.abc import Iterable


try:
Expand All @@ -37,7 +38,6 @@
from sure.core import _get_file_name
from sure.core import _get_line_number
from sure.core import itemize_length
from sure.compat import Iterable


def identify_callable_location(callable_object):
Expand Down Expand Up @@ -160,7 +160,7 @@ def raises(self, exc, msg=None):
if isinstance(msg, string_types) and msg not in err:
raise AssertionError('''
%r raised %s, but the exception message does not
match.\n\nEXPECTED:\n%s\n\nGOT:\n%s'''.strip() % (
match.\n\nEXPECTATION:\n%s\n\nACTUAL:\n%s'''.strip() % (
self._src,
type(e).__name__,
msg, err))
Expand Down

0 comments on commit 97eb021

Please sign in to comment.