Blob Blame History Raw
module Pass_square_rec =

(*  Utilities lens *)
let dels (s:string) = del s s

(************************************************************************
 *                        Recursive square lens
 *************************************************************************)
(* test square with left and right as dels *)
let lr (body:lens) =
    let k = key "c" . body* in
    let d = dels "ab" in
        [ square d k d ]

let rec lr2 = lr lr2

test lr2 get "abcabcabab" =
  { "c"
    { "c" }
  }

let open_tag = key /[a-z]+/
let close_tag = del /[a-z]+/ "a"

(* Basic element *)
let xml_element (body:lens) =
    let g = del ">" ">" . body . del "</" "</" in
        [ del "<" "<" . square open_tag g close_tag . del ">" ">" ] *

let rec xml_rec = xml_element xml_rec

test xml_rec get "<a><b><c><d><e></e></d></c></b></a>" =
  { "a"
    { "b"
      { "c"
        { "d"
          { "e" }
        }
      }
    }
  }

test xml_rec get "<a><b></b><c></c><d></d><e></e></a>" =
  { "a"
    { "b" }
    { "c" }
    { "d" }
    { "e" }
  }

test xml_rec put "<a></a><b><c></c></b>" after clear "/x/y/z" = "<a></a><b><c></c></b><x><y><z></z></y></x>"

(* mismatch tag *)
test xml_rec get "<a></c>" = *
test xml_rec get "<a><b></b></c>" = *
test xml_rec get "<a><b></c></a>" = *


(* test ctype_nullable and typecheck *)
let rec z =
	let k = key "ab" in
	let d = dels "ab" in
	[ square k z? d ]
test z get "abab" = { "ab" }

(* test tip handling when using store inside body *)
let c (body:lens) =
    let sto = store "c" . body* in
    let d = dels "ab" in
    let k = key "ab" in
        [ square k sto d ]

let rec cc = c cc

test cc get "abcabcabab" =
  { "ab" = "c"
    { "ab" = "c" }
  }

(* test mixing regular and recursive lenses *)

let reg1 =
	let k = key "y" in
	let d = dels "y" in
	let e = dels "" in
	[ square k e d ]

let reg2 =
	let k = key "y" in
	let d = dels "y" in
	[ square k reg1 d ]

let rec rec2 =
	let d1 = dels "x" in
	let k1 = key "x" in
	let body = reg2 | rec2 in
	[ square k1 body d1 ]?

test rec2 get "xyyyyx" =
  { "x"
    { "y"
      { "y" }
    }
  }

test rec2 put "" after clear "/x/y/y" = "xyyyyx"

(* test correct put behavior *)
let input3 = "aaxyxbbaaaxyxbb"
let b3 = dels "y"
let sqr3 =
	let k = key /[x]/ in
	let d = dels "x" in
	[ del /[a]*/ "a" . square k b3 d . del /[b]*/ "b" ]*
test sqr3 get input3 = { "x" }{ "x" }
test sqr3 put input3 after clear "/x[1]" = input3

let b4 = dels "x"
let rec sqr4 =
	let k = key /[b]|[c]/ in
	let d = del /[b]|[c]/ "b" in
	[ del /[a]+/ "a" . square k (b4|sqr4) d ]
test sqr4 put "aabaaacxcb" after rm "x" = "aabaaacxcb"

(* test concat multiple squares *)
let rex = /[a-z]/
let rec csqr =
	let k = key rex in
	let d = del rex "a" in
	let e = dels "" in
	[ square k e d . csqr* . square d e d ]

test csqr get "aabbccdd" =
  { "a"
    { "b" }
  }

test csqr put "aabbccdd" after clear "/a" = "aabbccdd"
test csqr put "aabb" after clear "/a/z" = "aazzaabb"