class TestGraphAddNodeExceptionWarning(UnittestPythonCompatibility): """ Test logged warnings and raised Exceptions by Graph add_node. Same as for add_nodes """ def setUp(self): """ Build empty graph to add a node to and test default state """ self.graph = Graph() def test_add_node_none(self): """ Unable to add 'None' node when auto_nid False """ # no problem when auto_nid self.graph.add_node() self.assertTrue(len(self.graph) == 1) self.graph.auto_nid = False self.assertRaises(GraphitException, self.graph.add_node, None) def test_add_node_hasable(self): """ When auto_nid equals False, the nid should be a hashable object :return: """ self.graph.auto_nid = False self.assertRaises(GraphitException, self.graph.add_node, [1, 2]) def test_add_node_duplicate(self): """ Duplication is no problem with auto_nid but without the previous node is updated with the attributes of the new one. A warning is logged. """ # With auto_nid self.graph.add_nodes([1, 1]) self.assertEqual(len(self.graph), 2) # Without auto_nid self.graph.auto_nid = False self.graph.add_nodes([3, 3]) self.assertEqual(len(self.graph), 3) self.assertItemsEqual(self.graph.keys(), [1, 1, 3]) self.assertItemsEqual(self.graph.keys('_id'), [1, 2, 3])
class TestGraphNodeAttribute(UnittestPythonCompatibility): """ Test methods to get and set node attributes using a node storage driver. `DictStorage` is the default driver tested here. """ def setUp(self): """ Build default Graph with node and edge attributes """ self.graph = Graph() self.graph.add_nodes([('g', {'weight': 1.0, 'value': 'gr'}), ('r', {'weight': 1.5, 'value': 'ra'}), ('a', {'weight': 2.0, 'value': 'ap'}), ('p', {'weight': 2.5, 'value': 'ph'}), ('h', {'weight': 3.0})]) self.graph.add_edges([(1, 2), (2, 3), (3, 4), (3, 5), (4, 5)], value=True, weight=43.2, key='edge') def test_graph_node_attr_storeget(self): """ Test getting node attributes directly from the `nodes` storage """ self.assertEqual(self.graph.nodes[1]['weight'], 1.0) self.assertEqual(self.graph.nodes[3]['value'], 'ap') def test_graph_node_attr_storeset(self): """ Test setting node attributes directly from the `nodes` storage """ self.graph.nodes[1]['weight'] = 5.0 self.graph.nodes[3]['value'] = 'dd' self.assertEqual(self.graph.nodes[1]['weight'], 5.0) self.assertEqual(self.graph.nodes[3]['value'], 'dd') def test_graph_node_attr_key_tag(self): """ Test get attributes based on `key_tag` """ self.assertEqual(self.graph.nodes[1][self.graph.data.key_tag], 'g') self.assertEqual(self.graph.nodes[3][self.graph.data.key_tag], 'a') self.assertEqual(self.graph.get(1), 'g') # uses default node data tag def test_graph_node_attr_value_tag(self): """ Test get attributes based on `value_tag` """ self.assertEqual(self.graph.nodes[1][self.graph.data.value_tag], 'gr') self.assertEqual(self.graph.nodes[3][self.graph.data.value_tag], 'ap') def test_graph_node_attr_dict(self): """ Test if the returned full attribute dictionary is of expected format """ self.assertDictEqual(self.graph.nodes[1], {'_id': 1, 'key': 'g', 'weight': 1.0, 'value': 'gr'}) self.assertDictEqual(self.graph.nodes[3], {'_id': 3, 'key': 'a', 'weight': 2.0, 'value': 'ap'}) def test_graph_node_attr_exception(self): """ Test `nodes` exception if node not present """ self.assertRaises(GraphitException, self.graph.__getitem__, 10) self.assertIsNone(self.graph.nodes.get(10)) def test_graph_node_attr_graphget(self): """ Test access node attributes by nid using the (sub)graph 'get' method """ self.assertEqual(self.graph.get(4), 'p') self.assertEqual(self.graph.get(4, 'weight'), 2.5) # Key does not exist self.assertIsNone(self.graph.get(4, key='no_key')) # Key does not exist return defaultkey self.assertEqual(self.graph.get(4, key='no_key', defaultattr='weight'), 2.5) def test_graph_node_attr_singlenode_get(self): """ Test getting node attribute values directly using the single node Graph API which has the required methods (node_tools) added to it. """ node = self.graph.getnodes(5) self.assertEqual(node['key'], 'h') self.assertEqual(node.key, 'h') self.assertEqual(node.get('key'), 'h') self.assertEqual(node['weight'], 3.0) self.assertEqual(node.weight, 3.0) self.assertEqual(node.get('weight'), 3.0) def test_graph_node_attr_singlenode_set(self): """ Test setting node attribute values directly using the single node Graph API which has the required methods (node_tools) added to it. """ node = self.graph.getnodes(5) node.weight = 5.0 node['key'] = 'z' node.set('value', True) self.assertEqual(node.nodes[5]['weight'], 5.0) self.assertEqual(node.nodes[5]['key'], 'z') self.assertEqual(node.nodes[5]['value'], True) def test_graph_node_attr_singlenode_exception(self): """ Test exceptions in direct access to node attributes in a single graph class """ node = self.graph.getnodes(5) self.assertEqual(node.get(), None) # Default get returns value, not set self.assertRaises(KeyError, node.__getitem__, 'no_key') self.assertRaises(AttributeError, node.__getattr__, 'no_key') def test_graph_nodes_dict_keys(self): """ Test graph dict-like 'keys' support. """ self.assertListEqual(self.graph.keys(), ['g', 'r', 'a', 'p', 'h']) self.assertListEqual(self.graph.keys('weight'), [1.0, 1.5, 2.0, 2.5, 3.0]) def test_graph_nodes_dict_values(self): """ Test graph dict-like 'values' support. """ self.assertListEqual(self.graph.values(), ['gr', 'ra', 'ap', 'ph', None]) self.assertItemsEqual(self.graph.values('no_value'), [None, None, None, None, None]) def test_graph_nodes_dict_items(self): """ Test graph dict-like 'items' support. """ self.assertItemsEqual(self.graph.items(), [('g', 'gr'), ('r', 'ra'), ('a', 'ap'), ('p', 'ph'), ('h', None)]) self.assertItemsEqual(self.graph.items(valuestring='_id'), [('g', 1), ('r', 2), ('a', 3), ('p', 4), ('h', 5)]) self.assertItemsEqual(self.graph.items(keystring='_id', valuestring='weight'), [(1, 1.0), (2, 1.5), (3, 2.0), (4, 2.5), (5, 3.0)])
class TestGraphAddNode(UnittestPythonCompatibility): """ Test Graph add_node method with the Graph.auto_nid set to False mimicking the behaviour of many popular graph packages """ currpath = os.path.dirname(__file__) image = os.path.join(currpath, '../', 'files', 'graph_tgf.png') def setUp(self): """ Build empty graph to add a node to and test default state """ self.graph = Graph(auto_nid=False) # empty before addition self.assertTrue(len(self.graph) == 0) self.assertTrue(len(self.graph.nodes) == 0) self.assertTrue(len(self.graph.edges) == 0) self.assertTrue(len(self.graph.adjacency) == 0) # auto_nid self.assertFalse(self.graph.auto_nid) def tearDown(self): """ Test state after node addition """ nid = list(self.graph.nodes) # The nid should equal the node self.assertEqual(nid, [self.node]) # The _id is still set self.assertEqual(self.graph.nodes[self.node]['_id'], 1) self.assertEqual(self.graph._nodeid, 2) # filled after addition self.assertTrue(len(self.graph) == 1) self.assertTrue(len(self.graph.nodes) == 1) self.assertTrue(len(self.graph.edges) == 0) self.assertTrue(len(self.graph.adjacency) == 1) # no adjacency self.assertTrue(len(self.graph.adjacency[nid[0]]) == 0) # node key self.assertItemsEqual(self.graph.keys(), [self.node]) def test_add_node_string(self): """ Test adding a single node, string type """ self.node = 'first' nid = self.graph.add_node(self.node) # Added string should be unicode self.assertIsInstance(self.graph.nodes[nid][self.graph.key_tag], UNICODE_TYPE) def test_add_node_int(self): """ Test adding a single node, int type """ self.node = 100 self.graph.add_node(self.node) def test_add_node_float(self): """ Test adding a single node, float type """ self.node = 4.55 self.graph.add_node(self.node) def test_add_node_bool(self): """ Test adding a single node, float bool """ self.node = False self.graph.add_node(self.node) def test_add_node_function(self): """ Test adding a single node, function type """ self.node = map self.graph.add_node(self.node) def test_add_node_object(self): """ Test adding an object as a single node. In this case the object is file """ self.node = open(self.image, 'r') self.graph.add_node(self.node)
class TestGraphAddNodesAutonid(UnittestPythonCompatibility): """ Test Graph the add_nodes method using different input with the Graph class set to default auto_nid = True """ def setUp(self): """ Build empty graph to add nodes to and test default state """ self.graph = Graph() # empty before addition self.assertTrue(len(self.graph) == 0) self.assertTrue(len(self.graph.nodes) == 0) self.assertTrue(len(self.graph.edges) == 0) self.assertTrue(len(self.graph.adjacency) == 0) # auto_nid self.assertTrue(self.graph.auto_nid) self.assertEqual(self.graph._nodeid, 1) def tearDown(self): """ Test state after node addition """ length = len(self.itr) nids = range(1, length + 1) # auto_nid self.assertItemsEqual(list(self.graph.nodes), nids) self.assertEqual(self.graph._nodeid, length + 1) # filled after addition self.assertTrue(len(self.graph) == length) self.assertTrue(len(self.graph.nodes) == length) self.assertTrue(len(self.graph.edges) == 0) self.assertTrue(len(self.graph.adjacency) == length) # node key self.assertItemsEqual(self.graph.keys(), self.itr) def test_add_nodes_from_list(self): """ Test adding multiple nodes from a list """ self.itr = [1, 2, 3] self.graph.add_nodes(self.itr) def test_add_nodes_from_tuple(self): """ Test adding multiple nodes from a tuple """ self.itr = [1, 2, 3] self.graph.add_nodes(tuple(self.itr)) def test_add_nodes_from_set(self): """ Test adding multiple nodes from a set """ self.itr = [1, 2, 3] self.graph.add_nodes(set(self.itr)) def test_add_nodes_from_dict(self): """ Test adding multiple nodes from a dict """ self.itr = [1, 2, 3] self.graph.add_nodes({1: 'one', 2: 'two', 3: 'three'}) def test_add_nodes_from_string(self): """ Test adding multiple nodes from a string """ self.itr = ['g', 'r', 'a', 'p', 'h'] self.graph.add_nodes(''.join(self.itr)) def test_add_nodes_from_range(self): """ Test adding multiple nodes from a range """ self.itr = range(5) self.graph.add_nodes(self.itr) def test_add_nodes_from_graph(self): """ Test adding multiple nodes from another graph """ self.itr = [1, 2, 3] g = Graph() g.add_nodes(self.itr) self.graph.add_nodes(g.nodes)
class TestGraphAddNodeAutonid(UnittestPythonCompatibility): """ Test Graph add_node method using different input with the Graph class set to default auto_nid = True """ currpath = os.path.dirname(__file__) image = os.path.join(currpath, '../', 'files', 'graph_tgf.png') def setUp(self): """ Build empty graph to add a node to and test default state """ self.graph = Graph() # empty before addition self.assertTrue(len(self.graph) == 0) self.assertTrue(len(self.graph.nodes) == 0) self.assertTrue(len(self.graph.edges) == 0) self.assertTrue(len(self.graph.adjacency) == 0) # auto_nid self.assertTrue(self.graph.auto_nid) self.assertEqual(self.graph._nodeid, 1) def tearDown(self): """ Test state after node addition """ nid = list(self.graph.nodes) # auto_nid self.assertItemsEqual(nid, [1]) self.assertEqual(self.graph._nodeid, 2) # filled after addition self.assertTrue(len(self.graph) == 1) self.assertTrue(len(self.graph.nodes) == 1) self.assertTrue(len(self.graph.edges) == 0) self.assertTrue(len(self.graph.adjacency) == 1) # no adjacency self.assertTrue(len(self.graph.adjacency[nid[0]]) == 0) # node key self.assertItemsEqual(self.graph.keys(), [self.node]) def test_add_node_string(self): """ Test adding a single node, string type """ self.node = 'first' nid = self.graph.add_node(self.node) # Added string should be unicode self.assertIsInstance(self.graph.nodes[nid][self.graph.key_tag], UNICODE_TYPE) def test_add_node_int(self): """ Test adding a single node, int type """ self.node = 100 self.graph.add_node(self.node) def test_add_node_float(self): """ Test adding a single node, float type """ self.node = 4.55 self.graph.add_node(self.node) def test_add_node_bool(self): """ Test adding a single node, float bool """ self.node = False self.graph.add_node(self.node) def test_add_node_function(self): """ Test adding a single node, function type """ self.node = map self.graph.add_node(self.node) def test_add_node_list(self): """ Test adding a single node, list type """ self.node = [1.22, 4.5, 6] self.graph.add_node(self.node) def test_add_node_set(self): """ Test adding a single node, set type """ self.node = {1.22, 4.5, 6} self.graph.add_node(self.node) def test_add_node_object(self): """ Test adding an object as a single node. In this case the object is file """ self.node = open(self.image, 'rb') self.graph.add_node(self.node) def test_add_node_image(self): """ Test adding an object as a single node. In this case the object is file and we do not convert it to unicode """ self.node = open(self.image, 'rb').read() self.graph.add_node(self.node, unicode_convert=False)