[xbuild] Handle a repeat build of a target, when building through ..
[mono.git] / mcs / class / Microsoft.Build.Engine / Test / Microsoft.Build.BuildEngine / TargetTest.cs
index 03edf3db2b09f01b3164203c8a92626c59c7e731..d36ae158701c0db1fa8a9243e154b77e399d63bd 100644 (file)
@@ -40,6 +40,7 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
        [TestFixture]
        public class TargetTest {
                
+               static bool isMono = Type.GetType ("Mono.Runtime", false) != null;
                Engine                  engine;
                Project                 project;
                
@@ -284,6 +285,51 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
                        t [0].RemoveTask (null);
                }
 
+               [Test]
+               public void TestRunTargetTwice ()
+               {
+                       string documentString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+                       <Target Name=""Foo"">
+                               <Message Text=""Foo ran""/>
+                       </Target>
+                       <Target Name=""Main"">
+                               <MSBuild Projects=""$(MSBuildProjectFile)"" Targets=""Foo;Foo"" />
+                       </Target>
+
+               </Project>";
+
+                       var filepath = Path.GetTempFileName ();
+                       try {
+                               File.WriteAllText (filepath, documentString);
+
+                               var engine = new Engine (Consts.BinPath);
+                               var project = engine.CreateNewProject ();
+                               project.Load (filepath);
+
+                               var logger = new TestMessageLogger ();
+                               engine.RegisterLogger (logger);
+
+                               var result = project.Build ("Main");
+                               if (!result) {
+                                       logger.DumpMessages ();
+                                       Assert.Fail ("Build failed, see the logs");
+                               }
+
+                               Assert.AreEqual(1, logger.NormalMessageCount, "Expected number of messages");
+                               logger.CheckLoggedMessageHead ("Foo ran", "A1");
+
+                               Assert.AreEqual(0, logger.NormalMessageCount, "Extra messages found");
+                               Assert.AreEqual(0, logger.WarningMessageCount, "Extra warning messages found");
+
+                               Assert.AreEqual(2, logger.TargetStarted, "TargetStarted count");
+                               Assert.AreEqual(2, logger.TargetFinished, "TargetFinished count");
+
+                               Assert.IsTrue (result);
+                       } finally {
+                               File.Delete (filepath);
+                       }
+               }
+
                [Test]
                public void TestTargetOutputs1 ()
                {
@@ -349,24 +395,23 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
                        }
                }
 
-#if NET_3_5
                bool Build (string projectXml, ILogger logger)
                {
-                       if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
+                       if (!isMono) {
                                var reader = new StringReader (projectXml);
                                var xml = XmlReader.Create (reader);
-                               return BuildOnWindows (xml, logger);
+                               return BuildOnDotNet (xml, logger);
                        } else {
-                               return BuildOnLinux (projectXml, logger);
+                               return BuildOnMono (projectXml, logger);
                        }
                }
 
-               bool BuildOnWindows (XmlReader reader, ILogger logger)
+               bool BuildOnDotNet (XmlReader reader, ILogger logger)
                {
                        var type = Type.GetType ("Microsoft.Build.Evaluation.ProjectCollection, Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
 
                        var prop = type.GetProperty ("GlobalProjectCollection");
-                       var coll = prop.GetValue (null);
+                       var coll = prop.GetValue (null, null);
                                
                        var loadProject = coll.GetType ().GetMethod (
                                        "LoadProject", new Type[] { typeof (XmlReader), typeof (string) });
@@ -377,7 +422,7 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
                        return ret;
                }
 
-               bool BuildOnLinux (string projectXml, ILogger logger)
+               bool BuildOnMono (string projectXml, ILogger logger)
                {
                        var engine = new Engine (Consts.BinPath);
                        var project = engine.CreateNewProject ();
@@ -402,6 +447,11 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
                }
 
                void ItemGroupInsideTarget (string xml, params string[] messages)
+               {
+                       ItemGroupInsideTarget (xml, 1, messages);
+               }
+
+               void ItemGroupInsideTarget (string xml, int expectedTargetCount, params string[] messages)
                {
                        var logger = CreateLogger (xml);
                        
@@ -411,9 +461,10 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
                                for (int i = 0; i < messages.Length; i++)
                                        logger.CheckLoggedMessageHead (messages [i], i.ToString ());
                                Assert.AreEqual(0, logger.NormalMessageCount, "Extra messages found");
+                               Assert.AreEqual(0, logger.WarningMessageCount, "Extra warningmessages found");
                                
-                               Assert.AreEqual(1, logger.TargetStarted, "TargetStarted count");
-                               Assert.AreEqual(1, logger.TargetFinished, "TargetFinished count");
+                               Assert.AreEqual(expectedTargetCount, logger.TargetStarted, "TargetStarted count");
+                               Assert.AreEqual(expectedTargetCount, logger.TargetFinished, "TargetFinished count");
                                Assert.AreEqual(messages.Length, logger.TaskStarted, "TaskStarted count");
                                Assert.AreEqual(messages.Length, logger.TaskFinished, "TaskFinished count");
                        }
@@ -692,7 +743,121 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
                                </Project>", "D");
                }
 
-#endif
+               [Test]
+               public void ItemGroupInsideTarget_UpdateMetadata ()
+               {
+                       ItemGroupInsideTarget (
+                               @"<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+                                       <ItemGroup>
+                                               <ProjectReference Include='xyz'/>
+                                       </ItemGroup>
+
+                                       <Target Name='Main' DependsOnTargets='CreateBar'>
+                                               <Message Text='Before: $(Bar)'/>
+                                               <ItemGroup>
+                                                       <ProjectReference>
+                                                               <AdditionalProperties>A=b</AdditionalProperties>
+                                                       </ProjectReference>
+                                               </ItemGroup>
+                                               <Message Text='After: $(Bar)'/>
+                                       </Target>
+
+                                       <Target Name='CreateBar'>
+                                               <PropertyGroup>
+                                                       <Bar>Bar01</Bar>
+                                               </PropertyGroup>
+                                       </Target>
+                               </Project>", 2, "Before: Bar01", "After: Bar01");
+               }
+
+               [Test]
+               public void ItemGroupInsideTarget_Batching ()
+               {
+                       ItemGroupInsideTarget (
+                               @"<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+                                       <Target Name='Main'>
+                                               <ItemGroup>
+                                                       <Foo Include='A;B' />
+                                                       <All Include='%(Foo.Identity)' />
+                                               </ItemGroup>
+                                               <Message Text='%(All.Identity)' />
+                                       </Target>
+                               </Project>", "A", "B");
+               }
+
+               [Test]
+               public void ItemGroupInsideTarget_Condition ()
+               {
+                       ItemGroupInsideTarget (
+                               @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""4.0"">
+                                       <PropertyGroup>
+                                               <Summer>true</Summer>
+                                       </PropertyGroup>
+                                       <ItemGroup>
+                                               <Weather Include='Sun;Rain' />
+                                       </ItemGroup>
+                               
+                                       <Target Name='Main'>
+                                               <ItemGroup Condition=""'$(Summer)' != 'true'"">
+                                                       <Weather Include='Snow' />
+                                               </ItemGroup>
+                                               <Message Text='%(Weather.Identity)' />
+                                       </Target>
+                               </Project>", "Sun", "Rain");
+               }
+
+               [Test]
+               public void PropertyGroupInsideTarget_Condition ()
+               {
+                       ItemGroupInsideTarget (
+                               @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""4.0"">
+                                       <ItemGroup>
+                                               <Shells Include=""/bin/sh;/bin/bash;/bin/false"" />
+                                       </ItemGroup>
+
+                                       <Target Name='Main'>
+                                               <PropertyGroup>
+                                                       <HasBash Condition=""'%(Shells.Filename)' == 'bash'"">true</HasBash>
+                                               </PropertyGroup>
+
+                                               <ItemGroup Condition=""'$(HasBash)' == 'true'"">
+                                                       <Weather Include='Rain' />
+                                               </ItemGroup>
+                                               <Message Text='%(Weather.Identity)' />
+                                       </Target>
+                               </Project>", "Rain");
+               }
+
+               [Test]
+               // Bug #14661
+               public void ItemGroupInsideTarget_Expression_in_Metadata ()
+               {
+                       ItemGroupInsideTarget (
+                       @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""4.0"">
+                               <ItemGroup>
+                                       <Foo Include='output1'>
+                                               <Inputs>input1a;input1b</Inputs>
+                                       </Foo>
+                                       <Foo Include='output2'>
+                                               <Inputs>input2a;input2b</Inputs>
+                                       </Foo>
+                               </ItemGroup>
+
+                               <Target Name='Main' DependsOnTargets='_PrepareItems' Inputs='@(_Foo)' Outputs='%(Result)'>
+                                       <Message Text='COMPILE: @(_Foo) - %(_Foo.Result)' />
+                               </Target>
+
+                               <Target Name='_PrepareItems'>
+                                       <ItemGroup>
+                                               <_Foo Include='%(Foo.Inputs)'>
+                                                       <Result>%(Foo.Identity)</Result>
+                                               </_Foo>
+                                       </ItemGroup>
+                               </Target>
+                       </Project>",
+                       3, "COMPILE: input1a;input1b - output1", "COMPILE: input2a;input2b - output2");
+               }
+
 
                [Test]
                public void TestTargetOutputsIncludingMetadata ()
@@ -813,7 +978,6 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
                        Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
                }
 
-#if NET_4_0
                [Test]
                [Category ("NotDotNet")]
                public void TestBeforeAndAfterTargets ()
@@ -868,7 +1032,27 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
                        //warnings for referencing unknown targets: NonExistant and Foo
                        Assert.AreEqual (2, logger.WarningsCount, "Expected warnings not raised");
                }
-#endif
+
+               [Test]
+               public void TestTargetReturns ()
+               {
+                       engine = new Engine (Consts.BinPath);
+                       project = engine.CreateNewProject ();
+                       project.Load (Path.Combine ("Test", Path.Combine ("resources", "TestReturns.csproj")));
+
+                       var logger = new TestMessageLogger ();
+                       engine.RegisterLogger (logger);
+
+                       bool result = project.Build ("Main");
+                       if (!result) {
+                               logger.DumpMessages ();
+                               Assert.Fail ("Build failed");
+                       }
+
+                       logger.CheckLoggedMessageHead ("Result: Bar", "A1");
+
+                       Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
+               }
 
        }
 }