File: tst_barline.cpp

package info (click to toggle)
musescore 2.0.3%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 202,532 kB
  • ctags: 58,769
  • sloc: cpp: 257,595; xml: 172,226; ansic: 139,931; python: 6,565; sh: 6,383; perl: 423; makefile: 290; awk: 142; pascal: 67; sed: 3
file content (345 lines) | stat: -rw-r--r-- 14,377 bytes parent folder | download | duplicates (7)
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
//=============================================================================
//  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/barline.h"
#include "libmscore/measure.h"
#include "libmscore/score.h"
#include "libmscore/system.h"
#include "libmscore/undo.h"

#define DIR QString("libmscore/barline/")

using namespace Ms;

//---------------------------------------------------------
//   TestBarline
//---------------------------------------------------------

class TestBarline : public QObject, public MTest
      {
      Q_OBJECT

   private slots:
      void initTestCase();
      void barline01();
      void barline02();
      void barline03();
      void barline04();
      void barline05();
      void barline06();
      };

//---------------------------------------------------------
//   initTestCase
//---------------------------------------------------------

void TestBarline::initTestCase()
      {
      initMTest();
      }

//---------------------------------------------------------
///  barline01
///   Check bar line and brackets presence and length with hidden empty staves:
//    A score with:
//          3 staves,
//          bracket across all 3 staves
//          bar lines across all 3 staves
//          systems with each staff hidden in turn because empty
//    is loaded, laid out and bracket/bar line sizes are checked.
//
//    NO REFERENCE SCORE IS USED: the test has to do with layout/formatting,
//    not with edit or read/save operations.
//---------------------------------------------------------

// actual 3-staff bracket should be high 28.6 SP ca.: allow for some layout margin
static const qreal      BRACKET0_HEIGHT_MIN     = 27;
static const qreal      BRACKET0_HEIGHT_MAX     = 30;
// actual 2-staff bracket should be high 18.1 SP ca.
static const qreal      BRACKET_HEIGHT_MIN      = 17;
static const qreal      BRACKET_HEIGHT_MAX      = 20;
// actual 3-staff bar line should be high 25 SP
static const qreal      BARLINE0_HEIGHT_MIN     = 24;
static const qreal      BARLINE0_HEIGHT_MAX     = 26;
// actual 2-staff bar line should be high 14.5 SP
static const qreal      BARLINE_HEIGHT_MIN      = 14;
static const qreal      BARLINE_HEIGHT_MAX      = 15;

void TestBarline::barline01()
      {
      char msg[256];
      Score* score = readScore(DIR + "barline01.mscx");
      score->doLayout();

      qreal height, heightMin, heightMax;
      qreal spatium = score->spatium();
      int sysNo = 0;
      foreach(System* sys , *score->systems()) {
            // check number of the brackets of each system
            sprintf(msg, "Wrong number of brackets in system %d.", sysNo+1);
            QVERIFY2(sys->brackets().count() == 1, msg);

            // check height of the bracket of each system
            // (bracket height is different between first system (3 staves) and other systems (2 staves) )
            Bracket* bracket = sys->brackets().at(0);
            height      = bracket->bbox().height() / spatium;
            heightMin   = (sysNo == 0) ? BRACKET0_HEIGHT_MIN : BRACKET_HEIGHT_MIN;
            heightMax   = (sysNo == 0) ? BRACKET0_HEIGHT_MAX : BRACKET_HEIGHT_MAX;
            sprintf(msg, "Wrong bracket height in system %d.", sysNo+1);
            QVERIFY2(height > heightMin && height < heightMax, msg);

            // check presence and height of the bar line of each measure of each system
            // (2 measure for each system)
            heightMin = (sysNo == 0) ? BARLINE0_HEIGHT_MIN : BARLINE_HEIGHT_MIN;
            heightMax = (sysNo == 0) ? BARLINE0_HEIGHT_MAX : BARLINE_HEIGHT_MAX;
            for (int msrNo=0; msrNo < 2; ++msrNo) {
                  BarLine* bar = nullptr;
                  Measure* msr = static_cast<Measure*>(sys->measure(msrNo));
                  Segment* seg = msr->findSegment(Segment::Type::EndBarLine, msr->tick()+msr->ticks());
                  sprintf(msg, "No SegEndBarLine in measure %d of system %d.", msrNo+1, sysNo+1);
                  QVERIFY2(seg != nullptr, msg);

                  bar = static_cast<BarLine*>(seg->element(0));
                  sprintf(msg, "No barline in measure %d of system %d.", msrNo+1, sysNo+1);
                  QVERIFY2(bar != nullptr, msg);

                  height      = bar->bbox().height() / spatium;
                  sprintf(msg, "Wrong barline height in measure %d of system %d.", msrNo+1, sysNo+1);
                  QVERIFY2(height > heightMin && height < heightMax, msg);
            }
            sysNo++;
      }

//      QVERIFY(saveCompareScore(score, "barline01.mscx", DIR + "barline01-ref.mscx"));
      delete score;
      }

//---------------------------------------------------------
///   barline02
///   add a 3/4 time signature in the second measure and chech bar line 'generated' status
//
//    NO REFERENCE SCORE IS USED.
//---------------------------------------------------------

void TestBarline::barline02()
      {
      char msg[256];
      Score* score = readScore(DIR + "barline02.mscx");
      QVERIFY(score);
      Measure* msr = score->firstMeasure()->nextMeasure();
      TimeSig* ts = new TimeSig(score);
      ts->setSig(Fraction(3, 4), TimeSigType::NORMAL);

      score->cmdAddTimeSig(msr, 0, ts, false);
      score->doLayout();

      msr = score->firstMeasure();
      int msrNo = 1;
      while ( (msr=msr->nextMeasure()) != nullptr ) {
            ++msrNo;
            Segment* seg = msr->findSegment(Segment::Type::EndBarLine, msr->tick()+msr->ticks());
            sprintf(msg, "No SegEndBarLine in measure %d.", msrNo);
            QVERIFY2(seg != nullptr, msg);

            BarLine* bar = static_cast<BarLine*>(seg->element(0));
            sprintf(msg, "No barline in measure %d.", msrNo);
            QVERIFY2(bar != nullptr, msg);

            // bar line should be generated if NORMAL, except the END one at the end
            sprintf(msg, "Barline in measure %d changed into 'non-generated'.", msrNo);
            bool test = (bar->barLineType() == BarLineType::NORMAL)
                        ? bar->generated() : !bar->generated();
            QVERIFY2(test, msg);
      }
//      QVERIFY(saveCompareScore(score, "barline02.mscx", DIR + "barline02-ref.mscx"));
      delete score;
      }

//---------------------------------------------------------
///   barline03
///   Sets a staff bar line span involving spanFrom and spanTo and
///   check tht it is properly applied to start-repeat
//
//    NO REFERENCE SCORE IS USED.
//---------------------------------------------------------

void TestBarline::barline03()
      {
      Score* score = readScore(DIR + "barline03.mscx");
      QVERIFY(score);
      score->doLayout();
      score->undoChangeBarLineSpan(score->staff(0), 2, 2, 6);
      score->doLayout();

      // 'go' to 5th measure
      Measure* msr = score->firstMeasure();
      for (int i=0; i < 4; i++)
            msr = msr->nextMeasure();
      // check span data of measure-initial start-repeat bar line
      Segment* seg = msr->findSegment(Segment::Type::StartRepeatBarLine, msr->tick());
      QVERIFY2(seg != nullptr, "No SegStartRepeatBarLine segment in measure 5.");

      BarLine* bar = static_cast<BarLine*>(seg->element(0));
      QVERIFY2(bar != nullptr, "No start-repeat barline in measure 5.");

      QVERIFY2(bar->span() == 2 && bar->spanFrom() == 2 && bar->spanTo() == 6,
            "Wrong span data in start-repeat barline of measure 5.");

      // check start-repeat bar ine in second staff is gone
      QVERIFY2(seg->element(1) == nullptr, "Extra start-repeat barline in 2nd staff of measure 5.");

//      QVERIFY(saveCompareScore(score, "barline03.mscx", DIR + "barline03-ref.mscx"));
      delete score;
      }

//---------------------------------------------------------
///   barline04
///   Sets custom span parameters to a system-initial start-repeat bar line and
///   check tht it is properly applied to it and to the start-reapeat bar lines of staves below.
//
//    NO REFERENCE SCORE IS USED.
//---------------------------------------------------------

void TestBarline::barline04()
      {
      Score* score = readScore(DIR + "barline04.mscx");
      QVERIFY(score);
      score->doLayout();

      // 'go' to 5th measure
      Measure* msr = score->firstMeasure();
      for (int i=0; i < 4; i++)
            msr = msr->nextMeasure();
      // check span data of measure-initial start-repeat bar line
      Segment* seg = msr->findSegment(Segment::Type::StartRepeatBarLine, msr->tick());
      QVERIFY2(seg != nullptr, "No SegStartRepeatBarLine segment in measure 5.");

      BarLine* bar = static_cast<BarLine*>(seg->element(0));
      QVERIFY2(bar != nullptr, "No start-repeat barline in measure 5.");

      score->undoChangeSingleBarLineSpan(bar, 2, 2, 6);
      score->doLayout();
      QVERIFY2(bar->span() == 2 && bar->spanFrom() == 2 && bar->spanTo() == 6,
            "Wrong span data in start-repeat barline of measure 5.");

      // check start-repeat bar ine in second staff is gone
      QVERIFY2(seg->element(1) == nullptr, "Extra start-repeat barline in 2nd staff of measure 5.");

//      QVERIFY(saveCompareScore(score, "barline04.mscx", DIR + "barline04-ref.mscx"));
      delete score;
      }

//---------------------------------------------------------
///   barline05
///   Adds a line break in the middle of a end-start-repeat bar line and then checks the two resulting
///   bar lines (an end-repeat and a start-repeat) are not marked as generated.
//
//    NO REFERENCE SCORE IS USED.
//---------------------------------------------------------

void TestBarline::barline05()
      {
      Score* score = readScore(DIR + "barline05.mscx");
      QVERIFY(score);
      score->doLayout();

      // 'go' to 4th measure
      Measure* msr = score->firstMeasure();
      for (int i=0; i < 3; i++)
            msr = msr->nextMeasure();
      // create and add a LineBreak element
      LayoutBreak* lb = new LayoutBreak(score);
      lb->setLayoutBreakType(LayoutBreak::Type::LINE);
      lb->setTrack(-1);             // system-level element
      lb->setParent(msr);
      score->undoAddElement(lb);
      score->doLayout();

      // check an end-repeat bar line has been created at the end of this measure and it is generated
      Segment* seg = msr->findSegment(Segment::Type::EndBarLine, msr->tick()+msr->ticks());
      QVERIFY2(seg != nullptr, "No SegEndBarLine segment in measure 4.");
      BarLine* bar = static_cast<BarLine*>(seg->element(0));
      QVERIFY2(bar != nullptr, "No end-repeat barline in measure 4.");
      QVERIFY2(bar->barLineType() == BarLineType::END_REPEAT, "Barline at measure 4 is not END-REPEAT");
      QVERIFY2(bar->generated(), "End-repeat barline in measure 4 is non-generated.");

      // check an end-repeat bar line has been created at the beginning of the next measure and it is not generated
      msr = msr->nextMeasure();
      seg = msr->findSegment(Segment::Type::StartRepeatBarLine, msr->tick());
      QVERIFY2(seg != nullptr, "No SegStartRepeatBarLine segment in measure 5.");
      bar = static_cast<BarLine*>(seg->element(0));
      QVERIFY2(bar != nullptr, "No start-repeat barline in measure 5.");
      QVERIFY2(!bar->generated(), "Start-reapeat barline in measure 5 is generated.");

//      QVERIFY(saveCompareScore(score, "barline05.mscx", DIR + "barline05-ref.mscx"));
      delete score;
      }

//---------------------------------------------------------
///   barline06
///   Read a score with 3 staves and custom bar line sub-types for staff i-th at measure i-th
///   and check the custom syb-types are applied only to their respective bar lines,
///   rather than to whole measures.
//
//    NO REFERENCE SCORE IS USED.
//---------------------------------------------------------

void TestBarline::barline06()
      {
      char  msg[256];
      Score* score = readScore(DIR + "barline06.mscx");
      QVERIFY(score);
      score->doLayout();

      // scan each measure
      Measure*    msr   = score->firstMeasure();
      int         msrNo = 1;
      for (int i=0; i < 3; i++) {
            // check measure endbarline type
            sprintf(msg, "EndBarLineType not NORMAL in measure %d.", msrNo);
            QVERIFY2(msr->endBarLineType() == BarLineType::NORMAL, msg);
            // locate end-measure bar line segment
            Segment* seg = msr->findSegment(Segment::Type::EndBarLine, msr->tick()+msr->ticks());
            sprintf(msg, "No SegEndBarLine in measure %d.", msr->no());
            QVERIFY2(seg != nullptr, msg);

            // check only i-th staff has custom bar line type
            for (int j=0; j < 3; j++) {
                  BarLine* bar = static_cast<BarLine*>(seg->element(j*VOICES));
                  // if not the i-th staff, bar should be normal and not custom
                  if (j != i) {
                        sprintf(msg, "barline type NOT NORMAL or CUSTOM TYPE in staff %d of measure %d.", j+1, msrNo);
                        QVERIFY2(bar->barLineType() == BarLineType::NORMAL, msg);
                        QVERIFY2(bar->customSubtype() == false, msg);
                        }
                  // in the i-th staff, the bar line should be of type DOUBLE and custom type should be true
                  else {
                        sprintf(msg, "No barline for staff %d in measure %d", j+1, msrNo);
                        QVERIFY2(bar != nullptr, msg);
                        sprintf(msg, "barline type NOT DOUBLE or NOT CUSTOM TYPE in staff %d of measure %d.", j+1, msrNo);
                        QVERIFY2(bar->barLineType() == BarLineType::DOUBLE, msg);
                        QVERIFY2(bar->customSubtype() == true, msg);
                        }
                  }

            msr = msr->nextMeasure();
            msrNo++;
            }
//      QVERIFY(saveCompareScore(score, "barline06.mscx", DIR + "barline06-ref.mscx"));
      delete score;
      }

QTEST_MAIN(TestBarline)
#include "tst_barline.moc"