def __new__(cls, name, bases, namespace): """ Construct a new ``Controller`` subclass. :param str name: The name of the new class. :param bases: A tuple of base classes. :type bases: ``tuple`` of classes :param dict namespace: The namespace of the new class. :returns: A newly constructed subclass of the ``Controller`` class. """ # Construct a new Root root = elements.Root() # Collect delegations delegations = {} # Walk the namespace looking for elements and callables with # Method elements for ident, value in namespace.items(): # Add elements to the root if isinstance(value, elements.Element): root.add_elem(value, ident) continue # Add HTTP methods to the root as well if hasattr(value, '_micropath_methods'): for meth in value._micropath_methods: root.add_elem(meth, ident) # Mount the delegation to the root if isinstance(value, elements.Delegation): if value.element is None: root.mount(value) else: root.add_elem(value.element, ident) # Add it to the set of delegations delegations[ident] = value continue # Deal with handlers if getattr(value, '_micropath_handler', False): # If it doesn't have an elem, set it to the root if getattr(value, '_micropath_elem', None) is None: value._micropath_elem = root # Add the root and handlers list to the namespace namespace.update( _micropath_root=root, _micropath_delegations=[ delegation for _name, delegation in sorted(delegations.items(), key=lambda x: x[0]) ], ) return super(ControllerMeta, cls).__new__(cls, name, bases, namespace)
def test_add_elem_self(self, mocker): obj = elements.Root() obj.add_elem(obj) assert obj.paths == {} assert obj.bindings is None assert obj.methods == {}
def test_init(self, mocker): mock_init = mocker.patch.object( elements.Element, '__init__', return_value=None, ) result = elements.Root() assert isinstance(result, elements.Root) mock_init.assert_called_once_with(None)
def test_add_elem_set_ident(self, mocker): elem = mocker.Mock(spec=elements.Path, ident=None) elem.parent = None obj = elements.Root() obj.add_elem(elem, 'spam') assert obj.paths == {} assert obj.bindings is None assert obj.methods == {} assert elem.ident is None assert elem.parent is obj elem.set_ident.assert_called_once_with('spam')
def test_add_elem_binding_no_ident(self, mocker): elem = mocker.Mock(spec=elements.Binding, ident=None) elem.parent = None obj = elements.Root() obj.add_elem(elem) assert obj.paths == {} assert obj.bindings is None assert obj.methods == {} assert elem.ident is None assert elem.parent is obj elem.set_ident.assert_not_called()
def test_add_elem_root(self, mocker): elem = mocker.Mock(spec=elements.Root, ident=None) elem.parent = None obj = elements.Root() with pytest.raises(ValueError): obj.add_elem(elem) assert obj.paths == {} assert obj.bindings is None assert obj.methods == {} assert elem.ident is None assert elem.parent is None elem.set_ident.assert_not_called()
def test_add_elem_method(self, mocker): elem = mocker.Mock(spec=elements.Method, ident='spam') elem.parent = None obj = elements.Root() obj.add_elem(elem) assert obj.paths == {} assert obj.bindings is None assert obj.methods == {'spam': elem} assert elem.ident == 'spam' assert elem.parent is obj elem.set_ident.assert_not_called()
def test_add_elem_method_all_conflict(self, mocker): elem = mocker.Mock(spec=elements.Method, ident=None) elem.parent = None obj = elements.Root() obj.methods[None] = 'conflict' with pytest.raises(ValueError): obj.add_elem(elem) assert obj.paths == {} assert obj.bindings is None assert obj.methods == {None: 'conflict'} assert elem.ident is None assert elem.parent is None elem.set_ident.assert_not_called()
def test_add_elem_binding_conflict(self, mocker): elem = mocker.Mock(spec=elements.Binding, ident='spam') elem.parent = None obj = elements.Root() obj.bindings = 'conflict' with pytest.raises(ValueError): obj.add_elem(elem) assert obj.paths == {} assert obj.bindings == 'conflict' assert obj.methods == {} assert elem.ident == 'spam' assert elem.parent is None elem.set_ident.assert_not_called()
def test_add_elem_parents(self, mocker): elem = mocker.Mock(spec=elements.Path, ident='spam') elem.parent = None descendant = mocker.Mock(spec=elements.Path, ident=None) descendant.parent = elem obj = elements.Root() obj.add_elem(descendant, 'descendant') assert obj.paths == {'spam': elem} assert obj.bindings is None assert obj.methods == {} assert elem.ident == 'spam' assert elem.parent is obj elem.set_ident.assert_not_called() descendant.set_ident.assert_called_once_with('descendant')
def test_set_ident(self): obj = elements.Root() with pytest.raises(ValueError): obj.set_ident('ident')