
/*
This Java source file was generated by test-to-java.xsl
and is a derived work from the source document.
The source document contained the following notice:



Copyright (c) 2001 World Wide Web Consortium, 
(Massachusetts Institute of Technology, Institut National de
Recherche en Informatique et en Automatique, Keio University).  All 
Rights Reserved.  This program is distributed under the W3C's Software
Intellectual Property License.  This program is distributed in the 
hope that it will be useful, but WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
PURPOSE.  

See W3C License http://www.w3.org/Consortium/Legal/ for more details.


*/

package org.w3c.domts.level2.core;

import org.w3c.dom.*;


import org.w3c.domts.DOMTestCase;
import org.w3c.domts.DOMTestDocumentBuilderFactory;



/**
 *     The "importNode(importedNode,deep)" method for a 
 *    Document should import the given importedNode into that Document.
 *    The importedNode is of type Attr. 
 *    The ownerElement is set to null. Specified flag is set to true.
 *    Children is imported.
 *    
 *    Create a new attribute whose name is "elem:attr1" in a different document.
 *    Create a child Text node with value "importedText" for the attribute node above.
 *    Invoke method importNode(importedNode,deep) on this document with
 *    importedNode being the newly created attribute.
 *    Method should return a node whose name matches "elem:attr1" and a child node
 *    whose value equals "importedText".
 *    The returned node should belong to this document whose systemId is "staff.dtd"
* @author NIST
* @author Mary Brady
* @see <a href="http://www.w3.org/TR/DOM-Level-2-Core/core#Core-Document-importNode">http://www.w3.org/TR/DOM-Level-2-Core/core#Core-Document-importNode</a>
*/
public final class importNode01 extends DOMTestCase {

   /**
    * Constructor.
    * @param factory document factory, may not be null
    * @throws org.w3c.domts.DOMTestIncompatibleException Thrown if test is not compatible with parser configuration
    */
   public importNode01(final DOMTestDocumentBuilderFactory factory)  throws org.w3c.domts.DOMTestIncompatibleException {
      super(factory);

    //
    //   check if loaded documents are supported for content type
    //
    String contentType = getContentType();
    preload(contentType, "staffNS", true);
    preload(contentType, "staffNS", true);
    }

   /**
    * Runs the test case.
    * @throws Throwable Any uncaught exception causes test to fail
    */
   public void runTest() throws Throwable {
      Document doc;
      Document aNewDoc;
      Attr newAttr;
      Text importedChild;
      Node aNode;
      Document ownerDocument;
      Element attrOwnerElement;
      DocumentType docType;
      String system;
      boolean specified;
      NodeList childList;
      String nodeName;
      Node child;
      String childValue;
      java.util.List result = new java.util.ArrayList();
      
      java.util.List expectedResult = new java.util.ArrayList();
      expectedResult.add("elem:attr1");
      expectedResult.add("importedText");
      
      doc = (Document) load("staffNS", true);
      aNewDoc = (Document) load("staffNS", true);
      newAttr = aNewDoc.createAttribute("elem:attr1");
      importedChild = aNewDoc.createTextNode("importedText");
      aNode = newAttr.appendChild(importedChild);
      aNode = doc.importNode(newAttr, false);
      ownerDocument = aNode.getOwnerDocument();
      docType = ownerDocument.getDoctype();
      system = docType.getSystemId();
      assertNotNull("aNode", aNode);
      assertURIEquals("systemId", null, null, null, "staffNS.dtd", null, null, null, null, system);
attrOwnerElement = ((Attr) /*Node */aNode).getOwnerElement();
      assertNull("ownerElement", attrOwnerElement);
      specified = ((Attr) /*Node */aNode).getSpecified();
      assertTrue("specified", specified);
      childList = aNode.getChildNodes();
      assertSize("childList", 1, childList);
      nodeName = aNode.getNodeName();
      assertEquals("nodeName", "elem:attr1", nodeName);
      child = aNode.getFirstChild();
      childValue = child.getNodeValue();
      assertEquals("childValue", "importedText", childValue);
      }
   /**
    *  Gets URI that identifies the test.
    *  @return uri identifier of test
    */
   public String getTargetURI() {
      return "http://www.w3.org/2001/DOM-Test-Suite/level2/core/importNode01";
   }
   /**
    * Runs this test from the command line.
    * @param args command line arguments
    */
   public static void main(final String[] args) {
        DOMTestCase.doMain(importNode01.class, args);
   }
}

