
use strict;
use warnings;

use Test::More tests => 275 ;
BEGIN { use_ok('Sleepycat::DbXml', 'simple') };
BEGIN { use_ok('File::Path') };


my $tmp_dir = "tmp" ;

if (-d $tmp_dir)
{
    rmtree($tmp_dir);
}

mkdir $tmp_dir, 0777 ;

my $prefix = '<?xml version="1.0" encoding="utf-8" standalone="no" ?>';

sub runSuite
{
    my $content = shift ;
    my @data = @_ ;

    # XMlDocument::modifyDocument
    # XmlModify with string xpath
    foreach my $test (@data)
    {
        my $doc = new XmlDocument(); 
        $doc->setContent($content);

        my @params = @$test ;
        my $expected = pop @params ;
	
        my $modify = new XmlModify(@params);

        ok $modify, "created XmlModify object with xpath '$params[0]'" ;

        $doc->modifyDocument($modify);

        my $cont = $doc->getContentAsString();
    
        #print "content is [$cont]\n" ;

        ok $cont eq $expected, "getContentAsString returned correct content" ;
        my $count = $modify->getNumModifications();
        ok $count, "carried out $count modifications";
    }

    # XMlContainer::modifyDocument 
    # XmlModify with string xpath
    foreach my $test (@data)
    {
        my $container_name = "$tmp_dir/fred" ;
        my $container = new XmlContainer($container_name); 
        ok $container, "new XmlContainer returned object" ;
        $container->open(Db::DB_CREATE); 

        my $doc = new XmlDocument(); 
        $doc->setContent($content);

        my $id = $container->putDocument($doc);

        my @params = @$test ;
        my $expected = pop @params ;
	
        my $modify = new XmlModify(@params);

        ok $modify, "created XmlModify object with xpath '$params[0]'" ;

        $container->modifyDocument($modify);

        my $d = $container->getDocument($id);
        my $got = $d->getContentAsString();
    
        #print "content is [$got]\n" ;

        ok $got eq $expected, "getContentAsString returned correct content" ;

        my $count = $modify->getNumModifications();
        ok $count, "carried out $count modifications";

        $container->close() ;
        $container->remove()
    }

    # XMlContainer::modifyDocument 
    # XmlModify with XmlQueryExpression
    foreach my $test (@data)
    {
        my $container_name = "$tmp_dir/fred" ;
        my $container = new XmlContainer($container_name); 
        ok $container, "new XmlContainer returned object" ;
        $container->open(Db::DB_CREATE); 

        my $doc = new XmlDocument(); 
        $doc->setContent($content);

        my $id = $container->putDocument($doc);

        my @params = @$test ;
        my $xpath = shift @params ;
        my $expected = pop @params ;

	my $context = new XmlQueryContext();
	$context->setReturnType(XmlQueryContext::ResultDocumentsAndValues);
        ok $context, "created XmlContext object" ;

	my $expression = $container->parseXPathExpression($xpath, $context) ;
        ok $expression, "created XmlQueryExpression object with xpath '$xpath'" ;

	
        my $modify = new XmlModify($expression, @params);

        ok $modify, "created XmlModify object" ;

        $container->modifyDocument($modify);

        my $d = $container->getDocument($id);
        my $got = $d->getContentAsString();
    
        #print "content is [$got]\n" ;

        ok $got eq $expected, "getContentAsString returned correct content" ;

        my $count = $modify->getNumModifications();
        ok $count, "carried out $count modifications";

        $container->close() ;
        $container->remove()
    }

}


eval {

{
    # XmlDocument::modifyDocument 

    my $content = qq{$prefix<root/>};

    my @data = (

    [ '/root', XmlModify::Append, XmlModify::Element, 'new', 'new content',
        qq{$prefix<root><new>new content</new></root>} 
    ],

    [ "/root", XmlModify::Append, XmlModify::Attribute, "new", "foo",
        qq{$prefix<root new="foo"/>} 
    ],

    [ "/root", XmlModify::Append, XmlModify::ProcessingInstruction, "newPI", "PIcontent",
        qq{$prefix<root><?newPI PIcontent?></root>} 
    ],

    [ "/root", XmlModify::Append, XmlModify::Comment, "", "comment content",
        qq{$prefix<root><!--comment content--></root>}
    ],

    [ "/root", XmlModify::Append, XmlModify::Text, "", "text content",
        qq{$prefix<root>text content</root>} 
    ]


    );

    runSuite($content, @data) ;
}

{
    # XmlDocument::modifyDocument 

    my $content = qq{$prefix<root><a att1="att1">a content</a><b att1="att1" att2="att2">b content 1</b><b att1="att1" att2="att2">b content 2</b><!--comment--></root>} ;

    my @data = (


    [ '/root/b/@att1', XmlModify::Remove, XmlModify::None, "", "",
      '<?xml version="1.0" encoding="utf-8" standalone="no" ?><root><a att1="att1">a content</a><b att2="att2">b content 1</b><b att2="att2">b content 2</b><!--comment--></root>'],

    ["/root/b[text()='b content 2']", XmlModify::Remove, XmlModify::None, "", "",
      "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\" ?><root><a att1=\"att1\">a content</a><b att1=\"att1\" att2=\"att2\">b content 1</b><!--comment--></root>"],

    ["/root/comment()", XmlModify::Remove, XmlModify::None, "", "",
      "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\" ?><root><a att1=\"att1\">a content</a><b att1=\"att1\" att2=\"att2\">b content 1</b><b att1=\"att1\" att2=\"att2\">b content 2</b></root>" ],

    [ "/root/a/text()", XmlModify::Remove, XmlModify::None, "", "",
      "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\" ?><root><a att1=\"att1\"/><b att1=\"att1\" att2=\"att2\">b content 1</b><b att1=\"att1\" att2=\"att2\">b content 2</b><!--comment--></root>"],

    [ "/root", XmlModify::Append, XmlModify::Element, "new", "",
      "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\" ?><root><a att1=\"att1\">a content</a><b att1=\"att1\" att2=\"att2\">b content 1</b><b att1=\"att1\" att2=\"att2\">b content 2</b><!--comment--><new/></root>"],

    ["/root", XmlModify::Append, XmlModify::Element, "new", "", 0,
     "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\" ?><root><new/><a att1=\"att1\">a content</a><b att1=\"att1\" att2=\"att2\">b content 1</b><b att1=\"att1\" att2=\"att2\">b content 2</b><!--comment--></root>"],

    [ "/root", XmlModify::Append, XmlModify::Element, "new", "", 2,
      "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\" ?><root><a att1=\"att1\">a content</a><b att1=\"att1\" att2=\"att2\">b content 1</b><new/><b att1=\"att1\" att2=\"att2\">b content 2</b><!--comment--></root>"],

    [ "/root/a", XmlModify::InsertBefore, XmlModify::Element, "new", "",
      "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\" ?><root><new/><a att1=\"att1\">a content</a><b att1=\"att1\" att2=\"att2\">b content 1</b><b att1=\"att1\" att2=\"att2\">b content 2</b><!--comment--></root>" ],

    [ "/root/a", XmlModify::InsertAfter, XmlModify::Element, "new", "",
      "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\" ?><root><a att1=\"att1\">a content</a><new/><b att1=\"att1\" att2=\"att2\">b content 1</b><b att1=\"att1\" att2=\"att2\">b content 2</b><!--comment--></root>"],

    [ "/root/a", XmlModify::Rename, XmlModify::None, "x", "",
      "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\" ?><root><x att1=\"att1\">a content</x><b att1=\"att1\" att2=\"att2\">b content 1</b><b att1=\"att1\" att2=\"att2\">b content 2</b><!--comment--></root>" ],

    [ '/root/a/@att1', XmlModify::Rename, XmlModify::None, "att2", "",
      "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\" ?><root><a att2=\"att1\">a content</a><b att1=\"att1\" att2=\"att2\">b content 1</b><b att1=\"att1\" att2=\"att2\">b content 2</b><!--comment--></root>" ],


    );

    runSuite($content, @data) ;
}

{
    # XmlDocument::modifyDocument 

    my $content = qq{$prefix<root><a>a content 1<c/>a content 2</a><b>b content 1</b><!--comment--></root>};

    my @data = (

    [ "/root/comment()", XmlModify::Update, XmlModify::None, "", "new comment",
      "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\" ?><root><a>a content 1<c/>a content 2</a><b>b content 1</b><!--new comment--></root>"],

    [ "/root/a", XmlModify::Update, XmlModify::None, "", "new a text",
      "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\" ?><root><a><c/>new a text</a><b>b content 1</b><!--comment--></root>"],

    [ "/root/a", XmlModify::Update, XmlModify::None, "", "",
      "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\" ?><root><a><c/></a><b>b content 1</b><!--comment--></root>"],

    [ "/root", XmlModify::Update, XmlModify::None, "", "new root text",
      "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\" ?><root><a>a content 1<c/>a content 2</a><b>b content 1</b><!--comment-->new root text</root>"],

    [ "/root/b", XmlModify::Update, XmlModify::None, "", "new b text",
      "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\" ?><root><a>a content 1<c/>a content 2</a><b>new b text</b><!--comment--></root>"],


    );

    runSuite($content, @data) ;

}


} ;

my $e;
    
if ($e = catch std::exception)
{
    warn "exception: " . $e->what() . "\n";
}
elsif ($@)
{
    warn $@;
}

__END__


