From: <bo...@us...> - 2010-05-03 06:49:19
|
Revision: 375 http://xmlunit.svn.sourceforge.net/xmlunit/?rev=375&view=rev Author: bodewig Date: 2010-05-03 06:49:13 +0000 (Mon, 03 May 2010) Log Message: ----------- .NET version of XPath engine Modified Paths: -------------- trunk/xmlunit/src/tests/net-core/builder/InputTest.cs Added Paths: ----------- trunk/xmlunit/src/main/net-core/util/ trunk/xmlunit/src/main/net-core/util/Convert.cs trunk/xmlunit/src/main/net-core/xpath/ trunk/xmlunit/src/main/net-core/xpath/XPathEngine.cs trunk/xmlunit/src/tests/net-core/TestResources.cs trunk/xmlunit/src/tests/net-core/xpath/ trunk/xmlunit/src/tests/net-core/xpath/XPathEngineTest.cs Added: trunk/xmlunit/src/main/net-core/util/Convert.cs =================================================================== --- trunk/xmlunit/src/main/net-core/util/Convert.cs (rev 0) +++ trunk/xmlunit/src/main/net-core/util/Convert.cs 2010-05-03 06:49:13 UTC (rev 375) @@ -0,0 +1,38 @@ +/* + This file is licensed to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +using System.Collections.Generic; +using System.Xml; + +namespace net.sf.xmlunit.util { + /// <summary> + /// Conversion methods. + /// </summary> + public sealed class Convert { + private Convert() { } + + /// <summary> + /// Creates a namespace resolver from a Map prefix => + /// Namespace URI. + /// </summary> + public static XmlNamespaceManager + ToNamespaceContext(IDictionary<string, string> prefix2URI) { + XmlNamespaceManager man = new XmlNamespaceManager(new NameTable()); + foreach (KeyValuePair<string, string> kv in prefix2URI) { + man.AddNamespace(kv.Key, kv.Value); + } + return man; + } + } +} Property changes on: trunk/xmlunit/src/main/net-core/util/Convert.cs ___________________________________________________________________ Added: svn:eol-style + native Added: trunk/xmlunit/src/main/net-core/xpath/XPathEngine.cs =================================================================== --- trunk/xmlunit/src/main/net-core/xpath/XPathEngine.cs (rev 0) +++ trunk/xmlunit/src/main/net-core/xpath/XPathEngine.cs 2010-05-03 06:49:13 UTC (rev 375) @@ -0,0 +1,80 @@ +/* + This file is licensed to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +using System.Collections.Generic; +using System.Xml; +using System.Xml.XPath; +using net.sf.xmlunit.exceptions; +using net.sf.xmlunit.util; + +namespace net.sf.xmlunit.xpath { + + /// <summary> + /// Simplified access to System.Xml.XPath API. + /// </summary> + public class XPathEngine { + private XmlNamespaceManager nsContext; + + /// <summary> + /// Returns a potentially empty collection of Nodes matching an + /// XPath expression. + /// </summary> + public IEnumerable<XmlNode> SelectNodes(string xPath, ISource s) { + try { + XmlDocument doc = new XmlDocument(); + doc.Load(s.Reader); + return ToNodeEnumerable(doc.SelectNodes(xPath, nsContext)); + } catch (XPathException ex) { + throw new XMLUnitException(ex); + } + } + + /// <summary> + /// Evaluates an XPath expression and stringifies the result. + /// </summary> + public string Evaluate(string xPath, ISource s) { + try { + XPathDocument doc = new XPathDocument(s.Reader); + object v = doc.CreateNavigator().Evaluate(xPath, nsContext); + if (v == null) { + return string.Empty; + } else if (v is XPathNodeIterator) { + XPathNodeIterator it = v as XPathNodeIterator; + if (it.MoveNext()) { + return (string) it.Current + .ValueAs(typeof(string), nsContext); + } + return string.Empty; + } + return v.ToString(); + } catch (XPathException ex) { + throw new XMLUnitException(ex); + } + } + + public IDictionary<string, string> NamespaceContext { + set { + nsContext = Convert.ToNamespaceContext(value); + } + } + + private IEnumerable<XmlNode> ToNodeEnumerable(XmlNodeList it) { + LinkedList<XmlNode> l = new LinkedList<XmlNode>(); + foreach (XmlNode n in it) { + l.AddLast(n); + } + return l; + } + } +} \ No newline at end of file Property changes on: trunk/xmlunit/src/main/net-core/xpath/XPathEngine.cs ___________________________________________________________________ Added: svn:eol-style + native Copied: trunk/xmlunit/src/tests/net-core/TestResources.cs (from rev 372, trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/TestResources.java) =================================================================== --- trunk/xmlunit/src/tests/net-core/TestResources.cs (rev 0) +++ trunk/xmlunit/src/tests/net-core/TestResources.cs 2010-05-03 06:49:13 UTC (rev 375) @@ -0,0 +1,22 @@ +/* + This file is licensed to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +namespace net.sf.xmlunit { + + public sealed class TestResources { + public const string ANIMAL_FILE = "../../../src/tests/resources/test1.xml"; + public const string BLAME_FILE = "../../../src/tests/resources/test.blame.html"; + + private TestResources() { } + } +} Modified: trunk/xmlunit/src/tests/net-core/builder/InputTest.cs =================================================================== --- trunk/xmlunit/src/tests/net-core/builder/InputTest.cs 2010-04-30 14:29:47 UTC (rev 374) +++ trunk/xmlunit/src/tests/net-core/builder/InputTest.cs 2010-05-03 06:49:13 UTC (rev 375) @@ -22,8 +22,6 @@ [TestFixture] public class InputTest { - private const string TEST_FILE = "../../../src/tests/resources/test1.xml"; - private static XmlDocument Parse(ISource s) { XmlDocument d = new XmlDocument(); d.Load(s.Reader); @@ -31,23 +29,25 @@ } [Test] public void ShouldParseADocument() { - XmlDocument d = Parse(Input.FromFile(TEST_FILE).Build()); + XmlDocument d = Parse(Input.FromFile(TestResources.ANIMAL_FILE) + .Build()); AllIsWellFor(Input.FromDocument(d).Build()); } [Test] public void ShouldParseAnExistingFileByName() { - AllIsWellFor(Input.FromFile(TEST_FILE).Build()); + AllIsWellFor(Input.FromFile(TestResources.ANIMAL_FILE).Build()); } [Test] public void ShouldParseAnExistingFileFromStream() { - using (FileStream fs = new FileStream(TEST_FILE, FileMode.Open, + using (FileStream fs = new FileStream(TestResources.ANIMAL_FILE, + FileMode.Open, FileAccess.Read)) { AllIsWellFor(Input.FromStream(fs).Build()); } } [Test] public void ShouldParseAnExistingFileFromReader() { - using (StreamReader r = new StreamReader(TEST_FILE)) { + using (StreamReader r = new StreamReader(TestResources.ANIMAL_FILE)) { AllIsWellFor(Input.FromReader(r).Build()); } } @@ -63,12 +63,15 @@ [Ignore("looks as if file-URIs didn't work, revisit")] [Test] public void ShouldParseFileFromURIString() { - AllIsWellFor(Input.FromURI("file:" + TEST_FILE).Build()); + AllIsWellFor(Input.FromURI("file:" + TestResources.ANIMAL_FILE) + .Build()); } [Ignore("looks as if file-URIs didn't work, revisit")] [Test] public void ShouldParseFileFromURI() { - AllIsWellFor(Input.FromURI(new Uri("file:" + TEST_FILE)).Build()); + AllIsWellFor(Input.FromURI(new Uri("file:" + + TestResources.ANIMAL_FILE)) + .Build()); } [Test] public void ShouldParseATransformationFromSource() { @@ -102,7 +105,7 @@ } private static byte[] ReadTestFile() { - using (FileStream fs = new FileStream(TEST_FILE, FileMode.Open, + using (FileStream fs = new FileStream(TestResources.ANIMAL_FILE, FileMode.Open, FileAccess.Read)) using (MemoryStream ms = new MemoryStream()) { byte[] buffer = new byte[1024]; Copied: trunk/xmlunit/src/tests/net-core/xpath/XPathEngineTest.cs (from rev 370, trunk/xmlunit/src/tests/java-core/net/sf/xmlunit/xpath/JAXPXPathEngineTest.java) =================================================================== --- trunk/xmlunit/src/tests/net-core/xpath/XPathEngineTest.cs (rev 0) +++ trunk/xmlunit/src/tests/net-core/xpath/XPathEngineTest.cs 2010-05-03 06:49:13 UTC (rev 375) @@ -0,0 +1,148 @@ +/* + This file is licensed to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +using System.Collections.Generic; +using System.Xml; +using NUnit.Framework; +using net.sf.xmlunit.builder; +using net.sf.xmlunit.exceptions; + +namespace net.sf.xmlunit.xpath { + + [TestFixture] + public class XPathEngineTest { + + private ISource source; + + [SetUp] public void ReadSource() { + source = Input.FromFile(TestResources.BLAME_FILE).Build(); + } + + [Test] public void SelectNodesWithNoMatches() { + IEnumerable<XmlNode> i = new XPathEngine().SelectNodes("foo", + source); + Assert.IsNotNull(i); + Assert.IsFalse(i.GetEnumerator().MoveNext()); + } + + [Test] public void SelectNodesWithSingleMatch() { + IEnumerable<XmlNode> i = new XPathEngine().SelectNodes("//ul", + source); + Assert.IsNotNull(i); + IEnumerator<XmlNode> it = i.GetEnumerator(); + Assert.IsTrue(it.MoveNext()); + Assert.AreEqual("ul", it.Current.Name); + Assert.IsFalse(it.MoveNext()); + } + + [Test] public void SelectNodesWithMultipleMatchs() { + IEnumerable<XmlNode> i = new XPathEngine().SelectNodes("//li", + source); + Assert.IsNotNull(i); + int count = 0; + foreach (XmlNode n in i) { + count++; + Assert.AreEqual("li", n.Name); + } + Assert.AreEqual(4, count); + } + + [Test] + public void SelectNodesWithInvalidXPath() { + try { + new XPathEngine().SelectNodes("//li[", source); + Assert.Fail("expected an exception"); + } catch (XMLUnitException) { + // expected + } + } + + [Test] public void EvaluateWithNoMatches() { + Assert.AreEqual(string.Empty, new XPathEngine().Evaluate("foo", + source)); + } + + [Test] public void EvaluateWithSingleMatch() { + Assert.AreEqual("Don't blame it on the...", + new XPathEngine().Evaluate("//title", source)); + } + + [Test] public void EvaluateWithSingleMatchTextSelector() { + Assert.AreEqual("Don't blame it on the...", + new XPathEngine().Evaluate("//title/text()", + source)); + } + + [Test] public void EvaluateWithMultipleMatches() { + Assert.AreEqual("sunshine", + new XPathEngine().Evaluate("//li", source)); + } + + [Test] + public void EvaluateWithInvalidXPath() { + try { + new XPathEngine().Evaluate("//li[", source); + Assert.Fail("expected an exception"); + } catch (XMLUnitException) { + // expected + } + } + + [Test] public void SelectNodesWithNS() { + XPathEngine e = new XPathEngine(); + source = Input.FromMemory("<n:d xmlns:n='urn:test:1'><n:e/></n:d>") + .Build(); + Dictionary<string, string> m = new Dictionary<string, string>(); + m["x"] = "urn:test:1"; + e.NamespaceContext = m; + IEnumerable<XmlNode> it = e.SelectNodes("/x:d/x:e", source); + Assert.IsTrue(it.GetEnumerator().MoveNext()); + } + + [Test] public void SelectNodesWithDefaultNS() { + XPathEngine e = new XPathEngine(); + source = Input.FromMemory("<d xmlns='urn:test:1'><e/></d>") + .Build(); + Dictionary<string, string> m = new Dictionary<string, string>(); + m["x"] = "urn:test:1"; + e.NamespaceContext = m; + IEnumerable<XmlNode> it = e.SelectNodes("/x:d/x:e", source); + Assert.IsTrue(it.GetEnumerator().MoveNext()); + } + + // throws an exception "'/:d/:e' has an invalid token." + public void SelectNodesWithDefaultNSEmptyPrefix() { + XPathEngine e = new XPathEngine(); + source = Input.FromMemory("<d xmlns='urn:test:1'><e/></d>") + .Build(); + Dictionary<string, string> m = new Dictionary<string, string>(); + m[string.Empty] = "urn:test:1"; + e.NamespaceContext = m; + IEnumerable<XmlNode> it = e.SelectNodes("/:d/:e", source); + Assert.IsTrue(it.GetEnumerator().MoveNext()); + } + + // doesn't match + public void SelectNodesWithDefaultNSNoPrefix() { + XPathEngine e = new XPathEngine(); + source = Input.FromMemory("<d xmlns='urn:test:1'><e/></d>") + .Build(); + Dictionary<string, string> m = new Dictionary<string, string>(); + m[string.Empty] = "urn:test:1"; + e.NamespaceContext = m; + IEnumerable<XmlNode> it = e.SelectNodes("/d/e", source); + Assert.IsTrue(it.GetEnumerator().MoveNext()); + } + } +} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |