From ebdfb8cc5bab1e59b593a4ea60e55b9e7af455ef Mon Sep 17 00:00:00 2001 From: Raphaël Barrois Date: Fri, 1 Mar 2013 01:35:26 +0100 Subject: Improve Iterator and SubFactory declarations. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Iterator now cycles by default * Iterator can be provided with a custom getter * SubFactory accepts a factory import path as well Deprecates: * InfiniteIterator * CircularSubFactory Signed-off-by: Raphaël Barrois --- tests/cyclic/bar.py | 2 +- tests/test_declarations.py | 72 ++++++++++++++++++++++++++++++++++++++++++++++ tests/test_using.py | 34 ++++++++++++++++++++++ 3 files changed, 107 insertions(+), 1 deletion(-) (limited to 'tests') diff --git a/tests/cyclic/bar.py b/tests/cyclic/bar.py index a8c9670..fed0602 100644 --- a/tests/cyclic/bar.py +++ b/tests/cyclic/bar.py @@ -33,5 +33,5 @@ class BarFactory(factory.Factory): FACTORY_FOR = Bar y = 13 - foo = factory.CircularSubFactory('cyclic.foo', 'FooFactory') + foo = factory.SubFactory('cyclic.foo.FooFactory') diff --git a/tests/test_declarations.py b/tests/test_declarations.py index 214adc0..ecec244 100644 --- a/tests/test_declarations.py +++ b/tests/test_declarations.py @@ -21,10 +21,14 @@ # THE SOFTWARE. import datetime +import itertools +import warnings from factory import declarations from .compat import unittest +from . import tools + class OrderedDeclarationTestCase(unittest.TestCase): def test_errors(self): @@ -88,6 +92,28 @@ class SelfAttributeTestCase(unittest.TestCase): self.assertEqual(declarations._UNSPECIFIED, a.default) +class IteratorTestCase(unittest.TestCase): + def test_cycle(self): + it = declarations.Iterator([1, 2]) + self.assertEqual(1, it.evaluate(0, None)) + self.assertEqual(2, it.evaluate(1, None)) + self.assertEqual(1, it.evaluate(2, None)) + self.assertEqual(2, it.evaluate(3, None)) + + def test_no_cycling(self): + it = declarations.Iterator([1, 2], cycle=False) + self.assertEqual(1, it.evaluate(0, None)) + self.assertEqual(2, it.evaluate(1, None)) + self.assertRaises(StopIteration, it.evaluate, 2, None) + + def test_getter(self): + it = declarations.Iterator([(1, 2), (1, 3)], getter=lambda p: p[1]) + self.assertEqual(2, it.evaluate(0, None)) + self.assertEqual(3, it.evaluate(1, None)) + self.assertEqual(2, it.evaluate(2, None)) + self.assertEqual(3, it.evaluate(3, None)) + + class PostGenerationDeclarationTestCase(unittest.TestCase): def test_extract_no_prefix(self): decl = declarations.PostGenerationDeclaration() @@ -105,7 +131,51 @@ class PostGenerationDeclarationTestCase(unittest.TestCase): self.assertEqual(kwargs, {'baz': 1}) +class SubFactoryTestCase(unittest.TestCase): + def test_lazyness(self): + f = declarations.SubFactory('factory.declarations.Sequence', x=3) + self.assertEqual(None, f.factory) + + self.assertEqual({'x': 3}, f.defaults) + + factory_class = f.get_factory() + self.assertEqual(declarations.Sequence, factory_class) + + def test_cache(self): + orig_date = datetime.date + f = declarations.SubFactory('datetime.date') + self.assertEqual(None, f.factory) + + factory_class = f.get_factory() + self.assertEqual(orig_date, factory_class) + + try: + # Modify original value + datetime.date = None + # Repeat import + factory_class = f.get_factory() + self.assertEqual(orig_date, factory_class) + + finally: + # IMPORTANT: restore attribute. + datetime.date = orig_date + + class CircularSubFactoryTestCase(unittest.TestCase): + + def test_circularsubfactory_deprecated(self): + with warnings.catch_warnings(record=True) as w: + __warningregistry__.clear() + + warnings.simplefilter('always') + declarations.CircularSubFactory('datetime', 'date') + + self.assertEqual(1, len(w)) + self.assertIn('CircularSubFactory', str(w[0].message)) + self.assertIn('deprecated', str(w[0].message)) + + + @tools.disable_warnings def test_lazyness(self): f = declarations.CircularSubFactory('factory.declarations', 'Sequence', x=3) self.assertEqual(None, f.factory) @@ -115,6 +185,7 @@ class CircularSubFactoryTestCase(unittest.TestCase): factory_class = f.get_factory() self.assertEqual(declarations.Sequence, factory_class) + @tools.disable_warnings def test_cache(self): orig_date = datetime.date f = declarations.CircularSubFactory('datetime', 'date') @@ -134,5 +205,6 @@ class CircularSubFactoryTestCase(unittest.TestCase): # IMPORTANT: restore attribute. datetime.date = orig_date + if __name__ == '__main__': unittest.main() diff --git a/tests/test_using.py b/tests/test_using.py index fb0e8b0..fb8c207 100644 --- a/tests/test_using.py +++ b/tests/test_using.py @@ -1076,6 +1076,21 @@ class IteratorTestCase(unittest.TestCase): for i, obj in enumerate(objs): self.assertEqual(i + 10, obj.one) + def test_infinite_iterator_deprecated(self): + with warnings.catch_warnings(record=True) as w: + __warningregistry__.clear() + + warnings.simplefilter('always') + class TestObjectFactory(factory.Factory): + FACTORY_FOR = TestObject + + foo = factory.InfiniteIterator(range(5)) + + self.assertEqual(1, len(w)) + self.assertIn('InfiniteIterator', str(w[0].message)) + self.assertIn('deprecated', str(w[0].message)) + + @disable_warnings def test_infinite_iterator(self): class TestObjectFactory(factory.Factory): FACTORY_FOR = TestObject @@ -1088,6 +1103,7 @@ class IteratorTestCase(unittest.TestCase): self.assertEqual(i % 5, obj.one) @unittest.skipUnless(is_python2, "Scope bleeding fixed in Python3+") + @disable_warnings def test_infinite_iterator_list_comprehension_scope_bleeding(self): class TestObjectFactory(factory.Factory): FACTORY_FOR = TestObject @@ -1098,6 +1114,7 @@ class IteratorTestCase(unittest.TestCase): self.assertRaises(TypeError, TestObjectFactory.build) + @disable_warnings def test_infinite_iterator_list_comprehension_protected(self): class TestObjectFactory(factory.Factory): FACTORY_FOR = TestObject @@ -1125,6 +1142,23 @@ class IteratorTestCase(unittest.TestCase): for i, obj in enumerate(objs): self.assertEqual(i + 10, obj.one) + def test_infinite_iterator_decorator_deprecated(self): + with warnings.catch_warnings(record=True) as w: + __warningregistry__.clear() + + warnings.simplefilter('always') + class TestObjectFactory(factory.Factory): + FACTORY_FOR = TestObject + + @factory.infinite_iterator + def one(): + return range(5) + + self.assertEqual(1, len(w)) + self.assertIn('infinite_iterator', str(w[0].message)) + self.assertIn('deprecated', str(w[0].message)) + + @disable_warnings def test_infinite_iterator_decorator(self): class TestObjectFactory(factory.Factory): FACTORY_FOR = TestObject -- cgit v1.2.3