2015-01-27 16:53:17 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
from __future__ import absolute_import, division, print_function
|
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
2015-01-28 10:15:40 +00:00
|
|
|
from attr._funcs import ls, has, to_dict
|
2015-01-27 16:53:17 +00:00
|
|
|
from attr._make import (
|
|
|
|
Attribute,
|
|
|
|
_make_attr,
|
2015-01-28 10:35:16 +00:00
|
|
|
_add_methods,
|
2015-01-27 16:53:17 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
2015-01-28 10:35:16 +00:00
|
|
|
@_add_methods
|
2015-01-27 16:53:17 +00:00
|
|
|
class C(object):
|
|
|
|
x = _make_attr()
|
|
|
|
y = _make_attr()
|
|
|
|
|
|
|
|
|
|
|
|
class TestLs(object):
|
2015-01-28 10:15:40 +00:00
|
|
|
"""
|
|
|
|
Tests for `ls`.
|
|
|
|
"""
|
2015-01-27 16:53:17 +00:00
|
|
|
def test_instance(self):
|
|
|
|
"""
|
2015-01-28 13:36:11 +00:00
|
|
|
Raises `TypeError` on non-classes.
|
2015-01-27 16:53:17 +00:00
|
|
|
"""
|
2015-01-28 13:36:11 +00:00
|
|
|
with pytest.raises(TypeError) as e:
|
|
|
|
ls(C(1, 2))
|
|
|
|
assert "Passed object must be a class." == e.value.args[0]
|
2015-01-27 16:53:17 +00:00
|
|
|
|
|
|
|
def test_handler_non_attrs_class(self):
|
|
|
|
"""
|
2015-01-28 13:36:11 +00:00
|
|
|
Raises `ValueError` if passed a non-``attrs`` instance.
|
2015-01-27 16:53:17 +00:00
|
|
|
"""
|
2015-01-28 13:36:11 +00:00
|
|
|
with pytest.raises(ValueError) as e:
|
2015-01-27 16:53:17 +00:00
|
|
|
ls(object)
|
|
|
|
assert (
|
|
|
|
"{o!r} is not an attrs-decorated class.".format(o=object)
|
|
|
|
) == e.value.args[0]
|
|
|
|
|
|
|
|
def test_ls(self):
|
|
|
|
"""
|
2015-01-28 13:36:11 +00:00
|
|
|
Returns a list of `Attribute`a.
|
2015-01-27 16:53:17 +00:00
|
|
|
"""
|
|
|
|
assert all(isinstance(a, Attribute) for a in ls(C))
|
|
|
|
|
|
|
|
|
|
|
|
class TestToDict(object):
|
2015-01-28 10:15:40 +00:00
|
|
|
"""
|
|
|
|
Tests for `to_dict`.
|
|
|
|
"""
|
2015-01-27 16:53:17 +00:00
|
|
|
def test_shallow(self):
|
|
|
|
"""
|
|
|
|
Shallow to_dict returns correct dict.
|
|
|
|
"""
|
|
|
|
assert {
|
|
|
|
"x": 1,
|
|
|
|
"y": 2,
|
|
|
|
} == to_dict(C(x=1, y=2), False)
|
|
|
|
|
|
|
|
def test_recurse(self):
|
|
|
|
"""
|
|
|
|
Deep to_dict returns correct dict.
|
|
|
|
"""
|
|
|
|
assert {
|
|
|
|
"x": {"x": 1, "y": 2},
|
|
|
|
"y": {"x": 3, "y": 4},
|
|
|
|
} == to_dict(C(
|
|
|
|
C(1, 2),
|
|
|
|
C(3, 4),
|
|
|
|
))
|
2015-01-28 10:15:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
class TestHas(object):
|
|
|
|
"""
|
|
|
|
Tests for `has`.
|
|
|
|
"""
|
|
|
|
def test_positive(self):
|
|
|
|
"""
|
|
|
|
Returns `True` on decorated classes.
|
|
|
|
"""
|
|
|
|
assert has(C)
|
|
|
|
|
|
|
|
def test_positive_empty(self):
|
|
|
|
"""
|
|
|
|
Returns `True` on decorated classes even if there are no attributes.
|
|
|
|
"""
|
2015-01-28 10:35:16 +00:00
|
|
|
@_add_methods
|
2015-01-28 10:15:40 +00:00
|
|
|
class D(object):
|
|
|
|
pass
|
|
|
|
|
|
|
|
assert has(D)
|
|
|
|
|
|
|
|
def test_negative(self):
|
|
|
|
"""
|
|
|
|
Returns `False` on non-decorated classes.
|
|
|
|
"""
|
|
|
|
assert not has(object)
|