/* 
 * E-XML Library:  For XML, XML-RPC, HTTP, and related.
 * Copyright (C) 2002-2008  Elias Ross
 * 
 * genman@noderunner.net
 * http://noderunner.net/~genman
 * 
 * 1025 NE 73RD ST
 * SEATTLE WA 98115
 * USA
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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 the GNU
 * Lesser General Public License for more details.
 * 
 * $Id$
 */

package net.noderunner.exml;

import java.io.IOException;
import java.io.StringReader;

/**
 * This class is for unit testing the ElementRule class.
 *
 * @see ElementRule
 * @author Elias Ross
 * @version 1.0
 */
public class AttributeRuleTest
	extends junit.framework.TestCase
{
	public AttributeRuleTest(String name) {
		super(name);
	}

	public static void main(String[] args) {
		junit.textui.TestRunner.run(AttributeRuleTest.class);
	}

	public String[] attDefs = {
		"x CDATA #IMPLIED",
		"x (a | b | c) \"a\"",
		"x NOTATION (TeX | Tiff) #FIXED \"TeX\"",
		"x NMTOKENS #REQUIRED",
		"x NMTOKEN #IMPLIED",
		"x ID #REQUIRED",
		"x NOTATION (BOB) #REQUIRED",
		"x IDREF #REQUIRED",
		"x CDATA #REQUIRED",
		"x CDATA \"NORMAL\"",
		"x ENTITIES #IMPLIED",
		"x ENTITY \"far\""};

	public void testAllow()
		throws Exception
	{
		AttributeRule arule;
		arule = makeRule("x (a | b) #FIXED \"a\"");
		assertTrue("fixed " + arule, arule.isFixed());
		assertTrue("required " + arule, !arule.isRequired());
		assertTrue("allow " + arule, arule.allowedValue("a"));
		assertTrue("allow " + arule, !arule.allowedValue("b"));
		try {
			arule = makeRule("y (a | b) #FIXED \"c\"");
			fail("should not fix to c " + arule);
		} catch (AttributeRuleException e) {
		}
		arule = makeRule("x (a | b) #REQUIRED");
		assertTrue("fixed " + arule, !arule.isFixed());
		assertTrue("required " + arule, arule.isRequired());
		assertTrue("allow " + arule, arule.allowedValue("a"));
		assertTrue("allow " + arule, arule.allowedValue("b"));
		assertTrue("allow " + arule, !arule.allowedValue("c"));
		arule = makeRule("x (a | b) #IMPLIED");
		assertTrue("fixed " + arule, !arule.isFixed());
		assertTrue("required " + arule, !arule.isRequired());
		assertTrue("allow " + arule, arule.allowedValue("a"));
		assertTrue("allow " + arule, !arule.allowedValue("c"));
	}

	public static AttributeRule makeRule(String s)
		throws XmlException, IOException
	{
		ElementRule erule = new ElementRule();
		XmlReader reader;
		reader = new XmlReader(new StringReader(" " + s));
		reader.AttDef(erule);
		AttributeRule arule = (AttributeRule)erule.getAttributeRules().get(0);
		return arule;
	}

	public void testDefs()
		throws Exception
	{
		for (int i = 0; i < attDefs.length; i++) {
			AttributeRule arule = makeRule(attDefs[i]);
			assertNotNull("not null", arule);
			assertEquals(attDefs[i], arule.toString());
		}
	}

	public void testReq()
		throws Exception
	{
		String in = "<?xml version='1.0' ?>" +
			"<!DOCTYPE doc [" +
			"       <!ATTLIST doc gender CDATA #REQUIRED>" +
			"       <!ATTLIST doc fun (y|n) #REQUIRED>" +
			"	<!ELEMENT doc EMPTY>" +
			"]>";
		Element e;
		XmlReader reader;
		reader = new XmlReader(new StringReader(in + "<doc gender='m' fun='y'/>"));
		e = reader.document().getRootElement();
		assertEquals(e.getAttValue("gender"), "m");
		try {
			reader = new XmlReader(new StringReader(in + "<doc fun='n'/>"));
			reader.document();
			fail("require gender");
		} catch (XmlException xe) {
			assertTrue(xe instanceof AttributeRuleException);
		}
		try {
			reader = new XmlReader(new StringReader(in + "<doc gender='m'/>"));
			reader.document();
			fail("require fun");
		} catch (XmlException xe) {
			assertTrue(xe instanceof AttributeRuleException);
		}
	}

	public void testDef()
		throws Exception
	{
		String in = "<?xml version='1.0' ?>" +
			"<!DOCTYPE doc [" +
			"       <!ATTLIST doc fun (y|n) 'y'>" +
			"       <!ATTLIST doc gender CDATA 'm'>" +
			"	<!ELEMENT doc EMPTY>" +
			"]>";
		XmlReader reader;
		reader = new XmlReader(new StringReader(in + "<doc gender='f' fun='n'/>"));
		Element e;
		e = reader.document().getRootElement();
		assertEquals(e.getAttValue("gender"), "f");
		assertEquals(e.getAttValue("fun"), "n");
		// accept defaults
		reader = new XmlReader(new StringReader(in + "<doc/>"));
		e = reader.document().getRootElement();
		assertEquals("m", e.getAttValue("gender"));
		assertEquals("y", e.getAttValue("fun"));
		// accept mix
		reader = new XmlReader(new StringReader(in + "<doc fun='n'/>"));
		e = reader.document().getRootElement();
		assertEquals(e.getAttValue("gender"), "m");
		assertEquals(e.getAttValue("fun"), "n");
	}

}
