From 013e94c2809f96ea0150986c2b618b118078c6ff Mon Sep 17 00:00:00 2001 From: rameel Date: Fri, 9 May 2025 02:35:43 +0500 Subject: [PATCH] Add tests for StringBuffer --- .../Utilities/StringBuffer.cs | 16 +++- .../Utilities/StringBufferTests.cs | 91 +++++++++++++++++++ 2 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 tests/Ramstack.Parsing.Tests/Utilities/StringBufferTests.cs diff --git a/src/Ramstack.Parsing/Utilities/StringBuffer.cs b/src/Ramstack.Parsing/Utilities/StringBuffer.cs index 3d98310..6840c81 100644 --- a/src/Ramstack.Parsing/Utilities/StringBuffer.cs +++ b/src/Ramstack.Parsing/Utilities/StringBuffer.cs @@ -107,16 +107,24 @@ ref MemoryMarshal.GetArrayDataReference(chars), [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string ToString() { - return ToStringImpl(_chars, _count); + var chars = _chars; + var count = _count; + _chars = []; + _count = 0; + + return ToStringImpl(chars, count); [MethodImpl(MethodImplOptions.NoInlining)] static string ToStringImpl(char[] buffer, int length) { - var result = new string(buffer.AsSpan(0, length)); - if (buffer.Length != 0) + if (buffer.Length != 0 && (uint)length <= (uint)buffer.Length) + { + var result = new string(buffer.AsSpan(0, length)); ArrayPool.Shared.Return(buffer); + return result; + } - return result; + return ""; } } diff --git a/tests/Ramstack.Parsing.Tests/Utilities/StringBufferTests.cs b/tests/Ramstack.Parsing.Tests/Utilities/StringBufferTests.cs new file mode 100644 index 0000000..3328e01 --- /dev/null +++ b/tests/Ramstack.Parsing.Tests/Utilities/StringBufferTests.cs @@ -0,0 +1,91 @@ +namespace Ramstack.Parsing.Utilities; + +[TestFixture] +public class StringBufferTests +{ + [Test] + public void Ctor() + { + var sb = new StringBuffer(); + + Assert.That(sb.ToString(), Is.EqualTo("")); + Assert.That(sb.Length, Is.EqualTo(0)); + } + + [Test] + public void Ctor_Capacity() + { + var sb = new StringBuffer(10); + + Assert.That(sb.Length, Is.EqualTo(0)); + Assert.That(sb.ToString(), Is.EqualTo("")); + } + + [TestCase(-1)] + [TestCase(-10)] + [TestCase(int.MinValue)] + [TestCase(-int.MaxValue)] + public void Ctor_InvalidCapacity(int capacity) => + Assert.Throws(() => _ = new StringBuffer(capacity)); + + [Test] + public void Append_Char() + { + for (var count = 1; count <= 256; count++) + { + var sb = new StringBuffer(); + var expected = ""; + + for (var n = 1; n <= count; n++) + { + sb.Append('a'); + expected += 'a'; + + Assert.That(sb.Length, Is.EqualTo(n)); + } + + Assert.That(sb.ToString(), Is.EqualTo(expected)); + } + } + + [TestCase("")] + [TestCase("1")] + [TestCase("12")] + [TestCase("123456789")] + public void Append_ReadOnlySpan(string text) + { + var sb = new StringBuffer(); + sb.Append(text); + + Assert.That(sb.Length, Is.EqualTo(text.Length)); + Assert.That(sb.ToString(), Is.EqualTo(text)); + } + + [Test] + public void Append_LargeValue() + { + var a1 = new string('a', 50); + var a2 = new string('b', 1000); + + var sb = new StringBuffer(); + + sb.Append(a1); + Assert.That(sb.Length, Is.EqualTo(a1.Length)); + + sb.Append(a2); + Assert.That(sb.Length, Is.EqualTo(a1.Length + a2.Length)); + + Assert.That(sb.ToString(), Is.EqualTo(a1 + a2)); + } + + [Test] + public void FailOnLargeString() + { + Assert.Throws(() => + { + var sb = new StringBuffer(); + sb.Append(new char[2_000_000_000]); + sb.Append(new char[500_000_000]); + }); + } +}