diff options
author | Sébastien Dailly <sebastien@dailly.me> | 2025-01-17 20:48:43 +0100 |
---|---|---|
committer | Sébastien Dailly <sebastien@dailly.me> | 2025-01-22 12:22:26 +0100 |
commit | 8e012f4804ecf1665819e761283120a3c0e73643 (patch) | |
tree | c168efe3e1f0edf5e45695c643e62b3e5447be37 | |
parent | bf2af26d896bb499f2c312a4f1ecd3210e2d7780 (diff) |
Switched from OUnit to alcotest
40 files changed, 369 insertions, 450 deletions
diff --git a/dune-project b/dune-project index 11dc9e3..3ba9568 100755 --- a/dune-project +++ b/dune-project @@ -9,7 +9,7 @@ (package (name importer) (depends - (ocaml (>= 4.14.0)) + (ocaml (>= 5.1.0)) (sqlite3 (>= 5.1.0)) (SZXX (and (>= 2.1.0) (<= 4.0.0))) (csv (>= 2.4)) diff --git a/lib/analysers/dependency.ml b/lib/analysers/dependency.ml index 9dd4736..d0ea8b3 100644 --- a/lib/analysers/dependency.ml +++ b/lib/analysers/dependency.ml @@ -23,6 +23,7 @@ type key = { expression : Path.column Expression.t; columns : ImportContainers.IntSet.t Lazy.t; } +[@@deriving show, eq] type t = { table : Table.t; diff --git a/lib/analysers/dependency.mli b/lib/analysers/dependency.mli index c89522a..bc761ae 100644 --- a/lib/analysers/dependency.mli +++ b/lib/analysers/dependency.mli @@ -1,9 +1,9 @@ type t val get_process_order : ImportConf.Syntax.t -> t list -(** Extract the file list to process, following the identified dependancies. - Try to load first the document which does not required another spreadsheet, - and keep going in the topological order +(** Extract the file list to process, following the identified dependancies. Try + to load first the document which does not required another spreadsheet, and + keep going in the topological order Raise [Unknown_source file] if a source is referenced but is not declared. The order matter : the exception will be raised in a source is referenced @@ -13,28 +13,29 @@ val table : t -> ImportDataTypes.Table.t (** Get the table to proceed. *) val columns : t -> ImportContainers.IntSet.t -(** A set of columns loaded in this table. Thoses columns may not need - reported in the final export. +(** A set of columns loaded in this table. Thoses columns may not need reported + in the final export. - Each column is identified by is index in the Excel document. + Each column is identified by is index in the Excel document. - This set does not include the columns used in the keys. They can be - fetched with the [keys] function *) + This set does not include the columns used in the keys. They can be fetched + with the [keys] function *) type key = { name : string; (** This is the name of the target table we are pointed to *) expression : ImportDataTypes.Path.column ImportExpression.T.t; (** The expression used as key *) columns : ImportContainers.IntSet.t Lazy.t; - (** The list of columns used in the key. All the columns are referenced - in the expression. We can have many columns used inside a single - key when a function is used (for example for joining multiple - columns into a single key) *) + (** The list of columns used in the key. All the columns are referenced in + the expression. We can have many columns used inside a single key when + a function is used (for example for joining multiple columns into a + single key) *) } +[@@deriving show, eq] (** This type describe the join key in a table. The name is the refering table using this key (the key name in the datable is key_"name" ), and the expression describe how to build the key. *) val keys : t -> key list -(** [keys] is the list of columns pointed by another one. They are - considered as join key between the diffrent tables. *) +(** [keys] is the list of columns pointed by another one. They are considered as + join key between the diffrent tables. *) diff --git a/lib/analysers/dune b/lib/analysers/dune index 1bbc30f..382dd6b 100755 --- a/lib/analysers/dune +++ b/lib/analysers/dune @@ -9,4 +9,8 @@ importErrors
tsort
)
+ (preprocess (pps
+ ppx_deriving.ord
+ ppx_deriving.show
+ ppx_deriving.eq ))
)
diff --git a/lib/configuration/dune b/lib/configuration/dune index c29ba49..74ace87 100755 --- a/lib/configuration/dune +++ b/lib/configuration/dune @@ -11,9 +11,12 @@ importExpression
importErrors
)
+ (preprocess (pps
+ ppx_deriving.ord
+ ppx_deriving.show
+ ppx_deriving.eq
+ ))
(foreign_stubs (language c) (names locale))
-
-(preprocess (pps ppx_deriving.ord))
)
(rule
diff --git a/lib/configuration/importConf.ml b/lib/configuration/importConf.ml index 47f4ea4..2f56bd6 100644 --- a/lib/configuration/importConf.ml +++ b/lib/configuration/importConf.ml @@ -72,11 +72,5 @@ let get_dependancies_for_table : Syntax.t -> Table.t -> Syntax.Extern.t list = | Some v -> String.equal v source.name | None -> is_root)) -let print_path_expression t = ImportExpression.Repr.repr Path.repr t - -let print_extern t = - let toml = Syntax.Extern.toml_of_extern t in - Otoml.Printer.to_string toml - let expression_from_string s = Read_conf.ExpressionParser.of_string Read_conf.ExpressionParser.path s diff --git a/lib/configuration/importConf.mli b/lib/configuration/importConf.mli index c88b0f1..9ddc40c 100644 --- a/lib/configuration/importConf.mli +++ b/lib/configuration/importConf.mli @@ -14,9 +14,5 @@ val get_table_for_name : Syntax.t -> string option -> Table.t val get_dependancies_for_table : Syntax.t -> Table.t -> Syntax.Extern.t list (** Get all the externals refered by the source *) -val print_path_expression : Path.t ImportExpression.T.t -> string - val expression_from_string : string -> (Path.t ImportExpression.T.t, string) result - -val print_extern : Syntax.Extern.t -> string diff --git a/lib/configuration/syntax.ml b/lib/configuration/syntax.ml index 253720e..ee47277 100644 --- a/lib/configuration/syntax.ml +++ b/lib/configuration/syntax.ml @@ -21,6 +21,7 @@ module Extern = struct allow_missing : bool; match_rule : string option; } + [@@deriving show, eq] (** Describe a relation beteween two tables *) let toml_of_extern extern = @@ -28,7 +29,7 @@ module Extern = struct [ ( "intern_key", Otoml.string - @@ ImportExpression.Repr.repr ~top:true Path.repr extern.intern_key ); + @@ ImportExpression.Repr.repr ~top:true Path.show extern.intern_key ); ( "extern_key", Otoml.string @@ ImportExpression.Repr.repr ~top:true @@ -67,7 +68,7 @@ let repr t = let repr_expression_list l = Otoml.array (List.map l ~f:(fun v -> - Otoml.string (ImportExpression.Repr.repr ~top:true Path.repr v))) + Otoml.string (ImportExpression.Repr.repr ~top:true Path.show v))) in let sheet = diff --git a/lib/containers/dune b/lib/containers/dune index 46d0e24..70bbf0b 100755 --- a/lib/containers/dune +++ b/lib/containers/dune @@ -4,4 +4,8 @@ importDataTypes
importConf
)
+ (preprocess (pps
+ ppx_deriving.ord
+ ppx_deriving.show
+ ppx_deriving.eq ))
)
diff --git a/lib/containers/importContainers.ml b/lib/containers/importContainers.ml index bf65ba4..6da8374 100644 --- a/lib/containers/importContainers.ml +++ b/lib/containers/importContainers.ml @@ -2,8 +2,7 @@ module Conf = ImportConf module Syntax = Conf.Syntax module Table = ImportDataTypes.Table -(** This key is used to create the table of each externals in the - configuration. +(** This key is used to create the table of each externals in the configuration. This table allow to check if there are cycles between the references *) module KeyName : sig @@ -49,13 +48,12 @@ end = struct end module Externals = MoreLabels.Map.Make (KeyName) -module IntSet = MoreLabels.Set.Make (Int) - -let show_intSet set = - let b = Buffer.create 16 in - IntSet.iter - ~f:(fun v -> - Buffer.add_string b (string_of_int v); - Buffer.add_char b ',') - set; - Buffer.contents b + +module IntSet = struct + include MoreLabels.Set.Make (Int) + + let pp : Format.formatter -> t -> unit = + fun format set -> + let iter' f = iter ~f in + Format.pp_print_iter iter' Format.pp_print_int format set +end diff --git a/lib/data_types/dune b/lib/data_types/dune index e38310b..b735171 100644 --- a/lib/data_types/dune +++ b/lib/data_types/dune @@ -4,7 +4,8 @@ importCSV ) - (preprocess (pps ppx_deriving.ord)) + (preprocess (pps + ppx_deriving.ord + ppx_deriving.show + ppx_deriving.eq )) ) - - diff --git a/lib/data_types/path.ml b/lib/data_types/path.ml index 6684b5a..0a87109 100644 --- a/lib/data_types/path.ml +++ b/lib/data_types/path.ml @@ -1,14 +1,14 @@ -type column = int [@@deriving ord] +type column = int [@@deriving ord, show, eq] type t = { alias : string option; (* External file to load, when the information is missing, load in - the current file *) + the current file *) column : column; } -[@@deriving ord] +[@@deriving ord, show, eq] -let repr { alias; column } = +let show { alias; column } = let column_text = ImportCSV.Csv.column_to_string column in match alias with | None -> ":" ^ column_text diff --git a/lib/data_types/table.ml b/lib/data_types/table.ml index 82a7d95..2dd956b 100644 --- a/lib/data_types/table.ml +++ b/lib/data_types/table.ml @@ -5,6 +5,7 @@ type t = { tab : int; name : string; } +[@@deriving show, eq] (** Get the internal name for the given table. diff --git a/lib/data_types/types.ml b/lib/data_types/types.ml index 37fd90f..866e923 100644 --- a/lib/data_types/types.ml +++ b/lib/data_types/types.ml @@ -5,11 +5,4 @@ type t = | None | Extern | Float - -let string_of_t : t -> string = function - | Number -> "Number" - | String -> "String" - | Bool -> "Bool" - | None -> "None" - | Extern -> "Extern" - | Float -> "Float" +[@@deriving show, eq] diff --git a/lib/errors/dune b/lib/errors/dune index ab71219..c39f47f 100644 --- a/lib/errors/dune +++ b/lib/errors/dune @@ -1,6 +1,7 @@ (library (name importErrors) (libraries + ppx_deriving.runtime csv sqlite3 importCSV diff --git a/lib/errors/importErrors.ml b/lib/errors/importErrors.ml index 97a6259..f888725 100644 --- a/lib/errors/importErrors.ml +++ b/lib/errors/importErrors.ml @@ -43,8 +43,8 @@ let repr_error = function | TypeError { expected; actual; expression; subset } -> Printf.sprintf "In this expression %s has type %s but %s was expected:\n%s" subset - (ImportDataTypes.Types.string_of_t actual) - (ImportDataTypes.Types.string_of_t expected) + (ImportDataTypes.Types.show actual) + (ImportDataTypes.Types.show expected) expression | Unknown_extension ext -> Printf.sprintf "Unknown file extension %s" ext | UnknowFunction name -> diff --git a/lib/expression/dune b/lib/expression/dune index 96e386e..d141b7b 100755 --- a/lib/expression/dune +++ b/lib/expression/dune @@ -6,4 +6,7 @@ importDataTypes
importErrors
)
+ (preprocess (pps
+ ppx_deriving.show
+ ppx_deriving.eq ))
)
diff --git a/lib/expression/t.ml b/lib/expression/t.ml index 9ce21b8..fec8fd7 100644 --- a/lib/expression/t.ml +++ b/lib/expression/t.ml @@ -6,6 +6,7 @@ type 'a window = | Counter | Previous of 'a | Sum of 'a +[@@deriving show, eq] type 'a t = | Empty @@ -21,6 +22,7 @@ type 'a t = | BOperator of binary_operator * 'a t * 'a t | GEquality of binary_operator * 'a t * 'a t list | Function' of funct * 'a t list +[@@deriving show, eq] and binary_operator = | Equal diff --git a/lib/expression/t.mli b/lib/expression/t.mli index 49ef3e7..4e1af55 100644 --- a/lib/expression/t.mli +++ b/lib/expression/t.mli @@ -19,6 +19,7 @@ type 'a t = | BOperator of binary_operator * 'a t * 'a t | GEquality of binary_operator * 'a t * 'a t list | Function' of funct * 'a t list +[@@deriving show, eq] and binary_operator = | Equal diff --git a/lib/sql/db.ml b/lib/sql/db.ml index 0f06f15..f1aee8c 100644 --- a/lib/sql/db.ml +++ b/lib/sql/db.ml @@ -16,7 +16,7 @@ let reset = T.reset let insert_header = Header.insert_header let query_headers = Header.query_headers -let with_db : string -> (Sqlite3.db -> unit T.result) -> unit T.result = +let with_db : string -> (Sqlite3.db -> 'b T.result) -> 'b T.result = fun filename f -> let db = Sqlite3.db_open filename in diff --git a/lib/sql/db.mli b/lib/sql/db.mli index 478d762..91933c4 100644 --- a/lib/sql/db.mli +++ b/lib/sql/db.mli @@ -3,7 +3,7 @@ module Syntax = ImportConf.Syntax type 'a t type 'a result = ('a, exn) Result.t -val with_db : string -> ('a t -> unit result) -> unit result +val with_db : string -> ('a t -> 'b result) -> 'b result val check_table_schema : 'a t -> ImportAnalyser.Dependency.t -> bool result (** Check if a table with the same structure already exists in the database. diff --git a/tests/analyser_dependency.ml b/tests/analyser_dependency.ml index 279b5e5..8409d73 100644 --- a/tests/analyser_dependency.ml +++ b/tests/analyser_dependency.ml @@ -1,4 +1,3 @@ -open OUnit2 open StdLabels module A = ImportAnalyser.Dependency module Cont = ImportContainers @@ -6,6 +5,7 @@ module Syntax = ImportConf.Syntax module Expression = ImportExpression.T module Table = ImportDataTypes.Table open ConfLoader +open Test_migration let test_order = "Order" >:: fun _ -> @@ -13,8 +13,9 @@ let test_order = let expected_order = [ external_table_last; external_table_other; external_table_source ] in - assert_equal ~cmp:(cmp_list cmp_source) ~printer:show_sources expected_order - order + Alcotest.check + (Alcotest.list Test_migration.table_testable) + "" expected_order order let test_columns = "Columns" >:: fun _ -> @@ -25,9 +26,8 @@ let test_columns = |> A.columns in - assert_equal - ~cmp:(fun a b -> 0 = Cont.IntSet.compare a b) - ~printer:Cont.show_intSet expected_colums columns + Alcotest.check Test_migration.int_container_testable "" expected_colums + columns let test_keys = "Keys" >:: fun _ -> @@ -49,8 +49,7 @@ let test_keys = |> List.find ~f:(fun v -> A.table v = external_table_other) |> A.keys in - - assert_equal ~cmp:(cmp_list key_cmp) ~printer:keys_printer expected_keys keys + Alcotest.(check (list Test_migration.dep_key_testable)) "" expected_keys keys let test_keys_missing = "Keys missing" >:: fun _ -> @@ -72,13 +71,13 @@ let test_keys_missing = |> A.keys in - assert_equal ~cmp:(cmp_list key_cmp) ~printer:keys_printer expected_keys keys + Alcotest.(check (list Test_migration.dep_key_testable)) "" expected_keys keys let test_unknow_source = "Unknown source" >:: fun _ -> let conf = { conf with externals = [] } in - assert_raises (ImportErrors.Unknown_source "last_file") (fun () -> - A.get_process_order conf) + Alcotest.check_raises "" (ImportErrors.Unknown_source "last_file") (fun () -> + ignore @@ A.get_process_order conf) let test_unordered = "Unorderd references" >:: fun _ -> @@ -86,8 +85,7 @@ let test_unordered = error. *) let conf = load - {|version = 1 -[source] + {|[source] file = "source.xlsx" name = "source" @@ -106,16 +104,15 @@ let test_unordered = [sheet] columns = []|} in - assert_raises (ImportErrors.Unknown_source "other") (fun () -> - A.get_process_order conf) + Alcotest.check_raises "" (ImportErrors.Unknown_source "other") (fun () -> + ignore @@ A.get_process_order conf) let test_circular = "Unlinked reference" >:: fun _ -> (* A reference to itself should be understood *) let conf = load - {|version = 1 -[source] + {|[source] file = "source.xlsx" name = "source" @@ -130,7 +127,7 @@ let test_circular = in let elements = A.get_process_order conf in - assert_equal ~printer:string_of_int 1 (List.length elements) + Alcotest.check Alcotest.int "" 1 (List.length elements) let test_unlinked = "Circular reference" >:: fun _ -> @@ -164,8 +161,8 @@ let test_unlinked = uniq = []; } in - assert_raises (ImportErrors.Unknown_source "circular2") (fun () -> - A.get_process_order conf |> List.map ~f:A.table) + Alcotest.check_raises "" (ImportErrors.Unknown_source "circular2") (fun () -> + A.get_process_order conf |> List.map ~f:A.table |> ignore) let conf_with_unlinked = Syntax. @@ -204,7 +201,9 @@ let test_order_filter = |> A.get_process_order |> List.map ~f:A.table in let expected_order = [ external_table_other; external_table_source ] in - assert_equal ~printer:show_sources expected_order order + Alcotest.check + (Alcotest.list Test_migration.table_testable) + "" expected_order order (** A table referenced only in the order list shall be loaded correctly *) let test_order_sort = @@ -217,7 +216,9 @@ let test_order_sort = |> A.get_process_order |> List.map ~f:A.table in let expected_order = [ external_table_other; external_table_source ] in - assert_equal ~printer:show_sources expected_order order + Alcotest.check + (Alcotest.list Test_migration.table_testable) + "" expected_order order (** A table referenced only in the uniq list shall be loaded correctly *) let test_order_uniq = @@ -230,7 +231,9 @@ let test_order_uniq = |> A.get_process_order |> List.map ~f:A.table in let expected_order = [ external_table_other; external_table_source ] in - assert_equal ~printer:show_sources expected_order order + Alcotest.check + (Alcotest.list Test_migration.table_testable) + "" expected_order order let tests = "analyser_dependency" diff --git a/tests/analyser_query_test.ml b/tests/analyser_query_test.ml index 5d7366b..0e23f11 100644 --- a/tests/analyser_query_test.ml +++ b/tests/analyser_query_test.ml @@ -1,60 +1,22 @@ -open OUnit2 open StdLabels module A = ImportAnalyser.Dependency module Q = ImportAnalyser.Query module C = ImportConf module Syntax = ImportConf.Syntax module Expr = Expression_builder - -let show_source (source : ImportDataTypes.Table.t) = - Printf.sprintf "%s:%d" source.ImportDataTypes.Table.file source.tab - -let show_sources sources = - let b = Buffer.create 16 in - Buffer.add_string b "["; - List.iter sources ~f:(fun source -> - Buffer.add_string b (show_source source); - Buffer.add_string b ","); - - let len = Buffer.length b in - if len > 1 then Buffer.truncate b (len - 1); - Buffer.add_string b "]"; - - Buffer.contents b +open Test_migration (** This is sample configuration used in the tests *) let conf = Syntax. { - version = 1; - locale = None; - source = { file = "source.xlsx"; tab = 1; name = "source" }; - externals = - [ - { - intern_key = Path { alias = None; column = 1 }; - target = { file = "other.xlsx"; tab = 1; name = "other" }; - extern_key = Path 3; - allow_missing = false; - match_rule = None; - }; - { - intern_key = Path { alias = Some "other"; column = 1 }; - target = { file = "last.xlsx"; tab = 1; name = "last_file" }; - extern_key = Path 3; - allow_missing = true; - match_rule = None; - }; - ]; + ConfLoader.conf with columns = [ Concat [ Path { alias = None; column = 1 }; Literal "_"; Empty ]; Path { alias = None; column = 2 }; Path { alias = Some "last_file"; column = 5 }; ]; - filters = []; - sort = []; - uniq = []; } let create_table = @@ -63,7 +25,7 @@ let create_table = let query = Q.create_table (List.hd out) in - assert_equal ~printer:Fun.id + Alcotest.check Alcotest.string "" "CREATE TABLE 'last' (id INTEGER PRIMARY KEY,'key_last_file','col_5')" query let select = @@ -78,7 +40,7 @@ LEFT JOIN 'other' AS 'other' ON rtrim(upper('source'.col_1)) = 'other'.'key_othe LEFT JOIN 'last' AS 'last_file' ON rtrim(upper('other'.col_1)) = 'last_file'.'key_last_file'|} in - assert_equal ~printer:Fun.id expected_query query.q + Alcotest.check Alcotest.string "" expected_query query.q let check_externals = "Check external" >:: fun _ -> @@ -92,7 +54,7 @@ let check_externals = IS NOT NULL AND 'source'.col_1 <> ''" in - assert_equal ~printer:Fun.id expected_query query.q + Alcotest.check Alcotest.string "" expected_query query.q let previous = "Test window previous" >:: fun _ -> @@ -117,13 +79,13 @@ let previous = } in - let res, _ = ImportAnalyser.Query.select conf in - let query = + let query, _ = ImportAnalyser.Query.select conf in + let expected_query = "SELECT LAG('previous'.col_5) OVER (PARTITION BY 'previous'.col_1 ORDER BY \ 'previous'.col_3) AS result_0\n\ FROM 'source' AS 'previous'" in - assert_equal ~printer:Fun.id query res.q + Alcotest.check Alcotest.string "" expected_query query.q let sum = "Test window sum" >:: fun _ -> @@ -148,13 +110,13 @@ let sum = } in - let res, _ = ImportAnalyser.Query.select conf in - let query = + let query, _ = ImportAnalyser.Query.select conf in + let expected_query = "SELECT SUM('previous'.col_5) OVER (PARTITION BY 'previous'.col_1) AS \ result_0\n\ FROM 'source' AS 'previous'" in - assert_equal ~printer:Fun.id query res.q + Alcotest.check Alcotest.string "" expected_query query.q let sum_total = "Test sum over the whole range" >:: fun _ -> @@ -173,11 +135,11 @@ let sum_total = } in - let res, _ = ImportAnalyser.Query.select conf in - let query = + let query, _ = ImportAnalyser.Query.select conf in + let expected_query = "SELECT SUM('previous'.col_5) AS result_0\nFROM 'source' AS 'previous'" in - assert_equal ~printer:Fun.id query res.q + Alcotest.check Alcotest.string "" expected_query query.q let sum_unfiltered = "Test sum over the whole range" >:: fun _ -> @@ -202,11 +164,11 @@ let sum_unfiltered = } in - let res, _ = ImportAnalyser.Query.select conf in - let query = + let query, _ = ImportAnalyser.Query.select conf in + let expected_query = "SELECT SUM('previous'.col_5) AS result_0\nFROM 'source' AS 'previous'" in - assert_equal ~printer:Fun.id query res.q + Alcotest.check Alcotest.string "" expected_query query.q let prepare_insert = "Test prepare_insert" >:: fun _ -> @@ -225,7 +187,7 @@ let prepare_insert = let expected = "rtrim(upper(COALESCE(:col_1,'') || '_' || ''))" in - assert_equal ~printer:Fun.id expected contents + Alcotest.check Alcotest.string "" expected contents (** Test a request with a group in a filter. @@ -256,7 +218,7 @@ INNER JOIN 'cte' ON cte.id = source.id WHERE (cte.group0)|} in - assert_equal ~printer:(fun s -> Printf.sprintf "\n%s" s) expected contents.q + Alcotest.check Alcotest.string "" expected contents.q (** Test a request with a group in a filter. @@ -290,7 +252,7 @@ WHERE COALESCE('source'.col_3,0)=0 AND (cte.group0)|} in - assert_equal ~printer:(fun s -> Printf.sprintf "\n%s" s) expected contents.q + Alcotest.check Alcotest.string "" expected contents.q let test_suit = [ diff --git a/tests/confLoader.ml b/tests/confLoader.ml index bce4db0..4adedd6 100644 --- a/tests/confLoader.ml +++ b/tests/confLoader.ml @@ -1,5 +1,3 @@ -open StdLabels - (** Read the configuration in toml and return the internal representation *) let load : string -> ImportConf.Syntax.t = fun content -> @@ -7,9 +5,7 @@ let load : string -> ImportConf.Syntax.t = let conf = load - {|version = 1 - -[source] + {|[source] file = "source.xlsx" name = "source" @@ -60,69 +56,3 @@ let external_last = allow_missing = true; match_rule = None; } - -let show_source (source : ImportDataTypes.Table.t) = - Printf.sprintf "%s:%d" source.ImportDataTypes.Table.file - source.ImportDataTypes.Table.tab - -(* - * Compare two external sources - *) - -let show_sources sources = - let b = Buffer.create 16 in - Buffer.add_string b "["; - List.iter sources ~f:(fun source -> - Buffer.add_string b (show_source source); - Buffer.add_string b ","); - - let len = Buffer.length b in - if len > 1 then Buffer.truncate b (len - 1); - Buffer.add_string b "]"; - - Buffer.contents b - -and cmp_source : ImportDataTypes.Table.t -> ImportDataTypes.Table.t -> bool = - fun s1 s2 -> - String.equal s1.ImportDataTypes.Table.name s2.ImportDataTypes.Table.name - && String.equal s1.ImportDataTypes.Table.file s2.ImportDataTypes.Table.file - && s1.ImportDataTypes.Table.tab = s2.ImportDataTypes.Table.tab - -let cmp_list : ('a -> 'a -> bool) -> 'a list -> 'a list -> bool = - fun cmp elems1 elems2 -> List.for_all2 ~f:cmp elems1 elems2 - -(* - * Compare keys in the dependencies - *) - -let key_printer : ImportAnalyser.Dependency.key -> string = - fun { name; expression; _ } -> - let path_name = - let buffer = Buffer.create 16 in - ImportExpression.Headers.headers_of_expression buffer - (fun col buffer -> - Buffer.add_string buffer (ImportCSV.Csv.column_to_string col)) - expression; - Buffer.contents buffer - in - Printf.sprintf "%s, %s" name path_name - -and key_cmp a b = - 0 - = ImportExpression.T.cmp - (fun a b -> a - b) - a.ImportAnalyser.Dependency.expression - b.ImportAnalyser.Dependency.expression - -let keys_printer : ImportAnalyser.Dependency.key list -> string = - fun contents -> - let b = Buffer.create 16 in - List.iter contents ~f:(fun v -> Buffer.add_string b (key_printer v)); - Buffer.contents b - -(* - * Represents externals - *) - -let pp_externals : ImportConf.Syntax.Extern.t list -> string = - fun ext -> ImportConf.Syntax.Extern.toml ext |> Otoml.Printer.to_string diff --git a/tests/configuration_expression.ml b/tests/configuration_expression.ml index fc4c0ec..cd28589 100644 --- a/tests/configuration_expression.ml +++ b/tests/configuration_expression.ml @@ -1,18 +1,14 @@ -open StdLabels -open OUnit2 -module Expression = ImportExpression.T module Path = ImportDataTypes.Path -open Path +open Test_migration -let printer = function - | Ok e -> ImportExpression.Repr.repr ImportConf.Path.repr e - | Error msg -> msg +let result_testable = + Alcotest.result Test_migration.expression_testable Alcotest.string let parse_dquoted = "parse_dquoted" >:: fun _ -> let expr = "match(\"\\(..\\)\", :B)" in let result = ImportConf.expression_from_string expr in - assert_equal ~printer + Alcotest.check result_testable "" (Ok (Function ("match", [ Literal "\\(..\\)"; Path { alias = None; column = 2 } ]))) @@ -22,7 +18,7 @@ let parse_quoted = "parse_quoted" >:: fun _ -> let expr = "match('\\(..\\)', :B)" in let result = ImportConf.expression_from_string expr in - assert_equal ~printer + Alcotest.check result_testable "" (Ok (Function ("match", [ Literal "\\(..\\)"; Path { alias = None; column = 2 } ]))) @@ -32,7 +28,7 @@ let concat = "concat" >:: fun _ -> let expr = ":A ^ :B" in let result = ImportConf.expression_from_string expr in - assert_equal ~printer + Alcotest.check result_testable "" (Ok (Concat [ @@ -44,7 +40,7 @@ let concat2 = "concat2" >:: fun _ -> let expr = "'A' ^ '_' ^ 'B'" in let result = ImportConf.expression_from_string expr in - assert_equal ~printer + Alcotest.check result_testable "" (Ok (Concat [ Literal "A"; Literal "_"; Literal "B" ])) result @@ -53,37 +49,37 @@ let litteral = (* The text is quoted in shall not be considered as a path *) let expr = "':A'" in let result = ImportConf.expression_from_string expr in - assert_equal ~printer (Ok (Literal ":A")) result + Alcotest.check result_testable "" (Ok (Literal ":A")) result let empty = "empty" >:: fun _ -> let expr = "" in let result = ImportConf.expression_from_string expr in - assert_equal ~printer (Ok Empty) result + Alcotest.check result_testable "" (Ok Empty) result let upper_nvl = "upper_nvl" >:: fun _ -> let expr = "NVL('','')" in let result = ImportConf.expression_from_string expr in - assert_equal ~printer (Ok (Nvl [ Empty; Empty ])) result + Alcotest.check result_testable "" (Ok (Nvl [ Empty; Empty ])) result let lower_nvl = "lower_nvl" >:: fun _ -> let expr = "nvl('','')" in let result = ImportConf.expression_from_string expr in - assert_equal ~printer (Ok (Nvl [ Empty; Empty ])) result + Alcotest.check result_testable "" (Ok (Nvl [ Empty; Empty ])) result let numeric = "numeric" >:: fun _ -> let expr = "123" in let result = ImportConf.expression_from_string expr in - assert_equal ~printer (Ok (Integer "123")) result + Alcotest.check result_testable "" (Ok (Integer "123")) result let numeric_neg = "numeric_neg" >:: fun _ -> let expr = "-123" in let result = ImportConf.expression_from_string expr in - assert_equal ~printer (Ok (Integer "-123")) result + Alcotest.check result_testable "" (Ok (Integer "-123")) result let op_priority = "operator_priority" >:: fun _ -> @@ -94,7 +90,7 @@ let op_priority = BOperator (GT, BOperator (Add, Integer "1", Integer "2"), Integer "2")) in - assert_equal ~printer (Ok expected) result + Alcotest.check result_testable "" (Ok expected) result let op_priority2 = "operator_priority" >:: fun _ -> @@ -105,13 +101,13 @@ let op_priority2 = BOperator (Equal, Concat [ Integer "1"; Integer "2" ], Integer "2")) in - assert_equal ~printer (Ok expected) result + Alcotest.check result_testable "" (Ok expected) result let join = "join" >:: fun _ -> let expr = "join('sep', :A, :B)" in let result = ImportConf.expression_from_string expr in - assert_equal ~printer + Alcotest.check result_testable "" (Ok (Join ( "sep", @@ -125,7 +121,7 @@ let join_empty = "join" >:: fun _ -> let expr = "join('', :A, :B)" in let result = ImportConf.expression_from_string expr in - assert_equal ~printer + Alcotest.check result_testable "" (Ok (Join ( "", @@ -139,30 +135,29 @@ let upper = "upper" >:: fun _ -> let expr = "upper('')" in let result = ImportConf.expression_from_string expr in - assert_equal ~printer (Ok (Function' (Upper, [ Empty ]))) result + Alcotest.check result_testable "" (Ok (Function' (Upper, [ Empty ]))) result let trim = "trim" >:: fun _ -> let expr = "trim('')" in let result = ImportConf.expression_from_string expr in - assert_equal ~printer (Ok (Function' (Trim, [ Empty ]))) result + Alcotest.check result_testable "" (Ok (Function' (Trim, [ Empty ]))) result (** Extract the columns from a window function *) let fold_values = "fold_values" >:: fun _ -> + let open Path in (* The expression we want to test *) let expr = - Expression.Window + ImportExpression.T.Window ( Previous (Path { alias = None; column = 1 }), [ Path { alias = None; column = 2 } ], [ Path { alias = None; column = 3 } ] ) in - (* Extract the columns from the expression. The result is sorted because - the order is not preserved during the extraction. *) let result = - Expression.fold_values ~init:[] ~f:(fun acc v -> v :: acc) expr - |> List.sort ~cmp:Path.compare + ImportExpression.T.fold_values ~init:[] ~f:(fun acc v -> v :: acc) expr + |> List.rev in let expected = @@ -173,21 +168,23 @@ let fold_values = ] in - assert_equal expected result + Alcotest.check + (Alcotest.list @@ Test_migration.make_test (module Path)) + "" expected result let bad_quote = "bad_quote" >:: fun _ -> let expr = "':source.A" in let result = ImportConf.expression_from_string expr in - assert_equal ~printer (Error "Unclosed quote at line 1 : \"':source.A\"") - result + Alcotest.check result_testable "" + (Error "Unclosed quote at line 1 : \"':source.A\"") result let nested_expression = "nested_expression" >:: fun _ -> let expr = "1 = (1 = 0)" in let result = ImportConf.expression_from_string expr in - assert_equal ~printer + Alcotest.check result_testable "" (Ok (BOperator ( Equal, @@ -199,7 +196,7 @@ let priority_equality = "priority_equality" >:: fun _ -> let expr = "1 = 1 = 0" in let result = ImportConf.expression_from_string expr in - assert_equal ~printer + Alcotest.check result_testable "" (Ok (BOperator (Equal, Integer "1", BOperator (Equal, Integer "1", Integer "0")))) @@ -209,7 +206,7 @@ let priority_operator_and = "priority_equality" >:: fun _ -> let expr = "1 and 1 = 0" in let result = ImportConf.expression_from_string expr in - assert_equal ~printer + Alcotest.check result_testable "" (Ok (BOperator (And, Integer "1", BOperator (Equal, Integer "1", Integer "0")))) result @@ -218,7 +215,7 @@ let priority_operator_or = "priority_equality" >:: fun _ -> let expr = "1 <> 1 or 0" in let result = ImportConf.expression_from_string expr in - assert_equal ~printer + Alcotest.check result_testable "" (Ok (BOperator (Or, BOperator (Different, Integer "1", Integer "1"), Integer "0"))) @@ -229,7 +226,7 @@ let unknown_function = let expr = "function()" in let result = ImportConf.expression_from_string expr in - assert_equal ~printer + Alcotest.check result_testable "" (Error "Unknown function or wrong number of arguments for 'function'") result @@ -238,7 +235,7 @@ let wrong_arguments = let expr = "if()" in let result = ImportConf.expression_from_string expr in - assert_equal ~printer + Alcotest.check result_testable "" (Error "Unknown function or wrong number of arguments for 'if'") result let test_suit = diff --git a/tests/configuration_toml.ml b/tests/configuration_toml.ml index 67f8d75..dc1f769 100644 --- a/tests/configuration_toml.ml +++ b/tests/configuration_toml.ml @@ -1,6 +1,6 @@ -open OUnit2 module Expression = ImportExpression.T module Path = ImportDataTypes.Path +open Test_migration let test_suit = [ @@ -27,11 +27,10 @@ let test_suit = } in - let printer s = - String.concat "," (List.map ImportConf.print_extern s) - in - - assert_equal ~printer [ expected ] result.externals ); + ignore + @@ Alcotest.check + (Alcotest.list Test_migration.extern_testable) + "" [ expected ] result.externals ); ( "parse_columns" >:: fun _ -> let toml = Otoml.Parser.from_file "configuration/simple.toml" in let toml = ImportConf.t_of_toml toml in @@ -57,11 +56,9 @@ let test_suit = ] in - List.iter2 - (fun expected result -> - assert_equal ~printer:ImportConf.print_path_expression expected - result) - expected result.columns ); + Alcotest.check + (Alcotest.list Test_migration.expression_testable) + "" expected result.columns ); ( "parse_csv" >:: fun _ -> let toml = Otoml.Parser.from_file "configuration/example_csv.toml" in let toml = ImportConf.t_of_toml toml in @@ -2,10 +2,10 @@ (name importer_test) (deps (source_tree configuration)) (libraries - ounit2 + alcotest otoml - ppx_deriving.runtime sqlite3 + fmt importConf importAnalyser importContainers @@ -14,4 +14,8 @@ importErrors importExpression importSQL -)) + ) + (preprocess (pps + ppx_deriving.show + ppx_deriving.eq )) +) diff --git a/tests/expression_query.ml b/tests/expression_query.ml index e2abc43..367a1e2 100644 --- a/tests/expression_query.ml +++ b/tests/expression_query.ml @@ -1,13 +1,11 @@ -open OUnit2 module T = ImportExpression.T module Expr = Expression_builder module M = Expr.Make (ImportExpression.Query.Query) +open Test_migration let eval = M.eval ~path_repr:(fun formatter n -> Format.fprintf formatter "%s" n) -let printer = Fun.id - let test_expr ?(nested = ImportExpression.Query.QueryParameter.Literal) expr = let buffer = Buffer.create 16 in let formatter = Format.formatter_of_buffer buffer in @@ -15,26 +13,29 @@ let test_expr ?(nested = ImportExpression.Query.QueryParameter.Literal) expr = Format.pp_print_flush formatter (); Buffer.contents buffer +let assert_equal expected actual = + Alcotest.check Alcotest.string expected expected actual + let empty = "empty" >:: fun _ -> let expr = eval Expr.empty in let content = test_expr expr and expected = "''" in - assert_equal ~printer expected content + assert_equal expected content let litteral = "literal" >:: fun _ -> let expr = eval Expr.literal_test in let content = test_expr expr and expected = "'test'" in - assert_equal ~printer expected content + assert_equal expected content let litteral_quoted = "literal_quoted" >:: fun _ -> let expr = eval Expr.literal_quoted in let content = test_expr expr and expected = "'\''" in - assert_equal ~printer expected content + assert_equal expected content let litteral_raw = "literal_raw" >:: fun _ -> @@ -42,7 +43,7 @@ let litteral_raw = let nested = ImportExpression.Query.QueryParameter.(Raw Literal) in let content = test_expr expr ~nested and expected = "test" in - assert_equal ~printer expected content + assert_equal expected content let path = "path" >:: fun _ -> @@ -50,28 +51,28 @@ let path = let expr = eval @@ Expr.path "test" in let content = test_expr expr and expected = "test" in - assert_equal ~printer expected content + assert_equal expected content let concat = "concat" >:: fun _ -> let expr = eval Expr.concat in let content = test_expr expr and expected = "'' || 'test'" in - assert_equal ~printer expected content + assert_equal expected content let nvl = "nvl" >:: fun _ -> let expr = eval @@ Expr.nvl Expr.empty Expr.literal_test in let content = test_expr expr and expected = "COALESCE('', 'test')" in - assert_equal ~printer expected content + assert_equal expected content let upper = "upper" >:: fun _ -> let expr = eval @@ Expr.function' T.Upper [ Expr.literal_test ] in let content = test_expr expr and expected = "UPPER('test')" in - assert_equal ~printer expected content + assert_equal expected content let join = "join" >:: fun _ -> @@ -81,62 +82,62 @@ let join = in let content = test_expr expr and expected = "CONCAT(',', '', 'test')" in - assert_equal ~printer expected content + assert_equal expected content let boperator_eq = "boperator_eq" >:: fun _ -> let expr = eval @@ Expr.equal Expr.empty Expr.literal_test in let content = test_expr expr and expected = "''='test'" in - assert_equal ~printer expected content + assert_equal expected content let boperator_div = "boperator_div" >:: fun _ -> let expr = eval @@ Expr.divide Expr.integer_one Expr.integer_zero in let content = test_expr expr and expected = "CAST(1 AS REAL)/0" in - assert_equal ~printer expected content + assert_equal expected content let boperator_neq = "boperator_neq" >:: fun _ -> let expr = eval @@ Expr.different Expr.empty Expr.literal_test in let content = test_expr expr and expected = "''<>'test'" in - assert_equal ~printer expected content + assert_equal expected content let expr = "expr" >:: fun _ -> let expr = eval Expr.expr in let content = test_expr expr and expected = "(test NOT NULL)" in - assert_equal ~printer expected content + assert_equal expected content let unify_int = "unify_int" >:: fun _ -> let expr = eval @@ Expr.equal (Expr.path "external") Expr.integer_zero in let content = test_expr expr and expected = "COALESCE(external,0)=0" in - assert_equal ~printer expected content + assert_equal expected content let unify_string = "unify_string" >:: fun _ -> let expr = eval @@ Expr.equal (Expr.path "external") Expr.literal_zero in let content = test_expr expr and expected = "COALESCE(external,'')='0'" in - assert_equal ~printer expected content + assert_equal expected content let in_string = "in_string" >:: fun _ -> let expr = eval @@ Expr.in_ (Expr.path "external") [ Expr.literal_zero ] in let content = test_expr expr and expected = "COALESCE(external,'') IN('0')" in - assert_equal ~printer expected content + assert_equal expected content let not_in_string = "in_string" >:: fun _ -> let expr = eval @@ Expr.not_in (Expr.path "external") [ Expr.literal_zero ] in let content = test_expr expr and expected = "COALESCE(external,'') NOT IN('0')" in - assert_equal ~printer expected content + assert_equal expected content (* Evaluate the max function *) let max = @@ -151,7 +152,7 @@ let max = UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)" in - assert_equal ~printer expected content + assert_equal expected content let in_int = "in_int" >:: fun _ -> @@ -160,7 +161,7 @@ let in_int = @@ Expr.in_ (Expr.path "external") [ Expr.integer_zero; Expr.integer_one ] in let content = test_expr expr and expected = "COALESCE(external,0) IN(0, 1)" in - assert_equal ~printer expected content + assert_equal expected content let counter_no_order = "counter_no_order" >:: fun _ -> @@ -169,7 +170,7 @@ let counter_no_order = let content = test_expr expr and expected = "COUNT() OVER (PARTITION BY :A)" in - assert_equal ~printer expected content + assert_equal expected content let counter_order = "counter_no_order" >:: fun _ -> @@ -178,7 +179,7 @@ let counter_order = let content = test_expr expr and expected = "ROW_NUMBER() OVER (PARTITION BY :A ORDER BY :B)" in - assert_equal ~printer expected content + assert_equal expected content let cmp = "cmp" >:: fun _ -> @@ -195,7 +196,7 @@ let cmp = ]) in let content = test_expr expr and expected = "IIF(0=1, 0, IIF(0>1, 1, -1))" in - assert_equal ~printer expected content + assert_equal expected content let test_suit = [ diff --git a/tests/expression_repr.ml b/tests/expression_repr.ml index 9ad321a..20a0484 100644 --- a/tests/expression_repr.ml +++ b/tests/expression_repr.ml @@ -1,35 +1,34 @@ -open OUnit2 module Expression = ImportExpression.T module Path = ImportDataTypes.Path module Expr = Expression_builder module M = Expr.Make (ImportExpression.Repr.E) +open Test_migration let eval = M.eval ~path_repr:ImportCSV.Csv.column_to_string let test_expr expr = ImportExpression.Repr.E.observe ~top:true expr -let printer = function - | Ok e -> ImportConf.print_path_expression e - | Error msg -> msg +let assert_equal expected actual = + Alcotest.(check string) expected expected actual let print_literal = "print_litteral" >:: fun _ -> let result = test_expr @@ eval (Literal "Content") in - assert_equal ~printer:Fun.id "'Content'" result + assert_equal "'Content'" result let print_quoted_literal = "print_quoted_literal" >:: fun _ -> let result = test_expr @@ eval Expression_builder.literal_quoted in - assert_equal ~printer:Fun.id "'\\''" result + assert_equal "'\\''" result let print_dquoted_literal = "print_dquoted_literal" >:: fun _ -> let result = test_expr @@ eval (Literal "\"") in - assert_equal ~printer:Fun.id "'\"'" result + assert_equal "'\"'" result let print_numeric = "print_numeric" >:: fun _ -> let result = test_expr @@ eval (Literal "123") in - assert_equal ~printer:Fun.id "123" result + assert_equal "123" result let test_suit = [ print_literal; print_quoted_literal; print_dquoted_literal; print_numeric ] diff --git a/tests/expression_type_of.ml b/tests/expression_type_of.ml index 706b3e7..a53748d 100644 --- a/tests/expression_type_of.ml +++ b/tests/expression_type_of.ml @@ -1,19 +1,21 @@ -open OUnit2 module T = ImportExpression.T module Types = ImportDataTypes.Types module Expr = Expression_builder module M = Expr.Make (ImportExpression.Type_of) +open Test_migration let eval = M.eval ~path_repr:(fun _ -> ()) -let printer = Types.string_of_t let test_expr expr = ImportExpression.Type_of.observe expr +let check expected actual = + Alcotest.check Test_migration.data_type_testable "" expected actual + let empty = "empty" >:: fun _ -> let expr = eval Expr.empty in let content = test_expr expr and expected = Types.None in - assert_equal ~printer expected content + check expected content (** Control an if statement with a predicate which is not a boolean *) let invalid_if = @@ -32,9 +34,9 @@ let invalid_if = subset = "the predicate"; } in - assert_raises exn (fun () -> + Alcotest.check_raises "" exn (fun () -> let expr = eval raw_expr in - test_expr expr) + ignore @@ test_expr expr) (** The application should infer that the expression is a string *) let valid_if = @@ -46,20 +48,20 @@ let valid_if = Expr.literal_test Expr.literal_test in let content = test_expr expr and expected = Types.String in - assert_equal ~printer expected content + check expected content let upper = "upper" >:: fun _ -> - let expr = eval @@ Expr.function' T.Upper [Expr.literal_test] in + let expr = eval @@ Expr.function' T.Upper [ Expr.literal_test ] in let content = test_expr expr and expected = Types.String in - assert_equal ~printer expected content + check expected content let in_int = "in_int" >:: fun _ -> let expr = eval @@ Expr.in_ (Expr.path "external") [ Expr.integer_one ] in let content = test_expr expr and expected = Types.Bool in - assert_equal ~printer expected content + check expected content -let tests = "expression_type_of" >::: [ empty; invalid_if; valid_if; in_int ; -upper ] +let tests = + "expression_type_of" >::: [ empty; invalid_if; valid_if; in_int; upper ] diff --git a/tests/importCSV_test.ml b/tests/importCSV_test.ml index bc21992..fc6d545 100644 --- a/tests/importCSV_test.ml +++ b/tests/importCSV_test.ml @@ -1,26 +1,19 @@ -open OUnit2 open ImportCSV +open Test_migration + +let assert_equal = Alcotest.(check int "") let test_suit = [ - ( "Column A" >:: fun _ -> - assert_equal - ~printer:(fun i -> Printf.sprintf "%d (%s)" i (Csv.column_to_string i)) - 1 (Csv.column_of_string "A") ); - ( "Column a" >:: fun _ -> - assert_equal - ~printer:(fun i -> Printf.sprintf "%d (%s)" i (Csv.column_to_string i)) - 1 (Csv.column_of_string "a") ); + ("Column A" >:: fun _ -> assert_equal 1 (Csv.column_of_string "A")); + ("Column a" >:: fun _ -> assert_equal 1 (Csv.column_of_string "a")); ( "Column name" >:: fun _ -> let () = for i = 1 to 1_000 do let column_name = Csv.column_to_string i in let column_index = Csv.column_of_string column_name in - assert_equal - ~printer:(fun i -> - Printf.sprintf "%d (%s)" i (Csv.column_to_string i)) - i column_index + assert_equal i column_index done in () ); diff --git a/tests/importConf_test.ml b/tests/importConf_test.ml index c94eb91..481b66c 100644 --- a/tests/importConf_test.ml +++ b/tests/importConf_test.ml @@ -1,22 +1,23 @@ -open OUnit2 open ConfLoader +open Test_migration + +let check = Alcotest.(check (list Test_migration.extern_testable) "") (** Test the dependencies extracted from the external named "source". Refer to the default configuration used in [ConfLoader] to see the - configuration. - *) + configuration. *) let test_get_dependencies_for_source = "get_dependancies_for_table" >:: fun _ -> let result = ImportConf.get_dependancies_for_table conf conf.source and expected = [ external_other ] in - assert_equal ~printer:pp_externals expected result + check expected result let test_get_dependencies_for_other = "get_dependancies_for_table" >:: fun _ -> let result = ImportConf.get_dependancies_for_table conf external_table_other and expected = [ external_last ] in - assert_equal ~printer:pp_externals expected result + check expected result let tests = "importConf_test" diff --git a/tests/importer_test.ml b/tests/importer_test.ml index 16ea663..a7b7f0d 100644 --- a/tests/importer_test.ml +++ b/tests/importer_test.ml @@ -1,21 +1,16 @@ -open OUnit2 - let _ = - run_test_tt_main - ("importer_tests" - >::: [ - ImportCSV_test.tests; - Sql_date.tests; - Sql_match.tests; - Sql_int.tests; - Sql_trim.tests; - ImportConf_test.tests; - Configuration_toml.tests; - Configuration_expression.tests; - Expression_repr.tests; - Expression_type_of.tests; - Expression_query.tests; - Analyser_dependency.tests; - Analyser_query_test.tests; - Sql_db.tests; - ]) + Alcotest.run "importer_tests" + [ + ImportCSV_test.tests; + Sql_functions.tests; + Sql_trim.tests; + ImportConf_test.tests; + Configuration_toml.tests; + Configuration_expression.tests; + Expression_repr.tests; + Expression_type_of.tests; + Expression_query.tests; + Analyser_dependency.tests; + Analyser_query_test.tests; + Sql_db.tests; + ] diff --git a/tests/sql_date.ml b/tests/sql_date.ml deleted file mode 100644 index 4becdf5..0000000 --- a/tests/sql_date.ml +++ /dev/null @@ -1,18 +0,0 @@ -open OUnit2 - -let test_suit = - [ - ( "Parse date" >:: fun _ -> - let text_date = Sqlite3.Data.TEXT "2002-04-08 15:59:41.000" - and format_date = Sqlite3.Data.TEXT "%Y-%m-%d %H:%M:%S.000" in - - assert_equal (Sqlite3.Data.INT 37354L) - (ImportSQL.Date.f format_date text_date) ); - ( "Parse date as int" >:: fun _ -> - let int_date = Sqlite3.Data.INT 37354L - and format_date = Sqlite3.Data.TEXT "%Y-%m-%d %H:%M:%S.000" in - - assert_equal int_date (ImportSQL.Date.f format_date int_date) ); - ] - -let tests = "sql_date" >::: test_suit diff --git a/tests/sql_db.ml b/tests/sql_db.ml index c966f4e..28666b2 100644 --- a/tests/sql_db.ml +++ b/tests/sql_db.ml @@ -1,21 +1,22 @@ (** Test the behavior of the sqlite with a in-memory database *) -open OUnit2 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 -> raise e + | Error e -> Error e -(** Test a process with a simple configuration in-memory *) +(** Test a process with a simple configuration in-memory. Only one table is + handlded *) let run_test ~configuration ~input ~expected name = - name >:: fun _ -> + name >:: fun () -> (* We expect a valid configuration *) - let conf = - ImportConf.t_of_toml (Otoml.Parser.from_string configuration) - |> Result.get_ok - in + let conf = ConfLoader.load configuration in let exec db = let table = List.hd @@ ImportAnalyser.Dependency.get_process_order conf in @@ -35,31 +36,22 @@ let run_test ~configuration ~input ~expected name = (result, i + 1)) in let* () = result in - let* () = ImportSQL.Db.finalize stmt in - let expected = ref expected in - (* Collect the data *) + let data = ref [] in let* () = ImportSQL.Db.query db conf ~f:(fun rows -> - match !expected with - | [] -> () - | hd :: tl -> - expected := tl; - let () = - Array.iter2 rows hd ~f:(fun (_, value) expected -> - assert_equal ~printer:ImportCSV.DataType.to_string value - expected) - in - ()) + let values = Array.map ~f:snd rows in + data := values :: !data) in - Ok () + Ok (List.rev !data) in (* Use a magic keyword for in-memory database *) - ignore @@ ImportSQL.Db.with_db ":memory:" exec + let result = ImportSQL.Db.with_db ":memory:" exec in + check name expected result (** Simple test used to check the process *) let simple_extraction = @@ -85,13 +77,14 @@ columns = [ ]; ] ~expected: - [ - [| - ImportCSV.DataType.Content "123_"; - ImportCSV.DataType.Integer 2; - ImportCSV.DataType.Integer 5; - |]; - ] + (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 *) @@ -128,11 +121,12 @@ columns = [ ]; ] ~expected: - [ - [| ImportCSV.DataType.Integer 1; ImportCSV.DataType.Integer 100 |]; - [| ImportCSV.DataType.Integer 2; ImportCSV.DataType.Integer 200 |]; - [| ImportCSV.DataType.Integer 3; ImportCSV.DataType.Integer 300 |]; - ] + (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" @@ -158,10 +152,7 @@ columns = [ ]; ] ~expected: - [ - [| ImportCSV.DataType.Integer 1; ImportCSV.DataType.Integer 200 |]; - [| ImportCSV.DataType.Integer 2; ImportCSV.DataType.Integer 200 |]; - ] + (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 *) @@ -189,10 +180,7 @@ columns = [ ]; ] ~expected: - [ - [| ImportCSV.DataType.Integer 1; ImportCSV.DataType.Integer 200 |]; - [| ImportCSV.DataType.Integer 2; ImportCSV.DataType.Integer 200 |]; - ] + (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 diff --git a/tests/sql_functions.ml b/tests/sql_functions.ml new file mode 100644 index 0000000..524e793 --- /dev/null +++ b/tests/sql_functions.ml @@ -0,0 +1,45 @@ +open Test_migration + +let check = Alcotest.check Test_migration.sql_testable + +let test_suit = + [ + ( "Parse date" >:: fun () -> + let text_date = Sqlite3.Data.TEXT "2002-04-08 15:59:41.000" + and format_date = Sqlite3.Data.TEXT "%Y-%m-%d %H:%M:%S.000" in + + check "parsing date" (Sqlite3.Data.INT 37354L) + (ImportSQL.Date.f format_date text_date) ); + ( "Parse date as int" >:: fun () -> + let int_date = Sqlite3.Data.INT 37354L + and format_date = Sqlite3.Data.TEXT "%Y-%m-%d %H:%M:%S.000" in + + check "parsing int date" int_date (ImportSQL.Date.f format_date int_date) + ); + ( "Parse regex" >:: fun _ -> + let text = Sqlite3.Data.TEXT "hello world" + and regex = Sqlite3.Data.TEXT "hello ([A-Za-z]+)" in + + check "Extracting regex" (Sqlite3.Data.TEXT "world") + (ImportSQL.Match.f regex text) ); + (* + Test the int function + *) + ( "Int_of_int" >:: fun _ -> + check "Converting int from int" (Sqlite3.Data.INT 37354L) + (ImportSQL.Math.int (Sqlite3.Data.INT 37354L)) ); + ( "Int_of_string" >:: fun _ -> + check "Converting int from string" (Sqlite3.Data.INT 37354L) + (ImportSQL.Math.int (Sqlite3.Data.TEXT "37354")) ); + ( "Int_of_string2" >:: fun _ -> + check "Converting int from string as float" (Sqlite3.Data.INT 37354L) + (ImportSQL.Math.int (Sqlite3.Data.TEXT "37354.0")) ); + ( "Int_of_float" >:: fun _ -> + check "Converting int from float" (Sqlite3.Data.INT 37354L) + (ImportSQL.Math.int (Sqlite3.Data.FLOAT 37354.0)) ); + ( "Int_of_Text" >:: fun _ -> + check "Converting int from invalid text" Sqlite3.Data.NULL + (ImportSQL.Math.int (Sqlite3.Data.TEXT "-")) ); + ] + +let tests = ("sql_functions", test_suit) diff --git a/tests/sql_int.ml b/tests/sql_int.ml deleted file mode 100644 index 76c25b2..0000000 --- a/tests/sql_int.ml +++ /dev/null @@ -1,29 +0,0 @@ -open OUnit2 - -let printer = function - | Sqlite3.Data.INT t -> Int64.to_string t - | Sqlite3.Data.NONE -> "None" - | Sqlite3.Data.NULL -> "Null" - | Sqlite3.Data.FLOAT f -> Float.to_string f - | Sqlite3.Data.TEXT t | Sqlite3.Data.BLOB t -> t - -let test_suit = - [ - ( "Int_of_int" >:: fun _ -> - assert_equal ~printer (Sqlite3.Data.INT 37354L) - (ImportSQL.Math.int (Sqlite3.Data.INT 37354L)) ); - ( "Int_of_string" >:: fun _ -> - assert_equal ~printer (Sqlite3.Data.INT 37354L) - (ImportSQL.Math.int (Sqlite3.Data.TEXT "37354")) ); - ( "Int_of_string2" >:: fun _ -> - assert_equal ~printer (Sqlite3.Data.INT 37354L) - (ImportSQL.Math.int (Sqlite3.Data.TEXT "37354.0")) ); - ( "Int_of_float" >:: fun _ -> - assert_equal ~printer (Sqlite3.Data.INT 37354L) - (ImportSQL.Math.int (Sqlite3.Data.FLOAT 37354.0)) ); - ( "Int_of_Text" >:: fun _ -> - assert_equal ~printer Sqlite3.Data.NULL - (ImportSQL.Math.int (Sqlite3.Data.TEXT "-")) ); - ] - -let tests = "sql_int" >::: test_suit diff --git a/tests/sql_match.ml b/tests/sql_match.ml deleted file mode 100644 index 0314bb3..0000000 --- a/tests/sql_match.ml +++ /dev/null @@ -1,12 +0,0 @@ -open OUnit2 - -let test_suit = - [ - ( "Parse regex" >:: fun _ -> - let text = Sqlite3.Data.TEXT "hello world" - and regex = Sqlite3.Data.TEXT "hello ([A-Za-z]+)" in - - assert_equal (Sqlite3.Data.TEXT "world") (ImportSQL.Match.f regex text) ); - ] - -let tests = "sql_match" >::: test_suit diff --git a/tests/sql_trim.ml b/tests/sql_trim.ml index 77e755e..dfa29e1 100644 --- a/tests/sql_trim.ml +++ b/tests/sql_trim.ml @@ -1,11 +1,13 @@ -open OUnit2 +open Test_migration + +let check = Alcotest.check Test_migration.sql_testable let test_suit = [ ( "Trim" >:: fun _ -> let text = Sqlite3.Data.TEXT " \nABC \n" in - assert_equal (Sqlite3.Data.TEXT "ABC") (ImportSQL.Trim.f text) ); + check "trim" (Sqlite3.Data.TEXT "ABC") (ImportSQL.Trim.f text) ); ] -let tests = "sql_trim" >::: test_suit +let tests = ("sql_trim", test_suit) diff --git a/tests/test_migration.ml b/tests/test_migration.ml new file mode 100644 index 0000000..35480d1 --- /dev/null +++ b/tests/test_migration.ml @@ -0,0 +1,55 @@ +(** Migration from OUnit to Alcotest *) +let ( >:: ) : string -> (unit -> unit) -> unit Alcotest.test_case = + fun name test -> Alcotest.test_case name `Quick test + +let ( >::: ) : string -> unit Alcotest.test_case list -> unit Alcotest.test = + fun test_name tests -> (test_name, tests) + +let make_test : + (module Alcotest.TESTABLE with type t = 't) -> 't Alcotest.testable = + fun (type t) (module T : Alcotest.TESTABLE with type t = t) -> + Alcotest.testable T.pp T.equal + +(** Create a testable for SQLite data type *) +let sql_testable = + make_test + (module struct + type t = Sqlite3.Data.t = + | NONE + | NULL + | INT of int64 + | FLOAT of float + | TEXT of string + | BLOB of string + [@@deriving show, eq] + end) + +let csv_data_type_testable = + make_test + (module struct + type t = ImportCSV.DataType.t = + | Null + | Error of string + | Content of string + | Integer of int + | Float of float + [@@deriving show, eq] + end) + +let csv_result = Alcotest.(list @@ array @@ csv_data_type_testable) +let data_type_testable = make_test (module ImportDataTypes.Types) +let extern_testable = make_test (module ImportConf.Syntax.Extern) +let table_testable = make_test (module ImportDataTypes.Table) +let int_container_testable = make_test (module ImportContainers.IntSet) + +let expression_testable = + make_test + (module struct + type t = ImportConf.Path.t ImportExpression.T.t [@@deriving show, eq] + end) + +let dep_key_testable = + make_test + (module struct + type t = ImportAnalyser.Dependency.key [@@deriving show, eq] + end) |