/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/Core/CodeAnalysisTest/EmbeddedTextTests.cs
305 строк
14 KB
Tomáš Matoušek
Add ChecksumAlgorithm to project snapshot (#62840)
10 окт 2022, 20:50
Не верифицирован
10 окт 2022, 20:50
157d34a
Код
Авторство
О чём код?
// 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.Collections.Generic; using System.IO; using Microsoft.CodeAnalysis.Text; using Roslyn.Utilities; using Xunit; using System.Text; using System.IO.Compression; using Roslyn.Test.Utilities; using System.Linq; namespace Microsoft.CodeAnalysis.UnitTests { public class EmbeddedTextTests { [Fact] public void FromBytes_ArgumentErrors() { Assert.Throws<ArgumentNullException>("filePath", () => EmbeddedText.FromBytes(null, default(ArraySegment<byte>))); Assert.Throws<ArgumentException>("filePath", () => EmbeddedText.FromBytes("", default(ArraySegment<byte>))); Assert.Throws<ArgumentNullException>("bytes", () => EmbeddedText.FromBytes("path", default(ArraySegment<byte>))); Assert.Throws<ArgumentException>("checksumAlgorithm", () => EmbeddedText.FromBytes("path", new ArraySegment<byte>(new byte[0], 0, 0), SourceHashAlgorithm.None)); } [Fact] public void FromSource_ArgumentErrors() { Assert.Throws<ArgumentNullException>("filePath", () => EmbeddedText.FromSource(null, null)); Assert.Throws<ArgumentException>("filePath", () => EmbeddedText.FromSource("", null)); Assert.Throws<ArgumentNullException>("text", () => EmbeddedText.FromSource("path", null)); // no encoding Assert.Throws<ArgumentException>("text", () => EmbeddedText.FromSource("path", SourceText.From("source"))); // embedding not allowed Assert.Throws<ArgumentException>("text", () => EmbeddedText.FromSource("path", SourceText.From(new byte[0], 0, Encoding.UTF8, canBeEmbedded: false))); Assert.Throws<ArgumentException>("text", () => EmbeddedText.FromSource("path", SourceText.From(new MemoryStream(new byte[0]), Encoding.UTF8, canBeEmbedded: false))); } [Fact] public void FromStream_ArgumentErrors() { Assert.Throws<ArgumentNullException>("filePath", () => EmbeddedText.FromStream(null, null)); Assert.Throws<ArgumentException>("filePath", () => EmbeddedText.FromStream("", null)); Assert.Throws<ArgumentNullException>("stream", () => EmbeddedText.FromStream("path", null)); Assert.Throws<ArgumentException>("stream", () => EmbeddedText.FromStream("path", new CannotReadStream())); Assert.Throws<ArgumentException>("stream", () => EmbeddedText.FromStream("path", new CannotSeekStream())); Assert.Throws<ArgumentException>("checksumAlgorithm", () => EmbeddedText.FromStream("path", new MemoryStream(), SourceHashAlgorithm.None)); } [Fact] public void FromStream_IOErrors() { Assert.Throws<IOException>(() => EmbeddedText.FromStream("path", new HugeStream())); Assert.Throws<EndOfStreamException>(() => EmbeddedText.FromStream("path", new TruncatingStream(10))); Assert.Throws<EndOfStreamException>(() => EmbeddedText.FromStream("path", new TruncatingStream(1000))); Assert.Throws<IOException>(() => EmbeddedText.FromStream("path", new ReadFailsStream())); } private const string SmallSource = @"class P {}"; private const string LargeSource = @" ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// class Program { static void Main() {} } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// "; [Fact] public void FromBytes_Empty() { var text = EmbeddedText.FromBytes("pathToEmpty", new ArraySegment<byte>(new byte[0], 0, 0), SourceHashAlgorithm.Sha1); Assert.Equal("pathToEmpty", text.FilePath); Assert.Equal(SourceHashAlgorithm.Sha1, text.ChecksumAlgorithm); AssertEx.Equal(SourceText.CalculateChecksum(new byte[0], 0, 0, SourceHashAlgorithm.Sha1), text.Checksum); AssertEx.Equal(new byte[] { 0, 0, 0, 0 }, text.Blob); } [Fact] public void FromStream_Empty() { var text = EmbeddedText.FromStream("pathToEmpty", new MemoryStream(new byte[0]), SourceHashAlgorithm.Sha1); var checksum = SourceText.CalculateChecksum(new byte[0], 0, 0, SourceHashAlgorithm.Sha1); Assert.Equal("pathToEmpty", text.FilePath); Assert.Equal(SourceHashAlgorithm.Sha1, text.ChecksumAlgorithm); AssertEx.Equal(checksum, text.Checksum); AssertEx.Equal(new byte[] { 0, 0, 0, 0 }, text.Blob); } [Fact] public void FromSource_Empty() { var source = SourceText.From("", new UTF8Encoding(encoderShouldEmitUTF8Identifier: false), SourceHashAlgorithm.Sha1); var text = EmbeddedText.FromSource("pathToEmpty", source); var checksum = SourceText.CalculateChecksum(new byte[0], 0, 0, SourceHashAlgorithm.Sha1); Assert.Equal("pathToEmpty", text.FilePath); Assert.Equal(SourceHashAlgorithm.Sha1, text.ChecksumAlgorithm); AssertEx.Equal(checksum, text.Checksum); AssertEx.Equal(new byte[] { 0, 0, 0, 0 }, text.Blob); } [Fact] public void FromBytes_Small() { var bytes = Encoding.UTF8.GetBytes(SmallSource); var checksum = SourceText.CalculateChecksum(bytes, 0, bytes.Length, SourceHashAlgorithm.Sha1); var text = EmbeddedText.FromBytes("pathToSmall", new ArraySegment<byte>(bytes, 0, bytes.Length)); Assert.Equal("pathToSmall", text.FilePath); Assert.Equal(SourceHashAlgorithm.Sha1, text.ChecksumAlgorithm); AssertEx.Equal(checksum, text.Checksum); AssertEx.Equal(new byte[] { 0, 0, 0, 0 }, text.Blob.Take(4)); AssertEx.Equal(bytes, text.Blob.Skip(4)); } [Fact] public void FromBytes_SmallSpan() { var bytes = Encoding.UTF8.GetBytes(SmallSource); var paddedBytes = new byte[] { 0 }.Concat(bytes).Concat(new byte[] { 0 }).ToArray(); var checksum = SourceText.CalculateChecksum(bytes, 0, bytes.Length, SourceHashAlgorithm.Sha1); var text = EmbeddedText.FromBytes("pathToSmall", new ArraySegment<byte>(paddedBytes, 1, bytes.Length)); Assert.Equal("pathToSmall", text.FilePath); AssertEx.Equal(checksum, text.Checksum); Assert.Equal(SourceHashAlgorithm.Sha1, text.ChecksumAlgorithm); AssertEx.Equal(new byte[] { 0, 0, 0, 0 }, text.Blob.Take(4)); AssertEx.Equal(bytes, text.Blob.Skip(4)); } [Fact] public void FromSource_Small() { var source = SourceText.From(SmallSource, Encoding.UTF8, SourceHashAlgorithm.Sha1); var text = EmbeddedText.FromSource("pathToSmall", source); Assert.Equal("pathToSmall", text.FilePath); Assert.Equal(SourceHashAlgorithm.Sha1, text.ChecksumAlgorithm); AssertEx.Equal(source.GetChecksum(), text.Checksum); AssertEx.Equal(new byte[] { 0, 0, 0, 0 }, text.Blob.Take(4)); AssertEx.Equal(Encoding.UTF8.GetPreamble().Concat(Encoding.UTF8.GetBytes(SmallSource)), text.Blob.Skip(4)); } [Fact] public void FromBytes_Large() { var bytes = Encoding.Unicode.GetBytes(LargeSource); var checksum = SourceText.CalculateChecksum(bytes, 0, bytes.Length, SourceHashAlgorithms.Default); var text = EmbeddedText.FromBytes("pathToLarge", new ArraySegment<byte>(bytes, 0, bytes.Length), SourceHashAlgorithms.Default); Assert.Equal("pathToLarge", text.FilePath); Assert.Equal(SourceHashAlgorithms.Default, text.ChecksumAlgorithm); AssertEx.Equal(checksum, text.Checksum); AssertEx.Equal(BitConverter.GetBytes(bytes.Length), text.Blob.Take(4)); AssertEx.Equal(bytes, Decompress(text.Blob.Skip(4))); } [Fact] public void FromBytes_LargeSpan() { var bytes = Encoding.Unicode.GetBytes(LargeSource); var paddedBytes = new byte[] { 0 }.Concat(bytes).Concat(new byte[] { 0 }).ToArray(); var checksum = SourceText.CalculateChecksum(bytes, 0, bytes.Length, SourceHashAlgorithms.Default); var text = EmbeddedText.FromBytes("pathToLarge", new ArraySegment<byte>(paddedBytes, 1, bytes.Length), SourceHashAlgorithms.Default); Assert.Equal("pathToLarge", text.FilePath); AssertEx.Equal(checksum, text.Checksum); Assert.Equal(SourceHashAlgorithms.Default, text.ChecksumAlgorithm); AssertEx.Equal(BitConverter.GetBytes(bytes.Length), text.Blob.Take(4)); AssertEx.Equal(bytes, Decompress(text.Blob.Skip(4))); } [Fact] public void FromSource_Large() { var source = SourceText.From(LargeSource, Encoding.Unicode, SourceHashAlgorithms.Default); var text = EmbeddedText.FromSource("pathToLarge", source); Assert.Equal("pathToLarge", text.FilePath); Assert.Equal(SourceHashAlgorithms.Default, text.ChecksumAlgorithm); AssertEx.Equal(source.GetChecksum(), text.Checksum); AssertEx.Equal(BitConverter.GetBytes(Encoding.Unicode.GetPreamble().Length + LargeSource.Length * sizeof(char)), text.Blob.Take(4)); AssertEx.Equal(Encoding.Unicode.GetPreamble().Concat(Encoding.Unicode.GetBytes(LargeSource)), Decompress(text.Blob.Skip(4))); } [Fact] public void FromTextReader_Small() { var expected = SourceText.From(SmallSource, Encoding.UTF8, SourceHashAlgorithm.Sha1); var expectedEmbedded = EmbeddedText.FromSource("pathToSmall", expected); var actual = SourceText.From(new StringReader(SmallSource), SmallSource.Length, Encoding.UTF8, SourceHashAlgorithm.Sha1); var actualEmbedded = EmbeddedText.FromSource(expectedEmbedded.FilePath, actual); Assert.Equal(expectedEmbedded.FilePath, actualEmbedded.FilePath); Assert.Equal(expectedEmbedded.ChecksumAlgorithm, actualEmbedded.ChecksumAlgorithm); AssertEx.Equal(expectedEmbedded.Checksum, actualEmbedded.Checksum); AssertEx.Equal(expectedEmbedded.Blob, actualEmbedded.Blob); } [Fact] public void FromTextReader_Large() { var expected = SourceText.From(LargeSource, Encoding.UTF8, SourceHashAlgorithm.Sha1); var expectedEmbedded = EmbeddedText.FromSource("pathToSmall", expected); var actual = SourceText.From(new StringReader(LargeSource), LargeSource.Length, Encoding.UTF8, SourceHashAlgorithm.Sha1); var actualEmbedded = EmbeddedText.FromSource(expectedEmbedded.FilePath, actual); Assert.Equal(expectedEmbedded.FilePath, actualEmbedded.FilePath); Assert.Equal(expectedEmbedded.ChecksumAlgorithm, actualEmbedded.ChecksumAlgorithm); AssertEx.Equal(expectedEmbedded.Checksum, actualEmbedded.Checksum); AssertEx.Equal(expectedEmbedded.Blob, actualEmbedded.Blob); } [Fact] public void FromSource_Precomputed() { byte[] bytes = Encoding.ASCII.GetBytes(LargeSource); bytes[0] = 0xFF; // invalid ASCII, should be reflected in checksum, blob. foreach (bool useStream in new[] { true, false }) { var source = useStream ? SourceText.From(new MemoryStream(bytes), Encoding.ASCII, SourceHashAlgorithm.Sha1, canBeEmbedded: true) : SourceText.From(bytes, bytes.Length, Encoding.ASCII, SourceHashAlgorithm.Sha1, canBeEmbedded: true); var text = EmbeddedText.FromSource("pathToPrecomputed", source); Assert.Equal("pathToPrecomputed", text.FilePath); Assert.Equal(SourceHashAlgorithm.Sha1, text.ChecksumAlgorithm); AssertEx.Equal(SourceText.CalculateChecksum(bytes, 0, bytes.Length, SourceHashAlgorithm.Sha1), source.GetChecksum()); AssertEx.Equal(source.GetChecksum(), text.Checksum); AssertEx.Equal(BitConverter.GetBytes(bytes.Length), text.Blob.Take(4)); AssertEx.Equal(bytes, Decompress(text.Blob.Skip(4))); } } [ConditionalFact(typeof(ClrOnly), Reason = "https://github.com/mono/mono/issues/12603")] public void FromBytes_EncodingFallbackCase() { var source = EncodedStringText.Create(new MemoryStream(new byte[] { 0xA9, 0x0D, 0x0A }), canBeEmbedded: true); var text = EmbeddedText.FromSource("pathToLarge", source); Assert.Equal("pathToLarge", text.FilePath); Assert.Equal(SourceHashAlgorithm.Sha1, text.ChecksumAlgorithm); AssertEx.Equal(source.GetChecksum(), text.Checksum); } private byte[] Decompress(IEnumerable<byte> bytes) { var destination = new MemoryStream(); using (var source = new DeflateStream(new MemoryStream(bytes.ToArray()), CompressionMode.Decompress)) { source.CopyTo(destination); } return destination.ToArray(); } private sealed class CannotReadStream : MemoryStream { public override bool CanRead => false; } private sealed class CannotSeekStream : MemoryStream { public override bool CanSeek => false; } private sealed class HugeStream : MemoryStream { public override long Length => (long)int.MaxValue + 1; } private sealed class TruncatingStream : MemoryStream { public TruncatingStream(long length) { Length = length; } public override long Length { get; } public override int Read(byte[] buffer, int offset, int count) => 0; } private sealed class ReadFailsStream : MemoryStream { public override int Read(byte[] buffer, int offset, int count) { throw new IOException(); } } } }