File: Construction\ProjectOutputElement_Tests.cs
Web Access
Project: ..\..\..\src\Build.OM.UnitTests\Microsoft.Build.Engine.OM.UnitTests.csproj (Microsoft.Build.Engine.OM.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.IO;
using System.Xml;
using Microsoft.Build.Construction;
using Xunit;
using InvalidProjectFileException = Microsoft.Build.Exceptions.InvalidProjectFileException;
 
#nullable disable
 
namespace Microsoft.Build.UnitTests.OM.Construction
{
    /// <summary>
    /// Test the ProjectOutputElement class
    /// </summary>
    public class ProjectOutputElement_Tests
    {
        /// <summary>
        /// Read an output item
        /// </summary>
        [Fact]
        public void ReadOutputItem()
        {
            ProjectOutputElement output = GetOutputItem();
 
            Assert.False(output.IsOutputProperty);
            Assert.True(output.IsOutputItem);
            Assert.Equal("p", output.TaskParameter);
            Assert.Equal(String.Empty, output.PropertyName);
            Assert.Equal("i1", output.ItemType);
        }
 
        /// <summary>
        /// Read an output property
        /// </summary>
        [Fact]
        public void ReadOutputProperty()
        {
            ProjectOutputElement output = GetOutputProperty();
 
            Assert.True(output.IsOutputProperty);
            Assert.False(output.IsOutputItem);
            Assert.Equal("p", output.TaskParameter);
            Assert.Equal("p1", output.PropertyName);
            Assert.Equal(String.Empty, output.ItemType);
        }
 
        /// <summary>
        /// Read an output property with missing itemname and propertyname
        /// </summary>
        [Fact]
        public void ReadInvalidOutputWithoutPropertyOrItem()
        {
            Assert.Throws<InvalidProjectFileException>(() =>
            {
                string content = @"
                    <Project>
                        <Target Name='t'>
                            <t1>
                                <Output TaskParameter='p'/>
                            </t1>
                            <t2/>
                        </Target>
                    </Project>
                ";
 
                ProjectRootElement.Create(XmlReader.Create(new StringReader(content)));
            });
        }
        /// <summary>
        /// Read an output property with reserved property name
        /// </summary>
        [Fact]
        public void ReadInvalidReservedOutputPropertyName()
        {
            Assert.Throws<InvalidProjectFileException>(() =>
            {
                string content = @"
                    <Project>
                        <Target Name='t'>
                            <t1>
                                <Output TaskParameter='p' PropertyName='MSBuildProjectFile'/>
                            </t1>
                            <t2/>
                        </Target>
                    </Project>
                ";
 
                ProjectRootElement.Create(XmlReader.Create(new StringReader(content)));
            });
        }
        /// <summary>
        /// Read an output property with missing taskparameter
        /// </summary>
        [Fact]
        public void ReadInvalidOutputWithoutTaskName()
        {
            Assert.Throws<InvalidProjectFileException>(() =>
            {
                string content = @"
                    <Project>
                        <Target Name='t'>
                            <t1>
                                <Output ItemName='i'/>
                            </t1>
                            <t2/>
                        </Target>
                    </Project>
                ";
 
                ProjectRootElement.Create(XmlReader.Create(new StringReader(content)));
            });
        }
        /// <summary>
        /// Read an output property with missing taskparameter
        /// </summary>
        [Fact]
        public void ReadInvalidOutputWithEmptyTaskName()
        {
            Assert.Throws<InvalidProjectFileException>(() =>
            {
                string content = @"
                    <Project>
                        <Target Name='t'>
                            <t1>
                                <Output TaskName='' ItemName='i'/>
                            </t1>
                            <t2/>
                        </Target>
                    </Project>
                ";
 
                ProjectRootElement.Create(XmlReader.Create(new StringReader(content)));
            });
        }
        /// <summary>
        /// Read an output property with child element
        /// </summary>
        [Fact]
        public void ReadInvalidOutputWithChildElement()
        {
            Assert.Throws<InvalidProjectFileException>(() =>
            {
                string content = @"
                    <Project>
                        <Target Name='t'>
                            <t1>
                                <Output ItemName='i' TaskParameter='x'>
                                     xxxxxxx
                                </Output>
                            </t1>
                            <t2/>
                        </Target>
                    </Project>
                ";
 
                ProjectRootElement.Create(XmlReader.Create(new StringReader(content)));
            });
        }
        /// <summary>
        /// Read an output property with propertyname but an empty itemname attribute
        /// </summary>
        [Fact]
        public void ReadInvalidPropertyValueItemBlank()
        {
            Assert.Throws<InvalidProjectFileException>(() =>
            {
                string content = @"
                    <Project>
                        <Target Name='t'>
                            <t1>
                                <Output TaskParameter='t' PropertyName='p' ItemName=''/>
                            </t1>
                            <t2/>
                        </Target>
                    </Project>
                ";
 
                ProjectRootElement.Create(XmlReader.Create(new StringReader(content)));
            });
        }
        /// <summary>
        /// Read an output property with an itemname but an empty propertyname attribute
        /// </summary>
        [Fact]
        public void ReadInvalidItemValuePropertyBlank()
        {
            Assert.Throws<InvalidProjectFileException>(() =>
            {
                string content = @"
                    <Project>
                        <Target Name='t'>
                            <t1>
                                <Output TaskParameter='t' ItemName='i' PropertyName=''/>
                            </t1>
                            <t2/>
                        </Target>
                    </Project>
                ";
 
                ProjectRootElement.Create(XmlReader.Create(new StringReader(content)));
            });
        }
        /// <summary>
        /// Modify the condition
        /// </summary>
        [Fact]
        public void SetOutputPropertyCondition()
        {
            ProjectOutputElement output = GetOutputProperty();
            Helpers.ClearDirtyFlag(output.ContainingProject);
 
            output.Condition = "c";
            Assert.Equal("c", output.Condition);
            Assert.True(output.ContainingProject.HasUnsavedChanges);
        }
 
        /// <summary>
        /// Modify the property name value
        /// </summary>
        [Fact]
        public void SetOutputPropertyName()
        {
            ProjectOutputElement output = GetOutputProperty();
            Helpers.ClearDirtyFlag(output.ContainingProject);
 
            output.PropertyName = "p1b";
            Assert.Equal("p1b", output.PropertyName);
            Assert.True(output.ContainingProject.HasUnsavedChanges);
        }
 
        /// <summary>
        /// Attempt to set the item name value when property name is set
        /// </summary>
        [Fact]
        public void SetOutputPropertyItemType()
        {
            Assert.Throws<InvalidOperationException>(() =>
            {
                ProjectOutputElement output = GetOutputProperty();
 
                output.ItemType = "i1b";
            });
        }
        /// <summary>
        /// Set the item name value
        /// </summary>
        [Fact]
        public void SetOutputItemItemType()
        {
            ProjectOutputElement output = GetOutputItem();
            Helpers.ClearDirtyFlag(output.ContainingProject);
 
            output.ItemType = "p1b";
            Assert.Equal("p1b", output.ItemType);
            Assert.True(output.ContainingProject.HasUnsavedChanges);
        }
 
        /// <summary>
        /// Attempt to set the property name when the item name is set
        /// </summary>
        [Fact]
        public void SetOutputItemPropertyName()
        {
            Assert.Throws<InvalidOperationException>(() =>
            {
                ProjectOutputElement output = GetOutputItem();
 
                output.PropertyName = "p1b";
            });
        }
        /// <summary>
        /// Helper to get a ProjectOutputElement for an output item
        /// </summary>
        private static ProjectOutputElement GetOutputItem()
        {
            string content = @"
                    <Project>
                        <Target Name='t'>
                            <t1>
                                <Output TaskParameter='p' ItemName='i1' />
                            </t1>
                            <t2/>
                        </Target>
                    </Project>
                ";
 
            using ProjectRootElementFromString projectRootElementFromString = new(content);
            ProjectRootElement project = projectRootElementFromString.Project;
            ProjectTargetElement target = (ProjectTargetElement)Helpers.GetFirst(project.Children);
            ProjectTaskElement task = (ProjectTaskElement)Helpers.GetFirst(target.Children);
            return Helpers.GetFirst(task.Outputs);
        }
 
        /// <summary>
        /// Helper to get a ProjectOutputElement for an output property
        /// </summary>
        private static ProjectOutputElement GetOutputProperty()
        {
            string content = @"
                    <Project>
                        <Target Name='t'>
                            <t1>
                                <Output TaskParameter='p' PropertyName='p1' />
                            </t1>
                            <t2/>
                        </Target>
                    </Project>
                ";
 
            using ProjectRootElementFromString projectRootElementFromString = new(content);
            ProjectRootElement project = projectRootElementFromString.Project;
            ProjectTargetElement target = (ProjectTargetElement)Helpers.GetFirst(project.Children);
            ProjectTaskElement task = (ProjectTaskElement)Helpers.GetFirst(target.Children);
            return Helpers.GetFirst(task.Outputs);
        }
    }
}