module Pass_square = (* Utilities lens *) let dels (s:string) = del s s (************************************************************************ * Regular square lens *************************************************************************) (* Simplest square lens *) let s = store /[ab]/ let sqr0 = let k = key "x" in let d = dels "x" in [ square k s d ] * test sqr0 get "xaxxbxxax" = { "x" = "a" }{ "x" = "b" }{ "x" = "a" } test sqr0 put "xax" after set "/x[3]" "b" = "xaxxbx" (* test mismatch tag *) test sqr0 get "xya" = * (* Test regular expression matching with multiple groups *) let body = del /([f]+)([f]+)/ "ff" . del /([g]+)([g]+)/ "gg" let sqr1 = let k = key /([a-b]*)([a-b]*)([a-b]*)/ in let d1 = del /([a-b]*)([a-b]*)([a-b]*)/ "a" in let d2 = del /([x]+)([x]+)/ "xx" in [ square k body d1 . d2 ] * test sqr1 get "aaffggaaxxbbffggbbxx" = { "aa" }{ "bb" } test sqr1 get "affggaxx" = { "a" } test sqr1 put "affggaxx" after clear "/b" = "affggaxxbffggbxx" (* Test XML like elements up to depth 2 *) let b = del ">" ">" . del /[a-z ]*/ "" . del "" ">" ] * let b2 = del ">" ">" . xml . del "" ">" ] * test xml get "" = { "a" }{ "b" } (* test error on mismatch tag *) test xml get "" = * (* test get nested tags of depth 2 *) test xml2 get "" = { "a" { "b" } { "c" } } (* test nested put of depth 2 *) test xml2 put "" after clear "/x/y" = "" (* test nested put of depth 3 : should fail *) test xml2 put "" after clear "/x/y/z" = * (* matches can be case-insensitive *) let s5 = store /[yz]/ let sqr5 = let k = key /x/i in let d = del /x/i "x" in [ square k s5 d ] * test sqr5 get "xyX" = { "x" = "y" } test sqr5 get "xyXXyxXyx" = { "x" = "y" }{ "X" = "y" }{ "X" = "y" } test sqr5 put "xyX" after set "/x[3]" "z" = "xyxxzx" (* test concat multiple squares *) let rex = /[a-z]/ let csqr = let k = key rex in let d = del rex "a" in let e = dels "" in [ square k e d . square d e d ] * test csqr get "aabbccdd" = { "a" } { "c" } test csqr put "aabb" after insa "z" "/a" = "aabbzzaa" (* test default square create values *) let create_square = let d = dels "a" in [ key "x" . square d d d ]* test create_square put "" after clear "/x" = "xaaa" (* test optional quotes *) let word = /[A-Za-z0-9_.-]+/ let entry = let k = key word in let quote = del /"?/ "\"" (* " *) in let body = store /[a-z]+/ in let v = square quote body quote in [ k . dels "=" . v ] test entry get "key=\"value\"" = { "key" = "value" } test entry get "key=value" = { "key" = "value" } test entry put "key=value" after set "/key" "other" = "key=other" test entry put "key=\"value\"" after set "/key" "other" = "key=\"other\"" (* create with square *) (* Passing this test successfully requires that the skeleton from the get *) (* is correctly detected as not matching the skeleton for the second lens *) (* in hte union - the reason for the mismatch is that the quote is *) (* optional in the first branch of the union, and the skeleton therefore *) (* does not have "@" in the right places, triggering a create *) let sq_create = let word = store /[a-z]+/ in let number = store /[0-9]+/ in let quot = dels "@" in let quot_opt = del /@?/ "@" in [ label "t" . square quot_opt word quot_opt ] | [ label "t" . square quot number quot ] test sq_create put "abc" after set "/t" "42" = "@42@"