package jp.sourceforge.glad.org.seasar.framework.model.impl;

import jp.sourceforge.glad.org.seasar.framework.model.domain.Person;
import jp.sourceforge.glad.org.seasar.framework.model.repository.PersonRepository;

import org.seasar.framework.unit.S2FrameworkTestCase;

/**
 * {@link ModelFactoryImpl}の単体テスト。
 * 
 * @author GLAD!!
 */
public class ModelFactoryImplTest extends S2FrameworkTestCase {

    ModelFactoryImpl factory;
    PersonRepository repository;

    protected void setUp() throws Exception {
        include("ModelFactoryImplTest.dicon");
    }

    /**
     * {@link ModelFactoryImpl#create}で、
     * 引数なしのコンストラクタを使用する場合。
     */
    public void testCreate() {
        final Person person = factory.create(Person.class);
        // Modelが生成されたこと。
        assertNotNull(person);
        // Modelが初期状態であること。
        assertEquals(null, person.getName());
        assertEquals(0, person.getAge());
        // ModelにRepositoryがDIされていること。
        assertSame(repository, person.getRepository());
        // Modelにアスペクトが適用されていること。
        assertFalse(Person.class.equals(person.getClass()));
        
        person.setName("Hoge");
        person.setAge(12);
        person.save();
        // ModelにDIされたRepositoryが呼び出されたこと。
        assertPersonEquals(person, repository.getPerson("Hoge"));
    }

    /**
     * {@link ModelFactoryImpl#create}で、
     * 引数ありのコンストラクタを使用する場合。
     */
    public void testCreateArgs() {
        final Person person = factory.create(Person.class, "Hoge", 12);
        // Modelが生成されたこと。
        assertNotNull(person);
        // Modelにコンストラクタの引数が設定されていること。
        assertEquals("Hoge", person.getName());
        assertEquals(12, person.getAge());
        // ModelにRepositoryがDIされていること。
        assertSame(repository, person.getRepository());
        // Modelにアスペクトが適用されていること。
        assertFalse(Person.class.equals(person.getClass()));
        
        person.save();
        // ModelにDIされたRepositoryが呼び出されたこと。
        assertPersonEquals(person, repository.getPerson("Hoge"));
    }

    void assertPersonEquals(final Person expected, final Person actual) {
        assertEquals(expected.getName(), actual.getName());
        assertEquals(expected.getAge(), actual.getAge());
    }

}
