BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
projectmanagerdecorator.test.cpp
Go to the documentation of this file.
1 // ************************************************************************************************
2 //
3 // qt-mvvm: Model-view-view-model framework for large GUI applications
4 //
5 //! @file mvvm/tests/testmodel/projectmanagerdecorator.test.cpp
6 //! @brief Implements class CLASS?
7 //!
8 //! @homepage http://www.bornagainproject.org
9 //! @license GNU General Public License v3 or higher (see COPYING)
10 //! @copyright Forschungszentrum Jülich GmbH 2020
11 //! @authors Gennady Pospelov et al, Scientific Computing Group at MLZ (see CITATION, AUTHORS)
12 //
13 // ************************************************************************************************
14 
15 #include "folderbasedtest.h"
16 #include "google_test.h"
21 #include "mvvm/utils/fileutils.h"
22 #include <cctype>
23 
24 using namespace ModelView;
25 
26 namespace {
27 const std::string samplemodel_name = "samplemodel";
28 
29 } // namespace
30 
31 //! Tests for ProjectManager class.
32 
34 public:
36  : FolderBasedTest("test_ProjectManagerDecorator")
37  , sample_model(std::make_unique<ModelView::SessionModel>(samplemodel_name))
38  {
39  }
41 
42  std::vector<SessionModel*> models() const { return {sample_model.get()}; };
43 
45  {
46  ProjectContext result;
47  result.m_models_callback = [this]() { return models(); };
48  return result;
49  }
50 
51  UserInteractionContext userContext(const std::string& create_dir = {},
52  const std::string& select_dir = {})
53  {
55  result.m_create_dir_callback = [create_dir]() -> std::string { return create_dir; };
56  result.m_select_dir_callback = [select_dir]() -> std::string { return select_dir; };
57  return result;
58  }
59 
60  std::unique_ptr<SessionModel> sample_model;
61 };
62 
64 
65 //! Initial state of ProjectManager. Project created, and not-saved.
66 
68 {
69  ProjectManagerDecorator manager(projectContext(), userContext());
70  EXPECT_TRUE(manager.currentProjectDir().empty());
71 }
72 
73 //! Starting from new document (without project dir defined).
74 //! Create new project in given directory.
75 
76 TEST_F(ProjectManagerDecoratorTest, untitledEmptyCreateNew)
77 {
78  const auto project_dir = createEmptyDir("Project_untitledEmptyCreateNew");
79 
80  ProjectManagerDecorator manager(projectContext(), userContext(project_dir, {}));
81  EXPECT_TRUE(manager.currentProjectDir().empty());
82 
83  // saving new project to 'project_dir' directory.
84  EXPECT_TRUE(manager.createNewProject());
85 
86  // checking that current projectDir has pointing to the right place
87  EXPECT_EQ(manager.currentProjectDir(), project_dir);
88 
89  // project directory should contain a json file with the model
90  auto model_json = Utils::join(project_dir, samplemodel_name + ".json");
91  EXPECT_TRUE(Utils::exists(model_json));
92 }
93 
94 //! Starting from new document (without project dir defined).
95 //! Saving project. Same behavior as SaveAs.
96 
97 TEST_F(ProjectManagerDecoratorTest, untitledEmptySaveCurrentProject)
98 {
99  const auto project_dir = createEmptyDir("Project_untitledEmptySaveCurrentProject");
100 
101  ProjectManagerDecorator manager(projectContext(), userContext(project_dir, {}));
102  EXPECT_TRUE(manager.currentProjectDir().empty());
103 
104  // saving new project to 'project_dir' directory.
105  EXPECT_TRUE(manager.saveCurrentProject());
106 
107  // checking thaxt current projectDir has pointing to the right place
108  EXPECT_EQ(manager.currentProjectDir(), project_dir);
109 
110  // project directory should contain a json file with the model
111  auto model_json = Utils::join(project_dir, samplemodel_name + ".json");
112  EXPECT_TRUE(Utils::exists(model_json));
113 }
114 
115 //! Starting from new document (without project dir defined).
116 //! Save under given name.
117 
118 TEST_F(ProjectManagerDecoratorTest, untitledEmptySaveAs)
119 {
120  const auto project_dir = createEmptyDir("Project_untitledEmptySaveAs");
121 
122  ProjectManagerDecorator manager(projectContext(), userContext(project_dir, {}));
123  EXPECT_TRUE(manager.currentProjectDir().empty());
124 
125  // saving new project to "project_dir" directory.
126  EXPECT_TRUE(manager.saveProjectAs());
127 
128  // checking that current projectDir has pointing to the right place
129  EXPECT_EQ(manager.currentProjectDir(), project_dir);
130 
131  // project directory should contain a json file with the model
132  auto model_json = Utils::join(project_dir, samplemodel_name + ".json");
133  EXPECT_TRUE(Utils::exists(model_json));
134 }
135 
136 //! Starting from new document (without project dir defined).
137 //! Attempt to save under empty name, immitating the user canceled directory selection dialog.
138 
139 TEST_F(ProjectManagerDecoratorTest, untitledEmptySaveAsCancel)
140 {
141  ProjectManagerDecorator manager(projectContext(), userContext({}, {})); // immitates canceling
142  EXPECT_TRUE(manager.currentProjectDir().empty());
143 
144  // saving new project to "project_dir" directory.
145  EXPECT_FALSE(manager.saveProjectAs());
146  EXPECT_TRUE(manager.currentProjectDir().empty());
147 }
148 
149 //! Starting from new document (without project dir defined).
150 //! Attempt to save in the non-existing directory.
151 
152 TEST_F(ProjectManagerDecoratorTest, untitledEmptySaveAsWrongDir)
153 {
154  ProjectManagerDecorator manager(projectContext(), userContext("non-existing", {}));
155 
156  // saving new project to "project_dir" directory.
157  EXPECT_FALSE(manager.saveProjectAs());
158  EXPECT_TRUE(manager.currentProjectDir().empty());
159 }
160 
161 //! Untitled, modified document. Attempt to open existing project will lead to
162 //! the dialog save/discard/cancel. As a result of whole exersize, existing project
163 //! should be opened, previous project saved.
164 
165 TEST_F(ProjectManagerDecoratorTest, untitledModifiedOpenExisting)
166 {
167  const auto existing_project_dir = createEmptyDir("Project_untitledModifiedOpenExisting1");
168  const auto unsaved_project_dir = createEmptyDir("Project_untitledModifiedOpenExisting2");
169 
170  // create "existing project"
171  {
172  ProjectManagerDecorator manager(projectContext(), userContext(existing_project_dir, {}));
173  manager.saveProjectAs();
174  }
175 
176  // preparing manager with untitled, unmodified project
177  auto open_dir = [&existing_project_dir]() -> std::string { return existing_project_dir; };
178  auto create_dir = [&unsaved_project_dir]() -> std::string { return unsaved_project_dir; };
179  auto result = SaveChangesAnswer::DISCARD;
180  auto ask_create = [&result]() {
181  result = SaveChangesAnswer::SAVE;
183  };
184  auto user_context = userContext({}, {});
185  user_context.m_create_dir_callback = create_dir;
186  user_context.m_select_dir_callback = open_dir;
187  user_context.m_answer_callback = ask_create;
188  ProjectManagerDecorator manager(projectContext(), user_context);
189 
190  // modifying untitled project
191  sample_model->insertItem<PropertyItem>();
192  EXPECT_TRUE(manager.isModified());
193  EXPECT_TRUE(manager.currentProjectDir().empty());
194 
195  // attempt to open existing project
196  manager.openExistingProject();
197 
198  // check if user was asked and his answer coincide with expectation
199  EXPECT_EQ(result, SaveChangesAnswer::SAVE);
200 
201  // check that previous project was saved
202  auto model_json = Utils::join(unsaved_project_dir, samplemodel_name + ".json");
203  EXPECT_TRUE(Utils::exists(model_json));
204 
205  // currently manager is pointing to existing project
206  EXPECT_FALSE(manager.isModified());
207  EXPECT_EQ(manager.currentProjectDir(), existing_project_dir);
208 }
Convenience class which creates a directory on disk for test content.
Decorator for ProjectManager to provide interaction with the user on open/save-as requests.
bool createNewProject(const std::string &dirname={}) override
Creates a new project in the directory 'dirname', returns 'true' in the case of success.
bool saveProjectAs(const std::string &dirname={}) override
Saves the project under a given directory, returns true in the case of success.
std::string currentProjectDir() const override
Returns current project directory.
bool saveCurrentProject() override
Saves current project, returns 'true' in the case of success.
bool isModified() const override
Returns true if project was modified since last save.
bool openExistingProject(const std::string &dirname={}) override
Opens existing project, returns 'true' in the case of success.
Item to carry concrete editable entity (e.g.
Definition: propertyitem.h:27
Main class to hold hierarchy of SessionItem objects.
Definition: sessionmodel.h:37
Tests for ProjectManager class.
UserInteractionContext userContext(const std::string &create_dir={}, const std::string &select_dir={})
std::unique_ptr< SessionModel > sample_model
std::vector< SessionModel * > models() const
Defines class CLASS?
Defines class CLASS?
Defines class CLASS?
MVVM_MODEL_EXPORT std::string join(const std::string &part1, const std::string &part2)
Joins two path elements into the path.
Definition: fileutils.cpp:37
MVVM_MODEL_EXPORT bool exists(const std::string &fileName)
Returns true if file exists.
Definition: fileutils.cpp:27
materialitems.h Collection of materials to populate MaterialModel.
Definition: filesystem.h:81
Defines class CLASS?
Defines class CLASS?
TEST_F(ProjectManagerDecoratorTest, initialState)
Initial state of ProjectManager. Project created, and not-saved.
Defines class CLASS?
Defines class CLASS?
Provides necessary information for Project construction.
Definition: project_types.h:32
models_callback_t m_models_callback
Definition: project_types.h:42
Defines the context to interact with the user regarding save/save-as/create-new project scenarious.
Definition: project_types.h:48
select_dir_callback_t m_select_dir_callback
Definition: project_types.h:58
create_dir_callback_t m_create_dir_callback
Definition: project_types.h:59