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

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;

import jp.co.cybec.cb3.accessor.fileaccess.xml.XMLPath;
import jp.co.cybec.cb3.exception.AccessorUnknownException;
import jp.co.cybec.cb3.exception.BadXmlGrammerException;
import junit.framework.Assert;

import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * {@link XMLPath} のテストケース。
 * @author Daisuke Suga
 */
public class XMLPathTest {

	XMLPath target = null;
	BufferedInputStream stream = null;
	XmlObject xml = null;

	/** 読み込み用 正常ファイル */
	private static final String FILE_READER1 = "./src/test/testdata/xml/reader1.xml";

	@Before
	public void setUp() throws Exception {
		File file = new File(FILE_READER1);
		stream = new BufferedInputStream(new FileInputStream(file));
		xml = XmlObject.Factory.parse(stream);
	}

	@After
	public void tearDown() throws Exception {
		if (stream != null) {
			stream.close();
			stream = null;
		}
	}

	/**
	 * {@link XMLPath#XMLPath()} のためのテスト・メソッド。<br>
	 * 例外が発生しないことを確認する。
	 */
	@Test
	public void testXMLPath() {
		target = new XMLPath();
		Assert.assertNotNull(target);
	}

	/**
	 * {@link XMLPath#XMLPath(String, org.apache.xmlbeans.XmlObject, String)} のためのテスト・メソッド。<br>
	 * 例外が発生しないことを確認する。
	 */
	@Test
	public void testXMLPathStringXmlObjectString() throws Exception {
		target = new XMLPath("test1", xml, "*/dept");
		Assert.assertNotNull(target);
	}

	/**
	 * {@link XMLPath#XMLPath(String, org.apache.xmlbeans.XmlObject, String)} のためのテスト・メソッド。<br>
	 * カーソルの作成に失敗したときに例外が発生することを確認する。
	 */
	@Test(expected = AccessorUnknownException.class)
	public void testXMLPathStringXmlObjectStringAccessorUnknownException() {
		target = new XMLPath("test1", (XmlObject) null, "*/dept");
	}

	/**
	 * {@link XMLPath#XMLPath(String, org.apache.xmlbeans.XmlObject, String)} のためのテスト・メソッド。<br>
	 * 引数の検索パスが正しくないときに例外が発生することを確認する。
	 */
	@Test(expected = BadXmlGrammerException.class)
	public void testXMLPathStringXmlObjectStringBadXmlGrammerException() throws Exception {
		target = new XMLPath("test1", xml, null);
		stream.close();
	}

	/**
	 * {@link XMLPath#XMLPath(String, org.apache.xmlbeans.XmlCursor, String)} のためのテスト・メソッド。<br>
	 * 例外が発生しないことを確認する。
	 */
	@Test
	public void testXMLPathStringXmlCursorString() throws Exception {
		target = new XMLPath("test1", xml.newCursor(), "*/dept");
		Assert.assertNotNull(target);
	}

	/**
	 * {@link XMLPath#next()} のためのテスト・メソッド。<br>
	 * 正しい値が取得できることを確認する。
	 */
	@Test
	public void testNext() {
		target = new XMLPath("test1", xml, "*/dept/employee-list/employee/name");
		Assert.assertNotNull(target);
		Assert.assertEquals("test10", target.next().toString());
		Assert.assertEquals("test11", target.next().toString());
		Assert.assertEquals("test20", target.next().toString());
		Assert.assertEquals("test21", target.next().toString());
		Assert.assertNull(target.next());
	}

	/**
	 * {@link XMLPath#next()} のためのテスト・メソッド。<br>
	 * XmlObjectがNULLのときに例外が発生することを確認する。
	 */
	@Test(expected = AccessorUnknownException.class)
	public void testNextAccessorUnknownException() {
		target = new XMLPath("test1", (XmlCursor) null, "*/dept/employee-list/employee/name");
		target.next();
	}

	/**
	 * {@link XMLPath#selectChildPath(String)} のためのテスト・メソッド。<br>
	 * 正しい値が取得できることを確認する。
	 */
	@Test
	public void testSelectChildPath() {
		XMLPath parent = new XMLPath("test1", xml, "*/dept");
		Assert.assertNotNull(parent);
		Assert.assertNotNull(parent.next());
		target = parent.selectChildPath("./employee-list/employee/name");
		Assert.assertEquals("test10", target.next().toString());
		Assert.assertEquals("test11", target.next().toString());
		Assert.assertNull(target.next());
		Assert.assertNotNull(parent.next());
		target = parent.selectChildPath("./employee-list/employee/name");
		Assert.assertEquals("test20", target.next().toString());
		Assert.assertEquals("test21", target.next().toString());
		Assert.assertNull(target.next());
		Assert.assertNull(parent.next());
	}

	/**
	 * {@link XMLPath#selectChildPath(String)} のためのテスト・メソッド。<br>
	 * XmlCursorがNULLのときに例外が発生することを確認する。
	 */
	@Test(expected = AccessorUnknownException.class)
	public void testSelectChildPathAccessorUnknownException() {
		target = new XMLPath("test1", (XmlCursor) null, "*/dept");
		target.selectChildPath("./employee-list/employee/name");
	}

	/**
	 * {@link XMLPath#selectChildPath(String)} のためのテスト・メソッド。<br>
	 * 引数の検索パスが正しくないときに例外が発生することを確認する。
	 */
	@Test(expected = BadXmlGrammerException.class)
	public void testSelectChildPathBadXmlGrammerException() {
		target = new XMLPath("test1", xml.newCursor(), "*/dept");
		target.selectChildPath("");
	}

}
