package org.jdom.tests;

import junit.framework.Test;
import junit.framework.TestSuite;
import junit.ui.LoadingTestRunner;

import org.jdom.ProcessingInstruction;
import org.jdom.IllegalNameException;
import org.jdom.IllegalDataException;

import java.util.Hashtable;

public class ProcessingInstructionTest extends junit.framework.TestCase {
   

  public ProcessingInstructionTest(String name) {
    super(name); 
  }

  private ProcessingInstruction stylesheetA;
  private ProcessingInstruction stylesheetB;
  private ProcessingInstruction robotsA;
  private ProcessingInstruction robotsB;
  private ProcessingInstruction php;

  protected void setUp() {

    stylesheetA = new ProcessingInstruction("xml-stylesheet", 
     "href=\"baseball.xsl\" type=\"text/xml\"");
    php = new ProcessingInstruction("php", 
        "mysql_connect(\"database.unc.edu\", \"clerk\", \"password\");\n" + 
        "$result = mysql(\"CYNW\", \"SELECT LastName, FirstName FROM Employees;\n" +  
        "ORDER BY LastName, FirstName\"); ;\\n" + 
        "$i = 0;;\n" + 
        "while ($i < mysql_numrows ($result)) {;\\n" + 
        "  $fields = mysql_fetch_row($result);\\n" + 
        "   echo \"<person>$fields[1] $fields[0] </person>\\r\\n\";\n" + 
        "   $i++;\n" + 
        "}\n" +
        "mysql_close();\n"
    );
    robotsA = new ProcessingInstruction("robots", "index=\"yes\" follow=\"no\"");
    
    Hashtable h = new Hashtable();
    h.put("index", "yes");
    h.put("follow", "no");
    robotsB = new ProcessingInstruction("robots", h);
    
    Hashtable s = new Hashtable();
    s.put("href", "baseball.xsl");
    s.put("type", "text/xml");
    stylesheetB = new ProcessingInstruction("xml-stylesheet", s);
    
    
  }

  public void testClone() {
    
    ProcessingInstruction piClone = (ProcessingInstruction) stylesheetA.clone();
    assertEquals(stylesheetA.getTarget(), piClone.getTarget());    
    assertEquals(stylesheetA.getData(), piClone.getData());    

    piClone = (ProcessingInstruction) robotsA.clone();
    assertEquals(robotsA.getTarget(), piClone.getTarget());    
    assertEquals(robotsA.getData(), piClone.getData());    

    piClone = (ProcessingInstruction) php.clone();
    assertEquals(php.getTarget(), piClone.getTarget());    
    assertEquals(php.getData(), piClone.getData());    

    assert(!stylesheetA.clone().equals(stylesheetA));   
    assert(!stylesheetB.clone().equals(stylesheetA));   
    assert(!robotsA.clone().equals(robotsA));   
    assert(!robotsA.clone().equals(robotsB));   
    assert(!php.clone().equals(php));   
    
  }
  
  public void testGetTarget() {
    assertEquals(stylesheetA.getTarget(), "xml-stylesheet");    
    assertEquals(stylesheetB.getTarget(), "xml-stylesheet");    
    assertEquals(robotsA.getTarget(), "robots");    
    assertEquals(robotsB.getTarget(), "robots");    
    assertEquals(php.getTarget(), "php");    
  }
  
  public void testConstructor() {
    
    try {
      new ProcessingInstruction("bad name", "some data");
      fail("Expected IllegalNameException");
    }
    catch (IllegalNameException ex) { // expected result
    }  
    
    try {
      new ProcessingInstruction("", "some data");
      fail("Expected IllegalNameException");
    }
    catch (IllegalNameException ex) { // expected result
    }  
    
    try {
      new ProcessingInstruction("879879", "some data");
      fail("Expected IllegalNameException");
    }
    catch (IllegalNameException ex) { // expected result
    }  
    
    try {
      new ProcessingInstruction("8yut", "some data");
      fail("Expected IllegalNameException");
    }
    catch (IllegalNameException ex) { // expected result
    }  
    
    try {
      new ProcessingInstruction("xml", "some data");
      fail("Expected IllegalNameException");
    }
    catch (IllegalNameException ex) { // expected result
    }  
    
    try {
      new ProcessingInstruction("Xml", "some data");
      fail("Expected IllegalNameException");
    }
    catch (IllegalNameException ex) { // expected result
    }  
    
    try {
      new ProcessingInstruction("XML", "some data");
      fail("Expected IllegalNameException");
    }
    catch (IllegalNameException ex) { // expected result
    }  
    
    try {
      new ProcessingInstruction("tryu", "some ?> data");
      fail("Expected IllegalDataException");
    }
    catch (IllegalDataException ex) { // expected result
    }  
    
    try {
      new ProcessingInstruction("tryu", "?>");
      fail("Expected IllegalDataException");
    }
    catch (IllegalDataException ex) { // expected result
    }  
    
    try {
      new ProcessingInstruction("hyut%jkdh", "some data");
      fail("Expected IllegalNameException");
    }
    catch (IllegalNameException ex) { // expected result
    }  
    
  }
  

  public void testToString() {
    
    assertNotNull(stylesheetA.toString());   
    assertNotNull(robotsA.toString());   
    assertNotNull(php.toString());   
    
  }
  
  public void testGetSerializedForm() {
    
    String s = stylesheetA.getSerializedForm();
    assertNotNull(s);   
    assert(s.startsWith("<?" + stylesheetA.getTarget()));
    assert(s.endsWith("?>"));  

    s = robotsA.getSerializedForm();
    assertNotNull(s);   
    assert(s.startsWith("<?" + robotsA.getTarget()));
    assert(s.endsWith("?>"));  

    s = php.getSerializedForm();
    assertNotNull(s);   
    assert(s.startsWith("<?" + php.getTarget()));
    assert(s.endsWith("?>"));  

  }
  
  public void testEquals() {
    
    assert(!stylesheetA.equals(stylesheetB));
    assert(!robotsA.equals(stylesheetB));
    assert(!robotsA.equals(robotsB));
    assertEquals(robotsA, robotsA);
    assertEquals(stylesheetB, stylesheetB);
    
  }
  
  public void testHashCode() {
    
    assertEquals(stylesheetA.hashCode(), stylesheetA.hashCode());
    assertEquals(robotsA.hashCode(), robotsA.hashCode());
    assert(robotsA.hashCode() != robotsB.hashCode());
    
  }
  
  public static Test suite() { 
    return new TestSuite(ProcessingInstructionTest.class); 
  }

	public static void main (String[] args) {
	  String[] tests = {"org.jdom.tests.ProcessingInstructionTest"};
		LoadingTestRunner.main(tests);
	}

}