diff options
-rw-r--r-- | _oasis | 14 | ||||
-rw-r--r-- | _tags | 5 | ||||
-rw-r--r-- | setup.ml | 206 | ||||
-rw-r--r-- | test/curly_parser_test.ml | 116 |
4 files changed, 337 insertions, 4 deletions
@@ -145,6 +145,14 @@ Executable "vyconf_config_test" Install: false BuildDepends: oUnit, toml, ppx_deriving.runtime, vyconf +Executable "curly_parser_test" + Path: test + MainIs: curly_parser_test.ml + Build$: flag(tests) + CompiledObject: best + Install: false + BuildDepends: oUnit, vyconf + Executable "session_test" Path: test MainIs: session_test.ml @@ -197,6 +205,12 @@ Test "vyconf_config_test" Command: $vyconf_config_test WorkingDirectory: test +Test "curly_parser_test" + Run$: flag(tests) + TestTools: curly_parser_test + Command: $curly_parser_test + WorkingDirectory: test + Test "util_test" Run$: flag(tests) TestTools: util_test @@ -1,5 +1,5 @@ # OASIS_START -# DO NOT EDIT (digest: 38b8e5e5c233095a76ae7d14148f4787) +# DO NOT EDIT (digest: adbc5f656e7c012d33ba25a4cb9be2ac) # Ignore VCS directories, you can use the same kind of rule outside # OASIS_START/STOP if you want to exclude directories that contains # useless stuff for the build process @@ -91,6 +91,9 @@ true: annot, bin_annot <test/vyconf_config_test.{native,byte}>: use_vyconf <test/*.ml{,i,y}>: pkg_ppx_deriving.runtime <test/*.ml{,i,y}>: pkg_toml +# Executable curly_parser_test +<test/curly_parser_test.{native,byte}>: pkg_oUnit +<test/curly_parser_test.{native,byte}>: use_vyconf # Executable session_test <test/session_test.{native,byte}>: pkg_fileutils <test/session_test.{native,byte}>: pkg_oUnit @@ -1,7 +1,7 @@ (* setup.ml generated for the first time by OASIS v0.4.8 *) (* OASIS_START *) -(* DO NOT EDIT (digest: 411e3584b87f0eb61c76f19c8ab886db) *) +(* DO NOT EDIT (digest: 044bf0771190034a61f341e0b3430b49) *) (* Regenerated by OASIS v0.4.8 Visit http://oasis.forge.ocamlcore.org for more information and @@ -7033,6 +7033,14 @@ let setup_t = cmd_clean = [(OASISExpr.EBool true, None)]; cmd_distclean = [(OASISExpr.EBool true, None)] }); + ("curly_parser_test", + CustomPlugin.Test.main + { + CustomPlugin.cmd_main = + [(OASISExpr.EBool true, ("$curly_parser_test", []))]; + cmd_clean = [(OASISExpr.EBool true, None)]; + cmd_distclean = [(OASISExpr.EBool true, None)] + }); ("util_test", CustomPlugin.Test.main { @@ -7104,6 +7112,14 @@ let setup_t = cmd_clean = [(OASISExpr.EBool true, None)]; cmd_distclean = [(OASISExpr.EBool true, None)] }); + ("curly_parser_test", + CustomPlugin.Test.clean + { + CustomPlugin.cmd_main = + [(OASISExpr.EBool true, ("$curly_parser_test", []))]; + cmd_clean = [(OASISExpr.EBool true, None)]; + cmd_distclean = [(OASISExpr.EBool true, None)] + }); ("util_test", CustomPlugin.Test.clean { @@ -7173,6 +7189,14 @@ let setup_t = cmd_clean = [(OASISExpr.EBool true, None)]; cmd_distclean = [(OASISExpr.EBool true, None)] }); + ("curly_parser_test", + CustomPlugin.Test.distclean + { + CustomPlugin.cmd_main = + [(OASISExpr.EBool true, ("$curly_parser_test", []))]; + cmd_clean = [(OASISExpr.EBool true, None)]; + cmd_distclean = [(OASISExpr.EBool true, None)] + }); ("util_test", CustomPlugin.Test.distclean { @@ -10240,6 +10264,151 @@ let setup_t = }); Executable ({ + cs_name = "curly_parser_test"; + cs_data = PropList.Data.create (); + cs_plugin_data = [] + }, + { + bs_build = + [ + (OASISExpr.EBool true, false); + (OASISExpr.EFlag "tests", true) + ]; + bs_install = [(OASISExpr.EBool true, false)]; + bs_path = "test"; + bs_compiled_object = Best; + bs_build_depends = + [ + FindlibPackage ("oUnit", None); + InternalLibrary "vyconf" + ]; + bs_build_tools = [ExternalTool "ocamlbuild"]; + bs_interface_patterns = + [ + { + OASISSourcePatterns.Templater.atoms = + [ + OASISSourcePatterns.Templater.Text ""; + OASISSourcePatterns.Templater.Expr + (OASISSourcePatterns.Templater.Call + ("capitalize_file", + OASISSourcePatterns.Templater.Ident + "module")); + OASISSourcePatterns.Templater.Text ".mli" + ]; + origin = "${capitalize_file module}.mli" + }; + { + OASISSourcePatterns.Templater.atoms = + [ + OASISSourcePatterns.Templater.Text ""; + OASISSourcePatterns.Templater.Expr + (OASISSourcePatterns.Templater.Call + ("uncapitalize_file", + OASISSourcePatterns.Templater.Ident + "module")); + OASISSourcePatterns.Templater.Text ".mli" + ]; + origin = "${uncapitalize_file module}.mli" + } + ]; + bs_implementation_patterns = + [ + { + OASISSourcePatterns.Templater.atoms = + [ + OASISSourcePatterns.Templater.Text ""; + OASISSourcePatterns.Templater.Expr + (OASISSourcePatterns.Templater.Call + ("capitalize_file", + OASISSourcePatterns.Templater.Ident + "module")); + OASISSourcePatterns.Templater.Text ".ml" + ]; + origin = "${capitalize_file module}.ml" + }; + { + OASISSourcePatterns.Templater.atoms = + [ + OASISSourcePatterns.Templater.Text ""; + OASISSourcePatterns.Templater.Expr + (OASISSourcePatterns.Templater.Call + ("uncapitalize_file", + OASISSourcePatterns.Templater.Ident + "module")); + OASISSourcePatterns.Templater.Text ".ml" + ]; + origin = "${uncapitalize_file module}.ml" + }; + { + OASISSourcePatterns.Templater.atoms = + [ + OASISSourcePatterns.Templater.Text ""; + OASISSourcePatterns.Templater.Expr + (OASISSourcePatterns.Templater.Call + ("capitalize_file", + OASISSourcePatterns.Templater.Ident + "module")); + OASISSourcePatterns.Templater.Text ".mll" + ]; + origin = "${capitalize_file module}.mll" + }; + { + OASISSourcePatterns.Templater.atoms = + [ + OASISSourcePatterns.Templater.Text ""; + OASISSourcePatterns.Templater.Expr + (OASISSourcePatterns.Templater.Call + ("uncapitalize_file", + OASISSourcePatterns.Templater.Ident + "module")); + OASISSourcePatterns.Templater.Text ".mll" + ]; + origin = "${uncapitalize_file module}.mll" + }; + { + OASISSourcePatterns.Templater.atoms = + [ + OASISSourcePatterns.Templater.Text ""; + OASISSourcePatterns.Templater.Expr + (OASISSourcePatterns.Templater.Call + ("capitalize_file", + OASISSourcePatterns.Templater.Ident + "module")); + OASISSourcePatterns.Templater.Text ".mly" + ]; + origin = "${capitalize_file module}.mly" + }; + { + OASISSourcePatterns.Templater.atoms = + [ + OASISSourcePatterns.Templater.Text ""; + OASISSourcePatterns.Templater.Expr + (OASISSourcePatterns.Templater.Call + ("uncapitalize_file", + OASISSourcePatterns.Templater.Ident + "module")); + OASISSourcePatterns.Templater.Text ".mly" + ]; + origin = "${uncapitalize_file module}.mly" + } + ]; + bs_c_sources = []; + bs_data_files = []; + bs_findlib_extra_files = []; + bs_ccopt = [(OASISExpr.EBool true, [])]; + bs_cclib = [(OASISExpr.EBool true, [])]; + bs_dlllib = [(OASISExpr.EBool true, [])]; + bs_dllpath = [(OASISExpr.EBool true, [])]; + bs_byteopt = [(OASISExpr.EBool true, [])]; + bs_nativeopt = [(OASISExpr.EBool true, [])] + }, + { + exec_custom = false; + exec_main_is = "curly_parser_test.ml" + }); + Executable + ({ cs_name = "session_test"; cs_data = PropList.Data.create (); cs_plugin_data = [] @@ -10711,6 +10880,37 @@ let setup_t = }); Test ({ + cs_name = "curly_parser_test"; + cs_data = PropList.Data.create (); + cs_plugin_data = [] + }, + { + test_type = (`Test, "custom", Some "0.4"); + test_command = + [(OASISExpr.EBool true, ("$curly_parser_test", []))]; + test_custom = + { + pre_command = [(OASISExpr.EBool true, None)]; + post_command = [(OASISExpr.EBool true, None)] + }; + test_working_directory = Some "test"; + test_run = + [ + (OASISExpr.ENot (OASISExpr.EFlag "tests"), false); + (OASISExpr.EFlag "tests", false); + (OASISExpr.EAnd + (OASISExpr.EFlag "tests", + OASISExpr.EFlag "tests"), + true) + ]; + test_tools = + [ + ExternalTool "ocamlbuild"; + InternalExecutable "curly_parser_test" + ] + }); + Test + ({ cs_name = "util_test"; cs_data = PropList.Data.create (); cs_plugin_data = [] @@ -10813,7 +11013,7 @@ let setup_t = }; oasis_fn = Some "_oasis"; oasis_version = "0.4.8"; - oasis_digest = Some "\007\199+\142\186\142<4#\132\203\130\253_\216;"; + oasis_digest = Some "\141\001l_\201\176\019\146o0\181\221d\139\016\029"; oasis_exec = None; oasis_setup_args = []; setup_update = false @@ -10821,7 +11021,7 @@ let setup_t = let setup () = BaseSetup.setup setup_t;; -# 10825 "setup.ml" +# 11025 "setup.ml" let setup_t = BaseCompat.Compat_0_4.adapt_setup_t setup_t open BaseCompat.Compat_0_4 (* OASIS_STOP *) diff --git a/test/curly_parser_test.ml b/test/curly_parser_test.ml new file mode 100644 index 0000000..6e6f675 --- /dev/null +++ b/test/curly_parser_test.ml @@ -0,0 +1,116 @@ +open OUnit2 + +module CT = Config_tree + +let config_empty = "" + +let config_trivial = "foo { }" + +let config_nested = "foo { bar { } baz { } }" + +let config_leaf_top_level = "foo bar;" + +let config_tag_top_level = "foo bar { baz quux; }" + +let config_with_leaf = "foo { bar baz; }" +let config_with_leaf_url_unquoted = "foo { bar http://www2.example.org/foo; }" +let config_with_leaf_value_quoted = "foo { bar \"foo bar\"; }" + +(* XXX: naive use of Menhir's separated_list doesn't allow [baz; xyzzy;], + perhaps we should support it too *) +let config_with_multi = "foo { bar [baz; xyzzy]; }" + +let config_with_tag = "foo { bar baz { quux xyzzy; } bar qwerty { quux foobar; } }" + +let config_with_comment = "foo { /* comment */ bar { } }" +let config_with_leaf_node_comment = "foo { /* comment */ bar baz; }" +let config_with_tag_node_comment = "foo { /* comment */ bar baz { } }" + +let parse s = Curly_parser.config Curly_lexer.token (Lexing.from_string s) + +(* Empty config is considered valid, creates just the root node *) +let test_parse_empty test_ctxt = + let config = parse config_empty in + assert_equal (Vytree.list_children config) [] + +(* A config with just an empty node is considered valid too. Not sure if it should! *) +let test_parse_trivial test_ctxt = + let config = parse config_trivial in + assert_equal (Vytree.list_children config) ["foo"] + +(* A config with nested nodes is parser correctly *) +let test_parse_nested test_ctxt = + let config = parse config_nested in + assert_equal (Vytree.get config ["foo"] |> Vytree.list_children ) ["bar"; "baz"] + +(* Leaf nodes are parsed correctly *) +let test_parse_with_leaf test_ctxt = + let config = parse config_with_leaf in + assert_equal (CT.get_value config ["foo"; "bar"]) "baz" + +(* Leaf nodes with [.:/] in values are parsed correctly *) +let test_parse_with_leaf_url_unquoted test_ctxt = + let config = parse config_with_leaf_url_unquoted in + assert_equal (CT.get_value config ["foo"; "bar"]) "http://www2.example.org/foo" + +(* Leaf nodes with quoted values are parsed correctly *) +let test_parse_with_leaf_value_quoted test_ctxt = + let config = parse config_with_leaf_value_quoted in + assert_equal (CT.get_value config ["foo"; "bar"]) "foo bar" + +(* Top level leaf nodes are not allowed *) +let test_parse_top_level_leaf_node test_ctxt = + assert_raises Curly_parser.Error (fun () -> parse config_leaf_top_level) + +(* Top level tag nodes are not allowed *) +let test_parse_top_level_tag_node test_ctxt = + assert_raises Curly_parser.Error (fun () -> parse config_tag_top_level) + +(* Nodes with multiple values are handled correctly *) +let test_parse_with_multi test_ctxt = + let config = parse config_with_multi in + assert_equal (CT.get_values config ["foo"; "bar"]) ["baz"; "xyzzy"] + +(* Comments should work *) +let test_parse_with_comment test_ctxt = + let config = parse config_with_comment in + assert_equal (CT.get_comment config ["foo"; "bar"]) (Some (String.trim "comment")) + +(* Comments in leaf nodes should work *) +let test_parse_with_leaf_node_comment test_ctxt = + let config = parse config_with_leaf_node_comment in + assert_equal (CT.get_comment config ["foo"; "bar"]) (Some (String.trim "comment")) + +(* Comments in tag nodes should work *) +let test_parse_with_tag_node_comment test_ctxt = + let config = parse config_with_tag_node_comment in + assert_equal (CT.get_comment config ["foo"; "bar"; "baz"]) (Some (String.trim "comment")) + +(* Tag nodes are parsed correctly *) +let test_parse_with_tag test_ctxt = + let config = parse config_with_tag in + assert_equal (Vytree.get config ["foo"; "bar"] |> Vytree.list_children) ["baz"; "qwerty"]; + assert_equal (CT.get_value config ["foo"; "bar"; "baz"; "quux"]) "xyzzy"; + assert_equal (CT.get_value config ["foo"; "bar"; "qwerty"; "quux"]) "foobar" + + +let suite = + "VyConf curly config parser tests" >::: [ + "test_make_node" >:: test_parse_empty; + "test_parse_trivial" >:: test_parse_trivial; + "test_parse_nested" >:: test_parse_nested; + "test_parse_with_leaf" >:: test_parse_with_leaf; + "test_parse_with_leaf_url_unquoted" >:: test_parse_with_leaf_url_unquoted; + "test_parse_with_leaf_value_quoted" >:: test_parse_with_leaf_value_quoted; + "test_parse_top_level_leaf_node" >:: test_parse_top_level_leaf_node; + "test_parse_top_level_tag_node" >:: test_parse_top_level_tag_node; + "test_parse_with_multi" >:: test_parse_with_multi; + "test_parse_with_tag" >:: test_parse_with_tag; + "test_parse_with_comment" >:: test_parse_with_comment; + "test_parse_with_leaf_node_comment" >:: test_parse_with_leaf_node_comment; + "test_parse_with_tag_node_comment" >:: test_parse_with_tag_node_comment; + ] + +let () = + run_test_tt_main suite + |