Skip to content

Commit

Permalink
scale-generator: Require N+1 notes from N intervals
Browse files Browse the repository at this point in the history
The problem has been explained in
exercism/problem-specifications#1640:

All previous cases only required N notes from N intervals, but that
meant the last interval was completely ignored.
That causes confusion (what is the last interval there for?).

To fix this, all tests with the `interval` property are updated.

The `tonic` and `intervals` inputs have not changed. The `expected` has
changed only in that there is one more note added, indicated by the last
interval, which was previously ignored.

exercism/problem-specifications#1888
  • Loading branch information
petertseng committed Nov 28, 2021
1 parent f3f1f0e commit 93d392d
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 18 deletions.
3 changes: 2 additions & 1 deletion exercises/practice/scale-generator/.meta/example.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,9 +346,10 @@ impl Scale {
let mut out = Vec::with_capacity(self.intervals.len());

let mut note = self.tonic;
out.push(note.canonicalize(self.lean).to_string());
for &interval in self.intervals.iter() {
out.push(note.canonicalize(self.lean).to_string());
note += interval;
out.push(note.canonicalize(self.lean).to_string());
}

out
Expand Down
58 changes: 41 additions & 17 deletions exercises/practice/scale-generator/tests/scale-generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fn test_chromatic_scale_with_sharps() {
process_chromatic_case(
"C",
&[
"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B",
"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B", "C",
],
);
}
Expand All @@ -47,7 +47,7 @@ fn test_chromatic_scale_with_flats() {
process_chromatic_case(
"F",
&[
"F", "Gb", "G", "Ab", "A", "Bb", "B", "C", "Db", "D", "Eb", "E",
"F", "Gb", "G", "Ab", "A", "Bb", "B", "C", "Db", "D", "Eb", "E", "F",
],
);
}
Expand All @@ -62,70 +62,90 @@ fn test_chromatic_scale_with_flats() {
///
/// The simplest major scale, with no sharps or flats.
fn test_simple_major_scale() {
process_interval_case("C", "MMmMMMm", &["C", "D", "E", "F", "G", "A", "B"]);
process_interval_case("C", "MMmMMMm", &["C", "D", "E", "F", "G", "A", "B", "C"]);
}

#[test]
#[ignore]
/// Major scale with sharps
fn test_major_scale_with_sharps() {
process_interval_case("G", "MMmMMMm", &["G", "A", "B", "C", "D", "E", "F#"]);
process_interval_case("G", "MMmMMMm", &["G", "A", "B", "C", "D", "E", "F#", "G"]);
}

#[test]
#[ignore]
/// Major scale with flats
fn test_major_scale_with_flats() {
process_interval_case("F", "MMmMMMm", &["F", "G", "A", "Bb", "C", "D", "E"]);
process_interval_case("F", "MMmMMMm", &["F", "G", "A", "Bb", "C", "D", "E", "F"]);
}

#[test]
#[ignore]
/// Minor scale with sharps
fn test_minor_scale_with_sharps() {
process_interval_case("f#", "MmMMmMM", &["F#", "G#", "A", "B", "C#", "D", "E"]);
process_interval_case(
"f#",
"MmMMmMM",
&["F#", "G#", "A", "B", "C#", "D", "E", "F#"],
);
}

#[test]
#[ignore]
/// Minor scale with flats
fn test_minor_scale_with_flats() {
process_interval_case("bb", "MmMMmMM", &["Bb", "C", "Db", "Eb", "F", "Gb", "Ab"]);
process_interval_case(
"bb",
"MmMMmMM",
&["Bb", "C", "Db", "Eb", "F", "Gb", "Ab", "Bb"],
);
}

#[test]
#[ignore]
/// Dorian mode
fn test_dorian_mode() {
process_interval_case("d", "MmMMMmM", &["D", "E", "F", "G", "A", "B", "C"]);
process_interval_case("d", "MmMMMmM", &["D", "E", "F", "G", "A", "B", "C", "D"]);
}

#[test]
#[ignore]
/// Mixolydian mode
fn test_mixolydian_mode() {
process_interval_case("Eb", "MMmMMmM", &["Eb", "F", "G", "Ab", "Bb", "C", "Db"]);
process_interval_case(
"Eb",
"MMmMMmM",
&["Eb", "F", "G", "Ab", "Bb", "C", "Db", "Eb"],
);
}

#[test]
#[ignore]
/// Lydian mode
fn test_lydian_mode() {
process_interval_case("a", "MMMmMMm", &["A", "B", "C#", "D#", "E", "F#", "G#"]);
process_interval_case(
"a",
"MMMmMMm",
&["A", "B", "C#", "D#", "E", "F#", "G#", "A"],
);
}

#[test]
#[ignore]
/// Phrygian mode
fn test_phrygian_mode() {
process_interval_case("e", "mMMMmMM", &["E", "F", "G", "A", "B", "C", "D"]);
process_interval_case("e", "mMMMmMM", &["E", "F", "G", "A", "B", "C", "D", "E"]);
}

#[test]
#[ignore]
/// Locrian mode
fn test_locrian_mode() {
process_interval_case("g", "mMMmMMM", &["G", "Ab", "Bb", "C", "Db", "Eb", "F"]);
process_interval_case(
"g",
"mMMmMMM",
&["G", "Ab", "Bb", "C", "Db", "Eb", "F", "G"],
);
}

#[test]
Expand All @@ -134,7 +154,7 @@ fn test_locrian_mode() {
///
/// Note that this case introduces the augmented second interval (A)
fn test_harmonic_minor() {
process_interval_case("d", "MmMMmAm", &["D", "E", "F", "G", "A", "Bb", "Db"]);
process_interval_case("d", "MmMMmAm", &["D", "E", "F", "G", "A", "Bb", "Db", "D"]);
}

#[test]
Expand All @@ -144,27 +164,31 @@ fn test_octatonic() {
process_interval_case(
"C",
"MmMmMmMm",
&["C", "D", "D#", "F", "F#", "G#", "A", "B"],
&["C", "D", "D#", "F", "F#", "G#", "A", "B", "C"],
);
}

#[test]
#[ignore]
/// Hexatonic
fn test_hexatonic() {
process_interval_case("Db", "MMMMMM", &["Db", "Eb", "F", "G", "A", "B"]);
process_interval_case("Db", "MMMMMM", &["Db", "Eb", "F", "G", "A", "B", "Db"]);
}

#[test]
#[ignore]
/// Pentatonic
fn test_pentatonic() {
process_interval_case("A", "MMAMA", &["A", "B", "C#", "E", "F#"]);
process_interval_case("A", "MMAMA", &["A", "B", "C#", "E", "F#", "A"]);
}

#[test]
#[ignore]
/// Enigmatic
fn test_enigmatic() {
process_interval_case("G", "mAMMMmm", &["G", "G#", "B", "C#", "D#", "F", "F#"]);
process_interval_case(
"G",
"mAMMMmm",
&["G", "G#", "B", "C#", "D#", "F", "F#", "G"],
);
}

0 comments on commit 93d392d

Please sign in to comment.