Skip to content

Commit

Permalink
Finished documenting generators
Browse files Browse the repository at this point in the history
  • Loading branch information
Xion committed May 12, 2012
1 parent 78246b2 commit f5f2a0d
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 4 deletions.
16 changes: 16 additions & 0 deletions docs/arbitraries.rst
Expand Up @@ -116,6 +116,13 @@ Combinators

.. currentmodule:: pyqcy.arbitraries.combinators

If you want to have a generator that produces values of more than one type,
use the simple :func:`one_of` function or the more sophisticated
:func:`frequency` combinator.

For a simpler task of always choosing a value from a predefined
set of objects, the :func:`elements` function will come handy.

.. autofunction:: one_of(*generators)

.. autofunction:: frequency(*distribution)
Expand All @@ -128,10 +135,19 @@ Combinators
Data structures
---------------

For testing higher level code, it is often required to prepare more complex
input data and not just simple, uniform collections of elements. Even then,
it can be possible to avoid writing a custom generator if we use the
:func:`data` function.

.. autofunction:: data


Applying functions
------------------

Yet another way of combining generators is to use them as building blocks
for whole object *pipelines*. This is possible thanks to :func:`apply`
combinator.

.. autofunction:: apply
31 changes: 28 additions & 3 deletions pyqcy/arbitraries/__init__.py
Expand Up @@ -9,15 +9,35 @@

@optional_args
class arbitrary(object):
"""@arbitrary decorator which can be applied on functions
that are intended to output "random" (arbitrary) values
"""Decorator to be applied on functions in order to turn
them into generators of arbitrary ("random") values
of given type.
:param type_: Type of values generated by the function
The `type_` argument is optional. If it's provided,
then objects returned by the function will be checked against
this type. Furthermore, it will be possible to use the type
directly when defining properties, e.g.::
from pyqcy import *
@arbitrary(MyClass)
def my_class():
return MyClass()
@qc
def my_class_works(obj=MyClass):
assert obj.is_valid()
"""
# Dictionary mapping types into
# generators of arbitrary values for those types
registry = {}

def __init__(self, type_=None):
if type_ is not None and not isinstance(type_, type):
raise TypeError("%r (a `%s`) is not a type" % (
type_, type(type_).__name__))
self.type_ = type_

def __call__(self, func):
Expand Down Expand Up @@ -67,12 +87,17 @@ def wrapper(*args, **kwargs):

return wrapper

def __coerce_to_arbitraries(self, args=[], kwargs={}):
def __coerce_to_arbitraries(self, args=None, kwargs=None):
"""Ensures given list and dictionary of positional and keyword
arguments contains appropriate arbitrary values' generators.
Elements that cannot be reasonably coerced into arbitraries
are left unchanged.
Returns a tuple of (args, kwargs) with coerced arguments.
"""
args = args or []
kwargs = kwargs or {}
args = [to_arbitrary(arg) if is_arbitrary(arg) else arg
for arg in args]
kwargs = dict((k, to_arbitrary(v) if is_arbitrary(v) else v)
Expand Down
2 changes: 1 addition & 1 deletion pyqcy/arbitraries/combinators.py
Expand Up @@ -57,7 +57,7 @@ def generator():
def data(schema):
"""Generator that outputs data structures conforming to given schema.
:param schema: A list of dictionary that contains either
:param schema: A list or dictionary that contains either
immediate values or other generators.
.. note::
Expand Down

0 comments on commit f5f2a0d

Please sign in to comment.