Passwordfile library  5.0.6
C++ library to read/write passwords from/to encrypted files
entrytests.cpp
Go to the documentation of this file.
1 #include "../io/entry.h"
2 
3 #include "./utils.h"
4 
5 #include <c++utilities/tests/testutils.h>
6 using namespace CppUtilities;
7 
8 #include <cppunit/TestFixture.h>
9 #include <cppunit/extensions/HelperMacros.h>
10 
11 using namespace std;
12 using namespace Io;
13 using namespace CppUtilities::Literals;
14 
15 using namespace CPPUNIT_NS;
16 
20 class EntryTests : public TestFixture {
21  CPPUNIT_TEST_SUITE(EntryTests);
22  CPPUNIT_TEST(testNewEntryCorrectlyInitialized);
23  CPPUNIT_TEST(testNesting);
24  CPPUNIT_TEST(testEntryByPath);
25  CPPUNIT_TEST(testUniqueLabels);
26  CPPUNIT_TEST_SUITE_END();
27 
28 public:
29  void setUp() override;
30  void tearDown() override;
31 
32  void testNewEntryCorrectlyInitialized();
33  void testNesting();
34  void testEntryByPath();
35  void testUniqueLabels();
36 };
37 
39 
41 {
42 }
43 
45 {
46 }
47 
52 {
53  const NodeEntry nodeEntry;
54  CPPUNIT_ASSERT(!nodeEntry.parent());
55  CPPUNIT_ASSERT_EQUAL(string(), nodeEntry.label());
56  CPPUNIT_ASSERT_EQUAL(0_st, nodeEntry.children().size());
57  CPPUNIT_ASSERT_EQUAL(-1, nodeEntry.index());
58  CPPUNIT_ASSERT_EQUAL(list<string>{ "" }, nodeEntry.path());
59  CPPUNIT_ASSERT(nodeEntry.isExpandedByDefault());
60  CPPUNIT_ASSERT_EQUAL(EntryType::Node, nodeEntry.type());
61 
62  const AccountEntry accountEntry;
63  CPPUNIT_ASSERT(!accountEntry.parent());
64  CPPUNIT_ASSERT_EQUAL(string(), nodeEntry.label());
65  CPPUNIT_ASSERT_EQUAL(0_st, accountEntry.fields().size());
66  CPPUNIT_ASSERT_EQUAL(-1, accountEntry.index());
67  CPPUNIT_ASSERT_EQUAL(list<string>{ "" }, accountEntry.path());
68  CPPUNIT_ASSERT_EQUAL(EntryType::Account, accountEntry.type());
69 
70  const NodeEntry nodeEntryWithLabel("foo");
71  CPPUNIT_ASSERT(!nodeEntryWithLabel.parent());
72  CPPUNIT_ASSERT_EQUAL("foo"s, nodeEntryWithLabel.label());
73  CPPUNIT_ASSERT_EQUAL(list<string>{ "foo" }, nodeEntryWithLabel.path());
74 }
75 
77 {
78  NodeEntry root("root");
79 
80  // create account under root
81  auto *const account = new AccountEntry("account", &root);
82  CPPUNIT_ASSERT_EQUAL_MESSAGE("account appended to root's children", vector<Entry *>{ account }, root.children());
83  CPPUNIT_ASSERT_EQUAL_MESSAGE("account's path contains parent", list<string>{ "root" CPP_UTILITIES_PP_COMMA "account" }, account->path());
84  CPPUNIT_ASSERT_EQUAL_MESSAGE("index initialized", 0, account->index());
85  CPPUNIT_ASSERT_MESSAGE("actual assignment happened", account->parent() == &root);
86 
87  // create new node entry under root
88  auto *const node = new NodeEntry("node", &root);
89  CPPUNIT_ASSERT_EQUAL_MESSAGE("node appended to root's children", vector<Entry *>{ account CPP_UTILITIES_PP_COMMA node }, root.children());
90  CPPUNIT_ASSERT_EQUAL_MESSAGE("account's path contains parent", list<string>{ "root" CPP_UTILITIES_PP_COMMA "node" }, node->path());
91  CPPUNIT_ASSERT_EQUAL_MESSAGE("index initialized", 1, node->index());
92  CPPUNIT_ASSERT_MESSAGE("actual assignment happened", node->parent() == &root);
93 
94  // nothing bad happens if we're setting the same parent again
95  node->setParent(&root);
96  CPPUNIT_ASSERT_EQUAL_MESSAGE("root's children not altered", vector<Entry *>{ account CPP_UTILITIES_PP_COMMA node }, root.children());
97  CPPUNIT_ASSERT_EQUAL_MESSAGE("index not altered", 0, account->index());
98  CPPUNIT_ASSERT_EQUAL_MESSAGE("index not altered", 1, node->index());
99 
100  // change the children's order
101  node->setParent(&root, 0);
102  CPPUNIT_ASSERT_EQUAL_MESSAGE("root's children not altered", vector<Entry *>{ node CPP_UTILITIES_PP_COMMA account }, root.children());
103  CPPUNIT_ASSERT_EQUAL_MESSAGE("index updated", 1, account->index());
104  CPPUNIT_ASSERT_EQUAL_MESSAGE("index updated", 0, node->index());
105 
106  // change the children's order the other way
107  node->setParent(&root, 1);
108  CPPUNIT_ASSERT_EQUAL_MESSAGE("root's children not altered", vector<Entry *>{ account CPP_UTILITIES_PP_COMMA node }, root.children());
109  CPPUNIT_ASSERT_EQUAL_MESSAGE("index updated", 0, account->index());
110  CPPUNIT_ASSERT_EQUAL_MESSAGE("index updated", 1, node->index());
111 
112  // specifying an invalid index inserts at the end
113  auto *const anotherNode = new NodeEntry("another node", &root);
114  anotherNode->setParent(&root, 2000);
115  CPPUNIT_ASSERT_EQUAL_MESSAGE(
116  "another node is at the end", vector<Entry *>{ account CPP_UTILITIES_PP_COMMA node CPP_UTILITIES_PP_COMMA anotherNode }, root.children());
117  CPPUNIT_ASSERT_EQUAL_MESSAGE("index initialized", 2, anotherNode->index());
118 
119  // move node into another node
120  node->setParent(anotherNode);
121  CPPUNIT_ASSERT_EQUAL_MESSAGE("index not altered", 0, account->index());
122  CPPUNIT_ASSERT_EQUAL_MESSAGE("index updated", 0, node->index());
123  CPPUNIT_ASSERT_EQUAL_MESSAGE("index updated", 1, anotherNode->index());
124  CPPUNIT_ASSERT_EQUAL_MESSAGE("root's childrens updated", vector<Entry *>{ account CPP_UTILITIES_PP_COMMA anotherNode }, root.children());
125  CPPUNIT_ASSERT_EQUAL_MESSAGE("another node's childrens updated", vector<Entry *>{ node }, anotherNode->children());
126  CPPUNIT_ASSERT_MESSAGE("node is still an indirect child of root", node->isIndirectChildOf(&root));
127  CPPUNIT_ASSERT_MESSAGE("node is direct and hence also an indirect child of another node", node->isIndirectChildOf(anotherNode));
128  CPPUNIT_ASSERT_MESSAGE("another node is no indirect child of node", !anotherNode->isIndirectChildOf(node));
129 
130  // replace children
131  auto *const replacementNode = new NodeEntry("replacement", &root);
132  CPPUNIT_ASSERT_EQUAL_MESSAGE("replacement's index initialized", 2, replacementNode->index());
133  root.replaceChild(1, replacementNode);
134  CPPUNIT_ASSERT_EQUAL_MESSAGE("root's childrens updated", vector<Entry *>{ account CPP_UTILITIES_PP_COMMA replacementNode }, root.children());
135  CPPUNIT_ASSERT_MESSAGE("another node parentless", !anotherNode->parent());
136  CPPUNIT_ASSERT_EQUAL_MESSAGE("another node's index updated", -1, anotherNode->index());
137  CPPUNIT_ASSERT_EQUAL_MESSAGE("replacement's index updated", 1, replacementNode->index());
138 
139  // delete children
140  anotherNode->setParent(&root, 0);
141  CPPUNIT_ASSERT_EQUAL_MESSAGE("index updated", 0, anotherNode->index());
142  CPPUNIT_ASSERT_EQUAL_MESSAGE("index updated", 1, account->index());
143  CPPUNIT_ASSERT_EQUAL_MESSAGE("index updated", 2, replacementNode->index());
144  root.deleteChildren(0, 1);
145  CPPUNIT_ASSERT_EQUAL_MESSAGE("root's childrens updated", vector<Entry *>{ account CPP_UTILITIES_PP_COMMA replacementNode }, root.children());
146  CPPUNIT_ASSERT_EQUAL_MESSAGE("index updated", 0, account->index());
147  CPPUNIT_ASSERT_EQUAL_MESSAGE("index updated", 1, replacementNode->index());
148 }
149 
151 {
152  NodeEntry root("root");
153  list<string> path;
154  auto createNode = EntryType::Node;
155  auto createAccount = EntryType::Account;
156 
157  CPPUNIT_ASSERT_MESSAGE("nullptr for empty path", !root.entryByPath(path));
158 
159  path = { "root" };
160  CPPUNIT_ASSERT_EQUAL_MESSAGE("return current instance", static_cast<Entry *>(&root), root.entryByPath(path));
161 
162  path = { "root", "foo" };
163  CPPUNIT_ASSERT_MESSAGE("nullptr for non-existent path", !root.entryByPath(path));
164 
165  path = { "root", "node" };
166  const auto *const node = root.entryByPath(path, true, &createNode);
167  CPPUNIT_ASSERT_MESSAGE("node created", node);
168  CPPUNIT_ASSERT_EQUAL_MESSAGE("actually a node", EntryType::Node, node->type());
169  CPPUNIT_ASSERT_EQUAL_MESSAGE("label assigned", "node"s, node->label());
170 
171  path = { "root", "account" };
172  const auto *const account = root.entryByPath(path, true, &createAccount);
173  CPPUNIT_ASSERT_MESSAGE("account created", account);
174  CPPUNIT_ASSERT_EQUAL_MESSAGE("actually an account", EntryType::Account, account->type());
175  CPPUNIT_ASSERT_EQUAL_MESSAGE("label assigned", "account"s, account->label());
176 
177  path = { "root", "account", "foo" };
178  CPPUNIT_ASSERT_MESSAGE("nullptr for trying to add child to account", !root.entryByPath(path, true, &createAccount));
179 
180  path = { "root", "node", "foo" };
181  const auto *const nestedAccount = root.entryByPath(path, true, &createAccount);
182  CPPUNIT_ASSERT_MESSAGE("nested account created", nestedAccount);
183  CPPUNIT_ASSERT_EQUAL_MESSAGE("nested account created", EntryType::Account, nestedAccount->type());
184  CPPUNIT_ASSERT_EQUAL_MESSAGE("label assigned", "foo"s, nestedAccount->label());
185  CPPUNIT_ASSERT_EQUAL_MESSAGE(
186  "path actually correct", list<string>{ "root" CPP_UTILITIES_PP_COMMA "node" CPP_UTILITIES_PP_COMMA "foo" }, nestedAccount->path());
187 }
188 
190 {
191  NodeEntry root("root");
192  const auto *const fooEntry = new AccountEntry("foo", &root);
193  CPP_UTILITIES_UNUSED(fooEntry)
194  const auto *const foo2Entry = new AccountEntry("foo", &root);
195  CPPUNIT_ASSERT_EQUAL_MESSAGE("2nd foo renamed to foo 2", "foo 2"s, foo2Entry->label());
196  const auto *const foo3Entry = new AccountEntry("foo", &root);
197  CPPUNIT_ASSERT_EQUAL_MESSAGE("3rd foo renamed to foo 3", "foo 3"s, foo3Entry->label());
198 }
The EntryTests class tests the Io::Entry class.
Definition: entrytests.cpp:20
void tearDown() override
Definition: entrytests.cpp:44
void testNewEntryCorrectlyInitialized()
Tests whether a new entry is correctly initialized (basically empty, default values set).
Definition: entrytests.cpp:51
void testNesting()
Definition: entrytests.cpp:76
void setUp() override
Definition: entrytests.cpp:40
void testUniqueLabels()
Definition: entrytests.cpp:189
void testEntryByPath()
Definition: entrytests.cpp:150
The exception that is thrown when a parsing error occurs.
Definition: entry.h:170
const std::vector< Field > & fields() const
Definition: entry.h:194
EntryType type() const override
Returns the type of the entry.
Definition: entry.h:189
Instances of the Entry class form a hierarchic data structure used to store account information.
Definition: entry.h:30
int index() const
Returns the index of the entry within its parent.
Definition: entry.h:98
NodeEntry * parent() const
Returns the parent entry.
Definition: entry.h:90
const std::string & label() const
Returns the label.
Definition: entry.h:70
std::list< std::string > path() const
Returns the path of the entry.
Definition: entry.cpp:154
The NodeEntry class acts as parent for other entries.
Definition: entry.h:114
Entry * entryByPath(std::list< std::string > &path, bool includeThis=true, const EntryType *creationType=nullptr)
Returns an entry specified by the provided path.
Definition: entry.cpp:350
void replaceChild(std::size_t at, Entry *newChild)
Replaces the child at the specified index with the specified newChild.
Definition: entry.cpp:317
EntryType type() const override
Returns the type of the entry.
Definition: entry.h:140
bool isExpandedByDefault() const
Definition: entry.h:150
void deleteChildren(int begin, int end)
Deletes children from the node entry.
Definition: entry.cpp:290
const std::vector< Entry * > & children() const
Definition: entry.h:145
CPPUNIT_TEST_SUITE_REGISTRATION(EntryTests)
Contains all IO related classes.