[xbuild] Add support for Before/AfterTargets.
[mono.git] / mcs / class / Microsoft.Build.Engine / Test / Microsoft.Build.BuildEngine / TargetTest.cs
index 734e25af86640cd9898d021bfef1058d39a97a04..ae0f18e78c914a7692c55064c16fb46d162fb7da 100644 (file)
@@ -31,6 +31,7 @@ using Microsoft.Build.BuildEngine;
 using Microsoft.Build.Framework;
 using Microsoft.Build.Utilities;
 using NUnit.Framework;
+using System.IO;
 
 namespace MonoTests.Microsoft.Build.BuildEngine {
        [TestFixture]
@@ -92,7 +93,6 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
                }
 
                [Test]
-               [Category ("NotWorking")]
                public void TestAddNewTask1 ()
                {
                         string documentString = @"
@@ -117,7 +117,6 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
 
                [Test]
                [ExpectedException (typeof (ArgumentNullException))]
-               [Category ("NotWorking")]
                public void TestAddNewTask2 ()
                {
                         string documentString = @"
@@ -166,6 +165,27 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
                        Assert.IsFalse (e.MoveNext (), "A3");
                }
 
+               [Test]
+               [ExpectedException (typeof (InvalidProjectFileException))]
+               public void TestOnError1 ()
+               {
+                       Engine engine;
+                       Project project;
+
+                       string documentString = @"
+                               <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+                                       <Target Name='A'>
+                                               <OnError ExecuteTargets='B' />
+                                               <Error Text='text' />
+                                       </Target>
+                               </Project>
+                       ";
+
+                       engine = new Engine (Consts.BinPath);
+                       project = engine.CreateNewProject ();
+                       project.LoadXml (documentString);
+               }
+
                [Test]
                public void TestRemoveTask1 ()
                {
@@ -215,5 +235,246 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
                        project.Targets.CopyTo (t, 0);
                        t [0].RemoveTask (null);
                }
+
+               [Test]
+               public void TestTargetOutputs1 ()
+               {
+                       Engine engine;
+                       Project project;
+
+                       string documentString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+                       <ItemGroup>
+                               <fruit Include=""apple""/>
+                               <fruit Include=""rhubarb""/>
+                               <fruit Include=""apricot""/>
+                       </ItemGroup>
+
+                       <Target Name=""Main"">
+                               <CallTarget Targets=""foo"">
+                                       <Output TaskParameter=""TargetOutputs"" ItemName=""AllOut""/>
+                               </CallTarget>
+
+                               <CallTarget Targets=""foo"">
+                                       <Output TaskParameter=""TargetOutputs"" ItemName=""AllOut""/>
+                               </CallTarget>
+                               <Message Text=""AllOut: @(AllOut)""/>
+                       </Target>
+
+                       <Target Name=""foo"" Outputs=""@(FooItem)"">
+                               <Message Text=""foo called""/>
+                               <CreateItem Include=""%(fruit.Identity)"">
+                                       <Output TaskParameter=""Include"" ItemName=""FooItem""/>
+                               </CreateItem>
+                               <Message Text=""FooItem: @(FooItem)""/>
+                       </Target>
+               </Project>";
+
+                       engine = new Engine (Consts.BinPath);
+                       project = engine.CreateNewProject ();
+                       project.LoadXml (documentString);
+
+                       MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+                               new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+                       engine.RegisterLogger (logger);
+
+                       bool result = project.Build ("Main");
+                       if (!result) {
+                               logger.DumpMessages ();
+                               Assert.Fail ("Build failed");
+                       }
+
+                       try {
+                               Assert.AreEqual (3, logger.NormalMessageCount, "Expected number of messages");
+                               logger.CheckLoggedMessageHead ("foo called", "A1");
+                               logger.CheckLoggedMessageHead ("FooItem: apple;rhubarb;apricot", "A2");
+                               logger.CheckLoggedMessageHead ("AllOut: apple;rhubarb;apricot;apple;rhubarb;apricot", "A3");
+                               Assert.AreEqual (0, logger.NormalMessageCount, "Extra messages found");
+
+                               Assert.AreEqual (2, logger.TargetStarted, "TargetStarted count");
+                               Assert.AreEqual (2, logger.TargetFinished, "TargetFinished count");
+                               Assert.AreEqual (8, logger.TaskStarted, "TaskStarted count");
+                               Assert.AreEqual (8, logger.TaskFinished, "TaskFinished count");
+
+                       } catch (AssertionException) {
+                               logger.DumpMessages ();
+                               throw;
+                       }
+               }
+
+               [Test]
+               public void TestTargetOutputsIncludingMetadata ()
+               {
+                       Engine engine;
+                       Project project;
+
+                       string documentString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+                       <ItemGroup>
+                               <fruit Include=""apple""><md>a</md></fruit>
+                               <fruit Include=""rhubarb""><md>b</md></fruit>
+                               <fruit Include=""apricot""><md>c</md></fruit>
+                       </ItemGroup>
+
+                       <Target Name=""Main"">
+                               <CallTarget Targets=""foo"">
+                                       <Output TaskParameter=""TargetOutputs"" ItemName=""AllOut""/>
+                               </CallTarget>
+
+                               <CallTarget Targets=""foo"">
+                                       <Output TaskParameter=""TargetOutputs"" ItemName=""AllOut""/>
+                               </CallTarget>
+                               <Message Text=""AllOut: @(AllOut) metadata: %(AllOut.md)""/>
+                       </Target>
+
+                       <Target Name=""foo"" Outputs=""@(FooItem)"">
+                               <Message Text=""foo called""/>
+                               <CreateItem Include=""@(fruit)"">
+                                       <Output TaskParameter=""Include"" ItemName=""FooItem""/>
+                               </CreateItem>
+                               <Message Text=""FooItem: @(FooItem) metadata: %(FooItem.md)""/>
+                       </Target>
+               </Project>";
+
+                       engine = new Engine (Consts.BinPath);
+                       project = engine.CreateNewProject ();
+                       project.LoadXml (documentString);
+
+                       MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+                               new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+                       engine.RegisterLogger (logger);
+
+                       bool result = project.Build ("Main");
+                       if (!result) {
+                               logger.DumpMessages ();
+                               Assert.Fail ("Build failed");
+                       }
+
+                       try {
+                               logger.CheckLoggedMessageHead ("foo called", "A1");
+                               logger.CheckLoggedMessageHead ("FooItem: apple metadata: a", "A2");
+                               logger.CheckLoggedMessageHead ("FooItem: rhubarb metadata: b", "A3");
+                               logger.CheckLoggedMessageHead ("FooItem: apricot metadata: c", "A4");
+
+                               logger.CheckLoggedMessageHead ("AllOut: apple;apple metadata: a", "A5");
+                               logger.CheckLoggedMessageHead ("AllOut: rhubarb;rhubarb metadata: b", "A6");
+                               logger.CheckLoggedMessageHead ("AllOut: apricot;apricot metadata: c", "A7");
+
+                               Assert.AreEqual (0, logger.NormalMessageCount, "Extra messages found");
+
+                               Assert.AreEqual (2, logger.TargetStarted, "TargetStarted count");
+                               Assert.AreEqual (2, logger.TargetFinished, "TargetFinished count");
+                               Assert.AreEqual (10, logger.TaskStarted, "TaskStarted count");
+                               Assert.AreEqual (10, logger.TaskFinished, "TaskFinished count");
+
+                       } catch (AssertionException) {
+                               logger.DumpMessages ();
+                               throw;
+                       }
+               }
+
+               [Test]
+               public void TestOverridingTargets ()
+               {
+                       Engine engine;
+                       Project project;
+
+                       string second = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+                               <Target Name='BeforeBuild'/>
+                               <Target Name='AfterBuild'/>
+                               <Target Name='Build' DependsOnTargets='BeforeBuild'>
+                                       <Message Text='Build executing'/>
+                                       <CallTarget Targets='AfterBuild'/>
+                               </Target>
+               </Project>";
+                       using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "second.proj")))) {
+                               sw.Write (second);
+                       }
+
+                       string documentString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+                               <Target Name='AfterBuild'>
+                                       <Message Text='Overriding AfterBuild'/>
+                               </Target>
+
+                               <Import Project='Test/resources/second.proj'/>
+                               <Target Name='BeforeBuild'>
+                                       <Message Text='Overriding BeforeBuild'/>
+                               </Target>
+               </Project>";
+
+                       engine = new Engine (Consts.BinPath);
+                       project = engine.CreateNewProject ();
+                       project.LoadXml (documentString);
+
+                       MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+                               new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+                       engine.RegisterLogger (logger);
+
+                       bool result = project.Build ("Build");
+                       if (!result) {
+                               logger.DumpMessages ();
+                               Assert.Fail ("Build failed");
+                       }
+
+                       logger.CheckLoggedMessageHead ("Overriding BeforeBuild", "A1");
+                       logger.CheckLoggedMessageHead ("Build executing", "A1");
+
+                       Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
+               }
+
+#if NET_4_0
+               [Test]
+               public void TestBeforeAndAfterTargets ()
+               {
+                       Engine engine;
+                       Project project;
+
+                       string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""4.0"">
+                         <Target Name=""DefaultBeforeTarget1"" BeforeTargets=""Default"">
+                           <Message Text=""Hello from DefaultBeforeTarget1""/>
+                         </Target>
+
+                         <Target Name=""DefaultBeforeTarget2"" BeforeTargets=""Default;Default;NonExistant"">
+                           <Message Text=""Hello from DefaultBeforeTarget2""/>
+                         </Target>
+
+
+                         <Target Name=""DefaultAfterTarget"" AfterTargets=""Default  ; Foo"">
+                           <Message Text=""Hello from DefaultAfterTarget""/>
+                         </Target>
+
+                         <Target Name=""Default"" DependsOnTargets=""DefaultDependsOn"">
+                           <Message Text=""Hello from Default""/>
+                         </Target>
+
+                         <Target Name=""DefaultDependsOn"">
+                           <Message Text=""Hello from DefaultDependsOn""/>
+                         </Target>
+                       </Project>";
+
+                       engine = new Engine ();
+                       project = engine.CreateNewProject ();
+                       project.LoadXml (projectString);
+
+                       MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
+                               new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+                       engine.RegisterLogger (logger);
+
+                       if (!project.Build ("Default")) {
+                               logger.DumpMessages ();
+                               Assert.Fail ("Build failed");
+                       }
+
+                       logger.CheckLoggedMessageHead ("Hello from DefaultDependsOn", "A1");
+                       logger.CheckLoggedMessageHead ("Hello from DefaultBeforeTarget1", "A1");
+                       logger.CheckLoggedMessageHead ("Hello from DefaultBeforeTarget2", "A1");
+                       logger.CheckLoggedMessageHead ("Hello from Default", "A1");
+                       logger.CheckLoggedMessageHead ("Hello from DefaultAfterTarget", "A1");
+
+                       Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected messages found");
+
+                       //warnings for referencing unknown targets: NonExistant and Foo
+                       Assert.AreEqual (2, logger.WarningsCount, "Expected warnings not raised");
+               }
+#endif
+
        }
 }