diff options
| author | Daniil Baturin <daniil@baturin.org> | 2018-02-17 23:15:57 +0700 | 
|---|---|---|
| committer | Daniil Baturin <daniil@baturin.org> | 2018-02-17 23:15:57 +0700 | 
| commit | bfa93363f3e8533ef352cad38c2adfa21dbc28a3 (patch) | |
| tree | 4c5786f9688f018d5cbead2588c409802d9dbc31 | |
| parent | d4ee9b96e02e1413cc19ce638aec07408468ca30 (diff) | |
| download | vyconf-bfa93363f3e8533ef352cad38c2adfa21dbc28a3.tar.gz vyconf-bfa93363f3e8533ef352cad38c2adfa21dbc28a3.zip | |
Add Config_tree.render_at_level function for correct rendering of configs for human consumption.
The idea of the correct (for subsequent parsing) and familiar for all other purposes rendering:
* When rendering the entire config, do not render the invisible "root" node, only render its children.
* When rendering config at specified path, do not include any nodes that are within the path
  (e.g. if path "system login" exists, "show system" request output should start with "login {",
   not "system { login { ...").
| -rw-r--r-- | src/config_tree.ml | 19 | ||||
| -rw-r--r-- | src/config_tree.mli | 12 | ||||
| -rw-r--r-- | test/config_tree_test.ml | 31 | 
3 files changed, 58 insertions, 4 deletions
| diff --git a/src/config_tree.ml b/src/config_tree.ml index 9fed465..c816d65 100644 --- a/src/config_tree.ml +++ b/src/config_tree.ml @@ -156,7 +156,7 @@ struct      let render              ?(indent=4) -            ?(reftree) +            ?(reftree=None)              ?(cmp=BatString.numeric_compare)              ?(showephemeral=false)              ?(showinactive=false) @@ -249,3 +249,20 @@ struct  end (* Renderer *)  let render = Renderer.render + +let render_at_level +  ?(indent=4) +  ?(reftree=None) +  ?(cmp=BatString.numeric_compare) +  ?(showephemeral=false) +  ?(showinactive=false) +  node +  path = +    let node =  +        match path with +        | [] -> node +        | _ -> Vytree.get node path +    in +    let children = Vytree.children_of_node node in +    let child_configs = List.map (render ~indent:indent ~reftree:reftree  ~cmp:cmp ~showephemeral:showephemeral ~showinactive:showinactive) children in +    List.fold_left (Printf.sprintf "%s\n%s") "" child_configs diff --git a/src/config_tree.mli b/src/config_tree.mli index f724df1..f72eda9 100644 --- a/src/config_tree.mli +++ b/src/config_tree.mli @@ -56,10 +56,20 @@ val is_ephemeral : t -> string list -> bool  *)  val render :      ?indent:int -> -    ?reftree:Reference_tree.t -> +    ?reftree:(Reference_tree.t option)->      ?cmp:(string -> string -> int) ->      ?showephemeral:bool ->      ?showinactive:bool ->      t ->      string +val render_at_level : +    ?indent:int -> +    ?reftree:(Reference_tree.t option)-> +    ?cmp:(string -> string -> int) -> +    ?showephemeral:bool -> +    ?showinactive:bool -> +    t -> +    string list -> +    string + diff --git a/test/config_tree_test.ml b/test/config_tree_test.ml index ad79df3..be8b320 100644 --- a/test/config_tree_test.ml +++ b/test/config_tree_test.ml @@ -153,13 +153,38 @@ let test_render_ephemeral_shown teset_ctxt =      }  }" +let test_render_at_level test_ctxt = +    let path = ["foo"; "bar"; "baz"] in +    let node = CT.make "root" in +    let node = CT.set node path (Some "quux") CT.AddValue in +    let rendered = CT.render_at_level node ["foo"] in +    assert_equal (String.trim rendered) +"bar { +    baz \"quux\"; +}" + +let test_render_at_level_top test_ctxt = +    let path1 = ["foo"; "bar"] in +    let path2 = ["baz"; "quux"] in +    let node = CT.make "root" in +    let node = CT.set node path1 (Some "quuux") CT.AddValue in +    let node = CT.set node path2 (Some "xyzzy") CT.AddValue in +    let rendered = CT.render_at_level node [] in +    assert_equal (String.trim rendered) +"baz { +    quux \"xyzzy\"; +} +foo { +    bar \"quuux\"; +}" +  (**** Reftree-based rendering *)  let test_render_rt_tag_node test_ctxt =      let reftree = load_reftree test_ctxt in      let path = ["system"; "login"; "user"; "full-name"] in      let node = CT.make "root" in      let node = CT.set node path (Some "name here") CT.AddValue in -    let rendered_curly_config = CT.render ~reftree node in +    let rendered_curly_config = CT.render ~reftree:(Some reftree) node in      let desired_rendered_form =  "root {      system { @@ -176,7 +201,7 @@ let test_render_rt_unspecified_node test_ctxt =      let path = ["system"; "login"; "user"; "unspecified_node"] in      let node = CT.make "root" in      let node = CT.set node path (Some "name here") CT.AddValue in -    let rendered_curly_config = CT.render ~reftree node in +    let rendered_curly_config = CT.render ~reftree:(Some reftree) node in      let desired_rendered_form =  "root {      system { @@ -204,6 +229,8 @@ let suite =          "test_render_nested_empty_with_comment" >:: test_render_nested_empty_with_comment;          "test_render_ephemeral_hidden " >:: test_render_ephemeral_hidden;          "test_render_ephemeral_shown"  >:: test_render_ephemeral_shown; +        "test_render_at_level" >:: test_render_at_level; +        "test_render_at_level_top" >:: test_render_at_level_top;          "test_render_rt_tag_node" >:: test_render_rt_tag_node;          "test_render_rt_unspecified_node" >:: test_render_rt_unspecified_node      ] | 
