testnotebookdatabase.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. #include "testnotebookdatabase.h"
  2. #include <QtTest>
  3. #include "dummynode.h"
  4. #include "dummynotebook.h"
  5. using namespace tests;
  6. using namespace vnotex;
  7. template <typename T>
  8. static void checkStringListEqual(T p_actual, T p_expected)
  9. {
  10. std::sort(p_actual.begin(), p_actual.end());
  11. std::sort(p_expected.begin(), p_expected.end());
  12. QCOMPARE(p_actual, p_expected);
  13. }
  14. TestNotebookDatabase::TestNotebookDatabase()
  15. {
  16. QVERIFY(m_testDir.isValid());
  17. m_notebook.reset(new DummyNotebook("test_notebook"));
  18. m_dbAccess.reset(new NotebookDatabaseAccess(m_notebook.data(), m_testDir.filePath("test.db")));
  19. m_dbAccess->initialize(0);
  20. QVERIFY(m_dbAccess->isFresh());
  21. QVERIFY(m_dbAccess->isValid());
  22. }
  23. TestNotebookDatabase::~TestNotebookDatabase()
  24. {
  25. m_dbAccess->close();
  26. m_dbAccess.reset();
  27. }
  28. void TestNotebookDatabase::test()
  29. {
  30. testNode();
  31. testTag();
  32. testNodeTag();
  33. }
  34. void TestNotebookDatabase::testNode()
  35. {
  36. // Invlaid node.
  37. {
  38. auto nodeRec = m_dbAccess->queryNode(1);
  39. QVERIFY(nodeRec == nullptr);
  40. }
  41. // Root node.
  42. QScopedPointer<DummyNode> rootNode(new DummyNode(Node::Flag::Container, 0, "", m_notebook.data(), nullptr));
  43. addAndQueryNode(rootNode.data(), true);
  44. // Node 1.
  45. QScopedPointer<DummyNode> node1(new DummyNode(Node::Flag::Content, 10, "a", m_notebook.data(), rootNode.data()));
  46. addAndQueryNode(node1.data(), true);
  47. // Node 2, respect id.
  48. QScopedPointer<DummyNode> node2(new DummyNode(Node::Flag::Content, 50, "b", m_notebook.data(), rootNode.data()));
  49. addAndQueryNode(node2.data(), false);
  50. QCOMPARE(node2->getId(), 50);
  51. // Node 3, respect id with invalid id.
  52. QScopedPointer<DummyNode> node3(new DummyNode(Node::Flag::Container, 0, "c", m_notebook.data(), rootNode.data()));
  53. addAndQueryNode(node3.data(), false);
  54. QVERIFY(node3->getId() != 0);
  55. // Node 4, deep level.
  56. QScopedPointer<DummyNode> node4(new DummyNode(Node::Flag::Container, 11, "ca", m_notebook.data(), node3.data()));
  57. addAndQueryNode(node4.data(), false);
  58. // Node 5, deep level.
  59. QScopedPointer<DummyNode> node5(new DummyNode(Node::Flag::Content, 60, "caa", m_notebook.data(), node4.data()));
  60. addAndQueryNode(node5.data(), false);
  61. // Node 6, deep level.
  62. QScopedPointer<DummyNode> node6(new DummyNode(Node::Flag::Content, 5, "cab", m_notebook.data(), node4.data()));
  63. addAndQueryNode(node6.data(), false);
  64. // Node 7/8, with non-exist parent.
  65. QScopedPointer<DummyNode> node7(new DummyNode(Node::Flag::Content, 55, "caba", m_notebook.data(), node6.data()));
  66. QScopedPointer<DummyNode> node8(new DummyNode(Node::Flag::Content, 555, "cabaa", m_notebook.data(), node7.data()));
  67. {
  68. bool ret = m_dbAccess->addNode(node8.data(), false);
  69. QVERIFY(!ret);
  70. ret = m_dbAccess->addNodeRecursively(node8.data(), false);
  71. queryAndVerifyNode(node7.data());
  72. QVERIFY(m_dbAccess->existsNode(node7.data()));
  73. queryAndVerifyNode(node8.data());
  74. QVERIFY(m_dbAccess->existsNode(node8.data()));
  75. }
  76. // queryNodeParentPath().
  77. {
  78. testQueryNodeParentPath(rootNode.data());
  79. testQueryNodeParentPath(node1.data());
  80. testQueryNodeParentPath(node2.data());
  81. testQueryNodeParentPath(node3.data());
  82. testQueryNodeParentPath(node4.data());
  83. testQueryNodeParentPath(node5.data());
  84. testQueryNodeParentPath(node6.data());
  85. }
  86. // updateNode().
  87. {
  88. node6->setParent(node5.data());
  89. node6->setName("caaa");
  90. bool ret = m_dbAccess->updateNode(node6.data());
  91. QVERIFY(ret);
  92. queryAndVerifyNode(node6.data());
  93. }
  94. // removeNode().
  95. {
  96. QVERIFY(m_dbAccess->existsNode(node6.data()));
  97. bool ret = m_dbAccess->removeNode(node6->getId());
  98. QVERIFY(ret);
  99. QVERIFY(!m_dbAccess->existsNode(node6.data()));
  100. // DELETE CASCADE.
  101. QVERIFY(m_dbAccess->existsNode(node3.data()));
  102. QVERIFY(m_dbAccess->existsNode(node4.data()));
  103. QVERIFY(m_dbAccess->existsNode(node5.data()));
  104. ret = m_dbAccess->removeNode(node3->getId());
  105. QVERIFY(ret);
  106. QVERIFY(!m_dbAccess->existsNode(node3.data()));
  107. QVERIFY(!m_dbAccess->existsNode(node4.data()));
  108. QVERIFY(!m_dbAccess->existsNode(node5.data()));
  109. // Add back nodes.
  110. addAndQueryNode(node3.data(), false);
  111. addAndQueryNode(node4.data(), false);
  112. addAndQueryNode(node5.data(), false);
  113. addAndQueryNode(node6.data(), false);
  114. }
  115. }
  116. void TestNotebookDatabase::addAndQueryNode(Node *p_node, bool p_ignoreId)
  117. {
  118. bool ret = m_dbAccess->addNode(p_node, p_ignoreId);
  119. QVERIFY(ret);
  120. QVERIFY(p_node->getId() != NotebookDatabaseAccess::InvalidId);
  121. queryAndVerifyNode(p_node);
  122. QVERIFY(m_dbAccess->existsNode(p_node));
  123. }
  124. void TestNotebookDatabase::queryAndVerifyNode(const vnotex::Node *p_node)
  125. {
  126. auto nodeRec = m_dbAccess->queryNode(p_node->getId());
  127. QVERIFY(nodeRec);
  128. QCOMPARE(nodeRec->m_id, p_node->getId());
  129. QCOMPARE(nodeRec->m_name, p_node->getName());
  130. QCOMPARE(nodeRec->m_signature, p_node->getSignature());
  131. QCOMPARE(nodeRec->m_parentId, p_node->getParent() ? p_node->getParent()->getId() : NotebookDatabaseAccess::InvalidId);
  132. }
  133. void TestNotebookDatabase::testQueryNodeParentPath(const vnotex::Node *p_node)
  134. {
  135. auto nodePath = m_dbAccess->queryNodeParentPath(p_node->getId());
  136. auto node = p_node;
  137. for (int i = nodePath.size() - 1; i >= 0; --i) {
  138. QVERIFY(node);
  139. QCOMPARE(nodePath[i], node->getName());
  140. node = node->getParent();
  141. }
  142. QVERIFY(m_dbAccess->checkNodePath(p_node, nodePath));
  143. QCOMPARE(m_dbAccess->queryNodePath(p_node->getId()), p_node->fetchPath());
  144. }
  145. void TestNotebookDatabase::testTag()
  146. {
  147. // Invalid tag.
  148. {
  149. auto nodeRec = m_dbAccess->queryTag("1");
  150. QVERIFY(nodeRec == nullptr);
  151. }
  152. // Tag 1.
  153. const QString tag1("1");
  154. addAndQueryTag(tag1, "");
  155. // Tag 2.
  156. QString tag2("2");
  157. addAndQueryTag(tag2, "");
  158. // Tag 3 as child of tag 2.
  159. QString tag3("21");
  160. addAndQueryTag(tag3, tag2);
  161. checkStringListEqual({tag2, tag3}, m_dbAccess->queryTagAndChildren(tag2));
  162. // Tag 4 as child of tag 2.
  163. const QString tag4("22");
  164. addAndQueryTag(tag4, tag2);
  165. checkStringListEqual({tag2, tag3, tag4}, m_dbAccess->queryTagAndChildren(tag2));
  166. // Tag 5 as child of tag 4.
  167. const QString tag5("221");
  168. addAndQueryTag(tag5, tag4);
  169. checkStringListEqual({tag4, tag5}, m_dbAccess->queryTagAndChildren(tag4));
  170. checkStringListEqual({tag2, tag3, tag4, tag5}, m_dbAccess->queryTagAndChildren(tag2));
  171. // Add with update.
  172. addAndQueryTag(tag3, tag1);
  173. // Add without update.
  174. {
  175. bool ret = m_dbAccess->addTag(tag3);
  176. QVERIFY(ret);
  177. queryAndVerifyTag(tag3, tag1);
  178. ret = m_dbAccess->addTag("3");
  179. QVERIFY(ret);
  180. queryAndVerifyTag("3", "");
  181. }
  182. // Rename.
  183. {
  184. bool ret = m_dbAccess->renameTag(tag3, "11");
  185. QVERIFY(ret);
  186. queryAndVerifyTag("11", tag1);
  187. // Tag should be gone.
  188. QVERIFY(!m_dbAccess->queryTag(tag3));
  189. tag3 = "11";
  190. ret = m_dbAccess->renameTag(tag2, "new2");
  191. QVERIFY(ret);
  192. queryAndVerifyTag("new2", "");
  193. QVERIFY(!m_dbAccess->queryTag(tag2));
  194. tag2 = "new2";
  195. queryAndVerifyTag(tag4, tag2);
  196. queryAndVerifyTag(tag5, tag4);
  197. }
  198. // removeTag().
  199. {
  200. bool ret = m_dbAccess->removeTag(tag3);
  201. QVERIFY(ret);
  202. QVERIFY(!m_dbAccess->queryTag(tag3));
  203. ret = m_dbAccess->removeTag(tag2);
  204. QVERIFY(ret);
  205. QVERIFY(!m_dbAccess->queryTag(tag2));
  206. QVERIFY(!m_dbAccess->queryTag(tag4));
  207. QVERIFY(!m_dbAccess->queryTag(tag5));
  208. // Add back tags.
  209. addAndQueryTag(tag3, tag1);
  210. addAndQueryTag(tag2, "");
  211. addAndQueryTag(tag4, tag2);
  212. addAndQueryTag(tag5, tag4);
  213. }
  214. }
  215. void TestNotebookDatabase::addAndQueryTag(const QString &p_name, const QString &p_parentName)
  216. {
  217. bool ret = m_dbAccess->addTag(p_name, p_parentName);
  218. QVERIFY(ret);
  219. queryAndVerifyTag(p_name, p_parentName);
  220. }
  221. void TestNotebookDatabase::queryAndVerifyTag(const QString &p_name, const QString &p_parentName)
  222. {
  223. auto tagRec = m_dbAccess->queryTag(p_name);
  224. QVERIFY(tagRec);
  225. QCOMPARE(tagRec->m_name, p_name);
  226. QCOMPARE(tagRec->m_parentName, p_parentName);
  227. }
  228. void TestNotebookDatabase::testNodeTag()
  229. {
  230. // Dummy root.
  231. QScopedPointer<DummyNode> rootNode(new DummyNode(Node::Flag::Container, 1, "", m_notebook.data(), nullptr));
  232. // Node 10 -> tag1.
  233. QScopedPointer<DummyNode> node10(new DummyNode(Node::Flag::Content, 0, "o", m_notebook.data(), rootNode.data()));
  234. addAndQueryNode(node10.data(), true);
  235. node10->updateTags({"1"});
  236. updateNodeTagsAndCheck(node10.data());
  237. // Node 11 -> tag2, tag3, tag1.
  238. QScopedPointer<DummyNode> node11(new DummyNode(Node::Flag::Container, 0, "p", m_notebook.data(), rootNode.data()));
  239. addAndQueryNode(node11.data(), true);
  240. node11->updateTags({"new2", "11", "1"});
  241. updateNodeTagsAndCheck(node11.data());
  242. // Node 12 -> tag4, tag100.
  243. QScopedPointer<DummyNode> node12(new DummyNode(Node::Flag::Content, 0, "pa", m_notebook.data(), node11.data()));
  244. addAndQueryNode(node12.data(), true);
  245. node12->updateTags({"22", "100"});
  246. updateNodeTagsAndCheck(node12.data());
  247. // Node 13 -> tag5.
  248. QScopedPointer<DummyNode> node13(new DummyNode(Node::Flag::Content, 0, "pb", m_notebook.data(), node11.data()));
  249. addAndQueryNode(node13.data(), true);
  250. node13->updateTags({"221"});
  251. updateNodeTagsAndCheck(node13.data());
  252. checkStringListEqual(m_dbAccess->queryTagNodes("1"), {node10->getId(), node11->getId()});
  253. checkStringListEqual(m_dbAccess->queryTagNodes("11"), {node11->getId()});
  254. checkStringListEqual(m_dbAccess->queryTagNodes("new2"), {node11->getId()});
  255. checkStringListEqual(m_dbAccess->queryTagNodes("22"), {node12->getId()});
  256. checkStringListEqual(m_dbAccess->queryTagNodes("100"), {node12->getId()});
  257. checkStringListEqual(m_dbAccess->queryTagNodes("221"), {node13->getId()});
  258. checkStringListEqual(m_dbAccess->queryTagNodesRecursive("1"), {node10->getId(), node11->getId()});
  259. checkStringListEqual(m_dbAccess->queryTagNodesRecursive("new2"), {node11->getId(), node12->getId(), node13->getId()});
  260. checkStringListEqual(m_dbAccess->queryTagNodesRecursive("22"), {node12->getId(), node13->getId()});
  261. checkStringListEqual(m_dbAccess->queryTagNodesRecursive("221"), {node13->getId()});
  262. }
  263. void TestNotebookDatabase::updateNodeTagsAndCheck(vnotex::Node *p_node)
  264. {
  265. m_dbAccess->updateNodeTags(p_node);
  266. checkStringListEqual(m_dbAccess->queryNodeTags(p_node->getId()), p_node->getTags());
  267. }