package com.thoughtworks.xstream.mapper;

import com.thoughtworks.acceptance.objects.Hardware;
import com.thoughtworks.acceptance.objects.Software;
import com.thoughtworks.xstream.alias.CannotResolveClassException;

import junit.framework.TestCase;

public class ClassAliasingMapperTest extends TestCase {
	
	private ClassAliasingMapper mapper;

	protected void setUp() throws Exception {
		mapper = new ClassAliasingMapper(new DefaultMapper(Thread.currentThread().getContextClassLoader()));
	}

	public final void testAddClass () {
		assertEquals(Hardware.class,mapper.realClass("com.thoughtworks.acceptance.objects.Hardware"));
		assertEquals("com.thoughtworks.acceptance.objects.Hardware",mapper.serializedClass(Hardware.class));
		try {
			mapper.realClass("Hardware");
			fail();
		} catch (CannotResolveClassException expected) {
		}
		mapper.addClassAlias("Hardware",Hardware.class);
		assertEquals(Hardware.class,mapper.realClass("com.thoughtworks.acceptance.objects.Hardware"));
		assertEquals(Hardware.class,mapper.realClass("Hardware"));
		assertEquals("Hardware",mapper.serializedClass(Hardware.class));
	}
	
	public final void testDefaultPackage () {
		assertEquals(Hardware.class,mapper.realClass("com.thoughtworks.acceptance.objects.Hardware"));
		assertEquals("com.thoughtworks.acceptance.objects.Hardware",mapper.serializedClass(Hardware.class));
		try {
			mapper.realClass("Hardware");
			fail();
		} catch (CannotResolveClassException expected) {
		}
		mapper.addPackage(Hardware.class.getPackage());
		assertEquals(Hardware.class,mapper.realClass("com.thoughtworks.acceptance.objects.Hardware"));
		assertEquals(Hardware.class,mapper.realClass("Hardware"));
		assertEquals("Hardware",mapper.serializedClass(Hardware.class));
	}
	
	public final void testDefaultPackageOtherOrder () {
		assertEquals(Hardware.class,mapper.realClass("com.thoughtworks.acceptance.objects.Hardware"));
		assertEquals("com.thoughtworks.acceptance.objects.Hardware",mapper.serializedClass(Hardware.class));
		try {
			mapper.realClass("Hardware");
			fail();
		} catch (CannotResolveClassException expected) {
		}
		mapper.addPackage(Hardware.class.getPackage());
		//Now do the serializedClass check first.
		assertEquals("Hardware",mapper.serializedClass(Hardware.class));
		assertEquals(Hardware.class,mapper.realClass("com.thoughtworks.acceptance.objects.Hardware"));
		assertEquals(Hardware.class,mapper.realClass("Hardware"));
	}
	
	public final void testDefaultPackageOtherClass () {
		assertEquals(Software.class,mapper.realClass("com.thoughtworks.acceptance.objects.Software"));
		assertEquals("com.thoughtworks.acceptance.objects.Software",mapper.serializedClass(Software.class));
		try {
			mapper.realClass("Software");
			fail();
		} catch (CannotResolveClassException expected) {
		}
		mapper.addPackage(Hardware.class.getPackage());
		//Now do the serializedClass check first.
		assertEquals("Software",mapper.serializedClass(Software.class));
		assertEquals(Software.class,mapper.realClass("com.thoughtworks.acceptance.objects.Software"));
		assertEquals(Software.class,mapper.realClass("Software"));
	}
	
	public final void testAliasSupercedesPackage () {
		mapper.addClassAlias("sw",Software.class);
		assertEquals(Software.class,mapper.realClass("sw"));
		assertEquals("sw",mapper.serializedClass(Software.class));
		//Hardware still mapped as fully qualyfied class name.
		assertEquals(Hardware.class,mapper.realClass("com.thoughtworks.acceptance.objects.Hardware"));
		assertEquals("com.thoughtworks.acceptance.objects.Hardware",mapper.serializedClass(Hardware.class));
		mapper.addPackage(Hardware.class.getPackage());
		assertEquals(Software.class,mapper.realClass("sw"));
		assertEquals("sw",mapper.serializedClass(Software.class));
		//Hardware now mapped as short class name
		assertEquals(Hardware.class,mapper.realClass("Hardware"));
		assertEquals("Hardware",mapper.serializedClass(Hardware.class));
		mapper.addClassAlias("hw",Hardware.class);
		assertEquals(Software.class,mapper.realClass("sw"));
		assertEquals("sw",mapper.serializedClass(Software.class));
		//Class alias supercedes package alias
		assertEquals(Hardware.class,mapper.realClass("hw"));
		assertEquals("hw",mapper.serializedClass(Hardware.class));
	}
}

