Created
January 3, 2023 20:19
-
-
Save nikanos/b6db3f3d133eda2e741815d1174504f4 to your computer and use it in GitHub Desktop.
C# string SafeFormat method - used as a wrapper to string.Format() and passing Undefined to any missing arguments
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Text.RegularExpressions; | |
public class StringUtils | |
{ | |
public static string SafeFormat(string format, params object[] parameters) | |
{ | |
const int MAX_NUMBER_OF_UNPASSED_PARAMETERS = 50; | |
const string UNDEFINED_PARAMETER_VALUE = "Undefined"; | |
List<object> parametersList = new List<object>(parameters); | |
List<int> parameterIndexes = new List<int>(); | |
// Use negative look behind to skip double { | |
// Capture the indexes digits after { in groups named "ParameterIndex" | |
const string RE_PATTERN = @"(?<!{){(?<ParameterIndex>\d+)"; | |
Regex re = new Regex(RE_PATTERN); | |
MatchCollection matches = re.Matches(format); | |
foreach (Match match in matches) | |
parameterIndexes.Add(Convert.ToInt32(match.Groups["ParameterIndex"].Value)); | |
if (parameterIndexes.Any()) | |
{ | |
int maxIndex = parameterIndexes.Max(); | |
if (maxIndex >= parametersList.Count) | |
{ | |
int parametersToAdd = (maxIndex - parametersList.Count) + 1; | |
if (parametersToAdd > MAX_NUMBER_OF_UNPASSED_PARAMETERS) | |
throw new FormatException($"Invalid format {format}.It would require {parametersToAdd} more arguments to pass"); | |
parametersList.AddRange(Enumerable.Repeat(UNDEFINED_PARAMETER_VALUE, parametersToAdd)); | |
} | |
} | |
return string.Format(format, parametersList.ToArray()); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.VisualStudio.TestTools.UnitTesting; | |
using System; | |
[TestClass] | |
public class StringUtilsTests | |
{ | |
[TestMethod] | |
public void StringUtilsSafeFormat_FormatWithoutPlaceholders_Succeeds() | |
{ | |
string template = "num"; | |
string result = StringUtils.SafeFormat(template); | |
Assert.IsNotNull(result); | |
Assert.AreEqual("num", result); | |
} | |
[TestMethod] | |
public void StringUtilsSafeFormat_WithCorrectNumberOfArguments_Succeeds() | |
{ | |
string template = "num {0}"; | |
string result = StringUtils.SafeFormat(template, 1); | |
Assert.IsNotNull(result); | |
Assert.AreEqual("num 1", result); | |
} | |
[TestMethod] | |
public void StringUtilsSafeFormat_WithCorrectNumberOfArgumentsAndHexFormatting_Succeeds() | |
{ | |
string template = "num {0:X}"; | |
string result = StringUtils.SafeFormat(template, 255); | |
Assert.IsNotNull(result); | |
Assert.AreEqual("num FF", result); | |
} | |
[TestMethod] | |
public void StringUtilsSafeFormat_WithFewerNumberOfArguments_SucceedsAndFillsMissingArguments() | |
{ | |
string template = "num {0}"; | |
string result = StringUtils.SafeFormat(template); | |
Assert.IsNotNull(result); | |
Assert.AreEqual("num Undefined", result); | |
} | |
[TestMethod] | |
[ExpectedException(typeof(FormatException))] | |
public void StringUtilsSafeFormat_WithTemplateThatWouldRequireManyArgumentsToBeAdded_Throws() | |
{ | |
string template = "num {100}"; | |
string result = StringUtils.SafeFormat(template); | |
} | |
[TestMethod] | |
public void StringUtilsSafeFormat_WithTemplateThatHasDoubleSquareBrackets_SucceedsAndDoesNoReplacement() | |
{ | |
string template = "num {{1}}"; | |
string result = StringUtils.SafeFormat(template); | |
Assert.IsNotNull(result); | |
Assert.AreEqual("num {1}", result); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment