/*
 * Copyright 2006 Takahiro Nakamura.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package woolpack.utils;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import junit.framework.TestCase;

public class DelegationMapTest extends TestCase {
	private final Map<String,String> base = new HashMap<String,String>();
	private final Map<String,String> map = new DelegationMap<String,String>(base);

	public void testConstructor(){
		try{
			new DelegationMap<String,String>(null);
			fail();
		}catch(NullPointerException expected){
		}
	}
	
	public void testNormal(){
		map.put("key0", "value0");
		{
			final Map<String,String> tmpMap = new HashMap<String,String>();
			tmpMap.put("key1", "value1");
			tmpMap.put("key2", "value2");
			map.putAll(tmpMap);
		}

		assertEquals(base.toString(), map.toString());
		assertEquals(base.hashCode(), map.hashCode());
		assertTrue(map.equals(base));
		
		{
			final Set<String> expected = new HashSet<String>();
			expected.add("key0");
			expected.add("key1");
			expected.add("key2");
			assertTrue(expected.containsAll(map.keySet()));
			assertTrue(map.keySet().containsAll(expected));
		}
		{
			final Set<String> expected = new HashSet<String>();
			expected.add("value0");
			expected.add("value1");
			expected.add("value2");
			assertTrue(expected.containsAll(map.values()));
			assertTrue(map.values().containsAll(expected));
		}
		{
			final Map<String,String> tmpMap = new HashMap<String,String>();
			for(final Map.Entry<String,String> e:map.entrySet()){
				tmpMap.put(e.getKey(), e.getValue());
			}
			final Map<String,String> expected = new HashMap<String,String>();
			expected.put("key0", "value0");
			expected.put("key1", "value1");
			expected.put("key2", "value2");
			assertEquals(expected, tmpMap);
		}
		assertFalse(map.isEmpty());
		assertEquals(3, map.size());
		assertTrue(map.containsKey("key0"));
		assertTrue(map.containsKey("key1"));
		assertTrue(map.containsKey("key2"));
		assertTrue(map.containsValue("value0"));
		assertTrue(map.containsValue("value1"));
		assertTrue(map.containsValue("value2"));
		assertEquals("value0", map.get(("key0")));
		assertEquals("value1", map.get(("key1")));
		assertEquals("value2", map.get(("key2")));
		
		map.remove("key2");

		{
			final Set<String> expected = new HashSet<String>();
			expected.add("key0");
			expected.add("key1");
			assertTrue(expected.containsAll(map.keySet()));
			assertTrue(map.keySet().containsAll(expected));
		}
		{
			final Set<String> expected = new HashSet<String>();
			expected.add("value0");
			expected.add("value1");
			assertTrue(expected.containsAll(map.values()));
			assertTrue(map.values().containsAll(expected));
		}
		{
			final Map<String,String> tmpMap = new HashMap<String,String>();
			for(final Map.Entry<String,String> e:map.entrySet()){
				tmpMap.put(e.getKey(), e.getValue());
			}
			final Map<String,String> expected = new HashMap<String,String>();
			expected.put("key0", "value0");
			expected.put("key1", "value1");
			assertEquals(expected, tmpMap);
		}
		assertFalse(map.isEmpty());
		assertEquals(2, map.size());
		assertTrue(map.containsKey("key0"));
		assertTrue(map.containsKey("key1"));
		assertFalse(map.containsKey("key2"));
		assertTrue(map.containsValue("value0"));
		assertTrue(map.containsValue("value1"));
		assertFalse(map.containsValue("value2"));
		assertEquals("value0", map.get(("key0")));
		assertEquals("value1", map.get(("key1")));
		assertNull(map.get(("key2")));
		
		map.clear();

		{
			final Set<String> expected = new HashSet<String>();
			assertTrue(expected.containsAll(map.keySet()));
			assertTrue(map.keySet().containsAll(expected));
		}
		{
			final Set<String> expected = new HashSet<String>();
			assertTrue(expected.containsAll(map.values()));
			assertTrue(map.values().containsAll(expected));
		}
		{
			final Map<String,String> tmpMap = new HashMap<String,String>();
			for(final Map.Entry<String,String> e:map.entrySet()){
				tmpMap.put(e.getKey(), e.getValue());
			}
			final Map<String,String> expected = new HashMap<String,String>();
			assertEquals(expected, tmpMap);
		}
		assertTrue(map.isEmpty());
		assertEquals(0, map.size());
		assertFalse(map.containsKey("key0"));
		assertFalse(map.containsKey("key1"));
		assertFalse(map.containsKey("key2"));
		assertFalse(map.containsValue("value0"));
		assertFalse(map.containsValue("value1"));
		assertFalse(map.containsValue("value2"));
		assertNull(map.get(("key0")));
		assertNull(map.get(("key1")));
		assertNull(map.get(("key2")));
	}
}
