7212: convert invalid dates to text on import
unit tests
This commit is contained in:
parent
b770de1a10
commit
86dc84470e
195
gramps/plugins/importer/test/importxml_test.py
Normal file
195
gramps/plugins/importer/test/importxml_test.py
Normal file
@ -0,0 +1,195 @@
|
||||
# Gramps - a GTK+/GNOME based genealogy program
|
||||
#
|
||||
# Copyright (C) 2011 Michiel D. Nauta
|
||||
# Copyright (C) 2013 Vassilii Khachaturov
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program 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 General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#
|
||||
|
||||
"""
|
||||
Test XML import.
|
||||
"""
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import unittest
|
||||
import time
|
||||
import os
|
||||
import subprocess
|
||||
import libxml2
|
||||
import libxslt
|
||||
|
||||
from gramps.plugins.lib.libgrampsxml import GRAMPS_XML_VERSION
|
||||
from gramps.gen.const import ROOT_DIR, USER_PLUGINS
|
||||
from gramps.version import VERSION
|
||||
|
||||
HAS_EXPORTRAW = os.path.isdir(os.path.join(USER_PLUGINS, 'ExportRaw'))
|
||||
|
||||
class CopiedDoc(object):
|
||||
"""Context manager that creates a deep copy of an libxml-xml document."""
|
||||
def __init__(self, xmldoc):
|
||||
self.xmldoc = xmldoc
|
||||
self.copy = libxml2.readDoc(str(self.xmldoc), '', None,
|
||||
libxml2.XML_PARSE_NONET)
|
||||
|
||||
def __enter__(self):
|
||||
return self.copy
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
self.copy.freeDoc()
|
||||
return False
|
||||
|
||||
class XpathContext(object):
|
||||
"""Context manager that creates a libxml2 xpath context that allows
|
||||
evaluation of xpath expressions."""
|
||||
def __init__(self, xmldoc):
|
||||
self.xmldoc = xmldoc
|
||||
self.ctxt = self.xmldoc.xpathNewContext()
|
||||
self.ctxt.xpathRegisterNs('g', 'http://gramps-project.org/xml/%s/' %
|
||||
GRAMPS_XML_VERSION)
|
||||
|
||||
def __enter__(self):
|
||||
return self.ctxt
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
self.ctxt.xpathFreeContext()
|
||||
return False
|
||||
|
||||
@unittest.skipUnless(HAS_EXPORTRAW,
|
||||
'These tests need the 3rd-party plugin "ExportRaw".')
|
||||
class BaseImportTest(unittest.TestCase):
|
||||
def base_setup(self):
|
||||
"""Set up code needed by all tests."""
|
||||
date = time.localtime(time.time())
|
||||
libxml2.keepBlanksDefault(0)
|
||||
styledoc = libxml2.parseFile(os.path.join(ROOT_DIR,
|
||||
"../data/gramps_canonicalize.xsl"))
|
||||
self.style = libxslt.parseStylesheetDoc(styledoc)
|
||||
self.basedoc = None
|
||||
self.base_str = """<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE database PUBLIC "-//GRAMPS//DTD GRAMPS XML %s//EN"
|
||||
"http://gramps-project.org/xml/%s/grampsxml.dtd">
|
||||
<database xmlns="http://gramps-project.org/xml/%s/">
|
||||
<header>
|
||||
<created date="%04d-%02d-%02d" version="%s"/>
|
||||
<researcher>\n </researcher>
|
||||
</header>
|
||||
""" % (GRAMPS_XML_VERSION, GRAMPS_XML_VERSION, GRAMPS_XML_VERSION,
|
||||
date[0], date[1], date[2], VERSION)
|
||||
|
||||
def tearDown(self):
|
||||
self.style.freeStylesheet()
|
||||
self.basedoc.freeDoc()
|
||||
|
||||
def canonicalize(self, doctxt):
|
||||
"""
|
||||
Return a canonicalized string representation
|
||||
|
||||
:param doctxt: the text to bring in canonical form.
|
||||
:type doctxt: either a string or an Xml document.
|
||||
:returns: The text but in canonical form.
|
||||
:rtype: string
|
||||
"""
|
||||
result = ''
|
||||
if isinstance(doctxt, basestring):
|
||||
doc = libxml2.readDoc(doctxt, '', None, libxml2.XML_PARSE_NONET)
|
||||
elif isinstance(doctxt, libxml2.xmlDoc):
|
||||
doc = doctxt
|
||||
else:
|
||||
raise TypeError
|
||||
param = {}
|
||||
canonical_doc = self.style.applyStylesheet(doc, param)
|
||||
result = self.style.saveResultToString(canonical_doc)
|
||||
canonical_doc.freeDoc()
|
||||
if isinstance(doctxt, basestring):
|
||||
doc.freeDoc()
|
||||
return result
|
||||
|
||||
def do_test(self, input_doc, expect_doc,
|
||||
test_error_str='', debug=False):
|
||||
"""Do the import and "assert" the result."""
|
||||
process = subprocess.Popen('python Gramps.py -d .Date -d .ImportXML '
|
||||
'--config=preferences.eprefix:DEFAULT '
|
||||
'-i - -f gramps '
|
||||
'-e - -f gramps',
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, shell=True)
|
||||
result_str, err_str = process.communicate(str(input_doc))
|
||||
if err_str:
|
||||
if test_error_str:
|
||||
self.assertIn(test_error_str, err_str)
|
||||
return
|
||||
else:
|
||||
if "Traceback (most recent call last):" in err_str:
|
||||
raise Exception(err_str)
|
||||
if debug:
|
||||
print('err_str:', err_str)
|
||||
print('input :', self.canonicalize(input_doc))
|
||||
print('result:', self.canonicalize(result_str))
|
||||
print('expect:', self.canonicalize(expect_doc))
|
||||
self.assertEqual(self.canonicalize(result_str),
|
||||
self.canonicalize(expect_doc))
|
||||
|
||||
class DateTest(BaseImportTest):
|
||||
def setUp(self):
|
||||
self.base_setup()
|
||||
self.events_str = """
|
||||
<events>
|
||||
<event handle="_e0000" id="E0000">
|
||||
<type>Birth</type>
|
||||
{datexml}
|
||||
<description>Event 0</description>
|
||||
</event>
|
||||
</events>
|
||||
</database>"""
|
||||
self.datexml_src = self.datexml_trg = None
|
||||
|
||||
def tearDown(self):
|
||||
self.basedoc = libxml2.readDoc(
|
||||
self.base_str + self.events_str.format(datexml=self.datexml_src),
|
||||
'', None, libxml2.XML_PARSE_NONET)
|
||||
expect = libxml2.readDoc(
|
||||
self.base_str + self.events_str.format(datexml=self.datexml_trg),
|
||||
'', None, libxml2.XML_PARSE_NONET)
|
||||
try:
|
||||
self.do_test(self.basedoc, expect)
|
||||
except:
|
||||
raise
|
||||
finally:
|
||||
expect.freeDoc()
|
||||
|
||||
def test_correct_dateval_passed_verbatim(self):
|
||||
self.datexml_trg = self.datexml_src = \
|
||||
'<dateval val="1787-05-20"/>'
|
||||
|
||||
def test_correct_daterange_passed_verbatim(self):
|
||||
self.datexml_trg = self.datexml_src = \
|
||||
'<daterange start="1746" stop="1755"/>'
|
||||
|
||||
def test_dateval_long_Feb_converted_to_datestr(self):
|
||||
self.datexml_src = '<dateval val="1787-02-30"/>'
|
||||
self.datexml_trg = '<datestr val="<dateval val="1787-02-30"/>"/>'
|
||||
|
||||
def test_datespan_long_Feb_converted_to_datestr(self):
|
||||
self.datexml_src = '<datespan start="1746-02-30" stop="2000"/>'
|
||||
self.datexml_trg = '<datestr val="<datespan start="1746-02-30" stop="2000"/>"/>'
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
if not HAS_EXPORTRAW:
|
||||
print('This program needs the third party "ExportRaw" plugin.', file=sys.stderr)
|
||||
sys.exit(1)
|
||||
unittest.main()
|
Loading…
Reference in New Issue
Block a user