Repository: Qiskit/qiskit

Issue:
qiskit/mapper/_coupling.py needs more testing
### What is the expected enhancement?

The coupling graph structure in `qiskit/mapper/_coupling.py` is currently not very well tested. Please, add more tests.



Discussion:

Resolving patch:
diff --git a/qiskit/mapper/_coupling.py b/qiskit/mapper/_coupling.py
--- a/qiskit/mapper/_coupling.py
+++ b/qiskit/mapper/_coupling.py
@@ -118,6 +118,11 @@ def add_qubit(self, name):
         """
         if name in self.qubits:
             raise CouplingError("%s already in coupling graph" % name)
+        if not isinstance(name, tuple):
+            raise CouplingError("name %s is not a tuple")
+        if not (isinstance(name[0], str) and isinstance(name[1], int)):
+            raise CouplingError("name %s is not of the right form, it must"
+                                " be: (regname, idx)")
 
         self.node_counter += 1
         self.G.add_node(self.node_counter)
@@ -144,7 +149,10 @@ def connected(self):
 
         Return True if connected, False otherwise
         """
-        return nx.is_weakly_connected(self.G)
+        try:
+            return nx.is_weakly_connected(self.G)
+        except nx.exception.NetworkXException:
+            return False
 
     def compute_distance(self):
         """
@@ -174,10 +182,14 @@ def distance(self, q1, q2):
 
     def __str__(self):
         """Return a string representation of the coupling graph."""
-        s = "qubits: "
-        s += ", ".join(["%s[%d] @ %d" % (k[0], k[1], v)
-                        for k, v in self.qubits.items()])
-        s += "\nedges: "
-        s += ", ".join(["%s[%d]-%s[%d]" % (e[0][0], e[0][1], e[1][0], e[1][1])
-                        for e in self.get_edges()])
+        s = ""
+        if self.qubits:
+            s += "qubits: "
+            s += ", ".join(["%s[%d] @ %d" % (k[0], k[1], v)
+                            for k, v in self.qubits.items()])
+        if self.get_edges():
+            s += "\nedges: "
+            s += ", ".join(
+                ["%s[%d]-%s[%d]" % (e[0][0], e[0][1], e[1][0], e[1][1])
+                 for e in self.get_edges()])
         return s


Test patch:
diff --git a/test/python/test_mapper__coupling.py b/test/python/test_mapper__coupling.py
new file mode 100644
--- /dev/null
+++ b/test/python/test_mapper__coupling.py
@@ -0,0 +1,84 @@
+# -*- coding: utf-8 -*-
+
+# Copyright 2018, IBM.
+#
+# This source code is licensed under the Apache License, Version 2.0 found in
+# the LICENSE.txt file in the root directory of this source tree.
+
+# pylint: disable=missing-docstring
+
+
+from qiskit.mapper import _coupling
+from .common import QiskitTestCase
+
+
+class CouplingTest(QiskitTestCase):
+
+    def test_coupling_dict2list(self):
+        input_dict = {0: [1, 2], 1: [2]}
+        result = _coupling.coupling_dict2list(input_dict)
+        expected = [[0, 1], [0, 2], [1, 2]]
+        self.assertEqual(expected, result)
+
+    def test_coupling_dict2list_empty_dict(self):
+        self.assertIsNone(_coupling.coupling_dict2list({}))
+
+    def test_coupling_list2dict(self):
+        input_list = [[0, 1], [0, 2], [1, 2]]
+        result = _coupling.coupling_list2dict(input_list)
+        expected = {0: [1, 2], 1: [2]}
+        self.assertEqual(expected, result)
+
+    def test_coupling_list2dict_empty_list(self):
+        self.assertIsNone(_coupling.coupling_list2dict([]))
+
+    def test_empty_coupling_class(self):
+        coupling = _coupling.Coupling()
+        self.assertEqual(0, coupling.size())
+        self.assertEqual([], coupling.get_qubits())
+        self.assertEqual([], coupling.get_edges())
+        self.assertFalse(coupling.connected())
+        self.assertEqual("", str(coupling))
+
+    def test_coupling_str(self):
+        coupling_dict = {0: [1, 2], 1: [2]}
+        coupling = _coupling.Coupling(coupling_dict)
+        expected = ("qubits: q[0] @ 1, q[1] @ 2, q[2] @ 3\n"
+                    "edges: q[0]-q[1], q[0]-q[2], q[1]-q[2]")
+        self.assertEqual(expected, str(coupling))
+
+    def test_coupling_compute_distance(self):
+        coupling_dict = {0: [1, 2], 1: [2]}
+        coupling = _coupling.Coupling(coupling_dict)
+        self.assertTrue(coupling.connected())
+        coupling.compute_distance()
+        qubits = coupling.get_qubits()
+        result = coupling.distance(qubits[0], qubits[1])
+        self.assertEqual(1, result)
+
+    def test_coupling_compute_distance_coupling_error(self):
+        coupling = _coupling.Coupling()
+        self.assertRaises(_coupling.CouplingError, coupling.compute_distance)
+
+    def test_add_qubit(self):
+        coupling = _coupling.Coupling()
+        self.assertEqual("", str(coupling))
+        coupling.add_qubit(('q', 0))
+        self.assertEqual("qubits: q[0] @ 1", str(coupling))
+
+    def test_add_qubit_not_tuple(self):
+        coupling = _coupling.Coupling()
+        self.assertRaises(_coupling.CouplingError, coupling.add_qubit, 'q0')
+
+    def test_add_qubit_tuple_incorrect_form(self):
+        coupling = _coupling.Coupling()
+        self.assertRaises(_coupling.CouplingError, coupling.add_qubit,
+                          ('q', '0'))
+
+    def test_add_edge(self):
+        coupling = _coupling.Coupling()
+        self.assertEqual("", str(coupling))
+        coupling.add_edge(("q", 0), ('q', 1))
+        expected = ("qubits: q[0] @ 1, q[1] @ 2\n"
+                    "edges: q[0]-q[1]")
+        self.assertEqual(expected, str(coupling))