
use strict;
use warnings;

use Test::More tests => 105 ;
BEGIN { use_ok('Sleepycat::DbXml') };


my $context = new XmlQueryContext() ;

ok $context, "created XmlQueryContext ok";

{
    # test typeless XmlValue

    my $value = new XmlValue();

    is $value->getType($context), XmlValue::NONE, "getType - None" ;
    ok   $value->isNull(), "isNull";
    ok ! $value->isBoolean(), "! isBoolean";
    ok ! $value->isNumber(), "! isNumber";
    ok ! $value->isString(), "! isString";
    ok ! $value->isDocument(), "! isDocument";
    ok ! $value->isVariable(), "! isVariable";
    ok ! $value->isNode(), "! isNode";
    
    eval { $value->asBoolean($context); };
    is $@->getExceptionCode, XmlException::INVALID_VALUE, "exception is INVALID_VALUE";

    eval { $value->asNumber($context); } ;
    is $@->getExceptionCode, XmlException::INVALID_VALUE, "exception is INVALID_VALUE";
    eval { $value->asString($context); } ;
    is $@->getExceptionCode, XmlException::INVALID_VALUE, "exception is INVALID_VALUE";
    
    eval { $value->asDocument($context) };
    is $@->getExceptionCode, XmlException::INVALID_VALUE, "exception is INVALID_VALUE";

}

{
    # test BOOLEAN XmlValue == true

    my $value = new XmlValue(XmlValue::BOOLEAN, 1);

    is $value->getType($context), XmlValue::BOOLEAN, "getType - Boolean" ;
    ok ! $value->isNull(), "! isNull";
    ok   $value->isBoolean(), "isBoolean";
    ok ! $value->isNumber(), "! isNumber";
    ok ! $value->isString(), "! isString";
    ok ! $value->isDocument(), "! isDocument";
    ok ! $value->isVariable(), "! isVariable";
    ok ! $value->isNode(), "! isNode";
    
    ok $value->asBoolean($context), "asBoolean returned ok";
    is $value->asNumber($context), 1, "asNumber returned ok";
    is $value->asString($context), "true", "asString returned ok";

    eval { $value->asDocument($context) };
    is $@->getExceptionCode, XmlException::INVALID_VALUE, "exception is INVALID_VALUE";
}

{
    # test BOOLEAN XmlValue == false

    my $value = new XmlValue(XmlValue::BOOLEAN, 0);

    is $value->getType($context), XmlValue::BOOLEAN, "getType - Boolean" ;
    ok ! $value->isNull(), "! isNull";
    ok   $value->isBoolean(), "isBoolean";
    ok ! $value->isNumber(), "! isNumber";
    ok ! $value->isString(), "! isString";
    ok ! $value->isDocument(), "! isDocument";
    ok ! $value->isVariable(), "! isVariable";
    ok ! $value->isNode(), "! isNode";
    
    ok !$value->asBoolean($context), "asBoolean returned ok";
    is $value->asNumber($context), 0, "asNumber returned ok";
    is $value->asString($context), "false", "asString returned ok";

    eval { $value->asDocument($context) };
    is $@->getExceptionCode, XmlException::INVALID_VALUE, "exception is INVALID_VALUE";
}

{
    # test NUMBER XmlValue

    my $number =  new XmlValue(XmlValue::NUMBER, 43.3);
    is $number->getType($context), XmlValue::NUMBER, "getType - Number" ;
    ok ! $number->isNull(), "! isNull";
    ok ! $number->isBoolean(), "! isBoolean";
    ok   $number->isNumber(), "isNumber";
    ok ! $number->isString(), "! isString";
    ok ! $number->isDocument(), "! isDocument";
    ok ! $number->isVariable(), "! isVariable";
    ok ! $number->isNode(), "! isNode";

    ok $number->asBoolean($context), "asBoolean returned ok";
    is $number->asNumber($context), 43.3, "asNumber returned ok";
    is $number->asString($context), "43.3", "asString returned ok";

    eval { $number->asDocument($context) };
    is $@->getExceptionCode, XmlException::INVALID_VALUE, "exception is INVALID_VALUE";
}


{
    # test STRING XmlValue

    my $string =  new XmlValue(XmlValue::STRING,"abc def");
    is $string->getType($context), XmlValue::STRING, "getType - String" ;
    ok ! $string->isNull(), "! isNull";
    ok ! $string->isBoolean(), "! isBoolean";
    ok ! $string->isNumber(), "! isNumber";
    ok   $string->isString(), "isString";
    ok ! $string->isDocument(), "! isDocument";
    ok ! $string->isVariable(), "! isVariable";
    ok ! $string->isNode(), "! isNode";

    ok $string->asBoolean($context), "asBoolean returned ok";
    is $string->asNumber($context), undef, "asNumber returned undef";
    is $string->asString($context), "abc def", "asString returned ok";

    eval { $string->asDocument($context) };
    is $@->getExceptionCode, XmlException::INVALID_VALUE, "exception is INVALID_VALUE";
}

{
    # test VARIABLE XmlValue

    my $string =  new XmlValue(XmlValue::VARIABLE,"fred");
    is $string->getType($context), XmlValue::VARIABLE, "getType - Variable" ;
    ok ! $string->isNull(), "! isNull";
    ok ! $string->isBoolean(), "! isBoolean";
    ok ! $string->isNumber(), "! isNumber";
    ok ! $string->isString(), "! isString";
    ok ! $string->isDocument(), "! isDocument";
    ok   $string->isVariable(), "isVariable";
    ok ! $string->isNode(), "! isNode";

    eval { $string->asDocument($context) };
    is $@->getExceptionCode, XmlException::NO_VARIABLE_BINDING, "exception is NO_VARIABLE_BINDING";

    eval { $string->asString($context) };
    is $@->getExceptionCode, XmlException::NO_VARIABLE_BINDING, "exception is NO_VARIABLE_BINDING";
    eval { $string->asBoolean($context) };
    is $@->getExceptionCode, XmlException::NO_VARIABLE_BINDING, "exception is NO_VARIABLE_BINDING";
    eval { $string->asNumber($context) };
    is $@->getExceptionCode, XmlException::NO_VARIABLE_BINDING, "exception is NO_VARIABLE_BINDING";
    
}

{
    # test DOCUMENT XmlValue

    my $document = "<abc />";
    my $docu =  new XmlValue(XmlValue::DOCUMENT, $document);
    is $docu->getType($context), XmlValue::DOCUMENT, "getType - Document" ;
    ok ! $docu->isNull(), "! isNull";
    ok ! $docu->isBoolean(), "! isBoolean";
    ok ! $docu->isNumber(), "! isNumber";
    ok ! $docu->isString(), "! isString";
    ok   $docu->isDocument(), "isDocument";
    ok ! $docu->isVariable(), "! isVariable";
    ok ! $docu->isNode(), "! isNode";

    my $got = $docu->asDocument($context);
    is $got->getContentAsString, $document, "asDocument returned correct value";

    eval {  $docu->asBoolean($context) };
    is $@->getExceptionCode, XmlException::INVALID_VALUE, "exception is INVALID_VALUE";
    eval { $docu->asNumber($context) };
    is $@->getExceptionCode, XmlException::INVALID_VALUE, "exception is INVALID_VALUE";
    is $docu->asString($context), $document, "asString returned ok";
}

if (0)
{
    # test NODELIST XmlValue

    my $title = '<title>Knowledge Discovery in Databases.</title>';
    my $document = "<book>$title</book>";
    my $docu =  new XmlValue(XmlValue::NODELIST, $document);
    is $docu->getType($context), XmlValue::NODELIST, "getType - Document" ;
    ok ! $docu->isNull(), "! isNull";
    ok ! $docu->isBoolean(), "! isBoolean";
    ok ! $docu->isNumber(), "! isNumber";
    ok ! $docu->isString(), "! isString";
    ok ! $docu->isDocument(), "! isDocument";
    ok ! $docu->isVariable(), "! isVariable";
    ok   $docu->isNode(), "isNode";

    eval { my $got = $docu->asDocument($context);};
    print $@->what . "\n";
    eval { is $docu->asString, $document, "asSTring returned correct value";};
    print $@->what . "\n";

    eval {  $docu->asBoolean($context) };
    is $@->getExceptionCode, XmlException::INVALID_VALUE, "exception is INVALID_VALUE";
    eval { $docu->asNumber($context) };
    is $@->getExceptionCode, XmlException::INVALID_VALUE, "exception is INVALID_VALUE";
    eval { $docu->asString($context); };
    print $@;
    #is $docu->asString($context), $document, "asString returned ok";
}

{
    # test XmlValue::equals

    my $string1 =  new XmlValue(XmlValue::STRING,"abc def");
    my $string1a =  $string1 ;
    my $string2 =  new XmlValue(XmlValue::STRING,"abc def");
    ok $string1->equals($string1a), "equals";
    ok $string1->equals($string1a, $context), "equals";
    ok $string1->equals($string2, $context), "equals";
    ok $string1->equals($string2), "equals";
    
    my $num1 =  new XmlValue(XmlValue::NUMBER, 3);
    my $num2 =  new XmlValue(XmlValue::NUMBER, 3);
    ok $num1->equals($num2, $context), "equals";
    ok $num1->equals($num2), "equals";
    
}


{
    # XmlValue with one parameter should be a STRING 

    my $string =  new XmlValue("abc def");
    is $string->getType($context), XmlValue::STRING, "getType - String" ;
    ok ! $string->isNull(), "! isNull";
    ok ! $string->isBoolean(), "! isBoolean";
    ok ! $string->isNumber(), "! isNumber";
    ok   $string->isString(), "isString";
    ok ! $string->isDocument(), "! isDocument";
    ok ! $string->isVariable(), "! isVariable";
    ok ! $string->isNode(), "! isNode";

    ok $string->asBoolean($context), "asBoolean returned ok";
    is $string->asNumber($context), undef, "asNumber returned undef";
    is $string->asString($context), "abc def", "asString returned ok";

    eval { $string->asDocument($context) };
    is $@->getExceptionCode, XmlException::INVALID_VALUE, "exception is INVALID_VALUE";
}

{
    # give XmlValue constructor too many parameters
    eval { my $x = new XmlValue(1,2,3,4) } ;
    like $@, qr/XmlValue::new expects between 0 & 2 parameters/, 
    	"Giving XmlValue::new too many parameters is trapped";
}
