PageRenderTime 22ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/tests/test_introspection.cpp

https://gitlab.com/ubuntu-omap/unity
C++ | 325 lines | 251 code | 42 blank | 32 comment | 10 complexity | f17bd53b2db7d916b2e472631fb7c847 MD5 | raw file
Possible License(s): GPL-3.0
  1. // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
  2. /*
  3. * Copyright (C) 2010 Canonical Ltd
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License version 3 as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. *
  17. * Authored by: Thomi Richards <thomi.richards@canonical.com>
  18. */
  19. #include <gtest/gtest.h>
  20. #include <glib.h>
  21. #include <memory>
  22. #include <boost/foreach.hpp>
  23. #include "Introspectable.h"
  24. #include "DebugDBusInterface.h"
  25. using namespace unity::debug;
  26. class MockIntrospectable : public Introspectable
  27. {
  28. public:
  29. MockIntrospectable(std::string const& name)
  30. : name_(name)
  31. {}
  32. std::string GetName() const
  33. {
  34. return name_;
  35. }
  36. void AddProperties(GVariantBuilder* builder)
  37. {
  38. g_variant_builder_add (builder, "{sv}", "Name", g_variant_new_string (name_.c_str()) );
  39. g_variant_builder_add (builder, "{sv}", "SomeProperty", g_variant_new_string ("SomeValue") );
  40. g_variant_builder_add (builder, "{sv}", "BoolPropertyTrue", g_variant_new_boolean (TRUE) );
  41. g_variant_builder_add (builder, "{sv}", "BoolPropertyFalse", g_variant_new_boolean (FALSE) );
  42. // 8-bit integer types:
  43. g_variant_builder_add (builder, "{sv}", "BytePropertyPos", g_variant_new_byte (12) );
  44. // 16-bit integer types:
  45. g_variant_builder_add (builder, "{sv}", "Int16PropertyPos", g_variant_new_int16 (1012) );
  46. g_variant_builder_add (builder, "{sv}", "Int16PropertyNeg", g_variant_new_int16 (-1034) );
  47. g_variant_builder_add (builder, "{sv}", "UInt16PropertyPos", g_variant_new_uint16 (1056) );
  48. // 32-bit integer types:
  49. g_variant_builder_add (builder, "{sv}", "Int32PropertyPos", g_variant_new_int32 (100012) );
  50. g_variant_builder_add (builder, "{sv}", "Int32PropertyNeg", g_variant_new_int32 (-100034) );
  51. g_variant_builder_add (builder, "{sv}", "UInt32PropertyPos", g_variant_new_uint32 (100056) );
  52. // 64-bit integer types
  53. g_variant_builder_add (builder, "{sv}", "Int64PropertyPos", g_variant_new_int32 (100000012) );
  54. g_variant_builder_add (builder, "{sv}", "Int64PropertyNeg", g_variant_new_int32 (-100000034) );
  55. g_variant_builder_add (builder, "{sv}", "UInt64PropertyPos", g_variant_new_uint32 (100000056) );
  56. }
  57. private:
  58. std::string name_;
  59. };
  60. class TestIntrospection : public ::testing::Test
  61. {
  62. public:
  63. TestIntrospection()
  64. : root_(new MockIntrospectable("Unity")),
  65. dc_(new MockIntrospectable("DashController")),
  66. pc_(new MockIntrospectable("PanelController")),
  67. foo1_(new MockIntrospectable("Foo")),
  68. foo2_(new MockIntrospectable("Foo")),
  69. foo3_(new MockIntrospectable("Foo"))
  70. {
  71. root_->AddChild(dc_.get());
  72. root_->AddChild(pc_.get());
  73. dc_->AddChild(foo1_.get());
  74. dc_->AddChild(foo2_.get());
  75. dc_->AddChild(foo3_.get());
  76. //root_->SetProperty(g_variant_new("{sv}", "SomeProperty", g_variant_new_string("SomeValue")));
  77. }
  78. protected:
  79. std::shared_ptr<MockIntrospectable> root_;
  80. std::shared_ptr<MockIntrospectable> dc_;
  81. std::shared_ptr<MockIntrospectable> pc_;
  82. std::shared_ptr<MockIntrospectable> foo1_;
  83. std::shared_ptr<MockIntrospectable> foo2_;
  84. std::shared_ptr<MockIntrospectable> foo3_;
  85. };
  86. TEST_F(TestIntrospection, TestTest)
  87. {
  88. ASSERT_STREQ("Unity", root_->GetName().c_str());
  89. }
  90. TEST_F(TestIntrospection, TestVariousRootQueries)
  91. {
  92. std::list<Introspectable*> results;
  93. std::string query;
  94. results = GetIntrospectableNodesFromQuery(query, root_.get());
  95. ASSERT_EQ(1, results.size());
  96. EXPECT_STREQ("Unity", results.front()->GetName().c_str());
  97. query = "/";
  98. results = GetIntrospectableNodesFromQuery(query, root_.get());
  99. ASSERT_EQ(1, results.size());
  100. EXPECT_STREQ("Unity", results.front()->GetName().c_str());
  101. query = "/Unity";
  102. results = GetIntrospectableNodesFromQuery(query, root_.get());
  103. ASSERT_EQ(1, results.size());
  104. EXPECT_STREQ("Unity", results.front()->GetName().c_str());
  105. }
  106. TEST_F(TestIntrospection, TestAbsoluteQueries)
  107. {
  108. std::list<Introspectable*> results;
  109. std::string query = "/Unity/DashController";
  110. results = GetIntrospectableNodesFromQuery(query, root_.get());
  111. ASSERT_EQ(1, results.size());
  112. EXPECT_STREQ("DashController", results.front()->GetName().c_str());
  113. }
  114. TEST_F(TestIntrospection, TestMalformedRelativeQueries)
  115. {
  116. std::list<Introspectable*> results;
  117. std::string query = "Unity";
  118. results = GetIntrospectableNodesFromQuery(query, root_.get());
  119. ASSERT_EQ(1, results.size());
  120. EXPECT_STREQ("Unity", results.front()->GetName().c_str());
  121. query = "Foo";
  122. results = GetIntrospectableNodesFromQuery(query, root_.get());
  123. ASSERT_EQ(3, results.size());
  124. for(auto p : results)
  125. {
  126. EXPECT_STREQ("Foo", p->GetName().c_str());
  127. }
  128. }
  129. TEST_F(TestIntrospection, TestSimpleRelativeQueries)
  130. {
  131. std::list<Introspectable*> results;
  132. std::string query = "//Unity";
  133. results = GetIntrospectableNodesFromQuery(query, root_.get());
  134. ASSERT_EQ(1, results.size());
  135. EXPECT_STREQ("Unity", results.front()->GetName().c_str());
  136. query = "//Foo";
  137. results = GetIntrospectableNodesFromQuery(query, root_.get());
  138. ASSERT_EQ(3, results.size());
  139. for(auto p : results)
  140. {
  141. EXPECT_STREQ("Foo", p->GetName().c_str());
  142. }
  143. }
  144. TEST_F(TestIntrospection, TestComplexRelativeQueries)
  145. {
  146. std::list<Introspectable*> results;
  147. std::string query = "//DashController/Foo";
  148. results = GetIntrospectableNodesFromQuery(query, root_.get());
  149. ASSERT_EQ(3, results.size());
  150. for(auto p : results)
  151. {
  152. EXPECT_STREQ("Foo", p->GetName().c_str());
  153. }
  154. }
  155. TEST_F(TestIntrospection, TestQueriesWithNoResults)
  156. {
  157. std::list<Introspectable*> results;
  158. std::string query = "//Does/Not/Exist";
  159. results = GetIntrospectableNodesFromQuery(query, root_.get());
  160. ASSERT_EQ(0, results.size());
  161. query = "DoesNotEverExist";
  162. results = GetIntrospectableNodesFromQuery(query, root_.get());
  163. ASSERT_EQ(0, results.size());
  164. query = "/Does/Not/Ever/Exist";
  165. results = GetIntrospectableNodesFromQuery(query, root_.get());
  166. ASSERT_EQ(0, results.size());
  167. }
  168. TEST_F(TestIntrospection, TestQueriesWithParams)
  169. {
  170. std::list<Introspectable*> results;
  171. // this should find our root node:
  172. results = GetIntrospectableNodesFromQuery("/Unity[SomeProperty=SomeValue]", root_.get());
  173. ASSERT_EQ(1, results.size());
  174. EXPECT_STREQ("Unity", results.front()->GetName().c_str());
  175. // but this should find nothing:
  176. results = GetIntrospectableNodesFromQuery("/Unity[SomeProperty=SomeOtherValue]", root_.get());
  177. ASSERT_EQ(0, results.size());
  178. // make sure relative paths work:
  179. results = GetIntrospectableNodesFromQuery("//Foo[Name=Foo]", root_.get());
  180. ASSERT_EQ(3, results.size());
  181. for(auto p : results)
  182. {
  183. EXPECT_STREQ("Foo", p->GetName().c_str());
  184. }
  185. // make sure param queries work with descendant nodes as well:
  186. results = GetIntrospectableNodesFromQuery("/Unity[SomeProperty=SomeValue]/DashController[Name=DashController]/Foo", root_.get());
  187. ASSERT_EQ(3, results.size());
  188. for(auto p : results)
  189. {
  190. EXPECT_STREQ("Foo", p->GetName().c_str());
  191. }
  192. }
  193. TEST_F(TestIntrospection, TestQueryTypeBool)
  194. {
  195. std::list<Introspectable*> results;
  196. // These are all equivilent and should return the root item and nothing more:
  197. std::list<std::string> queries = {"/Unity[BoolPropertyTrue=True]",
  198. "/Unity[BoolPropertyTrue=true]",
  199. "/Unity[BoolPropertyTrue=trUE]",
  200. "/Unity[BoolPropertyTrue=yes]",
  201. "/Unity[BoolPropertyTrue=ON]",
  202. "/Unity[BoolPropertyTrue=1]"};
  203. for(auto query : queries)
  204. {
  205. results = GetIntrospectableNodesFromQuery(query, root_.get());
  206. ASSERT_EQ(1, results.size());
  207. EXPECT_STREQ("Unity", results.front()->GetName().c_str());
  208. }
  209. // For boolean properties, anything that's not True, Yes, On or 1 is treated as false:
  210. queries = {"/Unity[BoolPropertyTrue=False]",
  211. "/Unity[BoolPropertyTrue=fAlSE]",
  212. "/Unity[BoolPropertyTrue=No]",
  213. "/Unity[BoolPropertyTrue=OFF]",
  214. "/Unity[BoolPropertyTrue=0]",
  215. "/Unity[BoolPropertyTrue=ThereWasAManFromNantucket]"};
  216. for(auto query : queries)
  217. {
  218. results = GetIntrospectableNodesFromQuery(query, root_.get());
  219. ASSERT_EQ(0, results.size());
  220. }
  221. }
  222. TEST_F(TestIntrospection, TestQueryTypeInt)
  223. {
  224. std::list<Introspectable*> results;
  225. // these should all select the root Unity node:
  226. std::list<std::string> queries = {"/Unity[BytePropertyPos=12]",
  227. "/Unity[Int16PropertyPos=1012]",
  228. "/Unity[Int16PropertyNeg=-1034]",
  229. "/Unity[UInt16PropertyPos=1056]",
  230. "/Unity[Int32PropertyPos=100012]",
  231. "/Unity[Int32PropertyNeg=-100034]",
  232. "/Unity[UInt32PropertyPos=100056]",
  233. "/Unity[Int64PropertyPos=100000012]",
  234. "/Unity[Int64PropertyNeg=-100000034]",
  235. "/Unity[UInt64PropertyPos=100000056]"};
  236. for(auto query : queries)
  237. {
  238. results = GetIntrospectableNodesFromQuery(query, root_.get());
  239. ASSERT_EQ(1, results.size()) << "Failing query: " << query;
  240. EXPECT_STREQ("Unity", results.front()->GetName().c_str());
  241. }
  242. // but these shouldn't:
  243. queries = {"/Unity[BytePropertyPos=1234]",
  244. "/Unity[Int16PropertyPos=0]",
  245. "/Unity[Int16PropertyNeg=-0]",
  246. "/Unity[Int16PropertyNeg=-]",
  247. "/Unity[UInt16PropertyPos=-1056]",
  248. "/Unity[Int32PropertyPos=999999999999999]",
  249. "/Unity[Int32PropertyNeg=Garbage]",
  250. "/Unity[UInt32PropertyPos=-23]"};
  251. for(auto query : queries)
  252. {
  253. results = GetIntrospectableNodesFromQuery(query, root_.get());
  254. ASSERT_EQ(0, results.size());
  255. }
  256. }
  257. TEST_F(TestIntrospection, TestMalformedQueries)
  258. {
  259. // this should work - we have not yet specified a parameter to test against.
  260. std::list<Introspectable*> results = GetIntrospectableNodesFromQuery("/Unity[", root_.get());
  261. ASSERT_EQ(1, results.size());
  262. std::list<std::string> queries = {"/Unity[BoolPropertyTrue",
  263. "/Unity[BoolPropertyTrue=",
  264. "/Unity[BoolPropertyTrue=]",
  265. "/Unity[BytePropertyPos=",
  266. "/Unity[BytePropertyPos=]",
  267. "/Unity[Int16PropertyPos=",
  268. "/Unity[Int16PropertyPos=]",
  269. "/Unity[Int16PropertyNeg=",
  270. "/Unity[Int16PropertyNeg=]",
  271. "/Unity[UInt16PropertyPos[=]]",
  272. "/Unity[Int32PropertyPos[[",
  273. "/Unity[Int32PropertyNeg]",
  274. "/Unity[UInt32PropertyPos=[",
  275. "/Unity[Int64PropertyPos[[",
  276. "/Unity[Int64PropertyNeg",
  277. "/Unity[UInt64PropertyPos]"};
  278. for (std::string query : queries)
  279. {
  280. results = GetIntrospectableNodesFromQuery(query, root_.get());
  281. ASSERT_EQ(0, results.size()) << "Failing query: " << query;
  282. }
  283. }