From Code to Community: Sponsoring The Perl and Raku Conference 2025 Learn more

#!/usr/bin/env perl
use strict;
no warnings 'qw';
use_ok 'Music::Cadence';
subtest perfect => sub {
my $mc = new_ok 'Music::Cadence' => [seven => 1];
my $chords = $mc->cadence;
is_deeply $chords, [ [qw/ G B D F /], [qw/ C E G A# C /] ], 'C7 0 perfect';
$chords = $mc->cadence(
key => 'C#',
octave => 4,
seven => 1,
);
is_deeply $chords, [ [qw/ G#4 C4 D#4 F#4 /], [qw/ C#4 F4 G#4 B4 C#5 /] ], 'C#7 4 perfect';
};
subtest plagal => sub {
my $mc = new_ok 'Music::Cadence' => [seven => 1];
my $chords = $mc->cadence( type => 'plagal' );
is_deeply $chords, [ [qw/ F A C D# /], [qw/ C E G A# /] ], 'C7 0 plagal';
$chords = $mc->cadence(
key => 'C#',
type => 'plagal',
);
is_deeply $chords, [ [qw/ F# A# C# E /], [qw/ C# F G# B /] ], 'C#7 0 plagal';
};
subtest half => sub {
my $mc = new_ok 'Music::Cadence' => [seven => 1];
my $chords = $mc->cadence(
type => 'half',
leading => 7,
);
is_deeply $chords, [ [qw/ B D F G# /], [qw/ G B D F /] ], 'C7 0 half 7';
$chords = $mc->cadence(
type => 'half',
leading => 2,
);
is_deeply $chords, [ [qw/ D F A C /], [qw/ G B D F /] ], 'C7 0 half 2';
$chords = $mc->cadence(
type => 'half',
leading => 2,
inversion => { 1 => 1 },
);
is_deeply $chords, [ [qw/ F A C D /], [qw/ G B D F /] ], 'C7 0 half 2 inversion 1-1';
$chords = $mc->cadence(
key => 'C#',
type => 'half',
leading => 2,
);
is_deeply $chords, [ [qw/ D# F# A# C# /], [qw/ G# C D# F# /] ], 'C#7 0 half 2';
$chords = $mc->cadence(
key => 'D',
scale => 'dorian',
type => 'half',
leading => 6,
);
is_deeply $chords, [ [qw/ B D F G# /], [qw/ A C E G /] ], 'D7 0 dorian half';
$chords = $mc->cadence(
key => 'E',
scale => 'phrygian',
type => 'half',
leading => 5,
);
is_deeply $chords, [ [qw/ B D F G# /], [qw/ B D F G# /] ], 'E7 0 phrygian half';
};
subtest deceptive => sub {
my $mc = new_ok 'Music::Cadence' => [seven => 1];
my $chords = $mc->cadence( type => 'deceptive' );
is_deeply $chords, [ [qw/ G B D F /], [qw/ A C E G /] ], 'C7 0 deceptive 1';
$chords = $mc->cadence(
key => 'C#',
type => 'deceptive',
variation => 2,
);
is_deeply $chords, [ [qw/ G# C D# F# /], [qw/ F# A# C# E /] ], 'C#7 0 deceptive 2';
};
subtest imperfect => sub {
my $mc = new_ok 'Music::Cadence' => [seven => 1];
my $chords = $mc->cadence( type => 'imperfect' );
is_deeply $chords, [ [qw/ G B D F /], [qw/ C E G A# /] ], 'C7 0 imperfect 1';
$chords = $mc->cadence(
type => 'imperfect',
variation => 2,
);
is_deeply $chords, [ [qw/ B D F G# /], [qw/ C E G A# /] ], 'C7 0 imperfect 2';
$chords = $mc->cadence(
type => 'imperfect',
inversion => { 1 => 1 },
);
is_deeply $chords, [ [qw/ B D F G /], [qw/ C E G A# /] ], 'C7 0 imperfect inversion 1-1';
$chords = $mc->cadence(
type => 'imperfect',
inversion => { 1 => 1, 2 => 0 },
);
is_deeply $chords, [ [qw/ B D F G /], [qw/ C E G A# /] ], 'C7 0 imperfect inversion 1-1,2-0';
$chords = $mc->cadence(
type => 'imperfect',
inversion => { 1 => 2 },
);
is_deeply $chords, [ [qw/ D F G B /], [qw/ C E G A# /] ], 'C7 0 imperfect inversion 1-2';
$chords = $mc->cadence(
type => 'imperfect',
inversion => { 1 => 1, 2 => 1 },
);
is_deeply $chords, [ [qw/ B D F G /], [qw/ E G A# C /] ], 'C7 0 imperfect inversion 1-1,2-1';
$chords = $mc->cadence(
octave => 4,
type => 'imperfect',
inversion => { 1 => 1, 2 => 1 },
);
is_deeply $chords, [ [qw/ B4 D4 F4 G5 /], [qw/ E4 G4 A#4 C5 /] ], 'C7 4 imperfect inversion 1-1,2-1';
$chords = $mc->cadence(
key => 'C#',
octave => 4,
type => 'imperfect',
inversion => { 1 => 1, 2 => 1 },
);
is_deeply $chords, [ [qw/ C4 D#4 F#4 G#5 /], [qw/ F4 G#4 B4 C#5 /] ], 'C#7 4 imperfect inversion 1-1,2-1';
$chords = $mc->cadence(
octave => 4,
type => 'imperfect',
inversion => { 1 => 3, 2 => 1 },
);
is_deeply $chords, [ [qw/ F4 G5 B5 D5 /], [qw/ E4 G4 A#4 C5 /] ], 'C7 4 imperfect inversion 1-3,2-1';
};
subtest evaded => sub {
my $mc = new_ok 'Music::Cadence' => [seven => 1];
my $chords = $mc->cadence(
octave => 4,
type => 'evaded',
);
is_deeply $chords, [ [qw/ F4 G5 B5 D5 /], [qw/ E4 G4 A#4 C5 /] ], 'C7 4 evaded';
$chords = $mc->cadence(
octave => 4,
type => 'evaded',
inversion => { 1 => 1, 2 => 2 },
);
is_deeply $chords, [ [qw/ B4 D4 F4 G5 /], [qw/ G4 A#4 C5 E5 /] ], 'C7 4 evaded inversion 1-1,2-2';
};
subtest format => sub {
my $mc = new_ok 'Music::Cadence' => [
key => 'C#',
octave => 5,
format => 'midi',
seven => 1,
];
my $chords = $mc->cadence;
is_deeply $chords, [ [qw/ Gs5 C5 Ds5 Fs5 /], [qw/ Cs5 F5 Gs5 B5 Cs6 /] ], 'C#7 5 perfect midi';
$mc = new_ok 'Music::Cadence' => [
octave => 4,
format => 'midinum',
seven => 1,
];
$chords = $mc->cadence;
is_deeply $chords, [ [ 67, 71, 62, 65 ], [ 60, 64, 67, 70, 72 ] ], 'C7 4 perfect midinum';
$mc = new_ok 'Music::Cadence' => [
format => 'midinum',
seven => 1,
];
$chords = $mc->cadence;
is_deeply $chords, [ [ 19, 23, 14, 17 ], [ 12, 16, 19, 22, 24 ] ], 'C7 0 perfect midinum';
$chords = $mc->cadence( octave => -1 );
is_deeply $chords, [ [ 7, 11, 2, 5 ], [ 0, 4, 7, 10, 12 ] ], 'C7 -1 perfect midinum';
};
done_testing();