Merge lp:~stolowski/unity-scope-click/header-apps into lp:unity-scope-click/devel
- header-apps
- Merge into devel
Status: | Merged |
---|---|
Approved by: | dobey |
Approved revision: | 320 |
Merged at revision: | 317 |
Proposed branch: | lp:~stolowski/unity-scope-click/header-apps |
Merge into: | lp:unity-scope-click/devel |
Diff against target: |
981 lines (+509/-126) 17 files modified
CMakeLists.txt (+4/-3) cmake/UseGSettings.cmake (+42/-0) data/CMakeLists.txt (+2/-0) data/com.canonical.unity.clickscope.gschema.xml (+10/-0) debian/control (+1/-0) debian/unity-scope-click.install (+1/-0) libclickscope/click/CMakeLists.txt (+4/-0) libclickscope/click/configuration.cpp (+37/-0) libclickscope/click/configuration.h (+16/-0) libclickscope/tests/test_configuration.cpp (+27/-0) scope/clickapps/apps-query.cpp (+132/-61) scope/clickapps/apps-query.h (+29/-6) scope/clickapps/apps-scope.cpp (+2/-1) scope/tests/CMakeLists.txt (+44/-0) scope/tests/test_apps_query.cpp (+84/-0) scope/tests/test_helpers.h (+71/-0) scope/tests/test_query.cpp (+3/-55) |
To merge this branch: | bzr merge lp:~stolowski/unity-scope-click/header-apps |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Approve | |
Alejandro J. Cura (community) | Approve | ||
Review via email: mp+225844@code.launchpad.net |
Commit message
Display preloaded core apps at the top in a dedicated headerless category. The list of apps to be displayed can be overriden with a dconf key.
Description of the change
Display preloaded core apps at the top in a dedicated headerless category. The list of apps to be displayed can be overriden with a dconf key.
PS Jenkins bot (ps-jenkins) wrote : | # |
Alejandro J. Cura (alecu) wrote : | # |
Code looks good; seems to be missing libgsettings-qt-dev in debian/control
Will test it on device after jenkins approves.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:320
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Alejandro J. Cura (alecu) wrote : | # |
Tested on mako, looks wonderful.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
PS Jenkins bot (ps-jenkins) : | # |
Preview Diff
1 | === modified file 'CMakeLists.txt' | |||
2 | --- CMakeLists.txt 2014-06-23 15:00:28 +0000 | |||
3 | +++ CMakeLists.txt 2014-07-08 07:23:41 +0000 | |||
4 | @@ -20,6 +20,7 @@ | |||
5 | 20 | set(APPS_DATA_DIR ${CMAKE_INSTALL_FULL_DATADIR}/unity/scopes/clickapps/) | 20 | set(APPS_DATA_DIR ${CMAKE_INSTALL_FULL_DATADIR}/unity/scopes/clickapps/) |
6 | 21 | 21 | ||
7 | 22 | include(FindPkgConfig) | 22 | include(FindPkgConfig) |
8 | 23 | include(UseGSettings) | ||
9 | 23 | 24 | ||
10 | 24 | pkg_check_modules(UNITY_SCOPES REQUIRED libunity-scopes>=0.5.0 libunity-api>=0.1.3) | 25 | pkg_check_modules(UNITY_SCOPES REQUIRED libunity-scopes>=0.5.0 libunity-api>=0.1.3) |
11 | 25 | add_definitions(${UNITY_SCOPES_CFLAGS} ${UNITY_SCOPES_CFLAGS_OTHER}) | 26 | add_definitions(${UNITY_SCOPES_CFLAGS} ${UNITY_SCOPES_CFLAGS_OTHER}) |
12 | @@ -75,7 +76,7 @@ | |||
13 | 75 | 76 | ||
14 | 76 | # Custom targets for the tests | 77 | # Custom targets for the tests |
15 | 77 | add_custom_target (test | 78 | add_custom_target (test |
17 | 78 | DEPENDS test-click-scope test-libclickscope | 79 | DEPENDS test-click-scope test-apps-scope test-libclickscope |
18 | 79 | ) | 80 | ) |
19 | 80 | 81 | ||
20 | 81 | add_custom_target (test-disabled | 82 | add_custom_target (test-disabled |
21 | @@ -90,13 +91,13 @@ | |||
22 | 90 | 91 | ||
23 | 91 | # Add a custom target for running the tests under valgrind. | 92 | # Add a custom target for running the tests under valgrind. |
24 | 92 | add_custom_target (test-valgrind | 93 | add_custom_target (test-valgrind |
26 | 93 | DEPENDS test-click-scope-valgrind test-libclickscope-valgrind | 94 | DEPENDS test-click-scope-valgrind test-apps-scope-valgrind test-libclickscope-valgrind |
27 | 94 | ) | 95 | ) |
28 | 95 | 96 | ||
29 | 96 | # Add a custom target for running the tests under valgrind with the | 97 | # Add a custom target for running the tests under valgrind with the |
30 | 97 | # full leak checks enabled. | 98 | # full leak checks enabled. |
31 | 98 | add_custom_target (test-leaks | 99 | add_custom_target (test-leaks |
33 | 99 | DEPENDS test-click-scope-leaks test-libclickscope-leaks | 100 | DEPENDS test-click-scope-leaks test-apps-scope-leaks test-libclickscope-leaks |
34 | 100 | ) | 101 | ) |
35 | 101 | 102 | ||
36 | 102 | # Also let "make check" and partners work. | 103 | # Also let "make check" and partners work. |
37 | 103 | 104 | ||
38 | === added file 'cmake/UseGSettings.cmake' | |||
39 | --- cmake/UseGSettings.cmake 1970-01-01 00:00:00 +0000 | |||
40 | +++ cmake/UseGSettings.cmake 2014-07-08 07:23:41 +0000 | |||
41 | @@ -0,0 +1,42 @@ | |||
42 | 1 | # GSettings.cmake, CMake macros written for Marlin, feel free to re-use them. | ||
43 | 2 | |||
44 | 3 | option (GSETTINGS_LOCALINSTALL "Install GSettings Schemas locally instead of to the GLib prefix" ${LOCAL_INSTALL}) | ||
45 | 4 | |||
46 | 5 | option (GSETTINGS_COMPILE "Compile GSettings Schemas after installation" ${GSETTINGS_LOCALINSTALL}) | ||
47 | 6 | |||
48 | 7 | if(GSETTINGS_LOCALINSTALL) | ||
49 | 8 | message(STATUS "GSettings schemas will be installed locally.") | ||
50 | 9 | endif() | ||
51 | 10 | |||
52 | 11 | if(GSETTINGS_COMPILE) | ||
53 | 12 | message(STATUS "GSettings shemas will be compiled.") | ||
54 | 13 | endif() | ||
55 | 14 | |||
56 | 15 | macro(add_schema SCHEMA_NAME) | ||
57 | 16 | |||
58 | 17 | set(PKG_CONFIG_EXECUTABLE pkg-config) | ||
59 | 18 | # Have an option to not install the schema into where GLib is | ||
60 | 19 | if (GSETTINGS_LOCALINSTALL) | ||
61 | 20 | SET (GSETTINGS_DIR "${CMAKE_INSTALL_PREFIX}/share/glib-2.0/schemas/") | ||
62 | 21 | else (GSETTINGS_LOCALINSTALL) | ||
63 | 22 | execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} glib-2.0 --variable prefix OUTPUT_VARIABLE _glib_prefix OUTPUT_STRIP_TRAILING_WHITESPACE) | ||
64 | 23 | SET (GSETTINGS_DIR "${_glib_prefix}/share/glib-2.0/schemas/") | ||
65 | 24 | endif (GSETTINGS_LOCALINSTALL) | ||
66 | 25 | |||
67 | 26 | # Run the validator and error if it fails | ||
68 | 27 | execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} gio-2.0 --variable glib_compile_schemas OUTPUT_VARIABLE _glib_comple_schemas OUTPUT_STRIP_TRAILING_WHITESPACE) | ||
69 | 28 | execute_process (COMMAND ${_glib_comple_schemas} --dry-run --schema-file=${CMAKE_CURRENT_SOURCE_DIR}/${SCHEMA_NAME} ERROR_VARIABLE _schemas_invalid OUTPUT_STRIP_TRAILING_WHITESPACE) | ||
70 | 29 | |||
71 | 30 | if (_schemas_invalid) | ||
72 | 31 | message (SEND_ERROR "Schema validation error: ${_schemas_invalid}") | ||
73 | 32 | endif (_schemas_invalid) | ||
74 | 33 | |||
75 | 34 | # Actually install and recomple schemas | ||
76 | 35 | message (STATUS "GSettings schemas will be installed into ${GSETTINGS_DIR}") | ||
77 | 36 | install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/${SCHEMA_NAME} DESTINATION ${GSETTINGS_DIR} OPTIONAL) | ||
78 | 37 | |||
79 | 38 | if (GSETTINGS_COMPILE) | ||
80 | 39 | install (CODE "message (STATUS \"Compiling GSettings schemas\")") | ||
81 | 40 | install (CODE "execute_process (COMMAND ${_glib_comple_schemas} ${GSETTINGS_DIR})") | ||
82 | 41 | endif () | ||
83 | 42 | endmacro() | ||
84 | 0 | 43 | ||
85 | === modified file 'data/CMakeLists.txt' | |||
86 | --- data/CMakeLists.txt 2014-06-30 21:50:00 +0000 | |||
87 | +++ data/CMakeLists.txt 2014-07-08 07:23:41 +0000 | |||
88 | @@ -2,6 +2,8 @@ | |||
89 | 2 | set(STORE_INI_TARGET com.canonical.scopes.clickstore.ini) | 2 | set(STORE_INI_TARGET com.canonical.scopes.clickstore.ini) |
90 | 3 | set(APPS_INI_TARGET clickscope.ini) | 3 | set(APPS_INI_TARGET clickscope.ini) |
91 | 4 | 4 | ||
92 | 5 | add_schema(com.canonical.unity.clickscope.gschema.xml) | ||
93 | 6 | |||
94 | 5 | configure_file( | 7 | configure_file( |
95 | 6 | ${STORE_INI_TARGET}.in.in | 8 | ${STORE_INI_TARGET}.in.in |
96 | 7 | ${STORE_INI_TARGET}.in | 9 | ${STORE_INI_TARGET}.in |
97 | 8 | 10 | ||
98 | === added file 'data/com.canonical.unity.clickscope.gschema.xml' | |||
99 | --- data/com.canonical.unity.clickscope.gschema.xml 1970-01-01 00:00:00 +0000 | |||
100 | +++ data/com.canonical.unity.clickscope.gschema.xml 2014-07-08 07:23:41 +0000 | |||
101 | @@ -0,0 +1,10 @@ | |||
102 | 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
103 | 2 | <schemalist> | ||
104 | 3 | <schema path="/com/canonical/unity/clickscope/" id="com.canonical.Unity.ClickScope" gettext-domain="unity-scope-click"> | ||
105 | 4 | <key type="as" name="core-apps"> | ||
106 | 5 | <default>[]</default> | ||
107 | 6 | <summary>Applications to display in the top category of the Apps scope</summary> | ||
108 | 7 | <description>List of application IDs that will be displayed in the upper area of the Applications scope for quick access.</description> | ||
109 | 8 | </key> | ||
110 | 9 | </schema> | ||
111 | 10 | </schemalist> | ||
112 | 0 | 11 | ||
113 | === modified file 'debian/control' | |||
114 | --- debian/control 2014-06-23 15:00:28 +0000 | |||
115 | +++ debian/control 2014-07-08 07:23:41 +0000 | |||
116 | @@ -14,6 +14,7 @@ | |||
117 | 14 | libubuntuoneauth-2.0-dev, | 14 | libubuntuoneauth-2.0-dev, |
118 | 15 | libunity-api-dev (>= 7.80.7), | 15 | libunity-api-dev (>= 7.80.7), |
119 | 16 | libunity-scopes-dev (>= 0.5.0), | 16 | libunity-scopes-dev (>= 0.5.0), |
120 | 17 | libgsettings-qt-dev, | ||
121 | 17 | pkg-config, | 18 | pkg-config, |
122 | 18 | python3-all, | 19 | python3-all, |
123 | 19 | Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com> | 20 | Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com> |
124 | 20 | 21 | ||
125 | === modified file 'debian/unity-scope-click.install' | |||
126 | --- debian/unity-scope-click.install 2014-06-20 20:00:53 +0000 | |||
127 | +++ debian/unity-scope-click.install 2014-07-08 07:23:41 +0000 | |||
128 | @@ -1,4 +1,5 @@ | |||
129 | 1 | usr/lib/*/unity-scopes/* | 1 | usr/lib/*/unity-scopes/* |
130 | 2 | usr/lib/unity-scope-click/* | 2 | usr/lib/unity-scope-click/* |
131 | 3 | usr/share/unity/scopes/* | 3 | usr/share/unity/scopes/* |
132 | 4 | usr/share/glib-2.0/schemas/* | ||
133 | 4 | usr/share/locale/*/LC_MESSAGES/unity-scope-click.mo | 5 | usr/share/locale/*/LC_MESSAGES/unity-scope-click.mo |
134 | 5 | 6 | ||
135 | === modified file 'libclickscope/click/CMakeLists.txt' | |||
136 | --- libclickscope/click/CMakeLists.txt 2014-06-23 15:00:28 +0000 | |||
137 | +++ libclickscope/click/CMakeLists.txt 2014-07-08 07:23:41 +0000 | |||
138 | @@ -2,11 +2,13 @@ | |||
139 | 2 | SET (CMAKE_AUTOMOC ON) | 2 | SET (CMAKE_AUTOMOC ON) |
140 | 3 | find_package (Qt5Core REQUIRED) | 3 | find_package (Qt5Core REQUIRED) |
141 | 4 | pkg_check_modules(JSON_CPP REQUIRED jsoncpp) | 4 | pkg_check_modules(JSON_CPP REQUIRED jsoncpp) |
142 | 5 | pkg_check_modules(GSETTINGS_QT REQUIRED gsettings-qt) | ||
143 | 5 | 6 | ||
144 | 6 | add_definitions( | 7 | add_definitions( |
145 | 7 | -DGETTEXT_PACKAGE=\"${PROJECT_NAME}\" | 8 | -DGETTEXT_PACKAGE=\"${PROJECT_NAME}\" |
146 | 8 | -DGETTEXT_LOCALEDIR=\"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LOCALEDIR}\" | 9 | -DGETTEXT_LOCALEDIR=\"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LOCALEDIR}\" |
147 | 9 | -DCLICK_INSTALL_HELPER=\"${CMAKE_INSTALL_PREFIX}/lib/unity-scope-click/install-helper\" | 10 | -DCLICK_INSTALL_HELPER=\"${CMAKE_INSTALL_PREFIX}/lib/unity-scope-click/install-helper\" |
148 | 11 | ${GSETTINGS_QT_CFLAGS} ${GSETTINGS_QT_OTHER} | ||
149 | 10 | ) | 12 | ) |
150 | 11 | 13 | ||
151 | 12 | add_library(${SCOPE_LIB_NAME} STATIC | 14 | add_library(${SCOPE_LIB_NAME} STATIC |
152 | @@ -32,6 +34,7 @@ | |||
153 | 32 | 34 | ||
154 | 33 | include_directories( | 35 | include_directories( |
155 | 34 | ${JSON_CPP_INCLUDE_DIRS} | 36 | ${JSON_CPP_INCLUDE_DIRS} |
156 | 37 | ${GSETTINGS_QT_INCLUDE_DIRS} | ||
157 | 35 | ${CMAKE_SOURCE_DIR}/libclickscope | 38 | ${CMAKE_SOURCE_DIR}/libclickscope |
158 | 36 | ) | 39 | ) |
159 | 37 | 40 | ||
160 | @@ -41,5 +44,6 @@ | |||
161 | 41 | ${UBUNTUONE_LDFLAGS} | 44 | ${UBUNTUONE_LDFLAGS} |
162 | 42 | ${UBUNTU_DOWNLOAD_MANAGER_CLIENT_LDFLAGS} | 45 | ${UBUNTU_DOWNLOAD_MANAGER_CLIENT_LDFLAGS} |
163 | 43 | ${UBUNTU_DOWNLOAD_MANAGER_COMMON_LDFLAGS} | 46 | ${UBUNTU_DOWNLOAD_MANAGER_COMMON_LDFLAGS} |
164 | 47 | ${GSETTINGS_QT_LIBRARIES} | ||
165 | 44 | -lboost_locale | 48 | -lboost_locale |
166 | 45 | ) | 49 | ) |
167 | 46 | 50 | ||
168 | === modified file 'libclickscope/click/configuration.cpp' | |||
169 | --- libclickscope/click/configuration.cpp 2014-06-25 21:33:59 +0000 | |||
170 | +++ libclickscope/click/configuration.cpp 2014-07-08 07:23:41 +0000 | |||
171 | @@ -32,6 +32,11 @@ | |||
172 | 32 | 32 | ||
173 | 33 | #include <QDir> | 33 | #include <QDir> |
174 | 34 | #include <QProcess> | 34 | #include <QProcess> |
175 | 35 | #include <QStringList> | ||
176 | 36 | #include <QVariant> | ||
177 | 37 | #include <QDebug> | ||
178 | 38 | |||
179 | 39 | #include <qgsettings.h> | ||
180 | 35 | 40 | ||
181 | 36 | #include <boost/algorithm/string.hpp> | 41 | #include <boost/algorithm/string.hpp> |
182 | 37 | #include <boost/algorithm/string/replace.hpp> | 42 | #include <boost/algorithm/string/replace.hpp> |
183 | @@ -141,4 +146,36 @@ | |||
184 | 141 | != FULL_LANG_CODES.end(); | 146 | != FULL_LANG_CODES.end(); |
185 | 142 | } | 147 | } |
186 | 143 | 148 | ||
187 | 149 | const std::vector<std::string> Configuration::get_dconf_strings(const std::string& schema, const std::string& key) const | ||
188 | 150 | { | ||
189 | 151 | if (!QGSettings::isSchemaInstalled(schema.c_str())) | ||
190 | 152 | { | ||
191 | 153 | qWarning() << "Schema" << QString::fromStdString(schema) << "is missing"; | ||
192 | 154 | return std::vector<std::string>(); | ||
193 | 155 | } | ||
194 | 156 | QGSettings qgs(schema.c_str()); | ||
195 | 157 | std::vector<std::string> v; | ||
196 | 158 | if (qgs.keys().contains(QString::fromStdString(key))) | ||
197 | 159 | { | ||
198 | 160 | auto locations = qgs.get(QString::fromStdString(key)).toStringList(); | ||
199 | 161 | for(const auto& l : locations) { | ||
200 | 162 | v.push_back(l.toStdString()); | ||
201 | 163 | } | ||
202 | 164 | } | ||
203 | 165 | else | ||
204 | 166 | { | ||
205 | 167 | qWarning() << "No" << QString::fromStdString(key) << " key in schema" << QString::fromStdString(schema); | ||
206 | 168 | } | ||
207 | 169 | return v; | ||
208 | 170 | } | ||
209 | 171 | |||
210 | 172 | const std::vector<std::string> Configuration::get_core_apps() const | ||
211 | 173 | { | ||
212 | 174 | auto apps = get_dconf_strings(Configuration::COREAPPS_SCHEMA, Configuration::COREAPPS_KEY); | ||
213 | 175 | if (apps.empty()) { | ||
214 | 176 | apps = get_default_core_apps(); | ||
215 | 177 | } | ||
216 | 178 | return apps; | ||
217 | 179 | } | ||
218 | 180 | |||
219 | 144 | } // namespace click | 181 | } // namespace click |
220 | 145 | 182 | ||
221 | === modified file 'libclickscope/click/configuration.h' | |||
222 | --- libclickscope/click/configuration.h 2014-06-25 21:33:59 +0000 | |||
223 | +++ libclickscope/click/configuration.h 2014-07-08 07:23:41 +0000 | |||
224 | @@ -54,10 +54,26 @@ | |||
225 | 54 | virtual std::string get_accept_languages(); | 54 | virtual std::string get_accept_languages(); |
226 | 55 | static bool is_full_lang_code(const std::string& language); | 55 | static bool is_full_lang_code(const std::string& language); |
227 | 56 | 56 | ||
228 | 57 | constexpr static const char* COREAPPS_SCHEMA {"com.canonical.Unity.ClickScope"}; | ||
229 | 58 | constexpr static const char* COREAPPS_KEY {"coreApps"}; | ||
230 | 59 | |||
231 | 60 | virtual const std::vector<std::string> get_core_apps() const; | ||
232 | 57 | virtual ~Configuration() {} | 61 | virtual ~Configuration() {} |
233 | 58 | protected: | 62 | protected: |
234 | 59 | virtual std::vector<std::string> list_folder(const std::string &folder, const std::string &pattern); | 63 | virtual std::vector<std::string> list_folder(const std::string &folder, const std::string &pattern); |
235 | 60 | virtual std::string architectureFromDpkg(); | 64 | virtual std::string architectureFromDpkg(); |
236 | 65 | virtual const std::vector<std::string> get_dconf_strings(const std::string& schema, const std::string& key) const; | ||
237 | 66 | static const std::vector<std::string>& get_default_core_apps() { | ||
238 | 67 | static std::vector<std::string> default_apps { | ||
239 | 68 | "dialer-app", | ||
240 | 69 | "messaging-app", | ||
241 | 70 | "com.ubuntu.calculator", | ||
242 | 71 | "com.ubuntu.clock", | ||
243 | 72 | "com.ubuntu.camera", | ||
244 | 73 | "com.ubuntu.calendar" | ||
245 | 74 | }; | ||
246 | 75 | return default_apps; | ||
247 | 76 | } | ||
248 | 61 | }; | 77 | }; |
249 | 62 | 78 | ||
250 | 63 | } // namespace click | 79 | } // namespace click |
251 | 64 | 80 | ||
252 | === modified file 'libclickscope/tests/test_configuration.cpp' | |||
253 | --- libclickscope/tests/test_configuration.cpp 2014-06-25 21:33:59 +0000 | |||
254 | +++ libclickscope/tests/test_configuration.cpp 2014-07-08 07:23:41 +0000 | |||
255 | @@ -27,6 +27,8 @@ | |||
256 | 27 | * files in the program, then also delete it here. | 27 | * files in the program, then also delete it here. |
257 | 28 | */ | 28 | */ |
258 | 29 | 29 | ||
259 | 30 | #include <QStringList> | ||
260 | 31 | |||
261 | 30 | #include <gmock/gmock.h> | 32 | #include <gmock/gmock.h> |
262 | 31 | #include <gtest/gtest.h> | 33 | #include <gtest/gtest.h> |
263 | 32 | 34 | ||
264 | @@ -42,10 +44,35 @@ | |||
265 | 42 | public: | 44 | public: |
266 | 43 | MOCK_METHOD2(list_folder, std::vector<std::string>( | 45 | MOCK_METHOD2(list_folder, std::vector<std::string>( |
267 | 44 | const std::string& folder, const std::string& pattern)); | 46 | const std::string& folder, const std::string& pattern)); |
268 | 47 | MOCK_CONST_METHOD2(get_dconf_strings, const std::vector<std::string>(const std::string& schema, const std::string& key)); | ||
269 | 48 | using Configuration::get_default_core_apps; | ||
270 | 45 | }; | 49 | }; |
271 | 46 | 50 | ||
272 | 47 | } | 51 | } |
273 | 48 | 52 | ||
274 | 53 | TEST(Configuration, getCoreAppsFound) | ||
275 | 54 | { | ||
276 | 55 | using namespace ::testing; | ||
277 | 56 | FakeConfiguration c; | ||
278 | 57 | EXPECT_CALL(c, get_dconf_strings(Configuration::COREAPPS_SCHEMA, | ||
279 | 58 | Configuration::COREAPPS_KEY)) | ||
280 | 59 | .WillOnce(Return(std::vector<std::string>{"package1", "package2"})); | ||
281 | 60 | auto found_apps = c.get_core_apps(); | ||
282 | 61 | auto expected_apps = std::vector<std::string>{"package1", "package2"}; | ||
283 | 62 | ASSERT_EQ(found_apps, expected_apps); | ||
284 | 63 | } | ||
285 | 64 | |||
286 | 65 | TEST(Configuration, getCoreAppsEmpty) | ||
287 | 66 | { | ||
288 | 67 | using namespace ::testing; | ||
289 | 68 | FakeConfiguration c; | ||
290 | 69 | EXPECT_CALL(c, get_dconf_strings(Configuration::COREAPPS_SCHEMA, | ||
291 | 70 | Configuration::COREAPPS_KEY)) | ||
292 | 71 | .WillOnce(Return(std::vector<std::string>{})); | ||
293 | 72 | auto found_apps = c.get_core_apps(); | ||
294 | 73 | auto expected_apps = c.get_default_core_apps(); | ||
295 | 74 | ASSERT_EQ(found_apps, expected_apps); | ||
296 | 75 | } | ||
297 | 49 | 76 | ||
298 | 50 | TEST(Configuration, getAvailableFrameworksUsesRightFolder) | 77 | TEST(Configuration, getAvailableFrameworksUsesRightFolder) |
299 | 51 | { | 78 | { |
300 | 52 | 79 | ||
301 | === modified file 'scope/clickapps/apps-query.cpp' | |||
302 | --- scope/clickapps/apps-query.cpp 2014-06-30 20:06:33 +0000 | |||
303 | +++ scope/clickapps/apps-query.cpp 2014-07-08 07:23:41 +0000 | |||
304 | @@ -42,6 +42,7 @@ | |||
305 | 42 | 42 | ||
306 | 43 | #include <click/click-i18n.h> | 43 | #include <click/click-i18n.h> |
307 | 44 | #include "apps-query.h" | 44 | #include "apps-query.h" |
308 | 45 | #include <QDebug> | ||
309 | 45 | 46 | ||
310 | 46 | namespace | 47 | namespace |
311 | 47 | { | 48 | { |
312 | @@ -64,24 +65,6 @@ | |||
313 | 64 | } | 65 | } |
314 | 65 | )"; | 66 | )"; |
315 | 66 | 67 | ||
316 | 67 | std::string CATEGORY_APPS_SEARCH = R"( | ||
317 | 68 | { | ||
318 | 69 | "schema-version" : 1, | ||
319 | 70 | "template" : { | ||
320 | 71 | "category-layout" : "grid", | ||
321 | 72 | "card-layout" : "horizontal", | ||
322 | 73 | "card-size": "large" | ||
323 | 74 | }, | ||
324 | 75 | "components" : { | ||
325 | 76 | "title" : "title", | ||
326 | 77 | "mascot" : { | ||
327 | 78 | "field": "art" | ||
328 | 79 | }, | ||
329 | 80 | "subtitle": "publisher" | ||
330 | 81 | } | ||
331 | 82 | } | ||
332 | 83 | )"; | ||
333 | 84 | |||
334 | 85 | static const char CATEGORY_STORE[] = R"( | 68 | static const char CATEGORY_STORE[] = R"( |
335 | 86 | { | 69 | { |
336 | 87 | "template": { | 70 | "template": { |
337 | @@ -104,51 +87,138 @@ | |||
338 | 104 | 87 | ||
339 | 105 | } | 88 | } |
340 | 106 | 89 | ||
346 | 107 | void click::Query::push_local_results(scopes::SearchReplyProxy const &replyProxy, | 90 | click::apps::ResultPusher::ResultPusher(const scopes::SearchReplyProxy &replyProxy, const std::vector<std::string>& core_apps) |
347 | 108 | std::vector<click::Application> const &apps, | 91 | : replyProxy(replyProxy), |
348 | 109 | std::string &categoryTemplate) | 92 | core_apps(core_apps), |
349 | 110 | { | 93 | top_apps_lookup(core_apps.begin(), core_apps.end()) |
350 | 111 | scopes::CategoryRenderer rdr(categoryTemplate); | 94 | { |
351 | 95 | } | ||
352 | 96 | |||
353 | 97 | void click::apps::ResultPusher::push_result(scopes::Category::SCPtr& cat, const click::Application& a) | ||
354 | 98 | { | ||
355 | 99 | scopes::CategorisedResult res(cat); | ||
356 | 100 | res.set_title(a.title); | ||
357 | 101 | res.set_art(a.icon_url); | ||
358 | 102 | res.set_uri(a.url); | ||
359 | 103 | res[click::apps::Query::ResultKeys::NAME] = a.name; | ||
360 | 104 | res[click::apps::Query::ResultKeys::DESCRIPTION] = a.description; | ||
361 | 105 | res[click::apps::Query::ResultKeys::MAIN_SCREENSHOT] = a.main_screenshot; | ||
362 | 106 | res[click::apps::Query::ResultKeys::INSTALLED] = true; | ||
363 | 107 | res[click::apps::Query::ResultKeys::VERSION] = a.version; | ||
364 | 108 | replyProxy->push(res); | ||
365 | 109 | } | ||
366 | 110 | |||
367 | 111 | // | ||
368 | 112 | // Return an application identifier used to match applications against core-apps dconf key; | ||
369 | 113 | // For click apps, it just returns application name (e.g. com.canonical.calculator). | ||
370 | 114 | // For non-click apps, it return the desktop file name (without extension), taken from app uri. | ||
371 | 115 | std::string click::apps::ResultPusher::get_app_identifier(const click::Application& app) | ||
372 | 116 | { | ||
373 | 117 | static const std::string app_prefix("application:///"); | ||
374 | 118 | if (!app.name.empty()) | ||
375 | 119 | { | ||
376 | 120 | return app.name; | ||
377 | 121 | } | ||
378 | 122 | if (app.url.size() > app_prefix.size()) | ||
379 | 123 | { | ||
380 | 124 | auto i = app.url.rfind('.'); | ||
381 | 125 | if (i != std::string::npos) | ||
382 | 126 | { | ||
383 | 127 | return app.url.substr(app_prefix.size(), i - app_prefix.size()); | ||
384 | 128 | } | ||
385 | 129 | } | ||
386 | 130 | throw std::runtime_error("Cannot determine application identifier for" + app.url); | ||
387 | 131 | } | ||
388 | 132 | |||
389 | 133 | void click::apps::ResultPusher::push_local_results( | ||
390 | 134 | const std::vector<click::Application> &apps, | ||
391 | 135 | const std::string &categoryTemplate) | ||
392 | 136 | { | ||
393 | 137 | const scopes::CategoryRenderer rdr(categoryTemplate); | ||
394 | 112 | auto cat = replyProxy->register_category("local", _("My apps"), "", rdr); | 138 | auto cat = replyProxy->register_category("local", _("My apps"), "", rdr); |
395 | 113 | 139 | ||
396 | 114 | for(const auto & a: apps) | 140 | for(const auto & a: apps) |
397 | 115 | { | 141 | { |
419 | 116 | scopes::CategorisedResult res(cat); | 142 | try |
420 | 117 | res.set_title(a.title); | 143 | { |
421 | 118 | res.set_art(a.icon_url); | 144 | if (top_apps_lookup.size() == 0 || top_apps_lookup.find(get_app_identifier(a)) == top_apps_lookup.end()) |
422 | 119 | res.set_uri(a.url); | 145 | { |
423 | 120 | res[click::Query::ResultKeys::NAME] = a.name; | 146 | push_result(cat, a); |
424 | 121 | res[click::Query::ResultKeys::DESCRIPTION] = a.description; | 147 | } |
425 | 122 | res[click::Query::ResultKeys::MAIN_SCREENSHOT] = a.main_screenshot; | 148 | } |
426 | 123 | res[click::Query::ResultKeys::INSTALLED] = true; | 149 | catch (const std::runtime_error &e) |
427 | 124 | res[click::Query::ResultKeys::VERSION] = a.version; | 150 | { |
428 | 125 | replyProxy->push(res); | 151 | qWarning() << QString::fromStdString(e.what()); |
429 | 126 | } | 152 | } |
430 | 127 | } | 153 | } |
431 | 128 | 154 | } | |
432 | 129 | struct click::Query::Private | 155 | |
433 | 130 | { | 156 | void click::apps::ResultPusher::push_top_results( |
434 | 131 | Private(click::Index& index, const scopes::SearchMetadata& metadata) | 157 | const std::vector<click::Application>& apps, |
435 | 132 | : index(index), | 158 | const std::string& categoryTemplate) |
436 | 133 | meta(metadata) | 159 | { |
437 | 134 | { | 160 | const scopes::CategoryRenderer rdr(categoryTemplate); |
438 | 135 | } | 161 | auto cat = replyProxy->register_category("predefined", "", "", rdr); |
439 | 136 | click::Index& index; | 162 | |
440 | 163 | // | ||
441 | 164 | // iterate over all apps, insert those matching core apps into top_apps_to_push | ||
442 | 165 | std::map<std::string, click::Application> top_apps_to_push; | ||
443 | 166 | for (const auto& a: apps) | ||
444 | 167 | { | ||
445 | 168 | try | ||
446 | 169 | { | ||
447 | 170 | const auto id = get_app_identifier(a); | ||
448 | 171 | if (top_apps_lookup.find(id) != top_apps_lookup.end()) | ||
449 | 172 | { | ||
450 | 173 | top_apps_to_push[id] = a; | ||
451 | 174 | if (core_apps.size() == top_apps_to_push.size()) | ||
452 | 175 | { | ||
453 | 176 | // no need to iterate over remaining apps | ||
454 | 177 | break; | ||
455 | 178 | } | ||
456 | 179 | } | ||
457 | 180 | } | ||
458 | 181 | catch (const std::runtime_error &e) | ||
459 | 182 | { | ||
460 | 183 | qWarning() << QString::fromStdString(e.what()); | ||
461 | 184 | } | ||
462 | 185 | } | ||
463 | 186 | |||
464 | 187 | // | ||
465 | 188 | // iterate over core apps and insert them based on top_apps_to_push; | ||
466 | 189 | // this way the order of core apps is preserved. | ||
467 | 190 | for (const auto &a: core_apps) | ||
468 | 191 | { | ||
469 | 192 | auto const it = top_apps_to_push.find(a); | ||
470 | 193 | if (it != top_apps_to_push.end()) | ||
471 | 194 | { | ||
472 | 195 | push_result(cat, it->second); | ||
473 | 196 | } | ||
474 | 197 | } | ||
475 | 198 | } | ||
476 | 199 | |||
477 | 200 | struct click::apps::Query::Private | ||
478 | 201 | { | ||
479 | 202 | Private(const scopes::SearchMetadata& metadata) | ||
480 | 203 | : meta(metadata) | ||
481 | 204 | { | ||
482 | 205 | } | ||
483 | 137 | scopes::SearchMetadata meta; | 206 | scopes::SearchMetadata meta; |
484 | 207 | click::Configuration configuration; | ||
485 | 138 | }; | 208 | }; |
486 | 139 | 209 | ||
488 | 140 | click::Query::Query(unity::scopes::CannedQuery const& query, click::Index& index, scopes::SearchMetadata const& metadata) | 210 | click::apps::Query::Query(unity::scopes::CannedQuery const& query, scopes::SearchMetadata const& metadata) |
489 | 141 | : unity::scopes::SearchQueryBase(query, metadata), | 211 | : unity::scopes::SearchQueryBase(query, metadata), |
491 | 142 | impl(new Private(index, metadata)) | 212 | impl(new Private(metadata)) |
492 | 143 | { | 213 | { |
493 | 144 | } | 214 | } |
494 | 145 | 215 | ||
496 | 146 | void click::Query::cancelled() | 216 | void click::apps::Query::cancelled() |
497 | 147 | { | 217 | { |
498 | 148 | qDebug() << "cancelling search of" << QString::fromStdString(query().query_string()); | 218 | qDebug() << "cancelling search of" << QString::fromStdString(query().query_string()); |
499 | 149 | } | 219 | } |
500 | 150 | 220 | ||
502 | 151 | click::Query::~Query() | 221 | click::apps::Query::~Query() |
503 | 152 | { | 222 | { |
504 | 153 | qDebug() << "destroying search"; | 223 | qDebug() << "destroying search"; |
505 | 154 | } | 224 | } |
506 | @@ -165,7 +235,7 @@ | |||
507 | 165 | 235 | ||
508 | 166 | } | 236 | } |
509 | 167 | 237 | ||
511 | 168 | void click::Query::add_fake_store_app(scopes::SearchReplyProxy const& searchReply) | 238 | void click::apps::Query::add_fake_store_app(scopes::SearchReplyProxy const& searchReply) |
512 | 169 | { | 239 | { |
513 | 170 | static const std::string title = _("Ubuntu Store"); | 240 | static const std::string title = _("Ubuntu Store"); |
514 | 171 | static const std::string cat_title = _("Get more apps from the store"); | 241 | static const std::string cat_title = _("Get more apps from the store"); |
515 | @@ -185,27 +255,28 @@ | |||
516 | 185 | res.set_title(title); | 255 | res.set_title(title); |
517 | 186 | res.set_art(STORE_DATA_DIR "/store-scope-icon.svg"); | 256 | res.set_art(STORE_DATA_DIR "/store-scope-icon.svg"); |
518 | 187 | res.set_uri(store_scope.to_uri()); | 257 | res.set_uri(store_scope.to_uri()); |
524 | 188 | res[click::Query::ResultKeys::NAME] = title; | 258 | res[click::apps::Query::ResultKeys::NAME] = title; |
525 | 189 | res[click::Query::ResultKeys::DESCRIPTION] = ""; | 259 | res[click::apps::Query::ResultKeys::DESCRIPTION] = ""; |
526 | 190 | res[click::Query::ResultKeys::MAIN_SCREENSHOT] = ""; | 260 | res[click::apps::Query::ResultKeys::MAIN_SCREENSHOT] = ""; |
527 | 191 | res[click::Query::ResultKeys::INSTALLED] = true; | 261 | res[click::apps::Query::ResultKeys::INSTALLED] = true; |
528 | 192 | res[click::Query::ResultKeys::VERSION] = ""; | 262 | res[click::apps::Query::ResultKeys::VERSION] = ""; |
529 | 193 | searchReply->push(res); | 263 | searchReply->push(res); |
530 | 194 | } | 264 | } |
531 | 195 | } | 265 | } |
532 | 196 | 266 | ||
534 | 197 | void click::Query::run(scopes::SearchReplyProxy const& searchReply) | 267 | void click::apps::Query::run(scopes::SearchReplyProxy const& searchReply) |
535 | 198 | { | 268 | { |
536 | 269 | const std::string categoryTemplate = CATEGORY_APPS_DISPLAY; | ||
537 | 199 | auto querystr = query().query_string(); | 270 | auto querystr = query().query_string(); |
539 | 200 | std::string categoryTemplate = CATEGORY_APPS_SEARCH; | 271 | |
540 | 272 | ResultPusher pusher(searchReply, querystr.empty() ? impl->configuration.get_core_apps() : std::vector<std::string>()); | ||
541 | 273 | auto localResults = clickInterfaceInstance().find_installed_apps(querystr); | ||
542 | 274 | |||
543 | 201 | if (querystr.empty()) { | 275 | if (querystr.empty()) { |
545 | 202 | categoryTemplate = CATEGORY_APPS_DISPLAY; | 276 | pusher.push_top_results(localResults, categoryTemplate); |
546 | 203 | } | 277 | } |
547 | 204 | auto localResults = clickInterfaceInstance().find_installed_apps( | ||
548 | 205 | querystr); | ||
549 | 206 | 278 | ||
552 | 207 | push_local_results( | 279 | pusher.push_local_results( |
551 | 208 | searchReply, | ||
553 | 209 | localResults, | 280 | localResults, |
554 | 210 | categoryTemplate); | 281 | categoryTemplate); |
555 | 211 | 282 | ||
556 | 212 | 283 | ||
557 | === modified file 'scope/clickapps/apps-query.h' | |||
558 | --- scope/clickapps/apps-query.h 2014-05-28 14:27:28 +0000 | |||
559 | +++ scope/clickapps/apps-query.h 2014-07-08 07:23:41 +0000 | |||
560 | @@ -37,14 +37,19 @@ | |||
561 | 37 | 37 | ||
562 | 38 | #include <QSharedPointer> | 38 | #include <QSharedPointer> |
563 | 39 | #include <set> | 39 | #include <set> |
564 | 40 | #include <unordered_set> | ||
565 | 40 | 41 | ||
566 | 41 | 42 | ||
567 | 42 | namespace click | 43 | namespace click |
568 | 43 | { | 44 | { |
569 | 44 | 45 | ||
570 | 45 | class Application; | 46 | class Application; |
571 | 47 | class Configuration; | ||
572 | 46 | class Index; | 48 | class Index; |
573 | 47 | 49 | ||
574 | 50 | namespace apps | ||
575 | 51 | { | ||
576 | 52 | |||
577 | 48 | class Query : public scopes::SearchQueryBase | 53 | class Query : public scopes::SearchQueryBase |
578 | 49 | { | 54 | { |
579 | 50 | public: | 55 | public: |
580 | @@ -60,7 +65,7 @@ | |||
581 | 60 | constexpr static const char* VERSION{"version"}; | 65 | constexpr static const char* VERSION{"version"}; |
582 | 61 | }; | 66 | }; |
583 | 62 | 67 | ||
585 | 63 | Query(unity::scopes::CannedQuery const& query, click::Index& index, scopes::SearchMetadata const& metadata); | 68 | Query(unity::scopes::CannedQuery const& query, scopes::SearchMetadata const& metadata); |
586 | 64 | virtual ~Query(); | 69 | virtual ~Query(); |
587 | 65 | 70 | ||
588 | 66 | virtual void cancelled() override; | 71 | virtual void cancelled() override; |
589 | @@ -69,14 +74,32 @@ | |||
590 | 69 | 74 | ||
591 | 70 | protected: | 75 | protected: |
592 | 71 | virtual void add_fake_store_app(scopes::SearchReplyProxy const &replyProxy); | 76 | virtual void add_fake_store_app(scopes::SearchReplyProxy const &replyProxy); |
593 | 72 | virtual void push_local_results(scopes::SearchReplyProxy const &replyProxy, | ||
594 | 73 | std::vector<click::Application> const &apps, | ||
595 | 74 | std::string& categoryTemplate); | ||
596 | 75 | |||
597 | 76 | private: | 77 | private: |
598 | 77 | struct Private; | 78 | struct Private; |
599 | 78 | QSharedPointer<Private> impl; | 79 | QSharedPointer<Private> impl; |
600 | 79 | }; | 80 | }; |
602 | 80 | } | 81 | |
603 | 82 | class ResultPusher | ||
604 | 83 | { | ||
605 | 84 | const scopes::SearchReplyProxy &replyProxy; | ||
606 | 85 | std::vector<std::string> core_apps; | ||
607 | 86 | std::unordered_set<std::string> top_apps_lookup; | ||
608 | 87 | |||
609 | 88 | public: | ||
610 | 89 | ResultPusher(const scopes::SearchReplyProxy &replyProxy, const std::vector<std::string>& core_apps); | ||
611 | 90 | virtual ~ResultPusher() = default; | ||
612 | 91 | |||
613 | 92 | virtual void push_local_results(const std::vector<click::Application> &apps, | ||
614 | 93 | const std::string& categoryTemplate); | ||
615 | 94 | |||
616 | 95 | virtual void push_top_results( | ||
617 | 96 | const std::vector<click::Application>& apps, | ||
618 | 97 | const std::string& categoryTemplate); | ||
619 | 98 | protected: | ||
620 | 99 | virtual void push_result(scopes::Category::SCPtr& cat, const click::Application& a); | ||
621 | 100 | static std::string get_app_identifier(const click::Application& app); | ||
622 | 101 | }; | ||
623 | 102 | } // namespace apps | ||
624 | 103 | } // namespace query | ||
625 | 81 | 104 | ||
626 | 82 | #endif // CLICK_QUERY_H | 105 | #endif // CLICK_QUERY_H |
627 | 83 | 106 | ||
628 | === modified file 'scope/clickapps/apps-scope.cpp' | |||
629 | --- scope/clickapps/apps-scope.cpp 2014-06-18 16:23:50 +0000 | |||
630 | +++ scope/clickapps/apps-scope.cpp 2014-07-08 07:23:41 +0000 | |||
631 | @@ -42,6 +42,7 @@ | |||
632 | 42 | #include "apps-scope.h" | 42 | #include "apps-scope.h" |
633 | 43 | #include "apps-query.h" | 43 | #include "apps-query.h" |
634 | 44 | 44 | ||
635 | 45 | using namespace click; | ||
636 | 45 | 46 | ||
637 | 46 | click::Scope::Scope() | 47 | click::Scope::Scope() |
638 | 47 | { | 48 | { |
639 | @@ -78,7 +79,7 @@ | |||
640 | 78 | 79 | ||
641 | 79 | scopes::SearchQueryBase::UPtr click::Scope::search(unity::scopes::CannedQuery const& q, scopes::SearchMetadata const& metadata) | 80 | scopes::SearchQueryBase::UPtr click::Scope::search(unity::scopes::CannedQuery const& q, scopes::SearchMetadata const& metadata) |
642 | 80 | { | 81 | { |
644 | 81 | return scopes::SearchQueryBase::UPtr(new click::Query(q, *index, metadata)); | 82 | return scopes::SearchQueryBase::UPtr(new click::apps::Query(q, metadata)); |
645 | 82 | } | 83 | } |
646 | 83 | 84 | ||
647 | 84 | 85 | ||
648 | 85 | 86 | ||
649 | === modified file 'scope/tests/CMakeLists.txt' | |||
650 | --- scope/tests/CMakeLists.txt 2014-06-23 15:00:28 +0000 | |||
651 | +++ scope/tests/CMakeLists.txt 2014-07-08 07:23:41 +0000 | |||
652 | @@ -1,4 +1,5 @@ | |||
653 | 1 | set (CLICKSCOPE_TESTS_TARGET click-scope-tests) | 1 | set (CLICKSCOPE_TESTS_TARGET click-scope-tests) |
654 | 2 | set (APPS_SCOPE_TESTS_TARGET apps-scope-tests) | ||
655 | 2 | find_package(Threads) | 3 | find_package(Threads) |
656 | 3 | 4 | ||
657 | 4 | # Qt5 bits | 5 | # Qt5 bits |
658 | @@ -19,7 +20,12 @@ | |||
659 | 19 | test_query.cpp | 20 | test_query.cpp |
660 | 20 | ) | 21 | ) |
661 | 21 | 22 | ||
662 | 23 | add_executable (${APPS_SCOPE_TESTS_TARGET} | ||
663 | 24 | test_apps_query.cpp | ||
664 | 25 | ) | ||
665 | 26 | |||
666 | 22 | qt5_use_modules(${CLICKSCOPE_TESTS_TARGET} Core DBus Network Test) | 27 | qt5_use_modules(${CLICKSCOPE_TESTS_TARGET} Core DBus Network Test) |
667 | 28 | qt5_use_modules(${APPS_SCOPE_TESTS_TARGET} Core DBus Network Test) | ||
668 | 23 | 29 | ||
669 | 24 | target_link_libraries(${CLICKSCOPE_TESTS_TARGET} | 30 | target_link_libraries(${CLICKSCOPE_TESTS_TARGET} |
670 | 25 | ${STORE_LIB_UNVERSIONED} | 31 | ${STORE_LIB_UNVERSIONED} |
671 | @@ -37,6 +43,22 @@ | |||
672 | 37 | ${CMAKE_THREAD_LIBS_INIT} | 43 | ${CMAKE_THREAD_LIBS_INIT} |
673 | 38 | ) | 44 | ) |
674 | 39 | 45 | ||
675 | 46 | target_link_libraries(${APPS_SCOPE_TESTS_TARGET} | ||
676 | 47 | ${APPS_LIB_UNVERSIONED} | ||
677 | 48 | ${SCOPE_LIB_NAME} | ||
678 | 49 | |||
679 | 50 | ${UNITY_SCOPES_LDFLAGS} | ||
680 | 51 | ${UBUNTUONE_LDFLAGS} | ||
681 | 52 | ${UBUNTU_DOWNLOAD_MANAGER_CLIENT_LDFLAGS} | ||
682 | 53 | ${UBUNTU_DOWNLOAD_MANAGER_COMMON_LDFLAGS} | ||
683 | 54 | ${JSON_CPP_LDFLAGS} | ||
684 | 55 | |||
685 | 56 | gmock | ||
686 | 57 | gmock_main | ||
687 | 58 | |||
688 | 59 | ${CMAKE_THREAD_LIBS_INIT} | ||
689 | 60 | ) | ||
690 | 61 | |||
691 | 40 | add_custom_target (test-click-scope | 62 | add_custom_target (test-click-scope |
692 | 41 | COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${CLICKSCOPE_TESTS_TARGET} | 63 | COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${CLICKSCOPE_TESTS_TARGET} |
693 | 42 | DEPENDS ${CLICKSCOPE_TESTS_TARGET} | 64 | DEPENDS ${CLICKSCOPE_TESTS_TARGET} |
694 | @@ -56,6 +78,28 @@ | |||
695 | 56 | DEPENDS ${CLICKSCOPE_TESTS_TARGET} | 78 | DEPENDS ${CLICKSCOPE_TESTS_TARGET} |
696 | 57 | ) | 79 | ) |
697 | 58 | 80 | ||
698 | 81 | # --- | ||
699 | 82 | |||
700 | 83 | add_custom_target (test-apps-scope | ||
701 | 84 | COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${APPS_SCOPE_TESTS_TARGET} | ||
702 | 85 | DEPENDS ${APPS_SCOPE_TESTS_TARGET} | ||
703 | 86 | ) | ||
704 | 87 | |||
705 | 88 | add_custom_target(test-apps-scope-valgrind | ||
706 | 89 | COMMAND valgrind --tool=memcheck ${CMAKE_CURRENT_BINARY_DIR}/${APPS_SCOPE_TESTS_TARGET} | ||
707 | 90 | DEPENDS ${APPS_SCOPE_TESTS_TARGET} | ||
708 | 91 | ) | ||
709 | 92 | |||
710 | 93 | add_custom_target(test-apps-scope-leaks | ||
711 | 94 | COMMAND valgrind --tool=memcheck --track-origins=yes --num-callers=40 --leak-resolution=high --leak-check=full ${CMAKE_CURRENT_BINARY_DIR}/${APPS_SCOPE_TESTS_TARGET} | ||
712 | 95 | DEPENDS ${APPS_SCOPE_TESTS_TARGET} | ||
713 | 96 | ) | ||
714 | 97 | add_custom_target (test-apps-scope-disabled | ||
715 | 98 | COMMAND GTEST_ALSO_RUN_DISABLED_TESTS=1 ${CMAKE_CURRENT_BINARY_DIR}/${APPS_SCOPE_TESTS_TARGET} | ||
716 | 99 | DEPENDS ${APPS_SCOPE_TESTS_TARGET} | ||
717 | 100 | ) | ||
718 | 101 | |||
719 | 102 | |||
720 | 59 | add_subdirectory(integration) | 103 | add_subdirectory(integration) |
721 | 60 | add_subdirectory(download_manager_tool) | 104 | add_subdirectory(download_manager_tool) |
722 | 61 | add_subdirectory(click_interface_tool) | 105 | add_subdirectory(click_interface_tool) |
723 | 62 | 106 | ||
724 | === added file 'scope/tests/test_apps_query.cpp' | |||
725 | --- scope/tests/test_apps_query.cpp 1970-01-01 00:00:00 +0000 | |||
726 | +++ scope/tests/test_apps_query.cpp 2014-07-08 07:23:41 +0000 | |||
727 | @@ -0,0 +1,84 @@ | |||
728 | 1 | /* | ||
729 | 2 | * Copyright (C) 2014 Canonical Ltd. | ||
730 | 3 | * | ||
731 | 4 | * This program is free software: you can redistribute it and/or modify it | ||
732 | 5 | * under the terms of the GNU General Public License version 3, as published | ||
733 | 6 | * by the Free Software Foundation. | ||
734 | 7 | * | ||
735 | 8 | * This program is distributed in the hope that it will be useful, but | ||
736 | 9 | * WITHOUT ANY WARRANTY; without even the implied warranties of | ||
737 | 10 | * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
738 | 11 | * PURPOSE. See the GNU General Public License for more details. | ||
739 | 12 | * | ||
740 | 13 | * You should have received a copy of the GNU General Public License along | ||
741 | 14 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
742 | 15 | * | ||
743 | 16 | * In addition, as a special exception, the copyright holders give | ||
744 | 17 | * permission to link the code of portions of this program with the | ||
745 | 18 | * OpenSSL library under certain conditions as described in each | ||
746 | 19 | * individual source file, and distribute linked combinations | ||
747 | 20 | * including the two. | ||
748 | 21 | * You must obey the GNU General Public License in all respects | ||
749 | 22 | * for all of the code used other than OpenSSL. If you modify | ||
750 | 23 | * file(s) with this exception, you may extend this exception to your | ||
751 | 24 | * version of the file(s), but you are not obligated to do so. If you | ||
752 | 25 | * do not wish to do so, delete this exception statement from your | ||
753 | 26 | * version. If you delete this exception statement from all source | ||
754 | 27 | * files in the program, then also delete it here. | ||
755 | 28 | */ | ||
756 | 29 | |||
757 | 30 | #include <string> | ||
758 | 31 | #include <memory> | ||
759 | 32 | |||
760 | 33 | #include <gtest/gtest.h> | ||
761 | 34 | #include <gmock/gmock.h> | ||
762 | 35 | |||
763 | 36 | #include <clickapps/apps-query.h> | ||
764 | 37 | |||
765 | 38 | #include <unity/scopes/SearchReply.h> | ||
766 | 39 | #include <unity/scopes/testing/MockSearchReply.h> | ||
767 | 40 | |||
768 | 41 | #include "test_helpers.h" | ||
769 | 42 | |||
770 | 43 | using namespace click::test::helpers; | ||
771 | 44 | using namespace ::testing; | ||
772 | 45 | |||
773 | 46 | class ResultPusherTest : public ::testing::Test | ||
774 | 47 | { | ||
775 | 48 | protected: | ||
776 | 49 | scopes::SearchReplyProxy reply; | ||
777 | 50 | public: | ||
778 | 51 | ResultPusherTest() | ||
779 | 52 | { | ||
780 | 53 | reply.reset(new scopes::testing::MockSearchReply()); | ||
781 | 54 | } | ||
782 | 55 | }; | ||
783 | 56 | |||
784 | 57 | MATCHER_P(HasApplicationTitle, n, "") { return arg["title"].get_string() == n; } | ||
785 | 58 | |||
786 | 59 | TEST_F(ResultPusherTest, testPushTopAndLocalResults) | ||
787 | 60 | { | ||
788 | 61 | std::string categoryTemplate("{}"); | ||
789 | 62 | std::vector<click::Application> apps { | ||
790 | 63 | {"app1", "App1", 0.0f, "icon", "url", "", "sshot"}, | ||
791 | 64 | {"app2", "App2", 0.0f, "icon", "url", "", "sshot"}, | ||
792 | 65 | {"app3", "App3", 0.0f, "icon", "url", "", "sshot"}, | ||
793 | 66 | {"", "App4", 0.0f, "icon", "application:///app4.desktop", "", "sshot"} // a non-click app | ||
794 | 67 | }; | ||
795 | 68 | |||
796 | 69 | click::apps::ResultPusher pusher(reply, {"app2", "app4"}); | ||
797 | 70 | auto mockreply = (scopes::testing::MockSearchReply*)reply.get(); | ||
798 | 71 | |||
799 | 72 | scopes::CategoryRenderer renderer("{}"); | ||
800 | 73 | auto ptrCat = std::make_shared<FakeCategory>("id", "", "", renderer); | ||
801 | 74 | |||
802 | 75 | EXPECT_CALL(*mockreply, register_category(_, _, _, _)).WillRepeatedly(Return(ptrCat)); | ||
803 | 76 | EXPECT_CALL(*mockreply, push(Matcher<unity::scopes::CategorisedResult const&>(HasApplicationTitle(std::string("App2"))))); | ||
804 | 77 | EXPECT_CALL(*mockreply, push(Matcher<unity::scopes::CategorisedResult const&>(HasApplicationTitle(std::string("App4"))))); | ||
805 | 78 | |||
806 | 79 | EXPECT_CALL(*mockreply, push(Matcher<unity::scopes::CategorisedResult const&>(HasApplicationTitle(std::string("App1"))))); | ||
807 | 80 | EXPECT_CALL(*mockreply, push(Matcher<unity::scopes::CategorisedResult const&>(HasApplicationTitle(std::string("App3"))))); | ||
808 | 81 | pusher.push_top_results(apps, categoryTemplate); | ||
809 | 82 | pusher.push_local_results(apps, categoryTemplate); | ||
810 | 83 | } | ||
811 | 84 | |||
812 | 0 | 85 | ||
813 | === added file 'scope/tests/test_helpers.h' | |||
814 | --- scope/tests/test_helpers.h 1970-01-01 00:00:00 +0000 | |||
815 | +++ scope/tests/test_helpers.h 2014-07-08 07:23:41 +0000 | |||
816 | @@ -0,0 +1,71 @@ | |||
817 | 1 | #ifndef TEST_HELPERS_H | ||
818 | 2 | #define TEST_HELPERS_H | ||
819 | 3 | |||
820 | 4 | #include <click/department-lookup.h> | ||
821 | 5 | #include <click/highlights.h> | ||
822 | 6 | #include "click/index.h" | ||
823 | 7 | #include <click/interface.h> | ||
824 | 8 | #include <click/package.h> | ||
825 | 9 | |||
826 | 10 | namespace click | ||
827 | 11 | { | ||
828 | 12 | namespace test | ||
829 | 13 | { | ||
830 | 14 | namespace helpers | ||
831 | 15 | { | ||
832 | 16 | static const std::string FAKE_QUERY {"FAKE_QUERY"}; | ||
833 | 17 | static const std::string FAKE_CATEGORY_TEMPLATE {"{}"}; | ||
834 | 18 | |||
835 | 19 | |||
836 | 20 | class MockIndex : public click::Index { | ||
837 | 21 | click::Packages packages; | ||
838 | 22 | click::Packages recommends; | ||
839 | 23 | click::DepartmentList departments; | ||
840 | 24 | click::DepartmentList bootstrap_departments; | ||
841 | 25 | click::HighlightList bootstrap_highlights; | ||
842 | 26 | public: | ||
843 | 27 | MockIndex(click::Packages packages = click::Packages(), | ||
844 | 28 | click::DepartmentList departments = click::DepartmentList(), | ||
845 | 29 | click::DepartmentList boot_departments = click::DepartmentList()) | ||
846 | 30 | : Index(QSharedPointer<click::web::Client>()), | ||
847 | 31 | packages(packages), | ||
848 | 32 | departments(departments), | ||
849 | 33 | bootstrap_departments(boot_departments) | ||
850 | 34 | { | ||
851 | 35 | |||
852 | 36 | } | ||
853 | 37 | |||
854 | 38 | click::web::Cancellable search(const std::string &query, std::function<void (click::Packages, click::Packages)> callback) override | ||
855 | 39 | { | ||
856 | 40 | do_search(query, callback); | ||
857 | 41 | callback(packages, recommends); | ||
858 | 42 | return click::web::Cancellable(); | ||
859 | 43 | } | ||
860 | 44 | |||
861 | 45 | click::web::Cancellable bootstrap(std::function<void(const click::DepartmentList&, const click::HighlightList&, Error, int)> callback) override | ||
862 | 46 | { | ||
863 | 47 | callback(bootstrap_departments, bootstrap_highlights, click::Index::Error::NoError, 0); | ||
864 | 48 | return click::web::Cancellable(); | ||
865 | 49 | } | ||
866 | 50 | |||
867 | 51 | MOCK_METHOD2(do_search, | ||
868 | 52 | void(const std::string&, | ||
869 | 53 | std::function<void(click::Packages, click::Packages)>)); | ||
870 | 54 | }; | ||
871 | 55 | |||
872 | 56 | |||
873 | 57 | class FakeCategory : public scopes::Category | ||
874 | 58 | { | ||
875 | 59 | public: | ||
876 | 60 | FakeCategory(std::string const& id, std::string const& title, | ||
877 | 61 | std::string const& icon, scopes::CategoryRenderer const& renderer) : | ||
878 | 62 | scopes::Category(id, title, icon, renderer) | ||
879 | 63 | { | ||
880 | 64 | } | ||
881 | 65 | |||
882 | 66 | }; | ||
883 | 67 | } // namespace helpers | ||
884 | 68 | } // namespace test | ||
885 | 69 | } // namespace click | ||
886 | 70 | |||
887 | 71 | #endif // TEST_HELPERS_H | ||
888 | 0 | 72 | ||
889 | === modified file 'scope/tests/test_query.cpp' | |||
890 | --- scope/tests/test_query.cpp 2014-06-24 17:18:53 +0000 | |||
891 | +++ scope/tests/test_query.cpp 2014-07-08 07:23:41 +0000 | |||
892 | @@ -35,8 +35,8 @@ | |||
893 | 35 | 35 | ||
894 | 36 | #include "click/qtbridge.h" | 36 | #include "click/qtbridge.h" |
895 | 37 | #include "clickstore/store-query.h" | 37 | #include "clickstore/store-query.h" |
896 | 38 | #include "click/index.h" | ||
897 | 39 | #include "click/application.h" | 38 | #include "click/application.h" |
898 | 39 | #include "test_helpers.h" | ||
899 | 40 | 40 | ||
900 | 41 | #include <tests/mock_network_access_manager.h> | 41 | #include <tests/mock_network_access_manager.h> |
901 | 42 | 42 | ||
902 | @@ -49,51 +49,10 @@ | |||
903 | 49 | 49 | ||
904 | 50 | using namespace ::testing; | 50 | using namespace ::testing; |
905 | 51 | using namespace click; | 51 | using namespace click; |
906 | 52 | using namespace click::test::helpers; | ||
907 | 52 | 53 | ||
908 | 53 | namespace | 54 | namespace |
909 | 54 | { | 55 | { |
910 | 55 | static const std::string FAKE_QUERY {"FAKE_QUERY"}; | ||
911 | 56 | static const std::string FAKE_CATEGORY_TEMPLATE {"{}"}; | ||
912 | 57 | |||
913 | 58 | |||
914 | 59 | class MockIndex : public click::Index { | ||
915 | 60 | click::Packages packages; | ||
916 | 61 | click::Packages recommends; | ||
917 | 62 | click::DepartmentList departments; | ||
918 | 63 | click::DepartmentList bootstrap_departments; | ||
919 | 64 | click::HighlightList bootstrap_highlights; | ||
920 | 65 | |||
921 | 66 | public: | ||
922 | 67 | MockIndex(click::Packages packages = click::Packages(), | ||
923 | 68 | click::DepartmentList departments = click::DepartmentList(), | ||
924 | 69 | click::DepartmentList boot_departments = click::DepartmentList()) | ||
925 | 70 | : Index(QSharedPointer<click::web::Client>()), | ||
926 | 71 | packages(packages), | ||
927 | 72 | departments(departments), | ||
928 | 73 | bootstrap_departments(boot_departments) | ||
929 | 74 | { | ||
930 | 75 | |||
931 | 76 | } | ||
932 | 77 | |||
933 | 78 | click::web::Cancellable search(const std::string &query, std::function<void (click::Packages, click::Packages)> callback) override | ||
934 | 79 | { | ||
935 | 80 | do_search(query, callback); | ||
936 | 81 | callback(packages, recommends); | ||
937 | 82 | return click::web::Cancellable(); | ||
938 | 83 | } | ||
939 | 84 | |||
940 | 85 | |||
941 | 86 | click::web::Cancellable bootstrap(std::function<void(const click::DepartmentList&, const click::HighlightList&, Error, int)> callback) override | ||
942 | 87 | { | ||
943 | 88 | callback(bootstrap_departments, bootstrap_highlights, click::Index::Error::NoError, 0); | ||
944 | 89 | return click::web::Cancellable(); | ||
945 | 90 | } | ||
946 | 91 | |||
947 | 92 | MOCK_METHOD2(do_search, | ||
948 | 93 | void(const std::string&, | ||
949 | 94 | std::function<void(click::Packages, click::Packages)>)); | ||
950 | 95 | }; | ||
951 | 96 | |||
952 | 97 | class MockQueryBase : public click::Query { | 56 | class MockQueryBase : public click::Query { |
953 | 98 | public: | 57 | public: |
954 | 99 | MockQueryBase(const unity::scopes::CannedQuery& query, click::Index& index, | 58 | MockQueryBase(const unity::scopes::CannedQuery& query, click::Index& index, |
955 | @@ -140,7 +99,7 @@ | |||
956 | 140 | public: | 99 | public: |
957 | 141 | MockQueryRun(const unity::scopes::CannedQuery& query, click::Index& index, | 100 | MockQueryRun(const unity::scopes::CannedQuery& query, click::Index& index, |
958 | 142 | click::DepartmentLookup& depts, | 101 | click::DepartmentLookup& depts, |
960 | 143 | click::HighlightList& highlights, | 102 | click::HighlightList& highlights, |
961 | 144 | scopes::SearchMetadata const& metadata) : MockQueryBase(query, index, depts, highlights, metadata) | 103 | scopes::SearchMetadata const& metadata) : MockQueryBase(query, index, depts, highlights, metadata) |
962 | 145 | { | 104 | { |
963 | 146 | 105 | ||
964 | @@ -154,17 +113,6 @@ | |||
965 | 154 | std::string& categoryTemplate)); | 113 | std::string& categoryTemplate)); |
966 | 155 | MOCK_METHOD0(get_installed_packages, PackageSet()); | 114 | MOCK_METHOD0(get_installed_packages, PackageSet()); |
967 | 156 | }; | 115 | }; |
968 | 157 | |||
969 | 158 | class FakeCategory : public scopes::Category | ||
970 | 159 | { | ||
971 | 160 | public: | ||
972 | 161 | FakeCategory(std::string const& id, std::string const& title, | ||
973 | 162 | std::string const& icon, scopes::CategoryRenderer const& renderer) : | ||
974 | 163 | scopes::Category(id, title, icon, renderer) | ||
975 | 164 | { | ||
976 | 165 | } | ||
977 | 166 | |||
978 | 167 | }; | ||
979 | 168 | } // namespace | 116 | } // namespace |
980 | 169 | 117 | ||
981 | 170 | TEST(QueryTest, testAddAvailableAppsCallsClickIndex) | 118 | TEST(QueryTest, testAddAvailableAppsCallsClickIndex) |
FAILED: Continuous integration, rev:319 jenkins. qa.ubuntu. com/job/ unity-team- unity-scope- click-devel- ci/166/ jenkins. qa.ubuntu. com/job/ unity-team- unity-scope- click-devel- utopic- amd64-ci/ 141/console jenkins. qa.ubuntu. com/job/ unity-team- unity-scope- click-devel- utopic- armhf-ci/ 140/console jenkins. qa.ubuntu. com/job/ unity-team- unity-scope- click-devel- utopic- i386-ci/ 140/console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/unity- team-unity- scope-click- devel-ci/ 166/rebuild
http://