summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Collins <robertc@robertcollins.net>2009-06-18 20:36:00 +1000
committerRobert Collins <robertc@robertcollins.net>2009-06-18 20:36:00 +1000
commit1193819c86eb94804733df982f8b8cada6b3f3a3 (patch)
treea9c31d3fcb95e6905c91a165ad73788f444bdea6
parentedb40a649dcae53acfa12932ccddaf99d66b0b1c (diff)
parentd42f74cedc8bf1811efc2e91fbcc29ea6152c93c (diff)
downloadtestresources-1193819c86eb94804733df982f8b8cada6b3f3a3.tar.gz
Merge and simply James Henstridge's reset patch.
-rw-r--r--NEWS5
-rw-r--r--lib/testresources/__init__.py22
-rw-r--r--lib/testresources/tests/test_test_resource.py58
3 files changed, 77 insertions, 8 deletions
diff --git a/NEWS b/NEWS
index 004e376..e78c696 100644
--- a/NEWS
+++ b/NEWS
@@ -19,6 +19,11 @@ IN DEVELOPMENT
* Expanded TODO. (Jonathan Lange)
+ * Resources can now be reset by overriding TestResource.reset, which for
+ some resources is significantly cheaper. If checking for dirtiness is
+ expensive, isDirty can also be overridden.
+ (James Henstridge, Robert Collins)
+
* Started keeping a NEWS file! (Jonathan Lange)
BUG FIXES:
diff --git a/lib/testresources/__init__.py b/lib/testresources/__init__.py
index 4bc7ef4..5ef36ca 100644
--- a/lib/testresources/__init__.py
+++ b/lib/testresources/__init__.py
@@ -247,7 +247,7 @@ class TestResource(object):
if self._uses == 0:
self._setResource(self._make_all())
elif self.isDirty():
- self._resetResource(self._currentResource)
+ self._setResource(self.reset(self._currentResource))
self._uses += 1
return self._currentResource
@@ -305,9 +305,23 @@ class TestResource(object):
result.append(self)
return result
- def _resetResource(self, old_resource):
- self._clean_all(old_resource)
- self._setResource(self._make_all())
+ def reset(self, old_resource):
+ """Override this to reset resources.
+
+ By default, the resource will be cleaned then remade if it had
+ previously been `dirtied`.
+
+ This function needs to take the dependent resource stack into
+ consideration as _make_all and _clean_all do.
+
+ :return: The new resource.
+ """
+ if self._dirty:
+ self._clean_all(old_resource)
+ resource = self._make_all()
+ else:
+ resource = old_resource
+ return resource
def _setResource(self, new_resource):
"""Set the current resource to a new value."""
diff --git a/lib/testresources/tests/test_test_resource.py b/lib/testresources/tests/test_test_resource.py
index a11c987..4d89469 100644
--- a/lib/testresources/tests/test_test_resource.py
+++ b/lib/testresources/tests/test_test_resource.py
@@ -57,6 +57,19 @@ class MockResource(testresources.TestResource):
return MockResourceInstance("Boo!")
+class MockResettableResource(MockResource):
+ """Mock resource that logs the number of reset calls too."""
+
+ def __init__(self):
+ MockResource.__init__(self)
+ self.resets = 0
+
+ def reset(self, resource):
+ self.resets += 1
+ resource._name += "!"
+ return resource
+
+
class TestTestResource(testtools.TestCase):
def testUnimplementedGetResource(self):
@@ -183,6 +196,33 @@ class TestTestResource(testtools.TestCase):
resource_manager.getResource()
self.assertEqual(1, resource_manager.makes)
+ def testGetResourceResetsUsedResource(self):
+ resource_manager = MockResettableResource()
+ resource_manager.getResource()
+ resource = resource_manager.getResource()
+ self.assertEqual(1, resource_manager.makes)
+ resource_manager.dirtied(resource)
+ resource_manager.getResource()
+ self.assertEqual(1, resource_manager.makes)
+ self.assertEqual(1, resource_manager.resets)
+ resource_manager.finishedWith(resource)
+
+ def testUsedResourceResetBetweenUses(self):
+ resource_manager = MockResettableResource()
+ # take two refs; like happens with OptimisingTestSuite.
+ resource_manager.getResource()
+ resource = resource_manager.getResource()
+ resource_manager.dirtied(resource)
+ resource_manager.finishedWith(resource)
+ # Get again, but its been dirtied.
+ resource = resource_manager.getResource()
+ resource_manager.finishedWith(resource)
+ resource_manager.finishedWith(resource)
+ # The resource is made once, reset once and cleaned once.
+ self.assertEqual(1, resource_manager.makes)
+ self.assertEqual(1, resource_manager.resets)
+ self.assertEqual(1, resource_manager.cleans)
+
def testFinishedWithDecrementsUses(self):
resource_manager = MockResource()
resource = resource_manager.getResource()
@@ -237,6 +277,8 @@ class TestTestResource(testtools.TestCase):
resource_manager.finishedWith(resource)
self.assertIs(resource, resource_manager._currentResource)
+ # The default implementation of reset() performs a make/clean if
+ # the dirty flag is set.
def testDirtiedSetsDirty(self):
resource_manager = MockResource()
resource = resource_manager.getResource()
@@ -257,15 +299,23 @@ class TestTestResource(testtools.TestCase):
resource_manager.finishedWith(resource1)
self.assertEqual(2, resource_manager.cleans)
- def testDirtyingResourceTriggersRemake(self):
+ def testDefaultResetMethodPreservesCleanResource(self):
+ resource_manager = MockResource()
+ resource = resource_manager.getResource()
+ self.assertEqual(1, resource_manager.makes)
+ self.assertEqual(False, resource_manager._dirty)
+ resource_manager.reset(resource)
+ self.assertEqual(1, resource_manager.makes)
+ self.assertEqual(0, resource_manager.cleans)
+
+ def testDefaultResetMethodRecreatesDirtyResource(self):
resource_manager = MockResource()
resource = resource_manager.getResource()
self.assertEqual(1, resource_manager.makes)
resource_manager.dirtied(resource)
- resource_manager.getResource()
- self.assertEqual(1, resource_manager.cleans)
+ resource_manager.reset(resource)
self.assertEqual(2, resource_manager.makes)
- self.assertEqual(False, resource_manager._dirty)
+ self.assertEqual(1, resource_manager.cleans)
def testDirtyingWhenUnused(self):
resource_manager = MockResource()