Usage¶
Here’s how to simply and quickly create sample objects using chide
.
For the examples, these two classes will be used:
class ClassOne(object):
def __init__(self, x, y):
self.x, self.y = x, y
class ClassTwo(object):
def __init__(self, a, b):
self.a, self.b = a, b
Creating sample objects¶
We can set up a registry of sample values as follows:
from chide import Collection
samples = Collection({
ClassOne: {'x': 1, 'y': 2},
ClassTwo: {'a': 1, 'b': ClassOne},
})
Now we can quickly make sample objects:
>>> samples.make(ClassOne)
<ClassOne ...>
>>> _.x, _.y
(1, 2)
We can provide our own overrides if we want:
>>> samples.make(ClassOne, y=3)
<ClassOne ...>
>>> _.x, _.y
(1, 3)
We can also create nested trees of objects:
>>> samples.make(ClassTwo)
<ClassTwo ...>
>>> _.b
<ClassOne ...>
These can also be overridden with another sample object:
>>> samples.make(ClassTwo, b=samples.make(ClassOne, x=-1))
<ClassTwo ...>
>>> _.b.x
-1
They can also be directly overridden with an appropriate instance:
>>> samples.make(ClassTwo, b=ClassOne(11, 3))
<ClassTwo ...>
>>> _.b.x, _.b.y
(11, 3)
Sets of unique sample objects¶
In some circumstances, you may need a set of related objects where the objects have a notion of an identifier, and only one object of each type with a given identifier can exist. Here’s an oversimplified example:
class Person(object):
def __init__(self, name, address):
self.name = name
self.address = address
class Address(object):
seen = set()
def __init__(self, value):
if value in self.seen:
raise Exception(value)
self.seen.add(value)
self.value = value
So, given that there can be multiple people but each address can only
be instantiated once we want all people used in tests, by default, to be at
the same address. We can do this using a Set
and an identify
function as follows:
from chide import Collection, Set
data = Collection({
Person: {'name': 'Fred', 'address': Address},
Address: {'value': 'some place in the clouds'},
})
def identify(type_, attrs):
if type_ is Address:
return attrs['value']
samples = Set(data, identify)
Now, we can create multiple sample people without having to specify their address:
>>> person1 = samples.get(Person, name='Chris')
>>> person2 = samples.get(Person, name='Kirsty')
They both just end up at the same address:
>>> person1.address.value
'some place in the clouds'
>>> person2.address.value
'some place in the clouds'
>>> person1.address is person2.address
True
We can still create people with different addresses:
>>> person3 = samples.get(Person, name='Fred', address=Address('elsewhere'))
>>> person3.address.value
'elsewhere'
The Set
can also be used to make sure that only one of each
address is used:
>>> person4 = samples.get(Person, name='Bob', address=samples.get(Address, value='here'))
>>> person5 = samples.get(Person, name='Joe', address=samples.get(Address, value='here'))
This way, we don’t have to manually ensure that only one address for here exists.
You’ll notice that we can still get multiple people with the same name from the
Set
:
>>> person6 = samples.get(Person, name='Chris')
>>> person1 is person6
False
This because the identify()
function above returns None
for all types
other than Address
. Returning None
from identify()
is the
way to indicate that a new object should be returned, regardless of the
attributes it has.