(**************************************************************************
 * You can add new test cases by adding new elements to the following lists
 * Format is:
 * TEST<X>ARG(<weight>, <function_name>, <arg1>, <arg2>, ..., <argX>)
 *
 * <X> is the number of argument that the function being tested takes.
 **************************************************************************)

open Mp2common

let even_count_fr_stu l = List.fold_right Student.even_count_fr_step l Student.even_count_fr_base
let even_count_fr_sol l = List.fold_right Solution.even_count_fr_step l Solution.even_count_fr_base

let pair_sums_map_arg_stu l = List.map Student.pair_sums_map_arg l
let pair_sums_map_arg_sol l = List.map Solution.pair_sums_map_arg l

let even_count_tr_stu l = List.fold_left Student.even_count_tr_step Student.even_count_tr_start l
let even_count_tr_sol l = List.fold_left Solution.even_count_tr_step Solution.even_count_tr_start l

let count_element_stu l m = List.fold_left (Student.count_element_step m) Student.count_element_start l
let count_element_sol l m = List.fold_left (Solution.count_element_step m) Solution.count_element_start l

let exists_between_stu m n l = List.fold_left (Student.exists_between_step m n) Student.exists_between_start l
let exists_between_sol m n l = List.fold_left (Solution.exists_between_step m n) Solution.exists_between_start l

(* This list is for regular problems *)
let rubric =
[
  (* Problem 1 *)
  TEST1ARG_TWOFUN(1, even_count_fr_sol, even_count_fr_stu, [1;2;3]);

  (* Problem 2 *)
  TEST1ARG_TWOFUN(1, pair_sums_map_arg_sol, pair_sums_map_arg_stu, [(1,6);(3,1);(3,2)]);
  
  (* Problem 3 *)
  TEST1ARG_TWOFUN(1, even_count_tr_sol, even_count_tr_stu, [1;2;3]);

  (* Problem 4 *)
  TEST2ARG_TWOFUN(1, count_element_sol, count_element_stu, [0;1;2;4;2;5;4;2], 2);
  TEST2ARG_TWOFUN(0, count_element_sol, count_element_stu, [()], ());

  (* Problem 5 *)
  TEST3ARG(1, app_all_with, [(fun x y -> x*y); (fun x y -> x+y)], 10, [-1;0;1]);
  TEST3ARG(0, app_all_with, [(fun () ((),()) -> true)], (), [ ((),());  ((),())]);


  (* Problem 6 *)
  TEST3ARG_TWOFUN(1, exists_between_sol, exists_between_stu, 5, 10, [1; 20; 7; 9]);
	TEST3ARG_TWOFUN(0, exists_between_sol, exists_between_stu, (), (), [()]);


  TEST2ARG(0, consk, (1, []), (List.map string_of_int));
  TEST2ARG(0, consk, (1, []), (fun x -> ()));
  TEST2ARG(0, concatk, ("hello", "world"), (fun s -> (s , String.length s)));
  TEST2ARG(0, concatk, ("hello", "world"), (fun s -> ()));
  TEST2ARG(0, string_of_intk, 1, (fun s -> (s , String.length s)));
  TEST2ARG(0, string_of_intk, 1, (fun s -> ()));
  TEST2ARG(0, truncatek, 3.14, string_of_int);
  TEST2ARG(0, truncatek, 3.14, (fun s -> ()));

  TEST2ARG(1, diff_flipk, 1, report_int);
  TEST2ARG(0, diff_flipk, 1, (fun s -> ()));

  TEST2ARG(1, quadk, (1, 1, 1), report_int);
  TEST2ARG(0, quadk, (1, 1, 1), (fun s -> ()));

  TEST2ARG(1, three_freezek, ("muda", "plop"), (fun s -> (s, String.length s)));
  TEST2ARG(0, three_freezek, ("muda", "plop"), (fun s -> ()));

  TEST2ARG(1, shiftk, ("--", 3.14), (fun s -> (s , String.length s)));
  TEST2ARG(0, shiftk, ("--", 3.14), (fun s -> (s , String.length s)));

  TEST1ARG(1, list_prod, [1;2;3]);
  TEST2ARG(1, list_prodk, [1;2;3], string_of_int);
  TEST2ARG(0, list_prodk, [], (fun s -> ()));

  TEST1ARG(1, all_positive, [5;3;6;(-1);7]);
  TEST2ARG(1, all_positivek, [5;3;6;(-1);7], (fun b -> if b then "true" else "false"));
  TEST2ARG(0, all_positivek, [], (fun b -> ()));

  TEST1ARG(1, even_count, [1;2;3]);
  TEST2ARG(1, even_countk, [1;2;3], string_of_int);
  TEST2ARG(0, even_countk, [1;2;3], (fun s -> ()))
]
(* Note: the last entry should not be followed by a semicolon. *)

let extra_rubric = [
	TEST1ARG(1, list_compose, [(fun x -> x * x) ; (fun x -> x + 2)]);
	TEST2ARG(1, list_composek, [(fun x -> mulk(x,x)) ; (fun x -> addk(x,2))], string_of_int);
	TEST2ARG(1, list_composek, [(fun x -> mulk(x,x)) ; (fun x -> addk(x,2))], (fun s -> ()))
]
