8a0a2991f24c5a0a7ae7df315f2bc8d360d7ae98
[mono.git] / mcs / class / Microsoft.Build / Test / Microsoft.Build.Construction / ProjectRootElementTest.cs
1 using System;
2 using System.IO;
3 using System.Linq;
4 using System.Xml;
5 using Microsoft.Build.Construction;
6 using NUnit.Framework;
7 using Microsoft.Build.Evaluation;
8 using Microsoft.Build.Exceptions;
9
10 namespace MonoTests.Microsoft.Build.Construction
11 {
12         [TestFixture]
13         public class ProjectRootElementTest
14         {
15                 const string empty_project_xml = "<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
16
17                 [Test]
18                 [ExpectedException (typeof (UriFormatException))]
19                 [Category ("NotWorking")] // URL is constructed for ElementLocation, which we don't support yet.
20                 public void CreateExpectsAbsoluteUri ()
21                 {
22                         var xml = XmlReader.Create (new StringReader (empty_project_xml), null, "foo.xml");
23                         ProjectRootElement.Create (xml);
24                 }
25
26                 [Test]
27                 public void CreateAndPaths ()
28                 {
29                         Assert.IsNull (ProjectRootElement.Create ().FullPath, "#1");
30                         var xml = XmlReader.Create (new StringReader (empty_project_xml), null, "file:///foo.xml");
31                         // This creator does not fill FullPath...
32                         var root = ProjectRootElement.Create (xml);
33
34                         // Expected to run from mcs/class/lib/profile
35                         var dir_name = Path.GetDirectoryName (new Uri (GetType ().Assembly.CodeBase).LocalPath);
36                         var namespace_path = Path.Combine (Directory.GetParent (dir_name).Parent.FullName, "Microsoft.Build");
37
38                         Assert.IsNull (root.FullPath, "#2");
39                         Assert.AreEqual (namespace_path, root.DirectoryPath, "#3");
40                 }
41
42                 [Test]
43                 public void FullPathSetter ()
44                 {
45                         var root = ProjectRootElement.Create ();
46                         root.FullPath = "test" + Path.DirectorySeparatorChar + "foo.xml";
47
48                         // Expected to run from mcs/class/lib/profile
49                         var dir_name = Path.GetDirectoryName (new Uri (GetType ().Assembly.CodeBase).LocalPath);
50                         var namespace_path = Path.Combine (Directory.GetParent (dir_name).Parent.FullName, "Microsoft.Build");
51                         var full = Path.Combine (namespace_path, "test", "foo.xml");
52                         Assert.AreEqual (full, root.FullPath, "#1");
53                         Assert.AreEqual (Path.GetDirectoryName (full), root.DirectoryPath, "#1");
54                 }
55
56                 [Test]
57                 [ExpectedException (typeof (ArgumentNullException))]
58                 public void FullPathSetNull ()
59                 {
60                         ProjectRootElement.Create ().FullPath = null;
61                 }
62
63                 [Test]
64                 public void InvalidProject ()
65                 {
66                         try {
67                                 ProjectRootElement.Create (XmlReader.Create (new StringReader (" <root/>")));
68                                 Assert.Fail ("should throw InvalidProjectFileException");
69                         } catch (InvalidProjectFileException ex) {
70                                 Assert.AreEqual (1, ex.LineNumber, "#1");
71                                 // it is very interesting, but unlike XmlReader.LinePosition it returns the position for '<'.
72                                 Assert.AreEqual (2, ex.ColumnNumber, "#2");
73                         }
74                 }
75
76                 [Test]
77                 public void CreateWithXmlLoads ()
78                 {
79                         string project_xml_1 = "<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'><ItemGroup><None Include='bar.txt' /></ItemGroup></Project>";
80                         var xml = XmlReader.Create (new StringReader (project_xml_1), null, "file://localhost/foo.xml");
81                         var root = ProjectRootElement.Create (xml);
82                         Assert.AreEqual (1, root.Items.Count, "#1");
83                 }
84                 
85                 [Test]
86                 public void ToolsVersionDefault ()
87                 {
88                         var g = ProjectCollection.GlobalProjectCollection;
89                         var root = ProjectRootElement.Create ();
90                         // this will be wrong in the future version, but since .NET 4.5 still expects "4.0" we can't say for sure.
91                         Assert.AreEqual ("4.0", root.ToolsVersion, "#1");
92                 }
93                 
94                 [Test]
95                 public void ToolsVersionIsEmptyWithXml ()
96                 {
97                         string project_xml_1 = "<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'><ItemGroup><None Include='bar.txt' /></ItemGroup></Project>";
98                         var xml = XmlReader.Create (new StringReader (project_xml_1), null, "file://localhost/foo.xml");
99                         var root = ProjectRootElement.Create (xml);
100                         Assert.AreEqual (string.Empty, root.ToolsVersion, "#1");
101                 }
102
103                 [Test]
104                 public void LoadUnknownChild ()
105                 {
106                         string project_xml_1 = "<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'><Unknown /></Project>";
107                         var xml = XmlReader.Create (new StringReader (project_xml_1), null, "file://localhost/foo.xml");
108                         try {
109                                 ProjectRootElement.Create (xml);
110                                 Assert.Fail ("should throw InvalidProjectFileException");
111                         } catch (InvalidProjectFileException ex) {
112                                 Assert.AreEqual (1, ex.LineNumber, "#1");
113                                 // unlike unexpected element case which returned the position for '<', it does return the name start char...
114                                 Assert.AreEqual (70, ex.ColumnNumber, "#2");
115                         }
116                 }
117
118                 [Test]
119                 public void LoadUnregisteredItem ()
120                 {
121                         string project_xml_1 = "<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'><ItemGroup><UnregisteredItem Include='bar.txt' /></ItemGroup></Project>";
122                         var xml = XmlReader.Create (new StringReader (project_xml_1), null, "file://localhost/foo.xml");
123                         var root = ProjectRootElement.Create (xml);
124                         Assert.AreEqual (1, root.Items.Count, "#1");
125                 }
126                 
127                 [Test]
128                 public void LoadInvalidProjectForBadCondition ()
129                 {
130                         string xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
131   <PropertyGroup>
132     <Foo>What are 'ESCAPE' &amp; ""EVALUATE"" ? $ # % ^</Foo>
133     <!-- Note that this contains invalid Condition expression. Project.ctor() fails to load. -->
134     <Baz Condition=""$(Void)=="">$(FOO)</Baz>
135   </PropertyGroup>
136 </Project>";
137                         var path = "file://localhost/foo.xml";
138                         var reader = XmlReader.Create (new StringReader (xml), null, path);
139                         var root = ProjectRootElement.Create (reader);
140                         Assert.AreEqual (2, root.Properties.Count, "#1");
141                 }
142                 
143                 [Test]
144                 [ExpectedException (typeof (InvalidProjectFileException))]
145                 public void LoadInvalidProjectGroupInProjectGroup ()
146                 {
147             string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
148   <Import Project='$(MSBuildToolsPath)\Microsoft.CSharp.targets' />
149   <PropertyGroup>
150     <Foo>Bar</Foo>
151     <PropertyGroup>
152       <X>x</X>
153       <Y>y</Y>
154       <Z>z</Z>
155     </PropertyGroup>
156   </PropertyGroup>
157 </Project>";
158             var xml = XmlReader.Create (new StringReader (project_xml));
159             ProjectRootElement.Create (xml);
160                 }
161                 
162                 [Test]
163                 [ExpectedException (typeof (InvalidProjectFileException))]
164                 public void LoadInvalidItemGroupInProjectGroup ()
165                 {
166             string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
167   <Import Project='$(MSBuildToolsPath)\Microsoft.CSharp.targets' />
168   <PropertyGroup>
169     <Foo>Bar</Foo>
170     <ItemGroup/>
171   </PropertyGroup>
172 </Project>";
173             var xml = XmlReader.Create (new StringReader (project_xml));
174             ProjectRootElement.Create (xml);
175                 }
176                 
177                 [Test]
178                 public void ChildAndAllChildren ()
179                 {
180             string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
181   <Import Project='$(MSBuildToolsPath)\Microsoft.CSharp.targets' />
182   <PropertyGroup>
183     <Foo>Bar</Foo>
184     <Item/>
185   </PropertyGroup>
186 </Project>";
187             var xml = XmlReader.Create (new StringReader (project_xml));
188             var root = ProjectRootElement.Create (xml);
189                         Assert.AreEqual (2, root.Children.Count, "#1");
190                         // AllChildren expands descendants
191                         Assert.AreEqual (4, root.AllChildren.Count (), "#2");
192                 }
193                 
194                 [Test]
195                 [ExpectedException (typeof (InvalidOperationException))]
196                 public void SaveWithoutFullPath ()
197                 {
198                         string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
199                         var xml = XmlReader.Create (new StringReader (project_xml), null, "file://localhost/foo.xml");
200                         var root = ProjectRootElement.Create (xml);
201                         root.Save ();
202                 }
203                 
204                 [Test]
205                 public void SaveToWriter ()
206                 {
207                         string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
208                         var xml = XmlReader.Create (new StringReader (project_xml), null, "file://localhost/foo.xml");
209                         var root = ProjectRootElement.Create (xml);
210                         var sw = new StringWriter ();
211                         root.Save (sw);
212                         // CRLF? mmm, k...
213                         Assert.AreEqual ("<?xml version=\"1.0\" encoding=\"utf-16\"?>\r\n" + project_xml.Replace ('\'', '"'), sw.ToString (), "#1");
214                 }
215                 
216                 [Test]
217                 [ExpectedException (typeof (InvalidProjectFileException))]
218                 public void ImportsMissingProject ()
219                 {
220                         string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
221   <Import Project='' />
222 </Project>";
223                         var xml = XmlReader.Create (new StringReader (project_xml));
224                         ProjectRootElement.Create (xml);
225                 }
226         }
227 }