Merge pull request #820 from brendanzagaeski/master
[mono.git] / mcs / class / Microsoft.Build.Engine / Test / Microsoft.Build.BuildEngine / BuildItemTest.cs
1 //
2 // BuildItemTest.cs
3 //
4 // Author:
5 //   Marek Sieradzki (marek.sieradzki@gmail.com)
6 //
7 // (C) 2005 Marek Sieradzki
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 using System;
29 using Microsoft.Build.BuildEngine;
30 using Microsoft.Build.Framework;
31 using Microsoft.Build.Utilities;
32 using NUnit.Framework;
33
34 namespace MonoTests.Microsoft.Build.BuildEngine {
35         [TestFixture]
36         public class BuildItemTest {
37
38                 BuildItem item;
39         
40                 [Test]
41                 public void TestCtor1 ()
42                 {
43                         string itemName = "itemName";
44                         string itemInclude = "a;b;c";
45         
46                         item = new BuildItem (itemName, itemInclude);
47         
48                         Assert.AreEqual (itemInclude, item.FinalItemSpec, "A1");
49                         Assert.AreEqual (itemInclude, item.Include, "A2");
50                         Assert.AreEqual (String.Empty, item.Exclude, "A3");
51                         Assert.AreEqual (String.Empty, item.Condition, "A4");
52                         Assert.AreEqual (false, item.IsImported, "A5");
53                         Assert.AreEqual (itemName, item.Name, "A6");
54                 }
55         
56                 [Test]
57                 public void TestCtor2 ()
58                 {
59                         string itemName = "itemName";
60                         string itemSpec = "a;b;c";
61                         // result of Utilities.Escape (itemSpec)
62                         string escapedInclude = "a%3bb%3bc";
63                         ITaskItem taskItem = new TaskItem (itemSpec);
64
65                         item = new BuildItem (itemName, taskItem);
66         
67                         Assert.AreEqual (itemSpec, item.FinalItemSpec, "A1");
68                         Assert.AreEqual (escapedInclude, item.Include, "A2");
69                         Assert.AreEqual (String.Empty, item.Exclude, "A3");
70                         Assert.AreEqual (String.Empty, item.Condition, "A4");
71                         Assert.AreEqual (false, item.IsImported, "A5");
72                         Assert.AreEqual (itemName, item.Name, "A6");
73                 }
74
75                 [Test]
76                 [ExpectedException (typeof (ArgumentNullException))]
77                 public void TestCtor3 ()
78                 {
79                         new BuildItem (null, (string) null);
80                 }
81
82                 [Test]
83                 [ExpectedException (typeof (ArgumentNullException))]
84                 [Category ("NotDotNet")]
85                 public void TestCtor4 ()
86                 {
87                         new BuildItem (null, (ITaskItem) null);
88                 }
89
90                 [Test]
91                 public void TestCtor5 ()
92                 {
93                         new BuildItem (null, "something");
94                 }
95
96                 // Parameter "itemInclude" cannot have zero length.
97                 [Test]
98                 [Category ("NotDotNet")]
99                 [ExpectedException (typeof (ArgumentException))]
100                 public void TestCtor6 ()
101                 {
102                         new BuildItem (null, String.Empty);
103                 }
104
105                 [Test]
106                 [Category ("NotDotNet")] //IndexOutOfRange throw by MS .NET 2.0
107                 public void TestCtor7 ()
108                 {
109                         new BuildItem (String.Empty, "something");
110                 }
111
112                 [Test]
113                 public void TestClone1 ()
114                 {
115                         item = new BuildItem ("name", "1;2;3");
116                         item.SetMetadata ("a", "b");
117
118                         BuildItem item2 = item.Clone ();
119
120                         Assert.AreEqual ("1;2;3", item2.FinalItemSpec, "A1");
121                         Assert.AreEqual ("1;2;3", item2.Include, "A2");
122                         Assert.AreEqual (String.Empty, item2.Exclude, "A3");
123                         Assert.AreEqual (String.Empty, item2.Condition, "A4");
124                         Assert.AreEqual (false, item2.IsImported, "A5");
125                         Assert.AreEqual ("name", item2.Name, "A6");
126                 }
127
128                 // Cannot set a condition on an object not represented by an XML element in the project file.
129                 [Test]
130                 [ExpectedException (typeof (InvalidOperationException))]
131                 public void TestCondition1 ()
132                 {
133                         item = new BuildItem ("name", "1");
134                         item.Condition = "true";
135                 }
136
137                 [Test]
138                 [Ignore ("weird test need to check how project.Xml looks")]
139                 public void TestCondition2 ()
140                 {
141                         Engine engine;
142                         Project project;
143                         BuildItemGroup [] groups = new BuildItemGroup [1];
144
145                         string documentString = @"
146                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
147                                         <ItemGroup>
148                                                 <A Include='a;b' />
149                                         </ItemGroup>
150                                 </Project>
151                         ";
152
153                         engine = new Engine (Consts.BinPath);
154                         project = engine.CreateNewProject ();
155                         project.LoadXml (documentString);
156
157                         project.EvaluatedItems [0].Condition = "true";
158                         project.ItemGroups.CopyTo (groups, 0);
159                         Assert.AreEqual (String.Empty, groups [0] [0].Condition, "A1");
160                         Assert.AreEqual ("true", project.EvaluatedItems [0].Condition, "A2");
161                 }
162
163                 [Test]
164                 [Ignore ("weird test need to check how project.Xml looks")]
165                 public void TestCondition3 ()
166                 {
167                         Engine engine;
168                         Project project;
169                         BuildItemGroup [] groups = new BuildItemGroup [1];
170
171                         string documentString = @"
172                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
173                                         <ItemGroup>
174                                                 <A Include='a;b' />
175                                         </ItemGroup>
176                                 </Project>
177                         ";
178
179                         engine = new Engine (Consts.BinPath);
180                         project = engine.CreateNewProject ();
181                         project.LoadXml (documentString);
182
183                         project.ItemGroups.CopyTo (groups, 0);
184                         groups [0] [0].Condition = "true";
185                         Assert.AreEqual ("true", groups [0] [0].Condition, "A1");
186                         Assert.AreEqual ("true", project.EvaluatedItems [0].Condition, "A2");
187                 }
188
189                 [Test]
190                 public void TestCopyCustomMetadataTo1 ()
191                 {
192                         BuildItem source, destination;
193                         string itemName1 = "a";
194                         string itemName2 = "b";
195                         string itemInclude = "a;b;c";
196                         string metadataName = "name";
197                         string metadataValue = "value";
198
199                         source = new BuildItem (itemName1, itemInclude);
200                         destination = new BuildItem (itemName2, itemInclude);
201
202                         source.SetMetadata (metadataName, metadataValue);
203
204                         source.CopyCustomMetadataTo (destination);
205
206                         Assert.AreEqual (metadataValue, destination.GetMetadata (metadataName), "A1");
207                         Assert.AreEqual (metadataValue, destination.GetEvaluatedMetadata (metadataName), "A2");
208                 }
209
210                 [Test]
211                 [ExpectedException (typeof (ArgumentNullException))]
212                 [Category ("NotDotNet")]
213                 public void TestCopyCustomMetadataTo2 ()
214                 {
215                         BuildItem item = new BuildItem ("name", "include");
216                         item.SetMetadata ("name", "value");
217                         
218                         item.CopyCustomMetadataTo (null);
219                 }
220
221                 // Assigning the "Exclude" attribute of a virtual item is not allowed.
222                 [Test]
223                 [ExpectedException (typeof (InvalidOperationException))]
224                 public void TestExclude1 ()
225                 {
226                         item = new BuildItem ("name", "1");
227                         item.Exclude = "e";
228                 }
229
230                 [Test]
231                 public void TestExclude2 ()
232                 {
233                         Engine engine;
234                         Project project;
235                         BuildItemGroup [] groups = new BuildItemGroup [1];
236
237                         string documentString = @"
238                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
239                                         <ItemGroup>
240                                                 <A Include='a;b' />
241                                         </ItemGroup>
242                                 </Project>
243                         ";
244
245                         engine = new Engine (Consts.BinPath);
246                         project = engine.CreateNewProject ();
247                         project.LoadXml (documentString);
248                         project.ItemGroups.CopyTo (groups, 0);
249
250                         Assert.AreEqual (String.Empty, groups [0] [0].Exclude, "A1");
251
252                         groups [0] [0].Exclude = "b";
253
254                         Assert.AreEqual ("b", groups [0] [0].Exclude, "A2");
255                         Assert.AreEqual ("a;b", groups [0] [0].Include, "A3");
256                 }
257
258                 [Test]
259                 public void TestGetMetadata1 ()
260                 {
261                         string itemName = "a";
262                         string itemInclude = "a;b;c";
263                         string metadataName = "name";
264                         string metadataValue = "a;b;c";
265
266                         item = new BuildItem (itemName, itemInclude);
267
268                         Assert.AreEqual (String.Empty, item.GetMetadata (metadataName), "A1");
269
270                         item.SetMetadata (metadataName, metadataValue);
271
272                         Assert.AreEqual (metadataValue, item.GetMetadata (metadataName), "A2");
273                         Assert.IsTrue (item.GetMetadata ("FullPath").EndsWith (Utilities.Escape (itemInclude)), "A3");
274                         //Assert.IsTrue (String.Empty != item.GetMetadata ("RootDir"), "A4");
275                         Assert.AreEqual (itemInclude, item.GetMetadata ("Filename"), "A5");
276                         Assert.AreEqual (String.Empty, item.GetMetadata ("Extension"), "A6");
277                         Assert.AreEqual (String.Empty, item.GetMetadata ("RelativeDir"), "A7");
278                         Assert.IsTrue (String.Empty != item.GetMetadata ("Directory"), "A8");
279                         Assert.AreEqual (String.Empty, item.GetMetadata ("RecursiveDir"), "A9");
280                         Assert.AreEqual (itemInclude, item.GetMetadata ("Identity"), "A10");
281                         // FIXME: test with CreatedTime
282                         Assert.AreEqual (String.Empty, item.GetMetadata ("ModifiedTime"), "A11");
283                         Assert.AreEqual (String.Empty, item.GetMetadata ("ModifiedTime"), "A12");
284                         Assert.AreEqual (String.Empty, item.GetMetadata ("AccessedTime"), "A13");
285                 }
286
287                 [Test]
288                 public void GetMetadata_UnescapedItemSpec ()
289                 {
290                         string itemInclude = "a;b;c";
291                         string escapedItemInclude = Utilities.Escape (itemInclude);
292
293                         item = new BuildItem ("name", itemInclude);
294                         Assert.IsTrue (item.GetMetadata ("FullPath").EndsWith (escapedItemInclude), "#1a");
295                         Assert.IsTrue (item.GetEvaluatedMetadata ("FullPath").EndsWith (itemInclude), "#1b");
296
297                         Assert.AreEqual (itemInclude, item.GetMetadata ("FileName"), "#2b");
298                         Assert.AreEqual (itemInclude, item.GetEvaluatedMetadata ("FileName"), "#2b");
299
300                         Assert.AreEqual (itemInclude, item.GetMetadata ("Identity"), "#3a");
301                         Assert.AreEqual (itemInclude, item.GetEvaluatedMetadata ("Identity"), "#3b");
302                 }
303
304                 [Test]
305                 public void GetMetadata_EscapedItemSpec ()
306                 {
307                         string itemInclude = "a;b;c";
308                         string escapedItemInclude = Utilities.Escape (itemInclude);
309
310                         item = new BuildItem ("name", escapedItemInclude);
311                         Assert.IsTrue (item.GetMetadata ("FullPath").EndsWith (escapedItemInclude), "#1a");
312                         Assert.IsTrue (item.GetEvaluatedMetadata ("FullPath").EndsWith (itemInclude), "#1b");
313
314                         Assert.AreEqual (escapedItemInclude, item.GetMetadata ("FileName"), "#2b");
315                         Assert.AreEqual (itemInclude, item.GetEvaluatedMetadata ("FileName"), "#2b");
316
317                         Assert.AreEqual (escapedItemInclude, item.GetMetadata ("Identity"), "#3a");
318                         Assert.AreEqual ("a;b;c", item.GetEvaluatedMetadata ("Identity"), "#3b");
319                 }
320
321                 [Test]
322                 [ExpectedException (typeof (ArgumentNullException))]
323                 public void TestGetMetadata2 ()
324                 {
325                         item = new BuildItem ("name", "spec");
326                         item.GetMetadata (null);
327                 }
328
329                 [Test]
330                 public void TestGetMetadata3 ()
331                 {
332                         Engine engine;
333                         Project project;
334                         BuildItemGroup [] groups = new BuildItemGroup [1];
335
336                         string documentString = @"
337                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
338                                         <ItemGroup>
339                                                 <A Include='a;b'>
340                                                         <Meta>Value</Meta>
341                                                 </A>
342                                         </ItemGroup>
343                                 </Project>
344                         ";
345
346                         engine = new Engine (Consts.BinPath);
347                         project = engine.CreateNewProject ();
348                         project.LoadXml (documentString);
349                         project.ItemGroups.CopyTo (groups, 0);
350
351                         Assert.AreEqual ("Value", groups [0] [0].GetMetadata ("Meta"), "A1");
352                         Assert.AreEqual (String.Empty, groups [0] [0].GetMetadata ("Other"), "A2");
353                 }
354
355                 [Test]
356                 public void TestGetEvaluatedMetadata1 ()
357                 {
358                         string itemName = "a";
359                         string itemInclude = "a";
360                         string metadataName = "name";
361                         string metadataValue = "a;b;c";
362
363                         item = new BuildItem (itemName, itemInclude);
364
365                         Assert.AreEqual (String.Empty, item.GetEvaluatedMetadata (metadataName), "A1");
366
367                         item.SetMetadata (metadataName, metadataValue);
368
369                         Assert.AreEqual (metadataValue, item.GetEvaluatedMetadata (metadataName), "A2");
370                         Assert.AreEqual (itemInclude, item.GetEvaluatedMetadata ("Identity"), "A3");
371                 }
372
373                 [Test]
374                 public void TestGetEvaluatedMetadata2 ()
375                 {
376                         Engine engine;
377                         Project project;
378                         BuildItemGroup [] groups = new BuildItemGroup [1];
379
380                         string documentString = @"
381                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
382                                         <PropertyGroup>
383                                                 <A>A</A>
384                                         </PropertyGroup>
385                                         <ItemGroup>
386                                                 <A Include='a;b'>
387                                                         <Meta>Value</Meta>
388                                                         <Meta2>$(A)</Meta2>
389                                                 </A>
390                                         </ItemGroup>
391                                 </Project>
392                         ";
393
394                         engine = new Engine (Consts.BinPath);
395                         project = engine.CreateNewProject ();
396                         project.LoadXml (documentString);
397                         project.ItemGroups.CopyTo (groups, 0);
398
399                         Assert.AreEqual ("Value", groups [0] [0].GetEvaluatedMetadata ("Meta"), "A1");
400                         Assert.AreEqual (String.Empty, groups [0] [0].GetEvaluatedMetadata ("Other"), "A2");
401                         Assert.AreEqual ("A", groups [0] [0].GetEvaluatedMetadata ("Meta2"), "A3");
402                 }
403
404                 [Test]
405                 public void TestHasMetadata1 ()
406                 {
407                         string itemName = "a";
408                         string itemInclude = "a";
409                         string metadataName = "name";
410
411                         item = new BuildItem (itemName, itemInclude);
412
413                         Assert.AreEqual (false, item.HasMetadata (metadataName), "A1");
414
415                         item.SetMetadata (metadataName, "value");
416
417                         Assert.AreEqual (true, item.HasMetadata (metadataName), "A2");
418                         Assert.IsTrue (item.HasMetadata ("FullPath"), "A3");
419                         Assert.IsTrue (item.HasMetadata ("RootDir"), "A4");
420                         Assert.IsTrue (item.HasMetadata ("Filename"), "A5");
421                         Assert.IsTrue (item.HasMetadata ("Extension"), "A6");
422                         Assert.IsTrue (item.HasMetadata ("RelativeDir"), "A7");
423                         Assert.IsTrue (item.HasMetadata ("Directory"), "A8");
424                         Assert.IsTrue (item.HasMetadata ("RecursiveDir"), "A9");
425                         Assert.IsTrue (item.HasMetadata ("Identity"), "A10");
426                         Assert.IsTrue (item.HasMetadata ("ModifiedTime"), "A11");
427                         Assert.IsTrue (item.HasMetadata ("CreatedTime"), "A12");
428                         Assert.IsTrue (item.HasMetadata ("AccessedTime"), "A13");
429                 }
430
431                 [Test]
432                 public void TestHasMetadata2 ()
433                 {
434                         Engine engine;
435                         Project project;
436                         BuildItemGroup [] groups = new BuildItemGroup [1];
437
438                         string documentString = @"
439                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
440                                         <ItemGroup>
441                                                 <A Include='a;b'>
442                                                         <Meta>Value</Meta>
443                                                 </A>
444                                         </ItemGroup>
445                                 </Project>
446                         ";
447
448                         engine = new Engine (Consts.BinPath);
449                         project = engine.CreateNewProject ();
450                         project.LoadXml (documentString);
451                         project.ItemGroups.CopyTo (groups, 0);
452
453                         BuildItem item = groups [0] [0];
454
455                         Assert.IsFalse (item.HasMetadata ("Other"), "A1");
456                         Assert.IsTrue (item.HasMetadata ("Meta"), "A2");
457                         Assert.IsTrue (item.HasMetadata ("FullPath"), "A3");
458                         Assert.IsTrue (item.HasMetadata ("RootDir"), "A4");
459                         Assert.IsTrue (item.HasMetadata ("Filename"), "A5");
460                         Assert.IsTrue (item.HasMetadata ("Extension"), "A6");
461                         Assert.IsTrue (item.HasMetadata ("RelativeDir"), "A7");
462                         Assert.IsTrue (item.HasMetadata ("Directory"), "A8");
463                         Assert.IsTrue (item.HasMetadata ("RecursiveDir"), "A9");
464                         Assert.IsTrue (item.HasMetadata ("Identity"), "A10");
465                         Assert.IsTrue (item.HasMetadata ("ModifiedTime"), "A11");
466                         Assert.IsTrue (item.HasMetadata ("CreatedTime"), "A12");
467                         Assert.IsTrue (item.HasMetadata ("AccessedTime"), "A13");
468                 }
469
470                 [Test]
471                 [ExpectedException (typeof (ArgumentNullException))]
472                 public void TestHasMetadata3 ()
473                 {
474                         item = new BuildItem ("name", "spec");
475                         item.HasMetadata (null);
476                 }
477
478                 [Test]
479                 [ExpectedException (typeof (InvalidProjectFileException))]
480                 public void TestInclude1 ()
481                 {
482                         Engine engine;
483                         Project project;
484
485                         string documentString = @"
486                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
487                                         <ItemGroup>
488                                                 <A Include='' />
489                                         </ItemGroup>
490                                 </Project>
491                         ";
492
493                         engine = new Engine (Consts.BinPath);
494                         project = engine.CreateNewProject ();
495                         project.LoadXml (documentString);
496                 }
497
498                 [Test]
499                 public void TestInclude2 ()
500                 {
501                         Engine engine;
502                         Project project;
503
504                         string documentString = @"
505                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
506                                         <ItemGroup>
507                                                 <A Include='a' />
508                                         </ItemGroup>
509                                 </Project>
510                         ";
511
512                         engine = new Engine (Consts.BinPath);
513                         project = engine.CreateNewProject ();
514                         project.LoadXml (documentString);
515
516                         Assert.AreEqual ("a", project.EvaluatedItems [0].Include, "A1");
517                 }
518
519                 [Test]
520                 public void TestInclude3 ()
521                 {
522                         BuildItem item = new BuildItem ("name", "a");
523                         item.Include = "b";
524                         Assert.AreEqual ("b", item.Include, "A1");
525                 }
526
527                 [Test]
528                 public void TestName1 ()
529                 {
530                         Engine engine;
531                         Project project;
532                         BuildItemGroup [] groups = new BuildItemGroup [1];
533
534                         string documentString = @"
535                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
536                                         <ItemGroup>
537                                                 <A Include='a;b' />
538                                         </ItemGroup>
539                                 </Project>
540                         ";
541
542                         engine = new Engine (Consts.BinPath);
543                         project = engine.CreateNewProject ();
544                         project.LoadXml (documentString);
545
546                         project.EvaluatedItems [0].Name = "C";
547
548                         Assert.AreEqual (2, project.EvaluatedItems.Count, "A1");
549                         Assert.AreEqual ("C", project.EvaluatedItems [0].Name, "A2");
550                         Assert.AreEqual ("A", project.EvaluatedItems [1].Name, "A3");
551                         project.ItemGroups.CopyTo (groups, 0);
552                         Assert.AreEqual (2, groups [0].Count, "A4");
553                         Assert.AreEqual ("C", groups [0] [0].Name, "A5");
554                         Assert.AreEqual ("A", groups [0] [1].Name, "A6");
555                 }
556
557                 [Test]
558                 public void TestName2 ()
559                 {
560                         BuildItem item = new BuildItem ("A", "V");
561                         item.Name = "B";
562                         Assert.AreEqual ("B", item.Name, "A1");
563                 }
564
565                 [Test]
566                 public void TestRemoveMetadata1 ()
567                 {
568                         string itemName = "a";
569                         string itemInclude = "a";
570                         string metadataName = "name";
571                         string metadataValue = "a;b;c";
572
573                         item = new BuildItem (itemName, itemInclude);
574
575                         item.SetMetadata (metadataName, metadataValue);
576
577                         Assert.AreEqual (true, item.HasMetadata (metadataName), "A1");
578
579                         item.RemoveMetadata (metadataName);
580
581                         Assert.AreEqual (false, item.HasMetadata (metadataName), "A2");
582                 }
583
584                 [Test]
585                 [ExpectedException (typeof (ArgumentNullException))]
586                 public void TestRemoveMetadata2 ()
587                 {
588                         item = new BuildItem ("name", "value");
589                         item.RemoveMetadata (null);
590                 }
591
592                 [Test]
593                 public void TestRemoveMetadata3 ()
594                 {
595                         item = new BuildItem ("name", "value");
596                         item.RemoveMetadata ("undefined_metadata");
597                 }
598
599                 // "Filename" is a reserved item meta-data, and cannot be modified or deleted.
600                 [Test]
601                 [ExpectedException (typeof (ArgumentException))]
602                 public void TestRemoveMetadata4 ()
603                 {
604                         item = new BuildItem ("name", "value");
605                         item.RemoveMetadata ("Filename");
606                 }
607
608                 [Test]
609                 public void TestRemoveMetadata5 ()
610                 {
611                         Engine engine;
612                         Project project;
613                         BuildItemGroup [] groups = new BuildItemGroup [1];
614
615                         string documentString = @"
616                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
617                                         <ItemGroup>
618                                                 <A Include='a;b'>
619                                                         <Meta>Value</Meta>
620                                                         <Meta2>$(A)</Meta2>
621                                                 </A>
622                                                 <B Include='a'/>
623                                         </ItemGroup>
624                                 </Project>
625                         ";
626
627                         engine = new Engine (Consts.BinPath);
628                         project = engine.CreateNewProject ();
629                         project.LoadXml (documentString);
630                         project.ItemGroups.CopyTo (groups, 0);
631
632                         Assert.AreEqual (3, project.EvaluatedItems.Count, "A1");
633
634                         groups [0] [0].RemoveMetadata ("Meta");
635                         Assert.IsFalse (groups [0] [0].HasMetadata ("Meta"), "A2");
636                         groups [0] [0].RemoveMetadata ("undefined_metadata");
637
638                         Assert.AreEqual (2, groups [0].Count, "A3");
639                         Assert.AreEqual (3, project.EvaluatedItems.Count, "A4");
640                 }
641
642                 [Test]
643                 public void TestRemoveMetadata6 ()
644                 {
645                         Engine engine;
646                         Project project;
647                         BuildItemGroup [] groups = new BuildItemGroup [1];
648
649                         string documentString = @"
650                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
651                                         <ItemGroup>
652                                                 <A Include='a;b;c'>
653                                                         <Meta>Value</Meta>
654                                                         <Meta2>$(A)</Meta2>
655                                                 </A>
656                                                 <B Include='a'/>
657                                         </ItemGroup>
658                                 </Project>
659                         ";
660
661                         engine = new Engine (Consts.BinPath);
662                         project = engine.CreateNewProject ();
663                         project.LoadXml (documentString);
664
665                         Assert.AreEqual (4, project.EvaluatedItems.Count, "A1");
666                         project.ItemGroups.CopyTo (groups, 0);
667                         Assert.AreEqual (2, groups [0].Count, "A2");
668
669                         BuildItem b1 = project.EvaluatedItems [0];
670
671                         b1.RemoveMetadata ("Meta");
672
673                         Assert.AreEqual (4, project.EvaluatedItems.Count, "A3");
674                         project.ItemGroups.CopyTo (groups, 0);
675                         Assert.AreEqual (4, groups [0].Count, "A4");
676                 }
677
678                 [Test]
679                 [ExpectedException (typeof (ArgumentNullException))]
680                 public void TestSetMetadata1 ()
681                 {
682                         item = new BuildItem ("name", "include");
683                         item.SetMetadata (null, null);
684                 }
685
686                 [Test]
687                 [ExpectedException (typeof (ArgumentNullException))]
688                 public void TestSetMetadata2 ()
689                 {
690                         item = new BuildItem ("name", "include");
691                         item.SetMetadata ("name", null);
692                 }
693
694                 [Test]
695                 public void TestSetMetadata3 ()
696                 {
697                         item = new BuildItem ("name", "include");
698                         item.SetMetadata ("a", "$(A)");
699                         item.SetMetadata ("b", "$(A)", true);
700                         item.SetMetadata ("c", "$(A)", false);
701
702                         Assert.AreEqual ("$(A)", item.GetEvaluatedMetadata ("a"), "A1");
703                         Assert.AreEqual ("$(A)", item.GetEvaluatedMetadata ("b"), "A2");
704                         Assert.AreEqual ("$(A)", item.GetEvaluatedMetadata ("c"), "A3");
705                         Assert.AreEqual ("$(A)", item.GetMetadata ("a"), "A4");
706                         Assert.AreEqual (Utilities.Escape ("$(A)"), item.GetMetadata ("b"), "A5");
707                         Assert.AreEqual ("$(A)", item.GetMetadata ("c"), "A6");
708                 }
709
710                 // "Filename" is a reserved item meta-data, and cannot be modified or deleted.
711                 [Test]
712                 [ExpectedException (typeof (ArgumentException))]
713                 public void TestSetMetadata4 ()
714                 {
715                         item = new BuildItem ("name", "include");
716                         item.SetMetadata ("Filename", "something");
717                 }
718
719                 [Test]
720                 public void TestSetMetadata5 ()
721                 {
722                         Engine engine;
723                         Project project;
724                         BuildItemGroup [] groups = new BuildItemGroup [1];
725
726                         string documentString = @"
727                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
728                                         <PropertyGroup>
729                                                 <A>A</A>
730                                         </PropertyGroup>
731                                         <ItemGroup>
732                                                 <A Include='a;b'/>
733                                         </ItemGroup>
734                                 </Project>
735                         ";
736
737                         engine = new Engine (Consts.BinPath);
738                         project = engine.CreateNewProject ();
739                         project.LoadXml (documentString);
740
741                         project.ItemGroups.CopyTo (groups, 0);
742
743                         groups [0] [0].SetMetadata ("Meta", "$(A)");
744                         Assert.AreEqual (2, project.EvaluatedItems.Count, "A0");
745
746                         Assert.AreEqual (1, groups [0].Count, "A1");
747                         Assert.AreEqual ("$(A)", groups [0] [0].GetMetadata ("Meta"), "A2");
748                         Assert.AreEqual ("$(A)", project.EvaluatedItems [0].GetMetadata ("Meta"), "A3");
749                         Assert.AreEqual ("$(A)", project.EvaluatedItems [1].GetMetadata ("Meta"), "A4");
750                         Assert.AreEqual ("A", project.EvaluatedItems [0].GetEvaluatedMetadata ("Meta"), "A5");
751                         Assert.AreEqual ("A", project.EvaluatedItems [1].GetEvaluatedMetadata ("Meta"), "A6");
752                 }
753
754                 [Test]
755                 public void TestSetMetadata5a () {
756                         Engine engine;
757                         Project project;
758                         BuildItemGroup[] groups = new BuildItemGroup[1];
759
760                         string documentString = @"
761                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
762                                         <PropertyGroup>
763                                                 <A>A</A>
764                                                 <C>@(D)</C>
765                                         </PropertyGroup>
766                                         <ItemGroup>
767                                                 <D Include='D'/>
768                                                 <C Include='$(C)'/>
769                                                 <A Include='a;b'>
770                                                         <Md>@(C)</Md>
771                                                 </A>
772                                                 <B Include='$(A)'/>
773                                         </ItemGroup>
774                                         <Target Name='main'>
775                                                 <Message Text=""a.md: %(A.Md)""/>
776                                                 <Message Text=""a.md: %(A.Meta)""/>
777                                         </Target>
778                                 </Project>
779                         ";
780
781                         engine = new Engine (Consts.BinPath);
782                         project = engine.CreateNewProject ();
783                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger = new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
784                         engine.RegisterLogger (logger);
785                         project.LoadXml (documentString);
786
787                         CheckMetadata (project, "A", "Md", new string [] {"@(C)", "@(C)"}, "G1");
788                         CheckEvaluatedMetadata (project, "A", "Md", new string[] { "D", "D" }, "G2");
789
790                         //@(B)
791                         Assert.AreEqual ("A", project.GetEvaluatedItemsByName ("B")[0].FinalItemSpec, "B2");
792
793                         project.ItemGroups.CopyTo (groups, 0);
794                         /*Broken right now:
795                           CheckBuildItemGroup (groups[0], new string[] {
796                                 "D", "D",
797                                 "C", "$(C)",
798                                 "A", "a;b",
799                                 "B", "$(A)"
800                         }, "H1");*/
801
802                         CheckBuildItemGroup (project.GetEvaluatedItemsByName ("C"), new string[] {
803                                 "C", "D"
804                         }, "H2");
805
806                         CheckBuildItemGroup (project.GetEvaluatedItemsByName ("C"), new string[] {
807                                 "C", "D"
808                         }, "I");
809
810                         project.GetEvaluatedItemsByName ("A")[0].SetMetadata ("Meta", "@(B)");
811
812                         Assert.AreEqual (5, project.EvaluatedItems.Count, "A0");
813                         Assert.AreEqual (2, project.GetEvaluatedItemsByName ("A").Count, "A7");
814
815                         CheckMetadata (project, "A", "Meta", new string[] { "@(B)", "" }, "J");
816
817                         if (!project.Build ()) {
818                                 logger.DumpMessages ();
819                                 Assert.Fail ("Build failed");
820                         }
821
822                         CheckMetadata (project, "A", "Meta", new string[] { "@(B)", "" }, "K1");
823                         CheckEvaluatedMetadata (project, "A", "Meta", new string[] { "", "" }, "K2");
824
825                         logger.CheckLoggedMessageHead ("a.md: D", "E10");
826                         logger.CheckLoggedMessageHead ("a.md: ", "E11");
827                         Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected messages left");
828                 }
829
830                 [Test]
831                 public void TestSetMetadata6 ()
832                 {
833                         Engine engine;
834                         Project project;
835                         BuildItemGroup [] groups = new BuildItemGroup [1];
836
837                         string documentString = @"
838                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
839                                         <ItemGroup>
840                                                 <A Include='a;b;c'/>
841                                         </ItemGroup>
842                                 </Project>
843                         ";
844
845                         engine = new Engine (Consts.BinPath);
846                         project = engine.CreateNewProject ();
847                         project.LoadXml (documentString);
848
849                         project.EvaluatedItems [0].SetMetadata ("Meta", "Value");
850                         //NOTE: this triggers reevaluation
851                         Assert.AreEqual ("A", project.EvaluatedItems [0].Name, "A0");
852                         project.ItemGroups.CopyTo (groups, 0);
853
854                         Assert.AreEqual (3, groups [0].Count, "A1");
855                         Assert.AreEqual ("Value", groups [0] [0].GetMetadata ("Meta"), "A2");
856                         Assert.AreEqual (String.Empty, groups [0] [1].GetMetadata ("Meta"), "A3");
857                         Assert.AreEqual (String.Empty, groups [0] [2].GetMetadata ("Meta"), "A4");
858                         Assert.AreEqual (3, project.EvaluatedItems.Count, "A5");
859                         Assert.AreEqual ("Value", project.EvaluatedItems [0].GetMetadata ("Meta"), "A6");
860                         Assert.AreEqual (String.Empty, project.EvaluatedItems [1].GetMetadata ("Meta"), "A7");
861                         Assert.AreEqual (String.Empty, project.EvaluatedItems [1].GetMetadata ("Meta"), "A8");
862                 }
863
864                 [Test]
865                 public void TestSetMetadata7 ()
866                 {
867                         Engine engine;
868                         Project project;
869                         BuildItemGroup [] groups = new BuildItemGroup [1];
870
871                         string documentString = @"
872                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
873                                         <ItemGroup>
874                                                 <A Include='a;b;c'>
875                                                         <Meta>Value2</Meta>
876                                                 </A>
877                                         </ItemGroup>
878                                 </Project>
879                         ";
880
881                         engine = new Engine (Consts.BinPath);
882                         project = engine.CreateNewProject ();
883                         project.LoadXml (documentString);
884
885                         project.ItemGroups.CopyTo (groups, 0);
886                         groups [0][0].SetMetadata ("Meta", "Value");
887                         Assert.AreEqual ("Value", groups [0] [0].GetEvaluatedMetadata ("Meta"), "A1");
888                         Assert.AreEqual ("Value", groups [0] [0].GetMetadata ("Meta"), "A2");
889                 }
890
891                 [Test]
892                 public void TestSetMetadata8 ()
893                 {
894                         Engine engine;
895                         Project project;
896                         BuildItemGroup [] groups = new BuildItemGroup [1];
897
898                         string documentString = @"
899                                 <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
900                                         <ItemGroup>
901                                                 <A Include='a' />
902                                         </ItemGroup>
903                                 </Project>
904                         ";
905
906                         engine = new Engine (Consts.BinPath);
907                         project = engine.CreateNewProject ();
908                         project.LoadXml (documentString);
909
910                         project.EvaluatedItems [0].SetMetadata ("Meta", "Value");
911
912                         Assert.AreEqual (1, project.EvaluatedItems.Count, "A1");
913                         Assert.AreEqual ("Value", project.EvaluatedItems [0].GetMetadata ("Meta"), "A2");
914                         project.ItemGroups.CopyTo (groups, 0);
915                         Assert.AreEqual (1, groups [0].Count, "A3");
916                 }
917
918                 [Test]
919                 public void TestBuildItemTransform ()
920                 {
921                         string projectText = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
922                                 <UsingTask TaskName='BatchingTestTask' AssemblyFile='Test\resources\TestTasks.dll' />
923
924                                 <ItemGroup>
925                                         <Foo Include='abc'/>
926                                         <Foo Include='def'/>
927                                 </ItemGroup>
928                                 <PropertyGroup>
929                                         <FooProp>PropValue/</FooProp>
930                                 </PropertyGroup>
931
932                                 <Target Name=""main"">
933                                         <CreateItem Include=""@(Foo)"">
934                                                 <Output TaskParameter =""Include"" ItemName=""SyntheticFoo""/>
935                                         </CreateItem>
936
937                                         <BatchingTestTask
938                                                 TaskItemsOutput=""@(SyntheticFoo->'$(FooProp)%(Identity).txt')"">
939                                                 <Output TaskParameter='TaskItemsOutput' ItemName='I0' />
940                                         </BatchingTestTask>
941                                 </Target>
942                         </Project>";
943
944                         Engine engine = new Engine (Consts.BinPath);
945                         MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
946                                 new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
947                         engine.RegisterLogger (logger);
948                         Project project = engine.CreateNewProject ();
949                         project.LoadXml (projectText);
950
951                         bool result = project.Build ("main");
952                         if (!result) {
953                                 logger.DumpMessages ();
954                                 Assert.Fail ("Build failed");
955                         }
956
957                         BuildItemGroup grp = project.GetEvaluatedItemsByName ("I0");
958                         Assert.AreEqual (2, grp.Count, "A1");
959                         Assert.AreEqual ("PropValue/abc.txt", grp [0].FinalItemSpec, "A2");
960                         Assert.AreEqual ("PropValue/def.txt", grp [1].FinalItemSpec, "A3");
961                 }
962
963                 void CheckMetadata (Project p, string itemname, string metadataname, string[] values, string prefix)
964                 {
965                         BuildItemGroup group = p.GetEvaluatedItemsByName (itemname);
966
967                         Assert.AreEqual (values.Length, group.Count, "Number of items for itemname " + itemname);
968
969                         for (int i = 0; i < values.Length; i++) {
970                                 Assert.AreEqual (values[i], group [i].GetMetadata (metadataname), prefix + "#" + i.ToString ());
971                         }
972                 }
973
974                 void CheckEvaluatedMetadata (Project p, string itemname, string metadataname, string[] values, string prefix)
975                 {
976                         BuildItemGroup group = p.GetEvaluatedItemsByName (itemname);
977
978                         Assert.AreEqual (values.Length, group.Count, "Number of items for itemname " + itemname);
979
980                         for (int i = 0; i < values.Length; i++) {
981                                 Assert.AreEqual (values[i], group [i].GetEvaluatedMetadata (metadataname), prefix + "#" + i.ToString ());
982                         }
983                 }
984
985                 void CheckBuildItemGroup (BuildItemGroup group, string[] names, string prefix)
986                 {
987                         try {
988                                 Assert.AreEqual (group.Count, names.Length / 2, "Number of items in group");
989                                 for (int i = 0; i < group.Count; i++) {
990                                         Assert.AreEqual (names[i * 2], group[i].Name, String.Format ("{0}#{1} : item name", prefix, i));
991                                         Assert.AreEqual (names[(i * 2) + 1], group[i].FinalItemSpec, String.Format ("{0}#{1} : FinalItemSpec", prefix, i));
992                                 }
993                         } catch (AssertionException) {
994                                 for (int i = 0; i < group.Count; i++) {
995                                         Console.WriteLine ("group[{0}] = {1}", i, group[i].Name);
996                                         Console.WriteLine ("group[{0}] = {1}", i, group[i].FinalItemSpec);
997                                 }
998                                 throw;
999                         }
1000                 }
1001         }
1002 }