# Licensed under a 3-clause BSD style license - see LICENSE.rst
import io
import pytest
from astropy.io.votable.exceptions import W07, W08, W21, W41
from astropy.io.votable import tree
from astropy.io.votable.table import parse
from astropy.io.votable.tree import VOTableFile, Resource
from astropy.utils.data import get_pkg_data_filename
from astropy.utils.exceptions import AstropyDeprecationWarning
def test_check_astroyear_fail():
config = {'verify': 'exception'}
field = tree.Field(None, name='astroyear', arraysize='1')
with pytest.raises(W07):
tree.check_astroyear('X2100', field, config)
def test_string_fail():
config = {'verify': 'exception'}
with pytest.raises(W08):
tree.check_string(42, 'foo', config)
def test_make_Fields():
votable = tree.VOTableFile()
# ...with one resource...
resource = tree.Resource()
votable.resources.append(resource)
# ... with one table
table = tree.Table(votable)
resource.tables.append(table)
table.fields.extend([tree.Field(
votable, name='Test', datatype="float", unit="mag")])
def test_unit_format():
data = parse(get_pkg_data_filename('data/irsa-nph-error.xml'))
assert data._config['version'] == '1.0'
assert tree._get_default_unit_format(data._config) == 'cds'
data = parse(get_pkg_data_filename('data/names.xml'))
assert data._config['version'] == '1.1'
assert tree._get_default_unit_format(data._config) == 'cds'
data = parse(get_pkg_data_filename('data/gemini.xml'))
assert data._config['version'] == '1.2'
assert tree._get_default_unit_format(data._config) == 'cds'
data = parse(get_pkg_data_filename('data/binary2_masked_strings.xml'))
assert data._config['version'] == '1.3'
assert tree._get_default_unit_format(data._config) == 'cds'
data = parse(get_pkg_data_filename('data/timesys.xml'))
assert data._config['version'] == '1.4'
assert tree._get_default_unit_format(data._config) == 'vounit'
def test_namespace_warning():
"""
A version 1.4 VOTable must use the same namespace as 1.3.
(see https://www.ivoa.net/documents/VOTable/20191021/REC-VOTable-1.4-20191021.html#ToC16)
"""
bad_namespace = b'''
'''
with pytest.warns(W41):
parse(io.BytesIO(bad_namespace), verify='exception')
good_namespace_14 = b'''
'''
parse(io.BytesIO(good_namespace_14), verify='exception')
good_namespace_13 = b'''
'''
parse(io.BytesIO(good_namespace_13), verify='exception')
def test_version():
"""
VOTableFile.__init__ allows versions of '1.0', '1.1', '1.2', '1.3' and '1.4'.
The '1.0' is curious since other checks in parse() and the version setter do not allow '1.0'.
This test confirms that behavior for now. A future change may remove the '1.0'.
"""
# Exercise the checks in __init__
with pytest.warns(AstropyDeprecationWarning):
VOTableFile(version='1.0')
for version in ('1.1', '1.2', '1.3', '1.4'):
VOTableFile(version=version)
for version in ('0.9', '2.0'):
with pytest.raises(ValueError, match=r"should be in \('1.0', '1.1', '1.2', '1.3', '1.4'\)."):
VOTableFile(version=version)
# Exercise the checks in the setter
vot = VOTableFile()
for version in ('1.1', '1.2', '1.3', '1.4'):
vot.version = version
for version in ('1.0', '2.0'):
with pytest.raises(ValueError, match=r"supports VOTable versions '1.1', '1.2', '1.3', '1.4'$"):
vot.version = version
# Exercise the checks in the parser.
begin = b''
# Valid versions
for bversion in (b'1.1', b'1.2', b'1.3'):
parse(io.BytesIO(begin + bversion + middle + bversion + end), verify='exception')
parse(io.BytesIO(begin + b'1.4' + middle + b'1.3' + end), verify='exception')
# Invalid versions
for bversion in (b'1.0', b'2.0'):
with pytest.warns(W21):
parse(io.BytesIO(begin + bversion + middle + bversion + end), verify='exception')
def votable_xml_string(version):
votable_file = VOTableFile(version=version)
votable_file.resources.append(Resource())
xml_bytes = io.BytesIO()
votable_file.to_xml(xml_bytes)
xml_bytes.seek(0)
bstring = xml_bytes.read()
s = bstring.decode("utf-8")
return s
def test_votable_tag():
xml = votable_xml_string('1.1')
assert 'xmlns="http://www.ivoa.net/xml/VOTable/v1.1"' in xml
assert 'xsi:noNamespaceSchemaLocation="http://www.ivoa.net/xml/VOTable/v1.1"' in xml
xml = votable_xml_string('1.2')
assert 'xmlns="http://www.ivoa.net/xml/VOTable/v1.2"' in xml
assert 'xsi:noNamespaceSchemaLocation="http://www.ivoa.net/xml/VOTable/v1.2"' in xml
xml = votable_xml_string('1.3')
assert 'xmlns="http://www.ivoa.net/xml/VOTable/v1.3"' in xml
assert 'xsi:schemaLocation="http://www.ivoa.net/xml/VOTable/v1.3 '
assert 'http://www.ivoa.net/xml/VOTable/VOTable-1.3.xsd"' in xml
xml = votable_xml_string('1.4')
assert 'xmlns="http://www.ivoa.net/xml/VOTable/v1.3"' in xml
assert 'xsi:schemaLocation="http://www.ivoa.net/xml/VOTable/v1.3 '
assert 'http://www.ivoa.net/xml/VOTable/VOTable-1.4.xsd"' in xml