
/*
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-2004 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.level1.core;

import org.w3c.dom.*;


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



/**
 *     The "cloneNode(deep)" method returns a copy of the node
 *     and the subtree under it if deep=true.
 *     
 *     Retrieve the second employee and invoke the
 *     "cloneNode(deep)" method with deep=true.   The
 *     method should clone this node and the subtree under it.
 *     The NodeName of each child in the returned node is 
 *     checked to insure the entire subtree under the second
 *     employee was cloned.
* @author NIST
* @author Mary Brady
* @see <a href="http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/level-one-core#ID-3A0ED0A4">http://www.w3.org/TR/1998/REC-DOM-Level-1-19981001/level-one-core#ID-3A0ED0A4</a>
*/
public final class nodeclonenodetrue 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 nodeclonenodetrue(final DOMTestDocumentBuilderFactory factory)  throws org.w3c.domts.DOMTestIncompatibleException {
      super(factory);

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

   /**
    * Runs the test case.
    * @throws Throwable Any uncaught exception causes test to fail
    */
   public void runTest() throws Throwable {
      Document doc;
      NodeList elementList;
      Node employeeNode;
      NodeList childList;
      Node clonedNode;
      NodeList clonedList;
      Node clonedChild;
      String clonedChildName;
      int length;
      java.util.List result = new java.util.ArrayList();
      
      java.util.List expectedWhitespace = new java.util.ArrayList();
      expectedWhitespace.add("#text");
      expectedWhitespace.add("employeeId");
      expectedWhitespace.add("#text");
      expectedWhitespace.add("name");
      expectedWhitespace.add("#text");
      expectedWhitespace.add("position");
      expectedWhitespace.add("#text");
      expectedWhitespace.add("salary");
      expectedWhitespace.add("#text");
      expectedWhitespace.add("gender");
      expectedWhitespace.add("#text");
      expectedWhitespace.add("address");
      expectedWhitespace.add("#text");
      
      java.util.List expectedNoWhitespace = new java.util.ArrayList();
      expectedNoWhitespace.add("employeeId");
      expectedNoWhitespace.add("name");
      expectedNoWhitespace.add("position");
      expectedNoWhitespace.add("salary");
      expectedNoWhitespace.add("gender");
      expectedNoWhitespace.add("address");
      
      doc = (Document) load("staff", true);
      elementList = doc.getElementsByTagName("employee");
      employeeNode = elementList.item(1);
      childList = employeeNode.getChildNodes();
      length = (int) childList.getLength();
      clonedNode = employeeNode.cloneNode(true);
      clonedList = clonedNode.getChildNodes();
      for (int indexN100AE = 0; indexN100AE < clonedList.getLength(); indexN100AE++) {
          clonedChild = (Node) clonedList.item(indexN100AE);
    clonedChildName = clonedChild.getNodeName();
      result.add(clonedChildName);
        }
      
      if (equals(6, length)) {
          assertEquals("nowhitespace", expectedNoWhitespace, result);
      } else {
          assertEquals("whitespace", expectedWhitespace, result);
      }
        
    }
   /**
    *  Gets URI that identifies the test.
    *  @return uri identifier of test
    */
   public String getTargetURI() {
      return "http://www.w3.org/2001/DOM-Test-Suite/level1/core/nodeclonenodetrue";
   }
   /**
    * Runs this test from the command line.
    * @param args command line arguments
    */
   public static void main(final String[] args) {
        DOMTestCase.doMain(nodeclonenodetrue.class, args);
   }
}

