def test_setitem_adds_id_to_both_values_and_keys_attr(self):
        c = MedleyContainer()
        c._frozen = Mock(__contains__=Mock(return_value=False))
        c._keys = Mock(add=Mock())
        c._values = MagicMock()

        c.__setitem__('foo', self.foo)
        c._values.__setitem__.assert_called_with('foo', self.foo)
        c._keys.add.assert_called_with('foo')
    def test_getitem_stores_raw_function_and_freezes(self):
        c = MedleyContainer()
        c._keys = Mock(__contains__=Mock(return_value=True))
        c._protected = Mock(__contains__=Mock(return_value=False))
        c._factories = Mock(__contains__=Mock(return_value=False))
        c._frozen = Mock(add=Mock())

        c._values = {'foo': self.foo}

        self.assertEqual(c.__getitem__('foo'), 'foo')
        self.assertEqual(c._values, {'foo': 'foo'})
        self.assertEqual(c._raw, {'foo': self.foo})
        c._frozen.add.assert_called_with('foo')
    def test_delitem_does_not_delete_from_factories_or_protected_when_id_is_str(
            self):
        c = MedleyContainer()
        c._keys = Mock(__contains__=Mock(return_value=True), discard=Mock())
        c._protected = Mock(discard=Mock())
        c._factories = Mock(discard=Mock())
        c._frozen = Mock(discard=Mock())

        c._values = {'foo': 'foo'}
        c.__delitem__('foo')

        c._factories.discard.assert_not_called()
        c._protected.discard.assert_not_called()
        self.assertEqual(c._values, {})
        self.assertEqual(c._raw, {})
        c._frozen.discard.assert_called_with('foo')
        c._keys.discard.assert_called_with('foo')
    def test_delitem_deletes_from_everywhere_wwhen_id_is_function(self):
        c = MedleyContainer()
        c._keys = Mock(__contains__=Mock(return_value=True), discard=Mock())
        c._protected = Mock(discard=Mock())
        c._factories = Mock(discard=Mock())
        c._frozen = Mock(discard=Mock())

        c._values = {'foo': self.foo}
        c._raw = {'foo': self.foo}

        self.assertFalse(c.__delitem__('foo'))
        c._factories.discard.assert_called_with(self.foo)
        c._protected.discard.assert_called_with(self.foo)
        self.assertEqual(c._values, {})
        self.assertEqual(c._raw, {})
        c._frozen.discard.assert_called_with('foo')
        c._keys.discard.assert_called_with('foo')
    def test_setitem_allows_non_function_values(self):
        c = MedleyContainer()
        c._frozen = Mock(__contains__=Mock(return_value=False))
        c._keys = Mock(add=Mock())
        c._values = MagicMock()

        c.__setitem__('str', 'str')
        c._keys.add.assert_called_with('str')
        c._values.__setitem__.assert_called_with('str', 'str')

        c.__setitem__('dict', {})
        c._keys.add.assert_called_with('dict')
        c._values.__setitem__.assert_called_with('dict', {})

        c.__setitem__('list', [])
        c._keys.add.assert_called_with('list')
        c._values.__setitem__.assert_called_with('list', [])

        c.__setitem__('tuple', ('foo', 'bar'))
        c._keys.add.assert_called_with('tuple')
        c._values.__setitem__.assert_called_with('tuple', ('foo', 'bar'))

        r = range(10)
        c.__setitem__('range', r)
        c._keys.add.assert_called_with('range')
        c._values.__setitem__.assert_called_with('range', r)

        c.__setitem__('regex', r'foo')
        c._keys.add.assert_called_with('regex')
        c._values.__setitem__.assert_called_with('regex', r'foo')

        c.__setitem__('set', set())
        c._keys.add.assert_called_with('set')
        c._values.__setitem__.assert_called_with('set', set())

        c.__setitem__('frozenset', frozenset())
        c._keys.add.assert_called_with('frozenset')
        c._values.__setitem__.assert_called_with('frozenset', frozenset())

        c.__setitem__('boolean', False)
        c._keys.add.assert_called_with('boolean')
        c._values.__setitem__.assert_called_with('boolean', False)

        c.__setitem__('int', int(10))
        c._keys.add.assert_called_with('int')
        c._values.__setitem__.assert_called_with('int', int(10))

        c.__setitem__('float', float(10.1))
        c._keys.add.assert_called_with('float')
        c._values.__setitem__.assert_called_with('float', float(10.1))

        c.__setitem__('complex', complex(10))
        c._keys.add.assert_called_with('complex')
        c._values.__setitem__.assert_called_with('complex', complex(10))

        c.__setitem__('bytes', b'bytes')
        c._keys.add.assert_called_with('bytes')
        c._values.__setitem__.assert_called_with('bytes', b'bytes')

        c.__setitem__('bytearray', bytearray(b'bytearray'))
        c._keys.add.assert_called_with('bytearray')
        c._values.__setitem__.assert_called_with('bytearray',
                                                 bytearray(b'bytearray'))

        c.__setitem__('none', None)
        c._keys.add.assert_called_with('none')
        c._values.__setitem__.assert_called_with('none', None)
    def test_setitem_throws_error_if_id_frozen(self):
        c = MedleyContainer()
        c._frozen = Mock(__contains__=Mock(return_value=True))

        with self.assertRaises(Exception):
            c.__setitem__('foo', self.foo)