1// Copyright © SixtyFPS GmbH <info@slint.dev>
2// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
3
4#include <chrono>
5#include <memory>
6#define CATCH_CONFIG_MAIN
7#include "catch2/catch.hpp"
8
9#include <slint.h>
10
11struct ModelObserver : public slint::private_api::ModelChangeListener
12{
13 void row_added(size_t index, size_t count) override
14 {
15 added_rows.push_back(x: Range { .row_index: index, .count: count });
16 }
17 void row_changed(size_t index) override { changed_rows.push_back(x: index); }
18 void row_removed(size_t index, size_t count) override
19 {
20 removed_rows.push_back(x: Range { .row_index: index, .count: count });
21 }
22 void reset() override { model_reset = true; }
23
24 void clear()
25 {
26 added_rows.clear();
27 changed_rows.clear();
28 removed_rows.clear();
29 model_reset = false;
30 }
31
32 struct Range
33 {
34 size_t row_index;
35 size_t count;
36
37 bool operator==(const Range &) const = default;
38 };
39 std::vector<Range> added_rows;
40 std::vector<size_t> changed_rows;
41 std::vector<Range> removed_rows;
42 bool model_reset = false;
43};
44
45std::ostream &operator<<(std::ostream &os, const ModelObserver::Range &value)
46{
47 os << "{ row_index: " << value.row_index << "; count: " << value.count << " }";
48 return os;
49}
50
51SCENARIO("Filtering Model")
52{
53 auto vec_model =
54 std::make_shared<slint::VectorModel<int>>(std::vector<int> { 1, 2, 3, 4, 5, 6 });
55
56 auto even_rows = std::make_shared<slint::FilterModel<int>>(
57 vec_model, [](auto value) { return value % 2 == 0; });
58
59 REQUIRE(even_rows->row_count() == 3);
60 REQUIRE(even_rows->row_data(0) == 2);
61 REQUIRE(even_rows->row_data(1) == 4);
62 REQUIRE(even_rows->row_data(2) == 6);
63}
64
65SCENARIO("Filtering Insert")
66{
67 auto vec_model =
68 std::make_shared<slint::VectorModel<int>>(std::vector<int> { 1, 2, 3, 4, 5, 6 });
69
70 auto even_rows = std::make_shared<slint::FilterModel<int>>(
71 vec_model, [](auto value) { return value % 2 == 0; });
72
73 auto observer = std::make_shared<ModelObserver>();
74 even_rows->attach_peer(observer);
75
76 REQUIRE(even_rows->row_count() == 3);
77 REQUIRE(even_rows->row_data(0) == 2);
78 REQUIRE(even_rows->row_data(1) == 4);
79 REQUIRE(even_rows->row_data(2) == 6);
80
81 vec_model->insert(2, 10);
82
83 REQUIRE(observer->added_rows.size() == 1);
84 REQUIRE(observer->added_rows[0] == ModelObserver::Range { 1, 1 });
85 REQUIRE(observer->changed_rows.empty());
86 REQUIRE(observer->removed_rows.empty());
87 REQUIRE(!observer->model_reset);
88 observer->clear();
89
90 REQUIRE(even_rows->row_count() == 4);
91 REQUIRE(even_rows->row_data(0) == 2);
92 REQUIRE(even_rows->row_data(1) == 10);
93 REQUIRE(even_rows->row_data(2) == 4);
94 REQUIRE(even_rows->row_data(3) == 6);
95
96 // insert odd number -> no change
97 vec_model->insert(0, 1);
98
99 REQUIRE(observer->added_rows.empty());
100 REQUIRE(observer->changed_rows.empty());
101 REQUIRE(observer->removed_rows.empty());
102 REQUIRE(!observer->model_reset);
103 observer->clear();
104}
105
106SCENARIO("Filtering Change")
107{
108 auto vec_model =
109 std::make_shared<slint::VectorModel<int>>(std::vector<int> { 1, 2, 3, 4, 5, 6 });
110
111 auto even_rows = std::make_shared<slint::FilterModel<int>>(
112 vec_model, [](auto value) { return value % 2 == 0; });
113
114 auto observer = std::make_shared<ModelObserver>();
115 even_rows->attach_peer(observer);
116
117 REQUIRE(even_rows->row_count() == 3);
118 REQUIRE(even_rows->row_data(0) == 2);
119 REQUIRE(even_rows->row_data(1) == 4);
120 REQUIRE(even_rows->row_data(2) == 6);
121
122 // change leading odd 1 to odd 3 -> no change
123 vec_model->set_row_data(0, 3);
124
125 REQUIRE(observer->added_rows.empty());
126 REQUIRE(observer->changed_rows.empty());
127 REQUIRE(observer->removed_rows.empty());
128 REQUIRE(!observer->model_reset);
129
130 REQUIRE(even_rows->row_count() == 3);
131 REQUIRE(even_rows->row_data(0) == 2);
132 REQUIRE(even_rows->row_data(1) == 4);
133 REQUIRE(even_rows->row_data(2) == 6);
134
135 // change trailing 6 to odd 1 -> one row less
136 vec_model->set_row_data(5, 1);
137
138 REQUIRE(observer->added_rows.empty());
139 REQUIRE(observer->changed_rows.empty());
140 REQUIRE(observer->removed_rows.size() == 1);
141 REQUIRE(observer->removed_rows[0] == ModelObserver::Range { 2, 1 });
142 REQUIRE(!observer->model_reset);
143 observer->clear();
144
145 REQUIRE(even_rows->row_count() == 2);
146 REQUIRE(even_rows->row_data(0) == 2);
147 REQUIRE(even_rows->row_data(1) == 4);
148
149 // change leading odd 3 to even 0 -> one new row
150 vec_model->set_row_data(0, 0);
151
152 REQUIRE(observer->added_rows.size() == 1);
153 REQUIRE(observer->added_rows[0] == ModelObserver::Range { 0, 1 });
154 REQUIRE(observer->changed_rows.empty());
155 REQUIRE(observer->removed_rows.empty());
156 REQUIRE(!observer->model_reset);
157 observer->clear();
158
159 REQUIRE(even_rows->row_count() == 3);
160 REQUIRE(even_rows->row_data(0) == 0);
161 REQUIRE(even_rows->row_data(1) == 2);
162 REQUIRE(even_rows->row_data(2) == 4);
163
164 // change trailing filtered 4 to even 0 -> one changed row
165 vec_model->set_row_data(3, 0);
166
167 REQUIRE(observer->added_rows.empty());
168 REQUIRE(observer->changed_rows.size() == 1);
169 REQUIRE(observer->changed_rows[0] == 2);
170 REQUIRE(observer->removed_rows.empty());
171 REQUIRE(!observer->model_reset);
172 observer->clear();
173
174 REQUIRE(even_rows->row_count() == 3);
175 REQUIRE(even_rows->row_data(0) == 0);
176 REQUIRE(even_rows->row_data(1) == 2);
177 REQUIRE(even_rows->row_data(2) == 0);
178}
179
180SCENARIO("Filtering Model Remove")
181{
182 auto vec_model =
183 std::make_shared<slint::VectorModel<int>>(std::vector<int> { 1, 2, 3, 4, 5, 6 });
184
185 auto even_rows = std::make_shared<slint::FilterModel<int>>(
186 vec_model, [](auto value) { return value % 2 == 0; });
187
188 auto observer = std::make_shared<ModelObserver>();
189 even_rows->attach_peer(observer);
190
191 REQUIRE(even_rows->row_count() == 3);
192 REQUIRE(even_rows->row_data(0) == 2);
193 REQUIRE(even_rows->row_data(1) == 4);
194 REQUIRE(even_rows->row_data(2) == 6);
195
196 // Erase unrelated row
197 vec_model->erase(0);
198
199 REQUIRE(observer->added_rows.empty());
200 REQUIRE(observer->changed_rows.empty());
201 REQUIRE(observer->removed_rows.empty());
202 REQUIRE(!observer->model_reset);
203 observer->clear();
204
205 REQUIRE(even_rows->row_count() == 3);
206 REQUIRE(even_rows->row_data(0) == 2);
207 REQUIRE(even_rows->row_data(1) == 4);
208 REQUIRE(even_rows->row_data(2) == 6);
209
210 // Erase trailing even 6
211 vec_model->erase(4);
212
213 REQUIRE(observer->added_rows.empty());
214 REQUIRE(observer->changed_rows.empty());
215 REQUIRE(observer->removed_rows.size() == 1);
216 REQUIRE(observer->removed_rows[0] == ModelObserver::Range { 2, 1 });
217 REQUIRE(!observer->model_reset);
218 observer->clear();
219
220 REQUIRE(even_rows->row_count() == 2);
221 REQUIRE(even_rows->row_data(0) == 2);
222 REQUIRE(even_rows->row_data(1) == 4);
223}
224
225SCENARIO("Filtering Model Reset")
226{
227 auto vec_model =
228 std::make_shared<slint::VectorModel<int>>(std::vector<int> { 1, 2, 3, 4, 5, 6 });
229
230 bool even = true;
231
232 auto even_rows = std::make_shared<slint::FilterModel<int>>(
233 vec_model, [&even](auto value) { return value % 2 == !even; });
234
235 auto observer = std::make_shared<ModelObserver>();
236 even_rows->attach_peer(observer);
237
238 REQUIRE(even_rows->row_count() == 3);
239 REQUIRE(even_rows->row_data(0) == 2);
240 REQUIRE(even_rows->row_data(1) == 4);
241 REQUIRE(even_rows->row_data(2) == 6);
242
243 even = false;
244 even_rows->reset();
245
246 REQUIRE(observer->added_rows.empty());
247 REQUIRE(observer->changed_rows.empty());
248 REQUIRE(observer->removed_rows.empty());
249 REQUIRE(observer->model_reset);
250 observer->clear();
251
252 REQUIRE(even_rows->row_count() == 3);
253 REQUIRE(even_rows->row_data(0) == 1);
254 REQUIRE(even_rows->row_data(1) == 3);
255 REQUIRE(even_rows->row_data(2) == 5);
256}
257
258template<typename ModelData>
259class TestDeferredFilterModel : public slint::FilterModel<ModelData>
260{
261public:
262 TestDeferredFilterModel(bool &initialized, bool &filtered,
263 std::shared_ptr<slint::Model<ModelData>> source_model)
264 : slint::FilterModel<ModelData> { std::move(source_model),
265 [&filtered]([[maybe_unused]] const ModelData &) {
266 if (!filtered) {
267 filtered = true;
268 }
269 return true;
270 } }
271 {
272 initialized = true;
273 }
274};
275
276SCENARIO("Filtering Model Ensure Deferred")
277{
278 auto source_model =
279 std::make_shared<slint::VectorModel<int>>(std::vector<int> { 0, 1, 2, 3, 4 });
280
281 bool initialized = false;
282 bool filtered = false;
283
284 auto filter_model =
285 std::make_shared<TestDeferredFilterModel<int>>(initialized, filtered, source_model);
286 REQUIRE(initialized);
287 REQUIRE_FALSE(filtered);
288
289 filter_model->row_data(0);
290 REQUIRE(filtered);
291}
292
293SCENARIO("Mapped Model")
294{
295 auto vec_model = std::make_shared<slint::VectorModel<int>>(std::vector<int> { 1, 2, 3, 4 });
296
297 int to_add = 1;
298
299 auto plus_one_model = std::make_shared<slint::MapModel<int, int>>(
300 vec_model, [&to_add](auto value) { return value + to_add; });
301
302 auto observer = std::make_shared<ModelObserver>();
303 plus_one_model->attach_peer(observer);
304
305 REQUIRE(plus_one_model->row_count() == 4);
306 REQUIRE(plus_one_model->row_data(0) == 2);
307 REQUIRE(plus_one_model->row_data(1) == 3);
308 REQUIRE(plus_one_model->row_data(2) == 4);
309 REQUIRE(plus_one_model->row_data(3) == 5);
310
311 vec_model->insert(0, 100);
312
313 REQUIRE(observer->added_rows.size() == 1);
314 REQUIRE(observer->added_rows[0] == ModelObserver::Range { 0, 1 });
315 REQUIRE(observer->changed_rows.empty());
316 REQUIRE(observer->removed_rows.empty());
317 REQUIRE(!observer->model_reset);
318 observer->clear();
319
320 REQUIRE(plus_one_model->row_count() == 5);
321 REQUIRE(plus_one_model->row_data(0) == 101);
322 REQUIRE(plus_one_model->row_data(1) == 2);
323 REQUIRE(plus_one_model->row_data(2) == 3);
324 REQUIRE(plus_one_model->row_data(3) == 4);
325 REQUIRE(plus_one_model->row_data(4) == 5);
326
327 vec_model->set_row_data(1, 3);
328
329 REQUIRE(observer->added_rows.empty());
330 REQUIRE(observer->changed_rows.size() == 1);
331 REQUIRE(observer->changed_rows[0] == 1);
332 REQUIRE(observer->removed_rows.empty());
333 REQUIRE(!observer->model_reset);
334 observer->clear();
335
336 REQUIRE(plus_one_model->row_count() == 5);
337 REQUIRE(plus_one_model->row_data(0) == 101);
338 REQUIRE(plus_one_model->row_data(1) == 4);
339 REQUIRE(plus_one_model->row_data(2) == 3);
340 REQUIRE(plus_one_model->row_data(3) == 4);
341 REQUIRE(plus_one_model->row_data(4) == 5);
342
343 vec_model->erase(3);
344
345 REQUIRE(observer->added_rows.empty());
346 REQUIRE(observer->changed_rows.empty());
347 REQUIRE(observer->removed_rows.size() == 1);
348 REQUIRE(observer->removed_rows[0] == ModelObserver::Range { 3, 1 });
349 REQUIRE(!observer->model_reset);
350 observer->clear();
351
352 REQUIRE(plus_one_model->row_count() == 4);
353 REQUIRE(plus_one_model->row_data(0) == 101);
354 REQUIRE(plus_one_model->row_data(1) == 4);
355 REQUIRE(plus_one_model->row_data(2) == 3);
356 REQUIRE(plus_one_model->row_data(3) == 5);
357
358 to_add = 51;
359 plus_one_model->reset();
360
361 REQUIRE(observer->added_rows.empty());
362 REQUIRE(observer->changed_rows.empty());
363 REQUIRE(observer->removed_rows.empty());
364 REQUIRE(observer->model_reset);
365 observer->clear();
366
367 REQUIRE(plus_one_model->row_count() == 4);
368 REQUIRE(plus_one_model->row_data(0) == 151);
369 REQUIRE(plus_one_model->row_data(1) == 54);
370 REQUIRE(plus_one_model->row_data(2) == 53);
371 REQUIRE(plus_one_model->row_data(3) == 55);
372}
373
374SCENARIO("Sorted Model Insert")
375{
376 auto vec_model = std::make_shared<slint::VectorModel<int>>(std::vector<int> { 3, 4, 1, 2 });
377
378 auto sorted_model = std::make_shared<slint::SortModel<int>>(
379 vec_model, [](auto lhs, auto rhs) { return lhs < rhs; });
380
381 auto observer = std::make_shared<ModelObserver>();
382 sorted_model->attach_peer(observer);
383
384 REQUIRE(sorted_model->row_count() == 4);
385 REQUIRE(sorted_model->row_data(0) == 1);
386 REQUIRE(sorted_model->row_data(1) == 2);
387 REQUIRE(sorted_model->row_data(2) == 3);
388 REQUIRE(sorted_model->row_data(3) == 4);
389
390 vec_model->insert(0, 10);
391
392 REQUIRE(observer->added_rows.size() == 1);
393 REQUIRE(observer->added_rows[0] == ModelObserver::Range { 4, 1 });
394 REQUIRE(observer->changed_rows.empty());
395 REQUIRE(observer->removed_rows.empty());
396 REQUIRE(!observer->model_reset);
397 observer->clear();
398
399 REQUIRE(sorted_model->row_count() == 5);
400 REQUIRE(sorted_model->row_data(0) == 1);
401 REQUIRE(sorted_model->row_data(1) == 2);
402 REQUIRE(sorted_model->row_data(2) == 3);
403 REQUIRE(sorted_model->row_data(3) == 4);
404 REQUIRE(sorted_model->row_data(4) == 10);
405}
406
407SCENARIO("Sorted Model Remove")
408{
409 auto vec_model = std::make_shared<slint::VectorModel<int>>(std::vector<int> { 3, 4, 1, 2 });
410
411 auto sorted_model = std::make_shared<slint::SortModel<int>>(
412 vec_model, [](auto lhs, auto rhs) { return lhs < rhs; });
413
414 auto observer = std::make_shared<ModelObserver>();
415 sorted_model->attach_peer(observer);
416
417 REQUIRE(sorted_model->row_count() == 4);
418 REQUIRE(sorted_model->row_data(0) == 1);
419 REQUIRE(sorted_model->row_data(1) == 2);
420 REQUIRE(sorted_model->row_data(2) == 3);
421 REQUIRE(sorted_model->row_data(3) == 4);
422
423 /// Remove the entry with the value 4
424 vec_model->erase(1);
425
426 REQUIRE(observer->added_rows.empty());
427 REQUIRE(observer->changed_rows.empty());
428 REQUIRE(observer->removed_rows.size() == 1);
429 REQUIRE(observer->removed_rows[0] == ModelObserver::Range { 3, 1 });
430 REQUIRE(!observer->model_reset);
431 observer->clear();
432
433 REQUIRE(sorted_model->row_count() == 3);
434 REQUIRE(sorted_model->row_data(0) == 1);
435 REQUIRE(sorted_model->row_data(1) == 2);
436 REQUIRE(sorted_model->row_data(2) == 3);
437}
438
439SCENARIO("Sorted Model Change")
440{
441 auto vec_model = std::make_shared<slint::VectorModel<int>>(std::vector<int> { 3, 4, 1, 2 });
442
443 auto sorted_model = std::make_shared<slint::SortModel<int>>(
444 vec_model, [](auto lhs, auto rhs) { return lhs < rhs; });
445
446 auto observer = std::make_shared<ModelObserver>();
447 sorted_model->attach_peer(observer);
448
449 REQUIRE(sorted_model->row_count() == 4);
450 REQUIRE(sorted_model->row_data(0) == 1);
451 REQUIRE(sorted_model->row_data(1) == 2);
452 REQUIRE(sorted_model->row_data(2) == 3);
453 REQUIRE(sorted_model->row_data(3) == 4);
454
455 /// Change the entry with the value 4 to 10 -> maintain order
456 vec_model->set_row_data(1, 10);
457
458 REQUIRE(observer->added_rows.empty());
459 REQUIRE(observer->changed_rows.size() == 1);
460 REQUIRE(observer->changed_rows[0] == 3);
461 REQUIRE(observer->removed_rows.empty());
462 REQUIRE(!observer->model_reset);
463 observer->clear();
464
465 REQUIRE(sorted_model->row_count() == 4);
466 REQUIRE(sorted_model->row_data(0) == 1);
467 REQUIRE(sorted_model->row_data(1) == 2);
468 REQUIRE(sorted_model->row_data(2) == 3);
469 REQUIRE(sorted_model->row_data(3) == 10);
470
471 /// Change the entry with the value 10 to 0 -> new order with remove and insert
472 vec_model->set_row_data(1, 0);
473
474 REQUIRE(observer->added_rows.size() == 1);
475 REQUIRE(observer->added_rows[0] == ModelObserver::Range { 0, 1 });
476 REQUIRE(observer->changed_rows.empty());
477 REQUIRE(observer->removed_rows.size() == 1);
478 REQUIRE(observer->removed_rows[0] == ModelObserver::Range { 3, 1 });
479 REQUIRE(!observer->model_reset);
480 observer->clear();
481
482 REQUIRE(sorted_model->row_count() == 4);
483 REQUIRE(sorted_model->row_data(0) == 0);
484 REQUIRE(sorted_model->row_data(1) == 1);
485 REQUIRE(sorted_model->row_data(2) == 2);
486 REQUIRE(sorted_model->row_data(3) == 3);
487}
488
489SCENARIO("Sorted Model Reset")
490{
491 auto vec_model = std::make_shared<slint::VectorModel<int>>(std::vector<int> { 3, 4, 1, 2 });
492
493 bool ascending = true;
494
495 auto sorted_model =
496 std::make_shared<slint::SortModel<int>>(vec_model, [&ascending](auto lhs, auto rhs) {
497 return ascending ? lhs < rhs : rhs < lhs;
498 });
499
500 auto observer = std::make_shared<ModelObserver>();
501 sorted_model->attach_peer(observer);
502
503 REQUIRE(sorted_model->row_count() == 4);
504 REQUIRE(sorted_model->row_data(0) == 1);
505 REQUIRE(sorted_model->row_data(1) == 2);
506 REQUIRE(sorted_model->row_data(2) == 3);
507 REQUIRE(sorted_model->row_data(3) == 4);
508
509 ascending = false;
510 sorted_model->reset();
511
512 REQUIRE(sorted_model->row_count() == 4);
513 REQUIRE(sorted_model->row_data(0) == 4);
514 REQUIRE(sorted_model->row_data(1) == 3);
515 REQUIRE(sorted_model->row_data(2) == 2);
516 REQUIRE(sorted_model->row_data(3) == 1);
517
518 REQUIRE(observer->model_reset);
519}
520
521template<typename ModelData>
522class TestDeferredSortModel : public slint::SortModel<ModelData>
523{
524public:
525 TestDeferredSortModel(bool &initialized, bool &sorted,
526 std::shared_ptr<slint::Model<ModelData>> source_model)
527 : slint::SortModel<ModelData> { std::move(source_model),
528 [&sorted](const ModelData &first, const ModelData &second) {
529 if (!sorted) {
530 sorted = true;
531 }
532 return first > second;
533 } }
534 {
535 initialized = true;
536 }
537};
538
539SCENARIO("Sorted Model Ensure Deferred")
540{
541 auto source_model =
542 std::make_shared<slint::VectorModel<int>>(std::vector<int> { 0, 1, 2, 3, 4 });
543
544 bool initialized = false;
545 bool sorted = false;
546
547 auto sort_model =
548 std::make_shared<TestDeferredSortModel<int>>(initialized, sorted, source_model);
549 REQUIRE(initialized);
550 REQUIRE_FALSE(sorted);
551
552 sort_model->row_data(0);
553 REQUIRE(sorted);
554}
555
556SCENARIO("Reverse Model Insert")
557{
558 auto vec_model = std::make_shared<slint::VectorModel<int>>(std::vector<int> { 3, 4, 1, 2 });
559
560 auto reverse_model = std::make_shared<slint::ReverseModel<int>>(vec_model);
561
562 auto observer = std::make_shared<ModelObserver>();
563 reverse_model->attach_peer(observer);
564
565 REQUIRE(reverse_model->row_count() == 4);
566 REQUIRE(reverse_model->row_data(0) == 2);
567 REQUIRE(reverse_model->row_data(1) == 1);
568 REQUIRE(reverse_model->row_data(2) == 4);
569 REQUIRE(reverse_model->row_data(3) == 3);
570
571 vec_model->insert(0, 10);
572
573 REQUIRE(observer->added_rows.size() == 1);
574 REQUIRE(observer->added_rows[0] == ModelObserver::Range { 4, 1 });
575 REQUIRE(observer->changed_rows.empty());
576 REQUIRE(observer->removed_rows.empty());
577 REQUIRE(!observer->model_reset);
578 observer->clear();
579
580 REQUIRE(reverse_model->row_count() == 5);
581 REQUIRE(reverse_model->row_data(0) == 2);
582 REQUIRE(reverse_model->row_data(1) == 1);
583 REQUIRE(reverse_model->row_data(2) == 4);
584 REQUIRE(reverse_model->row_data(3) == 3);
585 REQUIRE(reverse_model->row_data(4) == 10);
586}
587
588SCENARIO("Reverse Model Remove")
589{
590 auto vec_model = std::make_shared<slint::VectorModel<int>>(std::vector<int> { 3, 4, 1, 2 });
591
592 auto reverse_model = std::make_shared<slint::ReverseModel<int>>(vec_model);
593
594 auto observer = std::make_shared<ModelObserver>();
595 reverse_model->attach_peer(observer);
596
597 REQUIRE(reverse_model->row_count() == 4);
598 REQUIRE(reverse_model->row_data(0) == 2);
599 REQUIRE(reverse_model->row_data(1) == 1);
600 REQUIRE(reverse_model->row_data(2) == 4);
601 REQUIRE(reverse_model->row_data(3) == 3);
602
603 /// Remove the entry with the value 4
604 vec_model->erase(1);
605
606 REQUIRE(observer->added_rows.empty());
607 REQUIRE(observer->changed_rows.empty());
608 REQUIRE(observer->removed_rows.size() == 1);
609 REQUIRE(observer->removed_rows[0] == ModelObserver::Range { 2, 1 });
610 REQUIRE(!observer->model_reset);
611 observer->clear();
612
613 REQUIRE(reverse_model->row_count() == 3);
614 REQUIRE(reverse_model->row_data(0) == 2);
615 REQUIRE(reverse_model->row_data(1) == 1);
616 REQUIRE(reverse_model->row_data(2) == 3);
617}
618
619SCENARIO("Reverse Model Change")
620{
621 auto vec_model = std::make_shared<slint::VectorModel<int>>(std::vector<int> { 3, 4, 1, 2 });
622
623 auto reverse_model = std::make_shared<slint::ReverseModel<int>>(vec_model);
624
625 auto observer = std::make_shared<ModelObserver>();
626 reverse_model->attach_peer(observer);
627
628 REQUIRE(reverse_model->row_count() == 4);
629 REQUIRE(reverse_model->row_data(0) == 2);
630 REQUIRE(reverse_model->row_data(1) == 1);
631 REQUIRE(reverse_model->row_data(2) == 4);
632 REQUIRE(reverse_model->row_data(3) == 3);
633
634 /// Change the entry with the value 4 to 10 -> maintain order
635 vec_model->set_row_data(1, 10);
636
637 REQUIRE(observer->added_rows.empty());
638 REQUIRE(observer->changed_rows.size() == 1);
639 REQUIRE(observer->changed_rows[0] == 2);
640 REQUIRE(observer->removed_rows.empty());
641 REQUIRE(!observer->model_reset);
642 observer->clear();
643
644 REQUIRE(reverse_model->row_count() == 4);
645 REQUIRE(reverse_model->row_data(0) == 2);
646 REQUIRE(reverse_model->row_data(1) == 1);
647 REQUIRE(reverse_model->row_data(2) == 10);
648 REQUIRE(reverse_model->row_data(3) == 3);
649
650 vec_model->clear();
651 REQUIRE(observer->added_rows.empty());
652 REQUIRE(observer->changed_rows.empty());
653 REQUIRE(observer->removed_rows.empty());
654 REQUIRE(observer->model_reset);
655 observer->clear();
656
657 REQUIRE(reverse_model->row_count() == 0);
658}
659
660TEST_CASE("VectorModel clear and replace")
661{
662 using namespace slint::private_api;
663
664 auto model = std::make_shared<slint::VectorModel<int>>(std::vector<int> { 0, 1, 2, 3, 4 });
665
666 auto observer = std::make_shared<ModelObserver>();
667 model->attach_peer(observer);
668
669 REQUIRE(model->row_count() == 5);
670 model->clear();
671 REQUIRE(model->row_count() == 0);
672 REQUIRE(observer->added_rows.empty());
673 REQUIRE(observer->changed_rows.empty());
674 REQUIRE(observer->removed_rows.empty());
675 REQUIRE(observer->model_reset);
676 observer->clear();
677
678 model->clear();
679 REQUIRE(!observer->model_reset);
680 observer->clear();
681
682 model->set_vector({ 2, 3, 4 });
683 REQUIRE(model->row_count() == 3);
684 REQUIRE(model->row_data(1) == 3);
685 REQUIRE(observer->added_rows.empty());
686 REQUIRE(observer->changed_rows.empty());
687 REQUIRE(observer->removed_rows.empty());
688 REQUIRE(observer->model_reset);
689
690 // Test that taking a vector by value compiles
691 std::vector<int> new_data { 5, 6, 7, 8 };
692 model->set_vector(new_data);
693}
694

source code of slint/api/cpp/tests/models.cpp