Merge lp:~bregma/libertine-scope/release-20160426 into lp:libertine-scope/release

Proposed by Stephen M. Webb
Status: Merged
Approved by: Christopher Townsend
Approved revision: 31
Merged at revision: 30
Proposed branch: lp:~bregma/libertine-scope/release-20160426
Merge into: lp:libertine-scope/release
Diff against target: 1114 lines (+510/-183)
27 files modified
.bzrignore (+2/-0)
CMakeLists.txt (+5/-1)
data/libertine-scope-settings.ini.in (+5/-1)
debian/changelog (+17/-0)
debian/control (+2/-0)
libertine-scope.apparmor (+1/-1)
libertine-scope/CMakeLists.txt (+2/-0)
libertine-scope/applauncher.cpp (+23/-56)
libertine-scope/applauncher.h (+12/-12)
libertine-scope/container.cpp (+3/-2)
libertine-scope/container.h (+1/-1)
libertine-scope/libertine.cpp (+25/-43)
libertine-scope/preview.cpp (+20/-15)
libertine-scope/query.cpp (+37/-20)
libertine-scope/query.h (+7/-0)
po/CMakeLists.txt (+11/-0)
po/Makefile.in.in (+0/-1)
po/POTFILES.in (+0/-21)
po/POTFILES.in.in (+2/-0)
po/libertine-scope.pot (+26/-0)
tests/CMakeLists.txt (+8/-3)
tests/fake_container.cpp (+21/-2)
tests/fake_container.h (+1/-1)
tests/fake_container_json.h (+6/-2)
tests/test_preview.cpp (+63/-0)
tests/test_query.cpp (+210/-0)
tests/test_scope.cpp (+0/-1)
To merge this branch: bzr merge lp:~bregma/libertine-scope/release-20160426
Reviewer Review Type Date Requested Status
Christopher Townsend Approve
Review via email: mp+292973@code.launchpad.net

Description of the change

libertine-scope 1.1 release, for landing in vivid+overlay and release in OTA-11.

  [ Chris Townsend ]
  * Use the "unconfined" apparmor template to allow the scope to access user
    data (lp: #1558738).

  [ Larry Price ]
  * Redesigned preview pane with reasonably-sized image, title, and description.
  * Filtered app launchers based on a user-input regular expression.
  * Added a setting for listing app launcher names which should be excluded
    from the scope view.

  [ Stephen M. Webb ]
  * Added internationalization support.

To post a comment you must log in.
30. By Stephen M. Webb

synched with development trunk

31. By Stephen M. Webb

marking for 1.1 release

Revision history for this message
Christopher Townsend (townsend) wrote :

Looks sane to me.

review: Approve
32. By Stephen M. Webb

Fixed failing unit tests on Vivid.

33. By Larry Price

Integrate the ubuntu-app-launch C++ API.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file '.bzrignore'
2--- .bzrignore 1970-01-01 00:00:00 +0000
3+++ .bzrignore 2016-05-05 15:35:57 +0000
4@@ -0,0 +1,2 @@
5+po/POTFILES.in
6+po/Makefile.in.in
7
8=== modified file 'CMakeLists.txt'
9--- CMakeLists.txt 2016-02-03 20:26:02 +0000
10+++ CMakeLists.txt 2016-05-05 15:35:57 +0000
11@@ -1,6 +1,6 @@
12 cmake_minimum_required(VERSION 3.0)
13 project(libertine-scope
14- VERSION 1.0
15+ VERSION 1.1
16 LANGUAGES CXX)
17
18 # We require at least g++ 4.9, to avoid ABI breakage with earlier versions.
19@@ -30,12 +30,16 @@
20 find_package(Qt5Gui REQUIRED)
21
22 pkg_check_modules(SCOPE libunity-scopes>=0.6.0 REQUIRED)
23+pkg_check_modules(UAL ubuntu-app-launch-2>=0.5.0 REQUIRED)
24+pkg_check_modules(LIBERTINE libertine REQUIRED)
25
26 # Add our dependencies to the include paths
27 include_directories(
28 ${CMAKE_SOURCE_DIR}
29 ${CMAKE_SOURCE_DIR}/libertine-scope
30 ${SCOPE_INCLUDE_DIRS}
31+ ${UAL_INCLUDE_DIRS}
32+ ${LIBERTINE_INCLUDE_DIRS}
33 )
34
35 # Important project paths
36
37=== modified file 'data/libertine-scope-settings.ini.in'
38--- data/libertine-scope-settings.ini.in 2015-12-29 21:50:58 +0000
39+++ data/libertine-scope-settings.ini.in 2016-05-05 15:35:57 +0000
40@@ -1,3 +1,8 @@
41+[blacklist]
42+type = string
43+_displayName = Excluded Apps
44+defaultValue = Panel Manager;OpenJDK Java 7 Policy Tool;OpenJDK Java 8 Policy Tool;
45+
46 # Below are some example settings. You can access your scope's
47 # settings by calling settings() from the Query::run() method.
48 # E.g. auto location = settings().at("location").get_string();
49@@ -17,4 +22,3 @@
50 #type = boolean
51 #defaultValue = true
52 #_displayName = Show Forecast
53-
54
55=== modified file 'debian/changelog'
56--- debian/changelog 2016-02-05 13:58:17 +0000
57+++ debian/changelog 2016-05-05 15:35:57 +0000
58@@ -1,3 +1,20 @@
59+libertine-scope (1.1-0ubuntu1) UNRELEASED; urgency=medium
60+
61+ [ Chris Townsend ]
62+ * Use the "unconfined" apparmor template to allow the scope to access user
63+ data (lp: #1558738).
64+
65+ [ Larry Price ]
66+ * Redesigned preview pane with reasonably-sized image, title, and description.
67+ * Filtered app launchers based on a user-input regular expression.
68+ * Added a setting for listing app launcher names which should be excluded
69+ from the scope view.
70+
71+ [ Stephen M. Webb ]
72+ * Added internationalization support.
73+
74+ -- Stephen M. Webb <stephen.webb@bregmasoft.ca> Tue, 26 Apr 2016 11:31:09 -0400
75+
76 libertine-scope (1.0-0ubuntu1) xenial; urgency=low
77
78 * Initial release (lp: #1541417).
79
80=== modified file 'debian/control'
81--- debian/control 2016-02-05 13:58:24 +0000
82+++ debian/control 2016-05-05 15:35:57 +0000
83@@ -11,6 +11,8 @@
84 intltool,
85 libunity-scopes-dev (>= 0.6.0),
86 liburl-dispatcher1-dev,
87+ libubuntu-app-launch2-dev,
88+ liblibertine-dev,
89 pkg-config,
90 qtbase5-dev
91 Standards-Version: 3.9.6
92
93=== modified file 'libertine-scope.apparmor'
94--- libertine-scope.apparmor 2015-12-29 21:50:58 +0000
95+++ libertine-scope.apparmor 2016-05-05 15:35:57 +0000
96@@ -1,5 +1,5 @@
97 {
98- "template": "ubuntu-scope-network",
99+ "template": "unconfined",
100 "policy_groups": [],
101 "policy_version": 1.3
102 }
103
104=== modified file 'libertine-scope/CMakeLists.txt'
105--- libertine-scope/CMakeLists.txt 2016-02-03 15:42:16 +0000
106+++ libertine-scope/CMakeLists.txt 2016-05-05 15:35:57 +0000
107@@ -17,6 +17,8 @@
108
109 target_link_libraries(scope
110 ${SCOPE_LDFLAGS}
111+ ${UAL_LDFLAGS}
112+ ${LIBERTINE_LDFLAGS}
113 Qt5::Core
114 Qt5::Gui
115 ${URL_DISPATCHER_LIBRARIES}
116
117=== modified file 'libertine-scope/applauncher.cpp'
118--- libertine-scope/applauncher.cpp 2016-02-03 15:42:16 +0000
119+++ libertine-scope/applauncher.cpp 2016-05-05 15:35:57 +0000
120@@ -13,80 +13,40 @@
121 * You should have received a copy of the GNU General Public License
122 * along with this program. If not, see <http://www.gnu.org/licenses/>.
123 */
124+
125 #include "libertine-scope/applauncher.h"
126-
127-#include <QtCore/QByteArray>
128-#include <QtCore/QJsonArray>
129-#include <QtCore/QJsonDocument>
130-#include <QtCore/QJsonObject>
131-#include <QtCore/QFileInfo>
132-#include <QtGui/QImage>
133+#include <ubuntu-app-launch/registry.h>
134
135
136 AppLauncher::
137-AppLauncher(std::string const& json_string)
138+AppLauncher(const std::string& app_id, const std::string& container_id)
139 {
140- auto doc = QJsonDocument::fromJson(QByteArray::fromStdString(json_string));
141- auto obj = doc.object();
142-
143- name_ = obj["name"].toString().toStdString();
144-
145- no_display_ = obj["no_display"].toBool();
146-
147- QJsonValue icons = obj["icons"];
148- if (icons.isArray())
149- {
150- int width = 0;
151- for (auto const& icon: icons.toArray())
152- {
153- QString icon_file_name = icon.toString();
154- if (icon_file_name.endsWith(".svg", Qt::CaseInsensitive))
155- {
156- icon_ = "file://" + icon_file_name.toStdString();
157- break;
158- }
159-
160- QImage image = QImage(icon_file_name);
161- if (image.width() > width)
162- {
163- icon_ = "file://" + icon_file_name.toStdString();
164- width = image.width();
165- }
166- }
167- }
168-
169- desktop_file_ = obj["desktop_file_name"].toString().toStdString();
170+ auto appId = ubuntu::app_launch::AppID::parse(app_id);
171+ auto app = ubuntu::app_launch::Application::create(appId, ubuntu::app_launch::Registry::getDefault());
172+ name_ = app->info()->name().value();
173+ icon_ = app->info()->iconPath().value();
174+ description_ = app->info()->description().value();
175+ uri_ = "appid://" + container_id + "/" + appId.appname.value() + "/0.0";
176 }
177
178
179 AppLauncher::
180+AppLauncher() { /* empty */ }
181+
182+
183+AppLauncher::
184 ~AppLauncher()
185 {
186 }
187
188
189 std::string AppLauncher::
190-id() const
191-{
192- QFileInfo fi(QString::fromStdString(desktop_file_));
193- return fi.baseName().toStdString();
194-}
195-
196-
197-std::string AppLauncher::
198 name() const
199 {
200 return name_;
201 }
202
203
204-bool AppLauncher::
205-no_display() const
206-{
207- return no_display_;
208-}
209-
210-
211 std::string AppLauncher::
212 icon() const
213 {
214@@ -95,8 +55,15 @@
215
216
217 std::string AppLauncher::
218-desktop_file() const
219-{
220- return desktop_file_;
221+description() const
222+{
223+ return description_;
224+}
225+
226+
227+std::string AppLauncher::
228+uri() const
229+{
230+ return uri_;
231 }
232
233
234=== modified file 'libertine-scope/applauncher.h'
235--- libertine-scope/applauncher.h 2016-01-04 18:30:15 +0000
236+++ libertine-scope/applauncher.h 2016-05-05 15:35:57 +0000
237@@ -30,31 +30,31 @@
238 * Constructs an AppLaunchder object from a JSON string.
239 */
240 explicit
241- AppLauncher(std::string const& json_string);
242+ AppLauncher(const std::string& app_id, const std::string& container_name);
243
244 virtual
245 ~AppLauncher();
246
247 virtual std::string
248- id() const;
249-
250- virtual std::string
251 name() const;
252
253- virtual bool
254- no_display() const;
255-
256 virtual std::string
257 icon() const;
258
259 virtual std::string
260- desktop_file() const;
261-
262-private:
263+ description() const;
264+
265+ virtual std::string
266+ uri() const;
267+
268+protected:
269+ explicit
270+ AppLauncher();
271+
272 std::string name_;
273- bool no_display_;
274 std::string icon_;
275- std::string desktop_file_;
276+ std::string uri_;
277+ std::string description_;
278 };
279
280 #endif /* LIBERTINE_SCOPE_APPLAUNCHER_H */
281
282=== modified file 'libertine-scope/container.cpp'
283--- libertine-scope/container.cpp 2016-01-19 21:10:09 +0000
284+++ libertine-scope/container.cpp 2016-05-05 15:35:57 +0000
285@@ -13,13 +13,14 @@
286 * You should have received a copy of the GNU General Public License
287 * along with this program. If not, see <http://www.gnu.org/licenses/>.
288 */
289+
290 #include "libertine-scope/container.h"
291
292
293 Container::
294-Container(std::string const& container_id)
295+Container(std::string const& container_id, std::string const& container_name)
296 : id_(container_id)
297-, name_(container_id)
298+, name_(container_name)
299 { }
300
301
302
303=== modified file 'libertine-scope/container.h'
304--- libertine-scope/container.h 2016-01-19 21:10:09 +0000
305+++ libertine-scope/container.h 2016-05-05 15:35:57 +0000
306@@ -43,7 +43,7 @@
307 * launcher .desktop files and their icons.
308 */
309 explicit
310- Container(std::string const& container_id);
311+ Container(std::string const& container_id, std::string const& container_name);
312
313 virtual
314 ~Container() = 0;
315
316=== modified file 'libertine-scope/libertine.cpp'
317--- libertine-scope/libertine.cpp 2016-01-19 21:10:09 +0000
318+++ libertine-scope/libertine.cpp 2016-05-05 15:35:57 +0000
319@@ -13,56 +13,41 @@
320 * You should have received a copy of the GNU General Public License
321 * along with this program. If not, see <http://www.gnu.org/licenses/>.
322 */
323+
324 #include "libertine-scope/libertine.h"
325-
326 #include "libertine-scope/container.h"
327-#include <QtCore/QJsonArray>
328-#include <QtCore/QJsonDocument>
329-#include <QtCore/QJsonObject>
330-#include <QtCore/QJsonValue>
331-#include <QtCore/QProcess>
332-#include <QtCore/QString>
333-
334+#include <liblibertine/libertine.h>
335+#include <glib.h>
336
337 namespace
338 {
339
340 /**
341- * A real Libertine Container created by using the Libertine tools.
342+ * A real Libertine Container created by querying liblibertine.
343 */
344 class LibertineContainer
345 : public Container
346 {
347 public:
348- LibertineContainer(std::string const& container_id)
349- : Container(container_id)
350+ LibertineContainer(std::string const& container_id, std::string const& container_name)
351+ : Container(container_id, container_name)
352 {
353- QProcess libertine_container_manager;
354- libertine_container_manager.start("libertine-container-manager",
355- QStringList() << "list-apps"
356- << "--id"
357- << QString::fromStdString(id_)
358- << "--json");
359- if (libertine_container_manager.waitForFinished())
360+ auto apps = libertine_list_apps_for_container(container_id.c_str());
361+ for (auto i = 0; apps[i] != nullptr; ++i)
362 {
363- QJsonDocument json = QJsonDocument::fromJson(libertine_container_manager.readAllStandardOutput());
364- QJsonObject object = json.object();
365- QJsonValue name = object["name"];
366- if (name != QJsonValue::Undefined)
367- {
368- name_ = name.toString().toStdString();
369-
370- QJsonValue v = object["app_launchers"];
371- if (v != QJsonValue::Undefined)
372- {
373- for (auto const& app: v.toArray())
374- {
375- auto json = QJsonDocument(app.toObject()).toJson().toStdString();
376- app_launcher_list_.emplace_back(AppLauncher(json));
377- }
378- }
379+ try
380+ {
381+ app_launcher_list_.emplace_back(AppLauncher(apps[i], container_id));
382+ }
383+ catch(std::runtime_error)
384+ {
385+ /*
386+ * U-A-L will throw if an application cannot be displayed
387+ * for any reason. Ignore and continue.
388+ */
389 }
390 }
391+ g_strfreev(apps);
392 }
393
394 ~LibertineContainer()
395@@ -75,17 +60,14 @@
396 public:
397 LibertineCli()
398 {
399- QProcess libertine_container_manager;
400- libertine_container_manager.start("libertine-container-manager",
401- QStringList() << "list");
402- if (libertine_container_manager.waitForFinished())
403+ auto container_ids = libertine_list_containers();
404+ for (auto i = 0; container_ids[i] != nullptr; ++i)
405 {
406- QString container_id_list(libertine_container_manager.readAllStandardOutput());
407- for (auto const& id: container_id_list.split("\n", QString::SkipEmptyParts))
408- {
409- container_list_.emplace_back(new LibertineContainer(id.toStdString()));
410- }
411+ auto name = libertine_container_name(container_ids[i]);
412+ container_list_.emplace_back(new LibertineContainer(container_ids[i], name));
413+ g_free(name);
414 }
415+ g_strfreev(container_ids);
416 }
417
418 Libertine::ContainerList const&
419
420=== modified file 'libertine-scope/preview.cpp'
421--- libertine-scope/preview.cpp 2016-01-19 21:10:09 +0000
422+++ libertine-scope/preview.cpp 2016-05-05 15:35:57 +0000
423@@ -13,16 +13,19 @@
424 * You should have received a copy of the GNU General Public License
425 * along with this program. If not, see <http://www.gnu.org/licenses/>.
426 */
427+
428 #include "libertine-scope/preview.h"
429-
430 #include <unity/scopes/PreviewReply.h>
431 #include <unity/scopes/Variant.h>
432 #include <unity/scopes/VariantBuilder.h>
433+#include <unity/scopes/ActionMetadata.h>
434+#include <unity/scopes/Result.h>
435
436+namespace usc = unity::scopes;
437
438 Preview::
439-Preview(unity::scopes::Result const& result,
440- unity::scopes::ActionMetadata const& metadata)
441+Preview(usc::Result const& result,
442+ usc::ActionMetadata const& metadata)
443 : PreviewQueryBase(result, metadata)
444 {
445 }
446@@ -41,22 +44,24 @@
447
448
449 void Preview::
450-run(unity::scopes::PreviewReplyProxy const& reply)
451+run(usc::PreviewReplyProxy const& reply)
452 {
453- reply->push("description", unity::scopes::Variant("A Description"));
454-
455- unity::scopes::PreviewWidget image_widget("myimage", "image");
456- image_widget.add_attribute_mapping("source", "art");
457-
458- unity::scopes::PreviewWidget buttons("buttons", "actions");
459- unity::scopes::VariantBuilder vb;
460+ usc::PreviewWidget header("hdr", "header");
461+ header.add_attribute_mapping("title", "title");
462+ header.add_attribute_mapping("mascot", "art");
463+ header.add_attribute_value("fallback", usc::Variant("image://theme/placeholder-app-icon"));
464+
465+ usc::PreviewWidget buttons("buttons", "actions");
466+ usc::VariantBuilder vb;
467 vb.add_tuple({
468- {"id", unity::scopes::Variant("open")},
469- {"label", unity::scopes::Variant("Open")},
470+ {"id", usc::Variant("open")},
471+ {"label", usc::Variant("Open")},
472 });
473 buttons.add_attribute_value("actions", vb.end());
474
475- unity::scopes::PreviewWidgetList widgets{ image_widget, buttons };
476+ usc::PreviewWidget desc("desc", "text");
477+ desc.add_attribute_mapping("text", "description");
478+
479+ usc::PreviewWidgetList widgets{ header, desc, buttons };
480 reply->push(widgets);
481 }
482-
483
484=== modified file 'libertine-scope/query.cpp'
485--- libertine-scope/query.cpp 2016-01-19 21:10:09 +0000
486+++ libertine-scope/query.cpp 2016-05-05 15:35:57 +0000
487@@ -13,15 +13,17 @@
488 * You should have received a copy of the GNU General Public License
489 * along with this program. If not, see <http://www.gnu.org/licenses/>.
490 */
491+
492 #include "libertine-scope/query.h"
493-
494-#include "libertine-scope/applauncher.h"
495 #include "libertine-scope/container.h"
496-#include "libertine-scope/libertine.h"
497 #include <unity/scopes/CategorisedResult.h>
498 #include <unity/scopes/CategoryRenderer.h>
499 #include <unity/scopes/QueryBase.h>
500 #include <unity/scopes/SearchReply.h>
501+#include <QString>
502+#include <QStringList>
503+#include <QRegExp>
504+
505
506 namespace usc = unity::scopes;
507
508@@ -44,22 +46,13 @@
509 "title" : "title",
510 "art" : {
511 "field": "art",
512- "fill-mode": "fit"
513+ "fill-mode": "fit",
514+ "fallback": "image://theme/placeholder-app-icon"
515 }
516 }
517 }
518 )";
519
520-
521-/**
522- * Generates a ubuntu-application-launcher URI for a contained desktop file.
523- */
524-static std::string
525-app_uri(Container const& container, AppLauncher const& app)
526-{
527- return "appid://" + container.id() + "/" + app.id() + "/0.0";
528-}
529-
530 } // anonymous namespace
531
532
533@@ -79,29 +72,53 @@
534 }
535
536
537+unity::scopes::VariantMap
538+Query::settings() const
539+{
540+ return SearchQueryBase::settings();
541+}
542+
543+
544+QStringList
545+Query::blacklist() const
546+{
547+ QStringList blacklistedApps;
548+ auto blacklist = settings()["blacklist"];
549+ if (!blacklist.is_null()) {
550+ blacklistedApps = QString::fromStdString(blacklist.get_string())
551+ .remove("\"")
552+ .split(";", QString::SkipEmptyParts);
553+ }
554+ return blacklistedApps;
555+}
556+
557+
558 void Query::
559 run(usc::SearchReplyProxy const& reply)
560 {
561- usc::CannedQuery const& query(usc::SearchQueryBase::query());
562- std::string query_string = query.query_string();
563-
564+ auto blacklistedApps = blacklist();
565+ QRegExp re(QString::fromStdString(query().query_string()), Qt::CaseInsensitive);
566 Libertine::UPtr libertine = libertine_factory_();
567+
568 for (auto const& container: libertine->get_container_list())
569 {
570 auto category = reply->register_category(container->id(),
571 container->name(),
572 "Application",
573 usc::CategoryRenderer(CATEGORY_APPS_DISPLAY));
574-
575 for (auto const& app: container->app_launchers())
576 {
577- if (app.no_display())
578+ if (!(re.isEmpty() || QString::fromStdString(app.name()).contains(re))
579+ || blacklistedApps.contains(QString::fromStdString(app.name())))
580+ {
581 continue;
582+ }
583
584 usc::CategorisedResult result(category);
585 result.set_title(app.name());
586 result.set_art(app.icon());
587- result.set_uri(app_uri(*container, app));
588+ result.set_uri(app.uri());
589+ result["description"] = app.description();
590 if (!reply->push(result))
591 {
592 break;
593
594=== modified file 'libertine-scope/query.h'
595--- libertine-scope/query.h 2016-01-19 21:10:09 +0000
596+++ libertine-scope/query.h 2016-05-05 15:35:57 +0000
597@@ -20,6 +20,8 @@
598 #include <unity/scopes/ReplyProxyFwd.h>
599 #include <unity/scopes/SearchQueryBase.h>
600
601+class QStringList;
602+
603
604 /**
605 * Engine to run a specific scope query.
606@@ -40,7 +42,12 @@
607 void
608 run(unity::scopes::SearchReplyProxy const& reply) override;
609
610+ // Overriding base class method to add ability to test
611+ virtual unity::scopes::VariantMap settings() const;
612+
613 private:
614+ QStringList blacklist() const;
615+
616 Libertine::Factory libertine_factory_;
617 };
618
619
620=== modified file 'po/CMakeLists.txt'
621--- po/CMakeLists.txt 2015-12-29 21:50:58 +0000
622+++ po/CMakeLists.txt 2016-05-05 15:35:57 +0000
623@@ -1,5 +1,7 @@
624 intltool_update_potfile(
625 ALL
626+ KEYWORDS "_" "_:1,2" "N_" "N_:1,2"
627+ POTFILES_TEMPLATE POTFILES.in.in
628 GETTEXT_PACKAGE ${GETTEXT_PACKAGE}
629 )
630
631@@ -8,3 +10,12 @@
632 GETTEXT_PACKAGE ${GETTEXT_PACKAGE}
633 )
634
635+file(GLOB_RECURSE ALL_POFILES "*.po")
636+
637+add_custom_target(potfiles
638+ ALL
639+ SOURCES
640+ POTFILES.in.in
641+ ${GETTEXT_PACKAGE}.pot
642+ ${ALL_POFILES}
643+)
644
645=== removed file 'po/Makefile.in.in'
646--- po/Makefile.in.in 2015-12-29 21:50:58 +0000
647+++ po/Makefile.in.in 1970-01-01 00:00:00 +0000
648@@ -1,1 +0,0 @@
649-XGETTEXT_KEYWORDS=--c++ --keyword=_ --keyword=N_ --keyword=_:1,2
650
651=== removed file 'po/POTFILES.in'
652--- po/POTFILES.in 2016-01-19 21:10:09 +0000
653+++ po/POTFILES.in 1970-01-01 00:00:00 +0000
654@@ -1,21 +0,0 @@
655-libertine-scope/query.cpp
656-libertine-scope/container.cpp
657-libertine-scope/applauncher.cpp
658-libertine-scope/libertine.cpp
659-libertine-scope/preview.cpp
660-libertine-scope/scope.cpp
661-tests/fake_container.cpp
662-tests/fake_libertine.cpp
663-tests/test_scope.cpp
664-libertine-scope/preview.h
665-libertine-scope/libertine.h
666-libertine-scope/scope.h
667-libertine-scope/applauncher.h
668-libertine-scope/query.h
669-libertine-scope/container.h
670-libertine-scope/localization.h
671-tests/fake_container_json.h
672-tests/TypedScopeFixture.h
673-tests/fake_libertine.h
674-tests/scopefixture.h
675-tests/fake_container.h
676
677=== added file 'po/POTFILES.in.in'
678--- po/POTFILES.in.in 1970-01-01 00:00:00 +0000
679+++ po/POTFILES.in.in 2016-05-05 15:35:57 +0000
680@@ -0,0 +1,2 @@
681+[type: gettext/ini] data/libertine-scope.ini.in
682+@GENERATED_POTFILES@
683
684=== added file 'po/libertine-scope.pot'
685--- po/libertine-scope.pot 1970-01-01 00:00:00 +0000
686+++ po/libertine-scope.pot 2016-05-05 15:35:57 +0000
687@@ -0,0 +1,26 @@
688+# SOME DESCRIPTIVE TITLE.
689+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
690+# This file is distributed under the same license as the PACKAGE package.
691+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
692+#
693+#, fuzzy
694+msgid ""
695+msgstr ""
696+"Project-Id-Version: PACKAGE VERSION\n"
697+"Report-Msgid-Bugs-To: \n"
698+"POT-Creation-Date: 2016-04-27 14:37-0400\n"
699+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
700+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
701+"Language-Team: LANGUAGE <LL@li.org>\n"
702+"Language: \n"
703+"MIME-Version: 1.0\n"
704+"Content-Type: text/plain; charset=CHARSET\n"
705+"Content-Transfer-Encoding: 8bit\n"
706+
707+#: ../data/libertine-scope.ini.in.h:1
708+msgid "Legacy Applications Scope"
709+msgstr ""
710+
711+#: ../data/libertine-scope.ini.in.h:2
712+msgid "Deb-packaged X11-based legacy applications."
713+msgstr ""
714
715=== modified file 'tests/CMakeLists.txt'
716--- tests/CMakeLists.txt 2016-01-19 00:16:56 +0000
717+++ tests/CMakeLists.txt 2016-05-05 15:35:57 +0000
718@@ -6,7 +6,11 @@
719 add_executable(libertine_scope_tests
720 fake_container.cpp
721 fake_libertine.cpp
722+
723+ # tests
724 test_scope.cpp
725+ test_preview.cpp
726+ test_query.cpp
727 )
728
729 target_link_libraries(libertine_scope_tests
730@@ -16,6 +20,7 @@
731 gmock_main
732 )
733
734-add_test(test_scope
735- libertine_scope_tests
736-)
737+add_test(test_scope libertine_scope_tests)
738+add_test(test_preview libertine_scope_tests)
739+add_test(test_query libertine_scope_tests)
740+
741
742=== modified file 'tests/fake_container.cpp'
743--- tests/fake_container.cpp 2016-01-19 00:16:56 +0000
744+++ tests/fake_container.cpp 2016-05-05 15:35:57 +0000
745@@ -24,9 +24,28 @@
746 #include <QtCore/QString>
747
748
749+class TestAppLauncher : public AppLauncher
750+{
751+public:
752+ TestAppLauncher(const std::string& json)
753+ :AppLauncher()
754+ {
755+ auto doc = QJsonDocument::fromJson(QByteArray::fromStdString(json));
756+ auto obj = doc.object();
757+ name_ = obj["name"].toString().toStdString();
758+ if (obj["icons"].isArray())
759+ {
760+ icon_ = obj["icons"].toArray()[0].toString().toStdString();
761+ }
762+ description_ = obj["description"].toString().toStdString();
763+ uri_ = obj["uri"].toString().toStdString();
764+ }
765+};
766+
767+
768 FakeContainer::
769 FakeContainer(std::string const& json_string)
770-: Container("fake")
771+: Container("fakeId", "fakeName")
772 {
773 QJsonDocument json = QJsonDocument::fromJson(QByteArray::fromStdString(json_string), nullptr);
774 QJsonObject object = json.object();
775@@ -41,7 +60,7 @@
776 for (auto const& app: v.toArray())
777 {
778 auto json = QJsonDocument(app.toObject()).toJson().toStdString();
779- app_launcher_list_.emplace_back(AppLauncher(json));
780+ app_launcher_list_.emplace_back(TestAppLauncher(json));
781 }
782 }
783 }
784
785=== modified file 'tests/fake_container.h'
786--- tests/fake_container.h 2016-01-19 21:10:09 +0000
787+++ tests/fake_container.h 2016-05-05 15:35:57 +0000
788@@ -28,7 +28,7 @@
789 {
790 public:
791 explicit
792- FakeContainer(std::string const& json);
793+ FakeContainer(std::string const& container_id);
794
795 ~FakeContainer();
796 };
797
798=== modified file 'tests/fake_container_json.h'
799--- tests/fake_container_json.h 2016-01-19 00:16:56 +0000
800+++ tests/fake_container_json.h 2016-05-05 15:35:57 +0000
801@@ -30,7 +30,9 @@
802 ],
803 "mime_types": [],
804 "name": "Panel Manager",
805- "no_display": false
806+ "no_display": false,
807+ "description": "some description",
808+ "uri": "some/uri"
809 },
810 {
811 "desktop_file_name": "/home/someuser/.cache/libertine-container/fake1/rootfs/usr/share/applications/sakura.desktop",
812@@ -40,7 +42,9 @@
813 ],
814 "mime_types": [],
815 "name": "Sakura",
816- "no_display": false
817+ "no_display": false,
818+ "description": "some other description",
819+ "uri": "some/other/uri"
820 }
821 ]
822 }
823
824=== added file 'tests/test_preview.cpp'
825--- tests/test_preview.cpp 1970-01-01 00:00:00 +0000
826+++ tests/test_preview.cpp 2016-05-05 15:35:57 +0000
827@@ -0,0 +1,63 @@
828+/*
829+ * Copyright 2016 Canonical Ltd.
830+ *
831+ * This program is free software: you can redistribute it and/or modify it under
832+ * the terms of the GNU General Public License, version 3, as published by the
833+ * Free Software Foundation.
834+ *
835+ * This program is distributed in the hope that it will be useful,
836+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
837+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
838+ * GNU General Public License for more details.
839+ *
840+ * You should have received a copy of the GNU General Public License
841+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
842+ */
843+
844+#include "libertine-scope/preview.h"
845+#include <unity/scopes/Variant.h>
846+#include <gtest/gtest.h>
847+#include <unity/scopes/ActionMetadata.h>
848+#include <unity/scopes/testing/Result.h>
849+#include <unity/scopes/testing/MockPreviewReply.h>
850+#include <unity/scopes/PreviewWidget.h>
851+#include <memory>
852+#include <QDir>
853+
854+
855+TEST(TestPreview, pushesWidgetsWithAppInformation)
856+{
857+ unity::scopes::testing::Result result;
858+ unity::scopes::ActionMetadata metadata("en_US", "phone");
859+
860+ std::unique_ptr<unity::scopes::PreviewWidgetList> list(new unity::scopes::PreviewWidgetList());
861+ testing::NiceMock<unity::scopes::testing::MockPreviewReply> reply;
862+ EXPECT_CALL(reply, push(testing::_)).WillOnce(testing::SaveArg<0>(list.get()));
863+ unity::scopes::PreviewReplyProxy proxy(&reply, [](unity::scopes::PreviewReply*) {});
864+
865+ Preview preview(result, metadata);
866+ preview.run(proxy);
867+
868+ ASSERT_NE(nullptr, list);
869+ ASSERT_EQ(3, list->size());
870+
871+ auto header = list->front();
872+ EXPECT_EQ("hdr", header.id());
873+ EXPECT_EQ("header", header.widget_type());
874+ EXPECT_EQ("title", header.attribute_mappings()["title"]);
875+ EXPECT_EQ("art", header.attribute_mappings()["mascot"]);
876+
877+ list->pop_front();
878+ auto desc = list->front();
879+ EXPECT_EQ("desc", desc.id());
880+
881+ list->pop_front();
882+ auto buttons = list->front();
883+ EXPECT_EQ("buttons", buttons.id());
884+ EXPECT_EQ("actions", buttons.widget_type());
885+
886+ auto buttons_actions = buttons.attribute_values()["actions"].get_array();
887+ ASSERT_EQ(1, buttons_actions.size());
888+ EXPECT_EQ("open", buttons_actions[0].get_dict()["id"].get_string());
889+ EXPECT_EQ("Open", buttons_actions[0].get_dict()["label"].get_string());
890+}
891
892=== added file 'tests/test_query.cpp'
893--- tests/test_query.cpp 1970-01-01 00:00:00 +0000
894+++ tests/test_query.cpp 2016-05-05 15:35:57 +0000
895@@ -0,0 +1,210 @@
896+/*
897+ * Copyright 2016 Canonical Ltd.
898+ *
899+ * This program is free software: you can redistribute it and/or modify it under
900+ * the terms of the GNU General Public License, version 3, as published by the
901+ * Free Software Foundation.
902+ *
903+ * This program is distributed in the hope that it will be useful,
904+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
905+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
906+ * GNU General Public License for more details.
907+ *
908+ * You should have received a copy of the GNU General Public License
909+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
910+ */
911+
912+#include "libertine-scope/query.h"
913+#include "tests/fake_libertine.h"
914+#include <unity/scopes/SearchMetadata.h>
915+#include <unity/scopes/CannedQuery.h>
916+#include <unity/scopes/SearchReplyProxyFwd.h>
917+#include <unity/scopes/testing/MockSearchReply.h>
918+#include <unity/scopes/Category.h>
919+#include <vector>
920+#include <memory>
921+#include <gtest/gtest.h>
922+#include <gmock/gmock.h>
923+
924+namespace
925+{
926+const std::string LIBERTINE_OUTPUT_WITH_APPS = R"(
927+ {
928+ "name": "fake-container",
929+ "app_launchers": [{
930+ "name": "LibreOffice",
931+ "no_display": false,
932+ "uri": "appid://fake/libreoffice/0.0",
933+ "icons": ["file:///lo.png"],
934+ "description": "libreoffice!"
935+ }, {
936+ "name": "Linux",
937+ "no_display": true,
938+ "uri": "appid://fake/linux/0.0",
939+ "icons": ["file:///nix.png"],
940+ "description": "linux!"
941+ }, {
942+ "name": "Library",
943+ "no_display": false,
944+ "uri": "appid://fake/library/0.0",
945+ "icons": ["file:///lib.png"],
946+ "description": "library!"
947+ }]
948+ }
949+)";
950+
951+
952+class FakeCategory : public unity::scopes::Category
953+{
954+public:
955+ FakeCategory(std::string const& id, std::string const& title,
956+ std::string const& icon, unity::scopes::CategoryRenderer const& renderer) :
957+ unity::scopes::Category(id, title, icon, renderer)
958+ {
959+ }
960+
961+};
962+
963+
964+MATCHER_P4(ResultPropertiesMatch, title, art, description, uri, "")
965+{
966+ return arg.contains("title") && arg.contains("art") && arg.contains("description") && arg.contains("uri") &&
967+ arg["title"] == unity::scopes::Variant(title) &&
968+ arg["art"] == unity::scopes::Variant(art) &&
969+ arg["description"] == unity::scopes::Variant(description) &&
970+ arg["uri"] == unity::scopes::Variant(uri);
971+}
972+
973+
974+class TestQueryFixture : public ::testing::Test
975+{
976+public:
977+ TestQueryFixture()
978+ : metadata("en_US", "phone")
979+ , canned_query("libertine-scope")
980+ , reply()
981+ , proxy(&reply, [](unity::scopes::SearchReply*) {})
982+ , category(std::make_shared<FakeCategory>("fakeId", "fake-container", "Application", unity::scopes::CategoryRenderer()))
983+ {
984+ }
985+
986+ void expect_registry()
987+ {
988+ EXPECT_CALL(reply, register_category("fakeId", "fake-container", "Application", testing::_)).WillOnce(testing::Return(category));
989+ }
990+
991+ void expect_push(std::string title, std::string art, std::string description, std::string appId, bool success = true)
992+ {
993+ EXPECT_CALL(reply, push(testing::Matcher<unity::scopes::CategorisedResult const&>(ResultPropertiesMatch(title, art, description, appId)))).WillOnce(testing::Return(success));
994+ }
995+
996+ void expect_push_libreoffice(bool success = true)
997+ {
998+ expect_push("LibreOffice", "file:///lo.png", "libreoffice!", "appid://fake/libreoffice/0.0", success);
999+ }
1000+
1001+ void expect_push_library(bool success = true)
1002+ {
1003+ expect_push("Library", "file:///lib.png", "library!", "appid://fake/library/0.0", success);
1004+ }
1005+
1006+ void expect_push_linux(bool success = true)
1007+ {
1008+ expect_push("Linux", "file:///nix.png", "linux!", "appid://fake/linux/0.0", success);
1009+ }
1010+
1011+ unity::scopes::SearchMetadata metadata;
1012+ unity::scopes::CannedQuery canned_query;
1013+ testing::NiceMock<unity::scopes::testing::MockSearchReply> reply;
1014+ unity::scopes::SearchReplyProxy proxy;
1015+ std::shared_ptr<FakeCategory> category;
1016+};
1017+
1018+
1019+TEST_F(TestQueryFixture, returnsAllDisplayableAppsWithoutFilters)
1020+{
1021+ expect_registry();
1022+ expect_push_libreoffice();
1023+ expect_push_linux();
1024+ expect_push_library();
1025+
1026+ Query query(canned_query, metadata, []() {
1027+ return FakeLibertine::make_fake(LIBERTINE_OUTPUT_WITH_APPS);
1028+ });
1029+ query.run(proxy);
1030+}
1031+
1032+
1033+TEST_F(TestQueryFixture, returnsRegularExpressionFilteredListOfApps)
1034+{
1035+ expect_registry();
1036+ expect_push_libreoffice();
1037+ canned_query.set_query_string("li.*office");
1038+
1039+ Query query(canned_query, metadata, []() {
1040+ return FakeLibertine::make_fake(LIBERTINE_OUTPUT_WITH_APPS);
1041+ });
1042+ query.run(proxy);
1043+}
1044+
1045+
1046+TEST_F(TestQueryFixture, haltsFurtherPushesAfterFailedPush)
1047+{
1048+ expect_registry();
1049+ expect_push_libreoffice(false);
1050+
1051+ Query query(canned_query, metadata, []() {
1052+ return FakeLibertine::make_fake(LIBERTINE_OUTPUT_WITH_APPS);
1053+ });
1054+ query.run(proxy);
1055+}
1056+
1057+
1058+// Query class with faked out Settings
1059+class QueryWithFakeSettings : public Query
1060+{
1061+public:
1062+ QueryWithFakeSettings(unity::scopes::CannedQuery const& query,
1063+ unity::scopes::SearchMetadata const& metadata,
1064+ Libertine::Factory const& libertine_factory)
1065+ : Query(query, metadata, libertine_factory)
1066+ , settings_()
1067+ {
1068+ }
1069+
1070+ unity::scopes::VariantMap settings() const override
1071+ {
1072+ return settings_;
1073+ }
1074+
1075+ unity::scopes::VariantMap settings_;
1076+};
1077+
1078+
1079+TEST_F(TestQueryFixture, ignoresAnyBlacklistedApps)
1080+{
1081+ expect_registry();
1082+ expect_push_library();
1083+
1084+ QueryWithFakeSettings query(canned_query, metadata, []() {
1085+ return FakeLibertine::make_fake(LIBERTINE_OUTPUT_WITH_APPS);
1086+ });
1087+ query.settings_["blacklist"] = "LibreOffice;Linux";
1088+ query.run(proxy);
1089+}
1090+
1091+
1092+TEST_F(TestQueryFixture, stripsQuotationMarksFromBlacklist)
1093+{
1094+ expect_registry();
1095+ expect_push_linux();
1096+ expect_push_library();
1097+
1098+ QueryWithFakeSettings query(canned_query, metadata, []() {
1099+ return FakeLibertine::make_fake(LIBERTINE_OUTPUT_WITH_APPS);
1100+ });
1101+ query.settings_["blacklist"] = "\"LibreOffice\"";
1102+ query.run(proxy);
1103+}
1104+
1105+} // anonymous namespace
1106
1107=== modified file 'tests/test_scope.cpp'
1108--- tests/test_scope.cpp 2016-01-19 00:16:56 +0000
1109+++ tests/test_scope.cpp 2016-05-05 15:35:57 +0000
1110@@ -54,4 +54,3 @@
1111 SearchReplyProxy search_reply_proxy(&reply, [](unity::scopes::SearchReply*) {});
1112 search_query->run(search_reply_proxy);
1113 }
1114-

Subscribers

People subscribed via source and target branches