You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
372 lines
16 KiB
372 lines
16 KiB
import pytest
|
|
from calculate.vars.alt_datavars import NamespaceNode, VariableNode,\
|
|
Namespace, Variable, Dependence,\
|
|
CyclicVariableError, HashType,\
|
|
StringType, IntegerType, VariableType,\
|
|
VariableError, TableType
|
|
from calculate.utils.files import stderr_devnull
|
|
|
|
|
|
@pytest.mark.alt_vars
|
|
class TestNamespace:
|
|
# Сначала тестируем классы и методы необходимые для построения дерева
|
|
# переменных и пространств имен.
|
|
def test_if_NamespaceNode_just_initialized_with_its_name__the_NamespaceNode_object_contains_empty_namespaces_and_variables_dictionaries_and_fullname_method_returns_only_the_namespace_s_name(self):
|
|
namespace_1 = NamespaceNode('namespace_1')
|
|
|
|
assert namespace_1.namespaces == dict()
|
|
assert namespace_1.variables == dict()
|
|
assert namespace_1.fullname == 'namespace_1'
|
|
|
|
def test_if_namespace_node_added_in_an_other_namespace_node__a_parent_namespace_node_contains_child_namespace_in_its_namespaces_dictionary_and_child_namespace_object_has_parent_namespace_in_its_parent_attribute_and_its_fullname_method_returns_names_of_both_namespaces(self):
|
|
namespace_1 = NamespaceNode('namespace_1')
|
|
namespace_2 = NamespaceNode('namespace_2')
|
|
namespace_1.add_namespace(namespace_2)
|
|
|
|
assert namespace_1.namespaces == {'namespace_2': namespace_2}
|
|
assert namespace_1.variables == dict()
|
|
assert namespace_1.fullname == 'namespace_1'
|
|
|
|
assert namespace_1.namespace_2 == namespace_2
|
|
assert namespace_1['namespace_2'] == namespace_2
|
|
|
|
assert namespace_2.namespaces == dict()
|
|
assert namespace_2.variables == dict()
|
|
assert namespace_2.parent == namespace_1
|
|
assert namespace_2.fullname == 'namespace_1.namespace_2'
|
|
|
|
def test_if_two_VariableNode_objects_are_initialized_and_added_to_a_namespace__the_NamespaceNode_object_contains_this_variables_and_can_be_used_to_get_variables_values_and_variables_have_namespace_name_in_their_fullnames(self):
|
|
namespace_1 = NamespaceNode('namespace_1')
|
|
variable_1 = VariableNode('var_1', namespace_1, source='value_1')
|
|
variable_2 = VariableNode('var_2', namespace_1, source='value_2')
|
|
|
|
assert namespace_1.namespaces == dict()
|
|
assert namespace_1.variables == {'var_1': variable_1,
|
|
'var_2': variable_2}
|
|
assert namespace_1.fullname == 'namespace_1'
|
|
|
|
assert namespace_1.var_1 == 'value_1'
|
|
assert namespace_1['var_1'] == variable_1
|
|
|
|
assert namespace_1.var_2 == 'value_2'
|
|
assert namespace_1['var_2'] == variable_2
|
|
|
|
assert namespace_1['var_1'].fullname == 'namespace_1.var_1'
|
|
assert namespace_1['var_2'].fullname == 'namespace_1.var_2'
|
|
|
|
def test_find_vars(self):
|
|
Namespace.reset()
|
|
datavars = Namespace.datavars
|
|
|
|
with Namespace('namespace_1'):
|
|
Variable('var_1', source='val_1')
|
|
Variable('var_2', source=2, type=IntegerType)
|
|
Variable('var_3', source=4, type=IntegerType)
|
|
|
|
with Namespace('namespace_1_1'):
|
|
Variable('var_1', source='val_1')
|
|
|
|
assert Dependence._find_variable('.var_1') ==\
|
|
datavars.namespace_1.namespace_1_1['var_1']
|
|
assert Dependence._find_variable('..var_3') ==\
|
|
datavars.namespace_1['var_3']
|
|
|
|
with Namespace('namespace_2'):
|
|
assert Dependence._find_variable('namespace_1.var_2') ==\
|
|
datavars.namespace_1['var_2']
|
|
|
|
def test_compare_two_dependencies_equal(self):
|
|
namespace_1 = NamespaceNode('namespace_1')
|
|
variable_1 = VariableNode('var_1', namespace_1, source=2,
|
|
variable_type=IntegerType)
|
|
variable_2 = VariableNode('var_2', namespace_1, source=4,
|
|
variable_type=IntegerType)
|
|
|
|
dependence_1 = Dependence(
|
|
variable_1, variable_2, depend=lambda arg_1, arg_2:
|
|
'greater' if arg_1.value > arg_2.value else 'less')
|
|
|
|
dependence_2 = Dependence(
|
|
variable_1, variable_2, depend=lambda var_1, var_2:
|
|
'greater' if var_1.value > var_2.value else 'less')
|
|
assert dependence_1 == dependence_2
|
|
|
|
def test_compare_two_dependencies_equal_but_one_is_function_and_other_is_lambda(self):
|
|
namespace_1 = NamespaceNode('namespace_1')
|
|
variable_1 = VariableNode('var_1', namespace_1, source=2,
|
|
variable_type=IntegerType)
|
|
variable_2 = VariableNode('var_2', namespace_1, source=4,
|
|
variable_type=IntegerType)
|
|
|
|
dependence_1 = Dependence(
|
|
variable_1, variable_2, depend=lambda arg_1, arg_2:
|
|
'greater' if arg_1.value > arg_2.value else 'less')
|
|
|
|
def comparator(var_1, var_2):
|
|
if var_1.value > var_2.value:
|
|
return 'greater'
|
|
else:
|
|
return 'less'
|
|
dependence_2 = Dependence(variable_1, variable_2, depend=comparator)
|
|
assert dependence_1 == dependence_2
|
|
|
|
def test_compare_two_dependencies_not_equal(self):
|
|
namespace_1 = NamespaceNode('namespace_1')
|
|
variable_1 = VariableNode('var_1', namespace_1, source=2,
|
|
variable_type=IntegerType)
|
|
variable_2 = VariableNode('var_2', namespace_1, source=4,
|
|
variable_type=IntegerType)
|
|
|
|
dependence_1 = Dependence(
|
|
variable_1, variable_2, depend=lambda arg_1, arg_2:
|
|
'less' if arg_1.value > arg_2.value else 'greater')
|
|
|
|
dependence_2 = Dependence(
|
|
variable_1, variable_2, depend=lambda var_1, var_2:
|
|
'greater' if var_1.value > var_2.value else 'less')
|
|
assert dependence_1 != dependence_2
|
|
|
|
def test_compare_two_dependencies_not_equal_but_one_is_function_and_other_is_lambda(self):
|
|
namespace_1 = NamespaceNode('namespace_1')
|
|
variable_1 = VariableNode('var_1', namespace_1, source=2,
|
|
variable_type=IntegerType)
|
|
variable_2 = VariableNode('var_2', namespace_1, source=4,
|
|
variable_type=IntegerType)
|
|
|
|
dependence_1 = Dependence(
|
|
variable_1, variable_2, depend=lambda arg_1, arg_2:
|
|
'greater' if arg_1.value > arg_2.value else 'less')
|
|
|
|
def comparator(var_1, var_2):
|
|
if var_1 > var_2:
|
|
return 'less'
|
|
else:
|
|
return 'greater'
|
|
dependence_2 = Dependence(variable_1, variable_2, depend=comparator)
|
|
assert dependence_1 != dependence_2
|
|
|
|
def test_if_a_variable_subscribed_to_two_other_variables_using_set_function__the_(self):
|
|
namespace_1 = NamespaceNode('namespace_1')
|
|
variable_1 = VariableNode('var_1', namespace_1, source=2,
|
|
variable_type=IntegerType)
|
|
variable_2 = VariableNode('var_2', namespace_1, source=4,
|
|
variable_type=IntegerType)
|
|
|
|
namespace_2 = NamespaceNode('namespace_2')
|
|
variable = VariableNode('var_1', namespace_2)
|
|
variable.source = Dependence(
|
|
variable_1, variable_2, depend=lambda var_1, var_2:
|
|
'greater' if var_1.value > var_2.value else 'less')
|
|
|
|
assert namespace_2.var_1 == 'less'
|
|
|
|
namespace_1['var_1'].source = 5
|
|
assert namespace_2.var_1 == 'greater'
|
|
|
|
# Теперь тестируем интерфейс создания переменных.
|
|
def test_api(self):
|
|
Namespace.reset()
|
|
with Namespace('namespace_1'):
|
|
Variable('var_1', source='val_1')
|
|
|
|
var_2 = Variable('var_2', source=2, type=IntegerType)
|
|
|
|
Variable('var_3', source=4, type=IntegerType)
|
|
|
|
with Namespace('namespace_2'):
|
|
Variable('var_1', source=Dependence(
|
|
var_2, '..namespace_1.var_3', depend=lambda arg_1, arg_2:
|
|
'greater' if arg_1.value > arg_2.value else 'less'))
|
|
with Namespace('namespace_2_1'):
|
|
Variable('var_1', source='val_1')
|
|
|
|
datavars = Namespace.datavars
|
|
assert datavars.namespace_1.var_1 == 'val_1'
|
|
assert datavars.namespace_1.var_2 == 2
|
|
assert datavars.namespace_1.var_3 == 4
|
|
assert datavars.namespace_2.var_1 == 'less'
|
|
assert datavars.namespace_2.namespace_2_1.var_1 == 'val_1'
|
|
|
|
datavars.namespace_1['var_2'].source = 5
|
|
assert datavars.namespace_2.var_1 == 'greater'
|
|
|
|
def test_rewriting_if_source_changed_to_a_value(self):
|
|
Namespace.reset()
|
|
datavars = Namespace.datavars
|
|
|
|
with Namespace('namespace_1'):
|
|
var_1 = Variable('var_1', source='value_1')
|
|
Variable('var_2', source=Dependence(
|
|
var_1, depend=lambda arg_1:
|
|
'from var_1: {}'.format(arg_1.value)))
|
|
assert datavars.namespace_1.var_1 == 'value_1'
|
|
assert datavars.namespace_1.var_2 == 'from var_1: value_1'
|
|
|
|
with Namespace('namespace_1'):
|
|
Variable('var_1', source='value_2')
|
|
|
|
assert datavars.namespace_1.var_1 == 'value_2'
|
|
assert datavars.namespace_1.var_2 == 'from var_1: value_2'
|
|
|
|
def test_rewriting_if_source_changed_to_a_dependence(self):
|
|
Namespace.reset()
|
|
datavars = Namespace.datavars
|
|
|
|
with Namespace('namespace_1'):
|
|
Variable('var_1', source='value_1')
|
|
Variable('var_2', source=Dependence(
|
|
'.var_1', depend=lambda arg_1:
|
|
'from var_1: {}'.format(arg_1.value)))
|
|
Variable('var_3', source='value_3')
|
|
|
|
assert datavars.namespace_1.var_1 == 'value_1'
|
|
assert datavars.namespace_1.var_2 == 'from var_1: value_1'
|
|
|
|
with Namespace('namespace_1'):
|
|
Variable('var_2', source=Dependence(
|
|
'.var_3', depend=lambda arg_1:
|
|
'from var_3: {}'.format(arg_1.value)))
|
|
|
|
assert datavars.namespace_1.var_2 == 'from var_3: value_3'
|
|
|
|
def test_cyclic_dependence(self):
|
|
Namespace.reset()
|
|
datavars = Namespace.datavars
|
|
|
|
with Namespace('namespace_1'):
|
|
Variable('var_1', source='value_1')
|
|
Variable('var_2', source=Dependence(
|
|
'namespace_1.var_1', depend=lambda arg_1:
|
|
'from var_1: {}'.format(arg_1.value)))
|
|
|
|
def comparator(arg_1):
|
|
return 'from var_2: {}'.format(arg_1.value)
|
|
Variable('var_3', source=Dependence('.var_2', depend=comparator))
|
|
Variable('var_1',
|
|
source=Dependence('.var_3', depend=lambda arg_1:
|
|
'from var_3: {}'.format(arg_1.value)))
|
|
|
|
with pytest.raises(CyclicVariableError):
|
|
datavars.namespace_1.var_3
|
|
|
|
def test_hash(self):
|
|
Namespace.reset()
|
|
datavars = Namespace.datavars
|
|
|
|
with Namespace('namespace_1'):
|
|
Variable('var_1', source='value_1', type=StringType)
|
|
Variable('var_2', type=HashType, source={'key_1': 'value_1',
|
|
'key_2': 'value_2'})
|
|
Variable('var_3', source='value_3', type=StringType)
|
|
|
|
def depend_hash(arg_1, arg_2):
|
|
return {'key_1': 'value',
|
|
'key_2': arg_1.value,
|
|
'key_3': arg_2.value}
|
|
Variable('var_4', type=HashType,
|
|
source=Dependence('.var_1', '.var_2.key_1',
|
|
depend=depend_hash))
|
|
|
|
assert datavars.namespace_1.var_2.key_1 == 'value_1'
|
|
assert datavars.namespace_1.var_4.key_1 == 'value'
|
|
assert datavars.namespace_1.var_4.key_2 == 'value_1'
|
|
assert datavars.namespace_1.var_4.key_3 == 'value_1'
|
|
|
|
with Namespace('namespace_1'):
|
|
Variable('var_1', source='other_value', type=StringType)
|
|
Variable('var_2', source={'key_1': 'another_value',
|
|
'key_2': 'value_2'})
|
|
assert datavars.namespace_1.var_2.key_1 == 'another_value'
|
|
assert datavars.namespace_1.var_4.key_2 == 'other_value'
|
|
assert datavars.namespace_1.var_4.key_3 == 'another_value'
|
|
|
|
def test_getting_all_hash_to_depend_function(self):
|
|
Namespace.reset()
|
|
datavars = Namespace.datavars
|
|
|
|
with Namespace('namespace_1'):
|
|
Variable('var_1', source='value_1', type=StringType)
|
|
Variable('var_2', type=HashType, source={'key_1': 'value_1',
|
|
'key_2': 'value_2'})
|
|
Variable('var_3', source='value_3', type=StringType)
|
|
|
|
def depend_hash(arg_1):
|
|
return arg_1.value['key_1']
|
|
Variable('var_4', type=StringType,
|
|
source=Dependence('.var_2', depend=depend_hash))
|
|
|
|
assert datavars.namespace_1.var_4 == 'value_1'
|
|
|
|
def test_readonly(self):
|
|
Namespace.reset()
|
|
datavars = Namespace.datavars
|
|
|
|
with Namespace('namespace_1'):
|
|
Variable('var_1', source='value_1', type=StringType, readonly=True)
|
|
|
|
with Namespace('namespace_1'):
|
|
print('namespace_1:')
|
|
for name, namespace in datavars.namespaces.items():
|
|
print(namespace.fullname)
|
|
for name, variable in datavars.variables.items():
|
|
print(variable.fullname)
|
|
|
|
with pytest.raises(VariableError):
|
|
Variable('var_1', source='value_2', type=StringType)
|
|
|
|
def test_source_function_without_vars(self):
|
|
Namespace.reset()
|
|
datavars = Namespace.datavars
|
|
|
|
with Namespace('namespace_1'):
|
|
def source_function():
|
|
return 'value_from_function'
|
|
Variable('var', source=Dependence(depend=source_function),
|
|
type=VariableType)
|
|
|
|
assert datavars.namespace_1.var == 'value_from_function'
|
|
|
|
def test_source_function_with_dynamic_subscription(self):
|
|
Namespace.reset()
|
|
datavars = Namespace.datavars
|
|
|
|
with Namespace('namespace_1'):
|
|
Variable('var_1', source=5, type=IntegerType)
|
|
Variable('var_2', source='less')
|
|
Variable('var_3', source='greater')
|
|
|
|
def solver(arg_1, arg_2, arg_3):
|
|
if arg_1.value < 6:
|
|
return arg_2.value
|
|
else:
|
|
return arg_3.value
|
|
Variable('var_4', type=StringType,
|
|
source=Dependence('.var_1', '.var_2', '.var_3',
|
|
depend=solver))
|
|
|
|
assert datavars.namespace_1['var_4'].value is None
|
|
|
|
def test_tables(self):
|
|
Namespace.reset()
|
|
# datavars = Namespace.datavars
|
|
|
|
with Namespace('main'):
|
|
Variable('chroot', source='/', type=StringType, readonly=True)
|
|
|
|
with Namespace('os'):
|
|
def source_function(chroot_path):
|
|
from portage.package.ebuild.config import config
|
|
if chroot_path == '/':
|
|
with stderr_devnull():
|
|
return config()
|
|
Variable('config', source=Dependence('main.chroot',
|
|
depend=source_function),
|
|
type=VariableType)
|
|
Variable('var_1', source='value_1', type=StringType)
|
|
Variable('var_2', type=TableType, source=[{'name': 'name_1',
|
|
'value': 'value_1'},
|
|
{'name': 'name_2',
|
|
'value': 'value_2'},
|
|
{'name': 'name_3',
|
|
'value': 'value_3'}])
|