//
// Author:
// Marek Sieradzki (marek.sieradzki@gmail.com)
+// Ankit Jain (jankit@novell.com)
//
// (C) 2005 Marek Sieradzki
+// Copyright 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
using NUnit.Framework;
using System.Text;
+using MBT = MonoTests.Microsoft.Build.Tasks;
+
namespace MonoTests.Microsoft.Build.BuildEngine {
class TestLogger : Logger {
*/
[Test]
- [ExpectedException (typeof (InvalidProjectFileException),
- @"The default XML namespace of the project must be the MSBuild XML namespace." +
- " If the project is authored in the MSBuild 2003 format, please add " +
- "xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\" to the <Project> element. " +
- "If the project has been authored in the old 1.0 or 1.2 format, please convert it to MSBuild 2003 format. ")]
public void TestAssignment1 ()
{
Engine engine;
"<Project></Project>";
engine = new Engine (Consts.BinPath);
+
DateTime time = DateTime.Now;
project = engine.CreateNewProject ();
- project.LoadXml (documentString);
+ try {
+ project.LoadXml (documentString);
+ } catch (InvalidProjectFileException) {
+ Assert.AreEqual (true, project.BuildEnabled, "A1");
+ Assert.AreEqual (String.Empty, project.DefaultTargets, "A2");
+ Assert.AreEqual (String.Empty, project.FullFileName, "A3");
+ Assert.AreEqual (false, project.IsDirty, "A4");
+ Assert.AreEqual (false, project.IsValidated, "A5");
+ Assert.AreEqual (engine, project.ParentEngine, "A6");
+ //Console.WriteLine ("time: {0} p.t: {1}", time, project.TimeOfLastDirty);
+ Assert.IsTrue (time <= project.TimeOfLastDirty, "A7");
+ Assert.IsTrue (String.Empty != project.Xml, "A8");
+ return;
+ }
- Assert.AreEqual (true, project.BuildEnabled, "A1");
- Assert.AreEqual (String.Empty, project.DefaultTargets, "A2");
- Assert.AreEqual (String.Empty, project.FullFileName, "A3");
- Assert.AreEqual (false, project.IsDirty, "A4");
- Assert.AreEqual (false, project.IsValidated, "A5");
- Assert.AreEqual (engine, project.ParentEngine, "A6");
- Assert.IsTrue (time <= project.TimeOfLastDirty, "A7");
- Assert.IsTrue (String.Empty != project.Xml, "A8");
+ Assert.Fail ("Expected InvalidProjectFileException");
}
[Test]
string documentString = @"
<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
- <Target Name='T' Inputs='Test\resources\TestTasks.cs' Outputs='Test\resources\TestTasks.dll'>
+ <Target Name='T'>
<Message Text='text' />
</Target>
</Project>
";
engine = new Engine (Consts.BinPath);
- TestLogger tl = new TestLogger ();
+ MBT.TestMessageLogger tl = new MBT.TestMessageLogger();
engine.RegisterLogger (tl);
project = engine.CreateNewProject ();
project.LoadXml (documentString);
project.Build ("T");
project.Build ("T");
- Assert.AreEqual (2, tl.TargetStartedEvents, "A1");
- Assert.AreEqual (2, tl.TargetFinishedEvents, "A2");
+ Assert.AreEqual (2, tl.TargetStarted, "A1");
+ Assert.AreEqual (2, tl.TargetFinished, "A2");
+ Assert.AreEqual (2, tl.TaskStarted, "A3");
+ Assert.AreEqual (2, tl.TaskFinished, "A4");
}
[Test]
string documentString = @"
<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
- <Target Name='T' Inputs='Test\resources\TestTasks.cs' Outputs='Test\resources\TestTasks.dll'>
+ <Target Name='T'>
<Message Text='text' />
</Target>
</Project>
";
engine = new Engine (Consts.BinPath);
- TestLogger tl = new TestLogger ();
+ MBT.TestMessageLogger tl = new MBT.TestMessageLogger ();
engine.RegisterLogger (tl);
project = engine.CreateNewProject ();
project.LoadXml (documentString);
project.Build (new string [1] { "T" }, null, BuildSettings.None);
project.Build (new string [1] { "T" }, null, BuildSettings.None);
- Assert.AreEqual (2, tl.TargetStartedEvents, "A1");
- Assert.AreEqual (2, tl.TargetFinishedEvents, "A2");
+ Assert.AreEqual (2, tl.TargetStarted, "A1");
+ Assert.AreEqual (2, tl.TargetFinished, "A2");
+ Assert.AreEqual (2, tl.TaskStarted, "A3");
+ Assert.AreEqual (2, tl.TaskFinished, "A4");
}
[Test]
- [Category ("NotWorking")]
public void TestBuild4 ()
{
Engine engine;
string documentString = @"
<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
- <Target Name='T' Inputs='Test\resources\TestTasks.cs' Outputs='Test\resources\TestTasks.dll'>
+ <Target Name='T'>
<Message Text='text' />
</Target>
</Project>
";
engine = new Engine (Consts.BinPath);
- TestLogger tl = new TestLogger ();
+ MBT.TestMessageLogger tl = new MBT.TestMessageLogger ();
engine.RegisterLogger (tl);
project = engine.CreateNewProject ();
project.LoadXml (documentString);
project.Build (new string [1] { "T" }, null, BuildSettings.DoNotResetPreviouslyBuiltTargets);
project.Build (new string [1] { "T" }, null, BuildSettings.DoNotResetPreviouslyBuiltTargets);
- Assert.AreEqual (1, tl.TargetStartedEvents, "A1");
- Assert.AreEqual (1, tl.TargetFinishedEvents, "A2");
+ Assert.AreEqual (1, tl.TargetStarted, "A1");
+ Assert.AreEqual (1, tl.TargetFinished, "A2");
+ Assert.AreEqual (1, tl.TaskStarted, "A3");
+ Assert.AreEqual (1, tl.TaskFinished, "A4");
}
[Test]
p1.RemoveItemGroup (null);
}
+ // The "BuildItemGroup" object specified does not belong to the correct "Project" object.
[Test]
- [ExpectedException (typeof (InvalidOperationException),
- "The \"BuildItemGroup\" object specified does not belong to the correct \"Project\" object.")]
+ [ExpectedException (typeof (InvalidOperationException))]
[Category ("NotWorking")]
public void TestRemoveItemGroup2 ()
{
project.RemoveItem (null);
}
+ // The object passed in is not part of the project.
[Test]
- [ExpectedException (typeof (InvalidOperationException),
- "The object passed in is not part of the project.")]
+ [ExpectedException (typeof (InvalidOperationException))]
public void TestRemoveItem2 ()
{
Engine engine;
project.RemoveItem (new BuildItem ("name", "include"));
}
+ // The "BuildItemGroup" object specified does not belong to the correct "Project" object.
[Test]
- [ExpectedException (typeof (InvalidOperationException),
- "The \"BuildItemGroup\" object specified does not belong to the correct \"Project\" object.")]
+ [ExpectedException (typeof (InvalidOperationException))]
public void TestRemoveItem3 ()
{
Engine engine;
}
[Test]
- [Category ("NotWorking")]
public void TestResetBuildStatus ()
{
Engine engine;
project.Build ("T");
project.ResetBuildStatus ();
project.Build (new string [1] { "T" }, null, BuildSettings.DoNotResetPreviouslyBuiltTargets);
+ project.ResetBuildStatus ();
+ project.Build (new string [1] { "T" }, null, BuildSettings.DoNotResetPreviouslyBuiltTargets);
- Assert.AreEqual (2, tl.TargetStartedEvents, "A1");
- Assert.AreEqual (2, tl.TargetFinishedEvents, "A1");
+ Assert.AreEqual (3, tl.TargetStartedEvents, "A1");
+ Assert.AreEqual (3, tl.TargetFinishedEvents, "A1");
}
[Test]
[Test]
public void TestBatchedMetadataRef1 ()
{
+ //test for multiple items with same metadata also
string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
<UsingTask TaskName=""BatchingTestTask"" AssemblyFile=""Test/resources/TestTasks.dll"" />
<ItemGroup>
<Coll1 Include=""A1""><Name>Abc</Name></Coll1>
<Coll1 Include=""A2""><Name>Def</Name></Coll1>
<Coll1 Include=""A3""><Name>Xyz</Name></Coll1>
+ <Coll1 Include=""A4""><Name>Xyz</Name></Coll1>
<Coll2 Include=""B1""></Coll2>
</ItemGroup>
<Target Name=""ShowMessage"">
<Coll1 Include=""A1""><Name>Abc</Name></Coll1>
<Coll1 Include=""A2""><Name>Def</Name></Coll1>
<Coll1 Include=""A3""><Name>Xyz</Name></Coll1>
+ <Coll1 Include=""A4""><Name>Abc</Name></Coll1>
<Coll2 Include=""B1""><Name>Bar</Name></Coll2>
+ <Coll2 Include=""B2""><Name>Bar</Name></Coll2>
</ItemGroup>
<Target Name=""ShowMessage"">
<BatchingTestTask Sources=""%(Name)"" Strings=""@(Coll2)"">
<Coll1 Include=""A1""><Name>Abc</Name></Coll1>
<Coll1 Include=""A2""><Name>Def</Name></Coll1>
<Coll1 Include=""A3""><Name>Xyz</Name></Coll1>
+ <Coll1 Include=""A4""><Name>Abc</Name></Coll1>
<Coll2 Include=""B1""><Name>Bar</Name></Coll2>
+ <Coll2 Include=""B2""><Name>Bar</Name></Coll2>
</ItemGroup>
<Target Name=""ShowMessage"">
- <BatchingTestTask SingleString=""%(Coll2.Name)"" >
+ <BatchingTestTask SingleTaskItem=""%(Coll2.Name)"" >
<Output TaskParameter=""SingleStringOutput"" ItemName=""FinalList"" />
</BatchingTestTask>
<Message Text=""Msg: %(Coll1.Name)"" />
<Coll2 Include=""B1""><Name>Bar</Name></Coll2>
</ItemGroup>
<Target Name=""ShowMessage"">
- <BatchingTestTask SingleString=""%(Coll3.Name)"" >
+ <BatchingTestTask SingleTaskItem=""%(Coll3.Name)"" >
<Output TaskParameter=""SingleStringOutput"" ItemName=""FinalList"" />
</BatchingTestTask>
</Target>
Assert.AreEqual (0, include.Count, "A2");
}
+ [Test]
+ public void TestBatchedMetadataRef5 ()
+ {
+ string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <UsingTask TaskName=""BatchingTestTask"" AssemblyFile=""Test/resources/TestTasks.dll"" />
+ <ItemGroup>
+ <Coll1 Include=""A1""><Name>Abc</Name></Coll1>
+ <Coll1 Include=""A2""><Name>Def</Name></Coll1>
+ <Coll1 Include=""A3""><Name>Xyz</Name></Coll1>
+ <Coll2 Include=""B1""><Name>Bar</Name></Coll2>
+ </ItemGroup>
+ <Target Name=""ShowMessage"">
+ <Message Text=""Coll1: @(Coll1->'Foo%(Name)Bar')"" />
+ <BatchingTestTask Sources=""@(Coll1->'Foo%(Name)Bar')"" >
+ <Output TaskParameter=""Output"" ItemName=""FinalList"" />
+ </BatchingTestTask>
+ </Target>
+ </Project>";
+
+ Engine engine = new Engine (Consts.BinPath);
+ Project project = engine.CreateNewProject ();
+ MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+ new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+ engine.RegisterLogger (logger);
+
+ project.LoadXml (projectString);
+ bool result = project.Build ("ShowMessage");
+ if (!result) {
+ logger.DumpMessages ();
+ Assert.Fail ("A1: Build failed");
+ }
+ BuildItemGroup include = project.GetEvaluatedItemsByName ("FinalList");
+ Assert.AreEqual (3, include.Count, "A2");
+ }
+
+ [Test]
+ public void TestBatchedMetadataRefInOutput () {
+ string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <UsingTask TaskName=""BatchingTestTask"" AssemblyFile=""Test/resources/TestTasks.dll"" />
+ <ItemGroup>
+ <Coll1 Include=""A1""><Name>Abc</Name></Coll1>
+ <Coll1 Include=""A2""><Name>Def</Name></Coll1>
+ <Coll1 Include=""A3""><Name>Abc</Name></Coll1>
+ <Coll1 Include=""B1""><Name>Bar</Name></Coll1>
+ </ItemGroup>
+ <Target Name=""ShowMessage"">
+ <BatchingTestTask Sources=""@(Coll1)"" >
+ <Output TaskParameter=""Output"" ItemName=""AbcItems"" Condition=""'%(Coll1.Name)' == 'Abc'""/>
+ <Output TaskParameter=""Output"" ItemName=""NonAbcItems"" Condition=""'%(Coll1.Name)' != 'Abc'""/>
+ </BatchingTestTask>
+ <Message Text='AbcItems: @(AbcItems)' />
+ <Message Text='NonAbcItems: @(NonAbcItems)' />
+ </Target>
+ </Project>";
+
+ Engine engine = new Engine (Consts.BinPath);
+ Project project = engine.CreateNewProject ();
+ MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+ new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+ engine.RegisterLogger (logger);
+
+ project.LoadXml (projectString);
+ bool result = project.Build ("ShowMessage");
+ if (!result) {
+ logger.DumpMessages ();
+ Assert.Fail ("A1: Build failed");
+ }
+
+ logger.CheckLoggedMessageHead ("AbcItems: A1;A3", "A2");
+ logger.CheckLoggedMessageHead ("NonAbcItems: A2;B1", "A2");
+
+ if (logger.NormalMessageCount != 0) {
+ logger.DumpMessages ();
+ Assert.Fail ("Unexpected extra messages found");
+ }
+ }
+
+ [Test]
+ public void TestInitialTargets ()
+ {
+ Engine engine = new Engine (Consts.BinPath);
+ Project project = engine.CreateNewProject ();
+
+ project.LoadXml (@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" InitialTargets=""pre "">
+ <Target Name=""boo"">
+ <Message Text=""Executing boo target""/>
+ </Target>
+ <Target Name=""pre"">
+ <Message Text=""Executing pre target""/>
+ </Target>
+ </Project>");
+
+ MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+ new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+ engine.RegisterLogger (logger);
+
+ try {
+ Assert.IsTrue (project.Build (), "Build failed");
+
+ logger.CheckLoggedMessageHead ("Executing pre target", "A1");
+ logger.CheckLoggedMessageHead ("Executing boo target", "A2");
+
+ Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
+ } catch {
+ logger.DumpMessages ();
+ throw;
+ }
+ }
+
+ [Test]
+ public void TestInitialTargetsWithImports () {
+ Engine engine = new Engine (Consts.BinPath);
+ Project project = engine.CreateNewProject ();
+
+ string second = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" InitialTargets=""One "">
+ <Target Name=""One"">
+ <Message Text='Executing Second::One target'/>
+ </Target>
+ <Import Project='third.proj'/>
+ </Project>
+";
+ using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "second.proj")))) {
+ sw.Write (second);
+ }
+
+ string third = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" InitialTargets=""Two"">
+ <Target Name=""Two"">
+ <Message Text='Executing Third::Two target'/>
+ </Target>
+ </Project>
+";
+ using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "third.proj")))) {
+ sw.Write (third);
+ }
+
+ project.LoadXml (@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" InitialTargets=""pre"">
+ <Target Name=""boo"">
+ <Message Text=""Executing boo target""/>
+ </Target>
+ <Target Name=""pre"">
+ <Message Text=""Executing pre target""/>
+ </Target>
+ <Import Project='Test/resources/second.proj'/>
+ </Project>");
+
+ MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+ new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+ engine.RegisterLogger (logger);
+
+ try {
+ Assert.IsTrue (project.Build (), "Build failed");
+
+ logger.CheckLoggedMessageHead ("Executing pre target", "A1");
+ logger.CheckLoggedMessageHead ("Executing Second::One target", "A2");
+ logger.CheckLoggedMessageHead ("Executing Third::Two target", "A3");
+ logger.CheckLoggedMessageHead ("Executing boo target", "A4");
+ Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
+
+ Assert.AreEqual ("pre; One; Two", project.InitialTargets, "List of initial targets");
+ } catch {
+ logger.DumpMessages ();
+ throw;
+ }
+ }
+
+ [Test]
+ public void TestDefaultTargets () {
+ Engine engine = new Engine (Consts.BinPath);
+ Project project = engine.CreateNewProject ();
+
+ project.LoadXml (@"<Project DefaultTargets='pre' xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" >
+ <Target Name=""boo"">
+ <Message Text=""Executing boo target""/>
+ </Target>
+ <Target Name=""pre"">
+ <Message Text=""Executing pre target""/>
+ </Target>
+ </Project>");
+
+ MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+ new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+ engine.RegisterLogger (logger);
+
+ try {
+ Assert.IsTrue (project.Build (), "Build failed");
+
+ logger.CheckLoggedMessageHead ("Executing pre target", "A1");
+ Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
+
+ Assert.AreEqual ("pre", project.DefaultTargets, "Default targets");
+ } catch {
+ logger.DumpMessages ();
+ throw;
+ }
+ }
+
+
+ [Test]
+ public void TestDefaultTargetsWithImports () {
+ Engine engine = new Engine (Consts.BinPath);
+ Project project = engine.CreateNewProject ();
+
+ string second = @"<Project DefaultTargets='One' xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <Target Name=""One"">
+ <Message Text='Executing Second::One target'/>
+ </Target>
+ </Project>";
+ using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "second.proj")))) {
+ sw.Write (second);
+ }
+
+ project.LoadXml (@"<Project DefaultTargets='pre' xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" >
+ <Target Name=""boo"">
+ <Message Text=""Executing boo target""/>
+ </Target>
+ <Target Name=""pre"">
+ <Message Text=""Executing pre target""/>
+ </Target>
+ <Import Project='Test/resources/second.proj'/>
+ </Project>");
+
+ MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+ new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+ engine.RegisterLogger (logger);
+
+ try {
+ Assert.IsTrue (project.Build (), "Build failed");
+
+ logger.CheckLoggedMessageHead ("Executing pre target", "A1");
+ Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
+
+ Assert.AreEqual ("pre", project.DefaultTargets, "Default targets");
+ } catch {
+ logger.DumpMessages ();
+ throw;
+ }
+ }
+
+ [Test]
+ public void TestNoDefaultTargetsWithImports () {
+ Engine engine = new Engine (Consts.BinPath);
+ Project project = engine.CreateNewProject ();
+
+
+ string second = @"<Project DefaultTargets='; One ; Two' xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <Target Name=""One"">
+ <Message Text='Executing Second::One target'/>
+ </Target>
+ <Target Name=""Two"">
+ <Message Text='Executing Second::Two target'/>
+ </Target>
+
+ </Project>";
+ using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "second.proj")))) {
+ sw.Write (second);
+ }
+
+ project.LoadXml (@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" >
+ <Target Name=""boo"">
+ <Message Text=""Executing boo target""/>
+ </Target>
+ <Target Name=""pre"">
+ <Message Text=""Executing pre target""/>
+ </Target>
+ <Import Project='Test/resources/second.proj'/>
+ </Project>");
+
+ MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+ new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+ engine.RegisterLogger (logger);
+
+ try {
+ Assert.IsTrue (project.Build (), "Build failed");
+
+ logger.CheckLoggedMessageHead ("Executing Second::One target", "A1");
+ logger.CheckLoggedMessageHead ("Executing Second::Two target", "A2");
+ Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
+
+ Assert.AreEqual ("One; Two", project.DefaultTargets, "Default targets");
+ } catch {
+ logger.DumpMessages ();
+ throw;
+ }
+ }
+
+ [Test]
+ public void TestNoDefaultTargets () {
+ Engine engine = new Engine (Consts.BinPath);
+ Project project = engine.CreateNewProject ();
+
+ project.LoadXml (@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" >
+ <Target Name=""boo"">
+ <Message Text=""Executing boo target""/>
+ </Target>
+ <Target Name=""pre"">
+ <Message Text=""Executing pre target""/>
+ </Target>
+ </Project>");
+
+ MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+ new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+ engine.RegisterLogger (logger);
+
+ try {
+ Assert.IsTrue (project.Build (), "Build failed");
+
+ logger.CheckLoggedMessageHead ("Executing boo target", "A1");
+ Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
+
+ Assert.AreEqual ("", project.DefaultTargets, "Default targets");
+ } catch {
+ logger.DumpMessages ();
+ throw;
+ }
+ }
+
+ [Test]
+ public void TestPropertiesFromImportedProjects ()
+ {
+ Engine engine = new Engine (Consts.BinPath);
+ Project project = engine.CreateNewProject ();
+
+ string second = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + @">
+ <PropertyGroup>
+ <Prop1>InitialVal</Prop1>
+ </PropertyGroup>
+ <ItemGroup>
+ <Second Include=""$(ThirdProp):Third""/>
+ </ItemGroup>
+
+ <Target Name=""Main"">
+ <Message Text=""Prop1: $(Prop1) FooItem: @(FooItem)""/>
+ <Message Text=""Second: @(Second) ThirdProp: $(ThirdProp)""/>
+ </Target>
+ <Import Project=""third.proj""/>
+</Project>";
+ using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "second.proj")))) {
+ sw.Write (second);
+ }
+
+ string third = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + @">
+ <PropertyGroup>
+ <ThirdProp>Third Value</ThirdProp>
+ </PropertyGroup>
+</Project>";
+ using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "third.proj")))) {
+ sw.Write (third);
+ }
+
+ project.LoadXml (@"<Project InitialTargets=""Main"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <ItemGroup>
+ <FooItem Include=""$(Prop1):Something""/>
+ </ItemGroup>
+
+ <Import Project=""Test/resources/second.proj""/>
+</Project>");
+
+ MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+ new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+ engine.RegisterLogger (logger);
+
+ try {
+ Assert.IsTrue (project.Build (), "Build failed");
+
+ logger.CheckLoggedMessageHead ("Prop1: InitialVal FooItem: InitialVal:Something", "A1");
+ logger.CheckLoggedMessageHead ("Second: Third Value:Third ThirdProp: Third Value", "A2");
+
+ Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
+ } catch {
+ logger.DumpMessages ();
+ throw;
+ }
+ }
+
+ [Test]
+ public void TestMSBuildThisProperties ()
+ {
+ Engine engine = new Engine (Consts.BinPath);
+ Project project = engine.CreateNewProject ();
+
+ string base_dir = Path.GetFullPath (Path.Combine ("Test", "resources")) + Path.DirectorySeparatorChar;
+ string tmp_dir = Path.GetFullPath (Path.Combine (base_dir, "tmp")) + Path.DirectorySeparatorChar;
+
+ string first_project = Path.Combine (base_dir, "first.proj");
+ string second_project = Path.Combine (tmp_dir, "second.proj");
+ string third_project = Path.Combine (tmp_dir, "third.proj");
+
+ string first = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + @">
+ <PropertyGroup>
+ <FooInMain>$(MSBuildThisFileDirectory)</FooInMain>
+ </PropertyGroup>
+ <ItemGroup>
+ <ItemInMain Include=""$(MSBuildThisFileFullPath)"" />
+ </ItemGroup>
+ <Import Project=""tmp\second.proj""/>
+ </Project>";
+
+ string second = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + @">
+ <PropertyGroup>
+ <FooInImport1>$(MSBuildThisFileDirectory)</FooInImport1>
+ </PropertyGroup>
+ <PropertyGroup>
+ <FooInImport2>$(MSBuildThisFileDirectory)</FooInImport2>
+ </PropertyGroup>
+ <ItemGroup>
+ <ItemInImport1 Include=""$(MSBuildThisFileFullPath)"" />
+ </ItemGroup>
+
+ <Import Project=""third.proj""/>
+ </Project>";
+
+ string third = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + @">
+ <PropertyGroup>
+ <FooInTwo>$(MSBuildThisFileFullPath)</FooInTwo>
+ </PropertyGroup>
+ <ItemGroup>
+ <ItemInTwo Include=""$(MSBuildThisFileFullPath)"" />
+ </ItemGroup>
+
+ <Target Name=""TargetInTwo"">
+ <Message Text=""FooInMain: $(FooInMain)""/>
+ <Message Text=""FooInImport1: $(FooInImport1)""/>
+ <Message Text=""FooInImport2: $(FooInImport2)""/>
+ <Message Text=""FooInTwo: $(FooInTwo)""/>
+
+ <Message Text=""ItemInMain: %(ItemInMain.Identity)""/>
+ <Message Text=""ItemInImport1: %(ItemInImport1.Identity)""/>
+ <Message Text=""ItemInTwo: %(ItemInTwo.Identity)""/>
+ <Message Text=""Full path: $(MSBuildThisFileFullPath)""/>
+ </Target>
+ </Project>";
+
+ File.WriteAllText (first_project, first);
+
+ Directory.CreateDirectory (Path.Combine (base_dir, "tmp"));
+ File.WriteAllText (second_project, second);
+ File.WriteAllText (third_project, third);
+
+ MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+ new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+ engine.RegisterLogger (logger);
+
+ project.Load (first_project);
+ try {
+ Assert.IsTrue (project.Build (), "Build failed");
+
+ logger.CheckLoggedMessageHead ("FooInMain: " + base_dir, "A1");
+ logger.CheckLoggedMessageHead ("FooInImport1: " + tmp_dir, "A2");
+ logger.CheckLoggedMessageHead ("FooInImport2: " + tmp_dir, "A3");
+ logger.CheckLoggedMessageHead ("FooInTwo: " + third_project, "A4");
+ logger.CheckLoggedMessageHead ("ItemInMain: " + first_project, "A5");
+ logger.CheckLoggedMessageHead ("ItemInImport1: " + second_project, "A6");
+ logger.CheckLoggedMessageHead ("ItemInTwo: " + third_project, "A7");
+ logger.CheckLoggedMessageHead ("Full path: " + third_project, "A8");
+
+ Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
+ } catch {
+ logger.DumpMessages ();
+ throw;
+ } finally {
+ File.Delete (first_project);
+ File.Delete (second_project);
+ File.Delete (third_project);
+ }
+ }
+
+ [Test]
+ public void TestRequiredTask_String1 ()
+ {
+ CheckProjectForRequiredTests ("RequiredTestTask_String", "@(NonExistant)",
+ false, "Should've failed: No value specified for required field - 'Property' of RequiredTestTask_String", null);
+ }
+
+ [Test]
+ public void TestRequiredTask_String2 ()
+ {
+ CheckProjectForRequiredTests ("RequiredTestTask_String", "$(NonExistant)",
+ false, "Should've failed: No value specified for required field - 'Property' of RequiredTestTask_String", null);
+ }
+
+ [Test]
+ public void TestRequiredTask_Strings1 () {
+ CheckProjectForRequiredTests ("RequiredTestTask_Strings", "@(NonExistant)",
+ true, "Build failed", "0");
+ }
+
+ [Test]
+ public void TestRequiredTask_Strings2 () {
+ CheckProjectForRequiredTests ("RequiredTestTask_Strings", "$(NonExistant)",
+ true, "Build failed", "0");
+ }
+
+ [Test]
+ public void TestRequiredTask_Strings3 () {
+ CheckProjectForRequiredTests ("RequiredTestTask_Strings", "%(NonExistant.Md)",
+ true, "Build failed", "0");
+ }
+
+ [Test]
+ public void TestRequiredTask_Strings4 () {
+ CheckProjectForRequiredTests ("RequiredTestTask_Strings", " %(NonExistant.Md)",
+ true, "Build failed", "0");
+ }
+
+ [Test]
+ public void TestRequiredTask_Ints1 () {
+ CheckProjectForRequiredTests ("RequiredTestTask_IntArray", "@(NonExistant)",
+ true, "Build failed", "count: 0");
+ }
+
+ [Test]
+ public void TestRequiredTask_Ints2 () {
+ CheckProjectForRequiredTests ("RequiredTestTask_IntArray", "$(NonExistant)",
+ true, "Build failed", "count: 0");
+ }
+
+ [Test]
+ public void TestRequiredTask_OtherObjectsArray () {
+ CheckProjectForRequiredTests ("RequiredTestTask_OtherObjectArray", "@(NonExistant)",
+ false, "Should've failed: ObjectArray type not supported as a property type", null);
+ }
+
+ [Test]
+ public void TestRequiredTask_OtherObject () {
+ CheckProjectForRequiredTests ("RequiredTestTask_OtherObjectArray", "@(NonExistant)",
+ false, "Should've failed: ObjectArray type not supported as a property type", null);
+ }
+
+ [Test]
+ public void TestRequiredTask_MyTaskItems1 () {
+ CheckProjectForRequiredTests ("RequiredTestTask_MyTaskItemArray", "@(NonExistant)",
+ false, "Should've failed: ObjectArray type not supported as a property type", null);
+ }
+
+ [Test]
+ public void TestRequiredTask_TaskItem1 ()
+ {
+ Project p = CheckProjectForRequiredTests ("RequiredTestTask_TaskItem", "@(NonExistant)",
+ false, "Should've failed: No value specified for required field - 'Property' of RequiredTestTask_TaskItem", null);
+ }
+
+ [Test]
+ public void TestRequiredTask_TaskItem2 ()
+ {
+ Project p = CheckProjectForRequiredTests ("RequiredTestTask_TaskItem", "$(NonExistant)",
+ false, "Should've failed: No value specified for required field - 'Property' of RequiredTestTask_TaskItem", null);
+ }
+
+ [Test]
+ public void TestRequiredTask_TaskItemArray1 ()
+ {
+ Project p = CheckProjectForRequiredTests ("RequiredTestTask_TaskItems", "@(NonExistant)",
+ true, "Build failed", "count: 0");
+
+ BuildItemGroup group = p.GetEvaluatedItemsByName ("OutItem");
+ Assert.AreEqual (1, group.Count, "A2");
+ Assert.AreEqual ("count: 0", group [0].FinalItemSpec, "A3");
+ }
+
+ [Test]
+ public void TestRequiredTask_TaskItemArray2 ()
+ {
+ Project p = CheckProjectForRequiredTests ("RequiredTestTask_TaskItems", "$(NonExistant)",
+ true, "Build failed", "count: 0");
+
+ BuildItemGroup group = p.GetEvaluatedItemsByName ("OutItem");
+ Assert.AreEqual (1, group.Count, "A2");
+ Assert.AreEqual ("count: 0", group [0].FinalItemSpec, "A3");
+ }
+
+ [Test]
+ public void TestRequiredTask_TaskItemArray3 ()
+ {
+ Project p = CheckProjectForRequiredTests ("RequiredTestTask_IntArray", "$(NonExistant)",
+ true, "Build failed", "count: 0");
+
+ BuildItemGroup group = p.GetEvaluatedItemsByName ("OutItem");
+ Assert.AreEqual (1, group.Count, "A2");
+ Assert.AreEqual ("count: 0", group [0].FinalItemSpec, "A3");
+ }
+
+ [Test]
+ public void TestRequiredTask_TaskItemArray4 () {
+ Project p = CheckProjectForRequiredTests ("RequiredTestTask_IntArray", "%(NonExistant.Md)",
+ true, "Build failed", "count: 0");
+
+ BuildItemGroup group = p.GetEvaluatedItemsByName ("OutItem");
+ Assert.AreEqual (1, group.Count, "A2");
+ Assert.AreEqual ("count: 0", group[0].FinalItemSpec, "A3");
+ }
+
+ [Test]
+ public void TestRequiredTask_TaskItemArray5 () {
+ // with extra space in prop value
+ Project p = CheckProjectForRequiredTests ("RequiredTestTask_IntArray", " %(NonExistant.Md)",
+ true, "Build failed", "count: 0");
+
+ BuildItemGroup group = p.GetEvaluatedItemsByName ("OutItem");
+ Assert.AreEqual (1, group.Count, "A2");
+ Assert.AreEqual ("count: 0", group[0].FinalItemSpec, "A3");
+ }
+
+
+ [Test]
+ public void TestCaseSensitivityOfProjectElements ()
+ {
+ string projectXml = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + @">
+ <ItemGroup>
+ <Abc Include=""foo"">
+ <MetaDaTA1>md1</MetaDaTA1>
+ <METadata2>md2</METadata2>
+ </Abc>
+ <Abc Include=""FOO"">
+ <MetaDaTA1>MD1 caps</MetaDaTA1>
+ <METadata2>MD2 caps</METadata2>
+ </Abc>
+ <Abc Include=""hmm"">
+ <MetaDaTA1>Md1 CAPS</MetaDaTA1>
+ <METadata2>MD2 CAPS</METadata2>
+ </Abc>
+ <Abc Include=""bar"">
+ <MeTAdata1>md3</MeTAdata1>
+ <Metadata2>md4</Metadata2>
+ </Abc>
+ </ItemGroup>
+ <PropertyGroup><ProP1>ValueProp</ProP1></PropertyGroup>
+ <Target Name=""Main"">
+ <MesSAGE Text=""Full item: @(ABC)""/>
+ <MEssaGE Text=""metadata1 :%(AbC.MetaDATA1) metadata2: %(ABC.MetaDaTa2)""/>
+ <MEssaGE Text=""metadata2 : %(AbC.MetaDAta2)""/>
+ <MEssaGE Text=""Abc identity: %(ABC.IDENTitY)""/>
+ <MEssaGE Text=""prop1 : $(pROp1)""/>
+ </Target>
+</Project>
+";
+ Engine engine = new Engine (Consts.BinPath);
+ Project project = engine.CreateNewProject ();
+ MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+ new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+ engine.RegisterLogger (logger);
+
+ project.LoadXml (projectXml);
+ bool result = project.Build ("Main");
+ if (!result) {
+ logger.DumpMessages ();
+ Assert.Fail ("A1: Build failed");
+ }
+
+ logger.CheckLoggedMessageHead ("Full item: foo;FOO;hmm;bar", "#A2");
+ logger.CheckLoggedMessageHead ("metadata1 :md1 metadata2: md2", "#A3");
+ logger.CheckLoggedMessageHead ("metadata1 :MD1 caps metadata2: MD2 caps", "#A4");
+ logger.CheckLoggedMessageHead ("metadata1 :md3 metadata2: md4", "#A5");
+ logger.CheckLoggedMessageHead ("metadata2 : md2", "#A6");
+ logger.CheckLoggedMessageHead ("metadata2 : MD2 caps", "#A7");
+ logger.CheckLoggedMessageHead ("metadata2 : md4", "#A8");
+ logger.CheckLoggedMessageHead ("Abc identity: foo", "#A9");
+ logger.CheckLoggedMessageHead ("Abc identity: hmm", "#A10");
+ logger.CheckLoggedMessageHead ("Abc identity: bar", "#A11");
+ logger.CheckLoggedMessageHead ("prop1 : ValueProp", "#A12");
+
+ Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
+
+ }
+
+ // full solution test
+ //[Test]
+ public void TestBuildSolutionProject ()
+ {
+ string basepath = Path.Combine ("Test", Path.Combine ("resources", "Project01"));
+ string [] project_dirs = new string [] {
+ Path.Combine (basepath, "Lib4"),
+ Path.Combine (basepath, "Lib3"),
+ Path.Combine (basepath, "Lib2"),
+ Path.Combine (basepath, "Lib1"),
+ Path.Combine (basepath, "Project01")
+ };
+ string debug_extn = Consts.RunningOnMono () ? ".dll.mdb" : ".pdb";
+
+ // List of expected output files
+ // Lib3
+ string [] [] project_files = new string [5][] {
+ new string [] { "Lib4.dll", "Lib4" + debug_extn },
+ new string [] { "Lib3.dll" , "Lib3" + debug_extn },
+ // Lib2
+ new string [] {
+ "Lib2.dll", "Lib2" + debug_extn,
+ "lib2_folder/Lib2.deploy.txt",
+ Path.Combine ("fr-CA", "Lib2.resources.dll"),
+ Path.Combine ("fr-FR", "Lib2.resources.dll"),
+ "Lib4.dll", "Lib4" + debug_extn
+ },
+
+ // lib1
+ new string [] {
+ // lib1 files
+ "Lib1.dll", "Lib2" + debug_extn,
+ "Lib1.deploy.txt",
+ Path.Combine ("fr-CA", "Lib1.resources.dll"),
+ Path.Combine ("fr-FR", "Lib1.resources.dll"),
+ Path.Combine ("en-US", "Lib1.resources.dll"),
+ // lib2 files
+ "Lib2.dll", "Lib2" + debug_extn,
+ "lib2_folder/Lib2.deploy.txt",
+ Path.Combine ("fr-CA", "Lib2.resources.dll"),
+ Path.Combine ("fr-FR", "Lib2.resources.dll"),
+ // lib3 files
+ "Lib3.dll", "Lib3" + debug_extn,
+ "Lib4.dll", "Lib4" + debug_extn
+ },
+
+ new string [] {
+ "Project01.exe",
+ "Project01" + (Consts.RunningOnMono () ? ".exe.mdb" : ".pdb"),
+ // lib1 files
+ "Lib1.dll", "Lib1" + debug_extn,
+ "Lib1.deploy.txt",
+ Path.Combine ("fr-CA", "Lib1.resources.dll"),
+ Path.Combine ("fr-FR", "Lib1.resources.dll"),
+ Path.Combine ("en-US", "Lib1.resources.dll"),
+ // lib2 files
+ "Lib2.dll", "Lib2" + debug_extn,
+ "lib2_folder/Lib2.deploy.txt",
+ Path.Combine ("fr-CA", "Lib2.resources.dll"),
+ Path.Combine ("fr-FR", "Lib2.resources.dll"),
+ "Lib4.dll", "Lib4" + debug_extn,
+ }
+ };
+
+ // Cleanup
+ for (int i = 0; i < project_dirs.Length; i ++) {
+ string bin_path = Path.Combine (project_dirs [i], Path.Combine ("bin", "Debug"));
+ string obj_path = Path.Combine (project_dirs [i], Path.Combine ("obj", "Debug"));
+
+ DeleteAllInDir (bin_path);
+
+ DeleteAllInDir (obj_path);
+ }
+
+ Engine engine = new Engine (Consts.BinPath);
+ MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+ new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+ engine.RegisterLogger (logger);
+
+ engine.GlobalProperties = new BuildPropertyGroup ();
+ engine.GlobalProperties.SetProperty ("TreatWarningsAsErrors", "false");
+
+ Project project = engine.CreateNewProject ();
+ project.Load (Path.Combine (basepath, "Project01.sln.proj"));
+
+ bool result = project.Build ();
+ if (!result) {
+ logger.DumpMessages ();
+ Assert.Fail ("Build failed");
+ }
+
+ // We check only the output dir, not the 'obj'
+ string debug = Path.Combine ("bin", "Debug");
+ for (int i = 0; i < project_dirs.Length; i++) {
+ CheckFilesExistInDir (Path.Combine (project_dirs [i], debug),
+ project_files [i]);
+ }
+ }
+
+ void DeleteAllInDir (string path)
+ {
+ if (!Directory.Exists (path))
+ return;
+
+ foreach (string file in Directory.GetFiles (path))
+ File.Delete (file);
+ Directory.Delete (path, true);
+ }
+
+ void CheckFilesExistInDir (string dir, params string [] files)
+ {
+ foreach (string file in files) {
+ string path = Path.Combine (dir, file);
+ Assert.IsTrue (File.Exists (path),
+ String.Format ("Expected to find file {0}", path));
+ }
+ }
+
+ Project CheckProjectForRequiredTests (string taskname, string property_arg, bool expected_result, string error_msg,
+ string expected_output_msg)
+ {
+ string projectString = String.Format (@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <UsingTask TaskName=""{0}"" AssemblyFile=""Test/resources/TestTasks.dll"" />
+ <Target Name=""foo"">
+ <{0} Property=""{1}"">
+ <Output TaskParameter=""Output"" ItemName=""OutItem""/>
+ </{0}>
+ <Message Text='@(OutItem)'/>
+ </Target>
+ </Project>", taskname, property_arg);
+
+ Engine engine = new Engine (Consts.BinPath);
+ MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+ new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+ engine.RegisterLogger (logger);
+ Project project = engine.CreateNewProject ();
+ project.LoadXml (projectString);
+ try {
+ Assert.AreEqual (expected_result, project.Build (), error_msg);
+ if (expected_result) {
+ logger.CheckLoggedMessageHead (expected_output_msg, "A");
+ Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected messages found");
+ }
+ } catch {
+ logger.DumpMessages ();
+ }
+ return project;
+ }
+
static void CheckBuildItem (BuildItem item, string name, string [,] metadata, string finalItemSpec, string prefix)
{
Assert.AreEqual (name, item.Name, prefix + "#1");