// XmlAttributeTests.cs : Tests for the XmlAttribute class // // Author: Mike Kestner // Author: Martin Willemoes Hansen // // (C) 2002 Mike Kestner // (C) 2003 Martin Willemoes Hansen using System; using System.IO; using System.Xml; using NUnit.Framework; namespace MonoTests.System.Xml { [TestFixture] public class XmlAttributeTests : Assertion { XmlDocument doc; XmlAttribute attr; bool inserted; bool changed; bool removed; [SetUp] public void GetReady() { doc = new XmlDocument (); attr = doc.CreateAttribute ("attr1"); attr.Value = "val1"; } private void EventNodeInserted(Object sender, XmlNodeChangedEventArgs e) { inserted = true; } private void EventNodeChanged(Object sender, XmlNodeChangedEventArgs e) { changed = true; } private void EventNodeRemoved(Object sender, XmlNodeChangedEventArgs e) { removed = true; } [Test] public void Attributes () { AssertNull (attr.Attributes); } [Test] public void AttributeInnerAndOuterXml () { attr = doc.CreateAttribute ("foo", "bar", "http://abc.def"); attr.Value = "baz"; AssertEquals ("baz", attr.InnerXml); AssertEquals ("foo:bar=\"baz\"", attr.OuterXml); } [Test] public void AttributeWithNoValue () { XmlAttribute attribute = doc.CreateAttribute ("name"); AssertEquals (String.Empty, attribute.Value); Assert (!attribute.HasChildNodes); AssertNull (attribute.FirstChild); AssertNull (attribute.LastChild); AssertEquals (0, attribute.ChildNodes.Count); } [Test] public void AttributeWithValue () { XmlAttribute attribute = doc.CreateAttribute ("name"); attribute.Value = "value"; AssertEquals ("value", attribute.Value); Assert (attribute.HasChildNodes); AssertNotNull (attribute.FirstChild); AssertNotNull (attribute.LastChild); AssertEquals (1, attribute.ChildNodes.Count); AssertEquals (XmlNodeType.Text, attribute.ChildNodes [0].NodeType); AssertEquals ("value", attribute.ChildNodes [0].Value); } [Test] [ExpectedException (typeof (ArgumentException))] public void CheckPrefixWithNamespace () { XmlDocument doc = new XmlDocument (); doc.LoadXml (""); // hogehoge does not match to any namespace. AssertEquals ("xmlns:foo", doc.DocumentElement.Attributes [0].Name); doc.DocumentElement.Attributes [0].Prefix="hogehoge"; doc.Save (Console.Out); } [Test] public void NamespaceAttributes () { try { doc.CreateAttribute ("", "xmlns", "urn:foo"); Assertion.Fail ("Creating xmlns attribute with invalid nsuri should be error."); } catch (Exception) { } doc.LoadXml (""); try { doc.DocumentElement.SetAttribute ("xmlns", "urn:foo", "urn:bar"); Assertion.Fail ("SetAttribute for xmlns with invalid nsuri should be error."); } catch (ArgumentException) { } } [Test] public void HasChildNodes () { Assert (attr.HasChildNodes); } [Test] public void Name () { AssertEquals ("attr1", attr.Name); } [Test] public void NodeType () { AssertEquals (XmlNodeType.Attribute, attr.NodeType); } [Test] public void OwnerDocument () { AssertSame (doc, attr.OwnerDocument); } [Test] public void ParentNode () { AssertNull ("Attr parents not allowed", attr.ParentNode); } [Test] public void Value () { AssertEquals ("val1", attr.Value); } [Test] public void SetInnerTextAndXml () { string original = doc.OuterXml; doc.LoadXml (""); XmlAttribute attr = doc.DocumentElement.Attributes ["name"]; attr.InnerText = "a&b"; AssertEquals ("setInnerText", "a&b", attr.Value); attr.InnerXml = "a&b"; AssertEquals ("setInnerXml", "a&b", attr.Value); attr.InnerXml = "'a&b'"; AssertEquals ("setInnerXml.InnerXml", "'a&b'", attr.InnerXml); AssertEquals ("setInnerXml.Value", "'a&b'", attr.Value); attr.InnerXml = "\"a&b\""; AssertEquals ("\"a&b\"", attr.InnerXml); attr.InnerXml = "\"a&b'"; AssertEquals ("\"a&b'", attr.InnerXml); attr.Value = ""; XmlNodeChangedEventHandler evInserted = new XmlNodeChangedEventHandler (EventNodeInserted); XmlNodeChangedEventHandler evChanged = new XmlNodeChangedEventHandler (EventNodeChanged); XmlNodeChangedEventHandler evRemoved = new XmlNodeChangedEventHandler (EventNodeRemoved); doc.NodeInserted += evInserted; doc.NodeChanged += evChanged; doc.NodeRemoved += evRemoved; try { // set_InnerText event attr.InnerText = "fire"; AssertEquals ("setInnerText.NodeInserted", false, inserted); AssertEquals ("setInnerText.NodeChanged", true, changed); AssertEquals ("setInnerText.NodeRemoved", false, removed); inserted = changed = removed = false; // set_InnerXml event attr.InnerXml = "fire"; AssertEquals ("setInnserXml.NodeInserted", true, inserted); AssertEquals ("setInnserXml.NodeChanged", false, changed); AssertEquals ("setInnserXml.NodeRemoved", true, removed); inserted = changed = removed = false; } finally { doc.NodeInserted -= evInserted; doc.NodeChanged -= evChanged; doc.NodeRemoved -= evRemoved; } } private void OnSetInnerText (object o, XmlNodeChangedEventArgs e) { if(e.NewParent.Value == "fire") doc.DocumentElement.SetAttribute ("appended", "event was fired"); } [Test] public void WriteTo () { doc.AppendChild (doc.CreateElement ("root")); doc.DocumentElement.SetAttribute ("attr",""); doc.DocumentElement.Attributes ["attr"].InnerXml = "&ent;"; StringWriter sw = new StringWriter (); XmlTextWriter xtw = new XmlTextWriter (sw); xtw.WriteStartElement ("result"); XmlAttribute attr = doc.DocumentElement.Attributes ["attr"]; attr.WriteTo (xtw); xtw.Close (); Assertion.AssertEquals ("", sw.ToString ()); } [Test] public void IdentityConstraints () { string dtd = "]>"; string xml = dtd + ""; XmlValidatingReader vr = new XmlValidatingReader (xml, XmlNodeType.Document, null); doc.Load (vr); AssertNotNull (doc.GetElementById ("id1")); AssertNotNull (doc.GetElementById ("id2")); // MS.NET BUG: Later I try to append it to another element, but // it should raise InvalidOperationException. // (and if MS.NET conform to DOM 1.0, it should be XmlException.) // XmlAttribute attr = doc.DocumentElement.FirstChild.Attributes [0]; XmlAttribute attr = doc.DocumentElement.FirstChild.Attributes.RemoveAt (0); AssertEquals ("id1", attr.Value); doc.DocumentElement.LastChild.Attributes.SetNamedItem (attr); AssertNotNull (doc.GetElementById ("id1")); XmlElement elem2 = doc.GetElementById ("id2"); // MS.NET BUG: it doesn't remove replaced attribute with SetNamedItem! // AssertNull (elem2); // AssertEquals ("2", elem2.GetAttribute ("bar")); // elem2.RemoveAttribute ("foo"); // AssertEquals ("", elem2.GetAttribute ("foo")); // MS.NET BUG: elem should be the element which has the attribute bar='1'! XmlElement elem = doc.GetElementById ("id1"); // AssertEquals ("2", elem.GetAttribute ("bar")); // Here, required attribute foo is no more required, XmlElement elemNew = doc.CreateElement ("c"); doc.DocumentElement.AppendChild (elemNew); // but once attribute is set, document recognizes this ID. elemNew.SetAttribute ("foo", "id3"); AssertNotNull (doc.GetElementById ("id3")); elemNew.RemoveAttribute ("foo"); AssertNull (doc.GetElementById ("id3")); // MS.NET BUG: multiple IDs are allowed. // In such case GetElementById fails. elemNew.SetAttribute ("foo", "id2"); // While XmlValidatingReader validated ID cannot be removed. // It is too curious for me. elem.RemoveAttribute ("foo"); // Finally... doc.RemoveAll (); AssertNull (doc.GetElementById ("id1")); AssertNull (doc.GetElementById ("id2")); AssertNull (doc.GetElementById ("id3")); } int removeAllStep; [Test] public void DefaultAttributeRemoval () { XmlDocument doc = new XmlDocument (); doc.LoadXml ("]>"); doc.NodeInserted += new XmlNodeChangedEventHandler (OnInsert); doc.NodeChanged += new XmlNodeChangedEventHandler (OnChange); doc.NodeRemoved += new XmlNodeChangedEventHandler (OnRemove); doc.DocumentElement.RemoveAll (); } private void OnInsert (object o, XmlNodeChangedEventArgs e) { if (removeAllStep == 1) AssertEquals (XmlNodeType.Text, e.Node.NodeType); else if (removeAllStep == 2) { AssertEquals ("foo", e.Node.Name); Assert (! ((XmlAttribute) e.Node).Specified); } else Fail (); removeAllStep++; } private void OnChange (object o, XmlNodeChangedEventArgs e) { Fail ("Should not be called."); } private void OnRemove (object o, XmlNodeChangedEventArgs e) { AssertEquals (0, removeAllStep); AssertEquals ("foo", e.Node.Name); removeAllStep++; } [Test] public void EmptyStringHasTextNode () { doc.LoadXml (""); XmlAttribute attr = doc.DocumentElement.GetAttributeNode ("attr"); AssertNotNull (attr); AssertEquals (1, attr.ChildNodes.Count); AssertEquals (XmlNodeType.Text, attr.ChildNodes [0].NodeType); AssertEquals (String.Empty, attr.ChildNodes [0].Value); } [Test] public void CrazyPrefix () { XmlDocument doc = new XmlDocument (); doc.AppendChild (doc.CreateElement ("foo")); doc.DocumentElement.SetAttribute ("a", "urn:a", "attr"); XmlAttribute a = doc.DocumentElement.Attributes [0]; a.Prefix ="hoge:hoge:hoge"; // This test is nothing more than ****. AssertEquals ("hoge:hoge:hoge", a.Prefix); // The resulting string is not XML (so broken), so // it should not be tested. // doc.Save (TextWriter.Null); } } }