def setUp(self):
     self.container = SubscribersContainer()
     assert len(self.container) == 0
class ContainerTest(unittest.TestCase):
    """Test subscriber container/mapping without a ZODB fixture"""

    def setUp(self):
        self.container = SubscribersContainer()
        assert len(self.container) == 0

    def test_iface(self):
        assert ISubscribers.providedBy(self.container)
        for name in ("add", "get", "__getitem__", "__contains__", "__delitem__", "__len__"):
            assert isinstance(getattr(self.container, name, None), methodtype)

    def test_add_remove(self):
        key = ("email", "*****@*****.**")
        assert len(self.container) == 0
        assert key not in self.container
        subscriber = ItemSubscriber(name=u"Me", email="*****@*****.**")
        k, v = self.container.add(subscriber)
        assert k == key
        assert len(self.container) == 1

        # now check the key we expected to be generated in the add() operation
        assert key in self.container
        assert key in self.container.keys()
        assert subscriber in self.container.values()

        # subtle but important: we can identify an object as being "in" a
        # container, but not in its keys.
        # container.__contains__ is not same as container.keys().__contains__
        assert subscriber in self.container and subscriber not in self.container.keys()

        # now delete using the key we expected was generated
        del (self.container[key])
        assert len(self.container) == 0
        assert key not in self.container

        # now try adding again, then delete using subscriber object as a key
        k, v = self.container.add(subscriber)
        assert len(self.container) == 1
        del (self.container[subscriber])  # delete using unique value
        assert len(self.container) == 0

    def test_add_duplicate(self):
        key = ("email", "*****@*****.**")
        assert key not in self.container
        subscriber = ItemSubscriber(name=u"Me", email="*****@*****.**")
        k, v = self.container.add(subscriber)
        assert k == key
        assert subscriber in self.container
        assert key in self.container
        subscriber2 = ItemSubscriber(name=u"Different name, same email", email="*****@*****.**")
        # will not add, raises error
        self.assertRaises(ValueError, self.container.add, subscriber2)
        assert len(self.container) == 1  # size consistent
        # justify why: the key will be compositionally identical
        keyfn = self.container._normalize_key
        assert key == k == keyfn(subscriber) == keyfn(subscriber2)

    def test_add_subscriber_copy(self):
        mock = MockSub()
        assert IItemSubscriber.providedBy(mock)
        key = ("member", "somebody")
        assert key not in self.container
        self.container.add(mock)
        assert key in self.container
        stored = self.container[key]
        assert IItemSubscriber.providedBy(stored)
        assert stored is not mock
        assert stored.__class__ is not mock.__class__
        assert isinstance(stored, persistent.Persistent)
        assert isinstance(stored, ItemSubscriber)
        for fieldname in ("user", "namespace", "email", "name"):
            assert getattr(stored, fieldname) == getattr(mock, fieldname)

    def test_add_subscriber_ref(self):
        """Test add persistent subscriber, make reference"""
        sub = ItemSubscriber(**DATA)
        self.container.add(sub)
        assert DATAKEY in self.container
        stored = self.container[DATAKEY]
        assert stored is sub  # persistent same item
        assert sub in self.container

    def test_add_dict(self):
        self.container.add(DATA)
        assert DATAKEY in self.container

    def test_add_kwargs(self):
        self.container.add(**DATA)  # as kwargs, not positional dict
        assert DATAKEY in self.container

    def test_add_subscriber_email_only(self):
        # add by email, declare explicit namespace
        key = ("email", "*****@*****.**")
        self.container.add(namespace=key[0], email=key[1])
        assert key in self.container
        sub = self.container[key]
        assert IItemSubscriber.providedBy(sub)
        IItemSubscriber.validateInvariants(sub)
        assert sub.email == key[1]
        assert sub.namespace == key[0]

        # add by email, should imply namespace
        self.container.add(email="*****@*****.**")
        assert ("email", "*****@*****.**") in self.container

    def test_normalize_key_email(self):
        expected = ("email", "*****@*****.**")
        sub = ItemSubscriber()
        sub.email = expected[1]
        assert self.container._normalize_key(sub) == expected
        k, v = self.container.add(sub)
        assert k == expected
        assert expected in self.container

    def test_normalize_key_invalid(self):
        key = "somestring"
        self.assertRaises(KeyError, self.container.add, key)
        badsub = ItemSubscriber()
        badsub.email = None
        badsub.user = None
        self.assertRaises(Invalid, self.container.add, badsub)

    def test_contains(self):
        mock = MockSub()
        self.container.add(mock)
        assert mock not in self.container  # merely a copy of mock was added
        assert self.container._normalize_key(mock) in self.container
        del (self.container[mock])
        assert self.container._normalize_key(mock) not in self.container

    def test_len(self):
        assert hasattr(self.container, "size")
        self.assertEqual(self.container.size(), 0)
        self.assertEqual(self.container.size(), len(self.container))
        k, v = self.container.add(email="*****@*****.**")
        self.assertEqual(self.container.size(), 1)
        self.assertEqual(self.container.size(), len(self.container))
        del (self.container[k])
        self.assertEqual(self.container.size(), 0)
        self.assertEqual(self.container.size(), len(self.container))
        self.container.add(email="*****@*****.**")
        self.assertEqual(self.container.size(), 1)
        self.assertEqual(self.container.size(), len(self.container))
        k, v = self.container.add(email="*****@*****.**")
        self.assertEqual(self.container.size(), 2)
        self.assertEqual(self.container.size(), len(self.container))
        del (self.container[k])
        self.assertEqual(self.container.size(), 1)
        self.assertEqual(self.container.size(), len(self.container))

    def tearDown(self):
        for key in list(self.container):
            del (self.container[key])
        self.assertEquals(len(self.container), 0)