jmtk 0.0.3.3-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. data/.yardopts +10 -0
  2. data/DEVELOPMENT_NOTES.md +115 -0
  3. data/INTRO.md +129 -0
  4. data/LICENSE.txt +27 -0
  5. data/README.md +50 -0
  6. data/Rakefile +102 -0
  7. data/bin/jmtk +250 -0
  8. data/bin/mtk +250 -0
  9. data/examples/crescendo.rb +20 -0
  10. data/examples/drum_pattern.rb +23 -0
  11. data/examples/dynamic_pattern.rb +36 -0
  12. data/examples/gets_and_play.rb +27 -0
  13. data/examples/notation.rb +22 -0
  14. data/examples/play_midi.rb +17 -0
  15. data/examples/print_midi.rb +13 -0
  16. data/examples/random_tone_row.rb +18 -0
  17. data/examples/syntax_to_midi.rb +28 -0
  18. data/examples/test_output.rb +7 -0
  19. data/examples/tone_row_melody.rb +23 -0
  20. data/lib/mtk.rb +76 -0
  21. data/lib/mtk/core/duration.rb +213 -0
  22. data/lib/mtk/core/intensity.rb +158 -0
  23. data/lib/mtk/core/interval.rb +157 -0
  24. data/lib/mtk/core/pitch.rb +154 -0
  25. data/lib/mtk/core/pitch_class.rb +194 -0
  26. data/lib/mtk/events/event.rb +119 -0
  27. data/lib/mtk/events/note.rb +112 -0
  28. data/lib/mtk/events/parameter.rb +54 -0
  29. data/lib/mtk/events/timeline.rb +232 -0
  30. data/lib/mtk/groups/chord.rb +56 -0
  31. data/lib/mtk/groups/collection.rb +196 -0
  32. data/lib/mtk/groups/melody.rb +96 -0
  33. data/lib/mtk/groups/pitch_class_set.rb +163 -0
  34. data/lib/mtk/groups/pitch_collection.rb +23 -0
  35. data/lib/mtk/io/dls_synth_device.rb +146 -0
  36. data/lib/mtk/io/dls_synth_output.rb +62 -0
  37. data/lib/mtk/io/jsound_input.rb +87 -0
  38. data/lib/mtk/io/jsound_output.rb +82 -0
  39. data/lib/mtk/io/midi_file.rb +209 -0
  40. data/lib/mtk/io/midi_input.rb +97 -0
  41. data/lib/mtk/io/midi_output.rb +195 -0
  42. data/lib/mtk/io/notation.rb +162 -0
  43. data/lib/mtk/io/unimidi_input.rb +117 -0
  44. data/lib/mtk/io/unimidi_output.rb +140 -0
  45. data/lib/mtk/lang/durations.rb +57 -0
  46. data/lib/mtk/lang/intensities.rb +61 -0
  47. data/lib/mtk/lang/intervals.rb +73 -0
  48. data/lib/mtk/lang/mtk_grammar.citrus +237 -0
  49. data/lib/mtk/lang/parser.rb +29 -0
  50. data/lib/mtk/lang/pitch_classes.rb +29 -0
  51. data/lib/mtk/lang/pitches.rb +52 -0
  52. data/lib/mtk/lang/pseudo_constants.rb +26 -0
  53. data/lib/mtk/lang/variable.rb +32 -0
  54. data/lib/mtk/numeric_extensions.rb +66 -0
  55. data/lib/mtk/patterns/chain.rb +49 -0
  56. data/lib/mtk/patterns/choice.rb +43 -0
  57. data/lib/mtk/patterns/cycle.rb +18 -0
  58. data/lib/mtk/patterns/for_each.rb +71 -0
  59. data/lib/mtk/patterns/function.rb +39 -0
  60. data/lib/mtk/patterns/lines.rb +54 -0
  61. data/lib/mtk/patterns/palindrome.rb +45 -0
  62. data/lib/mtk/patterns/pattern.rb +171 -0
  63. data/lib/mtk/patterns/sequence.rb +20 -0
  64. data/lib/mtk/sequencers/event_builder.rb +132 -0
  65. data/lib/mtk/sequencers/legato_sequencer.rb +24 -0
  66. data/lib/mtk/sequencers/rhythmic_sequencer.rb +28 -0
  67. data/lib/mtk/sequencers/sequencer.rb +111 -0
  68. data/lib/mtk/sequencers/step_sequencer.rb +26 -0
  69. data/spec/mtk/core/duration_spec.rb +372 -0
  70. data/spec/mtk/core/intensity_spec.rb +289 -0
  71. data/spec/mtk/core/interval_spec.rb +265 -0
  72. data/spec/mtk/core/pitch_class_spec.rb +343 -0
  73. data/spec/mtk/core/pitch_spec.rb +297 -0
  74. data/spec/mtk/events/event_spec.rb +234 -0
  75. data/spec/mtk/events/note_spec.rb +174 -0
  76. data/spec/mtk/events/parameter_spec.rb +220 -0
  77. data/spec/mtk/events/timeline_spec.rb +430 -0
  78. data/spec/mtk/groups/chord_spec.rb +85 -0
  79. data/spec/mtk/groups/collection_spec.rb +374 -0
  80. data/spec/mtk/groups/melody_spec.rb +225 -0
  81. data/spec/mtk/groups/pitch_class_set_spec.rb +340 -0
  82. data/spec/mtk/io/midi_file_spec.rb +243 -0
  83. data/spec/mtk/io/midi_output_spec.rb +102 -0
  84. data/spec/mtk/lang/durations_spec.rb +89 -0
  85. data/spec/mtk/lang/intensities_spec.rb +101 -0
  86. data/spec/mtk/lang/intervals_spec.rb +143 -0
  87. data/spec/mtk/lang/parser_spec.rb +603 -0
  88. data/spec/mtk/lang/pitch_classes_spec.rb +62 -0
  89. data/spec/mtk/lang/pitches_spec.rb +56 -0
  90. data/spec/mtk/lang/pseudo_constants_spec.rb +20 -0
  91. data/spec/mtk/lang/variable_spec.rb +52 -0
  92. data/spec/mtk/numeric_extensions_spec.rb +83 -0
  93. data/spec/mtk/patterns/chain_spec.rb +110 -0
  94. data/spec/mtk/patterns/choice_spec.rb +97 -0
  95. data/spec/mtk/patterns/cycle_spec.rb +123 -0
  96. data/spec/mtk/patterns/for_each_spec.rb +136 -0
  97. data/spec/mtk/patterns/function_spec.rb +120 -0
  98. data/spec/mtk/patterns/lines_spec.rb +77 -0
  99. data/spec/mtk/patterns/palindrome_spec.rb +108 -0
  100. data/spec/mtk/patterns/pattern_spec.rb +132 -0
  101. data/spec/mtk/patterns/sequence_spec.rb +203 -0
  102. data/spec/mtk/sequencers/event_builder_spec.rb +245 -0
  103. data/spec/mtk/sequencers/legato_sequencer_spec.rb +45 -0
  104. data/spec/mtk/sequencers/rhythmic_sequencer_spec.rb +84 -0
  105. data/spec/mtk/sequencers/sequencer_spec.rb +215 -0
  106. data/spec/mtk/sequencers/step_sequencer_spec.rb +93 -0
  107. data/spec/spec_coverage.rb +2 -0
  108. data/spec/spec_helper.rb +12 -0
  109. data/spec/test.mid +0 -0
  110. metadata +226 -0
@@ -0,0 +1,289 @@
1
+ require 'spec_helper'
2
+
3
+ describe MTK::Core::Intensity do
4
+
5
+ let(:half_intensity) { Intensity[0.5] }
6
+
7
+
8
+ describe 'NAMES' do
9
+ it "is the list of base intensity names available" do
10
+ Intensity::NAMES.should =~ %w( ppp pp p mp mf o ff fff )
11
+ end
12
+
13
+ it "is immutable" do
14
+ lambda{ Intensity::NAMES << 'z' }.should raise_error
15
+ end
16
+ end
17
+
18
+
19
+ describe 'VALUES_BY_NAME' do
20
+ it 'maps names to values' do
21
+ Intensity::VALUES_BY_NAME.each do |name,value|
22
+ Intensity.from_s(name).value.should == value
23
+ end
24
+ end
25
+
26
+ it 'is immutable' do
27
+ lambda{ Intensity::VALUES_BY_NAME << 'z' }.should raise_error
28
+ end
29
+ end
30
+
31
+
32
+ describe '.new' do
33
+ it "constructs a Intensity with whatever value is given" do
34
+ float = 0.5
35
+ value = Intensity.new(float).value
36
+ value.should be_equal float
37
+ end
38
+ end
39
+
40
+
41
+ describe '.[]' do
42
+ it "constructs and caches a intensity from a Numeric" do
43
+ Intensity[1].should be_equal Intensity[1]
44
+ end
45
+
46
+ it "retains the new() method's ability to construct uncached objects" do
47
+ Intensity.new(1).should_not be_equal Intensity[1]
48
+ end
49
+
50
+ it "converts the value to floating point" do
51
+ value = Intensity[Rational(1,2)].value
52
+ value.should be_a Float
53
+ value.should == 0.5
54
+ end
55
+
56
+ end
57
+
58
+
59
+ describe '.from_i' do
60
+ it "acts like .[]" do
61
+ Intensity.from_i(0).value.should == 0.0
62
+ Intensity.from_i(4).value.should == 4.0
63
+ end
64
+ end
65
+
66
+ describe '.from_f' do
67
+ it "acts like .[]" do
68
+ value = Intensity.from_f(Rational(1,2)).value
69
+ value.should be_a Float
70
+ value.should == 0.5
71
+ end
72
+ end
73
+
74
+ describe '.from_s' do
75
+ it "converts any of the intensity NAMES into a Intensity with the value from the VALUES_BY_NAME mapping" do
76
+ for name in Intensity::NAMES
77
+ Intensity.from_s(name).value.should == Intensity::VALUES_BY_NAME[name]
78
+ end
79
+ end
80
+
81
+ it "adds 1.0/24 when the name ends with '+', except for 'fff+' which is 1.0 like 'fff'" do
82
+ for name in Intensity::NAMES
83
+ if name == 'fff'
84
+ Intensity.from_s("#{name}+").should == Intensity[1.0]
85
+ else
86
+ Intensity.from_s("#{name}+").should == Intensity[ Intensity::VALUES_BY_NAME[name] +1.0/24 ]
87
+ end
88
+ end
89
+ end
90
+
91
+ it "subtracts 1.0/24 when the name ends with '-'" do
92
+ for name in Intensity::NAMES
93
+ Intensity.from_s("#{name}-").should == Intensity[ Intensity::VALUES_BY_NAME[name] - 1.0/24 ]
94
+ end
95
+ end
96
+ end
97
+
98
+ describe '.from_name' do
99
+ it "acts like .from_s" do
100
+ for name in Intensity::NAMES
101
+ Intensity.from_name(name).value.should == Intensity::VALUES_BY_NAME[name]
102
+ end
103
+ end
104
+ end
105
+
106
+
107
+ describe '#value' do
108
+ it "is the value used to construct the Intensity" do
109
+ Intensity.new(1.111).value.should == 1.111
110
+ end
111
+ end
112
+
113
+
114
+ describe '#to_f' do
115
+ it "is the value as a floating point number" do
116
+ f = Intensity.new(Rational(1,2)).to_f
117
+ f.should be_a Float
118
+ f.should == 0.5
119
+ end
120
+ end
121
+
122
+ describe '#to_i' do
123
+ it "is the value rounded to the nearest integer" do
124
+ i = Intensity.new(0.5).to_i
125
+ i.should be_a Fixnum
126
+ i.should == 1
127
+ Intensity.new(0.49).to_i.should == 0
128
+ end
129
+ end
130
+
131
+ describe '#to_percentage' do
132
+ it 'is the value*100 rounded to the nearest integer' do
133
+ Intensity.new(0).to_percent.should == 0
134
+ Intensity.new(0.5).to_percent.should == 50
135
+ Intensity.new(1).to_percent.should == 100
136
+ Intensity.new(2).to_percent.should == 200
137
+ end
138
+ end
139
+
140
+ describe '#to_s' do
141
+ it "is to_percentage suffixed with '% intensity'" do
142
+ Intensity.new(0).to_s.should == '0% intensity'
143
+ Intensity.new(0.5).to_s.should == '50% intensity'
144
+ Intensity.new(1).to_s.should == '100% intensity'
145
+ Intensity.new(2).to_s.should == '200% intensity'
146
+ end
147
+ end
148
+
149
+ describe '#inspect' do
150
+ it 'is "#<MTK::Core::Intensity:{object_id} @value={value}>"' do
151
+ for value in [0, 60, 60.5, 127]
152
+ intensity = Intensity.new(value)
153
+ intensity.inspect.should == "#<MTK::Core::Intensity:#{intensity.object_id} @value=#{value}>"
154
+ end
155
+ end
156
+ end
157
+
158
+ describe '#==' do
159
+ it "compares two intensity values for equality" do
160
+ Intensity.new(Rational(1,2)).should == Intensity.new(0.5)
161
+ Intensity.new(4).should == Intensity.new(4)
162
+ Intensity.new(1.1).should_not == Intensity.new(1)
163
+ end
164
+ end
165
+
166
+ describe "#<=>" do
167
+ it "orders intensitys based on their underlying value" do
168
+ ( Intensity.new(1) <=> Intensity.new(1.1) ).should < 0
169
+ ( Intensity.new(2) <=> Intensity.new(1) ).should > 0
170
+ ( Intensity.new(1.0) <=> Intensity.new(1) ).should == 0
171
+ end
172
+ end
173
+
174
+
175
+
176
+ describe '#+' do
177
+ it 'adds #value to the Numeric argument' do
178
+ (half_intensity + 0.25).should == Intensity[0.75]
179
+ end
180
+
181
+ it 'works with an Intensity argument' do
182
+ (half_intensity + Intensity[0.25]).should == Intensity[0.75]
183
+ end
184
+
185
+ it 'returns a new intensity (Intensity is immutable)' do
186
+ original = half_intensity
187
+ modified = half_intensity + 0.25
188
+ original.should_not == modified
189
+ original.should == Intensity[0.5]
190
+ end
191
+ end
192
+
193
+ describe '#-' do
194
+ it 'subtract the Numeric argument from #value' do
195
+ (half_intensity - 0.25).should == Intensity[0.25]
196
+ end
197
+
198
+ it 'works with a Intensity argument' do
199
+ (half_intensity - Intensity[0.25]).should == Intensity[0.25]
200
+ end
201
+
202
+ it 'returns a new intensity (Intensity is immutable)' do
203
+ original = half_intensity
204
+ modified = half_intensity - 0.25
205
+ original.should_not == modified
206
+ original.should == Intensity[0.5]
207
+ end
208
+ end
209
+
210
+
211
+ describe '#*' do
212
+ it 'multiplies #value to the Numeric argument' do
213
+ (half_intensity * 0.1).should == Intensity[0.05]
214
+ end
215
+
216
+ it 'works with a Intensity argument' do
217
+ (half_intensity * Intensity[0.1]).should == Intensity[0.05]
218
+ end
219
+
220
+ it 'returns a new intensity (Intensity is immutable)' do
221
+ original = half_intensity
222
+ modified = half_intensity * 2
223
+ original.should_not == modified
224
+ original.should == Intensity[0.5]
225
+ end
226
+ end
227
+
228
+ describe '#/' do
229
+ it 'divides #value by the Numeric argument' do
230
+ (half_intensity / 2).should == Intensity[0.25]
231
+ end
232
+
233
+ it 'works with a Intensity argument' do
234
+ (half_intensity / Intensity[0.5]).should == Intensity[1]
235
+ end
236
+
237
+ it 'returns a new intensity (Intensity is immutable)' do
238
+ original = half_intensity
239
+ modified = half_intensity / 2
240
+ original.should_not == modified
241
+ original.should == Intensity[0.5]
242
+ end
243
+ end
244
+
245
+ describe '#coerce' do
246
+ it 'allows a Intensity to be added to a Numeric' do
247
+ (0.25 + half_intensity).should == Intensity[0.75]
248
+ end
249
+
250
+ it 'allows a Intensity to be subtracted from a Numeric' do
251
+ (0.9 - half_intensity).should == Intensity[0.4]
252
+ end
253
+
254
+ it 'allows a Intensity to be multiplied to a Numeric' do
255
+ (0.5 * half_intensity).should == Intensity[0.25]
256
+ end
257
+
258
+ it 'allows a Numeric to be divided by a Intensity' do
259
+ (0.1 / half_intensity).should == Intensity[0.2]
260
+ end
261
+ end
262
+
263
+ end
264
+
265
+ describe MTK do
266
+
267
+ describe '#Intensity' do
268
+ it "acts like .from_s if the argument is a String" do
269
+ Intensity('ppp').should == Intensity.from_s('ppp')
270
+ end
271
+
272
+ it "acts like .from_s if the argument is a Symbol" do
273
+ Intensity(:ppp).should == Intensity.from_s('ppp')
274
+ end
275
+
276
+ it "acts like .[] if the argument is a Numeric" do
277
+ Intensity(0.5).should be_equal Intensity[0.5]
278
+ end
279
+
280
+ it "returns the argument if it's already a Intensity" do
281
+ Intensity(Intensity[1]).should be_equal Intensity[1]
282
+ end
283
+
284
+ it "raises an error for types it doesn't understand" do
285
+ lambda{ Intensity({:not => :compatible}) }.should raise_error
286
+ end
287
+ end
288
+
289
+ end
@@ -0,0 +1,265 @@
1
+ require 'spec_helper'
2
+
3
+ describe MTK::Core::Interval do
4
+
5
+ let(:minor_second) { Interval[1] }
6
+
7
+
8
+ describe 'NAMES' do
9
+ it "is the list of base interval names available" do
10
+ Interval::NAMES.should =~ %w( P1 m2 M2 m3 M3 P4 TT P5 m6 M6 m7 M7 P8 )
11
+ end
12
+
13
+ it "is immutable" do
14
+ lambda{ Interval::NAMES << 'z' }.should raise_error
15
+ end
16
+ end
17
+
18
+
19
+ describe 'VALUES_BY_NAME' do
20
+ it 'maps names to values' do
21
+ Interval::VALUES_BY_NAME.each do |name,value|
22
+ Interval.from_s(name).value.should == value
23
+ end
24
+ end
25
+
26
+ it 'is immutable' do
27
+ lambda{ Interval::VALUES_BY_NAME << 'z' }.should raise_error
28
+ end
29
+ end
30
+
31
+
32
+ describe 'ALL_NAMES' do
33
+ it 'contains all NAMES' do
34
+ Interval::NAMES.each{|name| Interval::ALL_NAMES.should include name }
35
+ end
36
+ end
37
+
38
+
39
+ describe '.new' do
40
+ it "constructs a Interval with whatever value is given" do
41
+ float = 0.5
42
+ value = Interval.new(float).value
43
+ value.should be_equal float
44
+ end
45
+ end
46
+
47
+
48
+ describe '.[]' do
49
+ it "constructs and caches a interval from a Numeric" do
50
+ Interval[1].should be_equal Interval[1]
51
+ end
52
+
53
+ it "retains the new() method's ability to construct uncached objects" do
54
+ Interval.new(1).should_not be_equal Interval[1]
55
+ end
56
+
57
+ it "converts the value to floating point" do
58
+ value = Interval[Rational(1,2)].value
59
+ value.should be_a Float
60
+ value.should == 0.5
61
+ end
62
+
63
+ end
64
+
65
+
66
+ describe '.from_i' do
67
+ it "acts like .[]" do
68
+ Interval.from_i(0).value.should == 0.0
69
+ Interval.from_i(4).value.should == 4.0
70
+ end
71
+ end
72
+
73
+ describe '.from_f' do
74
+ it "acts like .[]" do
75
+ value = Interval.from_f(Rational(1,2)).value
76
+ value.should be_a Float
77
+ value.should == 0.5
78
+ end
79
+ end
80
+
81
+ describe '.from_s' do
82
+ it "converts any of the interval NAMES into a Interval with the value from the VALUES_BY_NAME mapping" do
83
+ for name in Interval::ALL_NAMES
84
+ Interval.from_s(name).value.should == Interval::VALUES_BY_NAME[name]
85
+ end
86
+ end
87
+ end
88
+
89
+ describe '.from_name' do
90
+ it "acts like .from_s" do
91
+ for name in Interval::NAMES
92
+ Interval.from_name(name).value.should == Interval::VALUES_BY_NAME[name]
93
+ end
94
+ end
95
+ end
96
+
97
+
98
+ describe '#value' do
99
+ it "is the value used to construct the Interval" do
100
+ Interval.new(1.111).value.should == 1.111
101
+ end
102
+ end
103
+
104
+
105
+ describe '#to_f' do
106
+ it "is the value as a floating point number" do
107
+ f = Interval.new(Rational(1,2)).to_f
108
+ f.should be_a Float
109
+ f.should == 0.5
110
+ end
111
+ end
112
+
113
+ describe '#to_i' do
114
+ it "is the value rounded to the nearest integer" do
115
+ i = Interval.new(0.5).to_i
116
+ i.should be_a Fixnum
117
+ i.should == 1
118
+ Interval.new(0.49).to_i.should == 0
119
+ end
120
+ end
121
+
122
+ describe '#to_s' do
123
+ it "should be value.to_s" do
124
+ for value in [1, Rational(1,2), 0.25]
125
+ Interval.new(value).to_s.should == value.to_s
126
+ end
127
+ end
128
+ end
129
+
130
+ describe '#==' do
131
+ it "compares two interval values for equality" do
132
+ Interval.new(Rational(1,2)).should == Interval.new(0.5)
133
+ Interval.new(4).should == Interval.new(4)
134
+ Interval.new(1.1).should_not == Interval.new(1)
135
+ end
136
+ end
137
+
138
+ describe "#<=>" do
139
+ it "orders intervals based on their underlying value" do
140
+ ( Interval.new(1) <=> Interval.new(1.1) ).should < 0
141
+ ( Interval.new(2) <=> Interval.new(1) ).should > 0
142
+ ( Interval.new(1.0) <=> Interval.new(1) ).should == 0
143
+ end
144
+ end
145
+
146
+
147
+
148
+ describe '#+' do
149
+ it 'adds #value to the Numeric argument' do
150
+ (minor_second + 0.25).should == Interval[1.25]
151
+ end
152
+
153
+ it 'works with an Interval argument' do
154
+ (minor_second + Interval[0.25]).should == Interval[1.25]
155
+ end
156
+
157
+ it 'returns a new interval (Interval is immutable)' do
158
+ original = minor_second
159
+ modified = minor_second + 0.25
160
+ original.should_not == modified
161
+ original.should == Interval[1]
162
+ end
163
+ end
164
+
165
+ describe '#-' do
166
+ it 'subtract the Numeric argument from #value' do
167
+ (minor_second - 0.25).should == Interval[0.75]
168
+ end
169
+
170
+ it 'works with a Interval argument' do
171
+ (minor_second - Interval[0.25]).should == Interval[0.75]
172
+ end
173
+
174
+ it 'returns a new interval (Interval is immutable)' do
175
+ original = minor_second
176
+ modified = minor_second - 0.25
177
+ original.should_not == modified
178
+ original.should == Interval[1]
179
+ end
180
+ end
181
+
182
+
183
+ describe '#*' do
184
+ it 'multiplies #value to the Numeric argument' do
185
+ (minor_second * 3).should == Interval[3]
186
+ end
187
+
188
+ it 'works with a Interval argument' do
189
+ (minor_second * Interval[3]).should == Interval[3]
190
+ end
191
+
192
+ it 'returns a new interval (Interval is immutable)' do
193
+ original = minor_second
194
+ modified = minor_second * 2
195
+ original.should_not == modified
196
+ original.should == Interval[1]
197
+ end
198
+ end
199
+
200
+ describe '#/' do
201
+ it 'divides #value by the Numeric argument' do
202
+ (minor_second / 2).should == Interval[0.5]
203
+ end
204
+
205
+ it 'works with a Interval argument' do
206
+ (minor_second / Interval[2]).should == Interval[0.5]
207
+ end
208
+
209
+ it 'returns a new interval (Interval is immutable)' do
210
+ original = minor_second
211
+ modified = minor_second / 2
212
+ original.should_not == modified
213
+ original.should == Interval[1]
214
+ end
215
+ end
216
+
217
+ describe '#coerce' do
218
+ it 'allows a Interval to be added to a Numeric' do
219
+ (0.25 + minor_second).should == Interval[1.25]
220
+ end
221
+
222
+ it 'allows a Interval to be subtracted from a Numeric' do
223
+ (3 - minor_second).should == Interval[2]
224
+ end
225
+
226
+ it 'allows a Interval to be multiplied to a Numeric' do
227
+ (3 * minor_second).should == Interval[3]
228
+ end
229
+
230
+ it 'allows a Numeric to be divided by a Interval' do
231
+ (4 / minor_second).should == Interval[4]
232
+ end
233
+ end
234
+
235
+ end
236
+
237
+ describe MTK do
238
+
239
+ describe '#Interval' do
240
+ it "acts like .from_s if the argument is a String" do
241
+ for name in Interval::ALL_NAMES
242
+ Interval(name).should == Interval.from_s(name)
243
+ end
244
+ end
245
+
246
+ it "acts like .from_s if the argument is a Symbol" do
247
+ for name in Interval::ALL_NAMES
248
+ Interval(name.to_sym).should == Interval.from_s(name)
249
+ end
250
+ end
251
+
252
+ it "acts like .[] if the argument is a Numeric" do
253
+ Interval(0.5).should be_equal Interval[0.5]
254
+ end
255
+
256
+ it "returns the argument if it's already a Interval" do
257
+ Interval(Interval[1]).should be_equal Interval[1]
258
+ end
259
+
260
+ it "raises an error for types it doesn't understand" do
261
+ lambda{ Interval({:not => :compatible}) }.should raise_error
262
+ end
263
+ end
264
+
265
+ end