open OUnit ;; open Num ;; let testData = [ ( Int 0 , Int 1 ) ; ( Int 1 , Int 1 ) ; ( Int 2 , Int 2 ) ; ( Int 3 , Int 6 ) ; ( Int 4 , Int 24 ) ; ( Int 5 , Int 120 ) ; ( Int 6 , Int 720 ) ; ( Int 7 , Int 5040 ) ; ( Int 8 , Int 40320 ) ; ( Int 9 , Int 362880 ) ; ( Int 10 , Int 3628800 ) ; ( Int 11 , Int 39916800 ) ; ( Int 12 , Int 479001600 ) ; ( Int 13 , num_of_string "6227020800" ) ; ( Int 14 , num_of_string "87178291200" ) ; ( Int 20 , num_of_string "2432902008176640000" ) ; ( Int 30 , num_of_string "265252859812191058636308480000000" ) ; ( Int 40 , num_of_string "815915283247897734345611269596115894272000000000" ) ] ;; let rec createRecursiveTestList data result = match data with [ ] -> List.rev result | _ -> let ( i , r ) = List.hd ( data ) in createRecursiveTestList ( List.tl data ) ( ( "recursive test " ^ ( string_of_num i ) >:: ( fun _ -> assert_equal r ( Factorial.recursive i ) ) ) :: result ) ;; let rec createTailRecursiveTestList data result = match data with [ ] -> List.rev result | _ -> let ( i , r ) = List.hd ( data ) in createTailRecursiveTestList ( List.tl data ) ( ( "tailRecursive test " ^ ( string_of_num i ) >:: ( fun _ -> assert_equal r ( Factorial.tailRecursive i ) ) ) :: result ) ;; let negativeData = [ -20 ; -10 ; -4 ; -2 ; -1 ] let rec createRecursiveNegativeList data result = match data with [ ] -> result | _ -> let i = List.hd data in createRecursiveNegativeList ( List.tl data ) ( ( "recursive negative test " ^ ( string_of_int i ) >:: ( fun _ -> assert_raises "negative" NegativeValue Factorial.recursive i ) ) :: result ) ;; let testFactorialZero _ = assert_equal ( Int 1 ) ( Factorial.tailRecursive ( Int 0 ) ) ;; let testFactorialOne _ = assert_equal ( Int 1 ) ( Factorial.tailRecursive ( Int 1 ) ) ;; let testFactorialTwo _ = assert_equal ( Int 2 ) ( Factorial.tailRecursive ( Int 2 ) ) ;; let suite = "Factorial Test" >::: createRecursiveTestList testData [ ] @ createTailRecursiveTestList testData [ ] @ [ "testFactorialZero" >:: testFactorialZero ; "testFactorialOne" >:: testFactorialOne ; "testFactorialTwo" >:: testFactorialTwo ] let _ = run_test_tt_main suite ;;