/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file 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. */ // // Various DOM tests. // Contents include // 1. Basic functionality for DOMString // 2. Regression tests for bugs fixed. // All individual are wrapped in a memory leak checker. // // DOM Level 3: // 1. textContent // 2. userData // 3. isEqualNode // // This is NOT a complete test of DOM functionality. // package dom.mem; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import org.apache.xerces.dom.DOMImplementationImpl; import org.apache.xerces.dom.DocumentImpl; import org.apache.xerces.dom.NodeImpl; import org.w3c.dom.Attr; import org.w3c.dom.CDATASection; import org.w3c.dom.Comment; import org.w3c.dom.DOMException; import org.w3c.dom.DOMImplementation; import org.w3c.dom.Document; import org.w3c.dom.DocumentFragment; import org.w3c.dom.DocumentType; import org.w3c.dom.Element; import org.w3c.dom.EntityReference; import org.w3c.dom.NamedNodeMap; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Notation; import org.w3c.dom.ProcessingInstruction; import org.w3c.dom.Text; import org.w3c.dom.UserDataHandler; import dom.util.Assertion; public class Test { /** * version 3.0 01/25/99 * * @return boolean * @param node java.lang.Object * @param mNameIndex int * @param signatureIndex int * @param parameters java.lang.Object[] * @param code short * * @author Philip W. Davis */ public static boolean DOMExceptionsTest(Object node, String methodName, Class[] methodSignature, Object[] parameters, short code) { boolean asExpected = false; Method method; try { method = node.getClass().getMethod(methodName,methodSignature); method.invoke(node, parameters); } catch(InvocationTargetException exc) { Throwable realE = exc.getTargetException(); if(realE instanceof DOMException) { asExpected = (((DOMException)realE).code== code); if(!asExpected) System.out.println("Wrong DOMException(" + ((DOMException)realE).code + ")"); } else { System.out.println("Wrong Exception (" + code + ")"); } if(!asExpected) { System.out.println("Expected DOMException (" + code + ") not thrown"); } } catch(Exception exc) { System.out.println("test invocation failure (" + exc + ")"); } return (asExpected); } public static void main(String argv[]) { System.out.println("DOM Memory Test..."); // // Test Doc01 Create a new empty document // { Document doc; doc = new DocumentImpl(); } // // Test Doc02 Create one of each kind of node using the // document createXXX methods. // Watch for memory leaks. // { // Do all operations in a preconditioning step, to force the // creation of implementation objects that are set up on first use. // Don't watch for leaks in this block (no / ) Document doc = new DocumentImpl(); Element el = doc.createElement("Doc02Element"); DocumentFragment frag = doc.createDocumentFragment (); Text text = doc.createTextNode("Doc02TextNode"); Comment comment = doc.createComment("Doc02Comment"); CDATASection cdataSec = doc.createCDATASection("Doc02CDataSection"); DocumentType docType = doc.getImplementation().createDocumentType("Doc02DocumentType", null, null); Notation notation = ((DocumentImpl) doc).createNotation("Doc02Notation"); ProcessingInstruction pi = doc.createProcessingInstruction("Doc02PITarget", "Doc02PIData"); NodeList nodeList = doc.getElementsByTagName("*"); } { Document doc = new DocumentImpl(); Element el = doc.createElement("Doc02Element"); } { Document doc = new DocumentImpl(); DocumentFragment frag = doc.createDocumentFragment (); }; { Document doc = new DocumentImpl(); Element el = doc.createElement("Doc02Element"); } { Document doc = new DocumentImpl(); Text text = doc.createTextNode("Doc02TextNode"); } { Document doc = new DocumentImpl(); Comment comment = doc.createComment("Doc02Comment"); } { Document doc = new DocumentImpl(); CDATASection cdataSec = doc.createCDATASection("Doc02CDataSection"); } { Document doc = new DocumentImpl(); DocumentType docType = doc.getImplementation().createDocumentType("Doc02DocumentType", null, null); } { Document doc = new DocumentImpl(); Notation notation = ((DocumentImpl)doc).createNotation("Doc02Notation"); } { Document doc = new DocumentImpl(); ProcessingInstruction pi = doc.createProcessingInstruction("Doc02PITarget", "Doc02PIData"); } { Document doc = new DocumentImpl(); Attr attribute = doc.createAttribute("Doc02Attribute"); } { Document doc = new DocumentImpl(); EntityReference er = doc.createEntityReference("Doc02EntityReference"); } { Document doc = new DocumentImpl(); NodeList nodeList = doc.getElementsByTagName("*"); } // // Doc03 - Create a small document tree // { Document doc = new DocumentImpl(); Element rootEl = doc.createElement("Doc03RootElement"); doc.appendChild(rootEl); Text textNode = doc.createTextNode("Doc03 text stuff"); Assertion.verify(rootEl.getFirstChild() == null); Assertion.verify(rootEl.getLastChild() == null); rootEl.appendChild(textNode); Assertion.verify(rootEl.getFirstChild() == textNode); Assertion.verify(rootEl.getLastChild() == textNode); Assertion.verify(textNode.getNextSibling() == null); Assertion.verify(textNode.getPreviousSibling() == null); Text textNode2 = doc.createTextNode("Doc03 text stuff"); rootEl.appendChild(textNode2); Assertion.verify(textNode.getNextSibling() == textNode2); Assertion.verify(textNode2.getNextSibling() == null); Assertion.verify(textNode.getPreviousSibling() == null); Assertion.verify(textNode2.getPreviousSibling() == textNode); Assertion.verify(rootEl.getFirstChild() == textNode); Assertion.verify(rootEl.getLastChild() == textNode2); NodeList nodeList = doc.getElementsByTagName("*"); }; // // Attr01 // { Document doc = new DocumentImpl(); Element rootEl = doc.createElement("RootElement"); doc.appendChild(rootEl); { Attr attr01 = doc.createAttribute("Attr01"); rootEl.setAttributeNode(attr01); } { Attr attr02 = doc.createAttribute("Attr01"); rootEl.setAttributeNode(attr02); } }; // // Attr02 // { Document doc = new DocumentImpl(); Element rootEl = doc.createElement("RootElement"); doc.appendChild(rootEl); Attr attr01 = doc.createAttribute("Attr02"); rootEl.setAttributeNode(attr01); Attr attr02 = doc.createAttribute("Attr02"); rootEl.setAttributeNode(attr02); } // // Attr03 // { Document doc = new DocumentImpl(); Element rootEl = doc.createElement("RootElement"); doc.appendChild(rootEl); Attr attr01 = doc.createAttribute("Attr03"); rootEl.setAttributeNode(attr01); attr01.setValue("Attr03Value1"); attr01.setValue("Attr03Value2"); } // // Text01 // { Document doc = new DocumentImpl(); Element rootEl = doc.createElement("RootElement"); doc.appendChild(rootEl); Text txt1 = doc.createTextNode("Hello Goodbye"); rootEl.appendChild(txt1); txt1.splitText(6); rootEl.normalize(); } // // Notation01 // { /* DOMImplementation impl = DOMImplementationImpl.getDOMImplementation(); DocumentType dt = impl.createDocumentType("DocType_for_Notation01", null, null, null); doc.appendChild(dt); NamedNodeMap notationMap = dt.getNotations(); Notation nt1 = ((DocumentImpl) doc).createNotation("Notation01"); ((NotationImpl) nt1).setPublicId("Notation01PublicId"); notationMap.setNamedItem (nt1); Notation nt2 = (Notation)notationMap.getNamedItem("Notation01"); Assertion.assert(nt1==nt2); nt2 = new NotationImpl((DocumentImpl)doc, null); nt1 = null; nt2 = (Notation)notationMap.getNamedItem("Notation01"); */ } // // NamedNodeMap01 - comparison operators. // { NamedNodeMap nnm = null; Assertion.verify(nnm == null); Document doc = new DocumentImpl(); nnm = doc.getAttributes(); // Should be null, because node type // is not Element. Assertion.verify(nnm == null); Assertion.verify(!(nnm != null)); Element el = doc.createElement("NamedNodeMap01"); NamedNodeMap nnm2 = el.getAttributes(); // Should be an empty, but non-null map. Assertion.verify(nnm2 != null); Assertion.verify(nnm != nnm2); nnm = nnm2; Assertion.verify(nnm == nnm2); } // // importNode quick test // { Document doc1 = new DocumentImpl(); Document doc2 = new DocumentImpl(); Element el1 = doc1.createElement("abc"); doc1.appendChild(el1); Assertion.verify(el1.getParentNode() != null); el1.setAttribute("foo", "foovalue"); Node el2 = doc2.importNode(el1, true); Assertion.verify(el2.getParentNode() == null); String tagName = el2.getNodeName(); Assertion.equals(tagName, "abc"); Assertion.verify(el2.getOwnerDocument() == doc2); Assertion.equals(((Element) el2).getAttribute("foo"), "foovalue"); Assertion.verify(doc1 != doc2); } // // getLength() tests. Both Node CharacterData and NodeList implement // getLength(). Early versions of the DOM had a clash // between the two, originating in the implementation class // hirearchy, which has NodeList as a (distant) base class // of CharacterData. This is a regression test to verify // that the problem stays fixed. // { Document doc = new DocumentImpl(); Text tx = doc.createTextNode("Hello"); Element el = doc.createElement("abc"); el.appendChild(tx); int textLength = tx.getLength(); Assertion.verify(textLength == 5); NodeList nl = tx.getChildNodes(); int nodeListLen = nl.getLength(); Assertion.verify(nodeListLen == 0); nl = el.getChildNodes(); nodeListLen = nl.getLength(); Assertion.verify(nodeListLen == 1); } // // NodeList - comparison operators, basic operation. // { NodeList nl = null; NodeList nl2 = null; Assertion.verify(nl == null); Assertion.verify(!(nl != null)); Assertion.verify(nl == nl2); Document doc = new DocumentImpl(); nl = doc.getChildNodes(); // Should be non-null, but empty Assertion.verify(nl != null); int len = nl.getLength(); Assertion.verify(len == 0); Element el = doc.createElement("NodeList01"); doc.appendChild(el); len = nl.getLength(); Assertion.verify(len == 1); Assertion.verify(nl != nl2); nl2 = nl; Assertion.verify(nl == nl2); } // // Name validity checking. // { Document doc = new DocumentImpl(); Assertion.verify(DOMExceptionsTest(doc, "createElement", new Class[]{String.class}, new Object[]{"!@@ bad element name"}, DOMException.INVALID_CHARACTER_ERR)); } // // Assignment ops return value // { Document doc = new DocumentImpl(); Element el = doc.createElement("NodeList01"); doc.appendChild(el); Element n1, n2, n3; n1 = n2 = n3 = el; Assertion.verify(n1 == n2); Assertion.verify(n1 == n3); Assertion.verify(n1 == el); Assertion.verify(n1 != null); n1 = n2 = n3 = null; Assertion.verify(n1 == null); } // // Cloning of a node with attributes. Regression test for a ref counting // bug in attributes of cloned nodes that occured when the "owned" flag // was not set in the clone. // { Document doc = new DocumentImpl(); Element root = doc.createElement("CTestRoot"); root.setAttribute("CTestAttr", "CTestAttrValue"); String s = root.getAttribute("CTestAttr"); Assertion.equals(s, "CTestAttrValue"); Element cloned = (Element)root.cloneNode(true); Attr a = cloned.getAttributeNode("CTestAttr"); Assertion.verify(a != null); s = a.getValue(); Assertion.equals(s, "CTestAttrValue"); a = null; a = cloned.getAttributeNode("CTestAttr"); Assertion.verify(a != null); s = a.getValue(); Assertion.equals(s, "CTestAttrValue"); } // // Cloning of default attributes. // { Document doc = new DocumentImpl(); Element root = doc.createElement("CTestRoot"); root.setAttribute("attr", "attrValue"); Attr attr = root.getAttributeNode("attr"); // turn this into a default attribute ((org.apache.xerces.dom.AttrImpl)attr).setSpecified(false); // add another attribute (this one is specified) root.setAttribute("attr2", "attr2Value"); Element cloned = (Element)root.cloneNode(true); Attr a = cloned.getAttributeNode("attr"); Assertion.verify(a.getSpecified() == false); a = cloned.getAttributeNode("attr2"); Assertion.verify(a.getSpecified() == true); // now if we clone the default attribute by itself the clone should be // specified a = (Attr)attr.cloneNode(true); Assertion.verify(a.getSpecified() == true); } // // DOM Level 2 tests. These should be split out as a separate test. // // // hasFeature. The set of supported options tested here is for Xerces 1.1 // { DOMImplementation impl = DOMImplementationImpl.getDOMImplementation(); Assertion.verify(impl.hasFeature("XML", "2.0") == true); Assertion.verify(impl.hasFeature("XML", null) == true); // We also support 1.0 Assertion.verify(impl.hasFeature("XML", "1.0") == true); //Assertion.verify(impl.hasFeature("XML", "3.0") == false); Assertion.verify(impl.hasFeature("Traversal", null) == true); Assertion.verify(impl.hasFeature("HTML", null) == false); Assertion.verify(impl.hasFeature("Views", null) == false); Assertion.verify(impl.hasFeature("StyleSheets", null) == false); Assertion.verify(impl.hasFeature("CSS", null) == false); Assertion.verify(impl.hasFeature("CSS2", null) == false); Assertion.verify(impl.hasFeature("Events", null) == true); Assertion.verify(impl.hasFeature("UIEvents", null) == false); Assertion.verify(impl.hasFeature("MouseEvents", null) == false); Assertion.verify(impl.hasFeature("MutationEvents", null) == true); Assertion.verify(impl.hasFeature("HTMLEvents", null) == false); Assertion.verify(impl.hasFeature("Range", null) == true); } // // CreateDocumentType // { DOMImplementation impl = DOMImplementationImpl.getDOMImplementation(); String qName = "foo:docName"; String pubId = "pubId"; String sysId = "http://sysId"; DocumentType dt = impl.createDocumentType(qName, pubId, sysId); Assertion.verify(dt != null); Assertion.verify(dt.getNodeType() == Node.DOCUMENT_TYPE_NODE); Assertion.equals(dt.getNodeName(), qName); Assertion.verify(dt.getNamespaceURI() == null); Assertion.verify(dt.getPrefix() == null); Assertion.verify(dt.getLocalName() == null); Assertion.equals(dt.getPublicId(), pubId); Assertion.equals(dt.getSystemId(), sysId); Assertion.verify(dt.getInternalSubset() == null); Assertion.verify(dt.getOwnerDocument() == null); NamedNodeMap nnm = dt.getEntities(); Assertion.verify(nnm.getLength() == 0); nnm = dt.getNotations(); Assertion.verify(nnm.getLength() == 0); // // Qualified name without prefix should also work. // qName = "docName"; dt = impl.createDocumentType(qName, pubId, sysId); Assertion.verify(dt != null); Assertion.verify(dt.getNodeType() == Node.DOCUMENT_TYPE_NODE); Assertion.equals(dt.getNodeName(), qName); Assertion.verify(dt.getNamespaceURI() == null); Assertion.verify(dt.getPrefix() == null); Assertion.verify(dt.getLocalName() == null); Assertion.equals(dt.getPublicId(), pubId); Assertion.equals(dt.getSystemId(), sysId); Assertion.verify(dt.getInternalSubset() == null); Assertion.verify(dt.getOwnerDocument() == null); // Creating a DocumentType with invalid or malformed qName should fail. Assertion.verify(DOMExceptionsTest(impl, "createDocumentType", new Class[]{String.class, String.class, String.class}, new Object[]{"