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

Proposed by Paweł Stołowski
Status: Merged
Approved by: Michi Henning
Approved revision: 298
Merged at revision: 346
Proposed branch: lp:unity-scopes-api/staging
Merge into: lp:unity-scopes-api
Diff against target: 1021 lines (+569/-24)
28 files modified
CMakeLists.txt (+1/-1)
RELEASE_NOTES.md (+7/-3)
STRUCTS (+3/-2)
debian/changelog (+6/-0)
debian/rules (+5/-0)
demo/stand-alone/stand-alone-client.cpp (+9/-2)
include/unity/scopes/ActivationResponse.h (+19/-0)
include/unity/scopes/Result.h (+6/-0)
include/unity/scopes/internal/ActivationResponseImpl.h (+4/-0)
include/unity/scopes/internal/ResultImpl.h (+2/-0)
src/scopes/ActivationResponse.cpp (+10/-0)
src/scopes/PreviewWidget.cpp (+47/-0)
src/scopes/Result.cpp (+5/-0)
src/scopes/internal/ActivationResponseImpl.cpp (+48/-0)
src/scopes/internal/RegistryConfig.cpp (+0/-4)
src/scopes/internal/ResultImpl.cpp (+20/-0)
src/scopes/internal/zmq_middleware/ZmqObject.cpp (+1/-1)
test/gtest/scopes/ActivationResponse/ActivationResponse_test.cpp (+51/-1)
test/gtest/scopes/CMakeLists.txt (+1/-0)
test/gtest/scopes/CategorisedResult/CategorisedResult_test.cpp (+32/-0)
test/gtest/scopes/StandAloneScope/CMakeLists.txt (+15/-0)
test/gtest/scopes/StandAloneScope/Runtime.ini.in (+2/-0)
test/gtest/scopes/StandAloneScope/SimpleScope.cpp (+99/-0)
test/gtest/scopes/StandAloneScope/SimpleScope.h (+37/-0)
test/gtest/scopes/StandAloneScope/SimpleScope.ini.in (+4/-0)
test/gtest/scopes/StandAloneScope/StandAloneScope_test.cpp (+132/-0)
test/gtest/scopes/StandAloneScope/Zmq.ini.in (+2/-0)
test/gtest/scopes/internal/RegistryConfig/RegistryConfig_test.cpp (+1/-10)
To merge this branch: bzr merge lp:unity-scopes-api/staging
Reviewer Review Type Date Requested Status
Michi Henning (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+268915@code.launchpad.net

Commit message

Support for preview widget updates. Disable tests on ppc and ppc64el.

Description of the change

Merge devel changes.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michi Henning (michihenning) wrote :

Looks good, thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2015-08-17 14:07:35 +0000
3+++ CMakeLists.txt 2015-08-24 13:38:51 +0000
4@@ -218,7 +218,7 @@
5 # API version
6 set(UNITY_SCOPES_MAJOR 1) # Major official release number
7 set(UNITY_SCOPES_MINOR 0) # Must be changed for ABI incompatible changes
8-set(UNITY_SCOPES_MICRO 0) # For ABI compatible changes
9+set(UNITY_SCOPES_MICRO 1) # For ABI compatible changes
10 set(UNITY_SCOPES_SOVERSION ${UNITY_SCOPES_MAJOR}.${UNITY_SCOPES_MINOR})
11
12 # Version for testing, with all symbols visible
13
14=== modified file 'RELEASE_NOTES.md'
15--- RELEASE_NOTES.md 2015-07-01 10:59:49 +0000
16+++ RELEASE_NOTES.md 2015-08-24 13:38:51 +0000
17@@ -1,6 +1,10 @@
18 Release notes
19 =============
20
21+Changes in version 0.6.20
22+=========================
23+ - Support preview widget updates via ActivationResponse.
24+
25 Changes in version 0.6.19
26 =========================
27 - Support UNITY_SCOPES_CONFIG_DIR environment variable.
28@@ -39,7 +43,7 @@
29 swiping to the scope while the device has no network access, or the scope's
30 data source is off-line.
31
32- Note: This is change is ABI compatible with gcc and clang despite the addition
33+ Note: This is change is ABI compatible with gcc and clang despite the addition
34 a new virtual function.
35
36 Changes in version 0.6.13
37@@ -116,7 +120,7 @@
38 - New setting to enable/disable of location data being fed to scopes.
39
40 - New DebugMode scope configuration option.
41-
42+
43 Changes in version 0.6.1
44 ========================
45 - Clear any signal masks inherited from the parent process when forking.
46@@ -304,7 +308,7 @@
47
48 - Preliminary API for filters has been added via OptionSelectorFilter and
49 FilterState classes. This part of the API is not yet supported by Unity shell
50- and should be considered highly experimental.
51+ and should be considered highly experimental.
52
53 - ScopeBase::create_query() method now takes Query object instance instead of
54 just a search query string. Search query string is now encapsulated in the
55
56=== modified file 'STRUCTS'
57--- STRUCTS 2015-05-29 10:17:42 +0000
58+++ STRUCTS 2015-08-24 13:38:51 +0000
59@@ -88,12 +88,12 @@
60 'query_string' : string
61 'department_id' : string
62 'filter_state' : dictionary (serialized FilterState)
63-
64+
65 Link (returned by serialize())
66 ==============================
67 'label' : string
68 'query' : Query
69-
70+
71 Annotation (returned by serialize())
72 ====================================
73 'type' : string
74@@ -160,6 +160,7 @@
75 'scope_data' : variant
76 'query' : variant (optional)
77 'updated_result' : variant (optional)
78+ 'updated_widgets': variant (optional)
79
80 QueryMetadata (returned by serialize())
81 =======================================
82
83=== modified file 'debian/changelog'
84--- debian/changelog 2015-08-21 22:11:51 +0000
85+++ debian/changelog 2015-08-24 13:38:51 +0000
86@@ -1,3 +1,9 @@
87+unity-scopes-api (1.0.1-0ubuntu1) UNRELEASED; urgency=medium
88+
89+ * Added support for preview widget updates via ActivationResponse.
90+
91+ -- Pawel Stolowski <pawel.stolowski@canonical.com> Tue, 20 Jul 2015 17:15:39 +0200
92+
93 unity-scopes-api (1.0.0+15.10.20150821.3-0ubuntu1) wily; urgency=medium
94
95 [ Michi Henning ]
96
97=== modified file 'debian/rules'
98--- debian/rules 2015-07-20 11:17:15 +0000
99+++ debian/rules 2015-08-24 13:38:51 +0000
100@@ -5,6 +5,9 @@
101 #export DH_VERBOSE=1
102 export DPKG_GENSYMBOLS_CHECK_LEVEL=4
103
104+# Skip tests on the archs they are known to be flaky with current configuration
105+testskip_architectures := powerpc ppc64el
106+
107 %:
108 dh $@ --parallel --fail-missing --with click
109
110@@ -13,7 +16,9 @@
111
112 # Tests are not written to be run in parallel.
113 override_dh_auto_test:
114+ifeq (,$(filter $(testskip_architectures),$(DEB_HOST_ARCH)))
115 dh_auto_test --max-parallel=1 -- ARGS="--verbose"
116+endif
117
118 override_dh_click:
119 dh_click --name scope
120
121=== modified file 'demo/stand-alone/stand-alone-client.cpp'
122--- demo/stand-alone/stand-alone-client.cpp 2014-07-28 08:30:35 +0000
123+++ demo/stand-alone/stand-alone-client.cpp 2015-08-24 13:38:51 +0000
124@@ -85,12 +85,19 @@
125 // Syntax: ipc://<endpoint>#<identity>!<timeout>!<category>
126 //
127 // "ipc://" - prefix for all proxies
128- // "/tmp/scope-A - endpoint at which the scope listens
129+ // "/path/scope-A - endpoint at which the scope listens
130 // "scope-A - scope ID (must be the same as last component of endpoint path)
131 // "t=300" - optional timeout (infinite if not specified)
132 // "c=Scope" - type of proxy (must be "c=Scope")
133
134- ObjectProxy p = rt->string_to_proxy("ipc:///tmp/scope-A#scope-A!t=300!c=Scope");
135+ char* xdg_runtime_dir = getenv("XDG_RUNTIME_DIR");
136+ if (!xdg_runtime_dir || *xdg_runtime_dir == '\0')
137+ {
138+ throw ConfigException("No endpoint directories specified, and XDG_RUNTIME_DIR "
139+ "environment variable not set");
140+ }
141+ string stringified_proxy = string("ipc://") + xdg_runtime_dir + "/zmq/priv/scope-A#scope-A!t=300!c=Scope";
142+ ObjectProxy p = rt->string_to_proxy(stringified_proxy);
143 assert(p);
144
145 // The returned proxy is of type ObjectProxy and must be down-cast to a scope proxy:
146
147=== modified file 'include/unity/scopes/ActivationResponse.h'
148--- include/unity/scopes/ActivationResponse.h 2015-06-02 05:06:25 +0000
149+++ include/unity/scopes/ActivationResponse.h 2015-08-24 13:38:51 +0000
150@@ -21,6 +21,7 @@
151 #include <unity/scopes/Variant.h>
152 #include <unity/scopes/CannedQuery.h>
153 #include <unity/scopes/Result.h>
154+#include <unity/scopes/PreviewWidget.h>
155 #include <memory>
156
157 namespace unity
158@@ -53,6 +54,7 @@
159 ShowPreview, /**< Preview should be requested for this result */
160 PerformQuery, /**< Perform new search. This state is implied if creating ActivationResponse with CannedQuery object and is invalid otherwise */
161 UpdateResult, /**< Update the result. This state is implied if creating ActivationResponse with Result object and is invalid otherwise */
162+ UpdatePreview /**< Update the preview. This state is implied if creating ActivationResponse with PreviewWidgetList and is invalid otherwise */
163 };
164
165 /**
166@@ -77,6 +79,16 @@
167 */
168 ActivationResponse(Result const& updated_result);
169
170+ /**
171+ \brief Creates ActivationResponse with status Status::UpdatePreview and an updated list of preview widgets
172+ that replace the original widgets in the preview. Widgets not included in this list stay intact and are still
173+ displayed in the preview. Responding with this type of ActivationResponse outside of a preview context will not
174+ have any effect.
175+ \param updated_widgets The updated widgets to replace the original widgets in the preview.
176+ \throws unity::InvalidArgumentException if updated_widgets list is empty.
177+ */
178+ ActivationResponse(PreviewWidgetList const& updated_widgets);
179+
180 /**@name Copy and assignment
181 Copy and assignment operators (move and non-move versions) have the usual value semantics.
182 */
183@@ -124,6 +136,13 @@
184 */
185 Result updated_result() const;
186
187+ /**
188+ \brief The updated widgets if status is Status::UpdatePreview.
189+ \throws unity::LogicException if the status of this ActivationResponse is anything other than Status::UpdatePreview.
190+ \return The widgets to be displayed instead of the original widgets with same IDs.
191+ */
192+ PreviewWidgetList updated_widgets() const;
193+
194 /// @cond
195 VariantMap serialize() const;
196
197
198=== modified file 'include/unity/scopes/Result.h'
199--- include/unity/scopes/Result.h 2015-07-13 08:44:43 +0000
200+++ include/unity/scopes/Result.h 2015-08-24 13:38:51 +0000
201@@ -240,6 +240,12 @@
202 */
203 bool is_account_login_result() const;
204
205+ /**
206+ \brief Compare result.
207+ \return True if results have all attributes equal.
208+ */
209+ bool operator==(Result const& other) const;
210+
211 /// @cond
212 protected:
213 explicit Result(const VariantMap &variant_map);
214
215=== modified file 'include/unity/scopes/internal/ActivationResponseImpl.h'
216--- include/unity/scopes/internal/ActivationResponseImpl.h 2015-06-08 14:05:12 +0000
217+++ include/unity/scopes/internal/ActivationResponseImpl.h 2015-08-24 13:38:51 +0000
218@@ -21,6 +21,7 @@
219 #include <unity/scopes/ActivationResponse.h>
220 #include <unity/scopes/CannedQuery.h>
221 #include <unity/scopes/Result.h>
222+#include <unity/scopes/PreviewWidget.h>
223
224 namespace unity
225 {
226@@ -39,6 +40,7 @@
227 ActivationResponseImpl(ActivationResponse::Status status);
228 ActivationResponseImpl(CannedQuery const& query);
229 ActivationResponseImpl(Result const& result);
230+ ActivationResponseImpl(PreviewWidgetList const& updated_widgets);
231 ActivationResponseImpl(VariantMap const& var, RuntimeImpl const* runtime);
232 ~ActivationResponseImpl() = default;
233
234@@ -52,6 +54,7 @@
235 Variant scope_data() const;
236 CannedQuery query() const;
237 Result updated_result() const;
238+ PreviewWidgetList updated_widgets() const;
239
240 VariantMap serialize() const;
241
242@@ -62,6 +65,7 @@
243 CannedQuery::SPtr query_;
244 Variant scope_data_;
245 Result::SPtr updated_result_;
246+ std::shared_ptr<PreviewWidgetList> updated_widgets_;
247 };
248
249 } // namespace internal
250
251=== modified file 'include/unity/scopes/internal/ResultImpl.h'
252--- include/unity/scopes/internal/ResultImpl.h 2015-06-08 14:05:12 +0000
253+++ include/unity/scopes/internal/ResultImpl.h 2015-08-24 13:38:51 +0000
254@@ -81,6 +81,8 @@
255
256 VariantMap serialize() const;
257
258+ bool compare(ResultImpl *other) const;
259+
260 // a public static method, so there's access to the private constructor
261 // without the need to define too many classes as friends
262 static Result create_result(VariantMap const&);
263
264=== modified file 'src/scopes/ActivationResponse.cpp'
265--- src/scopes/ActivationResponse.cpp 2015-05-29 10:17:42 +0000
266+++ src/scopes/ActivationResponse.cpp 2015-08-24 13:38:51 +0000
267@@ -41,6 +41,11 @@
268 {
269 }
270
271+ActivationResponse::ActivationResponse(PreviewWidgetList const& updated_widgets)
272+ :p(new internal::ActivationResponseImpl(updated_widgets))
273+{
274+}
275+
276 /// @cond
277 ActivationResponse::ActivationResponse(internal::ActivationResponseImpl* pimpl)
278 : p(pimpl)
279@@ -98,6 +103,11 @@
280 return p->updated_result();
281 }
282
283+PreviewWidgetList ActivationResponse::updated_widgets() const
284+{
285+ return p->updated_widgets();
286+}
287+
288 } // namespace scopes
289
290 } // namespace unity
291
292=== modified file 'src/scopes/PreviewWidget.cpp'
293--- src/scopes/PreviewWidget.cpp 2015-05-19 09:19:13 +0000
294+++ src/scopes/PreviewWidget.cpp 2015-08-24 13:38:51 +0000
295@@ -87,11 +87,14 @@
296 \arg \c gallery
297 \arg \c header
298 \arg \c actions
299+\arg \c icon-actions
300 \arg \c progress
301 \arg \c text
302 \arg \c rating-input
303 \arg \c rating-edit
304 \arg \c reviews
305+\arg \c comment-input
306+\arg \c comment
307 \arg \c expandable
308
309 \subsection audio audio widget
310@@ -242,6 +245,17 @@
311 }
312 \endcode
313
314+\subsection icon-actions icon-actions widget
315+
316+The icon-actions widget displays one or more buttons represented by icons and/or labels. It's similar to actions widget, but uses different layout.
317+Every button can provide an optional temporary icon to be displayed immediately after user taps it.
318+
319+List of attributes:
320+
321+\arg \c actions A composite attribute containing an array of tuples, where each tuple has at least
322+these fields: \c id (a mandatory string that is passed to unity::scopes::ScopeBase::activate_preview_action()),
323+\c label (optional string), \c icon (optional URI, required if label is missing), \c temporaryIcon (optional URI).
324+
325 \subsection progress progress widget
326
327 The progress widget displays the progress of an action, such as download progress.
328@@ -378,6 +392,39 @@
329 }
330 \endcode
331
332+\subsection comment-input comment-input widget
333+
334+The comment-input widget allows users to add comments. It displays an input box along with "Send" button.
335+
336+When a user presses the "Send" button, the scope receives a preview
337+action activation with the id \c "commented". The actual comment
338+can be accessed via unity::scopes::ActionMetadata::scope_data.
339+The scope data will be a VariantMap with the \c "comment" field holding
340+the text entered by the user.
341+
342+List of attributes:
343+
344+\arg \c submit-label String for the label of the submit button (optional, uses "Submit" by default).
345+
346+\code{.cpp}
347+{
348+ PreviewWidget w1("cmt", "comment-input");
349+
350+ w1.add_attribute_value("submit-label", Variant("Comment it!"));
351+ ...
352+}
353+\endcode
354+
355+\subsection comment comment widget
356+
357+The comment widget shows an avatar, author name, subtitle and a comment text.
358+
359+List of attributes:
360+\arg \c source URI for an avatar icon (optional)
361+\arg \c author A string specifying the author of the comment (mandatory)
362+\arg \c subtitle A string for the subtitle (optional)
363+\arg \c comment A string for the comment text (mandatory)
364+
365 \subsection expandable expandable widget
366
367 The expandable widget is used to group several widgets into an expandable pane.
368
369=== modified file 'src/scopes/Result.cpp'
370--- src/scopes/Result.cpp 2015-04-15 10:05:42 +0000
371+++ src/scopes/Result.cpp 2015-08-24 13:38:51 +0000
372@@ -119,6 +119,11 @@
373 return p->value(key);
374 }
375
376+bool Result::operator==(Result const& other) const
377+{
378+ return p->compare(other.p.get());
379+}
380+
381 std::string Result::uri() const noexcept
382 {
383 return p->uri();
384
385=== modified file 'src/scopes/internal/ActivationResponseImpl.cpp'
386--- src/scopes/internal/ActivationResponseImpl.cpp 2015-06-08 14:05:12 +0000
387+++ src/scopes/internal/ActivationResponseImpl.cpp 2015-08-24 13:38:51 +0000
388@@ -17,6 +17,7 @@
389 */
390
391 #include <unity/scopes/internal/ActivationResponseImpl.h>
392+#include <unity/scopes/internal/PreviewWidgetImpl.h>
393 #include <unity/UnityExceptions.h>
394 #include <unity/scopes/internal/CannedQueryImpl.h>
395 #include <unity/scopes/internal/ResultImpl.h>
396@@ -42,6 +43,10 @@
397 {
398 throw unity::InvalidArgumentException("ActivationResponse(): Status::UpdateResult allowed only with Result object");
399 }
400+ if (status == ActivationResponse::Status::UpdatePreview)
401+ {
402+ throw unity::InvalidArgumentException("ActivationResponse(): Status::UpdatePreview allowed only with PreviewWidgetList object");
403+ }
404 }
405
406 ActivationResponseImpl::ActivationResponseImpl(CannedQuery const& query)
407@@ -56,6 +61,16 @@
408 {
409 }
410
411+ActivationResponseImpl::ActivationResponseImpl(PreviewWidgetList const& updated_widgets)
412+ : status_(ActivationResponse::Status::UpdatePreview),
413+ updated_widgets_(std::make_shared<PreviewWidgetList>(updated_widgets))
414+{
415+ if (updated_widgets.size() == 0)
416+ {
417+ throw InvalidArgumentException("ActivationResponse(): the list of widgets to update cannot be empty");
418+ }
419+}
420+
421 ActivationResponseImpl::ActivationResponseImpl(VariantMap const& var, RuntimeImpl const* runtime)
422 {
423 auto it = var.find("scope_data");
424@@ -92,6 +107,20 @@
425 impl->set_runtime(runtime);
426 updated_result_ = std::make_shared<Result>(ResultImpl::create_result(impl));
427 }
428+ else if (status_ == ActivationResponse::Status::UpdatePreview)
429+ {
430+ it = var.find("updated_widgets");
431+ if (it == var.end())
432+ {
433+ throw LogicException("ActivationResponseImpl(): Invalid data, missing 'updated_widgets'");
434+ }
435+ updated_widgets_.reset(new PreviewWidgetList());
436+ VariantArray arr = it->second.get_array();
437+ for (unsigned i = 0; i < arr.size(); i++)
438+ {
439+ updated_widgets_->emplace_back(PreviewWidgetImpl::create(arr[i].get_dict()));
440+ }
441+ }
442 }
443
444 ActivationResponse::Status ActivationResponseImpl::status() const
445@@ -129,6 +158,16 @@
446 throw LogicException("ActivationResponse::updated_result(): updated result is only available for status of Status::UpdateResult");
447 }
448
449+PreviewWidgetList ActivationResponseImpl::updated_widgets() const
450+{
451+ if (updated_widgets_)
452+ {
453+ assert(status_ == ActivationResponse::Status::UpdatePreview);
454+ return *updated_widgets_;
455+ }
456+ throw LogicException("ActivationResponse::updated_widgets(): updated widgets are only available for status of Status::UpdatePreview");
457+}
458+
459 VariantMap ActivationResponseImpl::serialize() const
460 {
461 VariantMap vm;
462@@ -142,6 +181,15 @@
463 {
464 vm["updated_result"] = updated_result_->serialize();
465 }
466+ else if (updated_widgets_)
467+ {
468+ VariantArray arr;
469+ for (auto const& widget : *updated_widgets_)
470+ {
471+ arr.push_back(Variant(widget.serialize()));
472+ }
473+ vm["updated_widgets"] = arr;
474+ }
475 return vm;
476 }
477
478
479=== modified file 'src/scopes/internal/RegistryConfig.cpp'
480--- src/scopes/internal/RegistryConfig.cpp 2015-07-01 10:59:49 +0000
481+++ src/scopes/internal/RegistryConfig.cpp 2015-08-24 13:38:51 +0000
482@@ -51,10 +51,6 @@
483 ConfigBase(configfile, DFLT_REGISTRY_INI)
484 {
485 identity_ = identity;
486- if (identity.empty())
487- {
488- throw InvalidArgumentException("Registry identity cannot be an empty string");
489- }
490 mw_kind_ = get_middleware(registry_config_group, mw_kind_key);
491 mw_configfile_ = get_optional_string(registry_config_group, mw_kind_ + configfile_key);
492 scope_installdir_ = get_optional_string(registry_config_group, scope_installdir_key, DFLT_SCOPE_INSTALL_DIR);
493
494=== modified file 'src/scopes/internal/ResultImpl.cpp'
495--- src/scopes/internal/ResultImpl.cpp 2015-06-08 14:05:12 +0000
496+++ src/scopes/internal/ResultImpl.cpp 2015-08-24 13:38:51 +0000
497@@ -474,6 +474,26 @@
498 }
499 }
500
501+bool ResultImpl::compare(ResultImpl *other) const
502+{
503+ // Compare all attributes and stored result (if set).
504+ // Ignore origin, runtime and flags.
505+ if (this == other)
506+ {
507+ return true;
508+ }
509+
510+ if ((stored_result_ == nullptr) != (other->stored_result_ == nullptr))
511+ {
512+ return false;
513+ }
514+ if (stored_result_ != nullptr && *stored_result_ != *(other->stored_result_))
515+ {
516+ return false;
517+ }
518+ return attrs_ == other->attrs_;
519+}
520+
521 Result ResultImpl::create_result(VariantMap const& variant_map)
522 {
523 return Result(variant_map);
524
525=== modified file 'src/scopes/internal/zmq_middleware/ZmqObject.cpp'
526--- src/scopes/internal/zmq_middleware/ZmqObject.cpp 2015-07-01 11:02:46 +0000
527+++ src/scopes/internal/zmq_middleware/ZmqObject.cpp 2015-08-24 13:38:51 +0000
528@@ -212,7 +212,7 @@
529
530 // If a registry is configured and this object is not a registry itself,
531 // attempt to locate the scope before invoking it.
532- if (!this_is_registry && !this_is_ss_registry)
533+ if (registry_proxy && !this_is_registry && !this_is_ss_registry)
534 {
535 try
536 {
537
538=== modified file 'test/gtest/scopes/ActivationResponse/ActivationResponse_test.cpp'
539--- test/gtest/scopes/ActivationResponse/ActivationResponse_test.cpp 2015-06-08 14:20:04 +0000
540+++ test/gtest/scopes/ActivationResponse/ActivationResponse_test.cpp 2015-08-24 13:38:51 +0000
541@@ -68,7 +68,6 @@
542 EXPECT_EQ(res.uri(), resp.updated_result().uri());
543 }
544
545-
546 // Search only allowed with CannedQuery
547 {
548 try
549@@ -88,10 +87,49 @@
550 }
551 catch (unity::InvalidArgumentException const&) {}
552 }
553+
554+ // UpdatePreview only allowed with PreviewWidgetList
555+ {
556+ try
557+ {
558+ ActivationResponse resp(ActivationResponse::Status::UpdatePreview);
559+ FAIL();
560+ }
561+ catch (unity::InvalidArgumentException const&) {}
562+ }
563+}
564+
565+TEST(ActivationResponse, with_updated_widgets)
566+{
567+ {
568+ PreviewWidget w("w1", "foo");
569+ PreviewWidgetList const widgets {w};
570+
571+ ActivationResponse resp(widgets);
572+ EXPECT_EQ(ActivationResponse::Status::UpdatePreview, resp.status());
573+ EXPECT_EQ(1, resp.updated_widgets().size());
574+ EXPECT_EQ("w1", resp.updated_widgets().begin()->id());
575+ }
576+
577+ {
578+ PreviewWidgetList const widgets;
579+
580+ try
581+ {
582+ ActivationResponse resp(widgets);
583+ FAIL();
584+ }
585+ catch (unity::InvalidArgumentException const&)
586+ {
587+ }
588+ }
589 }
590
591 TEST(ActivationResponse, serialize)
592 {
593+ // just to make ResultImpl::set_runtime() happy, runtime must not be null.
594+ auto runtime = internal::RuntimeImpl::create("fooscope", TEST_DIR "/Runtime.ini");
595+
596 {
597 ActivationResponse resp(ActivationResponse::Status::HideDash);
598 {
599@@ -123,6 +161,18 @@
600 EXPECT_EQ(ActivationResponse::Status::UpdateResult, static_cast<ActivationResponse::Status>(var["status"].get_int()));
601 EXPECT_EQ("foo", var["updated_result"].get_dict()["attrs"].get_dict()["uri"].get_string());
602 }
603+ {
604+ PreviewWidget const w("w1", "foo");
605+ PreviewWidgetList const widgets {w};
606+
607+ ActivationResponse resp(widgets);
608+ auto var = resp.serialize();
609+
610+ ActivationResponse resp2 = internal::ActivationResponseImpl::create(var, runtime.get());
611+ EXPECT_EQ(ActivationResponse::Status::UpdatePreview, resp2.status());
612+ EXPECT_EQ(1, resp2.updated_widgets().size());
613+ EXPECT_EQ("w1", resp2.updated_widgets().begin()->id());
614+ }
615 }
616
617 TEST(ActivationResponse, deserialize)
618
619=== modified file 'test/gtest/scopes/CMakeLists.txt'
620--- test/gtest/scopes/CMakeLists.txt 2015-04-09 15:59:17 +0000
621+++ test/gtest/scopes/CMakeLists.txt 2015-08-24 13:38:51 +0000
622@@ -34,6 +34,7 @@
623 add_subdirectory(Runtime)
624 add_subdirectory(ScopeBase)
625 add_subdirectory(ScopeExceptions)
626+add_subdirectory(StandAloneScope)
627 add_subdirectory(StripLocation)
628 add_subdirectory(SwitchFilter)
629 add_subdirectory(ThrowingClient)
630
631=== modified file 'test/gtest/scopes/CategorisedResult/CategorisedResult_test.cpp'
632--- test/gtest/scopes/CategorisedResult/CategorisedResult_test.cpp 2015-02-25 03:38:29 +0000
633+++ test/gtest/scopes/CategorisedResult/CategorisedResult_test.cpp 2015-08-24 13:38:51 +0000
634@@ -105,6 +105,38 @@
635 }
636 }
637
638+TEST(CategorisedResult, compare)
639+{
640+ CategoryRegistry reg;
641+ CategoryRenderer rdr;
642+ auto cat = reg.register_category("1", "title", "icon", nullptr, rdr);
643+
644+ {
645+ CategorisedResult result1(cat);
646+ result1.set_uri("uri a");
647+ result1.set_title("title a");
648+ result1.set_art("icon a");
649+ result1["common"] = "o";
650+
651+ CategorisedResult result2(cat);
652+ result2.set_uri("uri a");
653+ result2.set_title("title a");
654+ result2.set_art("icon a");
655+ result2["common"] = "o";
656+
657+ EXPECT_TRUE(result1 == result2);
658+
659+ CategorisedResult result3(cat);
660+ result3.set_uri("uri b");
661+ result3.set_title("title a");
662+ result3.set_art("icon a");
663+ result3["common"] = "o";
664+
665+ EXPECT_FALSE(result1 == result3);
666+ EXPECT_FALSE(result2 == result3);
667+ }
668+}
669+
670 TEST(CategorisedResult, copy)
671 {
672 CategoryRegistry reg;
673
674=== added directory 'test/gtest/scopes/StandAloneScope'
675=== added file 'test/gtest/scopes/StandAloneScope/CMakeLists.txt'
676--- test/gtest/scopes/StandAloneScope/CMakeLists.txt 1970-01-01 00:00:00 +0000
677+++ test/gtest/scopes/StandAloneScope/CMakeLists.txt 2015-08-24 13:38:51 +0000
678@@ -0,0 +1,15 @@
679+configure_file(Runtime.ini.in ${CMAKE_CURRENT_BINARY_DIR}/Runtime.ini)
680+configure_file(Zmq.ini.in ${CMAKE_CURRENT_BINARY_DIR}/Zmq.ini)
681+
682+add_definitions(-DTEST_RUNTIME_PATH="${CMAKE_CURRENT_BINARY_DIR}")
683+add_definitions(-DTEST_RUNTIME_FILE="${CMAKE_CURRENT_BINARY_DIR}/Runtime.ini")
684+add_definitions(-DTEST_SCOPERUNNER_PATH="${PROJECT_BINARY_DIR}/scoperunner")
685+
686+add_executable(StandAloneScope_test StandAloneScope_test.cpp)
687+target_link_libraries(StandAloneScope_test ${TESTLIBS})
688+add_dependencies(StandAloneScope_test scoperunner)
689+
690+add_test(StandAloneScope StandAloneScope_test)
691+
692+configure_file(SimpleScope.ini.in ${CMAKE_CURRENT_BINARY_DIR}/SimpleScope.ini)
693+add_library(SimpleScope MODULE SimpleScope.cpp)
694
695=== added file 'test/gtest/scopes/StandAloneScope/Runtime.ini.in'
696--- test/gtest/scopes/StandAloneScope/Runtime.ini.in 1970-01-01 00:00:00 +0000
697+++ test/gtest/scopes/StandAloneScope/Runtime.ini.in 2015-08-24 13:38:51 +0000
698@@ -0,0 +1,2 @@
699+[Runtime]
700+Zmq.ConfigFile=@CMAKE_CURRENT_BINARY_DIR@/Zmq.ini
701
702=== added file 'test/gtest/scopes/StandAloneScope/SimpleScope.cpp'
703--- test/gtest/scopes/StandAloneScope/SimpleScope.cpp 1970-01-01 00:00:00 +0000
704+++ test/gtest/scopes/StandAloneScope/SimpleScope.cpp 2015-08-24 13:38:51 +0000
705@@ -0,0 +1,99 @@
706+/*
707+ * Copyright (C) 2015 Canonical Ltd
708+ *
709+ * This program is free software: you can redistribute it and/or modify
710+ * it under the terms of the GNU Lesser General Public License version 3 as
711+ * published by the Free Software Foundation.
712+ *
713+ * This program is distributed in the hope that it will be useful,
714+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
715+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
716+ * GNU Lesser General Public License for more details.
717+ *
718+ * You should have received a copy of the GNU Lesser General Public License
719+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
720+ *
721+ * Authored by: Michi Henning <michi.henning@canonical.com>
722+ */
723+
724+#include "SimpleScope.h"
725+
726+#include <unity/scopes/CategorisedResult.h>
727+#include <unity/scopes/ScopeBase.h>
728+#include <unity/scopes/SearchReply.h>
729+
730+using namespace std;
731+using namespace unity;
732+using namespace unity::scopes;
733+
734+namespace
735+{
736+
737+class TestQuery : public SearchQueryBase
738+{
739+public:
740+ TestQuery(CannedQuery const& query,
741+ SearchMetadata const& metadata)
742+ : SearchQueryBase(query, metadata)
743+ {
744+ }
745+
746+ virtual void cancelled() override
747+ {
748+ }
749+
750+ virtual void run(SearchReplyProxy const& reply) override
751+ {
752+ auto cat = reply->register_category("cat", "", "");
753+ CategorisedResult res(cat);
754+ res.set_uri("uri");
755+ res.set_title(query().query_string());
756+ if (valid())
757+ {
758+ reply->push(res);
759+ }
760+ }
761+};
762+
763+} // namespace
764+
765+void EchoScope::start(string const& /* scope_id */)
766+{
767+}
768+
769+void EchoScope::stop()
770+{
771+}
772+
773+void EchoScope::run()
774+{
775+}
776+
777+SearchQueryBase::UPtr EchoScope::search(CannedQuery const& query, SearchMetadata const& metadata)
778+{
779+ return SearchQueryBase::UPtr(new TestQuery(query, metadata));
780+}
781+
782+PreviewQueryBase::UPtr EchoScope::preview(Result const& /* result */, ActionMetadata const& /* metadata */)
783+{
784+ abort();
785+ return nullptr;
786+}
787+
788+extern "C"
789+{
790+
791+ unity::scopes::ScopeBase*
792+ // cppcheck-suppress unusedFunction
793+ UNITY_SCOPE_CREATE_FUNCTION()
794+ {
795+ return new EchoScope;
796+ }
797+
798+ void
799+ // cppcheck-suppress unusedFunction
800+ UNITY_SCOPE_DESTROY_FUNCTION(unity::scopes::ScopeBase* scope_base)
801+ {
802+ delete scope_base;
803+ }
804+}
805
806=== added file 'test/gtest/scopes/StandAloneScope/SimpleScope.h'
807--- test/gtest/scopes/StandAloneScope/SimpleScope.h 1970-01-01 00:00:00 +0000
808+++ test/gtest/scopes/StandAloneScope/SimpleScope.h 2015-08-24 13:38:51 +0000
809@@ -0,0 +1,37 @@
810+/*
811+ * Copyright (C) 2015 Canonical Ltd
812+ *
813+ * This program is free software: you can redistribute it and/or modify
814+ * it under the terms of the GNU Lesser General Public License version 3 as
815+ * published by the Free Software Foundation.
816+ *
817+ * This program is distributed in the hope that it will be useful,
818+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
819+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
820+ * GNU Lesser General Public License for more details.
821+ *
822+ * You should have received a copy of the GNU Lesser General Public License
823+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
824+ *
825+ * Authored by: Michi Henning <michi.henning@canonical.com>
826+ */
827+
828+#pragma once
829+
830+#include <unity/scopes/ScopeBase.h>
831+
832+class EchoScope : public unity::scopes::ScopeBase
833+{
834+public:
835+ virtual void start(std::string const&) override;
836+
837+ virtual void stop() override;
838+
839+ virtual void run() override;
840+
841+ virtual unity::scopes::SearchQueryBase::UPtr search(unity::scopes::CannedQuery const &,
842+ unity::scopes::SearchMetadata const &) override;
843+
844+ virtual unity::scopes::PreviewQueryBase::UPtr preview(unity::scopes::Result const&,
845+ unity::scopes::ActionMetadata const &) override;
846+};
847
848=== added file 'test/gtest/scopes/StandAloneScope/SimpleScope.ini.in'
849--- test/gtest/scopes/StandAloneScope/SimpleScope.ini.in 1970-01-01 00:00:00 +0000
850+++ test/gtest/scopes/StandAloneScope/SimpleScope.ini.in 2015-08-24 13:38:51 +0000
851@@ -0,0 +1,4 @@
852+[ScopeConfig]
853+DisplayName = SimpleScope
854+Description = Simple scope. Returns a single result containing the query string.
855+Author = Michi
856
857=== added file 'test/gtest/scopes/StandAloneScope/StandAloneScope_test.cpp'
858--- test/gtest/scopes/StandAloneScope/StandAloneScope_test.cpp 1970-01-01 00:00:00 +0000
859+++ test/gtest/scopes/StandAloneScope/StandAloneScope_test.cpp 2015-08-24 13:38:51 +0000
860@@ -0,0 +1,132 @@
861+/*
862+ * Copyright (C) 2015 Canonical Ltd
863+ *
864+ * This program is free software: you can redistribute it and/or modify
865+ * it under the terms of the GNU Lesser General Public License version 3 as
866+ * published by the Free Software Foundation.
867+ *
868+ * This program is distributed in the hope that it will be useful,
869+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
870+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
871+ * GNU Lesser General Public License for more details.
872+ *
873+ * You should have received a copy of the GNU Lesser General Public License
874+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
875+ *
876+ * Authored by: Michi Henning <michi.henning@canonical.com>
877+ */
878+
879+#include <unity/scopes/Runtime.h>
880+#include <unity/scopes/Scope.h>
881+#include <unity/scopes/ScopeExceptions.h>
882+#include <unity/scopes/SearchListenerBase.h>
883+#include <unity/scopes/SearchMetadata.h>
884+
885+#include <gtest/gtest.h>
886+
887+#include <chrono>
888+#include <condition_variable>
889+
890+using namespace std;
891+using namespace unity::scopes;
892+
893+class Receiver : public SearchListenerBase
894+{
895+public:
896+ Receiver()
897+ : done_(false)
898+ , finished_ok_(false)
899+ {
900+ }
901+
902+ virtual void push(CategorisedResult /* result */) override
903+ {
904+ }
905+
906+ virtual void finished(CompletionDetails const& details) override
907+ {
908+ std::lock_guard<std::mutex> lock(mutex_);
909+
910+ EXPECT_EQ(CompletionDetails::OK, details.status());
911+ EXPECT_EQ("", details.message());
912+ finished_ok_ = details.status() == CompletionDetails::OK;
913+ done_ = true;
914+ cond_.notify_all();
915+ }
916+
917+ bool wait_until_finished()
918+ {
919+ std::unique_lock<std::mutex> lock(mutex_);
920+ auto now = std::chrono::steady_clock::now();
921+ auto expiry_time = now + std::chrono::seconds(5);
922+ EXPECT_TRUE(cond_.wait_until(lock, expiry_time, [this]{ return done_; })) << "finished message not delivered";
923+ done_ = false;
924+ return finished_ok_;
925+ }
926+
927+private:
928+ bool done_;
929+ bool finished_ok_;
930+ std::mutex mutex_;
931+ std::condition_variable cond_;
932+};
933+
934+TEST(StandAloneScope, reachable)
935+{
936+ Runtime::UPtr rt = Runtime::create(TEST_RUNTIME_FILE); // No registry configured.
937+
938+ try
939+ {
940+ rt->registry();
941+ FAIL();
942+ }
943+ catch (ConfigException const& e)
944+ {
945+ ASSERT_STREQ("unity::scopes::ConfigException: registry(): no registry configured", e.what());
946+ }
947+
948+ string stringified_proxy = "ipc:///tmp/priv/SimpleScope#SimpleScope!t=1000!c=Scope";
949+ ObjectProxy p = rt->string_to_proxy(stringified_proxy);
950+ ASSERT_TRUE(bool(p));
951+
952+ ScopeProxy sp = dynamic_pointer_cast<Scope>(p);
953+ ASSERT_TRUE(bool(sp));
954+
955+ // We must be able to reach the scope even though the registry is not running.
956+ shared_ptr<Receiver> reply(new Receiver);
957+ auto ctrl = sp->search("", SearchMetadata("", ""), reply);
958+ EXPECT_TRUE(reply->wait_until_finished());
959+}
960+
961+int main(int argc, char **argv)
962+{
963+ ::testing::InitGoogleTest(&argc, argv);
964+
965+ int rc = 1;
966+
967+ // Set the "TEST_DESKTOP_FILES_DIR" env var before forking as not to create desktop files in ~/.local
968+ putenv(const_cast<char*>("TEST_DESKTOP_FILES_DIR=" TEST_RUNTIME_PATH));
969+
970+ auto rpid = fork();
971+ if (rpid == 0)
972+ {
973+ // Start a scoperunner without any registry config.
974+ const char* const args[] = {"scoperunner [StandAloneScope test]", TEST_RUNTIME_FILE, "SimpleScope.ini", nullptr};
975+ if (execv(TEST_SCOPERUNNER_PATH "/scoperunner", const_cast<char* const*>(args)) < 0)
976+ {
977+ perror("Error starting scoperunner:");
978+ }
979+ }
980+ else if (rpid > 0)
981+ {
982+ rc = RUN_ALL_TESTS();
983+ kill(rpid, SIGTERM);
984+ waitpid(rpid, nullptr, 0);
985+ }
986+ else
987+ {
988+ perror("Failed to fork:");
989+ }
990+
991+ return rc;
992+}
993
994=== added file 'test/gtest/scopes/StandAloneScope/Zmq.ini.in'
995--- test/gtest/scopes/StandAloneScope/Zmq.ini.in 1970-01-01 00:00:00 +0000
996+++ test/gtest/scopes/StandAloneScope/Zmq.ini.in 2015-08-24 13:38:51 +0000
997@@ -0,0 +1,2 @@
998+[Zmq]
999+EndpointDir = /tmp
1000
1001=== modified file 'test/gtest/scopes/internal/RegistryConfig/RegistryConfig_test.cpp'
1002--- test/gtest/scopes/internal/RegistryConfig/RegistryConfig_test.cpp 2014-08-28 00:20:56 +0000
1003+++ test/gtest/scopes/internal/RegistryConfig/RegistryConfig_test.cpp 2015-08-24 13:38:51 +0000
1004@@ -39,16 +39,7 @@
1005
1006 TEST(RegistryConfig, RegistryIDEmpty)
1007 {
1008- try
1009- {
1010- RegistryConfig c("", TEST_REGISTRY_PATH);
1011- FAIL();
1012- }
1013- catch (InvalidArgumentException const& e)
1014- {
1015- EXPECT_STREQ("unity::InvalidArgumentException: Registry identity cannot be an empty string",
1016- e.what());
1017- }
1018+ RegistryConfig c("", TEST_REGISTRY_PATH);
1019 }
1020
1021 TEST(RegistryConfig, HomeNotSet)

Subscribers

People subscribed via source and target branches

to all changes: