[xbuild] Clean up test logs.
[mono.git] / mcs / class / Microsoft.Build.Tasks / Test / Microsoft.Build.Tasks / TaskBatchingTest.cs
1 //
2 // TaskBatchingTest.cs
3 //
4 // Author:
5 //   Ankit Jain (jankit@novell.com)
6 //
7 // Copyright 2008 Novell, Inc (http://www.novell.com)
8 // Copyright 2009 Novell, Inc (http://www.novell.com)
9 //
10 // Permission is hereby granted, free of charge, to any person obtaining
11 // a copy of this software and associated documentation files (the
12 // "Software"), to deal in the Software without restriction, including
13 // without limitation the rights to use, copy, modify, merge, publish,
14 // distribute, sublicense, and/or sell copies of the Software, and to
15 // permit persons to whom the Software is furnished to do so, subject to
16 // the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
29 using System;
30 using System.Collections.Generic;
31 using System.Text;
32 using NUnit.Framework;
33 using Microsoft.Build.BuildEngine;
34 using Microsoft.Build.Framework;
35 using Microsoft.Build.Tasks;
36 using Microsoft.Build.Utilities;
37
38 namespace MonoTests.Microsoft.Build.Tasks
39 {
40         [TestFixture]
41         public class TaskBatchingTest
42         {
43                 string projectHeader;
44                 public TaskBatchingTest ()
45                 {
46                         projectHeader = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + ">";
47                 }
48
49                 [Test]
50                 public void Test1 ()
51                 {
52                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
53                                 <ItemGroup>
54                                         <ResXFile Include=""Item1"">
55                                                 <Culture>fr</Culture>
56                                         </ResXFile>
57                                         <ResXFile Include=""Item2"">
58                                                 <Culture>fr</Culture>
59                                         </ResXFile>
60                                         <ResXFile Include=""Item3"">
61                                                 <Culture>en</Culture>
62                                         </ResXFile>
63                                         <ResXFile Include=""Item4"">
64                                                 <Culture>gb</Culture>
65                                         </ResXFile>
66                                         <ResXFile Include=""Item5"">
67                                                 <Culture>fr</Culture>
68                                         </ResXFile>
69                                         <ResXFile Include=""Item6"">
70                                                 <Culture>it</Culture>
71                                         </ResXFile>
72                                 </ItemGroup>
73
74                                 <Target Name=""ShowMessage"">
75                                         <Message
76                                                 Text = ""Culture: %(ResXFile.Culture) -- ResXFile: @(ResXFile)"" />
77                                 </Target>
78                           </Project>";
79
80                         Engine engine = new Engine (Consts.BinPath);
81                         Project project = engine.CreateNewProject ();
82
83                         TestMessageLogger testLogger = new TestMessageLogger ();
84                         engine.RegisterLogger (testLogger);
85
86                         project.LoadXml (projectString);
87                         Assert.IsTrue (project.Build ("ShowMessage"), "A1: Build failed");
88
89                         CheckMessage (testLogger, "fr", "Item1;Item2;Item5", "A2");
90                         CheckMessage (testLogger, "en", "Item3", "A3");
91                         CheckMessage (testLogger, "gb", "Item4", "A4");
92                         CheckMessage (testLogger, "it", "Item6", "A5");
93
94                         CheckEngineEventCounts (testLogger, 1, 1, 4, 4);
95                 }
96
97                 // Test1 with unqualified %(Culture)
98                 [Test]
99                 public void Test2 ()
100                 {
101                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
102                                 <ItemGroup>
103                                         <ResXFile Include=""Item1"">
104                                                 <Culture>fr</Culture>
105                                         </ResXFile>
106                                         <ResXFile Include=""Item2"">
107                                                 <Culture>fr</Culture>
108                                         </ResXFile>
109                                         <ResXFile Include=""Item3"">
110                                                 <Culture>en</Culture>
111                                         </ResXFile>
112                                         <ResXFile Include=""Item4"">
113                                                 <Culture>gb</Culture>
114                                         </ResXFile>
115                                         <ResXFile Include=""Item5"">
116                                                 <Culture>fr</Culture>
117                                         </ResXFile>
118                                         <ResXFile Include=""Item6"">
119                                                 <Culture>it</Culture>
120                                         </ResXFile>
121                                 </ItemGroup>
122
123                                 <Target Name=""ShowMessage"">
124                                         <Message
125                                                 Text = ""Culture: %(Culture) -- ResXFile: @(ResXFile)"" />
126                                 </Target>
127                           </Project>";
128
129                         Engine engine = new Engine (Consts.BinPath);
130                         Project project = engine.CreateNewProject ();
131
132                         TestMessageLogger testLogger = new TestMessageLogger ();
133                         engine.RegisterLogger (testLogger);
134
135                         project.LoadXml (projectString);
136                         Assert.IsTrue (project.Build ("ShowMessage"), "A1: Build failed");
137
138                         CheckMessage (testLogger, "fr", "Item1;Item2;Item5", "A2");
139                         CheckMessage (testLogger, "en", "Item3", "A3");
140                         CheckMessage (testLogger, "gb", "Item4", "A4");
141                         CheckMessage (testLogger, "it", "Item6", "A5");
142
143                         CheckEngineEventCounts (testLogger, 1, 1, 4, 4);
144                 }
145
146                 [Test]
147                 public void TestUnqualifiedMetadataReference ()
148                 {
149                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
150                                 <ItemGroup>
151                                         <ResXFile Include=""Item1"">
152                                                 <Culture>fr</Culture>
153                                         </ResXFile>
154                                         <ResXFile Include=""Item5"" />
155                                         <ResXFile Include=""Item6"">
156                                                 <Culture>it</Culture>
157                                         </ResXFile>
158                                 </ItemGroup>
159
160                                 <Target Name=""ShowMessage"">
161                                         <Message
162                                                 Text = ""Culture: %(Culture) -- ResXFile: @(ResXFile)"" />
163                                 </Target>
164                           </Project>";
165
166                         Engine engine = new Engine (Consts.BinPath);
167                         Project project = engine.CreateNewProject ();
168
169                         TestMessageLogger testLogger = new TestMessageLogger ();
170                         engine.RegisterLogger (testLogger);
171
172                         project.LoadXml (projectString);
173
174                         //Fails as Culture is being referenced unqualified, and no Culture is
175                         //specified for "Item5"
176                         bool result = project.Build ("ShowMessage");
177                         if (result)
178                                 Assert.Fail ("A1: Build should have failed");
179
180                         CheckEngineEventCounts (testLogger, 1, 1, 0, 0);
181                 }
182
183                 [Test]
184                 public void Test4 ()
185                 {
186                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
187                                 <ItemGroup>
188                                         <ResXFile Include=""Item1"">
189                                                 <Culture>fr</Culture>
190                                         </ResXFile>
191                                         <ResXFile Include=""Item5"" />
192                                         <ResXFile Include=""Item6"">
193                                                 <Culture>it</Culture>
194                                         </ResXFile>
195                                 </ItemGroup>
196
197                                 <Target Name=""ShowMessage"">
198                                         <Message
199                                                 Text = ""Culture: %(ResXFile.Culture) -- ResXFile: @(ResXFile)"" />
200                                 </Target>
201                           </Project>";
202
203                         Engine engine = new Engine (Consts.BinPath);
204                         Project project = engine.CreateNewProject ();
205
206                         TestMessageLogger testLogger = new TestMessageLogger ();
207                         engine.RegisterLogger (testLogger);
208
209                         project.LoadXml (projectString);
210
211                         //no Culture is specified for "Item5", but
212                         //Culture is being referenced __qualified__, so works
213                         Assert.IsTrue (project.Build ("ShowMessage"), "A1: Build failed");
214
215                         CheckMessage (testLogger, "fr", "Item1", "A2");
216                         CheckMessage (testLogger, "", "Item5", "A3");
217                         CheckMessage (testLogger, "it", "Item6", "A3");
218                         CheckEngineEventCounts (testLogger, 1, 1, 3, 3);
219                 }
220
221                 [Test]
222                 public void TestMultiItemCollections ()
223                 {
224                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
225                                 <ItemGroup>
226                                         <ResXFile Include=""Item1"">
227                                                 <Culture>fr</Culture>
228                                         </ResXFile>
229                                         <ResXFile Include=""Item2"">
230                                                 <Culture>fr</Culture>
231                                         </ResXFile>
232                                         <ResXFile Include=""Item3"">
233                                                 <Culture>en</Culture>
234                                         </ResXFile>
235                                         <ResXFile Include=""Item4"">
236                                                 <Culture>gb</Culture>
237                                         </ResXFile>
238                                         <ResXFile Include=""Item6"">
239                                                 <Culture>it</Culture>
240                                         </ResXFile>
241
242                                         <NonResXFile Include=""Item7"">
243                                                 <Culture>it</Culture>
244                                         </NonResXFile>
245                                         <NonResXFile Include=""Item8"">
246                                                 <Culture>en</Culture>
247                                         </NonResXFile>
248                                         <NonResXFile Include=""Item9"">
249                                                 <Culture>en</Culture>
250                                         </NonResXFile>
251                                 </ItemGroup>
252
253                                 <Target Name=""ShowMessage"">
254                                         <Message
255                                                 Text = ""Culture: %(Culture) -- ResXFiles: @(ResXFile) NonResXFiles: @(NonResXFile)"" />
256                                 </Target>
257                           </Project>";
258
259                         Engine engine = new Engine (Consts.BinPath);
260                         Project project = engine.CreateNewProject ();
261
262                         TestMessageLogger testLogger = new TestMessageLogger ();
263                         engine.RegisterLogger (testLogger);
264
265                         project.LoadXml (projectString);
266                         Assert.IsTrue (project.Build ("ShowMessage"), "A1: Build failed");
267
268                         CheckMessage2 (testLogger, "fr", "Item1;Item2", string.Empty, "A2");
269                         CheckMessage2 (testLogger, "en", "Item3", "Item8;Item9", "A3");
270                         CheckMessage2 (testLogger, "gb", "Item4", string.Empty, "A4");
271                         CheckMessage2 (testLogger, "it", "Item6", "Item7", "A6");
272                         CheckEngineEventCounts (testLogger, 1, 1, 4, 4);
273                 }
274
275                 [Test]
276                 public void TestConditionalBatching ()
277                 {
278                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
279                                 <ItemGroup>
280                                         <ResXFile Include=""Item1"">
281                                                 <Culture>fr</Culture>
282                                         </ResXFile>
283                                         <ResXFile Include=""Item2"">
284                                                 <Culture>fr</Culture>
285                                         </ResXFile>
286                                         <ResXFile Include=""Item3"">
287                                                 <Culture>en</Culture>
288                                         </ResXFile>
289                                         <ResXFile Include=""Item4"">
290                                                 <Culture>gb</Culture>
291                                         </ResXFile>
292                                         <ResXFile Include=""Item6"">
293                                                 <Culture>it</Culture>
294                                         </ResXFile>
295
296                                         <NonResXFile Include=""Item7"">
297                                                 <Culture>it</Culture>
298                                         </NonResXFile>
299                                         <NonResXFile Include=""Item8"">
300                                                 <Culture>en</Culture>
301                                         </NonResXFile>
302                                         <NonResXFile Include=""Item9"">
303                                                 <Culture>en</Culture>
304                                         </NonResXFile>
305                                 </ItemGroup>
306
307                                 <Target Name=""ShowMessage"">
308                                         <Message
309                                                 Text = ""ResXFiles: @(ResXFile) NonResXFiles: @(NonResXFile)""
310                                                 Condition = ""'%(Culture)' == 'fr'""/>
311                                 </Target>
312                           </Project>";
313
314                         Engine engine = new Engine (Consts.BinPath);
315                         Project project = engine.CreateNewProject ();
316
317                         TestMessageLogger testLogger = new TestMessageLogger ();
318                         engine.RegisterLogger (testLogger);
319
320                         project.LoadXml (projectString);
321                         Assert.IsTrue (project.Build ("ShowMessage"), "A1: Build failed");
322
323                         testLogger.CheckLoggedMessageHead ("ResXFiles: Item1;Item2 NonResXFiles: ", "A2");
324                         CheckEngineEventCounts (testLogger, 1, 1, 1, 1);
325                 }
326
327                 [Test]
328                 public void TestMultipleMetadataReference ()
329                 {
330                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
331                                 <ItemGroup>
332                                         <ExampColl Include=""Item1"">
333                                                 <Number>1</Number>
334                                         </ExampColl>
335                                         <ExampColl Include=""Item2"">
336                                                 <Number>2</Number>
337                                         </ExampColl>
338                                         <ExampColl Include=""Item3"">
339                                         <Number>1</Number>
340                                         </ExampColl>
341
342                                         <ExampColl2 Include=""Item4"">
343                                                 <Number>1</Number>
344                                         </ExampColl2>
345                                         <ExampColl2 Include=""Item5"">
346                                                 <Number>2</Number>
347                                         <Color>Red</Color>
348                                         </ExampColl2>
349                                         <ExampColl2 Include=""Item6"">
350                                                 <Number>3</Number>
351                                         <Color>Green</Color>
352                                         </ExampColl2>
353                                 </ItemGroup>
354                                 <Target Name=""ShowMessage"">
355                                         <Message Text = ""Number: %(Number) Color: %(ExampColl2.Color)-- Items in ExampColl: @(ExampColl) ExampColl2: @(ExampColl2)""/>
356                                 </Target>
357                         </Project>";
358
359                         Engine engine = new Engine (Consts.BinPath);
360                         Project project = engine.CreateNewProject ();
361
362                         TestMessageLogger testLogger = new TestMessageLogger ();
363                         engine.RegisterLogger (testLogger);
364
365                         project.LoadXml (projectString);
366                         Assert.IsTrue (project.Build ("ShowMessage"), "A1: Build failed");
367
368                         CheckLoggedMessageAny (testLogger, "Number: 1 Color: -- Items in ExampColl: Item1;Item3 ExampColl2: Item4", "A2");
369                         CheckLoggedMessageAny (testLogger, "Number: 2 Color: Red-- Items in ExampColl:  ExampColl2: Item5", "A3");
370                         CheckLoggedMessageAny (testLogger, "Number: 3 Color: Green-- Items in ExampColl:  ExampColl2: Item6", "A4");
371                         CheckLoggedMessageAny (testLogger, "Number: 2 Color: -- Items in ExampColl: Item2 ExampColl2: ", "A5");
372                         Assert.AreEqual (0, testLogger.Count, "A6");
373                         CheckEngineEventCounts (testLogger, 1, 1, 4, 4);
374                 }
375
376                 [Test]
377                 public void TestMultipleMetadataReference2 ()
378                 {
379                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
380                                 <ItemGroup>
381                                         <GroupA Include=""file1.txt""/>
382                                         <GroupA Include=""file2.txt""/>
383                                         <GroupA Include=""file3.txt""/>
384                                         <GroupA Include=""file3.txt""/>
385                                         <GroupA Include=""file4.txt""/>
386                                 </ItemGroup>
387
388                                 <ItemGroup>
389                                         <GroupB Include=""file1.txt""/>
390                                         <GroupB Include=""file3.txt""/>
391                                         <GroupB Include=""file5.txt""/>
392
393                                         <GroupC Include=""PreExistingValue""/>
394                                 </ItemGroup>
395
396                                 <Target Name=""Build"">
397                                         <CreateItem Include=""@(GroupA)"" Condition=""'%(Identity)' != '' and '@(GroupA)' != '' and '@(GroupB)' != ''"" >
398                                                 <Output TaskParameter=""Include"" ItemName=""GroupC""/>
399                                         </CreateItem>
400                                         <Message Text=""%(GroupC.Identity)""/>
401                                 </Target>
402                         </Project>";
403
404                         Engine engine = new Engine (Consts.BinPath);
405                         Project project = engine.CreateNewProject ();
406
407                         TestMessageLogger testLogger = new TestMessageLogger ();
408                         engine.RegisterLogger (testLogger);
409
410                         project.LoadXml (projectString);
411                         Assert.IsTrue (project.Build ("Build"), "A1: Build failed");
412
413                         BuildItemGroup include = project.GetEvaluatedItemsByName ("GroupC");
414                         Assert.AreEqual (4, include.Count, "A2");
415
416                         string [,] additional_metadata = new string [,] { { "Identity", "PreExistingValue" } };
417                         CreateItemTest.CheckBuildItem (include [0], "GroupC", additional_metadata, "PreExistingValue", "A3");
418
419                         additional_metadata = new string [,] { { "Identity", "file1.txt" } };
420                         CreateItemTest.CheckBuildItem (include [1], "GroupC", additional_metadata, "file1.txt", "A4");
421
422                         additional_metadata = new string [,] { { "Identity", "file3.txt" } };
423                         CreateItemTest.CheckBuildItem (include [2], "GroupC", additional_metadata, "file3.txt", "A5");
424                         CreateItemTest.CheckBuildItem (include [3], "GroupC", additional_metadata, "file3.txt", "A6");
425
426                         CheckEngineEventCounts (testLogger, 1, 1, 5, 5);
427                 }
428
429                 [Test]
430                 public void TestIdentity ()
431                 {
432                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
433                                 <ItemGroup>
434                                         <ExampColl Include=""Item1""/>
435                                         <ExampColl Include=""Item2""/>
436                                         <ExampColl Include=""Item3""/>
437                                         <ExampColl Include=""Item4""/>
438                                         <ExampColl Include=""Item4""/>
439                                         <ExampColl Include=""Item5""/>
440                                         <ExampColl Include=""Item6""/>
441                                 </ItemGroup>
442                                 <Target Name=""ShowMessage"">
443                                         <Message Text = ""Identity: %(IdenTIty) -- Items in ExampColl: @(ExampColl)""/>
444                                 </Target>
445                         </Project>";
446
447                         Engine engine = new Engine (Consts.BinPath);
448                         Project project = engine.CreateNewProject ();
449
450                         TestMessageLogger testLogger = new TestMessageLogger ();
451                         engine.RegisterLogger (testLogger);
452
453                         project.LoadXml (projectString);
454                         Assert.IsTrue (project.Build ("ShowMessage"), "A1: Build failed");
455
456                         CheckLoggedMessageAny (testLogger, "Identity: Item1 -- Items in ExampColl: Item1", "A2");
457                         CheckLoggedMessageAny (testLogger, "Identity: Item2 -- Items in ExampColl: Item2", "A3");
458                         CheckLoggedMessageAny (testLogger, "Identity: Item3 -- Items in ExampColl: Item3", "A4");
459                         CheckLoggedMessageAny (testLogger, "Identity: Item4 -- Items in ExampColl: Item4;Item4", "A5");
460                         CheckLoggedMessageAny (testLogger, "Identity: Item5 -- Items in ExampColl: Item5", "A6");
461                         CheckLoggedMessageAny (testLogger, "Identity: Item6 -- Items in ExampColl: Item6", "A7");
462                         Assert.AreEqual (0, testLogger.Count, "A8");
463                         CheckEngineEventCounts (testLogger, 1, 1, 6, 6);
464                 }
465
466                 [Test]
467                 public void TestFilter ()
468                 {
469                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
470                                  <ItemGroup>
471                                          <fruit Include=""apple"">
472                                                  <consistency>firm</consistency>
473                                          </fruit>
474                                          <fruit Include=""orange"">
475                                                  <consistency>pulpy</consistency>
476                                          </fruit>
477                                          <fruit Include=""banana"">
478                                                  <consistency>softish</consistency>
479                                          </fruit>
480                                          <fruit Include=""pear"">
481                                                  <consistency>unsound</consistency>
482                                          </fruit>
483                                          <fruit Include=""apricot"">
484                                                  <consistency>unsound</consistency>
485                                          </fruit>
486                                  </ItemGroup>
487                                  <Target Name=""Compost"">
488                                          <CreateItem Include=""@(fruit)"" Condition=""'%(consistency)' == 'pulpy' or '%(consistency)' == 'unsound' "">
489                                                 <Output TaskParameter=""Include"" ItemName=""Final""/>
490                                          </CreateItem>
491                                  </Target>
492                          </Project>";
493
494                         Engine engine = new Engine (Consts.BinPath);
495                         Project project = engine.CreateNewProject ();
496
497                         TestMessageLogger testLogger = new TestMessageLogger ();
498                         engine.RegisterLogger (testLogger);
499
500                         project.LoadXml (projectString);
501                         Assert.IsTrue (project.Build ("Compost"), "A1: Build failed");
502
503                         BuildItemGroup include = project.GetEvaluatedItemsByName ("Final");
504                         Assert.AreEqual (3, include.Count, "A2");
505
506                         string [,] additional_metadata = new string [,] { { "Identity", "orange" } };
507                         CreateItemTest.CheckBuildItem (include [0], "Final", additional_metadata, "orange", "A3");
508
509                         additional_metadata = new string [,] { { "Identity", "pear" } };
510                         CreateItemTest.CheckBuildItem (include [1], "Final", additional_metadata, "pear", "A4");
511
512                         additional_metadata = new string [,] { { "Identity", "apricot" } };
513                         CreateItemTest.CheckBuildItem (include [2], "Final", additional_metadata, "apricot", "A5");
514                         CheckEngineEventCounts (testLogger, 1, 1, 2, 2);
515                 }
516
517                 [Test]
518                 // test for metadata refs in properties or items
519                 public void TestNoBatching () {
520                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
521         <ItemGroup>
522                 <item3 Include=""foo""/>
523                 <item2 Include=""%(item3.Identity)""/>
524                 <item0 Include=""@(item3)""/>
525         </ItemGroup>
526         <PropertyGroup>
527                 <Prop1>%(item0.Identity)</Prop1>
528         </PropertyGroup>
529         <Target Name='1'>
530                 <Message Text=""Prop1: $(Prop1)""/>
531                 <Message Text=""Item2: @(item2)""/>
532         </Target>
533 </Project>";
534
535                         Engine engine = new Engine (Consts.BinPath);
536                         Project project = engine.CreateNewProject ();
537
538                         TestMessageLogger testLogger = new TestMessageLogger ();
539                         engine.RegisterLogger (testLogger);
540
541                         project.LoadXml (projectString);
542                         if (!project.Build ("1")) {
543                                 testLogger.DumpMessages ();
544                                 Assert.Fail ("Build failed");
545                         }
546
547                         testLogger.CheckLoggedMessageHead ("Prop1: %(item0.Identity)", "A1");
548                         testLogger.CheckLoggedMessageHead ("Item2: %(item3.Identity)", "A2");
549                         Assert.AreEqual (0, testLogger.NormalMessageCount, "Unexpected extra messages found");
550                 }
551
552                 [Test]
553                 // test for metadata refs via metadata refs
554                 // batching should happen only on basis of the task attributes,
555                 // and not the resolved expression values
556                 public void TestBatching1 () {
557                         string projectString = projectHeader + @"
558         <ItemGroup>
559                 <item3 Include=""foo""/>
560                 <item2 Include=""%(item3.Identity)""/>
561
562                 <item4 Include=""%(item2.Identity);@(item3);@(nonexistant)""/>
563                 <item4 Include=""bar""/>
564         </ItemGroup>
565         <Target Name='1'>
566                 <Message Text=""Item4: %(item4.Identity)""/>
567         </Target>
568 </Project>";
569
570                         Engine engine = new Engine (Consts.BinPath);
571                         Project project = engine.CreateNewProject ();
572
573                         TestMessageLogger testLogger = new TestMessageLogger ();
574                         engine.RegisterLogger (testLogger);
575
576                         project.LoadXml (projectString);
577                         if (!project.Build ("1")) {
578                                 testLogger.DumpMessages ();
579                                 Assert.Fail ("Build failed");
580                         }
581
582                         testLogger.CheckLoggedMessageHead ("Item4: %(item2.Identity)", "A1");
583                         testLogger.CheckLoggedMessageHead ("Item4: foo", "A2");
584                         testLogger.CheckLoggedMessageHead ("Item4: bar", "A3");
585                         Assert.AreEqual (0, testLogger.NormalMessageCount, "Unexpected extra messages found");
586                 }
587
588                 [Test]
589                 // test for metadata refs via metadata refs
590                 // batching should happen only on basis of the task attributes,
591                 // and not the resolved expression values
592                 public void TestConditionalBatching2 () {
593                         string projectString = projectHeader + @"
594         <ItemGroup>
595                 <item2 Include=""%(item3.Identity)""/>
596                 <item4 Include=""%(item2.Identity);@(item3)""/>
597         </ItemGroup>
598         <Target Name='1'>
599                 <Message Text=""Item3: %(item2.Identity)"" Condition="" '%(item5.Identity)' == '' ""/>
600                 <Message Text=""Item4: %(item4.Identity)""/>
601         </Target>
602 </Project>";
603
604                         Engine engine = new Engine (Consts.BinPath);
605                         Project project = engine.CreateNewProject ();
606
607                         TestMessageLogger testLogger = new TestMessageLogger ();
608                         engine.RegisterLogger (testLogger);
609
610                         project.LoadXml (projectString);
611                         if (!project.Build ("1")) {
612                                 testLogger.DumpMessages ();
613                                 Assert.Fail ("Build failed");
614                         }
615
616                         testLogger.CheckLoggedMessageHead ("Item3: %(item3.Identity)", "A1");
617                         testLogger.CheckLoggedMessageHead ("Item4: %(item2.Identity)", "A2");
618                         Assert.AreEqual (0, testLogger.NormalMessageCount, "Unexpected extra messages found");
619                 }
620
621                 [Test]
622                 public void TestBatchingWithUnbatchedItems () {
623                         string projectString = projectHeader + @"
624         <ItemGroup>
625                 <Item1 Include=""One""/>
626                 <Item1 Include=""Two""/>
627
628                 <B Include=""abc""/>
629         </ItemGroup>
630         <Target Name='1'>
631                 <Message Text=""Item1: %(Item1.Identity) | B: @(B)""/>
632         </Target>
633 </Project>";
634
635                         Engine engine = new Engine (Consts.BinPath);
636                         Project project = engine.CreateNewProject ();
637
638                         TestMessageLogger testLogger = new TestMessageLogger ();
639                         engine.RegisterLogger (testLogger);
640
641                         project.LoadXml (projectString);
642                         if (!project.Build ("1")) {
643                                 testLogger.DumpMessages ();
644                                 Assert.Fail ("Build failed");
645                         }
646
647                         try {
648                                 testLogger.CheckLoggedMessageHead ("Item1: One | B: abc", "A1");
649                                 testLogger.CheckLoggedMessageHead ("Item1: Two | B: abc", "A2");
650
651                                 Assert.AreEqual (0, testLogger.NormalMessageCount, "Unexpected extra messages found");
652                         } catch (AssertionException) {
653                                 testLogger.DumpMessages ();
654                                 throw;
655                         }
656                 }
657
658                 [Test]
659                 public void TestPropertiesWithBatchedReferences () {
660                         string projectString = projectHeader + @"
661         <ItemGroup>
662                 <Item1 Include=""One""/>
663                 <Item1 Include=""Two""/>
664
665                 <Item1Ref Include=""@(Item1)""/>
666         </ItemGroup>
667         <PropertyGroup>
668                 <Prop1>@(Item1)</Prop1>
669                 <Prop2>@(Item1Ref)</Prop2>
670         </PropertyGroup>
671         <Target Name='1'>
672                 <Message Text=""Item1: %(Item1.Identity) | Prop1: $(Prop1) | Prop2: $(Prop2)""/>
673         </Target>
674 </Project>";
675
676                         Engine engine = new Engine (Consts.BinPath);
677                         Project project = engine.CreateNewProject ();
678
679                         TestMessageLogger testLogger = new TestMessageLogger ();
680                         engine.RegisterLogger (testLogger);
681
682                         project.LoadXml (projectString);
683                         if (!project.Build ("1")) {
684
685                                 testLogger.DumpMessages ();
686                                 Assert.Fail ("Build failed");
687                         }
688
689                         try {
690                                 testLogger.CheckLoggedMessageHead ("Item1: One | Prop1: One | Prop2: One;Two", "A1");
691                                 testLogger.CheckLoggedMessageHead ("Item1: Two | Prop1: Two | Prop2: One;Two", "A2");
692
693                                 Assert.AreEqual (0, testLogger.NormalMessageCount, "Unexpected extra messages found");
694                         } catch (AssertionException) {
695                                 testLogger.DumpMessages ();
696                                 throw;
697                         }
698                 }
699
700                 [Test]
701                 public void TestPropertiesWithDynamicItems () {
702                         string projectString = projectHeader + @"
703         <ItemGroup>
704                 <Item1 Include=""One""/>
705                 <Item1 Include=""Two""/>
706
707                 <Item2 Include=""Z""/>
708                 <Item2Ref Include=""@(Item2)"" />
709         </ItemGroup>
710         <PropertyGroup>
711                 <Prop1>@(Item2)</Prop1>
712                 <Prop2>@(Item2Ref)</Prop2>
713         </PropertyGroup>
714         <Target Name='1'>
715                 <Message Text=""Item1: %(Item1.Identity) | Prop1: $(Prop1) | Prop2: $(Prop2)""/>
716                 <Message Text=""Item2: @(Item2) | Item2Ref: @(Item2Ref)""/>
717                 <CreateItem Include=""A;B"">
718                         <Output TaskParameter=""Include"" ItemName=""Item2""/>
719                 </CreateItem>
720                 <Message Text=""Item1: %(Item1.Identity) | Prop1: $(Prop1) | Prop2: $(Prop2)""/>
721                 <Message Text=""Item2: @(Item2) | Item2Ref: @(Item2Ref)""/>
722         </Target>
723 </Project>";
724
725                         Engine engine = new Engine (Consts.BinPath);
726                         Project project = engine.CreateNewProject ();
727
728                         TestMessageLogger testLogger = new TestMessageLogger ();
729                         engine.RegisterLogger (testLogger);
730
731                         project.LoadXml (projectString);
732                         if (!project.Build ("1")) {
733
734                                 testLogger.DumpMessages ();
735                                 Assert.Fail ("Build failed");
736                         }
737
738                         try {
739
740                                 testLogger.CheckLoggedMessageHead ("Item1: One | Prop1: Z | Prop2: Z", "A1");
741                                 testLogger.CheckLoggedMessageHead ("Item1: Two | Prop1: Z | Prop2: Z", "A2");
742                                 testLogger.CheckLoggedMessageHead ("Item2: Z | Item2Ref: Z", "A3");
743
744                                 testLogger.CheckLoggedMessageHead ("Item1: One | Prop1: Z;A;B | Prop2: Z", "A4");
745                                 testLogger.CheckLoggedMessageHead ("Item1: Two | Prop1: Z;A;B | Prop2: Z", "A5");
746                                 testLogger.CheckLoggedMessageHead ("Item2: Z;A;B | Item2Ref: Z", "A3");
747
748                                 Assert.AreEqual (0, testLogger.NormalMessageCount, "Unexpected extra messages found");
749                         } catch (AssertionException) {
750                                 testLogger.DumpMessages ();
751                                 throw;
752                         }
753                 }
754
755                 [Test]
756                 public void TestTargetInvocationFromBatchedTask () {
757                         string projectString = projectHeader + @"
758         <ItemGroup>
759                 <Item1 Include=""One""/>
760                 <Item1 Include=""Two""/>
761
762                 <Item1Ref Include=""@(Item1)"" />
763         </ItemGroup>
764         <PropertyGroup>
765                 <Prop1>@(Item1)</Prop1>
766                 <Prop2>@(Item1Ref)</Prop2>
767         </PropertyGroup>
768         <Target Name='1'>
769                 <CallTarget Targets='foo' Condition="" '%(Item1.Identity)' != ''"" />
770                 <Message Text=""Item1: @(Item1) Item1Ref: @(Item1Ref)""/>
771                 <Message Text=""Prop1: $(Prop1) Prop2: $(Prop2)""/>
772         </Target>
773         <Target Name='foo'>
774                 <Message Text=""(foo) Item1: @(Item1) Item1Ref: @(Item1Ref)""/>
775                 <Message Text=""(foo) Prop1: $(Prop1) Prop2: $(Prop2)""/>
776         </Target>
777 </Project>";
778
779                         Engine engine = new Engine (Consts.BinPath);
780                         Project project = engine.CreateNewProject ();
781
782                         TestMessageLogger testLogger = new TestMessageLogger ();
783                         engine.RegisterLogger (testLogger);
784
785                         project.LoadXml (projectString);
786                         if (!project.Build ("1")) {
787
788                                 testLogger.DumpMessages ();
789                                 Assert.Fail ("Build failed");
790                         }
791
792                         try {
793                                 testLogger.CheckLoggedMessageHead ("(foo) Item1: One;Two Item1Ref: One;Two", "A1");
794                                 testLogger.CheckLoggedMessageHead ("(foo) Prop1: One;Two Prop2: One;Two", "A2");
795
796                                 testLogger.CheckLoggedMessageHead ("Item1: One;Two Item1Ref: One;Two", "A3");
797                                 testLogger.CheckLoggedMessageHead ("Prop1: One;Two Prop2: One;Two", "A4");
798
799                                 Assert.AreEqual (0, testLogger.NormalMessageCount, "Unexpected extra messages found");
800                         } catch (AssertionException) {
801                                 testLogger.DumpMessages ();
802                                 throw;
803                         }
804                 }
805
806                 [Test]
807                 public void TestTargetInvocationFromBatchedTarget () {
808                         string projectString = projectHeader + @"
809         <ItemGroup>
810                 <Item1 Include=""One""/>
811                 <Item1 Include=""Two""/>
812
813                 <Item1Ref Include=""@(Item1)"" />
814         </ItemGroup>
815         <PropertyGroup>
816                 <Prop1>@(Item1)</Prop1>
817                 <Prop2>@(Item1Ref)</Prop2>
818         </PropertyGroup>
819         <Target Name='1' Inputs=""%(Item1.Identity)"" Outputs=""Nonexistant.foobar"">
820                 <Message Text=""Item1: @(Item1) Item1Ref: @(Item1Ref)""/>
821                 <Message Text=""Prop1: $(Prop1) Prop2: $(Prop2)""/>
822
823                 <CallTarget Targets='foo' />
824
825                 <Message Text=""Item1: @(Item1) Item1Ref: @(Item1Ref)""/>
826                 <Message Text=""Prop1: $(Prop1) Prop2: $(Prop2)""/>
827         </Target>
828         <Target Name='foo' Condition="" '@(Item1)' != 'One' "">
829                 <Message Text=""(foo) Item1: @(Item1) Item1Ref: @(Item1Ref)""/>
830                 <Message Text=""(foo) Prop1: $(Prop1) Prop2: $(Prop2)""/>
831         </Target>
832 </Project>";
833
834                         Engine engine = new Engine (Consts.BinPath);
835                         Project project = engine.CreateNewProject ();
836
837                         TestMessageLogger testLogger = new TestMessageLogger ();
838                         engine.RegisterLogger (testLogger);
839
840                         project.LoadXml (projectString);
841                         if (!project.Build ("1")) {
842
843                                 testLogger.DumpMessages ();
844                                 Assert.Fail ("Build failed");
845                         }
846
847                         try {
848                                 testLogger.CheckLoggedMessageHead ("Item1: One Item1Ref: One;Two", "A1");
849                                 testLogger.CheckLoggedMessageHead ("Prop1: One Prop2: One;Two", "A2");
850
851                                 testLogger.CheckLoggedMessageHead ("(foo) Item1: One;Two Item1Ref: One;Two", "A3");
852                                 testLogger.CheckLoggedMessageHead ("(foo) Prop1: One;Two Prop2: One;Two", "A4");
853
854                                 testLogger.CheckLoggedMessageHead ("Item1: One Item1Ref: One;Two", "A5");
855                                 testLogger.CheckLoggedMessageHead ("Prop1: One Prop2: One;Two", "A6");
856
857                                 //second batch, foo has already run, so doesn't execute again
858                                 testLogger.CheckLoggedMessageHead ("Item1: Two Item1Ref: One;Two", "A7");
859                                 testLogger.CheckLoggedMessageHead ("Prop1: Two Prop2: One;Two", "A8");
860
861                                 testLogger.CheckLoggedMessageHead ("Item1: Two Item1Ref: One;Two", "A9");
862                                 testLogger.CheckLoggedMessageHead ("Prop1: Two Prop2: One;Two", "A10");
863
864                                 Assert.AreEqual (0, testLogger.NormalMessageCount, "Unexpected extra messages found");
865                         } catch (AssertionException) {
866                                 testLogger.DumpMessages ();
867                                 throw;
868                         }
869                 }
870
871                 [Test]
872                 public void TestBatchingWithUnqualifiedMetadataReference () {
873                         string projectString = projectHeader + @"
874         <ItemGroup>
875                 <Item1 Include=""One""><Md>1</Md></Item1>
876                 <Item1 Include=""Two""><Md>2</Md></Item1>
877                 <Item1Ref Include=""@(Item1)"" />
878
879                 <Item2 Include=""Three""><Md>3</Md></Item2>
880                 <Item2 Include=""Four""><Md>4</Md></Item2>
881                 <Item2Ref Include=""@(Item2)"" />
882         </ItemGroup>
883         <PropertyGroup>
884                 <Prop1>@(Item1)</Prop1>
885                 <Prop1Ref>@(Item1Ref)</Prop1Ref>
886
887                 <Prop2>@(Item2)</Prop2>
888                 <Prop2Ref>@(Item2Ref)</Prop2Ref>
889         </PropertyGroup>
890         <Target Name='1'>
891                 <Message Text=""For md: %(Md) Item1: @(Item1) Item1Ref: @(Item1Ref) Item2: @(Item2) Item2Ref: @(Item2Ref) " +
892                                           @" Prop1: $(Prop1) Prop1Ref: $(Prop1Ref) Prop2: $(Prop2) Prop2Ref: $(Prop2Ref)""/>
893         </Target>
894 </Project>";
895
896                         Engine engine = new Engine (Consts.BinPath);
897                         Project project = engine.CreateNewProject ();
898
899                         TestMessageLogger testLogger = new TestMessageLogger ();
900                         engine.RegisterLogger (testLogger);
901
902                         project.LoadXml (projectString);
903                         if (!project.Build ("1")) {
904
905                                 testLogger.DumpMessages ();
906                                 Assert.Fail ("Build failed");
907                         }
908
909                         try {
910                                 testLogger.CheckLoggedAny ("For md: 3 Item1:  Item1Ref:  Item2: Three Item2Ref: Three  Prop1:  Prop1Ref:  Prop2: Three Prop2Ref: Three", MessageImportance.Normal, "A1");
911                                 testLogger.CheckLoggedAny ("For md: 4 Item1:  Item1Ref:  Item2: Four Item2Ref: Four  Prop1:  Prop1Ref:  Prop2: Four Prop2Ref: Four", MessageImportance.Normal, "A2");
912                                 testLogger.CheckLoggedAny ("For md: 1 Item1: One Item1Ref: One Item2:  Item2Ref:   Prop1: One Prop1Ref: One Prop2:  Prop2Ref: ", MessageImportance.Normal, "A3");
913                                 testLogger.CheckLoggedAny ("For md: 2 Item1: Two Item1Ref: Two Item2:  Item2Ref:   Prop1: Two Prop1Ref: Two Prop2:  Prop2Ref: ", MessageImportance.Normal, "A4");
914
915                                 Assert.AreEqual (0, testLogger.NormalMessageCount, "Unexpected extra messages found");
916                         } catch (AssertionException) {
917                                 testLogger.DumpMessages ();
918                                 throw;
919                         }
920                 }
921
922
923                 //Target batching
924
925                 [Test]
926                 public void TestTargetBatching1 ()
927                 {
928                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
929                                 <ItemGroup>
930                                         <List1 Include=""fr_a.txt""><Culture>fr</Culture></List1>
931                                         <List1 Include=""en_b.txt""><Culture>en</Culture></List1>
932                                         <List1 Include=""fr_c.txt""><Culture>fr</Culture></List1>
933                                         <List1 Include=""gb_d.txt""><Culture>gb</Culture></List1>
934
935                                         <List2 Include=""fr_x.txt""><Culture>fr</Culture></List2>
936                                         <List2 Include=""gb_z.txt""><Culture>gb</Culture></List2>
937
938                                         <Foo Include=""1_a1""><Md>1</Md></Foo>
939                                         <Foo Include=""2_b1""><Md>2</Md></Foo>
940                                         <Foo Include=""1_c1""><Md>1</Md></Foo>
941                                 </ItemGroup>
942
943                                 <Target Name=""foo"" >
944                                         <Message Text=""TargetStarted""/>
945                                         <Message Text=""List1: @(List1): %(Culture)""/>
946                                         <Message Text=""Foo: @(Foo): %(Md)""/>
947                                 </Target>
948                 </Project>";
949
950                         Engine engine = new Engine (Consts.BinPath);
951                         Project project = engine.CreateNewProject ();
952
953                         TestMessageLogger testLogger = new TestMessageLogger ();
954                         engine.RegisterLogger (testLogger);
955
956                         project.LoadXml (projectString);
957                         bool res = project.Build ("foo");
958                         if (!res) {
959                                 testLogger.DumpMessages ();
960                                 Assert.Fail ("A1: Build failed");
961                         }
962
963                         CheckLoggedMessagesInOrder (testLogger, new string [] {
964                                 "TargetStarted", "List1: fr_a.txt;fr_c.txt: fr",
965                                 "List1: en_b.txt: en", "List1: gb_d.txt: gb",
966                                 "Foo: 1_a1;1_c1: 1", "Foo: 2_b1: 2"
967                         }, "A2");
968                         CheckEngineEventCounts (testLogger, 1, 1, 6, 6);
969                 }
970
971                 [Test]
972                 public void TestTargetBatching2 ()
973                 {
974                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
975                                 <ItemGroup>
976                                         <List1 Include=""fr_a.txt""><Culture>fr</Culture></List1>
977                                         <List1 Include=""en_b.txt""><Culture>en</Culture></List1>
978                                         <List1 Include=""fr_c.txt""><Culture>fr</Culture></List1>
979                                         <List1 Include=""gb_d.txt""><Culture>gb</Culture></List1>
980
981                                         <List2 Include=""fr_x.txt""><Culture>fr</Culture></List2>
982                                         <List2 Include=""gb_z.txt""><Culture>gb</Culture></List2>
983
984                                         <Foo Include=""1_a1""><Md>1</Md></Foo>
985                                         <Foo Include=""2_b1""><Md>2</Md></Foo>
986                                         <Foo Include=""1_c1""><Md>1</Md></Foo>
987                                 </ItemGroup>
988
989                                 <Target Name=""foo"" Inputs=""@(List1)"" Outputs=""%(Culture).foo"">
990                                         <Message Text=""TargetStarted""/>
991                                         <Message Text=""List1: @(List1): %(Culture)""/>
992                                         <Message Text=""Foo: @(Foo): %(Md)""/>
993                                 </Target>
994                 </Project>";
995
996                         Engine engine = new Engine (Consts.BinPath);
997                         Project project = engine.CreateNewProject ();
998
999                         TestMessageLogger testLogger = new TestMessageLogger ();
1000                         engine.RegisterLogger (testLogger);
1001
1002                         project.LoadXml (projectString);
1003                         bool res = project.Build ("foo");
1004                         if (!res) {
1005                                 testLogger.DumpMessages ();
1006                                 Assert.Fail ("A1: Build failed");
1007                         }
1008
1009                         CheckLoggedMessagesInOrder (testLogger, new string [] {
1010                                 "TargetStarted", "List1: fr_a.txt;fr_c.txt: fr",
1011                                 "Foo: 1_a1;1_c1: 1", "Foo: 2_b1: 2",
1012
1013                                 "TargetStarted", "List1: en_b.txt: en",
1014                                 "Foo: 1_a1;1_c1: 1", "Foo: 2_b1: 2",
1015
1016                                 "TargetStarted", "List1: gb_d.txt: gb",
1017                                 "Foo: 1_a1;1_c1: 1", "Foo: 2_b1: 2"
1018                         }, "A2");
1019                         CheckEngineEventCounts (testLogger, 3, 3, 12, 12);
1020                 }
1021
1022                 [Test]
1023                 public void TestTargetBatching3 ()
1024                 {
1025                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1026                                 <ItemGroup>
1027                                         <List1 Include=""fr_a.txt""><Culture>fr</Culture></List1>
1028                                         <List1 Include=""en_b.txt""><Culture>en</Culture></List1>
1029                                         <List1 Include=""fr_c.txt""><Culture>fr</Culture></List1>
1030                                         <List1 Include=""gb_d.txt""><Culture>gb</Culture></List1>
1031
1032                                         <List2 Include=""fr_x.txt""><Culture>fr</Culture></List2>
1033                                         <List2 Include=""gb_z.txt""><Culture>gb</Culture></List2>
1034
1035                                         <Foo Include=""1_a1""><Md>1</Md></Foo>
1036                                         <Foo Include=""2_b1""><Md>2</Md></Foo>
1037                                         <Foo Include=""1_c1""><Md>1</Md></Foo>
1038                                 </ItemGroup>
1039                                 <Target Name=""foo"" Inputs=""@(Foo)"" Outputs=""%(Md).foo"">
1040                                         <Message Text=""TargetStarted""/>
1041                                         <Message Text=""List1: @(List1): %(Culture)""/>
1042                                         <Message Text=""Foo: @(Foo): %(Md)""/>
1043                                 </Target>
1044                 </Project>";
1045
1046                         Engine engine = new Engine (Consts.BinPath);
1047                         Project project = engine.CreateNewProject ();
1048
1049                         TestMessageLogger testLogger = new TestMessageLogger ();
1050                         engine.RegisterLogger (testLogger);
1051
1052                         project.LoadXml (projectString);
1053                         bool res = project.Build ("foo");
1054                         if (!res) {
1055                                 testLogger.DumpMessages ();
1056                                 Assert.Fail ("A1: Build failed");
1057                         }
1058
1059                         CheckLoggedMessagesInOrder (testLogger, new string [] {
1060                                 "TargetStarted", "List1: fr_a.txt;fr_c.txt: fr",
1061                                 "List1: en_b.txt: en", "List1: gb_d.txt: gb",
1062                                 "Foo: 1_a1;1_c1: 1",
1063                                 "TargetStarted", "List1: fr_a.txt;fr_c.txt: fr",
1064                                 "List1: en_b.txt: en", "List1: gb_d.txt: gb",
1065                                 "Foo: 2_b1: 2"
1066                         }, "A2");
1067                         CheckEngineEventCounts (testLogger, 2, 2, 10, 10);
1068                 }
1069
1070                 [Test]
1071                 public void TestTargetBatching4 ()
1072                 {
1073                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1074                                 <ItemGroup>
1075                                         <List1 Include=""fr_a.txt""><Culture>fr</Culture></List1>
1076                                         <List1 Include=""en_b.txt""><Culture>en</Culture></List1>
1077                                         <List1 Include=""fr_c.txt""><Culture>fr</Culture></List1>
1078                                         <List1 Include=""gb_d.txt""><Culture>gb</Culture></List1>
1079
1080                                         <List2 Include=""fr_x.txt""><Culture>fr</Culture></List2>
1081                                         <List2 Include=""gb_z.txt""><Culture>gb</Culture></List2>
1082
1083                                         <Foo Include=""1_a1""><Md>1</Md></Foo>
1084                                         <Foo Include=""2_b1""><Md>2</Md></Foo>
1085                                         <Foo Include=""1_c1""><Md>1</Md></Foo>
1086                                 </ItemGroup>
1087                                 <Target Name=""foo"" Inputs=""@(List1)"" Outputs=""%(Culture).foo"">
1088                                         <Message Text=""TargetStarted""/>
1089                                         <Message Text=""List1: @(List1): %(Culture)""/>
1090                                         <Message Text=""List2: @(List2): %(Culture)""/>
1091                                         <Message Text=""Foo: @(Foo): %(Md)""/>
1092                                 </Target>
1093                 </Project>";
1094
1095                         Engine engine = new Engine (Consts.BinPath);
1096                         Project project = engine.CreateNewProject ();
1097
1098                         TestMessageLogger testLogger = new TestMessageLogger ();
1099                         engine.RegisterLogger (testLogger);
1100
1101                         project.LoadXml (projectString);
1102                         bool res = project.Build ("foo");
1103                         if (!res) {
1104                                 testLogger.DumpMessages ();
1105                                 Assert.Fail ("A1: Build failed");
1106                         }
1107
1108                         CheckLoggedMessagesInOrder (testLogger, new string [] {
1109                                 "TargetStarted", "List1: fr_a.txt;fr_c.txt: fr",
1110                                 "List2: fr_x.txt: fr", "List2: gb_z.txt: gb",
1111                                 "Foo: 1_a1;1_c1: 1", "Foo: 2_b1: 2",
1112
1113                                 "TargetStarted", "List1: en_b.txt: en",
1114                                 "List2: fr_x.txt: fr", "List2: gb_z.txt: gb",
1115                                 "Foo: 1_a1;1_c1: 1", "Foo: 2_b1: 2",
1116
1117                                 "TargetStarted", "List1: gb_d.txt: gb",
1118                                 "List2: fr_x.txt: fr", "List2: gb_z.txt: gb",
1119                                 "Foo: 1_a1;1_c1: 1", "Foo: 2_b1: 2"
1120                         }, "A2");
1121                         CheckEngineEventCounts (testLogger, 3, 3, 18, 18);
1122                 }
1123
1124                 [Test]
1125                 public void TestTargetBatching5 ()
1126                 {
1127                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1128                                 <Target Name=""foo"" Inputs=""@(List1)"" Outputs=""%(Culture).foo"">
1129                                         <Message Text=""TargetStarted""/>
1130                                 </Target>
1131                         </Project>";
1132
1133                         Engine engine = new Engine (Consts.BinPath);
1134                         Project project = engine.CreateNewProject ();
1135
1136                         TestMessageLogger testLogger = new TestMessageLogger ();
1137                         engine.RegisterLogger (testLogger);
1138
1139                         project.LoadXml (projectString);
1140                         bool res = project.Build ("foo");
1141                         if (!res) {
1142                                 testLogger.DumpMessages ();
1143                                 Assert.Fail ("A1: Build failed");
1144                         }
1145                         Assert.AreEqual (1, testLogger.CheckAny ("TargetStarted", MessageImportance.Normal),
1146                                 "A2: Target should've been skipped because of no inputs");
1147                         CheckEngineEventCounts (testLogger, 1, 1, 0, 0);
1148                 }
1149
1150                 [Test]
1151                 public void TestTargetBatching6 ()
1152                 {
1153                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1154                                 <ItemGroup>
1155                                         <List1 Include=""fr_a.txt""><Culture>fr</Culture></List1>
1156                                         <List1 Include=""en_b.txt""><Culture>en</Culture></List1>
1157                                         <List1 Include=""fr_c.txt""><Culture>fr</Culture></List1>
1158                                         <List1 Include=""gb_d.txt""><Culture>gb</Culture></List1>
1159
1160                                         <List3 Include=""fr_x.txt""><Culture>fr</Culture></List3>
1161                                         <List3 Include=""gb_z.txt""><Culture>gb</Culture></List3>
1162
1163                                         <Foo Include=""1_a1""><Md>1</Md></Foo>
1164                                         <Foo Include=""2_b1""><Md>2</Md></Foo>
1165                                         <Foo Include=""1_c1""><Md>1</Md></Foo>
1166                                 </ItemGroup>
1167
1168                                 <Target Name=""foo"" Inputs=""@(List1);@(List2)"" Outputs=""%(Culture).foo"">
1169                                         <Message Text=""TargetStarted"" />
1170                                         <Message Text=""List1: %(List1.Culture), List2: %(List2.Culture)"" />
1171                                         <Message Text=""List2: @(List2), Culture: %(Culture)"" />
1172                                         <Message Text=""List3: @(List3), Culture: %(Culture)"" />
1173                                 </Target>
1174                         </Project>";
1175
1176                         Engine engine = new Engine (Consts.BinPath);
1177                         Project project = engine.CreateNewProject ();
1178
1179                         TestMessageLogger testLogger = new TestMessageLogger ();
1180                         engine.RegisterLogger (testLogger);
1181
1182                         project.LoadXml (projectString);
1183                         bool res = project.Build ("foo");
1184                         if (!res) {
1185                                 testLogger.DumpMessages ();
1186                                 Assert.Fail ("A1: Build failed");
1187                         }
1188
1189                         CheckLoggedMessagesInOrder (testLogger, new string [] {
1190                                 "TargetStarted",
1191                                 "List1: fr, List2: ",
1192                                 "List2: , Culture: ",
1193                                 "List3: fr_x.txt, Culture: fr",
1194                                 "List3: gb_z.txt, Culture: gb",
1195
1196                                 "TargetStarted",
1197                                 "List1: en, List2: ",
1198                                 "List2: , Culture: ",
1199                                 "List3: fr_x.txt, Culture: fr",
1200                                 "List3: gb_z.txt, Culture: gb",
1201
1202                                 "TargetStarted",
1203                                 "List1: gb, List2: ",
1204                                 "List2: , Culture: ",
1205                                 "List3: fr_x.txt, Culture: fr",
1206                                 "List3: gb_z.txt, Culture: gb"
1207                         }, "A2");
1208                         CheckEngineEventCounts (testLogger, 3, 3, 15, 15);
1209                 }
1210
1211                 [Test]
1212                 public void TestTargetBatching7 ()
1213                 {
1214                         string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1215                                 <ItemGroup>
1216                                         <List1 Include=""fr_a.txt""><Culture>fr</Culture></List1>
1217                                         <List1 Include=""en_b.txt""><Culture>en</Culture></List1>
1218                                         <List1 Include=""fr_c.txt""><Culture>fr</Culture></List1>
1219                                         <List1 Include=""gb_d.txt""><Culture>gb</Culture></List1>
1220
1221                                         <List2 Include=""fr_x.txt""><Culture>fr</Culture></List2>
1222                                         <List2 Include=""gb_z.txt""><Culture>gb</Culture></List2>
1223
1224                                         <Foo Include=""1_a1""><Md>1</Md></Foo>
1225                                         <Foo Include=""2_b1""><Md>2</Md></Foo>
1226                                         <Foo Include=""1_c1""><Md>1</Md></Foo>
1227                                 </ItemGroup>
1228
1229                                 <Target Name=""foo"" Inputs=""@(List1);@(List2)"" Outputs=""%(Culture).foo"">
1230                                         <Message Text=""TargetStarted"" />
1231                                         <Message Text=""List1: @(List1), List2: @(List2)""/>
1232                                 </Target>
1233                         </Project>";
1234
1235                         Engine engine = new Engine (Consts.BinPath);
1236                         Project project = engine.CreateNewProject ();
1237
1238                         TestMessageLogger testLogger = new TestMessageLogger ();
1239                         engine.RegisterLogger (testLogger);
1240
1241                         project.LoadXml (projectString);
1242                         bool res = project.Build ("foo");
1243                         if (!res) {
1244                                 testLogger.DumpMessages ();
1245                                 Assert.Fail ("A1: Build failed");
1246                         }
1247
1248                         CheckLoggedMessagesInOrder (testLogger, new string [] {
1249                                 "TargetStarted",
1250                                 "List1: fr_a.txt;fr_c.txt, List2: fr_x.txt",
1251
1252                                 "TargetStarted",
1253                                 "List1: en_b.txt, List2: ",
1254
1255                                 "TargetStarted",
1256                                 "List1: gb_d.txt, List2: gb_z.txt"
1257                         }, "A2");
1258                         CheckEngineEventCounts (testLogger, 3, 3, 6, 6);
1259                 }
1260
1261                 void CheckLoggedMessagesInOrder (TestMessageLogger logger, string [] values, string prefix)
1262                 {
1263                         try {
1264                                 for (int i = 0; i < values.Length; i++) {
1265                                         logger.CheckLoggedMessageHead (values [i], prefix + "#" + i);
1266                                 }
1267                                 if (logger.NormalMessageCount > 0)
1268                                         Assert.Fail ("{0}: Expected {1} messages, but found {2}",
1269                                                 prefix, values.Length, values.Length + logger.NormalMessageCount);
1270                         } catch (NUnit.Framework.AssertionException) {
1271                                 logger.DumpMessages ();
1272                                 throw;
1273                         }
1274                 }
1275
1276                 void CheckMessage (TestMessageLogger logger, string culture, string items, string id)
1277                 {
1278                         logger.CheckLoggedMessageHead (String.Format ("Culture: {0} -- ResXFile: {1}", culture, items), id);
1279                 }
1280
1281                 void CheckMessage2 (TestMessageLogger logger, string culture, string resx_files, string nonresx_files, string id)
1282                 {
1283                         logger.CheckLoggedMessageHead (String.Format ("Culture: {0} -- ResXFiles: {1} NonResXFiles: {2}", culture, resx_files, nonresx_files), id);
1284                 }
1285
1286                 void CheckLoggedMessageAny (TestMessageLogger logger, string expected, string id)
1287                 {
1288                         if (logger.CheckAny (expected, MessageImportance.Normal) == 1)
1289                                 Assert.Fail ("{0}: Expected message '{1}' was not emitted.", id, expected);
1290                 }
1291
1292                 void CheckEngineEventCounts (TestMessageLogger logger, int target_start, int target_finish, int task_start, int task_finish)
1293                 {
1294                         Assert.AreEqual (target_start, logger.TargetStarted, "TargetStarted event count doesn't match");
1295                         Assert.AreEqual (target_finish, logger.TargetFinished, "TargetFinished event count doesn't match");
1296                         Assert.AreEqual (task_start, logger.TaskStarted, "TaskStarted event count doesn't match");
1297                         Assert.AreEqual (task_finish, logger.TaskFinished, "TaskFinished event count doesn't match");
1298                 }
1299         }
1300 }