|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#nullable disable
using System;
using System.Text;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.UnitTests
{
public sealed class StringTableTests
{
[Fact]
public void TestAddSameWithStringBuilderProducesSameStringInstance()
{
var st = new StringTable();
var sb1 = new StringBuilder("goo");
var sb2 = new StringBuilder("goo");
var s1 = st.Add(sb1);
var s2 = st.Add(sb2);
Assert.Same(s1, s2);
}
[Fact]
public void TestAddDifferentWithStringBuilderProducesDifferentStringInstance()
{
var st = new StringTable();
var sb1 = new StringBuilder("goo");
var sb2 = new StringBuilder("bar");
var s1 = st.Add(sb1);
var s2 = st.Add(sb2);
Assert.NotEqual((object)s1, (object)s2);
}
[Fact]
public void TestAddSameWithVariousInputsProducesSameStringInstance()
{
var st = new StringTable();
var s1 = st.Add(new StringBuilder(" "));
var s2 = st.Add(' ');
Assert.Same(s1, s2);
var s3 = st.Add(" ");
Assert.Same(s2, s3);
var s4 = st.Add(new char[1] { ' ' }, 0, 1);
Assert.Same(s3, s4);
var s5 = st.Add("ABC DEF", 3, 1);
Assert.Same(s4, s5);
}
[Fact]
public void TestAddSameWithCharProducesSameStringInstance()
{
var st = new StringTable();
var s1 = st.Add(' ');
var s2 = st.Add(' ');
Assert.Same(s1, s2);
}
[Fact]
public void TestSharedAddSameWithStringBuilderProducesSameStringInstance()
{
var sb1 = new StringBuilder("goo");
var sb2 = new StringBuilder("goo");
var s1 = new StringTable().Add(sb1);
var s2 = new StringTable().Add(sb2);
Assert.Same(s1, s2);
}
[Fact]
public void TestSharedAddSameWithCharProducesSameStringInstance()
{
// Regression test for a bug where single-char strings were not being
// found in the shared table.
var s1 = new StringTable().Add(' ');
var s2 = new StringTable().Add(' ');
Assert.Same(s1, s2);
}
private static unsafe bool TestTextEqualsASCII(string str, string ascii)
{
fixed (byte* ptr = Encoding.ASCII.GetBytes(ascii))
{
var ptrResult = StringTable.TextEqualsASCII(str, new ReadOnlySpan<byte>(ptr, ascii.Length));
var sbResult = StringTable.TextEquals(str, new StringBuilder(ascii));
var substrResult = StringTable.TextEquals(str, "xxx" + ascii + "yyy", 3, ascii.Length);
Assert.Equal(substrResult, sbResult);
Assert.Equal(ptrResult, sbResult);
return ptrResult;
}
}
[Fact]
public void TextEquals1()
{
Assert.True(TestTextEqualsASCII("", ""));
Assert.False(TestTextEqualsASCII("a", ""));
Assert.False(TestTextEqualsASCII("", "a"));
Assert.True(TestTextEqualsASCII("a", "a"));
Assert.False(TestTextEqualsASCII("a", "ab"));
Assert.False(TestTextEqualsASCII("ab", "a"));
Assert.False(TestTextEqualsASCII("abc", "a"));
Assert.False(TestTextEqualsASCII("abcd", "a"));
Assert.False(TestTextEqualsASCII("abcde", "a"));
Assert.False(TestTextEqualsASCII("abcdef", "a"));
Assert.False(TestTextEqualsASCII("abcdefg", "a"));
Assert.False(TestTextEqualsASCII("abcdefgh", "a"));
Assert.False(TestTextEqualsASCII("a", "ab"));
Assert.False(TestTextEqualsASCII("a", "abc"));
Assert.False(TestTextEqualsASCII("a", "abcd"));
Assert.False(TestTextEqualsASCII("a", "abcde"));
Assert.False(TestTextEqualsASCII("a", "abcdef"));
Assert.False(TestTextEqualsASCII("a", "abcdefg"));
Assert.False(TestTextEqualsASCII("a", "abcdefgh"));
Assert.False(TestTextEqualsASCII("\u1234", "a"));
Assert.False(TestTextEqualsASCII("\ud800", "xx"));
Assert.False(TestTextEqualsASCII("\uffff", ""));
}
[Fact]
public void TestAddEqualSubstringsFromDifferentStringsWorks()
{
// Make neither of the strings equal to the result of the substring call
// to test an issue that was surfaced by pooling the wrong string.
var str1 = "abcd1";
var str2 = "abcd2";
var st = new StringTable();
var s1 = st.Add(str1, 0, 4);
var s2 = st.Add(str2, 0, 4);
Assert.Same(s1, s2);
Assert.Equal("abcd", s1);
}
}
}
|