Merge lp:~dobey/unity-scope-click/sort-az into lp:unity-scope-click/devel

Proposed by dobey
Status: Merged
Approved by: dobey
Approved revision: 290
Merged at revision: 290
Proposed branch: lp:~dobey/unity-scope-click/sort-az
Merge into: lp:unity-scope-click/devel
Diff against target: 257 lines (+141/-20)
7 files modified
debian/control (+1/-0)
libclickscope/click/CMakeLists.txt (+1/-0)
libclickscope/click/interface.cpp (+38/-3)
libclickscope/click/interface.h (+1/-0)
libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-ubuntuone_webapp-ubuntuone_1.0.4.desktop (+0/-11)
libclickscope/tests/test_interface.cpp (+100/-1)
scope/clickapps/apps-query.cpp (+0/-5)
To merge this branch: bzr merge lp:~dobey/unity-scope-click/sort-az
Reviewer Review Type Date Requested Status
Alejandro J. Cura (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+222540@code.launchpad.net

Commit message

Sort installed apps alphabetically.
Add a test for the sort order.
Move the sorting back to find_installed_apps() to make testing easier.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
lp:~dobey/unity-scope-click/sort-az updated
286. By dobey

Use tolower on the titles when sorting, to avoid eBay sorting after Weather.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
lp:~dobey/unity-scope-click/sort-az updated
287. By dobey

Merge the fix-category branch in.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alejandro J. Cura (alecu) wrote :

The std::transform is happening twice for each comparison done during the sort; this looks bad cpu-wise;

One option to fix this is using a sorted map with the lowercased items as keys. Other option is moving the lowercasing to a method of Application, where we can cache it if needed.

Also, please move the sorting into its own function, and create unit tests for it.

review: Needs Fixing
lp:~dobey/unity-scope-click/sort-az updated
288. By dobey

Add dependency on libboost-locale-dev for building.
Move sorting of the apps list to a separate function.
Use boost::locale for sorting of apps by name.
If names are equal, sort based on package name.
Add tests for several different sorting cases.

289. By dobey

[ Rodney Dawes ]
* Remove unused method to fix failure building under gcc 4.9.
[ Rodney Dawes ]
* Handle some languages differently when submitting reviews. (LP:
  #1321154). Add runtime dependency on ubuntu-sdk-libs for the
  frameworks list. (LP: #1320975). Support hal+json in the search
  request. Fix issues in autopilot tests. Port autopilot tests to
  python3. Add README and HACKING files. (LP: #1226111). Translations
  updates. . (LP: #1321154, #1226111, #1320975)

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
lp:~dobey/unity-scope-click/sort-az updated
290. By dobey

Set the language in the other sorting tests as well, to prevent failures.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alejandro J. Cura (alecu) wrote :

Looks good to me.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2014-05-29 07:10:38 +0000
3+++ debian/control 2014-06-13 16:50:42 +0000
4@@ -6,6 +6,7 @@
5 dh-translations,
6 google-mock,
7 intltool,
8+ libboost-locale-dev,
9 libglib2.0-dev (>= 2.32),
10 libjsoncpp-dev,
11 libubuntu-download-manager-client-dev (>= 0.3+14.10.20140430-0ubuntu1),
12
13=== modified file 'libclickscope/click/CMakeLists.txt'
14--- libclickscope/click/CMakeLists.txt 2014-05-26 14:02:45 +0000
15+++ libclickscope/click/CMakeLists.txt 2014-06-13 16:50:42 +0000
16@@ -36,4 +36,5 @@
17 ${UBUNTUONE_LDFLAGS}
18 ${UBUNTU_DOWNLOAD_MANAGER_CLIENT_LDFLAGS}
19 ${UBUNTU_DOWNLOAD_MANAGER_COMMON_LDFLAGS}
20+ -lboost_locale
21 )
22
23=== modified file 'libclickscope/click/interface.cpp'
24--- libclickscope/click/interface.cpp 2014-06-09 16:49:10 +0000
25+++ libclickscope/click/interface.cpp 2014-06-13 16:50:42 +0000
26@@ -37,6 +37,9 @@
27 #include <sys/stat.h>
28 #include <map>
29
30+#include <boost/locale/collator.hpp>
31+#include <boost/locale/generator.hpp>
32+
33 #include <boost/property_tree/ptree.hpp>
34 #include <boost/property_tree/json_parser.hpp>
35 #include <boost/property_tree/exceptions.hpp>
36@@ -153,8 +156,7 @@
37 DESKTOP_FILE_GROUP,
38 DESKTOP_FILE_KEY_NAME,
39 domain);
40- struct stat times;
41- app.installed_time = stat(filename.c_str(), &times) == 0 ? times.st_mtime : 0;
42+
43 app.url = "application:///" + filename;
44 if (keyFile.has_key(DESKTOP_FILE_GROUP, DESKTOP_FILE_KEY_ICON)) {
45 app.icon_url = add_theme_scheme(keyFile.get_string(DESKTOP_FILE_GROUP,
46@@ -188,6 +190,39 @@
47 return app;
48 }
49
50+std::vector<click::Application> Interface::sort_apps(const std::vector<click::Application>& apps)
51+{
52+ std::vector<click::Application> result = apps;
53+ boost::locale::generator gen;
54+ const char* lang = getenv(click::Configuration::LANGUAGE_ENVVAR);
55+ if (lang == NULL) {
56+ lang = "C.UTF-8";
57+ }
58+ std::locale loc = gen(lang);
59+ std::locale::global(loc);
60+ typedef boost::locale::collator<char> coll_type;
61+
62+ // Sort applications alphabetically.
63+ std::sort(result.begin(), result.end(), [&loc](const Application& a,
64+ const Application& b) {
65+ bool lesser = false;
66+ int order = std::use_facet<coll_type>(loc)
67+ .compare(boost::locale::collator_base::quaternary,
68+ a.title, b.title);
69+ if (order == 0) {
70+ lesser = a.name < b.name;
71+ } else {
72+ // Because compare returns int, not bool, we have to check
73+ // that 0 is greater than the result, which tells us the
74+ // first element should be sorted priori
75+ lesser = order < 0;
76+ }
77+ return lesser;
78+ });
79+
80+ return result;
81+}
82+
83 /* find_installed_apps()
84 *
85 * Find all of the installed apps matching @search_query in a timeout.
86@@ -244,7 +279,7 @@
87 };
88
89 keyFileLocator->enumerateKeyFilesForInstalledApplications(enumerator);
90- return result;
91+ return sort_apps(result);
92 }
93
94 /* is_non_click_app()
95
96=== modified file 'libclickscope/click/interface.h'
97--- libclickscope/click/interface.h 2014-05-26 14:02:45 +0000
98+++ libclickscope/click/interface.h 2014-06-13 16:50:42 +0000
99@@ -81,6 +81,7 @@
100 const std::string& domain);
101 virtual Application load_app_from_desktop(const unity::util::IniParser& keyFile,
102 const std::string& filename);
103+ static std::vector<Application> sort_apps(const std::vector<Application>& apps);
104 virtual std::vector<Application> find_installed_apps(const std::string& search_query);
105
106 static bool is_non_click_app(const QString& filename);
107
108=== removed file 'libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-ubuntuone_webapp-ubuntuone_1.0.4.desktop'
109--- libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-ubuntuone_webapp-ubuntuone_1.0.4.desktop 2014-02-10 12:23:35 +0000
110+++ libclickscope/tests/applications/user/com.ubuntu.developer.webapps.webapp-ubuntuone_webapp-ubuntuone_1.0.4.desktop 1970-01-01 00:00:00 +0000
111@@ -1,11 +0,0 @@
112-[Desktop Entry]
113-Type=Application
114-Terminal=false
115-Exec=aa-exec-click -p com.ubuntu.developer.webapps.webapp-ubuntuone_webapp-ubuntuone_1.0.4 -- webbrowser-app --enable-back-forward --webappUrlPatterns=https?://one.ubuntu.com/*,https?://login.ubuntu.com/* --webapp https://one.ubuntu.com/
116-Name=Ubuntu One
117-Icon=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-ubuntuone/./ubuntuone.png
118-X-Ubuntu-Touch=true
119-X-Ubuntu-Single-Instance=true
120-Path=/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-ubuntuone
121-X-Ubuntu-Old-Icon=./ubuntuone.png
122-X-Ubuntu-Application-ID=com.ubuntu.developer.webapps.webapp-ubuntuone_webapp-ubuntuone_1.0.4
123
124=== modified file 'libclickscope/tests/test_interface.cpp'
125--- libclickscope/tests/test_interface.cpp 2014-06-09 16:42:23 +0000
126+++ libclickscope/tests/test_interface.cpp 2014-06-13 16:50:42 +0000
127@@ -53,7 +53,6 @@
128 // Maintaining this list here will become tedious over time.
129 static const std::vector<click::Application> non_desktop_applications =
130 {
131- {"com.ubuntu.developer.webapps.webapp-ubuntuone", "Ubuntu One", 0.0, "/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-ubuntuone/./ubuntuone.png", "application:///com.ubuntu.developer.webapps.webapp-ubuntuone_webapp-ubuntuone_1.0.4.desktop", "", ""},
132 {"com.ubuntu.stock-ticker-mobile", "Stock Ticker", 0.0, "/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.stock-ticker-mobile/icons/stock_icon_48.png", "application:///com.ubuntu.stock-ticker-mobile_stock-ticker-mobile_0.3.7.66.desktop", "", ""},
133 {"", "Weather", 0.0, "/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.weather/./weather64.png", "application:///com.ubuntu.weather_weather_1.0.168.desktop", "", ""},
134 {"com.ubuntu.developer.webapps.webapp-twitter", "Twitter", 0.0, "/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.developer.webapps.webapp-twitter/./twitter.png", "application:///com.ubuntu.developer.webapps.webapp-twitter_webapp-twitter_1.0.5.desktop", "", ""},
135@@ -182,6 +181,106 @@
136 EXPECT_TRUE(results.empty());
137 }
138
139+TEST(ClickInterface, testFindAppsInDirSorted)
140+{
141+ QSharedPointer<click::KeyFileLocator> keyFileLocator(
142+ new click::KeyFileLocator(
143+ testing::systemApplicationsDirectoryForTesting(),
144+ testing::userApplicationsDirectoryForTesting()));
145+
146+ click::Interface iface(keyFileLocator);
147+
148+ auto results = iface.find_installed_apps("ock");
149+
150+ const std::vector<click::Application> expected_results = {
151+ {"com.ubuntu.clock", "Clock", 0.0, "/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.clock/./clock64.png", "application:///com.ubuntu.clock_clock_1.0.300.desktop", "", ""},
152+ {"com.ubuntu.stock-ticker-mobile", "Stock Ticker", 0.0, "/usr/share/click/preinstalled/.click/users/@all/com.ubuntu.stock-ticker-mobile/icons/stock_icon_48.png", "application:///com.ubuntu.stock-ticker-mobile_stock-ticker-mobile_0.3.7.66.desktop", "", ""},
153+ };
154+ EXPECT_EQ(expected_results, results);
155+}
156+
157+TEST(ClickInterface, testSortApps)
158+{
159+ std::vector<click::Application> apps = {
160+ {"", "Sudoku", 0.0, "", "", "", ""},
161+ {"", "eBay", 0.0, "", "", "", ""},
162+ {"", "Facebook", 0.0, "", "", "", ""},
163+ {"", "Messaging", 0.0, "", "", "", ""},
164+ {"", "Contacts", 0.0, "", "", "", ""},
165+ };
166+
167+ std::vector<click::Application> expected = {
168+ {"", "Contacts", 0.0, "", "", "", ""},
169+ {"", "eBay", 0.0, "", "", "", ""},
170+ {"", "Facebook", 0.0, "", "", "", ""},
171+ {"", "Messaging", 0.0, "", "", "", ""},
172+ {"", "Sudoku", 0.0, "", "", "", ""},
173+ };
174+
175+ ASSERT_EQ(setenv(Configuration::LANGUAGE_ENVVAR, "en_US.UTF-8", 1), 0);
176+ EXPECT_EQ(expected, click::Interface::sort_apps(apps));
177+ ASSERT_EQ(unsetenv(Configuration::LANGUAGE_ENVVAR), 0);
178+}
179+
180+TEST(ClickInterface, testSortAppsWithDuplicates)
181+{
182+ std::vector<click::Application> apps = {
183+ {"com.sudoku.sudoku", "Sudoku", 0.0, "", "", "", ""},
184+ {"com.canonical.sudoku", "Sudoku", 0.0, "", "", "", ""},
185+ };
186+
187+ std::vector<click::Application> expected = {
188+ {"com.canonical.sudoku", "Sudoku", 0.0, "", "", "", ""},
189+ {"com.sudoku.sudoku", "Sudoku", 0.0, "", "", "", ""},
190+ };
191+
192+ ASSERT_EQ(setenv(Configuration::LANGUAGE_ENVVAR, "en_US.UTF-8", 1), 0);
193+ EXPECT_EQ(expected, click::Interface::sort_apps(apps));
194+ ASSERT_EQ(unsetenv(Configuration::LANGUAGE_ENVVAR), 0);
195+}
196+
197+TEST(ClickInterface, testSortAppsWithAccents)
198+{
199+ std::vector<click::Application> apps = {
200+ {"", "Robots", 0.0, "", "", "", ""},
201+ {"", "Æon", 0.0, "", "", "", ""},
202+ {"", "Contacts", 0.0, "", "", "", ""},
203+ {"", "Über", 0.0, "", "", "", ""},
204+ };
205+
206+ std::vector<click::Application> expected = {
207+ {"", "Æon", 0.0, "", "", "", ""},
208+ {"", "Contacts", 0.0, "", "", "", ""},
209+ {"", "Robots", 0.0, "", "", "", ""},
210+ {"", "Über", 0.0, "", "", "", ""},
211+ };
212+
213+ ASSERT_EQ(setenv(Configuration::LANGUAGE_ENVVAR, "en_US.UTF-8", 1), 0);
214+ EXPECT_EQ(expected, click::Interface::sort_apps(apps));
215+ ASSERT_EQ(unsetenv(Configuration::LANGUAGE_ENVVAR), 0);
216+}
217+
218+TEST(ClickInterface, testSortAppsMixedCharsets)
219+{
220+ std::vector<click::Application> apps = {
221+ {"", "Robots", 0.0, "", "", "", ""},
222+ {"", "汉字", 0.0, "", "", "", ""},
223+ {"", "漢字", 0.0, "", "", "", ""},
224+ {"", "Über", 0.0, "", "", "", ""},
225+ };
226+
227+ std::vector<click::Application> expected = {
228+ {"", "汉字", 0.0, "", "", "", ""},
229+ {"", "漢字", 0.0, "", "", "", ""},
230+ {"", "Robots", 0.0, "", "", "", ""},
231+ {"", "Über", 0.0, "", "", "", ""},
232+ };
233+
234+ ASSERT_EQ(setenv(Configuration::LANGUAGE_ENVVAR, "zh_CN.UTF-8", 1), 0);
235+ EXPECT_EQ(expected, click::Interface::sort_apps(apps));
236+ ASSERT_EQ(unsetenv(Configuration::LANGUAGE_ENVVAR), 0);
237+}
238+
239 TEST(ClickInterface, testFindAppByKeyword)
240 {
241 QSharedPointer<click::KeyFileLocator> keyFileLocator(
242
243=== modified file 'scope/clickapps/apps-query.cpp'
244--- scope/clickapps/apps-query.cpp 2014-06-10 20:40:33 +0000
245+++ scope/clickapps/apps-query.cpp 2014-06-13 16:50:42 +0000
246@@ -204,11 +204,6 @@
247 auto localResults = clickInterfaceInstance().find_installed_apps(
248 query);
249
250- // Sort applications so that newest come first.
251- std::sort(localResults.begin(), localResults.end(), [](const Application& a, const Application& b) {
252- return a.installed_time > b.installed_time;
253- });
254-
255 push_local_results(
256 searchReply,
257 localResults,

Subscribers

People subscribed via source and target branches

to all changes: