diff --git a/src/Core/Conventional.Tests/Conventional/Conventions/Assemblies/AssemblyConventionSpecificationTests.cs b/src/Core/Conventional.Tests/Conventional/Conventions/Assemblies/AssemblyConventionSpecificationTests.cs index c0b1e66..633a3c3 100644 --- a/src/Core/Conventional.Tests/Conventional/Conventions/Assemblies/AssemblyConventionSpecificationTests.cs +++ b/src/Core/Conventional.Tests/Conventional/Conventions/Assemblies/AssemblyConventionSpecificationTests.cs @@ -1,7 +1,9 @@ using System; +using System.IO; using System.Linq; using System.Reflection; using System.Text.RegularExpressions; +using Conventional.Extensions; using FluentAssertions; using NUnit.Framework; @@ -15,7 +17,7 @@ public class AssemblyConventionSpecificationTests public void Setup() { _testAssembly = Assembly.LoadFrom(KnownPaths.SolutionRoot + - "TestSolution/TestSolution.TestProject/bin/Debug/TestSolution.TestProject.dll"); + $"TestSolution{Path.DirectorySeparatorChar}TestSolution.TestProject{Path.DirectorySeparatorChar}bin{Path.DirectorySeparatorChar}Debug{Path.DirectorySeparatorChar}TestSolution.TestProject.dll"); } [Test] @@ -51,6 +53,7 @@ public void MustHaveFilesWithACertainExtensionBeResources_Success_FileExtension( .BeTrue(); } + [Test] public void MustHaveFilesWithACertainExtensionBeResources_Success_RegEx() { var matchResxFiles = new Regex(@"\.RESX$", RegexOptions.IgnoreCase); @@ -65,36 +68,24 @@ public void MustHaveFilesWithACertainExtensionBeResources_Success_RegEx() [Test] public void MustHaveFilesWithACertainExtensionBeResources_FailsWhenFilesAreNotResources_Regex() { - var expectedFailureMessage = - @"All files matching '.\.txt' within assembly 'Conventional.Tests' must have their build action set to 'Embedded Resource'" - + Environment.NewLine - + @"- Conventional\Conventions\Assemblies\non_embedded_text_file_first.txt" - + Environment.NewLine - + @"- Conventional\Conventions\Assemblies\non_embedded_text_file_second.txt"; - var result = typeof(AssemblyConventionSpecificationTests).Assembly .MustConformTo(Convention.MustHaveFilesBeResources(new Regex(@".\.txt"))); result.IsSatisfied.Should().BeFalse(); - result.Failures.Single().Should().Be(expectedFailureMessage); + result.Failures.Single().Should().Contain("non_embedded_text_file_first.txt"); + result.Failures.Single().Should().Contain("non_embedded_text_file_second.txt"); } [Test] public void MustHaveFilesWithACertainExtensionBeResources_FailsWhenFilesAreNotResources_FileExtension() { - var expectedFailureMessage = - @"All files matching '*.txt' within assembly 'Conventional.Tests' must have their build action set to 'Embedded Resource'" - + Environment.NewLine - + @"- Conventional\Conventions\Assemblies\non_embedded_text_file_first.txt" - + Environment.NewLine - + @"- Conventional\Conventions\Assemblies\non_embedded_text_file_second.txt"; - var result = typeof(AssemblyConventionSpecificationTests).Assembly .MustConformTo(Convention.MustHaveFilesBeResources("*.txt")); result.IsSatisfied.Should().BeFalse(); - result.Failures.Single().Should().Be(expectedFailureMessage); + result.Failures.Single().Should().Contain("non_embedded_text_file_first.txt"); + result.Failures.Single().Should().Contain("non_embedded_text_file_second.txt"); } @@ -135,38 +126,26 @@ public void MustHaveFilesWithACertainExtensionBeEmbeddedResources_Success_RegEx( public void MustHaveFilesWithACertainExtensionBeEmbeddedResources_FailsWhenFilesAreNotEmbeddedResources_FileExtension() { - var expectedFailureMessage = - "All files matching '*.txt' within assembly 'Conventional.Tests' must have their build action set to 'Embedded Resource'" - + Environment.NewLine - + @"- Conventional\Conventions\Assemblies\non_embedded_text_file_first.txt" - + Environment.NewLine - + @"- Conventional\Conventions\Assemblies\non_embedded_text_file_second.txt"; - var result = typeof(AssemblyConventionSpecificationTests).Assembly .MustConformTo(Convention.MustHaveFilesBeEmbeddedResources("*.txt")); result.IsSatisfied.Should().BeFalse(); - result.Failures.Single().Should().Be(expectedFailureMessage); + result.Failures.Single().Should().Contain("non_embedded_text_file_first.txt"); + result.Failures.Single().Should().Contain("non_embedded_text_file_second.txt"); } [Test] public void MustHaveFilesWithACertainExtensionBeEmbeddedResources_FailsWhenFilesAreNotEmbeddedResources_RegEx() { - var expectedFailureMessage = - "All files matching '.*NON_EMBEDDED.*' within assembly 'Conventional.Tests' must have their build action set to 'Embedded Resource'" - + Environment.NewLine - + @"- Conventional\Conventions\Assemblies\non_embedded_text_file_first.txt" - + Environment.NewLine - + @"- Conventional\Conventions\Assemblies\non_embedded_text_file_second.txt"; - var matchNonEmbeddedRegEx = new Regex(".*NON_EMBEDDED.*", RegexOptions.IgnoreCase); var result = typeof(AssemblyConventionSpecificationTests).Assembly .MustConformTo(Convention.MustHaveFilesBeEmbeddedResources(matchNonEmbeddedRegEx)); result.IsSatisfied.Should().BeFalse(); - result.Failures.Single().Should().Be(expectedFailureMessage); + result.Failures.Single().Should().Contain("non_embedded_text_file_first.txt"); + result.Failures.Single().Should().Contain("non_embedded_text_file_second.txt"); } [Test] diff --git a/src/Core/Conventional.Tests/Conventional/Conventions/Assemblies/MatchingFilesConventionTests.cs b/src/Core/Conventional.Tests/Conventional/Conventions/Assemblies/MatchingFilesConventionTests.cs index 3434210..f0dcb35 100644 --- a/src/Core/Conventional.Tests/Conventional/Conventions/Assemblies/MatchingFilesConventionTests.cs +++ b/src/Core/Conventional.Tests/Conventional/Conventions/Assemblies/MatchingFilesConventionTests.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Linq; using System.Reflection; using Conventional.Conventions.Assemblies; @@ -16,7 +17,7 @@ public void Setup() { _testAssembly = Assembly.LoadFrom(KnownPaths.SolutionRoot + - "TestSolution/TestSolution.TestProject/bin/Debug/TestSolution.TestProject.dll"); + $"TestSolution{Path.DirectorySeparatorChar}TestSolution.TestProject{Path.DirectorySeparatorChar}bin{Path.DirectorySeparatorChar}Debug{Path.DirectorySeparatorChar}TestSolution.TestProject.dll"); } [Test] @@ -56,9 +57,8 @@ public void MustIncludeAllMatchingFilesInFolder_ProducesAppropriateErrorMessage( { var result = _testAssembly.MustConformTo(Convention.MustIncludeAllMatchingFilesInFolder("*.js")); var failureText = result.Failures.Single(); - failureText.Should().Contain(@"All files matching '*.js' within "); - failureText.Should().Contain(@"\TestSolution\TestSolution.TestProject' must be included in the project."); - failureText.Should().Contain(@"\TestSolution\TestSolution.TestProject\Scripts\unincludedJsFile.js"); + failureText.Should().Contain("TestSolution.TestProject"); + failureText.Should().Contain("unincludedJsFile.js"); failureText.Split(new[] {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries).Length.Should().Be(2); } diff --git a/src/Core/Conventional.Tests/Conventional/Conventions/Database/DatabaseConventionSpecificationTests.cs b/src/Core/Conventional.Tests/Conventional/Conventions/Database/DatabaseConventionSpecificationTests.cs index 858dc06..09f7049 100644 --- a/src/Core/Conventional.Tests/Conventional/Conventions/Database/DatabaseConventionSpecificationTests.cs +++ b/src/Core/Conventional.Tests/Conventional/Conventions/Database/DatabaseConventionSpecificationTests.cs @@ -40,6 +40,7 @@ public void Teardown() } [Test] + [Category("Database")] public void AllCheckConstraintsMustBeNamedConventionalSpecification_Success() { ExecuteSqlScriptFromResource("AllCheckConstraintsMustBeNamedConventionalSpecification_Success.sql"); @@ -53,6 +54,7 @@ public void AllCheckConstraintsMustBeNamedConventionalSpecification_Success() } [Test] + [Category("Database")] public void AllCheckConstraintsMustBeNamedConventionalSpecification_Fail() { ExecuteSqlScriptFromResource("AllCheckConstraintsMustBeNamedConventionalSpecification_Fail.sql"); @@ -66,6 +68,7 @@ public void AllCheckConstraintsMustBeNamedConventionalSpecification_Fail() } [Test] + [Category("Database")] public void AllDefaultConstraintsMustBeNamedConventionalSpecification_Success() { ExecuteSqlScriptFromResource("AllDefaultConstraintsMustBeNamedConventionalSpecification_Success.sql"); @@ -79,6 +82,7 @@ public void AllDefaultConstraintsMustBeNamedConventionalSpecification_Success() } [Test] + [Category("Database")] public void AllDefaultConstraintsMustBeNamedConventionalSpecification_Fail() { ExecuteSqlScriptFromResource("AllDefaultConstraintsMustBeNamedConventionalSpecification_Fail.sql"); @@ -92,6 +96,7 @@ public void AllDefaultConstraintsMustBeNamedConventionalSpecification_Fail() } [Test] + [Category("Database")] public void AllPrimaryKeyConstraintsMustBeNamedConventionalSpecification_Success() { ExecuteSqlScriptFromResource("AllPrimaryKeyConstraintsMustBeNamedConventionalSpecification_Success.sql"); @@ -105,6 +110,7 @@ public void AllPrimaryKeyConstraintsMustBeNamedConventionalSpecification_Success } [Test] + [Category("Database")] public void AllPrimaryKeyConstraintsMustBeNamedConventionalSpecification_Fail() { ExecuteSqlScriptFromResource("AllPrimaryKeyConstraintsMustBeNamedConventionalSpecification_Fail.sql"); @@ -118,6 +124,7 @@ public void AllPrimaryKeyConstraintsMustBeNamedConventionalSpecification_Fail() } [Test] + [Category("Database")] public void AllReferenceConstraintsMustBeNamedConventionalSpecification_Success() { ExecuteSqlScriptFromResource("AllReferenceConstraintsMustBeNamedConventionalSpecification_Success.sql"); @@ -131,6 +138,7 @@ public void AllReferenceConstraintsMustBeNamedConventionalSpecification_Success( } [Test] + [Category("Database")] public void AllReferenceConstraintsMustBeNamedConventionalSpecification_Fail() { ExecuteSqlScriptFromResource("AllReferenceConstraintsMustBeNamedConventionalSpecification_Fail.sql"); @@ -144,6 +152,7 @@ public void AllReferenceConstraintsMustBeNamedConventionalSpecification_Fail() } [Test] + [Category("Database")] public void AllUniqueConstraintsMustBeNamedConventionalSpecification_Success() { ExecuteSqlScriptFromResource("AllUniqueConstraintsMustBeNamedConventionalSpecification_Success.sql"); @@ -157,6 +166,7 @@ public void AllUniqueConstraintsMustBeNamedConventionalSpecification_Success() } [Test] + [Category("Database")] public void AllUniqueConstraintsMustBeNamedConventionalSpecification_Fail() { ExecuteSqlScriptFromResource("AllUniqueConstraintsMustBeNamedConventionalSpecification_Fail.sql"); @@ -170,6 +180,7 @@ public void AllUniqueConstraintsMustBeNamedConventionalSpecification_Fail() } [Test] + [Category("Database")] public void AllNamedColumnsMustBeNullableConventionSpecification_Success() { ExecuteSqlScriptFromResource("AllNamedColumnsMustBeNullableConventionalSpecification_Success.sql"); @@ -183,6 +194,7 @@ public void AllNamedColumnsMustBeNullableConventionSpecification_Success() } [Test] + [Category("Database")] public void AllNamedColumnsMustBeNonNullableConventionSpecification_Fails() { ExecuteSqlScriptFromResource("AllNamedColumnsMustBeNullableConventionalSpecification_Fail.sql"); @@ -196,6 +208,7 @@ public void AllNamedColumnsMustBeNonNullableConventionSpecification_Fails() } [Test] + [Category("Database")] public void AllNamedColumnsMustBeNonNullableConventionSpecification_Success() { ExecuteSqlScriptFromResource("AllNamedColumnsMustBeNullableConventionalSpecification_Success.sql"); @@ -209,6 +222,7 @@ public void AllNamedColumnsMustBeNonNullableConventionSpecification_Success() } [Test] + [Category("Database")] public void AllNamedColumnsMustBeNullableConventionSpecification_Fails() { ExecuteSqlScriptFromResource("AllNamedColumnsMustBeNullableConventionalSpecification_Fail.sql"); @@ -222,6 +236,7 @@ public void AllNamedColumnsMustBeNullableConventionSpecification_Fails() } [Test] + [Category("Database")] public void AllIdentityColumnsMustBeNamedTableNameIdConventionSpecification_Success() { ExecuteSqlScriptFromResource("AllIdentityColumnsMustBeNamedTableNameIdConventionSpecificationSuccess.sql"); @@ -235,6 +250,7 @@ public void AllIdentityColumnsMustBeNamedTableNameIdConventionSpecification_Succ } [Test] + [Category("Database")] public void AllIdentityColumnsMustBeNamedTableNameIdConventionSpecification_FailsWhenIdentityColumnIsNotNamedId() { ExecuteSqlScriptFromResource("AllIdentityColumnsMustBeNamedTableNameIdConventionSpecificationFailure.sql"); @@ -248,6 +264,7 @@ public void AllIdentityColumnsMustBeNamedTableNameIdConventionSpecification_Fail } [Test] + [Category("Database")] public void AllTablesMustHaveAClusteredIndex_Success() { ExecuteSqlScriptFromResource("TablesWithoutClusteredIndexSuccess.sql"); @@ -261,6 +278,7 @@ public void AllTablesMustHaveAClusteredIndex_Success() } [Test] + [Category("Database")] public void AllTablesMustHaveAClusteredIndex_Failure() { ExecuteSqlScriptFromResource("TablesWithoutClusteredIndexFailure.sql"); @@ -274,6 +292,7 @@ public void AllTablesMustHaveAClusteredIndex_Failure() } [Test] + [Category("Database")] public void EachRowMustHaveACorrespondingEnum_Success() { ExecuteSqlScriptFromResource("EachRowMustHaveACorrespondingEnum_Success.sql"); @@ -287,6 +306,7 @@ public void EachRowMustHaveACorrespondingEnum_Success() } [Test] + [Category("Database")] public void EachRowMustHaveACorrespondingEnum_Fail() { ExecuteSqlScriptFromResource("EachRowMustHaveACorrespondingEnum_Fail.sql"); @@ -308,19 +328,15 @@ private void ExecuteSqlScriptFromResource(string resourceName) { if (stream == null) { throw new MissingManifestResourceException(fullResourceName); } - using (var reader = new StreamReader(stream)) - { - script = reader.ReadToEnd(); - } + using var reader = new StreamReader(stream); + script = reader.ReadToEnd(); } - using (IDbConnection dbConnection = new SqlConnection(_settings.ConnectionString)) - { - dbConnection.Open(); - var command = dbConnection.CreateCommand(); - command.CommandText = script; - command.ExecuteNonQuery(); - } + using var dbConnection = new SqlConnection(_settings.ConnectionString); + dbConnection.Open(); + var command = dbConnection.CreateCommand(); + command.CommandText = script; + command.ExecuteNonQuery(); } private void CreateDatabase() @@ -329,13 +345,11 @@ private void CreateDatabase() var dbName = sb.InitialCatalog; sb.InitialCatalog = "master"; - using (IDbConnection dbConnection = new SqlConnection(sb.ConnectionString)) - { - dbConnection.Open(); - var command = dbConnection.CreateCommand(); - command.CommandText = SqlScripts.CreateDb(dbName); - command.ExecuteNonQuery(); - } + using var dbConnection = new SqlConnection(sb.ConnectionString); + dbConnection.Open(); + var command = dbConnection.CreateCommand(); + command.CommandText = SqlScripts.CreateDb(dbName); + command.ExecuteNonQuery(); } private void DropDatabase() @@ -344,13 +358,11 @@ private void DropDatabase() var dbName = sb.InitialCatalog; sb.InitialCatalog = "master"; - using (IDbConnection dbConnection = new SqlConnection(sb.ConnectionString)) - { - dbConnection.Open(); - var command = dbConnection.CreateCommand(); - command.CommandText = SqlScripts.DropDb(dbName); - command.ExecuteNonQuery(); - } + using var dbConnection = new SqlConnection(sb.ConnectionString); + dbConnection.Open(); + var command = dbConnection.CreateCommand(); + command.CommandText = SqlScripts.DropDb(dbName); + command.ExecuteNonQuery(); } } } diff --git a/src/Core/Conventional.Tests/DoomsdayScenarios.cs b/src/Core/Conventional.Tests/DoomsdayScenarios.cs index bee0c65..64196b8 100644 --- a/src/Core/Conventional.Tests/DoomsdayScenarios.cs +++ b/src/Core/Conventional.Tests/DoomsdayScenarios.cs @@ -88,7 +88,9 @@ public void WhenNumberOfOffendersExceedsKnownOffenders_AssertsFailure() .WithKnownOffenders(1) .MustConformTo(Convention.NameMustEndWith("Esquire")); - _failure.Should().Be("Expected 1 or less offenders but found 2: \r\nConventional.Tests.DoomsdayScenarios+OffenderOne\r\n---------------------------------------------------\r\nType name does not end with Esquire\r\n\r\nConventional.Tests.DoomsdayScenarios+OffenderTwo\r\n---------------------------------------------------\r\nType name does not end with Esquire\r\n\r\n"); + _failure.Should().Contain("Type name does not end with Esquire"); + _failure.Should().Contain("Conventional.Tests.DoomsdayScenarios+OffenderOne"); + _failure.Should().Contain("Conventional.Tests.DoomsdayScenarios+OffenderTwo"); } [Test] @@ -120,7 +122,8 @@ public void WhenDoomsdayIsSupplied_FailsIfThereAreAnyOffendersAfterDoomsday() .ByDoomsday(doomsday) .MustConformTo(Convention.NameMustEndWith("One")); - _failure.Should().Be("Doomsday is upon us! \r\nConventional.Tests.DoomsdayScenarios+OffenderTwo\r\n---------------------------------------------------\r\nType name does not end with One\r\n\r\n"); + _failure.Should().Contain("Type name does not end with One"); + _failure.Should().Contain("Conventional.Tests.DoomsdayScenarios+OffenderTwo"); } [Test] @@ -133,7 +136,9 @@ public void WhenDoomsdayIsSupplied_AndANumberOfKnownOffendersIsSupplied_FailsWit .ByDoomsday(doomsday) .MustConformTo(Convention.NameMustEndWith("Esquire")); - _failure.Should().Be("Doomsday is upon us! \r\nConventional.Tests.DoomsdayScenarios+OffenderOne\r\n---------------------------------------------------\r\nType name does not end with Esquire\r\n\r\nConventional.Tests.DoomsdayScenarios+OffenderTwo\r\n---------------------------------------------------\r\nType name does not end with Esquire\r\n\r\n"); + _failure.Should().Contain("Type name does not end with Esquire"); + _failure.Should().Contain("Conventional.Tests.DoomsdayScenarios+OffenderOne"); + _failure.Should().Contain("Conventional.Tests.DoomsdayScenarios+OffenderTwo"); } [Test] @@ -170,7 +175,8 @@ public void WhenWarnWithinIsSupplied_WarnsWhenWithinTheTimespanOfDoomsdayAndOffe .WithWarningWithin(TimeSpan.FromDays(3)) .MustConformTo(Convention.NameMustEndWith("Two")); - _warning.Should().Be("Doomsday approaches! \r\nConventional.Tests.DoomsdayScenarios+OffenderOne\r\n---------------------------------------------------\r\nType name does not end with Two\r\n\r\n"); + _warning.Should().Contain("Type name does not end with Two"); + _warning.Should().Contain("Conventional.Tests.DoomsdayScenarios+OffenderOne"); } [Test] @@ -198,7 +204,9 @@ public void WhenWarnWithinIsSupplied_AndWhenWithinTheTimespanOfDoomsday_FailsIfO .WithWarningWithin(TimeSpan.FromDays(3)) .MustConformTo(Convention.NameMustEndWith("Esquire")); - _failure.Should().Be("Expected 1 or less offenders but found 2: \r\nConventional.Tests.DoomsdayScenarios+OffenderOne\r\n---------------------------------------------------\r\nType name does not end with Esquire\r\n\r\nConventional.Tests.DoomsdayScenarios+OffenderTwo\r\n---------------------------------------------------\r\nType name does not end with Esquire\r\n\r\n"); + _failure.Should().Contain("Type name does not end with Esquire"); + _failure.Should().Contain("Conventional.Tests.DoomsdayScenarios+OffenderOne"); + _failure.Should().Contain("Conventional.Tests.DoomsdayScenarios+OffenderTwo"); } [Test] @@ -212,7 +220,10 @@ public void WhenMessageIsSupplied_OutputsTheMessgeOnFailures() .WithMessage("Things should really end with Esquire, so they sound fancier.") .MustConformTo(Convention.NameMustEndWith("Esquire")); - _warning.Should().Be("Doomsday approaches! Things should really end with Esquire, so they sound fancier.\r\nConventional.Tests.DoomsdayScenarios+OffenderOne\r\n---------------------------------------------------\r\nType name does not end with Esquire\r\n\r\nConventional.Tests.DoomsdayScenarios+OffenderTwo\r\n---------------------------------------------------\r\nType name does not end with Esquire\r\n\r\n"); + _warning.Should().Contain("Things should really end with Esquire, so they sound fancier."); + _warning.Should().Contain("Conventional.Tests.DoomsdayScenarios+OffenderOne"); + _warning.Should().Contain("Conventional.Tests.DoomsdayScenarios+OffenderTwo"); + _warning.Should().Contain("Type name does not end with Esquire"); } } } \ No newline at end of file diff --git a/src/Core/Conventional.Tests/ThisAssemblyScenarios.cs b/src/Core/Conventional.Tests/ThisAssemblyScenarios.cs index e4c46e8..1f4e7c7 100644 --- a/src/Core/Conventional.Tests/ThisAssemblyScenarios.cs +++ b/src/Core/Conventional.Tests/ThisAssemblyScenarios.cs @@ -1,3 +1,4 @@ +using System.IO; using FluentAssertions; using NUnit.Framework; @@ -11,7 +12,8 @@ public void GivenAPattern_LocatesAndReturnsAssemblyForThatPattern() var assemblySpecimen = TheAssembly.WithNameMatching("TestSolution.TestProject"); assemblySpecimen.ProjectFilePath.Should() - .Match(x => x.EndsWith(@"TestSolution\TestSolution.TestProject\TestSolution.TestProject.csproj")); + .Match(x => x.EndsWith( + $"TestSolution{Path.DirectorySeparatorChar}TestSolution.TestProject{Path.DirectorySeparatorChar}TestSolution.TestProject.csproj")); } } } \ No newline at end of file diff --git a/src/Core/Conventional/Conventions/Assemblies/AssemblyConventionSpecification.cs b/src/Core/Conventional/Conventions/Assemblies/AssemblyConventionSpecification.cs index 5d2a1b0..cafc833 100644 --- a/src/Core/Conventional/Conventions/Assemblies/AssemblyConventionSpecification.cs +++ b/src/Core/Conventional/Conventions/Assemblies/AssemblyConventionSpecification.cs @@ -34,8 +34,8 @@ public ConventionResult IsSatisfiedBy(string projectFilePath) { assemblyName = projectFilePath.Substring( - projectFilePath.LastIndexOf("\\", StringComparison.Ordinal) + 1, - projectFilePath.LastIndexOf(".", StringComparison.Ordinal) - projectFilePath.LastIndexOf("\\", StringComparison.Ordinal) - 1); + projectFilePath.LastIndexOf(Path.DirectorySeparatorChar) + 1, + projectFilePath.LastIndexOf(".", StringComparison.Ordinal) - projectFilePath.LastIndexOf(Path.DirectorySeparatorChar) - 1); } return diff --git a/src/Core/Conventional/Conventions/Assemblies/MustHaveAllFilesBeEmbeddedResourcesConventionSpecification.cs b/src/Core/Conventional/Conventions/Assemblies/MustHaveAllFilesBeEmbeddedResourcesConventionSpecification.cs index 39356a7..12b95db 100644 --- a/src/Core/Conventional/Conventions/Assemblies/MustHaveAllFilesBeEmbeddedResourcesConventionSpecification.cs +++ b/src/Core/Conventional/Conventions/Assemblies/MustHaveAllFilesBeEmbeddedResourcesConventionSpecification.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Xml.Linq; @@ -44,14 +45,16 @@ protected override ConventionResult IsSatisfiedBy(string assemblyName, XDocument DirectoryEx .GetFilesExceptOutput(ProjectFolder, "*") .Where(x => _fileMatchRegex.IsMatch(x)) - .Select(x => x.Replace($"{ProjectFolder}\\", "")) + .Select(x => x.Replace($"{ProjectFolder}{Path.DirectorySeparatorChar}", "")) .ToArray(); + var normalisedIncludes = children.Select(c => c.Include.Replace('\\', Path.DirectorySeparatorChar)); + var failures = children .Where(itemGroupItem => itemGroupItem.MatchesPatternAndIsNotAnEmbeddedResourceOrReference(_fileMatchRegex)) .Select(itemGroupItem => itemGroupItem.ToString()) - .Union(projectFiles.Where(x => children.None(child => child.Include.Equals(x)))) + .Union(projectFiles.Where(x => normalisedIncludes.None(include => include.Equals(x)))) .ToArray(); return BuildResult(assemblyName, failures); diff --git a/src/Core/Conventional/Conventions/Assemblies/MustHaveAllFilesBeResourcesConventionSpecification.cs b/src/Core/Conventional/Conventions/Assemblies/MustHaveAllFilesBeResourcesConventionSpecification.cs index 40bfdbb..6fcd152 100644 --- a/src/Core/Conventional/Conventions/Assemblies/MustHaveAllFilesBeResourcesConventionSpecification.cs +++ b/src/Core/Conventional/Conventions/Assemblies/MustHaveAllFilesBeResourcesConventionSpecification.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Xml.Linq; @@ -45,14 +46,16 @@ protected override ConventionResult IsSatisfiedBy(string assemblyName, XDocument DirectoryEx .GetFilesExceptOutput(ProjectFolder, "*") .Where(x => _fileMatchRegex.IsMatch(x)) - .Select(x => x.Replace($"{ProjectFolder}\\", "")) + .Select(x => x.Replace($"{ProjectFolder}{Path.DirectorySeparatorChar}", "")) .ToArray(); + var normalisedUpdates = children.Select(c => c.Update.Replace('\\', Path.DirectorySeparatorChar)); + var failures = children .Where(itemGroupItem => itemGroupItem.MatchesPatternAndIsNotAnEmbeddedResource(_fileMatchRegex)) .Select(itemGroupItem => itemGroupItem.ToString()) - .Union(projectFiles.Where(x => children.None(child => child.Update.Equals(x)))) + .Union(projectFiles.Where(x => normalisedUpdates.None(update => update.Equals(x)))) .ToArray(); return BuildResult(assemblyName, failures, "Embedded Resource"); diff --git a/src/Core/Conventional/Conventions/Assemblies/MustHaveFilesBeContentConventionSpecification.cs b/src/Core/Conventional/Conventions/Assemblies/MustHaveFilesBeContentConventionSpecification.cs index 2a3f564..83d0e1c 100644 --- a/src/Core/Conventional/Conventions/Assemblies/MustHaveFilesBeContentConventionSpecification.cs +++ b/src/Core/Conventional/Conventions/Assemblies/MustHaveFilesBeContentConventionSpecification.cs @@ -1,4 +1,5 @@ using System; +using System.IO; using System.Linq; using System.Text.RegularExpressions; using System.Xml.Linq; @@ -44,14 +45,16 @@ protected override ConventionResult IsSatisfiedBy(string assemblyName, XDocument DirectoryEx .GetFilesExceptOutput(ProjectFolder, "*") .Where(x => _fileMatchRegex.IsMatch(x)) - .Select(x => x.Replace($"{ProjectFolder}\\", "")) + .Select(x => x.Replace($"{ProjectFolder}{Path.DirectorySeparatorChar}", "")) .ToArray(); + var normalisedIncludes = children.Select(c => c.Include.Replace('\\', Path.DirectorySeparatorChar)); + var failures = children .Where(itemGroupItem => itemGroupItem.MatchesPatternAndIsNotContentCopyNewest(_fileMatchRegex)) .Select(itemGroupItem => itemGroupItem.ToString()) - .Union(projectFiles.Where(x => children.None(child => child.Include.Equals(x)))) + .Union(projectFiles.Where(x => normalisedIncludes.None(include => include.Equals(x)))) .ToArray(); return BuildResult(assemblyName, failures); diff --git a/src/Core/Conventional/Conventions/Assemblies/MustIncludeAllMatchingFilesInFolderConventionSpecification.cs b/src/Core/Conventional/Conventions/Assemblies/MustIncludeAllMatchingFilesInFolderConventionSpecification.cs index 356dec0..8aef2bb 100644 --- a/src/Core/Conventional/Conventions/Assemblies/MustIncludeAllMatchingFilesInFolderConventionSpecification.cs +++ b/src/Core/Conventional/Conventions/Assemblies/MustIncludeAllMatchingFilesInFolderConventionSpecification.cs @@ -37,8 +37,11 @@ protected override ConventionResult IsSatisfiedByLegacyCsprojFormat(string assem { var files = AllMatchingFilesInFolder(ConventionTargetFolder); - var failures = files.Where(file => - ItemGroupItem.FromProjectDocument(projectDocument).None(igi => igi.MatchesAbsolutePath(file.Replace(this.ProjectFolder, "").TrimStart('\\')))) + var normalisedIncludes = ItemGroupItem.FromProjectDocument(projectDocument) + .Select(item => item.Include.Replace('\\', Path.DirectorySeparatorChar)); + + + var failures = files.Where(file => normalisedIncludes.None(include => include == file.Replace(ProjectFolder, "").TrimStart(Path.DirectorySeparatorChar))) .ToArray(); if (failures.Any()) diff --git a/src/Core/Conventional/Conventions/Cecil/ConventionalAssemblyResolver.cs b/src/Core/Conventional/Conventions/Cecil/ConventionalAssemblyResolver.cs index 72ee26f..fd757f3 100644 --- a/src/Core/Conventional/Conventions/Cecil/ConventionalAssemblyResolver.cs +++ b/src/Core/Conventional/Conventions/Cecil/ConventionalAssemblyResolver.cs @@ -1,5 +1,7 @@ using System; +using System.IO; using System.Reflection; +using System.Runtime.InteropServices; using Mono.Cecil; namespace Conventional.Conventions.Cecil @@ -16,7 +18,7 @@ public virtual AssemblyDefinition Resolve(string fullName) public virtual AssemblyDefinition Resolve(string fullName, ReaderParameters parameters) { if (fullName == null) - throw new ArgumentNullException("fullName"); + throw new ArgumentNullException(nameof(fullName)); return Resolve(AssemblyNameReference.Parse(fullName), parameters); } @@ -29,7 +31,7 @@ public AssemblyDefinition Resolve(AssemblyNameReference name) public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters parameters) { if (name == null) - throw new ArgumentNullException("name"); + throw new ArgumentNullException(nameof(name)); var assembly = Assembly.Load(name.Name); @@ -38,7 +40,11 @@ public AssemblyDefinition Resolve(AssemblyNameReference name, ReaderParameters p private static string GetPathToAssembly(Assembly assembly) { - return assembly.CodeBase.Replace(FileSchemePrefix, string.Empty); + var codebase = assembly.CodeBase.Replace(FileSchemePrefix, string.Empty); + + return + RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ? + $"/{codebase}" : codebase; } protected virtual void Dispose(bool disposing) diff --git a/src/Core/Conventional/Extensions/DirectoryEx.cs b/src/Core/Conventional/Extensions/DirectoryEx.cs index e69ad22..0935640 100644 --- a/src/Core/Conventional/Extensions/DirectoryEx.cs +++ b/src/Core/Conventional/Extensions/DirectoryEx.cs @@ -14,7 +14,7 @@ public static IEnumerable GetFilesExceptOutput( string filePattern) { return GetFiles(rootPath, - x => ProjectOutputFolders.Select(folder => $"\\{folder}\\").None(x.Contains), filePattern); + x => ProjectOutputFolders.Select(folder => $"{Path.DirectorySeparatorChar}{folder}{Path.DirectorySeparatorChar}").None(x.Contains), filePattern); } public static IEnumerable GetFiles( diff --git a/src/Core/Conventional/KnownPaths.cs b/src/Core/Conventional/KnownPaths.cs index 342528e..85c978a 100644 --- a/src/Core/Conventional/KnownPaths.cs +++ b/src/Core/Conventional/KnownPaths.cs @@ -6,8 +6,8 @@ namespace Conventional { public static class KnownPaths { - private static readonly Func DefaultSolutionRootFinder = x => x.Substring(0, x.LastIndexOf("\\bin\\", StringComparison.Ordinal)); - private static readonly Func DefaultSolutionRoot = () => Path.GetFullPath(Path.Combine(SolutionRootFinder(AppContext.BaseDirectory), @"..\")); + private static readonly Func DefaultSolutionRootFinder = x => x.Substring(0, x.LastIndexOf($"{Path.DirectorySeparatorChar}bin{Path.DirectorySeparatorChar}", StringComparison.Ordinal)); + private static readonly Func DefaultSolutionRoot = () => Directory.GetParent(SolutionRootFinder(AppContext.BaseDirectory)).FullName + Path.DirectorySeparatorChar; private static readonly Func DefaultPathToSolutionRoot = () => Directory.GetFiles(SolutionRoot, "*.sln", SearchOption.AllDirectories).FirstOrDefault(); private static Func _solutionRootFinder; @@ -23,9 +23,9 @@ public static string SolutionRoot get => _solutionRoot ?? DefaultSolutionRoot(); set { - if (value.EndsWith(@"\") == false) + if (value.ToCharArray().Last() != Path.DirectorySeparatorChar) { - value += @"\"; + value += Path.DirectorySeparatorChar; } _solutionRoot = value;