File: Construction\ProjectImportElement_Tests.cs
Web Access
Project: ..\..\..\src\Build.UnitTests\Microsoft.Build.Engine.UnitTests.csproj (Microsoft.Build.Engine.UnitTests)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System;
using System.Linq;
using Microsoft.Build.Construction;
using Microsoft.Build.Evaluation;
using Shouldly;
using Xunit;
 
#nullable disable
 
namespace Microsoft.Build.UnitTests.Construction
{
    public class ProjectImportElement_Tests
    {
        [Fact]
        public void SdkReferenceIsCorrect_CreatedFromOnDiskProject_SdkAndVersionAttributeSet()
        {
            using (TestEnvironment testEnvironment = TestEnvironment.Create())
            {
                TransientTestFile projectFile = testEnvironment.CreateFile(
                    "test.proj",
                    @"
<Project>
  <Import Project=""Sdk.props"" Sdk=""My.Sdk"" Version=""1.2.0"" />
</Project>");
                ProjectRootElement rootElement = ProjectRootElement.Open(projectFile.Path);
 
                ProjectImportElement importElement = rootElement.Imports.First();
 
                importElement.SdkReference.Name.ShouldBe("My.Sdk");
                importElement.SdkReference.Version.ShouldBe("1.2.0");
                importElement.SdkReference.MinimumVersion.ShouldBeNull();
 
                SetPropertyAndExpectProjectXmlChangedEventToNotFire(rootElement, () => importElement.Sdk = "My.Sdk");
                SetPropertyAndExpectProjectXmlChangedEventToNotFire(rootElement, () => importElement.Version = "1.2.0");
 
                SetPropertyAndExpectProjectXmlChangedEventToFire(rootElement, () => importElement.MinimumVersion = "1.0.0", "Set Import Minimum Version 1.0.0");
                SetPropertyAndExpectProjectXmlChangedEventToNotFire(rootElement, () => importElement.MinimumVersion = "1.0.0");
 
                importElement.SdkReference.Name.ShouldBe("My.Sdk");
                importElement.SdkReference.Version.ShouldBe("1.2.0");
                importElement.SdkReference.MinimumVersion.ShouldBe("1.0.0");
 
                SetPropertyAndExpectProjectXmlChangedEventToFire(rootElement, () => importElement.Sdk = "Some.Other.Sdk", "Set Import Sdk Some.Other.Sdk");
 
                importElement.SdkReference.Name.ShouldBe("Some.Other.Sdk");
                importElement.SdkReference.Version.ShouldBe("1.2.0");
                importElement.SdkReference.MinimumVersion.ShouldBe("1.0.0");
            }
        }
 
        [Fact]
        public void SdkReferenceIsCorrect_CreatedFromOnDiskProject_SdkAttributeSet()
        {
            using (TestEnvironment testEnvironment = TestEnvironment.Create())
            {
                TransientTestFile projectFile = testEnvironment.CreateFile(
                    "test.proj",
                    @"
<Project>
  <Import Project=""Sdk.props"" Sdk=""My.Sdk"" />
</Project>");
                ProjectRootElement rootElement = ProjectRootElement.Open(projectFile.Path);
 
                ProjectImportElement importElement = rootElement.Imports.First();
 
                importElement.SdkReference.Name.ShouldBe("My.Sdk");
                importElement.SdkReference.Version.ShouldBeNull();
                importElement.SdkReference.MinimumVersion.ShouldBeNull();
 
                SetPropertyAndExpectProjectXmlChangedEventToNotFire(rootElement, () => importElement.Sdk = "My.Sdk");
 
                SetPropertyAndExpectProjectXmlChangedEventToFire(rootElement, () => importElement.Version = "1.2.0", "Set Import Version 1.2.0");
                SetPropertyAndExpectProjectXmlChangedEventToNotFire(rootElement, () => importElement.Version = "1.2.0");
 
                importElement.SdkReference.Name.ShouldBe("My.Sdk");
                importElement.SdkReference.Version.ShouldBe("1.2.0");
                importElement.SdkReference.MinimumVersion.ShouldBeNull();
 
                SetPropertyAndExpectProjectXmlChangedEventToFire(rootElement, () => importElement.MinimumVersion = "1.0.0", "Set Import Minimum Version 1.0.0");
                SetPropertyAndExpectProjectXmlChangedEventToNotFire(rootElement, () => importElement.MinimumVersion = "1.0.0");
 
                importElement.SdkReference.Name.ShouldBe("My.Sdk");
                importElement.SdkReference.Version.ShouldBe("1.2.0");
                importElement.SdkReference.MinimumVersion.ShouldBe("1.0.0");
            }
        }
 
        /// <summary>
        /// Verifies that the <see cref="ProjectImportElement.SdkReference" /> object is correctly set when creating <see cref="ProjectImportElement" /> objects.
        /// </summary>
        [Fact]
        public void SdkReferenceIsCorrect_CreatedInMemory()
        {
            using (var env = TestEnvironment.Create())
            {
                ProjectRootElement rootElement = ProjectRootElement.Create(NewProjectFileOptions.None);
 
                ProjectImportElement importElement = rootElement.AddImport("Sdk.props");
 
                SetPropertyAndExpectProjectXmlChangedEventToFire(rootElement, () => importElement.Sdk = "My.Sdk", "Set Import Sdk My.Sdk");
                SetPropertyAndExpectProjectXmlChangedEventToNotFire(rootElement, () => importElement.Sdk = "My.Sdk");
 
                importElement.SdkReference.Name.ShouldBe("My.Sdk");
                importElement.SdkReference.Version.ShouldBeNull();
                importElement.SdkReference.MinimumVersion.ShouldBeNull();
 
                SetPropertyAndExpectProjectXmlChangedEventToFire(rootElement, () => importElement.Version = "1.2.0", "Set Import Version 1.2.0");
                SetPropertyAndExpectProjectXmlChangedEventToNotFire(rootElement, () => importElement.Version = "1.2.0");
 
                importElement.SdkReference.Name.ShouldBe("My.Sdk");
                importElement.SdkReference.Version.ShouldBe("1.2.0");
                importElement.SdkReference.MinimumVersion.ShouldBeNull();
 
                SetPropertyAndExpectProjectXmlChangedEventToFire(rootElement, () => importElement.MinimumVersion = "1.0.0", "Set Import Minimum Version 1.0.0");
                SetPropertyAndExpectProjectXmlChangedEventToNotFire(rootElement, () => importElement.MinimumVersion = "1.0.0");
 
                importElement.SdkReference.Name.ShouldBe("My.Sdk");
                importElement.SdkReference.Version.ShouldBe("1.2.0");
                importElement.SdkReference.MinimumVersion.ShouldBe("1.0.0");
 
                rootElement.Save(env.GetTempFile(".csproj").Path);
 
                SetPropertyAndExpectProjectXmlChangedEventToNotFire(rootElement, () => importElement.Sdk = "My.Sdk");
 
                SetPropertyAndExpectProjectXmlChangedEventToFire(rootElement, () => importElement.Sdk = "Some.Other.Sdk", "Set Import Sdk Some.Other.Sdk");
 
                importElement.SdkReference.Name.ShouldBe("Some.Other.Sdk");
                importElement.SdkReference.Version.ShouldBe("1.2.0");
                importElement.SdkReference.MinimumVersion.ShouldBe("1.0.0");
 
                rootElement.Save();
 
                SetPropertyAndExpectProjectXmlChangedEventToFire(rootElement, () => importElement.Version = "4.0.0", "Set Import Version 4.0.0");
 
                importElement.SdkReference.Name.ShouldBe("Some.Other.Sdk");
                importElement.SdkReference.Version.ShouldBe("4.0.0");
                importElement.SdkReference.MinimumVersion.ShouldBe("1.0.0");
 
                rootElement.Save();
 
                SetPropertyAndExpectProjectXmlChangedEventToFire(rootElement, () => importElement.MinimumVersion = "2.0.0", "Set Import Minimum Version 2.0.0");
 
                importElement.SdkReference.Name.ShouldBe("Some.Other.Sdk");
                importElement.SdkReference.Version.ShouldBe("4.0.0");
                importElement.SdkReference.MinimumVersion.ShouldBe("2.0.0");
 
                SetPropertyAndExpectProjectXmlChangedEventToFire(rootElement, () => importElement.Version = null, "Set Import Version ");
 
                importElement.SdkReference.Name.ShouldBe("Some.Other.Sdk");
                importElement.SdkReference.Version.ShouldBeNull();
                importElement.SdkReference.MinimumVersion.ShouldBe("2.0.0");
 
                SetPropertyAndExpectProjectXmlChangedEventToFire(rootElement, () => importElement.MinimumVersion = null, "Set Import Minimum Version ");
 
                importElement.SdkReference.Name.ShouldBe("Some.Other.Sdk");
                importElement.SdkReference.Version.ShouldBeNull();
                importElement.SdkReference.MinimumVersion.ShouldBeNull();
            }
        }
 
        private void SetPropertyAndExpectProjectXmlChangedEventToFire(ProjectRootElement rootElement, Action action, string expectedReason)
        {
            ProjectXmlChangedEventArgs projectXmlChangedEventArgs = null;
 
            void OnProjectXmlChanged(object sender, ProjectXmlChangedEventArgs args)
            {
                projectXmlChangedEventArgs = args;
            }
 
            rootElement.OnProjectXmlChanged += OnProjectXmlChanged;
            try
            {
                action();
            }
            finally
            {
                rootElement.OnProjectXmlChanged -= OnProjectXmlChanged;
            }
 
            projectXmlChangedEventArgs.ShouldNotBeNull();
            projectXmlChangedEventArgs.Reason.ShouldBe(expectedReason);
        }
 
        private void SetPropertyAndExpectProjectXmlChangedEventToNotFire(ProjectRootElement rootElement, Action action)
        {
            ProjectXmlChangedEventArgs projectXmlChangedEventArgs = null;
 
            void OnProjectXmlChanged(object sender, ProjectXmlChangedEventArgs args)
            {
                projectXmlChangedEventArgs = args;
            }
 
            rootElement.OnProjectXmlChanged += OnProjectXmlChanged;
            try
            {
                action();
            }
            finally
            {
                rootElement.OnProjectXmlChanged -= OnProjectXmlChanged;
            }
 
            projectXmlChangedEventArgs.ShouldBeNull();
        }
    }
}