def test_editable(self):
     editable_model = PyTableModel([[0]], editable=True)
     self.assertFalse(
         int(self.model.flags(self.model.index(0, 0)) & Qt.ItemIsEditable))
     self.assertTrue(
         int(
             editable_model.flags(editable_model.index(0, 0))
             & Qt.ItemIsEditable))
 def test_init_wrap_empty(self):
     # pylint: disable=protected-access
     t = []
     model = PyTableModel(t)
     self.assertIs(model._table, t)
     t.append([1, 2, 3])
     self.assertEqual(list(model), [[1, 2, 3]])
    def test_report_table_with_images(self):
        def basic_icon():
            pixmap = QPixmap(15, 15)
            pixmap.fill(QColor("red"))
            return QIcon(pixmap)

        def basic_scene():
            scene = QGraphicsScene()
            scene.addRect(QRectF(0, 0, 100, 100))
            return scene

        rep = OWReport()
        model = PyTableModel([['x', 1, 2]])
        model.setHorizontalHeaderLabels(['a', 'b', 'c'])

        model.setData(model.index(0, 1), basic_icon(), Qt.DecorationRole)
        model.setData(model.index(0, 2), basic_scene(), Qt.DisplayRole)

        view = gui.TableView()
        view.show()
        view.setModel(model)
        rep.report_table('Name', view)
        self.maxDiff = None
        pattern = re.compile(
            re.escape('<h2>Name</h2><table>\n'
                      '<tr>'
                      '<th style="color:black;border:0;background:transparent;'
                      'text-align:left;vertical-align:middle;">a</th>'
                      '<th style="color:black;border:0;background:transparent;'
                      'text-align:left;vertical-align:middle;">b</th>'
                      '<th style="color:black;border:0;background:transparent;'
                      'text-align:left;vertical-align:middle;">c</th>'
                      '</tr>'
                      '<tr>'
                      '<td style="color:black;border:0;background:transparent;'
                      'text-align:left;vertical-align:middle;">x</td>'
                      '<td style="color:black;border:0;background:transparent;'
                      'text-align:right;vertical-align:middle;">'
                      '<img src="data:image/png;base64,') + '(.+)' +
            re.escape(  # any string for the icon
                '"/>1</td>'
                '<td style="color:black;border:0;background:transparent;'
                'text-align:right;vertical-align:middle;">') + '(.+)' +
            re.escape('</td></tr></table>')  # str for the scene
        )
        self.assertTrue(bool(pattern.match(rep.report_html)))
    def test_report_table(self):
        rep = OWReport()
        model = PyTableModel([['x', 1, 2], ['y', 2, 2]])
        model.setHorizontalHeaderLabels(['a', 'b', 'c'])

        model.setData(model.index(0, 0), Qt.AlignHCenter | Qt.AlignTop,
                      Qt.TextAlignmentRole)
        model.setData(model.index(1, 0), QFont('', -1, QFont.Bold),
                      Qt.FontRole)
        model.setData(model.index(1, 2), QBrush(Qt.red), Qt.BackgroundRole)

        view = gui.TableView()
        view.show()
        view.setModel(model)
        rep.report_table('Name', view)
        self.maxDiff = None
        self.assertEqual(
            rep.report_html, '<h2>Name</h2><table>\n'
            '<tr>'
            '<th style="color:black;border:0;background:transparent;'
            'text-align:left;vertical-align:middle;">a</th>'
            '<th style="color:black;border:0;background:transparent;'
            'text-align:left;vertical-align:middle;">b</th>'
            '<th style="color:black;border:0;background:transparent;'
            'text-align:left;vertical-align:middle;">c</th>'
            '</tr>'
            '<tr>'
            '<td style="color:black;border:0;background:transparent;'
            'text-align:center;vertical-align:top;">x</td>'
            '<td style="color:black;border:0;background:transparent;'
            'text-align:right;vertical-align:middle;">1</td>'
            '<td style="color:black;border:0;background:transparent;'
            'text-align:right;vertical-align:middle;">2</td>'
            '</tr>'
            '<tr>'
            '<td style="color:black;border:0;background:transparent;'
            'font-weight: bold;text-align:left;vertical-align:middle;">y</td>'
            '<td style="color:black;border:0;background:transparent;'
            'text-align:right;vertical-align:middle;">2</td>'
            '<td style="color:black;border:0;background:#ff0000;'
            'text-align:right;vertical-align:middle;">2</td>'
            '</tr></table>')
 def test_init(self):
     self.model = PyTableModel()
     self.assertEqual(self.model.rowCount(), 0)
 def setUp(self):
     self.model = PyTableModel([[1, 4],
                                [2, 3]])
class TestPyTableModel(unittest.TestCase):
    def setUp(self):
        self.model = PyTableModel([[1, 4],
                                   [2, 3]])

    def test_init(self):
        self.model = PyTableModel()
        self.assertEqual(self.model.rowCount(), 0)

    def test_rowCount(self):
        self.assertEqual(self.model.rowCount(), 2)
        self.assertEqual(len(self.model), 2)

    def test_columnCount(self):
        self.assertEqual(self.model.columnCount(), 2)

    def test_data(self):
        mi = self.model.index(0, 0)
        self.assertEqual(self.model.data(mi), '1')
        self.assertEqual(self.model.data(mi, Qt.EditRole), 1)

    def test_editable(self):
        editable_model = PyTableModel([[0]], editable=True)
        self.assertFalse(int(self.model.flags(self.model.index(0, 0)) & Qt.ItemIsEditable))
        self.assertTrue(int(editable_model.flags(editable_model.index(0, 0)) & Qt.ItemIsEditable))

    def test_sort(self):
        self.model.sort(1)
        self.assertEqual(self.model.index(0, 0).data(Qt.EditRole), 2)

    def test_setHeaderLabels(self):
        self.model.setHorizontalHeaderLabels(['Col 1', 'Col 2'])
        self.assertEqual(self.model.headerData(1, Qt.Horizontal), 'Col 2')
        self.assertEqual(self.model.headerData(1, Qt.Vertical), 2)

    def test_removeRows(self):
        self.model.removeRows(0, 1)
        self.assertEqual(len(self.model), 1)
        self.assertEqual(self.model[0][1], 3)

    def test_removeColumns(self):
        self.model.removeColumns(0, 1)
        self.assertEqual(self.model.columnCount(), 1)
        self.assertEqual(self.model[1][0], 3)

    def test_insertRows(self):
        self.model.insertRows(0, 1)
        self.assertEqual(self.model[1][0], 1)

    def test_insertColumns(self):
        self.model.insertColumns(0, 1)
        self.assertEqual(self.model[0], ['', 1, 4])

    def test_wrap(self):
        self.model.wrap([[0]])
        self.assertEqual(self.model.rowCount(), 1)
        self.assertEqual(self.model.columnCount(), 1)

    def test_init_wrap_empty(self):
        # pylint: disable=protected-access
        t = []
        model = PyTableModel(t)
        self.assertIs(model._table, t)
        t.append([1, 2, 3])
        self.assertEqual(list(model), [[1, 2, 3]])

    def test_clear(self):
        self.model.clear()
        self.assertEqual(self.model.rowCount(), 0)

    def test_append(self):
        self.model.append([5, 6])
        self.assertEqual(self.model[2][1], 6)
        self.assertEqual(self.model.rowCount(), 3)

    def test_extend(self):
        self.model.extend([[5, 6]])
        self.assertEqual(self.model[2][1], 6)
        self.assertEqual(self.model.rowCount(), 3)

    def test_insert(self):
        self.model.insert(0, [5, 6])
        self.assertEqual(self.model[0][1], 6)
        self.assertEqual(self.model.rowCount(), 3)

    def test_remove(self):
        self.model.remove([2, 3])
        self.assertEqual(self.model.rowCount(), 1)

    def test_other_roles(self):
        self.model.append([2, 3])
        self.model.setData(self.model.index(2, 0),
                           Qt.AlignCenter,
                           Qt.TextAlignmentRole)
        del self.model[1]
        self.assertTrue(Qt.AlignCenter &
                        self.model.data(self.model.index(1, 0),
                                        Qt.TextAlignmentRole))
    def test_sorting(self):
        assert issubclass(PyTableModel, AbstractSortTableModel)
        model = PyTableModel([[1, 4],
                              [2, 2],
                              [3, 3]])
        model.sort(1, Qt.AscendingOrder)
        # mapToSourceRows
        self.assertSequenceEqual(model.mapToSourceRows(...).tolist(), [1, 2, 0])
        self.assertEqual(model.mapToSourceRows(1).tolist(), 2)
        self.assertSequenceEqual(model.mapToSourceRows([1, 2]).tolist(), [2, 0])
        self.assertSequenceEqual(model.mapToSourceRows([]), [])
        self.assertSequenceEqual(model.mapToSourceRows(np.array([], dtype=int)).tolist(), [])
        self.assertRaises(IndexError, model.mapToSourceRows, np.r_[0.])

        # mapFromSourceRows
        self.assertSequenceEqual(model.mapFromSourceRows(...).tolist(), [2, 0, 1])
        self.assertEqual(model.mapFromSourceRows(1).tolist(), 0)
        self.assertSequenceEqual(model.mapFromSourceRows([1, 2]).tolist(), [0, 1])
        self.assertSequenceEqual(model.mapFromSourceRows([]), [])
        self.assertSequenceEqual(model.mapFromSourceRows(np.array([], dtype=int)).tolist(), [])
        self.assertRaises(IndexError, model.mapFromSourceRows, np.r_[0.])

        model.sort(1, Qt.DescendingOrder)
        self.assertSequenceEqual(model.mapToSourceRows(...).tolist(), [0, 2, 1])
        self.assertSequenceEqual(model.mapFromSourceRows(...).tolist(), [0, 2, 1])
class TestPyTableModel(unittest.TestCase):
    def setUp(self):
        self.model = PyTableModel([[1, 4],
                                   [2, 3]])

    def test_init(self):
        self.model = PyTableModel()
        self.assertEqual(self.model.rowCount(), 0)

    def test_rowCount(self):
        self.assertEqual(self.model.rowCount(), 2)
        self.assertEqual(len(self.model), 2)

    def test_columnCount(self):
        self.assertEqual(self.model.columnCount(), 2)

    def test_data(self):
        mi = self.model.index(0, 0)
        self.assertEqual(self.model.data(mi), '1')
        self.assertEqual(self.model.data(mi, Qt.EditRole), 1)

    def test_editable(self):
        editable_model = PyTableModel([[0]], editable=True)
        self.assertFalse(self.model.flags(self.model.index(0, 0)) & Qt.ItemIsEditable)
        self.assertTrue(editable_model.flags(editable_model.index(0, 0)) & Qt.ItemIsEditable)

    def test_sort(self):
        self.model.sort(1)
        self.assertEqual(self.model.index(0, 0).data(Qt.EditRole), 2)

    def test_setHeaderLabels(self):
        self.model.setHorizontalHeaderLabels(['Col 1', 'Col 2'])
        self.assertEqual(self.model.headerData(1, Qt.Horizontal), 'Col 2')
        self.assertEqual(self.model.headerData(1, Qt.Vertical), 2)

    def test_removeRows(self):
        self.model.removeRows(0, 1)
        self.assertEqual(len(self.model), 1)
        self.assertEqual(self.model[0][1], 3)

    def test_removeColumns(self):
        self.model.removeColumns(0, 1)
        self.assertEqual(self.model.columnCount(), 1)
        self.assertEqual(self.model[1][0], 3)

    def test_insertRows(self):
        self.model.insertRows(0, 1)
        self.assertEqual(self.model[1][0], 1)

    def test_insertColumns(self):
        self.model.insertColumns(0, 1)
        self.assertEqual(self.model[0], ['', 1, 4])

    def test_wrap(self):
        self.model.wrap([[0]])
        self.assertEqual(self.model.rowCount(), 1)
        self.assertEqual(self.model.columnCount(), 1)

    def test_init_wrap_empty(self):
        # pylint: disable=protected-access
        t = []
        model = PyTableModel(t)
        self.assertIs(model._table, t)
        t.append([1, 2, 3])
        self.assertEqual(list(model), [[1, 2, 3]])

    def test_clear(self):
        self.model.clear()
        self.assertEqual(self.model.rowCount(), 0)

    def test_append(self):
        self.model.append([5, 6])
        self.assertEqual(self.model[2][1], 6)
        self.assertEqual(self.model.rowCount(), 3)

    def test_extend(self):
        self.model.extend([[5, 6]])
        self.assertEqual(self.model[2][1], 6)
        self.assertEqual(self.model.rowCount(), 3)

    def test_insert(self):
        self.model.insert(0, [5, 6])
        self.assertEqual(self.model[0][1], 6)
        self.assertEqual(self.model.rowCount(), 3)

    def test_remove(self):
        self.model.remove([2, 3])
        self.assertEqual(self.model.rowCount(), 1)

    def test_other_roles(self):
        self.model.append([2, 3])
        self.model.setData(self.model.index(2, 0),
                           Qt.AlignCenter,
                           Qt.TextAlignmentRole)
        del self.model[1]
        self.assertTrue(Qt.AlignCenter &
                        self.model.data(self.model.index(1, 0),
                                        Qt.TextAlignmentRole))

    def test_set_item_signals(self):
        def p(*s):
            return [[x] for x in s]

        def assert_changed(startrow, stoprow, ncolumns):
            start, stop = changed[-1][:2]
            self.assertEqual(start.row(), startrow)
            self.assertEqual(stop.row(), stoprow)
            self.assertEqual(start.column(), 0)
            self.assertEqual(stop.column(), ncolumns)

        self.model.wrap(p(0, 1, 2, 3, 4, 5))
        aboutinserted = QSignalSpy(self.model.rowsAboutToBeInserted)
        inserted = QSignalSpy(self.model.rowsInserted)
        aboutremoved = QSignalSpy(self.model.rowsAboutToBeRemoved)
        removed = QSignalSpy(self.model.rowsRemoved)
        changed = QSignalSpy(self.model.dataChanged)

        # Insert rows
        self.model[2:4] = p(6, 7, 8, 9, 10) + [[11, 2]]
        self.assertEqual(list(self.model), p(0, 1, 6, 7, 8, 9, 10) + [[11, 2]] + p(4, 5))
        self.assertEqual(len(changed), 1)
        assert_changed(2, 3, 1)
        self.assertEqual(aboutinserted[-1][1:], [4, 7])
        self.assertEqual(inserted[-1][1:], [4, 7])
        self.assertEqual(len(aboutremoved), 0)
        self.assertEqual(len(removed), 0)

        # Remove rows
        self.model[2:8] = p(2, 3)
        self.assertEqual(list(self.model), p(0, 1, 2, 3, 4, 5))
        self.assertEqual(len(changed), 2)  # one is from before
        assert_changed(2, 3, 0)
        self.assertEqual(aboutremoved[-1][1:], [4, 7])
        self.assertEqual(removed[-1][1:], [4, 7])
        self.assertEqual(len(inserted), 1)  # from before
        self.assertEqual(len(aboutinserted), 1)  # from before

        # Change rows
        self.model[-5:-3] = p(19, 20)
        self.assertEqual(list(self.model), p(0, 19, 20, 3, 4, 5))
        self.assertEqual(len(changed), 3)  # two are from before
        assert_changed(1, 2, 0)
        self.assertEqual(len(inserted), 1)  # from before
        self.assertEqual(len(aboutinserted), 1)  # from before
        self.assertEqual(len(removed), 1)  # from before
        self.assertEqual(len(aboutremoved), 1)  # from before

        # Insert without change
        self.model[3:3] = p(21, 22)
        self.assertEqual(list(self.model), p(0, 19, 20, 21, 22, 3, 4, 5))
        self.assertEqual(len(changed), 3)  #from before
        self.assertEqual(inserted[-1][1:], [3, 4])
        self.assertEqual(aboutinserted[-1][1:], [3, 4])
        self.assertEqual(len(removed), 1)  # from before
        self.assertEqual(len(aboutremoved), 1)  # from before

        # Remove without change
        self.model[3:5] = []
        self.assertEqual(list(self.model), p(0, 19, 20, 3, 4, 5))
        self.assertEqual(len(changed), 3)  #from before
        self.assertEqual(removed[-1][1:], [3, 4])
        self.assertEqual(aboutremoved[-1][1:], [3, 4])
        self.assertEqual(len(inserted), 2)  # from before
        self.assertEqual(len(aboutinserted), 2)  # from before

        # Remove all
        self.model[:] = []
        self.assertEqual(list(self.model), [])
        self.assertEqual(len(changed), 3)  #from before
        self.assertEqual(removed[-1][1:], [0, 5])
        self.assertEqual(aboutremoved[-1][1:], [0, 5])
        self.assertEqual(len(inserted), 2)  # from before
        self.assertEqual(len(aboutinserted), 2)  # from before

        # Add to empty
        self.model[:] = p(0, 1, 2, 3)
        self.assertEqual(list(self.model), p(0, 1, 2, 3))
        self.assertEqual(len(changed), 3)  #from before
        self.assertEqual(inserted[-1][1:], [0, 3])
        self.assertEqual(inserted[-1][1:], [0, 3])
        self.assertEqual(len(removed), 3)  # from before
        self.assertEqual(len(aboutremoved), 3)  # from before