Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

131 lines
4.9 KiB
C#

// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.IO;
using System.Net;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Web.WebPages;
using System.Xml;
using System.Xml.Resolvers;
using Xunit;
namespace System.Web.Helpers.Test
{
// see: http://msdn.microsoft.com/en-us/library/hdf992b8(v=VS.100).aspx
// see: http://blogs.msdn.com/xmlteam/archive/2008/08/14/introducing-the-xmlpreloadedresolver.aspx
public class XhtmlAssert
{
const string Xhtml10Wrapper = "<html xmlns=\"http://www.w3.org/1999/xhtml\"><head></head><body>{0}</body></html>";
const string DOCTYPE_XHTML1_1 = "<!DOCTYPE {0} PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"xhtml11-flat.dtd\">\r\n";
public static void Validate1_0(object result, bool addRoot = false)
{
string html = null;
if (addRoot)
{
html = String.Format(Xhtml10Wrapper, GetHtml(result));
}
else
{
html = GetHtml(result);
}
Validate1_0(html);
}
public static void Validate1_1(object result, string wrapper = null)
{
string root;
string html = GetHtml(result);
if (String.IsNullOrEmpty(wrapper))
{
root = GetRoot(html);
}
else
{
root = wrapper;
html = String.Format("<{0}>{1}</{0}>", wrapper, html);
}
Validate1_1(root, html);
}
private static string GetHtml(object result)
{
Assert.True((result is IHtmlString) || (result is HelperResult), "Helpers should return IHTMLString or HelperResult");
return result.ToString();
}
private static string GetRoot(string html)
{
Regex regex = new Regex(@"<(\w+)[\s>]");
Match match = regex.Match(html);
Assert.True(match.Success, "Could not determine root element");
Assert.True(match.Groups.Count > 1, "Could not determine root element");
return match.Groups[1].Value;
}
private static void Validate1_0(string html)
{
XmlReaderSettings settings = new XmlReaderSettings();
settings.DtdProcessing = DtdProcessing.Parse;
settings.XmlResolver = new XmlPreloadedResolver(XmlKnownDtds.Xhtml10);
Validate(settings, html);
}
private static void Validate1_1(string root, string html)
{
var settings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Parse, ValidationType = ValidationType.DTD, XmlResolver = new AssemblyResourceXmlResolver() };
string docType = String.Format(DOCTYPE_XHTML1_1, root);
Validate(settings, docType + html);
}
private static void Validate(XmlReaderSettings settings, string html)
{
using (StringReader sr = new StringReader(html))
{
using (XmlReader reader = XmlReader.Create(sr, settings))
{
while (reader.Read())
{
// XHTML element and attribute names must be lowercase, since XML is case sensitive.
// The W3C validator detects this, but we must manually check since the XmlReader does not.
// See: http://www.w3.org/TR/xhtml1/#h-4.2
if (reader.NodeType == XmlNodeType.Element)
{
string element = reader.Name;
Assert.True(element == element.ToLowerInvariant());
if (reader.HasAttributes)
{
for (int i = 0; i < reader.AttributeCount; i++)
{
reader.MoveToAttribute(i);
string attribute = reader.Name;
Assert.True(attribute == attribute.ToLowerInvariant());
}
// move back to element node
reader.MoveToElement();
}
}
}
}
}
}
private class AssemblyResourceXmlResolver : XmlResolver
{
public override ICredentials Credentials
{
set { throw new NotSupportedException(); }
}
public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
{
Assembly assembly = typeof(XhtmlAssert).Assembly;
return assembly.GetManifestResourceStream("System.Web.Helpers.Test.TestFiles.xhtml11-flat.dtd");
}
}
}
}