Template processing modules and some utils is added.

packages
Иванов Денис 4 years ago
parent 5f675b461a
commit 19cad172fa

@ -10,6 +10,10 @@ except ImportError:
from xml.etree.ElementTree import fromstring from xml.etree.ElementTree import fromstring
class FormatError(Exception):
pass
class BaseFormat(): class BaseFormat():
def __init__(self, processing_methods): def __init__(self, processing_methods):
self._processing_methods = processing_methods self._processing_methods = processing_methods

@ -1,6 +1,7 @@
# vim: fileencoding=utf-8 # vim: fileencoding=utf-8
# #
from calculate.utils.files import Process from calculate.utils.files import Process
from calculate.templates.format.base_format import FormatError
from os import path from os import path
@ -14,21 +15,16 @@ class DiffFormat():
self._changed_files_list = [] self._changed_files_list = []
def execute_format(self, root_path): def execute_format(self, root_path):
print
if path.exists(root_path): if path.exists(root_path):
self._root_path = root_path self._root_path = root_path
else: else:
# Какая-то обработка ошибки. raise FormatError('Root path does not exist.')
error_message = 'Root path does not exist.'
print(error_message)
return False
if self._patch_text: if self._patch_text:
return self._patch_document() return self._patch_document()
else: else:
# Какая-то обработка ошибки. raise FormatError('Empty patch file.')
error_message = 'Empty patch file.'
print(error_message)
return False
def _patch_document(self): def _patch_document(self):
for level in range(0, 4): for level in range(0, 4):
@ -44,19 +40,19 @@ class DiffFormat():
if patch_dry_run.success(): if patch_dry_run.success():
return '' return ''
else: else:
# Какая-то обработка ошибки. raise FormatError('Correction failed.')
error_message = 'Correction failed.'
print(error_message)
return False
self._last_level = level self._last_level = level
patch_run = Process('patch', '-p{}'.format(level), cwd=self._root_path) patch_run = Process('patch', '-p{}'.format(level), cwd=self._root_path)
patch_run.write(self._patch_text) patch_run.write(self._patch_text)
if patch_run.success(): if patch_run.success():
print('patch run is successful...')
for line in patch_run: for line in patch_run:
if line.startswith('patching file'): if line.startswith('patching file'):
self._changed_files_list.append(line[13:].strip()) self._changed_files_list.append(line[13:].strip())
return patch_run.read() return patch_run.read()
else: else:
print('patch run is no successful...')
print(patch_run.read_error())
return '' return ''

@ -44,6 +44,8 @@ class Variables(MutableMapping):
def resolve_or_missing(context, key, missing=missing, env={}): def resolve_or_missing(context, key, missing=missing, env={}):
'''Переопределение функции из для поиска значений переменных из jinja2.
Ищет переменные в datavars.'''
datavars = context.parent['__datavars__'] datavars = context.parent['__datavars__']
if key in context.vars: if key in context.vars:
return context.vars[key] return context.vars[key]
@ -58,6 +60,7 @@ def resolve_or_missing(context, key, missing=missing, env={}):
class CalculateContext(Context): class CalculateContext(Context):
'''Класс контекста позволяющий искать значения datavars и сохранять их.'''
_env_set = set() _env_set = set()
def resolve(self, key): def resolve(self, key):
@ -80,20 +83,20 @@ class CalculateContext(Context):
env=self._env_set) env=self._env_set)
class ConditionFailed(TemplateSyntaxError):
pass
class Parameters(MutableMapping): class Parameters(MutableMapping):
'''Класс для хранения параметров и условий, взятых из шаблона, и передачи '''Класс для хранения параметров, взятых из шаблона, и передачи
их шаблонизатору.''' их шаблонизатору.'''
def __init__(self, parameters_dictionary={}, condition=True): def __init__(self, parameters_dictionary={}):
self.__parameters = parameters_dictionary self.__parameters = parameters_dictionary
self.__condition = condition
def set_parameters(self, *args, **kwargs): def set_parameters(self, *args, **kwargs):
parameters = dict(*args, **kwargs) parameters = dict(*args, **kwargs)
self.__parameters.update(parameters) self.__parameters.update(parameters)
def set_condition(self, condition):
self.__condition = self.__condition and condition
def __getitem__(self, name): def __getitem__(self, name):
return self.__parameters[name] return self.__parameters[name]
@ -110,12 +113,7 @@ class Parameters(MutableMapping):
return len(self.__parameters) return len(self.__parameters)
def __repr__(self): def __repr__(self):
return '<Parameters: {0}, condition={1}>'.format(self.__parameters, return '<Parameters: {0}>'.format(self.__parameters)
self.__condition)
@property
def condition(self):
return self.__condition
@property @property
def parameters(self): def parameters(self):
@ -123,7 +121,9 @@ class Parameters(MutableMapping):
class CalculateExtension(Extension): class CalculateExtension(Extension):
'''Класс расширения для jinja2, поддерживающий теги calculate-шаблонов.'''
_parameters_set = set() _parameters_set = set()
_datavars = Variables()
def __init__(self, environment): def __init__(self, environment):
self.tags = {'calculate', 'save', 'set_var'} self.tags = {'calculate', 'save', 'set_var'}
@ -134,6 +134,8 @@ class CalculateExtension(Extension):
self.parse_methods = {'calculate': self.parse_calculate, self.parse_methods = {'calculate': self.parse_calculate,
'save': self.parse_save} 'save': self.parse_save}
self.environment = environment
def parse(self, parser): def parse(self, parser):
self.parser = parser self.parser = parser
self.stream = parser.stream self.stream = parser.stream
@ -141,6 +143,8 @@ class CalculateExtension(Extension):
return [self.parse_methods[tag_token]()] return [self.parse_methods[tag_token]()]
def parse_save(self): def parse_save(self):
'''Метод для разбора тега save, сохраняющего значение указанной
переменной datavars.'''
lineno = next(self.stream).lineno lineno = next(self.stream).lineno
target_file = nodes.Const('', lineno=lineno) target_file = nodes.Const('', lineno=lineno)
@ -175,9 +179,10 @@ class CalculateExtension(Extension):
lineno=lineno) lineno=lineno)
def parse_calculate(self): def parse_calculate(self):
'''Метод для разбора тега calculate, содержащего значения параметров и
условия выполнения шаблона.'''
pairs_list = [] pairs_list = []
expect_comma_flag = False expect_comma_flag = False
conditions = nodes.Const(True)
lineno = next(self.stream).lineno lineno = next(self.stream).lineno
@ -185,17 +190,22 @@ class CalculateExtension(Extension):
if expect_comma_flag: if expect_comma_flag:
self.stream.expect('comma') self.stream.expect('comma')
if self.stream.current.type == 'name': if (self.stream.current.type == 'name'
if (self.stream.current.value in self._parameters_set and and self.stream.current.value in self._parameters_set
self.stream.look().type != 'dot'): and self.stream.look().type != 'dot'
pairs_list.append(self.get_parameter_node()) and self.stream.look().type not in
else: self.CONDITION_TOKENS_TYPES):
conditions = nodes.And( # разбираем параметр.
self.parser.parse_expression( pairs_list.append(self.get_parameter_node())
with_condexpr=True elif (self.stream.current.type == 'name'
), or self.stream.current.type == 'lparen'):
conditions # разбираем условие. Если условие False -- кидаем исключение.
) condition_result = self.get_condition_result()
if not condition_result:
raise ConditionFailed(
'Condition is failed',
lineno=self.stream.current.lineno
)
else: else:
raise TemplateSyntaxError('Name is expected in calculate tag.', raise TemplateSyntaxError('Name is expected in calculate tag.',
lineno=self.stream.current.lineno) lineno=self.stream.current.lineno)
@ -203,13 +213,47 @@ class CalculateExtension(Extension):
dictionary_node = nodes.Dict(pairs_list) dictionary_node = nodes.Dict(pairs_list)
save_node = self.call_method('save_parameters', save_node = self.call_method('save_parameters',
[dictionary_node, [dictionary_node,
conditions,
nodes.ContextReference()], nodes.ContextReference()],
lineno=lineno) lineno=lineno)
return nodes.Output([save_node], lineno=lineno) return nodes.Output([save_node], lineno=lineno)
def get_condition_result(self):
'''Метод для разбора условий из тега calculate.'''
condition_list = []
# собираем исходный код условия из токенов.
# вероятно, следует придумать лучший способ.
while (self.stream.current.type != 'block_end' and
self.stream.current.type != 'comma'):
if self.stream.current.type == 'string':
condition_list.append("'{}'".format(
self.stream.current.value
))
elif self.stream.current.type == 'dot':
self.stream.skip(1)
if self.stream.current.type == 'name':
next_name = '.' + self.stream.current.value
else:
raise TemplateSyntaxError(
'Variable name is not correct.',
lineno=self.stream.current.lineno
)
condition_list[-1] = condition_list[-1] + next_name
else:
condition_list.append(
str(self.stream.current.value)
)
self.stream.skip(1)
condition = ' '.join(condition_list)
# компилируем исходный код условия и получаем результат его вычисления.
cond_expr = self.environment.compile_expression(condition)
condition_result = cond_expr(__datavars__=self._datavars)
return condition_result
def save_variable(self, variable_name, right_value, target_file, context): def save_variable(self, variable_name, right_value, target_file, context):
'''Временный метод для сохранения значений переменных.''' '''Метод для сохранения значений переменных указанных в теге save.'''
# временная реализация.
datavars = context.parent['__datavars__'] datavars = context.parent['__datavars__']
module_name = variable_name[0] module_name = variable_name[0]
namespaces = variable_name[1:-1] namespaces = variable_name[1:-1]
@ -228,6 +272,7 @@ class CalculateExtension(Extension):
return '' return ''
def get_parameter_node(self): def get_parameter_node(self):
'''Метод для разбра параметров, содержащихся в теге calculate.'''
lineno = self.stream.current.lineno lineno = self.stream.current.lineno
parameter_name = self.stream.expect('name').value parameter_name = self.stream.expect('name').value
parameter_name_node = nodes.Const(parameter_name, lineno=lineno) parameter_name_node = nodes.Const(parameter_name, lineno=lineno)
@ -235,6 +280,8 @@ class CalculateExtension(Extension):
parameter_value = self.stream.current.value parameter_value = self.stream.current.value
parameter_rvalue = self.parser.parse_expression(with_condexpr=True) parameter_rvalue = self.parser.parse_expression(with_condexpr=True)
if parameter_name == 'env': if parameter_name == 'env':
# если параметр env -- обновляем множенство значений env
# контекста вo время парсинга.
env_names = parameter_value.split(',') env_names = parameter_value.split(',')
for name in env_names: for name in env_names:
CalculateContext._env_set.add(name.strip()) CalculateContext._env_set.add(name.strip())
@ -242,18 +289,19 @@ class CalculateExtension(Extension):
parameter_rvalue = nodes.Const(True, lineno=lineno) parameter_rvalue = nodes.Const(True, lineno=lineno)
return nodes.Pair(parameter_name_node, parameter_rvalue) return nodes.Pair(parameter_name_node, parameter_rvalue)
def save_parameters(cls, parameters_dictionary, compare_result, context): def save_parameters(cls, parameters_dictionary, context):
'''Метод для сохранения значений параметров.'''
context.parent['__parameters__'].set_parameters(parameters_dictionary) context.parent['__parameters__'].set_parameters(parameters_dictionary)
context.parent['__parameters__'].set_condition(compare_result)
return '' return ''
class TemplateEngine(): class TemplateEngine:
def __init__(self, directory_path='/', def __init__(self, directory_path='/',
parameters_set=set(), parameters_set=set(),
env_set=set(), env_set=set(),
datavars_module=Variables()): datavars_module=Variables()):
CalculateExtension._parameters_set = parameters_set CalculateExtension._parameters_set = parameters_set
CalculateExtension._datavars = datavars_module
self._datavars_module = datavars_module self._datavars_module = datavars_module
self._parameters_object = Parameters() self._parameters_object = Parameters()
@ -264,32 +312,30 @@ class TemplateEngine():
self.environment.context_class = CalculateContext self.environment.context_class = CalculateContext
def change_directory(self, directory_path): def change_directory(self, directory_path):
'''Метод для смены директории в загрузчике.'''
self.environment.loader = FileSystemLoader(directory_path) self.environment.loader = FileSystemLoader(directory_path)
def process_template(self, template_path, env=set()): def process_template(self, template_path, env=set()):
'''Метод для обработки файла шаблона, расположенного по указанному
пути.'''
CalculateContext._env_set = env CalculateContext._env_set = env
template = self.environment.get_template(template_path) template = self.environment.get_template(template_path)
self._parameters_object = Parameters(parameters_dictionary={}, self._parameters_object = Parameters(parameters_dictionary={})
condition=True)
self._template_text = template.render( self._template_text = template.render(
__datavars__=self._datavars_module, __datavars__=self._datavars_module,
__parameters__=self._parameters_object __parameters__=self._parameters_object
) )
def process_template_from_string(self, string, env=set()): def process_template_from_string(self, string, env=set()):
'''Метод для обработки текста шаблона.'''
CalculateContext._env_set = env CalculateContext._env_set = env
template = self.environment.from_string(string) template = self.environment.from_string(string)
self._parameters_object = Parameters(parameters_dictionary={}, self._parameters_object = Parameters(parameters_dictionary={})
condition=True)
self._template_text = template.render( self._template_text = template.render(
__datavars__=self._datavars_module, __datavars__=self._datavars_module,
__parameters__=self._parameters_object __parameters__=self._parameters_object
) )
@property
def condition(self):
return self._parameters_object.condition
@property @property
def parameters(self): def parameters(self):
return self._parameters_object.parameters return self._parameters_object.parameters

@ -1,9 +1,12 @@
# vim: fileencoding=utf-8 # vim: fileencoding=utf-8
# #
from subprocess import Popen, PIPE from subprocess import Popen, PIPE, STDOUT
from io import TextIOWrapper from io import TextIOWrapper
from os import path from os import path
from .tools import GenericFS, get_traceback_caller
from glob import glob
import os import os
import sys
class FilesError(Exception): class FilesError(Exception):
@ -35,6 +38,9 @@ class KeyboardInputProcess():
class Process(): class Process():
STDOUT = STDOUT
PIPE = PIPE
def __init__(self, command, *parameters, **kwargs): def __init__(self, command, *parameters, **kwargs):
if 'stdin' not in kwargs: if 'stdin' not in kwargs:
self._stdin = PipeProcess() self._stdin = PipeProcess()
@ -54,7 +60,7 @@ class Process():
self._timeout = kwargs.get('timeout', None) self._timeout = kwargs.get('timeout', None)
self._cwd = kwargs.get('cwd', None) self._cwd = kwargs.get('cwd', None)
self._command = _get_program_path(command) self._command = get_program_path(command)
if not self._command: if not self._command:
raise FilesError("command not found '{}'".format(command)) raise FilesError("command not found '{}'".format(command))
self._command = [self._command, *parameters] self._command = [self._command, *parameters]
@ -221,7 +227,7 @@ class Process():
return self.return_code() != 0 return self.return_code() != 0
class ProgramPathCache(): class ProgramPathCache:
def __init__(self): def __init__(self):
self._cache = {} self._cache = {}
@ -246,16 +252,195 @@ class ProgramPathCache():
return False return False
_get_program_path = ProgramPathCache() get_program_path = ProgramPathCache()
def check_utils(*utils):
output = []
for util in utils:
util_path = get_program_path(util)
if not util_path:
raise FilesError("Command not found '{}'".
format(os.path.basename(util)))
output.append(util)
if len(output) == 1:
return output[0]
else:
return output
def join_paths(*paths): def join_paths(*paths):
if len(paths) == 1: if len(paths) == 1:
return next(iter(paths)) return next(iter(paths))
paths_to_join = filter(lambda path: path.strip() and path != "/", paths_to_join = []
map(lambda path: for _path in paths[1:]:
path[1:] if path.startswith('/') else path, if _path.startswith('/'):
paths[1:])) _path = _path.strip()[1:]
else:
_path = _path.strip()
if _path and _path != "/":
paths_to_join.append(_path)
output_path = path.join(paths[0], *paths_to_join) output_path = path.join(paths[0], *paths_to_join)
return output_path return output_path
def read_file(file_path):
try:
if path.exists(file_path):
with open(file_path, 'r') as opened_file:
return opened_file.read()
except (OSError, IOError) as error:
mod, lineno = get_traceback_caller(*sys.exc_info())
sys.stderr.write("WARNING: file read error, {}({}:{})\n".
format(str(error), mod, lineno))
sys.stderr.flush()
return ''
def write_file(file_path):
directory_path = path.dirname(file_path)
if not path.exists(directory_path):
os.makedirs(directory_path)
return open(file_path, 'w')
def read_file_lines(file_name, grab=False):
try:
if path.exists(file_name):
for file_line in open(file_name, 'r'):
if grab:
file_line = file_line.strip()
if not file_line.startswith('#'):
yield file_line
else:
yield file_line.rstrip('\n')
except (OSError, IOError):
pass
finally:
raise StopIteration
def quite_unlink(file_path):
try:
if path.lexists(file_path):
os.unlink(file_path)
except OSError:
pass
def list_directory(directory_path, full_path=False, only_dir=False):
if not path.exists(directory_path):
return []
try:
if full_path:
if only_dir:
return [node.path for node in os.scandir(directory_path)
if os.path.isdir(node.path)]
else:
return [node.path for node in os.scandir(directory_path)]
else:
if only_dir:
return [node.name for node in os.scandir(directory_path)
if os.path.isdir(node.path)]
else:
return os.listdir(directory_path)
except OSError:
return []
def make_directory(directory_path, force=False):
try:
parent = os.path.split(path.normpath(directory_path))[0]
if not path.exists(parent):
make_directory(parent)
else:
if os.path.exists(directory_path):
if force and not os.path.isdir(directory_path):
os.remove(directory_path)
else:
return True
os.mkdir(directory_path)
return True
except (OSError, IOError):
return False
class RealFS(GenericFS):
def __init__(self, prefix='/'):
self.prefix = prefix
if prefix == '/':
self.remove_prefix = lambda x: x
else:
self.remove_prefix = self._remove_prefix
def _remove_prefix(self, file_path):
prefix_length = len(self.prefix)
return file_path[:prefix_length]
def _get_path(self, file_path):
return join_paths(self.prefix, file_path)
def exists(self, file_path):
return os.path.lexists(self._get_path(file_path))
def read(self, file_path):
return read_file(self._get_path(file_path))
def glob(self, file_path):
for glob_path in glob(self._get_path(file_path)):
yield self.remove_prefix(glob_path)
def realpath(self, file_path):
return self.remove_prefix(path.realpath(file_path))
def write(self, file_path, data):
with write_file(file_path) as target_file:
target_file.write(data)
def listdir(self, file_path, full_path=False):
if full_path:
return [self.remove_prefix(listed_path)
for listed_path in list_directory(file_path,
full_path=full_path)]
else:
return list_directory(file_path, full_path=full_path)
def get_run_commands(not_chroot=False, chroot=None, uid=None, with_pid=False):
def get_cmdline(process_number):
cmdline_file = '/proc/{}/cmdline'.format(process_number)
try:
if uid is not None:
fstat = os.stat('/proc/{}'.format(process_number))
if fstat.st_uid != uid:
return ''
if path.exists(cmdline_file):
if not_chroot:
root_link = '/proc/{}/root'.format(process_number)
if os.readlink(root_link) != '/':
return ''
if chroot is not None:
root_link = '/proc/{}/root'.format(process_number)
if os.readlink(root_link) != chroot:
return ''
return read_file(cmdline_file).strip()
except Exception:
pass
return ''
if not os.access('/proc', os.R_OK):
return []
proc_directory = list_directory('/proc')
output = []
for file_name in proc_directory:
if file_name.isdigit():
cmdline = get_cmdline(file_name)
if cmdline:
if with_pid:
output.append((file_name, cmdline))
else:
output.append(cmdline)
return output

@ -2,7 +2,6 @@
# pytest.ini # pytest.ini
[pytest] [pytest]
markers = markers =
vars: marker for running tests for datavars
base: marker for running tests for base format class. base: marker for running tests for base format class.
bind: marker for running tests for bind format. bind: marker for running tests for bind format.
compiz: marker for running tests for compiz format. compiz: marker for running tests for compiz format.
@ -20,5 +19,9 @@ markers =
samba: marker for running tests for samba format. samba: marker for running tests for samba format.
xml_xfce: marker for running tests for xml xfce format. xml_xfce: marker for running tests for xml xfce format.
xml_gconf: marker for running tests for xml gconf format. xml_gconf: marker for running tests for xml gconf format.
files: marker for running tests for calculate.utils.files module. files: marker for running tests for calculate.utils.files module.
template_engine: marker for running tests for template_engine. vars: marker for running tests for datavars
template_engine: marker for running tests for TemplateEngine.
directory_processor: marker for running tests for DirectoryProcessor.
template_action: marker for running tests for TemplateAction.

@ -16,6 +16,8 @@ class TestExecuteMethods:
diff_patch = DiffFormat(patch_text) diff_patch = DiffFormat(patch_text)
print('Path:', root_path) print('Path:', root_path)
output = diff_patch.execute_format(root_path=root_path) output = diff_patch.execute_format(root_path=root_path)
print('Output:')
print(output)
if output: if output:
print('Changed files:') print('Changed files:')
for changed_file in diff_patch._changed_files_list: for changed_file in diff_patch._changed_files_list:

@ -1,5 +1,6 @@
import pytest import pytest
from calculate.templates.template_engine import TemplateEngine, Variables from calculate.templates.template_engine import TemplateEngine, Variables,\
ConditionFailed
PARAMETERS_SET = {'name', 'path', 'append', 'chmod', 'chown', PARAMETERS_SET = {'name', 'path', 'append', 'chmod', 'chown',
@ -11,7 +12,7 @@ PARAMETERS_SET = {'name', 'path', 'append', 'chmod', 'chown',
@pytest.mark.template_engine @pytest.mark.template_engine
class TestUtils(): class TestTemplateEngine():
def test_if_an_input_template_contains_calculate_tag_with_some_parameters__the_template_engine_object_will_collect_its_parameters(self): def test_if_an_input_template_contains_calculate_tag_with_some_parameters__the_template_engine_object_will_collect_its_parameters(self):
input_template = '''{% calculate name = 'filename', path = '/etc/path', force %}''' input_template = '''{% calculate name = 'filename', path = '/etc/path', force %}'''
parameters = {'name': 'filename', 'path': '/etc/path', 'force': True} parameters = {'name': 'filename', 'path': '/etc/path', 'force': True}
@ -48,7 +49,7 @@ class TestUtils():
output_parameters = template_engine.parameters output_parameters = template_engine.parameters
assert output_parameters == parameters assert output_parameters == parameters
def test_if_an_input_template_contains_condition__the_template_engine_object_will_contain_the_value_of_its_condition(self): def test_if_an_input_template_contains_condition_and_it_is_True__the_template_engine_object_will_be_initialized_without_any_exceptions(self):
input_template = '''{% calculate vars.var_1 < vars.var_2 or (not (var_3 == 'required status') and vars.var_4), env = 'vars' %}''' input_template = '''{% calculate vars.var_1 < vars.var_2 or (not (var_3 == 'required status') and vars.var_4), env = 'vars' %}'''
datavars_module = Variables({'vars': datavars_module = Variables({'vars':
Variables({'var_1': 12, Variables({'var_1': 12,
@ -57,14 +58,31 @@ class TestUtils():
'var_4': True})}) 'var_4': True})})
template_engine = TemplateEngine(parameters_set=PARAMETERS_SET, template_engine = TemplateEngine(parameters_set=PARAMETERS_SET,
datavars_module=datavars_module) datavars_module=datavars_module)
template_engine.process_template_from_string(input_template) try:
condition = template_engine.condition template_engine.process_template_from_string(input_template)
assert condition is True except ConditionFailed:
pytest.fail('Unexpected ConditionFailed exception.')
def test_if_an_input_template_contains_several_calculate_tags__the_template_engine_will_parse_them_all_and_will_contain_all_parameters_and_result_of_all_conditions(self): def test_if_an_input_template_contains_several_conditions_and_it_is_False__the_template_engine_raises_ConditionFailed_exception(self):
input_template = '''{% calculate name = vars.var_1, var_4 < var_5 %} input_template = '''{% calculate name = vars.var_1, var_4 < var_5 %}
{% calculate path = var_3, var_6 == 'value' %} {% calculate path = var_3, var_6 == 'value' %}
{% calculate env = 'other_vars'%}''' {% calculate env = 'other_vars'%}'''
datavars_module = Variables({'vars':
Variables({'var_1': 'filename',
'var_2': '/etc/path'}),
'other_vars':
Variables({'var_3': '/etc/other_path',
'var_4': 12, 'var_5': 1.2,
'var_6': 'value'})})
template_engine = TemplateEngine(parameters_set=PARAMETERS_SET,
datavars_module=datavars_module)
with pytest.raises(ConditionFailed):
template_engine.process_template_from_string(input_template)
def test_if_an_input_template_contains_several_calculate_tags__the_template_engine_will_parse_them_all_and_will_contain_all_parameters_and_result_of_all_conditions(self):
input_template = '''{% calculate name = vars.var_1, var_4 > var_5 %}
{% calculate path = var_3, var_6 == 'value' %}
{% calculate env = 'other_vars'%}'''
parameters = {'name': 'filename', 'path': '/etc/other_path', parameters = {'name': 'filename', 'path': '/etc/other_path',
'env': 'other_vars'} 'env': 'other_vars'}
datavars_module = Variables({'vars': datavars_module = Variables({'vars':
@ -77,9 +95,7 @@ class TestUtils():
template_engine = TemplateEngine(parameters_set=PARAMETERS_SET, template_engine = TemplateEngine(parameters_set=PARAMETERS_SET,
datavars_module=datavars_module) datavars_module=datavars_module)
template_engine.process_template_from_string(input_template) template_engine.process_template_from_string(input_template)
condition = template_engine.condition assert template_engine.parameters == parameters
output_parameters = template_engine.parameters
assert condition is False and output_parameters == parameters
def test_if_an_input_template_contains_variables_in_its_text__the_rendered_text_will_contain_values_of_this_variables(self): def test_if_an_input_template_contains_variables_in_its_text__the_rendered_text_will_contain_values_of_this_variables(self):
input_template = '''{% calculate name = 'filename', force -%} input_template = '''{% calculate name = 'filename', force -%}

Loading…
Cancel
Save