From 22668016a977192cc42e0a9348c2df5941ea825d Mon Sep 17 00:00:00 2001 From: andy840119 Date: Fri, 21 Jul 2023 00:24:29 +0800 Subject: [PATCH 1/3] Re-write the helper for more flexibility. --- .../Helper/TestCaseTagHelper.cs | 233 +++++++++++------- 1 file changed, 140 insertions(+), 93 deletions(-) diff --git a/osu.Game.Rulesets.Karaoke.Tests/Helper/TestCaseTagHelper.cs b/osu.Game.Rulesets.Karaoke.Tests/Helper/TestCaseTagHelper.cs index 5f67d8080..ec29dea40 100644 --- a/osu.Game.Rulesets.Karaoke.Tests/Helper/TestCaseTagHelper.cs +++ b/osu.Game.Rulesets.Karaoke.Tests/Helper/TestCaseTagHelper.cs @@ -1,6 +1,7 @@ // Copyright (c) andy840119 . Licensed under the GPL Licence. // See the LICENCE file in the repository root for full licence text. +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -18,157 +19,203 @@ namespace osu.Game.Rulesets.Karaoke.Tests.Helper; public static class TestCaseTagHelper { + private const string char_index_range_str = @"\[(?[-0-9]+)(?:,(?[-0-9]+))?\]"; + private const string time_index_regex = @"\[(?[-0-9]+),(?start|end)]"; + private const string time_range_str = @"\[(?[-0-9]+)(?:,(?[-0-9]+))?\]"; + private const string id_str = "(?[-0-9]+)]"; + + private static string getStringPropertyRegex(char prefix, string propertyName) + => @$"(?:{prefix}(?<{propertyName}>[^\s]+))?"; + + private static string getNumberPropertyRegex(char prefix, string propertyName) + => $"(?:{prefix}(?<{propertyName}>[-0-9]+|s*|))?"; + + private static string generateRegex(string regexPrefix, IEnumerable regexProperties) + => regexPrefix + string.Join("", regexProperties); + + private static TObject getMatchByStatement(string? str, string regexStr, Func returnValue) + { + if (string.IsNullOrEmpty(str)) + return returnValue(null); + + var regex = new Regex(regexStr); + var result = regex.Match(str); + if (!result.Success) + throw new RegexMatchTimeoutException(nameof(str)); + + return returnValue(result); + } + /// /// Process test case ruby string format into /// /// - /// [0]:ruby - /// [0,3]:ruby + /// [0]:ruby -> has range index with text.
+ /// [0,3]:ruby -> has range index with text.
+ /// [0]: -> has range index with empty text.
+ /// [0,3]: -> has range index with empty text.
+ /// [0] -> has range index with empty text.
+ /// [0,3] -> has range index with empty text.
///
/// Ruby tag string format /// Ruby tag object public static RubyTag ParseRubyTag(string? str) { - if (string.IsNullOrEmpty(str)) - return new RubyTag(); - - var regex = new Regex("\\[(?[-0-9]+)(?:,(?[-0-9]+))?\\]:(?.*$)"); - var result = regex.Match(str); - if (!result.Success) - throw new RegexMatchTimeoutException(nameof(str)); + string regex = generateRegex(char_index_range_str, new[] + { + getStringPropertyRegex(':', "ruby"), + }); - string startValue = result.Groups["start"].Value; - string endValue = result.Groups["end"].Value; + return getMatchByStatement(str, regex, result => + { + if (result == null) + return new RubyTag(); - int startIndex = int.Parse(startValue); - int endIndex = int.Parse(string.IsNullOrEmpty(endValue) ? startValue : endValue); - string text = result.Groups["ruby"].Value; + int startIndex = result.GetGroupValue("start"); + int? endIndex = result.GetGroupValue("end"); + string text = result.GetGroupValue("ruby"); - return new RubyTag - { - StartIndex = startIndex, - EndIndex = endIndex, - Text = text, - }; + return new RubyTag + { + StartIndex = startIndex, + EndIndex = endIndex ?? startIndex, + Text = text, + }; + }); } /// /// Process test case romaji string format into /// /// - /// [0]:romaji - /// [0,3]:romaji + /// [0]:romaji -> has range index with text.
+ /// [0,3]:romaji -> has range index with text.
+ /// [0]: -> has range index with empty text.
+ /// [0,3]: -> has range index with empty text.
+ /// [0] -> has range index with empty text.
+ /// [0,3] -> has range index with empty text.
///
/// Romaji tag string format /// Romaji tag object public static RomajiTag ParseRomajiTag(string? str) { - if (string.IsNullOrEmpty(str)) - return new RomajiTag(); - - var regex = new Regex("\\[(?[-0-9]+)(?:,(?[-0-9]+))?\\]:(?.*$)"); - var result = regex.Match(str); - if (!result.Success) - throw new RegexMatchTimeoutException(nameof(str)); + string regex = generateRegex(char_index_range_str, new[] + { + getStringPropertyRegex(':', "romaji"), + }); - string startValue = result.Groups["start"].Value; - string endValue = result.Groups["end"].Value; + return getMatchByStatement(str, regex, result => + { + if (result == null) + return new RomajiTag(); - int startIndex = int.Parse(startValue); - int endIndex = int.Parse(string.IsNullOrEmpty(endValue) ? startValue : endValue); - string text = result.Groups["romaji"].Value; + int startIndex = result.GetGroupValue("start"); + int? endIndex = result.GetGroupValue("end"); + string text = result.GetGroupValue("romaji"); - return new RomajiTag - { - StartIndex = startIndex, - EndIndex = endIndex, - Text = text, - }; + return new RomajiTag + { + StartIndex = startIndex, + EndIndex = endIndex ?? startIndex, + Text = text, + }; + }); } /// /// Process test case time tag string format into /// /// - /// [0,start]:1000 + /// [0,start]:1000 -> has time-tag index with time.
+ /// [0,start] -> has time-tag index with no time.
+ /// [0,start]: -> has time-tag index with no time.
///
/// Time tag string format /// Time tag object public static TimeTag ParseTimeTag(string? str) { - if (string.IsNullOrEmpty(str)) - return new TimeTag(new TextIndex()); + string regex = generateRegex(time_index_regex, new[] + { + getNumberPropertyRegex(':', "time"), + }); - var regex = new Regex("(?[-0-9]+),(?start|end)]:(?