summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaphaël Barrois <raphael.barrois@polyconseil.fr>2011-05-16 14:48:23 +0200
committerRaphaël Barrois <raphael.barrois@polyconseil.fr>2011-05-16 14:48:23 +0200
commitf7cb0a040cab507541405d64efbf44b874acf207 (patch)
tree54f7eb2603bb21ff5e5410a3b634e6261763cae0
parentdf8b1e10e06a6a6faa15808caa7167f3a8361c55 (diff)
downloadfactory-boy-f7cb0a040cab507541405d64efbf44b874acf207.tar
factory-boy-f7cb0a040cab507541405d64efbf44b874acf207.tar.gz
Add SubFactories, and full testing.
Signed-off-by: Raphaël Barrois <raphael.barrois@polyconseil.fr>
-rw-r--r--factory/__init__.py3
-rw-r--r--factory/base.py12
-rw-r--r--factory/containers.py48
-rw-r--r--factory/declarations.py15
-rw-r--r--factory/test_base.py63
-rw-r--r--factory/test_containers.py212
-rw-r--r--factory/test_declarations.py47
7 files changed, 369 insertions, 31 deletions
diff --git a/factory/__init__.py b/factory/__init__.py
index bf0fca2..9a1513d 100644
--- a/factory/__init__.py
+++ b/factory/__init__.py
@@ -18,7 +18,7 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
-__version__ = '1.0.0' # Remember to change in setup.py as well!
+__version__ = '1.0.2' # Remember to change in setup.py as well!
__author__ = 'Mark Sandstrom <mark@deliciouslynerdy.com>'
from base import (
@@ -33,6 +33,7 @@ from declarations import (
LazyAttribute,
Sequence,
LazyAttributeSequence,
+ SubFactory,
lazy_attribute,
sequence,
lazy_attribute_sequence
diff --git a/factory/base.py b/factory/base.py
index e78ec6e..733b130 100644
--- a/factory/base.py
+++ b/factory/base.py
@@ -153,7 +153,7 @@ class BaseFactory(object):
return next_sequence
@classmethod
- def attributes(cls, **kwargs):
+ def attributes(cls, create=False, **kwargs):
"""Build a dict of attribute values, respecting declaration order.
The process is:
@@ -166,7 +166,11 @@ class BaseFactory(object):
attributes = {}
cls.sequence = cls._generate_next_sequence()
- return getattr(cls, CLASS_ATTRIBUTE_DECLARATIONS).build_attributes(cls, kwargs)
+ return getattr(cls, CLASS_ATTRIBUTE_DECLARATIONS).build_attributes(cls, create, kwargs)
+
+ @classmethod
+ def declarations(cls):
+ return DeclarationsHolder(getattr(cls, CLASS_ATTRIBUTE_DECLARATIONS))
@classmethod
def build(cls, **kwargs):
@@ -230,8 +234,8 @@ class Factory(BaseFactory):
@classmethod
def build(cls, **kwargs):
- return cls._build(**cls.attributes(**kwargs))
+ return cls._build(**cls.attributes(create=False, **kwargs))
@classmethod
def create(cls, **kwargs):
- return cls._create(**cls.attributes(**kwargs))
+ return cls._create(**cls.attributes(create=True, **kwargs))
diff --git a/factory/containers.py b/factory/containers.py
index 63be161..8aa9955 100644
--- a/factory/containers.py
+++ b/factory/containers.py
@@ -18,7 +18,10 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
-from declarations import OrderedDeclaration
+from declarations import OrderedDeclaration, SubFactory
+
+
+ATTR_SPLITTER = '__'
class ObjectParamsWrapper(object):
'''A generic container that allows for getting but not setting of attributes.
@@ -27,8 +30,8 @@ class ObjectParamsWrapper(object):
initialized = False
- def __init__(self, dict):
- self.dict = dict
+ def __init__(self, attrs):
+ self.attrs = attrs
self.initialized = True
def __setattr__(self, name, value):
@@ -39,7 +42,7 @@ class ObjectParamsWrapper(object):
def __getattr__(self, name):
try:
- return self.dict[name]
+ return self.attrs[name]
except KeyError:
raise AttributeError("The param '{0}' does not exist. Perhaps your declarations are out of order?".format(name))
@@ -88,9 +91,12 @@ class OrderedDeclarationDict(object):
class DeclarationsHolder(object):
"""Holds all declarations, ordered and unordered."""
- def __init__(self):
+ def __init__(self, defaults=None):
+ if not defaults:
+ defaults = {}
self._ordered = OrderedDeclarationDict()
self._unordered = {}
+ self.update_base(defaults)
def update_base(self, attrs):
"""Updates the DeclarationsHolder from a class definition.
@@ -119,10 +125,29 @@ class DeclarationsHolder(object):
except KeyError:
return self._ordered[key]
- def build_attributes(self, factory, extra):
+ def iteritems(self):
+ for pair in self._unordered.iteritems():
+ yield pair
+ for pair in self._ordered.iteritems():
+ yield pair
+
+ def items(self):
+ return list(self.iteritems())
+
+ def build_attributes(self, factory, create=False, extra=None):
"""Build the list of attributes based on class attributes."""
+ if not extra:
+ extra = {}
+
attributes = {}
- # For fields in _unordered, use the value from attrs if any; otherwise,
+ sub_fields = {}
+ for key in list(extra.keys()):
+ if ATTR_SPLITTER in key:
+ cls_name, attr_name = key.split(ATTR_SPLITTER, 1)
+ if cls_name in self:
+ sub_fields.setdefault(cls_name, {})[attr_name] = extra.pop(key)
+
+ # For fields in _unordered, use the value from extra if any; otherwise,
# use the default value.
for key, value in self._unordered.iteritems():
attributes[key] = extra.get(key, value)
@@ -130,8 +155,13 @@ class DeclarationsHolder(object):
if key in extra:
attributes[key] = extra[key]
else:
- wrapper = ObjectParamsWrapper(attributes)
- attributes[key] = value.evaluate(factory, wrapper)
+ if isinstance(value, SubFactory):
+ new_value = value.evaluate(factory, create,
+ sub_fields.get(key, {}))
+ else:
+ wrapper = ObjectParamsWrapper(attributes)
+ new_value = value.evaluate(factory, wrapper)
+ attributes[key] = new_value
attributes.update(extra)
return attributes
diff --git a/factory/declarations.py b/factory/declarations.py
index 4c44e0c..a4a62af 100644
--- a/factory/declarations.py
+++ b/factory/declarations.py
@@ -75,6 +75,21 @@ class LazyAttributeSequence(Sequence):
def evaluate(self, factory, attributes):
return self.function(attributes, self.type(factory.sequence))
+class SubFactory(OrderedDeclaration):
+ """Base class for attributes based upon a sub-factory."""
+ def __init__(self, factory, **kwargs):
+ super(SubFactory, self).__init__()
+ self.defaults = factory.declarations()
+ self.defaults.update_base(kwargs)
+ self.factory = factory
+
+ def evaluate(self, factory, create, attributes):
+ attrs = self.defaults.build_attributes(self.factory, create, attributes)
+ if create:
+ return self.factory.create(**attrs)
+ else:
+ return self.factory.build(**attrs)
+
# Decorators... in case lambdas don't cut it
def lazy_attribute(func):
diff --git a/factory/test_base.py b/factory/test_base.py
index ee0bc3c..aa8257b 100644
--- a/factory/test_base.py
+++ b/factory/test_base.py
@@ -20,6 +20,9 @@
import unittest
+from base import BaseFactory, Factory, StubFactory, BUILD_STRATEGY, CREATE_STRATEGY, STUB_STRATEGY
+import declarations
+
class TestObject(object):
def __init__(self, one=None, two=None, three=None, four=None):
self.one = one
@@ -44,6 +47,12 @@ class FakeDjangoModel(object):
class TestModel(FakeDjangoModel):
pass
+
+class SafetyTestCase(unittest.TestCase):
+ def testBaseFactory(self):
+ self.assertRaises(RuntimeError, BaseFactory)
+
+
class FactoryTestCase(unittest.TestCase):
def testAttribute(self):
class TestObjectFactory(Factory):
@@ -54,8 +63,8 @@ class FactoryTestCase(unittest.TestCase):
def testSequence(self):
class TestObjectFactory(Factory):
- one = Sequence(lambda n: 'one' + n)
- two = Sequence(lambda n: 'two' + n)
+ one = declarations.Sequence(lambda n: 'one' + n)
+ two = declarations.Sequence(lambda n: 'two' + n)
test_object0 = TestObjectFactory.build()
self.assertEqual(test_object0.one, 'one0')
@@ -67,8 +76,8 @@ class FactoryTestCase(unittest.TestCase):
def testLazyAttribute(self):
class TestObjectFactory(Factory):
- one = LazyAttribute(lambda a: 'abc' )
- two = LazyAttribute(lambda a: a.one + ' xyz')
+ one = declarations.LazyAttribute(lambda a: 'abc' )
+ two = declarations.LazyAttribute(lambda a: a.one + ' xyz')
test_object = TestObjectFactory.build()
self.assertEqual(test_object.one, 'abc')
@@ -76,7 +85,7 @@ class FactoryTestCase(unittest.TestCase):
def testLazyAttributeNonExistentParam(self):
class TestObjectFactory(Factory):
- one = LazyAttribute(lambda a: a.does_not_exist )
+ one = declarations.LazyAttribute(lambda a: a.does_not_exist )
try:
TestObjectFactory()
@@ -86,8 +95,8 @@ class FactoryTestCase(unittest.TestCase):
def testLazyAttributeSequence(self):
class TestObjectFactory(Factory):
- one = LazyAttributeSequence(lambda a, n: 'abc' + n)
- two = LazyAttributeSequence(lambda a, n: a.one + ' xyz' + n)
+ one = declarations.LazyAttributeSequence(lambda a, n: 'abc' + n)
+ two = declarations.LazyAttributeSequence(lambda a, n: a.one + ' xyz' + n)
test_object0 = TestObjectFactory.build()
self.assertEqual(test_object0.one, 'abc0')
@@ -99,7 +108,7 @@ class FactoryTestCase(unittest.TestCase):
def testLazyAttributeDecorator(self):
class TestObjectFactory(Factory):
- @lazy_attribute
+ @declarations.lazy_attribute
def one(a):
return 'one'
@@ -108,7 +117,7 @@ class FactoryTestCase(unittest.TestCase):
def testSequenceDecorator(self):
class TestObjectFactory(Factory):
- @sequence
+ @declarations.sequence
def one(n):
return 'one' + n
@@ -117,10 +126,10 @@ class FactoryTestCase(unittest.TestCase):
def testLazyAttributeSequenceDecorator(self):
class TestObjectFactory(Factory):
- @lazy_attribute_sequence
+ @declarations.lazy_attribute_sequence
def one(a, n):
return 'one' + n
- @lazy_attribute_sequence
+ @declarations.lazy_attribute_sequence
def two(a, n):
return a.one + ' two' + n
@@ -130,8 +139,8 @@ class FactoryTestCase(unittest.TestCase):
def testBuildWithParameters(self):
class TestObjectFactory(Factory):
- one = Sequence(lambda n: 'one' + n)
- two = Sequence(lambda n: 'two' + n)
+ one = declarations.Sequence(lambda n: 'one' + n)
+ two = declarations.Sequence(lambda n: 'two' + n)
test_object0 = TestObjectFactory.build(three='three')
self.assertEqual(test_object0.one, 'one0')
@@ -153,13 +162,13 @@ class FactoryTestCase(unittest.TestCase):
def testInheritance(self):
class TestObjectFactory(Factory):
one = 'one'
- two = LazyAttribute(lambda a: a.one + ' two')
+ two = declarations.LazyAttribute(lambda a: a.one + ' two')
class TestObjectFactory2(TestObjectFactory):
FACTORY_FOR = TestObject
three = 'three'
- four = LazyAttribute(lambda a: a.three + ' four')
+ four = declarations.LazyAttribute(lambda a: a.three + ' four')
test_object = TestObjectFactory2.build()
self.assertEqual(test_object.one, 'one')
@@ -170,11 +179,11 @@ class FactoryTestCase(unittest.TestCase):
def testInheritanceWithInheritedClass(self):
class TestObjectFactory(Factory):
one = 'one'
- two = LazyAttribute(lambda a: a.one + ' two')
+ two = declarations.LazyAttribute(lambda a: a.one + ' two')
class TestFactory(TestObjectFactory):
three = 'three'
- four = LazyAttribute(lambda a: a.three + ' four')
+ four = declarations.LazyAttribute(lambda a: a.three + ' four')
test_object = TestFactory.build()
self.assertEqual(test_object.one, 'one')
@@ -221,6 +230,23 @@ class FactoryDefaultStrategyTestCase(unittest.TestCase):
self.assertEqual(test_model.one, 'one')
self.assertTrue(test_model.id)
+ def testSubFactory(self):
+ class TestModel2(FakeDjangoModel):
+ pass
+
+ class TestModelFactory(Factory):
+ FACTORY_FOR = TestModel
+ one = 3
+
+ class TestModel2Factory(Factory):
+ FACTORY_FOR = TestModel2
+ two = declarations.SubFactory(TestModelFactory, one=1)
+
+ test_model = TestModel2Factory(two__one=4)
+ self.assertEqual(4, test_model.two.one)
+ self.assertEqual(1, test_model.id)
+ self.assertEqual(1, test_model.two.id)
+
def testStubStrategy(self):
Factory.default_strategy = STUB_STRATEGY
@@ -247,6 +273,9 @@ class FactoryDefaultStrategyTestCase(unittest.TestCase):
self.assertRaises(StubFactory.UnsupportedStrategy, TestModelFactory)
+ TestModelFactory.default_strategy = BUILD_STRATEGY
+ self.assertRaises(StubFactory.UnsupportedStrategy, TestModelFactory)
+
class FactoryCreationTestCase(unittest.TestCase):
def testFactoryFor(self):
class TestFactory(Factory):
diff --git a/factory/test_containers.py b/factory/test_containers.py
new file mode 100644
index 0000000..3cc61e1
--- /dev/null
+++ b/factory/test_containers.py
@@ -0,0 +1,212 @@
+# Copyright (c) 2010 Mark Sandstrom
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+import unittest
+
+from containers import DeclarationsHolder, OrderedDeclarationDict, ObjectParamsWrapper
+import base
+import declarations
+
+class ObjectParamsWrapperTestCase(unittest.TestCase):
+ def test_read(self):
+ vals = {'one': 1, 'two': 2}
+ wrapper = ObjectParamsWrapper(vals)
+
+ self.assertEqual(1, wrapper.one)
+ self.assertEqual(2, wrapper.two)
+ self.assertRaises(AttributeError, getattr, wrapper, 'three')
+ self.assertRaises(AttributeError, setattr, wrapper, 'one', 1)
+
+ def test_standard_attributes(self):
+ wrapper = ObjectParamsWrapper({})
+ self.assertEqual(ObjectParamsWrapper, wrapper.__class__)
+
+
+class OrderedDeclarationMock(object):
+ def __init__(self, order):
+ self.order = order
+
+
+class OrderedDeclarationDictTestCase(unittest.TestCase):
+ def test_basics(self):
+ one = OrderedDeclarationMock(1)
+ two = OrderedDeclarationMock(2)
+ three = OrderedDeclarationMock(3)
+ d = OrderedDeclarationDict(one=one, two=two, three=three)
+ self.assertEqual(one, d['one'])
+ self.assertEqual(two, d['two'])
+ self.assertEqual(three, d['three'])
+
+ self.assertTrue('one' in d)
+ self.assertTrue('two' in d)
+ self.assertTrue('three' in d)
+
+ self.assertEqual(one, d.pop('one'))
+ self.assertFalse('one' in d)
+
+ d['one'] = one
+ self.assertTrue('one' in d)
+ self.assertEqual(one, d['one'])
+
+ self.assertEqual(set(['one', 'two', 'three']),
+ set(d))
+
+ def test_order(self):
+ one = OrderedDeclarationMock(1)
+ two = OrderedDeclarationMock(2)
+ ten = OrderedDeclarationMock(10)
+ d = OrderedDeclarationDict(one=one, two=two, ten=ten)
+
+ self.assertEqual(['one', 'two', 'ten'], list(d))
+ self.assertEqual([('one', one), ('two', two), ('ten', ten)],
+ d.items())
+ self.assertEqual([('one', one), ('two', two), ('ten', ten)],
+ list(d.iteritems()))
+
+ def test_insert(self):
+ one = OrderedDeclarationMock(1)
+ two = OrderedDeclarationMock(2)
+ four = OrderedDeclarationMock(4)
+ ten = OrderedDeclarationMock(10)
+ d = OrderedDeclarationDict(one=one, two=two, ten=ten)
+
+ self.assertEqual(['one', 'two', 'ten'], list(d))
+ d['four'] = four
+ self.assertEqual(['one', 'two', 'four', 'ten'], list(d))
+
+ def test_replace(self):
+ one = OrderedDeclarationMock(1)
+ two = OrderedDeclarationMock(2)
+ three = OrderedDeclarationMock(3)
+ ten = OrderedDeclarationMock(10)
+ d = OrderedDeclarationDict(one=one, two=two, ten=ten)
+
+ self.assertEqual(['one', 'two', 'ten'], list(d))
+ d['one'] = three
+
+ self.assertEqual(three, d['one'])
+ self.assertEqual(['two', 'one', 'ten'], list(d))
+
+
+class DeclarationsHolderTestCase(unittest.TestCase):
+ def test_empty(self):
+ holder = DeclarationsHolder()
+ self.assertRaises(KeyError, holder.__getitem__, 'one')
+ holder.update_base({'one': 1})
+ self.assertEqual(1, holder['one'])
+
+ def test_simple(self):
+ """Tests a simple use case without OrderedDeclaration."""
+ holder = DeclarationsHolder({'one': 1, 'two': 2})
+ self.assertTrue('one' in holder)
+ self.assertTrue('two' in holder)
+ holder.update_base({'two': 3, 'three': 3})
+ self.assertEqual(1, holder['one'])
+ self.assertEqual(3, holder['two'])
+ self.assertEqual(3, holder['three'])
+
+ attrs = holder.build_attributes(None)
+ self.assertEqual(1, attrs['one'])
+ self.assertEqual(3, attrs['two'])
+ self.assertEqual(3, attrs['three'])
+
+ self.assertEqual(set([('one', 1), ('two', 3), ('three', 3)]),
+ set(holder.items()))
+
+ attrs = holder.build_attributes(None, False, {'two': 2})
+ self.assertEqual(1, attrs['one'])
+ self.assertEqual(2, attrs['two'])
+ self.assertEqual(3, attrs['three'])
+
+ def test_skip_specials(self):
+ """Makes sure that attributes starting with _ are skipped."""
+ holder = DeclarationsHolder({'one': 1, '_two': 2})
+ self.assertTrue('one' in holder)
+ self.assertFalse('_two' in holder)
+
+ remains = holder.update_base({'_two': 2, 'three': 3})
+ self.assertTrue('three' in holder)
+ self.assertFalse('_two' in holder)
+ self.assertEqual({'_two': 2}, remains)
+
+ def test_ordered(self):
+ """Tests the handling of OrderedDeclaration."""
+ two = declarations.LazyAttribute(lambda o: 2 * o.one)
+ three = declarations.LazyAttribute(lambda o: o.one + o.two)
+ holder = DeclarationsHolder({'one': 1, 'two': two, 'three': three})
+
+ self.assertEqual([('one', 1), ('two', two), ('three', three)],
+ holder.items())
+
+ self.assertEqual(two, holder['two'])
+
+ attrs = holder.build_attributes(None)
+ self.assertEqual(1, attrs['one'])
+ self.assertEqual(2, attrs['two'])
+ self.assertEqual(3, attrs['three'])
+
+ attrs = holder.build_attributes(None, False, {'one': 4})
+ self.assertEqual(4, attrs['one'])
+ self.assertEqual(8, attrs['two'])
+ self.assertEqual(12, attrs['three'])
+
+ attrs = holder.build_attributes(None, False, {'one': 4, 'two': 2})
+ self.assertEqual(4, attrs['one'])
+ self.assertEqual(2, attrs['two'])
+ self.assertEqual(6, attrs['three'])
+
+ def test_sub_factory(self):
+ """Tests the behaviour of sub-factories."""
+ class TestObject(object):
+ def __init__(self, one=None, two=None, three=None, four=None):
+ self.one = one
+ self.two = two
+ self.three = three
+ self.four = four
+
+ class TestObjectFactory(base.Factory):
+ FACTORY_FOR = TestObject
+ two = 2
+
+ sub = declarations.SubFactory(TestObjectFactory,
+ three=3,
+ four=declarations.LazyAttribute(
+ lambda o: 2 * o.two))
+
+ holder = DeclarationsHolder(defaults={'sub': sub, 'one': 1})
+ self.assertEqual(sub, holder['sub'])
+ self.assertTrue('sub' in holder)
+
+ attrs = holder.build_attributes(None)
+ self.assertEqual(1, attrs['one'])
+ self.assertEqual(2, attrs['sub'].two)
+ self.assertEqual(3, attrs['sub'].three)
+ self.assertEqual(4, attrs['sub'].four)
+
+ attrs = holder.build_attributes(None, False, {'sub__two': 8, 'three__four': 4})
+ self.assertEqual(1, attrs['one'])
+ self.assertEqual(4, attrs['three__four'])
+ self.assertEqual(8, attrs['sub'].two)
+ self.assertEqual(3, attrs['sub'].three)
+ self.assertEqual(16, attrs['sub'].four)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/factory/test_declarations.py b/factory/test_declarations.py
new file mode 100644
index 0000000..27d5f9e
--- /dev/null
+++ b/factory/test_declarations.py
@@ -0,0 +1,47 @@
+# Copyright (c) 2010 Mark Sandstrom
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+
+import unittest
+
+from declarations import GlobalCounter, OrderedDeclaration, Sequence
+
+class GlobalCounterTestCase(unittest.TestCase):
+ def test_incr(self):
+ init = GlobalCounter.step()
+ mid = GlobalCounter.step()
+ last = GlobalCounter.step()
+ self.assertEqual(2, last - init)
+ self.assertEqual(1, mid - init)
+
+
+class OrderedDeclarationTestCase(unittest.TestCase):
+ def test_errors(self):
+ decl = OrderedDeclaration()
+ self.assertRaises(NotImplementedError, decl.evaluate, None, {})
+
+ def test_order(self):
+ decl1 = OrderedDeclaration()
+ decl2 = OrderedDeclaration()
+ decl3 = Sequence(lambda n: 3 * n)
+ self.assertTrue(decl1.order < decl2.order)
+ self.assertTrue(decl2.order < decl3.order)
+
+if __name__ == '__main__':
+ unittest.main()