Merge lp:~thomir/unity/wait_for-to-use-testtools-exception into lp:unity

Proposed by Thomi Richards on 2012-04-16
Status: Superseded
Proposed branch: lp:~thomir/unity/wait_for-to-use-testtools-exception
Merge into: lp:unity
Prerequisite: lp:~thomir/unity/autopilot-attribute-feature
Diff against target: 36 lines (+31/-0)
1 file modified
tests/autopilot/autopilot/matchers/__init__.py (+31/-0)
To merge this branch: bzr merge lp:~thomir/unity/wait_for-to-use-testtools-exception
Reviewer Review Type Date Requested Status
Tim Penhey (community) 2012-04-16 Needs Fixing on 2012-04-18
Alex Launi (community) Approve on 2012-04-17
Review via email: mp+102198@code.launchpad.net

This proposal has been superseded by a proposal from 2012-04-18.

Commit Message

Extend the autopilot wait_for feature to use testtools matcher instances as well as ordinary values. Also added an 'Eventually' matcher which makes tests more explicit.

Description of the Change

We'd like to be able to use testtools.matchers class instances with the new wait_for feature. Currently the wait_for feature allows us to do this:

emulator.attribute.wait_for(expected_value)

Which will wait until 'attribute' is equal to 'expected_value'. We can now extend this to use any testtools matcher object, for example:

emulator.attribute.wait_for(LessThan(123))
 - or -
emulator.attribute.wait_for(In(['several','possible','accepted','values'])

This makes the wait_for feature considerably more powerful.

To post a comment you must log in.
Tim Penhey (thumper) wrote :

Given that people can write matchers that are not in the testtools class, I think a better check would be to see if it had the match method.

# Remember hasattr is dangerous.
match_func = getattr(expected_value, 'match', None)
if callable(match_func)...

If expected_value isn't a matcher, make it one by:
  expected_value = Equals(expected_value)
then you don't need to have two code paths inside the time loop.

review: Needs Fixing
Thomi Richards (thomir) wrote :

Done.

Alex Launi (alexlauni) wrote :

Looks rad!

review: Approve
Unity Merger (unity-merger) wrote :

No proposals found for merge of lp:~thomir/unity/autopilot-attribute-feature into lp:unity.

Tim Penhey (thumper) wrote :

> if not wait_fun:

You shouldn't use a bool check here. What if the object had an attribute called wait_for that returned "foo"?

Instead use:

if wait_fun is None:
  raise...

review: Needs Fixing
2237. By Thomi Richards on 2012-04-18

Fixed code from review.

2238. By Thomi Richards on 2012-04-18

Fixed code from review.

2239. By Thomi Richards on 2012-04-18

Check match and wait_for attribute are callables.:

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'tests/autopilot/autopilot/matchers'
2=== added file 'tests/autopilot/autopilot/matchers/__init__.py'
3--- tests/autopilot/autopilot/matchers/__init__.py 1970-01-01 00:00:00 +0000
4+++ tests/autopilot/autopilot/matchers/__init__.py 2012-04-17 21:23:20 +0000
5@@ -0,0 +1,31 @@
6+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
7+# Copyright 2012 Canonical
8+# Author: Thomi Richards
9+#
10+# This program is free software: you can redistribute it and/or modify it
11+# under the terms of the GNU General Public License version 3, as published
12+# by the Free Software Foundation.
13+
14+"Autopilot-specific matchers."
15+
16+from testtools.matchers import Matcher
17+
18+
19+class Eventually(Matcher):
20+ """Asserts that a value will eventually equal a given Matcher object."""
21+
22+ def __init__(self, matcher):
23+ super(Eventually, self).__init__()
24+ match_fun = getattr(matcher, 'match', None)
25+ if not match_fun:
26+ raise TypeError("Eventually must be called with a testtools matcher argument.")
27+ self.matcher = matcher
28+
29+ def match(self, value):
30+ wait_fun = getattr(value, 'wait_for', None)
31+ if not wait_fun:
32+ raise TypeError("Eventually can only be used against autopilot attributes that have a wait_for funtion.")
33+ value.wait_for(self.matcher)
34+
35+ def __str__(self):
36+ return "Eventually " + str(self.matcher)