on xenial help sign in
[ Albert Astals Cid ]
c953116Josh Arenson
CMakeLists.txt+9
@@ -116,6 +116,14 @@ include_directories(
116 ${APPLICATION_API_INCLUDE_DIRS}
116 ${APPLICATION_API_INCLUDE_DIRS}
117)
117)
118
118
119+set(ARTIFACTS_DIR "" CACHE PATH "Store test artifacts in this directory.")
120+
121+# Quiet logger
122+set(QUIET_LOGGER OFF CACHE BOOL "Disable test output on stdout.")
123+if(NOT QUIET_LOGGER)
124+ set(STDOUT_LOGGER "-o" "-,txt")
125+endif()
126+
119# add subdirectories to build
127# add subdirectories to build
120add_subdirectory(include)
128add_subdirectory(include)
121add_subdirectory(libs)
129add_subdirectory(libs)
@@ -124,6 +132,7 @@ add_subdirectory(tools)
124add_subdirectory(qml)
132add_subdirectory(qml)
125
133
126# Tests
134# Tests
135+set(NO_TESTS OFF CACHE BOOL "Disable tests.")
127if (NOT NO_TESTS)
136if (NOT NO_TESTS)
128 include(CTest)
137 include(CTest)
129 enable_testing()
138 enable_testing()
CODING+4
@@ -158,6 +158,10 @@ To run the tests for a single component/class under gdb (so you can catch SEGFAU
158
158
159$ make gdbtestComponentName
159$ make gdbtestComponentName
160
160
161+To run a single test function of a single component/class:
162+
163+$ make testComponentName FUNCTION="TestCaseName::functionName"
164+
161To run a test application that allow you to manually test or to simply try out
165To run a test application that allow you to manually test or to simply try out
162a given component:
166a given component:
163
167
cmake/modules/QmlPlugins.cmake+1−3
@@ -107,8 +107,6 @@ macro(export_qmlplugin PLUGIN VERSION PATH)
107 set(multi TARGETS)
107 set(multi TARGETS)
108 cmake_parse_arguments(QMLPLUGIN "${options}" "${single}" "${multi}" ${ARGN})
108 cmake_parse_arguments(QMLPLUGIN "${options}" "${single}" "${multi}" ${ARGN})
109
109
110− get_target_property(qmlplugindump_executable qmlplugindump LOCATION)
111−
112 if(QMLPLUGIN_BINARY_DIR)
110 if(QMLPLUGIN_BINARY_DIR)
113 set(qmlplugin_dir ${QMLPLUGIN_BINARY_DIR}/${PATH})
111 set(qmlplugin_dir ${QMLPLUGIN_BINARY_DIR}/${PATH})
114 else()
112 else()
@@ -127,7 +125,7 @@ macro(export_qmlplugin PLUGIN VERSION PATH)
127 set(qmltypes_path ${CMAKE_CURRENT_SOURCE_DIR}/${plugin_suffix}.qmltypes)
125 set(qmltypes_path ${CMAKE_CURRENT_SOURCE_DIR}/${plugin_suffix}.qmltypes)
128
126
129 add_custom_target(${target_prefix}-qmltypes
127 add_custom_target(${target_prefix}-qmltypes
130− COMMAND env ${QMLPLUGIN_ENVIRONMENT} ${qmlplugindump_executable} -notrelocatable
128+ COMMAND env ${QMLPLUGIN_ENVIRONMENT} $<TARGET_FILE:qmlplugindump> -notrelocatable
131 ${PLUGIN} ${VERSION} ${QMLPLUGIN_MODULE_DIR} > ${qmltypes_path}
129 ${PLUGIN} ${VERSION} ${QMLPLUGIN_MODULE_DIR} > ${qmltypes_path}
132 WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
130 WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
133 )
131 )
cmake/modules/QmlTest.cmake+285−191
@@ -1,218 +1,312 @@
1−# add_qml_test(path component_name [NO_ADD_TEST] [NO_TARGETS]
1+# If you need to override the qmlscene or qmltestrunner executables,
2−# [TARGETS target1 [target2 [...]]]
2+# create the corresponding executable target.
3−# [IMPORT_PATHS import_path1 [import_path2 [...]]
3+
4−# [PROPERTIES prop1 value1 [prop2 value2 [...]]])
4+# These functions respect the global STDOUT_LOGGER and ARTIFACTS_DIR variables.
5+
6+# You can use those with cmake_parse_arguments
7+# if you need to wrap and mangle arguments.
8+set(QMLTEST_OPTIONS ADD_TEST CACHE INTERNAL "")
9+set(QMLTEST_SINGLE ITERATIONS ARG_PREFIX CACHE INTERNAL "")
10+set(QMLTEST_MULTI ARGS ENVIRONMENT DEPENDS IMPORT_PATHS TARGETS CACHE INTERNAL "")
11+
12+# import_executables(name1 [name2 [...]]
13+# [OPTIONAL] # continue when not found
14+# )
5#
15#
6−# NO_ADD_TEST will prevent adding the test to the "test" target
16+# This will find the named executables and import them
7−# NO_TARGETS will prevent adding the test to any targets
17+# to an imported target of the same name.
8−# TARGETS lists the targets the test should be added to
18+
9−# IMPORT_PATHS will pass those paths to qmltestrunner as "-import" arguments
19+function(import_executables)
10−# PROPERTIES will be set on the target and test target. See CMake's set_target_properties()
20+ cmake_parse_arguments(QMLTEST "OPTIONAL" "" "" ${ARGN})
21+
22+ foreach(NAME ${QMLTEST_UNPARSED_ARGUMENTS})
23+ if(NOT TARGET ${NAME})
24+ add_executable(${NAME} IMPORTED GLOBAL)
25+ find_program(${NAME}_exe ${NAME})
26+
27+ if(NOT QMLTEST_OPTIONAL AND NOT ${NAME}_exe)
28+ message(FATAL_ERROR "Could not locate ${NAME}.")
29+ elseif(NOT ${NAME}_exe)
30+ message(STATUS "Could not locate ${NAME}, skipping.")
31+ else()
32+ set_target_properties(${NAME} PROPERTIES IMPORTED_LOCATION ${${NAME}_exe})
33+ endif()
34+ endif()
35+ endforeach()
36+endfunction()
37+
38+
39+# add_qml_test(path component_name
40+# [...]
41+# )
11#
42#
12−# Two targets will be created:
43+# Add test targets for ${component_name} under ${path}. It's assumed
13−# - testComponentName - Runs the test with qmltestrunner
44+# that the test file is named ${path}/tst_${component_name}.qml.
14−# - tryComponentName - Runs the test with uqmlscene, for manual interaction
45+#
15−# - gdbtestComponentName - Runs the test with qmltestrunner under gdb
46+# This function wraps add_manual_qml_test and add_qml_unittest,
47+# see below for available arguments.
48+
49+function(add_qml_test PATH COMPONENT_NAME)
50+ cmake_parse_arguments(QMLTEST "${QMLTEST_OPTIONS}" "${QMLTEST_SINGLE}" "${QMLTEST_MULTI}" ${ARGN})
51+ mangle_arguments()
52+
53+ add_qml_unittest(${ARGV})
54+ add_manual_qml_test(${ARGV})
55+endfunction()
56+
57+
58+# add_qml_unittest(path component_name
59+# [...]
60+# )
61+#
62+# Add test targets for ${component_name} under ${path}. It's assumed
63+# that the test file is named ${path}/tst_${component_name}.qml.
64+#
65+# This function wraps add_executable_test, see below for available arguments.
66+
67+function(add_qml_unittest PATH COMPONENT_NAME)
68+ import_executables(qmltestrunner)
69+
70+ add_executable_test(${COMPONENT_NAME} qmltestrunner
71+ ${ARGN}
72+ ARGS -input ${CMAKE_CURRENT_SOURCE_DIR}/${PATH}/tst_${COMPONENT_NAME}.qml ${QMLTEST_ARGS}
73+ )
74+endfunction()
75+
76+
77+# add_manual_qml_test(path component_name
78+# [...]
79+# )
80+#
81+# Add manual test targets for ${component_name} under ${path}. It's assumed
82+# that the test file is named ${path}/tst_${component_name}.qml.
16#
83#
17−# To change/set a default value for the whole test suite, prior to calling add_qml_test, set:
84+# This function wraps add_manual_test, see below for available arguments.
18−# qmltest_DEFAULT_NO_ADD_TEST (default: FALSE)
85+
19−# qmltest_DEFAULT_TARGETS
86+function(add_manual_qml_test PATH COMPONENT_NAME)
20−# qmltest_DEFAULT_IMPORT_PATHS
87+ import_executables(qmlscene)
21−# qmltest_DEFAULT_PROPERTIES
88+ cmake_parse_arguments(QMLTEST "${QMLTEST_OPTIONS}" "${QMLTEST_SINGLE}" "${QMLTEST_MULTI}" ${ARGN})
22−
89+
23−find_program(qmltestrunner_exe qmltestrunner)
90+ add_manual_test(${COMPONENT_NAME} qmlscene
24−
91+ ${ARGN}
25−if(NOT qmltestrunner_exe)
92+ ARGS ${CMAKE_CURRENT_SOURCE_DIR}/${PATH}/tst_${COMPONENT_NAME}.qml ${QMLTEST_ARGS}
26− msg(FATAL_ERROR "Could not locate qmltestrunner.")
93+ )
94+endfunction()
95+
96+
97+# add_executable_test(target component_name
98+# [...] # see doc for add_manual_qml_test for common arguments
99+# [ADD_TEST] # whether to add to the "test" target
100+# [ARG_PREFIX arg_prefix] # prefix logging arguments with this string
101+# [ARGS] arg1 [arg2 [...]] # pass these arguments to the test executable
102+# [TARGETS target1 [target2 [...]]] # make the listed targets depend on this test
103+# # if a corresponding xvfbtarget1, xvfbtarget2 etc. exists,
104+# # this test running under xvfb will be added as a dependency
105+# # of those targets
106+# [ITERATIONS count] # run this test as a benchmark for ${count} iterations
107+# )
108+#
109+# Logging options in the standard form of "-o filename,format"
110+# will be appended to the arguments list, prefixed with ARG_PREFIX.
111+# XUnitXML files will be stored in current binary dir or under
112+# ARTIFACTS_DIR, if set.
113+#
114+# Three targets will be created:
115+# - test${component_name} - Runs the test
116+# - xvfbtest${component_name} - Runs the test under xvfb
117+# - gdbtest${component_name} - Runs the test under gdb
118+
119+function(add_executable_test COMPONENT_NAME TARGET)
120+ import_executables(gdb xvfb-run OPTIONAL)
121+
122+ cmake_parse_arguments(QMLTEST "${QMLTEST_OPTIONS}" "${QMLTEST_SINGLE}" "${QMLTEST_MULTI}" ${ARGN})
123+ mangle_arguments()
124+
125+ if(ARTIFACTS_DIR)
126+ file(RELATIVE_PATH path ${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
127+ file(MAKE_DIRECTORY ${ARTIFACTS_DIR}/${path})
128+ set(file_logger -o ${ARTIFACTS_DIR}/${path}/test${COMPONENT_NAME}.xml,xunitxml)
129+ else()
130+ set(file_logger -o ${CMAKE_CURRENT_BINARY_DIR}/test${COMPONENT_NAME}.xml,xunitxml)
27−endif()
131+ endif()
28−
132+
29−set(qmlscene_exe ${CMAKE_BINARY_DIR}/tests/uqmlscene/uqmlscene)
133+ bake_arguments("${QMLTEST_ARG_PREFIX}" args ${iterations} ${file_logger} ${STDOUT_LOGGER})
30−
134+
31−set(test_env LC_ALL=C UNITY_TESTING=1)
135+ set(qmltest_command
32−
136+ $<TARGET_FILE:${TARGET}>
33−macro(add_manual_qml_test SUBPATH COMPONENT_NAME)
137+ ${QMLTEST_ARGS}
34− set(options NO_ADD_TEST NO_TARGETS)
138+ ${args}
35− set(multi_value_keywords IMPORT_PATHS TARGETS PROPERTIES ENVIRONMENT)
139+ )
36−
140+
37− cmake_parse_arguments(qmltest "${options}" "" "${multi_value_keywords}" ${ARGN})
141+ add_qmltest_target(test${COMPONENT_NAME} ${TARGET}
38− cmake_parse_arguments(qmltest_default "${options}" "" "${multi_value_keywords}" ${qmltest_DEFAULT_PROPERTIES})
142+ COMMAND ${qmltest_command}
39−
143+ ${depends}
40− set(qmlscene_TARGET try${COMPONENT_NAME})
144+ ENVIRONMENT QML2_IMPORT_PATH=${imports} ${QMLTEST_ENVIRONMENT}
41− set(qmltest_FILE ${SUBPATH}/tst_${COMPONENT_NAME})
145+ ${add_test}
42−
146+ ${targets}
43− set(qmlscene_imports "")
147+ )
44− if(NOT "${qmltest_IMPORT_PATHS}" STREQUAL "")
148+
45− foreach(IMPORT_PATH ${qmltest_IMPORT_PATHS})
149+ if(TARGET xvfb-run)
46− list(APPEND qmlscene_imports "-I")
150+ add_qmltest_target(xvfbtest${COMPONENT_NAME} ${TARGET}
47− list(APPEND qmlscene_imports ${IMPORT_PATH})
151+ COMMAND $<TARGET_FILE:xvfb-run> --server-args "-screen 0 1024x768x24" --auto-servernum ${qmltest_command}
48− endforeach(IMPORT_PATH)
152+ ${depends}
49− elseif(NOT "${qmltest_DEFAULT_IMPORT_PATHS}" STREQUAL "")
153+ ENVIRONMENT QML2_IMPORT_PATH=${imports} ${QMLTEST_ENVIRONMENT} LD_PRELOAD=/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/mesa/libGL.so.1
50− foreach(IMPORT_PATH ${qmltest_DEFAULT_IMPORT_PATHS})
154+ TARGETS ${xvfb_targets}
51− list(APPEND qmlscene_imports "-I")
155+ )
52− list(APPEND qmlscene_imports ${IMPORT_PATH})
53− endforeach(IMPORT_PATH)
54 endif()
156 endif()
55
157
56− if("${qmltest_ENVIRONMENT}" STREQUAL "")
158+ if(TARGET gdb)
57− set(qmltest_ENVIRONMENT "${qmltest_default_ENVIRONMENT}")
159+ add_qmltest_target(gdbtest${COMPONENT_NAME} ${TARGET}
160+ COMMAND $<TARGET_FILE:gdb> -ex run -args ${qmltest_command}
161+ ${depends}
162+ ENVIRONMENT QML2_IMPORT_PATH=${imports} ${QMLTEST_ENVIRONMENT}
163+ )
58 endif()
164 endif()
165+endfunction()
166+
167+
168+# add_manual_test(target component_name
169+# [DEPENDS target1 [target2 [...]]] # make this test depend on the specified targets
170+# [IMPORT_PATHS import_path1 [import_path2 [...]] # use these QML import paths
171+# # (they're searched first to last)
172+# [ENVIRONMENT var1=value1 [var2=value2 [...]]] # set these environment variables
173+# )
174+#
175+# Two targets will be created:
176+# - try${component_name} - Runs the test for manual interaction
177+# - gdbtry${component_name} - Runs the test under gdb
178+
179+function(add_manual_test COMPONENT_NAME TARGET)
180+ import_executables(gdb OPTIONAL)
181+
182+ cmake_parse_arguments(QMLTEST "${QMLTEST_OPTIONS}" "${QMLTEST_SINGLE}" "${QMLTEST_MULTI}" ${ARGN})
183+ mangle_arguments()
184+
185+ bake_arguments("${QMLTEST_ARG_PREFIX}" args -qmljsdebugger=port:3768)
186+
187+ set(qmltry_command
188+ $<TARGET_FILE:${TARGET}>
189+ ${QMLTEST_ARGS}
190+ ${args}
191+ )
59
192
60− set(qmlscene_command
193+ add_qmltest_target(try${COMPONENT_NAME} ${TARGET}
61− env ${test_env} ${qmltest_ENVIRONMENT}
194+ COMMAND ${qmltry_command}
62− ${qmlscene_exe} -qmljsdebugger=port:3768 ${CMAKE_CURRENT_SOURCE_DIR}/${qmltest_FILE}.qml
195+ ${depends}
63− ${qmlscene_imports}
196+ ENVIRONMENT QML2_IMPORT_PATH=${imports} ${QMLTEST_ENVIRONMENT}
64 )
197 )
65− add_custom_target(${qmlscene_TARGET} ${qmlscene_command})
198+
66−
199+ if(TARGET gdb)
67−endmacro(add_manual_qml_test)
200+ add_qmltest_target(gdbtry${COMPONENT_NAME} ${TARGET}
68−
201+ COMMAND $<TARGET_FILE:gdb> -ex run -args ${qmltry_command}
69−macro(add_qml_benchmark SUBPATH COMPONENT_NAME ITERATIONS)
202+ ${depends}
70− add_qml_test_internal(${SUBPATH} ${COMPONENT_NAME} ${ITERATIONS} ${ARGN})
203+ ENVIRONMENT QML2_IMPORT_PATH=${imports} ${QMLTEST_ENVIRONMENT}
71−endmacro(add_qml_benchmark)
204+ )
72−
73−macro(add_qml_test SUBPATH COMPONENT_NAME)
74− add_qml_test_internal(${SUBPATH} ${COMPONENT_NAME} 0 ${ARGN})
75−endmacro(add_qml_test)
76−
77−macro(add_qml_test_internal SUBPATH COMPONENT_NAME ITERATIONS)
78− set(options NO_ADD_TEST NO_TARGETS)
79− set(multi_value_keywords IMPORT_PATHS TARGETS PROPERTIES ENVIRONMENT)
80−
81− cmake_parse_arguments(qmltest "${options}" "" "${multi_value_keywords}" ${ARGN})
82− cmake_parse_arguments(qmltest_default "${options}" "" "${multi_value_keywords}" ${qmltest_DEFAULT_PROPERTIES})
83−
84− set(qmltest_TARGET test${COMPONENT_NAME})
85− set(qmltest_gdb_TARGET gdbtest${COMPONENT_NAME})
86− set(qmltest_xvfb_TARGET xvfbtest${COMPONENT_NAME})
87− set(qmltest_FILE ${SUBPATH}/tst_${COMPONENT_NAME})
88−
89− set(qmltestrunner_imports "")
90− if(NOT "${qmltest_IMPORT_PATHS}" STREQUAL "")
91− foreach(IMPORT_PATH ${qmltest_IMPORT_PATHS})
92− list(APPEND qmltestrunner_imports "-import")
93− list(APPEND qmltestrunner_imports ${IMPORT_PATH})
94− endforeach(IMPORT_PATH)
95− elseif(NOT "${qmltest_DEFAULT_IMPORT_PATHS}" STREQUAL "")
96− foreach(IMPORT_PATH ${qmltest_DEFAULT_IMPORT_PATHS})
97− list(APPEND qmltestrunner_imports "-import")
98− list(APPEND qmltestrunner_imports ${IMPORT_PATH})
99− endforeach(IMPORT_PATH)
100 endif()
205 endif()
206+endfunction()
207+
208+
209+################### INTERNAL ####################
210+
211+# add_qmltest_target(target_name target
212+# COMMAND test_exe [arg1 [...]] # execute this test with arguments
213+# [...] # see above for available arguments:
214+# # ADD_TEST, ENVIRONMENT, DEPENDS and TARGETS
215+# )
101
216
217+function(add_qmltest_target TARGET_NAME TARGET)
218+ cmake_parse_arguments(QMLTEST "${QMLTEST_OPTIONS}" "${QMLTEST_SINGLE}" "COMMAND;${QMLTEST_MULTI}" ${ARGN})
219+ mangle_arguments()
220+
221+ # Additional arguments
102 string(TOLOWER "${CMAKE_GENERATOR}" cmake_generator_lower)
222 string(TOLOWER "${CMAKE_GENERATOR}" cmake_generator_lower)
103 if(cmake_generator_lower STREQUAL "unix makefiles")
223 if(cmake_generator_lower STREQUAL "unix makefiles")
104− set(function_ARGS $(FUNCTION))
224+ set(function "$(FUNCTION)")
105− else()
106− set(function_ARGS "")
107 endif()
225 endif()
108
226
109− if (${ITERATIONS} GREATER 0)
227+ add_custom_target(${TARGET_NAME}
110− set(ITERATIONS_STRING "-iterations" ${ITERATIONS})
228+ env ${QMLTEST_ENVIRONMENT}
111− else()
229+ ${QMLTEST_COMMAND} ${function}
112− set(ITERATIONS_STRING "")
230+ DEPENDS ${TARGET} ${QMLTEST_DEPENDS}
231+ )
232+
233+ if(QMLTEST_ADD_TEST)
234+ add_test(
235+ NAME ${TARGET_NAME}
236+ COMMAND ${QMLTEST_COMMAND}
237+ )
238+
239+ foreach(ENV ${QMLTEST_ENVIRONMENT})
240+ set_property(TEST ${TARGET_NAME} APPEND PROPERTY ENVIRONMENT ${ENV})
241+ endforeach()
242+
243+ set_property(TEST ${TARGET_NAME} APPEND PROPERTY DEPENDS ${TARGET})
244+ foreach(DEPEND ${DEPENDS})
245+ set_property(TEST ${TARGET_NAME} APPEND PROPERTY DEPENDS ${DEPEND})
246+ endforeach()
113 endif()
247 endif()
114
248
115− if("${qmltest_ENVIRONMENT}" STREQUAL "")
249+ foreach(UPSTREAM_TARGET ${QMLTEST_TARGETS})
116− set(qmltest_ENVIRONMENT "${qmltest_default_ENVIRONMENT}")
250+ add_dependencies(${UPSTREAM_TARGET} ${TARGET_NAME})
251+ endforeach()
252+endfunction()
253+
254+
255+# mangle_arguments(${ARGN})
256+#
257+# Verify there were no unparsed arguments and
258+# mangle the known ones for further processing.
259+
260+macro(mangle_arguments)
261+ if(QMLTEST_UNPARSED_ARGUMENTS)
262+ message(FATAL_ERROR "Unexpected arguments: ${QMLTEST_UNPARSED_ARGUMENTS}")
117 endif()
263 endif()
118
264
119− set(qmltest_command
265+ if(QMLTEST_ADD_TEST)
120− env ${test_env} ${qmltest_ENVIRONMENT}
266+ set(add_test ADD_TEST)
121− ${qmltestrunner_exe} -input ${CMAKE_CURRENT_SOURCE_DIR}/${qmltest_FILE}.qml
122− ${qmltestrunner_imports}
123− ${ITERATIONS_STRING}
124− -o ${CMAKE_BINARY_DIR}/${qmltest_TARGET}.xml,xunitxml
125− -o -,txt
126− ${function_ARGS}
127− )
128− find_program(DPKG dpkg-architecture)
129− if(DPKG)
130− exec_program(${DPKG} ARGS "-qDEB_BUILD_MULTIARCH" OUTPUT_VARIABLE ARCH_TRIPLET )
131− set(LD_PRELOAD_PATH "LD_PRELOAD=/usr/lib/${ARCH_TRIPLET}/mesa/libGL.so.1")
132 endif()
267 endif()
133− set(qmltest_xvfb_command
134− env ${test_env} ${qmltest_ENVIRONMENT} ${LD_PRELOAD_PATH}
135− xvfb-run --server-args "-screen 0 1024x768x24" --auto-servernum
136− ${qmltestrunner_exe} -input ${CMAKE_CURRENT_SOURCE_DIR}/${qmltest_FILE}.qml
137− ${qmltestrunner_imports}
138− -o ${CMAKE_BINARY_DIR}/${qmltest_TARGET}.xml,xunitxml
139− -o -,txt
140− ${function_ARGS}
141− )
142
268
143− set(qmltest_gdb_command
269+ if(QMLTEST_IMPORT_PATHS)
144− env ${test_env} ${qmltest_ENVIRONMENT} ${LD_PRELOAD_PATH}
270+ string(REPLACE ";" ":" imports "${QMLTEST_IMPORT_PATHS}")
145− gdb -e ${qmltestrunner_exe} -ex \"run -input ${CMAKE_CURRENT_SOURCE_DIR}/${qmltest_FILE}.qml ${qmltestrunner_imports} ${ITERATIONS_STRING}\"
271+ endif()
146− )
147
272
148− add_qmltest_target(${qmltest_TARGET} "${qmltest_command}" TRUE ${qmltest_NO_ADD_TEST})
273+ if(QMLTEST_ITERATIONS)
149− add_qmltest_target(${qmltest_xvfb_TARGET} "${qmltest_xvfb_command}" ${qmltest_NO_TARGETS} TRUE)
274+ set(iterations -iterations ${QMLTEST_ITERATIONS})
150− add_qmltest_target(${qmltest_gdb_TARGET} "${qmltest_gdb_command}" TRUE TRUE)
151− add_manual_qml_test(${SUBPATH} ${COMPONENT_NAME} ${ARGN})
152−endmacro(add_qml_test_internal)
153−
154−macro(add_binary_qml_test CLASS_NAME LD_PATH DEPS ENVVAR)
155− set(testCommand
156− ${ENVVAR}
157− LD_LIBRARY_PATH=${LD_PATH}
158− dbus-test-runner
159− -m 300
160− -t ${CMAKE_CURRENT_BINARY_DIR}/${CLASS_NAME}TestExec
161− -p -o -p ${CMAKE_BINARY_DIR}/test${CLASS_NAME}.xml,xunitxml
162− -p -o -p -,txt)
163−
164− add_qmltest_target(test${CLASS_NAME} "${testCommand}" FALSE TRUE)
165− add_dependencies(test${CLASS_NAME} ${CLASS_NAME}TestExec ${DEPS})
166−
167− find_program( HAVE_GCC gcc )
168− if (NOT ${HAVE_GCC} STREQUAL "")
169− exec_program( gcc ARGS "-dumpmachine" OUTPUT_VARIABLE ARCH_TRIPLET )
170− set(LD_PRELOAD_PATH "LD_PRELOAD=/usr/lib/${ARCH_TRIPLET}/mesa/libGL.so.1")
171 endif()
275 endif()
172− set(xvfbtestCommand
276+
173− ${LD_PRELOAD_PATH}
277+ if(QMLTEST_DEPENDS)
174− ${ENVVAR}
278+ set(depends DEPENDS ${QMLTEST_DEPENDS})
175− LD_LIBRARY_PATH=${LD_PATH}
176− xvfb-run --server-args "-screen 0 1024x768x24" --auto-servernum
177− dbus-test-runner
178− -m 300
179− -t ${CMAKE_CURRENT_BINARY_DIR}/${CLASS_NAME}TestExec
180− -p -o -p ${CMAKE_BINARY_DIR}/test${CLASS_NAME}.xml,xunitxml
181− -p -o -p -,txt)
182−
183− add_qmltest_target(xvfbtest${CLASS_NAME} "${xvfbtestCommand}" FALSE TRUE)
184− add_dependencies(qmluitests xvfbtest${CLASS_NAME})
185−endmacro(add_binary_qml_test)
186−
187−macro(add_qmltest_target qmltest_TARGET qmltest_command qmltest_NO_TARGETS qmltest_NO_ADD_TEST)
188− add_custom_target(${qmltest_TARGET} ${qmltest_command})
189−
190− if(NOT "${qmltest_PROPERTIES}" STREQUAL "")
191− set_target_properties(${qmltest_TARGET} PROPERTIES ${qmltest_PROPERTIES})
192− elseif(NOT "${qmltest_DEFAULT_PROPERTIES}" STREQUAL "")
193− set_target_properties(${qmltest_TARGET} PROPERTIES ${qmltest_DEFAULT_PROPERTIES})
194 endif()
279 endif()
195
280
196− if("${qmltest_NO_ADD_TEST}" STREQUAL FALSE AND NOT "${qmltest_DEFAULT_NO_ADD_TEST}" STREQUAL "TRUE")
281+ if(QMLTEST_TARGETS)
197− add_test(${qmltest_TARGET} ${qmltest_command})
282+ set(targets TARGETS ${QMLTEST_TARGETS})
283+ endif()
198
284
199− if(NOT "${qmltest_UNPARSED_ARGUMENTS}" STREQUAL "")
285+ set(xvfb_targets "")
200− set_tests_properties(${qmltest_TARGET} PROPERTIES ${qmltest_PROPERTIES})
286+ foreach(target ${QMLTEST_TARGETS})
201− elseif(NOT "${qmltest_DEFAULT_PROPERTIES}" STREQUAL "")
287+ if(TARGET xvfb${target})
202− set_tests_properties(${qmltest_TARGET} PROPERTIES ${qmltest_DEFAULT_PROPERTIES})
288+ list(APPEND xvfb_targets xvfb${target})
203 endif()
289 endif()
204− endif("${qmltest_NO_ADD_TEST}" STREQUAL FALSE AND NOT "${qmltest_DEFAULT_NO_ADD_TEST}" STREQUAL "TRUE")
205−
206− if("${qmltest_NO_TARGETS}" STREQUAL "FALSE")
207− if(NOT "${qmltest_TARGETS}" STREQUAL "")
208− foreach(TARGET ${qmltest_TARGETS})
209− add_dependencies(${TARGET} ${qmltest_TARGET})
210− endforeach(TARGET)
290+ endforeach()
211− elseif(NOT "${qmltest_DEFAULT_TARGETS}" STREQUAL "")
291+ set(xvfb_targets "${xvfb_targets}" PARENT_SCOPE)
212− foreach(TARGET ${qmltest_DEFAULT_TARGETS})
292+endmacro()
213− add_dependencies(${TARGET} ${qmltest_TARGET})
293+
214− endforeach(TARGET)
215− endif()
216− endif("${qmltest_NO_TARGETS}" STREQUAL "FALSE")
217
294
218−endmacro(add_qmltest_target)
295+# bake_arguments(prefix output
296+# arg1 [arg2 [...]]
297+# )
298+#
299+# If set, add the argument prefix before every passed
300+# argument and store the result in ${OUTPUT} variable.
301+
302+function(bake_arguments PREFIX OUTPUT)
303+ set(args "${ARGN}")
304+ if(PREFIX)
305+ set(args "")
306+ foreach(arg ${ARGN})
307+ list(APPEND args ${PREFIX})
308+ list(APPEND args ${arg})
309+ endforeach()
310+ endif()
311+ set(${OUTPUT} "${args}" PARENT_SCOPE)
312+endfunction()
debian/changelog+38
@@ -1,3 +1,41 @@
1+unity8 (8.10+15.10.20150618-0ubuntu1) wily; urgency=medium
2+
3+ [ Albert Astals Cid ]
4+ * Refactor QmlTest.cmake module so that all tests can go through it.
5+ Also a bit of cleanup around tests.
6+ * Support fallback images for dash card and preview widgets (LP:
7+ #1324142)
8+
9+ [ CI Train Bot ]
10+ * New rebuild forced.
11+ * Resync trunk.
12+
13+ [ Daniel d'Andrada ]
14+ * Fix Shell tests
15+
16+ [ Josh Arenson ]
17+ * Refactor greeter emulator to unlock the greeter via dbus
18+
19+ [ Lukáš Tinkl ]
20+ * respect target window's devicePixelRatio in MouseTouchAdaptor
21+
22+ [ Michael Zanetti ]
23+ * Refactor QmlTest.cmake module so that all tests can go through it.
24+ Also a bit of cleanup around tests.
25+
26+ [ Michał Sawicz ]
27+ * Refactor QmlTest.cmake module so that all tests can go through it.
28+ Also a bit of cleanup around tests.
29+
30+ [ handsome_feng ]
31+ * Forbid closing apps during the edge gesture. (LP: #1445572)
32+ * Removed the horizonal rule on pin unlock screen. (LP: #1368798)
33+
34+ [ handsome_feng<445865575@qq.com> ]
35+ * Forbid closing apps during the edge gesture. (LP: #1445572)
36+
37+ -- CI Train Bot <ci-train-bot@canonical.com> Thu, 18 Jun 2015 19:40:06 +0000
38+
1unity8 (8.10+15.10.20150612-0ubuntu2) wily; urgency=medium
39unity8 (8.10+15.10.20150612-0ubuntu2) wily; urgency=medium
2
40
3 * No-change rebuild against Qt 5.4.2.
41 * No-change rebuild against Qt 5.4.2.
debian/control+1−1
@@ -151,7 +151,7 @@ Depends: autopilot-qt5 (>= 1.4),
151 python3-fixtures,
151 python3-fixtures,
152 python3-gi,
152 python3-gi,
153 qttestability-autopilot (>= 1.4),
153 qttestability-autopilot (>= 1.4),
154− ubuntu-ui-toolkit-autopilot,
154+ ubuntu-ui-toolkit-autopilot (>= 1.2.1485+15.04.20150417.1-0ubuntu1),
155 unity-scope-click,
155 unity-scope-click,
156 unity8 (= ${source:Version}),
156 unity8 (= ${source:Version}),
157 unity8-fake-env (= ${source:Version}),
157 unity8-fake-env (= ${source:Version}),
plugins/Dash/CardCreator.js+32−10
@@ -16,6 +16,9 @@
16
16
17.pragma library
17.pragma library
18
18
19+// %1 is the template["card-background"] string
20+// %2 is the template["card-background"]["elements"][0]
21+// %3 is the template["card-background"]["elements"][1]
19var kBackgroundLoaderCode = 'Loader {\n\
22var kBackgroundLoaderCode = 'Loader {\n\
20 id: backgroundLoader; \n\
23 id: backgroundLoader; \n\
21 objectName: "backgroundLoader"; \n\
24 objectName: "backgroundLoader"; \n\
@@ -34,18 +37,14 @@ var kBackgroundLoaderCode = 'Loader {\n\
34 objectName: "backgroundImage"; \n\
37 objectName: "backgroundImage"; \n\
35 source: { \n\
38 source: { \n\
36 if (cardData && typeof cardData["background"] === "string") return cardData["background"]; \n\
39 if (cardData && typeof cardData["background"] === "string") return cardData["background"]; \n\
37− else if (template && typeof template["card-background"] === "string") return template["card-background"]; \n\
40+ else return "%1"; \n\
38− else return ""; \n\
39 } \n\
41 } \n\
40 } \n\
42 } \n\
41 function getColor(index) { \n\
43 function getColor(index) { \n\
42 if (cardData && typeof cardData["background"] === "object" \n\
44 if (cardData && typeof cardData["background"] === "object" \n\
43 && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) { \n\
45 && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) { \n\
44 return cardData["background"]["elements"][index]; \n\
46 return cardData["background"]["elements"][index]; \n\
45− } else if (template && typeof template["card-background"] === "object" \n\
47+ } else return index === 0 ? %2 : %3; \n\
46− && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) { \n\
47− return template["card-background"]["elements"][index]; \n\
48− } else return undefined; \n\
49 } \n\
48 } \n\
50 } \n\
49 } \n\
51 }\n';
50 }\n';
@@ -70,6 +69,7 @@ var kArtShapeHolderCode = 'Item { \n\
70 property bool doShapeItem: components["art"]["conciergeMode"] !== true; \n\
69 property bool doShapeItem: components["art"]["conciergeMode"] !== true; \n\
71 visible: image.status == Image.Ready; \n\
70 visible: image.status == Image.Ready; \n\
72 readonly property alias image: artImage.image; \n\
71 readonly property alias image: artImage.image; \n\
72+ property alias borderSource: artShapeShape.borderSource; \n\
73 ShaderEffectSource { \n\
73 ShaderEffectSource { \n\
74 id: artShapeSource; \n\
74 id: artShapeSource; \n\
75 sourceItem: artImage; \n\
75 sourceItem: artImage; \n\
@@ -79,6 +79,7 @@ var kArtShapeHolderCode = 'Item { \n\
79 hideSource: doShapeItem; \n\
79 hideSource: doShapeItem; \n\
80 } \n\
80 } \n\
81 Shape { \n\
81 Shape { \n\
82+ id: artShapeShape; \n\
82 image: artShapeSource; \n\
83 image: artShapeSource; \n\
83 anchors.fill: parent; \n\
84 anchors.fill: parent; \n\
84 visible: doShapeItem; \n\
85 visible: doShapeItem; \n\
@@ -315,9 +316,11 @@ var kSummaryLabelCode = 'Label { \n\
315
316
316function cardString(template, components) {
317function cardString(template, components) {
317 var code;
318 var code;
319+
320+ var templateInteractive = (template == null ? true : (template["non-interactive"] !== undefined ? !template["non-interactive"] : true)) ? "true" : "false";
321+
318 code = 'AbstractButton { \n\
322 code = 'AbstractButton { \n\
319 id: root; \n\
323 id: root; \n\
320− property var template; \n\
321 property var components; \n\
324 property var components; \n\
322 property var cardData; \n\
325 property var cardData; \n\
323 property var artShapeBorderSource: undefined; \n\
326 property var artShapeBorderSource: undefined; \n\
@@ -330,8 +333,8 @@ function cardString(template, components) {
330 property bool asynchronous: true; \n\
333 property bool asynchronous: true; \n\
331 property bool showHeader: true; \n\
334 property bool showHeader: true; \n\
332 implicitWidth: childrenRect.width; \n\
335 implicitWidth: childrenRect.width; \n\
333− enabled: root.template == null ? true : (root.template["non-interactive"] !== undefined ? !root.template["non-interactive"] : true); \n\
336+ enabled: %1; \n\
334− \n';
337+ \n'.arg(templateInteractive);
335
338
336 var hasArt = components["art"] && components["art"]["field"] || false;
339 var hasArt = components["art"] && components["art"]["field"] || false;
337 var hasSummary = components["summary"] || false;
340 var hasSummary = components["summary"] || false;
@@ -348,7 +351,18 @@ function cardString(template, components) {
348 var hasAttributes = hasTitle && components["attributes"]["field"] || false;
351 var hasAttributes = hasTitle && components["attributes"]["field"] || false;
349
352
350 if (hasBackground) {
353 if (hasBackground) {
354+ var templateCardBackground = (template && typeof template["card-background"] === "string") ? template["card-background"] : "";
355+ var backgroundElements0;
356+ var backgroundElements1;
357+ if (template && typeof template["card-background"] === "object" && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) {
358+ if (template["card-background"]["elements"][0] !== undefined) {
359+ backgroundElements0 = '"%1"'.arg(template["card-background"]["elements"][0]);
360+ }
361+ if (template["card-background"]["elements"][1] !== undefined) {
362+ backgroundElements1 = '"%1"'.arg(template["card-background"]["elements"][1]);
363+ }
364+ }
351− code += kBackgroundLoaderCode;
365+ code += kBackgroundLoaderCode.arg(templateCardBackground).arg(backgroundElements0).arg(backgroundElements1);
352 }
366 }
353
367
354 if (hasArt) {
368 if (hasArt) {
@@ -375,6 +389,10 @@ function cardString(template, components) {
375 }
389 }
376
390
377 code += kArtShapeHolderCode.arg(artAnchors).arg(widthCode).arg(heightCode);
391 code += kArtShapeHolderCode.arg(artAnchors).arg(widthCode).arg(heightCode);
392+ var fallback = components["art"] && components["art"]["fallback"] || "";
393+ if (fallback !== "") {
394+ code += 'Connections { target: artShapeLoader.item ? artShapeLoader.item.image : null; onStatusChanged: if (artShapeLoader.item.image.status === Image.Error) artShapeLoader.item.image.source = "%1"; } \n'.arg(fallback);
395+ }
378 } else {
396 } else {
379 code += 'readonly property size artShapeSize: Qt.size(-1, -1);\n'
397 code += 'readonly property size artShapeSize: Qt.size(-1, -1);\n'
380 }
398 }
@@ -454,6 +472,10 @@ function cardString(template, components) {
454
472
455 var mascotImageVisible = useMascotShape ? 'false' : 'showHeader';
473 var mascotImageVisible = useMascotShape ? 'false' : 'showHeader';
456 mascotCode = kMascotImageCode.arg(mascotAnchors).arg(mascotImageVisible);
474 mascotCode = kMascotImageCode.arg(mascotAnchors).arg(mascotImageVisible);
475+ var fallback = components["mascot"] && components["mascot"]["fallback"] || "";
476+ if (fallback !== "") {
477+ code += 'Connections { target: mascotImage.image; onStatusChanged: if (mascotImage.image.status === Image.Error) mascotImage.source = "%1"; } \n'.arg(fallback);
478+ }
457 }
479 }
458
480
459 var summaryColorWithBackground = 'backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white")';
481 var summaryColorWithBackground = 'backgroundLoader.active && backgroundLoader.item && root.scopeStyle ? root.scopeStyle.getTextColor(backgroundLoader.item.luminance) : (backgroundLoader.item && backgroundLoader.item.luminance > 0.7 ? Theme.palette.normal.baseText : "white")';
plugins/Wizard/PageList.cpp+1−1
@@ -45,7 +45,7 @@ PageList::PageList(QObject *parent)
45 QSet<QString> disabledPages;
45 QSet<QString> disabledPages;
46 QStringList dataDirs;
46 QStringList dataDirs;
47
47
48− if (!isRunningInstalled() && getenv("UNITY_TEST_ENV") == nullptr) {
48+ if (!isRunningInstalled() && getenv("WIZARD_TESTING") == nullptr) {
49 dataDirs = QStringList() << qmlDirectory();
49 dataDirs = QStringList() << qmlDirectory();
50 } else {
50 } else {
51 dataDirs = shellDataDirs();
51 dataDirs = shellDataDirs();
po/ast.po+1−1
@@ -15,7 +15,7 @@ msgstr ""
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-06-13 05:48+0000\n"
18+"X-Launchpad-Export-Date: 2015-06-16 11:20+0000\n"
19"X-Generator: Launchpad (build 17557)\n"
19"X-Generator: Launchpad (build 17557)\n"
20
20
21#: plugins/LightDM/Greeter.cpp:112
21#: plugins/LightDM/Greeter.cpp:112
po/de.po+6−6
@@ -8,15 +8,15 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2015-04-14 16:13+0200\n"
10"POT-Creation-Date: 2015-04-14 16:13+0200\n"
11−"PO-Revision-Date: 2015-05-14 15:49+0000\n"
11+"PO-Revision-Date: 2015-06-17 14:05+0000\n"
12−"Last-Translator: Tobias Bannert <Unknown>\n"
12+"Last-Translator: JkB <Unknown>\n"
13"Language-Team: German <de@li.org>\n"
13"Language-Team: German <de@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-05-15 05:31+0000\n"
18+"X-Launchpad-Export-Date: 2015-06-23 05:32+0000\n"
19−"X-Generator: Launchpad (build 17493)\n"
19+"X-Generator: Launchpad (build 17572)\n"
20
20
21#: plugins/LightDM/Greeter.cpp:112
21#: plugins/LightDM/Greeter.cpp:112
22msgid "Password: "
22msgid "Password: "
@@ -117,7 +117,7 @@ msgstr "Ja"
117#: qml/Components/Dialogs.qml:152
117#: qml/Components/Dialogs.qml:152
118msgctxt "Title: Power off/Restart dialog"
118msgctxt "Title: Power off/Restart dialog"
119msgid "Power"
119msgid "Power"
120−msgstr "Leistung"
120+msgstr "Ausschalten"
121
121
122#: qml/Components/Dialogs.qml:153
122#: qml/Components/Dialogs.qml:153
123msgid ""
123msgid ""
@@ -276,7 +276,7 @@ msgstr "%1 eingeben"
276
276
277#: qml/Greeter/NarrowView.qml:116 qml/Wizard/Pages/passwd-set.qml:60
277#: qml/Greeter/NarrowView.qml:116 qml/Wizard/Pages/passwd-set.qml:60
278msgid "Enter passphrase"
278msgid "Enter passphrase"
279−msgstr "Passwort eingeben"
279+msgstr "Passphrase eingeben"
280
280
281#: qml/Greeter/NarrowView.qml:117
281#: qml/Greeter/NarrowView.qml:117
282msgid "Enter passcode"
282msgid "Enter passcode"
po/el.po+11−11
@@ -8,15 +8,15 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2015-04-14 16:13+0200\n"
10"POT-Creation-Date: 2015-04-14 16:13+0200\n"
11−"PO-Revision-Date: 2015-04-22 09:03+0000\n"
11+"PO-Revision-Date: 2015-06-18 19:05+0000\n"
12"Last-Translator: Simos Xenitellis <Unknown>\n"
12"Last-Translator: Simos Xenitellis <Unknown>\n"
13"Language-Team: Greek <el@li.org>\n"
13"Language-Team: Greek <el@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-04-23 06:48+0000\n"
18+"X-Launchpad-Export-Date: 2015-06-23 05:33+0000\n"
19−"X-Generator: Launchpad (build 17430)\n"
19+"X-Generator: Launchpad (build 17572)\n"
20
20
21#: plugins/LightDM/Greeter.cpp:112
21#: plugins/LightDM/Greeter.cpp:112
22msgid "Password: "
22msgid "Password: "
@@ -117,7 +117,7 @@ msgstr "Ναι"
117#: qml/Components/Dialogs.qml:152
117#: qml/Components/Dialogs.qml:152
118msgctxt "Title: Power off/Restart dialog"
118msgctxt "Title: Power off/Restart dialog"
119msgid "Power"
119msgid "Power"
120−msgstr ""
120+msgstr "Τερματισμός"
121
121
122#: qml/Components/Dialogs.qml:153
122#: qml/Components/Dialogs.qml:153
123msgid ""
123msgid ""
@@ -165,17 +165,17 @@ msgstr "Αναζήτηση"
165#: qml/Dash/PageHeader.qml:269
165#: qml/Dash/PageHeader.qml:269
166msgctxt "Button: Open the Ubuntu Store"
166msgctxt "Button: Open the Ubuntu Store"
167msgid "Store"
167msgid "Store"
168−msgstr ""
168+msgstr "Κατάστημα"
169
169
170#: qml/Dash/PageHeader.qml:276
170#: qml/Dash/PageHeader.qml:276
171msgctxt "Button: Start a search in the current dash scope"
171msgctxt "Button: Start a search in the current dash scope"
172msgid "Search"
172msgid "Search"
173−msgstr ""
173+msgstr "Αναζήτηση"
174
174
175#: qml/Dash/PageHeader.qml:286
175#: qml/Dash/PageHeader.qml:286
176msgctxt "Button: Show the current dash scope settings"
176msgctxt "Button: Show the current dash scope settings"
177msgid "Settings"
177msgid "Settings"
178−msgstr ""
178+msgstr "Ρυθμίσεις"
179
179
180#: qml/Dash/PageHeader.qml:293
180#: qml/Dash/PageHeader.qml:293
181msgid "Remove from Favorites"
181msgid "Remove from Favorites"
@@ -378,7 +378,7 @@ msgstr "Πατήστε εδώ για συνέχεια."
378
378
379#: qml/Tutorial/TutorialContent.qml:81
379#: qml/Tutorial/TutorialContent.qml:81
380msgid "Click here to finish."
380msgid "Click here to finish."
381−msgstr ""
381+msgstr "Πατήστε εδώ για τέλος."
382
382
383#: qml/Tutorial/TutorialLeftFinish.qml:24
383#: qml/Tutorial/TutorialLeftFinish.qml:24
384msgid "These are the shortcuts to favorite apps"
384msgid "These are the shortcuts to favorite apps"
@@ -510,12 +510,12 @@ msgstr "Επιτρέψετε το τηλέφωνο να εντοπίσει τη
510
510
511#: qml/Wizard/Pages/50-location.qml:69
511#: qml/Wizard/Pages/50-location.qml:69
512msgid "Using GPS only (less accurate)"
512msgid "Using GPS only (less accurate)"
513−msgstr "Χρήση μόνο GPS (λιγότερο ακριβή)"
513+msgstr "Χρήση μόνο GPS (λιγότερο ακριβής)"
514
514
515#: qml/Wizard/Pages/50-location.qml:86
515#: qml/Wizard/Pages/50-location.qml:86
516msgid "Using GPS, anonymized Wi-Fi and cellular network info (recommended)"
516msgid "Using GPS, anonymized Wi-Fi and cellular network info (recommended)"
517msgstr ""
517msgstr ""
518−"Χρήση GPS, ανωνυνοποιημένα δίκτυα Wi-Fi και πληροφορίες δικτύων κινητής "
518+"Χρήση GPS, ανωνυμοποιημένων δικτύων Wi-Fi και πληροφορίες δικτύων κινητής "
519"τηλεφωνίας (συνιστάται)"
519"τηλεφωνίας (συνιστάται)"
520
520
521#. TRANSLATORS: HERE is a trademark for Nokia's location service, you probably shouldn't translate it
521#. TRANSLATORS: HERE is a trademark for Nokia's location service, you probably shouldn't translate it
@@ -546,7 +546,7 @@ msgid ""
546"partners, the makers of the operating system."
546"partners, the makers of the operating system."
547msgstr ""
547msgstr ""
548"Το τηλέφωνό σας είναι ρυθμισμένο να στέλνει αυτόματα αναφορές σφαλμάτων στην "
548"Το τηλέφωνό σας είναι ρυθμισμένο να στέλνει αυτόματα αναφορές σφαλμάτων στην "
549−"Canonical και τους συνεργάτες της, τους δημιουργούς τους λειτουργικού "
549+"Canonical και τους συνεργάτες της, τους δημιουργούς του λειτουργικού "
550"συστήματος."
550"συστήματος."
551
551
552#: qml/Wizard/Pages/60-reporting.qml:43
552#: qml/Wizard/Pages/60-reporting.qml:43
po/hu.po+4−4
@@ -8,15 +8,15 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2015-04-14 16:13+0200\n"
10"POT-Creation-Date: 2015-04-14 16:13+0200\n"
11−"PO-Revision-Date: 2015-05-04 18:02+0000\n"
11+"PO-Revision-Date: 2015-06-19 09:54+0000\n"
12"Last-Translator: Richard Somlói <ricsipontaz@gmail.com>\n"
12"Last-Translator: Richard Somlói <ricsipontaz@gmail.com>\n"
13"Language-Team: Hungarian <hu@li.org>\n"
13"Language-Team: Hungarian <hu@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-05-05 05:47+0000\n"
18+"X-Launchpad-Export-Date: 2015-06-23 05:33+0000\n"
19−"X-Generator: Launchpad (build 17474)\n"
19+"X-Generator: Launchpad (build 17572)\n"
20
20
21#: plugins/LightDM/Greeter.cpp:112
21#: plugins/LightDM/Greeter.cpp:112
22msgid "Password: "
22msgid "Password: "
@@ -113,7 +113,7 @@ msgstr "Igen"
113#: qml/Components/Dialogs.qml:152
113#: qml/Components/Dialogs.qml:152
114msgctxt "Title: Power off/Restart dialog"
114msgctxt "Title: Power off/Restart dialog"
115msgid "Power"
115msgid "Power"
116−msgstr "Főkapcsoló"
116+msgstr "Menü"
117
117
118#: qml/Components/Dialogs.qml:153
118#: qml/Components/Dialogs.qml:153
119msgid ""
119msgid ""
po/it.po+9−9
@@ -8,15 +8,15 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2015-04-14 16:13+0200\n"
10"POT-Creation-Date: 2015-04-14 16:13+0200\n"
11−"PO-Revision-Date: 2015-03-21 12:42+0000\n"
11+"PO-Revision-Date: 2015-06-17 09:56+0000\n"
12"Last-Translator: Claudio Arseni <claudio.arseni@gmail.com>\n"
12"Last-Translator: Claudio Arseni <claudio.arseni@gmail.com>\n"
13"Language-Team: Italian <it@li.org>\n"
13"Language-Team: Italian <it@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
17"Plural-Forms: nplurals=2; plural=n != 1;\n"
18−"X-Launchpad-Export-Date: 2015-04-23 06:48+0000\n"
18+"X-Launchpad-Export-Date: 2015-06-23 05:33+0000\n"
19−"X-Generator: Launchpad (build 17430)\n"
19+"X-Generator: Launchpad (build 17572)\n"
20
20
21#: plugins/LightDM/Greeter.cpp:112
21#: plugins/LightDM/Greeter.cpp:112
22msgid "Password: "
22msgid "Password: "
@@ -375,7 +375,7 @@ msgstr "Toccare qui per continuare."
375
375
376#: qml/Tutorial/TutorialContent.qml:81
376#: qml/Tutorial/TutorialContent.qml:81
377msgid "Click here to finish."
377msgid "Click here to finish."
378−msgstr ""
378+msgstr "Fare clic qui per terminare."
379
379
380#: qml/Tutorial/TutorialLeftFinish.qml:24
380#: qml/Tutorial/TutorialLeftFinish.qml:24
381msgid "These are the shortcuts to favorite apps"
381msgid "These are the shortcuts to favorite apps"
@@ -640,11 +640,6 @@ msgstr "%1 〉"
640#~ msgstr ""
640#~ msgstr ""
641#~ "Provare a far scorrere dal bordo in alto per accedere agli indicatori"
641#~ "Provare a far scorrere dal bordo in alto per accedere agli indicatori"
642
642
643−#~ msgid "Swipe up again to close the settings screen"
644−#~ msgstr ""
645−#~ "Far scorrere verso l'alto nuovamente per chiudere la schermata delle "
646−#~ "impostazioni"
647−
648#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
643#~ msgid "Swipe from the left to reveal the launcher for quick access to apps"
649#~ msgstr ""
644#~ msgstr ""
650#~ "Far scorrere il bordo sinistro per mostrare il Launcher e avere un rapido "
645#~ "Far scorrere il bordo sinistro per mostrare il Launcher e avere un rapido "
@@ -698,3 +693,8 @@ msgstr "%1 〉"
698
693
699#~ msgid "Manage Scopes"
694#~ msgid "Manage Scopes"
700#~ msgstr "Gestisci Scope"
695#~ msgstr "Gestisci Scope"
696+
697+#~ msgid "Swipe up again to close the settings screen"
698+#~ msgstr ""
699+#~ "Far scorrere nuovamente verso l'alto per chiudere la schermata delle "
700+#~ "impostazioni"
po/zh_CN.po+93−94
@@ -8,15 +8,15 @@ msgstr ""
8"Project-Id-Version: unity\n"
8"Project-Id-Version: unity\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
9"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
10"POT-Creation-Date: 2015-04-14 16:13+0200\n"
10"POT-Creation-Date: 2015-04-14 16:13+0200\n"
11−"PO-Revision-Date: 2015-04-28 20:51+0000\n"
11+"PO-Revision-Date: 2015-06-29 07:55+0000\n"
12−"Last-Translator: Aron Xu <Unknown>\n"
12+"Last-Translator: Mydin <imydin@163.com>\n"
13"Language-Team: Chinese (Simplified) <zh_CN@li.org>\n"
13"Language-Team: Chinese (Simplified) <zh_CN@li.org>\n"
14"MIME-Version: 1.0\n"
14"MIME-Version: 1.0\n"
15"Content-Type: text/plain; charset=UTF-8\n"
15"Content-Type: text/plain; charset=UTF-8\n"
16"Content-Transfer-Encoding: 8bit\n"
16"Content-Transfer-Encoding: 8bit\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
17"Plural-Forms: nplurals=1; plural=0;\n"
18−"X-Launchpad-Export-Date: 2015-04-29 05:27+0000\n"
18+"X-Launchpad-Export-Date: 2015-06-30 05:51+0000\n"
19−"X-Generator: Launchpad (build 17453)\n"
19+"X-Generator: Launchpad (build 17578)\n"
20
20
21#: plugins/LightDM/Greeter.cpp:112
21#: plugins/LightDM/Greeter.cpp:112
22msgid "Password: "
22msgid "Password: "
@@ -33,22 +33,21 @@ msgstr "取消固定快捷方式"
33
33
34#: qml/Components/DelayedLockscreen.qml:49
34#: qml/Components/DelayedLockscreen.qml:49
35msgid "Device Locked"
35msgid "Device Locked"
36−msgstr ""
36+msgstr "设备锁定"
37
37
38#: qml/Components/DelayedLockscreen.qml:64
38#: qml/Components/DelayedLockscreen.qml:64
39msgid "You have been locked out due to too many failed passphrase attempts."
39msgid "You have been locked out due to too many failed passphrase attempts."
40−msgstr ""
40+msgstr "您因太多失败的口令密语尝试而被锁定。"
41
41
42#: qml/Components/DelayedLockscreen.qml:65
42#: qml/Components/DelayedLockscreen.qml:65
43msgid "You have been locked out due to too many failed passcode attempts."
43msgid "You have been locked out due to too many failed passcode attempts."
44−msgstr ""
44+msgstr "您因太多失败的密码尝试而被锁定。"
45
45
46#: qml/Components/DelayedLockscreen.qml:74
46#: qml/Components/DelayedLockscreen.qml:74
47#, qt-format
47#, qt-format
48msgid "Please wait %1 minute and then try again…"
48msgid "Please wait %1 minute and then try again…"
49msgid_plural "Please wait %1 minutes and then try again…"
49msgid_plural "Please wait %1 minutes and then try again…"
50−msgstr[0] ""
50+msgstr[0] "请稍候 %1 分钟,然后重试..."
51−msgstr[1] ""
52
51
53#: qml/Components/Dialogs.qml:69
52#: qml/Components/Dialogs.qml:69
54msgctxt "Title: Lock/Log out dialog"
53msgctxt "Title: Lock/Log out dialog"
@@ -57,7 +56,7 @@ msgstr "退出"
57
56
58#: qml/Components/Dialogs.qml:70
57#: qml/Components/Dialogs.qml:70
59msgid "Are you sure you want to log out?"
58msgid "Are you sure you want to log out?"
60−msgstr ""
59+msgstr "您确定要注销?"
61
60
62#: qml/Components/Dialogs.qml:72
61#: qml/Components/Dialogs.qml:72
63msgctxt "Button: Lock the system"
62msgctxt "Button: Lock the system"
@@ -113,7 +112,7 @@ msgstr "是"
113#: qml/Components/Dialogs.qml:152
112#: qml/Components/Dialogs.qml:152
114msgctxt "Title: Power off/Restart dialog"
113msgctxt "Title: Power off/Restart dialog"
115msgid "Power"
114msgid "Power"
116−msgstr ""
115+msgstr "电源"
117
116
118#: qml/Components/Dialogs.qml:153
117#: qml/Components/Dialogs.qml:153
119msgid ""
118msgid ""
@@ -126,7 +125,7 @@ msgstr ""
126#: qml/Components/Dialogs.qml:155
125#: qml/Components/Dialogs.qml:155
127msgctxt "Button: Power off the system"
126msgctxt "Button: Power off the system"
128msgid "Power off"
127msgid "Power off"
129−msgstr "关机"
128+msgstr "关闭电源"
130
129
131#: qml/Components/Dialogs.qml:164
130#: qml/Components/Dialogs.qml:164
132msgctxt "Button: Restart the system"
131msgctxt "Button: Restart the system"
@@ -135,7 +134,7 @@ msgstr "重启"
135
134
136#: qml/Components/Lockscreen.qml:245
135#: qml/Components/Lockscreen.qml:245
137msgid "Return to Call"
136msgid "Return to Call"
138−msgstr ""
137+msgstr "回到呼叫"
139
138
140#: qml/Components/Lockscreen.qml:245
139#: qml/Components/Lockscreen.qml:245
141msgid "Emergency Call"
140msgid "Emergency Call"
@@ -161,7 +160,7 @@ msgstr "搜索"
161#: qml/Dash/PageHeader.qml:269
160#: qml/Dash/PageHeader.qml:269
162msgctxt "Button: Open the Ubuntu Store"
161msgctxt "Button: Open the Ubuntu Store"
163msgid "Store"
162msgid "Store"
164−msgstr ""
163+msgstr "商店"
165
164
166#: qml/Dash/PageHeader.qml:276
165#: qml/Dash/PageHeader.qml:276
167msgctxt "Button: Start a search in the current dash scope"
166msgctxt "Button: Start a search in the current dash scope"
@@ -175,11 +174,11 @@ msgstr "设置"
175
174
176#: qml/Dash/PageHeader.qml:293
175#: qml/Dash/PageHeader.qml:293
177msgid "Remove from Favorites"
176msgid "Remove from Favorites"
178−msgstr ""
177+msgstr "从收藏夹中移除"
179
178
180#: qml/Dash/PageHeader.qml:293
179#: qml/Dash/PageHeader.qml:293
181msgid "Add to Favorites"
180msgid "Add to Favorites"
182−msgstr ""
181+msgstr "添加到收藏夹"
183
182
184#: qml/Dash/Previews/PreviewActionCombo.qml:35
183#: qml/Dash/Previews/PreviewActionCombo.qml:35
185msgid "More..."
184msgid "More..."
@@ -203,93 +202,93 @@ msgstr "发送"
203
202
204#: qml/Dash/PullToRefreshScopeStyle.qml:55
203#: qml/Dash/PullToRefreshScopeStyle.qml:55
205msgid "Pull to refresh…"
204msgid "Pull to refresh…"
206−msgstr ""
205+msgstr "下拉刷新..."
207
206
208#: qml/Dash/PullToRefreshScopeStyle.qml:60
207#: qml/Dash/PullToRefreshScopeStyle.qml:60
209msgid "Release to refresh…"
208msgid "Release to refresh…"
210−msgstr ""
209+msgstr "放开刷新..."
211
210
212#: qml/Dash/ScopeSettings/ScopeSettingBoolean.qml:43
211#: qml/Dash/ScopeSettings/ScopeSettingBoolean.qml:43
213msgid "Enable location data"
212msgid "Enable location data"
214−msgstr ""
213+msgstr "启用位置信息"
215
214
216#: qml/Dash/ScopesList.qml:66
215#: qml/Dash/ScopesList.qml:66
217msgid "Manage"
216msgid "Manage"
218−msgstr ""
217+msgstr "管理"
219
218
220#: qml/Dash/ScopesList.qml:112
219#: qml/Dash/ScopesList.qml:112
221msgid "Home"
220msgid "Home"
222−msgstr ""
221+msgstr "首页"
223
222
224#: qml/Dash/ScopesList.qml:113
223#: qml/Dash/ScopesList.qml:113
225msgid "Also installed"
224msgid "Also installed"
226−msgstr ""
225+msgstr "已安装"
227
226
228#: qml/Greeter/CoverPage.qml:107
227#: qml/Greeter/CoverPage.qml:107
229msgid "Unlock"
228msgid "Unlock"
230−msgstr ""
229+msgstr "解锁"
231
230
232#: qml/Greeter/LoginList.qml:236
231#: qml/Greeter/LoginList.qml:236
233msgid "Retry"
232msgid "Retry"
234−msgstr ""
233+msgstr "重试"
235
234
236#: qml/Greeter/LoginList.qml:237
235#: qml/Greeter/LoginList.qml:237
237msgid "Tap to unlock"
236msgid "Tap to unlock"
238−msgstr ""
237+msgstr "点击解锁"
239
238
240#: qml/Greeter/NarrowView.qml:53 qml/Wizard/Pages/passwd-confirm.qml:53
239#: qml/Greeter/NarrowView.qml:53 qml/Wizard/Pages/passwd-confirm.qml:53
241msgid "Sorry, incorrect passphrase."
240msgid "Sorry, incorrect passphrase."
242−msgstr ""
241+msgstr "对不起,口令密语错误"
243
242
244#: qml/Greeter/NarrowView.qml:54 qml/Wizard/Pages/passwd-confirm.qml:54
243#: qml/Greeter/NarrowView.qml:54 qml/Wizard/Pages/passwd-confirm.qml:54
245msgid "Sorry, incorrect passcode."
244msgid "Sorry, incorrect passcode."
246−msgstr ""
245+msgstr "对不起,密码错误。"
247
246
248#: qml/Greeter/NarrowView.qml:55
247#: qml/Greeter/NarrowView.qml:55
249msgid "This will be your last attempt."
248msgid "This will be your last attempt."
250−msgstr ""
249+msgstr "这是您最后的尝试机会。"
251
250
252#: qml/Greeter/NarrowView.qml:57
251#: qml/Greeter/NarrowView.qml:57
253msgid ""
252msgid ""
254"If passphrase is entered incorrectly, your phone will conduct a factory "
253"If passphrase is entered incorrectly, your phone will conduct a factory "
255"reset and all personal data will be deleted."
254"reset and all personal data will be deleted."
256−msgstr ""
255+msgstr "如果输入的密语不正确,您的手机将恢复到出厂设置并且所有的个人数据将被删除。"
257
256
258#: qml/Greeter/NarrowView.qml:58
257#: qml/Greeter/NarrowView.qml:58
259msgid ""
258msgid ""
260"If passcode is entered incorrectly, your phone will conduct a factory reset "
259"If passcode is entered incorrectly, your phone will conduct a factory reset "
261"and all personal data will be deleted."
260"and all personal data will be deleted."
262−msgstr ""
261+msgstr "如果输入的密码不正确,您的手机将恢复到出厂设置并且所有的个人数据将被删除。"
263
262
264#: qml/Greeter/NarrowView.qml:115
263#: qml/Greeter/NarrowView.qml:115
265#, qt-format
264#, qt-format
266msgid "Enter %1"
265msgid "Enter %1"
267−msgstr ""
266+msgstr "输入 %1"
268
267
269#: qml/Greeter/NarrowView.qml:116 qml/Wizard/Pages/passwd-set.qml:60
268#: qml/Greeter/NarrowView.qml:116 qml/Wizard/Pages/passwd-set.qml:60
270msgid "Enter passphrase"
269msgid "Enter passphrase"
271−msgstr ""
270+msgstr "输入口令密语"
272
271
273#: qml/Greeter/NarrowView.qml:117
272#: qml/Greeter/NarrowView.qml:117
274msgid "Enter passcode"
273msgid "Enter passcode"
275−msgstr ""
274+msgstr "输入密码"
276
275
277#: qml/Greeter/NarrowView.qml:118
276#: qml/Greeter/NarrowView.qml:118
278#, qt-format
277#, qt-format
279msgid "Sorry, incorrect %1"
278msgid "Sorry, incorrect %1"
280−msgstr ""
279+msgstr "对不起,%1 不正确"
281
280
282#: qml/Greeter/NarrowView.qml:119
281#: qml/Greeter/NarrowView.qml:119
283msgid "Sorry, incorrect passphrase"
282msgid "Sorry, incorrect passphrase"
284−msgstr ""
283+msgstr "对不起,密语不正确"
285
284
286#: qml/Greeter/NarrowView.qml:120
285#: qml/Greeter/NarrowView.qml:120
287msgid "Please re-enter"
286msgid "Please re-enter"
288−msgstr ""
287+msgstr "请重新输入"
289
288
290#: qml/Greeter/NarrowView.qml:121
289#: qml/Greeter/NarrowView.qml:121
291msgid "Sorry, incorrect passcode"
290msgid "Sorry, incorrect passcode"
292−msgstr ""
291+msgstr "对不起,密码错误"
293
292
294#: qml/Notifications/NotificationMenuItemFactory.qml:128
293#: qml/Notifications/NotificationMenuItemFactory.qml:128
295msgid "Show password"
294msgid "Show password"
@@ -305,7 +304,7 @@ msgstr "会议"
305
304
306#: qml/Panel/Indicators/MenuItemFactory.qml:639
305#: qml/Panel/Indicators/MenuItemFactory.qml:639
307msgid "Nothing is playing"
306msgid "Nothing is playing"
308−msgstr ""
307+msgstr "无正在播放的项目"
309
308
310#: qml/Panel/Indicators/MenuItemFactory.qml:787
309#: qml/Panel/Indicators/MenuItemFactory.qml:787
311msgid "In queue…"
310msgid "In queue…"
@@ -334,7 +333,7 @@ msgstr "下载失败,请点击重试"
334#: qml/Panel/Indicators/MessageMenuItemFactory.qml:149
333#: qml/Panel/Indicators/MessageMenuItemFactory.qml:149
335msgctxt "Label: Hint in message indicator line edit"
334msgctxt "Label: Hint in message indicator line edit"
336msgid "Reply"
335msgid "Reply"
337−msgstr ""
336+msgstr "回复"
338
337
339#: qml/Panel/Indicators/ModemInfoItem.qml:105
338#: qml/Panel/Indicators/ModemInfoItem.qml:105
340msgid "Unlock SIM"
339msgid "Unlock SIM"
@@ -346,244 +345,244 @@ msgstr "漫游"
346
345
347#: qml/Tutorial/TutorialBottomFinish.qml:24
346#: qml/Tutorial/TutorialBottomFinish.qml:24
348msgid "This action does different things for different apps"
347msgid "This action does different things for different apps"
349−msgstr ""
348+msgstr "这个操作对不同的应用有不同的行为"
350
349
351#: qml/Tutorial/TutorialBottomFinish.qml:25
350#: qml/Tutorial/TutorialBottomFinish.qml:25
352msgid "Tap here to finish."
351msgid "Tap here to finish."
353−msgstr ""
352+msgstr "点击这里完成。"
354
353
355#: qml/Tutorial/TutorialBottom.qml:28
354#: qml/Tutorial/TutorialBottom.qml:28
356msgid "Open special menus"
355msgid "Open special menus"
357−msgstr ""
356+msgstr "打开专题菜单"
358
357
359#: qml/Tutorial/TutorialBottom.qml:29
358#: qml/Tutorial/TutorialBottom.qml:29
360msgid "Swipe up from the bottom edge."
359msgid "Swipe up from the bottom edge."
361−msgstr ""
360+msgstr "从底部边缘上滑"
362
361
363#: qml/Tutorial/TutorialContent.qml:81 qml/Tutorial/TutorialLeftFinish.qml:25
362#: qml/Tutorial/TutorialContent.qml:81 qml/Tutorial/TutorialLeftFinish.qml:25
364#: qml/Tutorial/TutorialRight.qml:144
363#: qml/Tutorial/TutorialRight.qml:144
365msgid "Tap here to continue."
364msgid "Tap here to continue."
366−msgstr ""
365+msgstr "点击这里继续"
367
366
368#: qml/Tutorial/TutorialContent.qml:81
367#: qml/Tutorial/TutorialContent.qml:81
369msgid "Click here to finish."
368msgid "Click here to finish."
370−msgstr ""
369+msgstr "点击这里完成。"
371
370
372#: qml/Tutorial/TutorialLeftFinish.qml:24
371#: qml/Tutorial/TutorialLeftFinish.qml:24
373msgid "These are the shortcuts to favorite apps"
372msgid "These are the shortcuts to favorite apps"
374−msgstr ""
373+msgstr "这里是已收藏应用的快捷方式"
375
374
376#: qml/Tutorial/TutorialLeft.qml:26
375#: qml/Tutorial/TutorialLeft.qml:26
377msgid "Open the launcher"
376msgid "Open the launcher"
378−msgstr ""
377+msgstr "打开启动器"
379
378
380#: qml/Tutorial/TutorialLeft.qml:27
379#: qml/Tutorial/TutorialLeft.qml:27
381msgid "Short swipe from the left edge."
380msgid "Short swipe from the left edge."
382−msgstr ""
381+msgstr "从左侧边缘短距离滑动。"
383
382
384#: qml/Tutorial/TutorialPage.qml:178
383#: qml/Tutorial/TutorialPage.qml:178
385msgid "You almost got it!"
384msgid "You almost got it!"
386−msgstr ""
385+msgstr "即将完成!"
387
386
388#: qml/Tutorial/TutorialPage.qml:195
387#: qml/Tutorial/TutorialPage.qml:195
389msgid "Try again."
388msgid "Try again."
390−msgstr ""
389+msgstr "再试试。"
391
390
392#: qml/Tutorial/TutorialRight.qml:31
391#: qml/Tutorial/TutorialRight.qml:31
393msgid "To view open apps"
392msgid "To view open apps"
394−msgstr ""
393+msgstr "查看打开的应用"
395
394
396#: qml/Tutorial/TutorialRight.qml:32
395#: qml/Tutorial/TutorialRight.qml:32
397msgid "Long swipe from the right edge."
396msgid "Long swipe from the right edge."
398−msgstr ""
397+msgstr "从右侧边缘长距离滑动。"
399
398
400#: qml/Tutorial/TutorialRight.qml:122
399#: qml/Tutorial/TutorialRight.qml:122
401msgid "View all your running tasks."
400msgid "View all your running tasks."
402−msgstr ""
401+msgstr "查看你所有运行的任务。"
403
402
404#: qml/Wizard/Page.qml:89
403#: qml/Wizard/Page.qml:89
405msgctxt "Button: Go back one page in the Wizard"
404msgctxt "Button: Go back one page in the Wizard"
406msgid "Back"
405msgid "Back"
407−msgstr ""
406+msgstr "上一步"
408
407
409#: qml/Wizard/Pages/10-welcome.qml:27
408#: qml/Wizard/Pages/10-welcome.qml:27
410msgid "Hi!"
409msgid "Hi!"
411−msgstr ""
410+msgstr "Hi!"
412
411
413#: qml/Wizard/Pages/10-welcome.qml:44
412#: qml/Wizard/Pages/10-welcome.qml:44
414msgid "Welcome to your Ubuntu phone."
413msgid "Welcome to your Ubuntu phone."
415−msgstr ""
414+msgstr "欢迎使用您的 Ubuntu 手机。"
416
415
417#: qml/Wizard/Pages/10-welcome.qml:52
416#: qml/Wizard/Pages/10-welcome.qml:52
418msgid "Let’s get started."
417msgid "Let’s get started."
419−msgstr ""
418+msgstr "让我们开始吧。"
420
419
421#: qml/Wizard/Pages/10-welcome.qml:88 qml/Wizard/Pages/30-passwd-type.qml:128
420#: qml/Wizard/Pages/10-welcome.qml:88 qml/Wizard/Pages/30-passwd-type.qml:128
422#: qml/Wizard/Pages/40-wifi.qml:215 qml/Wizard/Pages/50-location.qml:131
421#: qml/Wizard/Pages/40-wifi.qml:215 qml/Wizard/Pages/50-location.qml:131
423#: qml/Wizard/Pages/60-reporting.qml:50 qml/Wizard/Pages/passwd-confirm.qml:82
422#: qml/Wizard/Pages/60-reporting.qml:50 qml/Wizard/Pages/passwd-confirm.qml:82
424#: qml/Wizard/Pages/passwd-set.qml:90
423#: qml/Wizard/Pages/passwd-set.qml:90
425msgid "Continue"
424msgid "Continue"
426−msgstr ""
425+msgstr "下一步"
427
426
428#: qml/Wizard/Pages/20-sim.qml:25
427#: qml/Wizard/Pages/20-sim.qml:25
429msgid "Add a SIM card and restart your device"
428msgid "Add a SIM card and restart your device"
430−msgstr ""
429+msgstr "插入 SIM 卡并重启你的设备"
431
430
432#: qml/Wizard/Pages/20-sim.qml:59
431#: qml/Wizard/Pages/20-sim.qml:59
433msgid "Without it, you won’t be able to make calls or use text messaging."
432msgid "Without it, you won’t be able to make calls or use text messaging."
434−msgstr ""
433+msgstr "离开它,您将不能使用电话或短信功能。"
435
434
436#: qml/Wizard/Pages/20-sim.qml:73 qml/Wizard/Pages/40-wifi.qml:215
435#: qml/Wizard/Pages/20-sim.qml:73 qml/Wizard/Pages/40-wifi.qml:215
437msgid "Skip"
436msgid "Skip"
438−msgstr ""
437+msgstr "跳过"
439
438
440#: qml/Wizard/Pages/30-passwd-type.qml:39
439#: qml/Wizard/Pages/30-passwd-type.qml:39
441msgid "Lock security"
440msgid "Lock security"
442−msgstr ""
441+msgstr "锁屏安全设定"
443
442
444#: qml/Wizard/Pages/30-passwd-type.qml:74
443#: qml/Wizard/Pages/30-passwd-type.qml:74
445msgid "Please select how you’d like to unlock your phone."
444msgid "Please select how you’d like to unlock your phone."
446−msgstr ""
445+msgstr "请选择您喜欢的手机解锁方式。"
447
446
448#: qml/Wizard/Pages/30-passwd-type.qml:97
447#: qml/Wizard/Pages/30-passwd-type.qml:97
449msgctxt "Label: Type of security method"
448msgctxt "Label: Type of security method"
450msgid "Swipe"
449msgid "Swipe"
451−msgstr ""
450+msgstr "滑动"
452
451
453#: qml/Wizard/Pages/30-passwd-type.qml:98
452#: qml/Wizard/Pages/30-passwd-type.qml:98
454msgctxt "Label: Description of security method"
453msgctxt "Label: Description of security method"
455msgid "No security"
454msgid "No security"
456−msgstr ""
455+msgstr "无安全机制"
457
456
458#: qml/Wizard/Pages/30-passwd-type.qml:100
457#: qml/Wizard/Pages/30-passwd-type.qml:100
459msgctxt "Label: Type of security method"
458msgctxt "Label: Type of security method"
460msgid "Passcode"
459msgid "Passcode"
461−msgstr ""
460+msgstr "密码"
462
461
463#: qml/Wizard/Pages/30-passwd-type.qml:101
462#: qml/Wizard/Pages/30-passwd-type.qml:101
464msgctxt "Label: Description of security method"
463msgctxt "Label: Description of security method"
465msgid "4 digits only"
464msgid "4 digits only"
466−msgstr ""
465+msgstr "仅4位数"
467
466
468#: qml/Wizard/Pages/30-passwd-type.qml:103
467#: qml/Wizard/Pages/30-passwd-type.qml:103
469msgctxt "Label: Type of security method"
468msgctxt "Label: Type of security method"
470msgid "Passphrase"
469msgid "Passphrase"
471−msgstr ""
470+msgstr "口令密语"
472
471
473#: qml/Wizard/Pages/30-passwd-type.qml:104
472#: qml/Wizard/Pages/30-passwd-type.qml:104
474msgctxt "Label: Description of security method"
473msgctxt "Label: Description of security method"
475msgid "Numbers and letters"
474msgid "Numbers and letters"
476−msgstr ""
475+msgstr "数字和字母"
477
476
478#: qml/Wizard/Pages/40-wifi.qml:29
477#: qml/Wizard/Pages/40-wifi.qml:29
479msgid "Connect to Wi‑Fi"
478msgid "Connect to Wi‑Fi"
480−msgstr ""
479+msgstr "连接 Wi-Fi"
481
480
482#: qml/Wizard/Pages/40-wifi.qml:168
481#: qml/Wizard/Pages/40-wifi.qml:168
483msgid "Available networks…"
482msgid "Available networks…"
484−msgstr ""
483+msgstr "可用的网络..."
485
484
486#: qml/Wizard/Pages/40-wifi.qml:169
485#: qml/Wizard/Pages/40-wifi.qml:169
487msgid "No available networks."
486msgid "No available networks."
488−msgstr ""
487+msgstr "无可用网络。"
489
488
490#: qml/Wizard/Pages/50-location.qml:27
489#: qml/Wizard/Pages/50-location.qml:27
491msgid "Location"
490msgid "Location"
492−msgstr ""
491+msgstr "位置"
493
492
494#: qml/Wizard/Pages/50-location.qml:62
493#: qml/Wizard/Pages/50-location.qml:62
495msgid "Let the phone detect your location:"
494msgid "Let the phone detect your location:"
496−msgstr ""
495+msgstr "允许手机检测您的位置:"
497
496
498#: qml/Wizard/Pages/50-location.qml:69
497#: qml/Wizard/Pages/50-location.qml:69
499msgid "Using GPS only (less accurate)"
498msgid "Using GPS only (less accurate)"
500−msgstr ""
499+msgstr "仅使用 GPS (不精确)"
501
500
502#: qml/Wizard/Pages/50-location.qml:86
501#: qml/Wizard/Pages/50-location.qml:86
503msgid "Using GPS, anonymized Wi-Fi and cellular network info (recommended)"
502msgid "Using GPS, anonymized Wi-Fi and cellular network info (recommended)"
504−msgstr ""
503+msgstr "使用 GPS、匿名 Wi-Fi 和移动网络信息 (推荐)"
505
504
506#. TRANSLATORS: HERE is a trademark for Nokia's location service, you probably shouldn't translate it
505#. TRANSLATORS: HERE is a trademark for Nokia's location service, you probably shouldn't translate it
507#: qml/Wizard/Pages/50-location.qml:103
506#: qml/Wizard/Pages/50-location.qml:103
508msgid ""
507msgid ""
509"By selecting this option you agree to the Nokia HERE <a href='#'>terms and "
508"By selecting this option you agree to the Nokia HERE <a href='#'>terms and "
510"conditions</a>."
509"conditions</a>."
511−msgstr ""
510+msgstr "选择这个选项表示你同意 Nokia HERE <a href='#'>条款声明</a>。"
512
511
513#: qml/Wizard/Pages/50-location.qml:112
512#: qml/Wizard/Pages/50-location.qml:112
514msgid "Not at all"
513msgid "Not at all"
515−msgstr ""
514+msgstr "一点也不"
516
515
517#: qml/Wizard/Pages/50-location.qml:124
516#: qml/Wizard/Pages/50-location.qml:124
518msgid "You can change your mind later in <b>System Settings</b>."
517msgid "You can change your mind later in <b>System Settings</b>."
519−msgstr ""
518+msgstr "你可以稍后通过<b>系统设置</b>改变你的决定。"
520
519
521#: qml/Wizard/Pages/60-reporting.qml:24
520#: qml/Wizard/Pages/60-reporting.qml:24
522msgid "Improving your experience"
521msgid "Improving your experience"
523−msgstr ""
522+msgstr "改善您的体验"
524
523
525#: qml/Wizard/Pages/60-reporting.qml:36
524#: qml/Wizard/Pages/60-reporting.qml:36
526msgid ""
525msgid ""
527"Your phone is set up to automatically report errors to Canonical and its "
526"Your phone is set up to automatically report errors to Canonical and its "
528"partners, the makers of the operating system."
527"partners, the makers of the operating system."
529−msgstr ""
528+msgstr "您的手机设置为自动向操作系统的制造商Canonical 及其合作伙伴发送错误报告。"
530
529
531#: qml/Wizard/Pages/60-reporting.qml:43
530#: qml/Wizard/Pages/60-reporting.qml:43
532msgid ""
531msgid ""
533"This can be disabled in <b>System Settings</b> under <b>Security &amp; "
532"This can be disabled in <b>System Settings</b> under <b>Security &amp; "
534"Privacy</b>"
533"Privacy</b>"
535−msgstr ""
534+msgstr "这个可以在<b>系统设置</b>下的 <b>安全与隐私</b>里被禁用。"
536
535
537#: qml/Wizard/Pages/80-finished.qml:24
536#: qml/Wizard/Pages/80-finished.qml:24
538msgid "All done"
537msgid "All done"
539−msgstr ""
538+msgstr "大功告成"
540
539
541#: qml/Wizard/Pages/80-finished.qml:39
540#: qml/Wizard/Pages/80-finished.qml:39
542msgid "Nice work!"
541msgid "Nice work!"
543−msgstr ""
542+msgstr "干得好!"
544
543
545#: qml/Wizard/Pages/80-finished.qml:46
544#: qml/Wizard/Pages/80-finished.qml:46
546msgid "Your phone is now ready to use."
545msgid "Your phone is now ready to use."
547−msgstr ""
546+msgstr "您的手机现在可以使用了。"
548
547
549#: qml/Wizard/Pages/80-finished.qml:53
548#: qml/Wizard/Pages/80-finished.qml:53
550msgid "Finish"
549msgid "Finish"
551−msgstr ""
550+msgstr "结束"
552
551
553#: qml/Wizard/Pages/here-terms.qml:27
552#: qml/Wizard/Pages/here-terms.qml:27
554msgid "Terms & Conditions"
553msgid "Terms & Conditions"
555−msgstr ""
554+msgstr "条款与条件"
556
555
557#: qml/Wizard/Pages/passwd-confirm.qml:49
556#: qml/Wizard/Pages/passwd-confirm.qml:49
558msgid "Confirm passphrase"
557msgid "Confirm passphrase"
559−msgstr ""
558+msgstr "确认口令密语"
560
559
561#: qml/Wizard/Pages/passwd-confirm.qml:50
560#: qml/Wizard/Pages/passwd-confirm.qml:50
562msgid "Confirm passcode"
561msgid "Confirm passcode"
563−msgstr ""
562+msgstr "确认新密码"
564
563
565#: qml/Wizard/Pages/passwd-confirm.qml:53
564#: qml/Wizard/Pages/passwd-confirm.qml:53
566#: qml/Wizard/Pages/passwd-confirm.qml:54
565#: qml/Wizard/Pages/passwd-confirm.qml:54
567msgid "Please try again."
566msgid "Please try again."
568−msgstr ""
567+msgstr "请再试一次。"
569
568
570#: qml/Wizard/Pages/passwd-set.qml:61
569#: qml/Wizard/Pages/passwd-set.qml:61
571msgid "Choose your passcode"
570msgid "Choose your passcode"
572−msgstr ""
571+msgstr "选择您的密码"
573
572
574#: qml/Wizard/Pages/passwd-set.qml:68
573#: qml/Wizard/Pages/passwd-set.qml:68
575msgid "Passphrase must be 4 characters long"
574msgid "Passphrase must be 4 characters long"
576−msgstr ""
575+msgstr "口令密语必须为4个字符长度"
577
576
578#: qml/Wizard/StackButton.qml:39
577#: qml/Wizard/StackButton.qml:39
579#, qt-format
578#, qt-format
580msgid "〈 %1"
579msgid "〈 %1"
581−msgstr ""
580+msgstr "〈 %1"
582
581
583#: qml/Wizard/StackButton.qml:42
582#: qml/Wizard/StackButton.qml:42
584#, qt-format
583#, qt-format
585msgid "%1 〉"
584msgid "%1 〉"
586−msgstr ""
585+msgstr "%1 〉"
587
586
588#~ msgid "Confirm"
587#~ msgid "Confirm"
589#~ msgstr "确认"
588#~ msgstr "确认"
qml/Components/PinLockscreen.qml+1−5
@@ -52,7 +52,7 @@ Item {
52 verticalCenter: parent.verticalCenter;
52 verticalCenter: parent.verticalCenter;
53 verticalCenterOffset: Math.max(-units.gu(10), -(root.height - height) / 2) + units.gu(4)
53 verticalCenterOffset: Math.max(-units.gu(10), -(root.height - height) / 2) + units.gu(4)
54 }
54 }
55− spacing: units.gu(2)
55+ spacing: units.gu(4)
56
56
57 Column {
57 Column {
58 id: shakeContainer
58 id: shakeContainer
@@ -154,10 +154,6 @@ Item {
154 }
154 }
155 }
155 }
156
156
157− ThinDivider {
158− anchors { left: parent.left; right: parent.right; margins: units.gu(2) }
159− }
160−
161 Grid {
157 Grid {
162 id: numbersGrid
158 id: numbersGrid
163 objectName: "numbersGrid"
159 objectName: "numbersGrid"
qml/Components/ResponsiveVerticalJournal.qml+7−2
@@ -39,6 +39,8 @@ import Dash 0.1
39 +-----+
39 +-----+
40*/
40*/
41Item {
41Item {
42+ id: root
43+
42 property real minimumColumnSpacing: units.gu(1)
44 property real minimumColumnSpacing: units.gu(1)
43
45
44 property alias columnWidth: verticalJournalView.columnWidth
46 property alias columnWidth: verticalJournalView.columnWidth
@@ -46,8 +48,8 @@ Item {
46 property alias model: verticalJournalView.model
48 property alias model: verticalJournalView.model
47 property alias delegate: verticalJournalView.delegate
49 property alias delegate: verticalJournalView.delegate
48 property alias cacheBuffer: verticalJournalView.cacheBuffer
50 property alias cacheBuffer: verticalJournalView.cacheBuffer
49− property alias displayMarginBeginning: verticalJournalView.displayMarginBeginning
51+ property real displayMarginBeginning: 0
50− property alias displayMarginEnd: verticalJournalView.displayMarginEnd
52+ property real displayMarginEnd: 0
51
53
52 implicitHeight: verticalJournalView.implicitHeight + rowSpacing
54 implicitHeight: verticalJournalView.implicitHeight + rowSpacing
53 clip: height < implicitHeight
55 clip: height < implicitHeight
@@ -63,6 +65,9 @@ Item {
63 bottomMargin: rowSpacing / 2
65 bottomMargin: rowSpacing / 2
64 }
66 }
65
67
68+ displayMarginBeginning: -Math.max(-root.displayMarginBeginning - anchors.topMargin, 0)
69+ displayMarginEnd:-Math.max(-root.displayMarginEnd - anchors.topMargin, 0)
70+
66 function px2gu(pixels) {
71 function px2gu(pixels) {
67 return Math.floor(pixels / units.gu(1))
72 return Math.floor(pixels / units.gu(1))
68 }
73 }
qml/Components/ZoomableImage.qml+1
@@ -30,6 +30,7 @@ Item {
30 property var zoomable: false
30 property var zoomable: false
31 property alias imageStatus: imageRenderer.status
31 property alias imageStatus: imageRenderer.status
32 property alias asynchronous: imageRenderer.asynchronous
32 property alias asynchronous: imageRenderer.asynchronous
33+ readonly property alias status: imageRenderer.status
33
34
34 Flickable {
35 Flickable {
35 id: flickable
36 id: flickable
qml/Dash/CardCarousel.qml−1
@@ -61,7 +61,6 @@ DashRenderer {
61 item.fixedHeaderHeight = Qt.binding(function() { return carousel.headerHeight; });
61 item.fixedHeaderHeight = Qt.binding(function() { return carousel.headerHeight; });
62 item.height = Qt.binding(function() { return cardTool.cardHeight; });
62 item.height = Qt.binding(function() { return cardTool.cardHeight; });
63 item.cardData = Qt.binding(function() { return model; });
63 item.cardData = Qt.binding(function() { return model; });
64− item.template = Qt.binding(function() { return cardTool.template; });
65 item.components = Qt.binding(function() { return cardTool.components; });
64 item.components = Qt.binding(function() { return cardTool.components; });
66 item.fontScale = Qt.binding(function() { return carousel.fontScale; });
65 item.fontScale = Qt.binding(function() { return carousel.fontScale; });
67 item.showHeader = Qt.binding(function() { return loader.explicitlyScaled; });
66 item.showHeader = Qt.binding(function() { return loader.explicitlyScaled; });
qml/Dash/CardGrid.qml−1
@@ -66,7 +66,6 @@ DashRenderer {
66 item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
66 item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
67 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
67 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
68 item.cardData = Qt.binding(function() { return model; });
68 item.cardData = Qt.binding(function() { return model; });
69− item.template = Qt.binding(function() { return cardTool.template; });
70 item.components = Qt.binding(function() { return cardTool.components; });
69 item.components = Qt.binding(function() { return cardTool.components; });
71 item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
70 item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
72 item.scopeStyle = root.scopeStyle;
71 item.scopeStyle = root.scopeStyle;
qml/Dash/CardHorizontalList.qml−1
@@ -53,7 +53,6 @@ DashRenderer {
53 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
53 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
54 item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
54 item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
55 item.cardData = Qt.binding(function() { return model; });
55 item.cardData = Qt.binding(function() { return model; });
56− item.template = Qt.binding(function() { return cardTool.template; });
57 item.components = Qt.binding(function() { return cardTool.components; });
56 item.components = Qt.binding(function() { return cardTool.components; });
58 item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
57 item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
59 item.scopeStyle = root.scopeStyle;
58 item.scopeStyle = root.scopeStyle;
qml/Dash/CardTool.qml+16−15
@@ -198,8 +198,8 @@ Item {
198
198
199 Loader {
199 Loader {
200 id: cardLoader
200 id: cardLoader
201− property var fields: ["art", "mascot", "title", "subtitle", "summary", "attributes"]
201+ readonly property var fields: ["art", "mascot", "title", "subtitle", "summary", "attributes"]
202− property var maxData: {
202+ readonly property var maxData: {
203 "art": Qt.resolvedUrl("graphics/pixel.png"),
203 "art": Qt.resolvedUrl("graphics/pixel.png"),
204 "mascot": Qt.resolvedUrl("graphics/pixel.png"),
204 "mascot": Qt.resolvedUrl("graphics/pixel.png"),
205 "title": "—\n—",
205 "title": "—\n—",
@@ -211,26 +211,27 @@ Item {
211 onLoaded: {
211 onLoaded: {
212 item.objectName = "cardToolCard";
212 item.objectName = "cardToolCard";
213 item.asynchronous = false;
213 item.asynchronous = false;
214− item.template = Qt.binding(function() { return cardTool.template; });
215 item.components = Qt.binding(function() { return cardTool.components; });
214 item.components = Qt.binding(function() { return cardTool.components; });
216 item.width = Qt.binding(function() { return cardTool.cardWidth || item.implicitWidth; });
215 item.width = Qt.binding(function() { return cardTool.cardWidth || item.implicitWidth; });
217 item.height = Qt.binding(function() { return cardTool.cardHeight || item.implicitHeight; });
216 item.height = Qt.binding(function() { return cardTool.cardHeight || item.implicitHeight; });
218 }
217 }
219 Connections {
218 Connections {
220− target: cardLoader.item
219+ target: cardTool
220+ onTemplateChanged: cardLoader.updateCardData();
221− onComponentsChanged: {
221+ onComponentsChanged: cardLoader.updateCardData();
222+ }
223+ function updateCardData() {
222− var data = {};
224+ var data = {};
223− for (var k in cardLoader.fields) {
225+ for (var k in fields) {
224− var component = cardLoader.item.components[cardLoader.fields[k]];
226+ var component = cardTool.components[fields[k]];
225− var key = cardLoader.fields[k];
227+ var key = fields[k];
226− if ((typeof component === "string" && component.length > 0) ||
228+ if ((typeof component === "string" && component.length > 0) ||
227− (typeof component === "object" && component !== null
229+ (typeof component === "object" && component !== null
228− && typeof component["field"] === "string" && component["field"].length > 0)) {
230+ && typeof component["field"] === "string" && component["field"].length > 0)) {
229− data[key] = cardLoader.maxData[key];
231+ data[key] = maxData[key];
230− }
231 }
232 }
232− cardLoader.item.cardData = data;
233 }
233 }
234+ item.cardData = data;
234 }
235 }
235 }
236 }
236}
237}
qml/Dash/CardVerticalJournal.qml−1
@@ -72,7 +72,6 @@ DashRenderer {
72 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
72 item.fixedArtShapeSize = Qt.binding(function() { return cardTool.artShapeSize; });
73 item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
73 item.fixedHeaderHeight = Qt.binding(function() { return cardTool.headerHeight; });
74 item.cardData = Qt.binding(function() { return model; });
74 item.cardData = Qt.binding(function() { return model; });
75− item.template = Qt.binding(function() { return cardTool.template; });
76 item.components = Qt.binding(function() { return cardTool.components; });
75 item.components = Qt.binding(function() { return cardTool.components; });
77 item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
76 item.titleAlignment = Qt.binding(function() { return cardTool.titleAlignment; });
78 item.scopeStyle = root.scopeStyle;
77 item.scopeStyle = root.scopeStyle;
qml/Dash/GenericScopeView.qml+1−1
@@ -425,7 +425,7 @@ FocusScope {
425 // to the next, we set the visible range to the viewport so
425 // to the next, we set the visible range to the viewport so
426 // items are not culled (invisible) but still use no cacheBuffer
426 // items are not culled (invisible) but still use no cacheBuffer
427 // (it will be set once the scope is the current one)
427 // (it will be set once the scope is the current one)
428− var displayMarginBeginning = baseItem.y;
428+ var displayMarginBeginning = baseItem.y + rendererLoader.anchors.topMargin;
429 displayMarginBeginning = -Math.max(-displayMarginBeginning, 0);
429 displayMarginBeginning = -Math.max(-displayMarginBeginning, 0);
430 displayMarginBeginning = -Math.min(-displayMarginBeginning, baseItem.height);
430 displayMarginBeginning = -Math.min(-displayMarginBeginning, baseItem.height);
431 displayMarginBeginning = Math.round(displayMarginBeginning);
431 displayMarginBeginning = Math.round(displayMarginBeginning);
qml/Dash/Previews/PreviewHeader.qml+6
@@ -22,6 +22,7 @@ import "../"
22/*! This preview widget shows a header
22/*! This preview widget shows a header
23 * The title comes in widgetData["title"]
23 * The title comes in widgetData["title"]
24 * The mascot comes in widgetData["mascot"]
24 * The mascot comes in widgetData["mascot"]
25+ * The mascot fall back image comes in widgetData["fallback"]
25 * The subtitle comes in widgetData["subtitle"]
26 * The subtitle comes in widgetData["subtitle"]
26 * The attributes comes in widgetData["attributes"]
27 * The attributes comes in widgetData["attributes"]
27 */
28 */
@@ -35,11 +36,15 @@ PreviewWidget {
35 id: headerRoot
36 id: headerRoot
36 objectName: "innerPreviewHeader"
37 objectName: "innerPreviewHeader"
37 readonly property url mascot: root.widgetData["mascot"] || ""
38 readonly property url mascot: root.widgetData["mascot"] || ""
39+ readonly property url fallback: root.widgetData["fallback"] || ""
38 readonly property string title: root.widgetData["title"] || ""
40 readonly property string title: root.widgetData["title"] || ""
39 readonly property string subtitle: root.widgetData["subtitle"] || ""
41 readonly property string subtitle: root.widgetData["subtitle"] || ""
40 readonly property var attributes: root.widgetData["attributes"] || null
42 readonly property var attributes: root.widgetData["attributes"] || null
41 readonly property color fontColor: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText
43 readonly property color fontColor: root.scopeStyle ? root.scopeStyle.foreground : Theme.palette.normal.baseText
42
44
45+ // Rewire the source since we may have unwired it on onStatusChanged
46+ onMascotChanged: if (mascotShapeLoader.item) mascotShapeLoader.item.image.source = mascot;
47+
43 implicitHeight: row.height + row.margins * 2
48 implicitHeight: row.height + row.margins * 2
44 width: parent.width
49 width: parent.width
45
50
@@ -82,6 +87,7 @@ PreviewWidget {
82 fillMode: Image.PreserveAspectCrop
87 fillMode: Image.PreserveAspectCrop
83 horizontalAlignment: Image.AlignHCenter
88 horizontalAlignment: Image.AlignHCenter
84 verticalAlignment: Image.AlignVCenter
89 verticalAlignment: Image.AlignVCenter
90+ onStatusChanged: if (status === Image.Error) source = headerRoot.fallback;
85 }
91 }
86 }
92 }
87 }
93 }
qml/Dash/Previews/PreviewImageGallery.qml+14
@@ -20,6 +20,7 @@ import "../../Components"
20
20
21/*! This preview widget shows a horizontal list of images.
21/*! This preview widget shows a horizontal list of images.
22 * The URIs for the images should be an array in widgetData["sources"].
22 * The URIs for the images should be an array in widgetData["sources"].
23+ * Images fall back to widgetData["fallback"] if loading fails
23 */
24 */
24
25
25PreviewWidget {
26PreviewWidget {
@@ -72,6 +73,14 @@ PreviewWidget {
72 overlay.show();
73 overlay.show();
73 }
74 }
74 }
75 }
76+
77+ Connections {
78+ target: sourceImage
79+ // If modelData would change after failing to load it would not be
80+ // reloaded since the source binding is destroyed by the source = fallback
81+ // But at the moment the model never changes
82+ onStatusChanged: if (sourceImage.status === Image.Error) sourceImage.source = widgetData["fallback"];
83+ }
75 }
84 }
76 }
85 }
77
86
@@ -122,6 +131,11 @@ PreviewWidget {
122 source: modelData ? modelData : ""
131 source: modelData ? modelData : ""
123 fillMode: Image.PreserveAspectFit
132 fillMode: Image.PreserveAspectFit
124 sourceSize { width: screenshot.width; height: screenshot.height }
133 sourceSize { width: screenshot.width; height: screenshot.height }
134+
135+ // If modelData would change after failing to load it would not be
136+ // reloaded since the source binding is destroyed by the source = fallback
137+ // But at the moment the model never changes
138+ onStatusChanged: if (status === Image.Error) source = widgetData["fallback"];
125 }
139 }
126
140
127 MouseArea {
141 MouseArea {
qml/Dash/Previews/PreviewZoomableImage.qml+13
@@ -21,6 +21,7 @@ import "../../Components"
21/*! \brief Preview widget for image.
21/*! \brief Preview widget for image.
22
22
23 This widget shows image contained in widgetData["source"],
23 This widget shows image contained in widgetData["source"],
24+ and falls back to widgetData["fallback"] if loading fails
24 can be zoomable accordingly with widgetData["zoomable"].
25 can be zoomable accordingly with widgetData["zoomable"].
25 */
26 */
26
27
@@ -53,6 +54,14 @@ PreviewWidget {
53 overlay.show();
54 overlay.show();
54 }
55 }
55 }
56 }
57+
58+ Connections {
59+ target: lazyImage.sourceImage
60+ // If modelData would change after failing to load it would not be
61+ // reloaded since the source binding is destroyed by the source = fallback
62+ // But at the moment the model never changes
63+ onStatusChanged: if (lazyImage.sourceImage.status === Image.Error) lazyImage.sourceImage.source = widgetData["fallback"];
64+ }
56 }
65 }
57
66
58 PreviewOverlay {
67 PreviewOverlay {
@@ -67,6 +76,10 @@ PreviewWidget {
67 anchors.fill: parent
76 anchors.fill: parent
68 source: widgetData["source"]
77 source: widgetData["source"]
69 zoomable: widgetData["zoomable"] ? widgetData["zoomable"] : false
78 zoomable: widgetData["zoomable"] ? widgetData["zoomable"] : false
79+ // If modelData would change after failing to load it would not be
80+ // reloaded since the source binding is destroyed by the source = fallback
81+ // But at the moment the model never changes
82+ onStatusChanged: if (status === Image.Error) source = widgetData["fallback"];
70 }
83 }
71 }
84 }
72}
85}
qml/Notifications/ShapedIcon.qml+4−3
@@ -14,8 +14,8 @@
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
15 */
16
16
17−import QtQuick 2.0
17+import QtQuick 2.3
18−import Ubuntu.Components 0.1
18+import Ubuntu.Components 1.2
19
19
20Item {
20Item {
21 property string fileSource
21 property string fileSource
@@ -25,7 +25,8 @@ Item {
25 objectName: "shapedIcon"
25 objectName: "shapedIcon"
26 anchors.fill: parent
26 anchors.fill: parent
27 visible: shaped
27 visible: shaped
28− image: realImage
28+ source: realImage
29+ sourceFillMode: UbuntuShape.PreserveAspectCrop
29 }
30 }
30
31
31 Image {
32 Image {
qml/Stages/PhoneStage.qml+7
@@ -548,6 +548,13 @@ Rectangle {
548 }
548 }
549 }
549 }
550
550
551+ //eat touch events during the right edge gesture
552+ MouseArea {
553+ objectName: "eventEaterArea"
554+ anchors.fill: parent
555+ enabled: spreadDragArea.dragging
556+ }
557+
551 DirectionalDragArea {
558 DirectionalDragArea {
552 id: spreadDragArea
559 id: spreadDragArea
553 objectName: "spreadDragArea"
560 objectName: "spreadDragArea"
qml/Stages/TabletStage.qml+6
@@ -724,6 +724,12 @@ Rectangle {
724 }
724 }
725 }
725 }
726
726
727+ //eat touch events during the right edge gesture
728+ MouseArea {
729+ anchors.fill: parent
730+ enabled: spreadDragArea.dragging
731+ }
732+
727 DirectionalDragArea {
733 DirectionalDragArea {
728 id: spreadDragArea
734 id: spreadDragArea
729 objectName: "spreadDragArea"
735 objectName: "spreadDragArea"
runtests.sh+1−1
@@ -41,7 +41,7 @@ sleep 1
41
41
42cd -
42cd -
43
43
44−make -k qmltests
44+make -k xvfballtests
45if [ $? -ne 0 ]; then
45if [ $? -ne 0 ]; then
46 echo '<?xml version="1.0" encoding="UTF-8" ?><testsuite errors="0" failures="1" tests="1" name="makeExitStatusTest"><properties/><testcase result="fail" name="makeExitStatus"><failure message="Make test did not suceed" result="fail"/></testcase><system-err/></testsuite>' > testMakeExitStatus.xml
46 echo '<?xml version="1.0" encoding="UTF-8" ?><testsuite errors="0" failures="1" tests="1" name="makeExitStatusTest"><properties/><testcase result="fail" name="makeExitStatus"><failure message="Make test did not suceed" result="fail"/></testcase><system-err/></testsuite>' > testMakeExitStatus.xml
47fi
47fi
src/MouseTouchAdaptor.cpp+6−6
@@ -104,10 +104,10 @@ bool MouseTouchAdaptor::handleButtonPress(xcb_button_press_event_t *pressEvent)
104 if (button != Qt::LeftButton)
104 if (button != Qt::LeftButton)
105 return true;
105 return true;
106
106
107− QPoint windowPos(pressEvent->event_x, pressEvent->event_y);
108−
109 QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(pressEvent->event));
107 QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(pressEvent->event));
110
108
109+ QPoint windowPos(pressEvent->event_x / targetWindow->devicePixelRatio(), pressEvent->event_y / targetWindow->devicePixelRatio());
110+
111 QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
111 QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
112 false /* autoCommit */);
112 false /* autoCommit */);
113 touchEvent.press(0 /* touchId */, windowPos);
113 touchEvent.press(0 /* touchId */, windowPos);
@@ -125,10 +125,10 @@ bool MouseTouchAdaptor::handleButtonRelease(xcb_button_release_event_t *releaseE
125 if (button != Qt::LeftButton)
125 if (button != Qt::LeftButton)
126 return true;
126 return true;
127
127
128− QPoint windowPos(releaseEvent->event_x, releaseEvent->event_y);
129−
130 QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(releaseEvent->event));
128 QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(releaseEvent->event));
131
129
130+ QPoint windowPos(releaseEvent->event_x / targetWindow->devicePixelRatio(), releaseEvent->event_y / targetWindow->devicePixelRatio());
131+
132 QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
132 QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
133 false /* autoCommit */);
133 false /* autoCommit */);
134 touchEvent.release(0 /* touchId */, windowPos);
134 touchEvent.release(0 /* touchId */, windowPos);
@@ -144,10 +144,10 @@ bool MouseTouchAdaptor::handleMotionNotify(xcb_motion_notify_event_t *event)
144 return true;
144 return true;
145 }
145 }
146
146
147− QPoint windowPos(event->event_x, event->event_y);
148−
149 QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(event->event));
147 QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(event->event));
150
148
149+ QPoint windowPos(event->event_x / targetWindow->devicePixelRatio(), event->event_y / targetWindow->devicePixelRatio());
150+
151 QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
151 QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice,
152 false /* autoCommit */);
152 false /* autoCommit */);
153 touchEvent.move(0 /* touchId */, windowPos);
153 touchEvent.move(0 /* touchId */, windowPos);
tests/CMakeLists.txt+120−8
@@ -1,16 +1,128 @@
1+include(QmlTest)
2+
1# QML tests that do not require graphical capabilities.
3# QML tests that do not require graphical capabilities.
2−add_custom_target(qmlunittests)
4+add_custom_target(unittests)
3
5
4# QML tests that require graphical capabilities.
6# QML tests that require graphical capabilities.
5−add_custom_target(qmluitests)
7+add_custom_target(uitests)
8+add_custom_target(xvfbuitests)
6
9
7−add_custom_target(qmltests)
10+add_custom_target(alltests)
8−add_dependencies(qmltests qmlunittests qmluitests)
11+add_dependencies(alltests unittests uitests)
9
12
10−add_subdirectory(libs)
13+add_custom_target(xvfballtests)
11−add_subdirectory(qmltests)
14+add_dependencies(xvfballtests unittests xvfbuitests)
15+
16+# Support libraries and plugins
12add_subdirectory(mocks)
17add_subdirectory(mocks)
13−add_subdirectory(whitespace)
14−add_subdirectory(plugins)
15add_subdirectory(utils)
18add_subdirectory(utils)
16add_subdirectory(uqmlscene)
19add_subdirectory(uqmlscene)
20+
21+# Use our custom implementation of qmlscene and import dbus-test-runner
22+add_executable(qmlscene ALIAS uqmlscene)
23+import_executables(dbus-test-runner)
24+
25+set(UNITY_IMPORT_PATHS
26+ ${CMAKE_BINARY_DIR}/tests/mocks
27+ ${CMAKE_BINARY_DIR}/tests/utils/modules
28+ ${CMAKE_BINARY_DIR}/plugins
29+)
30+set(UNITY_IMPORT_PATHS ${UNITY_IMPORT_PATHS} CACHE INTERNAL "")
31+
32+macro(unity8_parse_arguments)
33+ cmake_parse_arguments(U8TEST
34+ "${QMLTEST_OPTIONS};LIGHTDM"
35+ "${QMLTEST_SINGLE}"
36+ "${QMLTEST_MULTI}"
37+ ${ARGN}
38+ )
39+
40+ set(ld_paths)
41+ if(U8TEST_LIGHTDM)
42+ list(APPEND ld_paths
43+ ${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics
44+ ${CMAKE_BINARY_DIR}/tests/mocks/LightDM/liblightdm
45+ )
46+ endif()
47+
48+ if(ld_paths)
49+ string(REPLACE ";" ":" ld_library_path "${ld_paths}")
50+ set(ld_library_path LD_LIBRARY_PATH=${ld_library_path})
51+ endif()
52+
53+ set(U8TEST_ARGN "${ARGN}")
54+ list(REMOVE_ITEM U8TEST_ARGN LIGHTDM)
55+
56+ set(environment
57+ UNITY_TESTING=1
58+ LANGUAGE=C
59+ LC_ALL=C.UTF-8
60+ ${ld_library_path}
61+ )
62+endmacro()
63+
64+
65+# add a non-graphical unit test
66+# see QmlTest.cmake for additional options
67+function(add_unity8_unittest COMPONENT_NAME TARGET)
68+ unity8_parse_arguments(${ARGN})
69+ add_executable_test(${COMPONENT_NAME} ${TARGET}
70+ ADD_TEST
71+ IMPORT_PATHS ${UNITY_IMPORT_PATHS}
72+ TARGETS unittests
73+ ${U8TEST_ARGN}
74+ ENVIRONMENT ${environment}
75+ QT_QPA_PLATFORM=minimal
76+ ${U8TEST_ENVIRONMENT}
77+ )
78+endfunction()
79+
80+# add a graphical unit test
81+function(add_unity8_uitest COMPONENT_NAME TARGET)
82+ unity8_parse_arguments(${ARGN})
83+ add_executable_test(${COMPONENT_NAME} ${TARGET}
84+ IMPORT_PATHS ${UNITY_IMPORT_PATHS}
85+ TARGETS uitests
86+ ${U8TEST_ARGN}
87+ ENVIRONMENT ${environment}
88+ ${U8TEST_ENVIRONMENT}
89+ )
90+endfunction()
91+
92+# add a non-graphical qml unit test
93+function(add_unity8_qmlunittest PATH COMPONENT_NAME)
94+ unity8_parse_arguments(${ARGN})
95+ add_qml_unittest(${PATH} ${COMPONENT_NAME}
96+ ADD_TEST
97+ IMPORT_PATHS ${UNITY_IMPORT_PATHS}
98+ TARGET unittests
99+ ${U8TEST_ARGN}
100+ ENVIRONMENT ${environment}
101+ QT_QPA_PLATFORM=minimal
102+ ${U8TEST_ENVIRONMENT}
103+ )
104+endfunction()
105+
106+# add a graphical qml test
107+function(add_unity8_qmltest PATH COMPONENT_NAME)
108+ unity8_parse_arguments(${ARGN})
109+ add_qml_test(${PATH} ${COMPONENT_NAME}
110+ IMPORT_PATHS ${UNITY_IMPORT_PATHS}
111+ TARGETS uitests
112+ ${U8TEST_ARGN}
113+ ENVIRONMENT ${environment}
114+ ${U8TEST_ENVIRONMENT}
115+ )
116+endfunction()
117+
118+# add a graphical qml benchmark
119+function(add_unity8_qmlbenchmark PATH COMPONENT_NAME ITERATIONS)
120+ add_unity8_qmltest(${PATH} ${COMPONENT_NAME} ITERATIONS ${ITERATIONS} ${ARGN})
121+endfunction()
122+
123+
124+# Actual test definitions
125+add_subdirectory(libs)
126+add_subdirectory(plugins)
127+add_subdirectory(qmltests)
128+add_subdirectory(whitespace)
tests/autopilot/unity8/application_lifecycle/tests/__init__.py+2−2
@@ -31,8 +31,8 @@ class ApplicationLifeCycleTestCase(tests.UnityTestCase):
31 super().setUp()
31 super().setUp()
32 self._qml_mock_enabled = False
32 self._qml_mock_enabled = False
33 self._data_dirs_mock_enabled = False
33 self._data_dirs_mock_enabled = False
34− unity_proxy = self.launch_unity()
34+ self.launch_unity()
35− process_helpers.unlock_unity(unity_proxy)
35+ process_helpers.unlock_unity()
36
36
37 def create_test_application(self):
37 def create_test_application(self):
38 desktop_file_dict = fixture_setup.DEFAULT_DESKTOP_FILE_DICT
38 desktop_file_dict = fixture_setup.DEFAULT_DESKTOP_FILE_DICT
tests/autopilot/unity8/greeter/__init__.py+52
@@ -0,0 +1,52 @@
1+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2+#
3+# Unity Autopilot Test Suite
4+# Copyright (C) 2015 Canonical
5+#
6+# This program is free software: you can redistribute it and/or modify
7+# it under the terms of the GNU General Public License as published by
8+# the Free Software Foundation, either version 3 of the License, or
9+# (at your option) any later version.
10+#
11+# This program is distributed in the hope that it will be useful,
12+# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+# GNU General Public License for more details.
15+#
16+# You should have received a copy of the GNU General Public License
17+# along with this program. If not, see <http://www.gnu.org/licenses/>.
18+#
19+
20+import dbus
21+
22+from autopilot.matchers import Eventually
23+from testtools.matchers import Equals
24+
25+
26+def hide_greeter_with_dbus():
27+ dbus_proxy = _get_greeter_dbus_proxy()
28+ if _is_greeter_active():
29+ dbus_proxy.HideGreeter()
30+
31+
32+def show_greeter_with_dbus():
33+ dbus_proxy = _get_greeter_dbus_proxy()
34+ if not _is_greeter_active():
35+ dbus_proxy.ShowGreeter()
36+
37+
38+def wait_for_greeter():
39+ Eventually(Equals(True), timeout=300).match(_is_greeter_active)
40+
41+
42+def _get_greeter_dbus_proxy():
43+ bus = dbus.SessionBus()
44+ return bus.get_object('com.canonical.UnityGreeter', '/')
45+
46+
47+def _is_greeter_active():
48+ try:
49+ dbus_proxy = _get_greeter_dbus_proxy()
50+ return dbus_proxy.Get('com.canonical.UnityGreeter', 'IsActive')
51+ except:
52+ return False
tests/autopilot/unity8/indicators/tests/__init__.py+1−1
@@ -31,7 +31,7 @@ class IndicatorTestCase(tests.UnityTestCase):
31 def setUp(self):
31 def setUp(self):
32 super().setUp()
32 super().setUp()
33 self.unity_proxy = self.launch_unity()
33 self.unity_proxy = self.launch_unity()
34− process_helpers.unlock_unity(self.unity_proxy)
34+ process_helpers.unlock_unity()
35
35
36
36
37class DeviceIndicatorTestCase(IndicatorTestCase):
37class DeviceIndicatorTestCase(IndicatorTestCase):
tests/autopilot/unity8/process_helpers.py+7−94
@@ -19,14 +19,11 @@
19
19
20import logging
20import logging
21import subprocess
21import subprocess
22−import dbus
23
22
24import ubuntuuitoolkit
23import ubuntuuitoolkit
25−from autopilot.exceptions import ProcessSearchError
26from autopilot.introspection import get_proxy_object_for_existing_process
24from autopilot.introspection import get_proxy_object_for_existing_process
27
25
28−from unity8.shell import emulators
26+from unity8 import greeter
29−from unity8.shell.emulators import main_window as main_window_emulator
30
27
31logger = logging.getLogger(__name__)
28logger = logging.getLogger(__name__)
32
29
@@ -39,104 +36,20 @@ class CannotAccessUnity(Exception):
39 pass
36 pass
40
37
41
38
42−def unlock_unity(unity_proxy_obj=None):
39+def unlock_unity():
43 """Helper function that attempts to unlock the unity greeter.
40 """Helper function that attempts to unlock the unity greeter.
44
41
45− If unity_proxy_object is None create a proxy object by querying for the
46− running unity process.
47− Otherwise re-use the passed proxy object.
48−
49− :raises RuntimeError: if the greeter attempts and fails to be unlocked.
50−
51− :raises RuntimeWarning: when the greeter cannot be found because it is
52− already unlocked.
53− :raises CannotAccessUnity: if unity is not introspectable or cannot be
54− found on dbus.
55− :raises CannotAccessUnity: if unity's upstart status is not "start" or the
56− upstart job cannot be found at all.
57−
58 """
42 """
59− if unity_proxy_obj is None:
43+ greeter.wait_for_greeter()
60− try:
44+ greeter.hide_greeter_with_dbus()
61− pid = get_unity_pid()
62− unity = _get_unity_proxy_object(pid)
63− main_window = unity.select_single(main_window_emulator.QQuickView)
64− except ProcessSearchError as e:
65− raise CannotAccessUnity(
66− "Cannot introspect unity, make sure that it has been started "
67− "with testability. Perhaps use the function "
68− "'restart_unity_with_testability' this module provides."
69− "(%s)"
70− % str(e)
71− )
72− else:
73− main_window = unity_proxy_obj.select_single(
74− main_window_emulator.QQuickView)
75−
76− greeter = main_window.get_greeter()
77− if greeter.created is False:
78− raise RuntimeWarning("Greeter appears to be already unlocked.")
79−
80− bus = dbus.SessionBus()
81− dbus_proxy = bus.get_object("com.canonical.UnityGreeter", "/")
82− try:
83− dbus_proxy.HideGreeter()
84− except dbus.DBusException:
85− logger.info("Failed to unlock greeter")
86− raise
87− else:
88− greeter.created.wait_for(False)
89− logger.info("Greeter unlocked, continuing.")
90
45
91
46
92−def lock_unity(unity_proxy_obj=None):
47+def lock_unity():
93 """Helper function that attempts to lock unity greeter.
48 """Helper function that attempts to lock unity greeter.
94
49
95− If unity_proxy_object is None create a proxy object by querying for the
96− running unity process.
97− Otherwise re-use the passed proxy object.
98−
99− :raises RuntimeError: if the greeter attempts and fails to be locked.
100−
101− :raises RuntimeWarning: when the greeter is found because it is
102− already locked.
103− :raises CannotAccessUnity: if unity is not introspectable or cannot be
104− found on dbus.
105− :raises CannotAccessUnity: if unity's upstart status is not "start" or the
106− upstart job cannot be found at all.
107−
108 """
50 """
109− if unity_proxy_obj is None:
51+ greeter.show_greeter_with_dbus()
110− try:
52+ greeter.wait_for_greeter()
111− pid = get_unity_pid()
112− unity = _get_unity_proxy_object(pid)
113− main_window = unity.select_single(main_window_emulator.QQuickView)
114− except ProcessSearchError as e:
115− raise CannotAccessUnity(
116− "Cannot introspect unity, make sure that it has been started "
117− "with testability. Perhaps use the function "
118− "'restart_unity_with_testability' this module provides."
119− "(%s)"
120− % str(e)
121− )
122− else:
123− main_window = unity_proxy_obj.select_single(
124− main_window_emulator.QQuickView)
125−
126− greeter = main_window.get_greeter()
127− if greeter.created is True:
128− raise RuntimeWarning("Greeter appears to be already locked.")
129−
130− bus = dbus.SessionBus()
131− dbus_proxy = bus.get_object("com.canonical.UnityGreeter", "/")
132− try:
133− dbus_proxy.ShowGreeter()
134− except dbus.DBusException:
135− logger.info("Failed to lock greeter")
136− raise
137− else:
138− greeter.created.wait_for(True)
139− logger.info("Greeter locked, continuing.")
140
53
141
54
142def restart_unity_with_testability(*args):
55def restart_unity_with_testability(*args):
tests/autopilot/unity8/shell/emulators/dash.py+17−10
@@ -130,7 +130,7 @@ class Dash(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
130 x, y, width, height = dash_content.globalRect
130 x, y, width, height = dash_content.globalRect
131 # Make the drag range be a multiple of the drag "rate" value.
131 # Make the drag range be a multiple of the drag "rate" value.
132 # Workarounds https://bugs.launchpad.net/mir/+bug/1399690
132 # Workarounds https://bugs.launchpad.net/mir/+bug/1399690
133− rate = 10
133+ rate = 5
134 divisions = 5
134 divisions = 5
135 jump = (width / divisions) // rate * rate
135 jump = (width / divisions) // rate * rate
136 start_x = x + jump
136 start_x = x + jump
@@ -146,7 +146,7 @@ class Dash(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
146 x, y, width, height = dash_content.globalRect
146 x, y, width, height = dash_content.globalRect
147 # Make the drag range be a multiple of the drag "rate" value.
147 # Make the drag range be a multiple of the drag "rate" value.
148 # Workarounds https://bugs.launchpad.net/mir/+bug/1399690
148 # Workarounds https://bugs.launchpad.net/mir/+bug/1399690
149− rate = 10
149+ rate = 5
150 divisions = 5
150 divisions = 5
151 jump = (width / divisions) // rate * rate
151 jump = (width / divisions) // rate * rate
152 start_x = x + jump * (divisions - 1)
152 start_x = x + jump * (divisions - 1)
@@ -185,14 +185,15 @@ class Dash(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
185
185
186
186
187class ListViewWithPageHeader(ubuntuuitoolkit.QQuickFlickable):
187class ListViewWithPageHeader(ubuntuuitoolkit.QQuickFlickable):
188− pass
188+
189+ margin_to_swipe_from_bottom = ubuntuuitoolkit.units.gu(4)
189
190
190
191
191class GenericScopeView(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
192class GenericScopeView(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
192 """Autopilot emulator for generic scopes."""
193 """Autopilot emulator for generic scopes."""
193
194
194 @autopilot_logging.log_action(logger.info)
195 @autopilot_logging.log_action(logger.info)
195− def open_preview(self, category, app_name):
196+ def open_preview(self, category, app_name, press_duration=0.10):
196 """Open the preview of an application.
197 """Open the preview of an application.
197
198
198 :parameter category: The name of the category where the application is.
199 :parameter category: The name of the category where the application is.
@@ -203,16 +204,19 @@ class GenericScopeView(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
203 # FIXME some categories need a long press in order to see the preview.
204 # FIXME some categories need a long press in order to see the preview.
204 # Some categories do not show previews, like recent apps.
205 # Some categories do not show previews, like recent apps.
205 # --elopio - 2014-1-14
206 # --elopio - 2014-1-14
206− self.click_scope_item(category, app_name)
207+ self.click_scope_item(category, app_name, press_duration)
207 preview_list = self.wait_select_single(
208 preview_list = self.wait_select_single(
208 'QQuickLoader', objectName='subPageLoader')
209 'QQuickLoader', objectName='subPageLoader')
209 preview_list.subPageShown.wait_for(True)
210 preview_list.subPageShown.wait_for(True)
210 preview_list.x.wait_for(0)
211 preview_list.x.wait_for(0)
212+ self.get_root_instance().select_single(
213+ objectName='processingIndicator').visible.wait_for(False)
211 return preview_list.select_single(
214 return preview_list.select_single(
212− Preview, objectName='preview{}'.format(preview_list.currentIndex))
215+ Preview, objectName='preview{}'.format(
216+ preview_list.initialIndex))
213
217
214 @autopilot_logging.log_action(logger.debug)
218 @autopilot_logging.log_action(logger.debug)
215− def click_scope_item(self, category, title):
219+ def click_scope_item(self, category, title, press_duration=0.10):
216 """Click an item from the scope.
220 """Click an item from the scope.
217
221
218 :parameter category: The name of the category where the item is.
222 :parameter category: The name of the category where the item is.
@@ -220,9 +224,12 @@ class GenericScopeView(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
220
224
221 """
225 """
222 category_element = self._get_category_element(category)
226 category_element = self._get_category_element(category)
223− icon = category_element.wait_select_single('AbstractButton',
227+ icon = category_element.wait_select_single(
224− title=title)
228+ 'AbstractButton', title=title)
229+ list_view = self.select_single(
230+ ListViewWithPageHeader, objectName='categoryListView')
231+ list_view.swipe_child_into_view(icon)
225− self.pointing_device.click_object(icon)
232+ self.pointing_device.click_object(icon, press_duration=press_duration)
226
233
227 def _get_category_element(self, category):
234 def _get_category_element(self, category):
228 try:
235 try:
tests/autopilot/unity8/shell/tests/test_emulators.py+8−2
@@ -41,8 +41,8 @@ class MainWindowTestCase(tests.UnityTestCase):
41
41
42 def setUp(self):
42 def setUp(self):
43 super().setUp()
43 super().setUp()
44− unity_proxy = self.launch_unity()
44+ self.launch_unity()
45− process_helpers.unlock_unity(unity_proxy)
45+ process_helpers.unlock_unity()
46
46
47
47
48class DashEmulatorTestCase(tests.DashBaseTestCase):
48class DashEmulatorTestCase(tests.DashBaseTestCase):
@@ -120,6 +120,12 @@ class GenericScopeViewEmulatorTestCase(tests.DashBaseTestCase):
120 self.assertIsInstance(preview, dash_emulators.Preview)
120 self.assertIsInstance(preview, dash_emulators.Preview)
121 self.assertTrue(preview.isCurrent)
121 self.assertTrue(preview.isCurrent)
122
122
123+ def test_open_preview_of_non_visible_item(self):
124+ """Open an item that requires swiping to make it visible."""
125+ preview = self.generic_scope.open_preview('2', 'Title.2.0')
126+ self.assertIsInstance(preview, dash_emulators.Preview)
127+ self.assertTrue(preview.isCurrent)
128+
123
129
124class DashAppsEmulatorTestCase(tests.DashBaseTestCase):
130class DashAppsEmulatorTestCase(tests.DashBaseTestCase):
125
131
tests/autopilot/unity8/shell/tests/test_notifications.py+22−22
@@ -119,8 +119,8 @@ class InteractiveNotificationBase(NotificationsBase):
119
119
120 def test_interactive(self):
120 def test_interactive(self):
121 """Interactive notification must react upon click on itself."""
121 """Interactive notification must react upon click on itself."""
122− unity_proxy = self.launch_unity()
122+ self.launch_unity()
123− unlock_unity(unity_proxy)
123+ unlock_unity()
124
124
125 notify_list = self._get_notifications_list()
125 notify_list = self._get_notifications_list()
126
126
@@ -156,8 +156,8 @@ class InteractiveNotificationBase(NotificationsBase):
156 """Snap-decision with three actions should use
156 """Snap-decision with three actions should use
157 one-over two button layout.
157 one-over two button layout.
158 """
158 """
159− unity_proxy = self.launch_unity()
159+ self.launch_unity()
160− unlock_unity(unity_proxy)
160+ unlock_unity()
161
161
162 summary = "Theatre at Ferria Stadium"
162 summary = "Theatre at Ferria Stadium"
163 body = "at Ferria Stadium in Bilbao, Spain\n07578545317"
163 body = "at Ferria Stadium in Bilbao, Spain\n07578545317"
@@ -197,8 +197,8 @@ class InteractiveNotificationBase(NotificationsBase):
197 """Snap-decision should block input to shell
197 """Snap-decision should block input to shell
198 without greeter/lockscreen.
198 without greeter/lockscreen.
199 """
199 """
200− unity_proxy = self.launch_unity()
200+ self.launch_unity()
201− unlock_unity(unity_proxy)
201+ unlock_unity()
202
202
203 summary = "Incoming file"
203 summary = "Incoming file"
204 body = "Frank would like to send you the file: essay.pdf"
204 body = "Frank would like to send you the file: essay.pdf"
@@ -421,8 +421,8 @@ class EphemeralNotificationsTests(NotificationsBase):
421
421
422 def test_icon_summary_body(self):
422 def test_icon_summary_body(self):
423 """Notification must display the expected summary and body text."""
423 """Notification must display the expected summary and body text."""
424− unity_proxy = self.launch_unity()
424+ self.launch_unity()
425− unlock_unity(unity_proxy)
425+ unlock_unity()
426
426
427 notify_list = self._get_notifications_list()
427 notify_list = self._get_notifications_list()
428
428
@@ -458,8 +458,8 @@ class EphemeralNotificationsTests(NotificationsBase):
458 def test_icon_summary(self):
458 def test_icon_summary(self):
459 """Notification must display the expected summary and secondary
459 """Notification must display the expected summary and secondary
460 icon."""
460 icon."""
461− unity_proxy = self.launch_unity()
461+ self.launch_unity()
462− unlock_unity(unity_proxy)
462+ unlock_unity()
463
463
464 notify_list = self._get_notifications_list()
464 notify_list = self._get_notifications_list()
465
465
@@ -491,8 +491,8 @@ class EphemeralNotificationsTests(NotificationsBase):
491 def test_urgency_order(self):
491 def test_urgency_order(self):
492 """Notifications must be displayed in order according to their
492 """Notifications must be displayed in order according to their
493 urgency."""
493 urgency."""
494− unity_proxy = self.launch_unity()
494+ self.launch_unity()
495− unlock_unity(unity_proxy)
495+ unlock_unity()
496
496
497 notify_list = self._get_notifications_list()
497 notify_list = self._get_notifications_list()
498
498
@@ -578,8 +578,8 @@ class EphemeralNotificationsTests(NotificationsBase):
578
578
579 def test_summary_and_body(self):
579 def test_summary_and_body(self):
580 """Notification must display the expected summary- and body-text."""
580 """Notification must display the expected summary- and body-text."""
581− unity_proxy = self.launch_unity()
581+ self.launch_unity()
582− unlock_unity(unity_proxy)
582+ unlock_unity()
583
583
584 notify_list = self._get_notifications_list()
584 notify_list = self._get_notifications_list()
585
585
@@ -603,8 +603,8 @@ class EphemeralNotificationsTests(NotificationsBase):
603
603
604 def test_summary_only(self):
604 def test_summary_only(self):
605 """Notification must display only the expected summary-text."""
605 """Notification must display only the expected summary-text."""
606− unity_proxy = self.launch_unity()
606+ self.launch_unity()
607− unlock_unity(unity_proxy)
607+ unlock_unity()
608
608
609 notify_list = self._get_notifications_list()
609 notify_list = self._get_notifications_list()
610
610
@@ -621,8 +621,8 @@ class EphemeralNotificationsTests(NotificationsBase):
621 def test_update_notification_same_layout(self):
621 def test_update_notification_same_layout(self):
622 """Notification must allow updating its contents while being
622 """Notification must allow updating its contents while being
623 displayed."""
623 displayed."""
624− unity_proxy = self.launch_unity()
624+ self.launch_unity()
625− unlock_unity(unity_proxy)
625+ unlock_unity()
626
626
627 notify_list = self._get_notifications_list()
627 notify_list = self._get_notifications_list()
628
628
@@ -660,8 +660,8 @@ class EphemeralNotificationsTests(NotificationsBase):
660 def test_update_notification_layout_change(self):
660 def test_update_notification_layout_change(self):
661 """Notification must allow updating its contents and layout while
661 """Notification must allow updating its contents and layout while
662 being displayed."""
662 being displayed."""
663− unity_proxy = self.launch_unity()
663+ self.launch_unity()
664− unlock_unity(unity_proxy)
664+ unlock_unity()
665
665
666 notify_list = self._get_notifications_list()
666 notify_list = self._get_notifications_list()
667
667
@@ -709,8 +709,8 @@ class EphemeralNotificationsTests(NotificationsBase):
709 """ use the create notification script to get a notification dialog.
709 """ use the create notification script to get a notification dialog.
710 Check that the arguments passed to the script match the fields. """
710 Check that the arguments passed to the script match the fields. """
711
711
712− unity_proxy = self.launch_unity()
712+ self.launch_unity()
713− unlock_unity(unity_proxy)
713+ unlock_unity()
714
714
715 summary = 'Helper summary'
715 summary = 'Helper summary'
716 body = 'Helper body'
716 body = 'Helper body'
tests/copyright/CMakeLists.txt+1−1
@@ -2,5 +2,5 @@
2# Test that all source files contain a copyright header.
2# Test that all source files contain a copyright header.
3#
3#
4
4
5−add_test(copyright ${CMAKE_CURRENT_SOURCE_DIR}/check_copyright.sh
5+add_test(Copyright ${CMAKE_CURRENT_SOURCE_DIR}/check_copyright.sh
6 ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR})
6 ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR})
tests/libs/UbuntuGestures/CMakeLists.txt+4−8
@@ -4,17 +4,13 @@ include_directories(
4 )
4 )
5
5
6macro(add_gesture_test CLASSNAME)
6macro(add_gesture_test CLASSNAME)
7− set(testCommand
8− ${CLASSNAME}TestExec -o ${CMAKE_BINARY_DIR}/test${CLASSNAME}.xml,xunitxml -o -,txt)
9−
10− add_test(NAME test${CLASSNAME} COMMAND ${testCommand})
11−
12− set_tests_properties(test${CLASSNAME} PROPERTIES
13− ENVIRONMENT LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/libs/UbuntuGestures)
14−
15 add_executable(${CLASSNAME}TestExec tst_${CLASSNAME}.cpp)
7 add_executable(${CLASSNAME}TestExec tst_${CLASSNAME}.cpp)
16 qt5_use_modules(${CLASSNAME}TestExec Test Core Gui Quick)
8 qt5_use_modules(${CLASSNAME}TestExec Test Core Gui Quick)
17 target_link_libraries(${CLASSNAME}TestExec UbuntuGestures)
9 target_link_libraries(${CLASSNAME}TestExec UbuntuGestures)
10+
11+ add_unity8_unittest(${CLASSNAME} ${CLASSNAME}TestExec
12+ ENVIRONMENT LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/libs/UbuntuGestures
13+ )
18endmacro(add_gesture_test)
14endmacro(add_gesture_test)
19
15
20add_gesture_test(TouchRegistry)
16add_gesture_test(TouchRegistry)
tests/plugins/AccountsService/CMakeLists.txt+5−4
@@ -43,12 +43,13 @@ add_executable(test-accountsservice
43 )
43 )
44qt5_use_modules(test-accountsservice Core DBus Test)
44qt5_use_modules(test-accountsservice Core DBus Test)
45
45
46−add_test(NAME test-accountsservice
47− COMMAND dbus-test-runner
46+add_unity8_unittest(AccountsService dbus-test-runner
47+ ARG_PREFIX "--parameter"
48+ ARGS
48− --task ${CMAKE_CURRENT_BINARY_DIR}/mock-server
49+ --task $<TARGET_FILE:mock-server>
49 --task-name server
50 --task-name server
50 --ignore-return
51 --ignore-return
51− --task ${CMAKE_CURRENT_BINARY_DIR}/test-accountsservice
52+ --task $<TARGET_FILE:test-accountsservice>
52 --task-name client
53 --task-name client
53 --wait-for org.freedesktop.Accounts
54 --wait-for org.freedesktop.Accounts
54 )
55 )
tests/plugins/Dash/CMakeLists.txt+10−17
@@ -32,7 +32,7 @@ macro(add_lvwph_test FILENAME TESTNAME)
32 qt5_use_modules(${TESTNAME}TestExec Test Core Qml)
32 qt5_use_modules(${TESTNAME}TestExec Test Core Qml)
33 target_link_libraries(${TESTNAME}TestExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
33 target_link_libraries(${TESTNAME}TestExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
34
34
35− add_binary_qml_test(${TESTNAME} "" "Dash-qml" "")
35+ add_unity8_uitest(${TESTNAME} ${TESTNAME}TestExec DEPENDS Dash-qml)
36endmacro()
36endmacro()
37
37
38add_lvwph_test(listviewwithpageheader ListViewWithPageHeader)
38add_lvwph_test(listviewwithpageheader ListViewWithPageHeader)
@@ -48,19 +48,16 @@ macro(add_dashview_try_test FILENAME TESTNAME)
48 qt5_use_modules(${TESTNAME}TestExec Test Core Qml)
48 qt5_use_modules(${TESTNAME}TestExec Test Core Qml)
49 target_link_libraries(${TESTNAME}TestExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
49 target_link_libraries(${TESTNAME}TestExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
50
50
51− add_binary_qml_test(${TESTNAME} "" "Dash-qml" "")
51+ add_unity8_uitest(${TESTNAME} ${TESTNAME}TestExec DEPENDS Dash-qml)
52
52
53− add_executable(${TESTNAME}tryExec
53+ add_executable(${TESTNAME}TryExec
54 ${FILENAME}try.cpp
54 ${FILENAME}try.cpp
55 ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/Dash/${FILENAME}.cpp
55 ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/Dash/${FILENAME}.cpp
56 ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/Dash/abstractdashview.cpp
56 ${CMAKE_CURRENT_SOURCE_DIR}/../../../plugins/Dash/abstractdashview.cpp
57 )
57 )
58− qt5_use_modules(${TESTNAME}tryExec Test Core Qml)
58+ qt5_use_modules(${TESTNAME}TryExec Test Core Qml)
59− target_link_libraries(${TESTNAME}tryExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
59+ target_link_libraries(${TESTNAME}TryExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
60− add_custom_target(try${TESTNAME}
60+ add_manual_test(${TESTNAME} ${TESTNAME}TryExec DEPENDS Dash-qml)
61− ${CMAKE_CURRENT_BINARY_DIR}/${TESTNAME}tryExec
62− DEPENDS ${TESTNAME}tryExec Dash-qml
63− )
64endmacro()
61endmacro()
65
62
66add_dashview_try_test(verticaljournal VerticalJournal)
63add_dashview_try_test(verticaljournal VerticalJournal)
@@ -71,13 +68,9 @@ add_dashview_try_test(organicgrid OrganicGrid)
71add_executable(CardCreatorTestExec cardcreatortest.cpp)
68add_executable(CardCreatorTestExec cardcreatortest.cpp)
72qt5_use_modules(CardCreatorTestExec Test Core Qml)
69qt5_use_modules(CardCreatorTestExec Test Core Qml)
73target_link_libraries(CardCreatorTestExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
70target_link_libraries(CardCreatorTestExec ${Qt5Gui_LIBRARIES} ${Qt5Quick_LIBRARIES})
74−add_binary_qml_test(CardCreator "" "Dash-qml" "QML2_IMPORT_PATH=${CMAKE_BINARY_DIR}/tests/mocks/")
71+add_unity8_uitest(CardCreator CardCreatorTestExec DEPENDS Dash-qml)
75
72
76# plain qml test
73# plain qml test
77−set(qmltest_DEFAULT_TARGETS qmluitests)
74+foreach(dash_test ScopeStyle ListViewWithPageHeaderQML CardAttributes CroppedImageMinimumSourceSize)
78−set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
75+ add_unity8_qmltest(. ${dash_test})
79−set(qmltest_DEFAULT_PROPERTIES ENVIRONMENT "LC_ALL=C")
76+endforeach()
80−add_qml_test(. ScopeStyle IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
81−add_qml_test(. ListViewWithPageHeaderQML IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
82−add_qml_test(. CardAttributes IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
83−add_qml_test(. CroppedImageMinimumSourceSize IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
tests/plugins/Dash/cardcreator/1.res+3−2
@@ -1,6 +1,5 @@
1AbstractButton {
1AbstractButton {
2 id: root;
2 id: root;
3− property var template;
4 property var components;
3 property var components;
5 property var cardData;
4 property var cardData;
6 property var artShapeBorderSource: undefined;
5 property var artShapeBorderSource: undefined;
@@ -13,7 +12,7 @@ AbstractButton {
13 property bool asynchronous: true;
12 property bool asynchronous: true;
14 property bool showHeader: true;
13 property bool showHeader: true;
15 implicitWidth: childrenRect.width;
14 implicitWidth: childrenRect.width;
16− enabled: root.template == null ? true : (root.template["non-interactive"] !== undefined ? !root.template["non-interactive"] : true);
15+ enabled: true;
17
16
18onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; }
17onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; }
19readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
18readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
@@ -34,6 +33,7 @@ Item {
34 property bool doShapeItem: components["art"]["conciergeMode"] !== true;
33 property bool doShapeItem: components["art"]["conciergeMode"] !== true;
35 visible: image.status == Image.Ready;
34 visible: image.status == Image.Ready;
36 readonly property alias image: artImage.image;
35 readonly property alias image: artImage.image;
36+ property alias borderSource: artShapeShape.borderSource;
37 ShaderEffectSource {
37 ShaderEffectSource {
38 id: artShapeSource;
38 id: artShapeSource;
39 sourceItem: artImage;
39 sourceItem: artImage;
@@ -43,6 +43,7 @@ Item {
43 hideSource: doShapeItem;
43 hideSource: doShapeItem;
44 }
44 }
45 Shape {
45 Shape {
46+ id: artShapeShape;
46 image: artShapeSource;
47 image: artShapeSource;
47 anchors.fill: parent;
48 anchors.fill: parent;
48 visible: doShapeItem;
49 visible: doShapeItem;
tests/plugins/Dash/cardcreator/2.res+3−8
@@ -1,6 +1,5 @@
1AbstractButton {
1AbstractButton {
2 id: root;
2 id: root;
3− property var template;
4 property var components;
3 property var components;
5 property var cardData;
4 property var cardData;
6 property var artShapeBorderSource: undefined;
5 property var artShapeBorderSource: undefined;
@@ -13,7 +12,7 @@ AbstractButton {
13 property bool asynchronous: true;
12 property bool asynchronous: true;
14 property bool showHeader: true;
13 property bool showHeader: true;
15 implicitWidth: childrenRect.width;
14 implicitWidth: childrenRect.width;
16− enabled: root.template == null ? true : (root.template["non-interactive"] !== undefined ? !root.template["non-interactive"] : true);
15+ enabled: true;
17
16
18Loader {
17Loader {
19 id: backgroundLoader;
18 id: backgroundLoader;
@@ -33,18 +32,14 @@ Loader {
33 objectName: "backgroundImage";
32 objectName: "backgroundImage";
34 source: {
33 source: {
35 if (cardData && typeof cardData["background"] === "string") return cardData["background"];
34 if (cardData && typeof cardData["background"] === "string") return cardData["background"];
36− else if (template && typeof template["card-background"] === "string") return template["card-background"];
35+ else return "";
37− else return "";
38 }
36 }
39 }
37 }
40 function getColor(index) {
38 function getColor(index) {
41 if (cardData && typeof cardData["background"] === "object"
39 if (cardData && typeof cardData["background"] === "object"
42 && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) {
40 && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) {
43 return cardData["background"]["elements"][index];
41 return cardData["background"]["elements"][index];
44− } else if (template && typeof template["card-background"] === "object"
42+ } else return index === 0 ? "#E9E9E9" : undefined;
45− && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) {
46− return template["card-background"]["elements"][index];
47− } else return undefined;
48 }
43 }
49 }
44 }
50 }
45 }
tests/plugins/Dash/cardcreator/3.res+3−2
@@ -1,6 +1,5 @@
1AbstractButton {
1AbstractButton {
2 id: root;
2 id: root;
3− property var template;
4 property var components;
3 property var components;
5 property var cardData;
4 property var cardData;
6 property var artShapeBorderSource: undefined;
5 property var artShapeBorderSource: undefined;
@@ -13,7 +12,7 @@ AbstractButton {
13 property bool asynchronous: true;
12 property bool asynchronous: true;
14 property bool showHeader: true;
13 property bool showHeader: true;
15 implicitWidth: childrenRect.width;
14 implicitWidth: childrenRect.width;
16− enabled: root.template == null ? true : (root.template["non-interactive"] !== undefined ? !root.template["non-interactive"] : true);
15+ enabled: true;
17
16
18onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; }
17onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; }
19readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
18readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
@@ -34,6 +33,7 @@ Item {
34 property bool doShapeItem: components["art"]["conciergeMode"] !== true;
33 property bool doShapeItem: components["art"]["conciergeMode"] !== true;
35 visible: image.status == Image.Ready;
34 visible: image.status == Image.Ready;
36 readonly property alias image: artImage.image;
35 readonly property alias image: artImage.image;
36+ property alias borderSource: artShapeShape.borderSource;
37 ShaderEffectSource {
37 ShaderEffectSource {
38 id: artShapeSource;
38 id: artShapeSource;
39 sourceItem: artImage;
39 sourceItem: artImage;
@@ -43,6 +43,7 @@ Item {
43 hideSource: doShapeItem;
43 hideSource: doShapeItem;
44 }
44 }
45 Shape {
45 Shape {
46+ id: artShapeShape;
46 image: artShapeSource;
47 image: artShapeSource;
47 anchors.fill: parent;
48 anchors.fill: parent;
48 visible: doShapeItem;
49 visible: doShapeItem;
tests/plugins/Dash/cardcreator/4.res+1−2
@@ -1,6 +1,5 @@
1AbstractButton {
1AbstractButton {
2 id: root;
2 id: root;
3− property var template;
4 property var components;
3 property var components;
5 property var cardData;
4 property var cardData;
6 property var artShapeBorderSource: undefined;
5 property var artShapeBorderSource: undefined;
@@ -13,7 +12,7 @@ AbstractButton {
13 property bool asynchronous: true;
12 property bool asynchronous: true;
14 property bool showHeader: true;
13 property bool showHeader: true;
15 implicitWidth: childrenRect.width;
14 implicitWidth: childrenRect.width;
16− enabled: root.template == null ? true : (root.template["non-interactive"] !== undefined ? !root.template["non-interactive"] : true);
15+ enabled: true;
17
16
18readonly property size artShapeSize: Qt.size(-1, -1);
17readonly property size artShapeSize: Qt.size(-1, -1);
19readonly property int headerHeight: row.height;
18readonly property int headerHeight: row.height;
tests/plugins/Dash/cardcreator/5.res+3−2
@@ -1,6 +1,5 @@
1AbstractButton {
1AbstractButton {
2 id: root;
2 id: root;
3− property var template;
4 property var components;
3 property var components;
5 property var cardData;
4 property var cardData;
6 property var artShapeBorderSource: undefined;
5 property var artShapeBorderSource: undefined;
@@ -13,7 +12,7 @@ AbstractButton {
13 property bool asynchronous: true;
12 property bool asynchronous: true;
14 property bool showHeader: true;
13 property bool showHeader: true;
15 implicitWidth: childrenRect.width;
14 implicitWidth: childrenRect.width;
16− enabled: root.template == null ? true : (root.template["non-interactive"] !== undefined ? !root.template["non-interactive"] : true);
15+ enabled: false;
17
16
18onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; }
17onArtShapeBorderSourceChanged: { if (artShapeBorderSource !== undefined && artShapeLoader.item) artShapeLoader.item.borderSource = artShapeBorderSource; }
19readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
18readonly property size artShapeSize: artShapeLoader.item ? Qt.size(artShapeLoader.item.width, artShapeLoader.item.height) : Qt.size(-1, -1);
@@ -34,6 +33,7 @@ Item {
34 property bool doShapeItem: components["art"]["conciergeMode"] !== true;
33 property bool doShapeItem: components["art"]["conciergeMode"] !== true;
35 visible: image.status == Image.Ready;
34 visible: image.status == Image.Ready;
36 readonly property alias image: artImage.image;
35 readonly property alias image: artImage.image;
36+ property alias borderSource: artShapeShape.borderSource;
37 ShaderEffectSource {
37 ShaderEffectSource {
38 id: artShapeSource;
38 id: artShapeSource;
39 sourceItem: artImage;
39 sourceItem: artImage;
@@ -43,6 +43,7 @@ Item {
43 hideSource: doShapeItem;
43 hideSource: doShapeItem;
44 }
44 }
45 Shape {
45 Shape {
46+ id: artShapeShape;
46 image: artShapeSource;
47 image: artShapeSource;
47 anchors.fill: parent;
48 anchors.fill: parent;
48 visible: doShapeItem;
49 visible: doShapeItem;
tests/plugins/Dash/cardcreator/5.tst+1−1
@@ -1,3 +1,3 @@
1−template: {"card-layout":"vertical","card-size":"medium","category-layout":"carousel","collapsed-rows":2,"overlay":true}
1+template: {"non-interactive":true,"card-layout":"vertical","card-size":"medium","category-layout":"carousel","collapsed-rows":2,"overlay":true}
2components: {"art":{"aspect-ratio":1,"field":"art"},"subtitle":{"field":"artist"},"title":{"field":"title"},"attributes":{}}
2components: {"art":{"aspect-ratio":1,"field":"art"},"subtitle":{"field":"artist"},"title":{"field":"title"},"attributes":{}}
3result: 5.res
3result: 5.res
tests/plugins/Dash/cardcreator/6.res+3−8
@@ -1,6 +1,5 @@
1AbstractButton {
1AbstractButton {
2 id: root;
2 id: root;
3− property var template;
4 property var components;
3 property var components;
5 property var cardData;
4 property var cardData;
6 property var artShapeBorderSource: undefined;
5 property var artShapeBorderSource: undefined;
@@ -13,7 +12,7 @@ AbstractButton {
13 property bool asynchronous: true;
12 property bool asynchronous: true;
14 property bool showHeader: true;
13 property bool showHeader: true;
15 implicitWidth: childrenRect.width;
14 implicitWidth: childrenRect.width;
16− enabled: root.template == null ? true : (root.template["non-interactive"] !== undefined ? !root.template["non-interactive"] : true);
15+ enabled: true;
17
16
18Loader {
17Loader {
19 id: backgroundLoader;
18 id: backgroundLoader;
@@ -33,18 +32,14 @@ Loader {
33 objectName: "backgroundImage";
32 objectName: "backgroundImage";
34 source: {
33 source: {
35 if (cardData && typeof cardData["background"] === "string") return cardData["background"];
34 if (cardData && typeof cardData["background"] === "string") return cardData["background"];
36− else if (template && typeof template["card-background"] === "string") return template["card-background"];
35+ else return "http://assets.ubuntu.com/sites/ubuntu/latest/u/img/logos/logo-ubuntu-grey.png";
37− else return "";
38 }
36 }
39 }
37 }
40 function getColor(index) {
38 function getColor(index) {
41 if (cardData && typeof cardData["background"] === "object"
39 if (cardData && typeof cardData["background"] === "object"
42 && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) {
40 && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) {
43 return cardData["background"]["elements"][index];
41 return cardData["background"]["elements"][index];
44− } else if (template && typeof template["card-background"] === "object"
42+ } else return index === 0 ? undefined : undefined;
45− && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) {
46− return template["card-background"]["elements"][index];
47− } else return undefined;
48 }
43 }
49 }
44 }
50 }
45 }
tests/plugins/Dash/cardcreator/6.tst+1−1
@@ -1,3 +1,3 @@
1−template: {"card-background":{"elements":["#E9E9E9"],"type":"color"},"card-layout":"vertical","card-size":"medium","category-layout":"grid","collapsed-rows":2}
1+template: {"card-background":"http://assets.ubuntu.com/sites/ubuntu/latest/u/img/logos/logo-ubuntu-grey.png","card-layout":"vertical","card-size":"medium","category-layout":"grid","collapsed-rows":2}
2components: {"art":{"aspect-ratio":1},"background":{"field":"background"},"subtitle":{"field":"author"},"title":{"field":"title"},"emblem":{"field":"source"},"attributes":{}}
2components: {"art":{"aspect-ratio":1},"background":{"field":"background"},"subtitle":{"field":"author"},"title":{"field":"title"},"emblem":{"field":"source"},"attributes":{}}
3result: 6.res
3result: 6.res
tests/plugins/Dash/cardcreator/7.res+3−8
@@ -1,6 +1,5 @@
1AbstractButton {
1AbstractButton {
2 id: root;
2 id: root;
3− property var template;
4 property var components;
3 property var components;
5 property var cardData;
4 property var cardData;
6 property var artShapeBorderSource: undefined;
5 property var artShapeBorderSource: undefined;
@@ -13,7 +12,7 @@ AbstractButton {
13 property bool asynchronous: true;
12 property bool asynchronous: true;
14 property bool showHeader: true;
13 property bool showHeader: true;
15 implicitWidth: childrenRect.width;
14 implicitWidth: childrenRect.width;
16− enabled: root.template == null ? true : (root.template["non-interactive"] !== undefined ? !root.template["non-interactive"] : true);
15+ enabled: true;
17
16
18Loader {
17Loader {
19 id: backgroundLoader;
18 id: backgroundLoader;
@@ -33,18 +32,14 @@ Loader {
33 objectName: "backgroundImage";
32 objectName: "backgroundImage";
34 source: {
33 source: {
35 if (cardData && typeof cardData["background"] === "string") return cardData["background"];
34 if (cardData && typeof cardData["background"] === "string") return cardData["background"];
36− else if (template && typeof template["card-background"] === "string") return template["card-background"];
35+ else return "";
37− else return "";
38 }
36 }
39 }
37 }
40 function getColor(index) {
38 function getColor(index) {
41 if (cardData && typeof cardData["background"] === "object"
39 if (cardData && typeof cardData["background"] === "object"
42 && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) {
40 && (cardData["background"]["type"] === "color" || cardData["background"]["type"] === "gradient")) {
43 return cardData["background"]["elements"][index];
41 return cardData["background"]["elements"][index];
44− } else if (template && typeof template["card-background"] === "object"
42+ } else return index === 0 ? "#E9E9E9" : "#E9AAE9";
45− && (template["card-background"]["type"] === "color" || template["card-background"]["type"] === "gradient")) {
46− return template["card-background"]["elements"][index];
47− } else return undefined;
48 }
43 }
49 }
44 }
50 }
45 }
tests/plugins/Dash/cardcreator/7.tst+1−1
@@ -1,3 +1,3 @@
1−template: {"card-background":{"elements":["#E9E9E9"],"type":"color"},"card-layout":"vertical","card-size":"medium","category-layout":"grid","collapsed-rows":2}
1+template: {"card-background":{"elements":["#E9E9E9","#E9AAE9"],"type":"color"},"card-layout":"vertical","card-size":"medium","category-layout":"grid","collapsed-rows":2}
2components: {"art":{"aspect-ratio":1},"background":{"field":"background"},"mascot":{"field":"icon"},"subtitle":{"field":"author"},"title":{"field":"title"},"attributes":{"field":"attributes","max-count":2}}
2components: {"art":{"aspect-ratio":1},"background":{"field":"background"},"mascot":{"field":"icon"},"subtitle":{"field":"author"},"title":{"field":"title"},"attributes":{"field":"attributes","max-count":2}}
3result: 7.res
3result: 7.res
tests/plugins/Greeter/Unity/Launcher/CMakeLists.txt+4−5
@@ -13,11 +13,6 @@ add_definitions(-DSRCDIR="${CMAKE_CURRENT_SOURCE_DIR}")
13add_definitions(-DLAUNCHER_TESTING)
13add_definitions(-DLAUNCHER_TESTING)
14
14
15### LauncherModelASTest
15### LauncherModelASTest
16−set(testModelCommand dbus-test-runner --task ${CMAKE_CURRENT_BINARY_DIR}/launchermodelastestExec
17− --parameter -o --parameter ${CMAKE_BINARY_DIR}/launchermodeltest.xml,xunitxml
18− --parameter -o --parameter -,txt)
19−add_test(NAME launchermodelastest COMMAND ${testModelCommand})
20−add_custom_target(launchermodelastest ${testModelCommand})
21add_executable(launchermodelastestExec
16add_executable(launchermodelastestExec
22 launchermodelastest.cpp
17 launchermodelastest.cpp
23 AccountsServiceDBusAdaptor.cpp
18 AccountsServiceDBusAdaptor.cpp
@@ -36,6 +31,10 @@ target_link_libraries(launchermodelastestExec
36 ${GSETTINGS_QT_LDFLAGS}
31 ${GSETTINGS_QT_LDFLAGS}
37 )
32 )
38qt5_use_modules(launchermodelastestExec Test Core DBus Gui)
33qt5_use_modules(launchermodelastestExec Test Core DBus Gui)
34+add_unity8_unittest(LauncherModelAS dbus-test-runner
35+ ARG_PREFIX "--parameter"
36+ ARGS --task $<TARGET_FILE:launchermodelastestExec>
37+)
39
38
40# copy .desktop files into build directory for shadow builds
39# copy .desktop files into build directory for shadow builds
41file(GLOB DESKTOP_FILES *.desktop)
40file(GLOB DESKTOP_FILES *.desktop)
tests/plugins/IntegratedLightDM/CMakeLists.txt+13−4
@@ -18,7 +18,13 @@ target_include_directories(GreeterDBusTestExec PUBLIC
18 ${CMAKE_SOURCE_DIR}/plugins/IntegratedLightDM
18 ${CMAKE_SOURCE_DIR}/plugins/IntegratedLightDM
19 ${CMAKE_SOURCE_DIR}/tests/mocks/IntegratedLightDM
19 ${CMAKE_SOURCE_DIR}/tests/mocks/IntegratedLightDM
20 )
20 )
21−add_binary_qml_test(GreeterDBus "${CMAKE_BINARY_DIR}/tests/mocks/IntegratedLightDM/liblightdm" MockLightDM "QML2_IMPORT_PATH=${CMAKE_BINARY_DIR}/tests/mocks")
21+add_unity8_uitest(GreeterDBus dbus-test-runner
22+ ARG_PREFIX "--parameter"
23+ ARGS --task $<TARGET_FILE:GreeterDBusTestExec>
24+ DEPENDS MockLightDM
25+ IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks
26+ LIGHTDM
27+ )
22
28
23add_executable(GreeterPamTestExec
29add_executable(GreeterPamTestExec
24 pam.cpp
30 pam.cpp
@@ -31,8 +37,7 @@ target_link_libraries(GreeterPamTestExec
31target_include_directories(GreeterPamTestExec PUBLIC
37target_include_directories(GreeterPamTestExec PUBLIC
32 ${CMAKE_SOURCE_DIR}/plugins/IntegratedLightDM/liblightdm
38 ${CMAKE_SOURCE_DIR}/plugins/IntegratedLightDM/liblightdm
33 )
39 )
34−add_qmltest_target(testGreeterPam "${CMAKE_CURRENT_BINARY_DIR}/GreeterPamTestExec" TRUE FALSE)
40+add_qmltest_target(testGreeterPam GreeterPamTestExec COMMAND $<TARGET_FILE:GreeterPamTestExec>)
35−add_dependencies(testGreeterPam GreeterPamTestExec)
36
41
37add_executable(GreeterUsersModelTestExec
42add_executable(GreeterUsersModelTestExec
38 usersmodel.cpp
43 usersmodel.cpp
@@ -49,4 +54,8 @@ target_include_directories(GreeterUsersModelTestExec PUBLIC
49 ${CMAKE_SOURCE_DIR}/plugins/Utils
54 ${CMAKE_SOURCE_DIR}/plugins/Utils
50 ${CMAKE_SOURCE_DIR}/tests/mocks/IntegratedLightDM
55 ${CMAKE_SOURCE_DIR}/tests/mocks/IntegratedLightDM
51 )
56 )
52−add_binary_qml_test(GreeterUsersModel "${CMAKE_BINARY_DIR}/tests/mocks/LightDM/liblightdm" MockLightDM "LIBLIGHTDM_MOCK_MODE=full")
57+add_unity8_uitest(GreeterUsers GreeterUsersModelTestExec
58+ ENVIRONMENT LIBLIGHTDM_MOCK_MODE=full
59+ DEPENDS MockLightDM
60+ LIGHTDM
61+ )
tests/plugins/Ubuntu/Gestures/CMakeLists.txt+22−24
@@ -12,43 +12,41 @@ include_directories(
12 ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
12 ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
13 )
13 )
14
14
15−file(GLOB qmlFiles *.qml)
15+export_qmlfiles(UbuntuGesturesTest .)
16−add_custom_target(UbuntuGesturesTestQmlFiles ALL
17− COMMAND cp ${qmlFiles} ${CMAKE_CURRENT_BINARY_DIR}
18− DEPENDS ${qmlFiles}
19−)
20
16
21add_definitions(-DUBUNTU_GESTURES_PLUGIN_DIR="${CMAKE_BINARY_DIR}/plugins")
17add_definitions(-DUBUNTU_GESTURES_PLUGIN_DIR="${CMAKE_BINARY_DIR}/plugins")
22add_definitions(-DTESTS_UTILS_MODULES_DIR="${CMAKE_BINARY_DIR}/tests/utils/modules")
18add_definitions(-DTESTS_UTILS_MODULES_DIR="${CMAKE_BINARY_DIR}/tests/utils/modules")
23
19
24−macro(add_gesture_ui_test CLASSNAME)
20+macro(build_gesture_test CLASSNAME)
25 add_executable(${CLASSNAME}TestExec tst_${CLASSNAME}.cpp GestureTest.cpp TestItem.cpp)
21 add_executable(${CLASSNAME}TestExec tst_${CLASSNAME}.cpp GestureTest.cpp TestItem.cpp)
26 qt5_use_modules(${CLASSNAME}TestExec Test Core Qml Gui Quick)
22 qt5_use_modules(${CLASSNAME}TestExec Test Core Qml Gui Quick)
27 target_link_libraries(${CLASSNAME}TestExec UbuntuGesturesQml UbuntuGestures)
23 target_link_libraries(${CLASSNAME}TestExec UbuntuGesturesQml UbuntuGestures)
24+endmacro()
25+
26+macro(add_gesture_unit_test CLASSNAME)
27+ build_gesture_test(${CLASSNAME})
28+ add_unity8_unittest(${CLASSNAME} ${CLASSNAME}TestExec
29+ ENVIRONMENT LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/plugins/Ubuntu/Gestures
30+ DEPENDS UbuntuGesturesTest-qmlfiles
31+ ${ARGN}
32+ )
33+endmacro()
28
34
35+macro(add_gesture_ui_test CLASSNAME)
36+ build_gesture_test(${CLASSNAME})
37+ add_unity8_uitest(${CLASSNAME} ${CLASSNAME}TestExec
29− add_binary_qml_test(${CLASSNAME} ${CMAKE_BINARY_DIR}/plugins/Ubuntu/Gestures UbuntuGesturesTestQmlFiles "")
38+ ENVIRONMENT LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/plugins/Ubuntu/Gestures
39+ DEPENDS UbuntuGesturesTest-qmlfiles
40+ ${ARGN}
41+ )
30 add_manual_qml_test(. ${CLASSNAME} IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins
42 add_manual_qml_test(. ${CLASSNAME} IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins
31 ${CMAKE_BINARY_DIR}/tests/utils/modules)
43 ${CMAKE_BINARY_DIR}/tests/utils/modules)
32−endmacro(add_gesture_ui_test)
44+endmacro()
33−
34−macro(add_gesture_test CLASSNAME)
35− set(testCommand
36− ${CLASSNAME}TestExec -o ${CMAKE_BINARY_DIR}/test${CLASSNAME}.xml,xunitxml -o -,txt)
37−
38− add_test(NAME test${CLASSNAME} COMMAND ${testCommand})
39−
40− set_tests_properties(test${CLASSNAME} PROPERTIES
41− ENVIRONMENT LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/plugins/Ubuntu/Gestures)
42−
43− add_executable(${CLASSNAME}TestExec tst_${CLASSNAME}.cpp)
44− qt5_use_modules(${CLASSNAME}TestExec Test Core)
45− target_link_libraries(${CLASSNAME}TestExec UbuntuGesturesQml)
46−endmacro(add_gesture_test)
47
45
48add_gesture_ui_test(DirectionalDragArea)
46add_gesture_ui_test(DirectionalDragArea)
49add_gesture_ui_test(FloatingFlickable)
47add_gesture_ui_test(FloatingFlickable)
50add_gesture_ui_test(PressedOutsideNotifier)
48add_gesture_ui_test(PressedOutsideNotifier)
51add_gesture_ui_test(TouchDispatcher)
49add_gesture_ui_test(TouchDispatcher)
52add_gesture_ui_test(TouchGate)
50add_gesture_ui_test(TouchGate)
53−add_gesture_test(Damper)
51+add_gesture_unit_test(Damper)
54−add_gesture_test(AxisVelocityCalculator)
52+add_gesture_unit_test(AxisVelocityCalculator)
tests/plugins/Unity/Indicators/CMakeLists.txt+9−12
@@ -17,13 +17,8 @@ macro(indicator_test TEST)
17 set(multi_value_keywords ADDITIONAL_CPPS ADDITIONAL_LIBS)
17 set(multi_value_keywords ADDITIONAL_CPPS ADDITIONAL_LIBS)
18 cmake_parse_arguments(test "" "" "${multi_value_keywords}" ${ARGN})
18 cmake_parse_arguments(test "" "" "${multi_value_keywords}" ${ARGN})
19
19
20− set(testCommand ${CMAKE_CURRENT_BINARY_DIR}/${TEST}Exec
21− -o ${CMAKE_BINARY_DIR}/${TEST}.xml,xunitxml
22− -o -,txt)
23− add_test(NAME ${TEST} COMMAND ${testCommand})
24− add_custom_target(${TEST} ${testCommand})
25 add_executable(${TEST}Exec
20 add_executable(${TEST}Exec
26− ${TEST}.cpp
21+ ${TEST}Test.cpp
27 ${test_ADDITIONAL_CPPS}
22 ${test_ADDITIONAL_CPPS}
28 )
23 )
29 qt5_use_modules(${TEST}Exec Test Core Qml)
24 qt5_use_modules(${TEST}Exec Test Core Qml)
@@ -33,11 +28,13 @@ macro(indicator_test TEST)
33 ${GIO_LIBRARIES}
28 ${GIO_LIBRARIES}
34 ${QMENUMODEL_LDFLAGS}
29 ${QMENUMODEL_LDFLAGS}
35 )
30 )
31+
32+ add_unity8_unittest(${TEST} ${TEST}Exec)
36endmacro(indicator_test)
33endmacro(indicator_test)
37
34
38−indicator_test(indicatorsmanagertest ADDITIONAL_LIBS IndicatorsQml)
35+indicator_test(IndicatorsManager ADDITIONAL_LIBS IndicatorsQml)
39−indicator_test(indicatorsmodeltest ADDITIONAL_LIBS IndicatorsQml)
36+indicator_test(IndicatorsModel ADDITIONAL_LIBS IndicatorsQml)
40−indicator_test(menucontentactivatortest ADDITIONAL_CPPS ${INDICATORS_DIR}/menucontentactivator.cpp)
37+indicator_test(MenuContentActivator ADDITIONAL_CPPS ${INDICATORS_DIR}/menucontentactivator.cpp)
41−indicator_test(unitymenumodelstacktest ADDITIONAL_CPPS ${TEST_DIR}/mocks/QMenuModel/unitymenumodel.cpp ${INDICATORS_DIR}/unitymenumodelstack.cpp)
38+indicator_test(UnityMenuModelStack ADDITIONAL_CPPS ${TEST_DIR}/mocks/QMenuModel/unitymenumodel.cpp ${INDICATORS_DIR}/unitymenumodelstack.cpp)
42−indicator_test(rootactionstatetest ADDITIONAL_LIBS IndicatorsQml)
39+indicator_test(RootActionState ADDITIONAL_LIBS IndicatorsQml)
43−indicator_test(sharedunitymenumodeltest ADDITIONAL_LIBS IndicatorsQml)
40+indicator_test(SharedUnityMenuModel ADDITIONAL_LIBS IndicatorsQml)
tests/plugins/Unity/Indicators/indicatorsmanagertest.cpp → tests/plugins/Unity/Indicators/IndicatorsManagerTest.cpprenamed+1−1
@@ -180,4 +180,4 @@ private Q_SLOTS:
180};
180};
181
181
182QTEST_GUILESS_MAIN(IndicatorsManagerTest)
182QTEST_GUILESS_MAIN(IndicatorsManagerTest)
183−#include "indicatorsmanagertest.moc"
183+#include "IndicatorsManagerTest.moc"
tests/plugins/Unity/Indicators/indicatorsmodeltest.cpp → tests/plugins/Unity/Indicators/IndicatorsModelTest.cpprenamed+1−1
@@ -138,4 +138,4 @@ private Q_SLOTS:
138
138
139QTEST_GUILESS_MAIN(IndicatorsModelTest)
139QTEST_GUILESS_MAIN(IndicatorsModelTest)
140
140
141−#include "indicatorsmodeltest.moc"
141+#include "IndicatorsModelTest.moc"
tests/plugins/Unity/Indicators/menucontentactivatortest.cpp → tests/plugins/Unity/Indicators/MenuContentActivatorTest.cpprenamed+1−1
@@ -299,4 +299,4 @@ private:
299};
299};
300
300
301QTEST_GUILESS_MAIN(MenuConentActivatorTest)
301QTEST_GUILESS_MAIN(MenuConentActivatorTest)
302−#include "menucontentactivatortest.moc"
302+#include "MenuContentActivatorTest.moc"
tests/plugins/Unity/Indicators/rootactionstatetest.cpp → tests/plugins/Unity/Indicators/RootActionStateTest.cpprenamed+1−1
@@ -92,4 +92,4 @@ private Q_SLOTS:
92};
92};
93
93
94QTEST_GUILESS_MAIN(RootActionStateTest)
94QTEST_GUILESS_MAIN(RootActionStateTest)
95−#include "rootactionstatetest.moc"
95+#include "RootActionStateTest.moc"
tests/plugins/Unity/Indicators/sharedunitymenumodeltest.cpp → tests/plugins/Unity/Indicators/SharedUnityMenuModelTest.cpprenamed+1−1
@@ -99,4 +99,4 @@ private Q_SLOTS:
99};
99};
100
100
101QTEST_GUILESS_MAIN(SharedUnityMenuModelTest)
101QTEST_GUILESS_MAIN(SharedUnityMenuModelTest)
102−#include "sharedunitymenumodeltest.moc"
102+#include "SharedUnityMenuModelTest.moc"
tests/plugins/Unity/Indicators/unitymenumodelstacktest.cpp → tests/plugins/Unity/Indicators/UnityMenuModelStackTest.cpprenamed+1−1
@@ -205,4 +205,4 @@ public:
205};
205};
206
206
207QTEST_GUILESS_MAIN(UnityMenuModelStackTest)
207QTEST_GUILESS_MAIN(UnityMenuModelStackTest)
208−#include "unitymenumodelstacktest.moc"
208+#include "UnityMenuModelStackTest.moc"
tests/plugins/Unity/Launcher/CMakeLists.txt+5−5
@@ -14,11 +14,6 @@ add_definitions(-DSRCDIR="${CMAKE_CURRENT_SOURCE_DIR}")
14add_definitions(-DLAUNCHER_TESTING)
14add_definitions(-DLAUNCHER_TESTING)
15
15
16### LauncherModelTest
16### LauncherModelTest
17−set(testModelCommand dbus-test-runner --task ${CMAKE_CURRENT_BINARY_DIR}/launchermodeltestExec
18− --parameter -o --parameter ${CMAKE_BINARY_DIR}/launchermodeltest.xml,xunitxml
19− --parameter -o --parameter -,txt)
20−add_test(NAME launchermodeltest COMMAND ${testModelCommand})
21−add_custom_target(launchermodeltest ${testModelCommand})
22add_executable(launchermodeltestExec
17add_executable(launchermodeltestExec
23 launchermodeltest.cpp
18 launchermodeltest.cpp
24 gsettings.cpp
19 gsettings.cpp
@@ -42,6 +37,11 @@ target_link_libraries(launchermodeltestExec
42 )
37 )
43qt5_use_modules(launchermodeltestExec Test Core DBus Xml Gui)
38qt5_use_modules(launchermodeltestExec Test Core DBus Xml Gui)
44
39
40+add_unity8_unittest(LauncherModel dbus-test-runner
41+ ARG_PREFIX "--parameter"
42+ ARGS --task $<TARGET_FILE:launchermodeltestExec>
43+)
44+
45# copy .desktop files into build directory for shadow builds
45# copy .desktop files into build directory for shadow builds
46file(GLOB DESKTOP_FILES *.desktop)
46file(GLOB DESKTOP_FILES *.desktop)
47
47
tests/plugins/Unity/Session/CMakeLists.txt+5−5
@@ -9,11 +9,6 @@ add_definitions(-DSRCDIR="${CMAKE_CURRENT_SOURCE_DIR}")
9add_definitions(-DSESSION_TESTING)
9add_definitions(-DSESSION_TESTING)
10
10
11### SessionBackendTest
11### SessionBackendTest
12−set(testBackendCommand dbus-test-runner --task ${CMAKE_CURRENT_BINARY_DIR}/sessionbackendtestExec
13− --parameter -o --parameter ${CMAKE_BINARY_DIR}/sessionbackendtest.xml,xunitxml
14− --parameter -o --parameter -,txt)
15−add_test(NAME sessionbackendtest COMMAND ${testBackendCommand})
16−add_custom_target(sessionbackendtest ${testBackendCommand})
17add_executable(sessionbackendtestExec
12add_executable(sessionbackendtestExec
18 sessionbackendtest.cpp
13 sessionbackendtest.cpp
19 ${CMAKE_SOURCE_DIR}/plugins/Unity/Session/dbusunitysessionservice.cpp
14 ${CMAKE_SOURCE_DIR}/plugins/Unity/Session/dbusunitysessionservice.cpp
@@ -22,3 +17,8 @@ target_link_libraries(sessionbackendtestExec
22 unity8-private
17 unity8-private
23 )
18 )
24qt5_use_modules(sessionbackendtestExec Test Core Qml DBus)
19qt5_use_modules(sessionbackendtestExec Test Core Qml DBus)
20+
21+add_unity8_unittest(SessionBackend dbus-test-runner
22+ ARG_PREFIX "--parameter"
23+ ARGS --task $<TARGET_FILE:sessionbackendtestExec>
24+)
tests/plugins/Utils/CMakeLists.txt+12−26
@@ -4,31 +4,17 @@ include_directories(
4 ${CMAKE_CURRENT_BINARY_DIR}
4 ${CMAKE_CURRENT_BINARY_DIR}
5 )
5 )
6
6
7−macro(run_tests)
8− set(_test_list "")
9− foreach(_test ${ARGN})
7+foreach(util_test
10− set(testCommand env "LC_ALL=C.UTF-8" ${CMAKE_CURRENT_BINARY_DIR}/${_test}Exec
8+ QLimitProxyModel
11− -o ${CMAKE_BINARY_DIR}/${_test}.xml,xunitxml
9+ UnitySortFilterProxyModel
12− -o -,txt)
10+ TimeFormatter
13− add_test(NAME ${_test} COMMAND ${testCommand})
11+ HomeKeyWatcher
14− add_custom_target(${_test} ${testCommand})
12+)
15− add_executable(${_test}Exec ${_test}.cpp modeltest.cpp)
13+ add_executable(${util_test}TestExec ${util_test}Test.cpp ModelTest.cpp)
16− qt5_use_modules(${_test}Exec Test Core Qml)
14+ qt5_use_modules(${util_test}TestExec Test Core Qml)
17− target_link_libraries(${_test}Exec
15+ target_link_libraries(${util_test}TestExec Utils-qml)
18− Utils-qml
16+ add_unity8_unittest(${util_test} ${util_test}TestExec ADD_TEST)
19− )
20− set(_test_list "${_test_list};${_test}")
21− endforeach()
17+endforeach()
22−endmacro(run_tests)
23−
24−run_tests(
25− qlimitproxymodeltest
26− unitysortfilterproxymodeltest
27− timeformattertest
28− homekeywatchertest
29− )
30
18
31# plain qml test
19# plain qml test
32−set(qmltest_DEFAULT_TARGETS qmltests)
20+add_unity8_qmlunittest(. UtilsStyle)
33−set(qmltest_DEFAULT_PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=minimal")
34−add_qml_test(. UtilsStyle IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins)
tests/plugins/Utils/homekeywatchertest.cpp → tests/plugins/Utils/HomeKeyWatcherTest.cpprenamed+1−1
@@ -320,4 +320,4 @@ AbstractTimer *FakeTimerFactory::create(QObject *parent)
320
320
321QTEST_GUILESS_MAIN(HomeKeyWatcherTest)
321QTEST_GUILESS_MAIN(HomeKeyWatcherTest)
322
322
323−#include "homekeywatchertest.moc"
323+#include "HomeKeyWatcherTest.moc"
tests/plugins/Utils/modeltest.cpp → tests/plugins/Utils/ModelTest.cpprenamed+1−1
@@ -47,7 +47,7 @@
47
47
48#include <QtGui/QtGui>
48#include <QtGui/QtGui>
49
49
50−#include "modeltest.h"
50+#include "ModelTest.h"
51
51
52#include <QtTest/QtTest>
52#include <QtTest/QtTest>
53
53
tests/plugins/Utils/modeltest.h → tests/plugins/Utils/ModelTest.hrenamed

The content is the same.

tests/plugins/Utils/qlimitproxymodeltest.cpp → tests/plugins/Utils/QLimitProxyModelTest.cpprenamed+2−2
@@ -16,7 +16,7 @@
16
16
17// local
17// local
18#include "qlimitproxymodelqml.h"
18#include "qlimitproxymodelqml.h"
19−#include "modeltest.h"
19+#include "ModelTest.h"
20
20
21// Qt
21// Qt
22#include <QTest>
22#include <QTest>
@@ -608,4 +608,4 @@ private Q_SLOTS:
608
608
609QTEST_GUILESS_MAIN(QLimitProxyModelTest)
609QTEST_GUILESS_MAIN(QLimitProxyModelTest)
610
610
611−#include "qlimitproxymodeltest.moc"
611+#include "QLimitProxyModelTest.moc"
tests/plugins/Utils/timeformattertest.cpp → tests/plugins/Utils/TimeFormatterTest.cpprenamed+1−11
@@ -45,16 +45,6 @@ private:
45 }
45 }
46
46
47private Q_SLOTS:
47private Q_SLOTS:
48− void initTestCase()
49− {
50− setenv("UNITY_TEST_ENV", "1", 1);
51− }
52−
53− void cleanupTestCase()
54− {
55− unsetenv("UNITY_TEST_ENV");
56− }
57−
58 void testTimeFormatter_Format_data() { addTestData(QList<int>() << 0); }
48 void testTimeFormatter_Format_data() { addTestData(QList<int>() << 0); }
59 void testTimeFormatter_Format()
49 void testTimeFormatter_Format()
60 {
50 {
@@ -162,4 +152,4 @@ private Q_SLOTS:
162
152
163QTEST_GUILESS_MAIN(TimeFormatterTest)
153QTEST_GUILESS_MAIN(TimeFormatterTest)
164
154
165−#include "timeformattertest.moc"
155+#include "TimeFormatterTest.moc"
tests/plugins/Utils/unitysortfilterproxymodeltest.cpp → tests/plugins/Utils/UnitySortFilterProxyModelTest.cpprenamed+2−2
@@ -19,7 +19,7 @@
19
19
20// local
20// local
21#include "unitysortfilterproxymodelqml.h"
21#include "unitysortfilterproxymodelqml.h"
22−#include "modeltest.h"
22+#include "ModelTest.h"
23
23
24// Qt
24// Qt
25#include <QTest>
25#include <QTest>
@@ -287,4 +287,4 @@ private Q_SLOTS:
287
287
288QTEST_GUILESS_MAIN(UnitySortFilterProxyModelTest)
288QTEST_GUILESS_MAIN(UnitySortFilterProxyModelTest)
289
289
290−#include "unitysortfilterproxymodeltest.moc"
290+#include "UnitySortFilterProxyModelTest.moc"
tests/plugins/Wizard/CMakeLists.txt+2−2
@@ -8,11 +8,11 @@ add_executable(tst-wizard-pagelist
8 ${CMAKE_SOURCE_DIR}/plugins/Wizard/PageList.cpp
8 ${CMAKE_SOURCE_DIR}/plugins/Wizard/PageList.cpp
9)
9)
10qt5_use_modules(tst-wizard-pagelist Core Qml Test)
10qt5_use_modules(tst-wizard-pagelist Core Qml Test)
11−add_test(NAME wizardpagelisttest COMMAND env UNITY_TEST_ENV=1 ${CMAKE_CURRENT_BINARY_DIR}/tst-wizard-pagelist)
11+add_unity8_unittest(WizardPageList tst-wizard-pagelist ENVIRONMENT WIZARD_TESTING=1)
12
12
13add_executable(tst-wizard-system
13add_executable(tst-wizard-system
14 tst_system.cpp
14 tst_system.cpp
15 ${CMAKE_SOURCE_DIR}/plugins/Wizard/System.cpp
15 ${CMAKE_SOURCE_DIR}/plugins/Wizard/System.cpp
16)
16)
17qt5_use_modules(tst-wizard-system Core DBus Qml Test)
17qt5_use_modules(tst-wizard-system Core DBus Qml Test)
18−add_test(NAME wizardsystemtest COMMAND ${CMAKE_CURRENT_BINARY_DIR}/tst-wizard-system)
18+add_unity8_unittest(WizardSystem tst-wizard-system)
tests/qmltests/CMakeLists.txt+77−94
@@ -1,97 +1,80 @@
1−# add_qml_test macro
2−include(QmlTest)
3
1
4add_subdirectory(Components)
2add_subdirectory(Components)
5
3
6−set(qmltest_DEFAULT_IMPORT_PATHS
7− ${CMAKE_BINARY_DIR}/plugins
8− ${CMAKE_BINARY_DIR}/tests/utils/modules
9− ${CMAKE_BINARY_DIR}/tests/mocks
10−)
11−
12−set(qmltest_DEFAULT_TARGETS qmlunittests)
13−set(qmltest_DEFAULT_NO_ADD_TEST FALSE)
14−set(qmltest_DEFAULT_PROPERTIES ENVIRONMENT "QT_QPA_PLATFORM=minimal")
15−add_qml_test(utils/Unity/Test UnityTest)
16−add_qml_test(Components PhysicalKeysMapper)
17−
18−set(qmltest_DEFAULT_TARGETS qmluitests)
19−set(qmltest_DEFAULT_NO_ADD_TEST TRUE)
20−set(qmltest_DEFAULT_PROPERTIES ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/libusermetrics:${CMAKE_BINARY_DIR}/tests/mocks/LightDM/liblightdm:${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
21−
22−add_qml_test(. OrientedShell)
4+add_unity8_qmltest(. OrientedShell)
23−add_qml_test(. Shell)
5+add_unity8_qmltest(. Shell LIGHTDM)
24−add_qml_test(. ShellWithPin)
6+add_unity8_qmltest(. ShellWithPin LIGHTDM)
25−add_qml_test(Components Background)
7+add_unity8_qmltest(Components Background)
26−add_qml_test(Components Carousel)
8+add_unity8_qmltest(Components Carousel)
27−add_qml_test(Components Dialogs)
9+add_unity8_qmltest(Components Dialogs LIGHTDM)
28−add_qml_test(Components DraggingArea)
10+add_unity8_qmltest(Components DraggingArea)
29−add_qml_test(Components LazyImage)
11+add_unity8_qmltest(Components LazyImage)
30−add_qml_test(Components Lockscreen)
12+add_unity8_qmltest(Components Lockscreen)
13+add_unity8_qmlunittest(Components PhysicalKeysMapper)
31−add_qml_test(Components Rating)
14+add_unity8_qmltest(Components Rating)
32−add_qml_test(Components ResponsiveGridView)
15+add_unity8_qmltest(Components ResponsiveGridView)
33−add_qml_test(Components ResponsiveVerticalJournal IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins)
16+add_unity8_qmltest(Components ResponsiveVerticalJournal)
34−add_qml_test(Components Showable)
17+add_unity8_qmltest(Components Showable)
35−add_qml_test(Components ZoomableImage)
18+add_unity8_qmltest(Components ZoomableImage)
36−add_qml_test(Dash Dash)
19+add_unity8_qmltest(Dash Dash)
37−add_qml_test(Dash DashContent)
20+add_unity8_qmltest(Dash DashContent)
38−add_qml_test(Dash Card)
21+add_unity8_qmltest(Dash Card)
39−add_qml_benchmark(Dash CardBenchmark 1000)
22+add_unity8_qmlbenchmark(Dash CardBenchmark 1000)
40−add_qml_test(Dash CardTool)
23+add_unity8_qmltest(Dash CardTool)
41−add_qml_test(Dash GenericScopeView)
24+add_unity8_qmltest(Dash GenericScopeView)
42−add_qml_test(Dash PageHeader)
25+add_unity8_qmltest(Dash PageHeader)
43−add_qml_test(Dash PreviewListView)
26+add_unity8_qmltest(Dash PreviewListView)
44−add_qml_test(Dash/Previews Preview)
27+add_unity8_qmltest(Dash/Previews Preview)
45−add_qml_test(Dash/Previews PreviewActions)
28+add_unity8_qmltest(Dash/Previews PreviewActions)
46−add_qml_test(Dash/Previews PreviewAudioPlayback)
29+add_unity8_qmltest(Dash/Previews PreviewAudioPlayback)
47−add_qml_test(Dash/Previews PreviewExpandable)
30+add_unity8_qmltest(Dash/Previews PreviewExpandable)
48−add_qml_test(Dash/Previews PreviewHeader)
31+add_unity8_qmltest(Dash/Previews PreviewHeader)
49−add_qml_test(Dash/Previews PreviewImageGallery)
32+add_unity8_qmltest(Dash/Previews PreviewImageGallery)
50−add_qml_test(Dash/Previews PreviewPayments)
33+add_unity8_qmltest(Dash/Previews PreviewPayments)
51−add_qml_test(Dash/Previews PreviewProgress)
34+add_unity8_qmltest(Dash/Previews PreviewProgress)
52−add_qml_test(Dash/Previews PreviewRatingDisplay)
35+add_unity8_qmltest(Dash/Previews PreviewRatingDisplay)
53−add_qml_test(Dash/Previews PreviewRatingEdit)
36+add_unity8_qmltest(Dash/Previews PreviewRatingEdit)
54−add_qml_test(Dash/Previews PreviewRatingInput)
37+add_unity8_qmltest(Dash/Previews PreviewRatingInput)
55−add_qml_test(Dash/Previews PreviewTable)
38+add_unity8_qmltest(Dash/Previews PreviewTable)
56−add_qml_test(Dash/Previews PreviewTextSummary)
39+add_unity8_qmltest(Dash/Previews PreviewTextSummary)
57−add_qml_test(Dash/Previews PreviewVideoPlayback)
40+add_unity8_qmltest(Dash/Previews PreviewVideoPlayback)
58−add_qml_test(Dash/Previews PreviewWidgetFactory)
41+add_unity8_qmltest(Dash/Previews PreviewWidgetFactory)
59−add_qml_test(Dash/Previews PreviewZoomableImage)
42+add_unity8_qmltest(Dash/Previews PreviewZoomableImage)
60−add_qml_test(Dash/ScopeSettings ScopeSettingBoolean)
43+add_unity8_qmltest(Dash/ScopeSettings ScopeSettingBoolean)
61−add_qml_test(Dash/ScopeSettings ScopeSettingList)
44+add_unity8_qmltest(Dash/ScopeSettings ScopeSettingList)
62−add_qml_test(Dash/ScopeSettings ScopeSettingNumber)
45+add_unity8_qmltest(Dash/ScopeSettings ScopeSettingNumber)
63−add_qml_test(Dash/ScopeSettings ScopeSettingString)
46+add_unity8_qmltest(Dash/ScopeSettings ScopeSettingString)
64−add_qml_test(Dash/ScopeSettings ScopeSettingsWidgetFactory)
47+add_unity8_qmltest(Dash/ScopeSettings ScopeSettingsWidgetFactory)
65−add_qml_test(Greeter Clock)
48+add_unity8_qmltest(Greeter Clock)
66−add_qml_test(Greeter Greeter)
49+add_unity8_qmltest(Greeter Greeter LIGHTDM)
67−add_qml_test(Greeter Infographics)
50+add_unity8_qmltest(Greeter Infographics LIGHTDM)
68−add_qml_test(Greeter NarrowView)
51+add_unity8_qmltest(Greeter NarrowView LIGHTDM)
69−add_qml_test(Greeter WideView)
52+add_unity8_qmltest(Greeter WideView LIGHTDM)
70−add_qml_test(Launcher Launcher)
53+add_unity8_qmltest(Launcher Launcher)
71−add_qml_test(Notifications Notifications)
54+add_unity8_qmltest(Notifications Notifications)
72−add_qml_test(Notifications VisualSnapDecisionsQueue)
55+add_unity8_qmltest(Notifications VisualSnapDecisionsQueue)
73−add_qml_test(Notifications OptionToggle)
56+add_unity8_qmltest(Notifications OptionToggle)
74−add_qml_test(Notifications SwipeToAct)
57+add_unity8_qmltest(Notifications SwipeToAct)
75−add_qml_test(Panel ActiveCallHint)
58+add_unity8_qmltest(Panel ActiveCallHint)
76−add_qml_test(Panel IndicatorItem)
59+add_unity8_qmltest(Panel IndicatorItem)
77−add_qml_test(Panel IndicatorItemRow)
60+add_unity8_qmltest(Panel IndicatorItemRow)
78−add_qml_test(Panel IndicatorPage)
61+add_unity8_qmltest(Panel IndicatorPage)
79−add_qml_test(Panel IndicatorsBar)
62+add_unity8_qmltest(Panel IndicatorsBar)
80−add_qml_test(Panel IndicatorsMenu)
63+add_unity8_qmltest(Panel IndicatorsMenu)
81−add_qml_test(Panel MenuContent)
64+add_unity8_qmltest(Panel MenuContent)
82−add_qml_test(Panel Panel)
65+add_unity8_qmltest(Panel Panel)
83−add_qml_test(Panel/Indicators IndicatorsLight ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/QMenuModel")
66+add_unity8_qmltest(Panel/Indicators IndicatorsLight)
84−# These MenuItemFactory tests need the test/mocks/ to come before plugins/
67+add_unity8_qmltest(Panel/Indicators MenuItemFactory)
85−add_qml_test(Panel/Indicators MenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS})
86−add_qml_test(Panel/Indicators MessageMenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS})
68+add_unity8_qmltest(Panel/Indicators MessageMenuItemFactory)
87−add_qml_test(Stages ApplicationWindow)
69+add_unity8_qmltest(Stages ApplicationWindow)
88−add_qml_test(Stages DesktopStage)
70+add_unity8_qmltest(Stages DesktopStage)
89−add_qml_test(Stages PhoneStage ENVIRONMENT)
71+add_unity8_qmltest(Stages PhoneStage)
90−add_qml_test(Stages SpreadDelegate ENVIRONMENT)
72+add_unity8_qmltest(Stages SpreadDelegate)
91−add_qml_test(Stages SurfaceContainer ENVIRONMENT)
73+add_unity8_qmltest(Stages SurfaceContainer)
92−add_qml_test(Stages SessionContainer ENVIRONMENT)
74+add_unity8_qmltest(Stages SessionContainer)
93−add_qml_test(Stages TabletStage)
75+add_unity8_qmltest(Stages TabletStage)
94−add_qml_test(Stages WindowMoveResizeArea)
76+add_unity8_qmltest(Stages WindowMoveResizeArea)
95−add_qml_test(Stages Splash)
77+add_unity8_qmltest(Stages Splash)
96−add_qml_test(Tutorial Tutorial)
78+add_unity8_qmltest(Tutorial Tutorial LIGHTDM)
97−add_qml_test(Wizard Wizard)
79+add_unity8_qmltest(Wizard Wizard ENVIRONMENT "OXIDE_NO_SANDBOX=1")
80+add_unity8_qmlunittest(utils/Unity/Test UnityTest)
tests/qmltests/Components/CMakeLists.txt+4−10
@@ -16,19 +16,13 @@ add_executable(DragHandleTestExec tst_DragHandle.cpp)
16qt5_use_modules(DragHandleTestExec Test Core Qml Gui Quick)
16qt5_use_modules(DragHandleTestExec Test Core Qml Gui Quick)
17target_link_libraries(DragHandleTestExec UbuntuGesturesQml UbuntuGestures)
17target_link_libraries(DragHandleTestExec UbuntuGesturesQml UbuntuGestures)
18
18
19−add_binary_qml_test(DragHandle ${CMAKE_BINARY_DIR}/plugins/Ubuntu/Gestures "" "")
19+add_unity8_uitest(DragHandle DragHandleTestExec ENVIRONMENT LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/plugins/Ubuntu/Gestures)
20−add_manual_qml_test(. DragHandle IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${CMAKE_BINARY_DIR}/tests/utils/modules)
20+add_manual_qml_test(. DragHandle IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${CMAKE_BINARY_DIR}/tests/utils/modules)
21
21
22−########## tst_EdgeDragEvaluator
23−
24−include_directories(
25− ${CMAKE_SOURCE_DIR}/plugins/Ubuntu/Gestures
26− ${CMAKE_SOURCE_DIR}/libs/UbuntuGestures
27− ${CMAKE_CURRENT_BINARY_DIR}
28− )
29
22
23+########## tst_EdgeDragEvaluator
30add_executable(EdgeDragEvaluatorTestExec tst_EdgeDragEvaluator.cpp)
24add_executable(EdgeDragEvaluatorTestExec tst_EdgeDragEvaluator.cpp)
31qt5_use_modules(EdgeDragEvaluatorTestExec Test Core Qml Gui Quick)
25qt5_use_modules(EdgeDragEvaluatorTestExec Test Core Qml Gui Quick)
32target_link_libraries(EdgeDragEvaluatorTestExec UbuntuGesturesQml UbuntuGestures)
26target_link_libraries(EdgeDragEvaluatorTestExec UbuntuGesturesQml UbuntuGestures)
33
27
34−add_binary_qml_test(EdgeDragEvaluator ${CMAKE_BINARY_DIR}/plugins/Ubuntu/Gestures "" "")
28+add_unity8_uitest(EdgeDragEvaluator EdgeDragEvaluatorTestExec ENVIRONMENT LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/plugins/Ubuntu/Gestures)
tests/qmltests/Dash/Previews/tst_PreviewHeader.qml+30
@@ -38,6 +38,22 @@ Rectangle {
38 "attributes": [{"value":"text1","icon":"image://theme/ok"},{"value":"text2","icon":"image://theme/cancel"}]
38 "attributes": [{"value":"text1","icon":"image://theme/ok"},{"value":"text2","icon":"image://theme/cancel"}]
39 }
39 }
40
40
41+ property var brokenheaderjson: {
42+ "title": "THE TITLE",
43+ "subtitle": "Something catchy",
44+ "mascot": "bad_path",
45+ "fallback": "",
46+ "attributes": [{"value":"text1","icon":"image://theme/ok"},{"value":"text2","icon":"image://theme/cancel"}]
47+ }
48+
49+ property var fallbackheaderjson: {
50+ "title": "THE TITLE",
51+ "subtitle": "Something catchy",
52+ "mascot": "bad_path2",
53+ "fallback": "../graphics/play_button.png",
54+ "attributes": [{"value":"text1","icon":"image://theme/ok"},{"value":"text2","icon":"image://theme/cancel"}]
55+ }
56+
41 PreviewHeader {
57 PreviewHeader {
42 id: previewHeader
58 id: previewHeader
43 widgetData: headerjson
59 widgetData: headerjson
@@ -121,5 +137,19 @@ Rectangle {
121 compare(innerPreviewHeader.subtitle, "Something catchy");
137 compare(innerPreviewHeader.subtitle, "Something catchy");
122 compare(innerPreviewHeader.mascot.toString().slice(-24), "graphics/play_button.png");
138 compare(innerPreviewHeader.mascot.toString().slice(-24), "graphics/play_button.png");
123 }
139 }
140+
141+ function test_fallback() {
142+ previewHeader.widgetData = brokenheaderjson;
143+ tryCompareFunction(function() { return findChild(previewHeader, "mascotShape") != null }, true);
144+ var mascot = findChild(previewHeader, "mascotShape");
145+ compare(mascot.visible, false);
146+
147+ previewHeader.widgetData = {};
148+ previewHeader.widgetData = fallbackheaderjson;
149+ tryCompareFunction(function() { return findChild(previewHeader, "mascotShape") != null }, true);
150+ var mascot = findChild(previewHeader, "mascotShape");
151+ tryCompare(mascot, "visible", true);
152+ tryCompare(mascot.image, "status", Image.Ready);
153+ }
124 }
154 }
125}
155}
tests/qmltests/Dash/Previews/tst_PreviewImageGallery.qml+21−1
@@ -33,10 +33,21 @@ Rectangle {
33 "sources": [
33 "sources": [
34 "../../graphics/phone_background.jpg",
34 "../../graphics/phone_background.jpg",
35 "../../graphics/tablet_background.jpg",
35 "../../graphics/tablet_background.jpg",
36− "../../graphics/clock@18.png"
36+ "../../graphics/clock@18.png",
37+ "../../graphics/borked"
37 ]
38 ]
38 }
39 }
39
40
41+ property var sourcesModel1WithFallback: {
42+ "sources": [
43+ "../../graphics/phone_background.jpg",
44+ "../../graphics/tablet_background.jpg",
45+ "../../graphics/clock@18.png",
46+ "../../graphics/borked"
47+ ]
48+ , "fallback": "../../graphics/clock@18.png"
49+ }
50+
40 PreviewImageGallery {
51 PreviewImageGallery {
41 id: imageGallery
52 id: imageGallery
42 width: parent.width
53 width: parent.width
@@ -103,5 +114,14 @@ Rectangle {
103 tryCompare(overlayListView, "currentIndex", data.index);
114 tryCompare(overlayListView, "currentIndex", data.index);
104 verify(image.source === overlayListView.currentItem.source);
115 verify(image.source === overlayListView.currentItem.source);
105 }
116 }
117+
118+ function test_fallback() {
119+ var image3 = findChild(imageGallery, "previewImage3");
120+ tryCompare(image3, "state", "error");
121+ imageGallery.widgetData = sourcesModel0;
122+ imageGallery.widgetData = sourcesModel1WithFallback;
123+ image3 = findChild(imageGallery, "previewImage3");
124+ tryCompare(image3, "state", "ready");
125+ }
106 }
126 }
107}
127}
tests/qmltests/Dash/Previews/tst_PreviewZoomableImage.qml+27−6
@@ -26,7 +26,7 @@ Rectangle {
26 color: "lightgrey"
26 color: "lightgrey"
27
27
28 property var widgetData0: {
28 property var widgetData0: {
29− "source": Qt.resolvedUrl("../artwork/checkers.png"),
29+ "source": "../../graphics/phone_background.jpg",
30 "zoomable": false
30 "zoomable": false
31 }
31 }
32
32
@@ -34,21 +34,35 @@ Rectangle {
34 "source": ""
34 "source": ""
35 }
35 }
36
36
37− PreviewZoomableImage {
37+ property var widgetData2: {
38− id: zoomableImage
38+ "source": "fadsasf",
39+ "fallback": "../../graphics/phone_background.jpg"
40+ }
41+
42+ Loader {
43+ id: loader
39 anchors.centerIn: parent
44 anchors.centerIn: parent
45+ sourceComponent: PreviewZoomableImage {
40− widgetData: widgetData0
46+ widgetData: widgetData0
47+ }
41 }
48 }
42
49
50+ property alias zoomableImage: loader.item
51+
43 UT.UnityTestCase {
52 UT.UnityTestCase {
44 name: "PreviewZoomableImageTest"
53 name: "PreviewZoomableImageTest"
45 when: windowShown
54 when: windowShown
46
55
47− property Item lazyImage: findChild(zoomableImage, "lazyImage");
56+ property Item lazyImage
48− property Item overlay: findChild(zoomableImage.rootItem, "overlay");
57+ property Item overlay
49
58
50 function init() {
59 function init() {
60+ // Use a loader so we start from scratch each time
61+ loader.active = false;
62+ loader.active = true;
63+ lazyImage = findChild(zoomableImage, "lazyImage");
51 waitForRendering(zoomableImage);
64 waitForRendering(zoomableImage);
65+ overlay = findChild(zoomableImage.rootItem, "overlay");
52 waitForRendering(overlay);
66 waitForRendering(overlay);
53 }
67 }
54
68
@@ -79,5 +93,12 @@ Rectangle {
79 mouseClick(overlayCloseButton);
93 mouseClick(overlayCloseButton);
80 tryCompare(overlay, "visible", false);
94 tryCompare(overlay, "visible", false);
81 }
95 }
96+
97+ function test_fallback() {
98+ zoomableImage.widgetData = widgetData2;
99+ waitForRendering(zoomableImage);
100+ waitForRendering(lazyImage);
101+ tryCompare(lazyImage, "state", "ready");
102+ }
82 }
103 }
83}
104}
tests/qmltests/Dash/tst_Card.qml+30−1
@@ -124,7 +124,6 @@ Rectangle {
124 sourceComponent: cardTool.cardComponent
124 sourceComponent: cardTool.cardComponent
125 clip: true
125 clip: true
126 onLoaded: {
126 onLoaded: {
127− item.template = Qt.binding(function() { return cardTool.template; });
128 item.components = Qt.binding(function() { return cardTool.components; });
127 item.components = Qt.binding(function() { return cardTool.components; });
129 item.cardData = Qt.binding(function() { return Helpers.mapData(dataArea.text, cardTool.components, dataError); });
128 item.cardData = Qt.binding(function() { return Helpers.mapData(dataArea.text, cardTool.components, dataError); });
130 item.width = Qt.binding(function() { return cardTool.cardWidth || item.implicitWidth; });
129 item.width = Qt.binding(function() { return cardTool.cardWidth || item.implicitWidth; });
@@ -224,6 +223,7 @@ Rectangle {
224 property Item mascotImage: findChild(card, "mascotImage");
223 property Item mascotImage: findChild(card, "mascotImage");
225
224
226 function init() {
225 function init() {
226+ cardTool.components = Qt.binding(function() { return Helpers.update(JSON.parse(Helpers.defaultLayout), Helpers.tryParse(layoutArea.text, layoutError))['components']; });
227 loader.visible = true;
227 loader.visible = true;
228 }
228 }
229
229
@@ -424,6 +424,7 @@ Rectangle {
424 ];
424 ];
425 }
425 }
426
426
427+
427 function test_background(data) {
428 function test_background(data) {
428 selector.selectedIndex = data.index;
429 selector.selectedIndex = data.index;
429 waitForRendering(selector);
430 waitForRendering(selector);
@@ -454,6 +455,34 @@ Rectangle {
454 }
455 }
455 }
456 }
456
457
458+ function test_fallback() {
459+ selector.selectedIndex = 0;
460+ waitForRendering(card);
461+
462+ card.cardData["art"] = "somethingbroken";
463+ card.cardDataChanged();
464+ waitForRendering(card);
465+ tryCompare(art, "visible", false);
466+
467+ cardTool.components["art"]["fallback"] = Qt.resolvedUrl("artwork/emblem.png");
468+ cardTool.componentsChanged();
469+ card.cardData["art"] = "somethingbroken";
470+ card.cardDataChanged();
471+ waitForRendering(card);
472+ tryCompare(art, "visible", true);
473+
474+ card.cardData["mascot"] = "somethingbroken2";
475+ card.cardDataChanged();
476+ compare(mascotImage.image.status, Image.Error);
477+
478+ cardTool.components["mascot"] = {"fallback": Qt.resolvedUrl("artwork/emblem.png")};
479+ cardTool.componentsChanged();
480+ card.cardData["mascot"] = "somethingbroken2";
481+ card.cardDataChanged();
482+ waitForRendering(card);
483+ tryCompare(mascotImage.image, "status", Image.Ready);
484+ }
485+
457 function test_font_weights_data() {
486 function test_font_weights_data() {
458 return [
487 return [
459 { tag: "Title only", index: 8, weight: Font.Normal },
488 { tag: "Title only", index: 8, weight: Font.Normal },
tests/qmltests/Dash/tst_GenericScopeView.qml+30−7
@@ -302,6 +302,7 @@ Item {
302 }
302 }
303
303
304 function closePreview() {
304 function closePreview() {
305+ tryCompare(testCase.subPageLoader, "x", 0);
305 var closePreviewMouseArea = findChild(subPageLoader.item, "pageHeader");
306 var closePreviewMouseArea = findChild(subPageLoader.item, "pageHeader");
306 mouseClick(closePreviewMouseArea, units.gu(2), units.gu(2));
307 mouseClick(closePreviewMouseArea, units.gu(2), units.gu(2));
307
308
@@ -616,27 +617,49 @@ Item {
616 waitForRendering(category0);
617 waitForRendering(category0);
617
618
618 var cardTool = findChild(category0, "cardTool");
619 var cardTool = findChild(category0, "cardTool");
619− var cardGrid = category0.item;
620−
621 cardTool.template["non-interactive"] = true;
620 cardTool.template["non-interactive"] = true;
621+ cardTool.templateChanged();
622+
623+ var category0 = findChild(categoryListView, "dashCategory0");
624+ waitForRendering(category0);
625+
626+ var cardGrid = category0.item;
622 compare(cardGrid.cardTool.template["non-interactive"], true);
627 compare(cardGrid.cardTool.template["non-interactive"], true);
623
628
624 var item0 = findChild(cardGrid, "delegate0");
629 var item0 = findChild(cardGrid, "delegate0");
625 waitForRendering(item0);
630 waitForRendering(item0);
626− item0.template = cardTool.template;
627− compare(item0.template["non-interactive"], true);
628 compare(item0.enabled, false);
631 compare(item0.enabled, false);
629 var touchdown = findChild(item0, "touchdown");
632 var touchdown = findChild(item0, "touchdown");
630
633
631 compare(touchdown.visible, false);
634 compare(touchdown.visible, false);
632− mouseClick(item0);
635+ mousePress(item0);
633 compare(touchdown.visible, false);
636 compare(touchdown.visible, false);
637+ mouseRelease(item0);
634
638
635 cardTool.template["non-interactive"] = false;
639 cardTool.template["non-interactive"] = false;
640+ cardTool.templateChanged();
636 compare(cardGrid.cardTool.template["non-interactive"], false);
641 compare(cardGrid.cardTool.template["non-interactive"], false);
637− item0.template = cardTool.template;
642+
638− compare(item0.template["non-interactive"], false);
643+ waitForRendering(category0);
644+ item0 = findChild(cardGrid, "delegate0");
639 compare(item0.enabled, true);
645 compare(item0.enabled, true);
646+ var touchdown = findChild(item0, "touchdown");
647+
648+ compare(touchdown.visible, false);
649+ mousePress(item0);
650+ compare(touchdown.visible, true);
651+ mouseRelease(item0);
652+ compare(touchdown.visible, false);
653+ closePreview();
654+ }
655+
656+ function test_carousel_borderSource() {
657+ var category = scrollToCategory("dashCategory1");
658+ var tile = findChild(category, "carouselDelegate0");
659+ tryCompareFunction(function() { return findChild(tile, "artShapeLoader") !== null; }, true);
660+ var artShapeLoader = findChild(tile, "artShapeLoader");
661+ var shape = findChildsByType(artShapeLoader, "UCUbuntuShape");
662+ compare(shape.borderSource, undefined);
640 }
663 }
641 }
664 }
642 }
665 }
tests/qmltests/Stages/tst_PhoneStage.qml+19
@@ -346,6 +346,25 @@ Item {
346 tryCompare(spreadView, "contentX", -spreadView.shift)
346 tryCompare(spreadView, "contentX", -spreadView.shift)
347 }
347 }
348
348
349+ function test_cantAccessPhoneStageWhileRightEdgeGesture() {
350+ var spreadView = findChild(phoneStage, "spreadView");
351+ var eventEaterArea = findChild(phoneStage, "eventEaterArea")
352+
353+ var startX = phoneStage.width - 2;
354+ var startY = phoneStage.height / 2;
355+ var endY = startY;
356+ var endX = phoneStage.width / 2;
357+
358+ touchFlick(phoneStage, startX, startY, endX, endY,
359+ true /* beginTouch */, false /* endTouch */, units.gu(10), 50);
360+
361+ compare(eventEaterArea.enabled, true);
362+
363+ touchRelease(phoneStage, endX, endY);
364+
365+ compare(eventEaterArea.enabled, false);
366+ }
367+
349 function test_leftEdge_data() {
368 function test_leftEdge_data() {
350 return [
369 return [
351 { tag: "normal", inSpread: false, leftEdgeDragWidth: units.gu(5), shouldMoveApp: true },
370 { tag: "normal", inSpread: false, leftEdgeDragWidth: units.gu(5), shouldMoveApp: true },
tests/qmltests/Stages/tst_WindowMoveResizeArea.qml+1
@@ -70,6 +70,7 @@ Item {
70 }
70 }
71
71
72 UT.UnityTestCase {
72 UT.UnityTestCase {
73+ name: "WindowMoveResizeArea"
73 when: windowShown
74 when: windowShown
74
75
75 function init() {
76 function init() {
tests/qmltests/tst_Shell.qml+14−17
@@ -83,7 +83,7 @@ Rectangle {
83 Shell {
83 Shell {
84 property string shellMode: "full-greeter" /* default */
84 property string shellMode: "full-greeter" /* default */
85
85
86− usageScenario: "phone"
86+ usageScenario: usageScenarioSelector.model[usageScenarioSelector.selectedIndex]
87 orientation: Qt.PortraitOrientation
87 orientation: Qt.PortraitOrientation
88 primaryOrientation: Qt.PortraitOrientation
88 primaryOrientation: Qt.PortraitOrientation
89 nativeOrientation: Qt.PortraitOrientation
89 nativeOrientation: Qt.PortraitOrientation
@@ -151,14 +151,11 @@ Rectangle {
151 }
151 }
152 }
152 }
153 ListItem.ItemSelector {
153 ListItem.ItemSelector {
154− id: usageModeSelector
154+ id: usageScenarioSelector
155 anchors { left: parent.left; right: parent.right }
155 anchors { left: parent.left; right: parent.right }
156 activeFocusOnPress: false
156 activeFocusOnPress: false
157− text: "Usage mode"
157+ text: "Usage scenario"
158− model: ["Staged", "Windowed"]
158+ model: ["phone", "tablet", "desktop"]
159− onSelectedIndexChanged: {
160− GSettingsController.setUsageMode(model[selectedIndex]);
161− }
162 }
159 }
163 MouseTouchEmulationCheckbox {
160 MouseTouchEmulationCheckbox {
164 id: mouseEmulation
161 id: mouseEmulation
@@ -725,7 +722,7 @@ Rectangle {
725
722
726 tryCompare(webApp.session.surface, "activeFocus", true);
723 tryCompare(webApp.session.surface, "activeFocus", true);
727
724
728− GSettingsController.setUsageMode("Windowed");
725+ shell.usageScenario = "desktop";
729
726
730 // check that the desktop stage and window have been loaded
727 // check that the desktop stage and window have been loaded
731 {
728 {
@@ -735,7 +732,7 @@ Rectangle {
735
732
736 tryCompare(webApp.session.surface, "activeFocus", true);
733 tryCompare(webApp.session.surface, "activeFocus", true);
737
734
738− GSettingsController.setUsageMode("Staged");
735+ shell.usageScenario = "tablet";
739
736
740 // check that the tablet stage and app surface delegate have been loaded
737 // check that the tablet stage and app surface delegate have been loaded
741 {
738 {
@@ -1205,30 +1202,30 @@ Rectangle {
1205
1202
1206 function test_stageLoader_data() {
1203 function test_stageLoader_data() {
1207 return [
1204 return [
1208− {tag: "phone", source: "Stages/PhoneStage.qml", formFactor: "phone", usageMode: "Staged"},
1205+ {tag: "phone", source: "Stages/PhoneStage.qml", formFactor: "phone", usageScenario: "phone"},
1209− {tag: "tablet", source: "Stages/TabletStage.qml", formFactor: "tablet", usageMode: "Staged"},
1206+ {tag: "tablet", source: "Stages/TabletStage.qml", formFactor: "tablet", usageScenario: "tablet"},
1210− {tag: "desktop", source: "Stages/DesktopStage.qml", formFactor: "tablet", usageMode: "Windowed"}
1207+ {tag: "desktop", source: "Stages/DesktopStage.qml", formFactor: "tablet", usageScenario: "desktop"}
1211 ]
1208 ]
1212 }
1209 }
1213
1210
1214 function test_stageLoader(data) {
1211 function test_stageLoader(data) {
1215− GSettingsController.setUsageMode(data.usageMode);
1216 loadShell(data.formFactor);
1212 loadShell(data.formFactor);
1213+ shell.usageScenario = data.usageScenario;
1217 var stageLoader = findChild(shell, "applicationsDisplayLoader");
1214 var stageLoader = findChild(shell, "applicationsDisplayLoader");
1218 verify(String(stageLoader.source).indexOf(data.source) >= 0);
1215 verify(String(stageLoader.source).indexOf(data.source) >= 0);
1219 }
1216 }
1220
1217
1221 function test_launcherInverted_data() {
1218 function test_launcherInverted_data() {
1222 return [
1219 return [
1223− {tag: "phone", formFactor: "phone", usageMode: "Staged", launcherInverted: true},
1220+ {tag: "phone", formFactor: "phone", usageScenario: "phone", launcherInverted: true},
1224− {tag: "tablet", formFactor: "tablet", usageMode: "Staged", launcherInverted: true},
1221+ {tag: "tablet", formFactor: "tablet", usageScenario: "tablet", launcherInverted: true},
1225− {tag: "desktop", formFactor: "tablet", usageMode: "Windowed", launcherInverted: false}
1222+ {tag: "desktop", formFactor: "tablet", usageScenario: "desktop", launcherInverted: false}
1226 ]
1223 ]
1227 }
1224 }
1228
1225
1229 function test_launcherInverted(data) {
1226 function test_launcherInverted(data) {
1230− GSettingsController.setUsageMode(data.usageMode);
1231 loadShell(data.formFactor);
1227 loadShell(data.formFactor);
1228+ shell.usageScenario = data.usageScenario;
1232
1229
1233 var launcher = findChild(shell, "launcher");
1230 var launcher = findChild(shell, "launcher");
1234 compare(launcher.inverted, data.launcherInverted);
1231 compare(launcher.inverted, data.launcherInverted);
tests/qmltests/utils/Unity/Test/tst_UnityTest.qml+5−8
@@ -20,6 +20,8 @@ import QtTest 1.0
20import Unity.Test 0.1
20import Unity.Test 0.1
21
21
22TestCase {
22TestCase {
23+ name: "UnityTest"
24+
23 Rectangle {
25 Rectangle {
24 id: rect
26 id: rect
25 }
27 }
@@ -28,28 +30,23 @@ TestCase {
28 id: testObject
30 id: testObject
29 }
31 }
30
32
31− // Singletons need to be bound to a property and not-named-imported
32− // for them to be able to be properly passed back to C++.
33− // See https://bugreports.qt-project.org/browse/QTBUG-30730
34− property var util: Util
35−
36 function test_direct() {
33 function test_direct() {
37 compare(Util.isInstanceOf(rect, "QQuickRectangle"), true, "rect should be an instance of QQuickRectangle");
34 compare(Util.isInstanceOf(rect, "QQuickRectangle"), true, "rect should be an instance of QQuickRectangle");
38− compare(Util.isInstanceOf(util, "TestUtil"), true, "Util should be an instance of TestUtil");
35+ compare(Util.isInstanceOf(Util, "TestUtil"), true, "Util should be an instance of TestUtil");
39 compare(Util.isInstanceOf(testObject, "MockObjectForInstanceOfTestChild"), true, "testObject should be an instance of MockObjectForInstanceOfTestChild");
36 compare(Util.isInstanceOf(testObject, "MockObjectForInstanceOfTestChild"), true, "testObject should be an instance of MockObjectForInstanceOfTestChild");
40 }
37 }
41
38
42 function test_inherited() {
39 function test_inherited() {
43 compare(Util.isInstanceOf(rect, "QQuickItem"), true, "rect should be an instance of QQuickItem");
40 compare(Util.isInstanceOf(rect, "QQuickItem"), true, "rect should be an instance of QQuickItem");
44 compare(Util.isInstanceOf(rect, "QObject"), true, "rect should be an instance of QObject");
41 compare(Util.isInstanceOf(rect, "QObject"), true, "rect should be an instance of QObject");
45− compare(Util.isInstanceOf(util, "QObject"), true, "Util should be an instance of QObject");
42+ compare(Util.isInstanceOf(Util, "QObject"), true, "Util should be an instance of QObject");
46 compare(Util.isInstanceOf(testObject, "MockObjectForInstanceOfTest"), true, "testObject should be an instance of MockObjectForInstanceOfTest");
43 compare(Util.isInstanceOf(testObject, "MockObjectForInstanceOfTest"), true, "testObject should be an instance of MockObjectForInstanceOfTest");
47 compare(Util.isInstanceOf(testObject, "QQuickRectangle"), true, "testObject should be an instance of QQuickRectangle");
44 compare(Util.isInstanceOf(testObject, "QQuickRectangle"), true, "testObject should be an instance of QQuickRectangle");
48 }
45 }
49
46
50 function test_negative() {
47 function test_negative() {
51 compare(Util.isInstanceOf(rect, "QQuickMouseArea"), false, "rect should not be an instance of MouseArea");
48 compare(Util.isInstanceOf(rect, "QQuickMouseArea"), false, "rect should not be an instance of MouseArea");
52− compare(Util.isInstanceOf(util, "QQuickItem"), false, "Util should not be an instance of QQuickItem");
49+ compare(Util.isInstanceOf(Util, "QQuickItem"), false, "Util should not be an instance of QQuickItem");
53 }
50 }
54
51
55 function test_undefined() {
52 function test_undefined() {
tests/utils/modules/Unity/Test/UnityTestCase.qml+2−1
@@ -26,6 +26,7 @@ TestCase {
26 // This is needed for waitForRendering calls to return
26 // This is needed for waitForRendering calls to return
27 // if the watched element already got rendered
27 // if the watched element already got rendered
28 Rectangle {
28 Rectangle {
29+ id: rotatingRectangle
29 width: units.gu(1)
30 width: units.gu(1)
30 height: width
31 height: width
31 parent: testCase.parent
32 parent: testCase.parent
@@ -35,7 +36,7 @@ TestCase {
35 visible: testCase.running
36 visible: testCase.running
36
37
37 RotationAnimation on rotation {
38 RotationAnimation on rotation {
38− running: parent.visible
39+ running: rotatingRectangle.visible
39 from: 0
40 from: 0
40 to: 360
41 to: 360
41 loops: Animation.Infinite
42 loops: Animation.Infinite
tests/whitespace/CMakeLists.txt+1−1
@@ -2,4 +2,4 @@
2# Test that all source files, cmakefiles, etc. do not contain trailing whitespace.
2# Test that all source files, cmakefiles, etc. do not contain trailing whitespace.
3#
3#
4
4
5−add_test(whitespace ${CMAKE_CURRENT_SOURCE_DIR}/check_whitespace.py ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR})
5+add_test(Whitespace ${CMAKE_CURRENT_SOURCE_DIR}/check_whitespace.py ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR})