using System;
using System.IO;
using System.Linq;
using System.Xml;
using Microsoft.Build.Construction;
using NUnit.Framework;
using Microsoft.Build.Evaluation;
using Microsoft.Build.Exceptions;
namespace MonoTests.Microsoft.Build.Construction
{
[TestFixture]
public class ProjectRootElementTest
{
const string empty_project_xml = "";
[Test]
[ExpectedException (typeof (UriFormatException))]
[Category ("NotWorking")] // URL is constructed for ElementLocation, which we don't support yet.
public void CreateExpectsAbsoluteUri ()
{
var xml = XmlReader.Create (new StringReader (empty_project_xml), null, "foo.xml");
ProjectRootElement.Create (xml);
}
[Test]
public void CreateAndPaths ()
{
Assert.IsNull (ProjectRootElement.Create ().FullPath, "#1");
var xml = XmlReader.Create (new StringReader (empty_project_xml), null, "file:///foo.xml");
// This creator does not fill FullPath...
var root = ProjectRootElement.Create (xml);
Assert.IsNull (root.FullPath, "#2");
Assert.AreEqual (Path.GetDirectoryName (new Uri (GetType ().Assembly.CodeBase).LocalPath), root.DirectoryPath, "#3");
}
[Test]
public void FullPathSetter ()
{
var root = ProjectRootElement.Create ();
root.FullPath = "test" + Path.DirectorySeparatorChar + "foo.xml";
var full = Path.Combine (Path.GetDirectoryName (new Uri (GetType ().Assembly.CodeBase).LocalPath), "test", "foo.xml");
Assert.AreEqual (full, root.FullPath, "#1");
Assert.AreEqual (Path.GetDirectoryName (full), root.DirectoryPath, "#1");
}
[Test]
[ExpectedException (typeof (ArgumentNullException))]
public void FullPathSetNull ()
{
ProjectRootElement.Create ().FullPath = null;
}
[Test]
public void InvalidProject ()
{
try {
ProjectRootElement.Create (XmlReader.Create (new StringReader (" ")));
Assert.Fail ("should throw InvalidProjectFileException");
} catch (InvalidProjectFileException ex) {
Assert.AreEqual (1, ex.LineNumber, "#1");
// it is very interesting, but unlike XmlReader.LinePosition it returns the position for '<'.
Assert.AreEqual (2, ex.ColumnNumber, "#2");
}
}
[Test]
public void CreateWithXmlLoads ()
{
string project_xml_1 = "";
var xml = XmlReader.Create (new StringReader (project_xml_1), null, "file://localhost/foo.xml");
var root = ProjectRootElement.Create (xml);
Assert.AreEqual (1, root.Items.Count, "#1");
}
[Test]
public void ToolsVersionDefault ()
{
var g = ProjectCollection.GlobalProjectCollection;
var root = ProjectRootElement.Create ();
// this will be wrong in the future version, but since .NET 4.5 still expects "4.0" we can't say for sure.
Assert.AreEqual ("4.0", root.ToolsVersion, "#1");
}
[Test]
public void ToolsVersionIsEmptyWithXml ()
{
string project_xml_1 = "";
var xml = XmlReader.Create (new StringReader (project_xml_1), null, "file://localhost/foo.xml");
var root = ProjectRootElement.Create (xml);
Assert.AreEqual (string.Empty, root.ToolsVersion, "#1");
}
[Test]
public void LoadUnknownChild ()
{
string project_xml_1 = "";
var xml = XmlReader.Create (new StringReader (project_xml_1), null, "file://localhost/foo.xml");
try {
ProjectRootElement.Create (xml);
Assert.Fail ("should throw InvalidProjectFileException");
} catch (InvalidProjectFileException ex) {
Assert.AreEqual (1, ex.LineNumber, "#1");
// unlike unexpected element case which returned the position for '<', it does return the name start char...
Assert.AreEqual (70, ex.ColumnNumber, "#2");
}
}
[Test]
public void LoadUnregisteredItem ()
{
string project_xml_1 = "";
var xml = XmlReader.Create (new StringReader (project_xml_1), null, "file://localhost/foo.xml");
var root = ProjectRootElement.Create (xml);
Assert.AreEqual (1, root.Items.Count, "#1");
}
[Test]
public void LoadInvalidProjectForBadCondition ()
{
string xml = @"
What are 'ESCAPE' & ""EVALUATE"" ? $ # % ^
$(FOO)
";
var path = "file://localhost/foo.xml";
var reader = XmlReader.Create (new StringReader (xml), null, path);
var root = ProjectRootElement.Create (reader);
Assert.AreEqual (2, root.Properties.Count, "#1");
}
[Test]
[ExpectedException (typeof (InvalidProjectFileException))]
public void LoadInvalidProjectGroupInProjectGroup ()
{
string project_xml = @"
Bar
x
y
z
";
var xml = XmlReader.Create (new StringReader (project_xml));
ProjectRootElement.Create (xml);
}
[Test]
[ExpectedException (typeof (InvalidProjectFileException))]
public void LoadInvalidItemGroupInProjectGroup ()
{
string project_xml = @"
Bar
";
var xml = XmlReader.Create (new StringReader (project_xml));
ProjectRootElement.Create (xml);
}
[Test]
public void ChildAndAllChildren ()
{
string project_xml = @"
Bar
";
var xml = XmlReader.Create (new StringReader (project_xml));
var root = ProjectRootElement.Create (xml);
Assert.AreEqual (2, root.Children.Count, "#1");
// AllChildren expands descendants
Assert.AreEqual (4, root.AllChildren.Count (), "#2");
}
[Test]
[ExpectedException (typeof (InvalidOperationException))]
public void SaveWithoutFullPath ()
{
string project_xml = @"";
var xml = XmlReader.Create (new StringReader (project_xml), null, "file://localhost/foo.xml");
var root = ProjectRootElement.Create (xml);
root.Save ();
}
[Test]
public void SaveToWriter ()
{
string project_xml = @"";
var xml = XmlReader.Create (new StringReader (project_xml), null, "file://localhost/foo.xml");
var root = ProjectRootElement.Create (xml);
var sw = new StringWriter ();
root.Save (sw);
// CRLF? mmm, k...
Assert.AreEqual ("\r\n" + project_xml.Replace ('\'', '"'), sw.ToString (), "#1");
}
[Test]
[ExpectedException (typeof (InvalidProjectFileException))]
public void ImportsMissingProject ()
{
string project_xml = @"
";
var xml = XmlReader.Create (new StringReader (project_xml));
ProjectRootElement.Create (xml);
}
}
}