/*******************************************************************************
 * Copyright (c) 2004 Actuate Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *  Actuate Corporation  - initial API and implementation
 *******************************************************************************/

package org.eclipse.birt.core.script;

import junit.framework.TestCase;

/**
 * FinanceTest.
 * 
 * Unit test for class finance, focus on each static function in the finance
 * class
 * 
 */
public class FinanceTest extends TestCase
{

	/*
	 * @see TestCase#setUp()
	 */
	protected void setUp( ) throws Exception
	{
		super.setUp( );
	}

	/*
	 * @see TestCase#tearDown()
	 */
	protected void tearDown( ) throws Exception
	{
		super.tearDown( );
	}

	public void testDdb( )
	{
		assertEquals( 280, Finance.ddb( 1400, 200, 10, 1 ), Double.MIN_VALUE );
		//All parameters of this function,cost,salvage,life,period should
		// be positive. If we provide a negative parameter, application will
		// report IllegalArgumentException
		boolean throwException = false;
		try
		{
			Finance.ddb( 1400, 200, -10, 1 );
		}
		catch ( IllegalArgumentException e )
		{
			throwException = true;
		}
		assertTrue( throwException );
	}

	public void testSln( )
	{
		assertEquals( 120, Finance.sln( 1400, 200, 10 ), Double.MIN_VALUE );
	}

	public void testSyd( )
	{

		assertEquals( 196.36363636363637, Finance.syd( 1400, 200, 10, 2 ),
				Double.MIN_VALUE );
		assertEquals( 218.18, Finance.syd( 1400, 200, 10, 1 ), 0.01 );
	}

	public void testFv( )
	{

		assertEquals( 27896.60, Finance
				.fv( 0.057 / 365, 18 * 365, 0, -10000, 1 ), 0.01 );
		assertEquals( 48575.82, Finance
				.fv( 0.057 / 12, 18 * 12, -55, -10000, 1 ), 0.01 );

		//All parameters of this function should be positive. If we provide a
		// negative parameter, application will report IllegalArgumentException.
		// And if we input the value of parameter due is neither 1 or 0,
		// application will also report error.
		boolean throwException = false;
		try
		{
			Finance.fv( 0.057 / 12, 18 * 12, -55, -10000, 3 );
		}
		catch ( IllegalArgumentException e )
		{
			throwException = true;
		}
		assertTrue( throwException );
	}

	public void testPmt( )
	{

		assertEquals( 653.26, Finance.pmt( 0.115 / 12, 36, -20000, 0, 1 ), 0.01 );

		// If we input the value of parameter due is neither 1 or 0,
		// application will also report error.
		boolean throwException = false;
		try
		{
			Finance.pmt( 0.115 / 12, 36, -20000, 0, -1 );
		}
		catch ( IllegalArgumentException e )
		{
			throwException = true;
		}
		assertTrue( throwException );
	}

	public void testIpmt( )
	{

		assertEquals( 171.82, Finance.ipmt( 0.115 / 12, 5, 36, -20000, 0, 1 ),
				0.01 );
		//If any parameter meet the following condition:rate < 0 || nPer < 0 ||
		// per > nPer || ( due != 1 && due != 0 ), application will report error
		boolean throwException1 = false;
		boolean throwException2 = false;
		try
		{
			Finance.ipmt( 0.115 / 12, 37, 36, -20000, 0, 1 );
		}
		catch ( IllegalArgumentException e )
		{
			throwException1 = true;
		}
		assertTrue( throwException1 );
		try
		{
			Finance.ipmt( 0.115 / 12, 3, 36, -20000, 0, 8 );
		}
		catch ( IllegalArgumentException e )
		{
			throwException2 = true;
		}
		assertTrue( throwException2 );

	}

	public void testPpmt( )
	{

		assertEquals( 481.43, Finance.ppmt( 0.115 / 12, 5, 36, -20000, 0, 1 ),
				0.01 );
		//If any parameter meet the following condition:rate < 0 || nPer < 0 ||
		// per > nPer || ( due != 1 && due != 0 ), application will report error
		boolean throwException1 = false;
		boolean throwException2 = false;
		try
		{
			Finance.ppmt( 0.115 / 12, 66, 36, -20000, 0, 1 );
		}
		catch ( IllegalArgumentException e )
		{
			throwException1 = true;
		}
		assertTrue( throwException1 );
		try
		{
			Finance.ppmt( 0.115 / 12, 5, 36, -20000, 0, 7 );
		}
		catch ( IllegalArgumentException e )
		{
			throwException2 = true;
		}
		assertTrue( throwException2 );
	}

	public void testNPer( )
	{
		assertEquals( 35.999, Finance.nper( 0.115 / 12, -653.26, 20000, 0, 1 ), 0.001 );
	}

	public void testPv( )
	{

		assertEquals( 2048.06,
				Finance.pv( 0.105 / 12, 3 * 12, -325, 11000, 1 ), 0.01 );
		//If any parameter meet the following condition:(( nPer < 0 || ( due !=
		// 1 && due != 0 ) ), application will report error
	}

	public void testRate( )
	{
		assertEquals( 0.115,
				Finance.rate( 3 * 12, -653.26, 20000, 0, 1, 0.1 ) * 12, 0.01 );
		//If any parameter meet the following condition:( nPer <= 0 || ( due !=
		// 1 && due != 0 ) ), application will report error
		boolean throwException = false;
		try
		{
			Finance.rate( -3, -653.26, 20000, 0, 1, 0.1 );
		}
		catch ( IllegalArgumentException e )
		{
			throwException = true;
		}
		assertTrue( throwException );
	}

	public void testPercent( )
	{
		assertEquals( 250, Finance.percent( 20, 50, 0.0 ), Double.MIN_VALUE );
		assertEquals( 0, Finance.percent( 50, 0, 0.0 ), Double.MIN_VALUE );
		assertEquals( 10, Finance.percent( 50, 0, 10 ), Double.MIN_VALUE );
	}

	public void testNpv( )
	{
		boolean throwException = false;
		//If user input illegal cash flow, application will throw exception
		try
		{
			double a[] = new double[]{-10000, 3000, 4200, 6800};
			assertEquals( 1188.4434123352207, Finance.npv(  0.1, a ),
					Double.MIN_VALUE );
		}
		catch ( IllegalArgumentException e )
		{
			throwException = true;
		}
		assertTrue( !throwException );
	}

	public void testIrr( )
	{
		double b[] = new double[]{-70000d, 12000d, 15000d, 18000d, 21000d,
				26000d};
		double a[] = new double[]{-70000, 12000, 15000};
		double c[] = new double[]{-70000d, 12000d, 15000d, 18000d, 21000d};
		//If the value of the guess is far from the correct answer, application
		// can't get the correct result and will report error
		//Finance.irr( a, 0.1 );
		assertEquals( -0.44, Finance.irr( a, -0.6 ), 0.01 );
		assertEquals( 0.0866, Finance.irr( b, 0.01 ), 0.0001 );
		assertEquals( -0.021244848272999998, Finance.irr( c, -0.1 ),
				Double.MIN_VALUE );

	}

	public void testMirr( )
	{
		//If the value of the guess is far from the correct answer, application
		// can't get the correct result and will report error
		double a[] = new double[]{-120000, 39000, 30000, 21000, 37000, 46000};
		double b[] = new double[]{-120000, 39000, 30000, 21000};

		assertEquals( 0.1260941303659051, Finance.mirr( a, 0.1, 0.12 ),
				Double.MIN_VALUE );
		assertEquals( 0.13475911082831482, Finance.mirr( a, 0.1, 0.14 ),
				Double.MIN_VALUE );
		assertEquals( -0.048044655249980806, Finance.mirr( b, 0.1, 0.12 ),
				Double.MIN_VALUE );

	}

}
