/*
 * Copyright 2006-2011 the Seasar Foundation and the Others.
 *
 * 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 org.seasar.codegen.lib.internal.impl;

import java.lang.reflect.Method;

import org.seasar.codegen.sample.condition.EmpTableCondition;
import org.seasar.codegen.sample.condition.EmpTableRelationCondition;
import org.seasar.codegen.sample.dao.EmpTableDao;
import org.seasar.codegen.sample.dao.ShiftJISDao;
import org.seasar.codegen.sample.entity.EmpTable;
import org.seasar.dao.BeanMetaData;
import org.seasar.dao.DaoMetaDataFactory;
import org.seasar.dao.SqlCommand;
import org.seasar.dao.impl.BeanArrayMetaDataResultSetHandler;
import org.seasar.dao.impl.BeanListMetaDataResultSetHandler;
import org.seasar.dao.impl.BeanMetaDataResultSetHandler;
import org.seasar.dao.unit.S2DaoTestCase;
import org.seasar.extension.jdbc.ResultSetHandler;

/**
 * @author azusa
 * 
 */
public class CodeGenDaoMetaDataImplTest extends S2DaoTestCase {

    public DaoMetaDataFactory daoMetaDataFactory;

    private CodeGenDaoMetaDataImpl codeGenDaoMetaDataImpl;

    Class clazz = EmpTableDao.class;

    /*
     * (非 Javadoc)
     * 
     * @see junit.framework.TestCase#setUp()
     */
    protected void setUp() throws Exception {
        include("dao.dicon");

    }

    @Override
    protected void setUpAfterBindFields() throws Throwable {
        codeGenDaoMetaDataImpl = (CodeGenDaoMetaDataImpl) daoMetaDataFactory.getDaoMetaData(clazz);
    }

    /**
     * インスタンス生成
     */
    public void testインスタンス生成() {
        assertNotNull(daoMetaDataFactory);
    }

    /**
     * {@link org.seasar.codegen.lib.internal.impl.CodeGenDaoMetaDataFactoryImpl.CodeGenDaoMetaDataImpl#setupMethod(java.lang.reflect.Method)}
     * のためのテスト・メソッド。
     */
    public void testSetupMethodMethod() {
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            codeGenDaoMetaDataImpl.setupMethod(method);
            assertNotNull(codeGenDaoMetaDataImpl.getSqlCommand(method.getName()));
        }
    }

    public void testエンコーディングがシフトJISなこと() {
        CodeGenDaoMetaDataImpl metaDataImpl = (CodeGenDaoMetaDataImpl) daoMetaDataFactory
                .getDaoMetaData(ShiftJISDao.class);
        assertEquals("JISAutoDetect", metaDataImpl.getSqlFileEncoding());
    }

    public void testエンコーディングがJISAutoDetectなこと() {
        CodeGenDaoMetaDataImpl metaDataImpl = (CodeGenDaoMetaDataImpl) daoMetaDataFactory
                .getDaoMetaData(EmpTableDao.class);
        assertEquals("UTF-8", metaDataImpl.getSqlFileEncoding());
    }

    /**
     * {@link org.seasar.codegen.lib.internal.impl.CodeGenDaoMetaDataFactoryImpl.CodeGenDaoMetaDataImpl#setupMethod(java.lang.reflect.Method)}
     * のためのテスト・メソッド。
     */
    public void testSetupMethodMethod_リレーションの場合() throws Exception {
        Method method = clazz.getMethod("findWithRelation", EmpTableRelationCondition.class);
        codeGenDaoMetaDataImpl.setupMethod(method);
        assertTrue(codeGenDaoMetaDataImpl.getSqlCommand(method.getName()) instanceof FindSqlCommand);
    }

    /**
     * {@link org.seasar.codegen.lib.internal.impl.CodeGenDaoMetaDataFactoryImpl.CodeGenDaoMetaDataImpl#setupFindMethod(java.lang.reflect.Method)}
     * のためのテスト・メソッド。
     */
    public void testSetupFindMethod() throws Exception {
        Method method = clazz.getMethod("find", EmpTableCondition.class);
        codeGenDaoMetaDataImpl.setupMethod(method);
        SqlCommand command = codeGenDaoMetaDataImpl.getSqlCommand(method.getName());
        assertTrue(command instanceof FindSqlCommand);

    }

    /**
     * {@link org.seasar.codegen.lib.internal.impl.CodeGenDaoMetaDataFactoryImpl.CodeGenDaoMetaDataImpl#getBeanMetaData(java.lang.Class)}
     * のためのテスト・メソッド。
     */
    public void testGetBeanMetaData() throws Exception {
        BeanMetaData beanMetaData = codeGenDaoMetaDataImpl.getBeanMetaData(EmpTable.class);
        assertEquals(EmpTable.class, beanMetaData.getBeanClass());

    }

    public void testCreateBaseSQLQuery_メソッドのアノテーションがある場合() throws Exception {
        Method method = clazz.getMethod("getEmpTable", Integer.class);
        BeanMetaData beanMetaData = codeGenDaoMetaDataImpl.getBeanMetaData(EmpTable.class);
        String result = codeGenDaoMetaDataImpl.createBaseSQL(method, beanMetaData);
        assertEquals(
                "SELECT EMP_TABLE.ENAME, EMP_TABLE.JOB, EMP_TABLE.MGR, EMP_TABLE.HIRE_DATE, EMP_TABLE.SAL, EMP_TABLE.COMM, EMP_TABLE.DEPT_NO, EMP_TABLE.VERSIONNO, EMP_TABLE.EMP_NO, EMP_TABLE.TSTAMP FROM EMP_TABLE WHERE EMP_NO = ?",
                result);
    }

    public void testCreateBaseSQLQuery_メソッドのアノテーションでOrderBy指定の場合() throws Exception {
        Method method = clazz.getMethod("getAllEmpTable", null);
        BeanMetaData beanMetaData = codeGenDaoMetaDataImpl.getBeanMetaData(EmpTable.class);
        String result = codeGenDaoMetaDataImpl.createBaseSQL(method, beanMetaData);
        assertEquals(
                "SELECT EMP_TABLE.ENAME, EMP_TABLE.JOB, EMP_TABLE.MGR, EMP_TABLE.HIRE_DATE, EMP_TABLE.SAL, EMP_TABLE.COMM, EMP_TABLE.DEPT_NO, EMP_TABLE.VERSIONNO, EMP_TABLE.EMP_NO, EMP_TABLE.TSTAMP FROM EMP_TABLE ORDER BY EMP_NO",
                result);
    }

    public void testCreateBaseSQL_メソッドの自動生成の場合() throws Exception {
        Method method = clazz.getMethod("find", EmpTableCondition.class);
        BeanMetaData beanMetaData = codeGenDaoMetaDataImpl.getBeanMetaData(EmpTable.class);
        String result = codeGenDaoMetaDataImpl.createBaseSQL(method, beanMetaData);
        assertEquals(
                "SELECT EMP_TABLE.ENAME, EMP_TABLE.JOB, EMP_TABLE.MGR, EMP_TABLE.HIRE_DATE, EMP_TABLE.SAL, EMP_TABLE.COMM, EMP_TABLE.DEPT_NO, EMP_TABLE.VERSIONNO, EMP_TABLE.EMP_NO, EMP_TABLE.TSTAMP FROM EMP_TABLE",
                result);

    }

    /**
     * {@link org.seasar.codegen.lib.internal.impl.CodeGenDaoMetaDataFactoryImpl.CodeGenDaoMetaDataImpl#getFindSqlCommand(java.lang.reflect.Method)}
     * のためのテスト・メソッド。
     */
    public void testGetFindSqlCommand() throws Exception {
        Method method = clazz.getMethod("find", EmpTableCondition.class);
        SqlCommand sqlCommand = codeGenDaoMetaDataImpl.getFindSqlCommand(method);
        assertTrue(sqlCommand instanceof FindSqlCommand);

    }

    /**
     * {@link org.seasar.codegen.lib.internal.impl.CodeGenDaoMetaDataFactoryImpl.CodeGenDaoMetaDataImpl#createResultSetHandlerFromReturnType(java.lang.reflect.Method, org.seasar.dao.BeanMetaData)}
     * のためのテスト・メソッド。
     */
    public void testCreateResultSetHandlerFromReturnType_リストの場合() throws Exception {
        Method method = clazz.getMethod("getAllEmpTable", null);
        BeanMetaData beanMetaData = codeGenDaoMetaDataImpl.getBeanMetaData(EmpTable.class);
        ResultSetHandler resultSetHandler = codeGenDaoMetaDataImpl.createResultSetHandlerFromReturnType(method,
                beanMetaData);
        assertTrue(resultSetHandler instanceof BeanListMetaDataResultSetHandler);
    }

    /**
     * {@link org.seasar.codegen.lib.internal.impl.CodeGenDaoMetaDataFactoryImpl.CodeGenDaoMetaDataImpl#createResultSetHandlerFromReturnType(java.lang.reflect.Method, org.seasar.dao.BeanMetaData)}
     * のためのテスト・メソッド。
     */
    public void testCreateResultSetHandlerFromReturnType_配列の場合() throws Exception {
        Method method = clazz.getMethod("getArray", null);
        BeanMetaData beanMetaData = codeGenDaoMetaDataImpl.getBeanMetaData(EmpTable.class);
        ResultSetHandler resultSetHandler = codeGenDaoMetaDataImpl.createResultSetHandlerFromReturnType(method,
                beanMetaData);
        assertTrue(resultSetHandler instanceof BeanArrayMetaDataResultSetHandler);
    }

    /**
     * {@link org.seasar.codegen.lib.internal.impl.CodeGenDaoMetaDataFactoryImpl.CodeGenDaoMetaDataImpl#createResultSetHandlerFromReturnType(java.lang.reflect.Method, org.seasar.dao.BeanMetaData)}
     * のためのテスト・メソッド。
     */
    public void testCreateResultSetHandlerFromReturnType_Beanの場合() throws Exception {
        Method method = clazz.getMethod("getEntity", null);
        BeanMetaData beanMetaData = codeGenDaoMetaDataImpl.getBeanMetaData(EmpTable.class);
        ResultSetHandler resultSetHandler = codeGenDaoMetaDataImpl.createResultSetHandlerFromReturnType(method,
                beanMetaData);
        assertTrue(resultSetHandler instanceof BeanMetaDataResultSetHandler);
    }

}
