fudge.inspector

Value inspectors that can be passed to fudge.Fake.with_args() for more expressive argument matching.

As a mnemonic device, an instance of the fudge.inspector.ValueInspector is available as “arg” :

>>> import fudge
>>> from fudge.inspector import arg
>>> image = fudge.Fake("image").expects("save").with_args(arg.endswith(".jpg"))

In other words, this declares that the first argument to image.save() should end with the suffix “.jpg”

class fudge.inspector.ValueInspector

Dispatches tests to inspect values.

any()

Match any value.

This is pretty much just a placeholder for when you want to inspect multiple arguments but don’t care about all of them.

>>> import fudge
>>> from fudge.inspector import arg
>>> db = fudge.Fake("db")
>>> db = db.expects("transaction").with_args(
...             "insert", isolation_level=arg.any())
...
>>> db.transaction("insert", isolation_level="lock")
>>> fudge.verify()

This also passes:

>>> db.transaction("insert", isolation_level="autocommit")
>>> fudge.verify()

The arg_not version will not match anything and is probably not very useful.

>>> import fudge
>>> from fudge.inspector import arg_not
>>> query = fudge.Fake('query').expects_call().with_args(
...     arg_not.any()
... )
>>> query('asdf')
Traceback (most recent call last):
...
AssertionError: fake:query((NOT) arg.any()) was called unexpectedly with args ('asdf')
>>> query()
Traceback (most recent call last):
...
AssertionError: fake:query((NOT) arg.any()) was called unexpectedly with args ()
any_value()

DEPRECATED: use arg.any()

contains(part)

Ensure that a value contains some part.

This is useful for when you only care that a substring or subelement exists in a value.

>>> import fudge
>>> from fudge.inspector import arg
>>> addressbook = fudge.Fake().expects("import_").with_args(
...                                     arg.contains("Baba Brooks"))
...
>>> addressbook.import_("Bill Brooks; Baba Brooks; Henry Brooks;")
>>> fudge.verify()

Since contains() just invokes the __in__() method, checking that a list item is present works as expected :

>>> colorpicker = fudge.Fake("colorpicker")
>>> colorpicker = colorpicker.expects("select").with_args(arg.contains("red"))
>>> colorpicker.select(["green","red","blue"])
>>> fudge.verify()

arg_not.contains matches an argument not containing some element.

>>> from fudge.inspector import arg_not
>>> colorpicker = colorpicker.expects('select').with_args(arg_not.contains('blue'))
>>> colorpicker.select('reddish')
>>> colorpicker.select(['red', 'green'])
>>> fudge.verify()

>>> colorpicker.select('blue-green')
Traceback (most recent call last):
...
AssertionError: fake:colorpicker.select(arg.contains('red'))[0] was called unexpectedly with args ('blue-green')
>>> colorpicker.select(['red', 'blue', 'green'])
Traceback (most recent call last):
...
AssertionError: fake:colorpicker.select((NOT) arg.contains('blue'))[1] was called unexpectedly with args (['red', 'blue', 'green'])
endswith(part)

Ensure that a value ends with some part.

This is useful for when values with dynamic parts that are hard to replicate.

>>> import fudge
>>> from fudge.inspector import arg
>>> tmpfile = fudge.Fake("tempfile").expects("mkname").with_args(
...                                             arg.endswith(".tmp"))
...
>>> tmpfile.mkname("7AakkkLazUUKHKJgh908JKjlkh.tmp")
>>> fudge.verify()

The arg_not version works as expected, matching arguments that do not end with the given element.

>>> from fudge.inspector import arg_not
>>> query = fudge.Fake('query').expects_call().with_args(arg_not.endswith('Ringo'))
>>> query('John, Paul, George and Steve')
>>> fudge.verify()
has_attr(**attributes)

Ensure that an object value has at least these attributes.

This is useful for testing that an object has specific attributes.

>>> import fudge
>>> from fudge.inspector import arg
>>> db = fudge.Fake("db").expects("update").with_args(arg.has_attr(
...                                                       first_name="Bob",
...                                                       last_name="James" ))
...
>>> class User:
...     first_name = "Bob"
...     last_name = "James"
...     job = "jazz musician" # this is ignored
...
>>> db.update(User())
>>> fudge.verify()

In case of error, the other object’s __repr__ will be invoked:

>>> class User:
...     first_name = "Bob"
...
...     def __repr__(self):
...         return repr(dict(first_name=self.first_name))
...
>>> db.update(User())
Traceback (most recent call last):
...
AssertionError: fake:db.update(arg.has_attr(first_name='Bob', last_name='James')) was called unexpectedly with args ({'first_name': 'Bob'})

When called as a method on arg_not, has_attr does the opposite, and ensures that the argument does not have the specified attributes.

>>> from fudge.inspector import arg_not
>>> class User:
...     first_name = 'Bob'
...     last_name = 'Dobbs'
>>> query = fudge.Fake('query').expects_call().with_args(
...     arg_not.has_attr(first_name='James')
... )
>>> query(User())
>>> fudge.verify()
isinstance(cls)

Check that a value is instance of specified class.

>>> import fudge
>>> from fudge.inspector import arg
>>> system = fudge.Fake("system")
>>> system = system.expects("set_status").with_args(arg.isinstance(str))
>>> system.set_status("active")
>>> fudge.verify()

Should return True if it’s allowed class or False if not.

>>> system.set_status(31337) 
Traceback (most recent call last):
...
AssertionError: fake:system.set_status(arg.isinstance('str')) was called unexpectedly with args (31337)
passes_test(test)

Check that a value passes some test.

For custom assertions you may need to create your own callable to inspect and verify a value.

>>> def is_valid(s):
...     if s in ('active','deleted'):
...         return True
...     else:
...         return False
...
>>> import fudge
>>> from fudge.inspector import arg
>>> system = fudge.Fake("system")
>>> system = system.expects("set_status").with_args(arg.passes_test(is_valid))
>>> system.set_status("active")
>>> fudge.verify()

The callable you pass takes one argument, the value, and should return True if it’s an acceptable value or False if not.

>>> system.set_status("sleep") 
Traceback (most recent call last):
...
AssertionError: fake:system.set_status(arg.passes_test(<function is_valid at...)) was called unexpectedly with args ('sleep')

If it makes more sense to perform assertions in your test function then be sure to return True :

>>> def is_valid(s):
...     assert s in ('active','deleted'), (
...         "Unexpected status value: %s" % s)
...     return True
...
>>> import fudge
>>> from fudge.inspector import arg
>>> system = fudge.Fake("system")
>>> system = system.expects("set_status").with_args(arg.passes_test(is_valid))
>>> system.set_status("sleep")
Traceback (most recent call last):
...
AssertionError: Unexpected status value: sleep

Using the inverted version, arg_not.passes_test, asserts that the argument does not pass the provided test.

>>> from fudge.inspector import arg_not
>>> query = fudge.Fake('query').expects_call().with_args(
...     arg_not.passes_test(lambda x: x > 10)
... )
>>> query(5)
>>> fudge.verify()
startswith(part)

Ensure that a value starts with some part.

This is useful for when values with dynamic parts that are hard to replicate.

>>> import fudge
>>> from fudge.inspector import arg
>>> keychain = fudge.Fake("keychain").expects("accept_key").with_args(
...                                                     arg.startswith("_key"))
...
>>> keychain.accept_key("_key-18657yojgaodfty98618652olkj[oollk]")
>>> fudge.verify()

Using arg_not.startswith instead ensures that arguments do not start with that part.

>>> from fudge.inspector import arg_not
>>> query = fudge.Fake('query').expects_call().with_args(
...     arg_not.startswith('asdf')
... )
>>> query('qwerty')
>>> fudge.verify()
class fudge.inspector.NotValueInspector

Inherits all the argument methods from ValueInspector, but inverts them to expect the opposite. See the ValueInspector method docstrings for examples.

__call__(thing)

This will match any value except the argument given.

>>> import fudge
>>> from fudge.inspector import arg, arg_not
>>> query = fudge.Fake('query').expects_call().with_args(
...     arg.any(),
...     arg_not('foobar')
... )
>>> query([1, 2, 3], 'asdf')
>>> query('asdf', 'foobar')
Traceback (most recent call last):
...
AssertionError: fake:query(arg.any(), arg_not(foobar)) was called unexpectedly with args ('asdf', 'foobar')