brevity 0.4.0

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.
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