diff --git a/README.md b/README.md index c9abe62..78e2b8d 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,7 @@ Immutable, validated musical value types plus an analysis layer that models harm ```csharp using ktsu.Semantics.Music; -Progression prog = Progression.Parse("| Dm7 | G7 | Cmaj7 |"); +Progression prog = Progression.Parse("4/4 Dm7 / / / | G7 / / / | Cmaj7 / / /"); Key key = prog.InferKey()!; // C major IReadOnlyList roman = prog.RomanNumerals(key); // ii7, V7, Imaj7 diff --git a/Semantics.Test/Music/ReadmeExampleTests.cs b/Semantics.Test/Music/ReadmeExampleTests.cs new file mode 100644 index 0000000..3e38e36 --- /dev/null +++ b/Semantics.Test/Music/ReadmeExampleTests.cs @@ -0,0 +1,53 @@ +// Copyright (c) 2023-2026 ktsu-dev contributors + +namespace ktsu.Semantics.Test.Music; + +using System.Text.RegularExpressions; + +using ktsu.Semantics.Music; + +/// +/// Checks the music examples in the READMEs against the library, so that an example a reader copies +/// from the package's front page runs. +/// +[TestClass] +public partial class ReadmeExampleTests +{ + private static readonly string[] Readmes = ["Root.md", "Music.md"]; + private static readonly string[] RootExampleNumerals = ["ii7", "V7", "Imaj7"]; + + private static string ReadmeDirectory => Path.Combine(AppContext.BaseDirectory, "Readmes"); + + [GeneratedRegex("""Progression\.Parse\("([^"]*)"\)""")] + private static partial Regex ProgressionLiteral(); + + private static string[] ProgressionLiterals(string readme) => + [.. ProgressionLiteral().Matches(File.ReadAllText(Path.Combine(ReadmeDirectory, readme))).Select(match => match.Groups[1].Value)]; + + [TestMethod] + public void EveryProgressionLiteralInTheReadmesParses() + { + foreach (string readme in Readmes) + { + string[] literals = ProgressionLiterals(readme); + Assert.IsNotEmpty(literals, readme); + + foreach (string literal in literals) + { + Assert.IsTrue(Progression.TryParse(literal, out _), $"{readme}: \"{literal}\""); + } + } + } + + [TestMethod] + public void RootReadmeMusicExample_GivesTheOutputsItsCommentsShow() + { + Progression prog = Progression.Parse(ProgressionLiterals("Root.md")[0]); + + Key? key = prog.InferKey(); + Assert.IsNotNull(key); + Assert.AreEqual(0, key.Tonic.Value); + Assert.AreEqual(Mode.Major, key.Mode); + Assert.AreSequenceEqual(RootExampleNumerals, prog.RomanNumerals(key)); + } +} diff --git a/Semantics.Test/Semantics.Test.csproj b/Semantics.Test/Semantics.Test.csproj index c9919f9..ff25bfd 100644 --- a/Semantics.Test/Semantics.Test.csproj +++ b/Semantics.Test/Semantics.Test.csproj @@ -62,6 +62,13 @@ CopyToOutputDirectory="PreserveNewest" /> + + + + + +