[xbuild] Clean up test logs.
[mono.git] / mcs / class / Microsoft.Build.Engine / Test / various / Items.cs
1 //
2 // Items.cs
3 //
4 // Author:
5 //   Marek Sieradzki (marek.sieradzki@gmail.com)
6 //   Ankit Jain (jankit@novell.com)
7 //
8 // (C) 2006 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.Text;
32 using System.Xml;
33 using Microsoft.Build.BuildEngine;
34 using NUnit.Framework;
35 using System.IO;
36 using Microsoft.Build.Framework;
37
38 namespace MonoTests.Microsoft.Build.BuildEngine.Various {
39         [TestFixture]
40         public class Items {
41                 private string GetItems (Project proj, string name)
42                 {
43                         BuildItemGroup big = proj.GetEvaluatedItemsByName (name);
44                         string str = String.Empty;
45                         if (big == null)
46                                 return str;
47
48                         foreach (BuildItem bi in big) {
49                                 if (str == String.Empty)
50                                         str = bi.FinalItemSpec;
51                                 else 
52                                         str += ";" + bi.FinalItemSpec;
53                         }
54                         
55                         return str;
56                 }
57
58                 private void CheckItems (Project proj, string name, string prefix, params string [] values)
59                 {
60                         BuildItemGroup big = proj.GetEvaluatedItemsByName (name);
61                         if (big == null) {
62                                 Assert.Fail ("{0}: Item corresponding '{1}' not found.", prefix, name);
63                                 return;
64                         }
65
66                         if (values.Length != big.Count) {
67                                 Console.Write ("Expected> ");
68                                 foreach (string s in values)
69                                         Console.Write ("{0}|", s);
70                                 Console.WriteLine ();
71                                 Console.Write ("Actual> ");
72                                 foreach (BuildItem item in big)
73                                         Console.Write ("{0}|", item.FinalItemSpec);
74                                 Console.WriteLine ();
75                                 Assert.AreEqual (values.Length, big.Count, String.Format ("{0}: Number of items", prefix));
76                         }
77                         for (int i = 0; i < values.Length; i ++)
78                                 Assert.AreEqual (values [i], big [i].FinalItemSpec,
79                                         String.Format ("{0}: Item named {1}, numbered {2}", prefix, name, i));
80                 }
81
82                 [Test]
83                 public void TestItems1 ()
84                 {
85                         Engine engine = new Engine (Consts.BinPath);
86                         Project proj = engine.CreateNewProject ();
87
88                         string documentString = @"
89                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
90                                         <ItemGroup>
91                                                 <Item0 Include='A' />
92                                                 <Item1 Include='A;B;C' />
93                                                 <Item2 Include='@(Item1);A;D' />
94                                                 <Item3 Include='@(Item2)' Exclude='A' />
95                                                 <Item4 Include='@(Item1);Q' Exclude='@(Item2)' />
96                                                 <Item5 Include='@(Item1)' Exclude='@(Item2)' />
97                                                 <Item6 Include='@(Item2)' Exclude='@(Item1)' />
98                                                 <Item7 Include='@(item_that_doesnt_exist)' />
99                                         </ItemGroup>
100                                 </Project>
101                         ";
102
103                         proj.LoadXml (documentString);
104                         CheckItems (proj, "Item0", "A1", "A");
105                         CheckItems (proj, "Item1", "A2", "A", "B", "C");
106                         CheckItems (proj, "Item2", "A3", "A", "B", "C", "A", "D");
107                         CheckItems (proj, "Item3", "A4", "B", "C", "D");
108                         CheckItems (proj, "Item4", "A5", "Q");
109                         CheckItems (proj, "Item5", "A6");
110                         CheckItems (proj, "Item6", "A7", "D");
111                         CheckItems (proj, "Item7", "A8");
112                 }
113
114                 [Test]
115                 public void TestItems2 ()
116                 {
117                         Engine engine = new Engine (Consts.BinPath);
118                         Project proj = engine.CreateNewProject ();
119
120                         string documentString = @"
121                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
122                                         <ItemGroup>
123                                                 <Item1 Include='A;B;C' />
124                                                 <Item2 Include=""@(Item1,'-')"" />
125                                                 <Item3 Include=""@(Item1,'xx')"" />
126                                         </ItemGroup>
127                                 </Project>
128                         ";
129
130                         proj.LoadXml (documentString);
131
132                         CheckItems (proj, "Item2", "A1", "A-B-C");
133                         CheckItems (proj, "Item3", "A2", "AxxBxxC");
134                 }
135
136                 [Test]
137                 // item with 1. item ref with a separator and 2. another item ref
138                 public void TestItems2a () {
139                         Engine engine = new Engine (Consts.BinPath);
140                         Project proj = engine.CreateNewProject ();
141
142                         string documentString = @"
143                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
144                                         <ItemGroup>
145                                                 <Item0 Include='D'/>
146                                                 <Item1 Include='A;B;C' />
147                                                 <Item2 Include=""@(Item1,'-');@(Item0)"" />
148                                                 <Item3 Include=""@(Item1,'xx')"" />
149                                         </ItemGroup>
150                                 </Project>
151                         ";
152
153                         proj.LoadXml (documentString);
154
155                         CheckItems (proj, "Item2", "A1", "A-B-C", "D");
156                         CheckItems (proj, "Item3", "A2", "AxxBxxC");
157                 }
158
159                 [Test]
160                 public void TestInheritedMetadataFromItemRefs () {
161                         Engine engine = new Engine (Consts.BinPath);
162                         Project proj = engine.CreateNewProject ();
163                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
164                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
165                         engine.RegisterLogger (logger);
166
167                         string documentString = @"
168                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
169                                         <ItemGroup>
170                                                 <Item0 Include='D'>
171                                                         <MD0>Val0</MD0>
172                                                 </Item0>
173                                                 <Item1 Include='A;@(Item0)' >
174                                                         <MD1>Val1</MD1>
175                                                 </Item1>
176                                                 <Item2 Include=""@(Item1,'-')"" />
177                                                 <Item3 Include=""@(Item1);Z"" />
178                                         </ItemGroup>
179
180                                                 <Target Name=""Main"">
181                 <Message Text=""Item2: %(Item2.Identity) MD0: %(Item2.MD0) MD1: %(Item2.MD1)""/>
182                 <Message Text=""Item3: %(Item3.Identity) MD0: %(Item3.MD0) MD1: %(Item3.MD1)""/>
183         </Target>
184                                 </Project>
185                         ";
186
187                         proj.LoadXml (documentString);
188
189                         CheckItems (proj, "Item2", "A1", "A-D");
190                         CheckItems (proj, "Item3", "A2", "A", "D", "Z");
191
192                         if (!proj.Build ("Main")) {
193                                 logger.DumpMessages ();
194                                 Assert.Fail ("Build failed");
195                         }
196
197                         logger.CheckLoggedMessageHead ("Item2: A-D MD0:  MD1: ", "A4");
198
199                         logger.CheckLoggedMessageHead ("Item3: A MD0:  MD1: Val1", "A5");
200                         logger.CheckLoggedMessageHead ("Item3: D MD0: Val0 MD1: Val1", "A6");
201                         logger.CheckLoggedMessageHead ("Item3: Z MD0:  MD1: ", "A7");
202
203                         Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
204                 }
205
206                 [Test]
207                 public void TestInheritedMetadataFromItemRefs2 () {
208                         Engine engine = new Engine (Consts.BinPath);
209                         Project proj = engine.CreateNewProject ();
210                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
211                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
212                         engine.RegisterLogger (logger);
213
214                         string documentString = @"
215                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
216                                         <ItemGroup>
217                                                 <Item5 Include='ZZ'>
218                                                         <MD5>Val5</MD5>
219                                                 </Item5>
220
221                                                 <Item0 Include='D'>
222                                                         <MD0>Val0</MD0>
223                                                 </Item0>
224                                                 <Item1 Include='A;@(Item0)' >
225                                                         <MD1>Val1</MD1>
226                                                 </Item1>
227                                                 <Item2 Include=""@(Item1,'-');@(Item5)"" />
228                                         </ItemGroup>
229
230                                                 <Target Name=""Main"">
231                 <Message Text=""Item2: %(Item2.Identity) MD0: %(Item2.MD0) MD1: %(Item2.MD1) MD5: %(Item2.MD5)""/>
232         </Target>
233                                 </Project>
234                         ";
235
236                         proj.LoadXml (documentString);
237
238                         CheckItems (proj, "Item2", "A1", "A-D", "ZZ");
239
240                         if (!proj.Build ("Main")) {
241                                 logger.DumpMessages ();
242                                 Assert.Fail ("Build failed");
243                         }
244
245                         logger.CheckLoggedMessageHead ("Item2: A-D MD0:  MD1:  MD5: ", "A4");
246                         logger.CheckLoggedMessageHead ("Item2: ZZ MD0:  MD1:  MD5: Val5", "A5");
247                         Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
248                 }
249
250                 [Test]
251                 public void TestItems3 ()
252                 {
253                         Engine engine = new Engine (Consts.BinPath);
254                         Project proj = engine.CreateNewProject ();
255
256                         string documentString = @"
257                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
258                                         <ItemGroup>
259                                                 <Item1 Include='A;B;C' />
260                                                 <Item2 Include=""@(Item1, '-')"" />
261                                         </ItemGroup>
262                                 </Project>
263                         ";
264
265                         proj.LoadXml (documentString);
266
267                         CheckItems (proj, "Item2", "A1", "A-B-C");
268                 }
269         
270
271                 [Test]
272                 public void TestItems4 ()
273                 {
274                         Engine engine = new Engine (Consts.BinPath);
275                         Project proj = engine.CreateNewProject ();
276
277                         string documentString = @"
278                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
279                                         <PropertyGroup>
280                                                 <Prop1>@(Item0)</Prop1>
281                                         </PropertyGroup>
282                                         <ItemGroup>
283                                                 <Item0 Include=""Foo""/>
284                                                 <Item1 Include='A;B;C' />
285                                                 <Item2 Include=""A\B.txt;A\C.txt;B\B.zip;B\C.zip"" />
286                                                 <ItemT0 Include=""@(Item1)"" />
287                                                 <ItemT1 Include=""@(Item1->'%(Identity)')"" />
288                                                 <ItemT2 Include=""@(Item1->'%(Identity)%(Identity)')"" />
289                                                 <ItemT3 Include=""@(Item1->'(-%(Identity)-)')"" />
290                                                 <ItemT4 Include=""@(Item2->'%(Extension)')"" />
291                                                 <ItemT5 Include=""@(Item2->'%(Filename)/%(Extension)')"" />
292                                                 <ItemT6 Include=""@(Item2->'%(Extension)/$(Prop1)')"" />
293                                         </ItemGroup>
294                                 </Project>
295                         ";
296
297                         proj.LoadXml (documentString);
298
299                         //Assert.IsTrue (proj.Build (), "Build failed");
300
301                         Assert.AreEqual ("@(Item0)", proj.EvaluatedProperties["Prop1"].FinalValue, "A0");
302                         //Assert.AreEqual ("@(Item2->'%(Extension)/$(Prop1)')", proj.EvaluatedItems [7].FinalItemSpec, "B0");
303
304                         CheckItems (proj, "ItemT0", "A1", "A", "B", "C");
305                         CheckItems (proj, "ItemT1", "A1", "A", "B", "C");
306                         CheckItems (proj, "ItemT2", "A2", "AA", "BB", "CC");
307                         CheckItems (proj, "ItemT3", "A3", "(-A-)", "(-B-)", "(-C-)");
308                         CheckItems (proj, "ItemT4", "A4", ".txt", ".txt", ".zip", ".zip");
309                         CheckItems (proj, "ItemT5", "A5", "B/.txt", "C/.txt", "B/.zip", "C/.zip");
310                         CheckItems (proj, "ItemT6", "A6", ".txt/@(Item0)", ".txt/@(Item0)", ".zip/@(Item0)", ".zip/@(Item0)");
311                 }
312
313                 [Test]
314                 public void TestItems5 ()
315                 {
316                         Engine engine = new Engine (Consts.BinPath);
317                         Project proj = engine.CreateNewProject ();
318
319                         string documentString = @"
320                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
321                                         <ItemGroup>
322                                                 <Item Include=""A\B.txt;A\C.txt;B\B.zip;B\C.zip"" />
323                                                 <ItemT Include=""@(Item->'%(RelativeDir)X\%(Filename)')"" />
324                                         </ItemGroup>
325                                 </Project>
326                         ";
327
328                         proj.LoadXml (documentString);
329
330                         string dir_a = Path.Combine ("A", "X");
331                         string dir_b = Path.Combine ("B", "X");
332                         CheckItems (proj, "ItemT", "A1", Path.Combine (dir_a, "B"), Path.Combine (dir_a, "C"),
333                                                                 Path.Combine (dir_b, "B"), Path.Combine (dir_b, "C"));
334                 }
335
336                 [Test]
337                 public void TestItems6 ()
338                 {
339                         Engine engine = new Engine (Consts.BinPath);
340                         Project proj = engine.CreateNewProject ();
341
342                         string documentString = @"
343                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
344                                         <PropertyGroup>
345                                                 <A>A</A>
346                                         </PropertyGroup>
347
348                                         <ItemGroup>
349                                                 <Item1 Include='A;B;C' />
350                                                 <Item2 Include='%(A.B)' />
351                                                 <Item3 Include='$(Z)' />
352                                                 <Item4 Include=""@(Item1, '$(A)')"" />
353                                                 <Item5 Include=""@(Item1, '%(A)')"" />
354                                                 <Item6 Include=""@(Item1, '@(A)')"" />
355                                                 <Item7 Include=""@(Item1-> '%(Filename)')"" />
356                                         </ItemGroup>
357                                 </Project>
358                         ";
359
360                         proj.LoadXml (documentString);
361
362                         CheckItems (proj, "Item2", "A1", "%(A.B)");
363                         CheckItems (proj, "Item3", "A2");
364                         CheckItems (proj, "Item4", "A3", "AABAC");
365                         CheckItems (proj, "Item5", "A4", "A%(A)B%(A)C");
366                         CheckItems (proj, "Item6", "A6", "A@(A)B@(A)C");
367                         CheckItems (proj, "Item7", "A6", "A", "B", "C");
368                 }
369
370                 // The expression "@(Item1, '@(A,'')')" cannot be used in this context. 
371                 // Item lists cannot be concatenated with other strings where an item list is expected. 
372                 // Use a semicolon to separate multiple item lists.
373                 [Test]
374                 [ExpectedException (typeof (InvalidProjectFileException))]
375                 [Category ("NotWorking")]
376                 public void TestItems7 ()
377                 {
378                         Engine engine = new Engine (Consts.BinPath);
379                         Project proj = engine.CreateNewProject ();
380
381                         string documentString = @"
382                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
383                                         <ItemGroup>
384                                                 <Item1 Include='A;B;C' />
385                                                 <Item7 Include=""@(Item1, '@(A,'')')"" />
386                                         </ItemGroup>
387                                 </Project>
388                         ";
389
390                         proj.LoadXml (documentString);
391                 }
392
393                 // The expression "@(Item1, '@(A->'')')" cannot be used in this context.
394                 // Item lists cannot be concatenated with other strings where an item list is expected.
395                 // Use a semicolon to separate multiple item lists.
396                 [Test]
397                 [ExpectedException (typeof (InvalidProjectFileException))]
398                 [Category ("NotWorking")]
399                 public void TestItems8 ()
400                 {
401                         Engine engine = new Engine (Consts.BinPath);
402                         Project proj = engine.CreateNewProject ();
403
404                         string documentString = @"
405                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
406                                         <ItemGroup>
407                                                 <Item1 Include='A;B;C' />
408                                                 <Item8 Include=""@(Item1, '@(A->'')')"" />
409                                         </ItemGroup>
410                                 </Project>
411                         ";
412
413                         proj.LoadXml (documentString);
414                 }
415
416                 // The expression "@(Item1, '@(A->'','')')" cannot be used in this context.
417                 // Item lists cannot be concatenated with other strings where an item list is expected.
418                 // Use a semicolon to separate multiple item lists.
419                 [Test]
420                 [ExpectedException (typeof (InvalidProjectFileException))]
421                 [Category ("NotWorking")]
422                 public void TestItems9 ()
423                 {
424                         Engine engine = new Engine (Consts.BinPath);
425                         Project proj = engine.CreateNewProject ();
426
427                         string documentString = @"
428                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
429                                         <ItemGroup>
430                                                 <Item1 Include='A;B;C' />
431                                                 <Item9 Include=""@(Item1, '@(A->'','')')"" />
432                                         </ItemGroup>
433                                 </Project>
434                         ";
435
436                         proj.LoadXml (documentString);
437                 }
438
439                 [Test]
440                 // test item metadata
441                 public void TestItems10 ()
442                 {
443                         string project_xml = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
444         <PropertyGroup>
445                 <Prop1>@(Item0)</Prop1>
446                 <Prop2>@(Ref1)</Prop2>
447         </PropertyGroup>
448         <ItemGroup>
449                 <Item0 Include=""Foo""/>
450                 <Ref1 Include=""File1"" />
451                 <IWithM Include=""A"">
452                         <Md>@(Item0)</Md>
453                         <Md2>$(Prop2)</Md2>
454                 </IWithM>
455         </ItemGroup>
456
457         <Target Name=""1"">
458                 <Message Text=""IWithM.md: %(IWithM.Md)""/>
459                 <Message Text=""IWithM.md2: %(IWithM.Md2)""/>
460
461                 <CreateItem Include=""Bar;Xyz"">
462                         <Output TaskParameter=""Include"" ItemName=""Item0""/>
463                 </CreateItem>
464                 
465                 <Message Text=""IWithM.md: %(IWithM.Md)""/>
466                 <Message Text=""IWithM.md2: %(IWithM.Md2)""/>
467         </Target>
468 </Project>
469 ";
470
471                         Engine engine = new Engine (Consts.BinPath);
472                         Project proj = engine.CreateNewProject ();
473                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
474                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
475                         proj.LoadXml (project_xml);
476                         engine.RegisterLogger (logger);
477
478                         if (!proj.Build ("1")) {
479                                 logger.DumpMessages ();
480                                 Assert.Fail ("Build failed");
481                         }
482
483                         logger.CheckLoggedMessageHead ("IWithM.md: Foo", "A1");
484                         logger.CheckLoggedMessageHead ("IWithM.md2: File1", "A2");
485
486                         logger.CheckLoggedMessageHead ("IWithM.md: Foo", "A3");
487                         logger.CheckLoggedMessageHead ("IWithM.md2: File1", "A4");
488                         Assert.AreEqual (0, logger.NormalMessageCount, "unexpected messages found");
489                 }
490
491                 [Test]
492                 // Test Item/prop references in conditions
493                 public void TestItems11 () {
494                         string project_xml = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
495         <PropertyGroup>
496                 <Prop1>@(Item0)</Prop1>
497         </PropertyGroup>
498         <ItemGroup>
499                 <Item0 Include=""Foo""/>
500                 <Item1 Include=""@(Item0)""/>
501
502                 <CondItem Condition=""'@(Item1)' == '@(Item0)'"" Include=""Equal to item0""/>
503                 <CondItem Condition=""'@(Item1)' == 'Foo'"" Include=""Equal to item0's value""/>
504
505                 <CondItem1 Condition=""'$(Prop1)' == '@(Item0)'"" Include=""Equal to item0""/>
506                 <CondItem1 Condition=""'$(Prop1)' == 'Foo'"" Include=""Equal to item0's value""/>
507         </ItemGroup>
508
509         <Target Name=""1"">
510                 <Message Text = ""CondItem: %(CondItem.Identity)""/>
511                 <Message Text = ""CondItem1: %(CondItem1.Identity)""/>
512         </Target>
513 </Project>
514 ";
515
516                         Engine engine = new Engine (Consts.BinPath);
517                         Project proj = engine.CreateNewProject ();
518                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
519                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
520                         proj.LoadXml (project_xml);
521                         engine.RegisterLogger (logger);
522
523                         if (!proj.Build ("1")) {
524                                 logger.DumpMessages ();
525                                 Assert.Fail ("Build failed");
526                         }
527
528                         logger.CheckLoggedMessageHead ("CondItem: Equal to item0", "A1");
529                         logger.CheckLoggedMessageHead ("CondItem: Equal to item0's value", "A2");
530                         logger.CheckLoggedMessageHead ("CondItem1: Equal to item0", "A3");
531                         logger.CheckLoggedMessageHead ("CondItem1: Equal to item0's value", "A4");
532                         Assert.AreEqual (0, logger.NormalMessageCount, "unexpected messages found");
533                 }
534
535                 [Test]
536                 // test properties and item refs, with dynamic properties/items
537                 public void TestItems12 ()
538                 {
539                         string project_xml = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
540         <PropertyGroup>
541                 <Prop2>@(Ref1)</Prop2>
542         </PropertyGroup>
543         <ItemGroup>
544                 <Ref1 Include=""File1"" />
545                 <Files Include=""@(Ref1)""/>
546         </ItemGroup>
547
548         <Target Name=""1"">
549                 <Message Text=""Prop2: $(Prop2)""/>
550                 
551                 <Message Text=""Files: @(Files)""/>
552                 <CreateItem Include=""foobar"">
553                         <Output TaskParameter=""Include"" ItemName=""Ref1""/>
554                 </CreateItem>
555                 <Message Text=""Files: @(Files)""/>
556
557                 <Message Text=""Prop2: $(Prop2)""/>
558                 <CreateProperty Value=""NewValue"">
559                         <Output TaskParameter=""Value"" PropertyName=""Prop2""/>
560                 </CreateProperty>
561                 <Message Text=""Prop2: $(Prop2)""/>
562         </Target>
563 </Project>
564 ";
565
566                         Engine engine = new Engine (Consts.BinPath);
567                         Project proj = engine.CreateNewProject ();
568                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
569                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
570                         proj.LoadXml (project_xml);
571                         engine.RegisterLogger (logger);
572
573                         if (!proj.Build ("1")) {
574                                 logger.DumpMessages ();
575                                 Assert.Fail ("Build failed");
576                         }
577
578                         logger.CheckLoggedMessageHead ("Prop2: File1", "A1");
579                         logger.CheckLoggedMessageHead ("Files: File1", "A1");
580                         logger.CheckLoggedMessageHead ("Files: File1", "A1");
581                         logger.CheckLoggedMessageHead ("Prop2: File1;foobar", "A1");
582                         logger.CheckLoggedMessageHead ("Prop2: NewValue", "A1");
583                         Assert.AreEqual (0, logger.NormalMessageCount, "unexpected messages found");
584                 }
585
586                 [Test]
587                 // test item refs in properties
588                 public void TestItems13 () {
589                         string project_xml = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
590         <PropertyGroup>
591                 <Prop1>@(Item0)</Prop1>
592         </PropertyGroup>
593         <ItemGroup>
594                 <Item0 Include=""Foo""/>
595                 <Item1 Include=""A\B.txt;A\C.txt;B\B.zip;B\C.zip"" />
596                 <Item2 Include=""@(Item1->'%(Extension)/$(Prop1)')"" />
597         </ItemGroup>
598
599         <Target Name='1'>
600                 <Message Text=""Item2: @(Item2)""/>
601         </Target>
602 </Project>";
603
604                         Engine engine = new Engine (Consts.BinPath);
605                         Project proj = engine.CreateNewProject ();
606                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
607                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
608                         proj.LoadXml (project_xml);
609                         engine.RegisterLogger (logger);
610
611                         if (!proj.Build ("1")) {
612                                 logger.DumpMessages ();
613                                 Assert.Fail ("Build failed");
614                         }
615
616                         logger.CheckLoggedMessageHead ("Item2: .txt/@(Item0);.txt/@(Item0);.zip/@(Item0);.zip/@(Item0)", "A1");
617                         Assert.AreEqual (0, logger.NormalMessageCount, "unexpected messages found");
618                 }
619
620                 [Test]
621                 public void TestMetadataFromItemReferences () {
622                         string project_xml = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
623         <ItemGroup>
624                 <Item1 Include=""Item1Val1;Item1Val2"">
625                         <Item1Md>False</Item1Md>
626                 </Item1>
627                 <Item2 Include=""Val1;Val2;@(Item1);Val3"">
628                         <Name>Random name</Name>
629                 </Item2>
630                 <Item3 Include=""foo;bar;@(Item2);Last""/>
631         </ItemGroup>
632
633         <Target Name=""Main"">
634                 <CreateItem Include=""@(Item3)"">
635                         <Output TaskParameter=""Include""  ItemName=""Final""/>
636                 </CreateItem>
637
638                 <Message Text=""Final: %(Final.Identity) Item1Md: %(Final.Item1Md) Name: %(Final.Name)""/>
639         </Target>
640 </Project>";
641
642                         Engine engine = new Engine (Consts.BinPath);
643                         Project proj = engine.CreateNewProject ();
644                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
645                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
646                         proj.LoadXml (project_xml);
647                         engine.RegisterLogger (logger);
648
649                         if (!proj.Build ("Main")) {
650                                 logger.DumpMessages ();
651                                 Assert.Fail ("Build failed");
652                         }
653
654                         CheckItems (proj, "Final", "Z", "foo", "bar", "Val1", "Val2", "Item1Val1", "Item1Val2", "Val3", "Last");
655
656                         logger.CheckLoggedMessageHead ("Final: foo Item1Md:  Name: ", "A1");
657                         logger.CheckLoggedMessageHead ("Final: bar Item1Md:  Name: ", "A2");
658                         logger.CheckLoggedMessageHead ("Final: Val1 Item1Md:  Name: Random name", "A3");
659                         logger.CheckLoggedMessageHead ("Final: Val2 Item1Md:  Name: Random name", "A4");
660                         logger.CheckLoggedMessageHead ("Final: Item1Val1 Item1Md: False Name: Random name", "A5");
661                         logger.CheckLoggedMessageHead ("Final: Item1Val2 Item1Md: False Name: Random name", "A6");
662                         logger.CheckLoggedMessageHead ("Final: Val3 Item1Md:  Name: Random name", "A7");
663                         logger.CheckLoggedMessageHead ("Final: Last Item1Md:  Name: ", "A8");
664
665                         Assert.AreEqual (0, logger.NormalMessageCount, "unexpected messages found");
666                 }
667
668                 [Test]
669                 public void TestSelfRefrentialItems ()
670                 {
671                         string project_xml = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
672         <PropertyGroup>
673                 <Prop1>@(Item1);Val</Prop1>
674                 <Prop2>@(Item2)</Prop2>
675                 <Prop3>@(Item3)</Prop3>
676         </PropertyGroup>
677         <ItemGroup>
678                 <Item1 Include=""Item1OldVal""/>
679                 <Item1 Include=""@(Item1);$(Prop1)""/>
680
681                 <Item2 Include=""Item2OldVal""/>
682                 <Item2 Include=""@(Item2->'%(Identity)');$(Prop2)""/>
683
684                 <Item3 Include=""Item3OldVal""/>
685                 <Item3 Include=""@(Item3, '_');$(Prop3)""/>
686
687                 <Item4 Include=""@(Item4)""/>
688         </ItemGroup>
689
690         <Target Name=""1"">
691                 <Message Text=""Item1: %(Item1.Identity)""/>
692                 <Message Text=""Item2: %(Item2.Identity)""/>
693                 <Message Text=""Item3: %(Item3.Identity)""/>
694                 <Message Text=""%(Item4.Identity)""/>
695                 <Message Text=""Item4: %(Item4.Identity)""/>
696         </Target>
697 </Project>
698 ";
699
700                         Engine engine = new Engine (Consts.BinPath);
701                         Project proj = engine.CreateNewProject ();
702                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
703                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
704                         proj.LoadXml (project_xml);
705                         engine.RegisterLogger (logger);
706
707                         if (!proj.Build ("1")) {
708                                 logger.DumpMessages ();
709                                 Assert.Fail ("Build failed");
710                         }
711
712                         logger.CheckLoggedMessageHead ("Item1: Item1OldVal", "A1");
713                         logger.CheckLoggedMessageHead ("Item1: Val", "A2");
714                         logger.CheckLoggedMessageHead ("Item2: Item2OldVal", "A3");
715                         logger.CheckLoggedMessageHead ("Item3: Item3OldVal", "A4");
716                         logger.CheckLoggedMessageHead ("Item4: ", "A5");
717                         Assert.AreEqual (0, logger.NormalMessageCount, "unexpected messages found");
718                 }
719
720                 [Test]
721                 public void TestEmptyItemsWithBatching ()
722                 {
723                         string project_xml = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
724                         <UsingTask TaskName='StringTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
725                         <UsingTask TaskName='TestTask_TaskItem' AssemblyFile='Test\resources\TestTasks.dll' />
726                         <UsingTask TaskName='TestTask_TaskItems' AssemblyFile='Test\resources\TestTasks.dll' />
727         <Target Name=""1"">
728                 <StringTestTask Property=""%(Item4.Identity)"">
729                         <Output TaskParameter=""OutputString"" PropertyName=""OutputString""/>
730                 </StringTestTask>
731                 <Message Text='output1: $(OutputString)'/>
732
733                 <StringTestTask Property=""  %(Item4.Identity)"">
734                         <Output TaskParameter=""OutputString"" PropertyName=""OutputString""/>
735                 </StringTestTask>
736                 <Message Text='output2: $(OutputString)'/>
737
738                 <StringTestTask Array=""%(Item4.Identity)"">
739                         <Output TaskParameter=""OutputString"" PropertyName=""OutputString""/>
740                 </StringTestTask>
741                 <Message Text='output3: $(OutputString)'/>
742
743                 <StringTestTask Array=""  %(Item4.Identity)"">
744                         <Output TaskParameter=""OutputString"" PropertyName=""OutputString""/>
745                 </StringTestTask>
746                 <Message Text='output4: $(OutputString)'/>
747
748
749                 <TestTask_TaskItem Property=""%(Item4.Identity)"">
750                         <Output TaskParameter=""Output"" PropertyName=""OutputString""/>
751                 </TestTask_TaskItem>
752                 <Message Text='output5: $(OutputString)'/>
753
754                 <TestTask_TaskItem Property=""  %(Item4.Identity)"">
755                         <Output TaskParameter=""Output"" PropertyName=""OutputString""/>
756                 </TestTask_TaskItem>
757                 <Message Text='output6: $(OutputString)'/>
758
759
760                 <TestTask_TaskItems Property=""  %(Item4.Identity)"">
761                         <Output TaskParameter=""Output"" PropertyName=""OutputString""/>
762                 </TestTask_TaskItems>
763                 <Message Text='output7: $(OutputString)'/>
764         
765
766                 <!-- no space in property -->
767                 <TestTask_TaskItems Property=""%(Item4.Identity)"">
768                         <Output TaskParameter=""Output"" PropertyName=""OutputString""/>
769                 </TestTask_TaskItems>
770                 <Message Text='output8: $(OutputString)'/>
771
772         </Target>
773 </Project>
774 ";
775
776                         Engine engine = new Engine (Consts.BinPath);
777                         Project proj = engine.CreateNewProject ();
778                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
779                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
780                         proj.LoadXml (project_xml);
781                         engine.RegisterLogger (logger);
782
783                         if (!proj.Build ("1")) {
784                                 logger.DumpMessages ();
785                                 Assert.Fail ("Build failed");
786                         }
787
788                         logger.CheckLoggedMessageHead ("output1: property: null ## array: null", "A1");
789                         logger.CheckLoggedMessageHead ("output2: property:    ## array: null", "A2");
790                         logger.CheckLoggedMessageHead ("output3: property: null ## array: null", "A3");
791                         logger.CheckLoggedMessageHead ("output4: property: null ## array: null", "A4");
792
793                         logger.CheckLoggedMessageHead ("output5: null", "A5");
794                         logger.CheckLoggedMessageHead ("output6: null", "A6");
795                         logger.CheckLoggedMessageHead ("output7: null", "A7");
796                         logger.CheckLoggedMessageHead ("output8: null", "A8");
797
798                         Assert.AreEqual (0, logger.NormalMessageCount, "unexpected messages found");
799                 }
800
801                 [Test]
802                 public void TestItemsInTarget1 ()
803                 {
804                         Engine engine = new Engine (Consts.BinPath);
805                         Project proj = engine.CreateNewProject ();
806
807                         string documentString = @"
808                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
809                                         <UsingTask TaskName='StringTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
810                                         <PropertyGroup>
811                                                 <A>A</A>
812                                                 <B>@(A)g</B>
813                                         </PropertyGroup>
814                                         <ItemGroup>
815                                                 <A Include='A;B;C' />
816                                         </ItemGroup>
817
818                                         <Target Name='1'>
819                                                 <StringTestTask Property='@(A)@(Z)'>
820                                                         <Output TaskParameter='Property' PropertyName='P1' />
821                                                 </StringTestTask>
822                                                 <StringTestTask Property=""@(A,'')"">
823                                                         <Output TaskParameter='Property' PropertyName='P2' />
824                                                 </StringTestTask>
825                                                 <StringTestTask Property=""@(A,'@(A)')"">
826                                                         <Output TaskParameter='Property' PropertyName='P3' />
827                                                 </StringTestTask>
828                                                 <StringTestTask Property=""@(A,'$(A)')"">
829                                                         <Output TaskParameter='Property' PropertyName='P4' />
830                                                 </StringTestTask>
831                                                 <StringTestTask Property=""@(A,'@(A,'')')"">
832                                                         <Output TaskParameter='Property' PropertyName='P5' />
833                                                 </StringTestTask>
834                                                 <StringTestTask Property=""@(A,'$(B)')"">
835                                                         <Output TaskParameter='Property' PropertyName='P6' />
836                                                 </StringTestTask>
837                                                 <StringTestTask Property=""%(A.Filename)"">
838                                                         <Output TaskParameter='Property' ItemName='I1' />
839                                                 </StringTestTask>
840                                                 <StringTestTask Property=""@(A) %(Filename)"">
841                                                         <Output TaskParameter='Property' ItemName='I2' />
842                                                 </StringTestTask>
843                                         </Target>
844                                 </Project>
845                         ";
846
847                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger = new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
848                         engine.RegisterLogger (logger);
849                         proj.LoadXml (documentString);
850                         if (!proj.Build ("1")) {
851                                 logger.DumpMessages ();
852                                 Assert.Fail ("build failed");
853                         }
854
855                         Assert.AreEqual ("A;B;C", proj.GetEvaluatedProperty ("P1"), "A1");
856                         Assert.AreEqual ("ABC", proj.GetEvaluatedProperty ("P2"), "A2");
857                         Assert.AreEqual ("A@(A)B@(A)C", proj.GetEvaluatedProperty ("P3"), "A3");
858                         Assert.AreEqual ("AABAC", proj.GetEvaluatedProperty ("P4"), "A4");
859                         Assert.AreEqual ("@(A,'ABC')", proj.GetEvaluatedProperty ("P5"), "A5");
860                         Assert.AreEqual ("A@(A)gB@(A)gC", proj.GetEvaluatedProperty ("P6"), "A6");
861                         CheckItems (proj, "I1", "A6", "A", "B", "C");
862                         CheckItems (proj, "I2", "A7", "A A", "B B", "C C");
863                 }
864
865
866
867                 [Test]
868                 [Category ("NotWorking")]
869                 public void TestItemsInTarget2 ()
870                 {
871                         Engine engine = new Engine (Consts.BinPath);
872                         Project proj = engine.CreateNewProject ();
873
874                         string documentString = @"
875                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
876                                         <UsingTask TaskName='StringTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
877                                         <ItemGroup>
878                                                 <A Include='A;B;C' />
879                                         </ItemGroup>
880
881                                         <Target Name='1'>
882                                                 <StringTestTask Property=""%(Filename)"">
883                                                         <Output TaskParameter='Property' ItemName='I2' />
884                                                 </StringTestTask>
885                                         </Target>
886                                 </Project>
887                         ";
888
889                         proj.LoadXml (documentString);
890                         Assert.IsFalse (proj.Build ("1"), "A1");
891                 }
892
893                 [Test]
894                 public void TestItemsInTarget3 ()
895                 {
896                         Engine engine = new Engine (Consts.BinPath);
897                         Project proj = engine.CreateNewProject ();
898
899                         string documentString = @"
900                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
901                                         <UsingTask TaskName='StringTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
902                                         <PropertyGroup>
903                                                 <A>A</A>
904                                                 <B>A;B</B>
905                                                 <C>A;;</C>
906                                         </PropertyGroup>
907                                         <ItemGroup>
908                                                 <A Include='A;B;C' />
909                                         </ItemGroup>";
910
911                         documentString += CreateTargetFragment ("StringTestTask", "Array", "Array", "I",
912                                         new string [] {
913                                                 "$(A)$(A)",
914                                                 "$(B)$(B)",
915                                                 "$(C)",
916                                                 "$(C)$(C)",
917                                                 "@(A);$(C)",
918                                                 "@(A);A;B;C",
919                                                 "Foo;@(A)",
920                                                 "@(A);Foo"
921                                         }) + "</Project>";
922
923                         proj.LoadXml (documentString);
924                         Assert.IsTrue (proj.Build ("1"), "Build failed");
925
926                         CheckItems (proj, "I0", "A0", "AA");
927                         CheckItems (proj, "I1", "A1", "A", "BA", "B");
928                         CheckItems (proj, "I2", "A2", "A");
929                         CheckItems (proj, "I3", "A3", "A", "A");
930                         CheckItems (proj, "I4", "A4", "A", "B", "C", "A");
931                         CheckItems (proj, "I5", "A5", "A", "B", "C", "A", "B", "C");
932                         CheckItems (proj, "I6", "A6", "Foo", "A", "B", "C");
933                         CheckItems (proj, "I7", "A7", "A", "B", "C", "Foo");
934                 }
935
936                 [Test]
937                 //Test with ITaskItem[]
938                 public void TestItemsInTarget3a ()
939                 {
940                         Engine engine = new Engine (Consts.BinPath);
941                         Project proj = engine.CreateNewProject ();
942
943                         string documentString = @"
944                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
945                                         <UsingTask TaskName='BatchingTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
946                                         <PropertyGroup>
947                                                 <A>A</A>
948                                                 <B>A;B</B>
949                                                 <C>A;;</C>
950                                         </PropertyGroup>
951                                         <ItemGroup>
952                                                 <A Include='A;B;C' />
953                                                 <B Include='Foo;' />
954                                         </ItemGroup>";
955
956                         documentString += CreateTargetFragment ("BatchingTestTask", "Sources", "Output", "I",
957                                         new string [] {
958                                                 "$(A)$(A)",
959                                                 "$(B)$(B)",
960                                                 "$(C)",
961                                                 "$(C)$(C)",
962                                                 "$(C)   $(C)",
963                                                 "  $(C)   Foo    $(C)  Bar ; $(B)   ",
964                                                 "@(A);$(C)",
965                                                 "@(A);A;B;C",
966                                                 "  abc;  @(A)  ;  $(C)  ;foo",
967                                         }) + "</Project>";
968
969
970                         proj.LoadXml (documentString);
971                         Assert.IsTrue (proj.Build ("1"), "Build failed");
972
973                         CheckItems (proj, "I0", "A0", "AA");
974                         CheckItems (proj, "I1", "A1", "A", "BA", "B");
975                         CheckItems (proj, "I2", "A2", "A");
976                         CheckItems (proj, "I3", "A3", "A", "A");
977                         CheckItems (proj, "I4", "A4", "A", "A");
978                         CheckItems (proj, "I5", "A5", "A", "Foo    A", "Bar", "A", "B");
979                         CheckItems (proj, "I6", "A6", "A", "B", "C", "A");
980                         CheckItems (proj, "I7", "A7", "A", "B", "C", "A", "B", "C");
981                         CheckItems(proj, "I8", "A8", "abc", "A", "B", "C", "A", "foo");
982                 }
983
984                 [Test]
985                 //Test with string[]
986                 public void TestItemsInTarget3b ()
987                 {
988                         Engine engine = new Engine (Consts.BinPath);
989                         Project proj = engine.CreateNewProject ();
990
991                         string documentString = @"
992                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
993                                         <UsingTask TaskName='BatchingTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
994                                         <PropertyGroup>
995                                                 <A>A</A>
996                                                 <B>A;B</B>
997                                                 <C>A;;</C>
998                                         </PropertyGroup>
999                                         <ItemGroup>
1000                                                 <A Include='A;B;;;C' />
1001                                         </ItemGroup>";
1002
1003                         documentString += CreateTargetFragment ("BatchingTestTask", "Strings", "StringsOutput", "I",
1004                                         new string [] {
1005                                                 "$(A)$(A)",
1006                                                 "$(B)$(B)",
1007                                                 "$(C)",
1008                                                 "$(C)$(C)",
1009                                                 "$(C) $(C) $(C)Bar$(C)",
1010                                                 "@(A);$(C)",
1011                                                 "@(A);A;B;C"
1012                                         }) + "</Project>";
1013
1014                         proj.LoadXml (documentString);
1015                         Assert.IsTrue (proj.Build ("1"), "Build failed");
1016
1017                         CheckItems (proj, "I0", "A0", "AA");
1018                         CheckItems (proj, "I1", "A1", "A", "BA", "B");
1019                         CheckItems (proj, "I2", "A2", "A");
1020                         CheckItems (proj, "I3", "A3", "A", "A");
1021                         CheckItems (proj, "I4", "A4", "A", "A", "A", "BarA");
1022                         CheckItems (proj, "I5", "A5", "A", "B", "C", "A");
1023                         CheckItems (proj, "I6", "A6", "A", "B", "C", "A", "B", "C");
1024                 }
1025
1026                 [Test]
1027                 //Test with string
1028                 public void TestItemsInTarget3c ()
1029                 {
1030                         Engine engine = new Engine (Consts.BinPath);
1031                         Project proj = engine.CreateNewProject ();
1032                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
1033                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger();
1034                         engine.RegisterLogger(logger);
1035
1036                         string documentString = @"
1037                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1038                                         <UsingTask TaskName='BatchingTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
1039                                         <PropertyGroup>
1040                                                 <A>A</A>
1041                                                 <B>A;B</B>
1042                                                 <C>A;;</C>
1043                                                 <D>$(C);Foo</D>
1044                                         </PropertyGroup>
1045                                         <ItemGroup>
1046                                                 <A Include='A;B;;;C' />
1047                                         </ItemGroup>";
1048
1049                         documentString += CreateTargetFragment ("BatchingTestTask", "SingleString", "SingleStringOutput", "I",
1050                                         new string [] {
1051                                                 "$(A)$(A)",
1052                                                 "$(B)$(B)",
1053                                                 "$(C)",
1054                                                 "$(C)$(C)",
1055                                                 "$(C) $(C)",
1056                                                 "@(A);$(C)",
1057                                                 "@(A);A;B;C",
1058                                                 "@(A) $(C) @(A)",
1059                                         }) + "</Project>";
1060
1061                         proj.LoadXml (documentString);
1062                         if (!proj.Build("1")) {
1063                                 logger.DumpMessages();
1064                                 Assert.Fail("Build failed");
1065                         }
1066
1067                         BuildProperty bp = proj.EvaluatedProperties ["D"];
1068                         Assert.AreEqual ("$(C);Foo", bp.Value, "B0");
1069                         Assert.AreEqual ("A;;;Foo", bp.FinalValue, "B1");
1070
1071                         bp = proj.EvaluatedProperties ["C"];
1072                         Assert.AreEqual ("A;;", bp.Value, "B3");
1073                         Assert.AreEqual ("A;;", bp.FinalValue, "B4");
1074
1075                         CheckItems (proj, "I0", "A0", "AA");
1076                         CheckItems (proj, "I1", "A1", "A;BA;B");
1077                         CheckItems (proj, "I2", "A2", "A;;");
1078                         CheckItems (proj, "I3", "A3", "A;;A;;");
1079                         CheckItems (proj, "I4", "A4", "A;; A;;");
1080                         CheckItems (proj, "I5", "A5", "A;B;C;A;;");
1081                         CheckItems (proj, "I6", "A6", "A;B;C;A;B;C");
1082                         CheckItems (proj, "I7", "A7", "A;B;C A;; A;B;C");
1083                 }
1084
1085                 [Test]
1086                 public void TestSingleTaskItemError1 ()
1087                 {
1088                         CheckSingleTaskItemProject ("$(B)$(B)");
1089                 }
1090
1091                 [Test]
1092                 public void TestSingleTaskItemError2 ()
1093                 {
1094                         CheckSingleTaskItemProject ("$(C)$(C)");
1095                 }
1096
1097                 [Test]
1098                 public void TestSingleTaskItemError3 ()
1099                 {
1100                         CheckSingleTaskItemProject ("$(C) $(C)");
1101                 }
1102
1103                 [Test]
1104                 public void TestSingleTaskItemError4 ()
1105                 {
1106                         CheckSingleTaskItemProject ("@(A)");
1107                 }
1108
1109                 [Test]
1110                 public void TestSingleTaskItemError5 ()
1111                 {
1112                         CheckSingleTaskItemProject ("@(A);$(C))");
1113                 }
1114
1115                 [Test]
1116                 public void TestSingleTaskItemError6 ()
1117                 {
1118                         CheckSingleTaskItemProject ("@(A);A;B;C");
1119                 }
1120
1121                 [Test]
1122                 public void TestSingleTaskItemError7 ()
1123                 {
1124                         CheckSingleTaskItemProject ("@(Item1)$(C)");
1125                 }
1126
1127                 [Test]
1128                 public void TestSingleTaskItemError8 ()
1129                 {
1130                         CheckSingleTaskItemProject ("$(B).foo");
1131                 }
1132
1133                 [Test]
1134                 public void TestSingleTaskItem1 ()
1135                 {
1136                         Project proj = BuildProjectForSingleTaskItem ("$(D)$(C)");
1137                         CheckItems (proj, "I0", "A0", "A");
1138                 }
1139
1140                 [Test]
1141                 public void TestSingleTaskItem2 ()
1142                 {
1143                         Project proj = BuildProjectForSingleTaskItem ("@(Item1)");
1144                         CheckItems (proj, "I0", "A0", "F");
1145                 }
1146
1147                 [Test]
1148                 public void TestSingleTaskItem3 ()
1149                 {
1150                         Project proj = BuildProjectForSingleTaskItem ("$(A).foo");
1151                         CheckItems (proj, "I0", "A0", "A.foo");
1152                 }
1153
1154                 [Test]
1155                 public void TestSingleTaskItem4 ()
1156                 {
1157                         Project proj = BuildProjectForSingleTaskItem ("$(C)");
1158                         CheckItems (proj, "I0", "A0", "A");
1159                 }
1160
1161                 void CheckSingleTaskItemProject (string expression)
1162                 {
1163                         string documentString = CreateProjectForSingleTaskItem (expression);
1164                         Engine engine = new Engine (Consts.BinPath);
1165                         Project proj = engine.CreateNewProject ();
1166                         proj.LoadXml (documentString);
1167                         Assert.IsFalse (proj.Build ("1"), "Build should've failed");
1168                 }
1169
1170                 Project BuildProjectForSingleTaskItem (string expression)
1171                 {
1172                         string documentString = CreateProjectForSingleTaskItem (expression);
1173                         Engine engine = new Engine (Consts.BinPath);
1174                         Project proj = engine.CreateNewProject ();
1175                         proj.LoadXml (documentString);
1176                         Assert.IsTrue (proj.Build ("1"), "Build failed");
1177
1178                         return proj;
1179                 }
1180
1181                 string CreateProjectForSingleTaskItem (string expression)
1182                 {
1183                         return @"
1184                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1185                                         <UsingTask TaskName='BatchingTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
1186                                         <PropertyGroup>
1187                                                 <A>A</A>
1188                                                 <B>A;B</B>
1189                                                 <C>A;;</C>
1190                                                 <D></D>
1191                                         </PropertyGroup>
1192                                         <ItemGroup>
1193                                                 <A Include='A;B;C' />
1194                                                 <Item1 Include='F' />
1195                                         </ItemGroup>
1196
1197                                         <Target Name='1'>
1198                                                 <BatchingTestTask SingleTaskItem='" + expression + @"'>
1199                                                         <Output TaskParameter='SingleStringOutput' ItemName='I0' />
1200                                                 </BatchingTestTask>
1201                                         </Target>
1202                                 </Project>";
1203                 }
1204
1205                 string CreateTargetFragment (string taskname, string task_param_in, string task_param_out, string item_prefix,
1206                                 string [] args)
1207                 {
1208                         StringBuilder sb = new StringBuilder ();
1209
1210                         sb.Append ("<Target Name='1'>");
1211                         for (int i = 0; i < args.Length; i ++) {
1212                                 sb.AppendFormat ("<{0} {1}='{2}'>\n", taskname, task_param_in, args [i]);
1213                                 sb.AppendFormat ("\t<Output TaskParameter='{0}' ItemName='{1}{2}' />\n", task_param_out, item_prefix, i);
1214                                 sb.AppendFormat ("</{0}>\n", taskname);
1215                         }
1216                         sb.Append ("</Target>");
1217
1218                         return sb.ToString ();
1219                 }
1220
1221                 [Test]
1222                 public void TestItemsInTarget4 ()
1223                 {
1224                         Engine engine = new Engine (Consts.BinPath);
1225                         Project proj = engine.CreateNewProject ();
1226
1227                         string documentString = @"
1228                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1229                                         <UsingTask TaskName='StringTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
1230                                         <ItemGroup>
1231                                                 <A Include='A;B;C' />
1232                                         </ItemGroup>
1233                                         <Target Name='1'>
1234                                                 <StringTestTask Array='@(A)@(A)'>
1235                                                         <Output TaskParameter='Array' ItemName='I1' />
1236                                                 </StringTestTask>
1237                                         </Target>
1238                                 </Project>
1239                         ";
1240
1241                         proj.LoadXml (documentString);
1242                         Assert.IsFalse (proj.Build ("1"));
1243                 }
1244
1245                 [Test]
1246                 public void TestItemsInTarget5 ()
1247                 {
1248                         Engine engine = new Engine (Consts.BinPath);
1249                         Project proj = engine.CreateNewProject ();
1250
1251                         string documentString = @"
1252                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1253                                         <UsingTask TaskName='StringTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
1254                                         <ItemGroup>
1255                                                 <A Include='A;B;C' />
1256                                         </ItemGroup>
1257                                         <Target Name='1'>
1258                                                 <StringTestTask Array='@(A)AAA'>
1259                                                         <Output TaskParameter='Array' ItemName='I1' />
1260                                                 </StringTestTask>
1261                                         </Target>
1262                                 </Project>
1263                         ";
1264
1265                         proj.LoadXml (documentString);
1266                         Assert.IsFalse (proj.Build ("1"));
1267                 }
1268
1269                 [Test]
1270                 public void TestItemsInTarget6 ()
1271                 {
1272                         Engine engine = new Engine (Consts.BinPath);
1273                         Project proj = engine.CreateNewProject ();
1274
1275                         string documentString = @"
1276                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1277                                         <UsingTask TaskName='StringTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
1278                                         <ItemGroup>
1279                                                 <A Include='A;B;C' />
1280                                         </ItemGroup>
1281                                         <PropertyGroup>
1282                                                 <A>A</A>
1283                                         </PropertyGroup>
1284                                         <Target Name='1'>
1285                                                 <StringTestTask Array='@(A)$(A)'>
1286                                                         <Output TaskParameter='Array' ItemName='I1' />
1287                                                 </StringTestTask>
1288                                         </Target>
1289                                 </Project>
1290                         ";
1291
1292                         proj.LoadXml (documentString);
1293                         Assert.IsFalse (proj.Build ("1"));
1294                 }
1295
1296                 [Test]
1297                 public void TestItemsInTarget7 ()
1298                 {
1299                         Engine engine = new Engine (Consts.BinPath);
1300                         Project proj = engine.CreateNewProject ();
1301
1302                         string documentString = @"
1303                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1304                                         <UsingTask TaskName='BatchingTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
1305                                         <ItemGroup>
1306                                                 <A Include='A;B;C' />
1307                                                 <B Include='Foo;' />
1308                                         </ItemGroup>
1309                                         <Target Name='1'>
1310                                                 <BatchingTestTask SingleTaskItem='Bar%(B.Identity)@(A)' />
1311                                         </Target>
1312                                 </Project>
1313                         ";
1314
1315                         proj.LoadXml (documentString);
1316                         Assert.IsFalse (proj.Build ("1"));
1317                 }
1318
1319                 [Test]
1320                 public void TestItemsInTarget8 ()
1321                 {
1322                         Engine engine = new Engine (Consts.BinPath);
1323                         Project proj = engine.CreateNewProject ();
1324
1325                         string documentString = @"
1326                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1327                                         <PropertyGroup>
1328                                                 <Foo>Five</Foo>
1329                                         </PropertyGroup>
1330                                         <ItemGroup>
1331                                                 <A Include='A'>
1332                                                         <M>True</M>
1333                                                         <M>False</M>
1334                                                 </A>
1335                                         </ItemGroup>
1336                                 </Project>
1337                         ";
1338
1339                         proj.LoadXml (documentString);
1340
1341                         Assert.AreEqual (1, proj.EvaluatedItems.Count, "A1");
1342                         BuildItem bi = proj.EvaluatedItems [0];
1343                         Assert.AreEqual ("False", bi.GetMetadata ("M"), "A2");
1344                 }
1345
1346
1347                 [Test]
1348                 public void TestItemsInTarget9 ()
1349                 {
1350                         Engine engine = new Engine (Consts.BinPath);
1351                         Project proj = engine.CreateNewProject ();
1352
1353                         string documentString = @"
1354                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1355                                         <PropertyGroup>
1356                                                 <Foo>Five</Foo>
1357                                         </PropertyGroup>
1358                                         <ItemGroup>
1359                                                 <A Include='A'>
1360                                                         <M Condition="" '$(Foo)' == 'Five' "">True</M>
1361                                                         <M Condition="" '$(Foo)' != 'Five' "">False</M>
1362                                                 </A>
1363                                         </ItemGroup>
1364                                 </Project>
1365                         ";
1366
1367                         proj.LoadXml (documentString);
1368
1369                         Assert.AreEqual (1, proj.EvaluatedItems.Count, "A1");
1370                         BuildItem bi = proj.EvaluatedItems [0];
1371                         Assert.AreEqual ("True", bi.GetMetadata ("M"), "A2");
1372                         Assert.AreEqual (0, bi.Condition.Length, "A3");
1373
1374                         BuildItemGroup big = proj.GetEvaluatedItemsByNameIgnoringCondition ("A");
1375                         Assert.AreEqual (1, big.Count, "A4");
1376                         bi = big [0];
1377                         Assert.AreEqual ("True", bi.GetMetadata ("M"), "A5");
1378                         Assert.AreEqual ("True", bi.GetEvaluatedMetadata ("M"), "A6");
1379
1380                         /*proj.SetProperty ("Foo", "Six");
1381                         proj.Build ();
1382                         bi = proj.GetEvaluatedItemsByName ("A") [0];
1383                         Assert.AreEqual ("False", bi.GetMetadata ("M"), "A7");
1384                         Assert.AreEqual ("False", bi.GetEvaluatedMetadata ("M"), "A7a");
1385                         Assert.AreEqual (0, bi.Condition.Length, "A8");
1386
1387                         big = proj.GetEvaluatedItemsByNameIgnoringCondition ("A");
1388                         Assert.AreEqual (1, big.Count, "A9");
1389                         bi = big [0];
1390                         Assert.AreEqual ("True", bi.GetMetadata ("M"), "A10");
1391                         Assert.AreEqual ("True", bi.GetEvaluatedMetadata ("M"), "A11");*/
1392                 }
1393
1394                 [Test]
1395                 public void TestItemsWithWildcards ()
1396                 {
1397                         Engine engine = new Engine (Consts.BinPath);
1398                         Project proj = engine.CreateNewProject ();
1399                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
1400                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
1401                         engine.RegisterLogger (logger);
1402
1403                         // Setup
1404
1405                         string basedir = PathCombine ("Test", "resources", "dir");
1406                         string aaa = PathCombine ("a", "aa", "aaa");
1407                         string bb = Path.Combine ("b", "bb");
1408
1409                         string[] dirs = { aaa, bb, "c" };
1410                         string [] files = {
1411                                                                 PathCombine (basedir, aaa, "foo.dll"),
1412                                                                 PathCombine (basedir, bb, "bar.dll"),
1413                                                                 PathCombine (basedir, bb, "sample.txt"),
1414                                                                 Path.Combine (basedir, "xyz.dll")
1415                                                           };
1416
1417                         string documentString = @"
1418                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1419                                         <ItemGroup>
1420                                                 <ItemsRel Include='dir\**\*.dll' Exclude='*\x*.dll' />
1421                                                 <ItemsRelExpanded Include=""@(ItemsRel->'%(FullPath)')"" />
1422                                                 <ItemsAbs Include='$(MSBuildProjectDirectory)\dir\**\*.dll'/>
1423                                         </ItemGroup>
1424
1425                                         <Target Name='Main'>
1426                                                 <Message Text=""ItemsRel: %(ItemsRel.FullPath) RecDir: %(ItemsRel.RecursiveDir)""/>
1427                                                 <Message Text=""ItemsRelExpanded: %(ItemsRelExpanded.Identity)""/>
1428                                                 <Message Text='ItemsAbs: %(ItemsAbs.Identity) RecDir: %(ItemsAbs.RecursiveDir)'/>
1429                                         </Target>
1430                                 </Project>";
1431
1432                         try {
1433                                 CreateDirectoriesAndFiles (basedir, dirs, files);
1434                                 string projectdir = Path.Combine ("Test", "resources");
1435                                 File.WriteAllText (Path.Combine (projectdir, "wild1.proj"), documentString);
1436                                 proj.Load (Path.Combine (projectdir, "wild1.proj"));
1437                                 if (!proj.Build ("Main")) {
1438                                         logger.DumpMessages ();
1439                                         Assert.Fail ("Build failed");
1440                                 }
1441                                 string full_base_dir = Path.GetFullPath (basedir);
1442
1443                                 logger.CheckLoggedAny (@"ItemsRel: "+ PathCombine (full_base_dir, aaa, "foo.dll") +
1444                                                         " RecDir: " + aaa + Path.DirectorySeparatorChar, MessageImportance.Normal, "A1");
1445
1446                                 logger.CheckLoggedAny (@"ItemsRel: " + PathCombine (full_base_dir, bb, "bar.dll") +
1447                                                         " RecDir: " + bb + Path.DirectorySeparatorChar, MessageImportance.Normal, "A2");
1448
1449                                 logger.CheckLoggedAny (@"ItemsRelExpanded: " + PathCombine (full_base_dir, aaa, "foo.dll"), MessageImportance.Normal, "A3");
1450                                 logger.CheckLoggedAny (@"ItemsRelExpanded: " + PathCombine (full_base_dir, bb, "bar.dll"), MessageImportance.Normal, "A4");
1451
1452                                 logger.CheckLoggedAny (@"ItemsAbs: " + PathCombine (full_base_dir, aaa, "foo.dll") +
1453                                                         @" RecDir: " + aaa + Path.DirectorySeparatorChar, MessageImportance.Normal, "A5");
1454                                 logger.CheckLoggedAny (@"ItemsAbs: " + PathCombine (full_base_dir, bb, "bar.dll") +
1455                                                         @" RecDir: " + bb + Path.DirectorySeparatorChar, MessageImportance.Normal, "A6");
1456                                 logger.CheckLoggedAny (@"ItemsAbs: " + PathCombine (full_base_dir, "xyz.dll") +
1457                                                         @" RecDir: ", MessageImportance.Normal, "A7");
1458
1459                                 Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
1460                         } catch (AssertionException) {
1461                                 logger.DumpMessages ();
1462                                 throw;
1463                         } finally {
1464                                 Directory.Delete (basedir, true);
1465                         }
1466                 }
1467
1468                 [Test]
1469                 public void TestReservedMetadata ()
1470                 {
1471                         Engine engine = new Engine (Consts.BinPath);
1472                         Project proj = engine.CreateNewProject ();
1473                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
1474                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
1475                         engine.RegisterLogger (logger);
1476
1477                         string documentString = @"
1478                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1479                                         <ItemGroup><File1 Include=""bar\foo.dll""/></ItemGroup>
1480                                         <Target Name='Main'>
1481                                                 <Message Text='file1: @(File1)'/>
1482                                                 <Message Text='file1: RootDir: %(File1.RootDir)'/>
1483                                                 <Message Text='file1: Directory: %(File1.Directory)'/>
1484                                         </Target>
1485                                 </Project>";
1486
1487                         string projectdir = Path.Combine ("Test", "resources");
1488                         File.WriteAllText (Path.Combine (projectdir, "test1.proj"), documentString);
1489                         proj.Load (Path.Combine (projectdir, "test1.proj"));
1490                         if (!proj.Build ("Main")) {
1491                                 logger.DumpMessages ();
1492                                 Assert.Fail ("Build failed");
1493                         }
1494
1495                         logger.CheckLoggedMessageHead ("file1: " + Path.Combine ("bar", "foo.dll"), "A1");
1496
1497                         string path_root = Path.GetPathRoot (Path.GetFullPath (projectdir));
1498                         logger.CheckLoggedMessageHead ("file1: RootDir: " + path_root, "A2");
1499
1500                         string fullpath = Path.GetFullPath (Path.Combine (projectdir, "bar"));
1501                         logger.CheckLoggedMessageHead ("file1: Directory: " + fullpath.Substring (path_root.Length) + Path.DirectorySeparatorChar, "A3");
1502
1503                         if (logger.NormalMessageCount != 0) {
1504                                 logger.DumpMessages ();
1505                                 Assert.Fail ("Unexpected extra messages found");
1506                         }
1507                 }
1508
1509                 void CreateDirectoriesAndFiles (string basedir, string[] dirs, string[] files)
1510                 {
1511                         foreach (string dir in dirs)
1512                                 Directory.CreateDirectory (Path.Combine (basedir, dir));
1513
1514                         foreach (string file in files)
1515                                 File.WriteAllText (file, String.Empty);
1516                 }
1517
1518                 string PathCombine (string path1, params string[] parts)
1519                 {
1520                         if (parts == null || parts.Length == 0)
1521                                 return path1;
1522
1523                         string final_path = path1;
1524                         foreach (string part in parts)
1525                                 final_path = Path.Combine (final_path, part);
1526
1527                         return final_path;
1528                 }
1529         }
1530 }