1\version "2.21.0"
2#(use-modules (srfi srfi-13)
3              (ice-9 format))
4
5%%%
6%%% Testing utilities
7%%%
8#(use-modules (scm display-lily))
9#(memoize-clef-names supported-clefs)
10#(define (parse-lily-and-compute-lily-string chr port)
11  (let ((lily-string (call-with-output-string
12                      (lambda (out)
13                        (do ((c (read-char port) (read-char port)))
14                            ((and (char=? c #\#)
15                                  (char=? (peek-char port) #\]))
16                             (read-char port))
17                          (display c out))))))
18    `(let* ((parser-clone (ly:parser-clone))
19            (input-str (string-trim-both ,lily-string))
20            (music (ly:parse-string-expression parser-clone input-str))
21            (result-str (string-trim-both (music->lily-string music))))
22       (cons input-str result-str))))
23
24#(read-hash-extend #\[ parse-lily-and-compute-lily-string) %{ ] %}
25#(ly:set-option 'warning-as-error #t)
26
27%% option can be one of the following
28%%
29%% not provided    The expected output is the input.  This should be
30%%                 the norm.  Any difference will be logged and cause
31%%                 the test to fail.
32%%
33%% "NOT A BUG"     The expected output differs from the input in an
34%%                 unspecified way.  The difference will be logged
35%%                 but will not cause the test to fail.
36%%
37%% "BUG"           The expected output differs from the input in an
38%%                 unspecified way.  The difference will be logged
39%%                 but will not cause the test to fail.
40%%
41%% other           This is the exact expected output.  Any difference
42%%                 will be logged and cause the test to fail.
43test =
44#(define-void-function (option strings)
45  ((string?) pair?)
46  (let* ((input (car strings))
47         (actual-output (cdr strings))
48         (suppression (cond
49                       ((equal? option "BUG") option)
50                       ((equal? option "NOT A BUG") option)
51                       (else #f)))
52         (expected-output (if (or (not option) suppression)
53                           input
54                           option)))
55   (if (not (equal? expected-output actual-output))
56    (if suppression
57     (ly:progress "Test unequal: ~a.
58input    = ~a
59expected = ~a
60actual   = ~a"
61      suppression input expected-output actual-output)
62     (ly:input-warning (*location*) "Test unequal: BUG.
63input    = ~a
64expected = ~a
65actual   = ~a"
66      input expected-output actual-output)))))
67
68%%%
69%%% Tests
70%%%
71\header {
72  texidoc = "This is a test of the display-lily-music unit. Problems are reported on the
73stderr of this run."
74}
75
76%% Sequential music
77\test ##[ { { a4 b4 } { c4 d4 } } #]		% SequentialMusic
78\test ##[ << { a4 b4 } { c4 d4 } >> #]		% SimultaneousMusic
79\test ##[ << { a4 b4 } \\ { c4 d4 } >> #]	% VoiceSeparator
80
81%% Chords and Notes
82\test ##[ { ceses4 ces4 c4 cis4 cisis4 } #]	% NoteEvent
83\test ##[ { deses4 des4 d4 dis4 disis4 } #]
84\test ##[ { eeses4 ees4 e4 eis4 eisis4 } #]
85\test ##[ { feses4 fes4 f4 fis4 fisis4 } #]
86\test ##[ { geses4 ges4 g4 gis4 gisis4 } #]
87\test ##[ { aeses4 aes4 a4 ais4 aisis4 } #]
88\test ##[ { beses4 bes4 b4 bis4 bisis4 } #]
89\test ##[ { c,,4 d'4 } #]
90\test ##[ { c'4 d'='4 } #]
91\test ##[ { c!4 c?4 } #]
92\test ##[ r1.*4/3 #]		% RestEvent
93\test ##[ c1\rest #]		% RestEvent
94\test ##[ s2..*3/4 #]		% SkipEvent
95\test ##[ R1.*2/3 #]		% MultiMeasureRestMusicGroup, MultiMeasureRestEvent
96\test ##[ \skip 2.*3/4 #]		% SkipMusic
97\test ##[ < c\1 e\3 >4.*3/4-. #]	% EventChord, NoteEvent, StringNumberEvent, ArticulationEvent
98\test ##[ < c-1\4 >8 #]
99\test ##[ { < c e g c' >4 q8-. } #] % RepeatedChord
100
101%% tags
102\test ##[ { \tag #'foo { c4 d4 } } #]
103\test ##[ c4-\tag #'foo -\tag #'baz -^-. #]
104
105%% Graces
106\test ##[ { \grace c8 d2 } #]				% GraceMusic
107\test ##[ { \appoggiatura c8 d2 } #]
108\test ##[ { \acciaccatura c8 d2 } #]
109\test ##[ { c1 \afterGrace { b,16 c16 } d2 } #]
110
111%% Clusters
112\test ##[ { \makeClusters { c4 g4 } } #]		% ClusterNoteEvent
113
114%% Figured bass
115\test ##[ \figures { < 6 >4 } #]			% BassFigureEvent
116\test ##[ \figuremode { < 1-- 3- >4 < 2+ 4++ >4 < _! 7! >4 } #]
117\test ##[ \figuremode { < [6 >4 < 5] >4 } #]
118
119%% Lyrics
120\test ##[ \lyrics { a b } #]
121\test ##[ \lyricmode { a -- b } #] 		% HyphenEvent
122\test ##[ \lyricmode { a __ b } #] 		% ExtenderEvent
123\test ##[ \lyricmode { "a " } #] 			% LyricEvent
124\test ##[ \lyricsto "foo" { bla bla  } #]		% LyricCombineMusic
125\test ##[ { { c4 d4 }
126  \addlyrics { bla bla  } } #]
127
128%% Drums
129\test ##[ \drums { hihat4 } #]
130\test ##[ \drummode { hihat4.*3/4 } #]
131
132%% Expressive marks
133\test ##[ c4 ~ #]			 		% TieEvent
134\test ##[ c4\noBeam #] 					% BeamForbidEvent
135\test ##[ c4\1 #] 					% StringNumberEvent
136\test ##[ { c4:8 c4:1 } #]				% TremoloEvent
137\test ##[ { c4-^ c4^^ c4_^ } #]				% ArticulationEvent
138\test ##[ { c4-+ c4^+ c4_+ } #]
139\test ##[ { c4-- c4^- c4_- } #]
140\test ##[ { c4-! c4^! c4_! } #]
141\test ##[ { c4-> c4^> c4_> } #]
142\test ##[ { c4-. c4^. c4_. } #]
143\test ##[ { c4-_ c4^_ c4__ } #]
144\test ##[ { c4\trill c4^\trill c4_\trill } #]
145\test ##[ { c4-1 c4^2 c4_3 } #]				% FingerEvent
146\test ##[ { c4-"foo" c4^"foo" c4_"foo" } #]		% TextScriptEvent
147\test ##[ { R1*4-"foo" R1*4^"foo" R1*4_"foo" } #]	% MultiMeasureTextEvent
148\test ##[ { < c\harmonic >4 < c e\harmonic >4 } #] 	% HarmonicEvent
149\test ##[ { c4\glissando c4^\glissando c4_\glissando } #]	% GlissandoEvent
150\test ##[ { c4\arpeggio c4^\arpeggio c4_\arpeggio } #] 	% ArpeggioEvent
151\test ##[ { c4\p c4^\ff c4_\sfz } #] 			% AbsoluteDynamicEvent
152\test ##[ { c4[ c4] c4^[ c4^] c4_[ c4_] } #] 		% BeamEvent
153\test ##[ { c4( c4) c4^( c4^) c4_( c4_) } #] 		% SlurEvent
154\test ##[ { c4\< c4\! c4^\< c4^\! c4_\< c4_\! } #]	% CrescendoEvent
155\test ##[ { c4\> c4\! c4^\> c4^\! c4_\> c4_\! } #]	% DecrescendoEvent
156\test ##[ { c4\episemInitium c4\episemFinis } #]	% EpisemaEvent
157\test ##[ { c4\( c4\) c4^\( c4^\) c4_\( c4_\) } #]	% PhrasingSlurEvent
158\test ##[ { c4\sustainOn c4\sustainOff } #]		% SustainEvent
159\test ##[ { c4\sostenutoOn c4\sostenutoOff } #]		% SostenutoEvent
160\test ##[ \melisma #]
161\test ##[ \melismaEnd #]
162\test ##[ { c4\startTextSpan c4\stopTextSpan } #]	% TextSpanEvent
163\test ##[ { c4\startTrillSpan c4\stopTrillSpan } #]	% TrillSpanEvent
164\test ##[ { c4 \startStaff c4 \stopStaff } #]		% StaffSpanEvent
165\test ##[ { c4\startGroup c4\stopGroup c4^\startGroup c4^\stopGroup c4_\startGroup c4_\stopGroup } #]    % NoteGroupingEvent
166\test ##[ { c4\unaCorda c4\treCorde } #]		% UnaCordaEvent
167\test ##[ \breathe #]
168\test ##[ { c4 \[ c4 \] } #]				% LigatureEvent
169\test ##[ \~ #]						% PesOrFlexaEvent
170\test ##[ \- #]						% DurationLineEvent
171\test ##[ c4\bendAfter #3 #]				% BendAfterEvent
172\test ##[ c4\rightHandFinger #1 #]			% StrokeFingerEvent
173
174\test ##[ \break #]
175\test ##[ \noBreak #]
176\test ##[ \pageBreak #]
177\test ##[ \noPageBreak #]
178\test ##[ \pageTurn #]
179\test ##[ \noPageTurn #]
180
181%% Checks
182\test ##[ \octaveCheck a' #]				% RelativeOctaveCheck
183\test ##[ | #]						% BarCheck
184
185%% Marks
186\test ##[ \mark \default #]			% MarkEvent
187\test ##[ \mark #3 #]
188\test ##[ \mark "Z" #]
189\test ##[ \mark \markup \italic "X" #]
190\test ##[ \mark "Allegro" #]
191\test ##[ \tempo 4 = 120 #]			% MetronomeChangeEvent
192\test ##[ \tempo 4 = 108 - 116 #]
193\test ##[ \tempo "Allegro" 4 = 132 #]
194\test ##[ \tempo "Andante" #]
195
196%% key, time, clef, bar
197\test ##[ \key \default #]			% KeyChangeEvent
198\test ##[ \key e \minor #]
199\test ##[ \clef "bass" #]
200\test ##[ \clef "french^2" #]
201\test ##[ \clef "treble_[8]" #]
202\test ##[ \clef "bass^(15)" #]
203\test ##[ \clef "alto_3" #]
204\test ##[ \time 2/4 #]
205\test ##[ \time 3,2 5/8 #]
206\test ##[ \bar "|." #]
207
208%% staff switches
209\test ##[ \autoChange { c4 d4 } #]			% AutoChangeMusic
210\test ##[ { \change Staff = "up" { c4 d4 } } #]		% ContextChange
211
212%% Tuplets
213\test ##[ \tuplet 3/2 { c8 d8 e8 } #]				% TimeScaledMusic
214\test ##[ \tuplet 6/4 { c16 d16 e16 f16 g16 a16 } #]
215\test ##[ \tuplet 3/2 { c4 d4 e4 \tuplet 5/2 { f4 e4 d2 d4 } c4 } #]
216\test ##[ \tuplet 3/2 2 { c4 d4 e4 \tuplet 5/2 2 { f4 e4 d2 d4 } c4 } #]
217
218%% pure rhythm
219\test ##[ { 4 4 8 \tuplet 3/2 { 8[ 16] } 16 } #]
220
221%% \relative and \transpose
222\test "\absolute { c'4 f'4 }"
223      ##[ \relative { c'4 f4 } #]			% RelativeOctaveMusic
224\test "{ d4 e4 }"
225      ##[ \transpose c d { c4 d4 } #]			% TransposedMusic
226
227%% Repeats
228\test ##[ \repeat volta 2 { c4 d4 } #]			% VoltaRepeatedMusic
229\test ##[ \repeat unfold 2 { c4 d4 } #]			% UnfoldedRepeatedMusic
230\test ##[ \repeat percent 2 { c4 d4 } #]		% PercentRepeatedMusic
231\test ##[ \repeat tremolo 4 { c16 d16 } #]		% TremoloRepeatedMusic
232\test ##[ \repeat tremolo 7 { c''32 b'32 } #]
233\test ##[ \repeat tremolo 15 { c''16 b'16 } #]
234\test ##[ \repeat volta 2 { c4 d4 } \alternative { { c4 d4 } { e4 f4 } } #]    %
235
236%% Context creation
237\test ##[ \new Staff { c4 d4 } #]			% ContextSpeccedMusic
238\test ##[ \new Staff = "up" { c4 d4 } #]		% ContextSpeccedMusic
239\test ##[ \context Staff { c4 d4 } #]
240\test ##[ \context Staff = "up" { c4 d4 } #]
241\test ##[
242\new Staff \with {
243  \consists "Timing_engraver"
244  \remove "Clef_engraver"
245} { c4 d4 } #]
246%% Context properties
247\test ##[ \once \set Score.skipBars = ##t #]		% PropertySet
248\test ##[ \set autoBeaming = ##f #]
249\test ##[ \unset Score.skipBars #]			% PropertyUnset
250\test ##[ \unset autoBeaming #]
251%% Layout properties
252\test ##[ \override Staff.Stem.thickness = #4.0 #]	% OverrideProperty
253\test ##[ \once \override Beam.beam-thickness = #0.6 #]
254\test ##[ \revert Staff.Stem.thickness #]		% RevertProperty
255\test ##[ \revert Beam.beam-thickness #]
256\test "NOT A BUG" ##[ \oneVoice #]	% resetting a bunch of properties
257\test ##[ \override StaffGrouper.staff-staff-spacing.basic-distance = #7 #]    % nested properties
258\test ##[ \revert StaffGrouper.staff-staff-spacing.basic-distance #]    % nested properties
259
260%% \applyOutput
261\test ##[ \applyOutput Foo #identity #]
262\test ##[ \applyOutput Foo.NoteHead #identity #]
263%% \applyContext
264\test ##[ \applyContext #identity #]
265
266%% \partial
267\test ##[ \partial 2 #]
268\test ##[ \partial 8. #]
269\test ##[ \partial 4*2/3 #]
270
271%% \partCombine
272\test ##[ \partCombine { c4 e4 }
273{ d4 f4 } #]
274\test ##[ \partCombineUp { c2 e2 }
275{ d2 f2 } #]
276\test ##[ \partCombineDown { c1 e1 }
277{ d1 f1 } #]
278
279%% Cue notes
280\test ##[ \cueDuring "foo" #1 { c4 d4 } #]
281\test ##[ \quoteDuring "foo" { c4 d4 } #]
282
283%% \ottava
284\test ##[ \ottava #1 #]    % OttavaMusic
285
286%% \tweak
287\test ##[ < \tweak duration-log #2 c >4 #]
288\test ##[ < c \tweak transparent ##t e >4 #]
289\test ##[ < \tweak color #'(1.0 0.0 0.0) \tweak duration-log #2 c >4 #]
290\test ##[ c4-\tweak font-size #3 -> #]
291\test ##[ < \tweak Accidental.color #'(1.0 0.0 0.0) cis eis g >4 #]
292
293%% end test.
294
295#(read-hash-extend #\[ #f) %{ ] %}
296