
/*
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-2003 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 "feature" parameter in the
 *     isSupported(feature,version)" method is the name
 *     of the feature and the version is the version number of the
 *     feature to test.   CORE is a legal value for the feature parameter 
 *     (Test for CORE, upper case). 
 *     Legal values for the version parameter are 1.0 and 2.0
 *     (Test for 1.0).
 *     
 *     Retrieve the root node of the DOM document by invoking 
 *     the "getDocumentElement()" method.   This should create a
 *     node object on which the "isSupported(feature,version)"
 *     method is invoked with "feature" equal to "CORE" and the version equal to 1.0.
 *     The method should return a boolean "true".
* @author NIST
* @author Mary Brady
* @see <a href="http://www.w3.org/TR/DOM-Level-2-Core/core#Level-2-Core-Node-supports">http://www.w3.org/TR/DOM-Level-2-Core/core#Level-2-Core-Node-supports</a>
*/
public final class isSupported12 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 isSupported12(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", false);
    }

   /**
    * Runs the test case.
    * @throws Throwable Any uncaught exception causes test to fail
    */
   public void runTest() throws Throwable {
      java.util.List features = new java.util.ArrayList();
      features.add("Core");
      features.add("XML");
      features.add("HTML");
      features.add("Views");
      features.add("StyleSheets");
      features.add("CSS");
      features.add("CSS2");
      features.add("Events");
      features.add("UIEvents");
      features.add("MouseEvents");
      features.add("MutationEvents");
      features.add("HTMLEvents");
      features.add("Range");
      features.add("Traversal");
      features.add("bogus.bogus.bogus");
      
      Document doc;
      Node rootNode;
      String featureElement;
      boolean state;
      doc = (Document) load("staff", false);
      rootNode = doc.getDocumentElement();
      state = rootNode.isSupported("Core", "2.0");
      assertTrue("Core2", state);
      for (int indexN10078 = 0; indexN10078 < features.size(); indexN10078++) {
          featureElement = (String) features.get(indexN10078);
    state = rootNode.isSupported(featureElement, "1.0");
        }
      for (int indexN10083 = 0; indexN10083 < features.size(); indexN10083++) {
          featureElement = (String) features.get(indexN10083);
    state = rootNode.isSupported(featureElement, "2.0");
        }
      }
   /**
    *  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/isSupported12";
   }
   /**
    * Runs this test from the command line.
    * @param args command line arguments
    */
   public static void main(final String[] args) {
        DOMTestCase.doMain(isSupported12.class, args);
   }
}

