|
// 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>
/// Tests for the ProjectTaskElement class
/// </summary>
public class ProjectTaskElement_Tests
{
/// <summary>
/// Read task with no parameters
/// </summary>
[Fact]
public void ReadNoParameters()
{
string content = @"
<Project>
<Target Name='t'>
<t1/>
</Target>
</Project>
";
ProjectTaskElement task = GetTaskFromContent(content);
var parameters = Helpers.MakeDictionary(task.Parameters);
Assert.Equal("t1", task.Name);
Assert.Empty(parameters);
Assert.Equal(0, Helpers.Count(task.Outputs));
Assert.Equal(String.Empty, task.ContinueOnError);
}
/// <summary>
/// Read task with continue on error
/// </summary>
[Fact]
public void ReadContinueOnError()
{
string content = @"
<Project>
<Target Name='t'>
<t1 ContinueOnError='coe'/>
</Target>
</Project>
";
ProjectTaskElement task = GetTaskFromContent(content);
Assert.Equal("coe", task.ContinueOnError);
}
/// <summary>
/// Read task with condition
/// </summary>
[Fact]
public void ReadCondition()
{
string content = @"
<Project>
<Target Name='t'>
<t1 Condition='c'/>
</Target>
</Project>
";
ProjectTaskElement task = GetTaskFromContent(content);
Assert.Equal("c", task.Condition);
}
/// <summary>
/// Read task with invalid child
/// </summary>
[Fact]
public void ReadInvalidChild()
{
Assert.Throws<InvalidProjectFileException>(() =>
{
string content = @"
<Project>
<Target Name='t'>
<t1>
<X/>
</t1>
</Target>
</Project>
";
GetTaskFromContent(content);
});
}
/// <summary>
/// Read task with empty parameter.
/// Although MSBuild does not set these on tasks, they
/// are visible in the XML objects for editing purposes.
/// </summary>
[Fact]
public void ReadEmptyParameter()
{
string content = @"
<Project>
<Target Name='t'>
<t1 p1='' />
</Target>
</Project>
";
ProjectTaskElement task = GetTaskFromContent(content);
var parameters = Helpers.MakeDictionary(task.Parameters);
Assert.Single(parameters);
}
/// <summary>
/// Read task with parameters
/// </summary>
[Fact]
public void ReadParameters()
{
string content = @"
<Project>
<Target Name='t'>
<t1 p1='v1' p2='v2' />
</Target>
</Project>
";
ProjectTaskElement task = GetTaskFromContent(content);
var parameters = Helpers.MakeDictionary(task.Parameters);
Assert.Equal(2, parameters.Count);
Assert.Equal("v1", parameters["p1"]);
Assert.Equal("v2", parameters["p2"]);
Assert.Equal("v1", task.GetParameter("p1"));
Assert.Equal(String.Empty, task.GetParameter("xxxx"));
}
/// <summary>
/// Change a parameter value on the task
/// </summary>
[Fact]
public void SetParameterValue()
{
ProjectTaskElement task = GetBasicTask();
Helpers.ClearDirtyFlag(task.ContainingProject);
task.SetParameter("p1", "v1b");
var parameters = Helpers.MakeDictionary(task.Parameters);
Assert.Equal("v1b", parameters["p1"]);
Assert.True(task.ContainingProject.HasUnsavedChanges);
}
/// <summary>
/// Set a parameter to null
/// </summary>
[Fact]
public void SetInvalidNullParameterValue()
{
Assert.Throws<ArgumentNullException>(() =>
{
ProjectTaskElement task = GetBasicTask();
task.SetParameter("p1", null);
});
}
/// <summary>
/// Set a parameter with the reserved name 'continueonerror'
/// </summary>
[Fact]
public void SetInvalidParameterNameContinueOnError()
{
Assert.Throws<ArgumentException>(() =>
{
ProjectTaskElement task = GetBasicTask();
task.SetParameter("ContinueOnError", "v");
});
}
/// <summary>
/// Set a parameter with the reserved name 'condition'
/// </summary>
[Fact]
public void SetInvalidParameterNameCondition()
{
Assert.Throws<ArgumentException>(() =>
{
ProjectTaskElement task = GetBasicTask();
task.SetParameter("Condition", "c");
});
}
/// <summary>
/// Set a parameter using a null name
/// </summary>
[Fact]
public void SetInvalidNullParameterName()
{
Assert.Throws<ArgumentNullException>(() =>
{
ProjectTaskElement task = GetBasicTask();
task.SetParameter(null, "v1");
});
}
/// <summary>
/// Add a parameter to the task
/// </summary>
[Fact]
public void SetNotExistingParameter()
{
ProjectTaskElement task = GetBasicTask();
Helpers.ClearDirtyFlag(task.ContainingProject);
task.SetParameter("p2", "v2");
var parameters = Helpers.MakeDictionary(task.Parameters);
Assert.Equal("v2", parameters["p2"]);
Assert.True(task.ContainingProject.HasUnsavedChanges);
}
/// <summary>
/// Remove a parameter from the task
/// </summary>
[Fact]
public void RemoveExistingParameter()
{
ProjectTaskElement task = GetBasicTask();
Helpers.ClearDirtyFlag(task.ContainingProject);
task.RemoveParameter("p1");
var parameters = Helpers.MakeDictionary(task.Parameters);
Assert.Empty(parameters);
Assert.True(task.ContainingProject.HasUnsavedChanges);
}
/// <summary>
/// Remove a parameter that is not on the task
/// </summary>
/// <remarks>
/// This should not throw.
/// </remarks>
[Fact]
public void RemoveNonExistingParameter()
{
ProjectTaskElement task = GetBasicTask();
task.RemoveParameter("XX");
var parameters = Helpers.MakeDictionary(task.Parameters);
Assert.Single(parameters);
}
/// <summary>
/// Set continue on error
/// </summary>
[Fact]
public void SetContinueOnError()
{
ProjectRootElement project = ProjectRootElement.Create();
ProjectTaskElement task = project.AddTarget("t").AddTask("tt");
Helpers.ClearDirtyFlag(task.ContainingProject);
task.ContinueOnError = "true";
Assert.Equal("true", task.ContinueOnError);
Assert.True(project.HasUnsavedChanges);
}
/// <summary>
/// Set condition
/// </summary>
[Fact]
public void SetCondition()
{
ProjectRootElement project = ProjectRootElement.Create();
ProjectTaskElement task = project.AddTarget("t").AddTask("tt");
Helpers.ClearDirtyFlag(task.ContainingProject);
task.Condition = "c";
Assert.Equal("c", task.Condition);
Assert.True(project.HasUnsavedChanges);
}
/// <summary>
/// Helper to return the first ProjectTaskElement from the parsed project content provided
/// </summary>
private static ProjectTaskElement GetTaskFromContent(string content)
{
using ProjectRootElementFromString projectRootElementFromString = new(content);
ProjectRootElement project = projectRootElementFromString.Project;
ProjectTargetElement target = (ProjectTargetElement)Helpers.GetFirst(project.Children);
return (ProjectTaskElement)Helpers.GetFirst(target.Children);
}
/// <summary>
/// Get a basic ProjectTaskElement with one parameter p1
/// </summary>
private static ProjectTaskElement GetBasicTask()
{
string content = @"
<Project>
<Target Name='t'>
<t1 p1='v1' />
</Target>
</Project>
";
ProjectTaskElement task = GetTaskFromContent(content);
return task;
}
}
}
|