on xenial help sign in
Started writing test for search indicator.
commiteb5de7fe6a6624b96d019e9e7f71859925a236f5 authorNicolas d'Offay <nicolas.doffay@canonical.com> dateMon 30 Sep 2013, 14:59 (13 years ago) parent4d5bcae366698d
5 files changed+175−136
plugins/Unity/scope.cpp+30−5 plugins/Unity/scope.h+7−2 tests/mocks/Unity/fake_scope.cpp+6 tests/mocks/Unity/fake_scope.h+4−1 tests/qmltests/Components/tst_PageHeader.qml+128−128
plugins/Unity/scope.cpp+30−5
@@ -33,12 +33,14 @@
3333#include <QQmlEngine>
3434
3535#include <UnityCore/Variant.h>
36+#include <UnityCore/GLibWrapper.h>
3637
3738#include <libintl.h>
3839#include <glib.h>
3940
4041Scope::Scope(QObject *parent) : QObject(parent)
4142 , m_formFactor("phone")
43+ , m_searchInProgress(false)
4244{
4345 m_categories.reset(new Categories(this));
4446}
@@ -68,6 +70,11 @@ QString Scope::searchHint() const
6870 return QString::fromStdString(m_unityScope->search_hint());
6971}
7072
73+bool Scope::searchInProgress() const
74+{
75+ return m_searchInProgress;
76+}
77+
7178bool Scope::visible() const
7279{
7380 return m_unityScope->visible();
@@ -115,10 +122,15 @@ void Scope::setSearchQuery(const QString& search_query)
115122 string ("") and m_searchQuery is the null string,
116123 search_query != m_searchQuery is still true.
117124 */
125+ using namespace std::placeholders;
126+
118127 if (m_searchQuery.isNull() || search_query != m_searchQuery) {
119128 m_searchQuery = search_query;
120− m_unityScope->Search(search_query.toStdString(), sigc::mem_fun(this, &Scope::searchFinished));
129+ m_cancellable.Renew();
130+ m_searchInProgress = true;
131+ m_unityScope->Search(search_query.toStdString(), std::bind(&Scope::onSearchFinished, this, _1, _2, _3), m_cancellable);
121132 Q_EMIT searchQueryChanged();
133+ Q_EMIT searchInProgressChanged();
122134 }
123135}
124136
@@ -294,8 +306,6 @@ void Scope::setUnityScope(const unity::dash::Scope::Ptr& scope)
294306 m_unityScope->visible.changed.connect(sigc::mem_fun(this, &Scope::visibleChanged));
295307 m_unityScope->shortcut.changed.connect(sigc::mem_fun(this, &Scope::shortcutChanged));
296308 m_unityScope->connected.changed.connect(sigc::mem_fun(this, &Scope::connectedChanged));
297− /* Signals forwarding */
298− connect(this, SIGNAL(searchFinished(const std::string &, unity::glib::HintsMap const &, unity::glib::Error const &)), SLOT(onSearchFinished(const std::string &, unity::glib::HintsMap const &)));
299309
300310 /* FIXME: signal should be forwarded instead of calling the handler directly */
301311 m_unityScope->activated.connect(sigc::mem_fun(this, &Scope::onActivated));
@@ -316,18 +326,33 @@ unity::dash::Scope::Ptr Scope::unityScope() const
316326
317327void Scope::synchronizeStates()
318328{
329+ using namespace std::placeholders;
330+
319331 if (connected()) {
320332 /* Forward local states to m_unityScope */
321333 if (!m_searchQuery.isNull()) {
322− m_unityScope->Search(m_searchQuery.toStdString());
334+ m_cancellable.Renew();
335+ m_searchInProgress = true;
336+ m_unityScope->Search(m_searchQuery.toStdString(), std::bind(&Scope::onSearchFinished, this, _1, _2, _3), m_cancellable);
337+ Q_EMIT searchInProgressChanged();
323338 }
324339 }
325340}
326341
327−void Scope::onSearchFinished(const std::string& /* query */, unity::glib::HintsMap const &hints)
342+void Scope::onSearchFinished(std::string const& /* query */, unity::glib::HintsMap const& hints, unity::glib::Error const& err)
328343{
329344 QString hint;
330345
346+ GError* error = const_cast<unity::glib::Error&>(err);
347+
348+ if (!err || !g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
349+ m_searchInProgress = false;
350+ Q_EMIT searchInProgressChanged();
351+ } else {
352+ // no need to check the results hint, we're still searching
353+ return;
354+ }
355+
331356 if (!m_unityScope->results()->count()) {
332357 unity::glib::HintsMap::const_iterator it = hints.find("no-results-hint");
333358 if (it != hints.end()) {
plugins/Unity/scope.h+7−2
@@ -28,6 +28,7 @@
2828// libunity-core
2929#include <UnityCore/Scope.h>
3030#include <UnityCore/Results.h>
31+#include <UnityCore/GLibWrapper.h>
3132
3233#include "categories.h"
3334#include "filters.h"
@@ -43,6 +44,7 @@ class Scope : public QObject
4344 Q_PROPERTY(QString iconHint READ iconHint NOTIFY iconHintChanged)
4445 Q_PROPERTY(QString description READ description NOTIFY descriptionChanged)
4546 Q_PROPERTY(QString searchHint READ searchHint NOTIFY searchHintChanged)
47+ Q_PROPERTY(bool searchInProgress READ searchInProgress NOTIFY searchInProgressChanged)
4648 Q_PROPERTY(bool visible READ visible NOTIFY visibleChanged)
4749 Q_PROPERTY(QString shortcut READ shortcut NOTIFY shortcutChanged)
4850 Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
@@ -65,6 +67,7 @@ public:
6567 bool visible() const;
6668 QString shortcut() const;
6769 bool connected() const;
70+ bool searchInProgress() const;
6871 Categories* categories() const;
6972 Filters* filters() const;
7073 QString searchQuery() const;
@@ -95,11 +98,11 @@ Q_SIGNALS:
9598 void iconHintChanged(const std::string&);
9699 void descriptionChanged(const std::string&);
97100 void searchHintChanged(const std::string&);
101+ void searchInProgressChanged();
98102 void visibleChanged(bool);
99103 void shortcutChanged(const std::string&);
100104 void connectedChanged(bool);
101105 void categoriesChanged();
102− void searchFinished(const std::string&, unity::glib::HintsMap const&, unity::glib::Error const&);
103106 void searchQueryChanged();
104107 void noResultsHintChanged();
105108 void formFactorChanged();
@@ -115,7 +118,7 @@ Q_SIGNALS:
115118
116119private Q_SLOTS:
117120 void synchronizeStates();
118− void onSearchFinished(const std::string &, unity::glib::HintsMap const &);
121+ void onSearchFinished(std::string const &, unity::glib::HintsMap const &, unity::glib::Error const&);
119122
120123private:
121124 unity::dash::LocalResult createLocalResult(const QVariant &uri, const QVariant &icon_hint,
@@ -133,6 +136,8 @@ private:
133136 QString m_searchQuery;
134137 QString m_noResultsHint;
135138 QString m_formFactor;
139+ bool m_searchInProgress;
140+ unity::glib::Cancellable m_cancellable;
136141 unity::glib::Cancellable m_previewCancellable;
137142};
138143
tests/mocks/Unity/fake_scope.cpp+6
@@ -30,6 +30,7 @@ static DeeModel* create_results_model(unsigned category_count, unsigned result_c
3030Scope::Scope(QObject* parent)
3131 : QObject(parent)
3232 , m_visible(false)
33+ , m_searching(false)
3334 , m_categories(new Categories(this))
3435 , m_results(new DeeListModel(this))
3536{
@@ -44,6 +45,7 @@ Scope::Scope(QString const& id, QString const& name, bool visible, QObject* pare
4445 , m_id(id)
4546 , m_name(name)
4647 , m_visible(visible)
48+ , m_searching(false)
4749 , m_categories(new Categories(this))
4850 , m_results(new DeeListModel(this))
4951{
@@ -85,6 +87,10 @@ bool Scope::connected() const {
8587 return true;
8688}
8789
90+bool Scope::searchInProgress() const {
91+ return m_searching;
92+}
93+
8894Categories* Scope::categories() const {
8995 return m_categories;
9096}
tests/mocks/Unity/fake_scope.h+4−1
@@ -32,6 +32,7 @@ class Scope : public QObject
3232 Q_PROPERTY(QString iconHint READ iconHint NOTIFY iconHintChanged)
3333 Q_PROPERTY(QString description READ description NOTIFY descriptionChanged)
3434 Q_PROPERTY(QString searchHint READ searchHint NOTIFY searchHintChanged)
35+ Q_PROPERTY(bool searchInProgress READ searchInProgress NOTIFY searchInProgressChanged)
3536 Q_PROPERTY(bool visible READ visible NOTIFY visibleChanged)
3637 Q_PROPERTY(QString shortcut READ shortcut NOTIFY shortcutChanged)
3738 Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
@@ -54,6 +55,7 @@ public:
5455 bool visible() const;
5556 QString shortcut() const;
5657 bool connected() const;
58+ bool searchInProgress() const;
5759 Categories* categories() const;
5860 QString searchQuery() const;
5961 QString noResultsHint() const;
@@ -78,11 +80,11 @@ Q_SIGNALS:
7880 void iconHintChanged(const QString&);
7981 void descriptionChanged(const QString&);
8082 void searchHintChanged(const QString&);
83+ void searchInProgressChanged();
8184 void visibleChanged(bool);
8285 void shortcutChanged(const QString&);
8386 void connectedChanged(bool);
8487 void categoriesChanged();
85− void searchFinished(const QString&);
8688 void searchQueryChanged();
8789 void noResultsHintChanged();
8890 void formFactorChanged();
@@ -103,6 +105,7 @@ protected:
103105 QString m_noResultsHint;
104106 QString m_formFactor;
105107 bool m_visible;
108+ bool m_searching;
106109
107110 Categories* m_categories;
108111 DeeListModel* m_results;
tests/qmltests/Components/tst_PageHeader.qml+128−128
@@ -26,174 +26,174 @@ Item {
2626 width: units.gu(110)
2727 height: units.gu(30)
2828
29− Scopes {
30− id: scopes
29+ Scope {
30+ id: scopeMock
3131 }
3232
33− ScopeView {
34− id: scopeView
35− anchors.fill: parent
33+ UT.UnityTestCase {
34+ name: "PageHeaderTest"
35+ when: windowShown
3636
37− UT.UnityTestCase {
38− name: "PageHeaderTest"
39− when: scopes.loaded
37+ property alias searchEnabled : pageHeader.searchEntryEnabled
38+ property alias searchQuery : pageHeader.searchQuery
4039
41− property alias searchEnabled : pageHeader.searchEntryEnabled
42− property alias searchQuery : pageHeader.searchQuery
40+ function test_search_disabled() {
41+ searchEnabled = false
42+ pageHeader.resetSearch()
4343
44− function init() {
45− scopeView.scope = scopes.get(0)
46− }
44+ pageHeader.triggerSearch()
45+ keyClick(Qt.Key_S)
4746
48− function test_search_disabled() {
49− searchEnabled = false
50− pageHeader.resetSearch()
47+ compare(searchQuery, "", "Search entry not disabled properly (could still type in textfield).")
48+ }
5149
52− pageHeader.triggerSearch()
53− keyClick(Qt.Key_S)
50+ function test_search_enable() {
51+ searchEnabled = true
52+ pageHeader.resetSearch()
5453
55− compare(searchQuery, "", "Search entry not disabled properly (could still type in textfield).")
56− }
54+ pageHeader.triggerSearch()
55+ typeString("test")
5756
58− function test_search_enable() {
59− searchEnabled = true
60− pageHeader.resetSearch()
57+ compare(searchQuery, "test", "Typing in the search field did not change searchQuery")
58+ }
6159
62− pageHeader.triggerSearch()
63− typeString("test")
60+ function test_search_hard_coded() {
61+ searchEnabled = true
62+ pageHeader.triggerSearch()
63+ searchQuery = "test1"
64+ typeString("test2")
65+ compare(searchQuery, "test1test2", "Setting searchQuery text does not update the TextField")
66+ }
6467
65− compare(searchQuery, "test", "Typing in the search field did not change searchQuery")
66− }
68+ function test_reset_search() {
69+ searchEnabled = true
70+ pageHeader.resetSearch()
6771
68− function test_search_hard_coded() {
69− searchEnabled = true
70− pageHeader.triggerSearch()
71− searchQuery = "test1"
72− typeString("test2")
73− compare(searchQuery, "test1test2", "Setting searchQuery text does not update the TextField")
74− }
72+ pageHeader.triggerSearch()
73+ keyClick(Qt.Key_S)
7574
76− function test_reset_search() {
77− searchEnabled = true
78− pageHeader.resetSearch()
75+ compare(searchQuery, "s", "Could not type in TextField.")
7976
80− pageHeader.triggerSearch()
81− keyClick(Qt.Key_S)
77+ pageHeader.resetSearch()
78+ compare(searchQuery, "", "Reset search did not reset searchQuery correctly.")
79+ }
8280
83− compare(searchQuery, "s", "Could not type in TextField.")
81+ function test_move_search_by_width()
82+ {
83+ searchEnabled = true
84+ pageHeader.resetSearch()
8485
85− pageHeader.resetSearch()
86− compare(searchQuery, "", "Reset search did not reset searchQuery correctly.")
87− }
86+ var searchContainer = findChild(pageHeader, "searchContainer")
8887
89− function test_move_search_by_width()
90− {
91− searchEnabled = true
92− pageHeader.resetSearch()
88+ parent.width = units.gu(40)
9389
94− var searchContainer = findChild(pageHeader, "searchContainer")
90+ verify(searchContainer !== undefined)
91+ verify(searchContainer.y <= 0)
9592
96− parent.width = units.gu(40)
93+ pageHeader.triggerSearch()
94+ verify(searchContainer.y >= 0)
9795
98− verify(searchContainer !== undefined)
99− verify(searchContainer.y <= 0)
96+ pageHeader.resetSearch()
97+ verify(searchContainer.y <= 0)
10098
101− pageHeader.triggerSearch()
102− verify(searchContainer.y >= 0)
99+ parent.width = units.gu(110)
100+ verify(searchContainer.y >= 0)
103101
104− pageHeader.resetSearch()
105− verify(searchContainer.y <= 0)
102+ pageHeader.triggerSearch()
103+ tryCompare(searchContainer, "narrowMode", false)
104+ tryCompare(searchContainer, "state", "active")
105+ tryCompare(searchContainer, "width", units.gu(40))
106+ }
106107
107− parent.width = units.gu(110)
108− verify(searchContainer.y >= 0)
108+ function test_history() {
109+ pageHeader.searchHistory.clear()
110+ compare(pageHeader.searchHistory.count, 0)
109111
110− pageHeader.triggerSearch()
111− tryCompare(searchContainer, "narrowMode", false)
112− tryCompare(searchContainer, "state", "active")
113− tryCompare(searchContainer, "width", units.gu(40))
114− }
112+ pageHeader.triggerSearch()
113+ typeString("humppa1")
114+ pageHeader.resetSearch()
115115
116− function test_history() {
117− pageHeader.searchHistory.clear()
118− compare(pageHeader.searchHistory.count, 0)
116+ compare(pageHeader.searchHistory.count, 1)
117+ compare(pageHeader.searchHistory.get(0).query, "humppa1")
119118
120− pageHeader.triggerSearch()
121− typeString("humppa1")
122− pageHeader.resetSearch()
119+ pageHeader.triggerSearch()
120+ typeString("humppa2")
121+ pageHeader.resetSearch()
123122
124− compare(pageHeader.searchHistory.count, 1)
125− compare(pageHeader.searchHistory.get(0).query, "humppa1")
123+ compare(pageHeader.searchHistory.count, 2)
124+ compare(pageHeader.searchHistory.get(0).query, "humppa2")
126125
127− pageHeader.triggerSearch()
128− typeString("humppa2")
129− pageHeader.resetSearch()
126+ pageHeader.triggerSearch()
127+ typeString("humppa3")
128+ pageHeader.resetSearch()
130129
131− compare(pageHeader.searchHistory.count, 2)
132− compare(pageHeader.searchHistory.get(0).query, "humppa2")
130+ compare(pageHeader.searchHistory.count, 3)
131+ compare(pageHeader.searchHistory.get(0).query, "humppa3")
133132
134− pageHeader.triggerSearch()
135− typeString("humppa3")
136− pageHeader.resetSearch()
133+ pageHeader.triggerSearch()
134+ typeString("humppa4")
135+ pageHeader.resetSearch()
137136
138− compare(pageHeader.searchHistory.count, 3)
139− compare(pageHeader.searchHistory.get(0).query, "humppa3")
137+ compare(pageHeader.searchHistory.count, 3)
138+ compare(pageHeader.searchHistory.get(0).query, "humppa4")
139+ }
140140
141− pageHeader.triggerSearch()
142− typeString("humppa4")
143− pageHeader.resetSearch()
141+ function test_search_indicator() {
142+ pageHeader.triggerSearch()
143+ typeString("test")
144+ tryCompare(pageHeader, "searchInProgress", true)
145+ pageHeader.resetSearch()
146+ }
147+ }
148+
149+ Column {
150+ anchors.fill: parent
151+ spacing: units.gu(1)
144152
145− compare(pageHeader.searchHistory.count, 3)
146− compare(pageHeader.searchHistory.get(0).query, "humppa4")
153+ PageHeader {
154+ id: pageHeader
155+ anchors {
156+ left: parent.left
157+ right: parent.right
147158 }
148− }
149159
150− Column {
151− anchors.fill: parent
152− spacing: units.gu(1)
160+ scope: scopeMock
153161
154− PageHeader {
155− id: pageHeader
156− anchors {
157− left: parent.left
158− right: parent.right
159− }
162+ searchEntryEnabled: true
163+ text: "%^$%^%^&%^&%^$%GHR%"
164+ }
160165
161− searchEntryEnabled: true
162− text: "%^$%^%^&%^&%^$%GHR%"
166+ Row {
167+ spacing: units.gu(1)
168+ anchors {
169+ left: parent.left
170+ right: parent.right
163171 }
164−
165− Row {
166− spacing: units.gu(1)
167− anchors {
168− left: parent.left
169− right: parent.right
170− }
171− Button {
172− text: "Set search query programmatically"
173− onClicked: pageHeader.searchQuery = "testsearch"
174− width: units.gu(40)
175− }
176− Label {
177− text: "searchQuery: \"" + pageHeader.searchQuery + "\""
178− anchors.verticalCenter: parent.verticalCenter
179− }
172+ Button {
173+ text: "Set search query programmatically"
174+ onClicked: pageHeader.searchQuery = "testsearch"
175+ width: units.gu(40)
176+ }
177+ Label {
178+ text: "searchQuery: \"" + pageHeader.searchQuery + "\""
179+ anchors.verticalCenter: parent.verticalCenter
180180 }
181+ }
181182
182− Row {
183− spacing: units.gu(1)
184− anchors {
185− left: parent.left
186− right: parent.right
187− }
188− Button {
189− text: "Clear history model"
190− onClicked: pageHeader.searchHistory.clear()
191− width: units.gu(40)
192− }
193− Label {
194− text: "History count: " + pageHeader.searchHistory.count
195− anchors.verticalCenter: parent.verticalCenter
196− }
183+ Row {
184+ spacing: units.gu(1)
185+ anchors {
186+ left: parent.left
187+ right: parent.right
188+ }
189+ Button {
190+ text: "Clear history model"
191+ onClicked: pageHeader.searchHistory.clear()
192+ width: units.gu(40)
193+ }
194+ Label {
195+ text: "History count: " + pageHeader.searchHistory.count
196+ anchors.verticalCenter: parent.verticalCenter
197197 }
198198 }
199199 }