musicality 0.11.1 → 0.12.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 (124) hide show
  1. checksums.yaml +5 -5
  2. data/.coveralls.yml +1 -0
  3. data/.ruby-version +1 -1
  4. data/.travis.yml +4 -0
  5. data/ChangeLog.md +11 -0
  6. data/README.md +3 -0
  7. data/Rakefile +11 -3
  8. data/lib/musicality/composition/model/rhythm.rb +33 -0
  9. data/lib/musicality/composition/model/rhythm_class.rb +30 -0
  10. data/lib/musicality/composition/sequencing/drum_machine/drum_kit.rb +18 -0
  11. data/lib/musicality/composition/sequencing/drum_machine/drum_machine.rb +59 -0
  12. data/lib/musicality/composition/sequencing/drum_machine/drum_parts.rb +21 -0
  13. data/lib/musicality/composition/sequencing/drum_machine/drum_pattern.rb +66 -0
  14. data/lib/musicality/composition/sequencing/drum_machine/drum_patterns/pop_drum_patterns.rb +146 -0
  15. data/lib/musicality/composition/sequencing/note_array.rb +33 -0
  16. data/lib/musicality/composition/sequencing/note_fifo.rb +73 -0
  17. data/lib/musicality/composition/sequencing/sequenceable.rb +9 -0
  18. data/lib/musicality/composition/sequencing/sequencer.rb +35 -0
  19. data/lib/musicality/errors.rb +2 -2
  20. data/lib/musicality/notation/model/dynamics.rb +2 -2
  21. data/lib/musicality/notation/model/key.rb +42 -91
  22. data/lib/musicality/notation/model/keys.rb +35 -34
  23. data/lib/musicality/notation/model/note.rb +31 -9
  24. data/lib/musicality/notation/model/pitch.rb +2 -2
  25. data/lib/musicality/notation/parsing/convenience_methods.rb +23 -12
  26. data/lib/musicality/notation/parsing/duration_parsing.rb +3 -3
  27. data/lib/musicality/notation/parsing/key_parsing.rb +150 -0
  28. data/lib/musicality/notation/parsing/key_parsing.treetop +37 -0
  29. data/lib/musicality/notation/parsing/meter_parsing.rb +3 -3
  30. data/lib/musicality/notation/parsing/numbers/nonnegative_float_parsing.rb +3 -1
  31. data/lib/musicality/notation/parsing/numbers/nonnegative_integer_parsing.rb +1 -0
  32. data/lib/musicality/notation/parsing/numbers/nonnegative_rational_parsing.rb +1 -1
  33. data/lib/musicality/notation/parsing/numbers/positive_float_parsing.rb +4 -1
  34. data/lib/musicality/notation/parsing/numbers/positive_rational_parsing.rb +1 -1
  35. data/lib/musicality/notation/parsing/parseable.rb +13 -17
  36. data/lib/musicality/notation/parsing/pitch_parsing.rb +7 -0
  37. data/lib/musicality/notation/parsing/segment_parsing.rb +3 -0
  38. data/lib/musicality/performance/conversion/note_sequence_extractor.rb +82 -134
  39. data/lib/musicality/performance/model/note_sequence.rb +22 -3
  40. data/lib/musicality/performance/supercollider/performer.rb +2 -2
  41. data/lib/musicality/performance/supercollider/sc_drum_kits.rb +29 -0
  42. data/lib/musicality/performance/supercollider/synthdefs/bass.rb +211 -0
  43. data/lib/musicality/performance/supercollider/synthdefs/claps.rb +80 -0
  44. data/lib/musicality/performance/supercollider/synthdefs/cymbals.rb +57 -0
  45. data/lib/musicality/performance/supercollider/synthdefs/hihats.rb +67 -0
  46. data/lib/musicality/performance/supercollider/synthdefs/kicks.rb +158 -0
  47. data/lib/musicality/performance/supercollider/synthdefs/mario.rb +49 -0
  48. data/lib/musicality/performance/supercollider/{synthdefs.rb → synthdefs/other.rb} +0 -767
  49. data/lib/musicality/performance/supercollider/synthdefs/pianos.rb +46 -0
  50. data/lib/musicality/performance/supercollider/synthdefs/snares.rb +169 -0
  51. data/lib/musicality/performance/supercollider/synthdefs/toms.rb +25 -0
  52. data/lib/musicality/performance/supercollider/synthdefs/volume.rb +20 -0
  53. data/lib/musicality/pitch_class.rb +1 -1
  54. data/lib/musicality/pitch_classes.rb +3 -5
  55. data/lib/musicality/version.rb +1 -1
  56. data/lib/musicality.rb +25 -1
  57. data/musicality.gemspec +3 -2
  58. data/spec/composition/convenience_methods_spec.rb +8 -8
  59. data/spec/composition/generation/random_rhythm_generator_spec.rb +5 -5
  60. data/spec/composition/model/pitch_class_spec.rb +22 -16
  61. data/spec/composition/model/pitch_classes_spec.rb +5 -5
  62. data/spec/composition/model/rhythm_class_spec.rb +42 -0
  63. data/spec/composition/model/rhythm_spec.rb +43 -0
  64. data/spec/composition/model/scale_class_spec.rb +26 -26
  65. data/spec/composition/model/scale_spec.rb +38 -38
  66. data/spec/composition/sequencing/drum_machine/drum_machine_spec.rb +67 -0
  67. data/spec/composition/sequencing/drum_machine/drum_pattern_spec.rb +58 -0
  68. data/spec/composition/sequencing/note_array_spec.rb +94 -0
  69. data/spec/composition/sequencing/note_fifo_spec.rb +183 -0
  70. data/spec/composition/sequencing/sequencer_spec.rb +76 -0
  71. data/spec/composition/util/adding_sequence_spec.rb +33 -33
  72. data/spec/composition/util/compound_sequence_spec.rb +6 -6
  73. data/spec/composition/util/note_generation_spec.rb +34 -34
  74. data/spec/composition/util/probabilities_spec.rb +7 -7
  75. data/spec/composition/util/random_sampler_spec.rb +3 -3
  76. data/spec/composition/util/repeating_sequence_spec.rb +28 -28
  77. data/spec/musicality_spec.rb +1 -1
  78. data/spec/notation/conversion/change_conversion_spec.rb +87 -87
  79. data/spec/notation/conversion/note_time_converter_spec.rb +22 -22
  80. data/spec/notation/conversion/score_conversion_spec.rb +1 -1
  81. data/spec/notation/conversion/score_converter_spec.rb +31 -31
  82. data/spec/notation/conversion/tempo_conversion_spec.rb +11 -11
  83. data/spec/notation/model/change_spec.rb +80 -80
  84. data/spec/notation/model/key_spec.rb +135 -69
  85. data/spec/notation/model/link_spec.rb +27 -27
  86. data/spec/notation/model/meter_spec.rb +28 -28
  87. data/spec/notation/model/note_spec.rb +68 -47
  88. data/spec/notation/model/part_spec.rb +19 -19
  89. data/spec/notation/model/pitch_spec.rb +69 -68
  90. data/spec/notation/model/score_spec.rb +50 -47
  91. data/spec/notation/parsing/articulation_parsing_spec.rb +4 -4
  92. data/spec/notation/parsing/convenience_methods_spec.rb +49 -10
  93. data/spec/notation/parsing/duration_nodes_spec.rb +13 -13
  94. data/spec/notation/parsing/duration_parsing_spec.rb +10 -10
  95. data/spec/notation/parsing/key_parsing_spec.rb +19 -0
  96. data/spec/notation/parsing/link_nodes_spec.rb +7 -7
  97. data/spec/notation/parsing/link_parsing_spec.rb +4 -4
  98. data/spec/notation/parsing/meter_parsing_spec.rb +5 -5
  99. data/spec/notation/parsing/note_node_spec.rb +19 -19
  100. data/spec/notation/parsing/note_parsing_spec.rb +4 -4
  101. data/spec/notation/parsing/numbers/nonnegative_float_spec.rb +8 -8
  102. data/spec/notation/parsing/numbers/nonnegative_integer_spec.rb +2 -2
  103. data/spec/notation/parsing/numbers/nonnegative_rational_spec.rb +1 -1
  104. data/spec/notation/parsing/numbers/positive_float_spec.rb +8 -8
  105. data/spec/notation/parsing/numbers/positive_integer_spec.rb +6 -6
  106. data/spec/notation/parsing/numbers/positive_rational_spec.rb +6 -6
  107. data/spec/notation/parsing/pitch_node_spec.rb +7 -7
  108. data/spec/notation/parsing/pitch_parsing_spec.rb +2 -2
  109. data/spec/notation/parsing/segment_parsing_spec.rb +3 -3
  110. data/spec/notation/util/function_spec.rb +15 -15
  111. data/spec/notation/util/transition_spec.rb +12 -12
  112. data/spec/notation/util/value_computer_spec.rb +35 -36
  113. data/spec/performance/conversion/glissando_converter_spec.rb +24 -24
  114. data/spec/performance/conversion/note_sequence_extractor_spec.rb +39 -39
  115. data/spec/performance/conversion/portamento_converter_spec.rb +23 -23
  116. data/spec/performance/midi/midi_util_spec.rb +41 -41
  117. data/spec/performance/midi/part_sequencer_spec.rb +10 -10
  118. data/spec/performance/midi/score_sequencer_spec.rb +15 -15
  119. data/spec/performance/midi/score_sequencing_spec.rb +2 -2
  120. data/spec/performance/util/optimization_spec.rb +9 -9
  121. data/spec/printing/note_engraving_spec.rb +16 -16
  122. data/spec/printing/score_engraver_spec.rb +5 -5
  123. data/spec/spec_helper.rb +5 -0
  124. metadata +85 -30
@@ -3,31 +3,31 @@ require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
3
3
  describe Change::Immediate do
4
4
  context '#initialize' do
5
5
  it 'should set end value to given' do
6
- Change::Immediate.new(5).end_value.should eq 5
6
+ expect(Change::Immediate.new(5).end_value).to eq 5
7
7
  end
8
8
  end
9
-
9
+
10
10
  describe '==' do
11
11
  it 'should return true if two immediate changes have the same end value' do
12
- Change::Immediate.new(5).should eq(Change::Immediate.new(5))
12
+ expect(Change::Immediate.new(5)).to eq(Change::Immediate.new(5))
13
13
  end
14
-
14
+
15
15
  it 'should return false if two immediate changes do not have the same end value' do
16
- Change::Immediate.new(5).should_not eq(Change::Immediate.new(4))
16
+ expect(Change::Immediate.new(5)).to_not eq(Change::Immediate.new(4))
17
17
  end
18
18
  end
19
-
19
+
20
20
  describe '#to_yaml' do
21
21
  it 'should produce YAML that can be loaded' do
22
22
  c = Change::Immediate.new(4)
23
- YAML.load(c.to_yaml).should eq c
23
+ expect(YAML.load(c.to_yaml)).to eq c
24
24
  end
25
25
  end
26
26
 
27
27
  describe '#pack' do
28
28
  it 'should produce a Hash' do
29
29
  h = Change::Immediate.new(2).pack
30
- h.should be_a Hash
30
+ expect(h).to be_a Hash
31
31
  end
32
32
  end
33
33
 
@@ -35,8 +35,8 @@ describe Change::Immediate do
35
35
  it 'should return a Change::Immediate equal to the original' do
36
36
  c1 = Change::Immediate.new(2)
37
37
  c2 = Change::Immediate.unpack(c1.pack)
38
- c2.should be_a Change::Immediate
39
- c2.should eq c1
38
+ expect(c2).to be_a Change::Immediate
39
+ expect(c2).to eq c1
40
40
  end
41
41
  end
42
42
  end
@@ -45,104 +45,104 @@ describe Change::Gradual do
45
45
  context '#initialize' do
46
46
  it 'should set end value and duration to given values' do
47
47
  ch = Change::Gradual.new(5,2,Change::Gradual::LINEAR)
48
- ch.end_value.should eq(5)
49
- ch.duration.should eq(2)
48
+ expect(ch.end_value).to eq(5)
49
+ expect(ch.duration).to eq(2)
50
50
  end
51
-
51
+
52
52
  it 'should set start_value to nil if not given' do
53
- Change::Gradual.linear(5,2).start_value.should be nil
53
+ expect(Change::Gradual.linear(5,2).start_value).to be nil
54
54
  end
55
-
55
+
56
56
  it 'should set start_value if given' do
57
- Change::Gradual.linear(5,2, start_value: 3).start_value.should eq(3)
57
+ expect(Change::Gradual.linear(5,2, start_value: 3).start_value).to eq(3)
58
58
  end
59
-
59
+
60
60
  it 'should raise NonPositiveError if duration is <= 0' do
61
61
  expect { Change::Gradual.new(11,0,Change::Gradual::LINEAR) }.to raise_error(NonPositiveError)
62
62
  expect { Change::Gradual.new(11,-1,Change::Gradual::LINEAR) }.to raise_error(NonPositiveError)
63
63
  end
64
64
  end
65
-
65
+
66
66
  describe '#relative?' do
67
67
  context 'start_value is nil' do
68
68
  it 'should return true' do
69
- Change::Gradual.linear(25,3).relative?.should be true
69
+ expect(Change::Gradual.linear(25,3).relative?).to be true
70
70
  end
71
71
  end
72
-
72
+
73
73
  context 'start_value is not nil' do
74
74
  it 'should return false' do
75
- Change::Gradual.linear(25,3, start_value: 10).relative?.should be false
75
+ expect(Change::Gradual.linear(25,3, start_value: 10).relative?).to be false
76
76
  end
77
77
  end
78
78
  end
79
-
79
+
80
80
  context '.linear' do
81
81
  before(:all){ @change = Change::Gradual.linear(55,20, start_value: 25) }
82
-
82
+
83
83
  it 'should assign end_value, duration, and start_value as normal' do
84
- @change.end_value.should eq(55)
85
- @change.duration.should eq(20)
86
- @change.start_value.should eq(25)
84
+ expect(@change.end_value).to eq(55)
85
+ expect(@change.duration).to eq(20)
86
+ expect(@change.start_value).to eq(25)
87
87
  end
88
-
88
+
89
89
  it 'should set transition to linear' do
90
- @change.transition.should eq(Change::Gradual::LINEAR)
90
+ expect(@change.transition).to eq(Change::Gradual::LINEAR)
91
91
  end
92
92
  end
93
93
 
94
94
  context '.sigmoid' do
95
95
  before(:all){ @change = Change::Gradual.sigmoid(55,20, start_value: 25) }
96
-
96
+
97
97
  it 'should assign end_value, duration, and start_value as normal' do
98
- @change.end_value.should eq(55)
99
- @change.duration.should eq(20)
100
- @change.start_value.should eq(25)
98
+ expect(@change.end_value).to eq(55)
99
+ expect(@change.duration).to eq(20)
100
+ expect(@change.start_value).to eq(25)
101
101
  end
102
-
102
+
103
103
  it 'should set transition to SIGMOID' do
104
- @change.transition.should eq(Change::Gradual::SIGMOID)
104
+ expect(@change.transition).to eq(Change::Gradual::SIGMOID)
105
105
  end
106
106
  end
107
-
107
+
108
108
  describe '==' do
109
109
  context 'two gradual changes have the same end value, duration, and start value' do
110
110
  it 'should return true' do
111
- Change::Gradual.linear(5,2).should eq(Change::Gradual.linear(5,2))
112
- Change::Gradual.linear(5,2,start_value:0).should eq(Change::Gradual.linear(5,2,start_value:0))
111
+ expect(Change::Gradual.linear(5,2)).to eq(Change::Gradual.linear(5,2))
112
+ expect(Change::Gradual.linear(5,2,start_value:0)).to eq(Change::Gradual.linear(5,2,start_value:0))
113
113
  end
114
114
  end
115
-
115
+
116
116
  context 'two gradual changes do not have the same end value' do
117
117
  it 'should return false' do
118
- Change::Gradual.linear(5,2).should_not eq(Change::Gradual.linear(4,2))
118
+ expect(Change::Gradual.linear(5,2)).to_not eq(Change::Gradual.linear(4,2))
119
119
  end
120
120
  end
121
-
121
+
122
122
  context 'two gradual changes do not have the same duration' do
123
123
  it 'should return false' do
124
- Change::Gradual.linear(5,2).should_not eq(Change::Gradual.linear(5,1))
124
+ expect(Change::Gradual.linear(5,2)).to_not eq(Change::Gradual.linear(5,1))
125
125
  end
126
126
  end
127
-
127
+
128
128
  context 'two gradual changes do not have the start value' do
129
129
  it 'should return false' do
130
- Change::Gradual.linear(5,2, start_value: 3).should_not eq(Change::Gradual.linear(5,1))
130
+ expect(Change::Gradual.linear(5,2, start_value: 3)).to_not eq(Change::Gradual.linear(5,1))
131
131
  end
132
132
  end
133
133
  end
134
-
134
+
135
135
  describe '#to_yaml' do
136
136
  it 'should produce YAML that can be loaded' do
137
137
  c = Change::Gradual.linear(4,2)
138
- YAML.load(c.to_yaml).should eq c
138
+ expect(YAML.load(c.to_yaml)).to eq c
139
139
  end
140
140
  end
141
141
 
142
142
  describe '#pack' do
143
143
  it 'should produce a Hash' do
144
144
  h = Change::Gradual.linear(4,2).pack
145
- h.should be_a Hash
145
+ expect(h).to be_a Hash
146
146
  end
147
147
  end
148
148
 
@@ -150,47 +150,47 @@ describe Change::Gradual do
150
150
  it 'should return a Change::Gradual equal to the original' do
151
151
  c1 = Change::Gradual.linear(4,2)
152
152
  c2 = Change::Gradual.unpack(c1.pack)
153
- c2.should be_a Change::Gradual
154
- c2.should eq c1
153
+ expect(c2).to be_a Change::Gradual
154
+ expect(c2).to eq c1
155
155
  end
156
156
  end
157
157
  end
158
158
 
159
159
  describe Change::Gradual::Trimmed do
160
160
  it 'should be a Change::Gradual' do
161
- Change::Gradual::Trimmed.new(35,1,Change::Gradual::LINEAR,preceding: 0, remaining: 0.5).should be_a Change::Gradual
161
+ expect(Change::Gradual::Trimmed.new(35,1,Change::Gradual::LINEAR,preceding: 0, remaining: 0.5)).to be_a Change::Gradual
162
162
  end
163
-
163
+
164
164
  describe '.linear' do
165
165
  before(:all){ @change = Change::Gradual::Trimmed.linear(55,20,preceding:5,remaining:6) }
166
-
166
+
167
167
  it 'should assign end_value, duration, preceding, and remaining as normal' do
168
- @change.end_value.should eq(55)
169
- @change.duration.should eq(20)
170
- @change.preceding.should eq(5)
171
- @change.remaining.should eq(6)
168
+ expect(@change.end_value).to eq(55)
169
+ expect(@change.duration).to eq(20)
170
+ expect(@change.preceding).to eq(5)
171
+ expect(@change.remaining).to eq(6)
172
172
  end
173
-
173
+
174
174
  it 'should set transition to linear' do
175
- @change.transition.should eq(Change::Gradual::LINEAR)
175
+ expect(@change.transition).to eq(Change::Gradual::LINEAR)
176
176
  end
177
177
  end
178
-
178
+
179
179
  describe '.sigmoid' do
180
180
  before(:all){ @change = Change::Gradual::Trimmed.sigmoid(55,20,preceding:5,remaining:6) }
181
-
181
+
182
182
  it 'should assign end_value, duration, preceding, and remaining as normal' do
183
- @change.end_value.should eq(55)
184
- @change.duration.should eq(20)
185
- @change.preceding.should eq(5)
186
- @change.remaining.should eq(6)
183
+ expect(@change.end_value).to eq(55)
184
+ expect(@change.duration).to eq(20)
185
+ expect(@change.preceding).to eq(5)
186
+ expect(@change.remaining).to eq(6)
187
187
  end
188
-
188
+
189
189
  it 'should set transition to SIGMOID' do
190
- @change.transition.should eq(Change::Gradual::SIGMOID)
190
+ expect(@change.transition).to eq(Change::Gradual::SIGMOID)
191
191
  end
192
192
  end
193
-
193
+
194
194
  it 'should raise NegativeError if preceding is < 0' do
195
195
  expect { Change::Gradual::Trimmed.linear(11,1,preceding: -1,remaining: 0.5) }.to raise_error(NegativeError)
196
196
  end
@@ -199,41 +199,41 @@ describe Change::Gradual::Trimmed do
199
199
  expect { Change::Gradual::Trimmed.linear(11,3,preceding: 1,remaining: 0) }.to raise_error(NonPositiveError)
200
200
  expect { Change::Gradual::Trimmed.linear(11,3,preceding: 1,remaining: -1) }.to raise_error(NonPositiveError)
201
201
  end
202
-
202
+
203
203
  describe '#untrim' do
204
204
  before :all do
205
205
  @trimmed = Change::Gradual.linear(51,12).trim(2,2)
206
206
  @untrimmed = @trimmed.untrim
207
207
  end
208
-
208
+
209
209
  it 'should return a Change::Gradual' do
210
- @untrimmed.should be_a Change::Gradual
210
+ expect(@untrimmed).to be_a Change::Gradual
211
211
  end
212
-
212
+
213
213
  it 'should keep end_value, duration, and transition' do
214
- @untrimmed.end_value.should eq(@trimmed.end_value)
215
- @untrimmed.duration.should eq(@trimmed.duration)
216
- @untrimmed.transition.should eq(@trimmed.transition)
214
+ expect(@untrimmed.end_value).to eq(@trimmed.end_value)
215
+ expect(@untrimmed.duration).to eq(@trimmed.duration)
216
+ expect(@untrimmed.transition).to eq(@trimmed.transition)
217
217
  end
218
218
  end
219
-
219
+
220
220
  describe '#trailing' do
221
221
  it 'should return the amount of transition unused at the end' do
222
- Change::Gradual.linear(41,19).trim(4,9).trailing.should eq(9)
222
+ expect(Change::Gradual.linear(41,19).trim(4,9).trailing).to eq(9)
223
223
  end
224
224
  end
225
225
 
226
226
  describe '#to_yaml' do
227
227
  it 'should produce YAML that can be loaded' do
228
228
  c = Change::Gradual::Trimmed.linear(4,2, preceding: 1, remaining: 0.5)
229
- YAML.load(c.to_yaml).should eq c
229
+ expect(YAML.load(c.to_yaml)).to eq c
230
230
  end
231
231
  end
232
232
 
233
233
  describe '#pack' do
234
234
  it 'should produce a Hash' do
235
235
  h = Change::Gradual::Trimmed.linear(4,2, preceding: 1, remaining: 0.5).pack
236
- h.should be_a Hash
236
+ expect(h).to be_a Hash
237
237
  end
238
238
  end
239
239
 
@@ -241,8 +241,8 @@ describe Change::Gradual::Trimmed do
241
241
  it 'should return a Change::Gradual::Trimmed equal to the original' do
242
242
  c1 = Change::Gradual::Trimmed.linear(4,2, preceding: 1, remaining: 0.5)
243
243
  c2 = Change::Gradual::Trimmed.unpack(c1.pack)
244
- c2.should be_a Change::Gradual::Trimmed
245
- c2.should eq c1
244
+ expect(c2).to be_a Change::Gradual::Trimmed
245
+ expect(c2).to eq c1
246
246
  end
247
247
  end
248
- end
248
+ end
@@ -1,44 +1,28 @@
1
1
  require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
2
2
 
3
3
  describe Key do
4
- describe '.major_flat' do
5
- it 'should set triad to MAJOR and accidental_pref to FLAT' do
6
- k = Key.major_flat(0)
7
- k.triad.should eq(Key::MAJOR)
8
- k.accidental_pref.should eq(Key::FLAT)
4
+ describe '.major' do
5
+ it 'should set triad to MAJOR' do
6
+ k = Key.major(PitchClasses::C)
7
+ expect(k.triad_type).to eq(Key::MAJOR)
8
+ expect(k.accidental_type).to eq(Key::NONE)
9
9
  end
10
10
  end
11
11
 
12
- describe '.minor_flat' do
13
- it 'should set triad to MAJOR and accidental_pref to SHARP' do
14
- k = Key.major_sharp(0)
15
- k.triad.should eq(Key::MAJOR)
16
- k.accidental_pref.should eq(Key::SHARP)
17
- end
18
- end
19
-
20
- describe '.major_sharp' do
21
- it 'should set triad to MINOR and accidental_pref to FLAT' do
22
- k = Key.minor_flat(0)
23
- k.triad.should eq(Key::MINOR)
24
- k.accidental_pref.should eq(Key::FLAT)
25
- end
26
- end
27
-
28
- describe '.minor_sharp' do
29
- it 'should set triad to MINOR and accidental_pref to SHARP' do
30
- k = Key.minor_sharp(0)
31
- k.triad.should eq(Key::MINOR)
32
- k.accidental_pref.should eq(Key::SHARP)
12
+ describe '.minor' do
13
+ it 'should set triad to MINOR' do
14
+ k = Key.minor(PitchClasses::A)
15
+ expect(k.triad_type).to eq(Key::MINOR)
16
+ expect(k.accidental_type).to eq(Key::NONE)
33
17
  end
34
18
  end
35
19
 
36
20
  describe '.new' do
37
21
  context 'given tonic_pc that is not in 0..11' do
38
22
  it 'should apply mod 12 to bring it in range' do
39
- { 12 => 0, 13 => 1, -1 => 11, 24 => 0, 18 => 6
23
+ { 12 => 0, 13 => 1, -1 => 11, 24 => 0, 18 => 6
40
24
  }.each do |t1,t2|
41
- Key.major_flat(t1).tonic_pc.should eq(t2)
25
+ expect(Key.major(t1).tonic_pc).to eq(t2)
42
26
  end
43
27
  end
44
28
  end
@@ -46,33 +30,33 @@ describe Key do
46
30
  context 'given tonic_pc in 0..11' do
47
31
  it 'should not change' do
48
32
  (0..11).each do |pc|
49
- Key.major_flat(pc).tonic_pc.should eq(pc)
33
+ expect(Key.major(pc).tonic_pc).to eq(pc)
50
34
  end
51
35
  end
52
36
  end
53
-
37
+
54
38
  context 'given triad that is not MAJOR or MINOR' do
55
39
  it 'should raise ArgumentError' do
56
40
  expect { Key.new(0, triad: :flipping) }.to raise_error(ArgumentError)
57
41
  end
58
42
  end
59
-
60
- context 'given accidental_pref that is not FLAT or SHARP' do
61
- it 'should raise ArgumentError' do
62
- expect { Key.new(0, accidental_pref: :squiggle) }.to raise_error(ArgumentError)
63
- end
64
- end
65
43
  end
66
-
44
+
67
45
  describe '#flat?' do
68
- context 'given accidental_pref is FLAT' do
46
+
47
+ context 'given accidental type is FLAT' do
69
48
  it 'should return true' do
70
- Key.major_flat(0).flat?.should be true
49
+ expect(Key.major(PitchClasses::F).flat?).to be true
71
50
  end
72
51
  end
73
- context 'given accidental_pref is SHARP' do
52
+ context 'given accidental type is SHARP' do
53
+ it 'should return false' do
54
+ expect(Key.major(PitchClasses::D).flat?).to be false
55
+ end
56
+ end
57
+ context 'given accidental type is NONE' do
74
58
  it 'should return false' do
75
- Key.major_sharp(0).flat?.should be false
59
+ expect(Key.major(PitchClasses::C).flat?).to be false
76
60
  end
77
61
  end
78
62
  end
@@ -80,12 +64,17 @@ describe Key do
80
64
  describe '#sharp?' do
81
65
  context 'given accidental_pref is FLAT' do
82
66
  it 'should return false' do
83
- Key.major_flat(0).sharp?.should be false
67
+ expect(Key.major(PitchClasses::F).sharp?).to be false
84
68
  end
85
69
  end
86
70
  context 'given accidental_pref is SHARP' do
87
71
  it 'should return true' do
88
- Key.major_sharp(0).sharp?.should be true
72
+ expect(Key.major(PitchClasses::D).sharp?).to be true
73
+ end
74
+ end
75
+ context 'given accidental type is NONE' do
76
+ it 'should return false' do
77
+ expect(Key.major(PitchClasses::C).sharp?).to be false
89
78
  end
90
79
  end
91
80
  end
@@ -93,12 +82,12 @@ describe Key do
93
82
  describe '#major?' do
94
83
  context 'given triad is MAJOR' do
95
84
  it 'should return true' do
96
- Key.major_flat(0).major?.should be true
85
+ expect(Key.major(0).major?).to be true
97
86
  end
98
87
  end
99
88
  context 'given triad is MINOR' do
100
89
  it 'should return false' do
101
- Key.minor_flat(0).major?.should be false
90
+ expect(Key.minor(0).major?).to be false
102
91
  end
103
92
  end
104
93
  end
@@ -106,66 +95,143 @@ describe Key do
106
95
  describe '#minor?' do
107
96
  context 'given triad is MAJOR' do
108
97
  it 'should return false' do
109
- Key.major_flat(0).minor?.should be false
98
+ expect(Key.major(0).minor?).to be false
110
99
  end
111
100
  end
112
101
  context 'given triad is MINOR' do
113
102
  it 'should return true' do
114
- Key.minor_flat(0).minor?.should be true
103
+ expect(Key.minor(0).minor?).to be true
115
104
  end
116
105
  end
117
106
  end
118
-
107
+
119
108
  describe '#==' do
120
109
  context 'objects with different tonic_pc' do
121
110
  it 'should return false' do
122
- Key.major_flat(0).should_not eq(Key.major_flat(1))
111
+ expect(Key.major(0)).to_not eq(Key.major(1))
123
112
  end
124
113
  end
125
-
114
+
126
115
  context 'objects with different triad' do
127
116
  it 'should return false' do
128
- Key.major_flat(0).should_not eq(Key.minor_flat(0))
129
- end
130
- end
131
-
132
- context 'objects with different accidental_type' do
133
- it 'should return false' do
134
- Key.major_flat(0).should_not eq(Key.major_sharp(0))
117
+ expect(Key.major(0)).to_not eq(Key.minor(0))
135
118
  end
136
119
  end
137
-
138
- context 'objects with same tonic_pc, triad, and accidental_type' do
120
+
121
+ context 'objects with same tonic_pc and triad type' do
139
122
  it 'should return true' do
140
- Key.major_flat(0).should eq(Key.major_flat(0))
123
+ expect(Key.major(0)).to eq(Key.major(0))
141
124
  end
142
125
  end
143
126
  end
144
-
127
+
145
128
  describe '#clone' do
146
129
  it 'should return a different, equal object' do
147
- k1 = Key.major_flat(0)
130
+ k1 = Key.major(0)
148
131
  k2 = k1.clone
149
- k1.should_not be k2
150
- k1.should eq k2
132
+ expect(k1).to_not be k2
133
+ expect(k1).to eq k2
151
134
  end
152
135
  end
153
-
136
+
154
137
  describe '#accidentals' do
138
+ context 'C major or A minor' do
139
+ it 'should have no accidentals' do
140
+ expect(Keys::C_MAJOR.accidentals).to be_empty
141
+ expect(Keys::A_MINOR.accidentals).to be_empty
142
+ end
143
+ end
144
+
145
+ context 'F major or D minor' do
146
+ it 'should have one flat' do
147
+ expect(Keys::F_MAJOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(1))
148
+ expect(Keys::D_MINOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(1))
149
+ end
150
+ end
151
+
152
+ context 'Bb major or G minor' do
153
+ it 'should have two flats' do
154
+ expect(Keys::Bb_MAJOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(2))
155
+ expect(Keys::G_MINOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(2))
156
+ end
157
+ end
158
+
159
+ context 'Eb major or C minor' do
160
+ it 'should have three flats' do
161
+ expect(Keys::Eb_MAJOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(3))
162
+ expect(Keys::C_MINOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(3))
163
+ end
164
+ end
165
+
166
+ context 'Ab major or F minor' do
167
+ it 'should have four flats' do
168
+ expect(Keys::Ab_MAJOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(4))
169
+ expect(Keys::F_MINOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(4))
170
+ end
171
+ end
172
+
173
+ context 'Db major or Bb minor' do
174
+ it 'should have five flats' do
175
+ expect(Keys::Db_MAJOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(5))
176
+ expect(Keys::Bb_MINOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(5))
177
+ end
178
+ end
179
+
180
+ context 'Gb major or Eb minor' do
181
+ it 'should have six flats' do
182
+ expect(Keys::Gb_MAJOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(6))
183
+ expect(Keys::Eb_MINOR.accidentals).to eq(Key::ACCIDENTALS[Key::FLAT].take(6))
184
+ end
185
+ end
186
+
187
+ context 'G major or E minor' do
188
+ it 'should have one sharp' do
189
+ expect(Keys::G_MAJOR.accidentals).to eq(Key::ACCIDENTALS[Key::SHARP].take(1))
190
+ expect(Keys::E_MINOR.accidentals).to eq(Key::ACCIDENTALS[Key::SHARP].take(1))
191
+ end
192
+ end
193
+
194
+ context 'D major or B minor' do
195
+ it 'should have two sharps' do
196
+ expect(Keys::D_MAJOR.accidentals).to eq(Key::ACCIDENTALS[Key::SHARP].take(2))
197
+ expect(Keys::B_MINOR.accidentals).to eq(Key::ACCIDENTALS[Key::SHARP].take(2))
198
+ end
199
+ end
200
+
201
+ context 'A major or F# minor' do
202
+ it 'should have three sharps' do
203
+ expect(Keys::A_MAJOR.accidentals).to eq(Key::ACCIDENTALS[Key::SHARP].take(3))
204
+ expect(Keys::Fs_MINOR.accidentals).to eq(Key::ACCIDENTALS[Key::SHARP].take(3))
205
+ end
206
+ end
207
+
208
+ context 'E major or C# minor' do
209
+ it 'should have four sharps' do
210
+ expect(Keys::E_MAJOR.accidentals).to eq(Key::ACCIDENTALS[Key::SHARP].take(4))
211
+ expect(Keys::Cs_MINOR.accidentals).to eq(Key::ACCIDENTALS[Key::SHARP].take(4))
212
+ end
213
+ end
214
+
215
+ context 'B major or G# minor' do
216
+ it 'should have five sharps' do
217
+ expect(Keys::B_MAJOR.accidentals).to eq(Key::ACCIDENTALS[Key::SHARP].take(5))
218
+ expect(Keys::Gs_MINOR.accidentals).to eq(Key::ACCIDENTALS[Key::SHARP].take(5))
219
+ end
220
+ end
155
221
  end
156
222
 
157
223
  describe '#pack' do
158
224
  it 'should return a Hash' do
159
- Key.major_sharp(1).pack.should be_a Hash
225
+ expect(Key.major(1).pack).to be_a Hash
160
226
  end
161
227
  end
162
228
 
163
229
  describe '.unpack' do
164
230
  it 'should return a Key object equal to the original' do
165
- k1 = Key.major_sharp(1)
231
+ k1 = Key.major(1)
166
232
  k2 = Key.unpack k1.pack
167
- k2.should be_a Key
168
- k2.should eq(k1)
233
+ expect(k2).to be_a Key
234
+ expect(k2).to eq(k1)
169
235
  end
170
236
  end
171
237
  end