def test_create_factory_decorator_calls_factory(self):
        c = MedleyContainer()
        c.__setitem__ = Mock()
        c.factory = Mock(return_value='bar')

        @c.create_factory('foo')
        def foo(c):
            return 'bar'

        c.__setitem__.assert_called_once_with('foo', 'bar')
        c.factory.assert_called_once()
    def test_factory_throws_error_if_arg_not_function(self):
        c = MedleyContainer()

        with self.assertRaises(Exception):
            c.factory('foo')

        with self.assertRaises(Exception):
            c.factory(False)

        with self.assertRaises(Exception):
            c.factory(r'match')

        with self.assertRaises(Exception):
            c.factory(0xf)
    def test_factory_adds_factory_function_to_factories_attr(self):
        c = MedleyContainer()
        factories = set()

        with patch.object(c, '_factories', wraps=factories):
            c.factory(self.foo)
            c._factories.add.assert_called_with(self.foo)

            c.factory(self.bar)
            c._factories.add.assert_called_with(self.bar)

            c.factory(self.baz)
            c._factories.add.assert_called_with(self.baz)

            self.assertEqual(c._factories.add.call_count, 3)
    def test_factory_prevents_duplicates(self):
        c = MedleyContainer()
        factories = set()

        with patch.object(c, '_factories', wraps=factories):
            c.factory(self.foo)
            c._factories.add.assert_called_with(self.foo)

            c.factory(self.foo)
            c._factories.add.assert_called_with(self.foo)

            c.factory(self.foo)
            c._factories.add.assert_called_with(self.foo)

            self.assertEqual(c._factories.add.call_count, 3)
            self.assertEqual(len(factories), 1)