Chris@1612: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
Chris@1612: 
Chris@1612: /*
Chris@1612:     Sonic Visualiser
Chris@1612:     An audio file viewer and annotation editor.
Chris@1612:     Centre for Digital Music, Queen Mary, University of London.
Chris@1612:     
Chris@1612:     This program is free software; you can redistribute it and/or
Chris@1612:     modify it under the terms of the GNU General Public License as
Chris@1612:     published by the Free Software Foundation; either version 2 of the
Chris@1612:     License, or (at your option) any later version.  See the file
Chris@1612:     COPYING included with this distribution for more information.
Chris@1612: */
Chris@1612: 
Chris@1615: #ifndef TEST_EVENT_SERIES_H
Chris@1615: #define TEST_EVENT_SERIES_H
Chris@1612: 
Chris@1615: #include "../EventSeries.h"
Chris@1612: 
Chris@1612: #include <QObject>
Chris@1612: #include <QtTest>
Chris@1612: 
Chris@1612: #include <iostream>
Chris@1612: 
Chris@1612: using namespace std;
Chris@1612: 
Chris@1615: class TestEventSeries : public QObject
Chris@1612: {
Chris@1612:     Q_OBJECT
Chris@1612: 
Chris@1612: private slots:
Chris@1612:     void empty() {
Chris@1612: 
Chris@1615:         EventSeries s;
Chris@1612:         QCOMPARE(s.isEmpty(), true);
Chris@1612:         QCOMPARE(s.count(), 0);
Chris@1612: 
Chris@1615:         Event p(10, QString());
Chris@1612:         QCOMPARE(s.contains(p), false);
Chris@1616:         QCOMPARE(s.getEventsCovering(400), EventVector());
Chris@1612:     }
Chris@1612: 
Chris@1615:     void singleEvent() {
Chris@1612: 
Chris@1615:         EventSeries s;
Chris@1615:         Event p(10, QString());
Chris@1612:         s.add(p);
Chris@1612:         QCOMPARE(s.isEmpty(), false);
Chris@1612:         QCOMPARE(s.count(), 1);
Chris@1612:         QCOMPARE(s.contains(p), true);
Chris@1612: 
Chris@1612:         s.remove(p);
Chris@1612:         QCOMPARE(s.isEmpty(), true);
Chris@1616:         QCOMPARE(s.count(), 0);
Chris@1612:         QCOMPARE(s.contains(p), false);
Chris@1612:     }
Chris@1612: 
Chris@1616:     void duplicateEvents() {
Chris@1612: 
Chris@1615:         EventSeries s;
Chris@1615:         Event p(10, QString());
Chris@1612:         s.add(p);
Chris@1616:         s.add(p);
Chris@1616:         QCOMPARE(s.isEmpty(), false);
Chris@1616:         QCOMPARE(s.count(), 2);
Chris@1616:         QCOMPARE(s.contains(p), true);
Chris@1616: 
Chris@1616:         s.remove(p);
Chris@1616:         QCOMPARE(s.isEmpty(), false);
Chris@1616:         QCOMPARE(s.count(), 1);
Chris@1616:         QCOMPARE(s.contains(p), true);
Chris@1616: 
Chris@1616:         s.remove(p);
Chris@1616:         QCOMPARE(s.isEmpty(), true);
Chris@1616:         QCOMPARE(s.count(), 0);
Chris@1616:         QCOMPARE(s.contains(p), false);
Chris@1612:     }
Chris@1612: 
Chris@1616:     void singleEventCover() {
Chris@1616: 
Chris@1616:         EventSeries s;
Chris@1616:         Event p(10, QString());
Chris@1616:         s.add(p);
Chris@1616:         EventVector cover;
Chris@1616:         cover.push_back(p);
Chris@1616:         QCOMPARE(s.getEventsCovering(10), cover);
Chris@1616:         QCOMPARE(s.getEventsCovering(11), EventVector());
Chris@1616:         QCOMPARE(s.getEventsCovering(9), EventVector());
Chris@1616:     }
Chris@1616: 
Chris@1617:     void singleEventSpan() {
Chris@1617: 
Chris@1617:         EventSeries s;
Chris@1617:         Event p(10, QString());
Chris@1617:         s.add(p);
Chris@1617:         EventVector span;
Chris@1617:         span.push_back(p);
Chris@1617:         QCOMPARE(s.getEventsSpanning(10, 2), span);
Chris@1617:         QCOMPARE(s.getEventsSpanning(9, 2), span);
Chris@1617:         QCOMPARE(s.getEventsSpanning(8, 2), EventVector());
Chris@1617:         QCOMPARE(s.getEventsSpanning(7, 2), EventVector());
Chris@1617:         QCOMPARE(s.getEventsSpanning(11, 2), EventVector());
Chris@1617:     }
Chris@1617:     
Chris@1617:     void identicalEventsCover() {
Chris@1617: 
Chris@1617:         EventSeries s;
Chris@1617:         Event p(10, QString());
Chris@1617:         s.add(p);
Chris@1617:         s.add(p);
Chris@1617: 
Chris@1617:         EventVector cover;
Chris@1617:         cover.push_back(p);
Chris@1617:         cover.push_back(p);
Chris@1617:         QCOMPARE(s.getEventsCovering(10), cover);
Chris@1617:         QCOMPARE(s.getEventsCovering(11), EventVector());
Chris@1617:         QCOMPARE(s.getEventsCovering(9), EventVector());
Chris@1617: 
Chris@1617:         s.remove(p);
Chris@1617:         cover.clear();
Chris@1617:         cover.push_back(p);
Chris@1617:         QCOMPARE(s.getEventsCovering(10), cover);
Chris@1617:         QCOMPARE(s.getEventsCovering(11), EventVector());
Chris@1617:         QCOMPARE(s.getEventsCovering(9), EventVector());
Chris@1617:     }
Chris@1617:     
Chris@1617:     void identicalEventsSpan() {
Chris@1617: 
Chris@1617:         EventSeries s;
Chris@1617:         Event p(10, QString());
Chris@1617:         s.add(p);
Chris@1617:         s.add(p);
Chris@1617: 
Chris@1617:         EventVector span;
Chris@1617:         span.push_back(p);
Chris@1617:         span.push_back(p);
Chris@1617:         QCOMPARE(s.getEventsSpanning(10, 2), span);
Chris@1617:         QCOMPARE(s.getEventsSpanning(9, 2), span);
Chris@1617:         QCOMPARE(s.getEventsSpanning(8, 2), EventVector());
Chris@1617:         QCOMPARE(s.getEventsSpanning(11, 2), EventVector());
Chris@1617:     }
Chris@1617: 
Chris@1616:     void similarEventsCover() {
Chris@1616: 
Chris@1616:         EventSeries s;
Chris@1616:         Event a(10, QString("a"));
Chris@1616:         Event b(10, QString("b"));
Chris@1616:         s.add(a);
Chris@1616:         s.add(b);
Chris@1616:         EventVector cover;
Chris@1616:         cover.push_back(a);
Chris@1616:         cover.push_back(b);
Chris@1616:         QCOMPARE(s.getEventsCovering(10), cover);
Chris@1616:         QCOMPARE(s.getEventsCovering(11), EventVector());
Chris@1616:         QCOMPARE(s.getEventsCovering(9), EventVector());
Chris@1616:     }
Chris@1616: 
Chris@1617:     void similarEventsSpan() {
Chris@1617: 
Chris@1617:         EventSeries s;
Chris@1617:         Event a(10, QString("a"));
Chris@1617:         Event b(10, QString("b"));
Chris@1617:         s.add(a);
Chris@1617:         s.add(b);
Chris@1617:         EventVector span;
Chris@1617:         span.push_back(a);
Chris@1617:         span.push_back(b);
Chris@1617:         QCOMPARE(s.getEventsSpanning(10, 2), span);
Chris@1617:         QCOMPARE(s.getEventsSpanning(9, 2), span);
Chris@1617:         QCOMPARE(s.getEventsSpanning(11, 2), EventVector());
Chris@1617:         QCOMPARE(s.getEventsSpanning(8, 2), EventVector());
Chris@1617:     }
Chris@1617: 
Chris@1616:     void singleEventWithDurationCover() {
Chris@1612: 
Chris@1615:         EventSeries s;
Chris@1615:         Event p(10, 1.0, 20, QString());
Chris@1612:         s.add(p);
Chris@1616:         EventVector cover;
Chris@1616:         cover.push_back(p);
Chris@1616:         QCOMPARE(s.getEventsCovering(10), cover);
Chris@1616:         QCOMPARE(s.getEventsCovering(11), cover);
Chris@1616:         QCOMPARE(s.getEventsCovering(29), cover);
Chris@1616:         QCOMPARE(s.getEventsCovering(30), EventVector());
Chris@1616:         QCOMPARE(s.getEventsCovering(9), EventVector());
Chris@1612:     }
Chris@1614: 
Chris@1617:     void singleEventWithDurationSpan() {
Chris@1614: 
Chris@1615:         EventSeries s;
Chris@1617:         Event p(10, 1.0, 20, QString());
Chris@1614:         s.add(p);
Chris@1617:         EventVector span;
Chris@1617:         span.push_back(p);
Chris@1617:         QCOMPARE(s.getEventsSpanning(9, 2), span);
Chris@1617:         QCOMPARE(s.getEventsSpanning(8, 2), EventVector());
Chris@1617:         QCOMPARE(s.getEventsSpanning(19, 4), span);
Chris@1617:         QCOMPARE(s.getEventsSpanning(29, 2), span);
Chris@1617:         QCOMPARE(s.getEventsSpanning(30, 2), EventVector());
Chris@1617:     }
Chris@1614: 
Chris@1616:     void identicalEventsWithDurationCover() {
Chris@1614: 
Chris@1615:         EventSeries s;
Chris@1615:         Event p(10, 1.0, 20, QString());
Chris@1614:         s.add(p);
Chris@1614:         s.add(p);
Chris@1616:         EventVector cover;
Chris@1616:         cover.push_back(p);
Chris@1616:         cover.push_back(p);
Chris@1616:         QCOMPARE(s.getEventsCovering(10), cover);
Chris@1616:         QCOMPARE(s.getEventsCovering(11), cover);
Chris@1616:         QCOMPARE(s.getEventsCovering(29), cover);
Chris@1616:         QCOMPARE(s.getEventsCovering(30), EventVector());
Chris@1616:         QCOMPARE(s.getEventsCovering(9), EventVector());
Chris@1614: 
Chris@1614:         s.remove(p);
Chris@1616:         cover.clear();
Chris@1616:         cover.push_back(p);
Chris@1616:         QCOMPARE(s.getEventsCovering(10), cover);
Chris@1616:         QCOMPARE(s.getEventsCovering(11), cover);
Chris@1616:         QCOMPARE(s.getEventsCovering(29), cover);
Chris@1616:         QCOMPARE(s.getEventsCovering(30), EventVector());
Chris@1616:         QCOMPARE(s.getEventsCovering(9), EventVector());
Chris@1614:     }
Chris@1614: 
Chris@1617:     void identicalEventsWithDurationSpan() {
Chris@1617: 
Chris@1617:         EventSeries s;
Chris@1617:         Event p(10, 1.0, 20, QString());
Chris@1617:         s.add(p);
Chris@1617:         s.add(p);
Chris@1617:         EventVector span;
Chris@1617:         span.push_back(p);
Chris@1617:         span.push_back(p);
Chris@1617:         QCOMPARE(s.getEventsSpanning(9, 2), span);
Chris@1617:         QCOMPARE(s.getEventsSpanning(10, 2), span);
Chris@1617:         QCOMPARE(s.getEventsSpanning(11, 2), span);
Chris@1617:         QCOMPARE(s.getEventsSpanning(29, 2), span);
Chris@1617:         QCOMPARE(s.getEventsSpanning(30, 2), EventVector());
Chris@1617:         QCOMPARE(s.getEventsSpanning(8, 2), EventVector());
Chris@1617:     }
Chris@1617: 
Chris@1616:     void multipleEventsCover() {
Chris@1614: 
Chris@1615:         EventSeries s;
Chris@1615:         Event a(10, QString("a"));
Chris@1615:         Event b(11, QString("b"));
Chris@1615:         Event c(40, QString("c"));
Chris@1614:         s.add(c);
Chris@1614:         s.add(a);
Chris@1614:         s.add(b);
Chris@1614:         s.remove(a);
Chris@1614:         s.add(a);
Chris@1614:         s.add(c);
Chris@1614:         s.remove(c);
Chris@1614:         QCOMPARE(s.count(), 3);
Chris@1616:         EventVector cover;
Chris@1616:         cover.push_back(a);
Chris@1616:         QCOMPARE(s.getEventsCovering(10), cover);
Chris@1616:         cover.clear();
Chris@1616:         cover.push_back(c);
Chris@1616:         QCOMPARE(s.getEventsCovering(40), cover);
Chris@1616:         QCOMPARE(s.getEventsCovering(9), EventVector());
Chris@1614:     }
Chris@1614: 
Chris@1617:     void multipleEventsSpan() {
Chris@1617: 
Chris@1617:         EventSeries s;
Chris@1617:         Event a(10, QString("a"));
Chris@1617:         Event b(11, QString("b"));
Chris@1617:         Event c(40, QString("c"));
Chris@1617:         s.add(c);
Chris@1617:         s.add(a);
Chris@1617:         s.add(b);
Chris@1617:         EventVector span;
Chris@1617:         span.push_back(a);
Chris@1617:         span.push_back(b);
Chris@1617:         QCOMPARE(s.getEventsSpanning(10, 2), span);
Chris@1617:         span.clear();
Chris@1617:         span.push_back(c);
Chris@1617:         QCOMPARE(s.getEventsSpanning(39, 3), span);
Chris@1617:         QCOMPARE(s.getEventsSpanning(9, 1), EventVector());
Chris@1617:         QCOMPARE(s.getEventsSpanning(10, 0), EventVector());
Chris@1617:     }
Chris@1617: 
Chris@1616:     void disjointEventsWithDurationCover() {
Chris@1614: 
Chris@1615:         EventSeries s;
Chris@1615:         Event a(10, 1.0f, 20, QString("a"));
Chris@1615:         Event b(100, 1.2f, 30, QString("b"));
Chris@1614:         s.add(a);
Chris@1614:         s.add(b);
Chris@1616:         QCOMPARE(s.getEventsCovering(0), EventVector());
Chris@1616:         QCOMPARE(s.getEventsCovering(10), EventVector({ a }));
Chris@1616:         QCOMPARE(s.getEventsCovering(15), EventVector({ a }));
Chris@1616:         QCOMPARE(s.getEventsCovering(30), EventVector());
Chris@1616:         QCOMPARE(s.getEventsCovering(99), EventVector());
Chris@1616:         QCOMPARE(s.getEventsCovering(100), EventVector({ b }));
Chris@1616:         QCOMPARE(s.getEventsCovering(120), EventVector({ b }));
Chris@1616:         QCOMPARE(s.getEventsCovering(130), EventVector());
Chris@1614:     }
Chris@1614:     
Chris@1619:     void disjointEventsWithDurationSpan() {
Chris@1619: 
Chris@1619:         EventSeries s;
Chris@1619:         Event a(10, 1.0f, 20, QString("a"));
Chris@1619:         Event b(100, 1.2f, 30, QString("b"));
Chris@1619:         s.add(a);
Chris@1619:         s.add(b);
Chris@1619:         QCOMPARE(s.getEventsSpanning(0, 10), EventVector());
Chris@1619:         QCOMPARE(s.getEventsSpanning(10, 10), EventVector({ a }));
Chris@1619:         QCOMPARE(s.getEventsSpanning(15, 85), EventVector({ a }));
Chris@1619:         QCOMPARE(s.getEventsSpanning(30, 5), EventVector());
Chris@1619:         QCOMPARE(s.getEventsSpanning(99, 1), EventVector());
Chris@1619:         QCOMPARE(s.getEventsSpanning(100, 1), EventVector({ b }));
Chris@1619:         QCOMPARE(s.getEventsSpanning(120, 20), EventVector({ b }));
Chris@1619:         QCOMPARE(s.getEventsSpanning(130, 109), EventVector());
Chris@1619:     }
Chris@1619:     
Chris@1616:     void overlappingEventsWithAndWithoutDurationCover() {
Chris@1614: 
Chris@1615:         EventSeries s;
Chris@1615:         Event p(20, QString("p"));
Chris@1616:         Event a(10, 1.0f, 20, QString("a"));
Chris@1614:         s.add(p);
Chris@1614:         s.add(a);
Chris@1616:         EventVector cover;
Chris@1616:         cover.push_back(a);
Chris@1616:         QCOMPARE(s.getEventsCovering(15), cover);
Chris@1616:         QCOMPARE(s.getEventsCovering(25), cover);
Chris@1616:         cover.clear();
Chris@1616:         cover.push_back(p);
Chris@1616:         cover.push_back(a);
Chris@1616:         QCOMPARE(s.getEventsCovering(20), cover);
Chris@1614:     }
Chris@1619:     
Chris@1619:     void overlappingEventsWithAndWithoutDurationSpan() {
Chris@1619: 
Chris@1619:         EventSeries s;
Chris@1619:         Event p(20, QString("p"));
Chris@1619:         Event a(10, 1.0f, 20, QString("a"));
Chris@1619:         s.add(p);
Chris@1619:         s.add(a);
Chris@1619:         EventVector span;
Chris@1619:         span.push_back(a);
Chris@1619:         QCOMPARE(s.getEventsSpanning(5, 10), span);
Chris@1619:         QCOMPARE(s.getEventsSpanning(25, 5), span);
Chris@1619:         span.clear();
Chris@1619:         span.push_back(p);
Chris@1619:         span.push_back(a);
Chris@1619:         QCOMPARE(s.getEventsSpanning(20, 1), span);
Chris@1619:     }
Chris@1614: 
Chris@1616:     void overlappingEventsWithDurationCover() {
Chris@1614: 
Chris@1615:         EventSeries s;
Chris@1616:         Event a(20, 1.0f, 10, QString("a"));
Chris@1616:         Event b(10, 1.0f, 20, QString("b"));
Chris@1616:         Event c(10, 1.0f, 40, QString("c"));
Chris@1614:         s.add(a);
Chris@1614:         s.add(b);
Chris@1614:         s.add(c);
Chris@1616:         QCOMPARE(s.getEventsCovering(10), EventVector({ b, c }));
Chris@1616:         QCOMPARE(s.getEventsCovering(20), EventVector({ b, c, a }));
Chris@1616:         QCOMPARE(s.getEventsCovering(25), EventVector({ b, c, a }));
Chris@1616:         QCOMPARE(s.getEventsCovering(30), EventVector({ c }));
Chris@1616:         QCOMPARE(s.getEventsCovering(40), EventVector({ c }));
Chris@1616:         QCOMPARE(s.getEventsCovering(50), EventVector());
Chris@1614:     }
Chris@1614: 
Chris@1619:     void overlappingEventsWithDurationSpan() {
Chris@1619: 
Chris@1619:         EventSeries s;
Chris@1619:         Event a(20, 1.0f, 10, QString("a"));
Chris@1619:         Event b(10, 1.0f, 20, QString("b"));
Chris@1619:         Event c(10, 1.0f, 40, QString("c"));
Chris@1619:         s.add(a);
Chris@1619:         s.add(b);
Chris@1619:         s.add(c);
Chris@1619:         QCOMPARE(s.getEventsSpanning(10, 5), EventVector({ b, c }));
Chris@1619:         QCOMPARE(s.getEventsSpanning(20, 15), EventVector({ b, c, a }));
Chris@1619:         QCOMPARE(s.getEventsSpanning(0, 100), EventVector({ b, c, a }));
Chris@1619:         QCOMPARE(s.getEventsSpanning(25, 4), EventVector({ b, c, a }));
Chris@1619:         QCOMPARE(s.getEventsSpanning(30, 4), EventVector({ c }));
Chris@1619:         QCOMPARE(s.getEventsSpanning(40, 15), EventVector({ c }));
Chris@1619:         QCOMPARE(s.getEventsSpanning(50, 10), EventVector());
Chris@1619:     }
Chris@1619: 
Chris@1616:     void eventPatternCover() {
Chris@1614: 
Chris@1615:         EventSeries s;
Chris@1616:         Event a(0, 1.0f, 18, QString("a"));
Chris@1616:         Event b(3, 2.0f, 6, QString("b"));
Chris@1616:         Event c(5, 3.0f, 2, QString("c"));
Chris@1616:         Event cc(5, 3.1f, 2, QString("cc"));
Chris@1616:         Event d(6, 4.0f, 10, QString("d"));
Chris@1616:         Event dd(6, 4.5f, 10, QString("dd"));
Chris@1616:         Event e(14, 5.0f, 3, QString("e"));
Chris@1614:         s.add(b);
Chris@1614:         s.add(c);
Chris@1614:         s.add(d);
Chris@1614:         s.add(a);
Chris@1616:         s.add(cc);
Chris@1616:         s.add(dd);
Chris@1614:         s.add(e);
Chris@1616:         QCOMPARE(s.getEventsCovering(8), EventVector({ a, b, d, dd }));
Chris@1616:     }
Chris@1616: 
Chris@1619:     void eventPatternSpan() {
Chris@1619: 
Chris@1619:         EventSeries s;
Chris@1619:         Event a(0, 1.0f, 18, QString("a"));
Chris@1619:         Event b(3, 2.0f, 6, QString("b"));
Chris@1619:         Event c(5, 3.0f, 2, QString("c"));
Chris@1619:         Event cc(5, 3.1f, 2, QString("cc"));
Chris@1619:         Event d(6, 4.0f, 10, QString("d"));
Chris@1619:         Event dd(6, 4.5f, 10, QString("dd"));
Chris@1619:         Event e(14, 5.0f, 3, QString("e"));
Chris@1619:         s.add(b);
Chris@1619:         s.add(c);
Chris@1619:         s.add(d);
Chris@1619:         s.add(a);
Chris@1619:         s.add(cc);
Chris@1619:         s.add(dd);
Chris@1619:         s.add(e);
Chris@1619:         QCOMPARE(s.getEventsSpanning(6, 2), EventVector({ a, b, c, cc, d, dd }));
Chris@1619:     }
Chris@1619: 
Chris@1616:     void eventPatternAddRemove() {
Chris@1616: 
Chris@1616:         // This is mostly here to exercise the innards of EventSeries
Chris@1616:         // and check it doesn't crash out with any internal
Chris@1616:         // consistency problems
Chris@1616:         
Chris@1616:         EventSeries s;
Chris@1616:         Event a(0, 1.0f, 18, QString("a"));
Chris@1616:         Event b(3, 2.0f, 6, QString("b"));
Chris@1616:         Event c(5, 3.0f, 2, QString("c"));
Chris@1616:         Event cc(5, 3.1f, 2, QString("cc"));
Chris@1616:         Event d(6, 4.0f, 10, QString("d"));
Chris@1616:         Event dd(6, 4.5f, 10, QString("dd"));
Chris@1616:         Event e(14, 5.0f, 3, QString("e"));
Chris@1616:         s.add(b);
Chris@1616:         s.add(c);
Chris@1616:         s.add(d);
Chris@1616:         s.add(a);
Chris@1616:         s.add(cc);
Chris@1616:         s.add(dd);
Chris@1616:         s.add(e);
Chris@1616:         QCOMPARE(s.count(), 7);
Chris@1616:         s.remove(d);
Chris@1616:         QCOMPARE(s.getEventsCovering(8), EventVector({ a, b, dd }));
Chris@1616:         s.remove(e);
Chris@1616:         s.remove(a);
Chris@1616:         QCOMPARE(s.getEventsCovering(8), EventVector({ b, dd }));
Chris@1616:         s.remove(cc);
Chris@1616:         s.remove(c);
Chris@1616:         s.remove(dd);
Chris@1616:         QCOMPARE(s.getEventsCovering(8), EventVector({ b }));
Chris@1616:         s.remove(b);
Chris@1616:         QCOMPARE(s.getEventsCovering(8), EventVector());
Chris@1616:         QCOMPARE(s.count(), 0);
Chris@1616:         QCOMPARE(s.isEmpty(), true);
Chris@1614:     }
Chris@1612: };
Chris@1612: 
Chris@1612: #endif