# $Id: 04node.t,v 1.1.1.2 2007/10/10 23:04:15 ahuda Exp $
##
# this test checks the DOM Node interface of XML::LibXML
# it relies on the success of t/01basic.t and t/02parse.t
# it will ONLY test the DOM capabilities as specified in DOM Level3
# XPath tests should be done in another test file
# since all tests are run on a preparsed
use Test;
BEGIN { plan tests => 136 };
use XML::LibXML;
use XML::LibXML::Common qw(:libxml);
my $xmlstring = q{bar};
my $parser = XML::LibXML->new();
my $doc = $parser->parse_string( $xmlstring );
print "# 1 Standalone Without NameSpaces\n\n";
print "# 1.1 Node Attributes\n";
{
my $node = $doc->documentElement;
my $rnode;
ok($node);
ok($node->nodeType, XML_ELEMENT_NODE);
ok($node->nodeName, "foo");
ok(not defined $node->nodeValue);
ok($node->hasChildNodes);
ok($node->textContent, "bar&foo bar");
{
my @children = $node->childNodes;
ok( scalar @children, 5 );
ok( $children[0]->nodeType, XML_TEXT_NODE );
ok( $children[0]->nodeValue, "bar" );
ok( $children[4]->nodeType, XML_CDATA_SECTION_NODE );
ok( $children[4]->nodeValue, "&foo bar" );
my $fc = $node->firstChild;
ok( $fc );
ok( $fc->isSameNode($children[0]));
ok( $fc->baseURI =~ /unknown-/ );
my $od = $fc->ownerDocument;
ok( $od );
ok( $od->isSameNode($doc));
my $xc = $fc->nextSibling;
ok( $xc );
ok( $xc->isSameNode($children[1]) );
$fc = $node->lastChild;
ok( $fc );
ok( $fc->isSameNode($children[4]));
$xc = $fc->previousSibling;
ok( $xc );
ok( $xc->isSameNode($children[3]) );
$rnode = $xc;
$xc = $fc->parentNode;
ok( $xc );
ok( $xc->isSameNode($node) );
$xc = $children[2];
{
print "# 1.2 Attribute Node\n";
ok( $xc->hasAttributes );
my $attributes = $xc->attributes;
ok( $attributes );
ok( ref($attributes), "XML::LibXML::NamedNodeMap" );
ok( $attributes->length, 1 );
my $attr = $attributes->getNamedItem("foo");
ok( $attr );
ok( $attr->nodeType, XML_ATTRIBUTE_NODE );
ok( $attr->nodeName, "foo" );
ok( $attr->nodeValue, "foobar" );
ok( $attr->hasChildNodes, 0);
}
{
my @attributes = $xc->attributes;
ok( scalar( @attributes ), 1 );
}
print "# 1.2 Node Cloning\n";
{
my $cnode = $doc->createElement("foo");
$cnode->setAttribute('aaa','AAA');
$cnode->setAttributeNS('http://ns','x:bbb','BBB');
my $c1node = $doc->createElement("bar");
$cnode->appendChild( $c1node );
my $xnode = $cnode->cloneNode(0);
ok( $xnode );
ok( $xnode->nodeName, "foo" );
ok( not $xnode->hasChildNodes );
ok( $xnode->getAttribute('aaa'),'AAA' );
ok( $xnode->getAttributeNS('http://ns','bbb'),'BBB' );
$xnode = $cnode->cloneNode(1);
ok( $xnode );
ok( $xnode->nodeName, "foo" );
ok( $xnode->hasChildNodes );
ok( $xnode->getAttribute('aaa'),'AAA' );
ok( $xnode->getAttributeNS('http://ns','bbb'),'BBB' );
my @cn = $xnode->childNodes;
ok( @cn );
ok( scalar(@cn), 1);
ok( $cn[0]->nodeName, "bar" );
ok( !$cn[0]->isSameNode( $c1node ) );
print "# clone namespaced elements\n";
my $nsnode = $doc->createElementNS( "fooNS", "foo:bar" );
my $cnsnode = $nsnode->cloneNode(0);
ok( $cnsnode->nodeName, "foo:bar" );
ok( $cnsnode->localNS() );
ok( $cnsnode->namespaceURI(), 'fooNS' );
print "# clone namespaced elements (recursive)\n";
my $c2nsnode = $nsnode->cloneNode(1);
ok( $c2nsnode->toString(), $nsnode->toString() );
}
print "# 1.3 Node Value\n";
my $string2 = "barfoo";
{
my $doc2 = $parser->parse_string( $string2 );
my $root = $doc2->documentElement;
ok( not defined $root->nodeValue );
ok( $root->textContent, "barfoo");
}
}
{
my $children = $node->childNodes;
ok( defined $children );
ok( ref($children), "XML::LibXML::NodeList" );
}
print "# 2. (Child) Node Manipulation\n";
print "# 2.1 Valid Operations\n";
{
print "# 2.1.1 Single Node\n";
my $inode = $doc->createElement("kungfoo"); # already tested
my $jnode = $doc->createElement("kungfoo");
my $xn = $node->insertBefore($inode, $rnode);
ok( $xn );
ok( $xn->isSameNode($inode) );
$node->insertBefore( $jnode, undef );
my @ta = $node->childNodes();
$xn = pop @ta;
ok( $xn->isSameNode( $jnode ) );
$jnode->unbindNode;
my @cn = $node->childNodes;
ok(scalar(@cn), 6);
ok( $cn[3]->isSameNode($inode) );
$xn = $node->removeChild($inode);
ok($xn);
ok($xn->isSameNode($inode));
@cn = $node->childNodes;
ok(scalar(@cn), 5);
ok( $cn[3]->isSameNode($rnode) );
$xn = $node->appendChild($inode);
ok($xn);
ok($xn->isSameNode($inode));
ok($xn->isSameNode($node->lastChild));
$xn = $node->removeChild($inode);
ok($xn);
ok($xn->isSameNode($inode));
ok($cn[-1]->isSameNode($node->lastChild));
$xn = $node->replaceChild( $inode, $rnode );
ok($xn);
ok($xn->isSameNode($rnode));
my @cn2 = $node->childNodes;
ok(scalar(@cn), 5);
ok( $cn2[3]->isSameNode($inode) );
}
{
print "\n# insertAfter Tests\n";
my $anode = $doc->createElement("a");
my $bnode = $doc->createElement("b");
my $cnode = $doc->createElement("c");
my $dnode = $doc->createElement("d");
$anode->insertAfter( $bnode, undef );
ok( $anode->toString(), '' );
$anode->insertAfter( $dnode, undef );
ok( $anode->toString(), '' );
$anode->insertAfter( $cnode, $bnode );
ok( $anode->toString(), '' );
}
{
print "\ntest\n" ;
my ($inode, $jnode );
$inode = $doc->createElement("kungfoo"); # already tested
$jnode = $doc->createElement("foobar");
my $xn = $inode->insertBefore( $jnode, undef);
ok( $xn );
ok( $xn->isSameNode( $jnode ) );
print( "# ". $xn->toString() );
}
{
print "# 2.1.2 Document Fragment\n";
my @cn = $doc->documentElement->childNodes;
my $rnode= $doc->documentElement;
my $frag = $doc->createDocumentFragment;
my $node1= $doc->createElement("kung");
my $node2= $doc->createElement("foo");
$frag->appendChild($node1);
$frag->appendChild($node2);
my $xn = $node->appendChild( $frag );
ok($xn);
my @cn2 = $node->childNodes;
ok(scalar(@cn2), 7);
ok($cn2[-1]->isSameNode($node2));
ok($cn2[-2]->isSameNode($node1));
$frag->appendChild( $node1 );
$frag->appendChild( $node2 );
@cn2 = $node->childNodes;
ok(scalar(@cn2), 5);
$xn = $node->replaceChild( $frag, $cn[3] );
ok($xn);
ok($xn->isSameNode($cn[3]));
@cn2 = $node->childNodes;
ok(scalar(@cn2), 6);
$frag->appendChild( $node1 );
$frag->appendChild( $node2 );
$xn = $node->insertBefore( $frag, $cn[0] );
ok($xn);
ok($node1->isSameNode($node->firstChild));
@cn2 = $node->childNodes;
ok(scalar(@cn2), 6);
}
print "# 2.2 Invalid Operations\n";
print "# 2.3 DOM extensions \n";
{
my $str = "com";
my $doc = XML::LibXML->new->parse_string( $str );
my $elem= $doc->documentElement;
ok( $elem );
ok( $elem->hasChildNodes );
$elem->removeChildNodes;
ok( $elem->hasChildNodes,0 );
$elem->toString;
}
}
print "# 3 Standalone With NameSpaces\n\n";
{
my $doc = XML::LibXML::Document->new();
my $URI ="http://kungfoo";
my $pre = "foo";
my $name= "bar";
my $elem = $doc->createElementNS($URI, $pre.":".$name);
ok($elem);
ok($elem->nodeName, $pre.":".$name);
ok($elem->namespaceURI, $URI);
ok($elem->prefix, $pre);
ok($elem->localname, $name );
ok( $elem->lookupNamespacePrefix( $URI ), $pre);
ok( $elem->lookupNamespaceURI( $pre ), $URI);
my @ns = $elem->getNamespaces;
ok( scalar(@ns) ,1 );
}
print "# 4. Document swtiching\n";
{
print "# 4.1 simple document\n";
my $docA = XML::LibXML::Document->new;
{
my $docB = XML::LibXML::Document->new;
my $e1 = $docB->createElement( "A" );
my $e2 = $docB->createElement( "B" );
my $e3 = $docB->createElementNS( "http://kungfoo", "C:D" );
$e1->appendChild( $e2 );
$e1->appendChild( $e3 );
$docA->setDocumentElement( $e1 );
}
my $elem = $docA->documentElement;
my @c = $elem->childNodes;
my $xroot = $c[0]->ownerDocument;
ok( $xroot->isSameNode($docA) );
}
print "# 5. libxml2 specials\n";
{
my $docA = XML::LibXML::Document->new;
my $e1 = $docA->createElement( "A" );
my $e2 = $docA->createElement( "B" );
my $e3 = $docA->createElement( "C" );
$e1->appendChild( $e2 );
my $x = $e2->replaceNode( $e3 );
my @cn = $e1->childNodes;
ok(@cn);
ok( scalar(@cn), 1 );
ok($cn[0]->isSameNode($e3));
ok($x->isSameNode($e2));
$e3->addSibling( $e2 );
@cn = $e1->childNodes;
ok( scalar(@cn), 2 );
ok($cn[0]->isSameNode($e3));
ok($cn[1]->isSameNode($e2));
}
print "# 6. implicit attribute manipulation\n";
{
my $parser = XML::LibXML->new();
my $doc = $parser->parse_string( '' );
my $root = $doc->documentElement;
my $attributes = $root->attributes;
ok($attributes);
my $newAttr = $doc->createAttribute( "kung", "foo" );
$attributes->setNamedItem( $newAttr );
my @att = $root->attributes;
ok(@att);
ok(scalar(@att), 2);
$newAttr = $doc->createAttributeNS( "http://kungfoo", "x:kung", "foo" );
$attributes->setNamedItem($newAttr);
@att = $root->attributes;
ok(@att);
ok(scalar(@att), 4); # because of the namespace ...
$newAttr = $doc->createAttributeNS( "http://kungfoo", "x:kung", "bar" );
$attributes->setNamedItem($newAttr);
@att = $root->attributes;
ok(@att);
ok(scalar(@att), 4);
ok($att[2]->isSameNode($newAttr));
$attributes->removeNamedItem("x:kung");
@att = $root->attributes;
ok(@att);
ok(scalar(@att), 3);
ok($attributes->length, 3);
}
print "# 7. importing and adopting\n";
{
my $parser = XML::LibXML->new;
my $doc1 = $parser->parse_string( "bar" );
my $doc2 = XML::LibXML::Document->new;
ok( $doc1 && $doc2 );
my $rnode1 = $doc1->documentElement;
ok( $rnode1 );
my $rnode2 = $doc2->importNode( $rnode1 );
ok( not $rnode2->isSameNode( $rnode1 ) ) ;
$doc2->setDocumentElement( $rnode2 );
my $node = $rnode2->cloneNode(0);
ok( $node );
my $cndoc = $node->ownerDocument;
ok( $cndoc );
ok( $cndoc->isSameNode( $doc2 ) );
my $xnode = XML::LibXML::Element->new("test");
my $node2 = $doc2->importNode($xnode);
ok( $node2 );
my $cndoc2 = $node2->ownerDocument;
ok( $cndoc2 );
ok( $cndoc2->isSameNode( $doc2 ) );
my $doc3 = XML::LibXML::Document->new;
my $node3 = $doc3->adoptNode( $xnode );
ok( $node3 );
ok( $xnode->isSameNode( $node3 ) );
ok( $doc3->isSameNode( $node3->ownerDocument ) );
my $xnode2 = XML::LibXML::Element->new("test");
$xnode2->setOwnerDocument( $doc3 ); # alternate version of adopt node
ok( $xnode2->ownerDocument );
ok( $doc3->isSameNode( $xnode2->ownerDocument ) );
}
{
# appending empty fragment
my $doc = XML::LibXML::Document->new();
my $frag = $doc->createDocumentFragment();
my $root = $doc->createElement( 'foo' );
my $r = $root->appendChild( $frag );
ok( $r );
}
{
for my $obj (qw(Document DocumentFragment Comment CDATASection PI Text)) {
}
}