Add support for ToolsVersion and correctly build msbuild+xbuild assemblies
[mcs.git] / class / Microsoft.Build.Tasks / Test / Microsoft.Build.Tasks / TaskBatchingTest.cs
blobe854812b76b16e12f7fd70b0d18dbc87d15eca3c
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:
18 // The above copyright notice and this permission notice shall be
19 // included in all copies or substantial portions of the Software.
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.
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;
38 namespace MonoTests.Microsoft.Build.Tasks
40 [TestFixture]
41 public class TaskBatchingTest
43 string projectHeader;
44 public TaskBatchingTest ()
46 projectHeader = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + ">";
49 [Test]
50 public void Test1 ()
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>
74 <Target Name=""ShowMessage"">
75 <Message
76 Text = ""Culture: %(ResXFile.Culture) -- ResXFile: @(ResXFile)"" />
77 </Target>
78 </Project>";
80 Engine engine = new Engine (Consts.BinPath);
81 Project project = engine.CreateNewProject ();
83 TestMessageLogger testLogger = new TestMessageLogger ();
84 engine.RegisterLogger (testLogger);
86 project.LoadXml (projectString);
87 Assert.IsTrue (project.Build ("ShowMessage"), "A1: Build failed");
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");
94 CheckEngineEventCounts (testLogger, 1, 1, 4, 4);
97 // Test1 with unqualified %(Culture)
98 [Test]
99 public void Test2 ()
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>
123 <Target Name=""ShowMessage"">
124 <Message
125 Text = ""Culture: %(Culture) -- ResXFile: @(ResXFile)"" />
126 </Target>
127 </Project>";
129 Engine engine = new Engine (Consts.BinPath);
130 Project project = engine.CreateNewProject ();
132 TestMessageLogger testLogger = new TestMessageLogger ();
133 engine.RegisterLogger (testLogger);
135 project.LoadXml (projectString);
136 Assert.IsTrue (project.Build ("ShowMessage"), "A1: Build failed");
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");
143 CheckEngineEventCounts (testLogger, 1, 1, 4, 4);
146 [Test]
147 public void TestUnqualifiedMetadataReference ()
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>
160 <Target Name=""ShowMessage"">
161 <Message
162 Text = ""Culture: %(Culture) -- ResXFile: @(ResXFile)"" />
163 </Target>
164 </Project>";
166 Engine engine = new Engine (Consts.BinPath);
167 Project project = engine.CreateNewProject ();
169 TestMessageLogger testLogger = new TestMessageLogger ();
170 engine.RegisterLogger (testLogger);
172 project.LoadXml (projectString);
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");
180 CheckEngineEventCounts (testLogger, 1, 1, 0, 0);
183 [Test]
184 public void Test4 ()
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>
197 <Target Name=""ShowMessage"">
198 <Message
199 Text = ""Culture: %(ResXFile.Culture) -- ResXFile: @(ResXFile)"" />
200 </Target>
201 </Project>";
203 Engine engine = new Engine (Consts.BinPath);
204 Project project = engine.CreateNewProject ();
206 TestMessageLogger testLogger = new TestMessageLogger ();
207 engine.RegisterLogger (testLogger);
209 project.LoadXml (projectString);
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");
215 CheckMessage (testLogger, "fr", "Item1", "A2");
216 CheckMessage (testLogger, "", "Item5", "A3");
217 CheckMessage (testLogger, "it", "Item6", "A3");
218 CheckEngineEventCounts (testLogger, 1, 1, 3, 3);
221 [Test]
222 public void TestMultiItemCollections ()
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>
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>
253 <Target Name=""ShowMessage"">
254 <Message
255 Text = ""Culture: %(Culture) -- ResXFiles: @(ResXFile) NonResXFiles: @(NonResXFile)"" />
256 </Target>
257 </Project>";
259 Engine engine = new Engine (Consts.BinPath);
260 Project project = engine.CreateNewProject ();
262 TestMessageLogger testLogger = new TestMessageLogger ();
263 engine.RegisterLogger (testLogger);
265 project.LoadXml (projectString);
266 Assert.IsTrue (project.Build ("ShowMessage"), "A1: Build failed");
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);
275 [Test]
276 public void TestConditionalBatching ()
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>
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>
307 <Target Name=""ShowMessage"">
308 <Message
309 Text = ""ResXFiles: @(ResXFile) NonResXFiles: @(NonResXFile)""
310 Condition = ""'%(Culture)' == 'fr'""/>
311 </Target>
312 </Project>";
314 Engine engine = new Engine (Consts.BinPath);
315 Project project = engine.CreateNewProject ();
317 TestMessageLogger testLogger = new TestMessageLogger ();
318 engine.RegisterLogger (testLogger);
320 project.LoadXml (projectString);
321 Assert.IsTrue (project.Build ("ShowMessage"), "A1: Build failed");
323 testLogger.CheckLoggedMessageHead ("ResXFiles: Item1;Item2 NonResXFiles: ", "A2");
324 CheckEngineEventCounts (testLogger, 1, 1, 1, 1);
327 [Test]
328 public void TestMultipleMetadataReference ()
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>
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>";
359 Engine engine = new Engine (Consts.BinPath);
360 Project project = engine.CreateNewProject ();
362 TestMessageLogger testLogger = new TestMessageLogger ();
363 engine.RegisterLogger (testLogger);
365 project.LoadXml (projectString);
366 Assert.IsTrue (project.Build ("ShowMessage"), "A1: Build failed");
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);
376 [Test]
377 public void TestMultipleMetadataReference2 ()
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>
388 <ItemGroup>
389 <GroupB Include=""file1.txt""/>
390 <GroupB Include=""file3.txt""/>
391 <GroupB Include=""file5.txt""/>
393 <GroupC Include=""PreExistingValue""/>
394 </ItemGroup>
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>";
404 Engine engine = new Engine (Consts.BinPath);
405 Project project = engine.CreateNewProject ();
407 TestMessageLogger testLogger = new TestMessageLogger ();
408 engine.RegisterLogger (testLogger);
410 project.LoadXml (projectString);
411 Assert.IsTrue (project.Build ("Build"), "A1: Build failed");
413 BuildItemGroup include = project.GetEvaluatedItemsByName ("GroupC");
414 Assert.AreEqual (4, include.Count, "A2");
416 string [,] additional_metadata = new string [,] { { "Identity", "PreExistingValue" } };
417 CreateItemTest.CheckBuildItem (include [0], "GroupC", additional_metadata, "PreExistingValue", "A3");
419 additional_metadata = new string [,] { { "Identity", "file1.txt" } };
420 CreateItemTest.CheckBuildItem (include [1], "GroupC", additional_metadata, "file1.txt", "A4");
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");
426 CheckEngineEventCounts (testLogger, 1, 1, 5, 5);
429 [Test]
430 public void TestIdentity ()
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>";
447 Engine engine = new Engine (Consts.BinPath);
448 Project project = engine.CreateNewProject ();
450 TestMessageLogger testLogger = new TestMessageLogger ();
451 engine.RegisterLogger (testLogger);
453 project.LoadXml (projectString);
454 Assert.IsTrue (project.Build ("ShowMessage"), "A1: Build failed");
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);
466 [Test]
467 public void TestFilter ()
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>";
494 Engine engine = new Engine (Consts.BinPath);
495 Project project = engine.CreateNewProject ();
497 TestMessageLogger testLogger = new TestMessageLogger ();
498 engine.RegisterLogger (testLogger);
500 project.LoadXml (projectString);
501 Assert.IsTrue (project.Build ("Compost"), "A1: Build failed");
503 BuildItemGroup include = project.GetEvaluatedItemsByName ("Final");
504 Assert.AreEqual (3, include.Count, "A2");
506 string [,] additional_metadata = new string [,] { { "Identity", "orange" } };
507 CreateItemTest.CheckBuildItem (include [0], "Final", additional_metadata, "orange", "A3");
509 additional_metadata = new string [,] { { "Identity", "pear" } };
510 CreateItemTest.CheckBuildItem (include [1], "Final", additional_metadata, "pear", "A4");
512 additional_metadata = new string [,] { { "Identity", "apricot" } };
513 CreateItemTest.CheckBuildItem (include [2], "Final", additional_metadata, "apricot", "A5");
514 CheckEngineEventCounts (testLogger, 1, 1, 2, 2);
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>";
535 Engine engine = new Engine (Consts.BinPath);
536 Project project = engine.CreateNewProject ();
538 TestMessageLogger testLogger = new TestMessageLogger ();
539 engine.RegisterLogger (testLogger);
541 project.LoadXml (projectString);
542 if (!project.Build ("1")) {
543 testLogger.DumpMessages ();
544 Assert.Fail ("Build failed");
547 testLogger.CheckLoggedMessageHead ("Prop1: %(item0.Identity)", "A1");
548 testLogger.CheckLoggedMessageHead ("Item2: %(item3.Identity)", "A2");
549 Assert.AreEqual (0, testLogger.NormalMessageCount, "Unexpected extra messages found");
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)""/>
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>";
570 Engine engine = new Engine (Consts.BinPath);
571 Project project = engine.CreateNewProject ();
573 TestMessageLogger testLogger = new TestMessageLogger ();
574 engine.RegisterLogger (testLogger);
576 project.LoadXml (projectString);
577 if (!project.Build ("1")) {
578 testLogger.DumpMessages ();
579 Assert.Fail ("Build failed");
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");
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>";
604 Engine engine = new Engine (Consts.BinPath);
605 Project project = engine.CreateNewProject ();
607 TestMessageLogger testLogger = new TestMessageLogger ();
608 engine.RegisterLogger (testLogger);
610 project.LoadXml (projectString);
611 if (!project.Build ("1")) {
612 testLogger.DumpMessages ();
613 Assert.Fail ("Build failed");
616 testLogger.CheckLoggedMessageHead ("Item3: %(item3.Identity)", "A1");
617 testLogger.CheckLoggedMessageHead ("Item4: %(item2.Identity)", "A2");
618 Assert.AreEqual (0, testLogger.NormalMessageCount, "Unexpected extra messages found");
621 [Test]
622 public void TestBatchingWithUnbatchedItems () {
623 string projectString = projectHeader + @"
624 <ItemGroup>
625 <Item1 Include=""One""/>
626 <Item1 Include=""Two""/>
628 <B Include=""abc""/>
629 </ItemGroup>
630 <Target Name='1'>
631 <Message Text=""Item1: %(Item1.Identity) | B: @(B)""/>
632 </Target>
633 </Project>";
635 Engine engine = new Engine (Consts.BinPath);
636 Project project = engine.CreateNewProject ();
638 TestMessageLogger testLogger = new TestMessageLogger ();
639 engine.RegisterLogger (testLogger);
641 project.LoadXml (projectString);
642 if (!project.Build ("1")) {
643 testLogger.DumpMessages ();
644 Assert.Fail ("Build failed");
647 try {
648 testLogger.CheckLoggedMessageHead ("Item1: One | B: abc", "A1");
649 testLogger.CheckLoggedMessageHead ("Item1: Two | B: abc", "A2");
651 Assert.AreEqual (0, testLogger.NormalMessageCount, "Unexpected extra messages found");
652 } catch (AssertionException) {
653 testLogger.DumpMessages ();
654 throw;
658 [Test]
659 public void TestPropertiesWithBatchedReferences () {
660 string projectString = projectHeader + @"
661 <ItemGroup>
662 <Item1 Include=""One""/>
663 <Item1 Include=""Two""/>
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>";
676 Engine engine = new Engine (Consts.BinPath);
677 Project project = engine.CreateNewProject ();
679 TestMessageLogger testLogger = new TestMessageLogger ();
680 engine.RegisterLogger (testLogger);
682 project.LoadXml (projectString);
683 if (!project.Build ("1")) {
685 testLogger.DumpMessages ();
686 Assert.Fail ("Build failed");
689 try {
690 testLogger.CheckLoggedMessageHead ("Item1: One | Prop1: One | Prop2: One;Two", "A1");
691 testLogger.CheckLoggedMessageHead ("Item1: Two | Prop1: Two | Prop2: One;Two", "A2");
693 Assert.AreEqual (0, testLogger.NormalMessageCount, "Unexpected extra messages found");
694 } catch (AssertionException) {
695 testLogger.DumpMessages ();
696 throw;
700 [Test]
701 public void TestPropertiesWithDynamicItems () {
702 string projectString = projectHeader + @"
703 <ItemGroup>
704 <Item1 Include=""One""/>
705 <Item1 Include=""Two""/>
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>";
725 Engine engine = new Engine (Consts.BinPath);
726 Project project = engine.CreateNewProject ();
728 TestMessageLogger testLogger = new TestMessageLogger ();
729 engine.RegisterLogger (testLogger);
731 project.LoadXml (projectString);
732 if (!project.Build ("1")) {
734 testLogger.DumpMessages ();
735 Assert.Fail ("Build failed");
738 try {
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");
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");
748 Assert.AreEqual (0, testLogger.NormalMessageCount, "Unexpected extra messages found");
749 } catch (AssertionException) {
750 testLogger.DumpMessages ();
751 throw;
755 [Test]
756 public void TestTargetInvocationFromBatchedTask () {
757 string projectString = projectHeader + @"
758 <ItemGroup>
759 <Item1 Include=""One""/>
760 <Item1 Include=""Two""/>
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>";
779 Engine engine = new Engine (Consts.BinPath);
780 Project project = engine.CreateNewProject ();
782 TestMessageLogger testLogger = new TestMessageLogger ();
783 engine.RegisterLogger (testLogger);
785 project.LoadXml (projectString);
786 if (!project.Build ("1")) {
788 testLogger.DumpMessages ();
789 Assert.Fail ("Build failed");
792 try {
793 testLogger.CheckLoggedMessageHead ("(foo) Item1: One;Two Item1Ref: One;Two", "A1");
794 testLogger.CheckLoggedMessageHead ("(foo) Prop1: One;Two Prop2: One;Two", "A2");
796 testLogger.CheckLoggedMessageHead ("Item1: One;Two Item1Ref: One;Two", "A3");
797 testLogger.CheckLoggedMessageHead ("Prop1: One;Two Prop2: One;Two", "A4");
799 Assert.AreEqual (0, testLogger.NormalMessageCount, "Unexpected extra messages found");
800 } catch (AssertionException) {
801 testLogger.DumpMessages ();
802 throw;
806 [Test]
807 public void TestTargetInvocationFromBatchedTarget () {
808 string projectString = projectHeader + @"
809 <ItemGroup>
810 <Item1 Include=""One""/>
811 <Item1 Include=""Two""/>
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)""/>
823 <CallTarget Targets='foo' />
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>";
834 Engine engine = new Engine (Consts.BinPath);
835 Project project = engine.CreateNewProject ();
837 TestMessageLogger testLogger = new TestMessageLogger ();
838 engine.RegisterLogger (testLogger);
840 project.LoadXml (projectString);
841 if (!project.Build ("1")) {
843 testLogger.DumpMessages ();
844 Assert.Fail ("Build failed");
847 try {
848 testLogger.CheckLoggedMessageHead ("Item1: One Item1Ref: One;Two", "A1");
849 testLogger.CheckLoggedMessageHead ("Prop1: One Prop2: One;Two", "A2");
851 testLogger.CheckLoggedMessageHead ("(foo) Item1: One;Two Item1Ref: One;Two", "A3");
852 testLogger.CheckLoggedMessageHead ("(foo) Prop1: One;Two Prop2: One;Two", "A4");
854 testLogger.CheckLoggedMessageHead ("Item1: One Item1Ref: One;Two", "A5");
855 testLogger.CheckLoggedMessageHead ("Prop1: One Prop2: One;Two", "A6");
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");
861 testLogger.CheckLoggedMessageHead ("Item1: Two Item1Ref: One;Two", "A9");
862 testLogger.CheckLoggedMessageHead ("Prop1: Two Prop2: One;Two", "A10");
864 Assert.AreEqual (0, testLogger.NormalMessageCount, "Unexpected extra messages found");
865 } catch (AssertionException) {
866 testLogger.DumpMessages ();
867 throw;
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)"" />
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>
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>";
896 Engine engine = new Engine (Consts.BinPath);
897 Project project = engine.CreateNewProject ();
899 TestMessageLogger testLogger = new TestMessageLogger ();
900 engine.RegisterLogger (testLogger);
902 project.LoadXml (projectString);
903 if (!project.Build ("1")) {
905 testLogger.DumpMessages ();
906 Assert.Fail ("Build failed");
908 testLogger.DumpMessages ();
910 try {
911 testLogger.CheckLoggedAny ("For md: 3 Item1: Item1Ref: Item2: Three Item2Ref: Three Prop1: Prop1Ref: Prop2: Three Prop2Ref: Three", MessageImportance.Normal, "A1");
912 testLogger.CheckLoggedAny ("For md: 4 Item1: Item1Ref: Item2: Four Item2Ref: Four Prop1: Prop1Ref: Prop2: Four Prop2Ref: Four", MessageImportance.Normal, "A2");
913 testLogger.CheckLoggedAny ("For md: 1 Item1: One Item1Ref: One Item2: Item2Ref: Prop1: One Prop1Ref: One Prop2: Prop2Ref: ", MessageImportance.Normal, "A3");
914 testLogger.CheckLoggedAny ("For md: 2 Item1: Two Item1Ref: Two Item2: Item2Ref: Prop1: Two Prop1Ref: Two Prop2: Prop2Ref: ", MessageImportance.Normal, "A4");
916 Assert.AreEqual (0, testLogger.NormalMessageCount, "Unexpected extra messages found");
917 } catch (AssertionException) {
918 testLogger.DumpMessages ();
919 throw;
924 //Target batching
926 [Test]
927 public void TestTargetBatching1 ()
929 string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
930 <ItemGroup>
931 <List1 Include=""fr_a.txt""><Culture>fr</Culture></List1>
932 <List1 Include=""en_b.txt""><Culture>en</Culture></List1>
933 <List1 Include=""fr_c.txt""><Culture>fr</Culture></List1>
934 <List1 Include=""gb_d.txt""><Culture>gb</Culture></List1>
936 <List2 Include=""fr_x.txt""><Culture>fr</Culture></List2>
937 <List2 Include=""gb_z.txt""><Culture>gb</Culture></List2>
939 <Foo Include=""1_a1""><Md>1</Md></Foo>
940 <Foo Include=""2_b1""><Md>2</Md></Foo>
941 <Foo Include=""1_c1""><Md>1</Md></Foo>
942 </ItemGroup>
944 <Target Name=""foo"" >
945 <Message Text=""TargetStarted""/>
946 <Message Text=""List1: @(List1): %(Culture)""/>
947 <Message Text=""Foo: @(Foo): %(Md)""/>
948 </Target>
949 </Project>";
951 Engine engine = new Engine (Consts.BinPath);
952 Project project = engine.CreateNewProject ();
954 TestMessageLogger testLogger = new TestMessageLogger ();
955 engine.RegisterLogger (testLogger);
957 project.LoadXml (projectString);
958 bool res = project.Build ("foo");
959 if (!res) {
960 testLogger.DumpMessages ();
961 Assert.Fail ("A1: Build failed");
964 CheckLoggedMessagesInOrder (testLogger, new string [] {
965 "TargetStarted", "List1: fr_a.txt;fr_c.txt: fr",
966 "List1: en_b.txt: en", "List1: gb_d.txt: gb",
967 "Foo: 1_a1;1_c1: 1", "Foo: 2_b1: 2"
968 }, "A2");
969 CheckEngineEventCounts (testLogger, 1, 1, 6, 6);
972 [Test]
973 public void TestTargetBatching2 ()
975 string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
976 <ItemGroup>
977 <List1 Include=""fr_a.txt""><Culture>fr</Culture></List1>
978 <List1 Include=""en_b.txt""><Culture>en</Culture></List1>
979 <List1 Include=""fr_c.txt""><Culture>fr</Culture></List1>
980 <List1 Include=""gb_d.txt""><Culture>gb</Culture></List1>
982 <List2 Include=""fr_x.txt""><Culture>fr</Culture></List2>
983 <List2 Include=""gb_z.txt""><Culture>gb</Culture></List2>
985 <Foo Include=""1_a1""><Md>1</Md></Foo>
986 <Foo Include=""2_b1""><Md>2</Md></Foo>
987 <Foo Include=""1_c1""><Md>1</Md></Foo>
988 </ItemGroup>
990 <Target Name=""foo"" Inputs=""@(List1)"" Outputs=""%(Culture).foo"">
991 <Message Text=""TargetStarted""/>
992 <Message Text=""List1: @(List1): %(Culture)""/>
993 <Message Text=""Foo: @(Foo): %(Md)""/>
994 </Target>
995 </Project>";
997 Engine engine = new Engine (Consts.BinPath);
998 Project project = engine.CreateNewProject ();
1000 TestMessageLogger testLogger = new TestMessageLogger ();
1001 engine.RegisterLogger (testLogger);
1003 project.LoadXml (projectString);
1004 bool res = project.Build ("foo");
1005 if (!res) {
1006 testLogger.DumpMessages ();
1007 Assert.Fail ("A1: Build failed");
1010 CheckLoggedMessagesInOrder (testLogger, new string [] {
1011 "TargetStarted", "List1: fr_a.txt;fr_c.txt: fr",
1012 "Foo: 1_a1;1_c1: 1", "Foo: 2_b1: 2",
1014 "TargetStarted", "List1: en_b.txt: en",
1015 "Foo: 1_a1;1_c1: 1", "Foo: 2_b1: 2",
1017 "TargetStarted", "List1: gb_d.txt: gb",
1018 "Foo: 1_a1;1_c1: 1", "Foo: 2_b1: 2"
1019 }, "A2");
1020 CheckEngineEventCounts (testLogger, 3, 3, 12, 12);
1023 [Test]
1024 public void TestTargetBatching3 ()
1026 string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1027 <ItemGroup>
1028 <List1 Include=""fr_a.txt""><Culture>fr</Culture></List1>
1029 <List1 Include=""en_b.txt""><Culture>en</Culture></List1>
1030 <List1 Include=""fr_c.txt""><Culture>fr</Culture></List1>
1031 <List1 Include=""gb_d.txt""><Culture>gb</Culture></List1>
1033 <List2 Include=""fr_x.txt""><Culture>fr</Culture></List2>
1034 <List2 Include=""gb_z.txt""><Culture>gb</Culture></List2>
1036 <Foo Include=""1_a1""><Md>1</Md></Foo>
1037 <Foo Include=""2_b1""><Md>2</Md></Foo>
1038 <Foo Include=""1_c1""><Md>1</Md></Foo>
1039 </ItemGroup>
1040 <Target Name=""foo"" Inputs=""@(Foo)"" Outputs=""%(Md).foo"">
1041 <Message Text=""TargetStarted""/>
1042 <Message Text=""List1: @(List1): %(Culture)""/>
1043 <Message Text=""Foo: @(Foo): %(Md)""/>
1044 </Target>
1045 </Project>";
1047 Engine engine = new Engine (Consts.BinPath);
1048 Project project = engine.CreateNewProject ();
1050 TestMessageLogger testLogger = new TestMessageLogger ();
1051 engine.RegisterLogger (testLogger);
1053 project.LoadXml (projectString);
1054 bool res = project.Build ("foo");
1055 if (!res) {
1056 testLogger.DumpMessages ();
1057 Assert.Fail ("A1: Build failed");
1060 CheckLoggedMessagesInOrder (testLogger, new string [] {
1061 "TargetStarted", "List1: fr_a.txt;fr_c.txt: fr",
1062 "List1: en_b.txt: en", "List1: gb_d.txt: gb",
1063 "Foo: 1_a1;1_c1: 1",
1064 "TargetStarted", "List1: fr_a.txt;fr_c.txt: fr",
1065 "List1: en_b.txt: en", "List1: gb_d.txt: gb",
1066 "Foo: 2_b1: 2"
1067 }, "A2");
1068 CheckEngineEventCounts (testLogger, 2, 2, 10, 10);
1071 [Test]
1072 public void TestTargetBatching4 ()
1074 string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1075 <ItemGroup>
1076 <List1 Include=""fr_a.txt""><Culture>fr</Culture></List1>
1077 <List1 Include=""en_b.txt""><Culture>en</Culture></List1>
1078 <List1 Include=""fr_c.txt""><Culture>fr</Culture></List1>
1079 <List1 Include=""gb_d.txt""><Culture>gb</Culture></List1>
1081 <List2 Include=""fr_x.txt""><Culture>fr</Culture></List2>
1082 <List2 Include=""gb_z.txt""><Culture>gb</Culture></List2>
1084 <Foo Include=""1_a1""><Md>1</Md></Foo>
1085 <Foo Include=""2_b1""><Md>2</Md></Foo>
1086 <Foo Include=""1_c1""><Md>1</Md></Foo>
1087 </ItemGroup>
1088 <Target Name=""foo"" Inputs=""@(List1)"" Outputs=""%(Culture).foo"">
1089 <Message Text=""TargetStarted""/>
1090 <Message Text=""List1: @(List1): %(Culture)""/>
1091 <Message Text=""List2: @(List2): %(Culture)""/>
1092 <Message Text=""Foo: @(Foo): %(Md)""/>
1093 </Target>
1094 </Project>";
1096 Engine engine = new Engine (Consts.BinPath);
1097 Project project = engine.CreateNewProject ();
1099 TestMessageLogger testLogger = new TestMessageLogger ();
1100 engine.RegisterLogger (testLogger);
1102 project.LoadXml (projectString);
1103 bool res = project.Build ("foo");
1104 if (!res) {
1105 testLogger.DumpMessages ();
1106 Assert.Fail ("A1: Build failed");
1109 CheckLoggedMessagesInOrder (testLogger, new string [] {
1110 "TargetStarted", "List1: fr_a.txt;fr_c.txt: fr",
1111 "List2: fr_x.txt: fr", "List2: gb_z.txt: gb",
1112 "Foo: 1_a1;1_c1: 1", "Foo: 2_b1: 2",
1114 "TargetStarted", "List1: en_b.txt: en",
1115 "List2: fr_x.txt: fr", "List2: gb_z.txt: gb",
1116 "Foo: 1_a1;1_c1: 1", "Foo: 2_b1: 2",
1118 "TargetStarted", "List1: gb_d.txt: gb",
1119 "List2: fr_x.txt: fr", "List2: gb_z.txt: gb",
1120 "Foo: 1_a1;1_c1: 1", "Foo: 2_b1: 2"
1121 }, "A2");
1122 CheckEngineEventCounts (testLogger, 3, 3, 18, 18);
1125 [Test]
1126 public void TestTargetBatching5 ()
1128 string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1129 <Target Name=""foo"" Inputs=""@(List1)"" Outputs=""%(Culture).foo"">
1130 <Message Text=""TargetStarted""/>
1131 </Target>
1132 </Project>";
1134 Engine engine = new Engine (Consts.BinPath);
1135 Project project = engine.CreateNewProject ();
1137 TestMessageLogger testLogger = new TestMessageLogger ();
1138 engine.RegisterLogger (testLogger);
1140 project.LoadXml (projectString);
1141 bool res = project.Build ("foo");
1142 if (!res) {
1143 testLogger.DumpMessages ();
1144 Assert.Fail ("A1: Build failed");
1146 Assert.AreEqual (1, testLogger.CheckAny ("TargetStarted", MessageImportance.Normal),
1147 "A2: Target should've been skipped because of no inputs");
1148 CheckEngineEventCounts (testLogger, 1, 1, 0, 0);
1151 [Test]
1152 public void TestTargetBatching6 ()
1154 string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1155 <ItemGroup>
1156 <List1 Include=""fr_a.txt""><Culture>fr</Culture></List1>
1157 <List1 Include=""en_b.txt""><Culture>en</Culture></List1>
1158 <List1 Include=""fr_c.txt""><Culture>fr</Culture></List1>
1159 <List1 Include=""gb_d.txt""><Culture>gb</Culture></List1>
1161 <List3 Include=""fr_x.txt""><Culture>fr</Culture></List3>
1162 <List3 Include=""gb_z.txt""><Culture>gb</Culture></List3>
1164 <Foo Include=""1_a1""><Md>1</Md></Foo>
1165 <Foo Include=""2_b1""><Md>2</Md></Foo>
1166 <Foo Include=""1_c1""><Md>1</Md></Foo>
1167 </ItemGroup>
1169 <Target Name=""foo"" Inputs=""@(List1);@(List2)"" Outputs=""%(Culture).foo"">
1170 <Message Text=""TargetStarted"" />
1171 <Message Text=""List1: %(List1.Culture), List2: %(List2.Culture)"" />
1172 <Message Text=""List2: @(List2), Culture: %(Culture)"" />
1173 <Message Text=""List3: @(List3), Culture: %(Culture)"" />
1174 </Target>
1175 </Project>";
1177 Engine engine = new Engine (Consts.BinPath);
1178 Project project = engine.CreateNewProject ();
1180 TestMessageLogger testLogger = new TestMessageLogger ();
1181 engine.RegisterLogger (testLogger);
1183 project.LoadXml (projectString);
1184 bool res = project.Build ("foo");
1185 if (!res) {
1186 testLogger.DumpMessages ();
1187 Assert.Fail ("A1: Build failed");
1190 CheckLoggedMessagesInOrder (testLogger, new string [] {
1191 "TargetStarted",
1192 "List1: fr, List2: ",
1193 "List2: , Culture: ",
1194 "List3: fr_x.txt, Culture: fr",
1195 "List3: gb_z.txt, Culture: gb",
1197 "TargetStarted",
1198 "List1: en, List2: ",
1199 "List2: , Culture: ",
1200 "List3: fr_x.txt, Culture: fr",
1201 "List3: gb_z.txt, Culture: gb",
1203 "TargetStarted",
1204 "List1: gb, List2: ",
1205 "List2: , Culture: ",
1206 "List3: fr_x.txt, Culture: fr",
1207 "List3: gb_z.txt, Culture: gb"
1208 }, "A2");
1209 CheckEngineEventCounts (testLogger, 3, 3, 15, 15);
1212 [Test]
1213 public void TestTargetBatching7 ()
1215 string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
1216 <ItemGroup>
1217 <List1 Include=""fr_a.txt""><Culture>fr</Culture></List1>
1218 <List1 Include=""en_b.txt""><Culture>en</Culture></List1>
1219 <List1 Include=""fr_c.txt""><Culture>fr</Culture></List1>
1220 <List1 Include=""gb_d.txt""><Culture>gb</Culture></List1>
1222 <List2 Include=""fr_x.txt""><Culture>fr</Culture></List2>
1223 <List2 Include=""gb_z.txt""><Culture>gb</Culture></List2>
1225 <Foo Include=""1_a1""><Md>1</Md></Foo>
1226 <Foo Include=""2_b1""><Md>2</Md></Foo>
1227 <Foo Include=""1_c1""><Md>1</Md></Foo>
1228 </ItemGroup>
1230 <Target Name=""foo"" Inputs=""@(List1);@(List2)"" Outputs=""%(Culture).foo"">
1231 <Message Text=""TargetStarted"" />
1232 <Message Text=""List1: @(List1), List2: @(List2)""/>
1233 </Target>
1234 </Project>";
1236 Engine engine = new Engine (Consts.BinPath);
1237 Project project = engine.CreateNewProject ();
1239 TestMessageLogger testLogger = new TestMessageLogger ();
1240 engine.RegisterLogger (testLogger);
1242 project.LoadXml (projectString);
1243 bool res = project.Build ("foo");
1244 if (!res) {
1245 testLogger.DumpMessages ();
1246 Assert.Fail ("A1: Build failed");
1249 CheckLoggedMessagesInOrder (testLogger, new string [] {
1250 "TargetStarted",
1251 "List1: fr_a.txt;fr_c.txt, List2: fr_x.txt",
1253 "TargetStarted",
1254 "List1: en_b.txt, List2: ",
1256 "TargetStarted",
1257 "List1: gb_d.txt, List2: gb_z.txt"
1258 }, "A2");
1259 CheckEngineEventCounts (testLogger, 3, 3, 6, 6);
1262 void CheckLoggedMessagesInOrder (TestMessageLogger logger, string [] values, string prefix)
1264 try {
1265 for (int i = 0; i < values.Length; i++) {
1266 logger.CheckLoggedMessageHead (values [i], prefix + "#" + i);
1268 if (logger.NormalMessageCount > 0)
1269 Assert.Fail ("{0}: Expected {1} messages, but found {2}",
1270 prefix, values.Length, values.Length + logger.NormalMessageCount);
1271 } catch (NUnit.Framework.AssertionException) {
1272 logger.DumpMessages ();
1273 throw;
1277 void CheckMessage (TestMessageLogger logger, string culture, string items, string id)
1279 logger.CheckLoggedMessageHead (String.Format ("Culture: {0} -- ResXFile: {1}", culture, items), id);
1282 void CheckMessage2 (TestMessageLogger logger, string culture, string resx_files, string nonresx_files, string id)
1284 logger.CheckLoggedMessageHead (String.Format ("Culture: {0} -- ResXFiles: {1} NonResXFiles: {2}", culture, resx_files, nonresx_files), id);
1287 void CheckLoggedMessageAny (TestMessageLogger logger, string expected, string id)
1289 if (logger.CheckAny (expected, MessageImportance.Normal) == 1)
1290 Assert.Fail ("{0}: Expected message '{1}' was not emitted.", id, expected);
1293 void CheckEngineEventCounts (TestMessageLogger logger, int target_start, int target_finish, int task_start, int task_finish)
1295 Assert.AreEqual (target_start, logger.TargetStarted, "TargetStarted event count doesn't match");
1296 Assert.AreEqual (target_finish, logger.TargetFinished, "TargetFinished event count doesn't match");
1297 Assert.AreEqual (task_start, logger.TaskStarted, "TaskStarted event count doesn't match");
1298 Assert.AreEqual (task_finish, logger.TaskFinished, "TaskFinished event count doesn't match");