2015-01-27 16:53:17 +00:00
|
|
|
from __future__ import absolute_import, division, print_function
|
|
|
|
|
2015-01-29 11:20:17 +00:00
|
|
|
import pytest
|
2015-01-27 16:53:17 +00:00
|
|
|
|
|
|
|
import attr
|
|
|
|
|
2015-01-29 15:24:49 +00:00
|
|
|
from attr._compat import TYPE
|
2015-01-30 07:57:33 +00:00
|
|
|
from attr._make import Attribute, NOTHING
|
2015-01-27 16:53:17 +00:00
|
|
|
|
|
|
|
|
|
|
|
@attr.s
|
|
|
|
class C1(object):
|
2015-01-29 11:20:17 +00:00
|
|
|
x = attr.ib(validator=attr.validators.instance_of(int))
|
2015-01-27 22:03:42 +00:00
|
|
|
y = attr.ib()
|
2015-01-27 16:53:17 +00:00
|
|
|
|
|
|
|
|
|
|
|
foo = None
|
|
|
|
|
|
|
|
|
|
|
|
@attr.s()
|
|
|
|
class C2(object):
|
2015-01-29 21:32:41 +00:00
|
|
|
x = attr.ib(default=foo)
|
2015-01-29 22:10:56 +00:00
|
|
|
y = attr.ib(default=attr.Factory(list))
|
2015-01-27 16:53:17 +00:00
|
|
|
|
|
|
|
|
2015-02-18 20:31:32 +00:00
|
|
|
@attr.s
|
|
|
|
class Super(object):
|
|
|
|
x = attr.ib()
|
|
|
|
|
|
|
|
def meth(self):
|
|
|
|
return self.x
|
|
|
|
|
|
|
|
|
|
|
|
@attr.s
|
|
|
|
class Sub(Super):
|
|
|
|
y = attr.ib()
|
|
|
|
|
|
|
|
|
2015-01-27 16:53:17 +00:00
|
|
|
class TestDarkMagic(object):
|
|
|
|
"""
|
|
|
|
Integration tests.
|
|
|
|
"""
|
2015-01-29 20:55:25 +00:00
|
|
|
def test_fields(self):
|
2015-01-27 16:53:17 +00:00
|
|
|
"""
|
2015-01-29 20:55:25 +00:00
|
|
|
`attr.fields` works.
|
2015-01-27 16:53:17 +00:00
|
|
|
"""
|
2015-03-23 08:16:43 +00:00
|
|
|
assert (
|
2015-02-20 12:29:47 +00:00
|
|
|
Attribute(name="x", default=foo, validator=None,
|
|
|
|
repr=True, cmp=True, hash=True, init=True),
|
2015-01-30 16:48:34 +00:00
|
|
|
Attribute(name="y", default=attr.Factory(list), validator=None,
|
2015-02-20 12:29:47 +00:00
|
|
|
repr=True, cmp=True, hash=True, init=True),
|
2015-03-23 08:16:43 +00:00
|
|
|
) == attr.fields(C2)
|
2015-01-27 16:53:17 +00:00
|
|
|
|
2015-01-29 20:50:07 +00:00
|
|
|
def test_asdict(self):
|
2015-01-27 16:53:17 +00:00
|
|
|
"""
|
2015-01-29 20:50:07 +00:00
|
|
|
`attr.asdict` works.
|
2015-01-27 16:53:17 +00:00
|
|
|
"""
|
|
|
|
assert {
|
|
|
|
"x": 1,
|
|
|
|
"y": 2,
|
2015-01-29 20:50:07 +00:00
|
|
|
} == attr.asdict(C1(x=1, y=2))
|
2015-01-29 11:20:17 +00:00
|
|
|
|
|
|
|
def test_validator(self):
|
|
|
|
"""
|
|
|
|
`instance_of` raises `TypeError` on type mismatch.
|
|
|
|
"""
|
|
|
|
with pytest.raises(TypeError) as e:
|
|
|
|
C1("1", 2)
|
|
|
|
assert (
|
|
|
|
"'x' must be <{type} 'int'> (got '1' that is a <{type} "
|
|
|
|
"'str'>).".format(type=TYPE),
|
|
|
|
C1.x, int, "1",
|
|
|
|
) == e.value.args
|
2015-01-29 12:05:04 +00:00
|
|
|
|
|
|
|
def test_renaming(self):
|
|
|
|
"""
|
|
|
|
Private members are renamed but only in `__init__`.
|
|
|
|
"""
|
|
|
|
@attr.s
|
|
|
|
class C3(object):
|
|
|
|
_x = attr.ib()
|
|
|
|
|
|
|
|
assert "C3(_x=1)" == repr(C3(x=1))
|
2015-01-30 07:57:33 +00:00
|
|
|
|
|
|
|
def test_programmatic(self):
|
|
|
|
"""
|
|
|
|
`attr.make_class` works.
|
|
|
|
"""
|
|
|
|
PC = attr.make_class("PC", ["a", "b"])
|
2015-03-23 08:16:43 +00:00
|
|
|
assert (
|
2015-02-20 12:29:47 +00:00
|
|
|
Attribute(name="a", default=NOTHING, validator=None,
|
|
|
|
repr=True, cmp=True, hash=True, init=True),
|
|
|
|
Attribute(name="b", default=NOTHING, validator=None,
|
|
|
|
repr=True, cmp=True, hash=True, init=True),
|
2015-03-23 08:16:43 +00:00
|
|
|
) == attr.fields(PC)
|
2015-02-18 20:31:32 +00:00
|
|
|
|
|
|
|
def test_subclassing(self):
|
|
|
|
"""
|
2015-02-18 20:54:27 +00:00
|
|
|
Sub-classing does what you'd hope for.
|
2015-02-18 20:31:32 +00:00
|
|
|
"""
|
|
|
|
obj = object()
|
|
|
|
i = Sub(x=obj, y=2)
|
|
|
|
assert i.x is i.meth() is obj
|
|
|
|
assert i.y == 2
|
|
|
|
assert "Sub(x={obj}, y=2)".format(obj=obj) == repr(i)
|