def test_add_field_detects_clashes(self): """.add_Field() detects field clashes and raises TypeError.""" foo_clash = Field() foo_clash.name = 'foo' # because we're not calling inspect_namespace() which does that self.set_field_names() self.fc.add_field(self.foo, 'cls') with self.assertRaisesRegex( TypeError, 'field other_cls.foo clashes with cls.foo'): self.fc.add_field(foo_clash, 'other_cls')
def setUp(self): """Common set-up code.""" self.foo = Field() self.bar = Field() self.ns = { 'foo': self.foo, 'bar': self.bar, 'do_sth': lambda: True, 'DATA': 42, } self.fc = _FieldCollection()
class D(B): f2 = Field()
class B(POD): f1 = Field(notify=True)
class T(POD): f = Field(notify=True)
class P(POD): f = Field()
class Employee(Person): salary = Field()
class B(POD): b = Field()
class T(POD): f = Field(initial=42)
class T(POD): m1 = Field(initial=MANDATORY) m2 = Field(initial=MANDATORY)
class T(POD): f1 = Field() f2 = Field(initial='default') f3 = Field(initial_fn=lambda: m())
class Base2(POD): froz = Field()
class Base1(POD): foo = Field() bar = Field()
class B(POD): f = Field()
class T(POD): f = Field()
class A(POD): a = Field()
class Person(POD): name = Field() age = Field() def __str__(self): return 'Mr. {}'.format(self.name)
class A(POD): f = Field()
class FieldCollectionTests(TestCase): """Tests for the _FieldCollection class.""" def setUp(self): """Common set-up code.""" self.foo = Field() self.bar = Field() self.ns = { 'foo': self.foo, 'bar': self.bar, 'do_sth': lambda: True, 'DATA': 42, } self.fc = _FieldCollection() def set_field_names(self): """Set names of the foo and bar fields.""" self.foo.gain_name('foo') self.bar.gain_name('bar') def test_add_field_builds_field_list(self): """.add_field() appends new fields to field_list.""" # because we're not calling inspect_namespace() which does that self.set_field_names() self.fc.add_field(self.foo, 'cls') self.assertEqual(self.fc.field_list, [self.foo]) self.fc.add_field(self.bar, 'cls') self.assertEqual(self.fc.field_list, [self.foo, self.bar]) def test_add_field_builds_field_origin_map(self): """.add_field() builds and maintains field_origin_map.""" # because we're not calling inspect_namespace() which does that self.set_field_names() self.fc.add_field(self.foo, 'cls') self.assertEqual(self.fc.field_origin_map, {'foo': 'cls'}) self.fc.add_field(self.bar, 'cls') self.assertEqual( self.fc.field_origin_map, {'foo': 'cls', 'bar': 'cls'}) def test_add_field_detects_clashes(self): """.add_Field() detects field clashes and raises TypeError.""" foo_clash = Field() foo_clash.name = 'foo' # because we're not calling inspect_namespace() which does that self.set_field_names() self.fc.add_field(self.foo, 'cls') with self.assertRaisesRegex( TypeError, 'field other_cls.foo clashes with cls.foo'): self.fc.add_field(foo_clash, 'other_cls') def test_inspect_base_classes_calls_add_field(self): """.inspect_base_classes() calls add_field() on each Field found.""" class Base1(POD): foo = Field() bar = Field() class Base2(POD): froz = Field() class Unrelated: field_list = [mock.Mock('fake_field')] with mock.patch.object(self.fc, 'add_field') as mock_add_field: self.fc.inspect_base_classes((Base1, Base2, Unrelated)) mock_add_field.assert_has_calls([ ((Base1.foo, 'Base1'), {}), ((Base1.bar, 'Base1'), {}), ((Base2.froz, 'Base2'), {}), ]) def test_inspect_namespace_calls_add_field(self): """.inspect_namespace() calls add_field() on each Field.""" with mock.patch.object(self.fc, 'add_field') as mock_add_field: self.fc.inspect_namespace(self.ns, 'cls') calls = [mock.call(self.foo, 'cls'), mock.call(self.bar, 'cls')] mock_add_field.assert_has_calls(calls, any_order=True) def test_inspect_namespace_sets_field_name(self): """.inspect_namespace() sets .name of each field.""" self.assertIsNone(self.foo.name) self.assertIsNone(self.bar.name) fc = _FieldCollection() fc.inspect_namespace(self.ns, 'cls') self.assertEqual(self.foo.name, 'foo') self.assertEqual(self.bar.name, 'bar') def test_inspect_namespace_sets_field_instance_attr(self): """.inspect_namespace() sets .instance_attr of each field.""" self.assertIsNone(self.foo.instance_attr) self.assertIsNone(self.bar.instance_attr) fc = _FieldCollection() fc.inspect_namespace(self.ns, 'cls') self.assertEqual(self.foo.instance_attr, '_foo') self.assertEqual(self.bar.instance_attr, '_bar') def test_notifier(self): """@field.change_notifier changes the notify function.""" @self.foo.change_notifier def on_foo_changed(pod, old, new): pass self.assertTrue(self.foo.notify) self.assertEqual(self.foo.notify_fn, on_foo_changed)