using System; using System.IO; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using Centron.Tests.EndToEnd.Infrastructure; using Xunit; using Xunit.Abstractions; namespace Centron.Tests.EndToEnd.Tests.FileEncoding { public class FileEncodingTest : CentronTest { public FileEncodingTest(ITestOutputHelper testOutputHelper) : base(testOutputHelper) { } [Fact] public void CSharpFilesHaveCorrectEncoding() { CheckFileEncoding("*.cs"); } [Fact] public void XamlFilesHaveCorrectEncoding() { CheckFileEncoding("*.xaml"); } private void CheckFileEncoding(string fileNamePattern, [CallerFilePath]string path = null) { var preamble = Encoding.UTF8.GetPreamble(); //UTF8 with BOM is our default encoding for all source-code files var slnDirectory = new FileInfo(path).Directory.Parent.Parent.Parent.Parent; var filesWithIncorrectEncoding = Directory.GetFiles(slnDirectory.FullName, fileNamePattern, SearchOption.AllDirectories) .Where(file => IsInBinOrObjDirectory(file) == false) .Where(file => FileStartsWith(file, preamble) == false) .ToList(); if (filesWithIncorrectEncoding.Any()) { string message = $"All our source-code files are supposed to have UTF8-BOM encoding, but there are some files that have a different encoding.{Environment.NewLine}" + $"Change the encoding in these files to UTF8-BOM by saving them again.{Environment.NewLine}{Environment.NewLine}" + $"The following files have an incorrect encoding:{Environment.NewLine}"; message += string.Join(Environment.NewLine, filesWithIncorrectEncoding); throw new Exception(message); } } private static readonly string BinDirectory = Path.DirectorySeparatorChar + "bin" + Path.DirectorySeparatorChar; private static readonly string ObjDirectory = Path.DirectorySeparatorChar + "obj" + Path.DirectorySeparatorChar; private bool IsInBinOrObjDirectory(string file) { return file.IndexOf(BinDirectory, StringComparison.InvariantCultureIgnoreCase) > 0 || file.IndexOf(ObjDirectory, StringComparison.InvariantCultureIgnoreCase) > 0; } private bool FileStartsWith(string filePath, byte[] preamble) { using (var stream = File.OpenRead(filePath)) { var bytesInFile = new byte[preamble.Length]; stream.ReadExactly(bytesInFile, 0, bytesInFile.Length); return preamble.SequenceEqual(bytesInFile); } } } }