Merge lp:unity-scopes-api/staging into lp:unity-scopes-api

Proposed by Marcus Tomlinson
Status: Merged
Approved by: Paweł Stołowski
Approved revision: 324
Merged at revision: 367
Proposed branch: lp:unity-scopes-api/staging
Merge into: lp:unity-scopes-api
Diff against target: 2397 lines (+1285/-441)
31 files modified
CMakeLists.txt (+3/-3)
RELEASE_NOTES.md (+7/-0)
debian/VERSION (+1/-1)
debian/changelog (+22/-0)
debian/control.in (+1/-1)
doc/tutorial.dox (+96/-1)
include/unity/scopes/internal/JsonCppNode.h (+17/-10)
include/unity/scopes/internal/JsonNodeInterface.h (+2/-3)
include/unity/scopes/internal/JsonSettingsSchema.h (+1/-1)
include/unity/scopes/internal/gobj_memory.h (+212/-0)
scoperegistry/scoperegistry.cpp (+0/-1)
src/scopes/CategoryRenderer.cpp (+1/-1)
src/scopes/PreviewWidget.cpp (+9/-2)
src/scopes/internal/JsonCppNode.cpp (+283/-200)
src/scopes/internal/JsonSettingsSchema.cpp (+149/-162)
src/scopes/internal/Logger.cpp (+2/-2)
src/scopes/internal/RuntimeImpl.cpp (+1/-1)
src/scopes/internal/ScopeConfig.cpp (+0/-2)
src/scopes/internal/smartscopes/SmartScopesClient.cpp (+10/-0)
src/scopes/internal/zmq_middleware/StopPublisher.cpp (+1/-1)
src/scopes/testing/ScopeMetadataBuilder.cpp (+1/-3)
test/copyright/check_copyright.sh (+1/-7)
test/gtest/scopes/Registry/Registry_test.cpp (+0/-1)
test/gtest/scopes/Registry/scopes/testscopeA/testscopeA.ini.in (+0/-1)
test/gtest/scopes/internal/CMakeLists.txt (+1/-0)
test/gtest/scopes/internal/JsonNode/JsonNode_test.cpp (+153/-17)
test/gtest/scopes/internal/JsonSettingsSchema/JsonSettingsSchema_test.cpp (+37/-5)
test/gtest/scopes/internal/SettingsDB/SettingsDB_test.cpp (+4/-4)
test/gtest/scopes/internal/gobj_ptr/CMakeLists.txt (+3/-0)
test/gtest/scopes/internal/gobj_ptr/gobj_ptr_test.cpp (+208/-0)
test/gtest/scopes/internal/smartscopes/SmartScopesClient/SmartScopesClient_test.cpp (+59/-11)
To merge this branch: bzr merge lp:unity-scopes-api/staging
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Pending
Unity Team Pending
Review via email: mp+295415@code.launchpad.net

Commit message

* Got rid of category header background, as per design (Bug #1446216).
* Re-enabled license/copyright test for xenial+.
* Removed libjson-cpp and replaced with json-glib based implementation (Bug #1360247).
* Fixed Yakkety build.

To post a comment you must log in.
lp:unity-scopes-api/staging updated
319. By Marcus Tomlinson

Sync changelog

320. By Marcus Tomlinson

Update changelog and RELEASE_NOTES.md

321. By Marcus Tomlinson

Bump version

322. By Marcus Tomlinson

Merge devel

323. By Marcus Tomlinson

Merged devel

324. By Paweł Stołowski

Merged devel changes

Revision history for this message
Robert Bruce Park (robru) wrote :

Changelog nitpick inline.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2016-03-31 23:48:56 +0000
+++ CMakeLists.txt 2016-06-17 07:24:44 +0000
@@ -66,11 +66,11 @@
66pkg_check_modules(APPARMOR REQUIRED libapparmor REQUIRED)66pkg_check_modules(APPARMOR REQUIRED libapparmor REQUIRED)
67pkg_check_modules(LTTNG_UST lttng-ust REQUIRED)67pkg_check_modules(LTTNG_UST lttng-ust REQUIRED)
68pkg_check_modules(LIBURCU_BP liburcu-bp REQUIRED)68pkg_check_modules(LIBURCU_BP liburcu-bp REQUIRED)
69pkg_check_modules(JSONCPP jsoncpp REQUIRED)
70pkg_check_modules(LIBACCOUNTS libaccounts-glib REQUIRED)69pkg_check_modules(LIBACCOUNTS libaccounts-glib REQUIRED)
71pkg_check_modules(LIBSIGNON libsignon-glib REQUIRED)70pkg_check_modules(LIBSIGNON libsignon-glib REQUIRED)
72pkg_check_modules(ZMQLIB libzmq REQUIRED)71pkg_check_modules(ZMQLIB libzmq REQUIRED)
73pkg_check_modules(NET_CPP net-cpp>=1.2.0 REQUIRED)72pkg_check_modules(NET_CPP net-cpp>=1.2.0 REQUIRED)
73pkg_check_modules(JSON_GLIB json-glib-1.0 REQUIRED)
7474
75find_library(ZMQPPLIB zmqpp)75find_library(ZMQPPLIB zmqpp)
76if(NOT ZMQPPLIB)76if(NOT ZMQPPLIB)
@@ -140,10 +140,10 @@
140)140)
141141
142set(OTHER_INCLUDE_DIRS ${OTHER_INCLUDE_DIRS} ${UNITY_API_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}142set(OTHER_INCLUDE_DIRS ${OTHER_INCLUDE_DIRS} ${UNITY_API_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
143 ${JSONCPP_INCLUDE_DIRS} ${PROCESS_CPP_INCLUDE_DIRS} ${APPARMOR_INCLUDE_DIRS}143 ${JSON_GLIB_INCLUDE_DIRS} ${PROCESS_CPP_INCLUDE_DIRS} ${APPARMOR_INCLUDE_DIRS}
144 ${LIBACCOUNTS_INCLUDE_DIRS} ${LIBSIGNON_INCLUDE_DIRS} ${NET_CPP_INCLUDE_DIRS})144 ${LIBACCOUNTS_INCLUDE_DIRS} ${LIBSIGNON_INCLUDE_DIRS} ${NET_CPP_INCLUDE_DIRS})
145set(OTHER_LIBS ${OTHER_LIBS} ${UNITY_API_LDFLAGS} ${APPARMOR_LDFLAGS} ${LIBACCOUNTS_LIBRARIES}145set(OTHER_LIBS ${OTHER_LIBS} ${UNITY_API_LDFLAGS} ${APPARMOR_LDFLAGS} ${LIBACCOUNTS_LIBRARIES}
146 ${LIBSIGNON_LIBRARIES} ${Boost_LIBRARIES} ${JSONCPP_LDFLAGS} ${PROCESS_CPP_LDFLAGS}146 ${LIBSIGNON_LIBRARIES} ${Boost_LIBRARIES} ${JSON_GLIB_LDFLAGS} ${PROCESS_CPP_LDFLAGS}
147 ${ZMQPPLIB} ${ZMQLIB_LDFLAGS} ${CAPNPLIB} ${KJLIB} ${DLLIB} ${NET_CPP_LDFLAGS} pthread)147 ${ZMQPPLIB} ${ZMQLIB_LDFLAGS} ${CAPNPLIB} ${KJLIB} ${DLLIB} ${NET_CPP_LDFLAGS} pthread)
148148
149# Standard install paths149# Standard install paths
150150
=== modified file 'RELEASE_NOTES.md'
--- RELEASE_NOTES.md 2016-04-11 07:58:52 +0000
+++ RELEASE_NOTES.md 2016-06-17 07:24:44 +0000
@@ -1,6 +1,13 @@
1Release notes1Release notes
2=============2=============
33
4Changes in version 1.0.6
5========================
6 - Got rid of category header background, as per design (Bug #1446216).
7 - Re-enabled license/copyright test for xenial+.
8 - Removed libjson-cpp and replaced with json-glib based implementation (Bug #1360247).
9 - Fixed Yakkety build.
10
4Changes in version 1.0.511Changes in version 1.0.5
5========================12========================
6 - Simplify debian/control munging.13 - Simplify debian/control munging.
714
=== modified file 'debian/VERSION'
--- debian/VERSION 2016-03-31 23:48:56 +0000
+++ debian/VERSION 2016-06-17 07:24:44 +0000
@@ -1,1 +1,1 @@
11.0.511.0.6
22
=== modified file 'debian/changelog'
--- debian/changelog 2016-04-13 09:51:48 +0000
+++ debian/changelog 2016-06-17 07:24:44 +0000
@@ -1,3 +1,25 @@
1unity-scopes-api (1.0.6+16.10.20160520.3-0ubuntu2) UNRELEASED; urgency=medium
2
3 * Got rid of category header background, as per design (Bug #1446216).
4 * Re-enabled license/copyright test for xenial+.
5 * Removed libjson-cpp and replaced with json-glib based implementation (Bug #1360247).
6 * Fixed Yakkety build.
7
8 -- Marcus Tomlinson <marcustomlinson@ubuntu> Mon, 23 May 2016 09:54:28 +0200
9
10unity-scopes-api (1.0.6+16.10.20160520.3-0ubuntu1) yakkety; urgency=medium
11
12 [ CI Train Bot ]
13 * No-change rebuild.
14
15 -- Marcus Tomlinson <marcus.tomlinson@canonical.com> Fri, 20 May 2016 14:55:39 +0000
16
17unity-scopes-api (1.0.5+16.04.20160413.1-0ubuntu2) yakkety; urgency=medium
18
19 * No-change rebuild of latest xenial trunk against current archive.
20
21 -- Łukasz 'sil2100' Zemczak <lukasz.zemczak@ubuntu.com> Thu, 19 May 2016 19:19:30 +0200
22
1unity-scopes-api (1.0.5+16.04.20160413.1-0ubuntu1) xenial; urgency=medium23unity-scopes-api (1.0.5+16.04.20160413.1-0ubuntu1) xenial; urgency=medium
224
3 [ Marcus Tomlinson ]25 [ Marcus Tomlinson ]
426
=== modified file 'debian/control.in'
--- debian/control.in 2016-03-16 12:35:22 +0000
+++ debian/control.in 2016-06-17 07:24:44 +0000
@@ -21,7 +21,7 @@
21 libboost-thread-dev,21 libboost-thread-dev,
22 libcapnp-dev (>= 0.4.0),22 libcapnp-dev (>= 0.4.0),
23 libdbustest1-dev,23 libdbustest1-dev,
24 libjsoncpp-dev,24 libjson-glib-dev,
25 liblttng-ust-dev,25 liblttng-ust-dev,
26 libnet-cpp-dev (>= 1.2.0),26 libnet-cpp-dev (>= 1.2.0),
27 libprocess-cpp-dev (>= 1.0.1),27 libprocess-cpp-dev (>= 1.0.1),
2828
=== modified file 'doc/tutorial.dox'
--- doc/tutorial.dox 2016-03-16 12:35:22 +0000
+++ doc/tutorial.dox 2016-06-17 07:24:44 +0000
@@ -636,6 +636,102 @@
636call to your `activate()` method. Your implementation of `activate()` should follow the same guidelines as for636call to your `activate()` method. Your implementation of `activate()` should follow the same guidelines as for
637`perform_action()` (except that widget and action identifiers do not apply to result activation).637`perform_action()` (except that widget and action identifiers do not apply to result activation).
638638
639\paragraph resultaction Handling result action activation
640
641Search results can embed simple action buttons (icons) in their cards. When the user taps an action icon, the scope gets notified and can update
642the affected result card to reflect the new state. A typical use case for this is to offer "social" actions, such as thumbs up/down buttons.
643
644The following snippet demonstrates how two actions can be added to a \link unity::scopes::CategorisedResult CategorisedResult\endlink:
645
646\code
647CategorisedResult res(cat);
648res.set_uri("myuri");
649res.set_title("My Title");
650
651// Add result actions
652VariantBuilder builder;
653builder.add_tuple({
654 {"id", Variant("thumbsup")},
655 {"icon", Variant("thOff")},
656 {"temporaryIcon", Variant("thOn")},
657 {"label", Variant("I like it")},
658});
659builder.add_tuple({
660 {"id", Variant("flag")},
661 {"icon", Variant("flag")},
662 {"temporaryIcon", Variant("flagOn")},
663 {"label", Variant("Flag this result")},
664});
665res["social-actions"] = builder.end();
666\endcode
667
668The attributes of result actions are as follows:
669<ul>
670<li>id - unique action identifier that will be reported to the scope.
671<li>icon - the icon for the action button.
672<li>temporaryIcon (optional) - defines an icon that will be shown immediately when the user taps the button, before the scope reacts to the action.
673<li>label - the text shown next to the icon.
674</ul>
675
676To respond to activation of result actions, your scope must implement
677\link unity::scopes::ScopeBase::activate_result_action ScopeBase::activate_result_action\endlink:
678
679\code{.cpp}
680class MyScope : public ScopeBase
681{
682 ...
683 ActivationQueryBase::UPtr activate_result_action(Result const& result,
684 ActionMetadata const& metadata,
685 std::string const& action_id) override;
686 ...
687}
688\endcode
689
690Like `search()` and `preview()`, `activate_result_action()` is a factory method. It must return an
691instance that derives from \link unity::scopes::ActivationQueryBase ActivationQueryBase\endlink.
692Your derived class must implement the \link unity::scopes::ActivationQueryBase::activate activate()\endlink method,
693whose job it is to respond to the activation (that is, the user pressing action button). `activate` must return
694an \link unity::scopes::ActivationResponse ActivationResponse\endlink, which tells the UI how it should
695behave in response to the result action activation. For result actions the typical and recommended behavior is to update the card
696for the result whose action was activated.
697
698For example, here is how to update the actions of an affected card in response to a "thumbsup" action, so that tapping the "thumbsup" action button replaces that
699button with "thumbsdown":
700
701\code{.cpp}
702class MyActivation : public ActivationQueryBase
703{
704 MyActivation(Result const& result, unity::scopes::ActionMetadata const& metadata, std::string const& action_id) :
705 ActivationQueryBase(result, metadata, action_id)
706 {
707 }
708
709 virtual ActivationResponse activate() override
710 {
711 if (action_id() == "thumbsup")
712 {
713 // ... update backend data for 'thumbs up' action ...
714
715 // get the affect result and update it
716 Result updatedRes(result());
717 VariantBuilder builder;
718 builder.add_tuple({
719 {"id", Variant("thumbsdown")},
720 {"icon", Variant("thOn")},
721 {"temporaryIcon", Variant("thOff")},
722 {"label", Variant("I don't like it")},
723 });
724 builder.add_tuple({ ... })
725 updatedRes["social-actions"] = builder.end();
726 return ActivationResponse(updatedRes);
727 }
728
729 if (action_id() == "thumbsdown")
730 ...
731 }
732};
733\endcode
734
639\paragraph export Exporting a scope735\paragraph export Exporting a scope
640736
641Your scope must be compiled into a `.so` shared library and, to be successfully737Your scope must be compiled into a `.so` shared library and, to be successfully
@@ -1430,7 +1526,6 @@
1430 ForegroundColor = default text color (defaults to theme-provided foreground color)1526 ForegroundColor = default text color (defaults to theme-provided foreground color)
1431 BackgroundColor = color of scope background (default is transparent)1527 BackgroundColor = color of scope background (default is transparent)
1432 ShapeImages = whether to use Ubuntu-shape for all cards and artwork (defaults to true)1528 ShapeImages = whether to use Ubuntu-shape for all cards and artwork (defaults to true)
1433 CategoryHeaderBackground = background scheme of the results categories
1434 PreviewButtonColor = color of preview buttons (defaults to theme-provided color)1529 PreviewButtonColor = color of preview buttons (defaults to theme-provided color)
1435 LogoOverlayColor = color for the overlay in scopes overview (defaults to semi-transparent black)1530 LogoOverlayColor = color for the overlay in scopes overview (defaults to semi-transparent black)
1436 PageHeader.Logo = image containing scope's logo1531 PageHeader.Logo = image containing scope's logo
14371532
=== modified file 'include/unity/scopes/internal/JsonCppNode.h'
--- include/unity/scopes/internal/JsonCppNode.h 2014-11-03 05:31:30 +0000
+++ include/unity/scopes/internal/JsonCppNode.h 2016-06-17 07:24:44 +0000
@@ -19,9 +19,15 @@
19#pragma once19#pragma once
2020
21#include <unity/scopes/internal/JsonNodeInterface.h>21#include <unity/scopes/internal/JsonNodeInterface.h>
22#include <jsoncpp/json/value.h>22
23#include <unity/scopes/internal/gobj_memory.h>
23#include <unity/scopes/Variant.h>24#include <unity/scopes/Variant.h>
2425
26#pragma GCC diagnostic push
27#pragma GCC diagnostic ignored "-Wold-style-cast"
28#include <json-glib/json-glib.h>
29#pragma GCC diagnostic pop
30
25namespace unity31namespace unity
26{32{
2733
@@ -34,10 +40,11 @@
34class JsonCppNode : public JsonNodeInterface40class JsonCppNode : public JsonNodeInterface
35{41{
36public:42public:
37 explicit JsonCppNode(std::string const& json_string = "");43 JsonCppNode();
38 explicit JsonCppNode(const Json::Value& root);44 JsonCppNode(std::string const& json_string);
39 explicit JsonCppNode(const Variant& var);45 explicit JsonCppNode(JsonNode* root);
40 ~JsonCppNode();46 explicit JsonCppNode(Variant const& var);
47 ~JsonCppNode() = default;
4148
42 void clear() override;49 void clear() override;
43 void read_json(std::string const& json_string) override;50 void read_json(std::string const& json_string) override;
@@ -49,8 +56,7 @@
49 NodeType type() const override;56 NodeType type() const override;
5057
51 std::string as_string() const override;58 std::string as_string() const override;
52 int as_int() const override;59 int64_t as_int() const override;
53 unsigned int as_uint() const override;
54 double as_double() const override;60 double as_double() const override;
55 bool as_bool() const override;61 bool as_bool() const override;
5662
@@ -61,9 +67,10 @@
61 JsonNodeInterface::SPtr get_node(unsigned int node_index) const override;67 JsonNodeInterface::SPtr get_node(unsigned int node_index) const override;
6268
63private:69private:
64 static Json::Value from_variant(Variant const& var);70 void init_from_string(std::string const& jscon_string);
65 static Variant to_variant(Json::Value const &val);71
66 Json::Value root_;72 typedef std::unique_ptr<JsonNode, decltype(&json_node_free)> NodePtr;
73 NodePtr root_;
67};74};
6875
69} // namespace internal76} // namespace internal
7077
=== modified file 'include/unity/scopes/internal/JsonNodeInterface.h'
--- include/unity/scopes/internal/JsonNodeInterface.h 2014-11-03 05:31:30 +0000
+++ include/unity/scopes/internal/JsonNodeInterface.h 2016-06-17 07:24:44 +0000
@@ -42,7 +42,7 @@
4242
43 enum NodeType43 enum NodeType
44 {44 {
45 Null, Array, Object, String, Int, UInt, Real, Bool45 Null, Array, Object, String, Int, Real, Bool
46 };46 };
4747
48 JsonNodeInterface() = default;48 JsonNodeInterface() = default;
@@ -58,8 +58,7 @@
58 virtual NodeType type() const = 0;58 virtual NodeType type() const = 0;
5959
60 virtual std::string as_string() const = 0;60 virtual std::string as_string() const = 0;
61 virtual int as_int() const = 0;61 virtual int64_t as_int() const = 0;
62 virtual unsigned int as_uint() const = 0;
63 virtual double as_double() const = 0;62 virtual double as_double() const = 0;
64 virtual bool as_bool() const = 0;63 virtual bool as_bool() const = 0;
6564
6665
=== modified file 'include/unity/scopes/internal/JsonSettingsSchema.h'
--- include/unity/scopes/internal/JsonSettingsSchema.h 2014-11-03 05:31:30 +0000
+++ include/unity/scopes/internal/JsonSettingsSchema.h 2016-06-17 07:24:44 +0000
@@ -49,7 +49,7 @@
49 void add_location_setting() override;49 void add_location_setting() override;
5050
51private:51private:
52 JsonSettingsSchema(std::string const& ini_file);52 JsonSettingsSchema(std::string const& json_string);
5353
54 JsonSettingsSchema();54 JsonSettingsSchema();
5555
5656
=== added file 'include/unity/scopes/internal/gobj_memory.h'
--- include/unity/scopes/internal/gobj_memory.h 1970-01-01 00:00:00 +0000
+++ include/unity/scopes/internal/gobj_memory.h 2016-06-17 07:24:44 +0000
@@ -0,0 +1,212 @@
1/*
2 * Copyright (C) 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Jussi Pakkanen <jussi.pakkanen@canonical.com>
17 */
18
19#pragma once
20
21#include <stdexcept>
22
23#pragma GCC diagnostic push
24#pragma GCC diagnostic ignored "-Wold-style-cast"
25#pragma GCC diagnostic ignored "-Wcast-qual"
26#include <glib-object.h>
27
28namespace unity
29{
30
31namespace scopes
32{
33
34namespace internal
35{
36
37/**
38 * This class is meant for automatically managing the lifetime of C objects derived
39 * from gobject. Its API perfectly mirrors the API of unique_ptr except that you
40 * can't define your own deleter function as it is always g_object_unref.
41 *
42 * API/ABI stability is not guaranteed. If you need to pass the object across an ABI
43 * boundary, pass the plain gobject.
44 *
45 * This is how you would use gobj_ptr 99% of the time:
46 *
47 * gobj_ptr<GSomeType> o(g_some_type_new(...));
48 *
49 * More specifically, the object will decrement the gobject reference count
50 * of the object it points to when it goes out of scope. It will never increment it.
51 * Thus you should only assign to it when already holding a reference. gobj_ptr
52 * will then take ownership of that particular reference.
53 *
54 * Floating gobjects can not be put in this container as they are meant to be put
55 * into native gobject aware containers immediately upon construction. Trying to insert
56 * a floating gobject into a gobj_ptr will throw an invalid_argument exception. To
57 * prevent accidental memory leaks, the floating gobject is unreffed in this case.
58 */
59template <typename T>
60class gobj_ptr final
61{
62private:
63 T* u;
64
65 void validate_float(T* t)
66 {
67 if (t != nullptr && g_object_is_floating(G_OBJECT(t)))
68 {
69 // LCOV_EXCL_START // False negative from gcovr.
70 throw std::invalid_argument("Tried to add a floating gobject into a gobj_ptr.");
71 // LCOV_EXCL_STOP
72 }
73 }
74
75public:
76 typedef T element_type;
77 typedef T* pointer;
78 typedef decltype(g_object_unref) deleter_type;
79
80 constexpr gobj_ptr() noexcept : u(nullptr)
81 {
82 }
83 explicit gobj_ptr(T* t)
84 : u(t)
85 {
86 // What should we do if validate throws? Unreffing unknown objs
87 // is dodgy but not unreffing runs the risk of
88 // memory leaks. Currently unrefs as u is destroyed
89 // when this exception is thrown.
90 validate_float(t);
91 }
92 constexpr gobj_ptr(std::nullptr_t) noexcept : u(nullptr){};
93 gobj_ptr(gobj_ptr&& o) noexcept
94 {
95 u = o.u;
96 o.u = nullptr;
97 }
98 gobj_ptr(const gobj_ptr& o)
99 : u(nullptr)
100 {
101 *this = o;
102 }
103 gobj_ptr& operator=(const gobj_ptr& o)
104 {
105 if (o.u != nullptr)
106 {
107 g_object_ref(o.u);
108 }
109 reset(o.u);
110 return *this;
111 }
112 ~gobj_ptr()
113 {
114 reset();
115 }
116
117 deleter_type& get_deleter() noexcept
118 {
119 return g_object_unref;
120 }
121 deleter_type& get_deleter() const noexcept
122 {
123 return g_object_unref;
124 }
125
126 void swap(gobj_ptr<T>& o) noexcept
127 {
128 T* tmp = u;
129 u = o.u;
130 o.u = tmp;
131 }
132 void reset(pointer p = pointer())
133 {
134 if (u != nullptr)
135 {
136 g_object_unref(G_OBJECT(u));
137 u = nullptr;
138 }
139 // Same throw dilemma as in pointer constructor.
140 u = p;
141 validate_float(p);
142 }
143
144 T* release() noexcept
145 {
146 T* r = u;
147 u = nullptr;
148 return r;
149 }
150 T* get() const noexcept
151 {
152 return u;
153 }
154
155 T& operator*() const
156 {
157 return *u;
158 }
159 T* operator->() const noexcept
160 {
161 return u;
162 }
163 explicit operator bool() const noexcept
164 {
165 return u != nullptr;
166 }
167
168 gobj_ptr& operator=(gobj_ptr&& o) noexcept
169 {
170 reset();
171 u = o.u;
172 o.u = nullptr;
173 return *this;
174 }
175 gobj_ptr& operator=(std::nullptr_t) noexcept
176 {
177 reset();
178 return *this;
179 }
180 bool operator==(const gobj_ptr<T>& o) const noexcept
181 {
182 return u == o.u;
183 }
184 bool operator!=(const gobj_ptr<T>& o) const noexcept
185 {
186 return u != o.u;
187 }
188 bool operator<(const gobj_ptr<T>& o) const noexcept
189 {
190 return u < o.u;
191 }
192 bool operator<=(const gobj_ptr<T>& o) const noexcept
193 {
194 return u <= o.u;
195 }
196 bool operator>(const gobj_ptr<T>& o) const noexcept
197 {
198 return u > o.u;
199 }
200 bool operator>=(const gobj_ptr<T>& o) const noexcept
201 {
202 return u >= o.u;
203 }
204};
205
206} // namespace internal
207
208} // namespace scopes
209
210} // namespace unity
211
212#pragma GCC diagnostic pop
0213
=== modified file 'scoperegistry/scoperegistry.cpp'
--- scoperegistry/scoperegistry.cpp 2015-09-11 07:29:12 +0000
+++ scoperegistry/scoperegistry.cpp 2016-06-17 07:24:44 +0000
@@ -338,7 +338,6 @@
338 convert_relative_attribute(inner_map, "navigation-background", scope_dir);338 convert_relative_attribute(inner_map, "navigation-background", scope_dir);
339 app_attrs["page-header"] = Variant(inner_map);339 app_attrs["page-header"] = Variant(inner_map);
340 }340 }
341 convert_relative_attribute(app_attrs, "category-header-background", scope_dir);
342 mi->set_appearance_attributes(app_attrs);341 mi->set_appearance_attributes(app_attrs);
343342
344 mi->set_scope_directory(scope_dir.native());343 mi->set_scope_directory(scope_dir.native());
345344
=== modified file 'src/scopes/CategoryRenderer.cpp'
--- src/scopes/CategoryRenderer.cpp 2016-03-08 10:09:42 +0000
+++ src/scopes/CategoryRenderer.cpp 2016-06-17 07:24:44 +0000
@@ -66,7 +66,7 @@
66\arg \c card-layout Specifies layout of the individual result cards; possible values: \c "vertical" (default), \c "horizontal"66\arg \c card-layout Specifies layout of the individual result cards; possible values: \c "vertical" (default), \c "horizontal"
67\arg \c card-size Size of the result cards; possible values: \c "small", \c "medium" (default), \c "large"; when using <tt>"category-layout": "vertical-journal"</tt> any integer between 12 and 3867\arg \c card-size Size of the result cards; possible values: \c "small", \c "medium" (default), \c "large"; when using <tt>"category-layout": "vertical-journal"</tt> any integer between 12 and 38
68\arg \c overlay Overlay text data on top of the art; boolean, default false68\arg \c overlay Overlay text data on top of the art; boolean, default false
69\arg \c collapsed-rows Number of result rows displayed while the category is collapsed; possible values: any non-negative integer, where 0 fully expands the category (only affects grid and vertical journal)69\arg \c collapsed-rows Number of result rows displayed while the category is collapsed; possible values: any non-negative integer, where 0 fully expands the category (only affects grid)
70\arg \c card-background Background color for the cards; string; URI in the format \verbatim color:///#rrggbb \endverbatim or \verbatim color:///color_name70\arg \c card-background Background color for the cards; string; URI in the format \verbatim color:///#rrggbb \endverbatim or \verbatim color:///color_name
71\endverbatim or \verbatim gradient:///#rrggbb/#rrggbb \endverbatim or an image URI (will be stretched)71\endverbatim or \verbatim gradient:///#rrggbb/#rrggbb \endverbatim or an image URI (will be stretched)
72\arg \c quick-preview-type The type of media content represented by result cards, for use with inline playback; the only currently supported type is "audio".72\arg \c quick-preview-type The type of media content represented by result cards, for use with inline playback; the only currently supported type is "audio".
7373
=== modified file 'src/scopes/PreviewWidget.cpp'
--- src/scopes/PreviewWidget.cpp 2016-01-18 19:50:19 +0000
+++ src/scopes/PreviewWidget.cpp 2016-06-17 07:24:44 +0000
@@ -431,15 +431,18 @@
431\subsection expandable expandable widget431\subsection expandable expandable widget
432432
433The expandable widget is used to group several widgets into an expandable pane.433The expandable widget is used to group several widgets into an expandable pane.
434The expandable widget can be collapsed or uncollapsed. When it's uncollapsed then
435all the contained widgets are shown. When collapsed, only the first few widgets determined
436by collapsed-widgets attribute are shown.
434437
435List of attributes:438List of attributes:
436\arg \c title A string specifying the title439\arg \c title A string specifying the title
437\arg \c collapsed-widgets Optional number of collapsed widgets (0 makes all of them visible)440\arg \c collapsed-widgets A number of widgets to show when the expandable widget is collapsed (optional).
438441
439\code442\code
440 PreviewWidget expandable("exp", "expandable");443 PreviewWidget expandable("exp", "expandable");
441 expandable.add_attribute_value("title", Variant("This is an expandable widget"));444 expandable.add_attribute_value("title", Variant("This is an expandable widget"));
442 expandable.add_attribute_value("collapsed-widgets", Variant(0));445 expandable.add_attribute_value("collapsed-widgets", Variant(2));
443446
444 PreviewWidget w1("w1", "text");447 PreviewWidget w1("w1", "text");
445 w1.add_attribute_value("title", Variant("Subwidget 1"));448 w1.add_attribute_value("title", Variant("Subwidget 1"));
@@ -447,8 +450,12 @@
447 PreviewWidget w2("w2", "text");450 PreviewWidget w2("w2", "text");
448 w2.add_attribute_value("title", Variant("Subwidget 2"));451 w2.add_attribute_value("title", Variant("Subwidget 2"));
449 w2.add_attribute_value("text", Variant("A text"));452 w2.add_attribute_value("text", Variant("A text"));
453 PreviewWidget w3("w3", "text");
454 w3.add_attribute_value("title", Variant("Subwidget 3"));
455 w3.add_attribute_value("text", Variant("A text"));
450 expandable.add_widget(w1);456 expandable.add_widget(w1);
451 expandable.add_widget(w2);457 expandable.add_widget(w2);
458 expandable.add_widget(w3);
452 ...459 ...
453\endcode460\endcode
454461
455462
=== modified file 'src/scopes/internal/JsonCppNode.cpp'
--- src/scopes/internal/JsonCppNode.cpp 2015-11-02 05:08:08 +0000
+++ src/scopes/internal/JsonCppNode.cpp 2016-06-17 07:24:44 +0000
@@ -14,316 +14,399 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *15 *
16 * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com>16 * Authored by: Marcus Tomlinson <marcus.tomlinson@canonical.com>
17 * Michi Henning <michi.henning@canonical.com>
17 */18 */
1819
19#include <unity/scopes/internal/JsonCppNode.h>20#include <unity/scopes/internal/JsonCppNode.h>
21
20#include <unity/UnityExceptions.h>22#include <unity/UnityExceptions.h>
21#include <jsoncpp/json/reader.h>
22#include <jsoncpp/json/writer.h>
23#include <sstream>
2423
24using namespace std;
25using namespace unity::scopes;25using namespace unity::scopes;
26using namespace unity::scopes::internal;26using namespace unity::scopes::internal;
2727
28JsonCppNode::JsonCppNode(std::string const& json_string)28void JsonCppNode::init_from_string(string const& json_string)
29{29{
30 if (!json_string.empty())30 if (json_string.find_first_not_of(" \t\n") == std::string::npos)
31 {31 {
32 read_json(json_string);32 throw unity::ResourceException("JsonCppNode(): empty string is not a valid JSON");
33 }33 }
34}34
3535 gobj_ptr<JsonParser> parser(json_parser_new());
36JsonCppNode::JsonCppNode(const Json::Value& root)36 GError *err = nullptr;
37 : root_(root)37 if (!json_parser_load_from_data(parser.get(), json_string.c_str(), json_string.size(), &err))
38{38 {
39}39 string msg = string("JsonCppNode(); parse error: ") + err->message;
4040 g_error_free(err);
41JsonCppNode::JsonCppNode(const Variant& var)41 throw unity::ResourceException(msg);
42{42 }
43 root_ = from_variant(var);43 root_.reset(json_node_copy(json_parser_get_root(parser.get())));
44}44}
4545
46JsonCppNode::~JsonCppNode()46JsonCppNode::JsonCppNode()
47{47 : root_(json_node_alloc(), json_node_free)
48}48{
4949 json_node_init_null(root_.get());
50Json::Value JsonCppNode::from_variant(Variant const& var)50}
51{51
52JsonCppNode::JsonCppNode(string const& json_string)
53 : JsonCppNode()
54{
55 init_from_string(json_string);
56}
57
58JsonCppNode::JsonCppNode(JsonNode* node)
59 : root_(json_node_copy(node), json_node_free)
60{
61}
62
63namespace
64{
65
66// Allocates a new node for each value. Caller is responsible for deallocating the root node.
67
68JsonNode* variant_to_node(Variant const& var)
69{
70 unique_ptr<JsonNode, decltype(&json_node_free)> node_guard(json_node_alloc(), json_node_free);
71 auto node = node_guard.get();
52 switch (var.which())72 switch (var.which())
53 {73 {
74 case Variant::Type::Null:
75 json_node_init_null(node);
76 break;
77 case Variant::Type::Array:
78 {
79 unique_ptr<JsonArray, decltype(&json_array_unref)> array(json_array_new(), json_array_unref);
80 for (auto const& v : var.get_array())
81 {
82 json_array_add_element(array.get(), variant_to_node(v));
83 }
84 json_node_init_array(node, array.get());
85 break;
86 }
87 case Variant::Type::Dict:
88 {
89 unique_ptr<JsonObject, decltype(&json_object_unref)> object(json_object_new(), json_object_unref);
90 for (auto const& v : var.get_dict())
91 {
92 json_object_set_member(object.get(), v.first.c_str(), variant_to_node(v.second));
93 }
94 json_node_set_object(node, object.get());
95 break;
96 }
97 case Variant::Type::String:
98 json_node_init_string(node, var.get_string().c_str());
99 break;
54 case Variant::Type::Int:100 case Variant::Type::Int:
55 return Json::Value(var.get_int());101 json_node_init_int(node, int64_t(var.get_int()));
102 break;
56 case Variant::Type::Int64:103 case Variant::Type::Int64:
57 return Json::Value(static_cast<Json::Int64>(var.get_int64_t()));104 json_node_init_int(node, var.get_int64_t());
105 break;
106 case Variant::Type::Double:
107 json_node_init_double(node, var.get_double());
108 break;
58 case Variant::Type::Bool:109 case Variant::Type::Bool:
59 return Json::Value(var.get_bool());110 {
60 case Variant::Type::String:111 json_node_init_boolean(node, var.get_bool());
61 return Json::Value(var.get_string());112 break;
62 case Variant::Type::Double:113 }
63 return Json::Value(var.get_double());
64 case Variant::Type::Dict:
65 {
66 Json::Value val(Json::ValueType::objectValue);
67 for (auto const& v: var.get_dict())
68 {
69 val[v.first] = from_variant(v.second);
70 }
71 return val;
72 }
73 case Variant::Type::Array:
74 {
75 Json::Value val(Json::ValueType::arrayValue);
76 for (auto const& v: var.get_array())
77 {
78 val.append(from_variant(v));
79 }
80 return val;
81 }
82 case Variant::Type::Null:
83 return Json::Value(Json::ValueType::nullValue);
84 default:114 default:
85 {115 {
86 std::ostringstream s;116 abort(); // LCOV_EXCL_LINE // Impossible
87 s << "JsonCppNode::from_variant(): unsupported variant type ";117 }
88 s << static_cast<int>(var.which());
89 throw unity::LogicException(s.str());
90 }
91 }118 }
92}119 return node_guard.release();
93120}
94Variant JsonCppNode::to_variant(Json::Value const& value)121
95{122} // namespace
96 switch (value.type())123
124JsonCppNode::JsonCppNode(Variant const& var)
125 : root_(variant_to_node(var), json_node_free)
126{
127}
128
129#pragma GCC diagnostic push
130#pragma GCC diagnostic ignored "-Wold-style-cast"
131
132namespace
133{
134
135Variant node_to_variant(JsonNode* node); // Mutual recursion, need forward declaration.
136
137extern "C"
138void add_to_array(JsonArray* /* array */, guint /* index */, JsonNode* element_node, gpointer user_data)
139{
140 VariantArray* va = reinterpret_cast<VariantArray*>(user_data);
141 va->push_back(node_to_variant(element_node));
142}
143
144extern "C"
145void add_to_map(JsonObject* /* object */, gchar const* member_name, JsonNode* member_node, gpointer user_data)
146{
147 VariantMap* vm = reinterpret_cast<VariantMap*>(user_data);
148 (*vm)[member_name] = node_to_variant(member_node);
149}
150
151Variant node_to_variant(JsonNode* node)
152{
153 switch (json_node_get_node_type(node))
97 {154 {
98 case Json::ValueType::nullValue:155 case JSON_NODE_NULL:
99 return Variant::null();156 return Variant::null();
100 case Json::ValueType::arrayValue:157 case JSON_NODE_ARRAY:
101 {158 {
102 VariantArray arr;159 VariantArray va;
103 for (unsigned int i=0; i<value.size(); ++i)160 auto array = json_node_get_array(node);
104 {161 json_array_foreach_element(array, add_to_array, &va);
105 arr.push_back(to_variant(value[i]));162 return Variant(va);
106 }163 }
107 return Variant(arr);164 case JSON_NODE_OBJECT:
108 }165 {
109 case Json::ValueType::objectValue:166 VariantMap vm;
110 {167 auto object = json_node_get_object(node);
111 VariantMap var;168 json_object_foreach_member(object, add_to_map, &vm);
112 for (auto const& m: value.getMemberNames())169 return Variant(vm);
113 {170 }
114 var[m] = to_variant(value[m]);171 case JSON_NODE_VALUE:
115 }172 {
116 return Variant(var);173 switch (json_node_get_value_type(node))
117 }174 {
118 case Json::ValueType::stringValue:175 case G_TYPE_STRING:
119 return Variant(value.asString());176 return Variant(string(json_node_get_string(node)));
120 case Json::ValueType::intValue:177 case G_TYPE_INT64:
121 case Json::ValueType::uintValue:178 {
122 // this can throw std::runtime_error from jsoncpp if unsigned int to int conversion is not possible179 // HACK: If the value fits into a 32-bit int, return an Int
123 if (value.isInt())180 // variant. Otherwise, return an Int64 variant.
124 {181 int64_t val64 = json_node_get_int(node);
125 return Variant(value.asInt());182 if (val64 < INT32_MIN || val64 > INT32_MAX)
126 }183 {
127 return Variant(static_cast<int64_t>(value.asInt64()));184 return Variant(val64);
128 case Json::ValueType::realValue:185 }
129 return Variant(value.asDouble());186 int32_t val32 = val64;
130 case Json::ValueType::booleanValue:187 return Variant(val32);
131 return Variant(value.asBool());188 }
189 case G_TYPE_DOUBLE:
190 return Variant(json_node_get_double(node));
191 case G_TYPE_BOOLEAN:
192 return Variant(bool(json_node_get_boolean(node)));
193 default:
194 abort(); // LCOV_EXCL_LINE // Impossible
195 }
196 }
132 default:197 default:
133 {198 abort(); // LCOV_EXCL_LINE // Impossible
134 std::ostringstream s;
135 s << "JsonCppNode::to_variant(): unsupported json type ";
136 s << static_cast<int>(value.type());
137 throw unity::LogicException(s.str());
138 }
139 }199 }
140}200}
141201
202} // namespace
203
142Variant JsonCppNode::to_variant() const204Variant JsonCppNode::to_variant() const
143{205{
144 return to_variant(root_);206 return node_to_variant(root_.get());
145}207}
146208
147void JsonCppNode::clear()209void JsonCppNode::clear()
148{210{
149 root_.clear();211 json_node_init_null(root_.get());
150}212}
151213
152void JsonCppNode::read_json(std::string const& json_string)214void JsonCppNode::read_json(string const& json_string)
153{215{
154 Json::Reader reader;216 init_from_string(json_string);
155 clear();217}
156218
157 if (!reader.parse(json_string, root_))219string JsonCppNode::to_json_string() const
158 {220{
159 throw unity::ResourceException("Failed to parse json string: " + reader.getFormattedErrorMessages());221 gobj_ptr<JsonGenerator> generator(json_generator_new());
160 }222 json_generator_set_root(generator.get(), root_.get());
161}223
162224 gsize len;
163std::string JsonCppNode::to_json_string() const225 unique_ptr<gchar, decltype(&g_free)> data(json_generator_to_data(generator.get(), &len), g_free);
164{226 string result(data.get(), len);
165 Json::FastWriter writer;227 result += '\n';
166 return writer.write(root_);228 return result;
167}229}
168230
169int JsonCppNode::size() const231int JsonCppNode::size() const
170{232{
171 return root_.size();233 switch (json_node_get_node_type(root_.get()))
172}234 {
173235 case JSON_NODE_ARRAY:
174std::vector<std::string> JsonCppNode::member_names() const236 {
175{237 auto array = json_node_get_array(root_.get());
176 if (root_.type() != Json::objectValue)238 return json_array_get_length(array);
239 }
240 case JSON_NODE_OBJECT:
241 {
242 auto object = json_node_get_object(root_.get());
243 return json_object_get_size(object);
244 }
245 default:
246 return 0;
247 }
248}
249
250namespace
251{
252
253extern "C"
254void add_name(JsonObject* /* object */, gchar const* member_name, JsonNode* /* member_node */, gpointer user_data)
255{
256 vector<string>* names = reinterpret_cast<vector<string>*>(user_data);
257 names->push_back(member_name);
258}
259
260}
261
262vector<string> JsonCppNode::member_names() const
263{
264 if (!JSON_NODE_HOLDS_OBJECT(root_.get()))
177 {265 {
178 throw unity::LogicException("Root node is not an object");266 throw unity::LogicException("Root node is not an object");
179 }267 }
180 return root_.getMemberNames();268
269 vector<string> names;
270 auto object = json_node_get_object(root_.get());
271 json_object_foreach_member(object, add_name, &names);
272 return names;
181}273}
182274
183JsonNodeInterface::NodeType JsonCppNode::type() const275JsonNodeInterface::NodeType JsonCppNode::type() const
184{276{
185 switch (root_.type())277 switch (json_node_get_node_type(root_.get()))
186 {278 {
187 case Json::nullValue:279 case JSON_NODE_NULL:
188 return Null;280 return Null;
189 case Json::arrayValue:281 case JSON_NODE_ARRAY:
190 return Array;282 return Array;
191 case Json::objectValue:283 case JSON_NODE_OBJECT:
192 return Object;284 return Object;
193 case Json::stringValue:285 case JSON_NODE_VALUE:
194 return String;286 {
195 case Json::intValue:287 switch (json_node_get_value_type(root_.get()))
196 return Int;288 {
197 case Json::uintValue:289 case G_TYPE_STRING:
198 return UInt;290 return String;
199 case Json::realValue:291 case G_TYPE_INT64:
200 return Real;292 return Int;
201 case Json::booleanValue:293 case G_TYPE_DOUBLE:
202 return Bool;294 return Real;
295 case G_TYPE_BOOLEAN:
296 return Bool;
297 default:
298 abort(); // LCOV_EXCL_LINE // Impossible
299 }
300 }
203 default:301 default:
204 break;302 abort(); // LCOV_EXCL_LINE // Impossible
205 }303 }
206304
207 return Null;305 abort(); // LCOV_EXCL_LINE
208}306}
209307
210std::string JsonCppNode::as_string() const308string JsonCppNode::as_string() const
211{309{
212 if (!root_.isConvertibleTo(Json::stringValue))310 if (JSON_NODE_HOLDS_NULL(root_.get()))
311 {
312 return string();
313 }
314 if (!JSON_NODE_HOLDS_VALUE(root_.get()) || json_node_get_value_type(root_.get()) != G_TYPE_STRING)
213 {315 {
214 throw unity::LogicException("Node does not contain a string value");316 throw unity::LogicException("Node does not contain a string value");
215 }317 }
216318
217 return root_.asString();319 return string(json_node_get_string(root_.get()));
218}320}
219321
220int JsonCppNode::as_int() const322int64_t JsonCppNode::as_int() const
221{323{
222 if (!root_.isConvertibleTo(Json::intValue))324 if (!JSON_NODE_HOLDS_VALUE(root_.get()) || json_node_get_value_type(root_.get()) != G_TYPE_INT64)
223 {325 {
224 throw unity::LogicException("Node does not contain an int value");326 throw unity::LogicException("Node does not contain an int value");
225 }327 }
226328
227 return root_.asInt();329 return json_node_get_int(root_.get());
228}
229
230unsigned int JsonCppNode::as_uint() const
231{
232 if (!root_.isConvertibleTo(Json::uintValue))
233 {
234 throw unity::LogicException("Node does not contain a unsigned int value");
235 }
236
237 return root_.asUInt();
238}330}
239331
240double JsonCppNode::as_double() const332double JsonCppNode::as_double() const
241{333{
242 if (!root_.isConvertibleTo(Json::realValue))334 if (!JSON_NODE_HOLDS_VALUE(root_.get()) || json_node_get_value_type(root_.get()) != G_TYPE_DOUBLE)
243 {335 {
244 throw unity::LogicException("Node does not contain a double value");336 throw unity::LogicException("Node does not contain a double value");
245 }337 }
246338
247 return root_.asDouble();339 return json_node_get_double(root_.get());
248}340}
249341
250bool JsonCppNode::as_bool() const342bool JsonCppNode::as_bool() const
251{343{
252 if (!root_.isConvertibleTo(Json::booleanValue))344 if (!JSON_NODE_HOLDS_VALUE(root_.get()) || json_node_get_value_type(root_.get()) != G_TYPE_BOOLEAN)
253 {345 {
254 throw unity::LogicException("Node does not contain a bool value");346 throw unity::LogicException("Node does not contain a bool value");
255 }347 }
256348
257 return root_.asBool();349 return json_node_get_boolean(root_.get());
258}350}
259351
260bool JsonCppNode::has_node(std::string const& node_name) const352#pragma GCC diagnostic pop
353
354bool JsonCppNode::has_node(string const& node_name) const
261{355{
262 if (!root_)356 if (JSON_NODE_HOLDS_NULL(root_.get()))
263 {357 {
264 throw unity::LogicException("Current node is empty");358 throw unity::LogicException("Current node is empty");
265 }359 }
266360
267 if (root_.type() != Json::objectValue)361 if (!JSON_NODE_HOLDS_OBJECT(root_.get()))
268 {362 {
269 throw unity::LogicException("Root node is not an object");363 throw unity::LogicException("Root node is not an object");
270 }364 }
271365
272 return root_.isMember(node_name);366 return json_object_has_member(json_node_get_object(root_.get()), node_name.c_str());
273}367}
274368
275JsonNodeInterface::SPtr JsonCppNode::get_node() const369JsonNodeInterface::SPtr JsonCppNode::get_node() const
276{370{
277 if (!root_)371 if (JSON_NODE_HOLDS_NULL(root_.get()))
278 {372 {
279 throw unity::LogicException("Current node is empty");373 throw unity::LogicException("Current node is empty");
280 }374 }
281375
282 return std::make_shared<JsonCppNode>(root_);376 return make_shared<JsonCppNode>(root_.get());
283}377}
284378
285JsonNodeInterface::SPtr JsonCppNode::get_node(std::string const& node_name) const379JsonNodeInterface::SPtr JsonCppNode::get_node(string const& node_name) const
286{380{
287 if (!root_)381 if (!has_node(node_name))
288 {
289 throw unity::LogicException("Current node is empty");
290 }
291
292 if (root_.type() != Json::objectValue)
293 {
294 throw unity::LogicException("Root node is not an object");
295 }
296 if (!root_.isMember(node_name))
297 {382 {
298 throw unity::LogicException("Node " + node_name + " does not exist");383 throw unity::LogicException("Node " + node_name + " does not exist");
299 }384 }
300385
301 const Json::Value& value_node = root_[node_name];386 auto object = json_node_get_object(root_.get());
302 return std::make_shared<JsonCppNode>(value_node);387 auto member = json_object_get_member(object, node_name.c_str());
388 return make_shared<JsonCppNode>(member);
303}389}
304390
305JsonNodeInterface::SPtr JsonCppNode::get_node(unsigned int node_index) const391JsonNodeInterface::SPtr JsonCppNode::get_node(unsigned int node_index) const
306{392{
307 if (!root_)393 if (JSON_NODE_HOLDS_NULL(root_.get()))
308 {394 {
309 throw unity::LogicException("Current node is empty");395 throw unity::LogicException("Current node is empty");
310 }396 }
311397
312 if (root_.type() != Json::arrayValue)398 if (!JSON_NODE_HOLDS_ARRAY(root_.get()))
313 {399 {
314 throw unity::LogicException("Root node is not an array");400 throw unity::LogicException("Root node is not an array");
315 }401 }
316 else if (node_index >= root_.size())402
317 {403 auto array = json_node_get_array(root_.get());
318 throw unity::LogicException("Invalid array index");404 auto size = json_array_get_length(array);
319 }405 if (node_index >= size)
320406 {
321 const Json::Value& value_node = root_[node_index];407 throw unity::LogicException("Invalid array index: " + to_string(node_index));
322408 }
323 if (!value_node)409
324 {410 auto element = json_array_get_element(array, node_index);
325 throw unity::LogicException("Node " + std::to_string(node_index) + " does not exist");411 return make_shared<JsonCppNode>(element);
326 }
327
328 return std::make_shared <JsonCppNode> (value_node);
329}412}
330413
=== modified file 'src/scopes/internal/JsonSettingsSchema.cpp'
--- src/scopes/internal/JsonSettingsSchema.cpp 2015-03-02 03:59:01 +0000
+++ src/scopes/internal/JsonSettingsSchema.cpp 2016-06-17 07:24:44 +0000
@@ -19,10 +19,10 @@
19#include <unity/scopes/internal/JsonSettingsSchema.h>19#include <unity/scopes/internal/JsonSettingsSchema.h>
2020
21#include <unity/scopes/internal/DfltConfig.h>21#include <unity/scopes/internal/DfltConfig.h>
22#include <unity/scopes/internal/JsonCppNode.h>
2223
23#include <boost/algorithm/string/predicate.hpp>24#include <boost/algorithm/string/predicate.hpp>
24#include <boost/filesystem.hpp>25#include <boost/filesystem.hpp>
25#include <jsoncpp/json/json.h>
26#include <unity/UnityExceptions.h>26#include <unity/UnityExceptions.h>
2727
28#include <set>28#include <set>
@@ -52,7 +52,7 @@
52public:52public:
53 NONCOPYABLE(Setting);53 NONCOPYABLE(Setting);
5454
55 Setting(Json::Value const& v);55 Setting(Variant const& v);
56 Setting(string const& id,56 Setting(string const& id,
57 string const& type,57 string const& type,
58 string const& display_name,58 string const& display_name,
@@ -68,13 +68,13 @@
6868
69private:69private:
7070
71 Json::Value get_mandatory(Json::Value const& v, Json::StaticString const& key, Json::ValueType expected_type) const;71 Variant get_mandatory(Variant const& v, string const& key, Variant::Type expected_type) const;
72 void set_default_value(Json::Value const& v, Type expected_type);72 void set_default_value(Variant const& v, Type expected_type);
73 Variant get_bool_default(Json::Value const& v) const;73 Variant get_bool_default(Variant const& v) const;
74 Variant get_enum_default(Json::Value const& v);74 Variant get_enum_default(Variant const& v);
75 Variant get_double_default(Json::Value const& v) const;75 Variant get_double_default(Variant const& v) const;
76 Variant get_string_default(Json::Value const& v) const;76 Variant get_string_default(Variant const& v) const;
77 void set_enumerators(Json::Value const& v);77 void set_enumerators(Variant const& v);
7878
79 string id_;79 string id_;
80 string type_;80 string type_;
@@ -90,32 +90,32 @@
90 { "string", Setting::StringT },90 { "string", Setting::StringT },
91 };91 };
9292
93Setting::Setting(Json::Value const& v)93Setting::Setting(Variant const& v)
94{94{
95 assert(v.isObject());95 assert(v.which() == Variant::Type::Dict);
9696
97 static auto const id_key = Json::StaticString("id");97 static string const id_key = "id";
98 static auto const type_key = Json::StaticString("type");98 static string const type_key = "type";
99 static auto const display_name_key = Json::StaticString("displayName");99 static string const display_name_key = "displayName";
100100
101 id_ = get_mandatory(v, id_key, Json::stringValue).asString();101 id_ = get_mandatory(v, id_key, Variant::Type::String).get_string();
102 if (id_.empty())102 if (id_.empty())
103 {103 {
104 throw ResourceException(string("JsonSettingsSchema(): invalid empty \"") + id_key.c_str() + "\" definition");104 throw ResourceException(string("JsonSettingsSchema(): invalid empty \"") + id_key + "\" definition");
105 }105 }
106106
107 auto v_type = get_mandatory(v, type_key, Json::stringValue);107 auto v_type = get_mandatory(v, type_key, Variant::Type::String);
108 string type_string = v_type.asString();108 string type_string = v_type.get_string();
109 auto const it = VALID_TYPES.find(type_string);109 auto const it = VALID_TYPES.find(type_string);
110 if (it == VALID_TYPES.end())110 if (it == VALID_TYPES.end())
111 {111 {
112 throw ResourceException(string("JsonSettingsSchema(): invalid \"") + type_key.c_str() + "\" setting: \""112 throw ResourceException(string("JsonSettingsSchema(): invalid \"") + type_key + "\" definition: \""
113 + type_string + "\", " "id = \"" + id_ + "\"");113 + type_string + "\", " "id = \"" + id_ + "\"");
114 }114 }
115 type_ = it->first;115 type_ = it->first;
116 set_default_value(v, it->second);116 set_default_value(v, it->second);
117117
118 display_name_ = get_mandatory(v, display_name_key, Json::stringValue).asString();118 display_name_ = get_mandatory(v, display_name_key, Variant::Type::String).get_string();
119}119}
120120
121Setting::Setting(string const& id,121Setting::Setting(string const& id,
@@ -131,11 +131,7 @@
131 assert(!id.empty());131 assert(!id.empty());
132132
133 auto const it = VALID_TYPES.find(type);133 auto const it = VALID_TYPES.find(type);
134 if (it == VALID_TYPES.end())134 assert(it != VALID_TYPES.end());
135 {
136 throw ResourceException(string("JsonSettingsSchema(): invalid \"type\" definition: \"")
137 + type + "\", setting = \"" + id_ + "\"");
138 }
139 type_ = it->first;135 type_ = it->first;
140}136}
141137
@@ -158,35 +154,33 @@
158 return Variant(schema);154 return Variant(schema);
159}155}
160156
161Json::Value Setting::get_mandatory(Json::Value const& v,157Variant Setting::get_mandatory(Variant const& v, string const& key, Variant::Type expected_type) const
162 Json::StaticString const& key,
163 Json::ValueType expected_type) const
164{158{
165 assert(v.isObject());159 assert(v.which() == Variant::Type::Dict);
166 auto val = v[key];160 auto val = v.get_dict()[key];
167 if (val.isNull())161 if (val.is_null())
168 {162 {
169 throw ResourceException(string("JsonSettingsSchema(): missing \"") + key.c_str() + "\" definition"163 throw ResourceException(string("JsonSettingsSchema(): missing \"") + key + "\" definition"
170 + (!id_.empty() ? ", id = \"" + id_ + "\"" : string()));164 + (!id_.empty() ? ", id = \"" + id_ + "\"" : string()));
171 }165 }
172 if (val.type() != expected_type)166 if (val.which() != expected_type)
173 {167 {
174 throw ResourceException(string("JsonSettingsSchema(): invalid value type for \"") + key.c_str() + "\" definition, "168 throw ResourceException(string("JsonSettingsSchema(): invalid value type for \"") + key
175 + "id = \"" + id_ + "\"");169 + "\" definition, " + "id = \"" + id_ + "\"");
176 }170 }
177 return val;171 return val;
178}172}
179173
180static auto const parameters_key = Json::StaticString("parameters");174static string const parameters_key = "parameters";
181175
182void Setting::set_default_value(Json::Value const& v, Type expected_type)176void Setting::set_default_value(Variant const& v, Type expected_type)
183{177{
184 auto v_param = v[parameters_key];178 auto v_param = v.get_dict()[parameters_key];
185 if (v_param.isNull())179 if (v_param.is_null())
186 {180 {
187 return;181 return;
188 }182 }
189 else if (!v_param.isObject())183 else if (v_param.which() != Variant::Type::Dict)
190 {184 {
191 throw ResourceException("JsonSettingsSchema(): expected value of type object for \"parameters\", id = \"" + id_ + "\"");185 throw ResourceException("JsonSettingsSchema(): expected value of type object for \"parameters\", id = \"" + id_ + "\"");
192 }186 }
@@ -219,124 +213,120 @@
219 }213 }
220}214}
221215
222static auto const dflt_key = Json::StaticString("defaultValue");216static string const dflt_key = "defaultValue";
223217
224Variant Setting::get_bool_default(Json::Value const& v) const218Variant Setting::get_bool_default(Variant const& v) const
225{219{
226 if (v.isNull()) // No "parameters" key220 assert(!v.is_null());
227 {221
228 return Variant();222 auto v_dflt = v.get_dict()[dflt_key];
229 }223 if (v_dflt.is_null())
230 auto v_dflt = v[dflt_key];224 {
231 if (v_dflt.isNull())225 return Variant(); // No "defaultValue" key
232 {226 }
233 return Variant(); // No "defaultValue" key227 if (v_dflt.which() != Variant::Type::Bool)
234 }228 {
235 if (!v_dflt.isBool())229 throw ResourceException(string("JsonSettingsSchema(): invalid value type for \"") + dflt_key
236 {230 + "\" definition, id = \"" + id_ + "\"");
237 throw ResourceException(string("JsonSettingsSchema(): invalid value type for \"") + dflt_key.c_str()231 }
238 + "\" definition, id = \"" + id_ + "\"");232 return v_dflt;
239 }233}
240 return Variant(v_dflt.asBool());234
241}235Variant Setting::get_double_default(Variant const& v) const
242236{
243Variant Setting::get_double_default(Json::Value const& v) const237 assert(!v.is_null());
244{238
245 if (v.isNull()) // No "parameters" key239 auto v_dflt = v.get_dict()[dflt_key];
246 {240 if (v_dflt.is_null())
247 return Variant();241 {
248 }242 return Variant(); // No "defaultValue" key
249 auto v_dflt = v[dflt_key];243 }
250 if (v_dflt.isNull())244 switch (v_dflt.which())
251 {245 {
252 return Variant(); // No "defaultValue" key246 case Variant::Type::Int:
253 }247 return Variant(double(v_dflt.get_int()));
254 if (!v_dflt.isNumeric())248 case Variant::Type::Int64:
255 {249 return Variant(double(v_dflt.get_int64_t()));
256 throw ResourceException(string("JsonSettingsSchema(): invalid value type for \"") + dflt_key.c_str()250 case Variant::Type::Double:
257 + "\" definition, id = \"" + id_ + "\"");251 return v_dflt;
258 }252 default:
259 return Variant(v_dflt.asDouble());253 throw ResourceException(string("JsonSettingsSchema(): invalid value type for \"") + dflt_key
260}254 + "\" definition, id = \"" + id_ + "\"");
261255 }
262Variant Setting::get_enum_default(Json::Value const& v)256}
263{257
264 assert(v.isObject());258Variant Setting::get_enum_default(Variant const& v)
265259{
266 if (v.isNull()) // No "parameters" key260 assert(v.which() == Variant::Type::Dict);
267 {261
268 throw ResourceException(string("JsonSettingsSchema(): missing \"") + parameters_key.c_str()262 auto v_dflt = v.get_dict()[dflt_key];
269 + "\" definition, id = \"" + id_ + "\"");263 if (v_dflt.is_null())
270 }264 {
271 auto v_dflt = v[dflt_key];265 return Variant(); // No "defaultValue" key
272 if (v_dflt.isNull())266 }
273 {267 if (v_dflt.which() != Variant::Type::Int)
274 return Variant(); // No "defaultValue" key268 {
275 }269 throw ResourceException(string("JsonSettingsSchema(): invalid value type for \"") + dflt_key
276 if (!v_dflt.isInt())270 + "\" definition, id = \"" + id_ + "\"");
277 {271 }
278 throw ResourceException(string("JsonSettingsSchema(): invalid value type for \"") + dflt_key.c_str()272
279 + "\" definition, id = \"" + id_ + "\"");273 static string const values_key = "values";
280 }274
281275 auto v_vals = v.get_dict()[values_key];
282 static auto const values_key = Json::StaticString("values");276 if (v_vals.which() != Variant::Type::Array)
283277 {
284 auto v_vals = v[values_key];278 throw ResourceException(string("JsonSettingsSchema(): invalid value type for \"") + values_key
285 if (!v_vals.isArray())279 + "\" definition, id = \"" + id_ + "\"");
286 {280 }
287 throw ResourceException(string("JsonSettingsSchema(): invalid value type for \"") + values_key.c_str()281 if (v_vals.get_array().size() == 0)
288 + "\" definition, id = \"" + id_ + "\"");282 {
289 }283 throw ResourceException(string("JsonSettingsSchema(): invalid empty \"") + values_key
290 if (v_vals.size() < 1)284 + "\" definition, id = \"" + id_ + "\"");
291 {
292 throw ResourceException(string("JsonSettingsSchema(): invalid empty \"") + values_key.c_str()
293 + "\" definition, id = \"" + id_ + "\"");
294 }285 }
295286
296 set_enumerators(v_vals);287 set_enumerators(v_vals);
297288
298 auto val = v_dflt.asInt();289 auto val = v_dflt.get_int();
299 if (val < 0 || val >= static_cast<int>(v_vals.size()))290 if (val < 0 || val >= static_cast<int>(v_vals.get_array().size()))
300 {291 {
301 throw ResourceException(string("JsonSettingsSchema(): \"") + dflt_key.c_str()292 throw ResourceException(string("JsonSettingsSchema(): \"") + dflt_key
302 + "\" out of range, id = \"" + id_ + "\"");293 + "\" out of range, id = \"" + id_ + "\"");
303 }294 }
304 return Variant(v_dflt.asInt());295 return v_dflt;
305}296}
306297
307Variant Setting::get_string_default(Json::Value const& v) const298Variant Setting::get_string_default(Variant const& v) const
308{299{
309 if (v.isNull()) // No "parameters" key300 assert(!v.is_null());
310 {301
311 return Variant();302 auto v_dflt = v.get_dict()[dflt_key];
312 }303 if (v_dflt.is_null())
313 auto v_dflt = v[dflt_key];
314 if (v_dflt.isNull())
315 {304 {
316 return Variant(); // No "defaultValue" key305 return Variant(); // No "defaultValue" key
317 }306 }
318 if (!v_dflt.isString())307 if (v_dflt.which() != Variant::Type::String)
319 {308 {
320 throw ResourceException(string("JsonSettingsSchema(): invalid value type for \"") + dflt_key.c_str()309 throw ResourceException(string("JsonSettingsSchema(): invalid value type for \"") + dflt_key
321 + "\" definition, id = \"" + id_ + "\"");310 + "\" definition, id = \"" + id_ + "\"");
322 }311 }
323 return Variant(v_dflt.asString());312 return v_dflt;
324}313}
325314
326void Setting::set_enumerators(Json::Value const& v)315void Setting::set_enumerators(Variant const& v)
327{316{
328 assert(v.isArray());317 assert(v.which() == Variant::Type::Array);
329318
330 set<string> enums_seen;319 set<string> enums_seen;
331320
332 for (unsigned i = 0; i < v.size(); ++i)321 VariantArray va = v.get_array();
322 for (unsigned i = 0; i < va.size(); ++i)
333 {323 {
334 Json::Value enumerator = v[i];324 Variant enumerator = v.get_array()[i];
335 if (!enumerator.isString())325 if (enumerator.which() != Variant::Type::String)
336 {326 {
337 throw ResourceException(string("JsonSettingsSchema(): invalid enumerator type, id = \"") + id_ + "\"");327 throw ResourceException(string("JsonSettingsSchema(): invalid enumerator type, id = \"") + id_ + "\"");
338 }328 }
339 string enum_str = enumerator.asString();329 string enum_str = enumerator.get_string();
340 if (enum_str.empty())330 if (enum_str.empty())
341 {331 {
342 throw ResourceException(string("JsonSettingsSchema(): invalid empty enumerator, id = \"") + id_ + "\"");332 throw ResourceException(string("JsonSettingsSchema(): invalid empty enumerator, id = \"") + id_ + "\"");
@@ -347,7 +337,7 @@
347 + "\", id = \"" + id_ + "\"");337 + "\", id = \"" + id_ + "\"");
348 }338 }
349 enums_seen.insert(enum_str);339 enums_seen.insert(enum_str);
350 enumerators_.emplace_back(Variant(enum_str));340 enumerators_.emplace_back(enumerator);
351 }341 }
352}342}
353343
@@ -367,39 +357,36 @@
367{357{
368 try358 try
369 {359 {
370 Json::Value root;360 JsonCppNode::SPtr root = make_shared<JsonCppNode>(json_string);
371 Json::Reader reader;361
372 if (!reader.parse(json_string, root))362 if (root->type() != JsonNodeInterface::Array)
373 {363 {
374 throw ResourceException("JsonSettingsSchema(): cannot parse schema: " + reader.getFormattedErrorMessages());364 if (root->type() != JsonNodeInterface::Object || !root->has_node("settings"))
375 }365 {
376366 throw ResourceException("JsonSettingsSchema(): missing \"settings\" definition");
377 if (!root.isArray())367 }
378 {368 root = root->get_node("settings");
379 root = root["settings"];369 if (root->type() != JsonNodeInterface::Array)
380 }370 {
381 if (root.isNull())371 throw ResourceException("JsonSettingsSchema(): value \"settings\" must be an array");
382 {372 }
383 throw ResourceException("JsonSettingsSchema(): missing \"settings\" definition");373 }
384 }374
385 if (!root.isArray())
386 {
387 throw ResourceException("JsonSettingsSchema(): value \"settings\" must be an array");
388 }
389 set<string> seen_settings;375 set<string> seen_settings;
390 for (unsigned i = 0; i < root.size(); ++i)376 for (int i = 0; i < root->size(); ++i)
391 {377 {
392 Setting s(root[i]);378 Setting s(root->get_node(i)->to_variant());
393 if (starts_with(s.id(), "internal."))379 if (starts_with(s.id(), "internal."))
394 {380 {
395 throw ResourceException(string("JsonSettingsSchema(): invalid key \"") + s.id() + "\" prefixed with \"internal.\"");381 throw ResourceException(string("JsonSettingsSchema(): invalid key \"") + s.id()
382 + "\" prefixed with \"internal.\"");
396 }383 }
397 if (seen_settings.find(s.id()) != seen_settings.end())384 if (seen_settings.find(s.id()) != seen_settings.end())
398 {385 {
399 throw ResourceException("JsonSettingsSchema(): duplicate definition, id = \"" + s.id() + "\"");386 throw ResourceException("JsonSettingsSchema(): duplicate definition, id = \"" + s.id() + "\"");
400 }387 }
388 seen_settings.insert(s.id());
401 definitions_.push_back(s.to_schema_definition());389 definitions_.push_back(s.to_schema_definition());
402 seen_settings.insert(s.id());
403 }390 }
404 }391 }
405 catch (ResourceException const&)392 catch (ResourceException const&)
406393
=== modified file 'src/scopes/internal/Logger.cpp'
--- src/scopes/internal/Logger.cpp 2016-02-22 05:00:23 +0000
+++ src/scopes/internal/Logger.cpp 2016-06-17 07:24:44 +0000
@@ -41,10 +41,10 @@
41static array<string, 5> const severities = {{"INFO", "WARNING", "ERROR", "FATAL", "TRACE"}};41static array<string, 5> const severities = {{"INFO", "WARNING", "ERROR", "FATAL", "TRACE"}};
4242
43static array<pair<string, LoggerChannel>, int(LoggerChannel::LastChannelEnum_)> const channel_names =43static array<pair<string, LoggerChannel>, int(LoggerChannel::LastChannelEnum_)> const channel_names =
44{44{ {
45 pair<string, LoggerChannel>{"", LoggerChannel::DefaultChannel},45 pair<string, LoggerChannel>{"", LoggerChannel::DefaultChannel},
46 pair<string, LoggerChannel>{"IPC", LoggerChannel::IPC}46 pair<string, LoggerChannel>{"IPC", LoggerChannel::IPC}
47};47} };
4848
49} // namespace49} // namespace
5050
5151
=== modified file 'src/scopes/internal/RuntimeImpl.cpp'
--- src/scopes/internal/RuntimeImpl.cpp 2016-02-22 14:16:26 +0000
+++ src/scopes/internal/RuntimeImpl.cpp 2016-06-17 07:24:44 +0000
@@ -366,7 +366,7 @@
366 string settings_schema = scope_dir.native() + "/" + scope_id_ + "-settings.ini";366 string settings_schema = scope_dir.native() + "/" + scope_id_ + "-settings.ini";
367367
368 boost::system::error_code ec;368 boost::system::error_code ec;
369 if (boost::filesystem::exists(settings_schema, ec))369 if (boost::filesystem::exists(settings_schema, ec) && boost::filesystem::file_size(settings_schema) > 0)
370 {370 {
371 shared_ptr<SettingsDB> db(SettingsDB::create_from_ini_file(settings_db, settings_schema));371 shared_ptr<SettingsDB> db(SettingsDB::create_from_ini_file(settings_db, settings_schema));
372 scope_base->p->set_settings_db(db);372 scope_base->p->set_settings_db(db);
373373
=== modified file 'src/scopes/internal/ScopeConfig.cpp'
--- src/scopes/internal/ScopeConfig.cpp 2015-07-17 09:03:33 +0000
+++ src/scopes/internal/ScopeConfig.cpp 2016-06-17 07:24:44 +0000
@@ -67,7 +67,6 @@
67 const string fg_color_key = "ForegroundColor";67 const string fg_color_key = "ForegroundColor";
68 const string bg_color_key = "BackgroundColor";68 const string bg_color_key = "BackgroundColor";
69 const string shape_images_key = "ShapeImages";69 const string shape_images_key = "ShapeImages";
70 const string category_header_bg_key = "CategoryHeaderBackground";
71 const string preview_button_color_key = "PreviewButtonColor";70 const string preview_button_color_key = "PreviewButtonColor";
72 const string logo_overlay_color_key = "LogoOverlayColor";71 const string logo_overlay_color_key = "LogoOverlayColor";
73 const string pageheader_logo_key = "PageHeader.Logo";72 const string pageheader_logo_key = "PageHeader.Logo";
@@ -317,7 +316,6 @@
317 fg_color_key,316 fg_color_key,
318 bg_color_key,317 bg_color_key,
319 shape_images_key,318 shape_images_key,
320 category_header_bg_key,
321 preview_button_color_key,319 preview_button_color_key,
322 logo_overlay_color_key,320 logo_overlay_color_key,
323 pageheader_logo_key,321 pageheader_logo_key,
324322
=== modified file 'src/scopes/internal/smartscopes/SmartScopesClient.cpp'
--- src/scopes/internal/smartscopes/SmartScopesClient.cpp 2016-02-25 11:40:06 +0000
+++ src/scopes/internal/smartscopes/SmartScopesClient.cpp 2016-06-17 07:24:44 +0000
@@ -592,6 +592,11 @@
592592
593void SmartScopesClient::handle_line(std::string const& json, PreviewReplyHandler const& handler)593void SmartScopesClient::handle_line(std::string const& json, PreviewReplyHandler const& handler)
594{594{
595 if (json.empty())
596 {
597 return;
598 }
599
595 JsonNodeInterface::SPtr root_node;600 JsonNodeInterface::SPtr root_node;
596 JsonNodeInterface::SPtr child_node;601 JsonNodeInterface::SPtr child_node;
597 {602 {
@@ -640,6 +645,11 @@
640645
641void SmartScopesClient::handle_line(std::string const& json, SearchReplyHandler& handler)646void SmartScopesClient::handle_line(std::string const& json, SearchReplyHandler& handler)
642{647{
648 if (json.empty())
649 {
650 return;
651 }
652
643 JsonNodeInterface::SPtr root_node;653 JsonNodeInterface::SPtr root_node;
644 JsonNodeInterface::SPtr child_node;654 JsonNodeInterface::SPtr child_node;
645655
646656
=== modified file 'src/scopes/internal/zmq_middleware/StopPublisher.cpp'
--- src/scopes/internal/zmq_middleware/StopPublisher.cpp 2014-11-18 07:04:04 +0000
+++ src/scopes/internal/zmq_middleware/StopPublisher.cpp 2016-06-17 07:24:44 +0000
@@ -121,7 +121,7 @@
121 s.set(zmqpp::socket_option::linger, 0);121 s.set(zmqpp::socket_option::linger, 0);
122 s.connect(endpoint_);122 s.connect(endpoint_);
123 s.subscribe("");123 s.subscribe("");
124 return move(s);124 return s;
125 }125 }
126 }126 }
127}127}
128128
=== modified file 'src/scopes/testing/ScopeMetadataBuilder.cpp'
--- src/scopes/testing/ScopeMetadataBuilder.cpp 2015-02-22 22:27:09 +0000
+++ src/scopes/testing/ScopeMetadataBuilder.cpp 2016-06-17 07:24:44 +0000
@@ -212,9 +212,7 @@
212 if (p->is_aggregator)212 if (p->is_aggregator)
213 impl->set_is_aggregator(*p->is_aggregator);213 impl->set_is_aggregator(*p->is_aggregator);
214214
215 return unity::scopes::internal::ScopeMetadataImpl::create(215 return unity::scopes::internal::ScopeMetadataImpl::create(std::unique_ptr<internal::ScopeMetadataImpl>{impl});
216 std::move(
217 std::unique_ptr<internal::ScopeMetadataImpl>{impl}));
218}216}
219217
220/// @endcond218/// @endcond
221219
=== modified file 'test/copyright/check_copyright.sh'
--- test/copyright/check_copyright.sh 2015-11-13 06:33:11 +0000
+++ test/copyright/check_copyright.sh 2016-06-17 07:24:44 +0000
@@ -31,13 +31,7 @@
31[ $# -lt 1 ] && usage31[ $# -lt 1 ] && usage
32[ $# -gt 2 ] && usage32[ $# -gt 2 ] && usage
3333
34# TODO: Temporary hack to work around broken licensecheck on xenial. Remove this once that is fixed.34ignore_pat="\\.sci$|.bzr|debian|tsan-suppress|valgrind-suppress|RELEASE_NOTES.md|partnerid|suppressions|README|_clang-format|TODO|CONFIGFILES|astyle-config|no_.*_cache|\\.txt$|\\.in$|\\.ini$|\\.xml$|\\.json$|\\.swp$|\\.gz$|\\.service$|\\.map$|\\.dox$|\\.html$|ParseArguments\\.cmake"
35distro=$(lsb_release -c -s)
36[ "$distro" = "xenial" ] && {
37 exit 0
38}
39
40ignore_pat="\\.sci$"
4135
42#36#
43# We don't use the -i option of licensecheck to add ignore_dir to the pattern because Jenkins creates directories37# We don't use the -i option of licensecheck to add ignore_dir to the pattern because Jenkins creates directories
4438
=== modified file 'test/gtest/scopes/Registry/Registry_test.cpp'
--- test/gtest/scopes/Registry/Registry_test.cpp 2015-07-06 13:47:54 +0000
+++ test/gtest/scopes/Registry/Registry_test.cpp 2016-06-17 07:24:44 +0000
@@ -122,7 +122,6 @@
122 EXPECT_EQ("fg_color", attrs["foreground-color"].get_string());122 EXPECT_EQ("fg_color", attrs["foreground-color"].get_string());
123 EXPECT_EQ("bg_color", attrs["background-color"].get_string());123 EXPECT_EQ("bg_color", attrs["background-color"].get_string());
124 EXPECT_TRUE(attrs["shape-images"].get_bool());124 EXPECT_TRUE(attrs["shape-images"].get_bool());
125 EXPECT_EQ(TEST_SCOPE_A_PATH "/cat_header_bg_scheme", attrs["category-header-background"].get_string());
126 EXPECT_EQ("preview_button_color", attrs["preview-button-color"].get_string());125 EXPECT_EQ("preview_button_color", attrs["preview-button-color"].get_string());
127 EXPECT_EQ("overlay_color", attrs["logo-overlay-color"].get_string());126 EXPECT_EQ("overlay_color", attrs["logo-overlay-color"].get_string());
128 auto page_hdr = attrs["page-header"].get_dict();127 auto page_hdr = attrs["page-header"].get_dict();
129128
=== modified file 'test/gtest/scopes/Registry/scopes/testscopeA/testscopeA.ini.in'
--- test/gtest/scopes/Registry/scopes/testscopeA/testscopeA.ini.in 2014-12-03 09:25:10 +0000
+++ test/gtest/scopes/Registry/scopes/testscopeA/testscopeA.ini.in 2016-06-17 07:24:44 +0000
@@ -16,7 +16,6 @@
16ForegroundColor = fg_color16ForegroundColor = fg_color
17BackgroundColor = bg_color17BackgroundColor = bg_color
18ShapeImages = true18ShapeImages = true
19CategoryHeaderBackground = cat_header_bg_scheme
20PreviewButtonColor = preview_button_color19PreviewButtonColor = preview_button_color
21LogoOverlayColor = overlay_color20LogoOverlayColor = overlay_color
22PageHeader.Logo = some_url21PageHeader.Logo = some_url
2322
=== modified file 'test/gtest/scopes/internal/CMakeLists.txt'
--- test/gtest/scopes/internal/CMakeLists.txt 2016-02-22 00:19:46 +0000
+++ test/gtest/scopes/internal/CMakeLists.txt 2016-06-17 07:24:44 +0000
@@ -1,6 +1,7 @@
1add_subdirectory(CategoryRegistry)1add_subdirectory(CategoryRegistry)
2add_subdirectory(ConfigBase)2add_subdirectory(ConfigBase)
3add_subdirectory(DynamicLoader)3add_subdirectory(DynamicLoader)
4add_subdirectory(gobj_ptr)
4add_subdirectory(IniSettingsSchema)5add_subdirectory(IniSettingsSchema)
5add_subdirectory(JsonNode)6add_subdirectory(JsonNode)
6add_subdirectory(JsonSettingsSchema)7add_subdirectory(JsonSettingsSchema)
78
=== modified file 'test/gtest/scopes/internal/JsonNode/JsonNode_test.cpp'
--- test/gtest/scopes/internal/JsonNode/JsonNode_test.cpp 2015-11-02 03:42:05 +0000
+++ test/gtest/scopes/internal/JsonNode/JsonNode_test.cpp 2016-06-17 07:24:44 +0000
@@ -43,6 +43,35 @@
43 JsonNodeInterface::SPtr root_node_;43 JsonNodeInterface::SPtr root_node_;
44};44};
4545
46TEST_F(JsonNodeTest, basic)
47{
48 try
49 {
50 JsonCppNode node("");
51 FAIL();
52 }
53 catch (unity::ResourceException const&)
54 {
55 }
56
57 EXPECT_EQ(0, root_node_->size());
58 EXPECT_EQ(JsonNodeInterface::Null, root_node_->type());
59
60 auto json = root_node_->to_json_string();
61 EXPECT_EQ("null\n", json);
62
63 root_node_->read_json("42");
64 EXPECT_EQ(JsonNodeInterface::Int, root_node_->type());
65 auto n = root_node_->get_node();
66 EXPECT_EQ(42, n->as_int());
67
68 EXPECT_THROW(root_node_->read_json(""), unity::ResourceException);
69 EXPECT_THROW(root_node_->read_json(" "), unity::ResourceException);
70
71 root_node_->clear();
72 EXPECT_EQ(JsonNodeInterface::Null, root_node_->type());
73}
74
46TEST_F(JsonNodeTest, flat_values)75TEST_F(JsonNodeTest, flat_values)
47{76{
48 std::string json_string = R"({77 std::string json_string = R"({
@@ -170,23 +199,45 @@
170199
171TEST_F(JsonNodeTest, from_variant)200TEST_F(JsonNodeTest, from_variant)
172{201{
173 VariantArray va({Variant(1), Variant(2), Variant(true)});202 {
174 VariantMap vm;203 VariantArray va({Variant(1), Variant(2), Variant(true)});
175 vm["foo"] = "bar";204 VariantMap vm;
176 vm["baz"] = 1;205 vm["foo"] = "bar";
177 vm["boo"] = 2.0f;206 vm["baz"] = 1;
178 vm["zee"] = true;207 vm["boo"] = 2.0f;
179 vm["wee"] = Variant(va);208 vm["zee"] = true;
180209 vm["wee"] = Variant(va);
181 Variant var(vm);210
182 JsonCppNode node(var);211 Variant var(vm);
183 EXPECT_EQ("bar", node.get_node("foo")->as_string());212 JsonCppNode node(var);
184 EXPECT_EQ(1, node.get_node("baz")->as_int());213 EXPECT_EQ(JsonNodeInterface::Object, node.type());
185 EXPECT_TRUE(node.get_node("boo")->as_double() - 2.0f < 0.00001f);214 EXPECT_EQ("bar", node.get_node("foo")->as_string());
186 EXPECT_TRUE(node.get_node("zee")->as_bool());215 EXPECT_EQ(JsonNodeInterface::String, node.get_node("foo")->type());
187 EXPECT_EQ(1, node.get_node("wee")->get_node(0)->as_int());216 EXPECT_EQ(1, node.get_node("baz")->as_int());
188 EXPECT_EQ(2, node.get_node("wee")->get_node(1)->as_int());217 EXPECT_EQ(JsonNodeInterface::Real, node.get_node("boo")->type());
189 EXPECT_TRUE(node.get_node("wee")->get_node(2)->as_bool());218 EXPECT_TRUE(node.get_node("boo")->as_double() - 2.0f < 0.00001f);
219 EXPECT_EQ(JsonNodeInterface::Bool, node.get_node("zee")->type());
220 EXPECT_TRUE(node.get_node("zee")->as_bool());
221 EXPECT_EQ(JsonNodeInterface::Array, node.get_node("wee")->type());
222 EXPECT_EQ(1, node.get_node("wee")->get_node(0)->as_int());
223 EXPECT_EQ(2, node.get_node("wee")->get_node(1)->as_int());
224 EXPECT_TRUE(node.get_node("wee")->get_node(2)->as_bool());
225 }
226
227 {
228 Variant var(1);
229 JsonCppNode node(var);
230 EXPECT_EQ(1, node.to_variant().get_int());
231 }
232
233 {
234 Variant var(2147483648); // > 2^31 - 1
235 JsonCppNode node(var);
236 EXPECT_EQ(2147483648, node.to_variant().get_int64_t());
237 }
238
239 JsonCppNode null_node((Variant()));
240 EXPECT_EQ(JsonNodeInterface::Null, null_node.type());
190}241}
191242
192TEST_F(JsonNodeTest, to_variant)243TEST_F(JsonNodeTest, to_variant)
@@ -206,4 +257,89 @@
206 EXPECT_EQ("foo", arr[2].get_string());257 EXPECT_EQ("foo", arr[2].get_string());
207}258}
208259
260TEST_F(JsonNodeTest, exceptions)
261{
262 EXPECT_THROW(JsonCppNode("syntax error"), unity::ResourceException);
263
264 try
265 {
266 JsonCppNode().member_names();
267 FAIL();
268 }
269 catch (unity::LogicException const& e)
270 {
271 EXPECT_STREQ("unity::LogicException: Root node is not an object", e.what());
272 }
273
274 try
275 {
276 JsonCppNode().has_node("x");
277 FAIL();
278 }
279 catch (unity::LogicException const& e)
280 {
281 EXPECT_STREQ("unity::LogicException: Current node is empty", e.what());
282 }
283
284 try
285 {
286 JsonCppNode("42").as_string();
287 FAIL();
288 }
289 catch (unity::LogicException const& e)
290 {
291 EXPECT_STREQ("unity::LogicException: Node does not contain a string value", e.what());
292 }
293
294 try
295 {
296 JsonCppNode("true").as_double();
297 FAIL();
298 }
299 catch (unity::LogicException const& e)
300 {
301 EXPECT_STREQ("unity::LogicException: Node does not contain a double value", e.what());
302 }
303
304 try
305 {
306 JsonCppNode("true").as_int();
307 FAIL();
308 }
309 catch (unity::LogicException const& e)
310 {
311 EXPECT_STREQ("unity::LogicException: Node does not contain an int value", e.what());
312 }
313
314 try
315 {
316 JsonCppNode("3.14").as_bool();
317 FAIL();
318 }
319 catch (unity::LogicException const& e)
320 {
321 EXPECT_STREQ("unity::LogicException: Node does not contain a bool value", e.what());
322 }
323
324 try
325 {
326 JsonCppNode().get_node(25);
327 FAIL();
328 }
329 catch (unity::LogicException const& e)
330 {
331 EXPECT_STREQ("unity::LogicException: Current node is empty", e.what());
332 }
333
334 try
335 {
336 JsonCppNode().get_node();
337 FAIL();
338 }
339 catch (unity::LogicException const& e)
340 {
341 EXPECT_STREQ("unity::LogicException: Current node is empty", e.what());
342 }
343}
344
209} // namespace345} // namespace
210346
=== modified file 'test/gtest/scopes/internal/JsonSettingsSchema/JsonSettingsSchema_test.cpp'
--- test/gtest/scopes/internal/JsonSettingsSchema/JsonSettingsSchema_test.cpp 2015-01-13 11:44:33 +0000
+++ test/gtest/scopes/internal/JsonSettingsSchema/JsonSettingsSchema_test.cpp 2016-06-17 07:24:44 +0000
@@ -22,7 +22,6 @@
22#include <unity/util/FileIO.h>22#include <unity/util/FileIO.h>
2323
24#include <gtest/gtest.h>24#include <gtest/gtest.h>
25#include <jsoncpp/json/json.h>
2625
27using namespace unity;26using namespace unity;
28using namespace unity::scopes;27using namespace unity::scopes;
@@ -153,6 +152,41 @@
153 EXPECT_EQ(Variant(), defs[10].get_dict()["defaultValue"]);152 EXPECT_EQ(Variant(), defs[10].get_dict()["defaultValue"]);
154}153}
155154
155TEST(JsonSettingsSchema, integer_sizes)
156{
157 char const* schema = R"delimiter(
158 {
159 "settings":
160 [
161 {
162 "id": "double_temp",
163 "displayName": "floating-point default",
164 "type": "number",
165 "parameters": {
166 "defaultValue": 3.14
167 }
168 },
169 {
170 "id": "too_old",
171 "displayName": "won't fit into 32 bits",
172 "type": "number",
173 "parameters": {
174 "defaultValue": 2147483648
175 }
176 }
177 ]
178 }
179 )delimiter";
180
181 auto s = JsonSettingsSchema::create(schema);
182
183 auto defs = s->definitions();
184 EXPECT_EQ(2, defs.size());
185
186 EXPECT_EQ(3.14, defs[0].get_dict()["defaultValue"].get_double());
187 EXPECT_EQ(2147483648, defs[1].get_dict()["defaultValue"].get_double());
188}
189
156TEST(JsonSettingsSchema, exceptions)190TEST(JsonSettingsSchema, exceptions)
157{191{
158 try192 try
@@ -162,9 +196,7 @@
162 }196 }
163 catch (ResourceException const& e)197 catch (ResourceException const& e)
164 {198 {
165 EXPECT_STREQ("unity::ResourceException: JsonSettingsSchema(): cannot parse schema: * Line 1, Column 1\n"199 EXPECT_STREQ("unity::ResourceException: JsonCppNode(): empty string is not a valid JSON", e.what());
166 " Syntax error: value, object or array expected.\n",
167 e.what());
168 }200 }
169201
170 try202 try
@@ -335,7 +367,7 @@
335 }367 }
336 catch (ResourceException const& e)368 catch (ResourceException const& e)
337 {369 {
338 EXPECT_STREQ("unity::ResourceException: JsonSettingsSchema(): invalid \"type\" setting: "370 EXPECT_STREQ("unity::ResourceException: JsonSettingsSchema(): invalid \"type\" definition: "
339 "\"no_such_type\", id = \"x\"",371 "\"no_such_type\", id = \"x\"",
340 e.what());372 e.what());
341 }373 }
342374
=== modified file 'test/gtest/scopes/internal/SettingsDB/SettingsDB_test.cpp'
--- test/gtest/scopes/internal/SettingsDB/SettingsDB_test.cpp 2015-11-26 05:48:01 +0000
+++ test/gtest/scopes/internal/SettingsDB/SettingsDB_test.cpp 2016-06-17 07:24:44 +0000
@@ -22,6 +22,7 @@
2222
23#include <unity/UnityExceptions.h>23#include <unity/UnityExceptions.h>
2424
25#include <boost/algorithm/string.hpp>
25#include <boost/regex.hpp> // Use Boost implementation until http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53631 is fixed.26#include <boost/regex.hpp> // Use Boost implementation until http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53631 is fixed.
26#include <gtest/gtest.h>27#include <gtest/gtest.h>
27#include <fcntl.h>28#include <fcntl.h>
@@ -321,10 +322,9 @@
321 }322 }
322 catch (ResourceException const& e)323 catch (ResourceException const& e)
323 {324 {
324 EXPECT_STREQ("unity::ResourceException: SettingsDB::create_from_json_string(): cannot parse schema, db = unused:\n"325 EXPECT_TRUE(boost::starts_with(e.what(),
325 " unity::ResourceException: JsonSettingsSchema(): cannot parse schema: * Line 1, Column 1\n"326 "unity::ResourceException: SettingsDB::create_from_json_string(): cannot parse "
326 " Syntax error: value, object or array expected.\n",327 "schema, db = unused:")) << e.what();
327 e.what());
328 }328 }
329329
330 try330 try
331331
=== added directory 'test/gtest/scopes/internal/gobj_ptr'
=== added file 'test/gtest/scopes/internal/gobj_ptr/CMakeLists.txt'
--- test/gtest/scopes/internal/gobj_ptr/CMakeLists.txt 1970-01-01 00:00:00 +0000
+++ test/gtest/scopes/internal/gobj_ptr/CMakeLists.txt 2016-06-17 07:24:44 +0000
@@ -0,0 +1,3 @@
1add_executable(gobj_ptr_test gobj_ptr_test.cpp)
2target_link_libraries(gobj_ptr_test ${TESTLIBS})
3add_test(gobj_ptr gobj_ptr_test)
04
=== added file 'test/gtest/scopes/internal/gobj_ptr/gobj_ptr_test.cpp'
--- test/gtest/scopes/internal/gobj_ptr/gobj_ptr_test.cpp 1970-01-01 00:00:00 +0000
+++ test/gtest/scopes/internal/gobj_ptr/gobj_ptr_test.cpp 2016-06-17 07:24:44 +0000
@@ -0,0 +1,208 @@
1/*
2 * Copyright (C) 2013 Canonical Ltd.
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 3 as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authored by: Jussi Pakkanen <jussi.pakkanen@canonical.com>
17 */
18
19#pragma GCC diagnostic push
20#pragma GCC diagnostic ignored "-Wold-style-cast"
21#pragma GCC diagnostic ignored "-Wcast-qual"
22
23#include <unity/scopes/internal/gobj_memory.h>
24#include <glib-object.h>
25#include <gtest/gtest.h>
26
27using namespace std;
28using namespace unity::scopes::internal;
29
30TEST(Gobj_ptr, trivial)
31{
32 gobj_ptr<GObject> basic(G_OBJECT(g_object_new(G_TYPE_OBJECT, nullptr)));
33 EXPECT_TRUE(bool(basic));
34 EXPECT_TRUE(G_IS_OBJECT(basic.get()));
35}
36
37TEST(Gobj_ptr, compare)
38{
39 GObject* o1 = G_OBJECT(g_object_new(G_TYPE_OBJECT, nullptr));
40 GObject* o2 = G_OBJECT(g_object_new(G_TYPE_OBJECT, nullptr));
41 if (o1 > o2)
42 {
43 std::swap(o1, o2);
44 }
45 ASSERT_TRUE(o1 < o2);
46 gobj_ptr<GObject> u1(o1);
47 gobj_ptr<GObject> u2(o2);
48
49 EXPECT_TRUE(!(u1 == nullptr));
50 EXPECT_TRUE(u1 != nullptr);
51 EXPECT_TRUE(u1 != u2);
52 EXPECT_TRUE(!(u1 == u2));
53 EXPECT_TRUE(u1 < u2);
54 EXPECT_TRUE(!(u2 < u1));
55 EXPECT_TRUE(!(u1 == u2));
56 EXPECT_TRUE(!(u2 == u1));
57 EXPECT_TRUE(u1 <= u2);
58 EXPECT_TRUE(!(u2 <= u1));
59}
60
61// This is its own thing due to need to avoid double release.
62
63TEST(Gobj_ptr, equality)
64{
65 GObject* o = G_OBJECT(g_object_new(G_TYPE_OBJECT, nullptr));
66 gobj_ptr<GObject> u1(o);
67 g_object_ref(o);
68 gobj_ptr<GObject> u2(o);
69 EXPECT_TRUE(u1 == u2);
70 EXPECT_TRUE(u2 == u1);
71 EXPECT_TRUE(!(u1 != u2));
72 EXPECT_TRUE(!(u2 != u1));
73}
74
75TEST(Gobj_ptr, release)
76{
77 GObject* o = G_OBJECT(g_object_new(G_TYPE_OBJECT, nullptr));
78 gobj_ptr<GObject> u(o);
79 EXPECT_TRUE(u != nullptr);
80 EXPECT_TRUE(u.get() != nullptr);
81 EXPECT_TRUE(o == u.release());
82 EXPECT_TRUE(!u);
83 EXPECT_TRUE(u.get() == nullptr);
84 g_object_unref(o);
85}
86
87TEST(Gobj_ptr, refcount)
88{
89 GObject* o = G_OBJECT(g_object_new(G_TYPE_OBJECT, nullptr));
90 EXPECT_EQ(1, o->ref_count);
91 g_object_ref(o);
92
93 {
94 EXPECT_EQ(2, o->ref_count);
95 gobj_ptr<GObject> u(o);
96 EXPECT_EQ(2, o->ref_count);
97 // Now it dies and refcount is reduced.
98 }
99
100 EXPECT_EQ(1, o->ref_count);
101 g_object_unref(o);
102}
103
104TEST(Gobj_ptr, copy)
105{
106 GObject* o = G_OBJECT(g_object_new(G_TYPE_OBJECT, nullptr));
107 gobj_ptr<GObject> u(o);
108 EXPECT_EQ(1, u->ref_count);
109 gobj_ptr<GObject> u2(u);
110 EXPECT_EQ(2, u->ref_count);
111 gobj_ptr<GObject> u3 = u2;
112 EXPECT_EQ(3, u->ref_count);
113 u3.reset();
114 u2.reset();
115 EXPECT_EQ(1, u->ref_count);
116}
117
118TEST(Gobj_ptr, swap)
119{
120 GObject* o1 = G_OBJECT(g_object_new(G_TYPE_OBJECT, nullptr));
121 GObject* o2 = G_OBJECT(g_object_new(G_TYPE_OBJECT, nullptr));
122 gobj_ptr<GObject> u1(o1);
123 gobj_ptr<GObject> u2(o2);
124
125 u1.swap(u2);
126 EXPECT_EQ(o2, u1.get());
127 EXPECT_EQ(o1, u2.get());
128
129 std::swap(u1, u2);
130 EXPECT_EQ(o1, u1.get());
131 EXPECT_EQ(o2, u2.get());
132}
133
134TEST(Gobj_ptr, floating)
135{
136 GObject* o = G_OBJECT(g_object_new(G_TYPE_INITIALLY_UNOWNED, nullptr));
137 try
138 {
139 gobj_ptr<GObject> u(o);
140 FAIL();
141 }
142 catch (const invalid_argument& c)
143 {
144 EXPECT_EQ("Tried to add a floating gobject into a gobj_ptr.", string(c.what()));
145 }
146 // Object accepted after sinking.
147 g_object_ref_sink(o);
148 gobj_ptr<GObject> u(o);
149}
150
151TEST(Gobj_ptr, move)
152{
153 GObject* o1 = G_OBJECT(g_object_new(G_TYPE_OBJECT, nullptr));
154 GObject* o2 = G_OBJECT(g_object_new(G_TYPE_OBJECT, nullptr));
155 g_object_ref(o1);
156 gobj_ptr<GObject> u1(o1);
157 gobj_ptr<GObject> u2(o2);
158 u1 = std::move(u2);
159 EXPECT_TRUE(u1.get() == o2);
160 EXPECT_TRUE(!u2);
161 EXPECT_TRUE(o1->ref_count == 1);
162 g_object_unref(o1);
163}
164
165TEST(Gobj_ptr, null)
166{
167 GObject* o1 = NULL;
168 GObject* o3 = G_OBJECT(g_object_new(G_TYPE_OBJECT, nullptr));
169 gobj_ptr<GObject> u1(o1);
170 gobj_ptr<GObject> u2(nullptr);
171 gobj_ptr<GObject> u3(o3);
172
173 EXPECT_TRUE(!u1);
174 EXPECT_TRUE(!u2);
175 u3 = nullptr;
176 EXPECT_TRUE(!u3);
177}
178
179TEST(Gobj_ptr, reset)
180{
181 GObject* o1 = G_OBJECT(g_object_new(G_TYPE_OBJECT, nullptr));
182 GObject* o2 = G_OBJECT(g_object_new(G_TYPE_OBJECT, nullptr));
183 gobj_ptr<GObject> u(o1);
184
185 u.reset(o2);
186 EXPECT_EQ(o2, u.get());
187 u.reset(nullptr);
188 EXPECT_TRUE(!u);
189}
190
191TEST(Gobj_ptr, sizeoftest)
192{
193 EXPECT_EQ(sizeof(GObject*), sizeof(gobj_ptr<GObject>));
194}
195
196TEST(Gobj_ptr, deleter)
197{
198 gobj_ptr<GObject> u1;
199 EXPECT_TRUE(g_object_unref == u1.get_deleter());
200}
201
202int main(int argc, char** argv)
203{
204 ::testing::InitGoogleTest(&argc, argv);
205 return RUN_ALL_TESTS();
206}
207
208#pragma GCC diagnostic pop
0209
=== modified file 'test/gtest/scopes/internal/smartscopes/SmartScopesClient/SmartScopesClient_test.cpp'
--- test/gtest/scopes/internal/smartscopes/SmartScopesClient/SmartScopesClient_test.cpp 2016-02-29 15:57:12 +0000
+++ test/gtest/scopes/internal/smartscopes/SmartScopesClient/SmartScopesClient_test.cpp 2016-06-17 07:24:44 +0000
@@ -130,13 +130,41 @@
130 EXPECT_EQ(nullptr, scopes[2].art);130 EXPECT_EQ(nullptr, scopes[2].art);
131 EXPECT_FALSE(scopes[2].invisible);131 EXPECT_FALSE(scopes[2].invisible);
132 EXPECT_EQ(nullptr, scopes[2].appearance);132 EXPECT_EQ(nullptr, scopes[2].appearance);
133 EXPECT_EQ("[{\"displayName\":\"Location\",\"id\":\"location\",\"parameters\":{\"defaultValue\":"133 {
134 "\"London\"},\"type\":\"string\"},{\"displayName\":\"Temperature Units\",\"id\":"134 JsonCppNode node(*scopes[2].settings);
135 "\"unitTemp\",\"parameters\":{\"defaultValue\":1,\"values\":[\"Celsius\",\"Fahrenheit"135 Variant v = node.to_variant();
136 "\"]},\"type\":\"list\"},{\"displayName\":\"Age\",\"id\":\"age\",\"parameters\":{"136
137 "\"defaultValue\":23},\"type\":\"number\"},{\"displayName\":\"Enabled\",\"id\":"137 VariantMap vm = v.get_array()[0].get_dict();
138 "\"enabled\",\"parameters\":{\"defaultValue\":true},\"type\":\"boolean\"}]\n",138 EXPECT_EQ("Location", vm["displayName"].get_string());
139 *scopes[2].settings);139 EXPECT_EQ("location", vm["id"].get_string());
140 EXPECT_EQ("string", vm["type"].get_string());
141 VariantMap params = vm["parameters"].get_dict();
142 EXPECT_EQ("London", params["defaultValue"].get_string());
143
144 vm = v.get_array()[1].get_dict();
145 EXPECT_EQ("Temperature Units", vm["displayName"].get_string());
146 EXPECT_EQ("unitTemp", vm["id"].get_string());
147 EXPECT_EQ("list", vm["type"].get_string());
148 params = vm["parameters"].get_dict();
149 EXPECT_EQ(1, params["defaultValue"].get_int());
150 VariantArray choices = params["values"].get_array();
151 EXPECT_EQ("Celsius", choices[0].get_string());
152 EXPECT_EQ("Fahrenheit", choices[1].get_string());
153
154 vm = v.get_array()[2].get_dict();
155 EXPECT_EQ("Age", vm["displayName"].get_string());
156 EXPECT_EQ("age", vm["id"].get_string());
157 EXPECT_EQ("number", vm["type"].get_string());
158 params = vm["parameters"].get_dict();
159 EXPECT_EQ(23, params["defaultValue"].get_int());
160
161 vm = v.get_array()[3].get_dict();
162 EXPECT_EQ("Enabled", vm["displayName"].get_string());
163 EXPECT_EQ("enabled", vm["id"].get_string());
164 EXPECT_EQ("boolean", vm["type"].get_string());
165 params = vm["parameters"].get_dict();
166 EXPECT_TRUE(params["defaultValue"].get_bool());
167 }
140 ASSERT_EQ(4, scopes[2].keywords.size());168 ASSERT_EQ(4, scopes[2].keywords.size());
141 EXPECT_NE(scopes[2].keywords.end(), scopes[2].keywords.find("music"));169 EXPECT_NE(scopes[2].keywords.end(), scopes[2].keywords.find("music"));
142 EXPECT_NE(scopes[2].keywords.end(), scopes[2].keywords.find("video"));170 EXPECT_NE(scopes[2].keywords.end(), scopes[2].keywords.find("video"));
@@ -392,10 +420,30 @@
392 EXPECT_EQ("widget_id_C", columns[2][2][0]);420 EXPECT_EQ("widget_id_C", columns[2][2][0]);
393421
394 ASSERT_EQ(3u, widgets.size());422 ASSERT_EQ(3u, widgets.size());
395423 {
396 EXPECT_EQ("{\"id\":\"widget_id_A\",\"text\":\"First widget.\",\"title\":\"Widget A\",\"type\":\"text\"}\n", widgets[0]);424 auto json = widgets[0];
397 EXPECT_EQ("{\"id\":\"widget_id_B\",\"text\":\"Second widget.\",\"title\":\"Widget B\",\"type\":\"text\"}\n", widgets[1]);425 JsonCppNode node(json);
398 EXPECT_EQ("{\"id\":\"widget_id_C\",\"text\":\"Third widget.\",\"title\":\"Widget C\",\"type\":\"text\"}\n", widgets[2]);426 EXPECT_EQ("widget_id_A", node.get_node("id")->as_string());
427 EXPECT_EQ("First widget.", node.get_node("text")->as_string());
428 EXPECT_EQ("Widget A", node.get_node("title")->as_string());
429 EXPECT_EQ("text", node.get_node("type")->as_string());
430 }
431 {
432 auto json = widgets[1];
433 JsonCppNode node(json);
434 EXPECT_EQ("widget_id_B", node.get_node("id")->as_string());
435 EXPECT_EQ("Second widget.", node.get_node("text")->as_string());
436 EXPECT_EQ("Widget B", node.get_node("title")->as_string());
437 EXPECT_EQ("text", node.get_node("type")->as_string());
438 }
439 {
440 auto json = widgets[2];
441 JsonCppNode node(json);
442 EXPECT_EQ("widget_id_C", node.get_node("id")->as_string());
443 EXPECT_EQ("Third widget.", node.get_node("text")->as_string());
444 EXPECT_EQ("Widget C", node.get_node("title")->as_string());
445 EXPECT_EQ("text", node.get_node("type")->as_string());
446 }
399}447}
400448
401TEST_F(SmartScopesClientTest, consecutive_searches)449TEST_F(SmartScopesClientTest, consecutive_searches)

Subscribers

People subscribed via source and target branches

to all changes: