Passwordfile library: tests/entrytests.cpp Source File

Passwordfile library 5.2.0 C++ library to read/write passwords from/to encrypted files

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