brevity 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +7 -0
  2. data/.document +3 -0
  3. data/.gitignore +7 -0
  4. data/.rspec +1 -0
  5. data/.ruby-version +1 -0
  6. data/.yardopts +1 -0
  7. data/ChangeLog.rdoc +4 -0
  8. data/Gemfile +3 -0
  9. data/LICENSE.txt +20 -0
  10. data/README.rdoc +27 -0
  11. data/Rakefile +67 -0
  12. data/bin/debrief +56 -0
  13. data/brevity.gemspec +28 -0
  14. data/examples/alley_cat.br +50 -0
  15. data/examples/hip.br +15 -0
  16. data/examples/missed_connection.br +6 -0
  17. data/examples/song1.br +11 -0
  18. data/examples/song2.br +10 -0
  19. data/examples/twinkle.br +18 -0
  20. data/lib/brevity/commands/constants.rb +18 -0
  21. data/lib/brevity/commands/expr.rb +17 -0
  22. data/lib/brevity/commands/meter.rb +20 -0
  23. data/lib/brevity/commands/part.rb +47 -0
  24. data/lib/brevity/commands/tempo.rb +13 -0
  25. data/lib/brevity/itemization.rb +73 -0
  26. data/lib/brevity/parsing/expression/dynamic.rb +280 -0
  27. data/lib/brevity/parsing/expression/dynamic.treetop +41 -0
  28. data/lib/brevity/parsing/expression/dynamic_nodes.rb +55 -0
  29. data/lib/brevity/parsing/expression/expression.rb +429 -0
  30. data/lib/brevity/parsing/expression/expression.treetop +39 -0
  31. data/lib/brevity/parsing/expression/expression_nodes.rb +26 -0
  32. data/lib/brevity/parsing/expression/gradual.rb +44 -0
  33. data/lib/brevity/parsing/expression/gradual.treetop +9 -0
  34. data/lib/brevity/parsing/expression/gradual_node.rb +11 -0
  35. data/lib/brevity/parsing/expression/label.rb +75 -0
  36. data/lib/brevity/parsing/expression/label.treetop +9 -0
  37. data/lib/brevity/parsing/expression/label_node.rb +15 -0
  38. data/lib/brevity/parsing/expression/sequence.rb +130 -0
  39. data/lib/brevity/parsing/expression/sequence.treetop +12 -0
  40. data/lib/brevity/parsing/expression/sequence_node.rb +14 -0
  41. data/lib/brevity/parsing/file/command.rb +216 -0
  42. data/lib/brevity/parsing/file/command.treetop +17 -0
  43. data/lib/brevity/parsing/file/command_node.rb +11 -0
  44. data/lib/brevity/parsing/file/comment.rb +178 -0
  45. data/lib/brevity/parsing/file/comment.treetop +21 -0
  46. data/lib/brevity/parsing/file/comment_node.rb +3 -0
  47. data/lib/brevity/parsing/file/file.rb +152 -0
  48. data/lib/brevity/parsing/file/file.treetop +16 -0
  49. data/lib/brevity/parsing/file/file_node.rb +7 -0
  50. data/lib/brevity/parsing/file/path.rb +235 -0
  51. data/lib/brevity/parsing/file/path.treetop +12 -0
  52. data/lib/brevity/parsing/modifiers/duplicate_modifier.rb +65 -0
  53. data/lib/brevity/parsing/modifiers/duplicate_modifier.treetop +11 -0
  54. data/lib/brevity/parsing/modifiers/duplicate_modifier_node.rb +8 -0
  55. data/lib/brevity/parsing/modifiers/modifier.rb +64 -0
  56. data/lib/brevity/parsing/modifiers/modifier.treetop +13 -0
  57. data/lib/brevity/parsing/modifiers/stretch_modifier.rb +69 -0
  58. data/lib/brevity/parsing/modifiers/stretch_modifier.treetop +11 -0
  59. data/lib/brevity/parsing/modifiers/stretch_modifier_node.rb +21 -0
  60. data/lib/brevity/parsing/modifiers/transpose_modifier.rb +69 -0
  61. data/lib/brevity/parsing/modifiers/transpose_modifier.treetop +11 -0
  62. data/lib/brevity/parsing/modifiers/transpose_modifier_node.rb +13 -0
  63. data/lib/brevity/parsing/note/accent.rb +44 -0
  64. data/lib/brevity/parsing/note/accent.treetop +9 -0
  65. data/lib/brevity/parsing/note/duration.rb +203 -0
  66. data/lib/brevity/parsing/note/duration.treetop +23 -0
  67. data/lib/brevity/parsing/note/duration_nodes.rb +19 -0
  68. data/lib/brevity/parsing/note/link.rb +69 -0
  69. data/lib/brevity/parsing/note/link.treetop +11 -0
  70. data/lib/brevity/parsing/note/link_node.rb +19 -0
  71. data/lib/brevity/parsing/note/note.rb +300 -0
  72. data/lib/brevity/parsing/note/note.treetop +30 -0
  73. data/lib/brevity/parsing/note/note_nodes.rb +77 -0
  74. data/lib/brevity/parsing/note/pitch.rb +81 -0
  75. data/lib/brevity/parsing/note/pitch.treetop +9 -0
  76. data/lib/brevity/parsing/note/pitch_node.rb +50 -0
  77. data/lib/brevity/parsing/numbers/nonnegative_integer.rb +53 -0
  78. data/lib/brevity/parsing/numbers/nonnegative_integer.treetop +9 -0
  79. data/lib/brevity/parsing/numbers/positive_integer.rb +91 -0
  80. data/lib/brevity/parsing/numbers/positive_integer.treetop +15 -0
  81. data/lib/brevity/read_file.rb +18 -0
  82. data/lib/brevity/score_maker.rb +64 -0
  83. data/lib/brevity/version.rb +4 -0
  84. data/lib/brevity.rb +53 -0
  85. data/manuals/brevity.pdf +0 -0
  86. data/manuals/brevity.tex +273 -0
  87. data/spec/brevity_spec.rb +8 -0
  88. data/spec/commands/expr_spec.rb +15 -0
  89. data/spec/commands/meter_spec.rb +21 -0
  90. data/spec/commands/part_spec.rb +16 -0
  91. data/spec/commands/tempo_spec.rb +20 -0
  92. data/spec/itemization_spec.rb +46 -0
  93. data/spec/parsing/expression/dynamic_nodes_spec.rb +32 -0
  94. data/spec/parsing/expression/dynamic_spec.rb +23 -0
  95. data/spec/parsing/expression/expression_nodes_spec.rb +87 -0
  96. data/spec/parsing/expression/expression_spec.rb +85 -0
  97. data/spec/parsing/expression/gradual_spec.rb +10 -0
  98. data/spec/parsing/expression/label_node_spec.rb +13 -0
  99. data/spec/parsing/expression/label_spec.rb +35 -0
  100. data/spec/parsing/file/command_node_spec.rb +29 -0
  101. data/spec/parsing/file/command_spec.rb +18 -0
  102. data/spec/parsing/file/comment_spec.rb +14 -0
  103. data/spec/parsing/file/file_node_spec.rb +19 -0
  104. data/spec/parsing/file/file_spec.rb +30 -0
  105. data/spec/parsing/modifiers/modifier_nodes_spec.rb +25 -0
  106. data/spec/parsing/modifiers/modifier_parsers_spec.rb +20 -0
  107. data/spec/parsing/note/accent_spec.rb +27 -0
  108. data/spec/parsing/note/duration_nodes_spec.rb +79 -0
  109. data/spec/parsing/note/duration_spec.rb +69 -0
  110. data/spec/parsing/note/link_node_spec.rb +30 -0
  111. data/spec/parsing/note/link_spec.rb +23 -0
  112. data/spec/parsing/note/note_nodes_spec.rb +82 -0
  113. data/spec/parsing/note/note_spec.rb +188 -0
  114. data/spec/parsing/note/pitch_node_spec.rb +48 -0
  115. data/spec/parsing/note/pitch_spec.rb +23 -0
  116. data/spec/parsing/numbers/nonnegative_integer_spec.rb +11 -0
  117. data/spec/parsing/numbers/positive_integer_spec.rb +17 -0
  118. data/spec/spec_helper.rb +112 -0
  119. 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