rougail/tests/test_others.py

166 lines
6.4 KiB
Python
Raw Normal View History

2021-02-22 19:28:51 +01:00
from pytest import raises
2022-11-02 22:52:50 +01:00
from lxml.etree import DTD
from os.path import isfile
from copy import copy
2021-02-22 19:28:51 +01:00
from rougail import RougailConvert, RougailConfig
from rougail.error import DictConsistencyError
2022-11-03 22:16:52 +01:00
def parse_dtd_subelement(obj_name, content, default_required=False):
2022-11-02 22:52:50 +01:00
if not content:
return
if content.type == 'pcdata':
2022-11-03 22:16:52 +01:00
if obj_name in ['value', 'param']:
type_ = 'any'
else:
type_ = 'str'
yield {'name': 'text', 'type': type_, 'required': False}
2022-11-02 22:52:50 +01:00
elif content.name:
2022-11-03 22:16:52 +01:00
yield {'name': content.name, 'type': None, 'required': default_required}
2022-11-02 22:52:50 +01:00
if content.left:
if content.left.type == 'pcdata':
2022-11-04 19:42:16 +01:00
# choice
yield {'name': 'text', 'type': 'any', 'required': False}
2022-11-02 22:52:50 +01:00
else:
2022-11-03 22:16:52 +01:00
yield {'name': content.left.name, 'type': None, 'required': default_required}
2022-11-02 22:52:50 +01:00
if content.right:
if content.occur == 'once':
if content.right and content.right.name:
2022-11-03 22:16:52 +01:00
yield {'name': content.right.name, 'type': None, 'required': default_required}
2023-01-25 22:48:13 +01:00
else:
yield from parse_dtd_subelement(obj_name, content.right, default_required=False)
2022-11-02 22:52:50 +01:00
elif content.occur == 'mult':
2022-11-03 22:16:52 +01:00
yield from parse_dtd_subelement(obj_name, content.right, default_required=False)
2022-11-02 22:52:50 +01:00
elif content.occur == 'plus':
2022-11-03 22:16:52 +01:00
yield from parse_dtd_subelement(obj_name, content.right, default_required=False)
2022-11-02 22:52:50 +01:00
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
2022-11-02 22:52:50 +01:00
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
2022-11-02 22:52:50 +01:00
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"
2022-11-03 22:16:52 +01:00
if subelt['type']:
schema += " " * subspace + 'type: ' + subelt['type'] + "\n"
2022-11-02 22:52:50 +01:00
if subelt['name'] != 'family' or subspace < 26:
schema += parse_dtd(subelt['name'], elts, subspace)
2023-01-25 22:48:13 +01:00
attributes = {attr.name: attr for attr in elt['elt'].iterattributes()}
for name, dtd_attr in attributes.items():
2022-11-02 22:52:50 +01:00
enum = list(dtd_attr.itervalues())
2022-11-03 22:16:52 +01:00
if set(enum) == {'True', 'False'} or set(enum) == {'True', 'False', 'nil'}:
# it's a boolean
type_ = 'bool'
elif enum == ['unix_permissions']:
2023-01-25 22:48:13 +01:00
continue
elif f'{name}_type' in attributes and list(attributes[f'{name}_type'].itervalues()) == ['unix_permissions']:
2023-01-25 22:48:13 +01:00
type_ = 'int'
2022-11-03 22:16:52 +01:00
else:
type_ = 'str'
2023-01-25 22:48:13 +01:00
schema += " " * space + name + ':\n'
2022-11-02 22:52:50 +01:00
subspace = space + 2
2023-01-25 22:48:13 +01:00
schema += " " * subspace + "type: " + type_ + '\n'
2022-11-02 22:52:50 +01:00
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():
2022-11-03 22:16:52 +01:00
subelts = tuple(parse_dtd_subelement(dtd_elt.name, dtd_elt.content))
2022-11-02 22:52:50 +01:00
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()
2023-01-07 21:39:14 +01:00
assert schema == ori_schema, f'DTD and YAML schema ({RougailConfig["yamlschema_filename"]}) are different'
2022-11-02 22:52:50 +01:00
2021-02-22 19:28:51 +01:00
def test_no_dtd():
cfg = RougailConfig.copy()
cfg['dtdfilename'] = 'notexists.dtd'
with raises(IOError):
eolobj = RougailConvert(cfg)
def test_mode_invalid_default():
2022-10-01 22:27:22 +02:00
# default variable mode is not in modes_level
2021-02-22 19:28:51 +01:00
RougailConfig['dictionaries_dir'] = ['tests/personalize_mode/dictionary']
RougailConfig['modes_level'] = ('level1', 'level2')
2022-10-01 22:27:22 +02:00
eolobj = RougailConvert()
with raises(DictConsistencyError) as err:
eolobj.reflexion()
assert err.value.errno == 72
2021-02-22 19:28:51 +01:00
def test_mode_invalid_default_family():
2022-10-01 22:27:22 +02:00
# default family mode is not in modes_level
2021-02-22 19:28:51 +01:00
RougailConfig['dictionaries_dir'] = ['tests/personalize_mode/dictionary']
RougailConfig['modes_level'] = ('level1', 'level2')
RougailConfig['default_variable_mode'] = 'level1'
2022-10-01 22:27:22 +02:00
eolobj = RougailConvert()
with raises(DictConsistencyError) as err:
eolobj.reflexion()
assert err.value.errno == 73
2021-02-22 19:28:51 +01:00
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():
2022-10-01 22:27:22 +02:00
# a variable has an unknown mode
2021-02-22 19:28:51 +01:00
RougailConfig['dictionaries_dir'] = ['tests/personalize_mode/dictionary']
RougailConfig['modes_level'] = ('level1',)
RougailConfig['default_variable_mode'] = 'level1'
RougailConfig['default_family_mode'] = 'level1'
2022-10-01 22:27:22 +02:00
eolobj = RougailConvert()
with raises(DictConsistencyError) as err:
eolobj.reflexion()
assert err.value.errno == 71