/*
 * DataAccessContextImplTest.java
 * Copyright (C) 2008 Cyber Beans Corporation. All rights reserved.
 */
package jp.co.cybec.cb3.accessor;

import java.util.HashMap;
import java.util.Map;

import jp.co.cybec.cb3.accessor.Accessor;
import jp.co.cybec.cb3.accessor.DataAccessContext;
import jp.co.cybec.cb3.accessor.DataAccessContextImpl;
import jp.co.cybec.cb3.exception.AccessorUnknownException;
import jp.co.cybec.cb3.exception.ConfigFileDefinitionException;
import jp.co.cybec.cb3.mock.accessor.MockAccessor;
import jp.co.cybec.cb3.mock.accessor.MockAccessorThrowException;
import junit.framework.Assert;

import org.junit.Test;

/**
 * DataAccessContextImplのテストケース。
 * @author Naoko Sugimoto
 */
public class DataAccessContextImplTest {

	/**
	 * {@link jp.co.cybec.cb3.accessor.DataAccessContextImpl#DataAccessContextImpl(java.util.Map)} のためのテスト・メソッド。
	 * DataAccessContextImplのコンストラクタでアクセッサの初期化が行われていることを確認する。
	 */
	@Test
	public void testDataAccessContextImpl() {

		// ダミーのアクセッサを生成。
		MockAccessor accessor1 = new MockAccessor();
		MockAccessor accessor2 = new MockAccessor();

		// アクセッサをMapに格納。
		Map<String, Accessor> accessors = new HashMap<String, Accessor>();
		accessors.put("accessor1", accessor1);
		accessors.put("accessor2", accessor2);

		// DataAccessContextImplを生成。
		DataAccessContext dataAccessContext = new DataAccessContextImpl(accessors);

		// アクセッサを取得。
		accessor1 = (MockAccessor)dataAccessContext.lookup("accessor1");
		accessor2 = (MockAccessor)dataAccessContext.lookup("accessor2");

		// アクセッサが初期化されていることを確認。
		Assert.assertTrue(accessor1.isInitialized());
		Assert.assertTrue(accessor2.isInitialized());
	}

	/**
	 * {@link jp.co.cybec.cb3.accessor.DataAccessContextImpl#DataAccessContextImpl(java.util.Map)} のためのテスト・メソッド。
	 * アクセッサの初期化に失敗したとき、適切な例外が発生することを確認する。
	 * {@link ConfigFileDefinitionException}の場合。
	 */
	@Test(expected=ConfigFileDefinitionException.class)
	public void testDataAccessContextImplThrowException() {

		// ダミーのアクセッサを生成。
		MockAccessorThrowException accessor1 = new MockAccessorThrowException();
		accessor1.setException(new ConfigFileDefinitionException("例外のテストです。"));

		// アクセッサをMapに格納。
		Map<String, Accessor> accessors = new HashMap<String, Accessor>();
		accessors.put("accessor1", accessor1);

		// DataAccessContextImplを生成。
		new DataAccessContextImpl(accessors);
	}

	/**
	 * {@link jp.co.cybec.cb3.accessor.DataAccessContextImpl#DataAccessContextImpl(java.util.Map)} のためのテスト・メソッド。
	 * アクセッサの初期化に失敗したとき、適切な例外が発生することを確認する。
	 * 予期しないエラーの場合。
	 */
	@Test(expected=AccessorUnknownException.class)
	public void testDataAccessContextImplThrowUnknownException() {

		// ダミーのアクセッサを生成。
		MockAccessorThrowException accessor1 = new MockAccessorThrowException();
		accessor1.setException(new NullPointerException("例外のテストです。"));

		// アクセッサをMapに格納。
		Map<String, Accessor> accessors = new HashMap<String, Accessor>();
		accessors.put("accessor1", accessor1);

		// DataAccessContextImplを生成。
		new DataAccessContextImpl(accessors);
	}

	/**
	 * {@link jp.co.cybec.cb3.accessor.DataAccessContextImpl#lookup(java.lang.String)} のためのテスト・メソッド。
	 * lookupメソッドで適切なアクセッサを取得できることを確認する。
	 */
	@Test
	public void testLookup() {

		// ダミーのアクセッサを生成。
		Accessor accessor1 = new MockAccessor();
		Accessor accessor2 = new MockAccessor();

		// アクセッサをMapに格納。
		Map<String, Accessor> accessors = new HashMap<String, Accessor>();
		accessors.put("accessor1", accessor1);
		accessors.put("accessor2", accessor2);

		// DataAccessContextImplを生成。
		DataAccessContext dataAccessContext = new DataAccessContextImpl(accessors);

		// lookupで取得したアクセッサが、注入したインスタンスと同じものであることを確認。
		Assert.assertSame(accessor1, dataAccessContext.lookup("accessor1"));
		Assert.assertSame(accessor2, dataAccessContext.lookup("accessor2"));
	}


	/**
	 * {@link jp.co.cybec.cb3.accessor.DataAccessContextImpl#lookup(java.lang.String)} のためのテスト・メソッド。
	 * lookupメソッドに指定したbeanが存在しない場合、適切な例外が発生することを確認する。
	 */
	@Test(expected=ConfigFileDefinitionException.class)
	public void testLookupNoBean() {

		// ダミーのアクセッサを生成。
		Accessor accessor1 = new MockAccessor();
		Accessor accessor2 = new MockAccessor();

		// アクセッサをMapに格納。
		Map<String, Accessor> accessors = new HashMap<String, Accessor>();
		accessors.put("accessor1", accessor1);
		accessors.put("accessor2", accessor2);

		// DataAccessContextImplを生成。
		DataAccessContext dataAccessContext = new DataAccessContextImpl(accessors);

		// 存在しないキーをlookupに指定。
		Assert.assertSame(accessor1, dataAccessContext.lookup("dummy"));
	}

	/**
	 * {@link jp.co.cybec.cb3.accessor.DataAccessContextImpl#release()} のためのテスト・メソッド。
	 * release()メソッドによって、アクセッサの終了処理が呼ばれていることを確認する。
	 */
	@Test
	public void testRelease() {
		// ダミーのアクセッサを生成。
		MockAccessor accessor1 = new MockAccessor();
		MockAccessor accessor2 = new MockAccessor();

		// アクセッサをMapに格納。
		Map<String, Accessor> accessors = new HashMap<String, Accessor>();
		accessors.put("accessor1", accessor1);
		accessors.put("accessor2", accessor2);

		// DataAccessContextImplを生成。
		DataAccessContextImpl dataAccessContext = new DataAccessContextImpl(accessors);

		// DataAccessContextImplを終了。
		dataAccessContext.release();

		// アクセッサの終了処理が呼ばれていることを確認する。
		Assert.assertTrue(accessor1.isReleased());
		Assert.assertTrue(accessor2.isReleased());
	}
}
