New ExpandTabs feature w/ tests
This commit is contained in:
Родитель
d7eb93f1eb
Коммит
d252809c8d
|
@ -136,5 +136,35 @@ namespace Unity.Core.Tests
|
|||
enumerable.StringJoin(Selector, " ** ").ShouldBe("String ** Int32 ** (null) ** ValueTuple`2");
|
||||
enumerable.StringJoin(Selector, '?').ShouldBe("String?Int32?(null)?ValueTuple`2");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExpandTabs_WithEmpty_Returns_Empty()
|
||||
{
|
||||
"".ExpandTabs(4).ShouldBeEmpty();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExpandTabs_WithNoTabs_Returns_IdenticalString() // i.e. no allocs
|
||||
{
|
||||
const string text = "abc def ghijkl";
|
||||
ReferenceEquals(text, text.ExpandTabs(4)).ShouldBeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExpandTabs_WithInvalidTabWidth_Throws()
|
||||
{
|
||||
Should.Throw<ArgumentException>(() => "".ExpandTabs(-123));
|
||||
Should.Throw<ArgumentException>(() => "abc".ExpandTabs(-1));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExpandTabs_BasicScenarios_ExpandsProperly()
|
||||
{
|
||||
"a\tbc\t\td".ExpandTabs(4).ShouldBe("a bc d");
|
||||
"a\tbc\t\td".ExpandTabs(3).ShouldBe("a bc d");
|
||||
"a\tbc\t\td".ExpandTabs(2).ShouldBe("a bc d");
|
||||
"a\tbc\t\td".ExpandTabs(1).ShouldBe("a bc d");
|
||||
"a\tbc\t\td".ExpandTabs(0).ShouldBe("abcd");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using JetBrains.Annotations;
|
||||
|
||||
namespace Unity.Core
|
||||
|
@ -60,5 +61,40 @@ namespace Unity.Core
|
|||
[NotNull]
|
||||
public static string StringJoin<T, TSelected>([NotNull] this IEnumerable<T> @this, [NotNull] Func<T, TSelected> selector, char separator)
|
||||
=> string.Join(new string(separator, 1), @this.Select(selector));
|
||||
|
||||
[NotNull]
|
||||
public static string ExpandTabs([NotNull] this string @this, int tabWidth, StringBuilder buffer = null)
|
||||
{
|
||||
if (tabWidth < 0)
|
||||
throw new ArgumentException("tabWidth must be >= 0", nameof(tabWidth));
|
||||
|
||||
var tabCount = @this.Count(c => c == '\t');
|
||||
|
||||
// early out if nothing to do
|
||||
if (tabCount == 0)
|
||||
return @this;
|
||||
|
||||
// more early-out and a bit silly scenarios, but why not..
|
||||
if (tabWidth == 0)
|
||||
return @this.Replace("\t", "");
|
||||
if (tabWidth == 1)
|
||||
return @this.Replace('\t', ' ');
|
||||
|
||||
var capacity = @this.Length + tabCount * (tabWidth - 1);
|
||||
if (buffer != null)
|
||||
buffer.EnsureCapacity(capacity);
|
||||
else
|
||||
buffer = new StringBuilder(capacity);
|
||||
|
||||
foreach (var c in @this)
|
||||
{
|
||||
if (c != '\t')
|
||||
buffer.Append(c);
|
||||
else
|
||||
buffer.Append(' ', tabWidth - buffer.Length % tabWidth);
|
||||
}
|
||||
|
||||
return buffer.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче