on 174fe91 help sign in
unity8/tests/plugins/Unity/filtersbindingstest.cpp
439 lines 17 kB history raw
1/*
2* Copyright (C) 2013 Canonical, Ltd.
3*
4* Authors:
5* Pawel Stolowski <pawel.stolowski@canonical.com>
6*
7* This program is free software; you can redistribute it and/or modify
8* it under the terms of the GNU General Public License as published by
9* the Free Software Foundation; version 3.
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.
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*/
20#include "filtersbindingstest.h"
22// libunity-core
23#include <UnityCore/Filter.h>
24#include <UnityCore/MultiRangeFilter.h>
26// Qt
27#include <QTest>
28#include <QSignalSpy>
30// libunity
31#include <unity.h>
33// local
34#include "filter.h"
35#include "multirangefilter.h"
36#include "combinedfilteroption.h"
37#include "checkoptionfilter.h"
38#include "radiooptionfilter.h"
39#include "ratingsfilter.h"
40#include "ratingfilteroption.h"
42void FiltersBindingsTest::initTestCase()
46GVariant* FiltersBindingsTest::createOptions(int numOfOptions)
48 auto vtype = g_variant_type_new("a(sssb)");
49 auto vb = g_variant_builder_new(vtype);
50 for (int i = 0; i<numOfOptions; i++) {
51 const std::string optId = "opt" + std::to_string(i);
52 const std::string optName = "Option " + std::to_string(i);
53 g_variant_builder_add(vb, "(sssb)", optId.c_str(), optName.c_str(), "", false);
54 }
55 return g_variant_builder_end(vb);
58DeeModel* FiltersBindingsTest::createFilterModel()
60 const char* filter_schema[8] = {"s", "s", "s", "s", "a{sv}", "b", "b", "b"};
61 auto model = dee_sequence_model_new();
62 dee_model_set_schema_full (DEE_MODEL(model), filter_schema, 8);
63 return model;
66void FiltersBindingsTest::createMultiRangeFilter(DeeModel *model, const std::string &id, const std::string &name, int optionCount)
68 createFilter(model, "filter-multirange", id, name, optionCount);
71void FiltersBindingsTest::createRadioOptionFilter(DeeModel *model, const std::string &id, const std::string &name, int optionCount)
73 createFilter(model, "filter-radiooption", id, name, optionCount);
76void FiltersBindingsTest::createCheckOptionFilter(DeeModel *model, const std::string &id, const std::string &name, int optionCount)
78 createFilter(model, "filter-checkoption", id, name, optionCount);
81void FiltersBindingsTest::createRatingsFilter(DeeModel *model, const std::string &id, const std::string &name)
83 GVariant* row[8];
85 row[0] = g_variant_new_string(id.c_str());
86 row[1] = g_variant_new_string(name.c_str());
87 row[2] = g_variant_new_string(""); // icon hint
88 row[3] = g_variant_new_string("filter-ratings");
90 GVariant *children[2];
91 GVariant *key1 = g_variant_new_string("show-all-button");
92 GVariant *key2 = g_variant_new_string("rating");
93 children[0] = g_variant_new_dict_entry(key1, g_variant_new_variant(g_variant_new_boolean(false)));
94 children[1] = g_variant_new_dict_entry(key2, g_variant_new_variant(g_variant_new_double(0.0f)));
95 auto fhints = g_variant_new_array(G_VARIANT_TYPE("{sv}"), children, 2);
97 row[4] = fhints;
98 row[5] = g_variant_new_boolean(true); // visible
99 row[6] = g_variant_new_boolean(false); // collapsed
100 row[7] = g_variant_new_boolean(false); // filtering
102 dee_model_append_row(model, row);
105void FiltersBindingsTest::createFilter(DeeModel *model, const std::string &renderer, const std::string &id, const std::string &name, int optionCount)
107 GVariant* row[8];
109 row[0] = g_variant_new_string(id.c_str());
110 row[1] = g_variant_new_string(name.c_str());
111 row[2] = g_variant_new_string(""); // icon hint
112 row[3] = g_variant_new_string(renderer.c_str()); // renderer
114 GVariant *children[2];
115 GVariant *key1 = g_variant_new_string("show-all-button");
116 GVariant *key2 = g_variant_new_string("options");
117 children[0] = g_variant_new_dict_entry(key1, g_variant_new_variant(g_variant_new_boolean(false)));
118 children[1] = g_variant_new_dict_entry(key2, g_variant_new_variant(createOptions(optionCount)));
119 auto fhints = g_variant_new_array(G_VARIANT_TYPE("{sv}"), children, 2);
121 row[4] = fhints;
122 row[5] = g_variant_new_boolean(true); // visible
123 row[6] = g_variant_new_boolean(false); // collapsed
124 row[7] = g_variant_new_boolean(false); // filtering
126 dee_model_append_row(model, row);
129void FiltersBindingsTest::testMultiRangeFilter()
131 auto model = createFilterModel();
133 createMultiRangeFilter(model, "f1", "Filter1", 1);
134 createMultiRangeFilter(model, "f2", "Filter2", 2);
135 createMultiRangeFilter(model, "f3", "Filter3", 3);
137 // create filter out of 1st row
138 auto iter = dee_model_get_first_iter(DEE_MODEL(model));
139 {
140 auto core_filter = unity::dash::Filter::FilterFromIter(model, iter);
141 QVERIFY(core_filter != nullptr);
142 auto bind_filter = Filter::newFromUnityFilter(core_filter);
143 auto multi_filter = dynamic_cast<MultiRangeFilter*>(bind_filter);
144 QVERIFY(multi_filter != nullptr);
145 auto options = multi_filter->options();
146 QCOMPARE(options->rowCount(), 1);
148 QVariant optvar = options->data(options->index(0));
149 CombinedFilterOption* opt1 = optvar.value<CombinedFilterOption*>();
150 QCOMPARE(opt1->id(), QString("opt0"));
152 delete multi_filter;
153 }
155 // create filter out of 2nd row
156 iter = dee_model_next(DEE_MODEL(model), iter);
157 {
158 auto core_filter = unity::dash::Filter::FilterFromIter(model, iter);
159 QVERIFY(core_filter != nullptr);
160 auto bind_filter = Filter::newFromUnityFilter(core_filter);
161 auto multi_filter = dynamic_cast<MultiRangeFilter*>(bind_filter);
162 QVERIFY(multi_filter != nullptr);
163 auto options = multi_filter->options();
164 QCOMPARE(options->rowCount(), 2);
166 QVariant optvar = options->data(options->index(0));
167 CombinedFilterOption* opt1 = optvar.value<CombinedFilterOption*>();
168 QCOMPARE(opt1->id(), QString("opt0-opt1"));
170 optvar = options->data(options->index(1));
171 CombinedFilterOption* opt2 = optvar.value<CombinedFilterOption*>();
172 QCOMPARE(opt2->id(), QString("opt1"));
174 delete multi_filter;
175 }
177 // create filter out of 3nd row
178 iter = dee_model_next(DEE_MODEL(model), iter);
179 {
180 auto core_filter = unity::dash::Filter::FilterFromIter(model, iter);
181 QVERIFY(core_filter != nullptr);
182 auto bind_filter = Filter::newFromUnityFilter(core_filter);
183 auto multi_filter = dynamic_cast<MultiRangeFilter*>(bind_filter);
184 QVERIFY(multi_filter != nullptr);
185 auto options = multi_filter->options();
186 QCOMPARE(options->rowCount(), 3);
188 QVariant optvar = options->data(options->index(0));
189 CombinedFilterOption* opt0 = optvar.value<CombinedFilterOption*>();
190 QCOMPARE(opt0->id(), QString("opt0-opt1"));
192 optvar = options->data(options->index(1));
193 CombinedFilterOption* opt1 = optvar.value<CombinedFilterOption*>();
194 QCOMPARE(opt1->id(), QString("opt1-opt2"));
196 optvar = options->data(options->index(2));
197 CombinedFilterOption* opt2 = optvar.value<CombinedFilterOption*>();
198 QCOMPARE(opt2->id(), QString("opt2"));
200 // verify combined filter options are bound to correct underlying unity options
201 auto core_multi_filter = std::dynamic_pointer_cast<unity::dash::MultiRangeFilter>(core_filter);
202 QCOMPARE(QString::fromStdString(core_multi_filter->options()[0]->id()), QString("opt0"));
203 QCOMPARE(QString::fromStdString(core_multi_filter->options()[1]->id()), QString("opt1"));
204 QCOMPARE(QString::fromStdString(core_multi_filter->options()[2]->id()), QString("opt2"));
206 QSignalSpy opt0spy(opt0, SIGNAL(activeChanged(bool)));
207 QSignalSpy opt1spy(opt1, SIGNAL(activeChanged(bool)));
208 QSignalSpy opt2spy(opt2, SIGNAL(activeChanged(bool)));
210 // test active property changes
211 QCOMPARE(opt0->active(), false);
213 opt0->setActive(true); // activate 1st combined option
214 QCOMPARE(opt0spy.count(), 1);
215 QCOMPARE(opt1spy.count(), 0);
216 QCOMPARE(opt2spy.count(), 0);
217 QCOMPARE(opt0->active(), true);
218 QCOMPARE(opt1->active(), false);
219 QCOMPARE(core_multi_filter->options()[0]->active(), true);
220 QCOMPARE(core_multi_filter->options()[1]->active(), true);
221 QCOMPARE(core_multi_filter->options()[2]->active(), false);
223 opt1->setActive(true); // activate another combined option
224 QCOMPARE(opt0spy.count(), 2);
225 QCOMPARE(opt1spy.count(), 1);
226 QCOMPARE(opt2spy.count(), 0);
227 QCOMPARE(opt0->active(), false); //1st combined option gets deactivated
228 QCOMPARE(opt1->active(), true);
229 QCOMPARE(core_multi_filter->options()[0]->active(), false);
230 QCOMPARE(core_multi_filter->options()[1]->active(), true); // shared option, stays active
231 QCOMPARE(core_multi_filter->options()[2]->active(), true);
233 opt1->setActive(false); // and de-activate it
234 QCOMPARE(opt0spy.count(), 2);
235 QCOMPARE(opt1spy.count(), 2);
236 QCOMPARE(opt2spy.count(), 0);
237 QCOMPARE(opt0->active(), false);
238 QCOMPARE(opt1->active(), false);
239 QCOMPARE(core_multi_filter->options()[0]->active(), false);
240 QCOMPARE(core_multi_filter->options()[1]->active(), false);
241 QCOMPARE(core_multi_filter->options()[2]->active(), false);
243 opt2->setActive(true); // activate another combined option
244 QCOMPARE(opt0spy.count(), 2);
245 QCOMPARE(opt1spy.count(), 2);
246 QCOMPARE(opt2spy.count(), 1);
247 QCOMPARE(opt0->active(), false);
248 QCOMPARE(opt1->active(), false);
249 QCOMPARE(opt2->active(), true);
250 QCOMPARE(core_multi_filter->options()[0]->active(), false);
251 QCOMPARE(core_multi_filter->options()[1]->active(), false);
252 QCOMPARE(core_multi_filter->options()[2]->active(), true);
254 delete multi_filter;
255 }
258void FiltersBindingsTest::testCheckOptionFilter()
260 auto model = createFilterModel();
262 createCheckOptionFilter(model, "f1", "Filter1", 3);
264 // create filter out of 1st row
265 auto iter = dee_model_get_first_iter(DEE_MODEL(model));
266 {
267 auto core_filter = unity::dash::Filter::FilterFromIter(model, iter);
268 QVERIFY(core_filter != nullptr);
269 auto bind_filter = Filter::newFromUnityFilter(core_filter);
270 auto check_filter = dynamic_cast<CheckOptionFilter*>(bind_filter);
271 QVERIFY(check_filter != nullptr);
272 auto options = check_filter->options();
273 QCOMPARE(options->rowCount(), 3);
275 QCOMPARE(check_filter->id(), QString("f1"));
276 QCOMPARE(check_filter->name(), QString("Filter1"));
277 QCOMPARE(check_filter->iconHint(), QString(""));
278 QCOMPARE(check_filter->rendererName(), QString("filter-checkoption"));
279 QCOMPARE(check_filter->visible(), true);
280 QCOMPARE(check_filter->collapsed(), false);
281 QCOMPARE(check_filter->filtering(), false);
283 QVariant optvar = options->data(options->index(0));
284 FilterOption* opt0 = optvar.value<FilterOption*>();
285 QCOMPARE(opt0->id(), QString("opt0"));
287 optvar = options->data(options->index(1));
288 FilterOption* opt1 = optvar.value<FilterOption*>();
289 QCOMPARE(opt1->id(), QString("opt1"));
291 optvar = options->data(options->index(2));
292 FilterOption* opt2 = optvar.value<FilterOption*>();
293 QCOMPARE(opt2->id(), QString("opt2"));
295 QSignalSpy opt0spy(opt0, SIGNAL(activeChanged(bool)));
296 QSignalSpy opt1spy(opt1, SIGNAL(activeChanged(bool)));
297 QSignalSpy opt2spy(opt2, SIGNAL(activeChanged(bool)));
299 // test active property changes
300 QCOMPARE(opt0->active(), false);
301 QCOMPARE(opt1->active(), false);
302 QCOMPARE(opt2->active(), false);
304 opt0->setActive(true);
305 QCOMPARE(opt0spy.count(), 1);
306 QCOMPARE(opt1spy.count(), 0);
307 QCOMPARE(opt2spy.count(), 0);
308 QCOMPARE(opt0->active(), true);
309 QCOMPARE(opt1->active(), false);
310 QCOMPARE(opt2->active(), false);
312 opt1->setActive(true);
313 QCOMPARE(opt0spy.count(), 2);
314 QCOMPARE(opt1spy.count(), 1);
315 QCOMPARE(opt2spy.count(), 0);
316 QCOMPARE(opt0->active(), false);
317 QCOMPARE(opt1->active(), true);
318 QCOMPARE(opt2->active(), false);
320 delete check_filter;
321 }
324void FiltersBindingsTest::testRadioOptionFilter()
326 auto model = createFilterModel();
328 createRadioOptionFilter(model, "f1", "Filter1", 3);
330 // create filter out of 1st row
331 auto iter = dee_model_get_first_iter(DEE_MODEL(model));
332 {
333 auto core_filter = unity::dash::Filter::FilterFromIter(model, iter);
334 QVERIFY(core_filter != nullptr);
335 auto bind_filter = Filter::newFromUnityFilter(core_filter);
336 auto radio_filter = dynamic_cast<RadioOptionFilter*>(bind_filter);
337 QVERIFY(radio_filter != nullptr);
338 auto options = radio_filter->options();
339 QCOMPARE(options->rowCount(), 3);
341 QVariant optvar = options->data(options->index(0));
342 FilterOption* opt0 = optvar.value<FilterOption*>();
343 QCOMPARE(opt0->id(), QString("opt0"));
345 optvar = options->data(options->index(1));
346 FilterOption* opt1 = optvar.value<FilterOption*>();
347 QCOMPARE(opt1->id(), QString("opt1"));
349 optvar = options->data(options->index(2));
350 FilterOption* opt2 = optvar.value<FilterOption*>();
351 QCOMPARE(opt2->id(), QString("opt2"));
353 QSignalSpy opt0spy(opt0, SIGNAL(activeChanged(bool)));
354 QSignalSpy opt1spy(opt1, SIGNAL(activeChanged(bool)));
355 QSignalSpy opt2spy(opt2, SIGNAL(activeChanged(bool)));
357 // test active property changes
358 QCOMPARE(opt0->active(), false);
359 QCOMPARE(opt1->active(), false);
360 QCOMPARE(opt2->active(), false);
362 opt0->setActive(true);
363 QCOMPARE(opt0spy.count(), 1);
364 QCOMPARE(opt1spy.count(), 0);
365 QCOMPARE(opt2spy.count(), 0);
366 QCOMPARE(opt0->active(), true);
367 QCOMPARE(opt1->active(), false);
368 QCOMPARE(opt2->active(), false);
370 opt1->setActive(true);
371 QCOMPARE(opt0spy.count(), 2);
372 QCOMPARE(opt1spy.count(), 1);
373 QCOMPARE(opt2spy.count(), 0);
374 QCOMPARE(opt0->active(), false);
375 QCOMPARE(opt1->active(), true);
376 QCOMPARE(opt2->active(), false);
378 delete radio_filter;
379 }
382void FiltersBindingsTest::testRatingsFilter()
384 auto model = createFilterModel();
386 createRatingsFilter(model, "f1", "Filter1");
388 // create filter out of 1st row
389 auto iter = dee_model_get_first_iter(DEE_MODEL(model));
390 {
391 auto core_filter = unity::dash::Filter::FilterFromIter(model, iter);
392 QVERIFY(core_filter != nullptr);
393 auto bind_filter = Filter::newFromUnityFilter(core_filter);
394 auto rating_filter = dynamic_cast<RatingsFilter*>(bind_filter);
395 QVERIFY(rating_filter != nullptr);
396 auto options = rating_filter->options();
397 QCOMPARE(options->rowCount(), 5);
399 RatingFilterOption* opt[5];
400 for (int i = 0; i<5; i++) {
401 opt[i] = options->data(options->index(i)).value<RatingFilterOption*>();
402 }
404 QSignalSpy opt0spy(opt[0], SIGNAL(activeChanged(bool)));
405 QSignalSpy opt4spy(opt[4], SIGNAL(activeChanged(bool)));
407 QVERIFY(qAbs(opt[0]->value() - 0.2f) <= 0.0001f);
408 QVERIFY(qAbs(opt[1]->value() - 0.4f) <= 0.0001f);
409 QVERIFY(qAbs(opt[2]->value() - 0.6f) <= 0.0001f);
410 QVERIFY(qAbs(opt[3]->value() - 0.8f) <= 0.0001f);
411 QVERIFY(qAbs(opt[4]->value() - 1.0f) <= 0.0001f);
413 // all options initially inactive
414 for (int i=0; i<5; i++) {
415 QCOMPARE(opt[i]->active(), false);
416 }
418 // verify activation for all options
419 for (int i=0; i<5; i++) {
420 opt[i]->setActive(true);
421 QCOMPARE(opt[i]->active(), true);
423 // verify that all other options are inactive
424 for (int j=0; j<5; j++) {
425 if (i != j) {
426 QCOMPARE(opt[j]->active(), false);
427 }
428 }
429 }
431 QCOMPARE(opt0spy.count(), 2);
432 QCOMPARE(opt4spy.count(), 1);
434 opt[4]->setActive(false);
435 QCOMPARE(opt4spy.count(), 2);
436 }
439QTEST_MAIN(FiltersBindingsTest)