diff --git a/LrcParser.Tests/Parser/Kar/Lines/KarLyricParserTest.cs b/LrcParser.Tests/Parser/Kar/Lines/KarLyricParserTest.cs index f5916bb..271d35b 100644 --- a/LrcParser.Tests/Parser/Kar/Lines/KarLyricParserTest.cs +++ b/LrcParser.Tests/Parser/Kar/Lines/KarLyricParserTest.cs @@ -37,8 +37,7 @@ public void TestDecode(string lyric, string text, string[] timeTags) }; var actual = Decode(lyric); - Assert.That(actual.Text, Is.EqualTo(expected.Text)); - Assert.That(actual.TimeTags, Is.EqualTo(expected.TimeTags)); + Assert.That(actual, Is.EqualTo(expected)); } [TestCase("帰り道は", new[] { "[0,start]:17970", "[1,start]:18370", "[2,start]:18550", "[3,start]:18940", "[3,end]:19220" }, "[00:17.97]帰[00:18.37]り[00:18.55]道[00:18.94]は[00:19.22]")] diff --git a/LrcParser.Tests/Parser/Kar/Lines/KarRubyParserTest.cs b/LrcParser.Tests/Parser/Kar/Lines/KarRubyParserTest.cs index bdab6d9..ef52f8c 100644 --- a/LrcParser.Tests/Parser/Kar/Lines/KarRubyParserTest.cs +++ b/LrcParser.Tests/Parser/Kar/Lines/KarRubyParserTest.cs @@ -39,11 +39,7 @@ public void TestDecode(string rubyTag, string parent, string ruby, string[] time }; var actual = Decode(rubyTag); - Assert.That(actual.Ruby, Is.EqualTo(expected.Ruby)); - Assert.That(actual.Parent, Is.EqualTo(expected.Parent)); - Assert.That(actual.TimeTags, Is.EqualTo(expected.TimeTags)); - Assert.That(actual.StartTime, Is.EqualTo(expected.StartTime)); - Assert.That(actual.EndTime, Is.EqualTo(expected.EndTime)); + Assert.That(actual, Is.EqualTo(expected)); } [TestCase("帰", "かえ", new string[] { }, 53190, 84770, "@Ruby1=帰,かえ,[00:53.19],[01:24.77]")] diff --git a/LrcParser.Tests/Parser/Lines/BaseSingleLineParserTest.cs b/LrcParser.Tests/Parser/Lines/BaseSingleLineParserTest.cs index a73facc..08b0386 100644 --- a/LrcParser.Tests/Parser/Lines/BaseSingleLineParserTest.cs +++ b/LrcParser.Tests/Parser/Lines/BaseSingleLineParserTest.cs @@ -1,11 +1,13 @@ // Copyright (c) karaoke.dev . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using LrcParser.Parser.Lines; namespace LrcParser.Tests.Parser.Lines; -public class BaseSingleLineParserTest where TParser : SingleLineParser, new() where TModel : class +public class BaseSingleLineParserTest + where TParser : SingleLineParser, new() where TModel : struct, IEquatable { protected bool CanDecode(string text) => new TParser().CanDecode(text); diff --git a/LrcParser.Tests/Parser/Lrc/Lines/LrcLyricParserTest.cs b/LrcParser.Tests/Parser/Lrc/Lines/LrcLyricParserTest.cs index af1297a..30a364a 100644 --- a/LrcParser.Tests/Parser/Lrc/Lines/LrcLyricParserTest.cs +++ b/LrcParser.Tests/Parser/Lrc/Lines/LrcLyricParserTest.cs @@ -36,8 +36,7 @@ public void TestDecode(string lyric, string text, string[] timeTags) }; var actual = Decode(lyric); - Assert.That(actual.Text, Is.EqualTo(expected.Text)); - Assert.That(actual.TimeTags, Is.EqualTo(expected.TimeTags)); + Assert.That(actual, Is.EqualTo(expected)); } [TestCase("帰り道は", new[] { "[0,start]:17970", "[1,start]:18370", "[2,start]:18550", "[3,start]:18940", "[3,end]:19220" }, "[00:17.97]帰[00:18.37]り[00:18.55]道[00:18.94]は[00:19.22]")] diff --git a/LrcParser.Tests/Parser/LyricParserTest.cs b/LrcParser.Tests/Parser/LyricParserTest.cs index 8664f3e..7581301 100644 --- a/LrcParser.Tests/Parser/LyricParserTest.cs +++ b/LrcParser.Tests/Parser/LyricParserTest.cs @@ -1,6 +1,7 @@ // Copyright (c) karaoke.dev . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Collections.Generic; using System.Linq; using LrcParser.Model; @@ -45,13 +46,13 @@ public TestLyricParser() protected override Song PostProcess(List values) { - var lines = values.OfType(); + var lines = values.OfType(); return new Song { Lyrics = lines.Select(l => new Lyric { - Text = l, + Text = l.Text, }).ToList(), }; } @@ -60,14 +61,31 @@ protected override IEnumerable PreProcess(Song song) => song.Lyrics.Select(lyric => lyric.Text); } - private class TestLineParser : SingleLineParser + private class TestLineParser : SingleLineParser { public override bool CanDecode(string text) => true; - public override string Decode(string text) => text; + public override Line Decode(string text) => new() + { + Text = text, + }; + + public override string Encode(Line component, int index) + => $"index:{index}, value: {component.Text}"; + } + + private struct Line : IEquatable + { + public Line() + { + } + + public string Text { get; set; } = string.Empty; - public override string Encode(string component, int index) - => $"index:{index}, value: {component}"; + public bool Equals(Line other) + { + return Text == other.Text; + } } } diff --git a/LrcParser/Parser/Kar/Metadata/KarLyric.cs b/LrcParser/Parser/Kar/Metadata/KarLyric.cs index 36a96f4..0142a0e 100644 --- a/LrcParser/Parser/Kar/Metadata/KarLyric.cs +++ b/LrcParser/Parser/Kar/Metadata/KarLyric.cs @@ -5,8 +5,12 @@ namespace LrcParser.Parser.Kar.Metadata; -public class KarLyric +public struct KarLyric : IEquatable { + public KarLyric() + { + } + /// /// Text /// @@ -16,4 +20,9 @@ public class KarLyric /// Time tags /// public SortedDictionary TimeTags { get; set; } = new(); + + public bool Equals(KarLyric other) + { + return Text == other.Text && TimeTags.SequenceEqual(other.TimeTags); + } } diff --git a/LrcParser/Parser/Kar/Metadata/KarRuby.cs b/LrcParser/Parser/Kar/Metadata/KarRuby.cs index 591e2b9..3a9f962 100644 --- a/LrcParser/Parser/Kar/Metadata/KarRuby.cs +++ b/LrcParser/Parser/Kar/Metadata/KarRuby.cs @@ -13,8 +13,12 @@ namespace LrcParser.Parser.Kar.Metadata; /// @Ruby25=時,じか,,[00:38:45] /// @Ruby49=時,とき,[00:38:45],[01:04:49] /// -public class KarRuby +public struct KarRuby : IEquatable { + public KarRuby() + { + } + /// /// Parent kanji /// @@ -33,10 +37,19 @@ public class KarRuby /// /// Start position /// - public int? StartTime { get; set; } + public int? StartTime { get; set; } = null; /// /// End position /// - public int? EndTime { get; set; } + public int? EndTime { get; set; } = null; + + public bool Equals(KarRuby other) + { + return Parent == other.Parent + && Ruby == other.Ruby + && TimeTags.SequenceEqual(other.TimeTags) + && StartTime == other.StartTime + && EndTime == other.EndTime; + } } diff --git a/LrcParser/Parser/Lines/SingleLineParser.cs b/LrcParser/Parser/Lines/SingleLineParser.cs index 82fd333..f8f8718 100644 --- a/LrcParser/Parser/Lines/SingleLineParser.cs +++ b/LrcParser/Parser/Lines/SingleLineParser.cs @@ -7,7 +7,7 @@ namespace LrcParser.Parser.Lines; /// Base component pass string /// /// Encode and decode object type -public abstract class SingleLineParser : ISingleLineParser where T : class +public abstract class SingleLineParser : ISingleLineParser where T : struct, IEquatable { public abstract bool CanDecode(string text); diff --git a/LrcParser/Parser/Lrc/Metadata/LrcLyric.cs b/LrcParser/Parser/Lrc/Metadata/LrcLyric.cs index 6d4e07b..3d12e20 100644 --- a/LrcParser/Parser/Lrc/Metadata/LrcLyric.cs +++ b/LrcParser/Parser/Lrc/Metadata/LrcLyric.cs @@ -5,8 +5,12 @@ namespace LrcParser.Parser.Lrc.Metadata; -public class LrcLyric +public struct LrcLyric : IEquatable { + public LrcLyric() + { + } + /// /// Text /// @@ -16,4 +20,9 @@ public class LrcLyric /// Time tags /// public SortedDictionary TimeTags { get; set; } = new(); + + public bool Equals(LrcLyric other) + { + return Text == other.Text && TimeTags.SequenceEqual(other.TimeTags); + } }