Add support for ToolsVersion and correctly build msbuild+xbuild assemblies
[mono.git] / mcs / class / Microsoft.Build.Tasks / Test / Microsoft.Build.Tasks / CreateItemTest.cs
1 //
2 // CreateItemTest.cs
3 //
4 // Author:
5 //   Marek Sieradzki (marek.sieradzki@gmail.com)
6 //
7 // (C) 2006 Marek Sieradzki
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 //
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 //
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28 using System;
29 using System.Collections;
30 using System.IO;
31 using Microsoft.Build.BuildEngine;
32 using Microsoft.Build.Framework;
33 using Microsoft.Build.Tasks;
34 using Microsoft.Build.Utilities;
35 using NUnit.Framework;
36
37 namespace MonoTests.Microsoft.Build.Tasks {
38
39         [TestFixture]
40         public class CreateItemTest {
41                 [Test]
42                 public void TestAssignment ()
43                 {
44                         CreateItem ci = new CreateItem ();
45
46                         ci.AdditionalMetadata = new string [1] { "a=1" };
47                         ci.Include = new ITaskItem [1] { new TaskItem ("1") };
48                         ci.Exclude = new ITaskItem [1] { new TaskItem ("2") };
49
50                         Assert.AreEqual ("a=1", ci.AdditionalMetadata [0], "A1");
51                         Assert.AreEqual ("1", ci.Include [0].ItemSpec, "A2");
52                         Assert.AreEqual ("2", ci.Exclude [0].ItemSpec, "A3");
53                 }
54
55                 [Test]
56                 public void TestExecution1 ()
57                 {
58                         Engine engine;
59                         Project project;
60
61                         string documentString = @"
62                                                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
63                                         <ItemGroup>
64                                                 <A Include='1;2'>
65                                                         <Sub>fooA</Sub>
66                                                 </A>
67                                                 <A Include='3;4'>
68                                                         <Sub>fooC</Sub>
69                                                 </A>
70                                                 <B Include='1;3'>
71                                                         <Sub>fooB</Sub>
72                                                 </B>
73                                         </ItemGroup>
74                                         <Target Name='1'>
75                                                 <CreateItem
76                                                         AdditionalMetadata='a=1; b  = 2 '
77                                                         Include='@(A)'
78                                                         Exclude='@(B)'
79                                                 >
80                                                         <Output
81                                                                 TaskParameter='Include'
82                                                                 ItemName='NewItem'
83                                                         />
84                                                 </CreateItem>
85                                         </Target>
86                                 </Project>
87                         ";
88
89                         engine = new Engine (Consts.BinPath);
90                         project = engine.CreateNewProject ();
91                         project.LoadXml (documentString);
92                         Assert.IsTrue (project.Build ("1"), "A1");
93
94                         BuildItemGroup include = project.GetEvaluatedItemsByName ("NewItem");
95                         Assert.AreEqual (2, include.Count, "A2");
96
97                         string [,] additional_metadata = new string [,] { { "a", "1" }, { "b", "2" }, { "Sub", "fooA" } };
98                         CheckBuildItem (include [0], "NewItem", additional_metadata, "2", "A");
99
100                         additional_metadata = new string [,] { { "a", "1" }, { "b", "2" }, { "Sub", "fooC" } };
101                         CheckBuildItem (include [1], "NewItem", additional_metadata, "4", "B");
102                 }
103
104                 [Test]
105                 public void TestExcludeAndCondition ()
106                 {
107                         Engine engine;
108                         Project project;
109
110                         string documentString = @"
111                                         <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
112                                         <ItemGroup>
113                                                 <A Include='1;2;5'>
114                                                         <Sub>fooA</Sub>
115                                                 </A>
116                                                 <A Include='3;4'>
117                                                         <Sub>fooC</Sub>
118                                                 </A>
119                                                 <B Include='1;3'>
120                                                         <Sub>fooB</Sub>
121                                                 </B>
122                                         </ItemGroup>
123                                         <Target Name='1'>
124                                                 <CreateItem
125                                                         AdditionalMetadata='a=1;b=2'
126                                                         Include='@(A)'
127                                                         Exclude='@(B)'
128                                                         Condition=""'%(Sub)' == 'fooA'""
129                                                 >
130                                                         <Output
131                                                                 TaskParameter='Include'
132                                                                 ItemName='NewItem'
133                                                         />
134                                                 </CreateItem>
135                                         </Target>
136                                 </Project>
137                         ";
138
139                         engine = new Engine (Consts.BinPath);
140                         project = engine.CreateNewProject ();
141                         project.LoadXml (documentString);
142                         Assert.IsTrue (project.Build ("1"), "A1");
143
144                         BuildItemGroup include = project.GetEvaluatedItemsByName ("NewItem");
145                         Assert.AreEqual (3, include.Count, "A2");
146
147                         string [,] additional_metadata = new string [,] { { "a", "1" }, {"b", "2"}, {"Sub", "fooA" } };
148                         CheckBuildItem (include [0], "NewItem", additional_metadata, "1", "A");
149                         CheckBuildItem (include [1], "NewItem", additional_metadata, "2", "B");
150                         CheckBuildItem (include [2], "NewItem", additional_metadata, "5", "C");
151                 }
152
153                 [Test]
154                 public void TestNullFields ()
155                 {
156                     Engine engine;
157                     Project project;
158
159                     string documentString = @"
160                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
161                                         <ItemGroup>
162                                                 <A Include='1;2;5'>
163                                                         <Sub>fooA</Sub>
164                                                 </A>
165                                         </ItemGroup>
166                                         <Target Name='1'>
167                                                 <CreateItem Include='@(A)' >
168                                                         <Output
169                                                                 TaskParameter='Include'
170                                                                 ItemName='NewItem'
171                                                         />
172                                                 </CreateItem>
173                                         </Target>
174                                 </Project>";
175
176                     engine = new Engine (Consts.BinPath);
177                     project = engine.CreateNewProject ();
178                     project.LoadXml (documentString);
179                     Assert.IsTrue (project.Build ("1"), "A1, Build failed");
180
181                     BuildItemGroup include = project.GetEvaluatedItemsByName ("NewItem");
182                     Assert.AreEqual (3, include.Count, "A2");
183
184                     string [,] additional_metadata = new string [0, 0];
185                     CheckBuildItem (include [0], "NewItem", additional_metadata, "1", "A");
186                     CheckBuildItem (include [1], "NewItem", additional_metadata, "2", "B");
187                     CheckBuildItem (include [2], "NewItem", additional_metadata, "5", "C");
188                 }
189
190                 [Test]
191                 public void TestVariableExpansion ()
192                 {
193                     Engine engine;
194                     Project project;
195
196                         string documentString = @"
197                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
198                                 <PropertyGroup>
199                                         <P1>FooP1</P1>
200                                         <P2>FooP2</P2>
201                                         <C>@(IG)</C>
202                                         <P3>@(Nine->'%(Identity)')</P3>
203                                 </PropertyGroup>
204                                 <ItemGroup>
205                                         <Nine Include=""Nine""/>
206                                         <Eight Include=""Eight""/>
207                                         <Seven Include=""@(Eight)""/>
208                                         <Six Include=""@(Seven);$(P3)""/>
209                                         <Third Include=""Abc""/>
210                                         <Fourth Include=""$(P2)""/>
211                                         <Second Include=""@(Third);$(P1);@(Fourth);@(Six)""/>
212                                         <IG Include=""@(Second)""/>
213                                 </ItemGroup>
214
215                                         <Target Name='1'>
216                                                 <CreateItem Include='$(C)' >
217                                                         <Output
218                                                                 TaskParameter='Include'
219                                                                 ItemName='Items'
220                                                         />
221                                                 </CreateItem>
222
223                                                 <Message Text=""C: $(C)""/>
224                                                 <Message Text=""items: @(items)""/>
225                                         </Target>
226                                 </Project>
227                         ";
228
229                         engine = new Engine (Consts.BinPath);
230
231                         TestMessageLogger testLogger = new TestMessageLogger ();
232                         engine.RegisterLogger (testLogger);
233
234                         project = engine.CreateNewProject ();
235                         project.LoadXml (documentString);
236                         if (!project.Build ("1")) {
237                                 testLogger.DumpMessages ();
238                                 Assert.Fail ("Build failed");
239                         }
240
241                         BuildItemGroup include = project.GetEvaluatedItemsByName ("Items");
242                         Assert.AreEqual (5, include.Count, "A2");
243
244                         Assert.AreEqual ("Abc", include [0].FinalItemSpec, "A#3");
245                         Assert.AreEqual ("FooP1", include[1].FinalItemSpec, "A#4");
246                         Assert.AreEqual ("FooP2", include[2].FinalItemSpec, "A#5");
247                         Assert.AreEqual ("Eight", include[3].FinalItemSpec, "A#6");
248                         Assert.AreEqual ("Nine", include[4].FinalItemSpec, "A#7");
249
250                         testLogger.CheckLoggedMessageHead ("C: Abc;FooP1;FooP2;Eight;Nine", "A#9");
251                         testLogger.CheckLoggedMessageHead ("items: Abc;FooP1;FooP2;Eight;Nine", "A#10");
252
253                 }
254
255 #if NET_3_5 || NET_4_0
256                 [Test]
257                 public void TestItemsWithWildcards () {
258                         Engine engine = new Engine (Consts.BinPath);
259                         Project proj = engine.CreateNewProject ();
260                         TestMessageLogger logger = new TestMessageLogger ();
261                         engine.RegisterLogger (logger);
262
263                         // Setup
264
265                         string basedir = PathCombine ("Test", "resources", "dir");
266                         string aaa = PathCombine ("a", "aa", "aaa");
267                         string bb = Path.Combine ("b", "bb");
268
269                         string[] dirs = { aaa, bb, "c" };
270                         string[] files = {
271                                                                 PathCombine (basedir, aaa, "foo.dll"),
272                                                                 PathCombine (basedir, bb, "bar.dll"),
273                                                                 PathCombine (basedir, bb, "sample.txt"),
274                                                                 Path.Combine (basedir, "xyz.dll")
275                                                           };
276
277                         string documentString = @"
278                                 <Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" " + Consts.ToolsVersionString + @">
279                                         <PropertyGroup>
280                                                 <WC>dir\**\*.dll</WC>
281                                                 <ExWC>*\x*.dll</ExWC>
282                                         </PropertyGroup>
283
284                                         <Target Name='Main'>
285                                                 <Copy SourceFiles='dir\xyz.dll' DestinationFiles='dir\abc.dll'/>
286                                                 <CreateItem Include='dir\**\*.dll' Exclude='*\x*.dll'>
287                                                         <Output TaskParameter='Include' ItemName='CI1' />
288                                                 </CreateItem>
289                                                 <Message Text=""CI1: %(CI1.FullPath)""/>
290
291                                                 <CreateItem Include='$(WC)' Exclude='$(ExWC)'>
292                                                         <Output TaskParameter='Include' ItemName='CI2' />
293                                                 </CreateItem>
294                                                 <Message Text=""CI2: %(CI2.FullPath)""/>
295                                         </Target>
296                                 </Project>";
297
298                         try {
299                                 CreateDirectoriesAndFiles (basedir, dirs, files);
300                                 string projectdir = Path.Combine ("Test", "resources");
301                                 File.WriteAllText (Path.Combine (projectdir, "wild1.proj"), documentString);
302                                 proj.Load (Path.Combine (projectdir, "wild1.proj"));
303                                 if (!proj.Build ("Main"))
304                                         Assert.Fail ("Build failed");
305
306                                 string full_base_dir = Path.GetFullPath (basedir);
307                                 foreach (string prefix in new string[] { "CI1: ", "CI2: " }) {
308                                         logger.CheckLoggedAny (prefix + PathCombine (full_base_dir, aaa, "foo.dll"),
309                                                                                 MessageImportance.Normal, "A1");
310                                         logger.CheckLoggedAny (prefix + PathCombine (full_base_dir, bb, "bar.dll"), MessageImportance.Normal, "A2");
311                                         logger.CheckLoggedAny (prefix + PathCombine (full_base_dir, "abc.dll"),
312                                                                                 MessageImportance.Normal, "A3");
313
314                                 }
315                         } catch (AssertionException) {
316                                 logger.DumpMessages ();
317                                 throw;
318                         } finally {
319                                 Directory.Delete (basedir, true);
320                         }
321                 }
322 #endif
323
324                 void CreateDirectoriesAndFiles (string basedir, string[] dirs, string[] files) {
325                         foreach (string dir in dirs)
326                                 Directory.CreateDirectory (Path.Combine (basedir, dir));
327
328                         foreach (string file in files)
329                                 File.WriteAllText (file, String.Empty);
330                 }
331
332                 string PathCombine (string path1, params string[] parts) {
333                         if (parts == null || parts.Length == 0)
334                                 return path1;
335
336                         string final_path = path1;
337                         foreach (string part in parts)
338                                 final_path = Path.Combine (final_path, part);
339
340                         return final_path;
341                 }
342
343                 public static void CheckBuildItem (BuildItem item, string name, string [,] metadata, string finalItemSpec, string prefix)
344                 {
345                         Assert.AreEqual (name, item.Name, prefix + "#1");
346                         for (int i = 0; i < metadata.GetLength (0); i ++) {
347                                 string key = metadata [i, 0];
348                                 string val = metadata [i, 1];
349                                 Assert.IsTrue (item.HasMetadata (key), String.Format ("{0}#2: Expected metadata '{1}' not found", prefix, key));
350                                 Assert.AreEqual (val, item.GetMetadata (key), String.Format ("{0}#3: Value for metadata {1}", prefix, key));
351                                 Assert.AreEqual (val, item.GetEvaluatedMetadata (key), String.Format ("{0}#4: Value for evaluated metadata {1}", prefix, key));
352                         }
353                         Assert.AreEqual (finalItemSpec, item.FinalItemSpec, prefix + "#5");
354                 }
355         }
356 }