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