# Copyright (c) 2000-2004 LOGILAB S.A. (Paris, FRANCE).
# http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
"""unit tests for xml rdf parsing
"""

__revision__ = '$Id$'

import os
import unittest
from xml.sax.xmlreader import InputSource
from logilab.common import testlib

from narval.elements.rdf import RDFStatementElement
from narval.actions.AlRDF import RDFHandler
from xml.sax import make_parser


try:
    from cStringIO import StringIO
except ImportError:
    from StringIO import StringIO
    

LOGILAB_NS = "http://www.logilab.org/namespaces/Narval/1.2"

DATA_SINGLE1 = '''  <rdf:Description rdf:about="Sylvain">
    <ns0:works_for xmlns:ns0="http://www.logilab.org/namespaces/Narval/1.2#">
       Logilab
    </ns0:works_for>
  </rdf:Description>
'''

DATA_SINGLE2 = '''  <rdf:Description rdf:about="Alexandre">
    <ns0:is_paid_by xmlns:ns0="http://www.logilab.org/namespaces/Narval/1.2#">
       Logilab
    </ns0:is_paid_by>
  </rdf:Description>
'''

DATA_WHOLE = '''<?xml version="1.0" encoding="utf-8"?> 
<rdf:RDF xmlns:rdf="http://www.logilab.org/namespaces/Narval/1.2#">
''' + DATA_SINGLE1 + DATA_SINGLE2 + '''
</rdf:RDF>             
'''

FOAF_DATA = '''<rdf:RDF
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
 xmlns:foaf="http://xmlns.com/foaf/0.1/"
 xmlns:admin="http://webns.net/mvcb/">
  <foaf:PersonalProfileDocument rdf:about="">
    <foaf:maker rdf:nodeID="me"/>
    <foaf:primaryTopic rdf:nodeID="me"/>
    <admin:generatorAgent :resource="http://www.ldodds.com/foaf/foaf-a-matic"/>
    <admin:errorReportsTo rdf:resource="mailto:leigh@ldodds.com"/>
  </foaf:PersonalProfileDocument>
  <foaf:Person rdf:nodeID="me">
    <foaf:name>Arthur Lutz</foaf:name>
    <foaf:title>Mr</foaf:title>
    <foaf:givenname>Arthur</foaf:givenname>
    <foaf:family_name>Lutz</foaf:family_name>
    <foaf:nick>arthur</foaf:nick>
    <foaf:mbox_sha1sum>521e7eb0443f80fec341282110329683c883f2b2</foaf:mbox_sha1sum>
    <foaf:workplaceHomepage rdf:resource="http://www.logilab.fr"/>
    <foaf:schoolHomepage 
     rdf:resource="http://www.bris.ac.uk"/>
  </foaf:Person>
</rdf:RDF>'''

#RDF_ELMT_SINGLE = '''<rdf-statement xmls:type="uri:memory:type" xmlns:al="%s">''' % LOGILAB_NS + DATA_SINGLE1 + '''</rdf-statement>'''
#RDF_ELMTS = '''<al:rdfxml>''' + DATA_WHOLE + '''</al:rdfxml>'''


class TestXMLRDFParse(testlib.TestCase):

    def setUp(self):
        self.handler = RDFHandler()
        self.parser = make_parser()
        self.parser.setContentHandler(self.handler)


    def test_as_rdf_xml(self):
        inpsrc = InputSource()
        inpsrc.setByteStream(StringIO(DATA_SINGLE1))
        self.parser.parse(inpsrc)
        statements = self.handler.elements

        for stmt in statements:
            self.assert_(isinstance(stmt, RDFStatementElement))

        self.assertListEquals(statements[0].as_rdf_xml().splitlines(),
                              DATA_SINGLE1.splitlines())

    def test_as_xml_multiple(self):
        inpsrc = InputSource()
        inpsrc.setByteStream(StringIO(DATA_WHOLE))
        self.parser.parse(inpsrc)
        statements = self.handler.elements

        for stmt in statements:
            self.assert_(isinstance(stmt, RDFStatementElement))
        self.assertListEquals(statements[0].as_rdf_xml().splitlines(),
                              DATA_SINGLE1.splitlines())
        self.assertListEquals(statements[1].as_rdf_xml().splitlines(),
                              DATA_SINGLE2.splitlines())

        
    def test_foaf_reading(self):
        inpsrc = InputSource()
        inpsrc.setByteStream(StringIO(FOAF_DATA))
        self.parser.parse(inpsrc)
        statements = self.handler.elements
        self.assert_(statements)
        copy_stmst = [('arthur', 'name', 'Arthur Lutz'),
                      ('arthur', 'title', 'Mr'),
                      ('arthur', 'givenname', 'Arthur'),
                      ('arthur', 'family_name', 'Lutz'),
                      ('arthur', 'nick', 'arthur'),
                      ('arthur', 'mbox_sha1sum', '521e7eb0443f80fec341282110329683c883f2b2'),
                      ('arthur', 'workplaceHomepage', 'http://www.logilab.fr'),
                      ('arthur', 'schoolHomepage', 'http://www.bris.ac.uk')]
        self.assertEquals(len(statements), len(copy_stmst))
        for stmt, copy in zip(statements, copy_stmst):
            self.assertEquals((stmt.subject, stmt.predicate, stmt.object),
                              copy)
            
    def test_complex_foaf_reading(self):
        inpsrc = InputSource()
        inpsrc.setByteStream(open(os.path.join('data','foaf.rdf')))
        self.parser.parse(inpsrc)
        statements = self.handler.elements
        self.assert_(statements)
        # FIXME: WHY 11 ? !!!!!!!!!!!!!!!!!!!!
        # arthur tell us this !!
        self.assertEquals(len([stmt for stmt in statements if stmt.predicate == 'knows']), 11)



if __name__ == '__main__':
    unittest.main()
