1 /*
2  * Copyright (C) 2008-2020 The Communi Project
3  *
4  * This test is free, and not covered by the BSD license. There is no
5  * restriction applied to their modification, redistribution, using and so on.
6  * You can study them, modify them, use them in your own program - either
7  * completely or partially.
8  */
9 
10 #include "ircbuffermodel.h"
11 #include "ircconnection.h"
12 #include "ircchannel.h"
13 #include "irccommand.h"
14 #include "ircbuffer.h"
15 #include "ircfilter.h"
16 #include <QtTest/QtTest>
17 #include "tst_ircclientserver.h"
18 #include "tst_ircdata.h"
19 
20 class tst_IrcBufferModel : public tst_IrcClientServer
21 {
22     Q_OBJECT
23 
24 public:
25     tst_IrcBufferModel();
26 
27 private slots:
28     void testDefaults();
29     void testBufferInit();
30     void testAddRemove();
31     void testSorting();
32     void testClear();
33     void testPersistent();
34     void testPrototypes();
35     void testChanges();
36     void testActive();
37     void testRoles();
38     void testAIM();
39     void testQML();
40     void testWarnings();
41     void testMonitor();
42 };
43 
Q_DECLARE_METATYPE(QModelIndex)44 Q_DECLARE_METATYPE(QModelIndex)
45 tst_IrcBufferModel::tst_IrcBufferModel()
46 {
47     Irc::registerMetaTypes();
48     qRegisterMetaType<QModelIndex>();
49     qRegisterMetaType<IrcBuffer*>("IrcBuffer*");
50     qRegisterMetaType<IrcChannel*>("IrcChannel*");
51     qRegisterMetaType<IrcConnection*>("IrcConnection*");
52     qRegisterMetaType<QList<IrcBuffer*> >("QList<IrcBuffer*>");
53     qRegisterMetaType<QList<IrcChannel*> >("QList<IrcChannel*>");
54 }
55 
testDefaults()56 void tst_IrcBufferModel::testDefaults()
57 {
58     IrcBufferModel model;
59     QCOMPARE(model.count(), 0);
60     QVERIFY(model.isEmpty());
61     QCOMPARE(model.sortOrder(), Qt::AscendingOrder);
62     QCOMPARE(model.sortMethod(), Irc::SortByHand);
63     QVERIFY(model.channels().isEmpty());
64     QCOMPARE(model.displayRole(), Irc::TitleRole);
65     QVERIFY(!model.isPersistent());
66     QVERIFY(model.buffers().isEmpty());
67     QVERIFY(!model.connection());
68     QVERIFY(!model.network());
69     QVERIFY(model.bufferPrototype());
70     QVERIFY(model.channelPrototype());
71     QVERIFY(!model.isMonitorEnabled());
72 }
73 
testBufferInit()74 void tst_IrcBufferModel::testBufferInit()
75 {
76     IrcBufferModel model(connection);
77     model.setSortMethod(Irc::SortByTitle);
78     IrcBuffer* buffer1 = new IrcBuffer(&model);
79     buffer1->setName("1");
80     model.add(buffer1);
81     IrcBuffer* buffer2 = new IrcBuffer(&model);
82     buffer2->setName("2");
83     model.add(buffer2);
84 }
85 
testAddRemove()86 void tst_IrcBufferModel::testAddRemove()
87 {
88     IrcBufferModel model;
89 
90     QSignalSpy countSpy(&model, SIGNAL(countChanged(int)));
91     QSignalSpy emptySpy(&model, SIGNAL(emptyChanged(bool)));
92     QSignalSpy addedSpy(&model, SIGNAL(added(IrcBuffer*)));
93     QSignalSpy removedSpy(&model, SIGNAL(removed(IrcBuffer*)));
94     QSignalSpy aboutToBeAddedSpy(&model, SIGNAL(aboutToBeAdded(IrcBuffer*)));
95     QSignalSpy aboutToBeRemovedSpy(&model, SIGNAL(aboutToBeRemoved(IrcBuffer*)));
96     QSignalSpy buffersSpy(&model, SIGNAL(buffersChanged(QList<IrcBuffer*>)));
97     QSignalSpy channelsSpy(&model, SIGNAL(channelsChanged(QStringList)));
98     QVERIFY(countSpy.isValid());
99     QVERIFY(emptySpy.isValid());
100     QVERIFY(addedSpy.isValid());
101     QVERIFY(removedSpy.isValid());
102     QVERIFY(aboutToBeAddedSpy.isValid());
103     QVERIFY(aboutToBeRemovedSpy.isValid());
104     QVERIFY(buffersSpy.isValid());
105     QVERIFY(channelsSpy.isValid());
106 
107     // IrcBuffer* IrcBufferModel::add(const QString& title)
108     IrcBuffer* first = model.add("first");
109     QCOMPARE(model.count(), 1);
110     QVERIFY(!model.isEmpty());
111     QCOMPARE(model.get(0), first);
112     QCOMPARE(model.find("first"), first);
113     QCOMPARE(model.buffers(), QList<IrcBuffer*>() << first);
114     QVERIFY(model.contains("first"));
115     QCOMPARE(model.indexOf(first), 0);
116     QVERIFY(model.channels().isEmpty());
117 
118     QCOMPARE(countSpy.count(), 1);
119     QCOMPARE(countSpy.last().last().toInt(), 1);
120     QCOMPARE(emptySpy.count(), 1);
121     QCOMPARE(emptySpy.last().last().toBool(), false);
122     QCOMPARE(aboutToBeAddedSpy.count(), 1);
123     QCOMPARE(aboutToBeAddedSpy.last().last().value<IrcBuffer*>(), first);
124     QCOMPARE(addedSpy.count(), 1);
125     QCOMPARE(addedSpy.last().last().value<IrcBuffer*>(), first);
126     QCOMPARE(buffersSpy.count(), 1);
127     QCOMPARE(buffersSpy.last().last().value<QList<IrcBuffer*> >(), QList<IrcBuffer*>() << first);
128     QCOMPARE(channelsSpy.count(), 0);
129 
130     QModelIndex firstIdx = model.index(first);
131     QVERIFY(firstIdx.isValid());
132     QCOMPARE(firstIdx.data(Irc::NameRole).toString(), QString("first"));
133     QCOMPARE(firstIdx.data(Irc::TitleRole).toString(), QString("first"));
134     QCOMPARE(firstIdx.data(Irc::PrefixRole).toString(), QString());
135     QCOMPARE(firstIdx.data(Irc::BufferRole).value<IrcBuffer*>(), first);
136     QVERIFY(!firstIdx.data(Irc::ChannelRole).value<IrcChannel*>());
137 
138     // void IrcBufferModel::add(IrcBuffer* buffer)
139     IrcBuffer* second = new IrcBuffer(&model);
140     second->setName("second");
141     model.add(second);
142     QCOMPARE(model.count(), 2);
143     QVERIFY(!model.isEmpty());
144     QCOMPARE(model.get(1), second);
145     QCOMPARE(model.find("second"), second);
146     QCOMPARE(model.buffers(), QList<IrcBuffer*>() << first << second);
147     QVERIFY(model.contains("second"));
148     QCOMPARE(model.indexOf(second), 1);
149     QVERIFY(model.channels().isEmpty());
150 
151     QCOMPARE(countSpy.count(), 2);
152     QCOMPARE(countSpy.last().last().toInt(), 2);
153     QCOMPARE(emptySpy.count(), 1);
154     QCOMPARE(aboutToBeAddedSpy.count(), 2);
155     QCOMPARE(aboutToBeAddedSpy.last().last().value<IrcBuffer*>(), second);
156     QCOMPARE(addedSpy.count(), 2);
157     QCOMPARE(addedSpy.last().last().value<IrcBuffer*>(), second);
158     QCOMPARE(buffersSpy.count(), 2);
159     QCOMPARE(buffersSpy.last().last().value<QList<IrcBuffer*> >(), QList<IrcBuffer*>() << first << second);
160     QCOMPARE(channelsSpy.count(), 0);
161 
162     QModelIndex secondIdx = model.index(second);
163     QVERIFY(secondIdx.isValid());
164     QCOMPARE(secondIdx.data(Irc::NameRole).toString(), QString("second"));
165     QCOMPARE(secondIdx.data(Irc::TitleRole).toString(), QString("second"));
166     QCOMPARE(secondIdx.data(Irc::PrefixRole).toString(), QString());
167     QCOMPARE(secondIdx.data(Irc::BufferRole).value<IrcBuffer*>(), second);
168     QVERIFY(!secondIdx.data(Irc::ChannelRole).value<IrcChannel*>());
169 
170     // void IrcBufferModel::remove(IrcBuffer* buffer)
171     model.remove(second);
172     QCOMPARE(model.count(), 1);
173     QVERIFY(!model.isEmpty());
174     QVERIFY(!model.find("second"));
175     QCOMPARE(model.buffers(), QList<IrcBuffer*>() << first);
176     QVERIFY(!model.contains("second"));
177     QVERIFY(model.channels().isEmpty());
178 
179     QCOMPARE(countSpy.count(), 3);
180     QCOMPARE(countSpy.last().last().toInt(), 1);
181     QCOMPARE(emptySpy.count(), 1);
182     QCOMPARE(aboutToBeRemovedSpy.count(), 1);
183     QCOMPARE(removedSpy.count(), 1);
184     QCOMPARE(buffersSpy.count(), 3);
185     QCOMPARE(buffersSpy.last().last().value<QList<IrcBuffer*> >(), QList<IrcBuffer*>() << first);
186     QCOMPARE(channelsSpy.count(), 0);
187 
188     // void IrcBufferModel::remove(const QString& title)
189     model.remove("first");
190     QCOMPARE(model.count(), 0);
191     QVERIFY(model.isEmpty());
192     QVERIFY(!model.find("first"));
193     QVERIFY(model.buffers().isEmpty());
194     QVERIFY(!model.contains("first"));
195     QVERIFY(model.channels().isEmpty());
196 
197     QCOMPARE(countSpy.count(), 4);
198     QCOMPARE(countSpy.last().last().toInt(), 0);
199     QCOMPARE(emptySpy.count(), 2);
200     QCOMPARE(emptySpy.last().last().toBool(), true);
201     QCOMPARE(aboutToBeRemovedSpy.count(), 2);
202     QCOMPARE(removedSpy.count(), 2);
203     QCOMPARE(buffersSpy.count(), 4);
204     QCOMPARE(buffersSpy.last().last().value<QList<IrcBuffer*> >(), QList<IrcBuffer*>());
205     QCOMPARE(channelsSpy.count(), 0);
206 }
207 
testSorting()208 void tst_IrcBufferModel::testSorting()
209 {
210     IrcBufferModel staticModel(connection);
211     IrcBufferModel dynamicModel(connection);
212 
213     connection->open();
214     waitForOpened();
215     waitForWritten(tst_IrcData::welcome());
216 
217     IrcBuffer* b = staticModel.add("b");
218     IrcBuffer* c = staticModel.add("#c");
219     IrcBuffer* a = staticModel.add("#a");
220 
221     QList<IrcBuffer*> buffers =  QList<IrcBuffer*>() << b << c << a;
222     QCOMPARE(staticModel.buffers(), buffers);
223 
224     // IGNORE INVALID COLUMNS
225     staticModel.sort(-1, Qt::AscendingOrder);
226     QCOMPARE(staticModel.buffers(), buffers);
227 
228     staticModel.sort(1, Qt::AscendingOrder);
229     QCOMPARE(staticModel.buffers(), buffers);
230 
231     // STATIC - BY NAME - ASCENDING
232     buffers =  QList<IrcBuffer*>() << a << b << c;
233     staticModel.setSortMethod(Irc::SortByName);
234     staticModel.sort(0, Qt::AscendingOrder);
235     QCOMPARE(staticModel.buffers(), buffers);
236 
237     // STATIC - BY NAME - DESCENDING
238     buffers =  QList<IrcBuffer*>() << c << b << a;
239     staticModel.setSortMethod(Irc::SortByName);
240     staticModel.sort(0, Qt::DescendingOrder);
241     QCOMPARE(staticModel.buffers(), buffers);
242 
243     // STATIC - BY TITLE - ASCENDING
244     buffers =  QList<IrcBuffer*>() << a << c << b;
245     staticModel.setSortMethod(Irc::SortByTitle);
246     staticModel.sort(0, Qt::AscendingOrder);
247     QCOMPARE(staticModel.buffers(), buffers);
248 
249     // STATIC - BY TITLE - DESCENDING
250     buffers =  QList<IrcBuffer*>() << b << c << a;
251     staticModel.setSortMethod(Irc::SortByTitle);
252     staticModel.sort(0, Qt::DescendingOrder);
253     QCOMPARE(staticModel.buffers(), buffers);
254 
255     // STATIC - BY TITLE - ASCENDING & STICKY
256     c->setSticky(true);
257     buffers =  QList<IrcBuffer*>() << c << a << b;
258     staticModel.setSortMethod(Irc::SortByTitle);
259     staticModel.sort(0, Qt::AscendingOrder);
260     QCOMPARE(staticModel.buffers(), buffers);
261 
262     // STATIC - BY TITLE - ASCENDING & 2 STICKIES
263     b->setSticky(true);
264     buffers =  QList<IrcBuffer*>() << c << b << a;
265     staticModel.setSortMethod(Irc::SortByTitle);
266     staticModel.sort(0, Qt::AscendingOrder);
267     QCOMPARE(staticModel.buffers(), buffers);
268 
269     b = dynamicModel.add("b");
270     c = dynamicModel.add("#c");
271     a = dynamicModel.add("#a");
272 
273     // DYNAMIC - BY NAME - ASCENDING
274     buffers =  QList<IrcBuffer*>() << a << b << c;
275     dynamicModel.setSortMethod(Irc::SortByName);
276     QCOMPARE(dynamicModel.buffers(), buffers);
277 
278     // DYNAMIC - BY TITLE - ASCENDING
279     buffers =  QList<IrcBuffer*>() << a << c << b;
280     dynamicModel.setSortMethod(Irc::SortByTitle);
281     QCOMPARE(dynamicModel.buffers(), buffers);
282 
283     dynamicModel.setSortOrder(Qt::DescendingOrder);
284 
285     // DYNAMIC - BY NAME - DESCENDING
286     buffers =  QList<IrcBuffer*>() << c << b << a;
287     dynamicModel.setSortMethod(Irc::SortByName);
288     QCOMPARE(dynamicModel.buffers(), buffers);
289 
290     // DYNAMIC - BY TITLE - DESCENDING
291     buffers =  QList<IrcBuffer*>() << b << c << a;
292     dynamicModel.setSortMethod(Irc::SortByTitle);
293     QCOMPARE(dynamicModel.buffers(), buffers);
294 
295     // DO NOTHING
296     dynamicModel.sort(Irc::SortByHand);
297     QCOMPARE(dynamicModel.buffers(), buffers);
298 }
299 
testClear()300 void tst_IrcBufferModel::testClear()
301 {
302     IrcBufferModel model(connection);
303     connection->open();
304     QVERIFY(waitForOpened());
305     QVERIFY(waitForWritten(tst_IrcData::welcome()));
306 
307     QPointer<IrcBuffer> a = model.add("#a");
308     QPointer<IrcBuffer> b = model.add("#b");
309     QPointer<IrcBuffer> c = model.add("c");
310     QPointer<IrcBuffer> d = model.add("d");
311 
312     QSignalSpy countSpy(&model, SIGNAL(countChanged(int)));
313     QSignalSpy buffersSpy(&model, SIGNAL(buffersChanged(QList<IrcBuffer*>)));
314     QSignalSpy channelsSpy(&model, SIGNAL(channelsChanged(QStringList)));
315     QSignalSpy modelAboutToBeResetSpy(&model, SIGNAL(modelAboutToBeReset()));
316     QSignalSpy modelResetSpy(&model, SIGNAL(modelReset()));
317 
318     QVERIFY(countSpy.isValid());
319     QVERIFY(buffersSpy.isValid());
320     QVERIFY(channelsSpy.isValid());
321     QVERIFY(modelAboutToBeResetSpy.isValid());
322     QVERIFY(modelResetSpy.isValid());
323 
324     b->setPersistent(true);
325     d->setPersistent(true);
326 
327     // #a, #b*, c, d*
328     model.clear();
329 
330     QCOMPARE(model.count(), 2);
331     QCOMPARE(model.buffers(), QList<IrcBuffer*>() << b << d);
332     QCOMPARE(model.channels(), QStringList() << "#b");
333 
334     QCOMPARE(model.get(0), b.data());
335     QCOMPARE(model.get(1), d.data());
336     QVERIFY(!model.get(2));
337     QVERIFY(!model.find("#a"));
338     QVERIFY(model.find("#b"));
339     QVERIFY(!model.find("c"));
340     QVERIFY(model.find("d"));
341     QVERIFY(!model.contains("#a"));
342     QVERIFY(model.contains("#b"));
343     QVERIFY(!model.contains("c"));
344     QVERIFY(model.contains("d"));
345 
346     QVERIFY(!a);
347     QVERIFY(b);
348     QVERIFY(!c);
349     QVERIFY(d);
350 
351     QCOMPARE(countSpy.count(), 1);
352     QCOMPARE(countSpy.last().at(0).toInt(), 2);
353 
354     QCOMPARE(buffersSpy.count(), 1);
355     QCOMPARE(buffersSpy.last().at(0).value<QList<IrcBuffer*> >(), QList<IrcBuffer*>() << b << d);
356 
357     QCOMPARE(channelsSpy.count(), 1);
358     QCOMPARE(channelsSpy.last().at(0).toStringList(), QStringList() << "#b");
359 
360     QCOMPARE(modelAboutToBeResetSpy.count(), 1);
361     QCOMPARE(modelResetSpy.count(), 1);
362 
363     b->setPersistent(false);
364 
365     countSpy.clear();
366     buffersSpy.clear();
367     channelsSpy.clear();
368     modelAboutToBeResetSpy.clear();
369     modelResetSpy.clear();
370 
371     // #b, d*
372     model.clear();
373 
374     QCOMPARE(model.count(), 1);
375     QCOMPARE(model.buffers(), QList<IrcBuffer*>() << d);
376     QCOMPARE(model.channels(), QStringList());
377 
378     QCOMPARE(model.get(0), d.data());
379     QVERIFY(!model.get(1));
380     QVERIFY(!model.find("#b"));
381     QVERIFY(model.find("d"));
382     QVERIFY(!model.contains("#b"));
383     QVERIFY(model.contains("d"));
384 
385     QVERIFY(!b);
386     QVERIFY(d);
387 
388     QCOMPARE(countSpy.count(), 1);
389     QCOMPARE(countSpy.last().at(0).toInt(), 1);
390 
391     QCOMPARE(buffersSpy.count(), 1);
392     QCOMPARE(buffersSpy.last().at(0).value<QList<IrcBuffer*> >(), QList<IrcBuffer*>() << d);
393 
394     QCOMPARE(channelsSpy.count(), 1);
395     QCOMPARE(channelsSpy.last().at(0).toStringList(), QStringList());
396 
397     QCOMPARE(modelAboutToBeResetSpy.count(), 1);
398     QCOMPARE(modelResetSpy.count(), 1);
399 
400     d->setPersistent(false);
401 
402     countSpy.clear();
403     buffersSpy.clear();
404     channelsSpy.clear();
405     modelAboutToBeResetSpy.clear();
406     modelResetSpy.clear();
407 
408     // d
409     model.clear();
410 
411     QCOMPARE(model.count(), 0);
412     QCOMPARE(model.buffers(), QList<IrcBuffer*>());
413     QCOMPARE(model.channels(), QStringList());
414 
415     QVERIFY(!model.get(0));
416     QVERIFY(!model.find("d"));
417     QVERIFY(!model.contains("d"));
418 
419     QVERIFY(!d);
420 
421     QCOMPARE(countSpy.count(), 1);
422     QCOMPARE(countSpy.last().at(0).toInt(), 0);
423 
424     QCOMPARE(buffersSpy.count(), 1);
425     QCOMPARE(buffersSpy.last().at(0).value<QList<IrcBuffer*> >(), QList<IrcBuffer*>());
426 
427     QCOMPARE(channelsSpy.count(), 0);
428 
429     QCOMPARE(modelAboutToBeResetSpy.count(), 1);
430     QCOMPARE(modelResetSpy.count(), 1);
431 
432     countSpy.clear();
433     buffersSpy.clear();
434     channelsSpy.clear();
435     modelAboutToBeResetSpy.clear();
436     modelResetSpy.clear();
437 
438     // <empty>
439     model.clear();
440 
441     QCOMPARE(countSpy.count(), 0);
442     QCOMPARE(buffersSpy.count(), 0);
443     QCOMPARE(channelsSpy.count(), 0);
444     QCOMPARE(modelAboutToBeResetSpy.count(), 0);
445     QCOMPARE(modelResetSpy.count(), 0);
446 
447     QPointer<IrcBuffer> e = model.add("e");
448     QPointer<IrcBuffer> f = model.add("f");
449 
450     e->setPersistent(true);
451     f->setPersistent(true);
452 
453     countSpy.clear();
454     buffersSpy.clear();
455     channelsSpy.clear();
456     modelAboutToBeResetSpy.clear();
457     modelResetSpy.clear();
458 
459     // e*, f*
460     model.clear();
461 
462     QVERIFY(e);
463     QVERIFY(f);
464 
465     QCOMPARE(countSpy.count(), 0);
466     QCOMPARE(buffersSpy.count(), 0);
467     QCOMPARE(channelsSpy.count(), 0);
468     QCOMPARE(modelAboutToBeResetSpy.count(), 0);
469     QCOMPARE(modelResetSpy.count(), 0);
470 
471     qDeleteAll(model.buffers());
472 
473     QCOMPARE(model.count(), 0);
474     QCOMPARE(model.buffers(), QList<IrcBuffer*>());
475     QCOMPARE(model.channels(), QStringList());
476 
477     QVERIFY(!model.get(0));
478     QVERIFY(!model.find("e"));
479     QVERIFY(!model.find("f"));
480     QVERIFY(!model.contains("e"));
481     QVERIFY(!model.contains("f"));
482 
483     QVERIFY(!e);
484     QVERIFY(!f);
485 
486     QCOMPARE(countSpy.count(), 2);
487     QCOMPARE(countSpy.at(0).at(0).toInt(), 1);
488     QCOMPARE(countSpy.at(1).at(0).toInt(), 0);
489 
490     QCOMPARE(buffersSpy.count(), 2);
491     QCOMPARE(buffersSpy.at(0).at(0).value<QList<IrcBuffer*> >().count(), 1);
492     QCOMPARE(buffersSpy.at(1).at(0).value<QList<IrcBuffer*> >(), QList<IrcBuffer*>());
493 
494     QCOMPARE(channelsSpy.count(), 0);
495 
496     QCOMPARE(modelAboutToBeResetSpy.count(), 0);
497     QCOMPARE(modelResetSpy.count(), 0);
498 }
499 
testPersistent()500 void tst_IrcBufferModel::testPersistent()
501 {
502     IrcBufferModel model(connection);
503     connection->open();
504     QVERIFY(waitForOpened());
505     QVERIFY(waitForWritten(tst_IrcData::welcome()));
506 
507     QVERIFY(waitForWritten(":communi!communi@hidd.en JOIN :#communi"));
508     QCOMPARE(model.count(), 1);
509 
510     QPointer<IrcChannel> channel = model.get(0)->toChannel();
511     QVERIFY(channel);
512 
513     QVERIFY(!model.isPersistent());
514     QVERIFY(!channel->isPersistent());
515     QVERIFY(waitForWritten(":communi!communi@hidd.en PART :#communi"));
516     QVERIFY(model.isEmpty());
517     QVERIFY(channel); // deleteLater()'d
518     QCoreApplication::sendPostedEvents(channel, QEvent::DeferredDelete);
519     QVERIFY(!channel); // deleteLater()'d
520 
521     QVERIFY(waitForWritten(":communi!communi@hidd.en JOIN :#communi"));
522     QCOMPARE(model.count(), 1);
523     channel = model.get(0)->toChannel();
524     QVERIFY(channel);
525 
526     model.setPersistent(true);
527     QVERIFY(model.isPersistent());
528     QVERIFY(!channel->isPersistent());
529     QVERIFY(waitForWritten(":communi!communi@hidd.en PART :#communi"));
530     QVERIFY(channel);
531     QCOMPARE(model.count(), 1);
532 
533     channel->setPersistent(true);
534     QVERIFY(model.isPersistent());
535     QVERIFY(channel->isPersistent());
536     QVERIFY(waitForWritten(":communi!communi@hidd.en PART :#communi"));
537     QVERIFY(channel);
538     QCOMPARE(model.count(), 1);
539 
540     model.setPersistent(false);
541     QVERIFY(!model.isPersistent());
542     QVERIFY(channel->isPersistent());
543     QVERIFY(waitForWritten(":communi!communi@hidd.en PART :#communi"));
544     QVERIFY(channel);
545     QCOMPARE(model.count(), 1);
546 
547     channel->setPersistent(false);
548     QVERIFY(!model.isPersistent());
549     QVERIFY(!channel->isPersistent());
550     QVERIFY(waitForWritten(":communi!communi@hidd.en PART :#communi"));
551     QVERIFY(model.isEmpty());
552     QVERIFY(channel); // deleteLater()'d
553     QCoreApplication::sendPostedEvents(channel, QEvent::DeferredDelete);
554     QVERIFY(!channel); // deleteLater()'d
555 }
556 
testPrototypes()557 void tst_IrcBufferModel::testPrototypes()
558 {
559     IrcBufferModel model;
560 
561     QSignalSpy bufferProtoSpy(&model, SIGNAL(bufferPrototypeChanged(IrcBuffer*)));
562     QSignalSpy channelProtoSpy(&model, SIGNAL(channelPrototypeChanged(IrcChannel*)));
563     QVERIFY(bufferProtoSpy.isValid());
564     QVERIFY(channelProtoSpy.isValid());
565 
566     model.setBufferPrototype(nullptr);
567     QVERIFY(model.bufferPrototype());
568     QCOMPARE(bufferProtoSpy.count(), 1);
569 
570     model.setChannelPrototype(nullptr);
571     QVERIFY(model.channelPrototype());
572     QCOMPARE(channelProtoSpy.count(), 1);
573 
574     IrcBuffer* bufferProto = new IrcBuffer(&model);
575     model.setBufferPrototype(bufferProto);
576     QCOMPARE(model.bufferPrototype(), bufferProto);
577     QCOMPARE(bufferProtoSpy.count(), 2);
578 
579     IrcChannel* channelProto = new IrcChannel(&model);
580     model.setChannelPrototype(channelProto);
581     QCOMPARE(model.channelPrototype(), channelProto);
582     QCOMPARE(channelProtoSpy.count(), 2);
583 }
584 
testChanges()585 void tst_IrcBufferModel::testChanges()
586 {
587     IrcBufferModel bufferModel;
588 
589     // IrcBufferModel signals
590     QSignalSpy countChangedSpy(&bufferModel, SIGNAL(countChanged(int)));
591     QSignalSpy addedSpy(&bufferModel, SIGNAL(added(IrcBuffer*)));
592     QSignalSpy removedSpy(&bufferModel, SIGNAL(removed(IrcBuffer*)));
593     QSignalSpy aboutToBeAddedSpy(&bufferModel, SIGNAL(aboutToBeAdded(IrcBuffer*)));
594     QSignalSpy aboutToBeRemovedSpy(&bufferModel, SIGNAL(aboutToBeRemoved(IrcBuffer*)));
595     QSignalSpy buffersChangedSpy(&bufferModel, SIGNAL(buffersChanged(QList<IrcBuffer*>)));
596     QSignalSpy channelsChangedSpy(&bufferModel, SIGNAL(channelsChanged(QStringList)));
597 
598     QVERIFY(countChangedSpy.isValid());
599     QVERIFY(addedSpy.isValid());
600     QVERIFY(removedSpy.isValid());
601     QVERIFY(aboutToBeAddedSpy.isValid());
602     QVERIFY(aboutToBeRemovedSpy.isValid());
603     QVERIFY(buffersChangedSpy.isValid());
604     QVERIFY(channelsChangedSpy.isValid());
605 
606     int countChangedCount = 0;
607     int aboutToBeAddedCount = 0, addedCount = 0;
608     int aboutToBeRemovedCount = 0, removedCount = 0;
609     int buffersChangedCount = 0;
610     int channelsChangedCount = 0;
611 
612     QSignalSpy connectionChangedSpy(&bufferModel, SIGNAL(connectionChanged(IrcConnection*)));
613     QSignalSpy networkChangedSpy(&bufferModel, SIGNAL(networkChanged(IrcNetwork*)));
614     QSignalSpy messageIgnoredSpy(&bufferModel, SIGNAL(messageIgnored(IrcMessage*)));
615 
616     QVERIFY(connectionChangedSpy.isValid());
617     QVERIFY(networkChangedSpy.isValid());
618     QVERIFY(messageIgnoredSpy.isValid());
619 
620     int connectionChangedCount = 0;
621     int networkChangedCount = 0;
622     int messageIgnoredCount = 0;
623 
624     // relevant QAbstractItemModel signals
625     QSignalSpy dataChangedSpy(&bufferModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)));
626     QSignalSpy layoutAboutToBeChangedSpy(&bufferModel, SIGNAL(layoutAboutToBeChanged()));
627     QSignalSpy layoutChangedSpy(&bufferModel, SIGNAL(layoutChanged()));
628     QSignalSpy rowsAboutToBeInsertedSpy(&bufferModel, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int)));
629     QSignalSpy rowsInsertedSpy(&bufferModel, SIGNAL(rowsInserted(QModelIndex,int,int)));
630     QSignalSpy rowsAboutToBeRemovedSpy(&bufferModel, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)));
631     QSignalSpy rowsRemovedSpy(&bufferModel, SIGNAL(rowsRemoved(QModelIndex,int,int)));
632 
633     QVERIFY(dataChangedSpy.isValid());
634     QVERIFY(layoutAboutToBeChangedSpy.isValid());
635     QVERIFY(layoutChangedSpy.isValid());
636     QVERIFY(rowsAboutToBeInsertedSpy.isValid());
637     QVERIFY(rowsInsertedSpy.isValid());
638     QVERIFY(rowsAboutToBeRemovedSpy.isValid());
639     QVERIFY(rowsRemovedSpy.isValid());
640 
641     int dataChangedCount = 0;
642     int layoutAboutToBeChangedCount = 0, layoutChangedCount = 0;
643     int rowsAboutToBeInsertedCount = 0, rowsInsertedCount = 0;
644     int rowsAboutToBeRemovedCount = 0, rowsRemovedCount = 0;
645 
646     bufferModel.setConnection(connection);
647     QCOMPARE(connectionChangedSpy.count(), ++connectionChangedCount);
648     QCOMPARE(networkChangedSpy.count(), ++networkChangedCount);
649 
650     connection->open();
651     QVERIFY(waitForOpened());
652     QVERIFY(waitForWritten(tst_IrcData::welcome()));
653 
654     messageIgnoredCount = tst_IrcData::welcome().split('\n').count(); // N lines + a combined motd msg
655 
656     QCOMPARE(bufferModel.count(), 0);
657     QCOMPARE(messageIgnoredSpy.count(), messageIgnoredCount);
658 
659     QVERIFY(waitForWritten(":communi!communi@hidd.en JOIN :#communi"));
660     QCOMPARE(messageIgnoredSpy.count(), messageIgnoredCount);
661 
662     QCOMPARE(bufferModel.count(), 1);
663 
664     QPointer<IrcChannel> communi = bufferModel.get(0)->toChannel();
665     QVERIFY(communi);
666     QCOMPARE(communi->title(), QString("#communi"));
667     QCOMPARE(communi->name(), QString("communi"));
668     QCOMPARE(communi->prefix(), QString("#"));
669 
670     int previousIndex = -1;
671 
672     QList<IrcBuffer*> buffers = QList<IrcBuffer*>() << communi;
673     QStringList channels = QStringList() << "#communi";
674 
675     int nextIndex = buffers.indexOf(communi);
676 
677     QCOMPARE(bufferModel.count(), buffers.count());
678     for (int i = 0; i < bufferModel.count(); ++i) {
679         QCOMPARE(bufferModel.get(i), buffers.at(i));
680         QCOMPARE(bufferModel.index(i).data(Irc::BufferRole).value<IrcBuffer*>(), buffers.at(i));
681         QCOMPARE(bufferModel.index(i).data(Irc::ChannelRole).value<IrcChannel*>(), buffers.at(i)->toChannel());
682     }
683     QCOMPARE(bufferModel.channels(), channels);
684 
685     QCOMPARE(countChangedSpy.count(), ++countChangedCount);
686     QCOMPARE(countChangedSpy.last().at(0).toInt(), buffers.count());
687 
688     QCOMPARE(aboutToBeAddedSpy.count(), ++aboutToBeAddedCount);
689     QCOMPARE(aboutToBeAddedSpy.last().at(0).value<IrcBuffer*>(), communi.data());
690 
691     QCOMPARE(addedSpy.count(), ++addedCount);
692     QCOMPARE(addedSpy.last().at(0).value<IrcBuffer*>(), communi.data());
693 
694     QCOMPARE(buffersChangedSpy.count(), ++buffersChangedCount);
695     QCOMPARE(buffersChangedSpy.last().at(0).value<QList<IrcBuffer*> >(), buffers);
696 
697     QCOMPARE(channelsChangedSpy.count(), ++channelsChangedCount);
698     QCOMPARE(channelsChangedSpy.last().at(0).toStringList(), channels);
699 
700     QCOMPARE(rowsAboutToBeRemovedSpy.count(), rowsAboutToBeRemovedCount);
701 
702     QCOMPARE(rowsRemovedSpy.count(), rowsRemovedCount);
703 
704     QCOMPARE(rowsAboutToBeInsertedSpy.count(), ++rowsAboutToBeInsertedCount);
705     QCOMPARE(rowsAboutToBeInsertedSpy.last().at(0).value<QModelIndex>(), QModelIndex());
706     QCOMPARE(rowsAboutToBeInsertedSpy.last().at(1).toInt(), nextIndex);
707     QCOMPARE(rowsAboutToBeInsertedSpy.last().at(2).toInt(), nextIndex);
708 
709     QCOMPARE(rowsInsertedSpy.count(), ++rowsInsertedCount);
710     QCOMPARE(rowsInsertedSpy.last().at(0).value<QModelIndex>(), QModelIndex());
711     QCOMPARE(rowsInsertedSpy.last().at(1).toInt(), nextIndex);
712     QCOMPARE(rowsInsertedSpy.last().at(2).toInt(), nextIndex);
713 
714     QVERIFY(waitForWritten(":ChanServ!ChanServ@services. NOTICE communi :fake..."));
715     QCOMPARE(messageIgnoredSpy.count(), ++messageIgnoredCount);
716 
717     QCOMPARE(bufferModel.count(), buffers.count());
718     QCOMPARE(bufferModel.buffers(), buffers);
719     QCOMPARE(bufferModel.channels(), channels);
720 
721     QCOMPARE(countChangedSpy.count(), countChangedCount);
722     QCOMPARE(aboutToBeAddedSpy.count(), aboutToBeAddedCount);
723     QCOMPARE(addedSpy.count(), addedCount);
724     QCOMPARE(buffersChangedSpy.count(), buffersChangedCount);
725     QCOMPARE(channelsChangedSpy.count(), channelsChangedCount);
726     QCOMPARE(rowsAboutToBeRemovedSpy.count(), rowsAboutToBeRemovedCount);
727     QCOMPARE(rowsRemovedSpy.count(), rowsRemovedCount);
728     QCOMPARE(rowsAboutToBeInsertedSpy.count(), rowsAboutToBeInsertedCount);
729     QCOMPARE(rowsInsertedSpy.count(), rowsInsertedCount);
730 
731     QVERIFY(waitForWritten(":ChanServ!ChanServ@services. PRIVMSG communi :fake..."));
732     QCOMPARE(messageIgnoredSpy.count(), messageIgnoredCount);
733 
734     QPointer<IrcBuffer> ChanServ = bufferModel.get(1);
735     QVERIFY(ChanServ);
736     QCOMPARE(ChanServ->title(), QString("ChanServ"));
737     QCOMPARE(ChanServ->name(), QString("ChanServ"));
738     QCOMPARE(ChanServ->prefix(), QString());
739 
740     previousIndex = -1;
741 
742     buffers = QList<IrcBuffer*>() << communi << ChanServ;
743     channels = QStringList() << "#communi";
744 
745     nextIndex = buffers.indexOf(ChanServ);
746 
747     QCOMPARE(bufferModel.count(), buffers.count());
748     QCOMPARE(bufferModel.buffers(), buffers);
749     QCOMPARE(bufferModel.channels(), channels);
750 
751     QCOMPARE(bufferModel.count(), buffers.count());
752     for (int i = 0; i < bufferModel.count(); ++i) {
753         QCOMPARE(bufferModel.get(i), buffers.at(i));
754         QCOMPARE(bufferModel.index(i).data(Irc::BufferRole).value<IrcBuffer*>(), buffers.at(i));
755         QCOMPARE(bufferModel.index(i).data(Irc::ChannelRole).value<IrcChannel*>(), buffers.at(i)->toChannel());
756     }
757 
758     QCOMPARE(countChangedSpy.count(), ++countChangedCount);
759     QCOMPARE(countChangedSpy.last().at(0).toInt(), buffers.count());
760 
761     QCOMPARE(aboutToBeAddedSpy.count(), ++aboutToBeAddedCount);
762     QCOMPARE(aboutToBeAddedSpy.last().at(0).value<IrcBuffer*>(), ChanServ.data());
763 
764     QCOMPARE(addedSpy.count(), ++addedCount);
765     QCOMPARE(addedSpy.last().at(0).value<IrcBuffer*>(), ChanServ.data());
766 
767     QCOMPARE(buffersChangedSpy.count(), ++buffersChangedCount);
768     QCOMPARE(buffersChangedSpy.last().at(0).value<QList<IrcBuffer*> >(), buffers);
769 
770     QCOMPARE(channelsChangedSpy.count(), channelsChangedCount);
771 
772     QCOMPARE(rowsAboutToBeRemovedSpy.count(), rowsAboutToBeRemovedCount);
773 
774     QCOMPARE(rowsRemovedSpy.count(), rowsRemovedCount);
775 
776     QCOMPARE(rowsAboutToBeInsertedSpy.count(), ++rowsAboutToBeInsertedCount);
777     QCOMPARE(rowsAboutToBeInsertedSpy.last().at(0).value<QModelIndex>(), QModelIndex());
778     QCOMPARE(rowsAboutToBeInsertedSpy.last().at(1).toInt(), nextIndex);
779     QCOMPARE(rowsAboutToBeInsertedSpy.last().at(2).toInt(), nextIndex);
780 
781     QCOMPARE(rowsInsertedSpy.count(), ++rowsInsertedCount);
782     QCOMPARE(rowsInsertedSpy.last().at(0).value<QModelIndex>(), QModelIndex());
783     QCOMPARE(rowsInsertedSpy.last().at(1).toInt(), nextIndex);
784     QCOMPARE(rowsInsertedSpy.last().at(2).toInt(), nextIndex);
785 
786     QVERIFY(waitForWritten(":ChanServ!ChanServ@services. NOTICE communi :fake..."));
787     QCOMPARE(messageIgnoredSpy.count(), messageIgnoredCount);
788 
789     QCOMPARE(bufferModel.count(), buffers.count());
790     QCOMPARE(bufferModel.buffers(), buffers);
791     QCOMPARE(bufferModel.channels(), channels);
792 
793     QCOMPARE(bufferModel.count(), buffers.count());
794     for (int i = 0; i < bufferModel.count(); ++i) {
795         QCOMPARE(bufferModel.get(i), buffers.at(i));
796         QCOMPARE(bufferModel.index(i).data(Irc::BufferRole).value<IrcBuffer*>(), buffers.at(i));
797         QCOMPARE(bufferModel.index(i).data(Irc::ChannelRole).value<IrcChannel*>(), buffers.at(i)->toChannel());
798     }
799 
800     QCOMPARE(countChangedSpy.count(), countChangedCount);
801     QCOMPARE(aboutToBeAddedSpy.count(), aboutToBeAddedCount);
802     QCOMPARE(addedSpy.count(), addedCount);
803     QCOMPARE(buffersChangedSpy.count(), buffersChangedCount);
804     QCOMPARE(channelsChangedSpy.count(), channelsChangedCount);
805     QCOMPARE(rowsAboutToBeRemovedSpy.count(), rowsAboutToBeRemovedCount);
806     QCOMPARE(rowsRemovedSpy.count(), rowsRemovedCount);
807     QCOMPARE(rowsAboutToBeInsertedSpy.count(), rowsAboutToBeInsertedCount);
808     QCOMPARE(rowsInsertedSpy.count(), rowsInsertedCount);
809 
810     QVERIFY(waitForWritten(":communi!communi@hidd.en JOIN :#freenode"));
811     QCOMPARE(messageIgnoredSpy.count(), messageIgnoredCount);
812 
813     QPointer<IrcChannel> freenode = bufferModel.get(2)->toChannel();
814     QVERIFY(freenode);
815     QCOMPARE(freenode->title(), QString("#freenode"));
816     QCOMPARE(freenode->name(), QString("freenode"));
817     QCOMPARE(freenode->prefix(), QString("#"));
818 
819     previousIndex = -1;
820 
821     buffers = QList<IrcBuffer*>() << communi << ChanServ << freenode;
822     channels = QStringList() << "#communi" << "#freenode";
823 
824     nextIndex = buffers.indexOf(freenode);
825 
826     QCOMPARE(bufferModel.count(), buffers.count());
827     QCOMPARE(bufferModel.buffers(), buffers);
828     QCOMPARE(bufferModel.channels(), channels);
829 
830     for (int i = 0; i < bufferModel.count(); ++i) {
831         QCOMPARE(bufferModel.get(i), buffers.at(i));
832         QCOMPARE(bufferModel.index(i).data(Irc::BufferRole).value<IrcBuffer*>(), buffers.at(i));
833         QCOMPARE(bufferModel.index(i).data(Irc::ChannelRole).value<IrcChannel*>(), buffers.at(i)->toChannel());
834     }
835 
836     QCOMPARE(countChangedSpy.count(), ++countChangedCount);
837     QCOMPARE(countChangedSpy.last().at(0).toInt(), buffers.count());
838 
839     QCOMPARE(aboutToBeAddedSpy.count(), ++aboutToBeAddedCount);
840     QCOMPARE(aboutToBeAddedSpy.last().at(0).value<IrcBuffer*>(), freenode.data());
841 
842     QCOMPARE(addedSpy.count(), ++addedCount);
843     QCOMPARE(addedSpy.last().at(0).value<IrcBuffer*>(), freenode.data());
844 
845     QCOMPARE(buffersChangedSpy.count(), ++buffersChangedCount);
846     QCOMPARE(buffersChangedSpy.last().at(0).value<QList<IrcBuffer*> >(), buffers);
847 
848     QCOMPARE(channelsChangedSpy.count(), ++channelsChangedCount);
849     QCOMPARE(channelsChangedSpy.last().at(0).toStringList(), channels);
850 
851     QCOMPARE(rowsAboutToBeRemovedSpy.count(), rowsAboutToBeRemovedCount);
852 
853     QCOMPARE(rowsRemovedSpy.count(), rowsRemovedCount);
854 
855     QCOMPARE(rowsAboutToBeInsertedSpy.count(), ++rowsAboutToBeInsertedCount);
856     QCOMPARE(rowsAboutToBeInsertedSpy.last().at(0).value<QModelIndex>(), QModelIndex());
857     QCOMPARE(rowsAboutToBeInsertedSpy.last().at(1).toInt(), nextIndex);
858     QCOMPARE(rowsAboutToBeInsertedSpy.last().at(2).toInt(), nextIndex);
859 
860     QCOMPARE(rowsInsertedSpy.count(), ++rowsInsertedCount);
861     QCOMPARE(rowsInsertedSpy.last().at(0).value<QModelIndex>(), QModelIndex());
862     QCOMPARE(rowsInsertedSpy.last().at(1).toInt(), nextIndex);
863     QCOMPARE(rowsInsertedSpy.last().at(2).toInt(), nextIndex);
864 
865     bufferModel.setSortMethod(Irc::SortByTitle);
866     QCOMPARE(layoutAboutToBeChangedSpy.count(), ++layoutAboutToBeChangedCount);
867     QCOMPARE(layoutChangedSpy.count(), ++layoutChangedCount);
868 
869     previousIndex = -1;
870 
871     // Irc::SortByTitle
872     buffers = QList<IrcBuffer*>() << communi << freenode << ChanServ;
873     channels = QStringList() << "#communi" << "#freenode";
874 
875     nextIndex = -1;
876 
877     QCOMPARE(bufferModel.count(), buffers.count());
878     QCOMPARE(bufferModel.buffers(), buffers);
879     QCOMPARE(bufferModel.channels(), channels);
880 
881     for (int i = 0; i < bufferModel.count(); ++i) {
882         QCOMPARE(bufferModel.get(i), buffers.at(i));
883         QCOMPARE(bufferModel.index(i).data(Irc::BufferRole).value<IrcBuffer*>(), buffers.at(i));
884         QCOMPARE(bufferModel.index(i).data(Irc::ChannelRole).value<IrcChannel*>(), buffers.at(i)->toChannel());
885     }
886 
887     bufferModel.setSortMethod(Irc::SortByName);
888     QCOMPARE(layoutAboutToBeChangedSpy.count(), ++layoutAboutToBeChangedCount);
889     QCOMPARE(layoutChangedSpy.count(), ++layoutChangedCount);
890 
891     bufferModel.setSortOrder(Qt::DescendingOrder);
892     QCOMPARE(layoutAboutToBeChangedSpy.count(), ++layoutAboutToBeChangedCount);
893     QCOMPARE(layoutChangedSpy.count(), ++layoutChangedCount);
894 
895     previousIndex = -1;
896 
897     // Irc::SortByName, Qt::DescendingOrder
898     buffers = QList<IrcBuffer*>() << freenode << communi << ChanServ;
899     channels = QStringList() << "#communi" << "#freenode";
900 
901     nextIndex = -1;
902 
903     QCOMPARE(bufferModel.count(), buffers.count());
904     QCOMPARE(bufferModel.buffers(), buffers);
905     QCOMPARE(bufferModel.channels(), channels);
906 
907     for (int i = 0; i < bufferModel.count(); ++i) {
908         QCOMPARE(bufferModel.get(i), buffers.at(i));
909         QCOMPARE(bufferModel.index(i).data(Irc::BufferRole).value<IrcBuffer*>(), buffers.at(i));
910         QCOMPARE(bufferModel.index(i).data(Irc::ChannelRole).value<IrcChannel*>(), buffers.at(i)->toChannel());
911     }
912 
913     QVERIFY(waitForWritten(":qtassistant!qtassistant@hidd.en PRIVMSG communi :hola"));
914     QCOMPARE(messageIgnoredSpy.count(), messageIgnoredCount);
915 
916     QPointer<IrcBuffer> qtassistant = bufferModel.get(0);
917     QVERIFY(qtassistant);
918     QCOMPARE(qtassistant->title(), QString("qtassistant"));
919     QCOMPARE(qtassistant->name(), QString("qtassistant"));
920     QCOMPARE(qtassistant->prefix(), QString());
921 
922     previousIndex = -1;
923 
924     // Irc::SortByName, Qt::DescendingOrder
925     buffers = QList<IrcBuffer*>() << qtassistant << freenode << communi << ChanServ;
926     channels = QStringList() << "#communi" << "#freenode";
927 
928     nextIndex = buffers.indexOf(qtassistant);
929 
930     QCOMPARE(bufferModel.count(), buffers.count());
931     QCOMPARE(bufferModel.buffers(), buffers);
932     QCOMPARE(bufferModel.channels(), channels);
933 
934     for (int i = 0; i < bufferModel.count(); ++i) {
935         QCOMPARE(bufferModel.get(i), buffers.at(i));
936         QCOMPARE(bufferModel.index(i).data(Irc::BufferRole).value<IrcBuffer*>(), buffers.at(i));
937         QCOMPARE(bufferModel.index(i).data(Irc::ChannelRole).value<IrcChannel*>(), buffers.at(i)->toChannel());
938     }
939 
940     QCOMPARE(countChangedSpy.count(), ++countChangedCount);
941     QCOMPARE(countChangedSpy.last().at(0).toInt(), buffers.count());
942 
943     QCOMPARE(aboutToBeAddedSpy.count(), ++aboutToBeAddedCount);
944     QCOMPARE(aboutToBeAddedSpy.last().at(0).value<IrcBuffer*>(), qtassistant.data());
945 
946     QCOMPARE(addedSpy.count(), ++addedCount);
947     QCOMPARE(addedSpy.last().at(0).value<IrcBuffer*>(), qtassistant.data());
948 
949     QCOMPARE(buffersChangedSpy.count(), ++buffersChangedCount);
950     QCOMPARE(buffersChangedSpy.last().at(0).value<QList<IrcBuffer*> >(), buffers);
951 
952     QCOMPARE(channelsChangedSpy.count(), channelsChangedCount);
953 
954     QCOMPARE(rowsAboutToBeRemovedSpy.count(), rowsAboutToBeRemovedCount);
955 
956     QCOMPARE(rowsRemovedSpy.count(), rowsRemovedCount);
957 
958     QCOMPARE(rowsAboutToBeInsertedSpy.count(), ++rowsAboutToBeInsertedCount);
959     QCOMPARE(rowsAboutToBeInsertedSpy.last().at(0).value<QModelIndex>(), QModelIndex());
960     QCOMPARE(rowsAboutToBeInsertedSpy.last().at(1).toInt(), nextIndex);
961     QCOMPARE(rowsAboutToBeInsertedSpy.last().at(2).toInt(), nextIndex);
962 
963     QCOMPARE(rowsInsertedSpy.count(), ++rowsInsertedCount);
964     QCOMPARE(rowsInsertedSpy.last().at(0).value<QModelIndex>(), QModelIndex());
965     QCOMPARE(rowsInsertedSpy.last().at(1).toInt(), nextIndex);
966     QCOMPARE(rowsInsertedSpy.last().at(2).toInt(), nextIndex);
967 
968     QSignalSpy titleChangedSpy(qtassistant, SIGNAL(titleChanged(QString)));
969     QSignalSpy nameChangedSpy(qtassistant, SIGNAL(nameChanged(QString)));
970     QSignalSpy prefixChangedSpy(qtassistant, SIGNAL(prefixChanged(QString)));
971 
972     QVERIFY(titleChangedSpy.isValid());
973     QVERIFY(nameChangedSpy.isValid());
974     QVERIFY(prefixChangedSpy.isValid());
975 
976     int titleChangedCount = 0;
977     int nameChangedCount = 0;
978     int prefixChangedCount = 0;
979 
980     QVERIFY(waitForWritten(":qtassistant!qtassistant@hidd.en NICK assistant :hola"));
981     QCOMPARE(messageIgnoredSpy.count(), messageIgnoredCount);
982 
983     QCOMPARE(qtassistant->title(), QString("assistant"));
984     QCOMPARE(qtassistant->name(), QString("assistant"));
985     QCOMPARE(qtassistant->prefix(), QString());
986 
987     QCOMPARE(titleChangedSpy.count(), ++titleChangedCount);
988     QCOMPARE(nameChangedSpy.count(), ++nameChangedCount);
989     QCOMPARE(prefixChangedSpy.count(), prefixChangedCount);
990 
991     previousIndex = buffers.indexOf(qtassistant);
992 
993     // Irc::SortByName, Qt::DescendingOrder
994     buffers = QList<IrcBuffer*>() << freenode << communi << ChanServ << qtassistant; // qtassistant=assistant
995     channels = QStringList() << "#communi" << "#freenode";
996 
997     nextIndex = buffers.indexOf(qtassistant);
998 
999     QCOMPARE(bufferModel.count(), buffers.count());
1000     QCOMPARE(bufferModel.buffers(), buffers);
1001     QCOMPARE(bufferModel.channels(), channels);
1002 
1003     for (int i = 0; i < bufferModel.count(); ++i) {
1004         QCOMPARE(bufferModel.get(i), buffers.at(i));
1005         QCOMPARE(bufferModel.index(i).data(Irc::BufferRole).value<IrcBuffer*>(), buffers.at(i));
1006         QCOMPARE(bufferModel.index(i).data(Irc::ChannelRole).value<IrcChannel*>(), buffers.at(i)->toChannel());
1007     }
1008 
1009     QCOMPARE(countChangedSpy.count(), countChangedCount);
1010 
1011     QCOMPARE(aboutToBeAddedSpy.count(), aboutToBeAddedCount);
1012 
1013     QCOMPARE(addedSpy.count(), addedCount);
1014 
1015     QCOMPARE(buffersChangedSpy.count(), ++buffersChangedCount);
1016     QCOMPARE(buffersChangedSpy.last().at(0).value<QList<IrcBuffer*> >(), buffers);
1017 
1018     QCOMPARE(channelsChangedSpy.count(), channelsChangedCount);
1019 
1020     QCOMPARE(dataChangedSpy.count(), ++dataChangedCount);
1021     QModelIndex topLeft = dataChangedSpy.last().at(0).value<QModelIndex>();
1022     QModelIndex bottomRight = dataChangedSpy.last().at(0).value<QModelIndex>();
1023     QVERIFY(!topLeft.parent().isValid());
1024     QVERIFY(topLeft.isValid());
1025     QVERIFY(bottomRight.isValid());
1026     QVERIFY(topLeft == bottomRight);
1027     QCOMPARE(topLeft.row(), previousIndex);
1028     QCOMPARE(topLeft.column(), 0);
1029 
1030     QCOMPARE(rowsAboutToBeRemovedSpy.count(), ++rowsAboutToBeRemovedCount);
1031     QCOMPARE(rowsAboutToBeRemovedSpy.last().at(0).value<QModelIndex>(), QModelIndex());
1032     QCOMPARE(rowsAboutToBeRemovedSpy.last().at(1).toInt(), previousIndex);
1033     QCOMPARE(rowsAboutToBeRemovedSpy.last().at(2).toInt(), previousIndex);
1034 
1035     QCOMPARE(rowsRemovedSpy.count(), ++rowsRemovedCount);
1036     QCOMPARE(rowsRemovedSpy.last().at(0).value<QModelIndex>(), QModelIndex());
1037     QCOMPARE(rowsRemovedSpy.last().at(1).toInt(), previousIndex);
1038     QCOMPARE(rowsRemovedSpy.last().at(2).toInt(), previousIndex);
1039 
1040     QCOMPARE(rowsAboutToBeInsertedSpy.count(), ++rowsAboutToBeInsertedCount);
1041     QCOMPARE(rowsAboutToBeInsertedSpy.last().at(0).value<QModelIndex>(), QModelIndex());
1042     QCOMPARE(rowsAboutToBeInsertedSpy.last().at(1).toInt(), nextIndex);
1043     QCOMPARE(rowsAboutToBeInsertedSpy.last().at(2).toInt(), nextIndex);
1044 
1045     QCOMPARE(rowsInsertedSpy.count(), ++rowsInsertedCount);
1046     QCOMPARE(rowsInsertedSpy.last().at(0).value<QModelIndex>(), QModelIndex());
1047     QCOMPARE(rowsInsertedSpy.last().at(1).toInt(), nextIndex);
1048     QCOMPARE(rowsInsertedSpy.last().at(2).toInt(), nextIndex);
1049 
1050     QVERIFY(waitForWritten(":communi!communi@hidd.en PART #communi"));
1051     QCOMPARE(messageIgnoredSpy.count(), messageIgnoredCount);
1052 
1053     QVERIFY(communi); // deleteLater()'d
1054 
1055     QCOMPARE(aboutToBeRemovedSpy.count(), ++aboutToBeRemovedCount);
1056     QCOMPARE(aboutToBeRemovedSpy.last().at(0).value<IrcBuffer*>(), communi.data());
1057 
1058     QCOMPARE(removedSpy.count(), ++removedCount);
1059     QCOMPARE(removedSpy.last().at(0).value<IrcBuffer*>(), communi.data());
1060 
1061     previousIndex = buffers.indexOf(communi);
1062 
1063     QCoreApplication::sendPostedEvents(communi, QEvent::DeferredDelete);
1064     QVERIFY(!communi);
1065 
1066     // Irc::SortByName, Qt::DescendingOrder
1067     buffers = QList<IrcBuffer*>() << freenode << ChanServ << qtassistant; // qtassistant=assistant
1068     channels = QStringList() << "#freenode";
1069 
1070     nextIndex = buffers.indexOf(communi);
1071 
1072     QCOMPARE(bufferModel.count(), buffers.count());
1073     QCOMPARE(bufferModel.buffers(), buffers);
1074     QCOMPARE(bufferModel.channels(), channels);
1075 
1076     for (int i = 0; i < bufferModel.count(); ++i) {
1077         QCOMPARE(bufferModel.get(i), buffers.at(i));
1078         QCOMPARE(bufferModel.index(i).data(Irc::BufferRole).value<IrcBuffer*>(), buffers.at(i));
1079         QCOMPARE(bufferModel.index(i).data(Irc::ChannelRole).value<IrcChannel*>(), buffers.at(i)->toChannel());
1080     }
1081 
1082     QCOMPARE(countChangedSpy.count(), ++countChangedCount);
1083     QCOMPARE(countChangedSpy.last().at(0).toInt(), buffers.count());
1084 
1085     QCOMPARE(aboutToBeAddedSpy.count(), aboutToBeAddedCount);
1086 
1087     QCOMPARE(addedSpy.count(), addedCount);
1088 
1089     QCOMPARE(buffersChangedSpy.count(), ++buffersChangedCount);
1090     QCOMPARE(buffersChangedSpy.last().at(0).value<QList<IrcBuffer*> >(), buffers);
1091 
1092     QCOMPARE(channelsChangedSpy.count(), ++channelsChangedCount);
1093     QCOMPARE(channelsChangedSpy.last().at(0).toStringList(), channels);
1094 
1095     QCOMPARE(dataChangedSpy.count(), dataChangedCount);
1096 
1097     QCOMPARE(rowsAboutToBeRemovedSpy.count(), ++rowsAboutToBeRemovedCount);
1098     QCOMPARE(rowsAboutToBeRemovedSpy.last().at(0).value<QModelIndex>(), QModelIndex());
1099     QCOMPARE(rowsAboutToBeRemovedSpy.last().at(1).toInt(), previousIndex);
1100     QCOMPARE(rowsAboutToBeRemovedSpy.last().at(2).toInt(), previousIndex);
1101 
1102     QCOMPARE(rowsRemovedSpy.count(), ++rowsRemovedCount);
1103     QCOMPARE(rowsRemovedSpy.last().at(0).value<QModelIndex>(), QModelIndex());
1104     QCOMPARE(rowsRemovedSpy.last().at(1).toInt(), previousIndex);
1105     QCOMPARE(rowsRemovedSpy.last().at(2).toInt(), previousIndex);
1106 
1107     QCOMPARE(rowsAboutToBeInsertedSpy.count(), rowsAboutToBeInsertedCount);
1108 
1109     QCOMPARE(rowsInsertedSpy.count(), rowsInsertedCount);
1110 
1111     // note: implicit replies are not targeted since 3.5
1112     waitForWritten(":moorcock.freenode.net 324 communi #freenode +s");
1113     QCOMPARE(messageIgnoredSpy.count(), ++messageIgnoredCount);
1114     QCOMPARE(freenode->mode(), QString("+s"));
1115 
1116     QVERIFY(waitForWritten(":jpnurmi!jpnurmi@qt/jpnurmi KICK #freenode communi"));
1117     QCOMPARE(messageIgnoredSpy.count(), messageIgnoredCount);
1118 
1119     QVERIFY(freenode); // deleteLater()'d
1120 
1121     QCOMPARE(aboutToBeRemovedSpy.count(), ++aboutToBeRemovedCount);
1122     QCOMPARE(aboutToBeRemovedSpy.last().at(0).value<IrcBuffer*>(), freenode.data());
1123 
1124     QCOMPARE(removedSpy.count(), ++removedCount);
1125     QCOMPARE(removedSpy.last().at(0).value<IrcBuffer*>(), freenode.data());
1126 
1127     previousIndex = buffers.indexOf(freenode);
1128 
1129     QCoreApplication::sendPostedEvents(freenode, QEvent::DeferredDelete);
1130     QVERIFY(!freenode);
1131 
1132     // Irc::SortByName, Qt::DescendingOrder
1133     buffers = QList<IrcBuffer*>() << ChanServ << qtassistant; // qtassistant=assistant
1134     channels = QStringList();
1135 
1136     nextIndex = buffers.indexOf(freenode);
1137 
1138     QCOMPARE(bufferModel.count(), buffers.count());
1139     QCOMPARE(bufferModel.buffers(), buffers);
1140     QCOMPARE(bufferModel.channels(), channels);
1141 
1142     for (int i = 0; i < bufferModel.count(); ++i) {
1143         QCOMPARE(bufferModel.get(i), buffers.at(i));
1144         QCOMPARE(bufferModel.index(i).data(Irc::BufferRole).value<IrcBuffer*>(), buffers.at(i));
1145         QCOMPARE(bufferModel.index(i).data(Irc::ChannelRole).value<IrcChannel*>(), buffers.at(i)->toChannel());
1146     }
1147 
1148     QCOMPARE(countChangedSpy.count(), ++countChangedCount);
1149     QCOMPARE(countChangedSpy.last().at(0).toInt(), buffers.count());
1150 
1151     QCOMPARE(aboutToBeAddedSpy.count(), aboutToBeAddedCount);
1152 
1153     QCOMPARE(addedSpy.count(), addedCount);
1154 
1155     QCOMPARE(buffersChangedSpy.count(), ++buffersChangedCount);
1156     QCOMPARE(buffersChangedSpy.last().at(0).value<QList<IrcBuffer*> >(), buffers);
1157 
1158     QCOMPARE(channelsChangedSpy.count(), ++channelsChangedCount);
1159     QCOMPARE(channelsChangedSpy.last().at(0).toStringList(), channels);
1160 
1161     QCOMPARE(dataChangedSpy.count(), dataChangedCount);
1162 
1163     QCOMPARE(rowsAboutToBeRemovedSpy.count(), ++rowsAboutToBeRemovedCount);
1164     QCOMPARE(rowsAboutToBeRemovedSpy.last().at(0).value<QModelIndex>(), QModelIndex());
1165     QCOMPARE(rowsAboutToBeRemovedSpy.last().at(1).toInt(), previousIndex);
1166     QCOMPARE(rowsAboutToBeRemovedSpy.last().at(2).toInt(), previousIndex);
1167 
1168     QCOMPARE(rowsRemovedSpy.count(), ++rowsRemovedCount);
1169     QCOMPARE(rowsRemovedSpy.last().at(0).value<QModelIndex>(), QModelIndex());
1170     QCOMPARE(rowsRemovedSpy.last().at(1).toInt(), previousIndex);
1171     QCOMPARE(rowsRemovedSpy.last().at(2).toInt(), previousIndex);
1172 
1173     QCOMPARE(rowsAboutToBeInsertedSpy.count(), rowsAboutToBeInsertedCount);
1174 
1175     QCOMPARE(rowsInsertedSpy.count(), rowsInsertedCount);
1176 
1177     QVERIFY(waitForWritten(":communi!communi@hidd.en PRIVMSG jpnurmi :echo"));
1178     QCOMPARE(messageIgnoredSpy.count(), messageIgnoredCount);
1179 
1180     QPointer<IrcBuffer> jpnurmi = bufferModel.get(0);
1181     QVERIFY(jpnurmi);
1182     QCOMPARE(jpnurmi->title(), QString("jpnurmi"));
1183     QCOMPARE(jpnurmi->name(), QString("jpnurmi"));
1184     QCOMPARE(jpnurmi->prefix(), QString());
1185 
1186     previousIndex = -1;
1187 
1188     // Irc::SortByName, Qt::DescendingOrder
1189     buffers = QList<IrcBuffer*>() << jpnurmi << ChanServ << qtassistant; // qtassistant=assistant
1190     channels = QStringList();
1191 
1192     nextIndex = buffers.indexOf(jpnurmi);
1193 
1194     QCOMPARE(bufferModel.count(), buffers.count());
1195     QCOMPARE(bufferModel.buffers(), buffers);
1196     QCOMPARE(bufferModel.channels(), channels);
1197 
1198     for (int i = 0; i < bufferModel.count(); ++i) {
1199         QCOMPARE(bufferModel.get(i), buffers.at(i));
1200         QCOMPARE(bufferModel.index(i).data(Irc::BufferRole).value<IrcBuffer*>(), buffers.at(i));
1201         QCOMPARE(bufferModel.index(i).data(Irc::ChannelRole).value<IrcChannel*>(), buffers.at(i)->toChannel());
1202     }
1203 
1204     QCOMPARE(countChangedSpy.count(), ++countChangedCount);
1205     QCOMPARE(countChangedSpy.last().at(0).toInt(), buffers.count());
1206 
1207     QCOMPARE(aboutToBeAddedSpy.count(), ++aboutToBeAddedCount);
1208     QCOMPARE(aboutToBeAddedSpy.last().at(0).value<IrcBuffer*>(), jpnurmi.data());
1209 
1210     QCOMPARE(addedSpy.count(), ++addedCount);
1211     QCOMPARE(addedSpy.last().at(0).value<IrcBuffer*>(), jpnurmi.data());
1212 
1213     QCOMPARE(buffersChangedSpy.count(), ++buffersChangedCount);
1214     QCOMPARE(buffersChangedSpy.last().at(0).value<QList<IrcBuffer*> >(), buffers);
1215 
1216     QCOMPARE(channelsChangedSpy.count(), channelsChangedCount);
1217 
1218     QCOMPARE(rowsAboutToBeRemovedSpy.count(), rowsAboutToBeRemovedCount);
1219 
1220     QCOMPARE(rowsRemovedSpy.count(), rowsRemovedCount);
1221 
1222     QCOMPARE(rowsAboutToBeInsertedSpy.count(), ++rowsAboutToBeInsertedCount);
1223     QCOMPARE(rowsAboutToBeInsertedSpy.last().at(0).value<QModelIndex>(), QModelIndex());
1224     QCOMPARE(rowsAboutToBeInsertedSpy.last().at(1).toInt(), nextIndex);
1225     QCOMPARE(rowsAboutToBeInsertedSpy.last().at(2).toInt(), nextIndex);
1226 
1227     QCOMPARE(rowsInsertedSpy.count(), ++rowsInsertedCount);
1228     QCOMPARE(rowsInsertedSpy.last().at(0).value<QModelIndex>(), QModelIndex());
1229     QCOMPARE(rowsInsertedSpy.last().at(1).toInt(), nextIndex);
1230     QCOMPARE(rowsInsertedSpy.last().at(2).toInt(), nextIndex);
1231 
1232     QVERIFY(waitForWritten(":communi!communi@hidd.en QUIT :bye"));
1233     QCOMPARE(messageIgnoredSpy.count(), messageIgnoredCount);
1234 
1235     serverSocket->close();
1236     QVERIFY(clientSocket->waitForDisconnected(100));
1237     QVERIFY(!connection->isConnected());
1238     QVERIFY(!connection->isActive());
1239 
1240     QCOMPARE(bufferModel.count(), buffers.count());
1241     QCOMPARE(bufferModel.buffers(), buffers);
1242     QCOMPARE(bufferModel.channels(), channels);
1243 
1244     for (int i = 0; i < bufferModel.count(); ++i) {
1245         QCOMPARE(bufferModel.get(i), buffers.at(i));
1246         QCOMPARE(bufferModel.index(i).data(Irc::BufferRole).value<IrcBuffer*>(), buffers.at(i));
1247         QCOMPARE(bufferModel.index(i).data(Irc::ChannelRole).value<IrcChannel*>(), buffers.at(i)->toChannel());
1248         QVERIFY(!buffers.at(i)->isActive());
1249     }
1250 
1251     QCOMPARE(countChangedSpy.count(), countChangedCount);
1252     QCOMPARE(aboutToBeAddedSpy.count(), aboutToBeAddedCount);
1253     QCOMPARE(addedSpy.count(), addedCount);
1254     QCOMPARE(buffersChangedSpy.count(), buffersChangedCount);
1255     QCOMPARE(channelsChangedSpy.count(), channelsChangedCount);
1256     QCOMPARE(dataChangedSpy.count(), dataChangedCount);
1257     QCOMPARE(rowsAboutToBeRemovedSpy.count(), rowsAboutToBeRemovedCount);
1258     QCOMPARE(rowsRemovedSpy.count(), rowsRemovedCount);
1259     QCOMPARE(rowsAboutToBeInsertedSpy.count(), rowsAboutToBeInsertedCount);
1260     QCOMPARE(rowsInsertedSpy.count(), rowsInsertedCount);
1261 }
1262 
testActive()1263 void tst_IrcBufferModel::testActive()
1264 {
1265     IrcBufferModel bufferModel;
1266     bufferModel.setConnection(connection);
1267 
1268     connection->open();
1269     QVERIFY(waitForOpened());
1270     QVERIFY(waitForWritten(tst_IrcData::welcome()));
1271 
1272     QVERIFY(waitForWritten(":communi!communi@hidd.en JOIN :#communi"));
1273 
1274     IrcChannel* channel = bufferModel.get(0)->toChannel();
1275     IrcBuffer* query = bufferModel.add("qtassistant");
1276 
1277     channel->setPersistent(true);
1278     query->setPersistent(true);
1279 
1280     QSignalSpy channelActiveSpy(channel, SIGNAL(activeChanged(bool)));
1281     QSignalSpy queryActiveSpy(query, SIGNAL(activeChanged(bool)));
1282     QVERIFY(channelActiveSpy.isValid());
1283     QVERIFY(queryActiveSpy.isValid());
1284     int channelActiveCount = 0;
1285     int queryActiveCount = 0;
1286 
1287     QVERIFY(channel->isActive());
1288     QVERIFY(query->isActive());
1289 
1290     connection->close();
1291 
1292     QVERIFY(!channel->isActive());
1293     QVERIFY(!query->isActive());
1294 
1295     QCOMPARE(channelActiveSpy.count(), ++channelActiveCount);
1296     QCOMPARE(queryActiveSpy.count(), ++queryActiveCount);
1297 
1298     connection->open();
1299     QVERIFY(waitForOpened());
1300     QVERIFY(waitForWritten(tst_IrcData::welcome()));
1301 
1302     QVERIFY(!channel->isActive());
1303     QVERIFY(query->isActive());
1304 
1305     QCOMPARE(channelActiveSpy.count(), channelActiveCount);
1306     QCOMPARE(queryActiveSpy.count(), ++queryActiveCount);
1307 
1308     QVERIFY(waitForWritten(":communi!communi@hidd.en JOIN :#communi"));
1309 
1310     QVERIFY(channel->isActive());
1311     QVERIFY(query->isActive());
1312 
1313     QCOMPARE(channelActiveSpy.count(), ++channelActiveCount);
1314     QCOMPARE(queryActiveSpy.count(), queryActiveCount);
1315 
1316     QVERIFY(waitForWritten(":communi!communi@hidd.en PART #communi"));
1317 
1318     QVERIFY(!channel->isActive());
1319     QVERIFY(query->isActive());
1320 
1321     QCOMPARE(channelActiveSpy.count(), ++channelActiveCount);
1322     QCOMPARE(queryActiveSpy.count(), queryActiveCount);
1323 
1324     connection->close();
1325 
1326     QVERIFY(!channel->isActive());
1327     QVERIFY(!query->isActive());
1328 
1329     QCOMPARE(channelActiveSpy.count(), channelActiveCount);
1330     QCOMPARE(queryActiveSpy.count(), ++queryActiveCount);
1331 }
1332 
testRoles()1333 void tst_IrcBufferModel::testRoles()
1334 {
1335     IrcBufferModel model;
1336     QHash<int, QByteArray> roles = model.roleNames();
1337     QCOMPARE(roles.take(Qt::DisplayRole), QByteArray("display"));
1338     QCOMPARE(roles.take(Irc::BufferRole), QByteArray("buffer"));
1339     QCOMPARE(roles.take(Irc::ChannelRole), QByteArray("channel"));
1340     QCOMPARE(roles.take(Irc::NameRole), QByteArray("name"));
1341     QCOMPARE(roles.take(Irc::PrefixRole), QByteArray("prefix"));
1342     QCOMPARE(roles.take(Irc::TitleRole), QByteArray("title"));
1343     QVERIFY(roles.isEmpty());
1344 }
1345 
testAIM()1346 void tst_IrcBufferModel::testAIM()
1347 {
1348     IrcBufferModel bufferModel(connection);
1349     IrcBuffer* a = bufferModel.add("#a");
1350     IrcBuffer* b = bufferModel.add("#b");
1351     IrcBuffer* c = bufferModel.add("c");
1352     IrcBuffer* o = nullptr;
1353 
1354     QAbstractItemModel* aim = &bufferModel;
1355     QModelIndex ai = aim->index(0, 0);
1356     QModelIndex bi = aim->index(1, 0);
1357     QModelIndex ci = aim->index(2, 0);
1358     QModelIndex oi = aim->index(100, 100);
1359 
1360     QVERIFY(ai.isValid());
1361     QVERIFY(bi.isValid());
1362     QVERIFY(ci.isValid());
1363     QVERIFY(!oi.isValid());
1364 
1365     QCOMPARE(aim->rowCount(QModelIndex()), 3);
1366     QCOMPARE(aim->rowCount(ai), 0);
1367 
1368     QCOMPARE(aim->columnCount(QModelIndex()), 1);
1369     QCOMPARE(aim->columnCount(ai), 0);
1370 
1371     QCOMPARE(bufferModel.index(a), ai);
1372     QCOMPARE(bufferModel.index(b), bi);
1373     QCOMPARE(bufferModel.index(c), ci);
1374     QVERIFY(!bufferModel.index(o).isValid());
1375 
1376     QCOMPARE(bufferModel.buffer(ai), a);
1377     QCOMPARE(bufferModel.buffer(bi), b);
1378     QCOMPARE(bufferModel.buffer(ci), c);
1379     QVERIFY(!bufferModel.buffer(oi));
1380 
1381     bufferModel.setDisplayRole(Irc::TitleRole);
1382     QCOMPARE(aim->data(ai, Qt::DisplayRole).toString(), a->title());
1383     QCOMPARE(aim->data(bi, Qt::DisplayRole).toString(), b->title());
1384     QCOMPARE(aim->data(ci, Qt::DisplayRole).toString(), c->title());
1385     QVERIFY(aim->data(oi, Qt::DisplayRole).toString().isEmpty());
1386 
1387     bufferModel.setDisplayRole(Irc::BufferRole);
1388     QCOMPARE(aim->data(ai, Qt::DisplayRole).value<IrcBuffer*>(), a);
1389     QCOMPARE(aim->data(bi, Qt::DisplayRole).value<IrcBuffer*>(), b);
1390     QCOMPARE(aim->data(ci, Qt::DisplayRole).value<IrcBuffer*>(), c);
1391     QVERIFY(!aim->data(oi, Qt::DisplayRole).value<IrcBuffer*>());
1392 
1393     QCOMPARE(aim->data(ai, Irc::BufferRole).value<IrcBuffer*>(), a);
1394     QCOMPARE(aim->data(bi, Irc::BufferRole).value<IrcBuffer*>(), b);
1395     QCOMPARE(aim->data(ci, Irc::BufferRole).value<IrcBuffer*>(), c);
1396     QVERIFY(!aim->data(oi, Irc::BufferRole).value<IrcBuffer*>());
1397 
1398     QCOMPARE(aim->data(ai, Irc::ChannelRole).value<IrcChannel*>(), a->toChannel());
1399     QCOMPARE(aim->data(bi, Irc::ChannelRole).value<IrcChannel*>(), b->toChannel());
1400     QCOMPARE(aim->data(ci, Irc::ChannelRole).value<IrcChannel*>(), c->toChannel());
1401     QVERIFY(!aim->data(oi, Irc::ChannelRole).value<IrcChannel*>());
1402 
1403     QCOMPARE(aim->data(ai, Irc::TitleRole).toString(), a->title());
1404     QCOMPARE(aim->data(bi, Irc::TitleRole).toString(), b->title());
1405     QCOMPARE(aim->data(ci, Irc::TitleRole).toString(), c->title());
1406     QVERIFY(aim->data(oi, Irc::TitleRole).toString().isEmpty());
1407 
1408     QCOMPARE(aim->data(ai, Irc::NameRole).toString(), a->name());
1409     QCOMPARE(aim->data(bi, Irc::NameRole).toString(), b->name());
1410     QCOMPARE(aim->data(ci, Irc::NameRole).toString(), c->name());
1411     QVERIFY(aim->data(oi, Irc::NameRole).toString().isEmpty());
1412 
1413     QCOMPARE(aim->data(ai, Irc::PrefixRole).toString(), QString("#"));
1414     QCOMPARE(aim->data(bi, Irc::PrefixRole).toString(), QString("#"));
1415     QVERIFY(aim->data(ci, Irc::PrefixRole).toString().isEmpty());
1416     QVERIFY(aim->data(oi, Irc::PrefixRole).toString().isEmpty());
1417 }
1418 
1419 class FakeQmlBufferModel : public IrcBufferModel
1420 {
1421     Q_OBJECT
1422     friend class tst_IrcBufferModel;
1423 
1424 public slots:
1425     // -Wno-overloaded-virtual
createBuffer(const QVariant & title)1426     QVariant createBuffer(const QVariant& title)
1427     {
1428         IrcBuffer* buffer = IrcBufferModel::createBuffer(title.toString());
1429         buffer->setObjectName("QML buffer");
1430         return QVariant::fromValue(buffer);
1431     }
createChannel(const QVariant & title)1432     QVariant createChannel(const QVariant& title)
1433     {
1434         IrcChannel* channel = IrcBufferModel::createChannel(title.toString());
1435         channel->setObjectName("QML channel");
1436         return QVariant::fromValue(channel);
1437     }
1438 };
1439 
testQML()1440 void tst_IrcBufferModel::testQML()
1441 {
1442     FakeQmlBufferModel model;
1443     model.setConnection(connection);
1444 
1445     connection->open();
1446     QVERIFY(waitForOpened());
1447     QVERIFY(waitForWritten(tst_IrcData::welcome()));
1448 
1449     QCOMPARE(model.add("buffer")->objectName(), QString("QML buffer"));
1450     QCOMPARE(model.add("#channel")->objectName(), QString("QML channel"));
1451 }
1452 
testWarnings()1453 void tst_IrcBufferModel::testWarnings()
1454 {
1455     IrcBufferModel model(connection);
1456     model.setConnection(connection);
1457 
1458     QTest::ignoreMessage(QtCriticalMsg, "IrcBufferModel::setConnection(): changing the connection on the fly is not supported.");
1459 
1460     IrcConnection another;
1461     model.setConnection(&another);
1462 }
1463 
1464 class TestCommandFilter : public QObject, public IrcCommandFilter
1465 {
1466     Q_OBJECT
1467     Q_INTERFACES(IrcCommandFilter)
1468 
1469 public:
TestCommandFilter(IrcConnection * connection)1470     TestCommandFilter(IrcConnection* connection) { connection->installCommandFilter(this); }
commandFilter(IrcCommand * command)1471     bool commandFilter(IrcCommand* command) override { commands += command->toString(); return false; }
1472     QStringList commands;
1473 };
1474 
testMonitor()1475 void tst_IrcBufferModel::testMonitor()
1476 {
1477     TestCommandFilter filter(connection);
1478 
1479     IrcBufferModel model(connection);
1480     model.setMonitorEnabled(true);
1481     QVERIFY(model.isMonitorEnabled());
1482 
1483     connection->open();
1484     QVERIFY(waitForOpened());
1485     QVERIFY(waitForWritten(tst_IrcData::welcome("freenode")));
1486     QVERIFY(connection->network()->numericLimit(IrcNetwork::MonitorCount) > 0);
1487 
1488     filter.commands.clear();
1489 
1490     IrcBuffer* buffer = model.add("jirssi");
1491     QVERIFY(!buffer->isActive());
1492     QCOMPARE(filter.commands.count(), 1);
1493     QCOMPARE(filter.commands.last(), QString("MONITOR + jirssi"));
1494 
1495     QVERIFY(waitForWritten(":card.freenode.net 730 * :jirssi!~jpnurmi@88.95.51.136"));
1496     QVERIFY(buffer->isActive());
1497 
1498     QVERIFY(waitForWritten(":card.freenode.net 731 jipsu :jirssi"));
1499     QVERIFY(!buffer->isActive());
1500 
1501     model.remove("jirssi");
1502     QCOMPARE(filter.commands.count(), 2);
1503     QCOMPARE(filter.commands.last(), QString("MONITOR - jirssi"));
1504 
1505     filter.commands.clear();
1506 
1507     // don't monitor channels
1508     buffer = model.add("#channel");
1509     QCOMPARE(model.channels(), QStringList() << "#channel");
1510     QVERIFY(filter.commands.isEmpty());
1511     delete buffer;
1512     QVERIFY(filter.commands.isEmpty());
1513 }
1514 
1515 QTEST_MAIN(tst_IrcBufferModel)
1516 
1517 #include "tst_ircbuffermodel.moc"
1518