diff --git a/src/Tasks.UnitTests/ProjectExtensionsImportTestBase.cs b/src/Tasks.UnitTests/ProjectExtensionsImportTestBase.cs index 38dc1447331..e72c228d93d 100644 --- a/src/Tasks.UnitTests/ProjectExtensionsImportTestBase.cs +++ b/src/Tasks.UnitTests/ProjectExtensionsImportTestBase.cs @@ -3,6 +3,8 @@ using Microsoft.Build.Evaluation; using System; using System.IO; +using System.Linq; +using Shouldly; using Xunit; namespace Microsoft.Build.UnitTests @@ -57,10 +59,10 @@ public void DoesNotImportProjectIfNotExist() string projectExtensionsPath = project.GetPropertyValue("MSBuildProjectExtensionsPath"); - Assert.True(!String.IsNullOrWhiteSpace(projectExtensionsPath), "The property 'MSBuildProjectExtensionsPath' should not be empty during project evaluation."); - Assert.True(!Directory.Exists(projectExtensionsPath), $"The project extension directory '{projectExtensionsPath}' should not exist."); - Assert.Equal("true", project.GetPropertyValue(PropertyNameToEnableImport), StringComparer.OrdinalIgnoreCase); - Assert.Equal(String.Empty, project.GetPropertyValue(PropertyNameToSignalImportSucceeded), StringComparer.OrdinalIgnoreCase); + projectExtensionsPath.ShouldNotBeNullOrWhiteSpace(); + Directory.Exists(projectExtensionsPath).ShouldBeFalse(); + project.GetPropertyValue(PropertyNameToEnableImport).ShouldBe("true"); + project.GetPropertyValue(PropertyNameToSignalImportSucceeded).ShouldBeEmpty(); } /// @@ -92,10 +94,10 @@ public void DoesNotImportProjectWhenDisabled() string projectExtensionsDirectory = Path.Combine(ObjectModelHelpers.TempProjectDir, Path.GetDirectoryName(ImportProjectPath)); - Assert.Equal("false", project.GetPropertyValue(PropertyNameToEnableImport), StringComparer.OrdinalIgnoreCase); - Assert.Equal(String.Empty, project.GetPropertyValue(PropertyNameToSignalImportSucceeded), StringComparer.OrdinalIgnoreCase); - Assert.True(Directory.Exists(projectExtensionsDirectory), $"The directory '{projectExtensionsDirectory}' should exist but doesn't."); - Assert.Equal($@"{projectExtensionsDirectory}{Path.DirectorySeparatorChar}", project.GetPropertyValue("MSBuildProjectExtensionsPath")); + project.GetPropertyValue(PropertyNameToEnableImport).ShouldBe("false"); + project.GetPropertyValue(PropertyNameToSignalImportSucceeded).ShouldBeEmpty(); + Directory.Exists(projectExtensionsDirectory).ShouldBeTrue(); + project.GetPropertyValue("MSBuildProjectExtensionsPath").ShouldBe($@"{projectExtensionsDirectory}{Path.DirectorySeparatorChar}"); } /// @@ -121,8 +123,8 @@ public void ImportsProjectIfCustomPath() ")); - Assert.Equal("true", project.GetPropertyValue(PropertyNameToEnableImport), StringComparer.OrdinalIgnoreCase); - Assert.Equal("true", project.GetPropertyValue(PropertyNameToSignalImportSucceeded), StringComparer.OrdinalIgnoreCase); + project.GetPropertyValue(PropertyNameToEnableImport).ShouldBe("true"); + project.GetPropertyValue(PropertyNameToSignalImportSucceeded).ShouldBe("true"); } /// @@ -145,8 +147,60 @@ public void ImportsProjectIfExists() ")); - Assert.Equal("true", project.GetPropertyValue(PropertyNameToEnableImport), StringComparer.OrdinalIgnoreCase); - Assert.Equal("true", project.GetPropertyValue(PropertyNameToSignalImportSucceeded), StringComparer.OrdinalIgnoreCase); + project.GetPropertyValue(PropertyNameToEnableImport).ShouldBe("true"); + project.GetPropertyValue(PropertyNameToSignalImportSucceeded).ShouldBe("true"); + } + + /// + /// Ensures that an error is logged if MSBuildProjectExtensionsPath is modified after it was set by Microsoft.Common.props. + /// + [Fact] + public void ErrorIfChangedInBodyOfProject() + { + Project project = ObjectModelHelpers.LoadProjectFileInTempProjectDirectory(ObjectModelHelpers.CreateFileInTempProjectDirectory(_projectRelativePath, @" + + + + + foo + + + + + ")); + + MockLogger logger = new MockLogger(); + + project.Build("_CheckForInvalidConfigurationAndPlatform", new[] {logger}).ShouldBeFalse(); + + logger.Errors.Select(i => i.Code).FirstOrDefault().ShouldBe("MSB3540"); + } + + /// + /// Ensures that an error is logged if BaseIntermediateOutputPath is modified after it was set by Microsoft.Common.props and + /// EnableBaseIntermediateOutputPathMismatchWarning is 'true'. + /// + [Fact] + public void WarningIfBaseIntermediateOutputPathIsChangedInBodyOfProject() + { + Project project = ObjectModelHelpers.LoadProjectFileInTempProjectDirectory(ObjectModelHelpers.CreateFileInTempProjectDirectory(_projectRelativePath, @" + + + + + true + foo + + + + + ")); + + MockLogger logger = new MockLogger(); + + project.Build("_CheckForInvalidConfigurationAndPlatform", new[] { logger }).ShouldBeTrue(); + + logger.Warnings.Select(i => i.Code).FirstOrDefault().ShouldBe("MSB3539"); } } -} \ No newline at end of file +} diff --git a/src/Tasks/Microsoft.Common.CurrentVersion.targets b/src/Tasks/Microsoft.Common.CurrentVersion.targets index f85d2936ee7..7f29228ca6a 100644 --- a/src/Tasks/Microsoft.Common.CurrentVersion.targets +++ b/src/Tasks/Microsoft.Common.CurrentVersion.targets @@ -766,6 +766,31 @@ Copyright (C) Microsoft Corporation. All rights reserved. x86 + + + + + + obj\ $(BaseIntermediateOutputPath)\ + <_InitialBaseIntermediateOutputPath>$(BaseIntermediateOutputPath) + $(BaseIntermediateOutputPath)