import org.testng.annotations.DataProvider ;
import org.testng.annotations.Test ;
import static org.testng.Assert.assertEquals ;

import java.math.BigInteger ;

public class Factorial_BigInteger_Test {
  private Factorial_BigInteger f = new Factorial_BigInteger ( ) ;
  @DataProvider ( name = "theData" ) public Object[][] createData ( ) {
    return new Object[][] {
      { 0 , "1" } ,
      { 1 , "1" } , 
      { 2 , "2" } ,
      { 3 , "6" } ,
      { 4 , "24" } ,
      { 5 , "120" } ,
      { 6 , "720" } ,
      { 7 , "5040" } ,
      { 8 , "40320" } ,
      { 9 , "362880" } ,
      { 10 , "3628800" } ,
      { 11 , "39916800" } ,
      { 12 , "479001600" } ,
      { 13 , "6227020800" } ,
      { 14 , "87178291200" } ,
      { 20 , "2432902008176640000" } ,
      { 30 , "265252859812191058636308480000000" } ,
      { 40 , "815915283247897734345611269596115894272000000000" }
    } ;
  }
  @Test ( dataProvider = "theData" ) public void correctIterative ( final long n , final String expected ) {
    assertEquals ( new BigInteger ( expected ) , Factorial_BigInteger.iterative ( n ) ) ;
  }
  @Test ( dataProvider = "theData" ) public void correctRecursive ( final long n , final String expected ) {
    assertEquals ( new BigInteger ( expected ) , Factorial_BigInteger.recursive ( n ) ) ;
  }
  @DataProvider ( name = "theNegative" ) public Object[][] createNegative ( ) {
    return new Object[][] { { -20 } , { -15 } , { -10 } , { -5 } , { -2 } , { -1 } } ;
  }
  @Test ( dataProvider = "theNegative" , expectedExceptions = { RuntimeException.class } )
  public void negativeIterative ( final long n ) { Factorial_BigInteger.iterative ( n ) ; }
  @Test ( dataProvider = "theNegative" , expectedExceptions = { RuntimeException.class } )
  public void negativeRecursive ( final long n ) { Factorial_BigInteger.recursive ( n ) ; }
}
