1
1
# This file is based on the original C++ qabstractitemmodeltester.cpp from:
2
2
# http://code.qt.io/cgit/qt/qtbase.git/tree/src/testlib/qabstractitemmodeltester.cpp
3
- # Commit 1f2f61d80860f55638cfd194bbed5d679a588b1f
3
+ # Commit b6759ff81c1b6ecb7e18144db0b7c9c5884d7f24
4
4
#
5
5
# Licensed under the following terms:
6
6
#
41
41
#
42
42
# $QT_END_LICENSE$
43
43
44
+ import enum
44
45
import collections
45
46
46
47
from pytestqt .qt_compat import qt_api
52
53
HAS_QT_TESTER = hasattr (qt_api .QtTest , "QAbstractItemModelTester" )
53
54
54
55
56
+ class _ChangeInFlight (enum .Enum ):
57
+
58
+ COLUMNS_INSERTED = enum .auto ()
59
+ COLUMNS_MOVED = enum .auto ()
60
+ COLUMNS_REMOVED = enum .auto ()
61
+ LAYOUT_CHANGED = enum .auto ()
62
+ MODEL_RESET = enum .auto ()
63
+ ROWS_INSERTED = enum .auto ()
64
+ ROWS_MOVED = enum .auto ()
65
+ ROWS_REMOVED = enum .auto ()
66
+
67
+
55
68
class ModelTester :
56
69
57
70
"""A tester for Qt's QAbstractItemModels."""
@@ -63,6 +76,7 @@ def __init__(self, config):
63
76
self ._remove = None
64
77
self ._changing = []
65
78
self ._qt_tester = None
79
+ self ._change_in_flight = None
66
80
67
81
def _debug (self , text ):
68
82
print ("modeltest: " + text )
@@ -131,10 +145,32 @@ def check(self, model, force_py=False):
131
145
# Special checks for changes
132
146
self ._model .layoutAboutToBeChanged .connect (self ._on_layout_about_to_be_changed )
133
147
self ._model .layoutChanged .connect (self ._on_layout_changed )
148
+
149
+ # column operations
150
+ self ._model .columnsAboutToBeInserted .connect (
151
+ self ._on_columns_about_to_be_inserted
152
+ )
153
+ self ._model .columnsAboutToBeMoved .connect (self ._on_columns_about_to_be_moved )
154
+ self ._model .columnsAboutToBeRemoved .connect (
155
+ self ._on_columns_about_to_be_removed
156
+ )
157
+ self ._model .columnsInserted .connect (self ._on_columns_inserted )
158
+ self ._model .columnsMoved .connect (self ._on_columns_moved )
159
+ self ._model .columnsRemoved .connect (self ._on_columns_removed )
160
+
161
+ # row operations
134
162
self ._model .rowsAboutToBeInserted .connect (self ._on_rows_about_to_be_inserted )
163
+ self ._model .rowsAboutToBeMoved .connect (self ._on_rows_about_to_be_moved )
135
164
self ._model .rowsAboutToBeRemoved .connect (self ._on_rows_about_to_be_removed )
136
165
self ._model .rowsInserted .connect (self ._on_rows_inserted )
166
+ self ._model .rowsMoved .connect (self ._on_rows_moved )
137
167
self ._model .rowsRemoved .connect (self ._on_rows_removed )
168
+
169
+ # reset
170
+ self ._model .modelAboutToBeReset .connect (self ._on_model_about_to_be_reset )
171
+ self ._model .modelReset .connect (self ._on_model_reset )
172
+
173
+ # data
138
174
self ._model .dataChanged .connect (self ._on_data_changed )
139
175
self ._model .headerDataChanged .connect (self ._on_header_data_changed )
140
176
@@ -515,11 +551,104 @@ def _test_data(self):
515
551
qt_api .QtCore .Qt .CheckState .Checked ,
516
552
]
517
553
554
+ def _on_columns_about_to_be_inserted (self , parent , start , end ):
555
+ assert self ._change_in_flight is None
556
+ self ._change_in_flight = _ChangeInFlight .COLUMNS_INSERTED
557
+ last_index = self ._model .index (start - 1 , 0 , parent )
558
+ self ._debug (
559
+ "columns about to be inserted: start {}, end {}, parent {}, "
560
+ "current count of parent {}, last before insertion {} {}" .format (
561
+ start ,
562
+ end ,
563
+ self ._modelindex_debug (parent ),
564
+ self ._model .rowCount (parent ),
565
+ self ._modelindex_debug (last_index ),
566
+ self ._model .data (last_index ),
567
+ )
568
+ )
569
+
570
+ def _on_columns_inserted (self , parent , start , end ):
571
+ assert self ._change_in_flight == _ChangeInFlight .COLUMNS_INSERTED
572
+ self ._change_in_flight = None
573
+ self ._debug (
574
+ "columns inserted: start {}, end {}, parent {}, "
575
+ "current count of parent {}, " .format (
576
+ start ,
577
+ end ,
578
+ self ._modelindex_debug (parent ),
579
+ self ._model .rowCount (parent ),
580
+ )
581
+ )
582
+
583
+ def _on_columns_about_to_be_moved (
584
+ self , source_parent , source_start , source_end , dest_parent , dest_column
585
+ ):
586
+ assert self ._change_in_flight is None
587
+ self ._change_in_flight = _ChangeInFlight .COLUMNS_MOVED
588
+ self ._debug (
589
+ "columns about to be moved: source start {}, source end {}, "
590
+ "source parent {}, destination parent {}, "
591
+ "destination column {}" .format (
592
+ source_start ,
593
+ source_end ,
594
+ self ._modelindex_debug (source_parent ),
595
+ self ._modelindex_debug (dest_parent ),
596
+ dest_column ,
597
+ )
598
+ )
599
+
600
+ def _on_columns_moved (
601
+ self , source_parent , source_start , source_end , dest_parent , dest_column
602
+ ):
603
+ assert self ._change_in_flight == _ChangeInFlight .COLUMNS_MOVED
604
+ self ._change_in_flight = None
605
+ self ._debug (
606
+ "columns moved: source start {}, source end {}, "
607
+ "source parent {}, destination parent {}, "
608
+ "destination column {}" .format (
609
+ source_start ,
610
+ source_end ,
611
+ self ._modelindex_debug (source_parent ),
612
+ self ._modelindex_debug (dest_parent ),
613
+ dest_column ,
614
+ )
615
+ )
616
+
617
+ def _on_columns_about_to_be_removed (self , parent , start , end ):
618
+ assert self ._change_in_flight is None
619
+ self ._change_in_flight = _ChangeInFlight .COLUMNS_REMOVED
620
+ last_index = self ._model .index (start - 1 , 0 , parent )
621
+ self ._debug (
622
+ "columns about to be removed: start {}, end {}, "
623
+ "parent {}, parent rowcount {}, last before removal {}" .format (
624
+ start ,
625
+ end ,
626
+ self ._modelindex_debug (parent ),
627
+ self ._model .rowCount (parent ),
628
+ self ._modelindex_debug (last_index ),
629
+ )
630
+ )
631
+
632
+ def _on_columns_removed (self , parent , start , end ):
633
+ assert self ._change_in_flight == _ChangeInFlight .COLUMNS_REMOVED
634
+ self ._change_in_flight = None
635
+ self ._debug (
636
+ "columns removed: start {}, end {}, parent {}, parent rowcount {}" .format (
637
+ start ,
638
+ end ,
639
+ self ._modelindex_debug (parent ),
640
+ self ._model .rowCount (parent ),
641
+ )
642
+ )
643
+
518
644
def _on_rows_about_to_be_inserted (self , parent , start , end ):
519
645
"""Store what is about to be inserted.
520
646
521
647
This gets stored to make sure it actually happens in rowsInserted.
522
648
"""
649
+ assert self ._change_in_flight is None
650
+ self ._change_in_flight = _ChangeInFlight .ROWS_INSERTED
651
+
523
652
last_index = self ._model .index (start - 1 , 0 , parent )
524
653
next_index = self ._model .index (start , 0 , parent )
525
654
parent_rowcount = self ._model .rowCount (parent )
@@ -545,6 +674,9 @@ def _on_rows_about_to_be_inserted(self, parent, start, end):
545
674
546
675
def _on_rows_inserted (self , parent , start , end ):
547
676
"""Confirm that what was said was going to happen actually did."""
677
+ assert self ._change_in_flight == _ChangeInFlight .ROWS_INSERTED
678
+ self ._change_in_flight = None
679
+
548
680
c = self ._insert .pop ()
549
681
last_data = (
550
682
self ._model .data (self ._model .index (start - 1 , 0 , parent ))
@@ -595,21 +727,72 @@ def _on_rows_inserted(self, parent, start, end):
595
727
if next_data is not None :
596
728
assert c .next == next_data
597
729
730
+ def _on_rows_about_to_be_moved (
731
+ self , source_parent , source_start , source_end , dest_parent , dest_row
732
+ ):
733
+ assert self ._change_in_flight is None
734
+ self ._change_in_flight = _ChangeInFlight .ROWS_MOVED
735
+ self ._debug (
736
+ "rows about to be moved: source start {}, source end {}, "
737
+ "source parent {}, destination parent {}, "
738
+ "destination row {}" .format (
739
+ source_start ,
740
+ source_end ,
741
+ self ._modelindex_debug (source_parent ),
742
+ self ._modelindex_debug (dest_parent ),
743
+ dest_row ,
744
+ )
745
+ )
746
+
747
+ def _on_rows_moved (
748
+ self , source_parent , source_start , source_end , dest_parent , dest_row
749
+ ):
750
+ assert self ._change_in_flight == _ChangeInFlight .ROWS_MOVED
751
+ self ._change_in_flight = None
752
+ self ._debug (
753
+ "rows moved: source start {}, source end {}, "
754
+ "source parent {}, destination parent {}, "
755
+ "destination row {}" .format (
756
+ source_start ,
757
+ source_end ,
758
+ self ._modelindex_debug (source_parent ),
759
+ self ._modelindex_debug (dest_parent ),
760
+ dest_row ,
761
+ )
762
+ )
763
+
598
764
def _on_layout_about_to_be_changed (self ):
765
+ assert self ._change_in_flight is None
766
+ self ._change_in_flight = _ChangeInFlight .LAYOUT_CHANGED
767
+
599
768
for i in range (max (self ._model .rowCount (), 100 )):
600
769
idx = qt_api .QtCore .QPersistentModelIndex (self ._model .index (i , 0 ))
601
770
self ._changing .append (idx )
602
771
603
772
def _on_layout_changed (self ):
773
+ assert self ._change_in_flight == _ChangeInFlight .LAYOUT_CHANGED
774
+ self ._change_in_flight = None
775
+
604
776
for p in self ._changing :
605
777
assert p == self ._model .index (p .row (), p .column (), p .parent ())
606
778
self ._changing = []
607
779
780
+ def _on_model_about_to_be_reset (self ):
781
+ assert self ._change_in_flight is None
782
+ self ._change_in_flight = _ChangeInFlight .MODEL_RESET
783
+
784
+ def _on_model_reset (self ):
785
+ assert self ._change_in_flight == _ChangeInFlight .MODEL_RESET
786
+ self ._change_in_flight = None
787
+
608
788
def _on_rows_about_to_be_removed (self , parent , start , end ):
609
789
"""Store what is about to be removed to make sure it actually happens.
610
790
611
791
This gets stored to make sure it actually happens in rowsRemoved.
612
792
"""
793
+ assert self ._change_in_flight is None
794
+ self ._change_in_flight = _ChangeInFlight .ROWS_REMOVED
795
+
613
796
parent_rowcount = self ._model .rowCount (parent )
614
797
last_index = (
615
798
self ._model .index (start - 1 , 0 , parent )
@@ -648,6 +831,9 @@ def _on_rows_about_to_be_removed(self, parent, start, end):
648
831
649
832
def _on_rows_removed (self , parent , start , end ):
650
833
"""Confirm that what was said was going to happen actually did."""
834
+ assert self ._change_in_flight == _ChangeInFlight .ROWS_REMOVED
835
+ self ._change_in_flight = None
836
+
651
837
c = self ._remove .pop ()
652
838
last_data = (
653
839
self ._model .data (self ._model .index (start - 1 , 0 , c .parent ))
0 commit comments