diff --git a/src/SmartFormat.Tests/Core/Output/CustomOutputTests.cs b/src/SmartFormat.Tests/Core/Output/CustomOutputTests.cs new file mode 100644 index 00000000..36c406f8 --- /dev/null +++ b/src/SmartFormat.Tests/Core/Output/CustomOutputTests.cs @@ -0,0 +1,53 @@ +using System; +using System.Globalization; +using System.Text; +using NUnit.Framework; +using SmartFormat.Core.Extensions; +using SmartFormat.Core.Formatting; +using SmartFormat.Core.Output; +using SmartFormat.ZString; + +namespace SmartFormat.Tests.Core.Output; + +internal class CustomOutput : IOutput +{ + private readonly StringBuilder _sb = new(1000); + private const string OutputFormat = "Format: {0}, Selector {1}, Formatted: {2}"; + + public override string ToString() + { + return _sb.ToString(); + } + + public void Write(string text, IFormattingInfo? formattingInfo = null) + { + Write(text.AsSpan(), formattingInfo); + } + + public void Write(ReadOnlySpan text, IFormattingInfo? formattingInfo = null) + { + var fi = (FormattingInfo) formattingInfo!; + _sb.AppendFormat(OutputFormat, fi.Format, fi.Selector, text.ToString()); + } + + public void Write(ZStringBuilder stringBuilder, IFormattingInfo? formattingInfo = null) + { + Write(stringBuilder.AsSpan(), formattingInfo); + } +} + +[TestFixture] +internal class CustomOutputTests +{ + [Test] + public void CustomOutput_GetsValid_FormattingInfo_Argument() + { + // This test ensures that the IOutput.Write method overloads + // get a valid IFormattingInfo argument. + var smart = Smart.CreateDefaultSmartFormat(); + var output = new CustomOutput(); + smart.FormatInto(output, CultureInfo.InvariantCulture, "{0:0.0000}", [9m]); + Assert.That(output.ToString(), + Is.EqualTo("Format: 0.0000, Selector 0, Formatted: 9.0000")); + } +} diff --git a/src/SmartFormat.Tests/Core/Output/StringOutputTests.cs b/src/SmartFormat.Tests/Core/Output/StringOutputTests.cs index baa15719..7a2c7bdc 100644 --- a/src/SmartFormat.Tests/Core/Output/StringOutputTests.cs +++ b/src/SmartFormat.Tests/Core/Output/StringOutputTests.cs @@ -12,7 +12,7 @@ public class StringOutputTests public void Output_Of_Span() { var so = new StringOutput(); - so.Write("text".AsSpan(), null!); + so.Write("text".AsSpan(), null); Assert.That(so.ToString(), Is.EqualTo("text")); } @@ -20,7 +20,7 @@ public void Output_Of_Span() public void Output_Of_String() { var so = new StringOutput(16); - so.Write("text", null!); + so.Write("text", null); Assert.That(so.ToString(), Is.EqualTo("text")); } @@ -30,7 +30,7 @@ public void Output_Of_ValueStringBuilder() var so = new StringOutput(); using var sb = ZStringBuilderUtilities.CreateZStringBuilder(); sb.Append("text"); - so.Write(sb, null!); + so.Write(sb, null); Assert.That(so.ToString(), Is.EqualTo("text")); } } diff --git a/src/SmartFormat/Core/Formatting/FormattingInfo.cs b/src/SmartFormat/Core/Formatting/FormattingInfo.cs index 4eafd42a..ae22a4d1 100644 --- a/src/SmartFormat/Core/Formatting/FormattingInfo.cs +++ b/src/SmartFormat/Core/Formatting/FormattingInfo.cs @@ -173,7 +173,7 @@ public void Write(ReadOnlySpan text) { if (Alignment == 0) { - FormatDetails.Output.Write(text); + FormatDetails.Output.Write(text, this); FormatDetails.Formatter.Evaluator.OnOutputWritten?.Invoke(this, new Evaluator.OutputWrittenEventArgs(text.ToString())); return; @@ -199,7 +199,7 @@ public void Write(ReadOnlySpan text) } // Write the aligned text to the output - FormatDetails.Output.Write(buffer.GetSpan()); + FormatDetails.Output.Write(buffer.GetSpan(), this); FormatDetails.Formatter.Evaluator.OnOutputWritten?.Invoke(this, new Evaluator.OutputWrittenEventArgs(buffer.ToString())); diff --git a/src/SmartFormat/Core/Output/IOutput.cs b/src/SmartFormat/Core/Output/IOutput.cs index 3766a150..bfdff630 100644 --- a/src/SmartFormat/Core/Output/IOutput.cs +++ b/src/SmartFormat/Core/Output/IOutput.cs @@ -16,8 +16,13 @@ public interface IOutput /// /// Writes a string to the output. /// + /// + /// Only implement a call to + /// using for ''. + /// /// /// + [Obsolete("Use Write(ReadOnlySpan text, IFormattingInfo? formattingInfo = null) instead.", false)] void Write(string text, IFormattingInfo? formattingInfo = null); /// @@ -25,12 +30,18 @@ public interface IOutput /// /// /// + // v4: Remove formattingInfo argument? Or make it non-optional and non-nullable? void Write(ReadOnlySpan text, IFormattingInfo? formattingInfo = null); /// /// Writes text of a to the output. /// + /// + /// Only implement a call to + /// using for ''. + /// /// /// + [Obsolete("Use Write(ReadOnlySpan text, IFormattingInfo? formattingInfo = null) instead.", false)] void Write(ZStringBuilder stringBuilder, IFormattingInfo? formattingInfo = null); -} \ No newline at end of file +} diff --git a/src/SmartFormat/Core/Output/StringOutput.cs b/src/SmartFormat/Core/Output/StringOutput.cs index 9f5371c2..0b9ebd78 100644 --- a/src/SmartFormat/Core/Output/StringOutput.cs +++ b/src/SmartFormat/Core/Output/StringOutput.cs @@ -57,7 +57,7 @@ public StringOutput(StringBuilder output) /// This parameter from will not be used here. public void Write(string text, IFormattingInfo? formattingInfo = null) { - Output.Append(text); + Write(text.AsSpan(), formattingInfo); } /// @@ -77,11 +77,7 @@ public void Write(ReadOnlySpan text, IFormattingInfo? formattingInfo = nul /// public void Write(ZStringBuilder stringBuilder, IFormattingInfo? formattingInfo = null) { -#if NETSTANDARD2_1 || NET6_0_OR_GREATER - Output.Append(stringBuilder.AsSpan()); -#else - Output.Append(stringBuilder); -#endif + Write(stringBuilder.AsSpan(), formattingInfo); } /// diff --git a/src/SmartFormat/Core/Output/TextWriterOutput.cs b/src/SmartFormat/Core/Output/TextWriterOutput.cs index 582dbbae..d51bb7b6 100644 --- a/src/SmartFormat/Core/Output/TextWriterOutput.cs +++ b/src/SmartFormat/Core/Output/TextWriterOutput.cs @@ -31,7 +31,7 @@ public TextWriterOutput(TextWriter output) /// public void Write(string text, IFormattingInfo? formattingInfo = null) { - Output.Write(text); + Write(text.AsSpan(), formattingInfo); } /// @@ -47,10 +47,6 @@ public void Write(ReadOnlySpan text, IFormattingInfo? formattingInfo = nul /// public void Write(ZStringBuilder stringBuilder, IFormattingInfo? formattingInfo = null) { -#if NETSTANDARD2_1 || NET6_0_OR_GREATER - Output.Write(stringBuilder.AsSpan()); -#else - Output.Write(stringBuilder.ToString()); -#endif + Write(stringBuilder.AsSpan(), formattingInfo); } } diff --git a/src/SmartFormat/Core/Output/ZStringOutput.cs b/src/SmartFormat/Core/Output/ZStringOutput.cs index ffecf586..48d57180 100644 --- a/src/SmartFormat/Core/Output/ZStringOutput.cs +++ b/src/SmartFormat/Core/Output/ZStringOutput.cs @@ -60,7 +60,7 @@ public ZStringOutput(ZStringBuilder stringBuilder) /// public void Write(string text, IFormattingInfo? formattingInfo = null) { - Output.Append(text); + Write(text.AsSpan(), formattingInfo); } /// @@ -72,7 +72,7 @@ public void Write(ReadOnlySpan text, IFormattingInfo? formattingInfo = nul /// public void Write(ZStringBuilder stringBuilder, IFormattingInfo? formattingInfo = null) { - Output.Append(stringBuilder); + Write(stringBuilder.AsSpan(), formattingInfo); } ///