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