import os import shutil import pytest import logging from calculate.variables.datavars import NamespaceNode, VariableNode,\ Namespace, Variable, Dependence,\ CyclicVariableError, HashType,\ StringType, IntegerType,\ VariableType, VariableError,\ TableType, BooleanType,\ VariableTypeError, FloatType,\ ListType, VariableNotFoundError,\ Copy, Format, Calculate, Static from calculate.templates.template_engine import TemplateEngine, FILE from calculate.templates.template_processor import TemplateExecutor from calculate.variables.loader import NamespaceIniFiller, Datavars from calculate.utils.files import stderr_devnull, read_file TESTFILES_PATH = os.path.join(os.getcwd(), 'tests/variables/testfiles') APPENDS_SET = TemplateExecutor(cl_config_path=os.path.join( TESTFILES_PATH, 'var/lib/calculate/config') ).available_appends class LoggingHandler(logging.Handler): '''Тестовый хэндлер для логгирования в список, который затем можно проверять в тестах.''' def __init__(self, msg_list: list): logging.Handler.__init__(self) # Список для хранения сообщений логгера. self.msg_list = msg_list def emit(self, record): log_record = (record.levelname, record.getMessage()) self.msg_list.append(log_record) @pytest.mark.vars class TestDatavars: # Сначала тестируем классы и методы необходимые для построения дерева # переменных и пространств имен. 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.get_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.get_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.get_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') variable_3 = VariableNode('name', namespace_1, source='name_value') assert namespace_1._namespaces == dict() assert namespace_1._variables == {'var_1': variable_1, 'var_2': variable_2, 'name': variable_3} assert namespace_1.get_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.name == 'name_value' assert namespace_1['name'] == variable_3 assert namespace_1['var_1'].get_fullname() == 'namespace_1.var_1' assert namespace_1['var_2'].get_fullname() == 'namespace_1.var_2' assert namespace_1['name'].get_fullname() == 'namespace_1.name' def test_if_two_dependencies_is_created_with_the_same_variables_and_their_depend_functions_are_equivalent_lambdas__the_dependencies_are_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_if_two_dependencies_is_created_with_the_same_variables_and_their_depend_functions_are_equivalent_lambda_and_function__the_dependencies_are_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') 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_if_two_dependencies_is_created_with_the_same_variables_and_their_depend_functions_are_not_equivalent_lambdas__the_dependencies_are_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_if_two_dependencies_is_created_with_the_same_variables_and_their_depend_functions_are_not_equivalent_lambda_and_function__the_dependencies_are_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') 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_variable_updates_using_the_variables_and_the_set_function_to_calculate_its_value(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_if_variables_creation_api_is_used_for_creating_of_a_number_of_variables_without_any_dependencies_in_their_sources__the_api_fabrics_creates_the_variables(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 datavars.namespace_1.var_1 == 'val_1' assert datavars.namespace_1.var_2 == 2 assert datavars.namespace_1.var_3 == 4 assert datavars.namespace_1.namespace_1_1.var_1 == 'val_1' def test_if_variables_creation_api_is_used_for_creating_of_a_namespace_and_of_a_number_of_variables_and_there_is_attempt_to_get_value_of_an_unexistent_variable_from_a_created_namespace__the_namespace_raises_the_VariableError_exception(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 pytest.raises(VariableError): datavars.namespace_1.var_4 def test_if_dependence_interface_object_is_used_for_finding_an_existing_variable_from_an_other_namespace_using_absolute_variable_name__the_find_variable_method_returns_the_desired_variable(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): Variable('var_1', source='val_1', type=StringType) with Namespace('namespace_2'): assert Dependence._get_variable('namespace_1.var_1') ==\ datavars.namespace_1['var_1'] def test_if_dependence_interface_object_is_used_for_finding_an_unexisting_variable_from_an_other_namespace_using_absolute_variable_name__the_find_variable_method_raises_the_VariableError_exception(self): Namespace.reset() with Namespace('namespace_1'): Variable('var_1', source='val_1', type=StringType) with Namespace('namespace_2'): with pytest.raises(VariableError): Dependence._get_variable('namespace_1.var_2') def test_if_dependence_interface_object_is_used_for_finding_an_existing_variable_from_a_same_namespace_using_relative_variable_name__the_find_variable_method_returns_the_desired_variable(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): Variable('var_1', source='val_1', type=StringType) 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', type=StringType) assert Dependence._get_variable('.var_1') ==\ datavars.namespace_1.namespace_1_1['var_1'] assert Dependence._get_variable('..var_3') ==\ datavars.namespace_1['var_3'] def test_if_dependence_interface_object_is_used_for_finding_an_unexisting_variable_from_a_same_namespace_using_relative_variable_name__the_find_variable_method_raises_the_VariableError_exception(self): Namespace.reset() with Namespace('namespace_1'): Variable('var_1', source='val_1', type=StringType) Variable('var_2', source=2, type=IntegerType) with Namespace('namespace_1_1'): with pytest.raises(VariableError): Dependence._get_variable('..var_3') def test_if_variable_is_created_with_dependence_in_its_source_and_the_dependence_has_only_set_function_without_any_arguments__the_variable_updates_its_value_using_only_set_function(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_if_a_variable_is_created_using_a_Copy_of_a_variable_in_the_source__the_new_variable_uses_this_variable_s_value_to_create_its_own_value(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): Variable('var_1', source='value_1', type=StringType) Variable('var_2', type=StringType, source=Copy('.var_1')) assert datavars.namespace_1.var_2 == 'value_1' def test_if_a_variable_is_created_using_a_Format_with_a_format_string_and_a_variable_in_the_source__the_new_variable_uses_the_variable_and_format_string_to_produce_a_new_string_value(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): Variable('var_1', source='value_1', type=StringType) Variable('var_2', type=StringType, source=Format('var_1 = { .var_1 }')) assert datavars.namespace_1.var_2 == 'var_1 = value_1' def test_if_a_variable_is_created_using_a_Calculate_with_a_variable_and_some_function_in_the_source__the_new_variable_uses_the_variable_and_the_function_for_calculating_of_its_value(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): Variable('var_1', source='value_1', type=StringType) def formatter(var_1): return 'var_1 = {}'.format(var_1.value) Variable('var_2', type=StringType, source=Calculate(formatter, '.var_1')) assert datavars.namespace_1.var_2 == 'var_1 = value_1' def test_if_a_variable_is_created_using_a_Dependence_with_a_static_value_a_variable_and_depend_function_in_the_source__the_new_variable_uses_the_variable_the_function_and_the_static_value_for_calculating_of_its_value(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): def source_function(static_value): return 'static value = {}'.format(static_value.value) Variable('var', type=StringType, source=Dependence(Static('value'), depend=source_function)) assert datavars.namespace_1.var == 'static value = value' def test_if_a_variable_is_created_using_a_Calculate_with_a_static_value_a_variable_and_some_function_in_the_source__the_new_variable_uses_the_variable_the_function_and_the_static_value_for_calculating_of_its_value(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): Variable('var_1', source='var value', type=StringType) def suspicious_function(static_value, var_1): return '{} and {}'.format(static_value.value, var_1.value) Variable('var_2', type=StringType, source=Calculate(suspicious_function, Static('static value'), '.var_1')) assert datavars.namespace_1.var_2 == 'static value and var value' def test_if_a_variable_is_created_using_a_Calculate_with_a_non_string_value_a_variable_and_some_function_in_the_source__the_new_variable_uses_the_variable_the_function_and_the_static_value_for_calculating_of_its_value(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): Variable('var_1', source=10, type=IntegerType) def suspicious_function(static_value, var_1): return static_value.value + var_1.value Variable('var_2', type=IntegerType, source=Calculate(suspicious_function, 12, '.var_1')) assert datavars.namespace_1.var_2 == 22 def test_if_a_variable_is_created_using_dependence_with_three_variables_and_a_set_function_but_during_the_calculation_only_two_variables_was_used__the_unused_variable_is_not_in_variable_subscriptions_and_is_invalidated_before_first_usage(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 == datavars.namespace_1.var_2 assert datavars.namespace_1['var_1'] in\ datavars.namespace_1['var_4']._subscriptions assert datavars.namespace_1['var_2'] in\ datavars.namespace_1['var_4']._subscriptions assert datavars.namespace_1['var_3'] not in\ datavars.namespace_1['var_4']._subscriptions assert datavars.namespace_1['var_3'].value is None def test_if_variables_creation_api_is_used_for_creating_of_a_number_of_variables_with_existing_variables_dependencies_in_their_sources__the_api_fabrics_creates_the_variables(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): var_1 = Variable('var_1', source=2, type=IntegerType) Variable('var_2', source=4, type=IntegerType) with Namespace('namespace_2'): Variable('var_1', source=Dependence( var_1, '..namespace_1.var_2', depend=lambda arg_1, arg_2: 'greater' if arg_1.value > arg_2.value else 'less')) assert datavars.namespace_1.var_1 == 2 assert datavars.namespace_1.var_2 == 4 assert datavars.namespace_2.var_1 == 'less' def test_if_variable_has_variable_dependence_in_its_source_and_the_subscription_variable_source_is_changed__the_subscriber_is_invalidated_and_then_updates_its_value(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): var_1 = Variable('var_1', source=2, type=IntegerType) Variable('var_2', source=4, type=IntegerType) with Namespace('namespace_2'): Variable('var_1', source=Dependence( var_1, '..namespace_1.var_2', depend=lambda arg_1, arg_2: 'greater' if arg_1.value > arg_2.value else 'less')) datavars = Namespace.datavars assert datavars.namespace_2.var_1 == 'less' datavars.namespace_1['var_1'].source = 5 assert datavars.namespace_2['var_1']._invalidated assert datavars.namespace_2.var_1 == 'greater' def test_if_variable_was_created_using_variables_api_and_then_was_created_again_with_simple_source_value__the_variable_just_changes_its_source(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_if_variable_was_created_using_variables_api_and_then_was_created_again_with_a_new_dependency_as_its_source__the_variable_just_changes_its_source_to_the_new_dependency(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_if_some_variables_created_with_dependencies_in_its_sources_and_subscribed_to_each_other__variables_raise_the_CyclicVariableError_exception_while_its_calculating(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_if_variables_with_string_type_is_created_with_correct_source__the_variable_api_creates_this_variables_and_the_variables_contains_strings(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): Variable('var_1', source='value', type=StringType) Variable('var_2', source=2, type=StringType) Variable('var_3', source=False, type=StringType) assert datavars.namespace_1.var_1 == 'value' assert datavars.namespace_1.var_2 == '2' assert datavars.namespace_1.var_3 == 'False' def test_if_variables_with_integer_type_is_created_with_correct_source__the_variable_api_creates_this_variables_and_the_variables_contains_integers(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): Variable('var_1', source=1, type=IntegerType) Variable('var_2', source='2', type=IntegerType) Variable('var_3', source=3.1, type=IntegerType) Variable('var_4', source='-4', type=IntegerType) assert datavars.namespace_1.var_1 == 1 assert datavars.namespace_1.var_2 == 2 assert datavars.namespace_1.var_3 == 3 assert datavars.namespace_1.var_4 == -4 def test_if_variable_with_integer_type_is_created_with_source_that_can_not_be_converted_to_an_integer_value__the_variable_api_raises_the_VariableTypeError_exception(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): Variable('var_1', source='a', type=IntegerType) with pytest.raises(VariableTypeError): datavars.namespace_1.var_1 def test_if_variables_with_float_type_is_created_with_correct_source__the_variable_api_creates_this_variables_and_the_variables_contains_floats(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): Variable('var_1', source=1.1, type=FloatType) Variable('var_2', source='2.2', type=FloatType) Variable('var_3', source=3, type=FloatType) Variable('var_4', source='-4.4', type=FloatType) assert datavars.namespace_1.var_1 == 1.1 assert datavars.namespace_1.var_2 == 2.2 assert datavars.namespace_1.var_3 == 3.0 assert datavars.namespace_1.var_4 == -4.4 def test_if_variable_with_float_type_is_created_with_source_that_can_not_be_converted_to_an_float_value__the_variable_api_raises_the_VariableTypeError_exception(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): Variable('var_1', source='a', type=FloatType) with pytest.raises(VariableTypeError): datavars.namespace_1.var_1 def test_if_variables_with_bool_type_is_created_with_correct_source__the_variable_api_creates_this_variables_and_the_variables_contains_bool(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): Variable('var_1', source=True, type=BooleanType) Variable('var_2', source='false', type=BooleanType) Variable('var_3', source='True', type=BooleanType) Variable('var_4', source='0', type=BooleanType) assert datavars.namespace_1.var_1 is True assert datavars.namespace_1.var_2 is False assert datavars.namespace_1.var_3 is True assert datavars.namespace_1.var_4 is True def test_if_variables_with_list_type_is_created_with_correct_source__the_variable_api_creates_this_variables_and_the_variables_contains_lists(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): Variable('var_1', source=['a', 'b', 'c'], type=ListType) Variable('var_2', source='a, b, c', type=ListType) Variable('var_3', source={'a', 'b', 'c'}, type=ListType) assert datavars.namespace_1.var_1 == ['a', 'b', 'c'] assert datavars.namespace_1.var_2 == ['a', 'b', 'c'] assert datavars.namespace_1.var_3 == list({'a', 'b', 'c'}) def test_if_variable_with_list_type_is_created_with_source_that_can_not_be_converted_to_an_list_value__the_variable_api_raises_the_VariableTypeError_exception(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): Variable('var_1', source=1, type=ListType) with pytest.raises(VariableTypeError): datavars.namespace_1.var_1 def test_if_hash_variable_is_created_with_Hash_type_and_with_a_dictionary_in_its_source__the_variable_is_created_with_Hash_value_in_it(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): Variable('var_1', type=HashType, source={'key_1': 'value_1', 'key_2': 'value_2'}) assert datavars.namespace_1.var_1.key_1 == 'value_1' assert datavars.namespace_1.var_1.key_2 == 'value_2' with Namespace('namespace_1'): Variable('var_1', source={'key_1': 'another_value', 'key_2': 'other_value'}) assert datavars.namespace_1.var_1.key_1 == 'another_value' assert datavars.namespace_1.var_1.key_2 == 'other_value' def test_if_hash_variable_is_created_with_Hash_type_and_with_a_dependence_in_its_source__the_variable_is_created_with_Hash_value_in_it_using_dictionary_returned_by_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, 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_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_if_hash_variable_is_created_as_not_fixed_and_then_changed_using_dictionary_with_a_new_key__the_hash_adds_a_new_key_to_the_first_hash(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): Variable('var_1', type=HashType, source={'key_1': 'value_1', 'key_2': 'value_2'}) assert datavars.namespace_1.var_1.key_1 == 'value_1' assert datavars.namespace_1.var_1.key_2 == 'value_2' with Namespace('namespace_1'): Variable('var_1', source={'key_1': 'another_value', 'key_2': 'other_value', 'key_3': 'new_value'}) assert datavars.namespace_1.var_1.key_1 == 'another_value' assert datavars.namespace_1.var_1.key_2 == 'other_value' assert datavars.namespace_1.var_1.key_3 == 'new_value' def test_if_hash_variable_is_created_as_fixed_and_then_changed_using_dictionary_with_a_new_key__the_hash_raises_the_VariableError_exception(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): Variable('var_1', type=HashType.fixed, source={'key_1': 'value_1', 'key_2': 'value_2'}) assert datavars.namespace_1.var_1.key_1 == 'value_1' assert datavars.namespace_1.var_1.key_2 == 'value_2' with Namespace('namespace_1'): Variable('var_1', source={'key_1': 'another_value', 'key_2': 'other_value', 'key_3': 'new_value'}) assert datavars.namespace_1['var_1'].fixed with pytest.raises(VariableError): datavars.namespace_1.var_1.key_1 def test_if_variable_is_created_with_dependence_and_one_of_arguments_of_a_depend_function_is_whole_hash__the_variable_will_set_this_argument_as_dictionary_of_the_whole_hash_in_a_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_if_a_variable_has_TableType_and_created_using_list_of_dicts_in_its_source_and_other_variable_created_using_depend_function_with_the_first_variable_in_its_arg__the_fitst_variable_is_created_with_Table_value_and_depend_function_of_the_second_variable_can_use_whole_table_for_the_calculating_of_the_variable_s_value(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): Variable('var_1', type=TableType, source=[{'name': 'name_1', 'value': 'value_1'}, {'name': 'name_2', 'value': 'value_2'}, {'name': 'name_3', 'value': 'value_3'}]) def depend_function(table): for row in table.value: if row['name'] == 'name_2': return row['value'] Variable('var_2', type=StringType, source=Dependence('namespace_1.var_1', depend=depend_function)) datavars.namespace_1.var_1[0] print(datavars.namespace_1.var_1[0]) assert datavars.namespace_1.var_2 == 'value_2' def test_if_variable_of_TableType_is_created_using_dependence_that_creates_table__the_created_variable_has_generated_table_as_its_value(self): try: from portage.package.ebuild.config import config value = [{'name': name, 'path': path} for path, name in config().repositories.location_map.items()] Namespace.reset() datavars = Namespace.datavars with Namespace('main'): Variable('chroot', source='/', type=StringType.readonly) with Namespace('os'): def source_function(chroot_path): if chroot_path.value == '/': with stderr_devnull(): return config() Variable('config', source=Dependence('main.chroot', depend=source_function), type=VariableType) def config_source(config): return [{'name': name, 'path': path} for path, name in config.value.repositories.location_map.items()] Variable('repositories', type=TableType, source=Dependence('.config', depend=config_source)) assert datavars.os.repositories.get_table() == value except ImportError: # Если тестируем на другой системе модуль portage будет не найден. assert True # Тестируем теперь заполнитель переменных из calculate.ini def test_if_calculate_ini_file_is_used_just_to_create_some_variables__the_namespace_filler_will_create_them(self): Namespace.reset() datavars = Namespace.datavars namespace_filler = NamespaceIniFiller(restrict_creation=False) calculate_ini_text = """ [os] test = 123 [os][linux] shortname = CLD fullname = Calculate Linux Desktop """ namespace_filler.fill(datavars, calculate_ini_text) assert datavars.os.test == '123' assert datavars.os.linux.shortname == 'CLD' assert datavars.os.linux.fullname == 'Calculate Linux Desktop' def test_if_a_calculate_ini_file_is_used_to_create_some_variables_and_an_other_one_is_used_to_update_value_of_the_variable__the_namespace_filler_creates_them_using_a_first_calculate_ini_and_then_changes_value_using_a_second_calculate_ini(self): Namespace.reset() datavars = Namespace.datavars namespace_filler = NamespaceIniFiller(restrict_creation=False) first_ini_text = """ [os] test = 123 [os][linux] shortname = CLD fullname = Calculate Linux Desktop """ namespace_filler.fill(datavars, first_ini_text) assert datavars.os.test == '123' assert datavars.os.linux.shortname == 'CLD' assert datavars.os.linux.fullname == 'Calculate Linux Desktop' second_ini_text = """ [os][linux] shortname = CLDX """ namespace_filler.fill(datavars, second_ini_text) assert datavars.os.linux.shortname == 'CLDX' def test_if_calculate_ini_file_creates_a_variable_and_then_uses_append_operation_to_append_any_value_to_the_created_variable__the_namespace_filler_appends_the_value_to_the_created_variable(self): Namespace.reset() datavars = Namespace.datavars namespace_filler = NamespaceIniFiller(restrict_creation=False) first_ini_text = """ [os] test = 123 [os] test += 345 """ namespace_filler.fill(datavars, first_ini_text) assert datavars.os.test == "123,345" second_ini_text = """ [os] test += asdf,qwer,zxcv """ namespace_filler.fill(datavars, second_ini_text) assert datavars.os.test == "123,345,asdf,qwer,zxcv" def test_if_calculate_ini_file_creates_a_variable_and_then_uses_remove_operation_to_remove_any_values_in_the_created_variable__the_namespace_filler_removes_the_values_from_the_created_variable(self): Namespace.reset() datavars = Namespace.datavars namespace_filler = NamespaceIniFiller(restrict_creation=False) first_ini_text = """ [os] test = 123,345,asdf,qwer,zxcv """ namespace_filler.fill(datavars, first_ini_text) assert datavars.os.test == "123,345,asdf,qwer,zxcv" second_ini_text = """ [os] test -= 345 """ namespace_filler.fill(datavars, second_ini_text) assert datavars.os.test == "123,asdf,qwer,zxcv" third_ini_text = """ [os] test -= asdf,zxcv """ namespace_filler.fill(datavars, third_ini_text) assert datavars.os.test == "123,qwer" def test_if_calculate_ini_file_is_used_for_creation_variables_in_the_custom_and_some_other_namespaces_and_for_changing_of_a_variable_from_not_custom_namespaces__the_NamespaceIniFiller_object_just_creates_variables_in_the_custom_namespace_and_modifies_variables_from_other_namespaces(self): Namespace.reset() datavars = Namespace.datavars namespace_filler = NamespaceIniFiller() with Namespace('os'): Variable('var_1', type=StringType, source='value_1') Variable('var_2', type=StringType, source='value_2') first_ini_text = """ [os] var_1 = other_value var_3 = value_3 [custom][test_1] var_1 = value_1 [custom][test_2] var_1 = value_1 """ namespace_filler.fill(datavars, first_ini_text) assert datavars.os.var_1 == "other_value" assert 'var_3' not in datavars.os assert datavars.custom.test_1.var_1 == "value_1" assert datavars.custom.test_2.var_1 == "value_1" def test_if_calculate_ini_file_is_used_for_clearing_namespaces_in_the_custom_and_some_other_namespaces__the_NamespaceIniFiller_object_clears_namespaces_only_from_the_custom_namespace(self): Namespace.reset() datavars = Namespace.datavars namespace_filler = NamespaceIniFiller() with Namespace('os'): Variable('var_1', type=StringType, source='value_1') Variable('var_2', type=StringType, source='value_2') first_ini_text = """ [custom][test] var_1 = value_1 var_2 = value_2 """ namespace_filler.fill(datavars, first_ini_text) assert datavars.custom.test.var_1 == 'value_1' assert datavars.custom.test.var_2 == 'value_2' second_ini_text = """ [custom][test][] [os][] """ namespace_filler.fill(datavars, second_ini_text) assert datavars.os.var_1 == 'value_1' assert datavars.os.var_2 == 'value_2' assert 'var_1' not in datavars.custom.test._variables assert 'var_2' not in datavars.custom.test._variables def test_if_calculate_ini_file_contains_some_errors__the_NamespaceIniFiller_object_collect_all_error_messages_to_the_error_attribute(self): Namespace.reset() datavars = Namespace.datavars namespace_filler = NamespaceIniFiller() input_text = '''[section varval1 = value1 varval2 = value2 [section][sub2] varval1 = value1 eee [section2 varval4 = value4 [section][] [section][][sub] [section][][sub][]''' if isinstance(datavars, Datavars): errors = ['SyntaxError:1: [section', 'SyntaxError:2: varval1 = value1', 'SyntaxError:3: varval2 = value2', ("VariableError:4: variables package 'section' is not" " found."), 'SyntaxError:6: eee', 'SyntaxError:8: [section2', ("VariableError:10: can not clear namespace 'section'." " Variables package 'section' is not found."), 'SyntaxError:11: [section][][sub]', 'SyntaxError:12: [section][][sub][]'] else: errors = ['SyntaxError:1: [section', 'SyntaxError:2: varval1 = value1', 'SyntaxError:3: varval2 = value2', ("VariableError:4: can not create namespace" " '.section' in not 'custom' namespace."), 'SyntaxError:6: eee', 'SyntaxError:8: [section2', ("VariableError:10: can not clear namespace 'section'." " Namespace is not found."), 'SyntaxError:11: [section][][sub]', 'SyntaxError:12: [section][][sub][]'] namespace_filler.fill(datavars, input_text) for parsed_error, error in zip(namespace_filler.errors, errors): assert parsed_error == error def test_if_a_variable_is_created_as_readonly_variable_and_there_is_a_try_to_new_value_using_ini_file__the_ini_parser_does_not_change_the_variable_and_sets_variable_error(self): Namespace.reset() datavars = Namespace.datavars namespace_filler = NamespaceIniFiller() with Namespace('os'): Variable('var_1', source='value_1', type=StringType.readonly) Variable('var_2', type=HashType.readonly, source={'key_1': 'value_1', 'key_2': 'value_2'}) first_ini_text = """[os] var_1 = new_value [os][var_2] key_1 = new_value """ namespace_filler.fill(datavars, first_ini_text) assert datavars.os.var_1 == 'value_1' assert datavars.os.var_2.get_hash() == {'key_1': 'value_1', 'key_2': 'value_2'} assert namespace_filler.errors == ["VariableError:2: can not change" " readonly variable 'os.var_1'", "VariableError:5: can not change" " readonly hash variable 'os.var_2'" ] def test_if_calculate_ini_file_is_used_for_changing_of_an_unfixed_hash_variable_created_using_the_variables_api_and_for_adding_of_the_new_key_in_it__the_NamespaceIniFiller_object_changes_hash_value_and_adds_a_new_key(self): Namespace.reset() datavars = Namespace.datavars namespace_filler = NamespaceIniFiller() with Namespace('os'): Variable('var_1', type=HashType, source={'key_1': 'value_1', 'key_2': 'value_2'}) first_ini_text = """ [os][var_1] key_1 = new_value key_3 = value_3 """ namespace_filler.fill(datavars, first_ini_text) assert datavars.os.var_1.get_hash() == {'key_1': 'new_value', 'key_2': 'value_2', 'key_3': 'value_3'} def test_if_calculate_ini_file_is_used_just_for_changing_of_an_fixed_hash_variable_created_using_the_variables_api__the_NamespaceIniFiller_object_changes_hash_value(self): Namespace.reset() datavars = Namespace.datavars namespace_filler = NamespaceIniFiller() with Namespace('os'): Variable('var_1', type=HashType.fixed, source={'key_1': 'value_1', 'key_2': 'value_2'}) first_ini_text = """ [os][var_1] key_1 = new_value key_2 = weird_value """ namespace_filler.fill(datavars, first_ini_text) print('NEW HASH VALUE: {}'.format(datavars.os.var_1.get_hash())) assert datavars.os.var_1.get_hash() == {'key_1': 'new_value', 'key_2': 'weird_value'} def test_if_calculate_ini_file_is_used_just_for_adding_a_new_key_to_an_fixed_hash_variable_created_using_the_variables_api__the_NamespaceIniFiller_object_raises_the_VariableError_exception(self): Namespace.reset() datavars = Namespace.datavars namespace_filler = NamespaceIniFiller() with Namespace('os'): Variable('var_1', type=HashType.fixed, source={'key_1': 'value_1', 'key_2': 'value_2'}) first_ini_text = """ [os][var_1] key_3 = weird_value """ namespace_filler.fill(datavars, first_ini_text) assert datavars.os.var_1.get_hash() == {'key_1': 'value_1', 'key_2': 'value_2'} def test_if_calculate_ini_file_is_used_for_creation_of_the_table_variable_in_the_custom_namespace__the_NamespaceIniFiller_object_creates_table_in_the_custom_namespace(self): Namespace.reset() datavars = Namespace.datavars namespace_filler = NamespaceIniFiller() with Namespace('os'): Variable('var_1', type=StringType, source='value_1') Variable('var_2', type=StringType, source='value_2') first_ini_text = """ [custom][test][0] name = name_0 value = value_0 [custom][test][1] name = name_1 value = value_1 [custom][test][2] name = name_2 value = value_2 """ namespace_filler.fill(datavars, first_ini_text) assert datavars.custom.test.get_table() ==\ [{'name': 'name_0', 'value': 'value_0'}, {'name': 'name_1', 'value': 'value_1'}, {'name': 'name_2', 'value': 'value_2'}] def test_if_calculate_ini_file_is_used_for_creation_of_the_table_variable_in_not_custom_namespaces__the_NamespaceIniFiller_object_does_not_create_anything(self): Namespace.reset() datavars = Namespace.datavars namespace_filler = NamespaceIniFiller() with Namespace('os'): Variable('var_1', type=StringType, source='value_1') Variable('var_2', type=StringType, source='value_2') first_ini_text = """ [os][test][0] name = name_0 value = value_0 [os][test][1] name = name_1 value = value_1 [os][test][2] name = name_2 value = value_2 """ namespace_filler.fill(datavars, first_ini_text) assert 'test' not in datavars.os def test_if_two_tables_are_created_using_calculate_ini_file_and_variables_api_and_then_calculate_ini_file_is_used_for_clearing_and_add_rows_in_the_both_tables__the_NamespaceIniFiller_object_clears_tables_and_adds_rows(self): Namespace.reset() datavars = Namespace.datavars namespace_filler = NamespaceIniFiller() with Namespace('os'): Variable('test', type=TableType, source=[{'name': 'name_1', 'value': 'value_1'}, {'name': 'name_2', 'value': 'value_2'}, {'name': 'name_3', 'value': 'value_3'}]) first_ini_text = """ # Создаем таблицу. [custom][test][0] name = name_0 value = value_0 [custom][test][1] name = name_1 value = value_1 # Очищаем таблицу. [custom][test][] # Добавляем в таблицу строку. [custom][test][0] name = name_0 value = value_0 # Очищаем таблицу созданную интерфейсом. [os][test][] # Добавляем в эту таблицу строку. [os][test][0] name = strange_name value = weird_value """ namespace_filler.fill(datavars, first_ini_text) assert datavars.custom.test.get_table() ==\ [{'name': 'name_0', 'value': 'value_0'}] assert datavars.os.test.get_table() ==\ [{'name': 'strange_name', 'value': 'weird_value'}] def test_if_calculate_ini_file_is_used_for_modifying_of_the_table_from_calculate_ini_file__the_NamespaceIniFiller_object_modifies_the_table(self): Namespace.reset() datavars = Namespace.datavars namespace_filler = NamespaceIniFiller() first_ini_text = """ # Создаем таблицу. [custom][test][0] name = name_0 value = value_0 [custom][test][1] name = name_1 value = value_1 """ namespace_filler.fill(datavars, first_ini_text) assert datavars.custom.test.get_table() ==\ [{'name': 'name_0', 'value': 'value_0'}, {'name': 'name_1', 'value': 'value_1'}] second_ini_text = """ [custom][test][1] name = other_name value = another_value """ namespace_filler.fill(datavars, second_ini_text) assert datavars.custom.test.get_table() ==\ [{'name': 'name_0', 'value': 'value_0'}, {'name': 'other_name', 'value': 'another_value'}] def test_if_calculate_ini_file_is_used_for_modifying_of_the_table_created_using_variables_api__the_NamespaceIniFiller_object_modifies_the_table(self): Namespace.reset() datavars = Namespace.datavars namespace_filler = NamespaceIniFiller() with Namespace('namespace_1'): Variable('test', type=TableType, source=[{'name': 'name_1', 'value': 'value_1'}, {'name': 'name_2', 'value': 'value_2'}, {'name': 'name_3', 'value': 'value_3'}]) first_ini_text = """ [namespace_1][test][0] name = new_name value = other_value [namespace_1][test][1] name = common_name value = another_value """ namespace_filler.fill(datavars, first_ini_text) assert datavars.namespace_1.test.get_table() ==\ [{'name': 'new_name', 'value': 'other_value'}, {'name': 'common_name', 'value': 'another_value'}, {'name': 'name_3', 'value': 'value_3'}] # Теперь тестируем применение объекта Datavars, через который # осуществляется доступ к переменным и их загрузка. def test_if_a_Datavars_object_is_created_with_path_to_the_variables_without_any_Dependencies_and_then_used_to_get_access_to_the_some_variables_from__the_datavars_object_dynamically_loads_variables_and_retruns_necessary_variables(self): datavars = Datavars( variables_path='tests/variables/testfiles/variables_0', repository_map={}) assert datavars.os.ns.var_1 == 'value_1' assert datavars.os.ns.var_2 == 2 assert 'other' not in datavars.root assert datavars.other.strange_variable == 'weird_value' assert datavars.other.plain_variable is True assert 'other' in datavars.root def test_if_a_Datavars_object_is_created_with_path_to_the_variables_with_some_Dependencies_and_then_used_to_get_access_to_the_some_variables_from__the_datavars_object_dynamically_loads_variables_and_retruns_necessary_variables(self): datavars = Datavars( variables_path='tests/variables/testfiles/variables_1', repository_map={}) assert datavars.main.chroot == '/' assert 'os' not in datavars.root assert datavars.os.calculate == 'test1 test2' assert 'os' in datavars.root assert datavars.level.level_2.vargetter == '/ test' assert 'main' in datavars.root assert datavars.level.simple == "simple value" assert datavars.level.use_local_simple == "Using simple value" assert datavars.level.use_full_simple == "Using simple value" assert datavars.level.device_child == "hdd" assert datavars.level.device.get_table() == [ {"dev": "/dev/sda", "type": "hdd", "name": "Samsung SSD"}, {"dev": "/dev/sdb", "type": "flash", "name": "Transcend 64GB"}] def test_if_a_Datavars_object_is_created_with_path_to_the_variables_with_Dependencies_and_then_the_variables_are_changed_using_calculate_ini_files_and_the_datavars_object_used_to_get_access_to_the_some_variables_from__the_datavars_object_dynamically_loads_variables_and_retruns_necessary_variables(self): datavars = Datavars( variables_path='tests/variables/testfiles/variables_4', repository_map={}) assert datavars.main.chroot == '/' assert 'os' not in datavars.root assert datavars.level.level_2.vargetter == '/ test' assert 'main' in datavars.root assert datavars.level.simple == "simple value" datavars._loader.fill_from_custom_ini(os.path.join(TESTFILES_PATH, 'calculate.ini')) assert 'os' in datavars.root assert datavars.level.simple == 'weird value' assert datavars.main.chroot == '/any/other/path' assert datavars.level.level_2.vargetter == '/any/other/path test' def test_to_make_testfiles(self): shutil.copytree(os.path.join(TESTFILES_PATH, 'gentoo.backup'), os.path.join(TESTFILES_PATH, 'gentoo'), symlinks=True) assert os.path.exists(os.path.join(TESTFILES_PATH, 'gentoo')) shutil.copytree(os.path.join(TESTFILES_PATH, 'ini_vars.backup'), os.path.join(TESTFILES_PATH, 'ini_vars')) assert os.path.exists(os.path.join(TESTFILES_PATH, 'ini_vars')) def test_test_if_Datavars_object_is_created_with_a_specific_variables_path_and_repository_map_is_set_and_profile_path_is_set_in_the_variables__the_Datavars_object_finds_all_variables_packages_and_ini_files_from_a_profile_using_the_profile_path_variable_and_the_repository_map(self): repository_map = {'distros': os.path.join(TESTFILES_PATH, "gentoo/repos/distros"), 'calculate': os.path.join(TESTFILES_PATH, "gentoo/repos/calculate"), 'gentoo': os.path.join(TESTFILES_PATH, "gentoo/portage")} datavars = Datavars( variables_path=os.path.join(TESTFILES_PATH, 'variables_2'), repository_map=repository_map) assert datavars.os.linux.shortname == 'CLD' assert datavars.os.linux.fullname == 'Calculate Linux Desktop' assert datavars.os.linux.ver == '20' assert datavars.os.linux.subname == 'KDE' assert datavars.os.linux.arch == 'amd64' assert datavars.os.hashvar.value1 == 'new1' assert datavars.os.hashvar.value2 == 'new2' assert datavars.os.tablevar.get_table() == [ {'dev': '/dev/sda1', 'mount': 'swap'}, {'dev': '/dev/sda2', 'mount': '/'}, {'dev': '/dev/sda5', 'mount': '/var/calculate'}] def test_test_if_Datavars_object_is_created_with_a_specific_variables_path_and_the_repository_map_and_the_current_profile_path_is_set_in_the_variables__the_Datavars_object_finds_all_variables_packages_and_ini_files_from_a_profile_using_the_profile_path_variable_and_the_repositories_variable(self): datavars = Datavars( variables_path=os.path.join(TESTFILES_PATH, 'variables_3')) assert datavars.os.linux.shortname == 'CLD' assert datavars.os.linux.fullname == 'Calculate Linux Desktop' assert datavars.os.linux.ver == '20' assert datavars.os.linux.subname == 'KDE' assert datavars.os.linux.arch == 'amd64' assert datavars.os.hashvar.value1 == 'new1' assert datavars.os.hashvar.value2 == 'new2' assert datavars.os.tablevar.get_table() == [ {'dev': '/dev/sda1', 'mount': 'swap'}, {'dev': '/dev/sda2', 'mount': '/'}, {'dev': '/dev/sda5', 'mount': '/var/calculate'}] def test_test_if_Datavars_object_is_created_with_a_specific_variables_path_and_the_repository_map_the_current_profile_path_and_some_ini_files_paths_is_set_in_the_variables__the_Datavars_object_finds_all_variables_packages_and_ini_files_from_a_profile_using_the_profile_path_variable_and_the_repositories_variable_and_loads_variables_from_ini_files_from_the_env_order_and_the_env_path_variables(self): datavars = Datavars( variables_path=os.path.join(TESTFILES_PATH, 'variables_5')) assert datavars.main.cl.system.env_order == ['system', 'local'] assert datavars.main.cl.system.env_path.get_hash() == { 'system': os.path.join( TESTFILES_PATH, 'ini_vars/calculate_0.ini'), 'local': os.path.join( TESTFILES_PATH, 'ini_vars/calculate_1.ini')} assert datavars.custom.ns.var_1 == '1' assert datavars.custom.ns.var_2 == 'weird value' assert datavars.custom.ns.var_3 ==\ '/the/true/path/to/eternity/in/the/abyss' assert datavars.custom.ns.var_4 == '12' assert datavars.os.linux.test == 'new value' assert datavars.os.linux.test_var == 'test = new value' assert datavars.os.hashvar.value1 == 'new1' assert datavars.os.hashvar.value2 == 'new2' assert datavars.os.calculate == 'new1 new2' def test_if_Datavars_object_is_created_and_all_variables_are_loaded__the_set_method_can_be_used_for_changing_just_variable_s_values_and_save_their_sources_and_the_reset_method_can_return_values_from_source(self): datavars = Datavars( variables_path=os.path.join(TESTFILES_PATH, 'variables_6')) datavars.os.linux['test'].set('other value') datavars.os['hashvar'].set({'value1': 'other1', 'value2': 'other2'}) assert datavars.os.linux['test'].set_by_user assert datavars.os['hashvar'].set_by_user assert datavars.os.linux.test == 'other value' assert datavars.os.hashvar.value1 == 'other1' assert datavars.os.hashvar.value2 == 'other2' assert datavars.os.linux.test_var == 'test = other value' assert datavars.os.calculate == 'other1 other2' datavars.os['calculate'].set('special value') assert datavars.os.calculate == 'special value' datavars.os['hashvar'].set({'value1': 'weird1', 'value2': 'weird2'}) assert datavars.os.hashvar.value1 == 'weird1' assert datavars.os.hashvar.value2 == 'weird2' # При изменении зависимости эта переменная не инвалидируется, потому # что была задана пользователем. Поэтому ее значение установленное set # сохраняется. assert datavars.os.calculate == 'special value' # Если сбросить значения будут пересчитаны, используя установленный # источник значения. datavars.os['calculate'].reset() assert datavars.os.calculate == 'weird1 weird2' datavars.os.linux['test'].reset() assert datavars.os.linux.test == 'new value' datavars.os['hashvar'].reset() assert datavars.os.hashvar.value1 == 'new1' assert datavars.os.hashvar.value2 == 'new2' assert datavars.os.calculate == 'new1 new2' def test_if_Datavars_object_is_created_and_all_variables_are_loaded__the_set_method_can_be_used_for_changing_hash_values_with_saving_of_their_sources(self): datavars = Datavars(variables_path=os.path.join(TESTFILES_PATH, 'variables_6')) datavars.os.hashvar['value1'].set('old but gold') assert datavars.os.hashvar.get_hash() == {'value1': 'old but gold', 'value2': 'new2'} datavars.os['hashvar'].reset() assert datavars.os.hashvar.get_hash() == {'value1': 'new1', 'value2': 'new2'} datavars.os.hashvar['value2'].set('almost blue') assert datavars.os.hashvar.get_hash() == {'value1': 'new1', 'value2': 'almost blue'} datavars.os.hashvar['value2'].reset() assert datavars.os.hashvar.get_hash() == {'value1': 'new1', 'value2': 'new2'} # Теперь тестируем применение объекта Datavars в шаблонах. def test_if_Datavars_object_is_set_as_the_datavars_for_the_TemplateEngine_object__variables_from_the_Datavars_object_can_be_inserted_in_the_processed_template(self): datavars = Datavars( variables_path=os.path.join(TESTFILES_PATH, 'variables_7')) template_engine = TemplateEngine(appends_set=APPENDS_SET, chroot_path=TESTFILES_PATH, datavars_module=datavars) input_template = '''{% calculate name = 'filename', force -%} os.linux.test = {{ os.linux.test }} os.hashvar.value1 = {{ os.hashvar.value1 }} os.hashvar.value2 = {{ os.hashvar.value2 }} os.calculate = {{ os.calculate }}''' output_text = '''os.linux.test = new value os.hashvar.value1 = new1 os.hashvar.value2 = new2 os.calculate = new1 new2''' template_engine.process_template_from_string(input_template, FILE) text = template_engine.template_text assert text == output_text def test_if_Datavars_object_is_set_as_the_datavars_for_the_TemplateEngine_object_and_save_tag_is_used_for_saving_some_variables_and_target_file_is_not_set_for_the_save_tag__the_Datavars_object_saves_and_modifies_variables_from_the_save_tag(self): datavars = Datavars( variables_path=os.path.join(TESTFILES_PATH, 'variables_7')) template_engine = TemplateEngine(appends_set=APPENDS_SET, chroot_path=TESTFILES_PATH, datavars_module=datavars) input_template_1 = '''{% calculate name = 'filename', force -%} {% save custom.ns.value = 12 -%} {% save os.linux.test = 'new value' %} {% save os.hashvar = {'value1': 'weird1', 'value2': 'weird2'} %}''' template_engine.process_template_from_string(input_template_1, FILE) assert datavars.custom.ns.value == '12' assert datavars.os.linux.test == 'new value' assert datavars.os.linux.test_var == 'test = new value' assert datavars.os.hashvar.value1 == 'weird1' assert datavars.os.hashvar.value2 == 'weird2' assert datavars.os.calculate == 'weird1 weird2' input_template_2 = '''{% calculate name = 'filename', force -%} {% save os.hashvar.value1 = 'new1' %}''' template_engine.process_template_from_string(input_template_2, FILE) assert datavars.os.hashvar.value1 == 'new1' assert datavars.os.hashvar.value2 == 'weird2' assert datavars.os.calculate == 'new1 weird2' def test_if_Datavars_object_is_set_as_the_datavars_for_the_TemplateEngine_object_and_save_tag_is_used_for_appending_and_removing_some_variable_s_values_and_target_file_is_not_set_for_the_save_tag__the_Datavars_object_changes_variables_from_the_save_tag(self): datavars = Datavars( variables_path=os.path.join(TESTFILES_PATH, 'variables_8')) template_engine = TemplateEngine(appends_set=APPENDS_SET, chroot_path=TESTFILES_PATH, datavars_module=datavars) input_template_1 = '''{% calculate name = 'filename', force -%} {% save custom.ns.var_1 += 12 -%} {% save os.linux.test_1 += 10 -%} {% save os.linux.test_2 += 12 -%} {% save os.linux.test_3 += 'd' -%} {% save os.linux.test_4 += [4, 5] -%} {% save custom.ns.var_2 += 'val4,val5' -%} ''' template_engine.process_template_from_string(input_template_1, FILE) assert datavars.custom.ns.var_1 == '1,12' assert datavars.os.linux.test_1 == 22 assert datavars.os.linux.test_2 == 13.2 assert datavars.os.linux.test_3 == ['a', 'b', 'c', 'd'] assert datavars.os.linux.test_4 == [1, 2, 3, 4, 5] assert datavars.custom.ns.var_2 == 'val1,val2,val3,val4,val5' input_template_2 = '''{% calculate name = 'filename', force -%} {% save custom.ns.var_1 -= 1 -%} {% save os.linux.test_1 -= 11 -%} {% save os.linux.test_2 -= 2.1 -%} {% save os.linux.test_3 -= 'a' -%} {% save os.linux.test_4 -= [1, 3] -%} {% save custom.ns.var_2 -= 'val1,val4' -%} ''' template_engine.process_template_from_string(input_template_2, FILE) assert datavars.custom.ns.var_1 == '12' assert datavars.os.linux.test_1 == 11 assert datavars.os.linux.test_2 == 11.1 assert datavars.os.linux.test_3 == ['b', 'c', 'd'] assert datavars.os.linux.test_4 == [2, 4, 5] assert datavars.custom.ns.var_2 == 'val2,val3,val5' def test_if_Datavars_object_is_set_as_the_datavars_for_the_TemplateEngine_object_and_save_tag_is_used_for_changing_some_variable_s_values_and_target_file_is_set_for_the_save_tag__the_Datavars_object_creates_new_and_modifies_existing_variables_and_saves_them_to_the_target_files(self): datavars = Datavars( variables_path=os.path.join(TESTFILES_PATH, 'variables_9')) template_engine = TemplateEngine(appends_set=APPENDS_SET, chroot_path=TESTFILES_PATH, datavars_module=datavars) input_template_1 = '''{% calculate name = 'filename', force -%} {% save.local custom.ns.var_3 = 'value' -%} {% save.local custom.ns.var_2 += 'val4' -%} {% save.system custom.ns.var_5 = '/highway/to/hell' -%} ''' local_ini_result = '''[custom][ns] var_1 = 1 var_2 = val1,val2,val3,val4 var_3 = value [os][linux] test_1 += 12 ''' system_ini_result = '''[custom][ns] var_5 = /highway/to/hell var_6 = 12 [os][linux] test = new value ''' template_engine.process_template_from_string(input_template_1, FILE) datavars.save_variables() assert local_ini_result == read_file( datavars.main.cl.system.env_path['local'].value) assert system_ini_result == read_file( datavars.main.cl.system.env_path['system'].value) def test_if_Datavars_object_is_set_as_the_datavars_for_the_TemplateEngine_object_and_save_tag_is_used_for_changing_some_hash_variable_s_values_and_target_file_is_set_for_the_save_tag__the_Datavars_object_modifies_hash_variables_and_saves_them_to_the_target_files_as_namespaces(self): datavars = Datavars( variables_path=os.path.join(TESTFILES_PATH, 'variables_10')) template_engine = TemplateEngine(appends_set=APPENDS_SET, chroot_path=TESTFILES_PATH, datavars_module=datavars) input_template_1 = '''{% calculate name = 'filename', force -%} {% save.system os.hashvar_0 = {'value1': 'new1', 'value2': 'new2'} -%} {% save.system os.hashvar_1.key1 = 'weird1' -%} {% save.system os.hashvar_2.id_1 = 1575 -%} {% save.system os.hashvar_2.id_2 = 1349 -%} ''' system_ini_result = '''[os][hashvar_0] value1 = new1 value2 = new2 [os][hashvar_1] key1 = weird1 [os][hashvar_2] id_1 = 1575 id_2 = 1349 ''' template_engine.process_template_from_string(input_template_1, FILE) datavars.save_variables() assert system_ini_result ==\ read_file(datavars.main.cl.system.env_path['system'].value) # Теперь тестируем обработку ошибок. def test_if_calculate_ini_file_has_some_syntax_errors_in_its_text__loader_skips_incorrect_lines_and_puts_some_error_messages_in_the_output(self): test_messages = [] test_handler = LoggingHandler(test_messages) test_logger = logging.getLogger("test") test_logger.addHandler(test_handler) Datavars(variables_path=os.path.join(TESTFILES_PATH, 'variables_12'), logger=test_logger) messages = [('ERROR', 'SyntaxError:1: [section'), ('ERROR', 'SyntaxError:2: varval1 = value1'), ('ERROR', 'SyntaxError:3: varval2 = value2'), ('ERROR', ("VariableError:4: variables package 'section'" " is not found.")), ('ERROR', 'SyntaxError:6: eee'), ('ERROR', 'SyntaxError:8: [section2'), ('ERROR', ("VariableError:10: can not clear namespace" " 'section'. Variables package 'section' is not" " found.")), ('ERROR', 'SyntaxError:11: [section][][sub]'), ('ERROR', 'SyntaxError:12: [section][][sub][]'), ('WARNING', 'Some variables was not loaded.'), ('INFO', "Variables from 'system' are loaded"), ('INFO', "Loading variables from file: 'local'"), ('WARNING', ("File 'local' is not found. Variables" " are not loaded"))] print('logged messages:', test_messages) for message, datavars_message in zip( messages, test_messages[-len(messages):]): assert message == datavars_message def test_if_any_variables_module_has_syntax_error_in_its_code__the_variables_loader_raises_the_VariableError_exception(self): with pytest.raises(VariableError): Datavars(variables_path=os.path.join(TESTFILES_PATH, 'variables_13')) def test_if_datavars_object_is_used_to_get_access_to_an_unexisting_variable_from_a_not_custom_namespace_and_from_a_custom_namespace__the_datavars_module_raises_the_VariableNotFound_exception_in_the_first_case_and_returns_None_value_in_the_second_case(self): datavars = Datavars(variables_path=os.path.join(TESTFILES_PATH, 'variables_14')) with pytest.raises(VariableNotFoundError): datavars.level.variable assert datavars.custom.variable is None def test_if_some_template_processed_by_the_template_engine_tries_to_get_value_of_a_variable_that_does_not_exist__the_template_engine_raises_the_VariableNotFound_error(self): datavars = Datavars( variables_path=os.path.join(TESTFILES_PATH, 'variables_15')) template_engine = TemplateEngine(appends_set=APPENDS_SET, chroot_path=TESTFILES_PATH, datavars_module=datavars) input_template = '''{% calculate name = 'filename', force -%} os.linux.test_3 = {{ os.linux.test_3 }} ''' with pytest.raises(VariableNotFoundError): template_engine.process_template_from_string(input_template, FILE) def test_two_datavars_objects(self): datavars_1 = Datavars(variables_path=os.path.join(TESTFILES_PATH, 'variables_7')) datavars_2 = Datavars(variables_path=os.path.join(TESTFILES_PATH, 'variables_7')) input_template_1 = '''{% calculate name = 'filename', force -%} {%- save os.linux.test = 'new_first' -%}''' input_template_2 = '''{% calculate name = 'filename', force -%} {%- save os.linux.test = 'new_second' -%}''' template_engine_1 = TemplateEngine(appends_set=APPENDS_SET, chroot_path=TESTFILES_PATH, datavars_module=datavars_1) template_engine_2 = TemplateEngine(appends_set=APPENDS_SET, chroot_path=TESTFILES_PATH, datavars_module=datavars_2) template_engine_1.process_template_from_string(input_template_1, FILE) template_engine_2.process_template_from_string(input_template_2, FILE) assert datavars_1.os.linux.test == 'new_first' assert datavars_2.os.linux.test == 'new_second' def test_adding_some_custom_variables(self): datavars = Datavars( variables_path=os.path.join(TESTFILES_PATH, 'variables_7')) template_engine = TemplateEngine(appends_set=APPENDS_SET, chroot_path=TESTFILES_PATH, datavars_module=datavars) input_template_1 = '''{% calculate run='/bin/bash' -%} {% save custom.qwerty = 'www-firefox,www-chromium' -%} {% save custom.zxcv2.qwerty = 'www-firefox,www-chromium2' -%} {% save custom.zxcv2.qwerty2 = 'www-firefox,www-chromium' -%} echo {{ custom.qwerty }} echo {{ custom.zxcv2.qwerty }} echo {{ custom.zxcv2.qwerty2 }} exit 0 ''' expected_output = '''echo www-firefox,www-chromium echo www-firefox,www-chromium2 echo www-firefox,www-chromium exit 0''' template_engine.process_template_from_string(input_template_1, FILE) result = template_engine.template_text assert result == expected_output def test_vars_with_class_method_as_depend_function(self): datavars = Datavars(variables_path=os.path.join(TESTFILES_PATH, 'variables_7')) assert datavars.main.test_0 == "test_0" assert datavars.main.test_1 == "test_1" def test_for_removing_testfiles(self): shutil.rmtree(os.path.join(TESTFILES_PATH, 'gentoo')) assert not os.path.exists(os.path.join(TESTFILES_PATH, 'gentoo')) shutil.rmtree(os.path.join(TESTFILES_PATH, 'ini_vars')) assert not os.path.exists(os.path.join(TESTFILES_PATH, 'ini_vars')) def test_getting_value_of_the_unexisting_row(self): Namespace.reset() datavars = Namespace.datavars with Namespace('namespace_1'): Variable('var_1', type=TableType, source=[{'name': 'name_1', 'value': 'value_1'}, {'name': 'name_2', 'value': 'value_2'}, {'name': 'name_3', 'value': 'value_3'}]) assert datavars.namespace_1.var_1[3]['value'] is None