lygre 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/grely.rb +37 -0
- data/lib/grely.rb +13 -0
- data/lib/lygre/gabcpitchreader.rb +134 -0
- data/lib/lygre/gabcscore.rb +88 -0
- data/lib/lygre/gabcsemantics.rb +138 -0
- data/lib/lygre/lilypondconvertor.rb +165 -0
- data/spec/gabcgrammar_spec.rb +222 -0
- data/spec/gabcparser_spec.rb +44 -0
- data/spec/gabcpitchreader_spec.rb +116 -0
- data/spec/gabcscore_spec.rb +143 -0
- data/spec/lilypondconvertor_spec.rb +144 -0
- data/spec/matchers.rb +20 -0
- data/spec/spec_helper.rb +37 -0
- metadata +125 -0
@@ -0,0 +1,222 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require_relative 'spec_helper'
|
4
|
+
|
5
|
+
# the GabcParser is described through the file format
|
6
|
+
# it should be able to parse
|
7
|
+
describe 'gabc' do
|
8
|
+
|
9
|
+
describe 'valid gabc file must contain a header delimiter' do
|
10
|
+
|
11
|
+
it 'file with just the header delimiter is valid' do
|
12
|
+
"%%\n".should compile
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'file without header delimiter is invalid' do
|
16
|
+
src = ""
|
17
|
+
src.should_not compile
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'header contains' do
|
22
|
+
|
23
|
+
describe 'whitespace' do
|
24
|
+
it '- any number of empty lines' do
|
25
|
+
src = "\n\n\n\n%%\n"
|
26
|
+
src.should compile
|
27
|
+
end
|
28
|
+
|
29
|
+
it '- spaces and tabs' do
|
30
|
+
src = " \n\t\n%%\n"
|
31
|
+
src.should compile
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe 'header fields' do
|
36
|
+
it '- e.g. "name"' do
|
37
|
+
src = "name: incipit;\n%%\n"
|
38
|
+
src.should compile
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'whose identifiers may include dashes' do
|
42
|
+
src = "office-part: introitus/...;\n%%\n"
|
43
|
+
src.should compile
|
44
|
+
end
|
45
|
+
|
46
|
+
it '- a lot of them' do
|
47
|
+
src = load_example 'header.gabc'
|
48
|
+
src.should compile
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'comments' do
|
53
|
+
it ', which may occupy a whole line' do
|
54
|
+
src = "% comment\n%%\n"
|
55
|
+
src.should compile
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'following whitespace' do
|
59
|
+
src = " % comm' comm' comment\n%%\n"
|
60
|
+
src.should compile
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'following header fields' do
|
64
|
+
src = "name: incipit; % what a beautiful name!\n%%\n"
|
65
|
+
src.should compile
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
describe 'body contains' do
|
72
|
+
|
73
|
+
describe 'whitespace' do
|
74
|
+
it '- any number of empty lines' do
|
75
|
+
"%%\n\n\n\n\n".should compile
|
76
|
+
end
|
77
|
+
|
78
|
+
it '- spaces and tabs' do
|
79
|
+
"%%\n \n\t\n".should compile
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe 'clef' do
|
84
|
+
it 'c clef on the 3rd line' do
|
85
|
+
"%%\n(c3)".should compile
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'c clef on the 1st line' do
|
89
|
+
"%%\n(c1)".should compile
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'c clef with bemol' do
|
93
|
+
"%%\n(cb3)".should compile
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'f clef on the 3rd line' do
|
97
|
+
"%%\n(f3)".should compile
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe 'music' do
|
102
|
+
it 'some simple notes' do
|
103
|
+
"%%\n(a) (h) (g) ".should compile
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'all possible notes' do
|
107
|
+
"%%\n (a) (b) (c) (d) (e) (f) (g) (h) (i) (j) (k) (l) (m)".should compile
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'empty music chunk is also valid' do
|
111
|
+
"%%\n ()".should compile
|
112
|
+
end
|
113
|
+
|
114
|
+
describe 'one-note neumes without and with shape modifiers' do
|
115
|
+
it { "%%\n (g)".should compile }
|
116
|
+
it { "%%\n (G) (G~) (G>)".should compile }
|
117
|
+
it { "%%\n (g~) (g<) (g>)".should compile }
|
118
|
+
it { "%%\n (go) (go~) (go<)".should compile }
|
119
|
+
it { "%%\n (gw) (gv) (gs) (gs<)".should compile }
|
120
|
+
it { "%%\n (-f)".should compile }
|
121
|
+
it { "%%\n (gqi)".should compile }
|
122
|
+
it { "%%\n (gWi)".should compile }
|
123
|
+
it { "%%\n (gr) (gR) (gr0)".should compile }
|
124
|
+
end
|
125
|
+
|
126
|
+
describe 'repetitions' do
|
127
|
+
it { "%%\n (gvv)".should compile }
|
128
|
+
it { "%%\n (gsss)".should compile }
|
129
|
+
end
|
130
|
+
|
131
|
+
describe 'rhythmic signs' do
|
132
|
+
it { "%%\n (g.)".should compile }
|
133
|
+
it { "%%\n (g..)".should compile }
|
134
|
+
it { "%%\n (g_)".should compile }
|
135
|
+
it { "%%\n (g')".should compile }
|
136
|
+
it { "%%\n (g_0)".should compile }
|
137
|
+
it { "%%\n (g__0)".should compile }
|
138
|
+
it { "%%\n (g_')".should compile }
|
139
|
+
it { "%%\n (g_h_)".should compile }
|
140
|
+
end
|
141
|
+
|
142
|
+
describe 'accents' do
|
143
|
+
it { "%%\n (gr1)".should compile }
|
144
|
+
it { "%%\n (gr0r1)".should compile } # linea punctum cavum + accent
|
145
|
+
it { "%%\n (gr2) (gr3) (gr4) (gr5)".should compile }
|
146
|
+
end
|
147
|
+
|
148
|
+
describe 'composed neumes' do
|
149
|
+
it { "%%\n (ghg)".should compile }
|
150
|
+
it { "%%\n (hvGFE)".should compile }
|
151
|
+
it { "%%\n (hghe)".should compile }
|
152
|
+
end
|
153
|
+
|
154
|
+
describe 'alterations' do
|
155
|
+
it { "%%\n (gxg)".should compile }
|
156
|
+
it { "%%\n (gyg)".should compile }
|
157
|
+
it { "%%\n (g#g)".should compile }
|
158
|
+
end
|
159
|
+
|
160
|
+
describe 'spaces' do
|
161
|
+
it { "%%\n (h/h)".should compile }
|
162
|
+
it { "%%\n (h//h)".should compile }
|
163
|
+
it { "%%\n (h h)".should compile }
|
164
|
+
it 'unbreakable space' do
|
165
|
+
"%%\n (h! h)".should compile
|
166
|
+
end
|
167
|
+
it 'prevent note linking' do
|
168
|
+
"%%\n (gh!i)".should compile
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
describe 'divisiones' do
|
173
|
+
it { "%%\n (,) (`) (;) (:) (::)".should compile }
|
174
|
+
it { "%%\n (;1) (;2) (;3) (;4) (;5) (;6)".should compile }
|
175
|
+
it { "%%\n (:') (,_)".should compile }
|
176
|
+
end
|
177
|
+
|
178
|
+
describe 'forced line-breaks' do
|
179
|
+
it { "%%\n (ez)".should compile }
|
180
|
+
it { "%%\n (eZ)".should compile }
|
181
|
+
end
|
182
|
+
|
183
|
+
describe 'custos, guide' do
|
184
|
+
it { "%%\n (z0)".should compile }
|
185
|
+
it { "%%\n (h) (g) (::) (h+)".should compile }
|
186
|
+
end
|
187
|
+
|
188
|
+
describe 'choral signs' do
|
189
|
+
it { "%%\n (g[cs:sign]h)".should compile }
|
190
|
+
end
|
191
|
+
|
192
|
+
describe 'braces' do
|
193
|
+
it { "%%\n (g[ob:1;6mm])".should compile }
|
194
|
+
it { "%%\n (g[ob:0;7mm])".should compile }
|
195
|
+
it { "%%\n (g[ocb:1;6mm])".should compile }
|
196
|
+
it { "%%\n (g[ocba:1;6mm])".should compile }
|
197
|
+
end
|
198
|
+
|
199
|
+
describe 'real-life examples that once failed' do
|
200
|
+
it { "%%\n ad(IV./hig)".should compile }
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
describe 'lyrics' do
|
205
|
+
it 'simple word with simple notes' do
|
206
|
+
"%%\n or(h)bis(h)".should compile
|
207
|
+
end
|
208
|
+
|
209
|
+
describe 'special characters' do
|
210
|
+
it { "%%\n <sp>R/</sp>() re(g)spon(f)sum(e)".should compile }
|
211
|
+
it { "%%\n tu(h)<sp>'ae</sp>(h)".should compile }
|
212
|
+
end
|
213
|
+
|
214
|
+
describe 'formatting' do
|
215
|
+
it { "%%\n <b>tu</b>(h)ae(h)".should compile }
|
216
|
+
it { "%%\n po(h)<i>pu</i>(h)<i>li</i>(h)".should compile }
|
217
|
+
it { "%%\n <sc>can. i</sc>()".should compile }
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
end
|
222
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe GabcParser do
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
# beginning of the Populus Sion example
|
9
|
+
@src = "name: Populus Sion;\n%%\n
|
10
|
+
(c3) Pó(eh/hi)pu(h)lus(h) Si(hi)on,(hgh.) *(;)
|
11
|
+
ec(hihi)ce(e.) Dó(e.f!gwh/hi)mi(h)nus(h) vé(hi)ni(ig/ih)et.(h.) (::)"
|
12
|
+
@parser = GabcParser.new
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#parse' do
|
16
|
+
it 'returns ScoreNode' do
|
17
|
+
@parser.parse(@src).should be_kind_of Gabc::ScoreNode
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'lyrics_syllable rule' do
|
22
|
+
it 'does not accept space' do
|
23
|
+
@parser.parse(' ', root: :lyrics_syllable).should be_nil
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'does not accept string beginning with space' do
|
27
|
+
@parser.parse(' aa', root: :lyrics_syllable).should be_nil
|
28
|
+
end
|
29
|
+
|
30
|
+
it 'accepts ascii characters' do
|
31
|
+
@parser.parse('aa', root: :lyrics_syllable).should be_true
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'accepts characters with accents' do
|
35
|
+
@parser.parse('áéíóúý', root: :lyrics_syllable).should be_true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe 'regular_word_character rule' do
|
40
|
+
it 'does not accept space' do
|
41
|
+
@parser.parse(' ', root: :regular_word_character).should be_nil
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,116 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
describe GabcPitchReader do
|
4
|
+
|
5
|
+
describe '.new' do
|
6
|
+
it 'takes clef type and position' do
|
7
|
+
pr = GabcPitchReader.new(:c, 3)
|
8
|
+
pr.clef.should eq :c
|
9
|
+
pr.clef_position.should eq 3
|
10
|
+
|
11
|
+
pr = GabcPitchReader.new(:f, 3)
|
12
|
+
pr.clef.should eq :f
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#base returns absolute pitch of the lowest writable note (a)' do
|
17
|
+
#it { GabcPitchReader.new(:c, 4).base.should eq NoteFactory["a"] }
|
18
|
+
#it { GabcPitchReader.new(:f, 2).base.should eq NoteFactory["a"] }
|
19
|
+
|
20
|
+
#it { GabcPitchReader.new(:c, 1).base.should eq NoteFactory["g'"] }
|
21
|
+
#it { GabcPitchReader.new(:f, 1).base.should eq NoteFactory["c'"] }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe NoteFactory do
|
26
|
+
|
27
|
+
before :all do
|
28
|
+
@f = NoteFactory
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '.create' do
|
32
|
+
it { @f.create("c'").value.should eq 60 }
|
33
|
+
it { @f.create("c''").value.should eq 72 }
|
34
|
+
it { @f.create("c'''").value.should eq 84 }
|
35
|
+
|
36
|
+
it { @f.create("c").value.should eq 48 }
|
37
|
+
it { @f.create("c,").value.should eq 36 }
|
38
|
+
it { @f.create("c,,").value.should eq 24 }
|
39
|
+
|
40
|
+
it { @f.create("c").value.should eq 48 }
|
41
|
+
it { @f.create("d").value.should eq 50 }
|
42
|
+
it { @f.create("e").value.should eq 52 }
|
43
|
+
it { @f.create("f").value.should eq 53 }
|
44
|
+
it { @f.create("g").value.should eq 55 }
|
45
|
+
it { @f.create("a").value.should eq 57 }
|
46
|
+
it { @f.create("b").value.should eq 59 }
|
47
|
+
|
48
|
+
it { expect { @f.create("x") }.to raise_exception ArgumentError }
|
49
|
+
it { expect { @f.create("c*") }.to raise_exception ArgumentError }
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '.lily_abs_pitch' do
|
53
|
+
it 'operates exactly reverse to .create' do
|
54
|
+
%w{ c d g c' f' a' b' g'' d''' c, c,, c,,, d, e, e,, b, }.each do |lypitch|
|
55
|
+
@f.lily_abs_pitch(@f[lypitch]).should eq lypitch
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
describe '[]' do
|
61
|
+
it { @f["c'"].value.should eq 60 }
|
62
|
+
it { @f["c''"].value.should eq 72 }
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe 'monkey-patched RBMusicTheory' do
|
67
|
+
|
68
|
+
before :each do
|
69
|
+
@f = NoteFactory
|
70
|
+
@s = @f["c''"].major_scale
|
71
|
+
end
|
72
|
+
|
73
|
+
describe 'Note#diatonic_steps' do
|
74
|
+
it { @f["c'"].diatonic_steps(1).should eq @f["d'"] }
|
75
|
+
it { @f["c'"].diatonic_steps(0).should eq @f["c'"] }
|
76
|
+
it { @f["c'"].diatonic_steps(7).should eq @f["c''"] }
|
77
|
+
it { @f["c'"].diatonic_steps(8).should eq @f["d''"] }
|
78
|
+
it { @f["c'"].diatonic_steps(-2).should eq @f["a"] }
|
79
|
+
it { @f["c''"].diatonic_steps(-9).should eq @f["a"] }
|
80
|
+
it { @f["c'''"].diatonic_steps(-9).should eq @f["a'"] }
|
81
|
+
it { @f["c,"].diatonic_steps(-9).should eq @f["a,,,"] }
|
82
|
+
it { @f["c,"].diatonic_steps(-10).should eq @f["g,,,"] }
|
83
|
+
end
|
84
|
+
|
85
|
+
describe 'Note#degree_in' do
|
86
|
+
it { @f["c''"].degree_in(@s).should eq 1 }
|
87
|
+
it { @f["d''"].degree_in(@s).should eq 2 }
|
88
|
+
|
89
|
+
it { @f["c'''"].degree_in(@s).should eq 8 }
|
90
|
+
it { @f["e'''"].degree_in(@s).should eq 10 }
|
91
|
+
it { @f["b'"].degree_in(@s).should eq 0 }
|
92
|
+
it { @f["a'"].degree_in(@s).should eq -1 }
|
93
|
+
it { @f["a"].degree_in(@s).should eq -8 }
|
94
|
+
|
95
|
+
it 'behaves consistently with Scale#degree' do
|
96
|
+
[2, 8, -1, -12].each do |deg|
|
97
|
+
@s.degree(deg).degree_in(@s).should eq deg
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe 'Scale#degree' do
|
103
|
+
describe 'for positive degrees it behaves as expected' do
|
104
|
+
it { @s.degree(1).should eq @f["c''"] }
|
105
|
+
it { @s.degree(2).should eq @f["d''"] }
|
106
|
+
it { @s.degree(8).should eq @f["c'''"] }
|
107
|
+
end
|
108
|
+
|
109
|
+
describe 'and then there is zero and negative numbers' do
|
110
|
+
it { @s.degree(0).should eq @f["b'"] }
|
111
|
+
it { @s.degree(-1).should eq @f["a'"] }
|
112
|
+
it { @s.degree(-8).should eq @f["a"] }
|
113
|
+
it { @s.degree(-15).should eq @f["a,"] }
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require_relative 'spec_helper'
|
4
|
+
|
5
|
+
# GabcScore is the parsing result returned by GabcParser
|
6
|
+
|
7
|
+
describe GabcScore do
|
8
|
+
|
9
|
+
before :each do
|
10
|
+
# beginning of the Populus Sion example
|
11
|
+
@src = "name: Populus Sion;\n%%\n
|
12
|
+
(c3) Pó(eh/hi)pu(h)lus(h) Si(hi)on,(hgh.) *(;)
|
13
|
+
ec(hihi)ce(e.) Dó(e.f!gwh/hi)mi(h)nus(h) vé(hi)ni(ig/ih)et.(h.) (::)"
|
14
|
+
@parser = GabcParser.new
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'creation' do
|
18
|
+
it 'is returned by ScoreNode#create_score' do
|
19
|
+
@parser.parse(@src).create_score.should be_a GabcScore
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#header' do
|
24
|
+
before :each do
|
25
|
+
@score = @parser.parse(@src).create_score
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'is a Hash' do
|
29
|
+
@score.header.should be_kind_of Hash
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'contains the field specified in the score' do
|
33
|
+
@score.header.should have_key 'name'
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'contains the field value' do
|
37
|
+
@score.header['name'].should eq 'Populus Sion'
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'may be empty' do
|
41
|
+
src = "%%\n"
|
42
|
+
score = @parser.parse(src).create_score
|
43
|
+
score.header.should be_empty
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#music' do
|
48
|
+
before :each do
|
49
|
+
@score = @parser.parse(@src).create_score
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'is GabcMusic' do
|
53
|
+
@score.music.should be_kind_of GabcMusic
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe GabcMusic do
|
59
|
+
|
60
|
+
before :each do
|
61
|
+
# beginning of the Populus Sion example
|
62
|
+
@src = "name: Populus Sion;\n%%\n
|
63
|
+
(c3) Pó(eh/hi)pu(h)lus(h) Si(hi)on,(hgh.) *(;)
|
64
|
+
ec(hihi)ce(e.) Dó(e.f!gwh/hi)mi(h)nus(h) vé(hi)ni(ig/ih)et.(h.) (::)"
|
65
|
+
@parser = GabcParser.new
|
66
|
+
@music = @parser.parse(@src).create_score.music
|
67
|
+
end
|
68
|
+
|
69
|
+
describe '#clef' do
|
70
|
+
subject { @music.clef }
|
71
|
+
it { should be_a GabcClef }
|
72
|
+
end
|
73
|
+
|
74
|
+
describe '#words' do
|
75
|
+
subject { @music.words }
|
76
|
+
it { should be_a Array }
|
77
|
+
it { should_not be_empty }
|
78
|
+
it { should contain_a GabcWord }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe GabcClef do
|
83
|
+
|
84
|
+
before :each do
|
85
|
+
# beginning of the Populus Sion example
|
86
|
+
@src = "name: Populus Sion;\n%%\n
|
87
|
+
(c3) Pó(eh/hi)pu(h)lus(h) Si(hi)on,(hgh.) *(;)
|
88
|
+
ec(hihi)ce(e.) Dó(e.f!gwh/hi)mi(h)nus(h) vé(hi)ni(ig/ih)et.(h.) (::)"
|
89
|
+
@parser = GabcParser.new
|
90
|
+
@music = @parser.parse(@src).create_score.music
|
91
|
+
@clef = @music.clef
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should return key from the score' do
|
95
|
+
@clef.to_s.should eq 'c3'
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'has no bemol' do
|
99
|
+
@clef.bemol.should be_false
|
100
|
+
end
|
101
|
+
|
102
|
+
describe 'has bemol' do
|
103
|
+
before :each do
|
104
|
+
src = "%%\n(cb3)"
|
105
|
+
@music = @parser.parse(src).create_score.music
|
106
|
+
end
|
107
|
+
|
108
|
+
it { @music.clef.bemol.should be_true }
|
109
|
+
it { @music.clef.to_s.should eq 'cb3' }
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
describe GabcWord do
|
114
|
+
before :each do
|
115
|
+
# beginning of the Populus Sion example
|
116
|
+
@src = "name: Populus Sion;\n%%\n
|
117
|
+
(c3) Pó(eh/hi)pu(h)lus(h) Si(hi)on,(hgh.) *(;)
|
118
|
+
ec(hihi)ce(e.) Dó(e.f!gwh/hi)mi(h)nus(h) vé(hi)ni(ig/ih)et.(h.) (::)"
|
119
|
+
@parser = GabcParser.new
|
120
|
+
@music = @parser.parse(@src).create_score.music
|
121
|
+
@word = @music.words.first
|
122
|
+
end
|
123
|
+
|
124
|
+
describe 'a simple word' do
|
125
|
+
subject { @word }
|
126
|
+
it { should_not be_empty }
|
127
|
+
it { should contain_a GabcSyllable }
|
128
|
+
end
|
129
|
+
|
130
|
+
describe 'lyrics' do
|
131
|
+
it { @word.size.should eq 3 }
|
132
|
+
it { @word.first.lyrics.should eq 'Pó' }
|
133
|
+
it { @word[1].lyrics.should eq 'pu' }
|
134
|
+
it { @music.words[1].first.lyrics.should eq 'Si' }
|
135
|
+
it { @music.words[-2].last.lyrics.should eq 'et.' }
|
136
|
+
it { @music.words.last.last.lyrics.should eq '' }
|
137
|
+
end
|
138
|
+
|
139
|
+
describe 'notes' do
|
140
|
+
it { @word.first.notes.should_not be_empty }
|
141
|
+
it { @word.first.notes.first.pitch.should eq :e }
|
142
|
+
end
|
143
|
+
end
|