rougail/tests/test_others.py

159 lines
6 KiB
Python

from pytest import raises
from lxml.etree import DTD
from os.path import isfile
from copy import copy
from rougail import RougailConvert, RougailConfig
from rougail.error import DictConsistencyError
def parse_dtd_subelement(obj_name, content, default_required=False):
if not content:
return
if content.type == 'pcdata':
if obj_name in ['value', 'param']:
type_ = 'any'
else:
type_ = 'str'
yield {'name': 'text', 'type': type_, 'required': False}
elif content.name:
yield {'name': content.name, 'type': None, 'required': default_required}
if content.left:
if content.left.type == 'pcdata':
# choice
yield {'name': 'text', 'type': 'any', 'required': False}
else:
yield {'name': content.left.name, 'type': None, 'required': default_required}
if content.right:
if content.occur == 'once':
if content.right and content.right.name:
yield {'name': content.right.name, 'type': None, 'required': default_required}
elif content.occur == 'mult':
yield from parse_dtd_subelement(obj_name, content.right, default_required=False)
elif content.occur == 'plus':
yield from parse_dtd_subelement(obj_name, content.right, default_required=False)
else:
raise Exception('pffff')
def parse_dtd(elt_name, elts, space=0):
elt = elts.get(elt_name)
if not elt:
return ''
schema = ''
if space:
schema += " " * space + "type: seq\n"
schema += " " * space + "sequence:\n"
space = space + 2
schema += " " * space + "- type: map\n"
space = space + 2
schema += " " * space + "mapping:\n"
if elt_name == 'variables':
# type
subspace = space + 2
schema += " " * subspace + "variable:\n"
schema += parse_dtd('variable', elts, subspace + 2)
# variables
if subspace < 50:
schema += " " * subspace + "family:\n"
schema += parse_dtd('family', elts, subspace + 2)
subspace = subspace + 8
schema += " " * subspace + "variables:\n"
schema += parse_dtd(elt_name, elts, subspace + 2)
else:
schema += " " * space + "type: map\n"
schema += " " * space + "mapping:\n"
space = space + 2
if elt_name != 'variables':
if 'subelts' in elt:
for subelt in elt['subelts']:
schema += " " * space + subelt['name'] + ":\n"
subspace = space + 2
schema += " " * subspace + 'required: ' + {False: 'false', True: 'true'}[subelt['required']] + "\n"
if subelt['type']:
schema += " " * subspace + 'type: ' + subelt['type'] + "\n"
if subelt['name'] != 'family' or subspace < 26:
schema += parse_dtd(subelt['name'], elts, subspace)
for dtd_attr in elt['elt'].iterattributes():
schema += " " * space + dtd_attr.name + ':\n'
enum = list(dtd_attr.itervalues())
type_ = 'str'
if set(enum) == {'True', 'False'} or set(enum) == {'True', 'False', 'nil'}:
# it's a boolean
type_ = 'bool'
else:
type_ = 'str'
subspace = space + 2
schema += " " * subspace + "type: " + type_ + '\n'
if type_ != 'bool' and enum:
enumspace = subspace + 2
schema += " " * subspace + 'enum:\n'
for value in enum:
schema += " " * enumspace + '- "' + value + '"\n'
return schema
def test_valid_dtd_schema_equal():
with open(RougailConfig['dtdfilename'], 'r') as dtdfd:
dtd = DTD(dtdfd)
elts = {}
for dtd_elt in dtd.iterelements():
subelts = tuple(parse_dtd_subelement(dtd_elt.name, dtd_elt.content))
ret = {'elt': dtd_elt}
if subelts:
ret['subelts'] = subelts
elts[dtd_elt.name] = ret
schema = parse_dtd('rougail', elts)
if not isfile(RougailConfig['yamlschema_filename']):
with open(RougailConfig['yamlschema_filename'], 'w') as ymldf:
ymldf.write(schema)
with open(RougailConfig['yamlschema_filename'], 'r') as ymldf:
ori_schema = ymldf.read()
assert schema == ori_schema, 'DTD and YAML schema are different'
def test_no_dtd():
cfg = RougailConfig.copy()
cfg['dtdfilename'] = 'notexists.dtd'
with raises(IOError):
eolobj = RougailConvert(cfg)
def test_mode_invalid_default():
# default variable mode is not in modes_level
RougailConfig['dictionaries_dir'] = ['tests/personalize_mode/dictionary']
RougailConfig['modes_level'] = ('level1', 'level2')
eolobj = RougailConvert()
with raises(DictConsistencyError) as err:
eolobj.reflexion()
assert err.value.errno == 72
def test_mode_invalid_default_family():
# default family mode is not in modes_level
RougailConfig['dictionaries_dir'] = ['tests/personalize_mode/dictionary']
RougailConfig['modes_level'] = ('level1', 'level2')
RougailConfig['default_variable_mode'] = 'level1'
eolobj = RougailConvert()
with raises(DictConsistencyError) as err:
eolobj.reflexion()
assert err.value.errno == 73
def test_personalize_mode():
RougailConfig['dictionaries_dir'] = ['tests/personalize_mode/dictionary']
RougailConfig['modes_level'] = ('level1', 'level2')
RougailConfig['default_variable_mode'] = 'level1'
RougailConfig['default_family_mode'] = 'level1'
eolobj = RougailConvert()
eolobj.save(None)
def test_personalize_mode_unknown():
# a variable has an unknown mode
RougailConfig['dictionaries_dir'] = ['tests/personalize_mode/dictionary']
RougailConfig['modes_level'] = ('level1',)
RougailConfig['default_variable_mode'] = 'level1'
RougailConfig['default_family_mode'] = 'level1'
eolobj = RougailConvert()
with raises(DictConsistencyError) as err:
eolobj.reflexion()
assert err.value.errno == 71