1 // Copyright (c) Microsoft. All rights reserved.
2 // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3 //-----------------------------------------------------------------------
4 // </copyright>
5 // <summary>Test the ProjectPropertyElement class.</summary>
6 //-----------------------------------------------------------------------
7 
8 using System;
9 using System.IO;
10 using System.Xml;
11 using Microsoft.Build.Construction;
12 
13 using InvalidProjectFileException = Microsoft.Build.Exceptions.InvalidProjectFileException;
14 using Xunit;
15 
16 namespace Microsoft.Build.UnitTests.OM.Construction
17 {
18     /// <summary>
19     /// Tests for the ProjectPropertyElement class
20     /// </summary>
21     public class ProjectPropertyElement_Tests
22     {
23         /// <summary>
24         /// Read simple property
25         /// </summary>
26         [Fact]
ReadProperty()27         public void ReadProperty()
28         {
29             ProjectPropertyElement property = GetPropertyXml();
30 
31             Assert.Equal("p", property.Name);
32             Assert.Equal("v", property.Value);
33             Assert.Equal("c", property.Condition);
34         }
35 
36         /// <summary>
37         /// Read property with children - they are merely part of its value
38         /// </summary>
39         [Fact]
ReadPropertyWithChildren()40         public void ReadPropertyWithChildren()
41         {
42             string content = @"
43                     <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' >
44                         <PropertyGroup>
45                             <p>A<B>C<D/></B>E</p>
46                         </PropertyGroup>
47                     </Project>
48                 ";
49 
50             ProjectRootElement project = ProjectRootElement.Create(XmlReader.Create(new StringReader(content)));
51             ProjectPropertyGroupElement propertyGroup = (ProjectPropertyGroupElement)Helpers.GetFirst(project.Children);
52             ProjectPropertyElement property = Helpers.GetFirst(propertyGroup.Properties);
53 
54             Assert.Equal("p", property.Name);
55             Assert.Equal(@"A<B xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">C<D /></B>E", property.Value);
56         }
57 
58         /// <summary>
59         /// Read property with invalid name (but legal xml)
60         /// </summary>
61         [Fact]
ReadInvalidName()62         public void ReadInvalidName()
63         {
64             Assert.Throws<InvalidProjectFileException>(() =>
65             {
66                 string content = @"
67                     <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' >
68                         <PropertyGroup>
69                             <" + "\u03A3" + @"/>
70                         </PropertyGroup>
71                     </Project>
72                 ";
73 
74                 ProjectRootElement.Create(XmlReader.Create(new StringReader(content)));
75             }
76            );
77         }
78         /// <summary>
79         /// Read property with invalid reserved name
80         /// </summary>
81         [Fact]
ReadInvalidReservedName()82         public void ReadInvalidReservedName()
83         {
84             Assert.Throws<InvalidProjectFileException>(() =>
85             {
86                 string content = @"
87                     <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' >
88                         <PropertyGroup>
89                             <PropertyGroup/>
90                         </PropertyGroup>
91                     </Project>
92                 ";
93 
94                 ProjectRootElement.Create(XmlReader.Create(new StringReader(content)));
95             }
96            );
97         }
98         /// <summary>
99         /// Read property with invalid built in name
100         /// </summary>
101         [Fact]
ReadInvalidBuiltInName()102         public void ReadInvalidBuiltInName()
103         {
104             Assert.Throws<InvalidProjectFileException>(() =>
105             {
106                 string content = @"
107                     <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' >
108                         <PropertyGroup>
109                             <MSBuildProjectFile/>
110                         </PropertyGroup>
111                     </Project>
112                 ";
113 
114                 ProjectRootElement.Create(XmlReader.Create(new StringReader(content)));
115             }
116            );
117         }
118         /// <summary>
119         /// Read property with invalid attribute
120         /// </summary>
121         [Fact]
ReadInvalidAttribute()122         public void ReadInvalidAttribute()
123         {
124             Assert.Throws<InvalidProjectFileException>(() =>
125             {
126                 string content = @"
127                     <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' >
128                         <PropertyGroup>
129                             <p XX='YY'/>
130                         </PropertyGroup>
131                     </Project>
132                 ";
133 
134                 ProjectRootElement.Create(XmlReader.Create(new StringReader(content)));
135             }
136            );
137         }
138         /// <summary>
139         /// Read property with child element
140         /// </summary>
141         [Fact]
ReadInvalidChildElement()142         public void ReadInvalidChildElement()
143         {
144             Assert.Throws<InvalidProjectFileException>(() =>
145             {
146                 string content = @"
147                     <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' >
148                         <PropertyGroup>
149                             <p>
150                                 <X/>
151                             <p>
152                         </PropertyGroup>
153                     </Project>
154                 ";
155 
156                 ProjectRootElement.Create(XmlReader.Create(new StringReader(content)));
157             }
158            );
159         }
160         /// <summary>
161         /// Set property value
162         /// </summary>
163         [Fact]
SetValue()164         public void SetValue()
165         {
166             ProjectPropertyElement property = GetPropertyXml();
167             Helpers.ClearDirtyFlag(property.ContainingProject);
168 
169             property.Value = "vb";
170             Assert.Equal("vb", property.Value);
171             Assert.Equal(true, property.ContainingProject.HasUnsavedChanges);
172         }
173 
174         /// <summary>
175         /// Set property value to the same value it was before.
176         /// This should not dirty the project.
177         /// </summary>
178         [Fact]
SetSameValue()179         public void SetSameValue()
180         {
181             ProjectRootElement project = ProjectRootElement.Create();
182             ProjectPropertyElement property = project.AddProperty("p", "v1");
183             Helpers.ClearDirtyFlag(property.ContainingProject);
184 
185             property.Value = "v1";
186             Assert.Equal("v1", property.Value);
187             Assert.Equal(false, property.ContainingProject.HasUnsavedChanges);
188         }
189 
190         /// <summary>
191         /// Rename
192         /// </summary>
193         [Fact]
SetName()194         public void SetName()
195         {
196             ProjectPropertyElement property = GetPropertyXml();
197 
198             property.Name = "p2";
199             Assert.Equal("p2", property.Name);
200             Assert.Equal(true, property.ContainingProject.HasUnsavedChanges);
201         }
202 
203         /// <summary>
204         /// Rename to same value should not mark dirty
205         /// </summary>
206         [Fact]
SetNameSame()207         public void SetNameSame()
208         {
209             ProjectPropertyElement property = GetPropertyXml();
210             Helpers.ClearDirtyFlag(property.ContainingProject);
211 
212             property.Name = "p";
213             Assert.Equal("p", property.Name);
214             Assert.Equal(false, property.ContainingProject.HasUnsavedChanges);
215         }
216 
217         /// <summary>
218         /// Rename to illegal name
219         /// </summary>
220         [Fact]
SetNameIllegal()221         public void SetNameIllegal()
222         {
223             Assert.Throws<ArgumentException>(() =>
224             {
225                 ProjectPropertyElement property = GetPropertyXml();
226 
227                 property.Name = "ImportGroup";
228             }
229            );
230         }
231         /// <summary>
232         /// Set property value to empty
233         /// </summary>
234         [Fact]
SetEmptyValue()235         public void SetEmptyValue()
236         {
237             ProjectPropertyElement property = GetPropertyXml();
238             Helpers.ClearDirtyFlag(property.ContainingProject);
239 
240             property.Value = String.Empty;
241             Assert.Equal(String.Empty, property.Value);
242             Assert.Equal(true, property.ContainingProject.HasUnsavedChanges);
243         }
244 
245         /// <summary>
246         /// Set property value to null
247         /// </summary>
248         [Fact]
SetInvalidNullValue()249         public void SetInvalidNullValue()
250         {
251             Assert.Throws<ArgumentNullException>(() =>
252             {
253                 ProjectPropertyElement property = GetPropertyXml();
254 
255                 property.Value = null;
256             }
257            );
258         }
259         /// <summary>
260         /// Set condition
261         /// </summary>
262         [Fact]
SetCondition()263         public void SetCondition()
264         {
265             ProjectRootElement project = ProjectRootElement.Create();
266             ProjectPropertyElement property = project.AddProperty("p", "v1");
267             Helpers.ClearDirtyFlag(property.ContainingProject);
268 
269             property.Condition = "c";
270             Assert.Equal("c", property.Condition);
271             Assert.Equal(true, property.ContainingProject.HasUnsavedChanges);
272         }
273 
274         /// <summary>
275         /// Helper to get a ProjectPropertyElement for a simple property
276         /// </summary>
GetPropertyXml()277         private static ProjectPropertyElement GetPropertyXml()
278         {
279             string content = @"
280                     <Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' >
281                         <PropertyGroup>
282                             <p Condition='c'>v</p>
283                         </PropertyGroup>
284                     </Project>
285                 ";
286 
287             ProjectRootElement project = ProjectRootElement.Create(XmlReader.Create(new StringReader(content)));
288             ProjectPropertyGroupElement propertyGroup = (ProjectPropertyGroupElement)Helpers.GetFirst(project.Children);
289             ProjectPropertyElement property = Helpers.GetFirst(propertyGroup.Properties);
290             return property;
291         }
292     }
293 }
294