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 ()
- 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')