Exemplo n.º 1
0
    def _on_rows_removed(self, parent, start, end):
        """Confirm that what was said was going to happen actually did."""
        c = self._remove.pop()
        last_data = self._model.data(self._model.index(start - 1, 0, c.parent))
        next_data = self._model.data(self._model.index(start, 0, c.parent))
        current_size = self._model.rowCount(parent)
        expected_size = c.old_size - (end - start + 1)

        self._debug("rows removed: start {}, end {}".format(start, end))
        self._debug("  from rowsAboutToBeRemoved: parent {}, "
                    "size {} (-> {} expected), "
                    "next data {!r}, last data {!r}".format(
                        self._modelindex_debug(c.parent), c.old_size,
                        expected_size, qt_api.extract_from_variant(c.next),
                        qt_api.extract_from_variant(c.last)))

        self._debug("  now in rowsRemoved:        parent {}, size {}, "
                    "next data {!r}, last data {!r}".format(
                        self._modelindex_debug(parent), current_size,
                        qt_api.extract_from_variant(next_data),
                        qt_api.extract_from_variant(last_data)))

        if not qt_api.QtCore.qVersion().startswith('4.'):
            # Skipping this on Qt4 as the parent changes for some reason
            # see _on_rows_inserted for details
            assert c.parent == parent

        assert current_size == expected_size
        assert c.last == last_data
        assert c.next == next_data
Exemplo n.º 2
0
    def _on_rows_inserted(self, parent, start, end):
        """Confirm that what was said was going to happen actually did."""
        c = self._insert.pop()
        last_data = (
            self._model.data(self._model.index(start - 1, 0, parent))
            if start - 1 >= 0
            else None
        )
        next_data = (
            self._model.data(self._model.index(end + 1, 0, c.parent))
            if end + 1 < self._model.rowCount(c.parent)
            else None
        )
        expected_size = c.old_size + (end - start + 1)
        current_size = self._model.rowCount(parent)

        self._debug("rows inserted: start {}, end {}".format(start, end))
        self._debug(
            "  from rowsAboutToBeInserted: parent {}, "
            "size {} (-> {} expected), "
            "next data {!r}, last data {!r}".format(
                self._modelindex_debug(c.parent),
                c.old_size,
                expected_size,
                qt_api.extract_from_variant(c.next),
                qt_api.extract_from_variant(c.last),
            )
        )

        self._debug(
            "  now in rowsInserted:        parent {}, size {}, "
            "next data {!r}, last data {!r}".format(
                self._modelindex_debug(parent),
                current_size,
                qt_api.extract_from_variant(next_data),
                qt_api.extract_from_variant(last_data),
            )
        )

        if not qt_api.QtCore.qVersion().startswith("4."):
            # Skipping this on Qt4 as the parent changes for some reason:
            # modeltest: rows about to be inserted: [...]
            #            parent <invalid> (0x7f8f540eacf8), [...]
            # [...]
            # modeltest: from rowsAboutToBeInserted:
            #            parent 0/0 None (0x7f8f540eacf8), [...]
            # modeltest: now in rowsInserted:
            #            parent <invalid> (0x7f8f60a96cf8) [...]
            assert c.parent == parent

        for ii in range(start, end + 1):
            idx = self._model.index(ii, 0, parent)
            self._debug(" item {} inserted: {}".format(ii, self._modelindex_debug(idx)))
        self._debug("")

        assert current_size == expected_size
        if last_data is not None:
            assert c.last == last_data
        if next_data is not None:
            assert c.next == next_data
Exemplo n.º 3
0
    def _test_data(self):
        """Test model's implementation of data()"""
        # Invalid index should return an invalid qvariant
        value = self._model.data(qt_api.QtCore.QModelIndex(),
                                 qt_api.QtCore.Qt.DisplayRole)
        assert qt_api.extract_from_variant(value) is None

        if self._model.rowCount() == 0:
            return

        # A valid index should have a valid QVariant data
        assert self._model.index(0, 0).isValid()

        # shouldn't be able to set data on an invalid index
        ok = self._model.setData(qt_api.QtCore.QModelIndex(), "foo",
                                 qt_api.QtCore.Qt.DisplayRole)
        assert not ok

        types = [
            (qt_api.QtCore.Qt.ToolTipRole, str),
            (qt_api.QtCore.Qt.StatusTipRole, str),
            (qt_api.QtCore.Qt.WhatsThisRole, str),
            (qt_api.QtCore.Qt.SizeHintRole, qt_api.QtCore.QSize),
            (qt_api.QtCore.Qt.FontRole, qt_api.QtGui.QFont),
            (qt_api.QtCore.Qt.BackgroundColorRole, (qt_api.QtGui.QColor,
                                                    qt_api.QtGui.QBrush)),
            (qt_api.QtCore.Qt.TextColorRole, (qt_api.QtGui.QColor,
                                              qt_api.QtGui.QBrush)),
        ]

        # General purpose roles with a fixed expected type
        for role, typ in types:
            data = self._model.data(self._model.index(0, 0), role)
            assert data == None or isinstance(data, typ), role

        # Check that the alignment is one we know about
        alignment = self._model.data(self._model.index(0, 0),
                                     qt_api.QtCore.Qt.TextAlignmentRole)
        alignment = qt_api.extract_from_variant(alignment)
        if alignment is not None:
            try:
                alignment = int(alignment)
            except (TypeError, ValueError):
                assert 0, '%r should be a TextAlignmentRole enum' % alignment
            mask = int(qt_api.QtCore.Qt.AlignHorizontal_Mask
                       | qt_api.QtCore.Qt.AlignVertical_Mask)
            assert alignment == alignment & mask

        # Check that the "check state" is one we know about.
        state = self._model.data(self._model.index(0, 0),
                                 qt_api.QtCore.Qt.CheckStateRole)
        assert state in [
            None, qt_api.QtCore.Qt.Unchecked,
            qt_api.QtCore.Qt.PartiallyChecked, qt_api.QtCore.Qt.Checked
        ]
Exemplo n.º 4
0
def test_qvariant(tmpdir):
    """Test that make_variant and extract_from_variant work in the same way
    across all supported Qt bindings.
    """
    settings = qt_api.QtCore.QSettings(str(tmpdir / 'foo.ini'),
                                       qt_api.QtCore.QSettings.IniFormat)
    settings.setValue('int', qt_api.make_variant(42))
    settings.setValue('str', qt_api.make_variant('Hello'))
    settings.setValue('empty', qt_api.make_variant())

    assert qt_api.extract_from_variant(settings.value('int')) == 42
    assert qt_api.extract_from_variant(settings.value('str')) == 'Hello'
    assert qt_api.extract_from_variant(settings.value('empty')) is None
Exemplo n.º 5
0
def test_qvariant(tmpdir):
    """Test that make_variant and extract_from_variant work in the same way
    across all supported Qt bindings.
    """
    settings = qt_api.QtCore.QSettings(str(tmpdir / "foo.ini"),
                                       qt_api.QtCore.QSettings.IniFormat)
    settings.setValue("int", qt_api.make_variant(42))
    settings.setValue("str", qt_api.make_variant("Hello"))
    settings.setValue("empty", qt_api.make_variant())

    assert qt_api.extract_from_variant(settings.value("int")) == 42
    assert qt_api.extract_from_variant(settings.value("str")) == "Hello"
    assert qt_api.extract_from_variant(settings.value("empty")) is None
Exemplo n.º 6
0
def test_qvariant(tmpdir):
    """Test that make_variant and extract_from_variant work in the same way
    across all supported Qt bindings.
    """
    settings = qt_api.QtCore.QSettings(str(tmpdir / 'foo.ini'),
                                       qt_api.QtCore.QSettings.IniFormat)
    settings.setValue('int', qt_api.make_variant(42))
    settings.setValue('str', qt_api.make_variant('Hello'))
    settings.setValue('empty', qt_api.make_variant())

    assert qt_api.extract_from_variant(settings.value('int')) == 42
    assert qt_api.extract_from_variant(settings.value('str')) == 'Hello'
    assert qt_api.extract_from_variant(settings.value('empty')) is None
Exemplo n.º 7
0
    def _test_data(self):
        """Test model's implementation of data()"""
        # Invalid index should return an invalid qvariant
        value = self._model.data(qt_api.QtCore.QModelIndex(), qt_api.QtCore.Qt.DisplayRole)
        assert qt_api.extract_from_variant(value) is None

        if self._model.rowCount() == 0:
            return

        # A valid index should have a valid QVariant data
        assert self._model.index(0, 0).isValid()

        # shouldn't be able to set data on an invalid index
        ok = self._model.setData(qt_api.QtCore.QModelIndex(), "foo",
                                 qt_api.QtCore.Qt.DisplayRole)
        assert not ok

        types = [
            (qt_api.QtCore.Qt.ToolTipRole, str),
            (qt_api.QtCore.Qt.StatusTipRole, str),
            (qt_api.QtCore.Qt.WhatsThisRole, str),
            (qt_api.QtCore.Qt.SizeHintRole, qt_api.QtCore.QSize),
            (qt_api.QtCore.Qt.FontRole, qt_api.QtGui.QFont),
            (qt_api.QtCore.Qt.BackgroundColorRole, qt_api.QtGui.QColor),
            (qt_api.QtCore.Qt.TextColorRole, qt_api.QtGui.QColor),
        ]

        # General purpose roles with a fixed expected type
        for role, typ in types:
            data = self._model.data(self._model.index(0, 0), role)
            assert data == None or isinstance(data, typ), role

        # Check that the alignment is one we know about
        alignment = self._model.data(self._model.index(0, 0),
                                     qt_api.QtCore.Qt.TextAlignmentRole)
        alignment = qt_api.extract_from_variant(alignment)
        if alignment is not None:
            try:
                alignment = int(alignment)
            except (TypeError, ValueError):
                assert 0, '%r should be a TextAlignmentRole enum' % alignment
            mask = int(qt_api.QtCore.Qt.AlignHorizontal_Mask |
                       qt_api.QtCore.Qt.AlignVertical_Mask)
            assert alignment == alignment & mask

        # Check that the "check state" is one we know about.
        state = self._model.data(self._model.index(0, 0),
                                 qt_api.QtCore.Qt.CheckStateRole)
        assert state in [None, qt_api.QtCore.Qt.Unchecked, qt_api.QtCore.Qt.PartiallyChecked,
                         qt_api.QtCore.Qt.Checked]
Exemplo n.º 8
0
def test_qvariant(tmpdir):
    """Test that make_variant and extract_from_variant work in the same way
    across all supported Qt bindings.
    """
    settings = qt_api.QtCore.QSettings(
        str(tmpdir / "foo.ini"), qt_api.QtCore.QSettings.IniFormat
    )
    settings.setValue("int", qt_api.make_variant(42))
    settings.setValue("str", qt_api.make_variant("Hello"))
    settings.setValue("empty", qt_api.make_variant())

    assert qt_api.extract_from_variant(settings.value("int")) == 42
    assert qt_api.extract_from_variant(settings.value("str")) == "Hello"
    assert qt_api.extract_from_variant(settings.value("empty")) is None
Exemplo n.º 9
0
    def _on_rows_inserted(self, parent, start, end):
        """Confirm that what was said was going to happen actually did."""
        c = self._insert.pop()
        last_data = self._model.data(self._model.index(start - 1, 0, parent))
        next_data = self._model.data(self._model.index(end + 1, 0, c.parent))
        expected_size = c.old_size + (end - start + 1)
        current_size = self._model.rowCount(parent)

        self._debug("rows inserted: start {}, end {}".format(start, end))
        self._debug("  from rowsAboutToBeInserted: parent {}, "
                    "size {} (-> {} expected), "
                    "next data {!r}, last data {!r}".format(
                        self._modelindex_debug(c.parent),
                        c.old_size, expected_size,
                        qt_api.extract_from_variant(c.next),
                        qt_api.extract_from_variant(c.last)
                    )
        )

        self._debug("  now in rowsInserted:        parent {}, size {}, "
                    "next data {!r}, last data {!r}".format(
                        self._modelindex_debug(parent),
                        current_size,
                        qt_api.extract_from_variant(next_data),
                        qt_api.extract_from_variant(last_data)
                    )
        )

        if not qt_api.QtCore.qVersion().startswith('4.'):
            # Skipping this on Qt4 as the parent changes for some reason:
            # modeltest: rows about to be inserted: [...]
            #            parent <invalid> (0x7f8f540eacf8), [...]
            # [...]
            # modeltest: from rowsAboutToBeInserted:
            #            parent 0/0 None (0x7f8f540eacf8), [...]
            # modeltest: now in rowsInserted:
            #            parent <invalid> (0x7f8f60a96cf8) [...]
            assert c.parent == parent

        for ii in range(start, end + 1):
            idx = self._model.index(ii, 0, parent)
            self._debug(" item {} inserted: {}".format(ii,
                                                       self._modelindex_debug(idx)))
        self._debug('')

        assert current_size == expected_size
        assert c.last == last_data
        assert c.next == next_data
Exemplo n.º 10
0
    def _test_basic(self):
        """Try to call a number of the basic functions (not all).

        Make sure the model doesn't outright segfault, testing the functions
        which make sense.
        """
        assert self._model.buddy(qt_api.QtCore.QModelIndex()) == qt_api.QtCore.QModelIndex()
        self._model.canFetchMore(qt_api.QtCore.QModelIndex())
        assert self._column_count(qt_api.QtCore.QModelIndex()) >= 0
        display_data = self._model.data(qt_api.QtCore.QModelIndex(),
                                        qt_api.QtCore.Qt.DisplayRole)

        assert qt_api.extract_from_variant(display_data) is None
        self._fetch_more(qt_api.QtCore.QModelIndex())
        flags = self._model.flags(qt_api.QtCore.QModelIndex())
        assert flags == qt_api.QtCore.Qt.ItemIsDropEnabled or not flags
        self._has_children(qt_api.QtCore.QModelIndex())
        self._model.hasIndex(0, 0)
        self._model.headerData(0, qt_api.QtCore.Qt.Horizontal)
        self._model.index(0, 0)
        self._model.itemData(qt_api.QtCore.QModelIndex())
        cache = None
        self._model.match(qt_api.QtCore.QModelIndex(), -1, cache)
        self._model.mimeTypes()
        assert self._parent(qt_api.QtCore.QModelIndex()) == qt_api.QtCore.QModelIndex()
        assert self._model.rowCount() >= 0
        self._model.setData(qt_api.QtCore.QModelIndex(), None, -1)
        self._model.setHeaderData(-1, qt_api.QtCore.Qt.Horizontal, None)
        self._model.setHeaderData(999999, qt_api.QtCore.Qt.Horizontal, None)
        self._model.sibling(0, 0, qt_api.QtCore.QModelIndex())
        self._model.span(qt_api.QtCore.QModelIndex())
        self._model.supportedDropActions()
Exemplo n.º 11
0
    def _test_basic(self):
        """Try to call a number of the basic functions (not all).

        Make sure the model doesn't outright segfault, testing the functions
        which make sense.
        """
        assert self._model.buddy(
            qt_api.QtCore.QModelIndex()) == qt_api.QtCore.QModelIndex()
        self._model.canFetchMore(qt_api.QtCore.QModelIndex())
        assert self._column_count(qt_api.QtCore.QModelIndex()) >= 0
        display_data = self._model.data(qt_api.QtCore.QModelIndex(),
                                        qt_api.QtCore.Qt.DisplayRole)

        assert qt_api.extract_from_variant(display_data) is None
        self._fetch_more(qt_api.QtCore.QModelIndex())
        flags = self._model.flags(qt_api.QtCore.QModelIndex())
        assert flags == qt_api.QtCore.Qt.ItemIsDropEnabled or not flags
        self._has_children(qt_api.QtCore.QModelIndex())
        self._model.hasIndex(0, 0)
        self._model.headerData(0, qt_api.QtCore.Qt.Horizontal)
        self._model.index(0, 0)
        self._model.itemData(qt_api.QtCore.QModelIndex())
        cache = None
        self._model.match(qt_api.QtCore.QModelIndex(), -1, cache)
        self._model.mimeTypes()
        assert self._parent(
            qt_api.QtCore.QModelIndex()) == qt_api.QtCore.QModelIndex()
        assert self._model.rowCount() >= 0
        self._model.setData(qt_api.QtCore.QModelIndex(), None, -1)
        self._model.setHeaderData(-1, qt_api.QtCore.Qt.Horizontal, None)
        self._model.setHeaderData(999999, qt_api.QtCore.Qt.Horizontal, None)
        self._model.sibling(0, 0, qt_api.QtCore.QModelIndex())
        self._model.span(qt_api.QtCore.QModelIndex())
        self._model.supportedDropActions()
Exemplo n.º 12
0
 def _modelindex_debug(self, index):
     """Get a string for debug output for a QModelIndex."""
     if not index.isValid():
         return '<invalid> (0x{:x})'.format(id(index))
     else:
         data = self._model.data(index, qt_api.QtCore.Qt.DisplayRole)
         return '{}/{} {!r} (0x{:x})'.format(
             index.row(), index.column(), qt_api.extract_from_variant(data),
             id(index))
Exemplo n.º 13
0
 def _modelindex_debug(self, index):
     """Get a string for debug output for a QModelIndex."""
     if not index.isValid():
         return '<invalid> (0x{:x})'.format(id(index))
     else:
         data = self._model.data(index, qt_api.QtCore.Qt.DisplayRole)
         return '{}/{} {!r} (0x{:x})'.format(
             index.row(), index.column(),
             qt_api.extract_from_variant(data),
             id(index))
Exemplo n.º 14
0
    def _on_rows_removed(self, parent, start, end):
        """Confirm that what was said was going to happen actually did."""
        c = self._remove.pop()
        last_data = self._model.data(self._model.index(start - 1, 0, c.parent))
        next_data = self._model.data(self._model.index(start, 0, c.parent))
        current_size = self._model.rowCount(parent)
        expected_size = c.old_size - (end - start + 1)

        self._debug("rows removed: start {}, end {}".format(start, end))
        self._debug("  from rowsAboutToBeRemoved: parent {}, "
                    "size {} (-> {} expected), "
                    "next data {!r}, last data {!r}".format(
                        self._modelindex_debug(c.parent),
                        c.old_size, expected_size,
                        qt_api.extract_from_variant(c.next),
                        qt_api.extract_from_variant(c.last)
                    )
        )

        self._debug("  now in rowsRemoved:        parent {}, size {}, "
                    "next data {!r}, last data {!r}".format(
                        self._modelindex_debug(parent),
                        current_size,
                        qt_api.extract_from_variant(next_data),
                        qt_api.extract_from_variant(last_data)
                    )
        )

        if not qt_api.QtCore.qVersion().startswith('4.'):
            # Skipping this on Qt4 as the parent changes for some reason
            # see _on_rows_inserted for details
            assert c.parent == parent

        assert current_size == expected_size
        assert c.last == last_data
        assert c.next == next_data
Exemplo n.º 15
0
    def _test_data(self):
        """Test model's implementation of data()"""
        if not self._has_children():
            return

        # A valid index should have a valid QVariant data
        assert self._model.index(0, 0).isValid()

        string_types = [str]
        if sys.version_info.major == 2:
            string_types.append(unicode)  # noqa
        if qt_api.QString is not None:
            string_types.append(qt_api.QString)

        string_types = tuple(string_types)

        types = [
            (qt_api.QtCore.Qt.DisplayRole, string_types),
            (qt_api.QtCore.Qt.ToolTipRole, string_types),
            (qt_api.QtCore.Qt.StatusTipRole, string_types),
            (qt_api.QtCore.Qt.WhatsThisRole, string_types),
            (qt_api.QtCore.Qt.SizeHintRole, qt_api.QtCore.QSize),
            (qt_api.QtCore.Qt.FontRole, qt_api.QtGui.QFont),
            (
                qt_api.QtCore.Qt.BackgroundColorRole,
                (qt_api.QtGui.QColor, qt_api.QtGui.QBrush),
            ),
            (
                qt_api.QtCore.Qt.TextColorRole,
                (qt_api.QtGui.QColor, qt_api.QtGui.QBrush),
            ),
            (
                qt_api.QtCore.Qt.DecorationRole,
                (
                    qt_api.QtGui.QPixmap,
                    qt_api.QtGui.QImage,
                    qt_api.QtGui.QIcon,
                    qt_api.QtGui.QColor,
                    qt_api.QtGui.QBrush,
                ),
            ),
        ]

        # General purpose roles with a fixed expected type
        for role, typ in types:
            data = self._model.data(self._model.index(0, 0), role)
            if data is not None:
                data = qt_api.extract_from_variant(data)
            assert data == None or isinstance(data, typ), role  # noqa

        # Check that the alignment is one we know about
        alignment = self._model.data(
            self._model.index(0, 0), qt_api.QtCore.Qt.TextAlignmentRole
        )
        alignment = qt_api.extract_from_variant(alignment)
        if alignment is not None:
            try:
                alignment = int(alignment)
            except (TypeError, ValueError):
                assert 0, "%r should be a TextAlignmentRole enum" % alignment
            mask = int(
                qt_api.QtCore.Qt.AlignHorizontal_Mask
                | qt_api.QtCore.Qt.AlignVertical_Mask
            )
            assert alignment == alignment & mask

        # Check that the "check state" is one we know about.
        state = self._model.data(
            self._model.index(0, 0), qt_api.QtCore.Qt.CheckStateRole
        )
        assert state in [
            None,
            qt_api.QtCore.Qt.Unchecked,
            qt_api.QtCore.Qt.PartiallyChecked,
            qt_api.QtCore.Qt.Checked,
        ]
Exemplo n.º 16
0
    def _check_children(self, parent, current_depth=0):
        """Check parent/children relationships.

        Called from the parent() test.

        A model that returns an index of parent X should also return X when
        asking for the parent of the index.

        This recursive function does pretty extensive testing on the whole
        model in an effort to catch edge cases.

        This function assumes that rowCount(), columnCount() and index()
        already work.  If they have a bug it will point it out, but the above
        tests should have already found the basic bugs because it is easier to
        figure out the problem in those tests then this one.
        """
        # First just try walking back up the tree.
        p = parent
        while p.isValid():
            p = p.parent()

        # For models that are dynamically populated
        if self._model.canFetchMore(parent):
            self._fetch_more(parent)

        rows = self._model.rowCount(parent)
        columns = self._column_count(parent)

        if rows > 0:
            assert self._has_children(parent)

        # Some further testing against rows(), columns(), and hasChildren()
        assert rows >= 0
        assert columns >= 0
        if rows > 0:
            assert self._has_children(parent)
        self._debug("Checking children of {} with depth {} "
                    "({} rows, {} columns)".format(
                        self._modelindex_debug(parent), current_depth,
                        rows, columns))

        top_left_child = self._model.index(0, 0, parent)

        assert not self._model.hasIndex(rows + 1, 0, parent)
        for r in range(rows):
            if self._model.canFetchMore(parent):
                self._fetch_more(parent)
            assert not self._model.hasIndex(r, columns + 1, parent)
            for c in range(columns):
                assert self._model.hasIndex(r, c, parent)
                index = self._model.index(r, c, parent)
                # rowCount() and columnCount() said that it existed...
                assert index.isValid()

                # index() should always return the same index when called twice
                # in a row
                modified_index = self._model.index(r, c, parent)
                assert index == modified_index

                # Make sure we get the same index if we request it twice in a
                # row
                a = self._model.index(r, c, parent)
                b = self._model.index(r, c, parent)
                assert a == b

                sibling = self._model.sibling(r, c, top_left_child)
                assert index == sibling

                sibling = top_left_child.sibling(r, c)
                assert index == sibling

                # Some basic checking on the index that is returned
                assert index.model() == self._model
                assert index.row() == r
                assert index.column() == c

                data = self._model.data(index, qt_api.QtCore.Qt.DisplayRole)
                if not self.data_display_may_return_none:
                    assert qt_api.extract_from_variant(data) is not None

                # If the next test fails here is some somewhat useful debug you
                # play with.

                if self._parent(index) != parent:
                    self._debug(
                        "parent-check failed for index {}:\n"
                        "  parent {} != expected {}".format(
                            self._modelindex_debug(index),
                            self._modelindex_debug(self._parent(index)),
                            self._modelindex_debug(parent)
                        )
                    )

                # Check that we can get back our real parent.
                assert self._parent(index) == parent

                # recursively go down the children
                if self._has_children(index) and current_depth < 10:
                    self._debug("{} has {} children".format(
                        self._modelindex_debug(index),
                        self._model.rowCount(index)
                    ))
                    self._check_children(index, current_depth + 1)

                # make sure that after testing the children that the index
                # doesn't change.
                newer_index = self._model.index(r, c, parent)
                assert index == newer_index
        self._debug("Children check for {} done".format(self._modelindex_debug(parent)))
Exemplo n.º 17
0
    def _check_children(self, parent, current_depth=0):
        """Check parent/children relationships.

        Called from the parent() test.

        A model that returns an index of parent X should also return X when
        asking for the parent of the index.

        This recursive function does pretty extensive testing on the whole
        model in an effort to catch edge cases.

        This function assumes that rowCount(), columnCount() and index()
        already work.  If they have a bug it will point it out, but the above
        tests should have already found the basic bugs because it is easier to
        figure out the problem in those tests then this one.
        """
        # First just try walking back up the tree.
        p = parent
        while p.isValid():
            p = p.parent()

        # For models that are dynamically populated
        if self._model.canFetchMore(parent):
            self._fetch_more(parent)

        rows = self._model.rowCount(parent)
        columns = self._column_count(parent)

        if rows > 0:
            assert self._has_children(parent)

        # Some further testing against rows(), columns(), and hasChildren()
        assert rows >= 0
        assert columns >= 0
        if rows > 0:
            assert self._has_children(parent)
        self._debug("Checking children of {} with depth {} "
                    "({} rows, {} columns)".format(
                        self._modelindex_debug(parent), current_depth, rows,
                        columns))

        top_left_child = self._model.index(0, 0, parent)

        assert not self._model.hasIndex(rows + 1, 0, parent)
        for r in range(rows):
            if self._model.canFetchMore(parent):
                self._fetch_more(parent)
            assert not self._model.hasIndex(r, columns + 1, parent)
            for c in range(columns):
                assert self._model.hasIndex(r, c, parent)
                index = self._model.index(r, c, parent)
                # rowCount() and columnCount() said that it existed...
                assert index.isValid()

                # index() should always return the same index when called twice
                # in a row
                modified_index = self._model.index(r, c, parent)
                assert index == modified_index

                # Make sure we get the same index if we request it twice in a
                # row
                a = self._model.index(r, c, parent)
                b = self._model.index(r, c, parent)
                assert a == b

                sibling = self._model.sibling(r, c, top_left_child)
                assert index == sibling

                sibling = top_left_child.sibling(r, c)
                assert index == sibling

                # Some basic checking on the index that is returned
                assert index.model() == self._model
                assert index.row() == r
                assert index.column() == c

                data = self._model.data(index, qt_api.QtCore.Qt.DisplayRole)
                if not self.data_display_may_return_none:
                    assert qt_api.extract_from_variant(data) is not None

                # If the next test fails here is some somewhat useful debug you
                # play with.

                if self._parent(index) != parent:
                    self._debug("parent-check failed for index {}:\n"
                                "  parent {} != expected {}".format(
                                    self._modelindex_debug(index),
                                    self._modelindex_debug(
                                        self._parent(index)),
                                    self._modelindex_debug(parent)))

                # Check that we can get back our real parent.
                assert self._parent(index) == parent

                # recursively go down the children
                if self._has_children(index) and current_depth < 10:
                    self._debug("{} has {} children".format(
                        self._modelindex_debug(index),
                        self._model.rowCount(index)))
                    self._check_children(index, current_depth + 1)

                # make sure that after testing the children that the index
                # doesn't change.
                newer_index = self._model.index(r, c, parent)
                assert index == newer_index
        self._debug("Children check for {} done".format(
            self._modelindex_debug(parent)))