1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2012 Werner Schweer
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2
// as published by the Free Software Foundation and appearing in
// the file LICENCE.GPL
//=============================================================================
#include <QtTest/QtTest>
#include "mtest/testutils.h"
#include "libmscore/score.h"
#include "libmscore/measure.h"
#include "libmscore/repeatlist.h"
#define DIR QString("libmscore/repeat/")
using namespace Ms;
//---------------------------------------------------------
// TestRepeat
//---------------------------------------------------------
class TestRepeat : public QObject, public MTest
{
Q_OBJECT
void repeat(const char* f1, const QString & ref);
private slots:
void initTestCase();
void repeat01() { repeat("repeat01.mscx", "1;2;3;2;3;4;5;6"); } // repeat barline 2 measures ||: | :||
void repeat02() { repeat("repeat02.mscx", "1;2;2;3;4;5;6"); } // repeat barline 1 measure ||: :||
void repeat03() { repeat("repeat03.mscx", "1;2;1;2;3;4;5;6"); } // repeat barline end to start :||
void repeat04() { repeat("repeat04.mscx", "1;2;3;2;3;4;2;3;4;5;6"); } // repeat barline ||: | :|| :||
void repeat05() { repeat("repeat05.mscx", "1;2;3;2;3;2;3;4;2;3;4;5;6"); } // repeat barline ||: | x2 :|| :||
void repeat06() { repeat("repeat06.mscx", "1;2;3;2;4;5;6"); } // simple volta
void repeat07() { repeat("repeat07.mscx", "1;2;3;4;5;6;1;2;3"); } // DC al fine
void repeat08() { repeat("repeat08.mscx", "1;2;3;4;5;6;2;3;4;7;8;9;10;11"); } // DS al coda
void repeat09() { repeat("repeat09.mscx", "1;2;3;2;5;6"); } // 3 voltas, but twice a volta1
void repeat10() { repeat("repeat10.mscx", "1;2;3;4; 1;2;5;6;7;8; 1;2;9;10; 1;2;11;12"); } // 3 voltas
void repeat11() { repeat("repeat11.mscx", "1;2;3;4;2;3;5;6;7;8;2;9;10"); } // volta after to coda
void repeat12() { repeat("repeat12.mscx", "1;2;3;4;3;5;6;2;3;5;6;7"); } // volta between segno & DS
void repeat13() { repeat("repeat13.mscx", "1;2;3;4;5"); } // no repeat
void repeat14() { repeat("repeat14.mscx", "1;2;3;4;5;6;7;8;9;10; 2;3;4;5;6;7;8;11;12; 2;3;4;5;6;7;8;13;14;15; 16;17;18; 16;17;18; 19;20;21;22;23; 5;6;7; 24;25;26"); } // complex roadmap DS al coda, volta, repeat
void repeat15() { repeat("repeat15.mscx", "1;2;2;2;2;2;2;2;2;3"); } // repeat barline ||: x8 :||
void repeat16() { repeat("repeat16.mscx", "1;2;3;4;4;1;2"); } // simple repeat ||: :|| in coda
void repeat17() { repeat("repeat17.mscx", "1;2;1;3;4;5;4;6;7;8;7;9"); } // volta in coda
void repeat18() { repeat("repeat18.mscx", "1;2;1;3;4;5;6;5;7;8"); } // twice volta
void repeat19() { repeat("repeat19.mscx", "1;2;3;4;1;2;4"); } // DS al coda after the coda
void repeat20() { repeat("repeat20.mscx", "1;2;3;1;4;5;6;7;8;5;6"); } // two sections, 1/ DS al Coda, 2/DS Al fine
void repeat21() { repeat("repeat21.mscx", "1;2;3;1;2;3;4;5;6;7;5;8"); } // two sections, 1/DS, 2/DS al Coda
void repeat22() { repeat("repeat22.mscx", "1;2;3;2;3;4;5;5;6"); } // DS and ||: :||
// complex roadmap
void repeat23() { repeat("repeat23.mscx", "1;2;1;2;3;2;3;4;5;6;7;6;7;8;9;10;11;9;10;12;12;13;14;13;14;15;16;13;14"); }
void repeat24() { repeat("repeat24.mscx", "1;2;3;4;5;3;4;2;3;4;5;6"); } // imbricated DS and ||: :||
void repeat25() { repeat("repeat25.mscx", "1;2;1;2;3;4;5;4;2;3;4;5"); } // imbricated DS and ||: :||
void repeat26() { repeat("repeat26.mscx", "1;1;2;2;3"); } // empty and garbage jump
void repeat27() { repeat("repeat27.mscx", "1;2;2;1"); } // #73486 single-measure repeat at end of section
void repeat28() { repeat("repeat28.mscx", "1;2;2;1;2;1"); } // #73486 single-measure repeat at end of section w/DC
void repeat29() { repeat("repeat29.mscx", "1;2;3;3;2;3;1"); } // #73486 single-measure repeat at end of section w/DS
void repeat30() { repeat("repeat30.mscx", "1;1;2;1;2"); } // #73496 single measure section at beginning of score followed by a section with end repeat (without beginning repeat)
void repeat31() { repeat("repeat31.mscx", "1;2;2;1;2"); } // #73531 ending measure has jump and repeat m1 |: m2 DC :|
void repeat32() { repeat("repeat32.mscx", "1;2;3;3;2;3"); } // #73531 ending measure has jump and repeat m1 |S m2 |: m3 DS :|
void repeat33() { repeat("repeat33.mscx", "1;2;3;2;3;1;2;3"); } // #73531 ending measure has jump and repeat m1 |: m2 | m3 DC :|
void repeat34() { repeat("repeat34.mscx", "1;2;3;2;4;5;5;1;2;4;5"); } // #73531 ending measure has jump and repeat m1 |: m2 |1e m3 :| 2e m4 |: m5 | DC :|
void repeat35() { repeat("repeat35.mscx", "1;2;1;2; 1;2;3;4;2;3; 1;2;3;1;2; 1;2;3;4;2;3;5"); } // #65161 multiple sections, each with possible DC, DS, al Fine
void repeat36() { repeat("repeat36.mscx", "1;2;3;2;3;4;5;6; 1;2;2;3;4;5;6; 1;2;1;2;3;4;5;6; 1;2;3;2;3;4;2;3;4;5;6; 1;2;3;2;3;2;3;4;2;3;4;5;6; 1;2;3;2;4;5;6; 1;2;3;4;5;6;1;2;3; 1;2;3;4;5;6;2;3;4;7;8;9;10;11; 1;2;3;2;5;6; 1;2;3;4;1;2;5;6;7;8;1;2;9;10;1;2;11;12; 1;2;3;4;2;3;5;6;7;8;2;9;10; 1;2;3;4;3;5;6;2;3;5;6;7; 1;2;3;4;5;6;7;8;9;10; 2;3;4;5;6;7;8;11;12; 2;3;4;5;6;7;8;13;14;15; 16;17;18; 16;17;18; 19;20;21;22;23; 5;6;7; 24;25;26; 1;2;2;2;2;2;2;2;2;3; 1;2;3;4;4;1;2; 1;2;1;3;4;5;4;6;7;8;7;9; 1;2;1;3;4;5;6;5;7;8; 1;2;3;4;1;2;4; 1;2;3;1;4;5;6;7;8;5;6; 1;2;3;1;2;3;4;5;6;7;5;8; 1;2;3;2;3;4;5;5;6; 1;2;1;2;3;2;3;4;5;6;7;6;7;8;9;10;11;9;10;12;12;13;14;13;14;15;16;13;14; 1;2;3;4;5;3;4;2;3;4;5;6; 1;2;1;2;3;4;5;4;2;3;4;5; 1;1;2;2;3; 1;2;2;1; 1;2;2;1;2;1; 1;2;3;3;2;3;1; 1;1;2;1;2; 1;2;2;1;2; 1;2;3;3;2;3; 1;2;3;2;3;1;2;3; 1;2;3;2;4;5;5;1;2;4;5; 1;2;1;2; 1;2;3;4;2;3; 1;2;3;1;2; 1;2;3;4;2;3;5"); } // #65161 entire album of 01-35, except 13.
void repeat37() { repeat("repeat37.mscx", "1;2;1; 1;2;1; 1;2;1; 1;2;1; 1;2;1"); } // #65161, with section breaks occurring on non-meausure frames
void repeat38() { repeat("repeat38.mscx", "1;2;2;3;4;2;2;3;5"); }
void repeat39() { repeat("repeat39.mscx", "1;2;3; 2;4;5; 2;3; 2;4;5; 2;6"); } // volta 1.3.,2.4.
void repeat40() { repeat("repeat40.mscx", "1;2;1;3;4;1;5"); } // #148276 Open volta lines must extend over entire ending: next endRepeat
void repeat41() { repeat("repeat41.mscx", "1;2;1;3;1;4;5"); } // #148276 Open volta lines must extend over entire ending: next endRepeat at volta (SLine) end
void repeat42() { repeat("repeat42.mscx", "1;2;1;3;5;1;4;5"); } // #148276 Open volta lines must extend over entire ending: next volta
void repeat43() { repeat("repeat43.mscx", "1;2;1;2;1;3;1;2;1;4;1;5"); } // #8604 Complex alternate endings 1.2.4. / 3./ 5.
void repeat44() { repeat("repeat44.mscx", "1;2;3;4;5;3;6;3;4;1;7"); } // Jump from within a volta
void repeat45() { repeat("repeat45.mscx", "1;2;3;4;3;5;6;2;3;4;3;5;6;7"); } // repeat12 but with 'play repeats' enabled
void repeat46() { repeat("repeat46.mscx", "1;2;3;4;5;3;4;2;3;4;5;3;4;5;6"); } // repeat24 but with 'play repeats' enabled
void repeat47() { repeat("repeat47.mscx", "1;2;3;2;4;5;6;7;6;8;9;10;11; 2;4;13;14;15; 9;10;16;17;18"); } // #269378 Double Coda messed up repeat rewind logic
void repeat48() { repeat("repeat48.mscx", "1;2;3;4;1;5;6;7;3;4;1;5;8"); } // jump into first volta, without playRepeats
void repeat49() { repeat("repeat49.mscx", "1;2;3;1;2;3;4;5;6;3;1;2;3;4;7"); } // D.S. with playRepeats
void repeat50() { repeat("repeat50.mscx", "1;2;3;4;1;2;3;4;5;6;1;2;3;4;1;2;3;7"); } // D.S. with playRepeats with ToCoda inside the repeat
void repeat51() { repeat("repeat51.mscx", "1;2;3;4;5;6;3;4;7;8;9;3;4;10;11"); } //#270332 twice D.S. with playRepeats to same target with different Coda
};
//---------------------------------------------------------
// initTestCase
//---------------------------------------------------------
void TestRepeat::initTestCase()
{
initMTest();
}
//---------------------------------------------------------
// repeat
//---------------------------------------------------------
void TestRepeat::repeat(const char* f1, const QString & ref)
{
MasterScore* score = readScore(DIR + f1);
QVERIFY(score);
score->setExpandRepeats(true);
QStringList sl;
for (const RepeatSegment* rs : score->repeatList()) {
int startTick = rs->tick;
int endTick = startTick + rs->len();
for (Measure* m = score->tick2measure(Fraction::fromTicks(startTick)); m; m = m->nextMeasure()) {
sl.append(QString::number(m->no()+1));
if (m->endTick().ticks() >= endTick)
break;
}
}
QString s = sl.join(";");
QString ref1 = ref;
ref1.replace(" ","");
qDebug("File <%s> sequence %s", f1, qPrintable(s));
QCOMPARE(s, ref1);
delete score;
}
QTEST_MAIN(TestRepeat)
#include "tst_repeat.moc"
|