1
1
using BaroquenMelody . Library . Composition . Choices ;
2
+ using BaroquenMelody . Library . Composition . Configurations ;
2
3
using BaroquenMelody . Library . Composition . Contexts ;
3
4
using BaroquenMelody . Library . Composition . Enums ;
4
5
using BaroquenMelody . Library . Composition . Strategies ;
@@ -14,6 +15,22 @@ namespace BaroquenMelody.Library.Tests.Composition.Strategies;
14
15
[ TestFixture ]
15
16
internal sealed class CompositionStrategyTests
16
17
{
18
+ private const byte MinSopranoPitch = 60 ;
19
+
20
+ private const byte MaxSopranoPitch = 72 ;
21
+
22
+ private const byte MinAltoPitch = 48 ;
23
+
24
+ private const byte MaxAltoPitch = 60 ;
25
+
26
+ private const byte MinTenorPitch = 36 ;
27
+
28
+ private const byte MaxTenorPitch = 48 ;
29
+
30
+ private const byte MinBassPitch = 24 ;
31
+
32
+ private const byte MaxBassPitch = 36 ;
33
+
17
34
private static readonly BigInteger MockChordContextCount = 5 ;
18
35
19
36
private static readonly BigInteger MockChordChoiceCount = 5 ;
@@ -28,6 +45,8 @@ internal sealed class CompositionStrategyTests
28
45
29
46
private CompositionStrategy _compositionStrategy = default ! ;
30
47
48
+ private CompositionConfiguration _compositionConfiguration = default ! ;
49
+
31
50
[ SetUp ]
32
51
public void Setup ( )
33
52
{
@@ -39,11 +58,22 @@ public void Setup()
39
58
_mockChordChoiceRepository . Count . Returns ( MockChordChoiceCount ) ;
40
59
_mockChordContextRepository . Count . Returns ( MockChordContextCount ) ;
41
60
61
+ _compositionConfiguration = new CompositionConfiguration (
62
+ new HashSet < VoiceConfiguration >
63
+ {
64
+ new ( Voice . Soprano , MinSopranoPitch , MaxSopranoPitch ) ,
65
+ new ( Voice . Alto , MinAltoPitch , MaxAltoPitch ) ,
66
+ new ( Voice . Tenor , MinTenorPitch , MaxTenorPitch ) ,
67
+ new ( Voice . Bass , MinBassPitch , MaxBassPitch )
68
+ }
69
+ ) ;
70
+
42
71
_compositionStrategy = new CompositionStrategy (
43
72
_mockChordChoiceRepository ,
44
73
_mockChordContextRepository ,
45
74
_mockRandomTrueIndexSelector ,
46
- _mockChordContextToChordChoiceMap
75
+ _mockChordContextToChordChoiceMap ,
76
+ _compositionConfiguration
47
77
) ;
48
78
}
49
79
@@ -54,20 +84,20 @@ public void GetNextChordChoice_returns_random_chord_choice()
54
84
var chordContext = new ChordContext (
55
85
new List < NoteContext >
56
86
{
57
- new ( Voice . Soprano , 25 , NoteMotion . Ascending , NoteSpan . Step ) ,
58
- new ( Voice . Alto , 25 , NoteMotion . Ascending , NoteSpan . Step ) ,
59
- new ( Voice . Tenor , 25 , NoteMotion . Ascending , NoteSpan . Step ) ,
60
- new ( Voice . Bass , 25 , NoteMotion . Ascending , NoteSpan . Step )
87
+ new ( Voice . Soprano , MaxSopranoPitch - 2 , NoteMotion . Ascending , NoteSpan . Step ) ,
88
+ new ( Voice . Alto , MinAltoPitch + 2 , NoteMotion . Ascending , NoteSpan . Step ) ,
89
+ new ( Voice . Tenor , MaxTenorPitch - 2 , NoteMotion . Ascending , NoteSpan . Step ) ,
90
+ new ( Voice . Bass , MinBassPitch + 2 , NoteMotion . Ascending , NoteSpan . Step )
61
91
}
62
92
) ;
63
93
64
94
var chordChoice = new ChordChoice (
65
95
new List < NoteChoice >
66
96
{
67
- new ( Voice . Soprano , NoteMotion . Ascending , 5 ) ,
68
- new ( Voice . Alto , NoteMotion . Ascending , 5 ) ,
69
- new ( Voice . Tenor , NoteMotion . Ascending , 5 ) ,
70
- new ( Voice . Bass , NoteMotion . Ascending , 5 )
97
+ new ( Voice . Soprano , NoteMotion . Ascending , 1 ) ,
98
+ new ( Voice . Alto , NoteMotion . Ascending , 1 ) ,
99
+ new ( Voice . Tenor , NoteMotion . Ascending , 1 ) ,
100
+ new ( Voice . Bass , NoteMotion . Ascending , 1 )
71
101
}
72
102
) ;
73
103
@@ -97,6 +127,84 @@ public void GetNextChordChoice_returns_random_chord_choice()
97
127
) ;
98
128
}
99
129
130
+ [ Test ]
131
+ public void GetNextChordChoice_invalidates_choices_out_of_voice_range_and_returns_random_chord_choice ( )
132
+ {
133
+ // arrange
134
+ var chordContext = new ChordContext (
135
+ new List < NoteContext >
136
+ {
137
+ new ( Voice . Soprano , MaxSopranoPitch - 2 , NoteMotion . Ascending , NoteSpan . Step ) ,
138
+ new ( Voice . Alto , MinAltoPitch + 2 , NoteMotion . Ascending , NoteSpan . Step ) ,
139
+ new ( Voice . Tenor , MaxTenorPitch - 2 , NoteMotion . Ascending , NoteSpan . Step ) ,
140
+ new ( Voice . Bass , MinBassPitch + 2 , NoteMotion . Ascending , NoteSpan . Step )
141
+ }
142
+ ) ;
143
+
144
+ var invalidChordChoiceA = new ChordChoice (
145
+ new List < NoteChoice >
146
+ {
147
+ new ( Voice . Soprano , NoteMotion . Ascending , 5 ) ,
148
+ new ( Voice . Alto , NoteMotion . Descending , 5 ) ,
149
+ new ( Voice . Tenor , NoteMotion . Ascending , 5 ) ,
150
+ new ( Voice . Bass , NoteMotion . Descending , 5 )
151
+ }
152
+ ) ;
153
+
154
+ var invalidChordChoiceB = new ChordChoice (
155
+ new List < NoteChoice >
156
+ {
157
+ new ( Voice . Soprano , NoteMotion . Ascending , 6 ) ,
158
+ new ( Voice . Alto , NoteMotion . Descending , 6 ) ,
159
+ new ( Voice . Tenor , NoteMotion . Ascending , 6 ) ,
160
+ new ( Voice . Bass , NoteMotion . Descending , 6 )
161
+ }
162
+ ) ;
163
+
164
+ var validChordChoice = new ChordChoice (
165
+ new List < NoteChoice >
166
+ {
167
+ new ( Voice . Soprano , NoteMotion . Ascending , 1 ) ,
168
+ new ( Voice . Alto , NoteMotion . Ascending , 1 ) ,
169
+ new ( Voice . Tenor , NoteMotion . Ascending , 1 ) ,
170
+ new ( Voice . Bass , NoteMotion . Ascending , 1 )
171
+ }
172
+ ) ;
173
+
174
+ const int chordContextIndex = 3 ;
175
+ const int invalidChordChoiceIndexA = 2 ;
176
+ const int invalidChordChoiceIndexB = 3 ;
177
+ const int validChordChoiceIndex = 4 ;
178
+
179
+ var bitArray = new BitArray ( new [ ] { true , true , true , true , true } ) ;
180
+
181
+ _mockChordContextRepository . GetChordContextIndex ( chordContext ) . Returns ( chordContextIndex ) ;
182
+ _mockChordContextToChordChoiceMap [ chordContextIndex ] . Returns ( bitArray ) ;
183
+
184
+ _mockRandomTrueIndexSelector . SelectRandomTrueIndex ( bitArray ) . Returns (
185
+ invalidChordChoiceIndexA ,
186
+ invalidChordChoiceIndexB ,
187
+ validChordChoiceIndex
188
+ ) ;
189
+
190
+ _mockChordChoiceRepository . GetChordChoice ( invalidChordChoiceIndexA ) . Returns ( invalidChordChoiceA ) ;
191
+ _mockChordChoiceRepository . GetChordChoice ( invalidChordChoiceIndexB ) . Returns ( invalidChordChoiceB ) ;
192
+ _mockChordChoiceRepository . GetChordChoice ( validChordChoiceIndex ) . Returns ( validChordChoice ) ;
193
+
194
+ _mockChordChoiceRepository . GetChordChoiceIndex ( invalidChordChoiceA ) . Returns ( invalidChordChoiceIndexA ) ;
195
+ _mockChordChoiceRepository . GetChordChoiceIndex ( invalidChordChoiceB ) . Returns ( invalidChordChoiceIndexB ) ;
196
+
197
+ // act
198
+ var result = _compositionStrategy . GetNextChordChoice ( chordContext ) ;
199
+
200
+ // assert
201
+ result . Should ( ) . BeEquivalentTo ( validChordChoice ) ;
202
+
203
+ bitArray [ invalidChordChoiceIndexA ] . Should ( ) . BeFalse ( ) ;
204
+ bitArray [ invalidChordChoiceIndexB ] . Should ( ) . BeFalse ( ) ;
205
+ bitArray [ validChordChoiceIndex ] . Should ( ) . BeTrue ( ) ;
206
+ }
207
+
100
208
[ Test ]
101
209
public void InvalidateChordChoice_sets_bit_to_false ( )
102
210
{
0 commit comments