BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
undostack.test.cpp File Reference

Implements class CLASS? More...

Include dependency graph for undostack.test.cpp:

Go to the source code of this file.

Classes

class  UndoStackTest
 

Functions

 TEST_F (UndoStackTest, beginMacrosEndMacros)
 Add item and changing its data from macros. More...
 
 TEST_F (UndoStackTest, commandTimeOfLife)
 Checking time of life of the command during undo/redo. More...
 
 TEST_F (UndoStackTest, copyLayerFromMultilayer)
 Creating two multilayers. Copying layer from one multilayer to another. More...
 
 TEST_F (UndoStackTest, expiredCommandTimeOfLife)
 Checking time of life of the command during undo/redo. More...
 
 TEST_F (UndoStackTest, initialState)
 
 TEST_F (UndoStackTest, insertAndSetData)
 Checks if we insert item, set data and undo everything we can get back to the data. More...
 
 TEST_F (UndoStackTest, insertDataAndGraph)
 Add GraphItem and Data1DItem, addisgn data to graph, undo, then redo. More...
 
 TEST_F (UndoStackTest, insertDataItemViaMacro)
 Setup Data1DItem via macro. More...
 
 TEST_F (UndoStackTest, insertNewItem)
 
 TEST_F (UndoStackTest, insertParentAndChild)
 Undo/redo scenario when few items inserted. More...
 
 TEST_F (UndoStackTest, insertPropertyItemID)
 Insert property item, unto, redo, and checking that identifier is preserved. More...
 
 TEST_F (UndoStackTest, itemIdentifierOnRemove)
 Insert item, remove row, undo and check item id. More...
 
 TEST_F (UndoStackTest, moveLayerFromMLDeleteAll)
 Create 2 multilayers, 3 layers each. More...
 
 TEST_F (UndoStackTest, moveLayerFromMLDeleteSecond)
 Move single layer from multilayer to another empty multilayer. More...
 
 TEST_F (UndoStackTest, moveLayerFromMultiLayer)
 Move single layer from multilayer to another empty multilayer. More...
 
 TEST_F (UndoStackTest, multiLayer)
 Create multilayer, add two layers, remove everything and undo. More...
 
 TEST_F (UndoStackTest, removeParentAndChild)
 Inserting parent and child, setting data to them, removing parent, undoing and checking. More...
 
 TEST_F (UndoStackTest, removeRow)
 Inserting item, setting the data, removing row, undoing, checking item and data. More...
 
 TEST_F (UndoStackTest, setData)
 Undo/redo scenario when item inserted and data set few times. More...
 
 TEST_F (UndoStackTest, setDataThroughItem)
 Undo/redo scenario when item data changed through item and not the model. More...
 
 TEST_F (UndoStackTest, setSameData)
 Undo/redo scenario when we set same data. Undo stack should be empty. More...
 

Detailed Description

Implements class CLASS?

Homepage:\n http://www.bornagainproject.org
License:\n GNU General Public License v3 or higher (see COPYING)
Authors
Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS)

Definition in file undostack.test.cpp.

Function Documentation

◆ TEST_F() [1/21]

TEST_F ( UndoStackTest  ,
beginMacrosEndMacros   
)

Add item and changing its data from macros.

Definition at line 782 of file undostack.test.cpp.

783 {
784  const int role = ItemDataRole::DATA;
785  const QVariant data(42);
786 
787  SessionModel model;
788  model.setUndoRedoEnabled(true);
789  auto stack = model.undoStack();
790 
791  stack->beginMacro("macro1");
792  auto item = model.insertItem<SessionItem>();
793  item->setData(data, role);
794  stack->endMacro();
795 
796  // initial state before removing the row
797  EXPECT_EQ(stack->count(), 1); // insert and setData commands
798  EXPECT_EQ(stack->index(), 1); // insert and setData commands
799  EXPECT_FALSE(model.undoStack()->canRedo());
800  EXPECT_TRUE(model.undoStack()->canUndo());
801  EXPECT_EQ(item->data<QVariant>(role), data);
802  EXPECT_EQ(model.rootItem()->childrenCount(), 1);
803 
804  // undoing and checking the data
805  stack->undo();
806  EXPECT_EQ(stack->count(), 1);
807  EXPECT_EQ(stack->index(), 0);
808  EXPECT_EQ(model.rootItem()->childrenCount(), 0);
809 
810  // redoing
811  stack->redo();
812  EXPECT_EQ(stack->count(), 1);
813  EXPECT_EQ(stack->index(), 1);
814  EXPECT_EQ(model.rootItem()->childrenCount(), 1);
815  item = Utils::ChildAt(model.rootItem(), 0);
816  EXPECT_EQ(model.data(item, role).value<double>(), 42.0);
817 }
The main object representing an editable/displayable/serializable entity.
Definition: sessionitem.h:38
bool setData(const T &value, int role=ItemDataRole::DATA, bool direct=false)
Sets data for a given role.
Definition: sessionitem.h:141
int childrenCount() const
Returns total number of children in all tags.
Main class to hold hierarchy of SessionItem objects.
Definition: sessionmodel.h:37
void setUndoRedoEnabled(bool value)
Sets undo/redo either enabled or disabled. By default undo/redo is disabled.
SessionItem * rootItem() const
Returns root item of the model.
T * insertItem(SessionItem *parent=nullptr, const TagRow &tagrow={})
Inserts item into given parent under given tagrow.
Definition: sessionmodel.h:104
UndoStackInterface * undoStack() const
Returns command stack to perform undo/redo.
Variant data(SessionItem *item, int role) const
Returns the data for given item and role.
virtual bool canUndo() const =0
virtual void beginMacro(const std::string &name)=0
virtual bool canRedo() const =0
const int DATA
main data role
Definition: mvvm_types.h:30
MVVM_MODEL_EXPORT SessionItem * ChildAt(const SessionItem *parent, int index)
Returns child at given index of parent.
Definition: itemutils.cpp:70

References ModelView::UndoStackInterface::beginMacro(), ModelView::UndoStackInterface::canRedo(), ModelView::UndoStackInterface::canUndo(), ModelView::Utils::ChildAt(), ModelView::SessionItem::childrenCount(), ModelView::ItemDataRole::DATA, ModelView::SessionModel::data(), ModelView::SessionModel::insertItem(), ModelView::SessionModel::rootItem(), ModelView::SessionItem::setData(), ModelView::SessionModel::setUndoRedoEnabled(), and ModelView::SessionModel::undoStack().

Here is the call graph for this function:

◆ TEST_F() [2/21]

TEST_F ( UndoStackTest  ,
commandTimeOfLife   
)

Checking time of life of the command during undo/redo.

This is connected with the fact, that Qt takes ownership of the command and we have to use our own wrapper.

Definition at line 44 of file undostack.test.cpp.

45 {
46  SessionModel model;
47  auto item = model.insertItem<PropertyItem>();
48  item->setData(42);
49 
50  std::weak_ptr<SetValueCommand> pw_command; // to trace command time of life
51 
52  UndoStack stack;
53 
54  {
55  // creating command
56  auto command =
57  std::make_shared<SetValueCommand>(item, QVariant::fromValue(43), ItemDataRole::DATA);
58  pw_command = command;
59  EXPECT_EQ(pw_command.use_count(), 1);
60 
61  // checking state of item, stack and command
62  EXPECT_EQ(item->data<int>(), 42);
63  EXPECT_FALSE(stack.canRedo());
64  EXPECT_FALSE(stack.canUndo());
65  EXPECT_EQ(stack.index(), 0);
66  EXPECT_EQ(stack.count(), 0);
67  EXPECT_EQ(command->isObsolete(), false);
68  EXPECT_FALSE(std::get<bool>(command->result()));
69 
70  // adding command to the stack, it will lead to command execution
71  stack.execute(command);
72  EXPECT_EQ(pw_command.use_count(), 2);
73 
74  // checking state of item, stack and command
75  EXPECT_EQ(item->data<int>(), 43);
76  EXPECT_FALSE(stack.canRedo());
77  EXPECT_TRUE(stack.canUndo());
78  EXPECT_EQ(stack.index(), 1);
79  EXPECT_EQ(stack.count(), 1);
80  EXPECT_EQ(command->isObsolete(), false);
81  EXPECT_TRUE(std::get<bool>(command->result()));
82 
83  // undoing
84  stack.undo();
85  EXPECT_EQ(item->data<int>(), 42);
86  EXPECT_TRUE(stack.canRedo());
87  EXPECT_FALSE(stack.canUndo());
88  EXPECT_EQ(stack.index(), 0);
89  EXPECT_EQ(stack.count(), 1);
90  EXPECT_EQ(command->isObsolete(), false);
91  EXPECT_TRUE(std::get<bool>(command->result()));
92 
93  // redoing
94  stack.redo();
95  EXPECT_EQ(item->data<int>(), 43);
96  EXPECT_FALSE(stack.canRedo());
97  EXPECT_TRUE(stack.canUndo());
98  EXPECT_EQ(stack.index(), 1);
99  EXPECT_EQ(stack.count(), 1);
100  EXPECT_EQ(command->isObsolete(), false);
101  EXPECT_TRUE(std::get<bool>(command->result()));
102  }
103 
104  EXPECT_EQ(pw_command.use_count(), 1);
105  if (auto command = pw_command.lock()) {
106  EXPECT_EQ(command->isObsolete(), false);
107  EXPECT_TRUE(std::get<bool>(command->result()));
108  }
109 }
Item to carry concrete editable entity (e.g.
Definition: propertyitem.h:27
Default undo stack implementation.
Definition: undostack.h:30
bool canRedo() const override
Definition: undostack.cpp:48
void undo() override
Definition: undostack.cpp:63
int index() const override
Definition: undostack.cpp:53
void execute(std::shared_ptr< AbstractItemCommand > command) override
Executes the command, then pushes it in the stack for possible undo.
Definition: undostack.cpp:29
bool canUndo() const override
Definition: undostack.cpp:43
int count() const override
Definition: undostack.cpp:58
void redo() override
Definition: undostack.cpp:68

References ModelView::UndoStack::canRedo(), ModelView::UndoStack::canUndo(), ModelView::UndoStack::count(), ModelView::ItemDataRole::DATA, ModelView::UndoStack::execute(), ModelView::UndoStack::index(), ModelView::SessionModel::insertItem(), ModelView::UndoStack::redo(), ModelView::SessionItem::setData(), and ModelView::UndoStack::undo().

Here is the call graph for this function:

◆ TEST_F() [3/21]

TEST_F ( UndoStackTest  ,
copyLayerFromMultilayer   
)

Creating two multilayers. Copying layer from one multilayer to another.

Definition at line 746 of file undostack.test.cpp.

747 {
748  auto pool = std::make_shared<ItemPool>();
749  ToyItems::SampleModel model(pool);
750  model.setUndoRedoEnabled(true);
751  auto stack = model.undoStack();
752 
753  const double expected_thickness = 55.0;
754 
755  // creating multi layer with 3 layers
756  auto multilayer0 = model.insertItem<ToyItems::MultiLayerItem>();
757  auto layer0 = model.insertItem<ToyItems::LayerItem>(multilayer0);
758  layer0->setProperty(ToyItems::LayerItem::P_THICKNESS, expected_thickness);
759  auto multilayer1 = model.insertItem<ToyItems::MultiLayerItem>();
760 
761  // copying layer
762  auto layer_copy = dynamic_cast<ToyItems::LayerItem*>(model.copyItem(layer0, multilayer1));
763  EXPECT_EQ(multilayer1->itemCount(ToyItems::MultiLayerItem::T_LAYERS), 1);
764  EXPECT_EQ(layer_copy->property<double>(ToyItems::LayerItem::P_THICKNESS), expected_thickness);
765  EXPECT_TRUE(layer0->identifier() != layer_copy->identifier());
766 
767  auto id = layer_copy->identifier();
768  EXPECT_EQ(pool->item_for_key(layer_copy->identifier()), layer_copy);
769 
770  // undoing
771  stack->undo();
772  EXPECT_EQ(multilayer1->itemCount(ToyItems::MultiLayerItem::T_LAYERS), 0);
773 
774  // redoing
775  stack->redo();
776  EXPECT_EQ(multilayer1->itemCount(ToyItems::MultiLayerItem::T_LAYERS), 1);
777  EXPECT_EQ(multilayer1->getItems(ToyItems::MultiLayerItem::T_LAYERS)[0]->identifier(), id);
778 }
std::string identifier() const
Returns unique identifier.
Definition: sessionitem.cpp:87
T property(const std::string &tag) const
Returns data stored in property item.
Definition: sessionitem.h:181
bool insertItem(SessionItem *item, const TagRow &tagrow)
Insert item into given tag under the given row.
void setProperty(const std::string &tag, const T &value)
Sets value to property item.
Definition: sessionitem.h:190
Represents a layer, with thickness and color, and possibly populated with particles.
Definition: toyitems.h:52
static const std::string P_THICKNESS
Definition: toyitems.h:54
Represents multilayer with collection of layers.
Definition: toyitems.h:44
static const std::string T_LAYERS
Definition: toyitems.h:46

References ModelView::SessionModel::copyItem(), ModelView::SessionItem::identifier(), ModelView::SessionModel::insertItem(), ToyItems::LayerItem::P_THICKNESS, ModelView::SessionItem::property(), ModelView::SessionItem::setProperty(), ModelView::SessionModel::setUndoRedoEnabled(), ToyItems::MultiLayerItem::T_LAYERS, and ModelView::SessionModel::undoStack().

Here is the call graph for this function:

◆ TEST_F() [4/21]

TEST_F ( UndoStackTest  ,
expiredCommandTimeOfLife   
)

Checking time of life of the command during undo/redo.

Same as above, but command is trying to set same value. It makes it "expired" and it should be removed from the stack.

Definition at line 115 of file undostack.test.cpp.

116 {
117  SessionModel model;
118  auto item = model.insertItem<PropertyItem>();
119  item->setData(42);
120 
121  std::weak_ptr<SetValueCommand> pw_command; // to trace command time of life
122 
123  UndoStack stack;
124 
125  {
126  // creating command which sets the same value
127  auto command =
128  std::make_shared<SetValueCommand>(item, QVariant::fromValue(42), ItemDataRole::DATA);
129  pw_command = command;
130  EXPECT_EQ(pw_command.use_count(), 1);
131 
132  // checking state of item, stack and command
133  EXPECT_EQ(item->data<int>(), 42);
134  EXPECT_FALSE(stack.canRedo());
135  EXPECT_FALSE(stack.canUndo());
136  EXPECT_EQ(stack.index(), 0);
137  EXPECT_EQ(stack.count(), 0);
138  EXPECT_EQ(command->isObsolete(), false);
139  EXPECT_FALSE(std::get<bool>(command->result()));
140 
141  // adding command to the stack, it will lead to command execution
142  stack.execute(command);
143  EXPECT_EQ(pw_command.use_count(), 1); // was already deleted from the stack
144 
145  // checking state of item, stack and command
146  EXPECT_EQ(item->data<int>(), 42);
147  EXPECT_FALSE(stack.canRedo());
148  EXPECT_FALSE(stack.canUndo());
149  EXPECT_EQ(stack.index(), 0);
150  EXPECT_EQ(stack.count(), 0);
151  EXPECT_EQ(command->isObsolete(), true);
152  EXPECT_FALSE(std::get<bool>(command->result()));
153  }
154 
155  EXPECT_EQ(pw_command.use_count(), 0);
156  EXPECT_EQ(pw_command.lock(), nullptr);
157 }

References ModelView::UndoStack::canRedo(), ModelView::UndoStack::canUndo(), ModelView::UndoStack::count(), ModelView::ItemDataRole::DATA, ModelView::UndoStack::execute(), ModelView::UndoStack::index(), ModelView::SessionModel::insertItem(), and ModelView::SessionItem::setData().

Here is the call graph for this function:

◆ TEST_F() [5/21]

TEST_F ( UndoStackTest  ,
initialState   
)

Definition at line 159 of file undostack.test.cpp.

160 {
161  SessionModel model;
162 
163  // no undo/redo stack by default
164  EXPECT_TRUE(model.undoStack() == nullptr);
165 
166  // switching undo/redo on
167  model.setUndoRedoEnabled(true);
168  auto stack = model.undoStack();
169  EXPECT_TRUE(stack != nullptr);
170 
171  // initial state of undo redo stack
172  EXPECT_TRUE(stack->isActive());
173  EXPECT_FALSE(stack->canRedo());
174  EXPECT_FALSE(stack->canUndo());
175  EXPECT_EQ(stack->index(), 0);
176 }

References ModelView::SessionModel::setUndoRedoEnabled(), and ModelView::SessionModel::undoStack().

Here is the call graph for this function:

◆ TEST_F() [6/21]

TEST_F ( UndoStackTest  ,
insertAndSetData   
)

Checks if we insert item, set data and undo everything we can get back to the data.

Definition at line 375 of file undostack.test.cpp.

376 {
377  const int role = ItemDataRole::DATA;
378  SessionModel model;
379  model.setUndoRedoEnabled(true);
380  auto stack = model.undoStack();
381 
382  // creating item
383  auto item = model.insertItem<SessionItem>();
384  EXPECT_FALSE(model.data(item, role).isValid());
385 
386  // setting new data
387  QVariant value(42.0);
388  model.setData(item, value, role);
389  EXPECT_EQ(model.data(item, role), value);
390 
391  EXPECT_EQ(stack->index(), 2); // insert and setData commands
392  EXPECT_FALSE(model.undoStack()->canRedo());
393  EXPECT_TRUE(model.undoStack()->canUndo());
394 
395  // undoing twice and checking
396  stack->undo();
397  stack->undo();
398  EXPECT_EQ(stack->index(), 0);
399  EXPECT_EQ(model.rootItem()->childrenCount(), 0);
400 
401  // returning all back
402  stack->redo();
403  stack->redo();
404  EXPECT_EQ(stack->index(), 2);
405  EXPECT_EQ(model.rootItem()->childrenCount(), 1);
406  item = Utils::ChildAt(model.rootItem(), 0);
407  EXPECT_EQ(model.data(item, role).value<double>(), 42.0);
408 }
bool setData(SessionItem *item, const Variant &value, int role)
Sets the data for given item.

References ModelView::UndoStackInterface::canRedo(), ModelView::UndoStackInterface::canUndo(), ModelView::Utils::ChildAt(), ModelView::SessionItem::childrenCount(), ModelView::ItemDataRole::DATA, ModelView::SessionModel::data(), ModelView::SessionModel::insertItem(), ModelView::SessionModel::rootItem(), ModelView::SessionModel::setData(), ModelView::SessionModel::setUndoRedoEnabled(), and ModelView::SessionModel::undoStack().

Here is the call graph for this function:

◆ TEST_F() [7/21]

TEST_F ( UndoStackTest  ,
insertDataAndGraph   
)

Add GraphItem and Data1DItem, addisgn data to graph, undo, then redo.

GraphItem should be pointing again to Data1DItem. This is real bug case.

Definition at line 823 of file undostack.test.cpp.

824 {
825  // constructing model with pool, enabling undo/redo
826  auto pool = std::make_shared<ItemPool>();
827  SessionModel model("Model", pool);
828  model.setUndoRedoEnabled(true);
829  EXPECT_EQ(model.undoStack()->index(), 0);
830  EXPECT_EQ(model.undoStack()->count(), 0);
831 
832  auto dataItem = model.insertItem<Data1DItem>();
833  auto graphItem = model.insertItem<GraphItem>();
834  graphItem->setDataItem(dataItem);
835 
836  auto data_item_identifier = dataItem->identifier();
837  auto graph_item_identifier = graphItem->identifier();
838 
839  // model has two elements, graph is pointing to the data
840  EXPECT_EQ(model.undoStack()->index(), 3);
841  EXPECT_EQ(model.undoStack()->count(), 3);
842  EXPECT_EQ(model.rootItem()->childrenCount(), 2);
843  EXPECT_EQ(graphItem->dataItem(), dataItem);
844 
845  // checking pool
846  EXPECT_EQ(pool->item_for_key(data_item_identifier), dataItem);
847  EXPECT_EQ(pool->item_for_key(graph_item_identifier), graphItem);
848 
849  // undoing once (setDataItem operation)
850  model.undoStack()->undo();
851  EXPECT_EQ(model.undoStack()->index(), 2);
852  EXPECT_EQ(model.undoStack()->count(), 3);
853  EXPECT_EQ(model.rootItem()->childrenCount(), 2);
854  EXPECT_EQ(graphItem->dataItem(), nullptr);
855 
856  // undoing two more times item
857  model.undoStack()->undo();
858  model.undoStack()->undo();
859  EXPECT_EQ(model.undoStack()->index(), 0);
860  EXPECT_EQ(model.undoStack()->count(), 3);
861  EXPECT_EQ(model.rootItem()->childrenCount(), 0);
862 
863  // redoing (dataItem is back)
864  model.undoStack()->redo();
865  EXPECT_EQ(model.undoStack()->index(), 1);
866  EXPECT_EQ(model.rootItem()->childrenCount(), 1);
867  auto restoredDataItem = model.topItem<Data1DItem>();
868  EXPECT_EQ(restoredDataItem->identifier(), data_item_identifier);
869  EXPECT_EQ(pool->item_for_key(data_item_identifier), restoredDataItem);
870 
871  // redoing (GraphItem) is back
872  model.undoStack()->redo();
873  EXPECT_EQ(model.undoStack()->index(), 2);
874  EXPECT_EQ(model.rootItem()->childrenCount(), 2);
875  auto restoredGraphItem = model.topItem<GraphItem>();
876  EXPECT_EQ(restoredGraphItem->identifier(), graph_item_identifier);
877  EXPECT_EQ(restoredGraphItem->dataItem(), nullptr);
878 
879  // redoing (graph is linked with data gaian)
880  model.undoStack()->redo();
881  EXPECT_EQ(model.undoStack()->index(), 3);
882  EXPECT_EQ(model.rootItem()->childrenCount(), 2);
883  EXPECT_EQ(restoredGraphItem->dataItem(), restoredDataItem);
884 }
Represents one-dimensional data (axis and values).
Definition: data1ditem.h:30
One-dimensional graph representation of Data1DItem.
Definition: graphitem.h:29

References ModelView::SessionItem::childrenCount(), ModelView::UndoStackInterface::count(), ModelView::SessionItem::identifier(), ModelView::UndoStackInterface::index(), ModelView::SessionModel::insertItem(), ModelView::UndoStackInterface::redo(), ModelView::SessionModel::rootItem(), ModelView::SessionModel::setUndoRedoEnabled(), ModelView::SessionModel::topItem(), ModelView::UndoStackInterface::undo(), and ModelView::SessionModel::undoStack().

Here is the call graph for this function:

◆ TEST_F() [8/21]

TEST_F ( UndoStackTest  ,
insertDataItemViaMacro   
)

Setup Data1DItem via macro.

Undo, then redo. Add GraphItem and Data1DItem, addisgn data to graph, undo, then redo. GraphItem should be pointing again to Data1DItem. This is real bug case.

Definition at line 891 of file undostack.test.cpp.

892 {
893  SessionModel model;
894  model.setUndoRedoEnabled(true);
895  EXPECT_EQ(model.undoStack()->index(), 0);
896  EXPECT_EQ(model.undoStack()->count(), 0);
897 
898  // setting up single data item via macro
899  model.undoStack()->beginMacro("AddDataItem");
900  auto dataItem = model.insertItem<Data1DItem>();
901  const std::vector<double> expected_values = {1.0, 2.0, 3.0};
902  const std::vector<double> expected_centers = {0.5, 1.5, 2.5};
903  dataItem->setAxis<FixedBinAxisItem>(3, 0.0, 3.0);
904  dataItem->setValues(expected_values);
905  model.undoStack()->endMacro();
906 
907  EXPECT_EQ(model.undoStack()->index(), 1);
908  EXPECT_EQ(model.undoStack()->count(), 1);
909 
910  // undoing and returning back
911  model.undoStack()->undo();
912  model.undoStack()->redo();
913  EXPECT_EQ(model.undoStack()->index(), 1);
914  EXPECT_EQ(model.undoStack()->count(), 1);
915 
916  auto restoredDataItem = model.topItem<Data1DItem>();
917  EXPECT_EQ(restoredDataItem->binCenters(), expected_centers);
918  EXPECT_EQ(restoredDataItem->binValues(), expected_values);
919 }
T * setAxis(Args &&... args)
Inserts axis of given type.
Definition: data1ditem.h:56
Item to represent fixed bin axis.
Definition: axisitems.h:75
T * topItem() const
Returns top item of the given type.
Definition: sessionmodel.h:126
virtual int index() const =0
virtual int count() const =0

References ModelView::UndoStackInterface::beginMacro(), ModelView::UndoStackInterface::count(), ModelView::UndoStackInterface::endMacro(), ModelView::UndoStackInterface::index(), ModelView::SessionModel::insertItem(), ModelView::UndoStackInterface::redo(), ModelView::Data1DItem::setAxis(), ModelView::SessionModel::setUndoRedoEnabled(), ModelView::SessionModel::topItem(), ModelView::UndoStackInterface::undo(), and ModelView::SessionModel::undoStack().

Here is the call graph for this function:

◆ TEST_F() [9/21]

TEST_F ( UndoStackTest  ,
insertNewItem   
)

Definition at line 178 of file undostack.test.cpp.

179 {
180  const model_type modelType(Constants::BaseType);
181  SessionModel model;
182  model.setUndoRedoEnabled(true);
183  auto stack = model.undoStack();
184 
185  // inserting single item
186  auto item = model.insertItem<SessionItem>();
187  EXPECT_TRUE(item != nullptr);
188  EXPECT_EQ(item->modelType(), Constants::BaseType);
189  EXPECT_EQ(model.rootItem()->childrenCount(), 1);
190  EXPECT_EQ(stack->index(), 1);
191  EXPECT_EQ(stack->count(), 1);
192  EXPECT_FALSE(stack->canRedo());
193  EXPECT_TRUE(stack->canUndo());
194 
195  // undoing item insertion
196  stack->undo();
197  EXPECT_EQ(model.rootItem()->childrenCount(), 0);
198  EXPECT_EQ(stack->index(), 0);
199  EXPECT_EQ(stack->count(), 1);
200  EXPECT_TRUE(stack->canRedo());
201  EXPECT_FALSE(stack->canUndo());
202 
203  // redoing item insertion
204  stack->redo();
205  EXPECT_EQ(model.rootItem()->childrenCount(), 1);
206  EXPECT_EQ(Utils::ChildAt(model.rootItem(), 0)->modelType(), modelType);
207  EXPECT_EQ(stack->index(), 1);
208  EXPECT_FALSE(stack->canRedo());
209  EXPECT_TRUE(stack->canUndo());
210 
211  // clearing stack
212  stack->clear();
213  EXPECT_EQ(stack->index(), 0);
214  EXPECT_FALSE(stack->canRedo());
215  EXPECT_FALSE(stack->canUndo());
216  EXPECT_EQ(model.rootItem()->childrenCount(), 1);
217  EXPECT_EQ(Utils::ChildAt(model.rootItem(), 0)->modelType(), modelType);
218 }
model_type modelType() const
Returns item's model type.
Definition: sessionitem.cpp:80
const model_type BaseType
Definition: mvvm_types.h:45
std::string model_type
Definition: types.h:23

References ModelView::Constants::BaseType, ModelView::Utils::ChildAt(), ModelView::SessionItem::childrenCount(), ModelView::SessionModel::insertItem(), ModelView::SessionItem::modelType(), ModelView::SessionModel::rootItem(), ModelView::SessionModel::setUndoRedoEnabled(), and ModelView::SessionModel::undoStack().

Here is the call graph for this function:

◆ TEST_F() [10/21]

TEST_F ( UndoStackTest  ,
insertParentAndChild   
)

Undo/redo scenario when few items inserted.

Definition at line 247 of file undostack.test.cpp.

248 {
249  SessionModel model;
250  model.setUndoRedoEnabled(true);
251  auto stack = model.undoStack();
252 
253  auto parent = model.insertItem<SessionItem>();
254  parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true);
255 
256  model.insertItem<PropertyItem>(parent);
257  model.insertItem<PropertyItem>(parent);
258 
259  // state of the stack after insertion of 3 items
260  EXPECT_EQ(stack->count(), 3);
261  EXPECT_EQ(stack->index(), 3);
262  EXPECT_EQ(model.rootItem()->childrenCount(), 1);
263  EXPECT_EQ(parent->childrenCount(), 2);
264 
265  // undoing two last insertions
266  stack->undo();
267  stack->undo();
268  EXPECT_EQ(stack->count(), 3);
269  EXPECT_EQ(stack->index(), 1);
270  EXPECT_EQ(model.rootItem()->childrenCount(), 1);
271  EXPECT_EQ(parent->childrenCount(), 0);
272 
273  // redoing once
274  stack->redo();
275  EXPECT_EQ(stack->count(), 3);
276  EXPECT_EQ(stack->index(), 2);
277  EXPECT_EQ(model.rootItem()->childrenCount(), 1);
278  EXPECT_EQ(parent->childrenCount(), 1);
279  EXPECT_EQ(Utils::ChildAt(parent, 0)->modelType(), Constants::PropertyType);
280 }
void registerTag(const TagInfo &tagInfo, bool set_as_default=false)
Registers tag to hold items under given name.
const model_type PropertyType
Definition: mvvm_types.h:59

References ModelView::Utils::ChildAt(), ModelView::SessionItem::childrenCount(), ModelView::SessionModel::insertItem(), ModelView::Constants::PropertyType, ModelView::SessionItem::registerTag(), ModelView::SessionModel::rootItem(), ModelView::SessionModel::setUndoRedoEnabled(), ModelView::SessionModel::undoStack(), and ModelView::TagInfo::universalTag().

Here is the call graph for this function:

◆ TEST_F() [11/21]

TEST_F ( UndoStackTest  ,
insertPropertyItemID   
)

Insert property item, unto, redo, and checking that identifier is preserved.

Definition at line 222 of file undostack.test.cpp.

223 {
224  SessionModel model;
225  model.setUndoRedoEnabled(true);
226  auto stack = model.undoStack();
227 
228  auto item = model.insertItem<PropertyItem>();
229  auto original_id = item->identifier();
230 
231  EXPECT_EQ(stack->index(), 1);
232  EXPECT_EQ(stack->count(), 1);
233 
234  model.undoStack()->undo();
235  EXPECT_EQ(model.rootItem()->childrenCount(), 0);
236 
237  model.undoStack()->redo();
238  EXPECT_EQ(model.rootItem()->childrenCount(), 1);
239 
240  auto restored_property_item = Utils::ChildAt(model.rootItem(), 0);
241  EXPECT_EQ(restored_property_item->modelType(), Constants::PropertyType);
242  EXPECT_EQ(restored_property_item->identifier(), original_id);
243 }

References ModelView::Utils::ChildAt(), ModelView::SessionItem::childrenCount(), ModelView::SessionItem::identifier(), ModelView::SessionModel::insertItem(), ModelView::Constants::PropertyType, ModelView::UndoStackInterface::redo(), ModelView::SessionModel::rootItem(), ModelView::SessionModel::setUndoRedoEnabled(), ModelView::UndoStackInterface::undo(), and ModelView::SessionModel::undoStack().

Here is the call graph for this function:

◆ TEST_F() [12/21]

TEST_F ( UndoStackTest  ,
itemIdentifierOnRemove   
)

Insert item, remove row, undo and check item id.

Definition at line 493 of file undostack.test.cpp.

494 {
495  SessionModel model;
496  model.setUndoRedoEnabled(true);
497  auto stack = model.undoStack();
498 
499  auto parent = model.insertItem<SessionItem>();
500  parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true);
501 
502  identifier_type parent_id = parent->identifier();
503  auto child = model.insertItem<PropertyItem>(parent);
504  identifier_type child_id = child->identifier();
505 
506  // removing parent
507  model.removeItem(model.rootItem(), {"", 0});
508  EXPECT_EQ(stack->count(), 3);
509  EXPECT_EQ(stack->index(), 3);
510  EXPECT_EQ(model.rootItem()->childrenCount(), 0);
511 
512  stack->undo();
513  auto parent_at = Utils::ChildAt(model.rootItem(), 0);
514  auto child_at = Utils::ChildAt(parent_at, 0);
515  identifier_type parent_id2 = parent_at->identifier();
516  identifier_type child_id2 = child_at->identifier();
517 
518  EXPECT_EQ(parent_id, parent_id2);
519  EXPECT_EQ(child_id, child_id2);
520 }
void removeItem(SessionItem *parent, const TagRow &tagrow)
Removes given row from parent.
std::string identifier_type
Definition: types.h:22

References ModelView::Utils::ChildAt(), ModelView::SessionItem::childrenCount(), ModelView::SessionItem::identifier(), ModelView::SessionModel::insertItem(), ModelView::SessionItem::registerTag(), ModelView::SessionModel::removeItem(), ModelView::SessionModel::rootItem(), ModelView::SessionModel::setUndoRedoEnabled(), ModelView::SessionModel::undoStack(), and ModelView::TagInfo::universalTag().

Here is the call graph for this function:

◆ TEST_F() [13/21]

TEST_F ( UndoStackTest  ,
moveLayerFromMLDeleteAll   
)

Create 2 multilayers, 3 layers each.

Move layer from one multilayer to another. Deleting everything and undoing.

Definition at line 674 of file undostack.test.cpp.

675 {
676  auto pool = std::make_shared<ItemPool>();
677 
678  ToyItems::SampleModel model(pool);
679  model.setUndoRedoEnabled(true);
680  auto stack = model.undoStack();
681 
682  // creating multi layer with 3 layers
683  auto multilayer0 = model.insertItem<ToyItems::MultiLayerItem>();
684  auto layer0 = model.insertItem<ToyItems::LayerItem>(multilayer0);
685  auto layer1 = model.insertItem<ToyItems::LayerItem>(multilayer0);
686  auto layer2 = model.insertItem<ToyItems::LayerItem>(multilayer0);
687 
688  // saving identifiers for further reference
689  identifier_type id_multilayer0 = multilayer0->identifier();
690  identifier_type id_layer0 = layer0->identifier();
691  identifier_type id_layer1 = layer1->identifier();
692  identifier_type id_layer2 = layer2->identifier();
693 
694  // creating another multi layer with 3 layers
695  auto multilayer1 = model.insertItem<ToyItems::MultiLayerItem>();
696  auto layer3 = model.insertItem<ToyItems::LayerItem>(multilayer1);
697  auto layer4 = model.insertItem<ToyItems::LayerItem>(multilayer1);
698  auto layer5 = model.insertItem<ToyItems::LayerItem>(multilayer1);
699 
700  // saving identifiers for further reference
701  identifier_type id_multilayer1 = multilayer1->identifier();
702  identifier_type id_layer3 = layer3->identifier();
703  identifier_type id_layer4 = layer4->identifier();
704  identifier_type id_layer5 = layer5->identifier();
705 
706  // checking status of unddo stack
707  EXPECT_EQ(stack->count(), 8);
708  EXPECT_EQ(stack->index(), 8);
709 
710  // moving layer1 to second multilayer
711  model.moveItem(layer1, multilayer1, {ToyItems::MultiLayerItem::T_LAYERS, 0});
712 
713  // removing multilayers
714  model.removeItem(model.rootItem(), {"", 1});
715  model.removeItem(model.rootItem(), {"", 0});
716 
717  // checking status of unddo stack
718  EXPECT_EQ(stack->count(), 11);
719  EXPECT_EQ(stack->index(), 11);
720 
721  // undoing thrice
722  stack->undo();
723  stack->undo();
724  stack->undo();
725 
726  // restoring pointers
727  auto multilayer0_r = pool->item_for_key(id_multilayer0);
728  auto layer0_r = pool->item_for_key(id_layer0);
729  auto layer1_r = pool->item_for_key(id_layer1);
730  auto layer2_r = pool->item_for_key(id_layer2);
731  auto multilayer1_r = pool->item_for_key(id_multilayer1);
732  auto layer3_r = pool->item_for_key(id_layer3);
733  auto layer4_r = pool->item_for_key(id_layer4);
734  auto layer5_r = pool->item_for_key(id_layer5);
735 
736  // checking layers
737  std::vector<SessionItem*> expected = {layer0_r, layer1_r, layer2_r};
738  EXPECT_EQ(multilayer0_r->children(), expected);
739 
740  expected = {layer3_r, layer4_r, layer5_r};
741  EXPECT_EQ(multilayer1_r->children(), expected);
742 }

References ModelView::SessionItem::identifier(), ModelView::SessionModel::insertItem(), ModelView::SessionModel::moveItem(), ModelView::SessionModel::removeItem(), ModelView::SessionModel::rootItem(), ModelView::SessionModel::setUndoRedoEnabled(), ToyItems::MultiLayerItem::T_LAYERS, and ModelView::SessionModel::undoStack().

Here is the call graph for this function:

◆ TEST_F() [14/21]

TEST_F ( UndoStackTest  ,
moveLayerFromMLDeleteSecond   
)

Move single layer from multilayer to another empty multilayer.

Delete second multilayer and undo.

Definition at line 623 of file undostack.test.cpp.

624 {
625  auto pool = std::make_shared<ItemPool>();
626 
627  ToyItems::SampleModel model(pool);
628  model.setUndoRedoEnabled(true);
629  auto stack = model.undoStack();
630 
631  // creating multi layer with 3 layers
632  auto multilayer0 = model.insertItem<ToyItems::MultiLayerItem>();
633  auto layer0 = model.insertItem<ToyItems::LayerItem>(multilayer0);
634  auto multilayer1 = model.insertItem<ToyItems::MultiLayerItem>();
635 
636  // saving identifiers for further reference
637  identifier_type id_multilayer0 = multilayer0->identifier();
638  identifier_type id_layer0 = layer0->identifier();
639  identifier_type id_multilayer1 = multilayer1->identifier();
640 
641  // moving layer from multilayer
642  model.moveItem(layer0, multilayer1, {"", 0});
643 
644  // checking results
645  std::vector<SessionItem*> expected = {layer0};
646  EXPECT_EQ(multilayer0->children().size(), 0);
647  EXPECT_EQ(multilayer1->children(), expected);
648  EXPECT_EQ(pool->item_for_key(id_layer0), layer0);
649 
650  // deleting second multilayer
651  model.removeItem(model.rootItem(), {"", 1});
652 
653  // undoing deletion
654  stack->undo();
655 
656  // restoring ponters
657  auto layer0_at = pool->item_for_key(id_layer0);
658  auto multilayer1_at = pool->item_for_key(id_multilayer1);
659 
660  expected = {layer0_at};
661  EXPECT_EQ(multilayer0->children().size(), 0);
662  EXPECT_EQ(multilayer1_at->children(), expected);
663 
664  // unoing move
665  stack->undo();
666 
667  EXPECT_EQ(multilayer0->children(), expected);
668  EXPECT_EQ(multilayer1_at->children().size(), 0);
669 }
std::vector< SessionItem * > children() const
Returns vector of children formed from all chidlren from all tags.

References ModelView::SessionItem::children(), ModelView::SessionItem::identifier(), ModelView::SessionModel::insertItem(), ModelView::SessionModel::moveItem(), ModelView::SessionModel::removeItem(), ModelView::SessionModel::rootItem(), ModelView::SessionModel::setUndoRedoEnabled(), and ModelView::SessionModel::undoStack().

Here is the call graph for this function:

◆ TEST_F() [15/21]

TEST_F ( UndoStackTest  ,
moveLayerFromMultiLayer   
)

Move single layer from multilayer to another empty multilayer.

Definition at line 586 of file undostack.test.cpp.

587 {
588  auto pool = std::make_shared<ItemPool>();
589 
590  ToyItems::SampleModel model(pool);
591  model.setUndoRedoEnabled(true);
592  auto stack = model.undoStack();
593 
594  // creating multi layer with 3 layers
595  auto multilayer0 = model.insertItem<ToyItems::MultiLayerItem>();
596  auto layer0 = model.insertItem<ToyItems::LayerItem>(multilayer0);
597  auto multilayer1 = model.insertItem<ToyItems::MultiLayerItem>();
598 
599  // saving identifiers for further reference
600  identifier_type id_multilayer0 = multilayer0->identifier();
601  identifier_type id_layer0 = layer0->identifier();
602  identifier_type id_multilayer1 = multilayer1->identifier();
603 
604  // moving layer from multilayer
605  model.moveItem(layer0, multilayer1, {"", 0});
606 
607  // checking results
608  std::vector<SessionItem*> expected = {layer0};
609  EXPECT_EQ(multilayer0->children().size(), 0);
610  EXPECT_EQ(multilayer1->children(), expected);
611  EXPECT_EQ(pool->item_for_key(id_layer0), layer0);
612 
613  // undoing
614  stack->undo();
615  EXPECT_EQ(multilayer0->children(), expected);
616  EXPECT_EQ(multilayer1->children().size(), 0);
617  EXPECT_EQ(pool->item_for_key(id_layer0), layer0);
618 }

References ModelView::SessionItem::children(), ModelView::SessionItem::identifier(), ModelView::SessionModel::insertItem(), ModelView::SessionModel::moveItem(), ModelView::SessionModel::setUndoRedoEnabled(), and ModelView::SessionModel::undoStack().

Here is the call graph for this function:

◆ TEST_F() [16/21]

TEST_F ( UndoStackTest  ,
multiLayer   
)

Create multilayer, add two layers, remove everything and undo.

Toy models are used here.

Definition at line 525 of file undostack.test.cpp.

526 {
527  auto pool = std::make_shared<ItemPool>();
528 
529  ToyItems::SampleModel model(pool);
530  model.setUndoRedoEnabled(true);
531  auto stack = model.undoStack();
532 
533  // creating multi layer
534  auto parent = model.insertItem<ToyItems::MultiLayerItem>();
535  EXPECT_TRUE(dynamic_cast<ToyItems::MultiLayerItem*>(parent) != nullptr);
536  EXPECT_EQ(parent->modelType(), ToyItems::Constants::MultiLayerItemType);
537 
538  // inserting two layers
539  auto layer0 = model.insertItem<ToyItems::LayerItem>(parent);
540  auto layer1 = model.insertItem<ToyItems::LayerItem>(parent);
541 
542  // saving identifiers for further reference
543  identifier_type id_parent = parent->identifier();
544  identifier_type id_layer0 = layer0->identifier();
545  identifier_type id_layer1 = layer1->identifier();
546 
547  // checking status of unddo stack
548  EXPECT_EQ(stack->count(), 3);
549  EXPECT_EQ(stack->index(), 3);
550 
551  // removing multi layer completely
552  model.removeItem(model.rootItem(), {"", 0});
553  EXPECT_EQ(stack->count(), 4);
554  EXPECT_EQ(stack->index(), 4);
555  EXPECT_EQ(model.rootItem()->childrenCount(), 0);
556 
557  // multilayer and its two layers should gone from registration
558  EXPECT_TRUE(pool->item_for_key(id_parent) == nullptr);
559  EXPECT_TRUE(pool->item_for_key(id_layer0) == nullptr);
560  EXPECT_TRUE(pool->item_for_key(id_layer1) == nullptr);
561 
562  // undoing multilayer removal
563  stack->undo();
564  EXPECT_EQ(stack->count(), 4);
565  EXPECT_EQ(stack->index(), 3);
566 
567  // restoring pointers back
568  auto parent_at = Utils::ChildAt(model.rootItem(), 0);
569  auto layer0_at = Utils::ChildAt(parent_at, 0);
570  auto layer1_at = Utils::ChildAt(parent_at, 1);
571 
572  // checking that restored item has corrrect identifiers
573  EXPECT_EQ(parent_at->identifier(), id_parent);
574  EXPECT_EQ(layer0_at->identifier(), id_layer0);
575  EXPECT_EQ(layer1_at->identifier(), id_layer1);
576 
577  // checking tag
578  EXPECT_EQ(layer0_at->tagRow().tag, ToyItems::MultiLayerItem::T_LAYERS);
579  EXPECT_EQ(layer1_at->tagRow().tag, ToyItems::MultiLayerItem::T_LAYERS);
580  std::vector<SessionItem*> expected = {layer0_at, layer1_at};
581  EXPECT_EQ(parent_at->getItems(ToyItems::MultiLayerItem::T_LAYERS), expected);
582 }
const ModelView::model_type MultiLayerItemType
Definition: toyitems.h:30

References ModelView::Utils::ChildAt(), ModelView::SessionItem::childrenCount(), ModelView::SessionItem::identifier(), ModelView::SessionModel::insertItem(), ToyItems::Constants::MultiLayerItemType, ModelView::SessionModel::removeItem(), ModelView::SessionModel::rootItem(), ModelView::SessionModel::setUndoRedoEnabled(), ToyItems::MultiLayerItem::T_LAYERS, and ModelView::SessionModel::undoStack().

Here is the call graph for this function:

◆ TEST_F() [17/21]

TEST_F ( UndoStackTest  ,
removeParentAndChild   
)

Inserting parent and child, setting data to them, removing parent, undoing and checking.

Definition at line 450 of file undostack.test.cpp.

451 {
452  const int role1(ItemDataRole::DATA), role2(ItemDataRole::DISPLAY);
453  const QVariant data1(42);
454  const QVariant data2 = QVariant::fromValue(std::string("abc"));
455 
456  SessionModel model;
457  model.setUndoRedoEnabled(true);
458  auto stack = model.undoStack();
459 
460  auto parent = model.insertItem<SessionItem>();
461  parent->registerTag(TagInfo::universalTag("defaultTag"), /*set_as_default*/ true);
462 
463  parent->setData(data1, role1);
464  auto child = model.insertItem<PropertyItem>(parent);
465  child->setData(data2, role2);
466 
467  EXPECT_EQ(stack->count(), 4);
468  EXPECT_EQ(stack->index(), 4);
469 
470  // removing parent
471  model.removeItem(model.rootItem(), {"", 0});
472  EXPECT_EQ(stack->count(), 5);
473  EXPECT_EQ(stack->index(), 5);
474  EXPECT_EQ(model.rootItem()->childrenCount(), 0);
475 
476  // undoing
477  stack->undo();
478  EXPECT_EQ(stack->count(), 5);
479  EXPECT_EQ(stack->index(), 4);
480  EXPECT_EQ(model.rootItem()->childrenCount(), 1);
481  auto parent_at = Utils::ChildAt(model.rootItem(), 0);
482  auto child_at = Utils::ChildAt(parent_at, 0);
483 
484  EXPECT_EQ(parent_at->modelType(), Constants::BaseType);
485  EXPECT_EQ(child_at->modelType(), Constants::PropertyType);
486 
487  EXPECT_EQ(parent_at->data<QVariant>(role1), data1);
488  EXPECT_EQ(child_at->data<QVariant>(role2), data2);
489 }
const int DISPLAY
display name
Definition: mvvm_types.h:31

References ModelView::Constants::BaseType, ModelView::Utils::ChildAt(), ModelView::SessionItem::childrenCount(), ModelView::ItemDataRole::DATA, ModelView::ItemDataRole::DISPLAY, ModelView::SessionModel::insertItem(), ModelView::Constants::PropertyType, ModelView::SessionItem::registerTag(), ModelView::SessionModel::removeItem(), ModelView::SessionModel::rootItem(), ModelView::SessionItem::setData(), ModelView::SessionModel::setUndoRedoEnabled(), ModelView::SessionModel::undoStack(), and ModelView::TagInfo::universalTag().

Here is the call graph for this function:

◆ TEST_F() [18/21]

TEST_F ( UndoStackTest  ,
removeRow   
)

Inserting item, setting the data, removing row, undoing, checking item and data.

Definition at line 412 of file undostack.test.cpp.

413 {
414  const int role = ItemDataRole::DATA;
415  const QVariant data(42);
416 
417  SessionModel model;
418  model.setUndoRedoEnabled(true);
419  auto stack = model.undoStack();
420 
421  auto item = model.insertItem<SessionItem>();
422  item->setData(data, role);
423 
424  // initial state before removing the row
425  EXPECT_EQ(stack->count(), 2); // insert and setData commands
426  EXPECT_EQ(stack->index(), 2); // insert and setData commands
427  EXPECT_FALSE(model.undoStack()->canRedo());
428  EXPECT_TRUE(model.undoStack()->canUndo());
429  EXPECT_EQ(item->data<QVariant>(role), data);
430  EXPECT_EQ(model.rootItem()->childrenCount(), 1);
431 
432  // removing the row
433  model.removeItem(model.rootItem(), {"", 0});
434  EXPECT_EQ(stack->count(), 3);
435  EXPECT_EQ(stack->index(), 3);
436  EXPECT_EQ(model.rootItem()->childrenCount(), 0);
437 
438  // undoing and checking the data
439  stack->undo();
440  EXPECT_EQ(stack->count(), 3);
441  EXPECT_EQ(stack->index(), 2);
442  EXPECT_EQ(model.rootItem()->childrenCount(), 1);
443  item = Utils::ChildAt(model.rootItem(), 0);
444  EXPECT_EQ(model.data(item, role).value<double>(), 42.0);
445  EXPECT_EQ(item->modelType(), Constants::BaseType);
446 }

References ModelView::Constants::BaseType, ModelView::UndoStackInterface::canRedo(), ModelView::UndoStackInterface::canUndo(), ModelView::Utils::ChildAt(), ModelView::SessionItem::childrenCount(), ModelView::ItemDataRole::DATA, ModelView::SessionModel::data(), ModelView::SessionModel::insertItem(), ModelView::SessionModel::removeItem(), ModelView::SessionModel::rootItem(), ModelView::SessionItem::setData(), ModelView::SessionModel::setUndoRedoEnabled(), and ModelView::SessionModel::undoStack().

Here is the call graph for this function:

◆ TEST_F() [19/21]

TEST_F ( UndoStackTest  ,
setData   
)

Undo/redo scenario when item inserted and data set few times.

Definition at line 284 of file undostack.test.cpp.

285 {
286  const int role = ItemDataRole::DATA;
287  SessionModel model;
288  model.setUndoRedoEnabled(true);
289  auto stack = model.undoStack();
290 
291  // creating item
292  auto item = model.insertItem<SessionItem>();
293  EXPECT_FALSE(model.data(item, role).isValid());
294 
295  // setting new data
296  QVariant value(42.0);
297  model.setData(item, value, role);
298  EXPECT_EQ(model.data(item, role), value);
299 
300  EXPECT_EQ(stack->index(), 2); // insert and setData commands
301  EXPECT_FALSE(model.undoStack()->canRedo());
302  EXPECT_TRUE(model.undoStack()->canUndo());
303 
304  // undoing and checking
305  stack->undo();
306  EXPECT_EQ(stack->index(), 1);
307  EXPECT_FALSE(model.data(item, role).isValid());
308 
309  // setting data three times
310  model.setData(item, QVariant::fromValue(42.0), role);
311  model.setData(item, QVariant::fromValue(43.0), role);
312  model.setData(item, QVariant::fromValue(44.0), role);
313  EXPECT_EQ(stack->index(), 4);
314  EXPECT_EQ(model.data(item, role).value<double>(), 44.0);
315  stack->undo();
316  stack->undo();
317  EXPECT_EQ(model.data(item, role).value<double>(), 42.0);
318  stack->redo();
319  stack->redo();
320  EXPECT_EQ(model.data(item, role).value<double>(), 44.0);
321 }

References ModelView::UndoStackInterface::canRedo(), ModelView::UndoStackInterface::canUndo(), ModelView::ItemDataRole::DATA, ModelView::SessionModel::data(), ModelView::SessionModel::insertItem(), ModelView::SessionModel::setData(), ModelView::SessionModel::setUndoRedoEnabled(), and ModelView::SessionModel::undoStack().

Here is the call graph for this function:

◆ TEST_F() [20/21]

TEST_F ( UndoStackTest  ,
setDataThroughItem   
)

Undo/redo scenario when item data changed through item and not the model.

Definition at line 325 of file undostack.test.cpp.

326 {
327  const int role = ItemDataRole::DATA;
328  const QVariant value(42.0);
329 
330  SessionModel model;
331  model.setUndoRedoEnabled(true);
332  auto stack = model.undoStack();
333 
334  // creating item
335  auto item = model.insertItem<SessionItem>();
336  EXPECT_FALSE(model.data(item, role).isValid());
337 
338  // setting new data through item (and not through model)
339  item->setData(value, role);
340  EXPECT_EQ(item->data<QVariant>(role), value);
341 
342  EXPECT_EQ(stack->index(), 2); // insert and setData commands
343  EXPECT_FALSE(model.undoStack()->canRedo());
344  EXPECT_TRUE(model.undoStack()->canUndo());
345 
346  // undoing and checking
347  stack->undo();
348  EXPECT_EQ(stack->index(), 1);
349  EXPECT_FALSE(model.data(item, role).isValid());
350 }

References ModelView::UndoStackInterface::canRedo(), ModelView::UndoStackInterface::canUndo(), ModelView::ItemDataRole::DATA, ModelView::SessionModel::data(), ModelView::SessionModel::insertItem(), ModelView::SessionModel::setUndoRedoEnabled(), and ModelView::SessionModel::undoStack().

Here is the call graph for this function:

◆ TEST_F() [21/21]

TEST_F ( UndoStackTest  ,
setSameData   
)

Undo/redo scenario when we set same data. Undo stack should be empty.

Definition at line 354 of file undostack.test.cpp.

355 {
356  SessionModel model;
357  auto item = model.insertItem<PropertyItem>();
358  item->setData(42.0);
359 
360  model.setUndoRedoEnabled(true);
361  auto stack = model.undoStack();
362  EXPECT_EQ(stack->index(), 0);
363  EXPECT_FALSE(model.undoStack()->canRedo());
364  EXPECT_FALSE(model.undoStack()->canUndo());
365 
366  // setting same data should not lead to appearance of command in a stack
367  item->setData(42.0);
368  EXPECT_EQ(stack->index(), 0);
369  EXPECT_FALSE(model.undoStack()->canRedo());
370  EXPECT_FALSE(model.undoStack()->canUndo());
371 }

References ModelView::UndoStackInterface::canRedo(), ModelView::UndoStackInterface::canUndo(), ModelView::SessionModel::insertItem(), ModelView::SessionItem::setData(), ModelView::SessionModel::setUndoRedoEnabled(), and ModelView::SessionModel::undoStack().

Here is the call graph for this function: