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

import jp.co.cybec.cb3.accessor.fileaccess.flat.FlatFileRecord;
import jp.co.cybec.cb3.accessor.fileaccess.flat.fixed.FixedLengthRecordReader;
import jp.co.cybec.cb3.exception.AccessorNotOpenException;
import jp.co.cybec.cb3.exception.ConfigFileNotFoundException;
import jp.co.cybec.cb3.exception.DataFormatException;
import junit.framework.Assert;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * {@link FixedLengthRecordReader} のテストケース。
 * @author Sufang Gou
 */

public class FixedLengthRecordReaderTest {
	// クラスをインスタンスする
	FixedLengthRecordReader target = null;
	private FlatFileRecord record;

	/** 読み込み用 正常ファイル */
	private static final String CONFIG_READER1 = "jp/co/cybec/cb3/accessor/fileaccess/flat/fixed/reader/readerConfig1.xml";
	private static final String CONFIG_READER2 = "jp/co/cybec/cb3/accessor/fileaccess/flat/fixed/reader/readerConfig2.xml";

	/** 読み込み用 データファイルの記述が正しくない */
	private static final String CONFIG_READER_PARSE_ERROR1 = "jp/co/cybec/cb3/accessor/fileaccess/flat/fixed/reader/readerConfig3.xml";
	private static final String CONFIG_READER_PARSE_ERROR2 = "jp/co/cybec/cb3/accessor/fileaccess/flat/fixed/reader/readerConfig4.xml";
	private static final String CONFIG_READER_PARSE_ERROR3 = "jp/co/cybec/cb3/accessor/fileaccess/flat/fixed/reader/readerConfig5.xml";
	private static final String CONFIG_READER_PARSE_ERROR4 = "jp/co/cybec/cb3/accessor/fileaccess/flat/fixed/reader/readerConfig6.xml";
	private static final String CONFIG_READER_PARSE_ERROR5 = "jp/co/cybec/cb3/accessor/fileaccess/flat/fixed/reader/readerConfig7.xml";

	/** 正常データファイル */
	private static final String FILE_NORMAL= "src/test/testdata/fixed/test1.txt";

	/**
	 * @throws Exception
	 */
	@Before
	public void setUp() throws Exception {
		// クラスをインスタンスする
		target = new FixedLengthRecordReader();
	}

	/**
	 * @throws Exception
	 */
	@After
	public void tearDown() throws Exception {
		target.release();
	}

	/**
	 * {@link FixedLengthRecordReader#open(String)} のためのテスト・メソッド。
	 * 例外が発生しないことを確認する。
	 */
	@Test
	public void testOpenString() {
		target.initialize(CONFIG_READER1);
		target.open(FILE_NORMAL);
	}

	/**
	 * {@link FixedLengthRecordReader#nextRecord()} のためのテスト・メソッド。
	 * 例外が発生しないことを確認する
	 * encode Shift_JIS
	 */
	@Test
	public void testNextRecord01() {
		// 設定ファイルを読み込む。
		target.initialize(CONFIG_READER1);

		//ファイルをオープンする。
		target.open();

		// データを取得する。
		record = target.nextRecord();

		// 結果をチェックする
		Assert.assertEquals("1111111111", record.getString("intField"));
		Assert.assertEquals("2222222222", record.getString("strField1"));
		Assert.assertEquals("翻 訳　先\"週の先週｛１２３｝", record.getString("strField2"));
		Assert.assertEquals("1234", record.getString("longField"));
		Assert.assertEquals("1234", record.getString("shortField"));
		Assert.assertEquals("1111.461", record.getString("floatField"));
		Assert.assertEquals("111111.012", record.getString("bigField1"));
		Assert.assertEquals("1234565648.011", record.getString("bigField2"));
		Assert.assertEquals("2007/05/28 00:00:00", record.getString("dateField1"));
		Assert.assertEquals("本田2のwww.bb@hotmail.com.cn", record.getString("strField3"));
		Assert.assertEquals("10%", record.getString("strField4"));
		Assert.assertEquals("2001/11/05 00:00:00", record.getString("dateField2"));
		Assert.assertEquals("2001/10/05 08:01:00", record.getString("dateField3"));
		Assert.assertEquals("2001/09/29 00:00:00", record.getString("dateField4"));
		Assert.assertEquals("2001/09/10 10:10:01", record.getString("dateField5"));

		record = null;
		// データを取得する。
		record = target.nextRecord();

		// 結果をチェックする。
		Assert.assertEquals("3333333333", record.getString("intField"));
		Assert.assertEquals("4444444444", record.getString("strField1"));
		Assert.assertEquals("翻 訳　先\"週の先週｛１２３｝", record.getString("strField2"));
		Assert.assertEquals("5678", record.getString("longField"));
		Assert.assertEquals("5678", record.getString("shortField"));
		Assert.assertEquals("1123.461", record.getString("floatField"));
		Assert.assertEquals("123456.012", record.getString("bigField1"));
		Assert.assertEquals("1234565648.012", record.getString("bigField2"));
		Assert.assertEquals("2008/08/08 00:00:00", record.getString("dateField1"));
		Assert.assertEquals("本田2のwww.bb@hotmail.com.cn", record.getString("strField3"));
		Assert.assertEquals("10%", record.getString("strField4"));
		Assert.assertEquals("2001/11/05 00:00:00", record.getString("dateField2"));
		Assert.assertEquals("2001/10/05 08:01:00", record.getString("dateField3"));
		Assert.assertEquals("2001/09/29 00:00:00", record.getString("dateField4"));
		Assert.assertEquals("2001/09/10 10:10:01", record.getString("dateField5"));

		// ファイルをクローズする。
		target.close();
	}

	/**
	 * {@link FixedLengthRecordReader#nextRecord()} のためのテスト・メソッド。
	 * 例外が発生しないことを確認する
	 * encode null
	 *
	 */
	@Test
	public void testNextRecord02() {
		// 設定ファイルを読み込む。
		target.initialize(CONFIG_READER2);

		//ファイルをオープンする。
		target.open();
		// データを取得する
		record = target.nextRecord();

		// 結果をチェックする。
		Assert.assertEquals("1111111111", record.getString("intField"));
		Assert.assertEquals("2222222222", record.getString("strField1"));
		Assert.assertEquals("翻 訳　先\"週の先週｛１２３｝", record.getString("strField2"));
		Assert.assertEquals("1234", record.getString("longField"));
		Assert.assertEquals("1234", record.getString("shortField"));
		Assert.assertEquals("1111.461", record.getString("floatField"));
		Assert.assertEquals("111111.012", record.getString("bigField1"));
		Assert.assertEquals("1234565648.011", record.getString("bigField2"));
		Assert.assertEquals("2007/05/28 00:00:00", record.getString("dateField1"));
		Assert.assertEquals("本田2のwww.bb@hotmail.com.cn", record.getString("strField3"));
		Assert.assertEquals("10%", record.getString("strField4"));
		Assert.assertEquals("2001/11/05 00:00:00", record.getString("dateField2"));
		Assert.assertEquals("2001/10/05 08:01:00", record.getString("dateField3"));
		Assert.assertEquals("2001/09/29 00:00:00", record.getString("dateField4"));
		Assert.assertEquals("2001/09/10 10:10:01", record.getString("dateField5"));

		record = null;
		// データを取得する。
		record = target.nextRecord();

		// 結果をチェックする。
		Assert.assertEquals("3333333333", record.getString("intField"));
		Assert.assertEquals("4444444444", record.getString("strField1"));
		Assert.assertEquals("翻 訳　先\"週の先週｛１２３｝", record.getString("strField2"));
		Assert.assertEquals("5678", record.getString("longField"));
		Assert.assertEquals("5678", record.getString("shortField"));
		Assert.assertEquals("1123.461", record.getString("floatField"));
		Assert.assertEquals("123456.012", record.getString("bigField1"));
		Assert.assertEquals("1234565648.012", record.getString("bigField2"));
		Assert.assertEquals("2008/08/08 00:00:00", record.getString("dateField1"));
		Assert.assertEquals("本田2のwww.bb@hotmail.com.cn", record.getString("strField3"));
		Assert.assertEquals("10%", record.getString("strField4"));
		Assert.assertEquals("2001/11/05 00:00:00", record.getString("dateField2"));
		Assert.assertEquals("2001/10/05 08:01:00", record.getString("dateField3"));
		Assert.assertEquals("2001/09/29 00:00:00", record.getString("dateField4"));
		Assert.assertEquals("2001/09/10 10:10:01", record.getString("dateField5"));

		// ファイルをクローズする。
		target.close();
	}

	/**
	 * {@link FixedLengthRecordReader#nextRecord()} のためのテスト・メソッド。
	 * ファイルをオープンしないときに例外が発生することを確認する。
	 */
	@Test(expected = AccessorNotOpenException.class)
	public void testNextRecord03() {
		// 設定ファイルを読み込む。
		target.initialize(CONFIG_READER2);

		// データを取得する
		target.nextRecord();

		// ファイルをクローズする。
		target.close();
	}

	/**
	 * {@link FixedLengthRecordReader#nextRecord()} のためのテスト・メソッド。
	 * 不正な場合のテスト
	 * １行データのバイト数 <> 設定ファイルのバイト数合計のときに例外が発生することを確認する。
	 */
	@Test(expected = DataFormatException.class)
	public void testNextRecord04() {
		// 設定ファイルを読み込む。
		target.initialize(CONFIG_READER_PARSE_ERROR1);

		//ファイルをオープンする。
		target.open();

		// データを取得する。
		target.nextRecord();

		// ファイルをクローズする。
		target.close();
	}

	/**
	 * {@link FixedLengthRecordReader#nextRecord()} のためのテスト・メソッド。
	 * 不正な場合のテスト
	 * ユーザー定義クラスのインスタンス失敗するときに例外が発生することを確認する。
	 */
	@Test(expected = DataFormatException.class)
	public void testNextRecord05() {
		// 設定ファイルを読み込む
		target.initialize(CONFIG_READER_PARSE_ERROR2);

		//ファイルをオープンする。
		target.open();

		// データを取得する。
		record = target.nextRecord();

		// ファイルをクローズする。
		target.close();
	}

	/**
	 * {@link FixedLengthRecordReader#nextRecord()} のためのテスト・メソッド。
	 * 不正な場合のテスト
	 * バイト配列の範囲外の場合のときに例外が発生することを確認する。
	 */
	@Test(expected = DataFormatException.class)
	public void testNextRecord06() {
		// 設定ファイルを読み込む
		target.initialize(CONFIG_READER_PARSE_ERROR3);

		//ファイルをオープンする。
		target.open();

		// データを取得する。
		record = target.nextRecord();

		// ファイルをクローズする。
		target.close();
	}

	/**
	 * {@link FixedLengthRecordReader#nextRecord()} のためのテスト・メソッド。
	 * データファイルのフィールドの長さが零の場合、例外が発生しないことを確認する。
	 */
	@Test
	public void testNextRecord07() {
		// 設定ファイルを読み込む
		target.initialize(CONFIG_READER_PARSE_ERROR4);

		//ファイルをオープンする。
		target.open();

		// データを取得する。
		record = target.nextRecord();

		// ファイルをクローズする。
		target.close();
	}

	/**
	 * {@link FixedLengthRecordReader#initialize(String)} のためのテスト・メソッド。<br>
	 * 例外が発生しないことを確認する。
	 */
	@Test
	public void testInitialize() {
		target.initialize(CONFIG_READER1);
		//ファイルをオープンする。
		target.open();
		// ファイルをクローズする。
		target.close();

	}

	/**
	 * {@link FixedLengthRecordReader#initialize(String)} のためのテスト・メソッド。<br>
	 * 引数に存在しないキー（設定ファイル）を指定したときに例外が発生することを確認する。
	 */
	@Test(expected = ConfigFileNotFoundException.class)
	public void testInitializeConfigFileNotFoundException() {
		target.initialize("aaa");
	}

	/**
	 * {@link FixedLengthRecordReader#nextRecord()} のためのテスト・メソッド。
	 * データファイルのフォーマットを失敗するの場合、例外が発生することを確認する。
	 */
	@Test(expected = DataFormatException.class)
	public void testNextRecord08() {
		// 設定ファイルを読み込む
		target.initialize(CONFIG_READER_PARSE_ERROR5);

		//ファイルをオープンする。
		target.open();

		// データを取得する。
		record = target.nextRecord();

		// ファイルをクローズする。
		target.close();
	}
}
