diff --git a/src/lib/transaction_logic/mina_transaction_logic.ml b/src/lib/transaction_logic/mina_transaction_logic.ml index e282ad9530a..456890f2b21 100644 --- a/src/lib/transaction_logic/mina_transaction_logic.ml +++ b/src/lib/transaction_logic/mina_transaction_logic.ml @@ -543,6 +543,24 @@ module type S = sig -> bool Or_error.t module For_tests : sig + module Stack (Elt : sig + type t + end) : sig + type t = Elt.t list + + val if_ : bool -> then_:t -> else_:t -> t + + val empty : unit -> t + + val is_empty : t -> bool + + val pop_exn : t -> Elt.t * t + + val pop : t -> (Elt.t * t) option + + val push : Elt.t -> onto:t -> t + end + val validate_timing_with_min_balance : account:Account.t -> txn_amount:Amount.t @@ -2503,6 +2521,8 @@ module Make (L : Ledger_intf.S) : >>= Mina_stdlib.Result.List.map ~f:(apply_transaction_second_pass ledger) module For_tests = struct + module Stack = Inputs.Stack + let validate_timing_with_min_balance = validate_timing_with_min_balance let validate_timing = validate_timing diff --git a/src/lib/transaction_logic/test/zkapp_logic.ml b/src/lib/transaction_logic/test/zkapp_logic.ml index 295a17c8db8..92d61590b24 100644 --- a/src/lib/transaction_logic/test/zkapp_logic.ml +++ b/src/lib/transaction_logic/test/zkapp_logic.ml @@ -862,3 +862,89 @@ let%test_module "Test transaction logic." = ) (run_zkapp_cmd ~fee_payer ~fee ~accounts txns) ) end ) + +(* This module tests Inputs.Stack *) +let%test_module "Test stack module" = + ( module struct + module Stack = Transaction_logic.For_tests.Stack (Int) + + let%test_unit "Ensure pop works on non-empty list." = + Quickcheck.test ~trials + (let open Quickcheck in + let open Generator.Let_syntax in + let%map stack = Generator.list_non_empty Generator.size in + let top = List.hd_exn stack in + let tail = List.tl_exn stack in + (stack, top, tail)) + ~f:(fun (stack, top, tail) -> + match Stack.pop stack with + | Some (x, xs) -> + assert (Int.equal x top && List.equal Int.equal xs tail) + | None -> + assert false ) + + let%test_unit "Ensure pop works on empty list." = + match Stack.pop (Stack.empty ()) with + | Some _ -> + assert false + | None -> + assert true + + let%test_unit "Ensure push functionality works." = + Quickcheck.test ~trials + (let open Quickcheck in + let open Generator.Let_syntax in + let%bind stack = Generator.list_non_empty Generator.size in + let%bind stack' = Generator.list_non_empty Generator.size in + let pushed = + List.fold_right stack' ~init:stack ~f:(fun x s -> + Stack.push x ~onto:s ) + in + let pushed' = List.append stack' stack in + return (pushed, pushed')) + ~f:(fun (pushed, pushed') -> + assert (List.equal Int.equal pushed pushed') ) + end ) + +(* This module tests Inputs.Stack *) +let%test_module "Test stack module" = + ( module struct + module Stack = Transaction_logic.For_tests.Stack (Int) + + let%test_unit "Ensure pop works on non-empty list." = + Quickcheck.test ~trials + (let open Quickcheck in + let open Generator.Let_syntax in + let%map stack = Generator.list_non_empty Generator.size in + let top = List.hd_exn stack in + let tail = List.tl_exn stack in + (stack, top, tail)) + ~f:(fun (stack, top, tail) -> + match Stack.pop stack with + | Some (x, xs) -> + assert (Int.equal x top && List.equal Int.equal xs tail) + | None -> + assert false ) + + let%test_unit "Ensure pop works on empty list." = + match Stack.pop (Stack.empty ()) with + | Some _ -> + assert false + | None -> + assert true + + let%test_unit "Ensure push functionality works." = + Quickcheck.test ~trials + (let open Quickcheck in + let open Generator.Let_syntax in + let%bind stack = Generator.list_non_empty Generator.size in + let%bind stack' = Generator.list_non_empty Generator.size in + let pushed = + List.fold_right stack' ~init:stack ~f:(fun x s -> + Stack.push x ~onto:s ) + in + let pushed' = List.append stack' stack in + return (pushed, pushed')) + ~f:(fun (pushed, pushed') -> + assert (List.equal Int.equal pushed pushed') ) + end )