3 Provides unit tests and examples for the <Xml> lens.
12 r:regexp - the pattern for the flag
14 let knode (r:regexp) = [ key r ]
16 (************************************************************************
17 * Group: Utilities lens
18 *************************************************************************)
20 let _ = print_regexp(lens_ctype(Xml.text))
21 let _ = print_endline ""
27 Comments get mapped into "#comment" nodes. *)
29 "<!-- declarations for <head> & <body> -->" =
31 { "#comment" = " declarations for <head> & <body> " }
34 This syntax is not understood. *)
36 "<!-- B+, B, or B--->" = *
38 (* Group: Prolog and declarations *)
41 The XML prolog tag is mapped in a "#declaration" node,
42 which contains an "#attribute" node with various attributes of the tag. *)
44 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" =
49 { "encoding" = "UTF-8" }
53 (* Test: Xml.decl_def_item
54 !ELEMENT declaration tags are mapped in "!ELEMENT" nodes.
55 The associated declaration attribute is mapped in a "#decl" subnode. *)
56 test Xml.decl_def_item get
57 "<!ELEMENT greeting (#PCDATA)>" =
59 { "!ELEMENT" = "greeting"
60 { "#decl" = "(#PCDATA)" }
63 (* Test: Xml.decl_def_item
64 !ENTITY declaration tags are mapped in "!ENTITY" nodes.
65 The associated declaration attribute is mapped in a "#decl" subnode. *)
66 test Xml.decl_def_item get
67 "<!ENTITY da \"
\">" =
70 { "#decl" = "
" }
74 !DOCTYPE tags are mapped in "!DOCTYPE" nodes.
75 The associated system attribute is mapped in a "SYSTEM" subnode. *)
77 "<!DOCTYPE greeting:foo SYSTEM \"hello.dtd\">" =
79 { "!DOCTYPE" = "greeting:foo"
80 { "SYSTEM" = "hello.dtd" }
84 This is an example of a !DOCTYPE tag with !ELEMENT children tags. *)
85 test Xml.doctype get "<!DOCTYPE foo [
86 <!ELEMENT bar (#PCDATA)>
87 <!ELEMENT baz (bar)* >
92 { "#decl" = "(#PCDATA)" }
95 { "#decl" = "(bar)*" }
99 (* Group: Attributes *)
101 (* Variable: att_def1 *)
102 let att_def1 = "<!ATTLIST termdef
104 name CDATA #IMPLIED>"
105 (* Variable: att_def2 *)
106 let att_def2 = "<!ATTLIST list
107 type (bullets|ordered|glossary) \"ordered\">"
108 (* Variable: att_def3 *)
109 let att_def3 = "<!ATTLIST form
110 method CDATA #FIXED \"POST\">"
112 (* Test: Xml.att_list_def *)
113 test Xml.att_list_def get
116 { "!ATTLIST" = "termdef"
124 { "#type" = "CDATA" }
129 (* Test: Xml.att_list_def *)
130 test Xml.att_list_def get
133 { "!ATTLIST" = "list"
136 { "#type" = "(bullets|ordered|glossary)" }
137 { "#FIXED" = "ordered" }
141 (* Test: Xml.att_list_def *)
142 test Xml.att_list_def get
145 { "!ATTLIST" = "form"
147 { "#name" = "method" }
148 { "#type" = "CDATA" }
149 { "#FIXED" = "POST" }
153 (* Test: Xml.notation_def *)
154 test Xml.notation_def get
155 "<!NOTATION not3 SYSTEM \"\">" =
157 { "!NOTATION" = "not3"
161 (* Variable: cdata1 *)
162 let cdata1 = "<![CDATA[testing]]>"
163 (* Test: Xml.cdata *)
164 test Xml.cdata get cdata1 = { "#CDATA" = "testing" }
166 (* Variable: attr1 *)
167 let attr1 = " attr1=\"value1\" attr2=\"value2\""
168 (* Variable: attr2 *)
169 let attr2 = " attr2=\"foo\""
170 (* Test: Xml.attributes *)
171 test Xml.attributes get attr1 =
173 { "attr1" = "value1" }
174 { "attr2" = "value2" }
177 (* Test: Xml.attributes *)
178 test Xml.attributes get " refs=\"A1\nA2 A3\"" =
180 { "refs" = "A1\nA2 A3" }
183 (* Test: Xml.attributes *)
184 test Xml.attributes put attr1 after rm "/#attribute[1]";
185 set "/#attribute/attr2" "foo" = attr2
188 (* well formed values *)
189 test Xml.attributes get " attr1=\"value1\"" = { "#attribute" { "attr1" = "value1" } }
190 test Xml.attributes get " attr1='value1'" = { "#attribute" { "attr1" = "value1" } }
191 test Xml.attributes get " attr1='va\"lue1'" = { "#attribute" { "attr1" = "va\"lue1" } }
192 test Xml.attributes get " attr1=\"va'lue1\"" = { "#attribute" { "attr1" = "va'lue1" } }
194 (* illegal as per the XML standard *)
195 test Xml.attributes get " attr1=\"va\"lue1\"" = *
196 test Xml.attributes get " attr1='va'lue1'" = *
198 (* malformed values *)
199 test Xml.attributes get " attr1=\"value1'" = *
200 test Xml.attributes get " attr1='value1\"" = *
204 (* Variable: empty1 *)
206 (* Variable: empty2 *)
207 let empty2 = "<a foo=\"bar\"/>"
208 (* Variable: empty3 *)
209 let empty3 = "<a foo=\"bar\"></a>\n"
210 (* Variable: empty4 *)
211 let empty4 = "<a foo=\"bar\" far=\"baz\"/>"
212 (* Test: Xml.empty_element *)
213 test Xml.empty_element get empty1 = { "a" = "#empty" }
214 (* Test: Xml.empty_element *)
215 test Xml.empty_element get empty2 =
216 { "a" = "#empty" { "#attribute" { "foo" = "bar"} } }
218 (* Test: Xml.empty_element *)
219 test Xml.empty_element put empty1 after set "/a/#attribute/foo" "bar" = empty2
221 (* Test: Xml.empty_element
222 The attribute node must be the first child of the element *)
223 test Xml.empty_element put empty1 after set "/a/#attribute/foo" "bar";
224 set "/a/#attribute/far" "baz" = empty4
226 (* Test: Xml.content *)
227 test Xml.content put "<a><b/></a>" after clear "/a/b" = "<a><b></b>\n</a>"
230 (* Group: Full lens *)
233 test Xml.lns put "<a></a >" after set "/a/#text[1]" "foo";
234 set "/a/#text[2]" "bar" = "<a>foobar</a >"
237 test Xml.lns get "<?xml version=\"1.0\"?>
238 <!DOCTYPE catalog PUBLIC \"-//OASIS//DTD XML Catalogs V1.0//EN\"
239 \"file:///usr/share/xml/schema/xml-core/catalog.dtd\">
243 { "version" = "1.0" }
246 { "!DOCTYPE" = "catalog"
248 { "#literal" = "-//OASIS//DTD XML Catalogs V1.0//EN" }
249 { "#literal" = "file:///usr/share/xml/schema/xml-core/catalog.dtd" }
255 test Xml.lns get "<oor:component-data xmlns:oor=\"http://openoffice.org/2001/registry\"/>
257 { "oor:component-data" = "#empty"
259 { "xmlns:oor" = "http://openoffice.org/2001/registry" }
263 (* Variable: input1 *)
264 let input1 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
271 <p class=\"main\">Augeas is now able to parse XML files!</p>
273 <li>Translate from XML to a tree syntax</li>
274 <li>Translate from the tree back to XML</li> <!-- this is some comment -->
282 Test <input1> with <Xml.doc> *)
283 test Xml.doc get input1 =
286 { "version" = "1.0" }
287 { "encoding" = "UTF-8" }
291 { "#text" = "\r\n " }
304 { "#text" = "Augeas" }
311 { "#text" = "Augeas is now able to parse XML files!" }
317 { "#text" = "Translate from XML to a tree syntax" }
321 { "#text" = "Translate from the tree back to XML" }
324 { "#comment" = " this is some comment " }
337 Modify <input1> with <Xml.doc> *)
338 test Xml.doc put input1 after rm "/html/body" =
339 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
358 test Xml.doc get ul1 =
363 { "#text" = "test1" }
367 { "#text" = "test2" }
371 { "#text" = "test3" }
375 { "#text" = "test4" }
380 test Xml.doc put ul1 after set "/ul/li[3]/#text" "bidon" = "
389 test Xml.doc put ul1 after rm "/ul/li[2]" = "
398 (* #text nodes don't move when inserting a node, the result depends on where the node is added *)
399 test Xml.doc put ul1 after insb "a" "/ul/li[2]" = "
409 test Xml.doc put ul1 after insa "a" "/ul/li[1]" = "
419 (* Attributes must be added before text nodes *)
420 test Xml.doc put ul1 after insb "#attribute" "/ul/li[2]/#text";
421 set "/ul/li[2]/#attribute/bidon" "gazou";
422 set "/ul/li[2]/#attribute/foo" "bar" = "
425 <li bidon=\"gazou\" foo=\"bar\">test2</li>
431 (* if empty element is allowed to be as root, this test triggers error *)
432 test Xml.lns get "<doc>
433 <a><c/><b><c/></b><c/><c/><a></a></a>
448 let p01pass2 = "<?PI before document element?>
449 <!-- comment after document element-->
450 <?PI before document element?>
451 <!-- comment after document element-->
452 <?PI before document element?>
453 <!-- comment after document element-->
454 <?PI before document element?>
465 <!-- comment after document element-->
466 <?PI after document element?>
467 <!-- comment after document element-->
468 <?PI after document element?>
469 <!-- comment after document element-->
470 <?PI after document element?>
473 test Xml.lns get p01pass2 =
476 { "#instruction" = "before document element" }
478 { "#comment" = " comment after document element" }
481 { "#instruction" = "before document element" }
483 { "#comment" = " comment after document element" }
486 { "#instruction" = "before document element" }
488 { "#comment" = " comment after document element" }
491 { "#instruction" = "before document element" }
516 { "#comment" = " comment after document element" }
519 { "#instruction" = "after document element" }
521 { "#comment" = " comment after document element" }
524 { "#instruction" = "after document element" }
526 { "#comment" = " comment after document element" }
529 { "#instruction" = "after document element" }
533 (* various valid Name constructions *)
534 test Xml.lns get "<doc>\n<A:._-0/>\n<::._-0/>\n<_:._-0/>\n<A/>\n<_/>\n<:/>\n</doc>" =
537 { "A:._-0" = "#empty" }
538 { "::._-0" = "#empty" }
539 { "_:._-0" = "#empty" }
545 test Xml.lns get "<doc>
546 <abcdefghijklmnopqrstuvwxyz/>
547 <ABCDEFGHIJKLMNOPQRSTUVWXYZ/>
553 { "abcdefghijklmnopqrstuvwxyz" = "#empty" }
554 { "ABCDEFGHIJKLMNOPQRSTUVWXYZ" = "#empty" }
555 { "A01234567890" = "#empty" }
556 { "A.-:" = "#empty" }
560 let p06fail1 = "<!--non-validating processors may pass this instance because they don't check the IDREFS attribute type-->
563 <!ELEMENT doc (a|refs)*>
565 <!ELEMENT refs EMPTY>
566 <!ATTLIST refs refs IDREFS #REQUIRED>
567 <!ATTLIST a id ID #REQUIRED>
570 <a id=\"A1\"/><a id=\"A2\"/><a id=\"A3\"/>
574 (* we accept this test because we do not verify XML references *)
575 test Xml.lns get p06fail1 =
576 { "#comment" = "non-validating processors may pass this instance because they don't check the IDREFS attribute type" }
579 { "#decl" = "(a|refs)*" }
582 { "#decl" = "EMPTY" }
584 { "!ELEMENT" = "refs"
585 { "#decl" = "EMPTY" }
587 { "!ATTLIST" = "refs"
590 { "#type" = "IDREFS" }
627 (* we accept dquote, but not single quotes, because of resulting ambiguity *)
628 let p10pass1_1 = "<doc><A a=\"asdf>'">\nasdf\n ?>%\"/></doc>"
629 let p10pass1_2 = "<doc><A a='\"\">'"'/></doc>"
631 test Xml.lns get p10pass1_1 =
635 { "a" = "asdf>'">\nasdf\n ?>%" }
640 test Xml.lns get p10pass1_2 =
644 { "a" = "\"\">'"" }
649 (* here again, test exclude single quote *)
650 let p11pass1 = "<!--Inability to resolve a notation should not be reported as an error-->
654 <!NOTATION not1 SYSTEM \"a%a&b�<!ELEMENT<!--<?</>?>/\''\">
655 <!NOTATION not3 SYSTEM \"\">
659 test Xml.lns get p11pass1 =
660 { "#comment" = "Inability to resolve a notation should not be reported as an error" }
663 { "#decl" = "EMPTY" }
665 { "!NOTATION" = "not1"
666 { "SYSTEM" = "a%a&b�<!ELEMENT<!--<?</>?>/\''" }
668 { "!NOTATION" = "not3"
674 test Xml.lns get "<doc>a%b%</doc></doc>]]<&</doc>" =
676 { "#text" = "a%b%</doc></doc>]]<&" }
679 let p15pass1 = "<!--a
688 test Xml.lns get p15pass1 =
698 let p22pass3 = "<?xml version=\"1.0\"?>
699 <!--comment--> <?pi some instruction ?>
702 test Xml.lns get p22pass3 =
705 { "version" = "1.0" }
708 { "#comment" = "comment" }
711 { "#instruction" = "some instruction" }
719 let p25pass2 = "<?xml version
728 test Xml.lns get p25pass2 =
731 { "version" = "1.0" }
737 test Xml.lns get "<!DOCTYPE
747 { "#decl" = "EMPTY" }
752 test Xml.lns get "<doc></doc \n>" = { "doc" }
754 test Xml.lns get "<a><doc att=\"val\" \natt2=\"val2\" att3=\"val3\"/></a>" =
765 test Xml.lns get "<doc/>" = { "doc" = "#empty" }
767 test Xml.lns get "<a><![CDATA[Thu, 13 Feb 2014 12:22:35 +0000]]></a>" =
769 { "#CDATA" = "Thu, 13 Feb 2014 12:22:35 +0000" } }
772 (* only one document element *)
773 test Xml.lns get "<doc></doc><bad/>" = *
775 (* document element must be complete *)
776 test Xml.lns get "<doc>" = *
778 (* accept empty document *)
779 test Xml.lns get "\n" = {}
781 (* malformed element *)
782 test Xml.lns get "<a><A@/></a>" = *
784 (* a Name cannot start with a digit *)
785 test Xml.lns get "<a><0A/></a>" = *
787 (* no space before "CDATA" *)
788 test Xml.lns get "<doc><![ CDATA[a]]></doc>" = *
790 (* no space after "CDATA" *)
791 test Xml.lns get "<doc><![CDATA [a]]></doc>" = *
793 (* FIXME: CDSect's can't nest *)
794 test Xml.lns get "<doc>
796 <![CDATA[XML doesn't allow CDATA sections to nest]]>
801 { "#CDATA" = "\n<![CDATA[XML doesn't allow CDATA sections to nest" }
803 { "#text" = ">\n" } }
805 (* Comment is illegal in VersionInfo *)
806 test Xml.lns get "<?xml version <!--bad comment--> =\"1.0\"?>
809 (* only declarations in DTD *)
810 test Xml.lns get "<!DOCTYPE doc [
815 (* we do not support external entities *)
816 test Xml.lns get "<!DOCTYPE doc [
817 <!ENTITY % eldecl \"<!ELEMENT doc EMPTY>\">
822 (* Escape character in attributes *)
823 test Xml.lns get "<a password=\"my\!pass\" />" =
825 { "#attribute" { "password" = "my\!pass" } } }
828 after set "/a" "#empty" = "<a/>\n"