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