zuzu-rust 0.6.0

Rust implementation of ZuzuScript
Documentation
from std/data/xml import *;
from test/more import *;
let doc := XML.parse( "<root><item id='a'>first</item><item id='b'>second</item></root>" );
let root := doc.documentElement();
is( root.nodeName(), "root", "documentElement nodeName" );
is( root.childNodes().length(), 2, "childNodes length" );
is( root.children().length(), 2, "children length" );
is( root.hasChildNodes(), 1, "hasChildNodes true" );
is( root.nodeKind(), "element", "nodeKind element" );
let items := doc.findnodes("/root/item");
is( items.length(), 2, "findnodes from document" );
is( doc.findvalue( "count(/root/item)" ), "2", "findvalue from document" );
is( doc.querySelectorAll("item").length(), 2, "doc querySelectorAll" );
is( doc.querySelector("item").id(), "a", "doc querySelector first" );
is( doc.querySelector(".missing"), null, "doc querySelector missing" );
is( doc.getElementsByTagName("item").length(), 2, "doc getElementsByTagName" );
let first := items.get( 0, null );
let second := items.get( 1, null );
is( first.tagName(), "item", "DOMElement tagName" );
is( first.id(), "a", "DOMElement id" );
first.setId("alpha");
is( first.id(), "alpha", "DOMElement setId" );
is( root.getElementsByTagName("item").length(), 2, "element getElementsByTagName" );
is( root.querySelectorAll("item").length(), 2, "node querySelectorAll" );
is( root.querySelector("item").id(), "alpha", "node querySelector first" );
is( first.getAttribute("id"), "alpha", "getAttribute" );
is( first.hasAttribute("id"), 1, "hasAttribute true" );
is( first.textContent(), "first", "textContent" );
first.setAttribute( "status", "new" );
is( first.getAttribute("status"), "new", "setAttribute" );
let attrs := first.attributeNames();
is( attrs.contains("id"), 1, "attributeNames contains id" );
is( attrs.contains("status"), 1, "attributeNames contains status" );
first.removeAttribute("status");
is( first.hasAttribute("status"), 0, "removeAttribute" );
let info := doc.createElement("info");
info.setTextContent("meta");
root.prependChild(info);
is( root.firstChild().nodeName(), "info", "prependChild" );
let comment := doc.createComment("tail");
root.appendChild(comment);
is( root.lastChild().nodeType(), "8", "appendChild comment node" );
is( comment.nodeKind(), "comment", "comment nodeKind" );
is( comment.data(), "tail", "comment data" );
comment.setData("fin");
is( comment.data(), "fin", "comment setData" );
let text := doc.createTextNode("!");
first.appendChild(text);
is( first.lastChild().nodeType(), "3", "createTextNode and appendChild" );
is( text.data(), "!", "text data" );
text.setData("?");
is( text.data(), "?", "text setData" );
let cdata := doc.createCDATASection("hello");
first.appendChild(cdata);
is( first.lastChild().textContent(), "hello", "createCDATASection" );
let before := doc.createElement("before");
root.insertBefore( before, second );
is( second.previousSibling().nodeName(), "before", "insertBefore" );
let repl := doc.createElement("replacement");
root.replaceChild( repl, second );
is( doc.findvalue( "name(/root/*[4])" ), "replacement", "replaceChild" );
root.removeChild(repl);
is( doc.findnodes( "/root/replacement" ).length(), 0, "removeChild" );
let to_remove := doc.findnodes( "/root/item[@id='alpha']" ).get( 0, null );
to_remove.remove();
is( doc.findnodes("/root/item").length(), 0, "remove" );
let cloned := info.cloneNode(true);
cloned.setAttribute( "copied", "yes" );
root.appendChild(cloned);
is( doc.findnodes("/root/info").length(), 2, "cloneNode and append" );
is( cloned.isEqualNode(info), 0, "isEqualNode false after mutation" );
is( info.contains( info.firstChild() ), 1, "contains descendant" );
is( info.isSameNode(info), 1, "isSameNode self" );
is( info.isSameNode(cloned), 0, "isSameNode other" );
is( doc.findnodes( "/root/info[@copied='yes']" ).length(), 1, "clone mutated only copy" );
like( cloned.ownerDocument().toXML(false), /<root>/, "ownerDocument" );
like( cloned.toXML(false), /copied="yes"/, "node toXML" );
let visited := [];
doc.visitEach( fn n -> visited.push( n.nodeName() ) );
is( visited.length() > 4, 1, "visitEach traverses tree" );
is( visited.get( 0, "" ), "#document", "visitEach starts at document" );
let found := doc.findFirst( fn n -> 1 );
is( found.nodeName(), "root", "findFirst on document" );
let found_under_root := root.findFirst( fn n -> 1 );
is( found_under_root.nodeName(), "info", "findFirst on node" );
let xml_text := doc.toXML(false);
like( xml_text, /<info>meta<\/info>/, "document toXML" );
like( xml_text, /<!--fin-->/, "serialized comment" );
done_testing();