def _resolve_partial(self, base_url, partial, recursions): """ Resolve a (partial) spec's references. :param mixed base_url: URL that the partial specs is located at. :param dict partial: The partial specs to work on. :param tuple recursions: A recursion stack for resolving references. :return: The partial with all references resolved. """ # Gather changes from the dereferencing iterator - we need to set new # values from the outside in, so we have to post-process this a little, # sorting paths by path length. changes = dict( tuple( self._dereferencing_iterator(base_url, partial, (), recursions))) paths = sorted(changes.keys(), key=len) # With the paths sorted, set them to the resolved values. from prance.util.path import path_set for path in paths: value = changes[path] if len(path) == 0: partial = value else: path_set(partial, list(path), value, create=True) return partial
def test_set_mixed_no_create(): # Sequence in Mapping must work result = path_set({ 'foo': [0] }, ('foo', 0), 42) assert { 'foo': [42] } == result # And Mapping in Sequence likewise result = path_set([{ 'foo': 'bar' }], (0, 'foo'), 42) assert [{ 'foo': 42 }] == result
def test_set_mixed_no_create(): # Sequence in Mapping must work result = path_set({"foo": [0]}, ("foo", 0), 42) assert {"foo": [42]} == result # And Mapping in Sequence likewise result = path_set([{"foo": "bar"}], (0, "foo"), 42) assert [{"foo": 42}] == result
def test_set_mapping_create(): # Setting missing keys must work result = path_set({}, ('foo',), 'bar', create = True) assert { 'foo': 'bar' } == result # Recursive setting must work result = path_set({}, ('foo', 'bar',), 'baz', create = True) assert { 'foo': { 'bar': 'baz' } } == result
def test_set_mixed_create(): # Creation should work based on the path element types result = path_set({}, ('foo', 0), 42, create = True) assert { 'foo': [42] } == result result = path_set([], (0, 'foo'), 42, create = True) assert [{ 'foo': 42 }] == result # Create int keys in dict result = path_set({}, (0,), 42, create = True) assert { 0: 42 } == result
def _translate_partial(self, base_url, partial): changes = dict(tuple(self._translating_iterator(base_url, partial, ()))) paths = sorted(changes.keys(), key=len) from prance.util.path import path_set for path in paths: value = changes[path] if len(path) == 0: partial = value else: path_set(partial, list(path), value, create=True) return partial
def test_set_mapping_create(): # Setting missing keys must work result = path_set({}, ("foo",), "bar", create=True) assert {"foo": "bar"} == result # Recursive setting must work result = path_set( {}, ( "foo", "bar", ), "baz", create=True, ) assert {"foo": {"bar": "baz"}} == result
def test_set_sequence_no_create(): # Tuples are not mutable - this must raise result = None with pytest.raises(TypeError): result = path_set((42,), (0,), "something") # Lists are mutable - this must work result = path_set( [ 42, ], (0,), "something", ) assert ["something"] == result # Try nested paths result = path_set([42, [1, 2]], (1, 0), "something") assert [42, ["something", 2]] == result # Bad paths must raise with pytest.raises(IndexError): path_set([], (0,), "something") with pytest.raises(IndexError): path_set([[]], (0, 1), "something")
def test_set_value(): value = 42 # Setting on a value type with a path should raise... with pytest.raises(TypeError): path_set(42, ('foo', 'bar'), 'something') with pytest.raises(TypeError): path_set(42, (0, 1), 'something') # ... and without a path or an empty path should raise an error with pytest.raises(KeyError): path_set(42, (), 'something') with pytest.raises(TypeError): path_set(42, None, 'something')
def test_set_mapping_no_create(): # Setting existing keys must work result = path_set({"foo": "bar"}, ("foo",), "new") assert {"foo": "new"} == result # Nested mappings should work just as well. result = path_set( {"foo": {"bar": "baz"}}, ( "foo", "bar", ), "new", ) assert {"foo": {"bar": "new"}} == result # Bad paths must raise with pytest.raises(KeyError): path_set({}, ("foo",), "something") with pytest.raises(KeyError): path_set( {"foo": {}}, ( "foo", "bar", ), "something", )
def test_set_value(): value = 42 # Setting on a value type with a path should raise... with pytest.raises(TypeError): path_set(42, ("foo", "bar"), "something") with pytest.raises(TypeError): path_set(42, (0, 1), "something") # ... and without a path or an empty path should raise an error with pytest.raises(KeyError): path_set(42, (), "something") with pytest.raises(TypeError): path_set(42, None, "something")
def test_set_bad_path(): # Raise with bad path types with pytest.raises(TypeError): path_set({}, 42, None) with pytest.raises(TypeError): path_set({}, 3.14, None) with pytest.raises(KeyError): path_set([], ('a', 'b'), None)
def test_set_mapping_no_create(): # Setting existing keys must work result = path_set({ 'foo': 'bar' }, ('foo',), 'new') assert { 'foo': 'new' } == result # Nested mappings should work just as well. result = path_set({ 'foo': { 'bar': 'baz' } }, ('foo', 'bar',), 'new') assert { 'foo': { 'bar': 'new' } } == result # Bad paths must raise with pytest.raises(KeyError): path_set({}, ('foo',), 'something') with pytest.raises(KeyError): path_set({ 'foo': {}}, ('foo', 'bar',), 'something')
def test_set_mixed_create_no_fill(): # Creation should not add items that are not necessary base = { 'foo': [123] } result = path_set(base, ('foo', 0), 42, create = True) assert { 'foo': [42] } == result
def test_set_sequence_create(): # If we want to create entries, then mutable sequences should have further # sequences added to it. result = path_set([], (1, 0), 'something', create = True) assert [None, ['something']] == result