on xenial help sign in
Add better test support
f5acba4Michael Terry
tests/mocks/MeeGo/QOfono/CMakeLists.txt+1
@@ -1,6 +1,7 @@
1set(MOCK_QOFONO_SOURCES
1set(MOCK_QOFONO_SOURCES
2 plugin.cpp
2 plugin.cpp
3 MockQOfono.cpp
3 MockQOfono.cpp
4+ MockQOfonoManager.cpp
4)
5)
5
6
6add_library(MockQOfono MODULE ${MOCK_QOFONO_SOURCES})
7add_library(MockQOfono MODULE ${MOCK_QOFONO_SOURCES})
tests/mocks/MeeGo/QOfono/MockOfonoManager.qmldeleted−23
@@ -1,23 +0,0 @@
1−/*
2− * Copyright (C) 2014 Canonical, Ltd.
3− *
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.
7− *
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.
12− *
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/>.
15− */
16−
17−import QtQuick 2.3
18−import MeeGo.QOfono 0.2
19−
20−Item {
21− readonly property var modems: MockQOfono.modems
22− readonly property bool available: MockQOfono.available
23−}
tests/mocks/MeeGo/QOfono/MockOfonoSimManager.qml+12−2
@@ -22,21 +22,31 @@ Item {
22
22
23 property string modemPath
23 property string modemPath
24 readonly property alias present: d.present
24 readonly property alias present: d.present
25+ readonly property alias ready: d.ready
25
26
26 QtObject {
27 QtObject {
27 id: d
28 id: d
28
29
29 property bool present: false
30 property bool present: false
31+ property bool ready: false
30
32
31 function updatePresence() {
33 function updatePresence() {
32 d.present = MockQOfono.isModemPresent(simManager.modemPath)
34 d.present = MockQOfono.isModemPresent(simManager.modemPath)
35+ d.ready = MockQOfono.isModemReady(simManager.modemPath);
33 }
36 }
34 }
37 }
35
38
39+ // Simulate QOfono's asynchronous initialization
40+ Timer {
41+ id: asyncTimer
42+ interval: 1
36− onModemPathChanged: d.updatePresence()
43+ onTriggered: d.updatePresence()
44+ }
45+
46+ onModemPathChanged: asyncTimer.start()
37
47
38 Connections {
48 Connections {
39 target: MockQOfono
49 target: MockQOfono
40− onModemsChanged: d.updatePresence()
50+ onModemsChanged: asyncTimer.start()
41 }
51 }
42}
52}
tests/mocks/MeeGo/QOfono/MockQOfono.cpp+41−5
@@ -16,13 +16,31 @@
16
16
17#include "MockQOfono.h"
17#include "MockQOfono.h"
18
18
19−MockQOfono::MockQOfono(QObject *parent)
19+static MockQOfono *m_instance = nullptr;
20+
21+MockQOfono *MockQOfono::instance()
22+{
23+ if (!m_instance) {
24+ m_instance = new MockQOfono();
25+ }
26+ return m_instance;
27+}
28+
29+MockQOfono::MockQOfono()
20− : QObject(parent),
30+ : QObject(),
21 m_available(false),
31 m_available(false),
32+ m_ready(false),
22 m_modems()
33 m_modems()
23{
34{
24}
35}
25
36
37+MockQOfono::~MockQOfono()
38+{
39+ if (m_instance == this) {
40+ m_instance = nullptr;
41+ }
42+}
43+
26bool MockQOfono::available() const
44bool MockQOfono::available() const
27{
45{
28 return m_available;
46 return m_available;
@@ -34,21 +52,39 @@ void MockQOfono::setAvailable(bool available)
34 Q_EMIT availableChanged();
52 Q_EMIT availableChanged();
35}
53}
36
54
55+bool MockQOfono::ready() const
56+{
57+ return m_ready;
58+}
59+
60+void MockQOfono::setReady(bool ready)
61+{
62+ m_ready = ready;
63+ Q_EMIT readyChanged();
64+}
65+
37QStringList MockQOfono::modems() const
66QStringList MockQOfono::modems() const
38{
67{
39 return m_modems.keys();
68 return m_modems.keys();
40}
69}
41
70
42−void MockQOfono::setModems(const QStringList &modems, const QList<bool> &present)
71+void MockQOfono::setModems(const QStringList &modems, const QList<bool> &present, const QList<bool> &ready)
43{
72{
44 m_modems.clear();
73 m_modems.clear();
45 for (int i = 0; i < modems.length(); i++) {
74 for (int i = 0; i < modems.length(); i++) {
75+ QList<bool> props;
76+ props << present.value(i, true) << ready.value(i, true);
46− m_modems[modems[i]] = present[i];
77+ m_modems[modems[i]] = props;
47 }
78 }
48 Q_EMIT modemsChanged();
79 Q_EMIT modemsChanged();
49}
80}
50
81
51bool MockQOfono::isModemPresent(const QString &modem)
82bool MockQOfono::isModemPresent(const QString &modem)
52{
83{
53− return m_modems.value(modem, false);
84+ return m_modems.value(modem).value(0, false);
85+}
86+
87+bool MockQOfono::isModemReady(const QString &modem)
88+{
89+ return m_modems.value(modem).value(1, false);
54}
90}
tests/mocks/MeeGo/QOfono/MockQOfono.h+12−3
@@ -28,25 +28,34 @@ class MockQOfono : public QObject
28{
28{
29 Q_OBJECT
29 Q_OBJECT
30 Q_PROPERTY(bool available READ available WRITE setAvailable NOTIFY availableChanged)
30 Q_PROPERTY(bool available READ available WRITE setAvailable NOTIFY availableChanged)
31+ Q_PROPERTY(bool ready READ ready WRITE setReady NOTIFY readyChanged)
31 Q_PROPERTY(QStringList modems READ modems NOTIFY modemsChanged)
32 Q_PROPERTY(QStringList modems READ modems NOTIFY modemsChanged)
32
33
33public:
34public:
34− explicit MockQOfono(QObject *parent = 0);
35+ static MockQOfono *instance();
36+ ~MockQOfono();
35
37
36 bool available() const;
38 bool available() const;
37 void setAvailable(bool available);
39 void setAvailable(bool available);
40+ bool ready() const;
41+ void setReady(bool ready);
38 QStringList modems() const;
42 QStringList modems() const;
39
43
40− Q_INVOKABLE void setModems(const QStringList &modems, const QList<bool> &present);
44+ Q_INVOKABLE void setModems(const QStringList &modems, const QList<bool> &present, const QList<bool> &ready);
41 Q_INVOKABLE bool isModemPresent(const QString &modem);
45 Q_INVOKABLE bool isModemPresent(const QString &modem);
46+ Q_INVOKABLE bool isModemReady(const QString &modem);
42
47
43Q_SIGNALS:
48Q_SIGNALS:
44 void availableChanged();
49 void availableChanged();
50+ void readyChanged();
45 void modemsChanged();
51 void modemsChanged();
46
52
47private:
53private:
54+ explicit MockQOfono();
55+
48 bool m_available;
56 bool m_available;
57+ bool m_ready;
49− QMap<QString, bool> m_modems;
58+ QMap<QString, QList<bool>> m_modems;
50};
59};
51
60
52#endif // MOCK_QOFONO_H
61#endif // MOCK_QOFONO_H
tests/mocks/MeeGo/QOfono/MockQOfonoManager.cppnew file+66
@@ -0,0 +1,66 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
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.
7+ *
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.
12+ *
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/>.
15+ */
16+
17+#include "MockQOfono.h"
18+#include "MockQOfonoManager.h"
19+#include <QTimer>
20+
21+MockQOfonoManager::MockQOfonoManager(QObject *parent)
22+ : QObject(parent),
23+ m_modemsSet(false),
24+ m_startedSet(false)
25+{
26+ connect(MockQOfono::instance(), SIGNAL(availableChanged()),
27+ this, SIGNAL(availableChanged()));
28+ connect(MockQOfono::instance(), SIGNAL(readyChanged()),
29+ this, SLOT(checkReady()));
30+ connect(MockQOfono::instance(), SIGNAL(modemsChanged()),
31+ this, SLOT(maybeModemsChanged()));
32+
33+ checkReady();
34+}
35+
36+bool MockQOfonoManager::available() const
37+{
38+ return MockQOfono::instance()->available();
39+}
40+
41+QStringList MockQOfonoManager::modems() const
42+{
43+ return m_modemsSet ? MockQOfono::instance()->modems() : QStringList();
44+}
45+
46+void MockQOfonoManager::maybeModemsChanged()
47+{
48+ if (m_modemsSet) {
49+ Q_EMIT modemsChanged();
50+ }
51+}
52+
53+void MockQOfonoManager::checkReady()
54+{
55+ if (!m_startedSet && MockQOfono::instance()->ready()) {
56+ m_startedSet = true;
57+ // Simulate QOfono's asynchronous initialization
58+ QTimer::singleShot(1, this, SLOT(setModems()));
59+ }
60+}
61+
62+void MockQOfonoManager::setModems()
63+{
64+ m_modemsSet = true;
65+ Q_EMIT modemsChanged(); // always emitted, even if new modem list is empty too
66+}
tests/mocks/MeeGo/QOfono/MockQOfonoManager.hnew file+49
@@ -0,0 +1,49 @@
1+/*
2+ * Copyright (C) 2015 Canonical, Ltd.
3+ *
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.
7+ *
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.
12+ *
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/>.
15+ */
16+
17+#ifndef MOCK_QOFONO_MANAGER_H
18+#define MOCK_QOFONO_MANAGER_H
19+
20+#include <QObject>
21+#include <QStringList>
22+
23+class MockQOfonoManager : public QObject
24+{
25+ Q_OBJECT
26+ Q_PROPERTY(bool available READ available NOTIFY availableChanged)
27+ Q_PROPERTY(QStringList modems READ modems NOTIFY modemsChanged)
28+
29+public:
30+ explicit MockQOfonoManager(QObject *parent = 0);
31+
32+ bool available() const;
33+ QStringList modems() const;
34+
35+Q_SIGNALS:
36+ void availableChanged();
37+ void modemsChanged();
38+
39+private Q_SLOTS:
40+ void maybeModemsChanged();
41+ void checkReady();
42+ void setModems();
43+
44+private:
45+ bool m_modemsSet;
46+ bool m_startedSet;
47+};
48+
49+#endif // MOCK_QOFONO_MANAGER_H
tests/mocks/MeeGo/QOfono/plugin.cpp+3−1
@@ -16,6 +16,7 @@
16
16
17#include "plugin.h"
17#include "plugin.h"
18#include "MockQOfono.h"
18#include "MockQOfono.h"
19+#include "MockQOfonoManager.h"
19
20
20#include <QtQml>
21#include <QtQml>
21
22
@@ -23,11 +24,12 @@ static QObject *mock_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
23{
24{
24 Q_UNUSED(engine)
25 Q_UNUSED(engine)
25 Q_UNUSED(scriptEngine)
26 Q_UNUSED(scriptEngine)
26− return new MockQOfono();
27+ return MockQOfono::instance();
27}
28}
28
29
29void BackendPlugin::registerTypes(const char *uri)
30void BackendPlugin::registerTypes(const char *uri)
30{
31{
31 Q_ASSERT(uri == QLatin1String("MeeGo.QOfono"));
32 Q_ASSERT(uri == QLatin1String("MeeGo.QOfono"));
32 qmlRegisterSingletonType<MockQOfono>(uri, 0, 2, "MockQOfono", mock_provider); // just for mock
33 qmlRegisterSingletonType<MockQOfono>(uri, 0, 2, "MockQOfono", mock_provider); // just for mock
34+ qmlRegisterType<MockQOfonoManager>(uri, 0, 2, "OfonoManager");
33}
35}
tests/mocks/MeeGo/QOfono/qmldir−1
@@ -1,4 +1,3 @@
1module MeeGo.QOfono
1module MeeGo.QOfono
2plugin MockQOfono
2plugin MockQOfono
3−OfonoManager 0.2 MockOfonoManager.qml
4OfonoSimManager 0.2 MockOfonoSimManager.qml
3OfonoSimManager 0.2 MockOfonoSimManager.qml
tests/qmltests/Wizard/tst_Wizard.qml+48−5
@@ -73,8 +73,9 @@ Item {
73 AccountsService.hereEnabled = false;
73 AccountsService.hereEnabled = false;
74 AccountsService.hereLicensePath = Qt.resolvedUrl("licenses");
74 AccountsService.hereLicensePath = Qt.resolvedUrl("licenses");
75 i18n.language = "en";
75 i18n.language = "en";
76− MockQOfono.setModems(["sim1"], [false]);
76+ MockQOfono.setModems(["sim1"], [false], []);
77 MockQOfono.available = true;
77 MockQOfono.available = true;
78+ MockQOfono.ready = true;
78 System.wizardEnabled = true;
79 System.wizardEnabled = true;
79
80
80 updateSessionLanguageSpy.clear();
81 updateSessionLanguageSpy.clear();
@@ -140,6 +141,19 @@ Item {
140 tryCompareFunction(function() { return stack.currentPage.objectName; }, name);
141 tryCompareFunction(function() { return stack.currentPage.objectName; }, name);
141 tryCompare(stack.currentPage, "opacity", 1.0);
142 tryCompare(stack.currentPage, "opacity", 1.0);
142 tryCompare(stack.currentPage, "enabled", true);
143 tryCompare(stack.currentPage, "enabled", true);
144+ tryCompare(stack.currentPage, "skipValid", true);
145+ tryCompare(stack.currentPage, "skip", false);
146+ waitForRendering(stack.currentPage);
147+ return stack.currentPage;
148+ }
149+
150+ function verifyPageIsBlocked(name) {
151+ var pages = findChild(wizard, "wizardPages");
152+ var stack = findChild(pages, "pageStack");
153+ // don't simply call tryCompare here, because stack.currentPage will be swapped out itself
154+ tryCompareFunction(function() { return stack.currentPage.objectName; }, name);
155+ tryCompare(stack.currentPage, "enabled", false);
156+ tryCompare(stack.currentPage, "skipValid", false);
143 waitForRendering(stack.currentPage);
157 waitForRendering(stack.currentPage);
144 return stack.currentPage;
158 return stack.currentPage;
145 }
159 }
@@ -223,25 +237,54 @@ Item {
223 }
237 }
224
238
225 function test_simNoModemsSkip() {
239 function test_simNoModemsSkip() {
226− MockQOfono.setModems([], []);
240+ MockQOfono.setModems([], [], []);
227 goToPage("passwdPage", true);
241 goToPage("passwdPage", true);
228 }
242 }
229
243
230 function test_simFirstSkip() {
244 function test_simFirstSkip() {
231− MockQOfono.setModems(["a", "b"], [true, false]);
245+ MockQOfono.setModems(["a", "b"], [true, false], []);
232 goToPage("passwdPage", true);
246 goToPage("passwdPage", true);
233 }
247 }
234
248
235 function test_simSecondSkip() {
249 function test_simSecondSkip() {
236− MockQOfono.setModems(["a", "b"], [false, true]);
250+ MockQOfono.setModems(["a", "b"], [false, true], []);
237 goToPage("passwdPage", true);
251 goToPage("passwdPage", true);
238 }
252 }
239
253
240 function test_simBothSkip() {
254 function test_simBothSkip() {
241− MockQOfono.setModems(["a", "b"], [true, true]);
255+ MockQOfono.setModems(["a", "b"], [true, true], []);
242 goToPage("passwdPage", true);
256 goToPage("passwdPage", true);
243 }
257 }
244
258
259+ function test_simWaitOnManagerAsync() {
260+ MockQOfono.ready = false;
261+ MockQOfono.setModems(["a"], [false], []);
262+
263+ // Go to SIM page, which will be waiting for skip to be valid
264+ var page = goToPage("languagePage");
265+ tap(findChild(page, "forwardButton"));
266+ verifyPageIsBlocked("simPage");
267+
268+ // Now release QOfono from blocking the page
269+ MockQOfono.ready = true;
270+
271+ waitForPage("simPage");
272+ }
273+
274+ function test_simWaitOnCardAsync() {
275+ MockQOfono.setModems(["a"], [false], [false]);
276+
277+ // Go to SIM page, which will be waiting for skip to be valid
278+ var page = goToPage("languagePage");
279+ tap(findChild(page, "forwardButton"));
280+ verifyPageIsBlocked("simPage");
281+
282+ // Now release QOfono from blocking the page
283+ MockQOfono.setModems(["a"], [false], [true]);
284+
285+ waitForPage("simPage");
286+ }
287+
245 function enterPasscode(passcode) {
288 function enterPasscode(passcode) {
246 for (var i = 0; i < passcode.length; ++i) {
289 for (var i = 0; i < passcode.length; ++i) {
247 var character = passcode.charAt(i);
290 var character = passcode.charAt(i);