package common.sql;


import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.JUnitCore;

import common.sql.LineParsedNodeItem;

public class TestLineParsedNodeItem {

	/**
	 * main
	 * @param args arguments
	 */
	public static void main(final String... args) {
		JUnitCore.main(TestLineParsedNodeItem.class.getName());
	}

	/**
	 * アクセス設定
	 *
	 * @param f 設定対象
	 */
	private static void setAccessible(final AccessibleObject f) {
		if (!f.isAccessible()) {
			AccessController.doPrivileged(new PrivilegedAction<Object>() {
				@Override
				public Object run() {
					f.setAccessible(true);
					return null;
				}
			});
		}
	}

	@Test
	public void 括弧パースOFFSET_LIMIT句() {
		LineParsedNodeItem sut = new LineParsedNodeItem(
				"OFFSET ((/*?Page*/1 - 1) * /*?Line*/20 ) LIMIT /*?Line*/20 \n");
		Assert.assertEquals("OFFSET ( ( /*?Page*/1 - 1 ) * /*?Line*/20 ) LIMIT /*?Line*/20", sut.toString());
	}

	@Test
	public void 括弧パースAND() {
		LineParsedNodeItem sut = new LineParsedNodeItem(
			"AND ((DT_DATTAI_YM = '      ' ) (( DT_DATTAI_YM >= ))/*:dtGyomu*/'200901' )");
		Assert.assertEquals("AND ( ( DT_DATTAI_YM = '      ' )( ( DT_DATTAI_YM >= ) ) /*:dtGyomu*/'200901' )", sut.toString());
	}

	@Test
	public void 括弧パース() {
		LineParsedNodeItem sut = new LineParsedNodeItem(
			"AND (DT_DATTAI_YM = '      ' OR DT_DATTAI_YM >= /*:dtGyomu*/'200901')");
		Assert.assertEquals("AND ( DT_DATTAI_YM = '      ' OR DT_DATTAI_YM >= /*:dtGyomu*/'200901' )", sut.toString());
	}

	@Test
	public void 括弧パースAND_OR() {
		LineParsedNodeItem sut = new LineParsedNodeItem(
			"AND ((DT_DATTAI_YM = '      ' AND MN_PAY > /*:mnPay*/1 ) OR (DT_DATTAI_YM >= /*:dtGyomu*/'200901' ))");
		Assert.assertEquals("AND ( ( DT_DATTAI_YM = '      ' AND MN_PAY > /*:mnPay*/1 ) OR ( DT_DATTAI_YM >= /*:dtGyomu*/'200901' ) )", sut.toString());
	}

	@Test
	public void 日時必須パース() {
		LineParsedNodeItem sut = new LineParsedNodeItem("UPDATE_DATETIME = /*:DateTime*/TO_DATE('20091225','YYYYMMDD') ,");
		Assert.assertEquals("UPDATE_DATETIME = /*:DateTime*/TO_DATE( '20091225','YYYYMMDD' ) ,", sut.toString());
	}

	@Test
	public void 日時必須パースAND_OR句() {
		LineParsedNodeItem sut = new LineParsedNodeItem(
			"AND ((DT_DATTAI_YM = /*:DateTime*/TO_DATE('20091225','YYYYMMDD') AND MN_PAY > /*:mnPay*/0 ) OR (DT_DATTAI_YM >= /*:dtGyomu*/'200901' ))");
		Assert.assertEquals("AND ( ( DT_DATTAI_YM = /*:DateTime*/TO_DATE( '20091225','YYYYMMDD' ) AND MN_PAY > /*:mnPay*/0 ) OR ( DT_DATTAI_YM >= /*:dtGyomu*/'200901' ) )", sut.toString());
	}

	@Test
	public void getBindString行末スペース() throws Exception {
		LineParsedNodeItem sut = new LineParsedNodeItem("");
		Method m = sut.getClass().getDeclaredMethod("getBindString", String.class, int.class);
		setAccessible(m);
		Assert.assertEquals("aaaaa#12345", m.invoke(sut, "aaaaa#12345)", Integer.valueOf(0)));
		Assert.assertEquals("aaaaa#0.00012", m.invoke(sut, "aaaaa#0.00012, ", Integer.valueOf(0)));
		Assert.assertEquals("aaaaa#-1234", m.invoke(sut, "aaaaa#-1234 ", Integer.valueOf(0)));
		Assert.assertEquals("aaaaa#-1234.53", m.invoke(sut, "aaaaa#-1234.53 ", Integer.valueOf(0)));
		Assert.assertEquals("aaaaa#-0.53", m.invoke(sut, "aaaaa#-0.53 ", Integer.valueOf(0)));
		Assert.assertEquals("aaaaa#-0.00", m.invoke(sut, "aaaaa#-0.00  ", Integer.valueOf(0)));
	}
}
