# -*- coding: utf-8 -*-
"""Test functions of dictlist.py"""
from __future__ import absolute_import
import re
from copy import copy, deepcopy
from pickle import HIGHEST_PROTOCOL, dumps, loads
import pytest
from cobra.core import DictList, Object
@pytest.fixture(scope="function")
[docs]def dict_list():
obj = Object("test1")
test_list = DictList()
test_list.append(obj)
return obj, test_list
[docs]def test_contains(dict_list):
obj, test_list = dict_list
assert obj in test_list
assert obj.id in test_list
assert Object("not_in") not in test_list
assert "not_in" not in test_list
[docs]def test_index(dict_list):
obj, test_list = dict_list
assert test_list.index("test1") == 0
assert test_list.index(obj) == 0
with pytest.raises(ValueError):
test_list.index("f")
with pytest.raises(ValueError):
test_list.index(Object("f"))
# Ensure indexing with an object that is a different object
# also raises an error
with pytest.raises(ValueError):
test_list.index(Object("test1"))
[docs]def test_independent():
a = DictList([Object("o1"), Object("o2")])
b = DictList()
assert "o1" in a
assert "o1" not in b
b.append(Object("o3"))
assert "o3" not in a
assert "o3" in b
[docs]def test_get_by_any(dict_list):
obj, test_list = dict_list
assert test_list.get_by_any(0) == [obj]
assert test_list.get_by_any("test1") == [obj]
with pytest.raises(KeyError):
test_list.get_by_any("not-in-list")
with pytest.raises(TypeError):
test_list.get_by_any(1.1)
assert test_list.get_by_any(obj) == [obj]
[docs]def test_append(dict_list):
obj, test_list = dict_list
obj2 = Object("test2")
test_list.append(obj2)
with pytest.raises(ValueError):
test_list.append(Object("test1"))
assert test_list.index(obj2) == 1
assert test_list[1] == obj2
assert test_list.get_by_id("test2") is obj2
assert len(test_list) == 2
[docs]def test_insert(dict_list):
obj, test_list = dict_list
obj2 = Object("a")
test_list.insert(0, obj2)
assert test_list.index(obj2) == 0
assert test_list.index("test1") == 1
assert test_list.get_by_id("a") is obj2
assert len(test_list) == 2
with pytest.raises(ValueError):
test_list.append(obj2)
[docs]def test_extend(dict_list):
obj, test_list = dict_list
obj_list = [Object("test%d" % (i)) for i in range(2, 10)]
test_list.extend(obj_list)
assert test_list[1].id == "test2"
assert test_list.get_by_id("test2") == obj_list[0]
assert test_list[8].id == "test9"
assert len(test_list) == 9
with pytest.raises(ValueError):
test_list.extend([Object("test1")])
# Even if the object is unique, if it is present twice in the new
# list, it should still raise an exception
with pytest.raises(ValueError):
test_list.extend([Object("testd"), Object("testd")])
[docs]def test_iadd(dict_list):
obj, test_list = dict_list
obj_list = [Object("test%d" % (i)) for i in range(2, 10)]
test_list += obj_list
assert test_list[1].id == "test2"
assert test_list.get_by_id("test2") == obj_list[0]
assert test_list[8].id == "test9"
assert len(test_list) == 9
[docs]def test_add(dict_list):
obj, test_list = dict_list
obj_list = [Object("test%d" % (i)) for i in range(2, 10)]
sum = test_list + obj_list
assert sum is not test_list
assert sum is not obj_list
assert test_list[0].id == "test1"
assert sum[1].id == "test2"
assert sum.get_by_id("test2") == obj_list[0]
assert sum[8].id == "test9"
assert len(test_list) == 1
assert len(sum) == 9
[docs]def test_sub(dict_list):
obj, test_list = dict_list
obj_list = [Object("test%d" % i) for i in range(2, 10)]
sum = test_list + obj_list
sub = sum - test_list
assert test_list[0].id == "test1"
assert sub[0].id == "test2"
assert len(sub) == 8
assert sum - obj_list == test_list
[docs]def test_isub(dict_list):
obj, test_list = dict_list
obj_list = [Object("test%d" % i) for i in range(2, 10)]
sum = test_list + obj_list
sum -= obj_list[2:4]
assert len(sum) == 7
with pytest.raises(ValueError):
sum -= [Object("bogus")]
[docs]def test_init_copy(dict_list):
obj, test_list = dict_list
test_list.append(Object("test2"))
copied = DictList(test_list)
assert test_list is not copied
assert isinstance(copied, test_list.__class__)
assert len(test_list) == len(copied)
for i, v in enumerate(test_list):
assert test_list[i].id == copied[i].id
assert i == copied.index(v.id)
assert test_list[i] is copied[i]
assert v is copied.get_by_id(v.id)
[docs]def test_slice(dict_list):
obj, test_list = dict_list
test_list.append(Object("test2"))
test_list.append(Object("test3"))
sliced = test_list[:-1]
assert test_list is not sliced
assert isinstance(sliced, test_list.__class__)
assert len(test_list) == len(sliced) + 1
for i, v in enumerate(sliced):
assert test_list[i].id == sliced[i].id
assert i == sliced.index(v.id)
assert test_list[i] is sliced[i]
assert test_list[i] is sliced.get_by_id(v.id)
[docs]def test_copy(dict_list):
obj, test_list = dict_list
test_list.append(Object("test2"))
copied = copy(test_list)
assert test_list is not copied
assert isinstance(copied, test_list.__class__)
assert len(test_list) == len(copied)
for i, v in enumerate(test_list):
assert test_list[i].id == copied[i].id
assert i == copied.index(v.id)
assert test_list[i] is copied[i]
assert v is copied.get_by_id(v.id)
[docs]def test_deepcopy(dict_list):
obj, test_list = dict_list
test_list.append(Object("test2"))
copied = deepcopy(test_list)
assert test_list is not copied
assert isinstance(copied, test_list.__class__)
assert len(test_list) == len(copied)
for i, v in enumerate(test_list):
assert test_list[i].id == copied[i].id
assert i == copied.index(v.id)
assert test_list[i] is not copied[i]
assert v is not copied.get_by_id(v.id)
[docs]def test_pickle(dict_list):
obj, test_list = dict_list
test_list.append(Object("test2"))
for protocol in range(HIGHEST_PROTOCOL):
pickle_str = dumps(test_list, protocol=protocol)
copied = loads(pickle_str)
assert test_list is not copied
assert isinstance(copied, test_list.__class__)
assert len(test_list) == len(copied)
for i, v in enumerate(test_list):
assert test_list[i].id == copied[i].id
assert i == copied.index(v.id)
assert test_list[i] is not copied[i]
assert v is not copied.get_by_id(v.id)
[docs]def test_query(dict_list):
obj, test_list = dict_list
obj2 = Object("test2")
obj2.name = "foobar1"
test_list.append(obj2)
result = test_list.query("test1") # matches only test1
assert len(result) == 1
result = test_list.query(u"test1", "id") # matches with unicode
assert len(result) == 1
assert result[0] == obj
result = test_list.query("foo", "name") # matches only test2
assert len(result) == 1
assert result[0] == obj2
result = test_list.query("test", "id") # matches test1 and test2
assert len(result) == 2
# Test with a regular expression
result = test_list.query(re.compile("test[0-9]"), "id")
assert len(result) == 2
result = test_list.query(re.compile("test[29]"), "id")
assert len(result) == 1
# Test query of name
result = test_list.query(re.compile("foobar."), "name")
assert len(result) == 1
# Test query with lambda function
result = test_list.query(lambda x: x.id == "test1")
assert len(result) == 1
[docs]def test_removal():
obj_list = DictList(Object("test%d" % (i)) for i in range(2, 10))
del obj_list[3]
assert "test5" not in obj_list
assert obj_list.index(obj_list[-1]) == len(obj_list) - 1
assert len(obj_list) == 7
del obj_list[3:5]
assert "test6" not in obj_list
assert "test7" not in obj_list
assert obj_list.index(obj_list[-1]) == len(obj_list) - 1
assert len(obj_list) == 5
removed = obj_list.pop(1)
assert obj_list.index(obj_list[-1]) == len(obj_list) - 1
assert removed.id == "test3"
assert "test3" not in obj_list
assert len(obj_list) == 4
removed = obj_list.pop()
assert removed.id == "test9"
assert removed.id not in obj_list
assert len(obj_list) == 3
[docs]def test_set():
obj_list = DictList(Object("test%d" % (i)) for i in range(10))
obj_list[4] = Object("testa")
assert obj_list.index("testa") == 4
assert obj_list[4].id == "testa"
obj_list[5:7] = [Object("testb"), Object("testc")]
assert obj_list.index("testb") == 5
assert obj_list[5].id == "testb"
assert obj_list.index("testc") == 6
assert obj_list[6].id == "testc"
# Even if the object is unique, if it is present twice in the new
# list, it should still raise an exception
with pytest.raises(ValueError):
obj_list.__setitem__(slice(5, 7), [Object("testd"), Object("testd")])
[docs]def test_sort_and_reverse():
dl = DictList(Object("test%d" % (i)) for i in reversed(range(10)))
assert dl[0].id == "test9"
dl.sort()
assert len(dl) == 10
assert dl[0].id == "test0"
assert dl.index("test0") == 0
dl.reverse()
assert dl[0].id == "test9"
assert dl.index("test0") == 9
[docs]def test_dir(dict_list):
obj, test_list = dict_list
# Make sure tab completion works
attrs = dir(test_list)
assert "test1" in attrs
assert "_dict" in attrs # attribute of DictList
[docs]def test_union(dict_list):
obj, test_list = dict_list
test_list.union([Object("test1"), Object("test2")])
# Add only 1 element
assert len(test_list) == 2
assert test_list.index("test2") == 1