|
// 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.Collections.Generic;
using System.IO;
using System.Linq;
using System.Xml;
using Microsoft.Build.Evaluation;
using Xunit;
#nullable disable
namespace Microsoft.Build.UnitTests.OM.Definition
{
/// <summary>
/// Tests around editing elements that are referenced by others or the ones that references others.
/// </summary>
public class EditingElementsReferencedByOrReferences_Tests
{
/// <summary>
/// Changes the item type on an item used with the at operator.
/// </summary>
[Fact]
public void ChangeItemTypeInReferencedItem()
{
Project project = GetProject(
@"<Project>
<ItemGroup>
<I Include=""X"" />
<I Include=""@(I);Y"" />
</ItemGroup>
</Project>");
ProjectItem item = project.GetItems("I").Where(i => i.UnevaluatedInclude == "X").First();
item.ItemType = "J";
string expected =
@"<Project>
<ItemGroup>
<J Include=""X"" />
<I Include=""@(I);Y"" />
</ItemGroup>
</Project>";
Helpers.VerifyAssertProjectContent(expected, project.Xml, false);
project.ReevaluateIfNecessary();
IEnumerable<ProjectItem> items = project.GetItems("I");
Assert.Single(items); // "Wrong number of items after changing type"
Assert.Equal("Y", items.First().EvaluatedInclude); // "Wrong evaluated include after changing type"
}
/// <summary>
/// Removes an item in a ; separated list. It blows up the list.
/// </summary>
[Fact]
public void RemoveItemInList()
{
Project project = GetProject(
@"<Project>
<ItemGroup>
<I Include=""X"" />
<I Include=""@(I);Y;Z"" />
</ItemGroup>
</Project>");
ProjectItem item = project.GetItems("I").Where(i => i.EvaluatedInclude == "Y").First();
project.RemoveItem(item);
string expected =
@"<Project>
<ItemGroup>
<I Include=""X"" />
<I Include=""X"" />
<I Include=""Z"" />
</ItemGroup>
</Project>";
Helpers.VerifyAssertProjectContent(expected, project.Xml, false);
}
/// <summary>
/// Renames an item in a ; separated list. It blows up the list.
/// </summary>
[Fact]
public void RenameItemInList()
{
Project project = GetProject(
@"<Project>
<ItemGroup>
<I Include=""X"" />
<I Include=""@(I);Y"" />
</ItemGroup>
</Project>");
ProjectItem item = project.GetItems("I").Where(i => i.EvaluatedInclude == "Y").First();
item.Rename("Z");
string expected =
@"<Project>
<ItemGroup>
<I Include=""X"" />
<I Include=""X"" />
<I Include=""Z"" />
</ItemGroup>
</Project>";
Helpers.VerifyAssertProjectContent(expected, project.Xml, false);
}
/// <summary>
/// Removes metadata duplicated in item.
/// </summary>
[Fact]
public void RemoveMetadata1()
{
Project project = GetProject(
@"<Project>
<ItemDefinitionGroup>
<I>
<M>A</M>
</I>
</ItemDefinitionGroup>
<ItemGroup>
<I Include=""X"">
<M>%(M);B</M>
<M>%(M);C</M>
</I>
<I Include=""Y"">
<M>%(M);D</M>
</I>
</ItemGroup>
</Project>");
ProjectItem item1 = project.GetItems("I").Where(i => i.EvaluatedInclude == "X").First();
Assert.Equal("A;B;C", item1.GetMetadataValue("M")); // "Invalid metadata at start"
ProjectItem item2 = project.GetItems("I").Where(i => i.EvaluatedInclude == "Y").First();
Assert.Equal("A;D", item2.GetMetadataValue("M")); // "Invalid metadata at start"
item1.RemoveMetadata("M");
string expected =
@"<Project>
<ItemDefinitionGroup>
<I>
<M>A</M>
</I>
</ItemDefinitionGroup>
<ItemGroup>
<I Include=""X"">
<M>%(M);B</M>
</I>
<I Include=""Y"">
<M>%(M);D</M>
</I>
</ItemGroup>
</Project>";
Helpers.VerifyAssertProjectContent(expected, project.Xml, false);
}
/// <summary>
/// Removes duplicated metadata and checks evaluation.
/// </summary>
[Fact]
public void RemoveMetadata2()
{
Project project = GetProject(
@"<Project>
<ItemDefinitionGroup>
<I>
<M>A</M>
</I>
</ItemDefinitionGroup>
<ItemGroup>
<I Include=""X"">
<M>%(M);B</M>
<M>%(M);C</M>
</I>
<I Include=""Y"">
<M>%(M);D</M>
</I>
</ItemGroup>
</Project>");
ProjectItem item1 = project.GetItems("I").Where(i => i.EvaluatedInclude == "X").First();
item1.RemoveMetadata("M");
string expected =
@"<Project>
<ItemDefinitionGroup>
<I>
<M>A</M>
</I>
</ItemDefinitionGroup>
<ItemGroup>
<I Include=""X"">
<M>%(M);B</M>
</I>
<I Include=""Y"">
<M>%(M);D</M>
</I>
</ItemGroup>
</Project>";
Helpers.VerifyAssertProjectContent(expected, project.Xml, false);
project.ReevaluateIfNecessary();
item1 = project.GetItems("I").Where(i => i.EvaluatedInclude == "X").First();
Assert.Equal("A;B", item1.GetMetadataValue("M")); // "Invalid metadata after first removal"
ProjectItem item2 = project.GetItems("I").Where(i => i.EvaluatedInclude == "Y").First();
Assert.Equal("A;D", item2.GetMetadataValue("M")); // "Invalid metadata after first removal"
}
/// <summary>
/// Removes metadata but still keep inherited one from item definition.
/// </summary>
[Fact]
public void RemoveMetadata3()
{
Project project = GetProject(
@"<Project>
<ItemDefinitionGroup>
<I>
<M>A</M>
</I>
</ItemDefinitionGroup>
<ItemGroup>
<I Include=""X"">
<M>%(M);B</M>
<M>%(M);C</M>
</I>
<I Include=""Y"">
<M>%(M);D</M>
</I>
</ItemGroup>
</Project>");
ProjectItem item1 = project.GetItems("I").Where(i => i.EvaluatedInclude == "X").First();
item1.RemoveMetadata("M");
project.ReevaluateIfNecessary();
ProjectItem item2 = project.GetItems("I").Where(i => i.EvaluatedInclude == "Y").First();
item2.RemoveMetadata("M");
string expected =
@"<Project>
<ItemDefinitionGroup>
<I>
<M>A</M>
</I>
</ItemDefinitionGroup>
<ItemGroup>
<I Include=""X"">
<M>%(M);B</M>
</I>
<I Include=""Y"" />
</ItemGroup>
</Project>";
Helpers.VerifyAssertProjectContent(expected, project.Xml, false);
project.ReevaluateIfNecessary();
item1 = project.GetItems("I").Where(i => i.EvaluatedInclude == "X").First();
Assert.Equal("A;B", item1.GetMetadataValue("M")); // "Invalid metadata after second removal"
item2 = project.GetItems("I").Where(i => i.EvaluatedInclude == "Y").First();
Assert.Equal("A", item2.GetMetadataValue("M")); // "Invalid metadata after second removal"
}
/// <summary>
/// Removes metadata referenced with % qualification.
/// </summary>
[Fact]
public void RemoveReferencedMetadata()
{
Project project = GetProject(
@"<Project>
<ItemGroup>
<I Include=""i"">
<M>m</M>
<N>%(I.M)</N>
</I>
</ItemGroup>
</Project>");
ProjectItem item = project.GetItems("I").First();
Assert.Equal("m", item.GetMetadataValue("N")); // "Wrong metadata value at startup"
item.RemoveMetadata("M");
string expected =
@"<Project>
<ItemGroup>
<I Include=""i"">
<N>%(I.M)</N>
</I>
</ItemGroup>
</Project>";
Helpers.VerifyAssertProjectContent(expected, project.Xml, false);
project.ReevaluateIfNecessary();
item = project.GetItems("I").First();
ProjectMetadata metadata = item.GetMetadata("N");
Assert.Equal("%(I.M)", metadata.UnevaluatedValue); // "Unevaluated value is wrong"
Assert.Equal(String.Empty, metadata.EvaluatedValue); // "Evaluated value is wrong"
}
/// <summary>
/// Removes duplicated property.
/// </summary>
[Fact]
public void RemoveProperty()
{
Project project = GetProject(
@"<Project>
<PropertyGroup>
<P>A</P>
<P>$(P)B</P>
</PropertyGroup>
</Project>");
ProjectProperty property = project.GetProperty("P");
project.RemoveProperty(property);
string expected =
@"<Project>
<PropertyGroup>
<P>A</P>
</PropertyGroup>
</Project>";
Helpers.VerifyAssertProjectContent(expected, project.Xml, false);
}
/// <summary>
/// Creates a new project the given contents.
/// </summary>
/// <param name="contents">The contents for the project.</param>
/// <returns>The project contents.</returns>
private Project GetProject(string contents)
{
using ProjectFromString projectFromString = new(contents);
Project project = projectFromString.Project;
return project;
}
}
}
|