aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/analyser_dependency.ml8
-rw-r--r--tests/analyser_filters.ml28
-rw-r--r--tests/analyser_query_test.ml97
-rw-r--r--tests/confLoader.ml26
-rw-r--r--tests/configuration_expression.ml181
-rw-r--r--tests/configuration_toml.ml348
-rw-r--r--tests/test_migration.ml9
7 files changed, 535 insertions, 162 deletions
diff --git a/tests/analyser_dependency.ml b/tests/analyser_dependency.ml
index 511b706..00f21d7 100644
--- a/tests/analyser_dependency.ml
+++ b/tests/analyser_dependency.ml
@@ -40,6 +40,7 @@ let test_keys =
name = "other";
expression = Expression.Path 3;
columns = lazy (Cont.IntSet.singleton 3);
+ filters = [];
};
]
in
@@ -61,6 +62,7 @@ let test_keys_missing =
name = "last_file";
expression = Expression.Path 3;
columns = lazy (Cont.IntSet.singleton 3);
+ filters = [];
};
]
in
@@ -145,14 +147,14 @@ let test_unlinked =
target = { file = "other.xlsx"; tab = 1; name = "circular" };
extern_key = Path 3;
allow_missing = true;
- match_rule = None;
+ filters = [];
};
{
intern_key = Path { alias = Some "circular"; column = 1 };
target = { file = "other2.xlsx"; tab = 1; name = "circular2" };
extern_key = Path 3;
allow_missing = true;
- match_rule = None;
+ filters = [];
};
];
columns = [];
@@ -177,7 +179,7 @@ let conf_with_unlinked =
target = { file = "other.xlsx"; tab = 1; name = "other" };
extern_key = Path 3;
allow_missing = false;
- match_rule = None;
+ filters = [];
};
];
columns =
diff --git a/tests/analyser_filters.ml b/tests/analyser_filters.ml
index 864cab7..9a54bde 100644
--- a/tests/analyser_filters.ml
+++ b/tests/analyser_filters.ml
@@ -35,7 +35,7 @@ let simple_filter () =
let chunk_predicates = Filters.generate_sql ~conf filter chunk_links in
let expected_predicates = Chunk.create () in
- Chunk.add_string expected_predicates " WHERE 1=COALESCE('source'.'col_1',0)";
+ Chunk.add_string expected_predicates " WHERE (1=COALESCE('source'.'col_1',0))";
Alcotest.(check @@ pair Test_migration.chunk Test_migration.chunk)
"Simple predicate"
@@ -58,7 +58,7 @@ let multiple_filters () =
(* The predicates can be executed in reverse order, but it’s not an issue
because they all are applied at the same time in the projection *)
Chunk.add_string expected_predicates
- " WHERE COALESCE('source'.'col_1','')=?\nAND 1";
+ " WHERE (COALESCE('source'.'col_1','')=?)\nAND (1)";
Alcotest.(check @@ pair Test_migration.chunk Test_migration.chunk)
"Combined predicate"
@@ -80,9 +80,9 @@ let group_filter () =
let expected_links = Chunk.create () in
Chunk.add_string expected_links
- "WITH filter0 AS (SELECT source.id, LAST_VALUE('source'.'col_1') OVER \
+ "WITH filter0 AS (SELECT source.id, (LAST_VALUE('source'.'col_1') OVER \
(PARTITION BY 'source'.'col_1' ORDER BY 'source'.'col_1' RANGE BETWEEN \
- UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)=1 AS group_function\n\
+ UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)=1) AS group_function\n\
FROM 'source' AS 'source')\n";
Alcotest.(check @@ pair Test_migration.chunk Test_migration.chunk)
@@ -106,10 +106,10 @@ let expression_with_group () =
let expected_links = Chunk.create () in
Chunk.add_string expected_links
- "WITH filter0 AS (SELECT source.id, LAST_VALUE('source'.'col_1') OVER \
+ "WITH filter0 AS (SELECT source.id, (LAST_VALUE('source'.'col_1') OVER \
(PARTITION BY 'source'.'col_1' ORDER BY 'source'.'col_1' RANGE BETWEEN \
- UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)=1 AS group_function\n\
- FROM 'source' AS 'source' WHERE 1=COALESCE('source'.'col_1',0))\n";
+ UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)=1) AS group_function\n\
+ FROM 'source' AS 'source' WHERE (1=COALESCE('source'.'col_1',0)))\n";
Alcotest.(check @@ pair Test_migration.chunk Test_migration.chunk)
"The predicate expression is inside of the CTE"
@@ -130,13 +130,13 @@ let group_with_expression () =
Chunk.add_string expected_predicates
"\n\
INNER JOIN 'filter0' ON filter0.id = source.id\n\
- WHERE 1=COALESCE('source'.'col_1',0) AND filter0.group_function";
+ WHERE (1=COALESCE('source'.'col_1',0)) AND filter0.group_function";
let expected_links = Chunk.create () in
Chunk.add_string expected_links
- "WITH filter0 AS (SELECT source.id, LAST_VALUE('source'.'col_1') OVER \
+ "WITH filter0 AS (SELECT source.id, (LAST_VALUE('source'.'col_1') OVER \
(PARTITION BY 'source'.'col_1' ORDER BY 'source'.'col_1' RANGE BETWEEN \
- UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)=1 AS group_function\n\
+ UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)=1) AS group_function\n\
FROM 'source' AS 'source')\n";
Alcotest.(check @@ pair Test_migration.chunk Test_migration.chunk)
@@ -161,13 +161,13 @@ let group_with_group () =
let expected_links = Chunk.create () in
Chunk.add_string expected_links
- "WITH filter0 AS (SELECT source.id, LAST_VALUE('source'.'col_1') OVER \
+ "WITH filter0 AS (SELECT source.id, (LAST_VALUE('source'.'col_1') OVER \
(PARTITION BY 'source'.'col_1' ORDER BY 'source'.'col_1' RANGE BETWEEN \
- UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)=1 AS group_function\n\
+ UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)=1) AS group_function\n\
FROM 'source' AS 'source')\n\
- , filter1 AS (SELECT source.id, LAST_VALUE('source'.'col_1') OVER \
+ , filter1 AS (SELECT source.id, (LAST_VALUE('source'.'col_1') OVER \
(PARTITION BY 'source'.'col_1' ORDER BY 'source'.'col_1' RANGE BETWEEN \
- UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)=1 AS group_function\n\
+ UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)=1) AS group_function\n\
FROM 'source' AS 'source'\n\
INNER JOIN 'filter0' ON filter0.id = source.id\n\
WHERE filter0.group_function)\n";
diff --git a/tests/analyser_query_test.ml b/tests/analyser_query_test.ml
index fd8914b..37a748b 100644
--- a/tests/analyser_query_test.ml
+++ b/tests/analyser_query_test.ml
@@ -46,11 +46,11 @@ let check_externals =
let query = Q.check_external conf (List.hd conf.externals) in
let expected_query =
- "SELECT 'source'.'id', 'source'.'col_1'\n\
+ "SELECT 'source'.'id', ('source'.'col_1')\n\
FROM 'source' AS 'source'\n\
LEFT JOIN 'other' AS 'other' ON rtrim(upper('source'.'col_1')) = \
'other'.'key_other' WHERE 'other'.'key_other' IS NULL AND \
- 'source'.'col_1' IS NOT NULL AND 'source'.'col_1' <> ''"
+ ('source'.'col_1') IS NOT NULL AND ('source'.'col_1') <> ''"
in
Alcotest.check Alcotest.string "" expected_query query.q
@@ -179,6 +179,7 @@ let prepare_insert =
name = "key_test";
expression = Concat [ Path 1; Literal "_"; Empty ];
columns = lazy (ImportContainers.IntSet.singleton 1);
+ filters = [];
}
in
@@ -207,7 +208,7 @@ let filter_group =
let contents, _ = ImportAnalyser.Query.select conf in
let expected =
- {|WITH filter0 AS (SELECT source.id, LAST_VALUE('source'.'col_3') OVER (PARTITION BY 'source'.'col_1' ORDER BY 'source'.'col_1' RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS group_function
+ {|WITH filter0 AS (SELECT source.id, (LAST_VALUE('source'.'col_3') OVER (PARTITION BY 'source'.'col_1' ORDER BY 'source'.'col_1' RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)) AS group_function
FROM 'source' AS 'source'
LEFT JOIN 'other' AS 'other' ON rtrim(upper('source'.'col_1')) = 'other'.'key_other'
LEFT JOIN 'last' AS 'last_file' ON rtrim(upper('other'.'col_1')) = 'last_file'.'key_last_file')
@@ -239,7 +240,7 @@ let filter_group2 =
let contents, _ = ImportAnalyser.Query.select conf in
let expected =
- {|WITH filter0 AS (SELECT source.id, LAST_VALUE('source'.'col_3') OVER (PARTITION BY 'source'.'col_1' ORDER BY 'source'.'col_1' RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS group_function
+ {|WITH filter0 AS (SELECT source.id, (LAST_VALUE('source'.'col_3') OVER (PARTITION BY 'source'.'col_1' ORDER BY 'source'.'col_1' RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)) AS group_function
FROM 'source' AS 'source'
LEFT JOIN 'other' AS 'other' ON rtrim(upper('source'.'col_1')) = 'other'.'key_other'
LEFT JOIN 'last' AS 'last_file' ON rtrim(upper('other'.'col_1')) = 'last_file'.'key_last_file')
@@ -248,11 +249,94 @@ FROM 'source' AS 'source'
LEFT JOIN 'other' AS 'other' ON rtrim(upper('source'.'col_1')) = 'other'.'key_other'
LEFT JOIN 'last' AS 'last_file' ON rtrim(upper('other'.'col_1')) = 'last_file'.'key_last_file'
INNER JOIN 'filter0' ON filter0.id = source.id
-WHERE COALESCE('source'.'col_3',0)=0 AND filter0.group_function|}
+WHERE (COALESCE('source'.'col_3',0)=0) AND filter0.group_function|}
in
Alcotest.check Alcotest.string "" expected contents.q
+(** Add an external with a filter. Ensure the predicate is reported in the
+ query. *)
+let external_filter =
+ "external_filter" >:: fun _ ->
+ let conf =
+ Syntax.
+ {
+ ConfLoader.conf with
+ externals =
+ [
+ {
+ ConfLoader.external_other with
+ filters = [ Expression_builder.(equal (path 1) integer_one) ];
+ };
+ ];
+ columns = [ Expression_builder.empty ];
+ }
+ in
+
+ let query, _ = ImportAnalyser.Query.select conf in
+ let expected_query =
+ {|SELECT '' AS result_0
+FROM 'source' AS 'source'
+LEFT JOIN 'other' AS 'other' ON rtrim(upper('source'.'col_1')) = 'other'.'key_other' AND (COALESCE('other'.'col_1',0)=1)|}
+ in
+ Alcotest.check Test_migration.trimed_string "" expected_query query.q
+
+let order_by =
+ "order_by" >:: fun () ->
+ let conf =
+ Syntax.
+ {
+ ConfLoader.conf with
+ externals = [];
+ columns =
+ [
+ Expression_builder.path
+ ImportDataTypes.Path.{ alias = None; column = 1 };
+ ];
+ sort =
+ [
+ Expression_builder.path
+ ImportDataTypes.Path.{ alias = None; column = 1 };
+ Expression_builder.integer_one;
+ ];
+ }
+ in
+ let query, _ = ImportAnalyser.Query.select conf in
+ let expected_query =
+ {|SELECT 'source'.'col_1' AS result_0
+FROM 'source' AS 'source'
+ORDER BY ('source'.'col_1'), (1)|}
+ in
+ Alcotest.check Test_migration.trimed_string "" expected_query query.q
+
+let group_by =
+ "order_by" >:: fun () ->
+ let conf =
+ Syntax.
+ {
+ ConfLoader.conf with
+ externals = [];
+ columns =
+ [
+ Expression_builder.path
+ ImportDataTypes.Path.{ alias = None; column = 1 };
+ ];
+ uniq =
+ [
+ Expression_builder.path
+ ImportDataTypes.Path.{ alias = None; column = 1 };
+ Expression_builder.integer_one;
+ ];
+ }
+ in
+ let query, _ = ImportAnalyser.Query.select conf in
+ let expected_query =
+ {|SELECT 'source'.'col_1' AS result_0
+FROM 'source' AS 'source'
+GROUP BY ('source'.'col_1'), (1)|}
+ in
+ Alcotest.check Test_migration.trimed_string "" expected_query query.q
+
let test_suit =
[
create_table;
@@ -265,6 +349,9 @@ let test_suit =
prepare_insert;
filter_group;
filter_group2;
+ external_filter;
+ order_by;
+ group_by;
]
let tests = "analyser_query_test" >::: test_suit
diff --git a/tests/confLoader.ml b/tests/confLoader.ml
index 13f9840..b0be690 100644
--- a/tests/confLoader.ml
+++ b/tests/confLoader.ml
@@ -1,5 +1,23 @@
-let load' : string -> (ImporterSyntax.t, string) Result.t =
- fun content -> Otoml.Parser.from_string content |> ImportConf.t_of_toml
+(** During the test, we don’t care with the file existence *)
+let context =
+ ImportConf.
+ { loadFile = (fun _ -> Otoml.array []); checkFile = (fun _ -> true) }
+
+let load' :
+ ?dataset:(string -> Otoml.t) ->
+ string ->
+ (ImporterSyntax.t, string) Result.t =
+ fun ?(dataset = fun _ -> Otoml.array []) content ->
+ let toml = Otoml.Parser.from_string content in
+ ImportConf.t_of_toml toml ~context:{ context with loadFile = dataset }
+
+let load_from_file :
+ ?dataset:(string -> Otoml.t) ->
+ string ->
+ (ImporterSyntax.t, string) Result.t =
+ fun ?(dataset = fun _ -> Otoml.array []) content ->
+ let toml = Otoml.Parser.from_file content in
+ ImportConf.t_of_toml toml ~context:{ context with loadFile = dataset }
(** Read the configuration in toml and return the internal representation *)
let load : string -> ImporterSyntax.t =
@@ -43,7 +61,7 @@ let external_other =
target = external_table_other;
extern_key = Path 3;
allow_missing = false;
- match_rule = None;
+ filters = [];
}
let external_table_last =
@@ -56,5 +74,5 @@ let external_last =
target = external_table_last;
extern_key = Path 3;
allow_missing = true;
- match_rule = None;
+ filters = [];
}
diff --git a/tests/configuration_expression.ml b/tests/configuration_expression.ml
index cd28589..6478903 100644
--- a/tests/configuration_expression.ml
+++ b/tests/configuration_expression.ml
@@ -4,104 +4,72 @@ open Test_migration
let result_testable =
Alcotest.result Test_migration.expression_testable Alcotest.string
+(** Helper used to test the equality between the litteral expression and it’s
+ AST *)
+let test : string -> Path.t ImportExpression.T.t -> unit =
+ fun expr result ->
+ let expression = ImportConf.expression_from_string expr in
+ Alcotest.check result_testable "" (Ok result) expression
+
+let path_column =
+ "column as path" >:: fun () ->
+ test ":A" (Path { Path.alias = None; column = 1 })
+
+let path_table =
+ "path with table" >:: fun () ->
+ test ":table.A" (Path { Path.alias = Some "table"; column = 1 })
+
+let path_subtable =
+ "path with table" >:: fun () ->
+ test ":table.Name.A" (Path { Path.alias = Some "table.Name"; column = 1 })
+
let parse_dquoted =
"parse_dquoted" >:: fun _ ->
- let expr = "match(\"\\(..\\)\", :B)" in
- let result = ImportConf.expression_from_string expr in
- Alcotest.check result_testable ""
- (Ok
- (Function
- ("match", [ Literal "\\(..\\)"; Path { alias = None; column = 2 } ])))
- result
+ test "match(\"\\(..\\)\", :B)"
+ (Function
+ ("match", [ Literal "\\(..\\)"; Path { alias = None; column = 2 } ]))
let parse_quoted =
"parse_quoted" >:: fun _ ->
- let expr = "match('\\(..\\)', :B)" in
- let result = ImportConf.expression_from_string expr in
- Alcotest.check result_testable ""
- (Ok
- (Function
- ("match", [ Literal "\\(..\\)"; Path { alias = None; column = 2 } ])))
- result
+ test "match('\\(..\\)', :B)"
+ (Function
+ ("match", [ Literal "\\(..\\)"; Path { alias = None; column = 2 } ]))
let concat =
"concat" >:: fun _ ->
- let expr = ":A ^ :B" in
- let result = ImportConf.expression_from_string expr in
- Alcotest.check result_testable ""
- (Ok
- (Concat
- [
- Path { alias = None; column = 1 }; Path { alias = None; column = 2 };
- ]))
- result
+ test ":A ^ :B"
+ (Concat
+ [ Path { alias = None; column = 1 }; Path { alias = None; column = 2 } ])
let concat2 =
"concat2" >:: fun _ ->
- let expr = "'A' ^ '_' ^ 'B'" in
- let result = ImportConf.expression_from_string expr in
- Alcotest.check result_testable ""
- (Ok (Concat [ Literal "A"; Literal "_"; Literal "B" ]))
- result
+ test "'A' ^ '_' ^ 'B'" (Concat [ Literal "A"; Literal "_"; Literal "B" ])
let litteral =
"litteral" >:: fun _ ->
(* The text is quoted in shall not be considered as a path *)
- let expr = "':A'" in
- let result = ImportConf.expression_from_string expr in
- Alcotest.check result_testable "" (Ok (Literal ":A")) result
+ test "':A'" (Literal ":A")
-let empty =
- "empty" >:: fun _ ->
- let expr = "" in
- let result = ImportConf.expression_from_string expr in
- Alcotest.check result_testable "" (Ok Empty) result
+let empty = "empty" >:: fun _ -> test "" Empty
let upper_nvl =
- "upper_nvl" >:: fun _ ->
- let expr = "NVL('','')" in
- let result = ImportConf.expression_from_string expr in
- Alcotest.check result_testable "" (Ok (Nvl [ Empty; Empty ])) result
+ "upper_nvl" >:: fun _ -> test "NVL('','')" (Nvl [ Empty; Empty ])
let lower_nvl =
- "lower_nvl" >:: fun _ ->
- let expr = "nvl('','')" in
- let result = ImportConf.expression_from_string expr in
- 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
- Alcotest.check result_testable "" (Ok (Integer "123")) result
+ "lower_nvl" >:: fun _ -> test "nvl('','')" (Nvl [ Empty; Empty ])
-let numeric_neg =
- "numeric_neg" >:: fun _ ->
- let expr = "-123" in
- let result = ImportConf.expression_from_string expr in
- Alcotest.check result_testable "" (Ok (Integer "-123")) result
+let numeric = "numeric" >:: fun _ -> test "123" (Integer "123")
+let numeric_neg = "numeric_neg" >:: fun _ -> test "-123" (Integer "-123")
let op_priority =
"operator_priority" >:: fun _ ->
- let expr = "1 + 2 > 2" in
- let result = ImportConf.expression_from_string expr
- and expected =
- ImportExpression.T.(
- BOperator (GT, BOperator (Add, Integer "1", Integer "2"), Integer "2"))
- in
-
- Alcotest.check result_testable "" (Ok expected) result
+ test "1 + 2 > 2"
+ (BOperator (GT, BOperator (Add, Integer "1", Integer "2"), Integer "2"))
let op_priority2 =
"operator_priority" >:: fun _ ->
- let expr = "1 ^ 2 = 2" in
- let result = ImportConf.expression_from_string expr
- and expected =
- ImportExpression.T.(
- BOperator (Equal, Concat [ Integer "1"; Integer "2" ], Integer "2"))
- in
-
- Alcotest.check result_testable "" (Ok expected) result
+ test "1 ^ 2 = 2"
+ (BOperator (Equal, Concat [ Integer "1"; Integer "2" ], Integer "2"))
let join =
"join" >:: fun _ ->
@@ -119,29 +87,15 @@ let join =
let join_empty =
"join" >:: fun _ ->
- let expr = "join('', :A, :B)" in
- let result = ImportConf.expression_from_string expr in
- Alcotest.check result_testable ""
- (Ok
- (Join
- ( "",
- [
- Path { alias = None; column = 1 };
- Path { alias = None; column = 2 };
- ] )))
- result
+ test "join('', :A, :B)"
+ (Join
+ ( "",
+ [
+ Path { alias = None; column = 1 }; Path { alias = None; column = 2 };
+ ] ))
-let upper =
- "upper" >:: fun _ ->
- let expr = "upper('')" in
- let result = ImportConf.expression_from_string expr in
- 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
- Alcotest.check result_testable "" (Ok (Function' (Trim, [ Empty ]))) result
+let upper = "upper" >:: fun _ -> test "upper('')" (Function' (Upper, [ Empty ]))
+let trim = "trim" >:: fun _ -> test "trim('')" (Function' (Trim, [ Empty ]))
(** Extract the columns from a window function *)
let fold_values =
@@ -182,44 +136,24 @@ let bad_quote =
let nested_expression =
"nested_expression" >:: fun _ ->
- let expr = "1 = (1 = 0)" in
- let result = ImportConf.expression_from_string expr in
- Alcotest.check result_testable ""
- (Ok
- (BOperator
- ( Equal,
- Integer "1",
- Expr (BOperator (Equal, Integer "1", Integer "0")) )))
- result
+ test "1 = (1 = 0)"
+ (BOperator
+ (Equal, Integer "1", Expr (BOperator (Equal, Integer "1", Integer "0"))))
let priority_equality =
"priority_equality" >:: fun _ ->
- let expr = "1 = 1 = 0" in
- let result = ImportConf.expression_from_string expr in
- Alcotest.check result_testable ""
- (Ok
- (BOperator
- (Equal, Integer "1", BOperator (Equal, Integer "1", Integer "0"))))
- result
+ test "1 = 1 = 0"
+ (BOperator (Equal, Integer "1", BOperator (Equal, Integer "1", Integer "0")))
let priority_operator_and =
"priority_equality" >:: fun _ ->
- let expr = "1 and 1 = 0" in
- let result = ImportConf.expression_from_string expr in
- Alcotest.check result_testable ""
- (Ok
- (BOperator (And, Integer "1", BOperator (Equal, Integer "1", Integer "0"))))
- result
+ test "1 and 1 = 0"
+ (BOperator (And, Integer "1", BOperator (Equal, Integer "1", Integer "0")))
let priority_operator_or =
"priority_equality" >:: fun _ ->
- let expr = "1 <> 1 or 0" in
- let result = ImportConf.expression_from_string expr in
- Alcotest.check result_testable ""
- (Ok
- (BOperator
- (Or, BOperator (Different, Integer "1", Integer "1"), Integer "0")))
- result
+ test "1 <> 1 or 0"
+ (BOperator (Or, BOperator (Different, Integer "1", Integer "1"), Integer "0"))
let unknown_function =
"unknown function" >:: fun _ ->
@@ -240,6 +174,9 @@ let wrong_arguments =
let test_suit =
[
+ path_column;
+ path_table;
+ path_subtable;
parse_dquoted;
parse_quoted;
concat;
diff --git a/tests/configuration_toml.ml b/tests/configuration_toml.ml
index 0a36faf..620a106 100644
--- a/tests/configuration_toml.ml
+++ b/tests/configuration_toml.ml
@@ -5,12 +5,12 @@ open Test_migration
let nested_group () =
let expected =
Error
- "in field \"sheet\":\n\
- \ in field \"columns\":\n\
- \ while decoding a list:\n\
- \ element 0:\n\
- \ A group function cannot contains another group function, but got\n\
- \ \"max(:A, [counter([:A], [:A])], [])\" \n"
+ {|in field "sheet":
+ in field "columns":
+ while decoding a list:
+ element 0:
+ A group function cannot contains another group function, but got
+ "max(:A, [counter([:A], [:A])], [])"|}
and result =
ConfLoader.load'
{|[source]
@@ -22,14 +22,325 @@ columns = [
"max(:A, [counter([:A], [:A])], [])",
]|}
in
- Alcotest.(check (result Test_migration.syntax string))
+ Alcotest.(check (result Test_migration.syntax Test_migration.trimed_string))
"duplicate" expected result
+(** Load a simple configuration *)
+let load_configuration () =
+ let configuration =
+ ConfLoader.load'
+ {|[source]
+name = ""
+file = ""
+tab = 0
+
+[sheet]
+columns = []|}
+ and expected = Ok ImporterSyntax.dummy_conf in
+ Alcotest.(check (result Test_migration.syntax string))
+ "Simple configuration" expected configuration
+
+let externals () =
+ let configuration =
+ ConfLoader.load'
+ {|[source]
+name = ""
+file = ""
+tab = 0
+
+[externals.other]
+ intern_key = ":A"
+ file = "other.xlsx"
+ extern_key = ":C"
+ allow_missing = false
+
+[sheet]
+columns = []|}
+ and expected =
+ Ok
+ {
+ ImporterSyntax.dummy_conf with
+ externals = [ ConfLoader.external_other ];
+ }
+ in
+ Alcotest.(check (result Test_migration.syntax Test_migration.trimed_string))
+ "Simple external" expected configuration
+
+(** There is an error in this configuration the key [intern_key] is missing in
+ the external *)
+let external_with_missing_key () =
+ let configuration =
+ ConfLoader.load'
+ {|[source]
+name = ""
+file = ""
+
+[externals.other]
+ file = ""
+ extern_key = ""
+
+[sheet]
+columns = []|}
+ and expected =
+ Error
+ {|in field "externals":
+ Failed while decoding key-value pairs:
+ Expected an object with an attribute "intern_key", but got
+ file = ""
+ extern_key = ""|}
+ in
+ Alcotest.(check (result Test_migration.syntax Test_migration.trimed_string))
+ "Missing key" expected configuration
+
+let sub_external () =
+ let configuration =
+ ConfLoader.load'
+ {|[source]
+name = ""
+file = ""
+tab = 0
+
+
+[externals.other-1]
+ intern_key = ":A"
+ file = "other.xlsx"
+ extern_key = ":C"
+ allow_missing = false
+
+[sheet]
+columns = []|}
+ and expected =
+ Ok
+ {
+ ImporterSyntax.dummy_conf with
+ externals =
+ ConfLoader.
+ [
+ {
+ external_other with
+ target = { external_table_other with name = "other-1" };
+ };
+ ];
+ }
+ in
+ Alcotest.(check (result Test_migration.syntax string))
+ "external with path" expected configuration
+
+let sub_external_with_missing_key () =
+ let configuration =
+ ConfLoader.load'
+ {|[source]
+name = ""
+file = ""
+
+[externals.other-1]
+ file = ""
+ extern_key = ""
+
+[sheet]
+columns = []|}
+ and expected =
+ Error
+ {|in field "externals":
+ Failed while decoding key-value pairs:
+ Expected an object with an attribute "intern_key", but got
+ file = ""
+ extern_key = ""|}
+ in
+ Alcotest.(check (result Test_migration.syntax Test_migration.trimed_string))
+ "Missing intern_key" expected configuration
+
+(** The same configuration has external, and sub-element external *)
+let sub_external_mixed () =
+ let configuration =
+ ConfLoader.load'
+ {|[source]
+name = ""
+file = ""
+tab = 0
+
+[externals.other]
+ intern_key = ":A"
+ file = "other.xlsx"
+ extern_key = ":C"
+ allow_missing = false
+
+[externals.other-1]
+ intern_key = ":A"
+ file = "other.xlsx"
+ extern_key = ":C"
+ allow_missing = false
+
+[sheet]
+columns = []|}
+ and expected =
+ Ok
+ {
+ ImporterSyntax.dummy_conf with
+ externals =
+ ConfLoader.
+ [
+ external_other;
+ {
+ external_other with
+ target = { external_table_other with name = "other-1" };
+ };
+ ];
+ }
+ in
+ Alcotest.(check (result Test_migration.syntax string))
+ "external with path" expected configuration
+
+let missing_dataset () =
+ let configuration =
+ ConfLoader.load' {|[source]
+name = ""
+tab = 0
+
+[sheet]
+columns = []|}
+ and expected =
+ Error
+ {|in field "source":
+ I tried the following decoders but they all failed:
+ "file" decoder:
+ Expected an object with an attribute "file", but got name = ""
+ tab = 0
+
+ "dataset" decoder: No dataset declared, but got name = ""
+ tab = 0|}
+ in
+ Alcotest.(check (result Test_migration.syntax Test_migration.trimed_string))
+ "No dataset provided" expected configuration
+
+let empty_dataset () =
+ let configuration =
+ ConfLoader.load'
+ ~dataset:(fun _ -> Otoml.TomlArray [])
+ {|
+
+dataset = "…"
+
+[source]
+name = ""
+
+[sheet]
+columns = []|}
+ and expected =
+ Error
+ {|in field "dataset": Expected an object with an attribute "files", but got []|}
+ in
+ Alcotest.(check (result Test_migration.syntax Test_migration.trimed_string))
+ "Invalid Dataset" expected configuration
+
+let dataset_with_invalid_key () =
+ let configuration =
+ ConfLoader.load'
+ ~dataset:(fun _ ->
+ Otoml.(
+ TomlTable
+ [ ("files", TomlTable [ ("other-1", TomlString "other.xlsx") ]) ]))
+ {|
+
+dataset = "…"
+
+[source]
+name = ""
+
+[sheet]
+columns = []|}
+ and expected =
+ Error
+ {|in field "dataset":
+ in field "files":
+ Failed while decoding key-value pairs:
+ Expected a key without '-', but got "other-1"|}
+ in
+ Alcotest.(check (result Test_migration.syntax Test_migration.trimed_string))
+ "Invalid Dataset: invalid key" expected configuration
+
+let external_dataset () =
+ let configuration =
+ ConfLoader.load'
+ ~dataset:(fun _ ->
+ Otoml.(
+ TomlTable
+ [ ("files", TomlTable [ ("other", TomlString "other.xlsx") ]) ]))
+ {|
+
+dataset = "…"
+
+[source]
+name = ""
+file = ""
+tab = 0
+
+
+[externals.other-1]
+ # The file is not defined here
+ # And in the dataset, there is no "other-1", just "other": the application
+ # should be able to infer the information from "other" and apply it here.
+ intern_key = ":A"
+ extern_key = ":C"
+ allow_missing = false
+
+[sheet]
+columns = []|}
+ and expected =
+ Ok
+ {
+ ImporterSyntax.dummy_conf with
+ externals =
+ ConfLoader.
+ [
+ {
+ external_other with
+ target = { external_table_other with name = "other-1" };
+ };
+ ];
+ }
+ in
+ Alcotest.(check (result Test_migration.syntax string))
+ "Dataset with alias" expected configuration
+
+let external_filters () =
+ let configuration =
+ ConfLoader.load'
+ {|[source]
+name = ""
+file = ""
+tab = 0
+
+[externals.other]
+ intern_key = ":A"
+ file = "other.xlsx"
+ extern_key = ":C"
+ filters = [":B = 1"]
+
+
+[sheet]
+columns = []|}
+ and expected =
+ Ok
+ {
+ ImporterSyntax.dummy_conf with
+ externals =
+ ConfLoader.
+ [
+ {
+ external_other with
+ filters = [ Expression_builder.(equal (path 2) integer_one) ];
+ };
+ ];
+ }
+ in
+ Alcotest.(check (result Test_migration.syntax string))
+ "Filters in external" expected configuration
+
let test_suit =
[
( "parse_extern" >:: fun _ ->
- let toml = Otoml.Parser.from_file "configuration/simple.toml" in
- let toml = ImportConf.t_of_toml toml in
+ let toml = ConfLoader.load_from_file "configuration/simple.toml" in
match toml with
| Error s -> raise (Failure s)
| Ok result ->
@@ -45,7 +356,7 @@ let test_suit =
Path { alias = None; column = 1 };
Path { alias = None; column = 2 };
] );
- match_rule = None;
+ filters = [];
allow_missing = true;
}
in
@@ -55,8 +366,7 @@ let test_suit =
(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
+ let toml = ConfLoader.load_from_file "configuration/simple.toml" in
match toml with
| Error s -> raise (Failure s)
@@ -83,10 +393,20 @@ let test_suit =
(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
+ let toml = ConfLoader.load_from_file "configuration/example_csv.toml" in
ignore toml );
("nested group", `Quick, nested_group);
+ ("Basic configuration", `Quick, load_configuration);
+ ("Configuration with external", `Quick, externals);
+ ("Faulty configuration", `Quick, external_with_missing_key);
+ ("Sub external", `Quick, sub_external);
+ ("Faulty configuration", `Quick, sub_external_with_missing_key);
+ ("Mix in external and sub external", `Quick, sub_external_mixed);
+ ("Missing dataset", `Quick, missing_dataset);
+ ("Empty dataset", `Quick, empty_dataset);
+ ("Dataset with invalid key", `Quick, dataset_with_invalid_key);
+ ("External dataset", `Quick, external_dataset);
+ ("External with filter", `Quick, external_filters);
]
let tests = "configuration_toml" >::: test_suit
diff --git a/tests/test_migration.ml b/tests/test_migration.ml
index 17e48cc..acf782d 100644
--- a/tests/test_migration.ml
+++ b/tests/test_migration.ml
@@ -42,6 +42,15 @@ let extern_testable = make_test (module ImporterSyntax.Extern)
let table_testable = make_test (module ImportDataTypes.Table)
let int_container_testable = make_test (module ImportContainers.IntSet)
+let trimed_string =
+ make_test
+ (module struct
+ type t = string
+
+ let equal s1 s2 = String.equal (String.trim s1) (String.trim s2)
+ let pp format t = Format.fprintf format "%s" (String.trim t)
+ end)
+
let expression_testable =
make_test
(module struct