/*
 * Created on Aug 2, 2005
 * 
 * $Log$
 * Revision 1.2  2005/09/21 22:00:46  dsowen
 * Split out the access stuff into accesslib.
 * New Creator interface off-loads object creation to user.
 *
 * Revision 1.1  2005/08/19 17:51:17  dsowen
 * Fixed: NPEs when using accessors from paths, &c.  Included tests.
 * Fixed: parsing exception wasn't very enlightening.
 *
 * Revision 1.2  2005/08/12 19:01:46  dsowen
 * Feature: can automatically fill missing parts of a graph.
 *
 * Revision 1.1  2005/08/03 00:35:29  dsowen
 * Initial commit.
 *
 */
package ws.fugue88;

import java.util.HashMap;

import junit.framework.TestCase;
import ws.fugue88.access.Accessor;
import ws.fugue88.jpath.Context;
import ws.fugue88.jpath.ContextFactory;
import ws.fugue88.jpath.GraphCreator;
import ws.fugue88.jpath.SimplePathParser;

/**
 * @author dsowen
 */
public class ContextTest extends TestCase {

	public void testFieldIdentifier() throws Exception
	{
		class A {

			String b = "test";
		}
		A a = new A();

		ContextFactory factory = new ContextFactory();
		Context context = factory.createContext(a, GraphCreator.NULL);
		assertSame(a.b, context.getTarget(new SimplePathParser().parse("/b")));

		Accessor accessor = context.getTargetAccessor(new SimplePathParser().parse("/b"));
		assertSame(a.b, accessor.getValue());
		accessor.setValue("done");
		assertEquals("done", accessor.getValue());
		assertEquals("done", a.b);
	}

	public void testGetterIdentifier() throws Exception
	{
		class A {

			String getB()
			{
				return "test";
			}
		}
		A a = new A();

		ContextFactory factory = new ContextFactory();
		Context context = factory.createContext(a, GraphCreator.NULL);
		assertEquals("test",
				context.getTarget(new SimplePathParser().parse("/b")));
		try {
			context.getTargetAccessor(new SimplePathParser().parse("/b")).setValue(
					"done");
			assertTrue(false);
		} catch(UnsupportedOperationException e) {}
	}

	public void testGetterSetterIdentifier() throws Exception
	{
		class A {

			String getB()
			{
				return x;
			}

			void setB(String s)
			{
				x = s;
			}

			String x = "test";
		}
		A a = new A();

		ContextFactory factory = new ContextFactory();
		Context context = factory.createContext(a, GraphCreator.NULL);
		assertEquals("test",
				context.getTarget(new SimplePathParser().parse("/b")));
		context.getTargetAccessor(new SimplePathParser().parse("/b")).setValue(
				"done");
		assertEquals("done", a.getB());
	}

	public void testKey() throws Exception
	{
		class A {

			HashMap b = new HashMap();

			A()
			{
				b.put("c", "test");
			}
		}
		A a = new A();

		ContextFactory factory = new ContextFactory();
		Context context = factory.createContext(a, GraphCreator.NULL);
		assertEquals("test",
				context.getTarget(new SimplePathParser().parse("/b['c']")));
		context.getTargetAccessor(new SimplePathParser().parse("/b['c']")).setValue(
				"done");
		assertEquals("done", a.b.get("c"));
	}

	public void testEarlyNull() throws Exception
	{
		class A {

			String s;
		}
		class B {

			A a;
		}
		B b = new B();

		ContextFactory factory = new ContextFactory();
		Context context = factory.createContext(b, GraphCreator.NULL);
		assertNull(context.getTarget(new SimplePathParser().parse("/a/s")));
		assertNull(b.a);
	}

	static class A {

		String s;
	}

	public void testAutoGraphTargets() throws Exception
	{
		class B {

			A a;
		}
		B b = new B();

		ContextFactory factory = new ContextFactory();
		Context context = factory.createContext(b, GraphCreator.DEFAULT);
		assertNull(context.getTarget(new SimplePathParser().parse("/a/s")));
		assertNotNull(b.a);
		assertNull(b.a.s);
	}

	public void testAutoGraphAccessors() throws Exception
	{
		class B {

			A a;
		}
		B b = new B();

		ContextFactory factory = new ContextFactory();
		Context context = factory.createContext(b, GraphCreator.DEFAULT);
		Accessor accessor = context.getTargetAccessor(new SimplePathParser().parse("/a/s"));
		assertNotNull(b.a);
		assertNull(b.a.s);
	}

	private static class PrivateClass {

		String s;

		private PrivateClass()
		{
		}
	}

	public void testConstructPrivate() throws Exception
	{
		class B {

			PrivateClass x;
		}
		B b = new B();

		ContextFactory factory = new ContextFactory();
		Context context = factory.createContext(b, GraphCreator.DEFAULT);
		assertNull(context.getTarget(new SimplePathParser().parse("/x/s")));
		assertNotNull(b.x);
		assertNull(b.x.s);
	}
}