325986470d7e1dc50054510f33353f744776a725
[mono.git] / mcs / class / Microsoft.Build.Engine / Test / Microsoft.Build.BuildEngine / ProjectTest.cs
1 //
2 // ProjectTest.cs:
3 //
4 // Author:
5 //   Marek Sieradzki (marek.sieradzki@gmail.com)
6 //   Ankit Jain (jankit@novell.com)
7 //
8 // (C) 2005 Marek Sieradzki
9 // Copyright 2009 Novell, Inc (http://www.novell.com)
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 //
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 //
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
30 using System;
31 using System.Collections;
32 using System.Collections.Generic;
33 using System.IO;
34 using System.Xml;
35 using Microsoft.Build.BuildEngine;
36 using Microsoft.Build.Framework;
37 using Microsoft.Build.Utilities;
38 using NUnit.Framework;
39 using System.Text;
40
41 using MBT = MonoTests.Microsoft.Build.Tasks;
42
43 namespace MonoTests.Microsoft.Build.BuildEngine {
44
45         class TestLogger : Logger {
46                 int target_started_events = 0;
47                 int target_finished_events = 0;
48
49                 public override void Initialize (IEventSource eventSource)
50                 {
51                         eventSource.TargetStarted += new TargetStartedEventHandler(TargetStarted);
52                         eventSource.TargetFinished += new TargetFinishedEventHandler(TargetFinished);
53                         eventSource.MessageRaised += new BuildMessageEventHandler(Message);
54                         eventSource.WarningRaised += new BuildWarningEventHandler(Warning);
55                 }
56
57                 void TargetStarted (object sender, TargetStartedEventArgs args)
58                 {
59                         target_started_events++;
60                 }
61
62                 void TargetFinished (object sender, TargetFinishedEventArgs args)
63                 {
64                         target_finished_events++;
65                 }
66
67                 void Message (object sender, BuildMessageEventArgs args)
68                 {
69                 }
70                 
71                 void Warning (object sender, BuildWarningEventArgs args)
72                 {
73                 }
74
75                 public int TargetStartedEvents { get { return target_started_events; } }
76
77                 public int TargetFinishedEvents { get { return target_finished_events; } }
78         }
79
80         [TestFixture]
81         public class ProjectTest {
82
83                 /*
84                 Import [] GetImports (ImportCollection ic)
85                 {
86                         List<Import> list = new List<Import> ();
87                         foreach (Import i in ic)
88                                 list.Add (i);
89                         return list.ToArray ();
90                 }
91                 */
92
93                 [Test]
94                 public void TestAssignment1 ()
95                 {
96                         Engine engine;
97                         Project project;
98                         string documentString =
99                                 "<Project></Project>";
100                         
101                         engine = new Engine (Consts.BinPath);
102
103                         DateTime time = DateTime.Now;
104                         project = engine.CreateNewProject ();
105                         try {
106                                 project.LoadXml (documentString);
107                         } catch (InvalidProjectFileException) {
108                                 Assert.AreEqual (true, project.BuildEnabled, "A1");
109                                 Assert.AreEqual (String.Empty, project.DefaultTargets, "A2");
110                                 Assert.AreEqual (String.Empty, project.FullFileName, "A3");
111                                 Assert.AreEqual (false, project.IsDirty, "A4");
112                                 Assert.AreEqual (false, project.IsValidated, "A5");
113                                 Assert.AreEqual (engine, project.ParentEngine, "A6");
114                                 Console.WriteLine ("time: {0} p.t: {1}", time, project.TimeOfLastDirty);
115                                 Assert.IsTrue (time <= project.TimeOfLastDirty, "A7");
116                                 Assert.IsTrue (String.Empty != project.Xml, "A8");
117                                 return;
118                         }
119
120                         Assert.Fail ("Expected InvalidProjectFileException");
121                 }
122
123                 [Test]
124                 public void TestAssignment2 ()
125                 {
126                         Engine engine;
127                         Project project;
128                         string documentString =
129                                 "<Project xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\"></Project>";
130                         
131                         engine = new Engine (Consts.BinPath);
132                         DateTime time = DateTime.Now;
133                         project = engine.CreateNewProject ();
134                         project.LoadXml (documentString);
135
136                         Assert.AreEqual (true, project.BuildEnabled, "A1");
137                         Assert.AreEqual (String.Empty, project.DefaultTargets, "A2");
138                         Assert.AreEqual (String.Empty, project.FullFileName, "A3");
139                         Assert.AreEqual (true, project.IsDirty, "A4");
140                         Assert.AreEqual (false, project.IsValidated, "A5");
141                         Assert.AreEqual (engine, project.ParentEngine, "A6");
142                         Assert.IsTrue (time <= project.TimeOfLastDirty, "A7");
143                         Assert.IsTrue (String.Empty != project.Xml, "A8");
144                 }
145
146                 [Test]
147                 [Category ("NotWorking")]
148                 public void TestAddNewImport1 ()
149                 {
150                         Engine engine;
151                         Project project;
152
153                         string documentString = @"
154                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
155                                         <PropertyGroup />
156                                         <ItemGroup />
157                                         <Target Name='a' />
158                                         <Import Project='Test/resources/Import.csproj' />
159                                 </Project>
160                         ";
161
162                         engine = new Engine (Consts.BinPath);
163                         project = engine.CreateNewProject ();
164                         project.LoadXml (documentString);
165
166                         project.AddNewImport ("a", "true");
167                         // reevaluation wasn't caused by anything so it has only old import
168                         Assert.AreEqual (1, project.Imports.Count, "A1");
169                 }
170
171                 [Test]
172                 [Ignore ("Too detailed probably (implementation specific)")]
173                 public void TestAddNewItem1 ()
174                 {
175                         Engine engine;
176                         Project project;
177                         BuildItemGroup [] groups = new BuildItemGroup [1];
178
179                         string documentString = @"
180                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
181                                 </Project>
182                         ";
183
184                         engine = new Engine (Consts.BinPath);
185                         project = engine.CreateNewProject ();
186                         project.LoadXml (documentString);
187
188                         BuildItem item = project.AddNewItem ("A", "B");
189
190                         Assert.AreEqual (1, project.ItemGroups.Count, "A1");
191                         project.ItemGroups.CopyTo (groups, 0);
192                         Assert.AreEqual (1, groups [0].Count, "A2");
193                         Assert.AreEqual ("B", groups [0] [0].Include, "A3");
194                         Assert.AreEqual ("B", groups [0] [0].FinalItemSpec, "A4");
195                         Assert.AreEqual ("A", groups [0] [0].Name, "A5");
196                         //Assert.AreNotSame (item, groups [0] [0], "A6");
197                         Assert.IsFalse (object.ReferenceEquals (item, groups [0] [0]), "A6");
198
199                         Assert.AreEqual (1, project.EvaluatedItems.Count, "A7");
200                         Assert.AreEqual ("B", project.EvaluatedItems [0].Include, "A8");
201                         Assert.AreEqual ("B", project.EvaluatedItems [0].FinalItemSpec, "A9");
202                         Assert.AreEqual ("A", project.EvaluatedItems [0].Name, "A10");
203                         //Assert.AreNotSame (item, project.EvaluatedItems [0], "A11");
204                         Assert.IsFalse (object.ReferenceEquals (item, project.EvaluatedItems [0]), "A11");
205                 }
206
207                 [Test]
208                 [Category ("NotWorking")]
209                 public void TestAddNewItem2 ()
210                 {
211                         Engine engine;
212                         Project project;
213
214                         engine = new Engine (Consts.BinPath);
215                         project = engine.CreateNewProject ();
216
217                         BuildItem item = project.AddNewItem ("A", "a;b;c");
218                         Assert.AreEqual ("a;b;c", item.Include, "A1");
219                         Assert.AreEqual ("a", item.FinalItemSpec, "A2");
220
221                         Assert.AreEqual (3, project.EvaluatedItems.Count, "A3");
222                 }
223
224                 [Test]
225                 public void TestAddNewItem3 ()
226                 {
227                         Engine engine;
228                         Project project;
229                         BuildItemGroup [] groups = new BuildItemGroup [4];
230
231                         string documentString = @"
232                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
233                                         <ItemGroup />
234                                         <ItemGroup>
235                                                 <A Include='a'/>
236                                         </ItemGroup>
237                                         <ItemGroup>
238                                                 <B Include='a'/>
239                                         </ItemGroup>
240                                         <ItemGroup>
241                                                 <B Include='a'/>
242                                         </ItemGroup>
243                                 </Project>
244                         ";
245
246                         engine = new Engine (Consts.BinPath);
247                         project = engine.CreateNewProject ();
248                         project.LoadXml (documentString);
249
250                         project.AddNewItem ("B", "b");
251
252                         project.ItemGroups.CopyTo (groups, 0);
253                         Assert.AreEqual (0, groups [0].Count, "A1");
254                         Assert.AreEqual (1, groups [1].Count, "A2");
255                         Assert.AreEqual (1, groups [2].Count, "A3");
256                         Assert.AreEqual (2, groups [3].Count, "A4");
257                 }
258                 [Test]
259                 public void TestAddNewItemGroup ()
260                 {
261                         Engine engine;
262                         Project project;
263
264                         string documentString = @"
265                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
266                                 </Project>
267                         ";
268
269                         engine = new Engine (Consts.BinPath);
270                         project = engine.CreateNewProject ();
271                         project.LoadXml (documentString);
272
273                         BuildItemGroup big = project.AddNewItemGroup ();
274                         Assert.IsNotNull (big, "A1");
275                         Assert.AreEqual (String.Empty, big.Condition, "A2");
276                         Assert.AreEqual (0, big.Count, "A3");
277                         Assert.AreEqual (false, big.IsImported, "A4");
278                         Assert.IsTrue (project.IsDirty, "A5");
279                 }
280
281                 [Test]
282                 public void TestAddNewPropertyGroup ()
283                 {
284                         Engine engine;
285                         Project project;
286
287                         string documentString = @"
288                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
289                                 </Project>
290                         ";
291
292                         engine = new Engine (Consts.BinPath);
293                         project = engine.CreateNewProject ();
294                         project.LoadXml (documentString);
295
296                         BuildPropertyGroup bpg = project.AddNewPropertyGroup (false);
297                         Assert.IsNotNull (bpg, "A1");
298                         Assert.AreEqual (String.Empty, bpg.Condition, "A2");
299                         Assert.AreEqual (0, bpg.Count, "A3");
300                         Assert.AreEqual (false, bpg.IsImported, "A4");
301                         Assert.IsTrue (project.IsDirty, "A5");
302                 }
303
304                 [Test]
305                 public void TestBuild0 ()
306                 {
307                         Engine engine;
308                         Project project;
309                         IDictionary hashtable = new Hashtable ();
310
311                         string documentString = @"
312                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
313                                         <Target 
314                                                 Name='Main'
315                                                 Inputs='a;b;c'
316                                                 Outputs='d;e;f'
317                                         >
318                                         </Target>
319                                 </Project>
320                         ";
321
322                         engine = new Engine (Consts.BinPath);
323                         project = engine.CreateNewProject ();
324                         project.LoadXml (documentString);
325
326                         Assert.AreEqual (true, project.Build (new string [] { "Main" }, hashtable), "A1");
327                         Assert.AreEqual (1, hashtable.Count, "A2");
328
329                         IDictionaryEnumerator e = hashtable.GetEnumerator ();
330                         e.MoveNext ();
331
332                         string name = (string) e.Key;
333                         Assert.AreEqual ("Main", name, "A3");
334                         ITaskItem [] arr = (ITaskItem []) e.Value;
335
336                         Assert.AreEqual (3, arr.Length, "A4");
337                         Assert.AreEqual ("d", arr [0].ItemSpec, "A5");
338                         Assert.AreEqual ("e", arr [1].ItemSpec, "A6");
339                         Assert.AreEqual ("f", arr [2].ItemSpec, "A7");
340                 }
341
342                 [Test]
343                 public void TestBuild1 ()
344                 {
345                         Engine engine;
346                         Project project;
347                         IDictionary hashtable = new Hashtable ();
348                         
349                         string documentString = @"
350                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
351                                         <Target Name='Main'>
352                                                 <Microsoft.Build.Tasks.Message Text='Text' />
353                                         </Target>
354                                 </Project>
355                         ";
356                         
357                         engine = new Engine (Consts.BinPath);
358                         project = engine.CreateNewProject ();
359                         project.LoadXml (documentString);
360
361                         Assert.AreEqual (true, project.Build (new string[] { "Main" }, hashtable), "A1");
362                         Assert.AreEqual (1, hashtable.Count, "A2");
363
364                         IDictionaryEnumerator e = hashtable.GetEnumerator ();
365                         e.MoveNext ();
366
367                         string name = (string) e.Key;
368                         Assert.AreEqual ("Main", name, "A3");
369                         Assert.IsNotNull ((ITaskItem []) e.Value, "A4");
370                 }
371
372                 [Test]
373                 public void TestBuild2 ()
374                 {
375                         Engine engine;
376                         Project project;
377
378                         string documentString = @"
379                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
380                                         <Target Name='T'>
381                                                 <Message Text='text' />
382                                         </Target>
383                                 </Project>
384                         ";
385
386                         engine = new Engine (Consts.BinPath);
387                         MBT.TestMessageLogger tl = new MBT.TestMessageLogger();
388                         engine.RegisterLogger (tl);
389                         project = engine.CreateNewProject ();
390                         project.LoadXml (documentString);
391
392                         project.Build ("T");
393                         project.Build ("T");
394
395                         Assert.AreEqual (2, tl.TargetStarted, "A1");
396                         Assert.AreEqual (2, tl.TargetFinished, "A2");
397                         Assert.AreEqual (2, tl.TaskStarted, "A3");
398                         Assert.AreEqual (2, tl.TaskFinished, "A4");
399                 }
400
401                 [Test]
402                 public void TestBuild3 ()
403                 {
404                         Engine engine;
405                         Project project;
406
407                         string documentString = @"
408                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
409                                         <Target Name='T'>
410                                                 <Message Text='text' />
411                                         </Target>
412                                 </Project>
413                         ";
414
415                         engine = new Engine (Consts.BinPath);
416                         MBT.TestMessageLogger tl = new MBT.TestMessageLogger ();
417                         engine.RegisterLogger (tl);
418                         project = engine.CreateNewProject ();
419                         project.LoadXml (documentString);
420
421                         project.Build (new string [1] { "T" }, null, BuildSettings.None);
422                         project.Build (new string [1] { "T" }, null, BuildSettings.None);
423
424                         Assert.AreEqual (2, tl.TargetStarted, "A1");
425                         Assert.AreEqual (2, tl.TargetFinished, "A2");
426                         Assert.AreEqual (2, tl.TaskStarted, "A3");
427                         Assert.AreEqual (2, tl.TaskFinished, "A4");
428                 }
429
430                 [Test]
431                 public void TestBuild4 ()
432                 {
433                         Engine engine;
434                         Project project;
435
436                         string documentString = @"
437                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
438                                         <Target Name='T'>
439                                                 <Message Text='text' />
440                                         </Target>
441                                 </Project>
442                         ";
443
444                         engine = new Engine (Consts.BinPath);
445                         MBT.TestMessageLogger tl = new MBT.TestMessageLogger ();
446                         engine.RegisterLogger (tl);
447                         project = engine.CreateNewProject ();
448                         project.LoadXml (documentString);
449
450                         project.Build (new string [1] { "T" }, null, BuildSettings.DoNotResetPreviouslyBuiltTargets);
451                         project.Build (new string [1] { "T" }, null, BuildSettings.DoNotResetPreviouslyBuiltTargets);
452
453                         Assert.AreEqual (1, tl.TargetStarted, "A1");
454                         Assert.AreEqual (1, tl.TargetFinished, "A2");
455                         Assert.AreEqual (1, tl.TaskStarted, "A3");
456                         Assert.AreEqual (1, tl.TaskFinished, "A4");
457                 }
458
459                 [Test]
460                 public void TestBuild5 ()
461                 {
462                         Engine engine;
463                         Project project;
464
465                         string documentString = @"
466                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
467                                 </Project>
468                         ";
469
470                         engine = new Engine (Consts.BinPath);
471                         project = engine.CreateNewProject ();
472                         project.LoadXml (documentString);
473
474                         Assert.IsFalse (project.Build ("target_that_doesnt_exist"));
475                 }
476
477                 [Test]
478                 public void TestEvaluatedItems1 ()
479                 {
480                         Engine engine;
481                         Project project;
482
483                         string documentString = @"
484                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
485                                         <ItemGroup>
486                                                 <A Include='a' />
487                                                 <B Include='b' Condition='false' />
488                                         </ItemGroup>
489                                 </Project>
490                         ";
491
492                         engine = new Engine (Consts.BinPath);
493                         project = engine.CreateNewProject ();
494                         project.LoadXml (documentString);
495
496                         Assert.AreEqual (1, project.EvaluatedItems.Count, "A1");
497
498                         BuildItem bi = project.EvaluatedItems [0];
499
500                         bi.Name = "C";
501                         bi.Include = "c";
502
503                         BuildItemGroup [] big = new BuildItemGroup [1];
504                         project.ItemGroups.CopyTo (big, 0);
505                         Assert.AreEqual ("C", big [0] [0].Name, "A2");
506                         Assert.AreEqual ("c", big [0] [0].Include, "A3");
507                 }
508
509                 [Test]
510                 public void TestEvaluatedItems2 ()
511                 {
512                         Engine engine;
513                         Project project;
514
515                         string documentString = @"
516                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
517                                         <ItemGroup>
518                                                 <A Include='a;b;c' />
519                                         </ItemGroup>
520                                 </Project>
521                         ";
522
523                         engine = new Engine (Consts.BinPath);
524                         project = engine.CreateNewProject ();
525                         project.LoadXml (documentString);
526
527                         BuildItemGroup [] big = new BuildItemGroup [1];
528                         project.ItemGroups.CopyTo (big, 0);
529
530                         Assert.AreEqual (3, project.EvaluatedItems.Count, "A1");
531                         Assert.AreEqual ("a;b;c", big [0] [0].Include, "A2");
532                         Assert.AreEqual (1, big [0].Count, "A3");
533
534                         BuildItem bi = project.EvaluatedItems [0];
535
536                         bi.Include = "d";
537
538                         Assert.AreEqual (3, big [0].Count, "A4");
539                         Assert.AreEqual ("d", big [0] [0].Include, "A5");
540                         Assert.AreEqual ("b", big [0] [1].Include, "A6");
541                         Assert.AreEqual ("c", big [0] [2].Include, "A7");
542                 }
543
544                 [Test]
545                 [Category ("NotWorking")]
546                 public void TestGetConditionedPropertyValues ()
547                 {
548                         Engine engine;
549                         Project project;
550
551                         string documentString = @"
552                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
553                                         <PropertyGroup Condition='true'>
554                                                 <A>A</A>
555                                                 <B Condition='true'>A</B>
556                                         </PropertyGroup>
557                                         <PropertyGroup>
558                                                 <C Condition='true'>A</C>
559                                                 <C Condition='false'>B</C>
560                                                 <C Condition='!false'>C</C>
561                                                 <D>A</D>
562                                                 <E Condition="" '$(C)' == 'A' "">E</E>
563                                         </PropertyGroup>
564                                 </Project>
565                         ";
566
567                         engine = new Engine (Consts.BinPath);
568                         project = engine.CreateNewProject ();
569                         project.LoadXml (documentString);
570
571                         Assert.AreEqual (0, project.GetConditionedPropertyValues ("A").Length, "A1");
572                         Assert.AreEqual (0, project.GetConditionedPropertyValues ("B").Length, "A2");
573                         Assert.AreEqual (1, project.GetConditionedPropertyValues ("C").Length, "A3");
574                         Assert.AreEqual (0, project.GetConditionedPropertyValues ("D").Length, "A4");
575                         Assert.AreEqual (0, project.GetConditionedPropertyValues ("E").Length, "A5");
576                         Assert.AreEqual ("A", project.GetConditionedPropertyValues ("C") [0], "A6");
577                 }
578
579                 [Test]
580                 [ExpectedException (typeof (ArgumentNullException))]
581                 public void TestGetEvaluatedItemsByName1 ()
582                 {
583                         Engine engine;
584                         Project project;
585
586                         string documentString = @"
587                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
588                                 </Project>
589                         ";
590
591                         engine = new Engine (Consts.BinPath);
592                         project = engine.CreateNewProject ();
593                         project.LoadXml (documentString);
594
595                         project.GetEvaluatedItemsByName (null);
596                 }
597
598                 [Test]
599                 public void TestGetEvaluatedItemsByName2 ()
600                 {
601                         Engine engine;
602                         Project project;
603
604                         string documentString = @"
605                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
606                                         <ItemGroup>
607                                                 <A Include='1' />
608                                                 <B Include='2' Condition='true' />
609                                                 <C Include='3' Condition='false' />
610                                         </ItemGroup>
611                                 </Project>
612                         ";
613
614                         engine = new Engine (Consts.BinPath);
615                         project = engine.CreateNewProject ();
616                         project.LoadXml (documentString);
617
618                         BuildItemGroup big;
619
620                         big = project.GetEvaluatedItemsByName (String.Empty);
621
622                         Assert.AreEqual (0, big.Count, "A1");
623
624                         big = project.GetEvaluatedItemsByName ("A");
625
626                         Assert.AreEqual (1, big.Count, "A2");
627                         Assert.AreEqual ("1", big [0].FinalItemSpec, "A3");
628
629                         big = project.GetEvaluatedItemsByName ("B");
630
631                         Assert.AreEqual (1, big.Count, "A4");
632                         Assert.AreEqual ("2", big [0].FinalItemSpec, "A5");
633
634                         big = project.GetEvaluatedItemsByName ("C");
635
636                         Assert.AreEqual (0, big.Count, "A6");
637                 }
638
639                 [Test]
640                 [ExpectedException (typeof (ArgumentNullException))]
641                 public void TestGetEvaluatedItemsByNameIgnoringCondition1 ()
642                 {
643                         Engine engine;
644                         Project project;
645
646                         string documentString = @"
647                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
648                                 </Project>
649                         ";
650
651                         engine = new Engine (Consts.BinPath);
652                         project = engine.CreateNewProject ();
653                         project.LoadXml (documentString);
654
655                         project.GetEvaluatedItemsByNameIgnoringCondition (null);
656                 }
657
658                 [Test]
659                 public void TestGetEvaluatedItemsByNameIgnoringCondition2 ()
660                 {
661                         Engine engine;
662                         Project project;
663
664                         string documentString = @"
665                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
666                                         <ItemGroup>
667                                                 <A Include='1' />
668                                                 <B Include='2' Condition='true' />
669                                                 <C Include='3' Condition='false' />
670                                         </ItemGroup>
671                                 </Project>
672                         ";
673
674                         engine = new Engine (Consts.BinPath);
675                         project = engine.CreateNewProject ();
676                         project.LoadXml (documentString);
677
678                         BuildItemGroup big;
679
680                         big = project.GetEvaluatedItemsByNameIgnoringCondition (String.Empty);
681
682                         Assert.AreEqual (0, big.Count, "A1");
683
684                         big = project.GetEvaluatedItemsByNameIgnoringCondition ("A");
685
686                         Assert.AreEqual (1, big.Count, "A2");
687                         Assert.AreEqual ("1", big [0].FinalItemSpec, "A3");
688
689                         big = project.GetEvaluatedItemsByNameIgnoringCondition ("B");
690
691                         Assert.AreEqual (1, big.Count, "A4");
692                         Assert.AreEqual ("2", big [0].FinalItemSpec, "A5");
693
694                         big = project.GetEvaluatedItemsByNameIgnoringCondition ("C");
695
696                         Assert.AreEqual (1, big.Count, "A6");
697                         Assert.AreEqual ("3", big [0].FinalItemSpec, "A7");
698                 }
699
700                 [Test]
701                 [ExpectedException (typeof (ArgumentNullException))]
702                 public void TestGetEvaluatedProperty1 ()
703                 {
704                         Engine engine;
705                         Project project;
706
707                         string documentString = @"
708                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
709                                 </Project>
710                         ";
711
712                         engine = new Engine (Consts.BinPath);
713                         project = engine.CreateNewProject ();
714                         project.LoadXml (documentString);
715
716                         project.GetEvaluatedProperty (null);
717                 }
718                 [Test]
719                 public void TestGetEvaluatedProperty2 ()
720                 {
721                         Engine engine;
722                         Project project;
723
724                         string documentString = @"
725                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
726                                         <PropertyGroup>
727                                                 <A>1</A>
728                                                 <B Condition='true'>2</B>
729                                                 <C Condition='false'>3</C>
730                                         </PropertyGroup>
731                                 </Project>
732                         ";
733
734                         engine = new Engine (Consts.BinPath);
735                         project = engine.CreateNewProject ();
736                         project.LoadXml (documentString);
737
738                         Assert.AreEqual ("1", project.GetEvaluatedProperty ("A"), "A1");
739                         Assert.AreEqual ("2", project.GetEvaluatedProperty ("B"), "A2");
740                         Assert.IsNull (project.GetEvaluatedProperty ("C"), "A3");
741                 }
742
743                 [Test]
744                 public void TestGetProjectExtensions ()
745                 {
746                         Engine engine;
747                         Project project;
748
749                         string documentString = @"
750                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
751                                         <ProjectExtensions>
752                                                 <Node>Text</Node>
753                                         </ProjectExtensions>
754                                 </Project>
755                         ";
756
757                         engine = new Engine (Consts.BinPath);
758                         project = engine.CreateNewProject ();
759                         project.LoadXml (documentString);
760
761                         Assert.AreEqual (String.Empty, project.GetProjectExtensions (null), "A1");
762                         Assert.AreEqual (String.Empty, project.GetProjectExtensions (String.Empty), "A2");
763                         Assert.AreEqual (String.Empty, project.GetProjectExtensions ("something"), "A3");
764                         Assert.AreEqual ("Text", project.GetProjectExtensions ("Node"), "A4");
765                 }
766
767                 [Test]
768                 public void TestGlobalProperties1 ()
769                 {
770                         Engine engine;
771                         Project project;
772                         
773                         string documentString = @"
774                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
775                                 </Project>
776                         ";
777                         
778                         engine = new Engine (Consts.BinPath);
779                         project = engine.CreateNewProject ();
780                         project.LoadXml (documentString);
781
782                         Assert.AreEqual (0, project.GlobalProperties.Count, "A1");
783                 }
784
785                 [Test]
786                 public void TestGlobalProperties2 ()
787                 {
788                         Engine engine;
789                         Project project;
790                         
791                         string documentString = @"
792                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
793                                 </Project>
794                         ";
795                         
796                         engine = new Engine (Consts.BinPath);
797                         engine.GlobalProperties.SetProperty ("Property", "Value");
798                         
799                         project = engine.CreateNewProject ();
800                         project.LoadXml (documentString);
801
802                         Assert.AreEqual (1, project.GlobalProperties.Count, "A1");
803                         Assert.AreEqual ("Property", project.GlobalProperties ["Property"].Name, "A2");
804                         Assert.AreEqual ("Value", project.GlobalProperties ["Property"].Value, "A3");
805                         Assert.AreEqual ("Value", project.GlobalProperties ["Property"].FinalValue, "A4");
806                         Assert.AreEqual ("Property", project.EvaluatedProperties ["Property"].Name, "A2");
807                         Assert.AreEqual ("Value", project.EvaluatedProperties ["Property"].Value, "A3");
808                         Assert.AreEqual ("Value", project.EvaluatedProperties ["Property"].FinalValue, "A4");
809                 }
810
811                 [Test]
812                 [Category ("NotDotNet")]
813                 [ExpectedException (typeof (ArgumentNullException))]
814                 public void TestGlobalProperties3 ()
815                 {
816                         Engine engine;
817                         Project project;
818                         
819                         string documentString = @"
820                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
821                                 </Project>
822                         ";
823                         
824                         engine = new Engine (Consts.BinPath);
825                         project = engine.CreateNewProject ();
826                         project.LoadXml (documentString);
827
828                         project.GlobalProperties = null;
829                 }
830
831                 [Test]
832                 [Ignore ("needs rewriting")]
833                 public void TestGlobalProperties4 ()
834                 {
835                         Engine engine;
836                         Project project;
837                         
838                         string documentString = @"
839                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
840                                         <PropertyGroup>
841                                                 <Property>a</Property>
842                                         </PropertyGroup>
843                                 </Project>
844                         ";
845                         
846                         engine = new Engine (Consts.BinPath);
847                         project = engine.CreateNewProject ();
848                         project.LoadXml (documentString);
849
850                         BuildPropertyGroup[] groups = new BuildPropertyGroup [1];
851                         project.PropertyGroups.CopyTo (groups, 0);
852
853                         project.GlobalProperties = groups [0];
854                         project.GlobalProperties = project.EvaluatedProperties;
855                 }
856
857                 [Test]
858                 [Category ("NotDotNet")]
859                 [ExpectedException (typeof (InvalidOperationException))]
860                 public void TestGlobalProperties5 ()
861                 {
862                         Engine engine;
863                         Project project;
864                         
865                         string documentString = @"
866                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
867                                         <PropertyGroup>
868                                                 <Property>a</Property>
869                                         </PropertyGroup>
870                                 </Project>
871                         ";
872                         
873                         engine = new Engine (Consts.BinPath);
874                         project = engine.CreateNewProject ();
875                         project.LoadXml (documentString);
876
877                         BuildPropertyGroup[] groups = new BuildPropertyGroup [1];
878                         project.PropertyGroups.CopyTo (groups, 0);
879                         project.GlobalProperties = groups [0];
880                 }
881
882                 [Test]
883                 [ExpectedException (typeof (InvalidProjectFileException))]
884                 public void TestLoad1 ()
885                 {
886                         Engine engine;
887                         Project project;
888
889                         string documentString = @"
890                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
891                                         <PropertyGroup>
892                                 </Project>
893                         ";
894
895                         engine = new Engine (Consts.BinPath);
896                         project = engine.CreateNewProject ();
897                         project.LoadXml (documentString);
898                 }
899
900                 [Test]
901                 [ExpectedException (typeof (InvalidProjectFileException))]
902                 public void TestLoad2 ()
903                 {
904                         Engine engine;
905                         Project project;
906
907                         engine = new Engine (Consts.BinPath);
908                         project = engine.CreateNewProject ();
909                         project.LoadXml ("project_file_that_doesnt_exist");
910                 }
911
912                 [Test]
913                 public void TestParentEngine ()
914                 {
915                         Engine engine;
916                         Project project;
917                         
918                         engine = new Engine (Consts.BinPath);
919                         project = engine.CreateNewProject ();
920
921                         Assert.AreEqual (engine, project.ParentEngine, "A1");
922                 }
923
924                 [Test]
925                 [Category ("NotDotNet")]
926                 [ExpectedException (typeof (ArgumentNullException))]
927                 public void TestRemoveItemGroup1 ()
928                 {
929                         Engine engine;
930                         Project p1;
931
932                         engine = new Engine (Consts.BinPath);
933                         p1 = engine.CreateNewProject ();
934
935                         p1.RemoveItemGroup (null);
936                 }
937
938                 // The "BuildItemGroup" object specified does not belong to the correct "Project" object.
939                 [Test]
940                 [ExpectedException (typeof (InvalidOperationException))]
941                 [Category ("NotWorking")]
942                 public void TestRemoveItemGroup2 ()
943                 {
944                         Engine engine;
945                         Project p1;
946                         Project p2;
947                         BuildItemGroup [] groups  = new BuildItemGroup [1];
948
949                         engine = new Engine (Consts.BinPath);
950                         p1 = engine.CreateNewProject ();
951                         p2 = engine.CreateNewProject ();
952
953                         p1.AddNewItem ("A", "B");
954                         p1.ItemGroups.CopyTo (groups, 0);
955
956                         p2.RemoveItemGroup (groups [0]);
957                 }
958
959                 [Test]
960                 [Category ("NotDotNet")]
961                 [ExpectedException (typeof (ArgumentNullException))]
962                 public void TestRemoveItem1 ()
963                 {
964                         Engine engine;
965                         Project project;
966
967                         engine = new Engine (Consts.BinPath);
968                         project = engine.CreateNewProject ();
969
970                         project.RemoveItem (null);
971                 }
972
973                 // The object passed in is not part of the project.
974                 [Test]
975                 [ExpectedException (typeof (InvalidOperationException))]
976                 public void TestRemoveItem2 ()
977                 {
978                         Engine engine;
979                         Project project;
980
981                         engine = new Engine (Consts.BinPath);
982                         project = engine.CreateNewProject ();
983
984                         project.RemoveItem (new BuildItem ("name", "include"));
985                 }
986
987                 // The "BuildItemGroup" object specified does not belong to the correct "Project" object.
988                 [Test]
989                 [ExpectedException (typeof (InvalidOperationException))]
990                 public void TestRemoveItem3 ()
991                 {
992                         Engine engine;
993                         Project p1;
994                         Project p2;
995
996                         engine = new Engine (Consts.BinPath);
997                         p1 = engine.CreateNewProject ();
998                         p2 = engine.CreateNewProject ();
999
1000                         p1.AddNewItem ("A", "B");
1001
1002                         p2.RemoveItem (p1.EvaluatedItems [0]);
1003                 }
1004
1005                 [Test]
1006                 [Category ("NotDotNet")]
1007                 [ExpectedException (typeof (InvalidOperationException))]
1008                 public void TestRemoveItem4 ()
1009                 {
1010                         Engine engine;
1011                         Project p1;
1012                         Project p2;
1013
1014                         engine = new Engine (Consts.BinPath);
1015                         p1 = engine.CreateNewProject ();
1016                         p2 = engine.CreateNewProject ();
1017
1018                         p1.AddNewItem ("A", "B");
1019                         p1.AddNewItem ("A", "C");
1020
1021                         p2.RemoveItem (p1.EvaluatedItems [0]);
1022                 }
1023
1024                 [Test]
1025                 public void TestRemoveItem5 ()
1026                 {
1027                         Engine engine;
1028                         Project project;
1029                         BuildItemGroup [] groups = new BuildItemGroup [1];
1030
1031                         string documentString = @"
1032                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
1033                                         <ItemGroup>
1034                                                 <A Include='a'/>
1035                                         </ItemGroup>
1036                                 </Project>
1037                         ";
1038
1039                         engine = new Engine (Consts.BinPath);
1040                         project = engine.CreateNewProject ();
1041                         project.LoadXml (documentString);
1042
1043                         project.RemoveItem (project.EvaluatedItems [0]);
1044                         Assert.AreEqual (0, project.EvaluatedItems.Count, "A1");
1045                         project.ItemGroups.CopyTo (groups, 0);
1046                         Assert.IsNull (groups [0], "A2");
1047                         Assert.AreEqual (0, project.ItemGroups.Count, "A3");
1048                 }
1049
1050                 [Test]
1051                 public void TestResetBuildStatus ()
1052                 {
1053                         Engine engine;
1054                         Project project;
1055
1056                         string documentString = @"
1057                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
1058                                         <Target Name='T' Inputs='Test\resources\TestTasks.cs' Outputs='Test\resources\TestTasks.dll'>
1059                                                 <Message Text='text' />
1060                                         </Target>
1061                                 </Project>
1062                         ";
1063
1064                         engine = new Engine (Consts.BinPath);
1065                         TestLogger tl = new TestLogger ();
1066                         engine.RegisterLogger (tl);
1067                         project = engine.CreateNewProject ();
1068                         project.LoadXml (documentString);
1069
1070                         project.Build ("T");
1071                         project.ResetBuildStatus ();
1072                         project.Build (new string [1] { "T" }, null, BuildSettings.DoNotResetPreviouslyBuiltTargets);
1073                         project.ResetBuildStatus ();
1074                         project.Build (new string [1] { "T" }, null, BuildSettings.DoNotResetPreviouslyBuiltTargets);
1075
1076                         Assert.AreEqual (3, tl.TargetStartedEvents, "A1");
1077                         Assert.AreEqual (3, tl.TargetFinishedEvents, "A1");
1078                 }
1079                 
1080                 [Test]
1081                 public void TestSchemaFile ()
1082                 {
1083                         Engine engine;
1084                         Project project;
1085                         
1086                         string documentString = @"
1087                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
1088                                 </Project>
1089                         ";
1090                         
1091                         engine = new Engine (Consts.BinPath);
1092                         project = engine.CreateNewProject ();
1093                         project.LoadXml (documentString);
1094
1095                         Assert.IsNull (project.SchemaFile, "A1");
1096                 }
1097                 [Test]
1098                 [Category ("NotDotNet")]
1099                 [ExpectedException (typeof (ArgumentNullException))]
1100                 public void TestSetProjectExtensions1 ()
1101                 {
1102                         Engine engine;
1103                         Project project;
1104
1105                         string documentString = @"
1106                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
1107                                 </Project>
1108                         ";
1109
1110                         engine = new Engine (Consts.BinPath);
1111                         project = engine.CreateNewProject ();
1112                         project.LoadXml (documentString);
1113
1114                         project.SetProjectExtensions (null, null);
1115                 }
1116
1117                 [Test]
1118                 public void TestSetProjectExtensions2 ()
1119                 {
1120                         Engine engine;
1121                         Project project;
1122
1123                         string documentString = @"
1124                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
1125                                 </Project>
1126                         ";
1127
1128                         engine = new Engine (Consts.BinPath);
1129                         project = engine.CreateNewProject ();
1130                         project.LoadXml (documentString);
1131
1132                         project.SetProjectExtensions ("name", "1");
1133                         Assert.AreEqual ("1", project.GetProjectExtensions ("name"), "A1");
1134                         project.SetProjectExtensions ("name", "2");
1135                         Assert.AreEqual ("2", project.GetProjectExtensions ("name"), "A2");
1136                         Assert.IsTrue (project.IsDirty, "A3");
1137                 }
1138
1139                 [Test]
1140                 public void TestSetProjectExtensions3 ()
1141                 {
1142                         Engine engine;
1143                         Project project;
1144
1145                         string documentString = @"
1146                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
1147                                         <ProjectExtensions>
1148                                         </ProjectExtensions>
1149                                 </Project>
1150                         ";
1151
1152                         engine = new Engine (Consts.BinPath);
1153                         project = engine.CreateNewProject ();
1154                         project.LoadXml (documentString);
1155
1156                         project.SetProjectExtensions ("name", "1");
1157                         Assert.AreEqual ("1", project.GetProjectExtensions ("name"), "A1");
1158                         Assert.IsTrue (project.IsDirty, "A2");
1159                 }
1160
1161                 [Test]
1162                 public void TestBuildProjectError1 ()
1163                 {
1164                         Engine engine = new Engine (Consts.BinPath);
1165                         Project project = engine.CreateNewProject ();
1166
1167                         Assert.IsFalse (project.Build ((string) null), "A1");
1168                         Assert.IsFalse (project.Build ((string[]) null), "A2");
1169                         Assert.IsFalse (project.Build ((string []) null, null), "A3");
1170                         Assert.IsFalse (project.Build ((string []) null, null, BuildSettings.None), "A4");
1171                 }
1172
1173                 [Test]
1174                 public void TestBuildProjectError2 ()
1175                 {
1176                         Engine engine = new Engine (Consts.BinPath);
1177                         Project project = engine.CreateNewProject ();
1178
1179                         try {
1180                                 project.Build (new string [] { null });
1181                         } catch {
1182                                 return;
1183                         }
1184                         Assert.Fail ("Expected exception for project.Build, null string in targetNames []");
1185                 }
1186
1187                 [Test]
1188                 public void TestBuildProjectFile1 ()
1189                 {
1190                         Project project = CreateAndLoadProject ("foo.proj", false, new string [] { "1", "2" }, new bool [] { true, true }, "TBPF1");
1191                         CheckProjectBuild (project, new string [] { "main" }, true, new string [] { "main" }, "TBPF1");
1192                 }
1193
1194                 [Test]
1195                 public void TestBuildProjectFileXml1 ()
1196                 {
1197                         Project project = CreateAndLoadProject (null, false, new string [] { "1", "2" }, new bool [] { true, true }, "TBPFX1");
1198                         CheckProjectBuild (project, new string [] { "main" }, true, new string [] { "main" }, "TBPFX1");
1199                 }
1200
1201                 [Test]
1202                 public void TestBuildProjectFile2 ()
1203                 {
1204                         Project project = CreateAndLoadProject ("foo.proj", false, new string [] { "1", "2", "3" }, new bool [] { true, false, true }, "TBPF2");
1205                         CheckProjectBuild (project, new string [] { "main" }, false, new string [0], "TBPF2");
1206                 }
1207
1208                 [Test]
1209                 public void TestBuildProjectFileXml2 ()
1210                 {
1211                         Project project = CreateAndLoadProject (null, false, new string [] { "1", "2", "3" }, new bool [] { true, false, true }, "TBPFX2");
1212                         CheckProjectBuild (project, new string [] { "main" }, false, new string [0], "TBPFX2");
1213                 }
1214
1215                 [Test]
1216                 public void TestBuildProjectFile3 ()
1217                 {
1218                         Project project = CreateAndLoadProject ("foo.proj", false, new string [] { "1", "2", "3" }, new bool [] { true, true, true }, "TBPF3");
1219                         CheckProjectBuild (project, new string [] { "1", "2" }, true, new string [] { "1", "2" }, "TBPF3");
1220                 }
1221
1222                 [Test]
1223                 public void TestBuildProjectFileXml3 ()
1224                 {
1225                         Project project = CreateAndLoadProject (null, false, new string [] { "1", "2", "3" }, new bool [] { true, true, true }, "TBPFX3");
1226                         CheckProjectBuild (project, new string [] { "1", "2" }, true, new string [] { "1", "2" }, "TBPFX3");
1227                 }
1228
1229                 [Test]
1230                 public void TestBuildProjectFile4 ()
1231                 {
1232                         Project project = CreateAndLoadProject ("foo.proj", false, new string [] { "1", "2", "3" }, new bool [] { true, false, true }, "TBPF4");
1233                         CheckProjectBuild (project, new string [] { "main" }, false, new string [0], "TBPF4");
1234                 }
1235
1236                 [Test]
1237                 public void TestBuildProjectFileXml4 ()
1238                 {
1239                         Project project = CreateAndLoadProject (null, false, new string [] { "1", "2", "3" }, new bool [] { true, false, true }, "TBPFX4");
1240                         CheckProjectBuild (project, new string [] { "main" }, false, new string [0], "TBPFX4");
1241                 }
1242
1243                 //Run separate tests
1244
1245                 //Run single target
1246                 [Test]
1247                 public void TestBuildProjectFile5 ()
1248                 {
1249                         Project project = CreateAndLoadProject ("foo.proj", true, new string [] { "1", "2", "3" }, new bool [] { true, false, true }, "TBPF5");
1250                         CheckProjectBuild (project, new string [] { "main" }, false, new string [0], "TBPF5");
1251                 }
1252
1253                 [Test]
1254                 public void TestBuildProjectFileXml5 ()
1255                 {
1256                         Project project = CreateAndLoadProject (null, true, new string [] { "1", "2", "3" }, new bool [] { true, false, true }, "TBPFX5");
1257                         CheckProjectBuild (project, new string [] { "main" }, false, new string [0], "TBPFX5");
1258                 }
1259
1260                 [Test]
1261                 public void TestBuildProjectFile6 ()
1262                 {
1263                         Project project = CreateAndLoadProject ("foo.proj", true, new string [] { "1", "2", "3" }, new bool [] { true, true, true }, "TBPF6");
1264                         CheckProjectBuild (project, new string [] { "main" }, true, new string [] { "main" }, "TBPF6");
1265                 }
1266
1267                 [Test]
1268                 public void TestBuildProjectFileXml6 ()
1269                 {
1270                         Project project = CreateAndLoadProject (null, true, new string [] { "1", "2", "3" }, new bool [] { true, true, true }, "TBPFX6");
1271                         CheckProjectBuild (project, new string [] { "main" }, true, new string [] { "main" }, "TBPFX6");
1272                 }
1273
1274                 // run multiple targets
1275                 [Test]
1276                 public void TestBuildProjectFile7 ()
1277                 {
1278                         Project project = CreateAndLoadProject ("foo.proj", true, new string [] { "1", "2", "3" }, new bool [] { true, true, true }, "TBPF7");
1279                         CheckProjectBuild (project, new string [] { "1", "2", "3" }, true, new string [] { "1", "2", "3" }, "TBPF7");
1280                 }
1281
1282                 [Test]
1283                 public void TestBuildProjectFileXml7 ()
1284                 {
1285                         Project project = CreateAndLoadProject (null, true, new string [] { "1", "2", "3" }, new bool [] { true, true, true }, "TBPFX7");
1286                         CheckProjectBuild (project, new string [] { "1", "2", "3" }, true, new string [] { "1", "2", "3" }, "TBPFX7");
1287                 }
1288
1289                 [Test]
1290                 public void TestBuildProjectFile8 ()
1291                 {
1292                         Project project = CreateAndLoadProject ("foo.proj", true, new string [] { "1", "2", "3" }, new bool [] { true, true, false }, "TBPF8");
1293                         CheckProjectBuild (project, new string [] { "1", "2", "3" }, false, new string [] { "1", "2"}, "TBPF8");
1294                 }
1295
1296                 [Test]
1297                 public void TestBuildProjectFileXml8 ()
1298                 {
1299                         Project project = CreateAndLoadProject (null, true, new string [] { "1", "2", "3" }, new bool [] { true, true, false }, "TBPFX8");
1300                         CheckProjectBuild (project, new string [] { "1", "2", "3" }, false, new string [] { "1", "2"}, "TBPFX8");
1301                 }
1302
1303                 [Test]
1304                 public void TestBatchedMetadataRef1 ()
1305                 {
1306                         //test for multiple items with same metadata also
1307                          string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1308                         <UsingTask TaskName=""BatchingTestTask"" AssemblyFile=""Test/resources/TestTasks.dll"" />
1309                         <ItemGroup>
1310                                 <Coll1 Include=""A1""><Name>Abc</Name></Coll1>
1311                                 <Coll1 Include=""A2""><Name>Def</Name></Coll1>
1312                                 <Coll1 Include=""A3""><Name>Xyz</Name></Coll1>
1313                                 <Coll1 Include=""A4""><Name>Xyz</Name></Coll1>
1314                                 <Coll2 Include=""B1""></Coll2>
1315                         </ItemGroup>
1316                                 <Target Name=""ShowMessage"">
1317                                         <BatchingTestTask Sources=""%(Coll1.Name)"">
1318                                                 <Output TaskParameter=""Output"" ItemName=""FinalList"" />
1319                                         </BatchingTestTask>
1320                                         <Message Text=""Msg: %(Coll1.Name)"" />
1321                                 </Target>
1322                  </Project>";
1323
1324                         Engine engine = new Engine (Consts.BinPath);
1325                         Project project = engine.CreateNewProject ();
1326
1327                         project.LoadXml (projectString);
1328                         Assert.IsTrue (project.Build ("ShowMessage"), "A1: Build failed");
1329
1330                         BuildItemGroup include = project.GetEvaluatedItemsByName ("FinalList");
1331                         Assert.AreEqual (3, include.Count, "A2");
1332
1333                         Assert.AreEqual ("FinalList", include [0].Name, "A3");
1334                         Assert.AreEqual ("Abc", include [0].FinalItemSpec, "A4");
1335
1336                         Assert.AreEqual ("FinalList", include [1].Name, "A5");
1337                         Assert.AreEqual ("Def", include [1].FinalItemSpec, "A6");
1338
1339                         Assert.AreEqual ("FinalList", include [2].Name, "A7");
1340                         Assert.AreEqual ("Xyz", include [2].FinalItemSpec, "A8");
1341                 }
1342
1343                 [Test]
1344                 public void TestBatchedMetadataRef2 ()
1345                 {
1346                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1347                         <UsingTask TaskName=""BatchingTestTask"" AssemblyFile=""Test/resources/TestTasks.dll"" />
1348                         <ItemGroup>
1349                                 <Coll1 Include=""A1""><Name>Abc</Name></Coll1>
1350                                 <Coll1 Include=""A2""><Name>Def</Name></Coll1>
1351                                 <Coll1 Include=""A3""><Name>Xyz</Name></Coll1>
1352                                 <Coll1 Include=""A4""><Name>Abc</Name></Coll1>
1353                                 <Coll2 Include=""B1""><Name>Bar</Name></Coll2>
1354                                 <Coll2 Include=""B2""><Name>Bar</Name></Coll2>
1355                         </ItemGroup>
1356                                 <Target Name=""ShowMessage"">
1357                                         <BatchingTestTask Sources=""%(Name)"" Strings=""@(Coll2)"">
1358                                                 <Output TaskParameter=""Output"" ItemName=""FinalList"" />
1359                                         </BatchingTestTask>
1360                                         <Message Text=""Msg: %(Coll1.Name)"" />
1361                                 </Target>
1362                                 <Target Name=""ShowMessage2"">
1363                                         <BatchingTestTask Sources=""%(Name)"" Strings=""@(Coll1)"">
1364                                                 <Output TaskParameter=""Output"" ItemName=""FinalList2"" />
1365                                         </BatchingTestTask>
1366                                         <Message Text=""Msg: %(Coll1.Name)"" />
1367                                 </Target>
1368                  </Project>";
1369
1370                         Engine engine = new Engine (Consts.BinPath);
1371                         Project project = engine.CreateNewProject ();
1372
1373                         project.LoadXml (projectString);
1374                         Assert.IsTrue (project.Build ("ShowMessage"), "A1: Build failed");
1375
1376                         BuildItemGroup include = project.GetEvaluatedItemsByName ("FinalList");
1377                         Assert.AreEqual (1, include.Count, "A2");
1378
1379                         Assert.AreEqual ("FinalList", include [0].Name, "A3");
1380                         Assert.AreEqual ("Bar", include [0].FinalItemSpec, "A4");
1381
1382                         Assert.IsTrue (project.Build ("ShowMessage2"), "A1: Build failed");
1383                         include = project.GetEvaluatedItemsByName ("FinalList2");
1384                         Assert.AreEqual (3, include.Count, "A5");
1385
1386                         Assert.AreEqual ("FinalList2", include [0].Name, "A6");
1387                         Assert.AreEqual ("Abc", include [0].FinalItemSpec, "A7");
1388
1389                         Assert.AreEqual ("FinalList2", include [1].Name, "A8");
1390                         Assert.AreEqual ("Def", include [1].FinalItemSpec, "A9");
1391
1392                         Assert.AreEqual ("FinalList2", include [2].Name, "A10");
1393                         Assert.AreEqual ("Xyz", include [2].FinalItemSpec, "A11");
1394                 }
1395
1396                 [Test]
1397                 public void TestBatchedMetadataRef3 ()
1398                 {
1399                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1400                         <UsingTask TaskName=""BatchingTestTask"" AssemblyFile=""Test/resources/TestTasks.dll"" />
1401                         <ItemGroup>
1402                                 <Coll1 Include=""A1""><Name>Abc</Name></Coll1>
1403                                 <Coll1 Include=""A2""><Name>Def</Name></Coll1>
1404                                 <Coll1 Include=""A3""><Name>Xyz</Name></Coll1>
1405                                 <Coll1 Include=""A4""><Name>Abc</Name></Coll1>
1406                                 <Coll2 Include=""B1""><Name>Bar</Name></Coll2>
1407                                 <Coll2 Include=""B2""><Name>Bar</Name></Coll2>
1408                         </ItemGroup>
1409                                 <Target Name=""ShowMessage"">
1410                                         <BatchingTestTask SingleTaskItem=""%(Coll2.Name)"" >
1411                                                 <Output TaskParameter=""SingleStringOutput"" ItemName=""FinalList"" />
1412                                         </BatchingTestTask>
1413                                         <Message Text=""Msg: %(Coll1.Name)"" />
1414                                 </Target>
1415                  </Project>";
1416
1417                         Engine engine = new Engine (Consts.BinPath);
1418                         Project project = engine.CreateNewProject ();
1419
1420                         project.LoadXml (projectString);
1421                         Assert.IsTrue (project.Build ("ShowMessage"), "A1: Build failed");
1422
1423                         BuildItemGroup include = project.GetEvaluatedItemsByName ("FinalList");
1424                         Assert.AreEqual (1, include.Count, "A2");
1425
1426                         Assert.AreEqual ("FinalList", include [0].Name, "A3");
1427                         Assert.AreEqual ("Bar", include [0].FinalItemSpec, "A4");
1428
1429                 }
1430
1431                 [Test]
1432                 public void TestBatchedMetadataRef4 ()
1433                 {
1434                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1435                         <UsingTask TaskName=""BatchingTestTask"" AssemblyFile=""Test/resources/TestTasks.dll"" />
1436                         <ItemGroup>
1437                                 <Coll1 Include=""A1""><Name>Abc</Name></Coll1>
1438                                 <Coll1 Include=""A2""><Name>Def</Name></Coll1>
1439                                 <Coll1 Include=""A3""><Name>Xyz</Name></Coll1>
1440                                 <Coll2 Include=""B1""><Name>Bar</Name></Coll2>
1441                         </ItemGroup>
1442                                 <Target Name=""ShowMessage"">
1443                                         <BatchingTestTask SingleTaskItem=""%(Coll3.Name)"" >
1444                                                 <Output TaskParameter=""SingleStringOutput"" ItemName=""FinalList"" />
1445                                         </BatchingTestTask>
1446                                 </Target>
1447                  </Project>";
1448
1449                         Engine engine = new Engine (Consts.BinPath);
1450                         Project project = engine.CreateNewProject ();
1451
1452                         project.LoadXml (projectString);
1453                         Assert.IsTrue (project.Build ("ShowMessage"), "A1: Build failed");
1454
1455                         BuildItemGroup include = project.GetEvaluatedItemsByName ("FinalList");
1456                         Assert.AreEqual (0, include.Count, "A2");
1457                 }
1458
1459                 [Test]
1460                 public void TestBatchedMetadataRef5 ()
1461                 {
1462                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1463                         <UsingTask TaskName=""BatchingTestTask"" AssemblyFile=""Test/resources/TestTasks.dll"" />
1464                         <ItemGroup>
1465                                 <Coll1 Include=""A1""><Name>Abc</Name></Coll1>
1466                                 <Coll1 Include=""A2""><Name>Def</Name></Coll1>
1467                                 <Coll1 Include=""A3""><Name>Xyz</Name></Coll1>
1468                                 <Coll2 Include=""B1""><Name>Bar</Name></Coll2>
1469                         </ItemGroup>
1470                                 <Target Name=""ShowMessage"">
1471                                         <Message Text=""Coll1: @(Coll1->'Foo%(Name)Bar')"" />
1472                                         <BatchingTestTask Sources=""@(Coll1->'Foo%(Name)Bar')"" >
1473                                                 <Output TaskParameter=""Output"" ItemName=""FinalList"" />
1474                                         </BatchingTestTask>
1475                                 </Target>
1476                  </Project>";
1477
1478                         Engine engine = new Engine (Consts.BinPath);
1479                         Project project = engine.CreateNewProject ();
1480                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
1481                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
1482                         engine.RegisterLogger (logger);
1483
1484                         project.LoadXml (projectString);
1485                         bool result = project.Build ("ShowMessage");
1486                         if (!result) {
1487                                 logger.DumpMessages ();
1488                                 Assert.Fail ("A1: Build failed");
1489                         }
1490                         logger.DumpMessages ();
1491                         BuildItemGroup include = project.GetEvaluatedItemsByName ("FinalList");
1492                         Assert.AreEqual (3, include.Count, "A2");
1493                 }
1494
1495                 [Test]
1496                 public void TestBatchedMetadataRefInOutput () {
1497                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1498                         <UsingTask TaskName=""BatchingTestTask"" AssemblyFile=""Test/resources/TestTasks.dll"" />
1499                         <ItemGroup>
1500                                 <Coll1 Include=""A1""><Name>Abc</Name></Coll1>
1501                                 <Coll1 Include=""A2""><Name>Def</Name></Coll1>
1502                                 <Coll1 Include=""A3""><Name>Abc</Name></Coll1>
1503                                 <Coll1 Include=""B1""><Name>Bar</Name></Coll1>
1504                         </ItemGroup>
1505                                 <Target Name=""ShowMessage"">
1506                                         <BatchingTestTask Sources=""@(Coll1)"" >
1507                                                 <Output TaskParameter=""Output"" ItemName=""AbcItems"" Condition=""'%(Coll1.Name)' == 'Abc'""/>
1508                                                 <Output TaskParameter=""Output"" ItemName=""NonAbcItems"" Condition=""'%(Coll1.Name)' != 'Abc'""/>
1509                                         </BatchingTestTask>
1510                                         <Message Text='AbcItems: @(AbcItems)' />
1511                                         <Message Text='NonAbcItems: @(NonAbcItems)' />
1512                                 </Target>
1513                  </Project>";
1514
1515                         Engine engine = new Engine (Consts.BinPath);
1516                         Project project = engine.CreateNewProject ();
1517                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
1518                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
1519                         engine.RegisterLogger (logger);
1520
1521                         project.LoadXml (projectString);
1522                         bool result = project.Build ("ShowMessage");
1523                         if (!result) {
1524                                 logger.DumpMessages ();
1525                                 Assert.Fail ("A1: Build failed");
1526                         }
1527
1528                         logger.CheckLoggedMessageHead ("AbcItems: A1;A3", "A2");
1529                         logger.CheckLoggedMessageHead ("NonAbcItems: A2;B1", "A2");
1530
1531                         if (logger.NormalMessageCount != 0) {
1532                                 logger.DumpMessages ();
1533                                 Assert.Fail ("Unexpected extra messages found");
1534                         }
1535                 }
1536
1537                 [Test]
1538                 public void TestInitialTargets ()
1539                 {
1540                         Engine engine = new Engine (Consts.BinPath);
1541                         Project project = engine.CreateNewProject ();
1542
1543                         project.LoadXml (@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" InitialTargets=""pre  "">
1544                                 <Target Name=""boo"">
1545                                         <Message Text=""Executing boo target""/>
1546                                 </Target>
1547                                 <Target Name=""pre"">
1548                                         <Message Text=""Executing pre target""/>
1549                                 </Target>
1550                         </Project>");
1551
1552                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
1553                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
1554                         engine.RegisterLogger (logger);
1555
1556                         try {
1557                                 Assert.IsTrue (project.Build (), "Build failed");
1558
1559                                 logger.CheckLoggedMessageHead ("Executing pre target", "A1");
1560                                 logger.CheckLoggedMessageHead ("Executing boo target", "A2");
1561
1562                                 Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
1563                         } catch {
1564                                 logger.DumpMessages ();
1565                                 throw;
1566                         }
1567                 }
1568
1569                 [Test]
1570                 public void TestInitialTargetsWithImports () {
1571                         Engine engine = new Engine (Consts.BinPath);
1572                         Project project = engine.CreateNewProject ();
1573
1574                         string second = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" InitialTargets=""One  "">
1575                                 <Target Name=""One"">
1576                                         <Message Text='Executing Second::One target'/>
1577                                 </Target>
1578                                 <Import Project='third.proj'/>
1579                         </Project>
1580 ";
1581                         using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "second.proj")))) {
1582                                 sw.Write (second);
1583                         }
1584
1585                         string third = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" InitialTargets=""Two"">
1586                                 <Target Name=""Two"">
1587                                         <Message Text='Executing Third::Two target'/>
1588                                 </Target>
1589                         </Project>
1590 ";
1591                         using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "third.proj")))) {
1592                                 sw.Write (third);
1593                         }
1594
1595                         project.LoadXml (@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" InitialTargets=""pre"">
1596                                 <Target Name=""boo"">
1597                                         <Message Text=""Executing boo target""/>
1598                                 </Target>
1599                                 <Target Name=""pre"">
1600                                         <Message Text=""Executing pre target""/>
1601                                 </Target>
1602                                 <Import Project='Test/resources/second.proj'/>
1603                         </Project>");
1604
1605                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
1606                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
1607                         engine.RegisterLogger (logger);
1608
1609                         try {
1610                                 Assert.IsTrue (project.Build (), "Build failed");
1611
1612                                 logger.CheckLoggedMessageHead ("Executing pre target", "A1");
1613                                 logger.CheckLoggedMessageHead ("Executing Second::One target", "A2");
1614                                 logger.CheckLoggedMessageHead ("Executing Third::Two target", "A3");
1615                                 logger.CheckLoggedMessageHead ("Executing boo target", "A4");
1616                                 Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
1617
1618                                 Assert.AreEqual ("pre; One; Two", project.InitialTargets, "List of initial targets");
1619                         } catch {
1620                                 logger.DumpMessages ();
1621                                 throw;
1622                         }
1623                 }
1624
1625                 [Test]
1626                 public void TestDefaultTargets () {
1627                         Engine engine = new Engine (Consts.BinPath);
1628                         Project project = engine.CreateNewProject ();
1629
1630                         project.LoadXml (@"<Project DefaultTargets='pre' xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" >
1631                                 <Target Name=""boo"">
1632                                         <Message Text=""Executing boo target""/>
1633                                 </Target>
1634                                 <Target Name=""pre"">
1635                                         <Message Text=""Executing pre target""/>
1636                                 </Target>
1637                         </Project>");
1638
1639                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
1640                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
1641                         engine.RegisterLogger (logger);
1642
1643                         try {
1644                                 Assert.IsTrue (project.Build (), "Build failed");
1645
1646                                 logger.CheckLoggedMessageHead ("Executing pre target", "A1");
1647                                 Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
1648
1649                                 Assert.AreEqual ("pre", project.DefaultTargets, "Default targets");
1650                         } catch {
1651                                 logger.DumpMessages ();
1652                                 throw;
1653                         }
1654                 }
1655
1656
1657                 [Test]
1658                 public void TestDefaultTargetsWithImports () {
1659                         Engine engine = new Engine (Consts.BinPath);
1660                         Project project = engine.CreateNewProject ();
1661
1662                         string second = @"<Project DefaultTargets='One' xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1663                                 <Target Name=""One"">
1664                                         <Message Text='Executing Second::One target'/>
1665                                 </Target>
1666                         </Project>";
1667                         using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "second.proj")))) {
1668                                 sw.Write (second);
1669                         }
1670
1671                         project.LoadXml (@"<Project DefaultTargets='pre' xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" >
1672                                 <Target Name=""boo"">
1673                                         <Message Text=""Executing boo target""/>
1674                                 </Target>
1675                                 <Target Name=""pre"">
1676                                         <Message Text=""Executing pre target""/>
1677                                 </Target>
1678                                 <Import Project='Test/resources/second.proj'/>
1679                         </Project>");
1680
1681                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
1682                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
1683                         engine.RegisterLogger (logger);
1684
1685                         try {
1686                                 Assert.IsTrue (project.Build (), "Build failed");
1687
1688                                 logger.CheckLoggedMessageHead ("Executing pre target", "A1");
1689                                 Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
1690
1691                                 Assert.AreEqual ("pre", project.DefaultTargets, "Default targets");
1692                         } catch {
1693                                 logger.DumpMessages ();
1694                                 throw;
1695                         }
1696                 }
1697
1698                 [Test]
1699                 public void TestNoDefaultTargetsWithImports () {
1700                         Engine engine = new Engine (Consts.BinPath);
1701                         Project project = engine.CreateNewProject ();
1702
1703
1704                         string second = @"<Project DefaultTargets='; One  ; Two' xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1705                                 <Target Name=""One"">
1706                                         <Message Text='Executing Second::One target'/>
1707                                 </Target>
1708                                 <Target Name=""Two"">
1709                                         <Message Text='Executing Second::Two target'/>
1710                                 </Target>
1711
1712                         </Project>";
1713                         using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "second.proj")))) {
1714                                 sw.Write (second);
1715                         }
1716
1717                         project.LoadXml (@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" >
1718                                 <Target Name=""boo"">
1719                                         <Message Text=""Executing boo target""/>
1720                                 </Target>
1721                                 <Target Name=""pre"">
1722                                         <Message Text=""Executing pre target""/>
1723                                 </Target>
1724                                 <Import Project='Test/resources/second.proj'/>
1725                         </Project>");
1726
1727                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
1728                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
1729                         engine.RegisterLogger (logger);
1730
1731                         try {
1732                                 Assert.IsTrue (project.Build (), "Build failed");
1733
1734                                 logger.CheckLoggedMessageHead ("Executing Second::One target", "A1");
1735                                 logger.CheckLoggedMessageHead ("Executing Second::Two target", "A2");
1736                                 Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
1737
1738                                 Assert.AreEqual ("One; Two", project.DefaultTargets, "Default targets");
1739                         } catch {
1740                                 logger.DumpMessages ();
1741                                 throw;
1742                         }
1743                 }
1744
1745                 [Test]
1746                 public void TestNoDefaultTargets () {
1747                         Engine engine = new Engine (Consts.BinPath);
1748                         Project project = engine.CreateNewProject ();
1749
1750                         project.LoadXml (@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" >
1751                                 <Target Name=""boo"">
1752                                         <Message Text=""Executing boo target""/>
1753                                 </Target>
1754                                 <Target Name=""pre"">
1755                                         <Message Text=""Executing pre target""/>
1756                                 </Target>
1757                         </Project>");
1758
1759                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
1760                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
1761                         engine.RegisterLogger (logger);
1762
1763                         try {
1764                                 Assert.IsTrue (project.Build (), "Build failed");
1765
1766                                 logger.CheckLoggedMessageHead ("Executing boo target", "A1");
1767                                 Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
1768
1769                                 Assert.AreEqual ("", project.DefaultTargets, "Default targets");
1770                         } catch {
1771                                 logger.DumpMessages ();
1772                                 throw;
1773                         }
1774                 }
1775
1776                 [Test]
1777                 public void TestPropertiesFromImportedProjects ()
1778                 {
1779                         Engine engine = new Engine (Consts.BinPath);
1780                         Project project = engine.CreateNewProject ();
1781
1782                         string second = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + @">
1783         <PropertyGroup>
1784           <Prop1>InitialVal</Prop1>
1785         </PropertyGroup>
1786         <ItemGroup>
1787                 <Second Include=""$(ThirdProp):Third""/>
1788         </ItemGroup>
1789
1790         <Target Name=""Main"">
1791                 <Message Text=""Prop1: $(Prop1) FooItem: @(FooItem)""/>
1792                 <Message Text=""Second: @(Second) ThirdProp: $(ThirdProp)""/>
1793         </Target>
1794         <Import Project=""third.proj""/>
1795 </Project>";
1796                         using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "second.proj")))) {
1797                                 sw.Write (second);
1798                         }
1799
1800                         string third = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + @">
1801         <PropertyGroup>
1802           <ThirdProp>Third Value</ThirdProp>
1803         </PropertyGroup>
1804 </Project>";
1805                         using (StreamWriter sw = new StreamWriter (Path.Combine ("Test", Path.Combine ("resources", "third.proj")))) {
1806                                 sw.Write (third);
1807                         }
1808
1809                         project.LoadXml (@"<Project InitialTargets=""Main"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1810         <ItemGroup>
1811                 <FooItem Include=""$(Prop1):Something""/>
1812         </ItemGroup>
1813
1814         <Import Project=""Test/resources/second.proj""/>
1815 </Project>");
1816
1817                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
1818                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
1819                         engine.RegisterLogger (logger);
1820
1821                         try {
1822                                 Assert.IsTrue (project.Build (), "Build failed");
1823
1824                                 logger.CheckLoggedMessageHead ("Prop1: InitialVal FooItem: InitialVal:Something", "A1");
1825                                 logger.CheckLoggedMessageHead ("Second: Third Value:Third ThirdProp: Third Value", "A2");
1826
1827                                 Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
1828                         } catch {
1829                                 logger.DumpMessages ();
1830                                 throw;
1831                         }
1832                 }
1833
1834                 [Test]
1835                 public void TestMSBuildThisProperties ()
1836                 {
1837                         Engine engine = new Engine (Consts.BinPath);
1838                         Project project = engine.CreateNewProject ();
1839
1840                         string base_dir = Path.GetFullPath (Path.Combine ("Test", "resources")) + Path.DirectorySeparatorChar;
1841                         string tmp_dir = Path.GetFullPath (Path.Combine (base_dir, "tmp")) + Path.DirectorySeparatorChar;
1842
1843                         string first_project = Path.Combine (base_dir, "first.proj");
1844                         string second_project = Path.Combine (tmp_dir, "second.proj");
1845                         string third_project = Path.Combine (tmp_dir, "third.proj");
1846
1847                         string first = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + @">
1848                                 <PropertyGroup>
1849                                         <FooInMain>$(MSBuildThisFileDirectory)</FooInMain>
1850                                 </PropertyGroup>
1851                                 <ItemGroup>
1852                                         <ItemInMain Include=""$(MSBuildThisFileFullPath)"" />
1853                                 </ItemGroup>
1854                                 <Import Project=""tmp\second.proj""/>
1855                         </Project>";
1856
1857                         string second = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + @">
1858                                 <PropertyGroup>
1859                                         <FooInImport1>$(MSBuildThisFileDirectory)</FooInImport1>
1860                                 </PropertyGroup>
1861                                 <PropertyGroup>
1862                                         <FooInImport2>$(MSBuildThisFileDirectory)</FooInImport2>
1863                                 </PropertyGroup>
1864                                 <ItemGroup>
1865                                         <ItemInImport1 Include=""$(MSBuildThisFileFullPath)"" />
1866                                 </ItemGroup>
1867
1868                                 <Import Project=""third.proj""/>
1869                         </Project>";
1870
1871                         string third = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + @">
1872                                 <PropertyGroup>
1873                                         <FooInTwo>$(MSBuildThisFileFullPath)</FooInTwo>
1874                                 </PropertyGroup>
1875                                 <ItemGroup>
1876                                         <ItemInTwo Include=""$(MSBuildThisFileFullPath)"" />
1877                                 </ItemGroup>
1878
1879                                 <Target Name=""TargetInTwo"">
1880                                         <Message Text=""FooInMain: $(FooInMain)""/>
1881                                         <Message Text=""FooInImport1: $(FooInImport1)""/>
1882                                         <Message Text=""FooInImport2: $(FooInImport2)""/>
1883                                         <Message Text=""FooInTwo: $(FooInTwo)""/>
1884
1885                                         <Message Text=""ItemInMain: %(ItemInMain.Identity)""/>
1886                                         <Message Text=""ItemInImport1: %(ItemInImport1.Identity)""/>
1887                                         <Message Text=""ItemInTwo: %(ItemInTwo.Identity)""/>
1888                                         <Message Text=""Full path: $(MSBuildThisFileFullPath)""/>
1889                                 </Target>
1890                         </Project>";
1891
1892                         File.WriteAllText (first_project, first);
1893
1894                         Directory.CreateDirectory (Path.Combine (base_dir, "tmp"));
1895                         File.WriteAllText (second_project, second);
1896                         File.WriteAllText (third_project, third);
1897
1898                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
1899                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
1900                         engine.RegisterLogger (logger);
1901
1902                         project.Load (first_project);
1903                         try {
1904                                 Assert.IsTrue (project.Build (), "Build failed");
1905
1906                                 logger.CheckLoggedMessageHead ("FooInMain: " + base_dir, "A1");
1907                                 logger.CheckLoggedMessageHead ("FooInImport1: " + tmp_dir, "A2");
1908                                 logger.CheckLoggedMessageHead ("FooInImport2: " + tmp_dir, "A3");
1909                                 logger.CheckLoggedMessageHead ("FooInTwo: " + third_project, "A4");
1910                                 logger.CheckLoggedMessageHead ("ItemInMain: " + first_project, "A5");
1911                                 logger.CheckLoggedMessageHead ("ItemInImport1: " + second_project, "A6");
1912                                 logger.CheckLoggedMessageHead ("ItemInTwo: " + third_project, "A7");
1913                                 logger.CheckLoggedMessageHead ("Full path: " + third_project, "A8");
1914
1915                                 Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
1916                         } catch {
1917                                 logger.DumpMessages ();
1918                                 throw;
1919                         } finally {
1920                                 File.Delete (first_project);
1921                                 File.Delete (second_project);
1922                                 File.Delete (third_project);
1923                         }
1924                 }
1925
1926                 [Test]
1927                 public void TestRequiredTask_String1 ()
1928                 {
1929                         CheckProjectForRequiredTests ("RequiredTestTask_String", "@(NonExistant)",
1930                                 false, "Should've failed: No value specified for required field - 'Property' of RequiredTestTask_String", null);
1931                 }
1932
1933                 [Test]
1934                 public void TestRequiredTask_String2 ()
1935                 {
1936                         CheckProjectForRequiredTests ("RequiredTestTask_String", "$(NonExistant)",
1937                                 false, "Should've failed: No value specified for required field - 'Property' of RequiredTestTask_String", null);
1938                 }
1939
1940                 [Test]
1941                 public void TestRequiredTask_Strings1 () {
1942                         CheckProjectForRequiredTests ("RequiredTestTask_Strings", "@(NonExistant)",
1943                                 true, "Build failed", "0");
1944                 }
1945
1946                 [Test]
1947                 public void TestRequiredTask_Strings2 () {
1948                         CheckProjectForRequiredTests ("RequiredTestTask_Strings", "$(NonExistant)",
1949                                 true, "Build failed", "0");
1950                 }
1951
1952                 [Test]
1953                 public void TestRequiredTask_Strings3 () {
1954                         CheckProjectForRequiredTests ("RequiredTestTask_Strings", "%(NonExistant.Md)",
1955                                 true, "Build failed", "0");
1956                 }
1957
1958                 [Test]
1959                 public void TestRequiredTask_Strings4 () {
1960                         CheckProjectForRequiredTests ("RequiredTestTask_Strings", "  %(NonExistant.Md)",
1961                                 true, "Build failed", "0");
1962                 }
1963
1964                 [Test]
1965                 public void TestRequiredTask_Ints1 () {
1966                         CheckProjectForRequiredTests ("RequiredTestTask_IntArray", "@(NonExistant)",
1967                                 true, "Build failed", "count: 0");
1968                 }
1969
1970                 [Test]
1971                 public void TestRequiredTask_Ints2 () {
1972                         CheckProjectForRequiredTests ("RequiredTestTask_IntArray", "$(NonExistant)",
1973                                 true, "Build failed", "count: 0");
1974                 }
1975
1976                 [Test]
1977                 public void TestRequiredTask_OtherObjectsArray () {
1978                         CheckProjectForRequiredTests ("RequiredTestTask_OtherObjectArray", "@(NonExistant)",
1979                                 false, "Should've failed: ObjectArray type not supported as a property type", null);
1980                 }
1981
1982                 [Test]
1983                 public void TestRequiredTask_OtherObject () {
1984                         CheckProjectForRequiredTests ("RequiredTestTask_OtherObjectArray", "@(NonExistant)",
1985                                 false, "Should've failed: ObjectArray type not supported as a property type", null);
1986                 }
1987
1988                 [Test]
1989                 public void TestRequiredTask_MyTaskItems1 () {
1990                         CheckProjectForRequiredTests ("RequiredTestTask_MyTaskItemArray", "@(NonExistant)",
1991                                 false, "Should've failed: ObjectArray type not supported as a property type", null);
1992                 }
1993
1994                 [Test]
1995                 public void TestRequiredTask_TaskItem1 ()
1996                 {
1997                         Project p = CheckProjectForRequiredTests ("RequiredTestTask_TaskItem", "@(NonExistant)",
1998                                 false, "Should've failed: No value specified for required field - 'Property' of RequiredTestTask_TaskItem", null);
1999                 }
2000
2001                 [Test]
2002                 public void TestRequiredTask_TaskItem2 ()
2003                 {
2004                         Project p = CheckProjectForRequiredTests ("RequiredTestTask_TaskItem", "$(NonExistant)",
2005                                 false, "Should've failed: No value specified for required field - 'Property' of RequiredTestTask_TaskItem", null);
2006                 }
2007
2008                 [Test]
2009                 public void TestRequiredTask_TaskItemArray1 ()
2010                 {
2011                         Project p = CheckProjectForRequiredTests ("RequiredTestTask_TaskItems", "@(NonExistant)",
2012                                 true, "Build failed", "count: 0");
2013
2014                         BuildItemGroup group = p.GetEvaluatedItemsByName ("OutItem");
2015                         Assert.AreEqual (1, group.Count, "A2");
2016                         Assert.AreEqual ("count: 0", group [0].FinalItemSpec, "A3");
2017                 }
2018
2019                 [Test]
2020                 public void TestRequiredTask_TaskItemArray2 ()
2021                 {
2022                         Project p = CheckProjectForRequiredTests ("RequiredTestTask_TaskItems", "$(NonExistant)",
2023                                 true, "Build failed", "count: 0");
2024
2025                         BuildItemGroup group = p.GetEvaluatedItemsByName ("OutItem");
2026                         Assert.AreEqual (1, group.Count, "A2");
2027                         Assert.AreEqual ("count: 0", group [0].FinalItemSpec, "A3");
2028                 }
2029
2030                 [Test]
2031                 public void TestRequiredTask_TaskItemArray3 ()
2032                 {
2033                         Project p = CheckProjectForRequiredTests ("RequiredTestTask_IntArray", "$(NonExistant)",
2034                                 true, "Build failed", "count: 0");
2035
2036                         BuildItemGroup group = p.GetEvaluatedItemsByName ("OutItem");
2037                         Assert.AreEqual (1, group.Count, "A2");
2038                         Assert.AreEqual ("count: 0", group [0].FinalItemSpec, "A3");
2039                 }
2040
2041                 [Test]
2042                 public void TestRequiredTask_TaskItemArray4 () {
2043                         Project p = CheckProjectForRequiredTests ("RequiredTestTask_IntArray", "%(NonExistant.Md)",
2044                                 true, "Build failed", "count: 0");
2045
2046                         BuildItemGroup group = p.GetEvaluatedItemsByName ("OutItem");
2047                         Assert.AreEqual (1, group.Count, "A2");
2048                         Assert.AreEqual ("count: 0", group[0].FinalItemSpec, "A3");
2049                 }
2050
2051                 [Test]
2052                 public void TestRequiredTask_TaskItemArray5 () {
2053                         // with extra space in prop value
2054                         Project p = CheckProjectForRequiredTests ("RequiredTestTask_IntArray", "  %(NonExistant.Md)",
2055                                 true, "Build failed", "count: 0");
2056
2057                         BuildItemGroup group = p.GetEvaluatedItemsByName ("OutItem");
2058                         Assert.AreEqual (1, group.Count, "A2");
2059                         Assert.AreEqual ("count: 0", group[0].FinalItemSpec, "A3");
2060                 }
2061
2062
2063                 [Test]
2064                 public void TestCaseSensitivityOfProjectElements ()
2065                 {
2066                         string projectXml = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + @">
2067         <ItemGroup>
2068                 <Abc Include=""foo"">
2069                         <MetaDaTA1>md1</MetaDaTA1>
2070                         <METadata2>md2</METadata2>
2071                 </Abc>
2072                 <Abc Include=""FOO"">
2073                         <MetaDaTA1>MD1 caps</MetaDaTA1>
2074                         <METadata2>MD2 caps</METadata2>
2075                 </Abc>
2076                 <Abc Include=""hmm"">
2077                         <MetaDaTA1>Md1 CAPS</MetaDaTA1>
2078                         <METadata2>MD2 CAPS</METadata2>
2079                 </Abc>
2080                 <Abc Include=""bar"">
2081                         <MeTAdata1>md3</MeTAdata1>
2082                         <Metadata2>md4</Metadata2>
2083                 </Abc>
2084         </ItemGroup> 
2085         <PropertyGroup><ProP1>ValueProp</ProP1></PropertyGroup>
2086         <Target Name=""Main"">
2087                 <MesSAGE Text=""Full item: @(ABC)""/>
2088                 <MEssaGE Text=""metadata1 :%(AbC.MetaDATA1) metadata2: %(ABC.MetaDaTa2)""/>
2089                 <MEssaGE Text=""metadata2 : %(AbC.MetaDAta2)""/>
2090                 <MEssaGE Text=""Abc identity: %(ABC.IDENTitY)""/>
2091                 <MEssaGE Text=""prop1 : $(pROp1)""/>
2092         </Target>
2093 </Project>
2094 ";
2095                         Engine engine = new Engine (Consts.BinPath);
2096                         Project project = engine.CreateNewProject ();
2097                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
2098                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
2099                         engine.RegisterLogger (logger);
2100
2101                         project.LoadXml (projectXml);
2102                         bool result = project.Build ("Main");
2103                         if (!result) {
2104                                 logger.DumpMessages ();
2105                                 Assert.Fail ("A1: Build failed");
2106                         }
2107                         logger.DumpMessages ();
2108
2109                         logger.CheckLoggedMessageHead ("Full item: foo;FOO;hmm;bar", "#A2");
2110                         logger.CheckLoggedMessageHead ("metadata1 :md1 metadata2: md2", "#A3");
2111                         logger.CheckLoggedMessageHead ("metadata1 :MD1 caps metadata2: MD2 caps", "#A4");
2112                         logger.CheckLoggedMessageHead ("metadata1 :md3 metadata2: md4", "#A5");
2113                         logger.CheckLoggedMessageHead ("metadata2 : md2", "#A6");
2114                         logger.CheckLoggedMessageHead ("metadata2 : MD2 caps", "#A7");
2115                         logger.CheckLoggedMessageHead ("metadata2 : md4", "#A8");
2116                         logger.CheckLoggedMessageHead ("Abc identity: foo", "#A9");
2117                         logger.CheckLoggedMessageHead ("Abc identity: hmm", "#A10");
2118                         logger.CheckLoggedMessageHead ("Abc identity: bar", "#A11");
2119                         logger.CheckLoggedMessageHead ("prop1 : ValueProp", "#A12");
2120
2121                         Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
2122
2123                 }
2124
2125                 // full solution test
2126                 //[Test]
2127                 public void TestBuildSolutionProject ()
2128                 {
2129                         string basepath = Path.Combine ("Test", Path.Combine ("resources", "Project01"));
2130                         string [] project_dirs = new string [] {
2131                                 Path.Combine (basepath, "Lib4"),
2132                                 Path.Combine (basepath, "Lib3"),
2133                                 Path.Combine (basepath, "Lib2"),
2134                                 Path.Combine (basepath, "Lib1"),
2135                                 Path.Combine (basepath, "Project01")
2136                         };
2137                         string debug_extn = Consts.RunningOnMono () ? ".dll.mdb" : ".pdb";
2138
2139                         // List of expected output files
2140                         // Lib3
2141                         string [] [] project_files = new string [5][] {
2142                                 new string [] { "Lib4.dll", "Lib4" + debug_extn },
2143                                 new string [] { "Lib3.dll" , "Lib3" + debug_extn },
2144                                 // Lib2
2145                                 new string [] {
2146                                         "Lib2.dll", "Lib2" + debug_extn,
2147                                         "lib2_folder/Lib2.deploy.txt",
2148                                         Path.Combine ("fr-CA", "Lib2.resources.dll"),
2149                                         Path.Combine ("fr-FR", "Lib2.resources.dll"),
2150                                         "Lib4.dll", "Lib4" + debug_extn
2151                                 },
2152                                 
2153                                 // lib1
2154                                 new string [] {
2155                                         // lib1 files
2156                                         "Lib1.dll", "Lib2" + debug_extn,
2157                                         "Lib1.deploy.txt",
2158                                         Path.Combine ("fr-CA", "Lib1.resources.dll"),
2159                                         Path.Combine ("fr-FR", "Lib1.resources.dll"),
2160                                         Path.Combine ("en-US", "Lib1.resources.dll"),
2161                                         // lib2 files
2162                                         "Lib2.dll", "Lib2" + debug_extn,
2163                                         "lib2_folder/Lib2.deploy.txt",
2164                                         Path.Combine ("fr-CA", "Lib2.resources.dll"),
2165                                         Path.Combine ("fr-FR", "Lib2.resources.dll"),
2166                                         // lib3 files
2167                                         "Lib3.dll", "Lib3" + debug_extn,
2168                                         "Lib4.dll", "Lib4" + debug_extn
2169                                         },
2170
2171                                 new string [] {
2172                                         "Project01.exe",
2173                                         "Project01" + (Consts.RunningOnMono () ? ".exe.mdb" : ".pdb"),
2174                                         // lib1 files
2175                                         "Lib1.dll", "Lib1" + debug_extn,
2176                                         "Lib1.deploy.txt",
2177                                         Path.Combine ("fr-CA", "Lib1.resources.dll"),
2178                                         Path.Combine ("fr-FR", "Lib1.resources.dll"),
2179                                         Path.Combine ("en-US", "Lib1.resources.dll"),
2180                                         // lib2 files
2181                                         "Lib2.dll", "Lib2" + debug_extn,
2182                                         "lib2_folder/Lib2.deploy.txt",
2183                                         Path.Combine ("fr-CA", "Lib2.resources.dll"),
2184                                         Path.Combine ("fr-FR", "Lib2.resources.dll"),
2185                                         "Lib4.dll", "Lib4" + debug_extn,
2186                                         }
2187                         };
2188
2189                         // Cleanup
2190                         for (int i = 0; i < project_dirs.Length; i ++) {
2191                                 string bin_path = Path.Combine (project_dirs [i], Path.Combine ("bin", "Debug"));
2192                                 string obj_path = Path.Combine (project_dirs [i], Path.Combine ("obj", "Debug"));
2193
2194                                 DeleteAllInDir (bin_path);
2195
2196                                 DeleteAllInDir (obj_path);
2197                         }
2198
2199                         Engine engine = new Engine (Consts.BinPath);
2200                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
2201                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
2202                         engine.RegisterLogger (logger);
2203
2204                         engine.GlobalProperties = new BuildPropertyGroup ();
2205                         engine.GlobalProperties.SetProperty ("TreatWarningsAsErrors", "false");
2206
2207                         Project project = engine.CreateNewProject ();
2208                         project.Load (Path.Combine (basepath, "Project01.sln.proj"));
2209                         
2210                         bool result = project.Build ();
2211                         if (!result) {
2212                                 logger.DumpMessages ();
2213                                 Assert.Fail ("Build failed");
2214                         }
2215
2216                         // We check only the output dir, not the 'obj'
2217                         string debug = Path.Combine ("bin", "Debug");
2218                         for (int i = 0; i < project_dirs.Length; i++) {
2219                                 CheckFilesExistInDir (Path.Combine (project_dirs [i], debug),
2220                                         project_files [i]);
2221                         }
2222                 }
2223
2224                 void DeleteAllInDir (string path)
2225                 {
2226                         if (!Directory.Exists (path))
2227                                 return;
2228
2229                         foreach (string file in Directory.GetFiles (path))
2230                                 File.Delete (file);
2231                         Directory.Delete (path, true);
2232                 }
2233
2234                 void CheckFilesExistInDir (string dir, params string [] files)
2235                 {
2236                         foreach (string file in files) {
2237                                 string path = Path.Combine (dir, file);
2238                                 Assert.IsTrue (File.Exists (path),
2239                                         String.Format ("Expected to find file {0}", path));
2240                         }
2241                 }
2242
2243                 Project CheckProjectForRequiredTests (string taskname, string property_arg, bool expected_result, string error_msg,
2244                         string expected_output_msg)
2245                 {
2246                         string projectString = String.Format (@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
2247                                 <UsingTask TaskName=""{0}"" AssemblyFile=""Test/resources/TestTasks.dll"" />
2248                                 <Target Name=""foo"">
2249                                         <{0} Property=""{1}"">
2250                                                 <Output TaskParameter=""Output"" ItemName=""OutItem""/>
2251                                         </{0}>
2252                                         <Message Text='@(OutItem)'/>
2253                                 </Target>
2254                         </Project>", taskname, property_arg);
2255
2256                         Engine engine = new Engine (Consts.BinPath);
2257                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
2258                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
2259                         engine.RegisterLogger (logger);
2260                         Project project = engine.CreateNewProject ();
2261                         project.LoadXml (projectString);
2262                         try {
2263                                 Assert.AreEqual (expected_result, project.Build (), error_msg);
2264                                 if (expected_result) {
2265                                         logger.CheckLoggedMessageHead (expected_output_msg, "A");
2266                                         Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected messages found");
2267                                 }
2268                         } finally {
2269                                 logger.DumpMessages ();
2270                         }
2271                         return project;
2272                 }
2273
2274                 static void CheckBuildItem (BuildItem item, string name, string [,] metadata, string finalItemSpec, string prefix)
2275                 {
2276                         Assert.AreEqual (name, item.Name, prefix + "#1");
2277                         for (int i = 0; i < metadata.GetLength (0); i++) {
2278                                 string key = metadata [i, 0];
2279                                 string val = metadata [i, 1];
2280                                 Assert.IsTrue (item.HasMetadata (key), String.Format ("{0}#2: Expected metadata '{1}' not found", prefix, key));
2281                                 Assert.AreEqual (val, item.GetMetadata (key), String.Format ("{0}#3: Value for metadata {1}", prefix, key));
2282                                 Assert.AreEqual (val, item.GetEvaluatedMetadata (key), String.Format ("{0}#4: Value for evaluated metadata {1}", prefix, key));
2283                         }
2284                         Assert.AreEqual (finalItemSpec, item.FinalItemSpec, prefix + "#5");
2285                 }
2286
2287                 void CheckProjectBuild (Project project, string [] targetNames, bool result, string [] outputNames, string prefix)
2288                 {
2289                         IDictionary targetOutputs = new Hashtable ();
2290
2291                         Assert.AreEqual (result, project.Build (targetNames, targetOutputs), prefix + "A1");
2292                         Assert.AreEqual (outputNames.Length, targetOutputs.Keys.Count, prefix + "A2");
2293
2294                         foreach (string outputName in outputNames) {
2295                                 Assert.IsTrue (targetOutputs.Contains (outputName), prefix + " A3: target " + outputName);
2296
2297                                 object o = targetOutputs [outputName];
2298                                 Assert.IsTrue (typeof (ITaskItem []).IsAssignableFrom (o.GetType ()), prefix + " A4: target " + outputName);
2299
2300                                 ITaskItem [] items = (ITaskItem [])o;
2301                                 Assert.AreEqual (0, items.Length, prefix + "A5: target " + outputName);
2302                         }
2303                 }
2304
2305                 string CreateProjectString (bool run_separate, string [] targets, bool [] results, string prefix)
2306                 {
2307                         StringBuilder sb = new StringBuilder ();
2308                         sb.Append (@"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">");
2309                         sb.AppendFormat ("<Target Name = \"{0}\"><Message Text = \"#Target {1}:{0} called\" />", "main", prefix);
2310
2311                         sb.AppendFormat ("<CallTarget Targets=\"");
2312                         for (int i = 0; i < targets.Length; i++)
2313                                 sb.AppendFormat ("{0};", targets [i]);
2314                         sb.AppendFormat ("\" ");
2315
2316                         if (run_separate)
2317                                 sb.AppendFormat (" RunEachTargetSeparately=\"true\" ");
2318                         sb.AppendFormat ("/></Target>\n");
2319
2320                         for (int i = 0; i < targets.Length; i++) {
2321                                 sb.AppendFormat ("<Target Name = \"{0}\"><Message Text = \"#Target {1}:{0} called\" />", targets [i], prefix);
2322                                 if (!results [i])
2323                                         sb.AppendFormat ("<Error Text = \"#Error message for target {0}:{1}\"/>", prefix, targets [i]);
2324                                 sb.Append ("</Target>\n");
2325                         }
2326
2327                         sb.Append ("</Project>");
2328
2329                         return sb.ToString ();
2330                 }
2331
2332                 void CreateProjectFile (string fname, bool run_separate, string [] targets, bool [] results, string prefix)
2333                 {
2334                         using (StreamWriter sw = new StreamWriter (fname))
2335                                 sw.Write (CreateProjectString (run_separate, targets, results, prefix));
2336                 }
2337
2338                 Project CreateAndLoadProject (string fname, bool run_separate, string [] targets, bool [] results, string prefix)
2339                 {
2340                         Engine engine = new Engine (Consts.BinPath);
2341                         Project project = engine.CreateNewProject ();
2342
2343                         string projectXml = CreateProjectString (run_separate, targets, results, prefix);
2344                         if (fname == null) {
2345                                 project.LoadXml (projectXml);
2346                         } else {
2347                                 using (StreamWriter sw = new StreamWriter (fname))
2348                                         sw.Write (projectXml);
2349                                 project.Load (fname);
2350                                 File.Delete (fname);
2351                         }
2352
2353                         return project;
2354                 }
2355         }
2356 }