(** Test the behavior of the sqlite with a in-memory database *) open StdLabels open Test_migration let result = Alcotest.(result Test_migration.csv_result reject) let check = Alcotest.check result let ( let* ) res cont = match res with | Ok value -> cont value | Error e -> Error e (** Test a process with a simple configuration in-memory. Only one table is handlded *) let run_test ~configuration ~input ~expected name = name >:: fun () -> (* We expect a valid configuration *) let conf = ConfLoader.load configuration in let exec db = let table = List.hd @@ ImportAnalyser.Dependency.get_process_order conf in let* () = ImportSQL.Db.create_table db table in (* Prepare the statement in order to import data *) let* stmt = ImportSQL.Db.prepare_insert db table in (* Inject some data into the table *) let result, _ = List.fold_left ~init:(Ok (), 0) input ~f:(fun (_, i) data -> let result = let* () = ImportSQL.Db.insert ~id:i db stmt data in let* () = ImportSQL.Db.reset stmt in Ok () in (result, i + 1)) in let* () = result in let* () = ImportSQL.Db.finalize stmt in (* Collect the data *) let data = ref [] in let* () = ImportSQL.Db.query db conf ~f:(fun rows -> let values = Array.map ~f:snd rows in data := values :: !data) in Ok (List.rev !data) in (* Use a magic keyword for in-memory database *) let result = ImportSQL.Db.with_db ":memory:" exec in check name expected result (** Simple test used to check the process *) let simple_extraction = run_test "simple_extraction" ~configuration: {|version = 1 [source] name = "source_name" file = "source_file" [sheet] columns = [ ":A ^ '_'", ":B", ":E"]|} ~input: [ [ (0, ImportCSV.DataType.Integer 123); (1, ImportCSV.DataType.Integer 2); (4, ImportCSV.DataType.Integer 5); ]; ] ~expected: (Ok [ [| ImportCSV.DataType.Content "123_"; ImportCSV.DataType.Integer 2; ImportCSV.DataType.Integer 5; |]; ]) (** Ensure the behavior of the sum function when a filter is given. It is expected to accumulate the values over each line *) let sum_sort = run_test "sum_sort" ~configuration: {|version = 1 [source] name = "source_name" file = "source_file" [sheet] columns = [ ":A", "sum(:C, [:B], [:A])", ]|} ~input: [ [ (0, ImportCSV.DataType.Integer 1); (1, ImportCSV.DataType.Content "A"); (2, ImportCSV.DataType.Integer 100); ]; [ (0, ImportCSV.DataType.Integer 2); (1, ImportCSV.DataType.Content "A"); (2, ImportCSV.DataType.Integer 100); ]; [ (0, ImportCSV.DataType.Integer 3); (1, ImportCSV.DataType.Content "A"); (2, ImportCSV.DataType.Integer 100); ]; ] ~expected: (Ok [ [| ImportCSV.DataType.Integer 1; ImportCSV.DataType.Integer 100 |]; [| ImportCSV.DataType.Integer 2; ImportCSV.DataType.Integer 200 |]; [| ImportCSV.DataType.Integer 3; ImportCSV.DataType.Integer 300 |]; ]) let sum_total = run_test "sum_total" ~configuration: {|version = 1 [source] name = "source_name" file = "source_file" [sheet] columns = [ ":A", "sum(:C, [], [])", ]|} ~input: [ [ (0, ImportCSV.DataType.Integer 1); (2, ImportCSV.DataType.Integer 100); ]; [ (0, ImportCSV.DataType.Integer 2); (2, ImportCSV.DataType.Integer 100); ]; ] ~expected: (Ok [ [| ImportCSV.DataType.Integer 1; ImportCSV.DataType.Integer 200 |] ]) (** Ensure the behavior of the sum function when no filter is given. It is expected to get the total sum for each line *) let sum_unfiltered = run_test "sum_unfiltered" ~configuration: {|version = 1 [source] name = "source_name" file = "source_file" [sheet] columns = [ ":A", "sum(:C, [], [:A])", ]|} ~input: [ [ (0, ImportCSV.DataType.Integer 1); (2, ImportCSV.DataType.Integer 100); ]; [ (0, ImportCSV.DataType.Integer 2); (2, ImportCSV.DataType.Integer 100); ]; ] ~expected: (Ok [ [| ImportCSV.DataType.Integer 1; ImportCSV.DataType.Integer 200 |] ]) let test_suit = [ simple_extraction; sum_sort; sum_total; sum_unfiltered ] let tests = "sql_db" >::: test_suit