Merge pull request #2323 from esdrubal/servicemodel
[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                 [Category ("NotDotNet")]
722                 public void TestEmptyItemsWithBatching ()
723                 {
724                         string project_xml = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
725                         <UsingTask TaskName='StringTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
726                         <UsingTask TaskName='TestTask_TaskItem' AssemblyFile='Test\resources\TestTasks.dll' />
727                         <UsingTask TaskName='TestTask_TaskItems' AssemblyFile='Test\resources\TestTasks.dll' />
728         <Target Name=""1"">
729                 <StringTestTask Property=""%(Item4.Identity)"">
730                         <Output TaskParameter=""OutputString"" PropertyName=""OutputString""/>
731                 </StringTestTask>
732                 <Message Text='output1: $(OutputString)'/>
733
734                 <StringTestTask Property=""  %(Item4.Identity)"">
735                         <Output TaskParameter=""OutputString"" PropertyName=""OutputString""/>
736                 </StringTestTask>
737                 <Message Text='output2: $(OutputString)'/>
738
739                 <StringTestTask Array=""%(Item4.Identity)"">
740                         <Output TaskParameter=""OutputString"" PropertyName=""OutputString""/>
741                 </StringTestTask>
742                 <Message Text='output3: $(OutputString)'/>
743
744                 <StringTestTask Array=""  %(Item4.Identity)"">
745                         <Output TaskParameter=""OutputString"" PropertyName=""OutputString""/>
746                 </StringTestTask>
747                 <Message Text='output4: $(OutputString)'/>
748
749
750                 <TestTask_TaskItem Property=""%(Item4.Identity)"">
751                         <Output TaskParameter=""Output"" PropertyName=""OutputString""/>
752                 </TestTask_TaskItem>
753                 <Message Text='output5: $(OutputString)'/>
754
755                 <TestTask_TaskItem Property=""  %(Item4.Identity)"">
756                         <Output TaskParameter=""Output"" PropertyName=""OutputString""/>
757                 </TestTask_TaskItem>
758                 <Message Text='output6: $(OutputString)'/>
759
760
761                 <TestTask_TaskItems Property=""  %(Item4.Identity)"">
762                         <Output TaskParameter=""Output"" PropertyName=""OutputString""/>
763                 </TestTask_TaskItems>
764                 <Message Text='output7: $(OutputString)'/>
765         
766
767                 <!-- no space in property -->
768                 <TestTask_TaskItems Property=""%(Item4.Identity)"">
769                         <Output TaskParameter=""Output"" PropertyName=""OutputString""/>
770                 </TestTask_TaskItems>
771                 <Message Text='output8: $(OutputString)'/>
772
773         </Target>
774 </Project>
775 ";
776
777                         Engine engine = new Engine (Consts.BinPath);
778                         Project proj = engine.CreateNewProject ();
779                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
780                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
781                         proj.LoadXml (project_xml);
782                         engine.RegisterLogger (logger);
783
784                         if (!proj.Build ("1")) {
785                                 logger.DumpMessages ();
786                                 Assert.Fail ("Build failed");
787                         }
788
789                         logger.CheckLoggedMessageHead ("output1: property: null ## array: null", "A1");
790                         logger.CheckLoggedMessageHead ("output2: property:    ## array: null", "A2");
791                         logger.CheckLoggedMessageHead ("output3: property: null ## array: null", "A3");
792                         logger.CheckLoggedMessageHead ("output4: property: null ## array: null", "A4");
793
794                         logger.CheckLoggedMessageHead ("output5: null", "A5");
795                         logger.CheckLoggedMessageHead ("output6: null", "A6");
796                         logger.CheckLoggedMessageHead ("output7: null", "A7");
797                         logger.CheckLoggedMessageHead ("output8: null", "A8");
798
799                         Assert.AreEqual (0, logger.NormalMessageCount, "unexpected messages found");
800                 }
801
802                 [Test]
803                 [Category ("NotDotNet")]
804                 public void TestItemsInTarget1 ()
805                 {
806                         Engine engine = new Engine (Consts.BinPath);
807                         Project proj = engine.CreateNewProject ();
808
809                         string documentString = @"
810                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
811                                         <UsingTask TaskName='StringTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
812                                         <PropertyGroup>
813                                                 <A>A</A>
814                                                 <B>@(A)g</B>
815                                         </PropertyGroup>
816                                         <ItemGroup>
817                                                 <A Include='A;B;C' />
818                                         </ItemGroup>
819
820                                         <Target Name='1'>
821                                                 <StringTestTask Property='@(A)@(Z)'>
822                                                         <Output TaskParameter='Property' PropertyName='P1' />
823                                                 </StringTestTask>
824                                                 <StringTestTask Property=""@(A,'')"">
825                                                         <Output TaskParameter='Property' PropertyName='P2' />
826                                                 </StringTestTask>
827                                                 <StringTestTask Property=""@(A,'@(A)')"">
828                                                         <Output TaskParameter='Property' PropertyName='P3' />
829                                                 </StringTestTask>
830                                                 <StringTestTask Property=""@(A,'$(A)')"">
831                                                         <Output TaskParameter='Property' PropertyName='P4' />
832                                                 </StringTestTask>
833                                                 <StringTestTask Property=""@(A,'@(A,'')')"">
834                                                         <Output TaskParameter='Property' PropertyName='P5' />
835                                                 </StringTestTask>
836                                                 <StringTestTask Property=""@(A,'$(B)')"">
837                                                         <Output TaskParameter='Property' PropertyName='P6' />
838                                                 </StringTestTask>
839                                                 <StringTestTask Property=""%(A.Filename)"">
840                                                         <Output TaskParameter='Property' ItemName='I1' />
841                                                 </StringTestTask>
842                                                 <StringTestTask Property=""@(A) %(Filename)"">
843                                                         <Output TaskParameter='Property' ItemName='I2' />
844                                                 </StringTestTask>
845                                         </Target>
846                                 </Project>
847                         ";
848
849                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger = new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
850                         engine.RegisterLogger (logger);
851                         proj.LoadXml (documentString);
852                         if (!proj.Build ("1")) {
853                                 logger.DumpMessages ();
854                                 Assert.Fail ("build failed");
855                         }
856
857                         Assert.AreEqual ("A;B;C", proj.GetEvaluatedProperty ("P1"), "A1");
858                         Assert.AreEqual ("ABC", proj.GetEvaluatedProperty ("P2"), "A2");
859                         Assert.AreEqual ("A@(A)B@(A)C", proj.GetEvaluatedProperty ("P3"), "A3");
860                         Assert.AreEqual ("AABAC", proj.GetEvaluatedProperty ("P4"), "A4");
861                         Assert.AreEqual ("@(A,'ABC')", proj.GetEvaluatedProperty ("P5"), "A5");
862                         Assert.AreEqual ("A@(A)gB@(A)gC", proj.GetEvaluatedProperty ("P6"), "A6");
863                         CheckItems (proj, "I1", "A6", "A", "B", "C");
864                         CheckItems (proj, "I2", "A7", "A A", "B B", "C C");
865                 }
866
867
868
869                 [Test]
870                 [Category ("NotWorking")]
871                 public void TestItemsInTarget2 ()
872                 {
873                         Engine engine = new Engine (Consts.BinPath);
874                         Project proj = engine.CreateNewProject ();
875
876                         string documentString = @"
877                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
878                                         <UsingTask TaskName='StringTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
879                                         <ItemGroup>
880                                                 <A Include='A;B;C' />
881                                         </ItemGroup>
882
883                                         <Target Name='1'>
884                                                 <StringTestTask Property=""%(Filename)"">
885                                                         <Output TaskParameter='Property' ItemName='I2' />
886                                                 </StringTestTask>
887                                         </Target>
888                                 </Project>
889                         ";
890
891                         proj.LoadXml (documentString);
892                         Assert.IsFalse (proj.Build ("1"), "A1");
893                 }
894
895                 [Test]
896                 [Category ("NotDotNet")]
897                 public void TestItemsInTarget3 ()
898                 {
899                         Engine engine = new Engine (Consts.BinPath);
900                         Project proj = engine.CreateNewProject ();
901
902                         string documentString = @"
903                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
904                                         <UsingTask TaskName='StringTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
905                                         <PropertyGroup>
906                                                 <A>A</A>
907                                                 <B>A;B</B>
908                                                 <C>A;;</C>
909                                         </PropertyGroup>
910                                         <ItemGroup>
911                                                 <A Include='A;B;C' />
912                                         </ItemGroup>";
913
914                         documentString += CreateTargetFragment ("StringTestTask", "Array", "Array", "I",
915                                         new string [] {
916                                                 "$(A)$(A)",
917                                                 "$(B)$(B)",
918                                                 "$(C)",
919                                                 "$(C)$(C)",
920                                                 "@(A);$(C)",
921                                                 "@(A);A;B;C",
922                                                 "Foo;@(A)",
923                                                 "@(A);Foo"
924                                         }) + "</Project>";
925
926                         proj.LoadXml (documentString);
927                         Assert.IsTrue (proj.Build ("1"), "Build failed");
928
929                         CheckItems (proj, "I0", "A0", "AA");
930                         CheckItems (proj, "I1", "A1", "A", "BA", "B");
931                         CheckItems (proj, "I2", "A2", "A");
932                         CheckItems (proj, "I3", "A3", "A", "A");
933                         CheckItems (proj, "I4", "A4", "A", "B", "C", "A");
934                         CheckItems (proj, "I5", "A5", "A", "B", "C", "A", "B", "C");
935                         CheckItems (proj, "I6", "A6", "Foo", "A", "B", "C");
936                         CheckItems (proj, "I7", "A7", "A", "B", "C", "Foo");
937                 }
938
939                 [Test]
940                 [Category ("NotDotNet")]
941                 //Test with ITaskItem[]
942                 public void TestItemsInTarget3a ()
943                 {
944                         Engine engine = new Engine (Consts.BinPath);
945                         Project proj = engine.CreateNewProject ();
946
947                         string documentString = @"
948                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
949                                         <UsingTask TaskName='BatchingTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
950                                         <PropertyGroup>
951                                                 <A>A</A>
952                                                 <B>A;B</B>
953                                                 <C>A;;</C>
954                                         </PropertyGroup>
955                                         <ItemGroup>
956                                                 <A Include='A;B;C' />
957                                                 <B Include='Foo;' />
958                                         </ItemGroup>";
959
960                         documentString += CreateTargetFragment ("BatchingTestTask", "Sources", "Output", "I",
961                                         new string [] {
962                                                 "$(A)$(A)",
963                                                 "$(B)$(B)",
964                                                 "$(C)",
965                                                 "$(C)$(C)",
966                                                 "$(C)   $(C)",
967                                                 "  $(C)   Foo    $(C)  Bar ; $(B)   ",
968                                                 "@(A);$(C)",
969                                                 "@(A);A;B;C",
970                                                 "  abc;  @(A)  ;  $(C)  ;foo",
971                                         }) + "</Project>";
972
973
974                         proj.LoadXml (documentString);
975                         Assert.IsTrue (proj.Build ("1"), "Build failed");
976
977                         CheckItems (proj, "I0", "A0", "AA");
978                         CheckItems (proj, "I1", "A1", "A", "BA", "B");
979                         CheckItems (proj, "I2", "A2", "A");
980                         CheckItems (proj, "I3", "A3", "A", "A");
981                         CheckItems (proj, "I4", "A4", "A", "A");
982                         CheckItems (proj, "I5", "A5", "A", "Foo    A", "Bar", "A", "B");
983                         CheckItems (proj, "I6", "A6", "A", "B", "C", "A");
984                         CheckItems (proj, "I7", "A7", "A", "B", "C", "A", "B", "C");
985                         CheckItems(proj, "I8", "A8", "abc", "A", "B", "C", "A", "foo");
986                 }
987
988                 [Test]
989                 [Category ("NotDotNet")]
990                 //Test with string[]
991                 public void TestItemsInTarget3b ()
992                 {
993                         Engine engine = new Engine (Consts.BinPath);
994                         Project proj = engine.CreateNewProject ();
995
996                         string documentString = @"
997                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
998                                         <UsingTask TaskName='BatchingTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
999                                         <PropertyGroup>
1000                                                 <A>A</A>
1001                                                 <B>A;B</B>
1002                                                 <C>A;;</C>
1003                                         </PropertyGroup>
1004                                         <ItemGroup>
1005                                                 <A Include='A;B;;;C' />
1006                                         </ItemGroup>";
1007
1008                         documentString += CreateTargetFragment ("BatchingTestTask", "Strings", "StringsOutput", "I",
1009                                         new string [] {
1010                                                 "$(A)$(A)",
1011                                                 "$(B)$(B)",
1012                                                 "$(C)",
1013                                                 "$(C)$(C)",
1014                                                 "$(C) $(C) $(C)Bar$(C)",
1015                                                 "@(A);$(C)",
1016                                                 "@(A);A;B;C"
1017                                         }) + "</Project>";
1018
1019                         proj.LoadXml (documentString);
1020                         Assert.IsTrue (proj.Build ("1"), "Build failed");
1021
1022                         CheckItems (proj, "I0", "A0", "AA");
1023                         CheckItems (proj, "I1", "A1", "A", "BA", "B");
1024                         CheckItems (proj, "I2", "A2", "A");
1025                         CheckItems (proj, "I3", "A3", "A", "A");
1026                         CheckItems (proj, "I4", "A4", "A", "A", "A", "BarA");
1027                         CheckItems (proj, "I5", "A5", "A", "B", "C", "A");
1028                         CheckItems (proj, "I6", "A6", "A", "B", "C", "A", "B", "C");
1029                 }
1030
1031                 [Test]
1032                 [Category ("NotDotNet")]
1033                 //Test with string
1034                 public void TestItemsInTarget3c ()
1035                 {
1036                         Engine engine = new Engine (Consts.BinPath);
1037                         Project proj = engine.CreateNewProject ();
1038                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
1039                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger();
1040                         engine.RegisterLogger(logger);
1041
1042                         string documentString = @"
1043                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1044                                         <UsingTask TaskName='BatchingTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
1045                                         <PropertyGroup>
1046                                                 <A>A</A>
1047                                                 <B>A;B</B>
1048                                                 <C>A;;</C>
1049                                                 <D>$(C);Foo</D>
1050                                         </PropertyGroup>
1051                                         <ItemGroup>
1052                                                 <A Include='A;B;;;C' />
1053                                         </ItemGroup>";
1054
1055                         documentString += CreateTargetFragment ("BatchingTestTask", "SingleString", "SingleStringOutput", "I",
1056                                         new string [] {
1057                                                 "$(A)$(A)",
1058                                                 "$(B)$(B)",
1059                                                 "$(C)",
1060                                                 "$(C)$(C)",
1061                                                 "$(C) $(C)",
1062                                                 "@(A);$(C)",
1063                                                 "@(A);A;B;C",
1064                                                 "@(A) $(C) @(A)",
1065                                         }) + "</Project>";
1066
1067                         proj.LoadXml (documentString);
1068                         if (!proj.Build("1")) {
1069                                 logger.DumpMessages();
1070                                 Assert.Fail("Build failed");
1071                         }
1072
1073                         BuildProperty bp = proj.EvaluatedProperties ["D"];
1074                         Assert.AreEqual ("$(C);Foo", bp.Value, "B0");
1075                         Assert.AreEqual ("A;;;Foo", bp.FinalValue, "B1");
1076
1077                         bp = proj.EvaluatedProperties ["C"];
1078                         Assert.AreEqual ("A;;", bp.Value, "B3");
1079                         Assert.AreEqual ("A;;", bp.FinalValue, "B4");
1080
1081                         CheckItems (proj, "I0", "A0", "AA");
1082                         CheckItems (proj, "I1", "A1", "A;BA;B");
1083                         CheckItems (proj, "I2", "A2", "A;;");
1084                         CheckItems (proj, "I3", "A3", "A;;A;;");
1085                         CheckItems (proj, "I4", "A4", "A;; A;;");
1086                         CheckItems (proj, "I5", "A5", "A;B;C;A;;");
1087                         CheckItems (proj, "I6", "A6", "A;B;C;A;B;C");
1088                         CheckItems (proj, "I7", "A7", "A;B;C A;; A;B;C");
1089                 }
1090
1091                 [Test]
1092                 public void TestSingleTaskItemError1 ()
1093                 {
1094                         CheckSingleTaskItemProject ("$(B)$(B)");
1095                 }
1096
1097                 [Test]
1098                 public void TestSingleTaskItemError2 ()
1099                 {
1100                         CheckSingleTaskItemProject ("$(C)$(C)");
1101                 }
1102
1103                 [Test]
1104                 public void TestSingleTaskItemError3 ()
1105                 {
1106                         CheckSingleTaskItemProject ("$(C) $(C)");
1107                 }
1108
1109                 [Test]
1110                 public void TestSingleTaskItemError4 ()
1111                 {
1112                         CheckSingleTaskItemProject ("@(A)");
1113                 }
1114
1115                 [Test]
1116                 public void TestSingleTaskItemError5 ()
1117                 {
1118                         CheckSingleTaskItemProject ("@(A);$(C))");
1119                 }
1120
1121                 [Test]
1122                 public void TestSingleTaskItemError6 ()
1123                 {
1124                         CheckSingleTaskItemProject ("@(A);A;B;C");
1125                 }
1126
1127                 [Test]
1128                 public void TestSingleTaskItemError7 ()
1129                 {
1130                         CheckSingleTaskItemProject ("@(Item1)$(C)");
1131                 }
1132
1133                 [Test]
1134                 public void TestSingleTaskItemError8 ()
1135                 {
1136                         CheckSingleTaskItemProject ("$(B).foo");
1137                 }
1138
1139                 [Test]
1140                 [Category ("NotDotNet")]
1141                 public void TestSingleTaskItem1 ()
1142                 {
1143                         Project proj = BuildProjectForSingleTaskItem ("$(D)$(C)");
1144                         CheckItems (proj, "I0", "A0", "A");
1145                 }
1146
1147                 [Test]
1148                 [Category ("NotDotNet")]
1149                 public void TestSingleTaskItem2 ()
1150                 {
1151                         Project proj = BuildProjectForSingleTaskItem ("@(Item1)");
1152                         CheckItems (proj, "I0", "A0", "F");
1153                 }
1154
1155                 [Test]
1156                 [Category ("NotDotNet")]
1157                 public void TestSingleTaskItem3 ()
1158                 {
1159                         Project proj = BuildProjectForSingleTaskItem ("$(A).foo");
1160                         CheckItems (proj, "I0", "A0", "A.foo");
1161                 }
1162
1163                 [Test]
1164                 [Category ("NotDotNet")]
1165                 public void TestSingleTaskItem4 ()
1166                 {
1167                         Project proj = BuildProjectForSingleTaskItem ("$(C)");
1168                         CheckItems (proj, "I0", "A0", "A");
1169                 }
1170
1171                 void CheckSingleTaskItemProject (string expression)
1172                 {
1173                         string documentString = CreateProjectForSingleTaskItem (expression);
1174                         Engine engine = new Engine (Consts.BinPath);
1175                         Project proj = engine.CreateNewProject ();
1176                         proj.LoadXml (documentString);
1177                         Assert.IsFalse (proj.Build ("1"), "Build should've failed");
1178                 }
1179
1180                 Project BuildProjectForSingleTaskItem (string expression)
1181                 {
1182                         string documentString = CreateProjectForSingleTaskItem (expression);
1183                         Engine engine = new Engine (Consts.BinPath);
1184                         Project proj = engine.CreateNewProject ();
1185                         proj.LoadXml (documentString);
1186                         Assert.IsTrue (proj.Build ("1"), "Build failed");
1187
1188                         return proj;
1189                 }
1190
1191                 string CreateProjectForSingleTaskItem (string expression)
1192                 {
1193                         return @"
1194                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1195                                         <UsingTask TaskName='BatchingTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
1196                                         <PropertyGroup>
1197                                                 <A>A</A>
1198                                                 <B>A;B</B>
1199                                                 <C>A;;</C>
1200                                                 <D></D>
1201                                         </PropertyGroup>
1202                                         <ItemGroup>
1203                                                 <A Include='A;B;C' />
1204                                                 <Item1 Include='F' />
1205                                         </ItemGroup>
1206
1207                                         <Target Name='1'>
1208                                                 <BatchingTestTask SingleTaskItem='" + expression + @"'>
1209                                                         <Output TaskParameter='SingleStringOutput' ItemName='I0' />
1210                                                 </BatchingTestTask>
1211                                         </Target>
1212                                 </Project>";
1213                 }
1214
1215                 string CreateTargetFragment (string taskname, string task_param_in, string task_param_out, string item_prefix,
1216                                 string [] args)
1217                 {
1218                         StringBuilder sb = new StringBuilder ();
1219
1220                         sb.Append ("<Target Name='1'>");
1221                         for (int i = 0; i < args.Length; i ++) {
1222                                 sb.AppendFormat ("<{0} {1}='{2}'>\n", taskname, task_param_in, args [i]);
1223                                 sb.AppendFormat ("\t<Output TaskParameter='{0}' ItemName='{1}{2}' />\n", task_param_out, item_prefix, i);
1224                                 sb.AppendFormat ("</{0}>\n", taskname);
1225                         }
1226                         sb.Append ("</Target>");
1227
1228                         return sb.ToString ();
1229                 }
1230
1231                 [Test]
1232                 public void TestItemsInTarget4 ()
1233                 {
1234                         Engine engine = new Engine (Consts.BinPath);
1235                         Project proj = engine.CreateNewProject ();
1236
1237                         string documentString = @"
1238                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1239                                         <UsingTask TaskName='StringTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
1240                                         <ItemGroup>
1241                                                 <A Include='A;B;C' />
1242                                         </ItemGroup>
1243                                         <Target Name='1'>
1244                                                 <StringTestTask Array='@(A)@(A)'>
1245                                                         <Output TaskParameter='Array' ItemName='I1' />
1246                                                 </StringTestTask>
1247                                         </Target>
1248                                 </Project>
1249                         ";
1250
1251                         proj.LoadXml (documentString);
1252                         Assert.IsFalse (proj.Build ("1"));
1253                 }
1254
1255                 [Test]
1256                 public void TestItemsInTarget5 ()
1257                 {
1258                         Engine engine = new Engine (Consts.BinPath);
1259                         Project proj = engine.CreateNewProject ();
1260
1261                         string documentString = @"
1262                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1263                                         <UsingTask TaskName='StringTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
1264                                         <ItemGroup>
1265                                                 <A Include='A;B;C' />
1266                                         </ItemGroup>
1267                                         <Target Name='1'>
1268                                                 <StringTestTask Array='@(A)AAA'>
1269                                                         <Output TaskParameter='Array' ItemName='I1' />
1270                                                 </StringTestTask>
1271                                         </Target>
1272                                 </Project>
1273                         ";
1274
1275                         proj.LoadXml (documentString);
1276                         Assert.IsFalse (proj.Build ("1"));
1277                 }
1278
1279                 [Test]
1280                 public void TestItemsInTarget6 ()
1281                 {
1282                         Engine engine = new Engine (Consts.BinPath);
1283                         Project proj = engine.CreateNewProject ();
1284
1285                         string documentString = @"
1286                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1287                                         <UsingTask TaskName='StringTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
1288                                         <ItemGroup>
1289                                                 <A Include='A;B;C' />
1290                                         </ItemGroup>
1291                                         <PropertyGroup>
1292                                                 <A>A</A>
1293                                         </PropertyGroup>
1294                                         <Target Name='1'>
1295                                                 <StringTestTask Array='@(A)$(A)'>
1296                                                         <Output TaskParameter='Array' ItemName='I1' />
1297                                                 </StringTestTask>
1298                                         </Target>
1299                                 </Project>
1300                         ";
1301
1302                         proj.LoadXml (documentString);
1303                         Assert.IsFalse (proj.Build ("1"));
1304                 }
1305
1306                 [Test]
1307                 public void TestItemsInTarget7 ()
1308                 {
1309                         Engine engine = new Engine (Consts.BinPath);
1310                         Project proj = engine.CreateNewProject ();
1311
1312                         string documentString = @"
1313                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1314                                         <UsingTask TaskName='BatchingTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
1315                                         <ItemGroup>
1316                                                 <A Include='A;B;C' />
1317                                                 <B Include='Foo;' />
1318                                         </ItemGroup>
1319                                         <Target Name='1'>
1320                                                 <BatchingTestTask SingleTaskItem='Bar%(B.Identity)@(A)' />
1321                                         </Target>
1322                                 </Project>
1323                         ";
1324
1325                         proj.LoadXml (documentString);
1326                         Assert.IsFalse (proj.Build ("1"));
1327                 }
1328
1329                 [Test]
1330                 public void TestItemsInTarget8 ()
1331                 {
1332                         Engine engine = new Engine (Consts.BinPath);
1333                         Project proj = engine.CreateNewProject ();
1334
1335                         string documentString = @"
1336                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1337                                         <PropertyGroup>
1338                                                 <Foo>Five</Foo>
1339                                         </PropertyGroup>
1340                                         <ItemGroup>
1341                                                 <A Include='A'>
1342                                                         <M>True</M>
1343                                                         <M>False</M>
1344                                                 </A>
1345                                         </ItemGroup>
1346                                 </Project>
1347                         ";
1348
1349                         proj.LoadXml (documentString);
1350
1351                         Assert.AreEqual (1, proj.EvaluatedItems.Count, "A1");
1352                         BuildItem bi = proj.EvaluatedItems [0];
1353                         Assert.AreEqual ("False", bi.GetMetadata ("M"), "A2");
1354                 }
1355
1356
1357                 [Test]
1358                 public void TestItemsInTarget9 ()
1359                 {
1360                         Engine engine = new Engine (Consts.BinPath);
1361                         Project proj = engine.CreateNewProject ();
1362
1363                         string documentString = @"
1364                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1365                                         <PropertyGroup>
1366                                                 <Foo>Five</Foo>
1367                                         </PropertyGroup>
1368                                         <ItemGroup>
1369                                                 <A Include='A'>
1370                                                         <M Condition="" '$(Foo)' == 'Five' "">True</M>
1371                                                         <M Condition="" '$(Foo)' != 'Five' "">False</M>
1372                                                 </A>
1373                                         </ItemGroup>
1374                                 </Project>
1375                         ";
1376
1377                         proj.LoadXml (documentString);
1378
1379                         Assert.AreEqual (1, proj.EvaluatedItems.Count, "A1");
1380                         BuildItem bi = proj.EvaluatedItems [0];
1381                         Assert.AreEqual ("True", bi.GetMetadata ("M"), "A2");
1382                         Assert.AreEqual (0, bi.Condition.Length, "A3");
1383
1384                         BuildItemGroup big = proj.GetEvaluatedItemsByNameIgnoringCondition ("A");
1385                         Assert.AreEqual (1, big.Count, "A4");
1386                         bi = big [0];
1387                         Assert.AreEqual ("True", bi.GetMetadata ("M"), "A5");
1388                         Assert.AreEqual ("True", bi.GetEvaluatedMetadata ("M"), "A6");
1389
1390                         /*proj.SetProperty ("Foo", "Six");
1391                         proj.Build ();
1392                         bi = proj.GetEvaluatedItemsByName ("A") [0];
1393                         Assert.AreEqual ("False", bi.GetMetadata ("M"), "A7");
1394                         Assert.AreEqual ("False", bi.GetEvaluatedMetadata ("M"), "A7a");
1395                         Assert.AreEqual (0, bi.Condition.Length, "A8");
1396
1397                         big = proj.GetEvaluatedItemsByNameIgnoringCondition ("A");
1398                         Assert.AreEqual (1, big.Count, "A9");
1399                         bi = big [0];
1400                         Assert.AreEqual ("True", bi.GetMetadata ("M"), "A10");
1401                         Assert.AreEqual ("True", bi.GetEvaluatedMetadata ("M"), "A11");*/
1402                 }
1403
1404                 [Test]
1405                 // Fails on wrench
1406                 [Category ("NotWorking")]
1407                 public void TestItemsWithWildcards ()
1408                 {
1409                         Engine engine = new Engine (Consts.BinPath);
1410                         Project proj = engine.CreateNewProject ();
1411                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
1412                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
1413                         engine.RegisterLogger (logger);
1414
1415                         // Setup
1416
1417                         string basedir = PathCombine ("Test", "resources", "dir");
1418                         string aaa = PathCombine ("a", "aa", "aaa");
1419                         string bb = Path.Combine ("b", "bb");
1420
1421                         string[] dirs = { aaa, bb, "c" };
1422                         string [] files = {
1423                                                                 PathCombine (basedir, aaa, "foo.dll"),
1424                                                                 PathCombine (basedir, bb, "bar.dll"),
1425                                                                 PathCombine (basedir, bb, "sample.txt"),
1426                                                                 Path.Combine (basedir, "xyz.dll")
1427                                                           };
1428
1429                         string documentString = @"
1430                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1431                                         <ItemGroup>
1432                                                 <ItemsRel Include='dir\**\*.dll' Exclude='*\x*.dll' />
1433                                                 <ItemsRelExpanded Include=""@(ItemsRel->'%(FullPath)')"" />
1434                                                 <ItemsAbs Include='$(MSBuildProjectDirectory)\dir\**\*.dll'/>
1435                                         </ItemGroup>
1436
1437                                         <Target Name='Main'>
1438                                                 <Message Text=""ItemsRel: %(ItemsRel.FullPath) RecDir: %(ItemsRel.RecursiveDir)""/>
1439                                                 <Message Text=""ItemsRelExpanded: %(ItemsRelExpanded.Identity)""/>
1440                                                 <Message Text='ItemsAbs: %(ItemsAbs.Identity) RecDir: %(ItemsAbs.RecursiveDir)'/>
1441                                         </Target>
1442                                 </Project>";
1443
1444                         try {
1445                                 CreateDirectoriesAndFiles (basedir, dirs, files);
1446                                 string projectdir = Path.Combine ("Test", "resources");
1447                                 File.WriteAllText (Path.Combine (projectdir, "wild1.proj"), documentString);
1448                                 proj.Load (Path.Combine (projectdir, "wild1.proj"));
1449                                 if (!proj.Build ("Main")) {
1450                                         logger.DumpMessages ();
1451                                         Assert.Fail ("Build failed");
1452                                 }
1453                                 string full_base_dir = Path.GetFullPath (basedir);
1454
1455                                 logger.CheckLoggedAny (@"ItemsRel: "+ PathCombine (full_base_dir, aaa, "foo.dll") +
1456                                                         " RecDir: " + aaa + Path.DirectorySeparatorChar, MessageImportance.Normal, "A1");
1457
1458                                 logger.CheckLoggedAny (@"ItemsRel: " + PathCombine (full_base_dir, bb, "bar.dll") +
1459                                                         " RecDir: " + bb + Path.DirectorySeparatorChar, MessageImportance.Normal, "A2");
1460
1461                                 logger.CheckLoggedAny (@"ItemsRelExpanded: " + PathCombine (full_base_dir, aaa, "foo.dll"), MessageImportance.Normal, "A3");
1462                                 logger.CheckLoggedAny (@"ItemsRelExpanded: " + PathCombine (full_base_dir, bb, "bar.dll"), MessageImportance.Normal, "A4");
1463
1464                                 logger.CheckLoggedAny (@"ItemsAbs: " + PathCombine (full_base_dir, aaa, "foo.dll") +
1465                                                         @" RecDir: " + aaa + Path.DirectorySeparatorChar, MessageImportance.Normal, "A5");
1466                                 logger.CheckLoggedAny (@"ItemsAbs: " + PathCombine (full_base_dir, bb, "bar.dll") +
1467                                                         @" RecDir: " + bb + Path.DirectorySeparatorChar, MessageImportance.Normal, "A6");
1468                                 logger.CheckLoggedAny (@"ItemsAbs: " + PathCombine (full_base_dir, "xyz.dll") +
1469                                                         @" RecDir: ", MessageImportance.Normal, "A7");
1470
1471                                 Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
1472                         } catch (AssertionException) {
1473                                 logger.DumpMessages ();
1474                                 throw;
1475                         } finally {
1476                                 Directory.Delete (basedir, true);
1477                         }
1478                 }
1479
1480                 [Test]
1481                 // Fails on wrench
1482                 [Category ("NotWorking")]
1483                 public void TestReservedMetadata ()
1484                 {
1485                         Engine engine = new Engine (Consts.BinPath);
1486                         Project proj = engine.CreateNewProject ();
1487                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
1488                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
1489                         engine.RegisterLogger (logger);
1490
1491                         string documentString = @"
1492                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1493                                         <ItemGroup><File1 Include=""bar\foo.dll""/></ItemGroup>
1494                                         <Target Name='Main'>
1495                                                 <Message Text='file1: @(File1)'/>
1496                                                 <Message Text='file1: RootDir: %(File1.RootDir)'/>
1497                                                 <Message Text='file1: Directory: %(File1.Directory)'/>
1498                                         </Target>
1499                                 </Project>";
1500
1501                         string projectdir = Path.Combine ("Test", "resources");
1502                         File.WriteAllText (Path.Combine (projectdir, "test1.proj"), documentString);
1503                         proj.Load (Path.Combine (projectdir, "test1.proj"));
1504                         if (!proj.Build ("Main")) {
1505                                 logger.DumpMessages ();
1506                                 Assert.Fail ("Build failed");
1507                         }
1508
1509                         logger.CheckLoggedMessageHead ("file1: " + Path.Combine ("bar", "foo.dll"), "A1");
1510
1511                         string path_root = Path.GetPathRoot (Path.GetFullPath (projectdir));
1512                         logger.CheckLoggedMessageHead ("file1: RootDir: " + path_root, "A2");
1513
1514                         string fullpath = Path.GetFullPath (Path.Combine (projectdir, "bar"));
1515                         logger.CheckLoggedMessageHead ("file1: Directory: " + fullpath.Substring (path_root.Length) + Path.DirectorySeparatorChar, "A3");
1516
1517                         if (logger.NormalMessageCount != 0) {
1518                                 logger.DumpMessages ();
1519                                 Assert.Fail ("Unexpected extra messages found");
1520                         }
1521                 }
1522
1523                 void CreateDirectoriesAndFiles (string basedir, string[] dirs, string[] files)
1524                 {
1525                         foreach (string dir in dirs)
1526                                 Directory.CreateDirectory (Path.Combine (basedir, dir));
1527
1528                         foreach (string file in files)
1529                                 File.WriteAllText (file, String.Empty);
1530                 }
1531
1532                 string PathCombine (string path1, params string[] parts)
1533                 {
1534                         if (parts == null || parts.Length == 0)
1535                                 return path1;
1536
1537                         string final_path = path1;
1538                         foreach (string part in parts)
1539                                 final_path = Path.Combine (final_path, part);
1540
1541                         return final_path;
1542                 }
1543         }
1544 }