@@ -1,423 +0,0 @@
2− * Copyright 2014-2016 Canonical Ltd.
4− * This program is free software; you can redistribute it and/or modify
5− * it under the terms of the GNU General Public License as published by
6− * the Free Software Foundation; version 3.
8− * This program is distributed in the hope that it will be useful,
9− * but WITHOUT ANY WARRANTY; without even the implied warranty of
10− * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11− * GNU General Public License for more details.
13− * You should have received a copy of the GNU General Public License
14− * along with this program. If not, see <http://www.gnu.org/licenses/>.
19−import Unity.Test 0.1 as UT
21−import "../../../qml/Components"
22−import "../../../qml/Stages"
23−import Ubuntu.Components 1.3
24−import Ubuntu.Components.ListItems 1.3 as ListItem
25−import Unity.Application 0.1
30− width: fakeShell.shortestDimension + controls.width
31− height: fakeShell.longestDimension
33− property QtObject fakeApplication: null
38− readonly property real shortestDimension: units.gu(40)
39− readonly property real longestDimension: units.gu(70)
41− width: landscape ? longestDimension : shortestDimension
42− height: landscape ? shortestDimension : longestDimension
44− x: landscape ? (height - width) / 2 : 0
45− y: landscape ? (width - height) / 2 : 0
47− property bool landscape: orientationAngle == 90 || orientationAngle == 270
48− property int orientationAngle: shellOrientationAngleSelector.value
50− rotation: orientationAngle
53− id: spreadDelegateLoader
55− height: parent.height
58− property bool itemDestroyed: false
59− sourceComponent: SpreadDelegate {
61− swipeToCloseEnabled: swipeToCloseCheckbox.checked
62− closeable: closeableCheckbox.checked
63− application: fakeApplication
64− surface: fakeApplication && fakeApplication.surfaceList.count > 0 ? fakeApplication.surfaceList.get(0) : null
65− shellOrientationAngle: shellOrientationAngleSelector.value
67− switch (shellOrientationAngleSelector.value) {
69− return Qt.PortraitOrientation;
71− return Qt.InvertedLandscapeOrientation;
73− return Qt.InvertedPortraitOrientation;
75− return Qt.LandscapeOrientation;
79− orientations: Orientations {
80− // the default values will do
83− maximizedAppTopMargin: units.gu(3)
84− Component.onDestruction: {
85− spreadDelegateLoader.itemDestroyed = true;
87− Component.onCompleted: {
88− spreadDelegateLoader.itemDestroyed = false;
97− x: fakeShell.shortestDimension
101− bottom: parent.bottom
105− anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
106− spacing: units.gu(1)
108− id: loadWithWeatherApp
109− text: "Load with ubuntu-weather-app"
110− onClicked: { testCase.restartWithApp("ubuntu-weather-app"); }
113− id: loadWithGalleryApp
114− text: "Load with gallery-app"
115− onClicked: { testCase.restartWithApp("gallery-app"); }
118− anchors { left: parent.left; right: parent.right }
119− CheckBox { id: swipeToCloseCheckbox; checked: false; }
120− Label { text: "swipeToCloseEnabled" }
123− anchors { left: parent.left; right: parent.right }
124− CheckBox { id: closeableCheckbox; checked: false }
125− Label { text: "closeable" }
127− ListItem.ItemSelector {
128− id: shellOrientationAngleSelector
129− anchors { left: parent.left; right: parent.right }
130− text: "shellOrientationAngle"
131− model: ["0", "90", "180", "270"]
132− property int value: selectedIndex * 90
135− id: matchShellButton
136− text: "matchShellOrientation()"
137− onClicked: { spreadDelegateLoader.item.matchShellOrientation(); }
140− id: animateToShellButton
141− text: "animateToShellOrientation()"
142− onClicked: { spreadDelegateLoader.item.animateToShellOrientation(); }
149− name: "SpreadDelegate"
154− target: spreadDelegateLoader.item
155− signalName: "closed"
158− property var dragArea
159− property Item spreadDelegate: spreadDelegateLoader.item
164− function cleanup() {
165− unloadSpreadDelegate();
166− spyClosedSignal.clear();
167− shellOrientationAngleSelector.selectedIndex = 0;
168− root.fakeApplication = null;
172− function restartWithApp(appId) {
173− if (spreadDelegateLoader.active) {
174− unloadSpreadDelegate();
176− if (root.fakeApplication) {
177− ApplicationManager.stopApplication(root.fakeApplication.appId);
180− root.fakeApplication = ApplicationManager.startApplication(appId);
181− spreadDelegateLoader.active = true;
182− tryCompare(spreadDelegateLoader, "status", Loader.Ready);
184− dragArea = findInvisibleChild(spreadDelegate, "dragArea");
185− dragArea.__dateTime = fakeDateTime;
188− function unloadSpreadDelegate() {
189− spreadDelegateLoader.active = false;
190− tryCompare(spreadDelegateLoader, "status", Loader.Null);
191− tryCompare(spreadDelegateLoader, "item", null);
192− // Loader.status might be Loader.Null and Loader.item might be null but the Loader
193− // item might still be alive. So if we set Loader.active back to true
194− // again right now we will get the very same Shell instance back. So no reload
195− // actually took place. Likely because Loader waits until the next event loop
196− // iteration to do its work. So to ensure the reload, we will wait until the
197− // Shell instance gets destroyed.
198− tryCompare(spreadDelegateLoader, "itemDestroyed", true);
202− function waitUntilAppWindowIsFullyLoaded() {
203− var appWindowStateGroup = findInvisibleChild(spreadDelegate, "applicationWindowStateGroup");
204− tryCompareFunction(function() { return appWindowStateGroup.state === "surface" }, true);
205− waitUntilTransitionsEnd(appWindowStateGroup);
207− var priv = findInvisibleChild(spreadDelegate, "spreadDelegatePriv");
209− tryCompare(priv, "startingUp", false);
212− function rotateShellTo(angle) {
213− shellOrientationAngleSelector.selectedIndex = angle / 90;
216− function waitUntilRotationAnimationStops() {
217− var orientationChangeAnimation = findInvisibleChild(spreadDelegate, "orientationChangeAnimation");
218− verify(orientationChangeAnimation);
219− tryCompare(orientationChangeAnimation, "running", false);
222− function checkAppWindowTransformationMatchesRotation(appWindow, angle) {
226− var bottomRightX = 0;
227− var bottomRightY = 0;
233− bottomRightX = fakeShell.shortestDimension;
234− bottomRightY = fakeShell.longestDimension;
237− topLeftX = fakeShell.shortestDimension;
240− bottomRightY = fakeShell.longestDimension;
243− // TODO implement 180 and 270 once we need them
247− var appWindowTopLeftInRootCoords = appWindow.mapToItem(root, 0, 0);
249− if (appWindowTopLeftInRootCoords.x !== topLeftX) {
250− qtest_fail("appWindow topLeft.x ("+appWindowTopLeftInRootCoords.x+")"
251− +" doesn't match expectations ("+topLeftX+").", 1);
253− if (appWindowTopLeftInRootCoords.y !== topLeftY) {
254− qtest_fail("appWindow topLeft.y ("+appWindowTopLeftInRootCoords.y+")"
255− +" doesn't match expectations ("+topLeftY+").", 1);
258− var appWindowBottomRightInRootCoords = appWindow.mapToItem(root, appWindow.width,
260− compare(appWindowBottomRightInRootCoords.x, bottomRightX);
261− compare(appWindowBottomRightInRootCoords.y, bottomRightY);
263− if (appWindowBottomRightInRootCoords.x !== bottomRightX) {
264− qtest_fail("appWindow bottomRight.x ("+appWindowBottomRightInRootCoords.x+")"
265− +" doesn't match expectations ("+bottomRightX+").", 1);
267− if (appWindowBottomRightInRootCoords.y !== bottomRightY) {
268− qtest_fail("appWindow bottomRight.y ("+appWindowBottomRightInRootCoords.y+")"
269− +" doesn't match expectations ("+bottomRightY+").", 1);
273− function test_swipeToClose_data() {
275− {tag: "swipeToClose=true closeable=true -> appWindow moves away",
276− swipeToClose: true, closeable: true },
278− {tag: "swipeToClose=true closeable=false -> appWindow bounces back",
279− swipeToClose: true, closeable: false },
281− {tag: "swipeToClose=false -> appWindow stays put",
282− swipeToClose: false, closeable: true },
286− function test_swipeToClose(data) {
287− loadWithGalleryApp.clicked();
288− var displacedAppWindowWithShadow = findChild(spreadDelegateLoader.item, "displacedAppWindowWithShadow");
290− verify(displacedAppWindowWithShadow.y === 0);
292− swipeToCloseCheckbox.checked = data.swipeToClose;
293− closeableCheckbox.checked = data.closeable;
295− var dragDistance = spreadDelegateLoader.item.height * 0.8;
296− var touchX = spreadDelegateLoader.item.width / 2;
297− var fromY = spreadDelegateLoader.item.height * 0.9;
298− var toY = fromY - dragDistance;
299− touchFlick(spreadDelegateLoader.item,
300− touchX /* fromX */, fromY, touchX /* toX */, toY,
301− true /* beginTouch */, false /* endTouch */, dragArea.minSpeedToClose * 1.1 /* speed */);
303− if (data.swipeToClose) {
304− verify(displacedAppWindowWithShadow.y < 0);
305− var threshold = findChild(spreadDelegateLoader.item, "dragArea").threshold
306− if (data.closeable) {
307− // Verify that the delegate started moving exactly "threshold" after the finger movement
308− // and did not jump up to the finger, but lags the threshold behind
309− compare(Math.abs(Math.abs(displacedAppWindowWithShadow.y) - dragDistance), threshold);
311− verify(Math.abs(Math.abs(displacedAppWindowWithShadow.y) - dragDistance) > threshold);
314− touchRelease(spreadDelegateLoader.item, touchX, toY - units.gu(1));
316− waitForCloseAnimationToFinish();
318− if (data.closeable) {
319− verify(spyClosedSignal.count === 1);
321− verify(spyClosedSignal.count === 0);
322− tryCompare(displacedAppWindowWithShadow, "y", 0);
326− verify(displacedAppWindowWithShadow.y === 0);
328− touchRelease(spreadDelegateLoader.item, touchX, toY);
332− function test_loadingLandscapeOnlyAppWhenShellInPortrait() {
333− loadWithWeatherApp.clicked();
335− var appWindow = findChild(spreadDelegate, "appWindow");
338− // It must have landscape dimensions as it does not support portrait
339− tryCompare(appWindow, "width", fakeShell.height);
340− tryCompare(appWindow, "height", fakeShell.width - spreadDelegate.maximizedAppTopMargin);
343− function test_keepsSceneTransformationWhenShellRotates_data() {
345− {tag: "0", selectedIndex: 0},
346− {tag: "90", selectedIndex: 1},
347− {tag: "180", selectedIndex: 2},
348− {tag: "270", selectedIndex: 3}
351− function test_keepsSceneTransformationWhenShellRotates(data) {
352− loadWithGalleryApp.clicked();
354− waitUntilAppWindowIsFullyLoaded();
356− var appWindowWithShadow = findChild(spreadDelegate, "appWindowWithShadow");
357− verify(appWindowWithShadow);
359− compare(appWindowWithShadow.state, "keepSceneRotation");
361− shellOrientationAngleSelector.selectedIndex = data.selectedIndex;
363− // must keep same aspect ratio
364− compare(appWindowWithShadow.width, fakeShell.shortestDimension);
365− compare(appWindowWithShadow.height, fakeShell.longestDimension);
368− // and scene transformation must be the identity (ie, no rotation or translation)
369− checkAppWindowTransformationMatchesRotation(appWindowWithShadow, 0);
372− function waitForCloseAnimationToFinish() {
373− var closeAnimation = findInvisibleChild(spreadDelegateLoader.item, "closeAnimation");
374− wait(closeAnimation.duration * 1.5);
375− tryCompare(closeAnimation, "running", false);
378− function test_showHighLight() {
379− loadWithGalleryApp.clicked();
380− var highlightRect = findChild(spreadDelegateLoader.item, "selectionHighlight")
381− tryCompare(highlightRect, "visible", false)
382− spreadDelegateLoader.item.highlightShown = true;
383− tryCompare(highlightRect, "visible", true)
387− Checks that the ApplicationWindow position, size and rotation is correct after
388− a sequence of shell rotations folowed by rotations (immediate or not) to match them
390− function test_animateToShellThenMatchShell() {
391− loadWithGalleryApp.clicked();
392− waitUntilAppWindowIsFullyLoaded();
394− var appWindowWithShadow = findChild(spreadDelegate, "appWindowWithShadow");
395− verify(appWindowWithShadow);
397− // appWindow transformation is 0 relative to display
398− checkAppWindowTransformationMatchesRotation(appWindowWithShadow, 0);
402− // appWindow transformation remains 0 relative to display
403− checkAppWindowTransformationMatchesRotation(appWindowWithShadow, 0);
405− animateToShellButton.clicked();
406− waitUntilRotationAnimationStops();
408− // appWindow transformation is now 90 relative to display, just like shell
409− checkAppWindowTransformationMatchesRotation(appWindowWithShadow, 90);
413− // appWindow transformation is remains 90 relative to display.
414− checkAppWindowTransformationMatchesRotation(appWindowWithShadow, 90);
416− matchShellButton.clicked();
418− // appWindow transformation is back to 0 relative to display, just like shell
419− checkAppWindowTransformationMatchesRotation(appWindowWithShadow, 0);