brevity 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.document +3 -0
- data/.gitignore +7 -0
- data/.rspec +1 -0
- data/.ruby-version +1 -0
- data/.yardopts +1 -0
- data/ChangeLog.rdoc +4 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +27 -0
- data/Rakefile +67 -0
- data/bin/debrief +56 -0
- data/brevity.gemspec +28 -0
- data/examples/alley_cat.br +50 -0
- data/examples/hip.br +15 -0
- data/examples/missed_connection.br +6 -0
- data/examples/song1.br +11 -0
- data/examples/song2.br +10 -0
- data/examples/twinkle.br +18 -0
- data/lib/brevity/commands/constants.rb +18 -0
- data/lib/brevity/commands/expr.rb +17 -0
- data/lib/brevity/commands/meter.rb +20 -0
- data/lib/brevity/commands/part.rb +47 -0
- data/lib/brevity/commands/tempo.rb +13 -0
- data/lib/brevity/itemization.rb +73 -0
- data/lib/brevity/parsing/expression/dynamic.rb +280 -0
- data/lib/brevity/parsing/expression/dynamic.treetop +41 -0
- data/lib/brevity/parsing/expression/dynamic_nodes.rb +55 -0
- data/lib/brevity/parsing/expression/expression.rb +429 -0
- data/lib/brevity/parsing/expression/expression.treetop +39 -0
- data/lib/brevity/parsing/expression/expression_nodes.rb +26 -0
- data/lib/brevity/parsing/expression/gradual.rb +44 -0
- data/lib/brevity/parsing/expression/gradual.treetop +9 -0
- data/lib/brevity/parsing/expression/gradual_node.rb +11 -0
- data/lib/brevity/parsing/expression/label.rb +75 -0
- data/lib/brevity/parsing/expression/label.treetop +9 -0
- data/lib/brevity/parsing/expression/label_node.rb +15 -0
- data/lib/brevity/parsing/expression/sequence.rb +130 -0
- data/lib/brevity/parsing/expression/sequence.treetop +12 -0
- data/lib/brevity/parsing/expression/sequence_node.rb +14 -0
- data/lib/brevity/parsing/file/command.rb +216 -0
- data/lib/brevity/parsing/file/command.treetop +17 -0
- data/lib/brevity/parsing/file/command_node.rb +11 -0
- data/lib/brevity/parsing/file/comment.rb +178 -0
- data/lib/brevity/parsing/file/comment.treetop +21 -0
- data/lib/brevity/parsing/file/comment_node.rb +3 -0
- data/lib/brevity/parsing/file/file.rb +152 -0
- data/lib/brevity/parsing/file/file.treetop +16 -0
- data/lib/brevity/parsing/file/file_node.rb +7 -0
- data/lib/brevity/parsing/file/path.rb +235 -0
- data/lib/brevity/parsing/file/path.treetop +12 -0
- data/lib/brevity/parsing/modifiers/duplicate_modifier.rb +65 -0
- data/lib/brevity/parsing/modifiers/duplicate_modifier.treetop +11 -0
- data/lib/brevity/parsing/modifiers/duplicate_modifier_node.rb +8 -0
- data/lib/brevity/parsing/modifiers/modifier.rb +64 -0
- data/lib/brevity/parsing/modifiers/modifier.treetop +13 -0
- data/lib/brevity/parsing/modifiers/stretch_modifier.rb +69 -0
- data/lib/brevity/parsing/modifiers/stretch_modifier.treetop +11 -0
- data/lib/brevity/parsing/modifiers/stretch_modifier_node.rb +21 -0
- data/lib/brevity/parsing/modifiers/transpose_modifier.rb +69 -0
- data/lib/brevity/parsing/modifiers/transpose_modifier.treetop +11 -0
- data/lib/brevity/parsing/modifiers/transpose_modifier_node.rb +13 -0
- data/lib/brevity/parsing/note/accent.rb +44 -0
- data/lib/brevity/parsing/note/accent.treetop +9 -0
- data/lib/brevity/parsing/note/duration.rb +203 -0
- data/lib/brevity/parsing/note/duration.treetop +23 -0
- data/lib/brevity/parsing/note/duration_nodes.rb +19 -0
- data/lib/brevity/parsing/note/link.rb +69 -0
- data/lib/brevity/parsing/note/link.treetop +11 -0
- data/lib/brevity/parsing/note/link_node.rb +19 -0
- data/lib/brevity/parsing/note/note.rb +300 -0
- data/lib/brevity/parsing/note/note.treetop +30 -0
- data/lib/brevity/parsing/note/note_nodes.rb +77 -0
- data/lib/brevity/parsing/note/pitch.rb +81 -0
- data/lib/brevity/parsing/note/pitch.treetop +9 -0
- data/lib/brevity/parsing/note/pitch_node.rb +50 -0
- data/lib/brevity/parsing/numbers/nonnegative_integer.rb +53 -0
- data/lib/brevity/parsing/numbers/nonnegative_integer.treetop +9 -0
- data/lib/brevity/parsing/numbers/positive_integer.rb +91 -0
- data/lib/brevity/parsing/numbers/positive_integer.treetop +15 -0
- data/lib/brevity/read_file.rb +18 -0
- data/lib/brevity/score_maker.rb +64 -0
- data/lib/brevity/version.rb +4 -0
- data/lib/brevity.rb +53 -0
- data/manuals/brevity.pdf +0 -0
- data/manuals/brevity.tex +273 -0
- data/spec/brevity_spec.rb +8 -0
- data/spec/commands/expr_spec.rb +15 -0
- data/spec/commands/meter_spec.rb +21 -0
- data/spec/commands/part_spec.rb +16 -0
- data/spec/commands/tempo_spec.rb +20 -0
- data/spec/itemization_spec.rb +46 -0
- data/spec/parsing/expression/dynamic_nodes_spec.rb +32 -0
- data/spec/parsing/expression/dynamic_spec.rb +23 -0
- data/spec/parsing/expression/expression_nodes_spec.rb +87 -0
- data/spec/parsing/expression/expression_spec.rb +85 -0
- data/spec/parsing/expression/gradual_spec.rb +10 -0
- data/spec/parsing/expression/label_node_spec.rb +13 -0
- data/spec/parsing/expression/label_spec.rb +35 -0
- data/spec/parsing/file/command_node_spec.rb +29 -0
- data/spec/parsing/file/command_spec.rb +18 -0
- data/spec/parsing/file/comment_spec.rb +14 -0
- data/spec/parsing/file/file_node_spec.rb +19 -0
- data/spec/parsing/file/file_spec.rb +30 -0
- data/spec/parsing/modifiers/modifier_nodes_spec.rb +25 -0
- data/spec/parsing/modifiers/modifier_parsers_spec.rb +20 -0
- data/spec/parsing/note/accent_spec.rb +27 -0
- data/spec/parsing/note/duration_nodes_spec.rb +79 -0
- data/spec/parsing/note/duration_spec.rb +69 -0
- data/spec/parsing/note/link_node_spec.rb +30 -0
- data/spec/parsing/note/link_spec.rb +23 -0
- data/spec/parsing/note/note_nodes_spec.rb +82 -0
- data/spec/parsing/note/note_spec.rb +188 -0
- data/spec/parsing/note/pitch_node_spec.rb +48 -0
- data/spec/parsing/note/pitch_spec.rb +23 -0
- data/spec/parsing/numbers/nonnegative_integer_spec.rb +11 -0
- data/spec/parsing/numbers/positive_integer_spec.rb +17 -0
- data/spec/spec_helper.rb +112 -0
- metadata +293 -0
@@ -0,0 +1,87 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe ExpressionNode do
|
4
|
+
describe '#primitives' do
|
5
|
+
context 'simple sequence' do
|
6
|
+
it 'should be converted to array of notes' do
|
7
|
+
str = SEQUENCES.keys.last
|
8
|
+
node = EXPR_PARSER.parse(str)
|
9
|
+
|
10
|
+
tgt = SEQUENCES[str]
|
11
|
+
node.primitives({}).should eq tgt
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context 'composed sequences' do
|
16
|
+
it 'should combine them into a single array' do
|
17
|
+
strA, strB = SEQUENCES.keys[-2..-1]
|
18
|
+
tgt = SEQUENCES[strA].clone + SEQUENCES[strB].clone
|
19
|
+
str = strA + " (#{strB})"
|
20
|
+
EXPR_PARSER.parse(str).primitives({}).should eq tgt
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context 'chained modifications' do
|
25
|
+
it 'should produce a single part, applying all modifications in sequence' do
|
26
|
+
str = SEQUENCES.keys.last
|
27
|
+
notes = SEQUENCES[str]
|
28
|
+
str = "(#{str})"
|
29
|
+
MODIFIERS.each do |modtype,modcases|
|
30
|
+
modstrs, modlambdas = modcases.entries.transpose
|
31
|
+
modstr = modstrs.join
|
32
|
+
tgt = notes.clone
|
33
|
+
modlambdas.each {|l| tgt = l.call(tgt) }
|
34
|
+
node = EXPR_PARSER.parse(str + modstr)
|
35
|
+
node.primitives({}).should eq(tgt)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'with dynamic changes' do
|
41
|
+
it 'should convert dynamic changes to dynamic values and gradual nodes' do
|
42
|
+
{
|
43
|
+
"mp /2 > /2A2 f < /4C4 mp" => [
|
44
|
+
Dynamics::MP, Note::Half.new, GradualParser.new.parse(">"),
|
45
|
+
Note::Half.new([A2]), Dynamics::F, GradualParser.new.parse("<"),
|
46
|
+
Note::Quarter.new([C4]), Dynamics::MP
|
47
|
+
]
|
48
|
+
}.each do |str,tgt|
|
49
|
+
node = EXPR_PARSER.parse(str)
|
50
|
+
primitives = node.primitives({})
|
51
|
+
primitives.should eq tgt
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe GroupNode do
|
59
|
+
describe '#primitives' do
|
60
|
+
it 'should produce same array as the string that is in parenthesis' do
|
61
|
+
SEQUENCES.each do |str,tgt|
|
62
|
+
node = EXPR_PARSER.parse(str)
|
63
|
+
node2 = EXPR_PARSER.parse("(#{str})")
|
64
|
+
node.primitives({}).should eq(node2.primitives({}))
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe ModifiableNode do
|
71
|
+
describe '#primitives' do
|
72
|
+
it 'should produce a modified array' do
|
73
|
+
SEQUENCES.each do |seqstr,tgt|
|
74
|
+
MODIFIERS.each do |modtype,modcases|
|
75
|
+
modcases.each do |modstr,modlambda|
|
76
|
+
str = "(#{seqstr})#{modstr}"
|
77
|
+
tgtmod = modlambda.call(tgt)
|
78
|
+
|
79
|
+
node = EXPR_PARSER.parse str
|
80
|
+
res = node.primitives({})
|
81
|
+
res.should eq tgtmod
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe ExpressionParser do
|
4
|
+
context 'single note' do
|
5
|
+
it 'should parse as ExpressionNode' do
|
6
|
+
NOTES.keys.each {|str| EXPR_PARSER.should parse_as(str,ExpressionNode) }
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
context 'note sequence only' do
|
11
|
+
it 'should parse as ExpressionNode' do
|
12
|
+
SEQUENCES.keys.each {|str| EXPR_PARSER.should parse_as(str,ExpressionNode) }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context 'grouped note sequence' do
|
17
|
+
it 'should parse as ExpressionNode' do
|
18
|
+
SEQUENCES.keys.each {|str| EXPR_PARSER.should parse_as("(#{str})",ExpressionNode) }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context 'composed sequences' do
|
23
|
+
it 'should parse as ExpressionNode' do
|
24
|
+
strs = SEQUENCES.keys[0..2]
|
25
|
+
str = "#{strs[0]} (#{strs[1]}) #{strs[2]}"
|
26
|
+
EXPR_PARSER.should parse_as(str,ExpressionNode)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context 'modified sequence' do
|
31
|
+
context 'labeled sequence' do
|
32
|
+
it 'should parse as ExpressionNode' do
|
33
|
+
MODIFIERS.each do |modtype,cases|
|
34
|
+
cases.keys.each do |modstr,modlambda|
|
35
|
+
str = "#{LABELS[0]}#{modstr}"
|
36
|
+
EXPR_PARSER.should parse_as(str,ExpressionNode)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'grouped sequence' do
|
43
|
+
it 'should parse as ExpressionNode' do
|
44
|
+
MODIFIERS.each do |modtype,cases|
|
45
|
+
cases.keys.each do |modstr,modlambda|
|
46
|
+
str = "(#{SEQUENCES.keys.last})#{modstr}"
|
47
|
+
EXPR_PARSER.should parse_as(str,ExpressionNode)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'single note' do
|
54
|
+
it 'should parse as ExpressionNode' do
|
55
|
+
MODIFIERS.each do |modtype,cases|
|
56
|
+
cases.keys.each do |modstr,modlambda|
|
57
|
+
str = "#{NOTES.keys[0]}#{modstr}"
|
58
|
+
EXPR_PARSER.should parse_as(str,ExpressionNode)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'chained modification' do
|
66
|
+
it 'should parse as ExpressionNode' do
|
67
|
+
str = "(#{SEQUENCES.keys.last}):1+2-2=/2*3/2"
|
68
|
+
EXPR_PARSER.should parse_as(str,ExpressionNode)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'with dynamic changes' do
|
73
|
+
it 'should parse as ExpressionNode' do
|
74
|
+
str = "mp /2 > /2A2 f < /4C4 mp"
|
75
|
+
EXPR_PARSER.should parse_as(str,ExpressionNode)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
context 'separated by spaces, tabs, carriage returns, and newlines' do
|
80
|
+
it 'should parse as ExpressionNode' do
|
81
|
+
str = "(mp /2 ppp \n /2) /4 /4 \r\n /4"
|
82
|
+
EXPR_PARSER.should parse_as(str,ExpressionNode)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe GradualParser do
|
4
|
+
context '> or <' do
|
5
|
+
it 'should parse as GradualNode' do
|
6
|
+
GradualParser.new.should parse_as('>',GradualNode)
|
7
|
+
GradualParser.new.should parse_as('<',GradualNode)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe LabelNode do
|
4
|
+
describe '#primitives' do
|
5
|
+
it 'should fetch whatever is in given Hash' do
|
6
|
+
LABELS.each do |str|
|
7
|
+
node = LABEL_PARSER.parse(str)
|
8
|
+
tgt = [Note::Quarter.new]
|
9
|
+
node.primitives({ node.to_key => tgt }).should eq tgt
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe LabelParser do
|
4
|
+
context 'alphabetic only' do
|
5
|
+
it 'should parse' do
|
6
|
+
["abc","HiThere","Yeah","oKAY"].each do |str|
|
7
|
+
LABEL_PARSER.parse(str).should_not be nil
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'alphabetic plus numbers (after first char)' do
|
13
|
+
it 'should parse' do
|
14
|
+
["abc123","HiThere1","C00kieCrisp"].each do |str|
|
15
|
+
LABEL_PARSER.parse(str).should_not be nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'alphabetic with underscores' do
|
21
|
+
it 'should parse' do
|
22
|
+
["_okaydokee","looks_good","Hey_There555"].each do |str|
|
23
|
+
LABEL_PARSER.parse(str).should_not be nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'non-alphabetic chars' do
|
29
|
+
it 'should not parse' do
|
30
|
+
["Hey there","what?","yeah."].each do |str|
|
31
|
+
LABEL_PARSER.parse(str).should be nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe CommandNode do
|
4
|
+
describe '#name' do
|
5
|
+
it 'should return the given command name' do
|
6
|
+
{
|
7
|
+
'\bake' => 'bake',
|
8
|
+
'\once{}' => 'once',
|
9
|
+
'\dosomething{123}{456}' => 'dosomething'
|
10
|
+
}.each do |str,tgt|
|
11
|
+
node = COMMAND_PARSER.parse(str)
|
12
|
+
node.name.should eq tgt
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe '#args' do
|
18
|
+
it 'should return the strings in braces' do
|
19
|
+
{
|
20
|
+
'\bake' => [],
|
21
|
+
'\once{}' => [''],
|
22
|
+
'\dosomething{123}{456}' => ['123','456']
|
23
|
+
}.each do |str,tgt|
|
24
|
+
node = COMMAND_PARSER.parse(str)
|
25
|
+
node.args.should eq tgt
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe CommandParser do
|
4
|
+
describe '#parse' do
|
5
|
+
before :all do
|
6
|
+
@parser = CommandParser.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should parse as a CommandNode' do
|
10
|
+
[ '\bake','\baketwo{}{}','\sandwich{Ham}{Cheese}',
|
11
|
+
'\icecream{Vanilla}{Chocolate Syrup}{sprinkles}',
|
12
|
+
'\gobbledegook{akw4hf&Q(#^$hlka}{::".[p,!!!}'
|
13
|
+
].each do |str|
|
14
|
+
@parser.should parse_as(str,CommandNode)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe CommentParser do
|
4
|
+
context 'string starts with #' do
|
5
|
+
it 'should parse' do
|
6
|
+
[ "#",
|
7
|
+
"# Hello world",
|
8
|
+
"# This can be anything at all :)"
|
9
|
+
].each do |str|
|
10
|
+
COMMENT_PARSER.should parse(str)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe FileNode do
|
4
|
+
describe '#command_nodes' do
|
5
|
+
it 'should return the given command nodes' do
|
6
|
+
cmd_strs = ['\bake','\once{}','\dosomething{123}{456}',"\\seq{abc}{\2 \2 \1C2\n \2 \2}"]
|
7
|
+
cmds = cmd_strs.map{ |str| COMMAND_PARSER.parse(str) }
|
8
|
+
[" ","\n"].each do |sep|
|
9
|
+
str = cmd_strs.join(sep)
|
10
|
+
node = FILE_PARSER.parse(str)
|
11
|
+
command_nodes = node.command_nodes
|
12
|
+
command_nodes.each_index do |i|
|
13
|
+
command_nodes[i].name.should eq cmds[i].name
|
14
|
+
command_nodes[i].args.should eq cmds[i].args
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe FileParser do
|
4
|
+
{
|
5
|
+
'commands spanning multiple lines' => (
|
6
|
+
"\t \\seq{ABC}{\n" +
|
7
|
+
"\t /2 /2 /4C2 /4C2 /2\n" +
|
8
|
+
"\t /2 /2:2 (/4 /4C4):2\n" +
|
9
|
+
"\t }\n" +
|
10
|
+
"\t \\seq{DEF}{\n" +
|
11
|
+
"\t /4 /4 mylabel}\n" +
|
12
|
+
"\n"),
|
13
|
+
'commands on same line' => (
|
14
|
+
"\\seq{ABC}{ /2 /4C2 }\\seq{DEF}{ /4C2 /4C2}\\starttempo{120}"
|
15
|
+
),
|
16
|
+
'expressions, commands, and comments' => (
|
17
|
+
"# This is a comment, everything after is fine!!!\n" +
|
18
|
+
"\\seq{ABC}{ /2 /4C2} \\seq{DEF}{ /4C2 /4C2}\n" +
|
19
|
+
"# Another comment here\n" +
|
20
|
+
"\\starttempo{120}\n" +
|
21
|
+
"# Annnnd, the last word.\n"
|
22
|
+
)
|
23
|
+
}.each do |context_str,str|
|
24
|
+
context context_str do
|
25
|
+
it 'should parse as FileNode' do
|
26
|
+
FILE_PARSER.should parse_as(str,FileNode)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
{ :duplicate => [DuplicateModifierParser.new,DuplicateModifierNode],
|
4
|
+
:transpose => [TransposeModifierParser.new,TransposeModifierNode],
|
5
|
+
:stretch => [StretchModifierParser.new,StretchModifierNode],
|
6
|
+
}.each do |modtype,classes|
|
7
|
+
modparser, nodeclass = classes
|
8
|
+
|
9
|
+
describe nodeclass do
|
10
|
+
describe '#process' do
|
11
|
+
it 'should produce a modified array, according to str' do
|
12
|
+
SEQUENCES.each do |seqstr,src|
|
13
|
+
MODIFIERS[modtype].each do |modstr,modlambda|
|
14
|
+
tgt = modlambda.call(src)
|
15
|
+
|
16
|
+
modnode = modparser.parse(modstr)
|
17
|
+
res = modnode.process src
|
18
|
+
res.should be_a Array
|
19
|
+
res.should eq tgt
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
{ :duplicate => [DuplicateModifierParser,DuplicateModifierNode],
|
4
|
+
:transpose => [TransposeModifierParser,TransposeModifierNode],
|
5
|
+
:stretch => [StretchModifierParser,StretchModifierNode],
|
6
|
+
}.each do |modtype,classes|
|
7
|
+
modparser, nodeclass = classes
|
8
|
+
|
9
|
+
describe modparser do
|
10
|
+
before :all do
|
11
|
+
@parser = modparser.new
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should parse as #{nodeclass}" do
|
15
|
+
MODIFIERS[modtype].keys.each do |str|
|
16
|
+
@parser.should parse_as(str,nodeclass)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe AccentParser do
|
4
|
+
before :all do
|
5
|
+
@parser = AccentParser.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should parse a "."' do
|
9
|
+
@parser.parse(".").should_not be nil
|
10
|
+
end
|
11
|
+
|
12
|
+
it "should parse a \"'\"" do
|
13
|
+
@parser.parse("'").should_not be nil
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should parse a ">"' do
|
17
|
+
@parser.parse(">").should_not be nil
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should parse a "^"' do
|
21
|
+
@parser.parse("^").should_not be nil
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should parse a "_"' do
|
25
|
+
@parser.parse("_").should_not be nil
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe NumDenNode do
|
4
|
+
{
|
5
|
+
'1/2' => Rational(1,2),
|
6
|
+
'5/100' => Rational(5,100),
|
7
|
+
'007/777' => Rational(7,777)
|
8
|
+
}.each do |str,tgt|
|
9
|
+
res = DUR_PARSER.parse(str)
|
10
|
+
context str do
|
11
|
+
it 'should parse as NumDenNode' do
|
12
|
+
res.should be_a NumDenNode
|
13
|
+
end
|
14
|
+
|
15
|
+
describe '#to_r' do
|
16
|
+
r = res.to_r
|
17
|
+
it 'should produce a Rational' do
|
18
|
+
r.should be_a Rational
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should produce value matching input str' do
|
22
|
+
r.should eq tgt
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe NumOnlyNode do
|
30
|
+
{
|
31
|
+
'1/' => Rational(1,1),
|
32
|
+
'5' => Rational(5,1),
|
33
|
+
'007/' => Rational(7,1)
|
34
|
+
}.each do |str,tgt|
|
35
|
+
res = DUR_PARSER.parse(str)
|
36
|
+
context str do
|
37
|
+
it 'should parse as NumOnlyNode' do
|
38
|
+
res.should be_a NumOnlyNode
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#to_r' do
|
42
|
+
r = res.to_r
|
43
|
+
it 'should produce a Rational' do
|
44
|
+
r.should be_a Rational
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should produce value matching input str' do
|
48
|
+
r.should eq tgt
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe DenOnlyNode do
|
56
|
+
{
|
57
|
+
'/2' => Rational(1,2),
|
58
|
+
'/100' => Rational(1,100),
|
59
|
+
'/777' => Rational(1,777)
|
60
|
+
}.each do |str,tgt|
|
61
|
+
res = DUR_PARSER.parse(str)
|
62
|
+
context str do
|
63
|
+
it 'should parse as DenOnlyNode' do
|
64
|
+
res.should be_a DenOnlyNode
|
65
|
+
end
|
66
|
+
|
67
|
+
describe '#to_r' do
|
68
|
+
r = res.to_r
|
69
|
+
it 'should produce a Rational' do
|
70
|
+
r.should be_a Rational
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should produce value matching input str' do
|
74
|
+
r.should eq tgt
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe DurationParser do
|
4
|
+
before :all do
|
5
|
+
@valid = {
|
6
|
+
:numbers => [1,5,50,3999,01,0010,0000005050],
|
7
|
+
}
|
8
|
+
|
9
|
+
@invalid = {
|
10
|
+
:numbers => [0,00],
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
context 'valid (non-zero) numerator and denominator' do
|
15
|
+
["n","n/","n/d","/d"].each do |expr|
|
16
|
+
it "should parse durations of the form #{expr}" do
|
17
|
+
@valid[:numbers].each do |n|
|
18
|
+
@valid[:numbers].each do |d|
|
19
|
+
str = expr.gsub('n',"#{n}")
|
20
|
+
str = str.gsub('d',"#{d}")
|
21
|
+
DUR_PARSER.parse(str).should_not be nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'invalid (zero) numerator and valid denominator' do
|
29
|
+
["n","n/","n/d"].each do |expr|
|
30
|
+
it "should parse durations of the form #{expr}" do
|
31
|
+
@invalid[:numbers].each do |n|
|
32
|
+
@valid[:numbers].each do |d|
|
33
|
+
str = expr.gsub('n',"#{n}")
|
34
|
+
str = str.gsub('d',"#{d}")
|
35
|
+
DUR_PARSER.parse(str).should be nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'valid numerator and invalid (zero) denominator' do
|
43
|
+
["n/d","/d"].each do |expr|
|
44
|
+
it "should parse durations of the form #{expr}" do
|
45
|
+
@valid[:numbers].each do |n|
|
46
|
+
@invalid[:numbers].each do |d|
|
47
|
+
str = expr.gsub('n',"#{n}")
|
48
|
+
str = str.gsub('d',"#{d}")
|
49
|
+
DUR_PARSER.parse(str).should be nil
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'invalid numerator and invalid denominator' do
|
57
|
+
["n","n/","n/d","/d"].each do |expr|
|
58
|
+
it "should parse durations of the form #{expr}" do
|
59
|
+
@invalid[:numbers].each do |n|
|
60
|
+
@invalid[:numbers].each do |d|
|
61
|
+
str = expr.gsub('n',"#{n}")
|
62
|
+
str = str.gsub('d',"#{d}")
|
63
|
+
DUR_PARSER.parse(str).should be nil
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe LinkNode do
|
4
|
+
parser = LinkParser.new
|
5
|
+
|
6
|
+
{
|
7
|
+
'=C4' => Link::Slur.new(C4),
|
8
|
+
'/Db2' => Link::Portamento.new(Db2),
|
9
|
+
'~C#2' => Link::Glissando.new(Db2),
|
10
|
+
'-Db2' => Link::Legato.new(Db2),
|
11
|
+
}.each do |str,tgt|
|
12
|
+
res = parser.parse(str)
|
13
|
+
context str do
|
14
|
+
it 'should parse as LinkNode' do
|
15
|
+
res.should be_a LinkNode
|
16
|
+
end
|
17
|
+
|
18
|
+
describe '#to_pitch' do
|
19
|
+
l = res.to_link
|
20
|
+
it 'should produce a Link object' do
|
21
|
+
l.should be_a Link
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should produce pitch matching input str' do
|
25
|
+
l.should eq tgt
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
describe LinkParser do
|
4
|
+
before :all do
|
5
|
+
@parser = LinkParser.new
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'should parse a "=C2"' do
|
9
|
+
@parser.parse("=C2").should_not be nil
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should parse a "-C2"' do
|
13
|
+
@parser.parse("-C2").should_not be nil
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should parse a "~C2"' do
|
17
|
+
@parser.parse("~C2").should_not be nil
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should parse a "/C2"' do
|
21
|
+
@parser.parse("/C2").should_not be nil
|
22
|
+
end
|
23
|
+
end
|