1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
"""
At the time of adding these tests, the implementation of add_parameter
had not changed since it was committed (f10b324 in July 2012). The tests
are checking that (not fully understood) implementation:
@classmethod
def _add_parameter(cls, param_name,param_obj):
'''
Add a new Parameter object into this object's class.
Supposed to result in a Parameter equivalent to one declared
in the class's source code.
'''
# CEBALERT: can't we just do
# setattr(cls,param_name,param_obj)? The metaclass's
# __setattr__ is actually written to handle that. (Would also
# need to do something about the params() cache. That cache
# is a pain, but it definitely improved the startup time; it
# would be worthwhile making sure no method except for one
# "add_param()" method has to deal with it (plus any future
# remove_param() method.)
type.__setattr__(cls,param_name,param_obj)
cls.__metaclass__._initialize_parameter(cls,param_name,param_obj)
# delete cached params()
try:
delattr(cls,'_%s__params'%cls.__name__)
except AttributeError:
pass
"""
import param
import pytest
def test_add_parameter_class():
class P(param.Parameterized):
x = param.Parameter()
P.param.add_parameter('y', param.Parameter())
assert 'y' in P.param
# Check the name is set
assert P.param.y.name == 'y'
def test_add_parameter_instance():
class P(param.Parameterized):
x = param.Parameter()
p = P()
p.param.add_parameter('y', param.Parameter())
assert 'y' in p.param
assert p.param.y.name == 'y'
def test_add_parameter_class_validation():
class P(param.Parameterized):
x = param.Parameter()
P.param.add_parameter('y', param.Number())
with pytest.raises(ValueError, match=r"Number parameter 'P.y' only takes numeric values, not <class 'str'>."):
P.y = 'test'
def test_add_parameter_instance_validation():
class P(param.Parameterized):
x = param.Parameter()
P.param.add_parameter('y', param.Number())
p = P()
with pytest.raises(ValueError, match=r"Number parameter 'P.y' only takes numeric values, not <class 'str'>."):
p.y = 'test'
def test_add_parameter_cache_cleared():
# Not sure why it's supposed to delete the Parameters cache, test it anyway
class P(param.Parameterized):
x = param.Parameter()
# Generate the cache
P.param.objects(instance=True)
assert 'x' in P._param__private.params
P.param.add_parameter('y', param.Parameter())
# Check the cache has been removed (not sure why)
assert not P._param__private.params
def test_add_parameter_subclass():
class A(param.Parameterized):
x = param.Parameter()
class B(A):
pass
B.param.add_parameter('y', param.Parameter())
assert 'y' not in A.param
assert 'y' in B.param
def test_add_parameter_override():
class P(param.Parameterized):
x = param.Parameter(default=1)
origin = P.param.x
new = param.Parameter(default=2)
P.param.add_parameter('x', new)
assert P.param.x.default == 2
assert P.param.x is new
assert P.param.x is not origin
def test_add_parameter_inheritance():
class A(param.Parameterized):
x = param.Parameter(default=1)
class B(A):
pass
B.param.add_parameter('x', param.Parameter(doc='some doc'))
assert B.param.x.default == 1
assert B.param.x.doc == 'some doc'
def test_add_parameter_watch_class():
class P(param.Parameterized):
x = param.Parameter()
P.param.add_parameter('y', param.Parameter())
acc = []
P.param.watch(lambda e: acc.append(e), 'y')
P.y = 1
assert len(acc) == 1
def test_add_parameter_watch_instance():
class P(param.Parameterized):
x = param.Parameter()
P.param.add_parameter('y', param.Parameter())
p = P()
acc = []
p.param.watch(lambda e: acc.append(e), 'y')
p.y = 1
assert len(acc) == 1
|