class TestHelpers(unittest.TestCase): def tearDown(self): pass def setUp(self): template_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_example_template.odt' ) outname = get_secure_filename() self.reference_template = Template(template_name, outname) os.unlink(outname) def test_move_1(self): """test that siblings are properly moved without keeping boundaries""" template_one_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_one.xml' ) test_template_one = lxml.etree.parse(template_one_name) start = test_template_one.find('mystruct/start') end = test_template_one.find('mystruct/end') new_ = lxml.etree.Element("finishcontainer") move_siblings(start, end, new_) result_s = lxml.etree.tostring( test_template_one, pretty_print=True, ).decode('utf-8') expected_result = open( pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_one_result.xml' ) ).read() expected_result = expected_result.replace( '\n', '').replace(' ', '').strip() result_s = result_s.replace('\n', '').replace(' ', '').strip() assert result_s == expected_result def test_move_2(self): """start.tail is correctly copied without keeping boundaries""" template_two_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_two.xml' ) test_template_two = lxml.etree.parse(template_two_name) start = test_template_two.find('mystruct/start') end = test_template_two.find('mystruct/end') new_ = lxml.etree.Element('finishcontainer') move_siblings(start, end, new_) result_s = lxml.etree.tostring( test_template_two, pretty_print=True, ).decode('utf-8') expected_result = open( pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_two_result.xml' ) ).read() expected_result = expected_result.replace( '\n', '').replace(' ', '').strip() result_s = result_s.replace('\n', '').replace(' ', '').strip() assert result_s == expected_result def test_move_keep_boundaries(self): """test that siblings are properly moved keeping boundaries""" template_three_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_three.xml' ) test_template_three = lxml.etree.parse(template_three_name) start = test_template_three.find('mystruct/start') end = test_template_three.find('mystruct/end') new_ = lxml.etree.Element('finishcontainer') move_siblings( start, end, new_, keep_start_boundary=True, keep_end_boundary=True, ) result_s = lxml.etree.tostring( test_template_three, pretty_print=True, ).decode('utf-8') expected_result = open( pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_three_result.xml' ) ).read() expected_result = expected_result.replace( '\n', '').replace(' ', '').strip() result_s = result_s.replace('\n', '').replace(' ', '').strip() assert result_s == expected_result def test_move_2_keep_boundaries(self): """test that start.tail is correctly copied keeping boundaries""" template_four_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_four.xml' ) test_template_four = lxml.etree.parse(template_four_name) start = test_template_four.find('mystruct/start') end = test_template_four.find('mystruct/end') new_ = lxml.etree.Element('finishcontainer') move_siblings( start, end, new_, keep_start_boundary=True, keep_end_boundary=True, ) result_s = lxml.etree.tostring( test_template_four, pretty_print=True, ).decode('utf-8') expected_result = open( pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_four_result.xml' ) ).read() expected_result = expected_result.replace( '\n', '').replace(' ', '').strip() result_s = result_s.replace('\n', '').replace(' ', '').strip() assert result_s == expected_result def test_get_user_variables(self): source_odt_filename = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_example_template.odt' ) outfilename = get_secure_filename() template = Template(source_odt_filename, outfilename) user_vars = template.get_user_variables() expected_vars = [ 'line.val1', 'line.val2', 'line.val3', 'item.Amount', 'item.Currency', 'item.InvoiceRef', 'document.total', ] assert set(user_vars) == set(expected_vars) def test_convertor(self): source_odt_filename = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_if_parser.odt' ) outfilename = get_secure_filename() template = Template(source_odt_filename, outfilename) user_vars = template.get_user_variables() expressions = template.get_all_user_python_expression() py_expression = template.convert_py3o_to_python_ast(expressions) convertor = Py3oConvertor() data_struct = convertor(py_expression) print(data_struct) assert 'objects' in data_struct objs = data_struct['objects'] assert 'company_label' in objs assert 'name' in objs assert isinstance(objs['company_label'], Py3oName) assert isinstance(objs['name'], Py3oName) # assert data_struct == Py3oModule( # { # 'objects': Py3oArray( # { # 'company_label': Py3oName({}), # 'name': Py3oName({}) # } # ) # } # ) expected_vars = [ 'registration.name', 'registration.company_label', ] assert set(user_vars) == set(expected_vars) def test_get_user_instructions(self): source_odt_filename = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_example_template.odt' ) outfilename = get_secure_filename() template = Template(source_odt_filename, outfilename) user_instructions = template.get_user_instructions() expected_vars = [ 'for="line in items"', '/for', 'for="item in items"', 'if="item.InvoiceRef==\'#1234\'"', '/if', '/for', ] assert set(user_instructions) == set(expected_vars) def test_detect_boundary_false(self): """boundary detection should say no!!""" source_xml_filename = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/keepboundary_detection_false.xml' ) test_xml = lxml.etree.parse(source_xml_filename) starts, ends = self.reference_template.find_instructions( [test_xml], self.reference_template.namespaces ) for start, base in starts: end = ends[id(start)] keep_start, keep_end = detect_keep_boundary( start, end, self.reference_template.namespaces ) assert keep_start is False assert keep_end is False def test_detect_boundary_true(self): """boundary detection should say yes!!""" source_xml_filename = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/keepboundary_detection_true.xml' ) test_xml = lxml.etree.parse(source_xml_filename) starts, ends = self.reference_template.find_instructions( [test_xml], self.reference_template.namespaces ) for index, (start, base) in enumerate(starts): end = ends[id(start)] keep_start, keep_end = detect_keep_boundary( start, end, self.reference_template.namespaces ) if index == 0: assert keep_start is False assert keep_end is True else: assert False, "We should find one single link" def test_move_siblings_1(self): template_xml = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_siblings.xml' ) test_xml = lxml.etree.parse(template_xml) starts, ends = self.reference_template.find_instructions( [test_xml], self.reference_template.namespaces ) assert len(starts) == 1 assert len(ends) == 1 start, _ = starts[0] end = ends[id(start)] keep_start, keep_end = detect_keep_boundary( start, end, self.reference_template.namespaces ) assert keep_start is True assert keep_end is False new_ = lxml.etree.Element('finishcontainer') start_parent = start.getparent() end_parent = end.getparent() start.getparent().remove(start) end.getparent().remove(end) move_siblings( start_parent, end_parent, new_, keep_start_boundary=keep_start, keep_end_boundary=keep_end, ) result_a = lxml.etree.tostring( test_xml, pretty_print=True, ).decode('utf-8') result_e = open( pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_siblings_result_1.xml' ) ).read() result_a = result_a.replace("\n", "").replace(" ", "") result_e = result_e.replace("\n", "").replace(" ", "") assert result_a == result_e def test_move_siblings_2(self): template_xml = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_siblings.xml' ) test_xml = lxml.etree.parse(template_xml) starts, ends = self.reference_template.find_instructions( [test_xml], self.reference_template.namespaces ) assert len(starts) == 1 assert len(ends) == 1 start, base = starts[0] end = ends[id(start)] keep_start, keep_end = detect_keep_boundary( start, end, self.reference_template.namespaces ) assert keep_start is True assert keep_end is False self.reference_template.handle_link(start, base, end) result_a = lxml.etree.tostring( test_xml, pretty_print=True, ).decode('utf-8') result_e = open( pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_siblings_result_2.xml' ) ).read() result_a = result_a.replace("\n", "").replace(" ", "") result_e = result_e.replace("\n", "").replace(" ", "") assert result_a == result_e def test_content_tree_with_child_instruction(self): template_xml = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_example_invalid_template.odt' ) t = Template(template_xml, get_secure_filename()) usr_insts = t.get_user_instructions() assert usr_insts == ['for="item in items"', '/for', 'for="item in items', '2', '"', '/for'] def test_remove_soft_page_breaks(self): template_xml = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_soft_page_break.odt' ) t = Template(template_xml, get_secure_filename()) soft_breaks = get_soft_breaks(t.content_trees[0], t.namespaces) assert len(soft_breaks) > 0 t.remove_soft_breaks() soft_breaks = get_soft_breaks(t.content_trees[0], t.namespaces) assert len(soft_breaks) == 0 t = Template(template_xml, get_secure_filename()) soft_breaks = get_soft_breaks(t.content_trees[0], t.namespaces) assert len(soft_breaks) > 0 t.render(data={"list1": [1, 2, 3]}) soft_breaks = get_soft_breaks(t.content_trees[0], t.namespaces) assert len(soft_breaks) == 0 def test_remove_soft_breaks_without_tail(self): template_xml = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_page_break_without_tail.odt' ) t = Template(template_xml, get_secure_filename()) soft_breaks = get_soft_breaks(t.content_trees[0], t.namespaces) assert len(soft_breaks) > 0 t.remove_soft_breaks() soft_breaks = get_soft_breaks(t.content_trees[0], t.namespaces) assert len(soft_breaks) == 0 t = Template(template_xml, get_secure_filename()) soft_breaks = get_soft_breaks(t.content_trees[0], t.namespaces) assert len(soft_breaks) > 0 t.render(data={"items": [ {'Amount': 3, 'Currency': 'D'}, {'Amount': 2, 'Currency': 'E'}, {'Amount': 1, 'Currency': 'C'}, ]}) soft_breaks = get_soft_breaks(t.content_trees[0], t.namespaces) assert len(soft_breaks) == 0 def __load_and_convert_template(self, path): template_xml = pkg_resources.resource_filename( 'py3o.template', path ) t = Template(template_xml, get_secure_filename()) expressions = t.get_all_user_python_expression() py_expr = t.convert_py3o_to_python_ast(expressions) return py_expr def test_access_global_variable_inside_loop(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_access_global_variable_inside_loop.odt' ) p = Py3oConvertor() res = p(py_expr) user_data = { 'global_var': Mock(val=1), 'my4list': [0, 1, 2, 3], } json_str = res.render(user_data) assert json_str == {'global_var': {'val': 1}} def test_access_in_loop_variable(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_access_in_loop_variable.odt' ) p = Py3oConvertor() res = p(py_expr) user_data = { 'my2list': [0, 1, 2, 3, 4] } json_str = res.render(user_data) assert json_str == {'my2list': [0, 1, 2, 3, 4]} def test_access_global_variable(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_access_global_variable.odt' ) p = Py3oConvertor() res = p(py_expr) user_data = { 'var0': 0, 'var1': 1, 'var2': 2, } json_str = res.render(user_data) assert json_str == {'var0': 0, 'var1': 1, 'var2': 2} def test_iterable_with_global_attribute(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_iterable_with_global_attribute.odt' ) p = Py3oConvertor() res = p(py_expr) user_data = { 'foo': Mock(my2list=[0, 1, 2, 3, 4]) } json_str = res.render(user_data) assert json_str == {'foo': {'my2list': [0, 1, 2, 3, 4]}} def test_two_for_list_on_same_attribute(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_two_for_list_on_same_attribute.odt' ) p = Py3oConvertor() res = p(py_expr) user_data = { 'foo': Mock( my2list=[0, 1, 2, 3, 4], my3list=[5, 6, 7, 8], ) } json_str = res.render(user_data) assert json_str == { 'foo': { 'my2list': [0, 1, 2, 3, 4], 'my3list': [5, 6, 7, 8], } } def test_access_in_loop_variable_with_attribute(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_access_in_loop_variable_with_attribute.odt' ) p = Py3oConvertor() res = p(py_expr) user_data = { 'my3list': [ Mock(val=0), Mock(val=1), Mock(val=2), ] } json_str = res.render(user_data) assert json_str == { 'my3list': [ {'val': 0}, {'val': 1}, {'val': 2}, ] } def test_access_in_loop_variable_with_multiple_attribute(self): py_expr = self.__load_and_convert_template( 'tests/templates/' 'py3o_access_in_loop_variable_with_multiple_attribute.odt' ) p = Py3oConvertor() res = p(py_expr) user_data = { 'my3list': [ Mock(foo=Mock(val=0)), Mock(foo=Mock(val=1)), Mock(foo=Mock(val=2)), ] } json_str = res.render(user_data) assert json_str == { 'my3list': [ {'foo': {'val': 0}}, {'foo': {'val': 1}}, {'foo': {'val': 2}}, ] } def test_access_parent_variable_in_nested_loop(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_access_parent_variable_in_nested_loop.odt' ) p = Py3oConvertor() res = p(py_expr) user_data = { 'my9list': [Mock(val=10), Mock(val=11)] } json_str = res.render(user_data) assert json_str == { 'my9list': [ {'val': 10}, {'val': 11}, ] } def test_access_parent_variable_in_nested_loop_with_attribute(self): py_expr = self.__load_and_convert_template( 'tests/templates/' 'py3o_access_parent_variable_in_nested_loop_with_attribute.odt' ) p = Py3oConvertor() res = p(py_expr) user_data = { 'my10list': [ Mock(my_list=[ Mock(val=10), Mock(val=11), ]), Mock(my_list=[ Mock(val=20), Mock(val=21), Mock(val=22), ]), ] } json_str = res.render(user_data) assert json_str == { 'my10list': [ {'my_list': [ {'val': 10}, {'val': 11}, ]}, {'my_list': [ {'val': 20}, {'val': 21}, {'val': 22}, ]}, ] } def test_access_variable_in_nested_loop(self): py_expr = self.__load_and_convert_template( 'tests/templates/' 'py3o_access_variable_in_nested_loop.odt' ) p = Py3oConvertor() res = p(py_expr) user_data = { 'my8list': [ [10, 11, 12], [20, 21, 22, 23], ] } json_str = res.render(user_data) assert json_str == { 'my8list': [ [10, 11, 12], [20, 21, 22, 23] ] } def test_bad_user_data(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_access_global_variable_inside_loop.odt' ) p = Py3oConvertor() res = p(py_expr) user_data = {} with self.assertRaises(Py3oDataError): res.render(user_data) def test_test_statement(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_test_statement.odt' ) p = Py3oConvertor() res = p(py_expr) user_data = { 'var0': 42, 'myvar': Mock( var0=43, var1='val', ), } json_dict = res.render(user_data) assert json_dict == { 'var0': 42, 'myvar': { 'var0': 43, 'var1': 'val', }, } def test_double_loop_on_same_object(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_double_loop_on_same_object.odt' ) p = Py3oConvertor() res = p(py_expr) user_data = { 'varlist': [ Mock(var0=42, var1=-42), Mock(var0=170, var1=-170), ] } json_dict = res.render(user_data) assert json_dict == { 'varlist': [ {'var0': 42, 'var1': -42}, {'var0': 170, 'var1': -170}, ] } def test_false_value(self): py_expr = self.__load_and_convert_template( 'tests/templates/test_false_value.odt' ) p = Py3oConvertor() res = p(py_expr) false_mock = Mock() false_mock.__nonzero__ = lambda x: False false_mock.__bool__ = lambda x: False user_data = { 'false_value': false_mock, } json_dict = res.render(user_data) assert json_dict == { 'false_value': u'', } # def test_enumerate(self): # #TODO: Make this works # py_expr = self.__load_and_convert_template( # 'tests/templates/py3o_enumerate.odt' # ) # p = Py3oConvertor() # res = p(py_expr) # # user_data = { # 'mylist': [10, 9, 8, 7, 6], # } # json_dict = res.render(user_data) # assert json_dict == { # 'mylist': [10, 9, 8, 7, 6], # } def test_template_function_call(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_template_function_call.odt' ) p = Py3oConvertor() res = p(py_expr) user_data = { 'amount': 32.123, } json_dict = res.render(user_data) assert json_dict == { 'amount': 32.123, } # def test_template_function_call_in_for_loop(self): # py_expr = self.__load_and_convert_template( # 'tests/templates/py3o_template_function_call_in_for_loop.odt' # ) # p = Py3oConvertor() # res = p(py_expr) # user_data = { # 'var': 32.123, # 'test': '2.3', # } # json_dict = res.render(user_data) # assert json_dict == { # 'var': 32.123, # 'test': '2.3', # } # Tes if function def test_if(self): expressions = [ 'if="item.mytest"', 'item.myvar', 'item.myvar2', '/if', ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({ 'item': Mock(mytest=0, myvar=1, myvar2=2), }) assert json_dict == { 'item': {'mytest': 0, 'myvar': 1, 'myvar2': 2}, } def test_if_global(self): expressions = [ 'if="mytest"', 'item.myvar', 'item.myvar2', '/if', ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({ 'item': Mock(myvar=1, myvar2=2), 'mytest': 0 }) assert json_dict == { 'mytest': 0, 'item': {'myvar': 1, 'myvar2': 2}, } def test_if_global_array(self): expressions = [ 'for="var in myarray"', 'if="var"', 'var', '/if', '/for', ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({ 'myarray': list(range(0, 5)), }) assert json_dict == { 'myarray': list(range(0, 5)), } def test_if_in_for(self): expressions = [ 'for="item in object.mylist"', 'if="item.mytest"', 'item.myvar', 'item.myvar2', '/if', '/for', ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({ 'object': Mock(mylist=[ Mock(mytest=0, myvar=1, myvar2=2), Mock(mytest=3, myvar=4, myvar2=5), Mock(mytest=6, myvar=7, myvar2=8), ]) }) assert json_dict == { 'object': { 'mylist': [ {'mytest': 0, 'myvar': 1, 'myvar2': 2}, {'mytest': 3, 'myvar': 4, 'myvar2': 5}, {'mytest': 6, 'myvar': 7, 'myvar2': 8}, ] } } def test_if_comparator(self): expressions = [ 'if="a in b"', '/if' ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({ 'a': 1, 'b': [0, 1, 2], }) assert json_dict == { 'a': 1, 'b': [0, 1, 2], } # Test function def test_function_in_for(self): expressions = [ 'for="item in object.mylist"', 'format_date(item.date)', '/for', ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({ 'object': Mock(mylist=[ Mock(date='2015-12-13'), Mock(date='2015-12-14'), Mock(date='2015-12-15'), ]) }) assert json_dict == { 'object': { 'mylist': [ {'date': '2015-12-13'}, {'date': '2015-12-14'}, {'date': '2015-12-15'}, ] } } def test_function_keywords(self): expressions = [ 'myfunc(object.var, k=object.k)', ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({ 'object': Mock(var=0, k=1), }) assert json_dict == { 'object': {'var': 0, 'k': 1} } def test_function_array(self): expressions = [ 'for="var in myarray"', 'myfunc(var)', '/for' ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({ 'myarray': [0, 1, 2, 3], }) assert json_dict == { 'myarray': [0, 1, 2, 3], }
class TestHelpers(unittest.TestCase): def tearDown(self): pass def setUp(self): template_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_example_template.odt') outname = get_secure_filename() self.reference_template = Template(template_name, outname) os.unlink(outname) def test_move_1(self): """test that siblings are properly moved without keeping boundaries""" template_one_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_one.xml') test_template_one = lxml.etree.parse(template_one_name) start = test_template_one.find('mystruct/start') end = test_template_one.find('mystruct/end') new_ = lxml.etree.Element("finishcontainer") move_siblings(start, end, new_) result_s = lxml.etree.tostring( test_template_one, pretty_print=True, ).decode('utf-8') expected_result = open( pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_one_result.xml')).read() expected_result = expected_result.replace('\n', '').replace(' ', '').strip() result_s = result_s.replace('\n', '').replace(' ', '').strip() assert result_s == expected_result def test_move_2(self): """start.tail is correctly copied without keeping boundaries""" template_two_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_two.xml') test_template_two = lxml.etree.parse(template_two_name) start = test_template_two.find('mystruct/start') end = test_template_two.find('mystruct/end') new_ = lxml.etree.Element('finishcontainer') move_siblings(start, end, new_) result_s = lxml.etree.tostring( test_template_two, pretty_print=True, ).decode('utf-8') expected_result = open( pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_two_result.xml')).read() expected_result = expected_result.replace('\n', '').replace(' ', '').strip() result_s = result_s.replace('\n', '').replace(' ', '').strip() assert result_s == expected_result def test_move_keep_boundaries(self): """test that siblings are properly moved keeping boundaries""" template_three_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_three.xml') test_template_three = lxml.etree.parse(template_three_name) start = test_template_three.find('mystruct/start') end = test_template_three.find('mystruct/end') new_ = lxml.etree.Element('finishcontainer') move_siblings( start, end, new_, keep_start_boundary=True, keep_end_boundary=True, ) result_s = lxml.etree.tostring( test_template_three, pretty_print=True, ).decode('utf-8') expected_result = open( pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_three_result.xml')).read() expected_result = expected_result.replace('\n', '').replace(' ', '').strip() result_s = result_s.replace('\n', '').replace(' ', '').strip() assert result_s == expected_result def test_move_2_keep_boundaries(self): """test that start.tail is correctly copied keeping boundaries""" template_four_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_four.xml') test_template_four = lxml.etree.parse(template_four_name) start = test_template_four.find('mystruct/start') end = test_template_four.find('mystruct/end') new_ = lxml.etree.Element('finishcontainer') move_siblings( start, end, new_, keep_start_boundary=True, keep_end_boundary=True, ) result_s = lxml.etree.tostring( test_template_four, pretty_print=True, ).decode('utf-8') expected_result = open( pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_four_result.xml')).read() expected_result = expected_result.replace('\n', '').replace(' ', '').strip() result_s = result_s.replace('\n', '').replace(' ', '').strip() assert result_s == expected_result def test_get_user_variables(self): source_odt_filename = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_example_template.odt') outfilename = get_secure_filename() template = Template(source_odt_filename, outfilename) user_vars = template.get_user_variables() expected_vars = [ 'line.val1', 'line.val2', 'line.val3', 'item.Amount', 'item.Currency', 'item.InvoiceRef', 'document.total', ] assert set(user_vars) == set(expected_vars) def test_convertor(self): source_odt_filename = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_if_parser.odt') outfilename = get_secure_filename() template = Template(source_odt_filename, outfilename) user_vars = template.get_user_variables() expressions = template.get_all_user_python_expression() py_expression = template.convert_py3o_to_python_ast(expressions) convertor = Py3oConvertor() data_struct = convertor(py_expression) assert 'objects' in data_struct objs = data_struct['objects'] assert 'company_label' in objs assert 'name' in objs assert isinstance(objs['company_label'], Py3oName) assert isinstance(objs['name'], Py3oName) # assert data_struct == Py3oModule( # { # 'objects': Py3oArray( # { # 'company_label': Py3oName({}), # 'name': Py3oName({}) # } # ) # } # ) expected_vars = [ 'registration.name', 'registration.company_label', ] assert set(user_vars) == set(expected_vars) def test_get_user_instructions(self): source_odt_filename = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_example_template.odt') outfilename = get_secure_filename() template = Template(source_odt_filename, outfilename) user_instructions = template.get_user_instructions() expected_vars = [ 'for="line in items"', '/for', 'for="item in items"', 'if="item.InvoiceRef==\'#1234\'"', '/if', '/for', ] assert set(user_instructions) == set(expected_vars) def test_calc(self): """Test date source extraction in ods files""" source_ods_filename = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_simple_calc.ods') outfilename = get_secure_filename() template = Template(source_ods_filename, outfilename) expressions = template.get_all_user_python_expression() expected_expressions = [ 'for="item in items"', 'item.col1', 'item.col2', 'item.col3', 'item.col4', '/for', ] self.assertEqual(expressions, expected_expressions) py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) user_data = { 'items': [ Mock(col0='0', col1=1, col2=2.0, col3='?', col4='!'), Mock(col0=0, col1=1.0, col2='2', col3='?', col4='!'), Mock(col0=0.0, col1='1', col2=2, col3='?', col4='!'), ] } json_dict = res.render(user_data) self.assertEqual( json_dict, { 'items': [ dict(col1=1, col2=2.0, col3='?', col4='!'), dict(col1=1.0, col2='2', col3='?', col4='!'), dict(col1='1', col2=2, col3='?', col4='!'), ] }) def test_detect_boundary_false(self): """boundary detection should say no!!""" source_xml_filename = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/keepboundary_detection_false.xml') test_xml = lxml.etree.parse(source_xml_filename) starts, ends = self.reference_template.find_instructions( [test_xml], self.reference_template.namespaces) for start, base in starts: end = ends[id(start)] keep_start, keep_end = detect_keep_boundary( start, end, self.reference_template.namespaces) assert keep_start is False assert keep_end is False def test_detect_boundary_true(self): """boundary detection should say yes!!""" source_xml_filename = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/keepboundary_detection_true.xml') test_xml = lxml.etree.parse(source_xml_filename) starts, ends = self.reference_template.find_instructions( [test_xml], self.reference_template.namespaces) for index, (start, base) in enumerate(starts): end = ends[id(start)] keep_start, keep_end = detect_keep_boundary( start, end, self.reference_template.namespaces) if index == 0: assert keep_start is False assert keep_end is True else: assert False, "We should find one single link" def test_move_siblings_1(self): template_xml = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_siblings.xml') test_xml = lxml.etree.parse(template_xml) starts, ends = self.reference_template.find_instructions( [test_xml], self.reference_template.namespaces) assert len(starts) == 1 assert len(ends) == 1 start, _ = starts[0] end = ends[id(start)] keep_start, keep_end = detect_keep_boundary( start, end, self.reference_template.namespaces) assert keep_start is True assert keep_end is False new_ = lxml.etree.Element('finishcontainer') start_parent = start.getparent() end_parent = end.getparent() start.getparent().remove(start) end.getparent().remove(end) move_siblings( start_parent, end_parent, new_, keep_start_boundary=keep_start, keep_end_boundary=keep_end, ) result_a = lxml.etree.tostring( test_xml, pretty_print=True, ).decode('utf-8') result_e = open( pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_siblings_result_1.xml')).read() result_a = result_a.replace("\n", "").replace(" ", "") result_e = result_e.replace("\n", "").replace(" ", "") assert result_a == result_e def test_move_siblings_2(self): template_xml = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_siblings.xml') test_xml = lxml.etree.parse(template_xml) starts, ends = self.reference_template.find_instructions( [test_xml], self.reference_template.namespaces) assert len(starts) == 1 assert len(ends) == 1 start, base = starts[0] end = ends[id(start)] keep_start, keep_end = detect_keep_boundary( start, end, self.reference_template.namespaces) assert keep_start is True assert keep_end is False self.reference_template.handle_link(start, base, end) result_a = lxml.etree.tostring( test_xml, pretty_print=True, ).decode('utf-8') result_e = open( pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_siblings_result_2.xml')).read() result_a = result_a.replace("\n", "").replace(" ", "") result_e = result_e.replace("\n", "").replace(" ", "") assert result_a == result_e def test_content_tree_with_child_instruction(self): template_xml = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_example_invalid_template.odt') t = Template(template_xml, get_secure_filename()) usr_insts = t.get_user_instructions() assert usr_insts == [ 'for="item in items"', '/for', 'for="item in items', '2', '"', '/for' ] def __load_and_convert_template(self, path): template_xml = pkg_resources.resource_filename('py3o.template', path) t = Template(template_xml, get_secure_filename()) expressions = t.get_all_user_python_expression() py_expr = t.convert_py3o_to_python_ast(expressions) return py_expr def test_access_global_variable_inside_loop(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_access_global_variable_inside_loop.odt') p = Py3oConvertor() res = p(py_expr) user_data = { 'global_var': Mock(val=1), 'my4list': [0, 1, 2, 3], } json_str = res.render(user_data) self.assertEquals(json_str, { 'global_var': dict(val=1), 'my4list': [0, 1, 2, 3], }) def test_access_in_loop_variable(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_access_in_loop_variable.odt') p = Py3oConvertor() res = p(py_expr) user_data = {'my2list': [0, 1, 2, 3, 4]} json_str = res.render(user_data) assert json_str == {'my2list': [0, 1, 2, 3, 4]} def test_access_global_variable(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_access_global_variable.odt') p = Py3oConvertor() res = p(py_expr) user_data = { 'var0': 0, 'var1': 1, 'var2': 2, } json_str = res.render(user_data) assert json_str == {'var0': 0, 'var1': 1, 'var2': 2} def test_iterable_with_global_attribute(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_iterable_with_global_attribute.odt') p = Py3oConvertor() res = p(py_expr) user_data = {'foo': Mock(my2list=[0, 1, 2, 3, 4])} json_str = res.render(user_data) assert json_str == {'foo': {'my2list': [0, 1, 2, 3, 4]}} def test_two_for_list_on_same_attribute(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_two_for_list_on_same_attribute.odt') p = Py3oConvertor() res = p(py_expr) user_data = { 'foo': Mock( my2list=[0, 1, 2, 3, 4], my3list=[5, 6, 7, 8], ) } json_str = res.render(user_data) assert json_str == { 'foo': { 'my2list': [0, 1, 2, 3, 4], 'my3list': [5, 6, 7, 8], } } def test_access_in_loop_variable_with_attribute(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_access_in_loop_variable_with_attribute.odt') p = Py3oConvertor() res = p(py_expr) user_data = { 'my3list': [ Mock(val=0), Mock(val=1), Mock(val=2), ] } json_str = res.render(user_data) assert json_str == { 'my3list': [ { 'val': 0 }, { 'val': 1 }, { 'val': 2 }, ] } def test_access_in_loop_variable_with_multiple_attribute(self): py_expr = self.__load_and_convert_template( 'tests/templates/' 'py3o_access_in_loop_variable_with_multiple_attribute.odt') p = Py3oConvertor() res = p(py_expr) user_data = { 'my3list': [ Mock(foo=Mock(val=0)), Mock(foo=Mock(val=1)), Mock(foo=Mock(val=2)), ] } json_str = res.render(user_data) assert json_str == { 'my3list': [ { 'foo': { 'val': 0 } }, { 'foo': { 'val': 1 } }, { 'foo': { 'val': 2 } }, ] } def test_access_parent_variable_in_nested_loop(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_access_parent_variable_in_nested_loop.odt') p = Py3oConvertor() res = p(py_expr) user_data = {'my9list': [Mock(val=10), Mock(val=11)]} json_str = res.render(user_data) assert json_str == { 'my9list': [ { 'val': 10 }, { 'val': 11 }, ] } def test_access_parent_variable_in_nested_loop_with_attribute(self): py_expr = self.__load_and_convert_template( 'tests/templates/' 'py3o_access_parent_variable_in_nested_loop_with_attribute.odt') p = Py3oConvertor() res = p(py_expr) user_data = { 'my10list': [ Mock(my_list=[ Mock(val=10), Mock(val=11), ]), Mock(my_list=[ Mock(val=20), Mock(val=21), Mock(val=22), ]), ] } json_str = res.render(user_data) assert json_str == { 'my10list': [ { 'my_list': [ { 'val': 10 }, { 'val': 11 }, ] }, { 'my_list': [ { 'val': 20 }, { 'val': 21 }, { 'val': 22 }, ] }, ] } def test_access_variable_in_nested_loop(self): py_expr = self.__load_and_convert_template( 'tests/templates/' 'py3o_access_variable_in_nested_loop.odt') p = Py3oConvertor() res = p(py_expr) user_data = { 'my8list': [ [10, 11, 12], [20, 21, 22, 23], ] } json_str = res.render(user_data) assert json_str == {'my8list': [[10, 11, 12], [20, 21, 22, 23]]} def test_bad_user_data(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_access_global_variable_inside_loop.odt') p = Py3oConvertor() res = p(py_expr) user_data = {} with self.assertRaises(Py3oDataError): res.render(user_data) def test_test_statement(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_test_statement.odt') p = Py3oConvertor() res = p(py_expr) user_data = { 'var0': 42, 'myvar': Mock( var0=43, var1='val', ), } json_dict = res.render(user_data) assert json_dict == { 'var0': 42, 'myvar': { 'var0': 43, 'var1': 'val', }, } def test_double_loop_on_same_object(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_double_loop_on_same_object.odt') p = Py3oConvertor() res = p(py_expr) user_data = { 'varlist': [ Mock(var0=42, var1=-42), Mock(var0=170, var1=-170), ] } json_dict = res.render(user_data) self.assertEqual(json_dict, { 'varlist': [ { 'var0': 42, 'var1': -42 }, { 'var0': 170, 'var1': -170 }, ] }) def test_false_value(self): py_expr = self.__load_and_convert_template( 'tests/templates/test_false_value.odt') p = Py3oConvertor() res = p(py_expr) false_mock = Mock() false_mock.__nonzero__ = lambda x: False false_mock.__bool__ = lambda x: False user_data = { 'false_value': false_mock, } json_dict = res.render(user_data) assert json_dict == { 'false_value': u'', } def test_enumerate(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_enumerate.odt') p = Py3oConvertor() res = p(py_expr) user_data = { 'mylist': [10, 9, 8, 7, 6], } json_dict = res.render(user_data) assert json_dict == { 'mylist': [10, 9, 8, 7, 6], } def test_enumerate_attribute_access(self): """For loop on enumerate: only attributes used in body are extracted. Since mylist is given as an argument to enumerate, a known builtin function, Py3oConvertor should be able to recognize that val refers to the elements of mylist. """ expressions = [ 'for="i, val in enumerate(mylist)"', 'i', 'val.var0', 'val.var2', '/for' ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) user_data = { 'mylist': [ Mock(var0='0', var1=1, var2=2.0), Mock(var0=0, var1=1.0, var2='2'), Mock(var0=0.0, var1='1', var2=2), ] } json_dict = res.render(user_data) self.assertEqual( json_dict, { 'mylist': [ dict(var0='0', var2=2.0), dict(var0=0, var2='2'), dict(var0=0.0, var2=2), ] }) def test_unknown_iterable_call(self): """For loop on unknown function call: extract the entire object""" expressions = [ 'for="i, val in not_enumerate(mylist)"', 'i', 'val.var0', 'val.var2', '/for' ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) user_data = { 'mylist': [ Mock(var0='0', var1=1, var2=2.0), Mock(var0=0, var1=1.0, var2='2'), Mock(var0=0.0, var1='1', var2=2), ] } json_dict = res.render(user_data) self.assertEqual( json_dict, { 'mylist': [ user_data['mylist'][0], user_data['mylist'][1], user_data['mylist'][2], ] }) def test_template_function_call(self): py_expr = self.__load_and_convert_template( 'tests/templates/py3o_template_function_call.odt') p = Py3oConvertor() res = p(py_expr) user_data = { 'amount': 32.123, } json_dict = res.render(user_data) assert json_dict == { 'amount': 32.123, } def test_template_function_call_in_for_loop(self): expressions = [ 'for="item in object.list"', 'item.test', 'format_number(item.var)', '/for', ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) user_data = { 'object': Mock(list=[ Mock(var=32.123, test='2.3'), Mock(var=43.2, test='1.0') ]) } json_dict = res.render(user_data) self.assertEqual( json_dict, { 'object': { 'list': [ { 'var': 32.123, 'test': '2.3' }, { 'var': 43.2, 'test': '1.0' }, ] } }) def test_double_for_loop_on_same_attribute(self): expressions = [ 'for="item in root.object.list"', 'item.var1', '/for', 'for="item in root.object.list"', 'item.var0', '/for', '/for' ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) user_data = { 'root': Mock(object=Mock(list=[ Mock(var0=42, var1=-42), Mock(var0=170, var1=-170), ])) } json_dict = res.render(user_data) self.assertEqual( json_dict, { 'root': { 'object': { 'list': [ dict(var0=42, var1=-42), dict(var0=170, var1=-170), ] } } }) def test_if(self): expressions = [ 'if="item.mytest"', 'item.myvar', 'item.myvar2', '/if', ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({ 'item': Mock(mytest=0, myvar=1, myvar2=2), }) assert json_dict == { 'item': { 'mytest': 0, 'myvar': 1, 'myvar2': 2 }, } def test_if_global(self): expressions = [ 'if="mytest"', 'item.myvar', 'item.myvar2', '/if', ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({'item': Mock(myvar=1, myvar2=2), 'mytest': 0}) assert json_dict == { 'mytest': 0, 'item': { 'myvar': 1, 'myvar2': 2 }, } def test_if_global_array(self): expressions = [ 'for="var in myarray"', 'if="var"', 'var', '/if', '/for', ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({ 'myarray': list(range(0, 5)), }) assert json_dict == { 'myarray': list(range(0, 5)), } def test_if_in_for(self): expressions = [ 'for="item in object.mylist"', 'if="item.mytest"', 'item.myvar', 'item.myvar2', '/if', '/for', ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({ 'object': Mock(mylist=[ Mock(mytest=0, myvar=1, myvar2=2), Mock(mytest=3, myvar=4, myvar2=5), Mock(mytest=6, myvar=7, myvar2=8), ]) }) assert json_dict == { 'object': { 'mylist': [ { 'mytest': 0, 'myvar': 1, 'myvar2': 2 }, { 'mytest': 3, 'myvar': 4, 'myvar2': 5 }, { 'mytest': 6, 'myvar': 7, 'myvar2': 8 }, ] } } def test_if_comparator(self): expressions = ['if="a in b"', '/if'] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({ 'a': 1, 'b': [0, 1, 2], }) assert json_dict == { 'a': 1, 'b': [0, 1, 2], } def test_if_comparator_literal(self): expressions = ['if="a == 1"', '/if'] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({ 'a': 1, }) self.assertEqual(json_dict, { 'a': 1, }) # Test function def test_function_in_for(self): expressions = [ 'for="item in object.mylist"', 'format_date(item.date)', '/for', ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({ 'object': Mock(mylist=[ Mock(date='2015-12-13'), Mock(date='2015-12-14'), Mock(date='2015-12-15'), ]) }) assert json_dict == { 'object': { 'mylist': [ { 'date': '2015-12-13' }, { 'date': '2015-12-14' }, { 'date': '2015-12-15' }, ] } } def test_function_keywords(self): expressions = [ 'myfunc(object.var, k=object.k)', ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({ 'object': Mock(var=0, k=1), }) assert json_dict == {'object': {'var': 0, 'k': 1}} def test_function_array(self): expressions = ['for="var in myarray"', 'myfunc(var)', '/for'] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({ 'myarray': [0, 1, 2, 3], }) assert json_dict == { 'myarray': [0, 1, 2, 3], } def test_empty_for_loop(self): u"""Test ast extraction on for loops whose body do not use any data""" expressions = [ 'for="var in myarray"', '/for', ] py_expr = Template.convert_py3o_to_python_ast(expressions) self.assertEqual(py_expr.strip(), 'for var in myarray:\n pass') p = Py3oConvertor() res = p(py_expr) data = {'myarray': [0, 1, 2, 3]} json_dict = res.render(data) self.assertEqual(json_dict, data) def test_unpack_from_data_source(self): expressions = ['for="a, b in myarray"', 'a', 'b.c', '/for'] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) data = { 'myarray': [ (1, Mock(c=2, d=3)), (4, Mock(c=5, d=6)), ] } json_dict = res.render(data) self.assertEqual(json_dict, {'myarray': [ [1, { 'c': 2 }], [4, { 'c': 5 }], ]})
class TestHelpers(unittest.TestCase): def tearDown(self): pass def setUp(self): template_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_example_template.odt' ) outname = get_secure_filename() self.reference_template = Template(template_name, outname) os.unlink(outname) def test_move_1(self): """test that siblings are properly moved without keeping boundaries""" template_one_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_one.xml' ) test_template_one = lxml.etree.parse(template_one_name) start = test_template_one.find('mystruct/start') end = test_template_one.find('mystruct/end') new_ = lxml.etree.Element("finishcontainer") move_siblings(start, end, new_) result_s = lxml.etree.tostring( test_template_one, pretty_print=True, ).decode('utf-8') expected_result = open( pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_one_result.xml' ) ).read() expected_result = expected_result.replace( '\n', '').replace(' ', '').strip() result_s = result_s.replace('\n', '').replace(' ', '').strip() assert result_s == expected_result def test_move_2(self): """start.tail is correctly copied without keeping boundaries""" template_two_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_two.xml' ) test_template_two = lxml.etree.parse(template_two_name) start = test_template_two.find('mystruct/start') end = test_template_two.find('mystruct/end') new_ = lxml.etree.Element('finishcontainer') move_siblings(start, end, new_) result_s = lxml.etree.tostring( test_template_two, pretty_print=True, ).decode('utf-8') expected_result = open( pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_two_result.xml' ) ).read() expected_result = expected_result.replace( '\n', '').replace(' ', '').strip() result_s = result_s.replace('\n', '').replace(' ', '').strip() assert result_s == expected_result def test_move_keep_boundaries(self): """test that siblings are properly moved keeping boundaries""" template_three_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_three.xml' ) test_template_three = lxml.etree.parse(template_three_name) start = test_template_three.find('mystruct/start') end = test_template_three.find('mystruct/end') new_ = lxml.etree.Element('finishcontainer') move_siblings( start, end, new_, keep_start_boundary=True, keep_end_boundary=True, ) result_s = lxml.etree.tostring( test_template_three, pretty_print=True, ).decode('utf-8') expected_result = open( pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_three_result.xml' ) ).read() expected_result = expected_result.replace( '\n', '').replace(' ', '').strip() result_s = result_s.replace('\n', '').replace(' ', '').strip() assert result_s == expected_result def test_move_2_keep_boundaries(self): """test that start.tail is correctly copied keeping boundaries""" template_four_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_four.xml' ) test_template_four = lxml.etree.parse(template_four_name) start = test_template_four.find('mystruct/start') end = test_template_four.find('mystruct/end') new_ = lxml.etree.Element('finishcontainer') move_siblings( start, end, new_, keep_start_boundary=True, keep_end_boundary=True, ) result_s = lxml.etree.tostring( test_template_four, pretty_print=True, ).decode('utf-8') expected_result = open( pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_four_result.xml' ) ).read() expected_result = expected_result.replace( '\n', '').replace(' ', '').strip() result_s = result_s.replace('\n', '').replace(' ', '').strip() assert result_s == expected_result def test_get_user_variables(self): source_odt_filename = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_example_template.odt' ) outfilename = get_secure_filename() template = Template(source_odt_filename, outfilename) user_vars = template.get_user_variables() expected_vars = [ 'line.val1', 'line.val2', 'line.val3', 'item.Amount', 'item.Currency', 'item.InvoiceRef', 'document.total', ] assert set(user_vars) == set(expected_vars) def test_get_user_instructions(self): source_odt_filename = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_example_template.odt' ) outfilename = get_secure_filename() template = Template(source_odt_filename, outfilename) user_instructions = template.get_user_instructions() expected_vars = [ 'for="line in items"', '/for', 'for="item in items"', 'if="item.InvoiceRef==\'#1234\'"', '/if', '/for', ] assert set(user_instructions) == set(expected_vars) def test_get_user_instruction_mapping(self): """test the jsonified result of get_user_instruction_mapping""" source_odt_filename = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_example_template.odt' ) outfilename = get_secure_filename() template = Template(source_odt_filename, outfilename) for_lists, vars = template.get_user_instructions_mapping() expected_res = { 'document': { 'total': 0 }, 'items': [{ 'val1': 1, 'val2': 2, 'val3': 3, 'Amount': 4, 'Currency': 5, 'InvoiceRef': 6, }] } data = { 'document': Mock(total=0), 'items': [ Mock( val1=1, val2=2, val3=3, Amount=4, Currency=5, InvoiceRef=6 ) ] } res = ForList.to_dict(for_lists, vars, data) assert res == expected_res def test_detect_boundary_false(self): """boundary detection should say no!!""" source_xml_filename = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/keepboundary_detection_false.xml' ) test_xml = lxml.etree.parse(source_xml_filename) starts, ends = self.reference_template.handle_instructions( [test_xml], self.reference_template.namespaces ) for start, base in starts: end = ends[id(start)] keep_start, keep_end = detect_keep_boundary( start, end, self.reference_template.namespaces ) assert keep_start is False assert keep_end is False def test_detect_boundary_true(self): """boundary detection should say yes!!""" source_xml_filename = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/keepboundary_detection_true.xml' ) test_xml = lxml.etree.parse(source_xml_filename) starts, ends = self.reference_template.handle_instructions( [test_xml], self.reference_template.namespaces ) for index, (start, base) in enumerate(starts): end = ends[id(start)] keep_start, keep_end = detect_keep_boundary( start, end, self.reference_template.namespaces ) if index == 0: assert keep_start is False assert keep_end is True else: assert False, "We should find one single link" def test_move_siblings_1(self): template_xml = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_siblings.xml' ) test_xml = lxml.etree.parse(template_xml) starts, ends = self.reference_template.handle_instructions( [test_xml], self.reference_template.namespaces ) assert len(starts) == 1 assert len(ends) == 1 start, _ = starts[0] end = ends[id(start)] keep_start, keep_end = detect_keep_boundary( start, end, self.reference_template.namespaces ) assert keep_start is True assert keep_end is False new_ = lxml.etree.Element('finishcontainer') start_parent = start.getparent() end_parent = end.getparent() start.getparent().remove(start) end.getparent().remove(end) move_siblings( start_parent, end_parent, new_, keep_start_boundary=keep_start, keep_end_boundary=keep_end, ) result_a = lxml.etree.tostring( test_xml, pretty_print=True, ).decode('utf-8') result_e = open( pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_siblings_result_1.xml' ) ).read() result_a = result_a.replace("\n", "").replace(" ", "") result_e = result_e.replace("\n", "").replace(" ", "") assert result_a == result_e def test_move_siblings_2(self): template_xml = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_siblings.xml' ) test_xml = lxml.etree.parse(template_xml) starts, ends = self.reference_template.handle_instructions( [test_xml], self.reference_template.namespaces ) assert len(starts) == 1 assert len(ends) == 1 start, base = starts[0] end = ends[id(start)] keep_start, keep_end = detect_keep_boundary( start, end, self.reference_template.namespaces ) assert keep_start is True assert keep_end is False self.reference_template.handle_link(start, base, end) result_a = lxml.etree.tostring( test_xml, pretty_print=True, ).decode('utf-8') result_e = open( pkg_resources.resource_filename( 'py3o.template', 'tests/templates/move_siblings_result_2.xml' ) ).read() result_a = result_a.replace("\n", "").replace(" ", "") result_e = result_e.replace("\n", "").replace(" ", "") assert result_a == result_e def test_content_tree_with_child_instruction(self): template_xml = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_example_invalid_template.odt' ) t = Template(template_xml, get_secure_filename()) usr_insts = t.get_user_instructions() assert usr_insts == ['for="item in items"', '/for', 'for="item in items', '2', '"', '/for'] def test_remove_soft_page_breaks(self): template_xml = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_soft_page_break.odt' ) t = Template(template_xml, get_secure_filename()) soft_breaks = get_soft_breaks(t.content_trees[0], t.namespaces) assert len(soft_breaks) > 0 t.remove_soft_breaks() soft_breaks = get_soft_breaks(t.content_trees[0], t.namespaces) assert len(soft_breaks) == 0 t = Template(template_xml, get_secure_filename()) soft_breaks = get_soft_breaks(t.content_trees[0], t.namespaces) assert len(soft_breaks) > 0 t.render(data={"list1": [1, 2, 3]}) soft_breaks = get_soft_breaks(t.content_trees[0], t.namespaces) assert len(soft_breaks) == 0
class TestHelpers(unittest.TestCase): def tearDown(self): pass def setUp(self): template_name = pkg_resources.resource_filename( "py3o.template", "tests/templates/py3o_example_template.odt" ) outname = get_secure_filename() self.reference_template = Template(template_name, outname) os.unlink(outname) def test_move_1(self): """test that siblings are properly moved without keeping boundaries""" template_one_name = pkg_resources.resource_filename( "py3o.template", "tests/templates/move_one.xml" ) test_template_one = lxml.etree.parse(template_one_name) start = test_template_one.find("mystruct/start") end = test_template_one.find("mystruct/end") new_ = lxml.etree.Element("finishcontainer") move_siblings(start, end, new_) result_s = lxml.etree.tostring( test_template_one, pretty_print=True ).decode("utf-8") expected_result = open( pkg_resources.resource_filename( "py3o.template", "tests/templates/move_one_result.xml" ) ).read() expected_result = ( expected_result.replace("\n", "").replace(" ", "").strip() ) result_s = result_s.replace("\n", "").replace(" ", "").strip() assert result_s == expected_result def test_move_2(self): """start.tail is correctly copied without keeping boundaries""" template_two_name = pkg_resources.resource_filename( "py3o.template", "tests/templates/move_two.xml" ) test_template_two = lxml.etree.parse(template_two_name) start = test_template_two.find("mystruct/start") end = test_template_two.find("mystruct/end") new_ = lxml.etree.Element("finishcontainer") move_siblings(start, end, new_) result_s = lxml.etree.tostring( test_template_two, pretty_print=True ).decode("utf-8") expected_result = open( pkg_resources.resource_filename( "py3o.template", "tests/templates/move_two_result.xml" ) ).read() expected_result = ( expected_result.replace("\n", "").replace(" ", "").strip() ) result_s = result_s.replace("\n", "").replace(" ", "").strip() assert result_s == expected_result def test_move_keep_boundaries(self): """test that siblings are properly moved keeping boundaries""" template_three_name = pkg_resources.resource_filename( "py3o.template", "tests/templates/move_three.xml" ) test_template_three = lxml.etree.parse(template_three_name) start = test_template_three.find("mystruct/start") end = test_template_three.find("mystruct/end") new_ = lxml.etree.Element("finishcontainer") move_siblings( start, end, new_, keep_start_boundary=True, keep_end_boundary=True ) result_s = lxml.etree.tostring( test_template_three, pretty_print=True ).decode("utf-8") expected_result = open( pkg_resources.resource_filename( "py3o.template", "tests/templates/move_three_result.xml" ) ).read() expected_result = ( expected_result.replace("\n", "").replace(" ", "").strip() ) result_s = result_s.replace("\n", "").replace(" ", "").strip() assert result_s == expected_result def test_move_2_keep_boundaries(self): """test that start.tail is correctly copied keeping boundaries""" template_four_name = pkg_resources.resource_filename( "py3o.template", "tests/templates/move_four.xml" ) test_template_four = lxml.etree.parse(template_four_name) start = test_template_four.find("mystruct/start") end = test_template_four.find("mystruct/end") new_ = lxml.etree.Element("finishcontainer") move_siblings( start, end, new_, keep_start_boundary=True, keep_end_boundary=True ) result_s = lxml.etree.tostring( test_template_four, pretty_print=True ).decode("utf-8") expected_result = open( pkg_resources.resource_filename( "py3o.template", "tests/templates/move_four_result.xml" ) ).read() expected_result = ( expected_result.replace("\n", "").replace(" ", "").strip() ) result_s = result_s.replace("\n", "").replace(" ", "").strip() assert result_s == expected_result def test_get_user_variables(self): source_odt_filename = pkg_resources.resource_filename( "py3o.template", "tests/templates/py3o_example_template.odt" ) outfilename = get_secure_filename() template = Template(source_odt_filename, outfilename) user_vars = template.get_user_variables() expected_vars = [ "line.val1", "line.val2", "line.val3", "item.Amount", "item.Currency", "item.InvoiceRef", "document.total", ] assert set(user_vars) == set(expected_vars) def test_convertor(self): source_odt_filename = pkg_resources.resource_filename( "py3o.template", "tests/templates/py3o_if_parser.odt" ) outfilename = get_secure_filename() template = Template(source_odt_filename, outfilename) user_vars = template.get_user_variables() expressions = template.get_all_user_python_expression() py_expression = template.convert_py3o_to_python_ast(expressions) convertor = Py3oConvertor() data_struct = convertor(py_expression) assert "objects" in data_struct objs = data_struct["objects"] assert "company_label" in objs assert "name" in objs assert isinstance(objs["company_label"], Py3oName) assert isinstance(objs["name"], Py3oName) # assert data_struct == Py3oModule( # { # 'objects': Py3oArray( # { # 'company_label': Py3oName({}), # 'name': Py3oName({}) # } # ) # } # ) expected_vars = ["registration.name", "registration.company_label"] assert set(user_vars) == set(expected_vars) def test_get_user_instructions(self): source_odt_filename = pkg_resources.resource_filename( "py3o.template", "tests/templates/py3o_example_template.odt" ) outfilename = get_secure_filename() template = Template(source_odt_filename, outfilename) user_instructions = template.get_user_instructions() expected_vars = [ 'for="line in items"', "/for", 'for="item in items"', "if=\"item.InvoiceRef=='#1234'\"", "/if", "/for", ] assert set(user_instructions) == set(expected_vars) def test_calc(self): """Test date source extraction in ods files""" source_ods_filename = pkg_resources.resource_filename( "py3o.template", "tests/templates/py3o_simple_calc.ods" ) outfilename = get_secure_filename() template = Template(source_ods_filename, outfilename) expressions = template.get_all_user_python_expression() expected_expressions = [ 'for="item in items"', "item.col1", "item.col2", "item.col3", "item.col4", "/for", ] self.assertEqual(expressions, expected_expressions) py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) user_data = { "items": [ Mock(col0="0", col1=1, col2=2.0, col3="?", col4="!"), Mock(col0=0, col1=1.0, col2="2", col3="?", col4="!"), Mock(col0=0.0, col1="1", col2=2, col3="?", col4="!"), ] } json_dict = res.render(user_data) self.assertEqual( json_dict, { "items": [ dict(col1=1, col2=2.0, col3="?", col4="!"), dict(col1=1.0, col2="2", col3="?", col4="!"), dict(col1="1", col2=2, col3="?", col4="!"), ] }, ) def test_detect_boundary_false(self): """boundary detection should say no!!""" source_xml_filename = pkg_resources.resource_filename( "py3o.template", "tests/templates/keepboundary_detection_false.xml" ) test_xml = lxml.etree.parse(source_xml_filename) starts, ends = self.reference_template.find_instructions( [test_xml], self.reference_template.namespaces ) for start, base in starts: end = ends[id(start)] keep_start, keep_end = detect_keep_boundary( start, end, self.reference_template.namespaces ) assert keep_start is False assert keep_end is False def test_detect_boundary_true(self): """boundary detection should say yes!!""" source_xml_filename = pkg_resources.resource_filename( "py3o.template", "tests/templates/keepboundary_detection_true.xml" ) test_xml = lxml.etree.parse(source_xml_filename) starts, ends = self.reference_template.find_instructions( [test_xml], self.reference_template.namespaces ) for index, (start, base) in enumerate(starts): end = ends[id(start)] keep_start, keep_end = detect_keep_boundary( start, end, self.reference_template.namespaces ) if index == 0: assert keep_start is False assert keep_end is True else: assert False, "We should find one single link" def test_move_siblings_1(self): template_xml = pkg_resources.resource_filename( "py3o.template", "tests/templates/move_siblings.xml" ) test_xml = lxml.etree.parse(template_xml) starts, ends = self.reference_template.find_instructions( [test_xml], self.reference_template.namespaces ) assert len(starts) == 1 assert len(ends) == 1 start, _ = starts[0] end = ends[id(start)] keep_start, keep_end = detect_keep_boundary( start, end, self.reference_template.namespaces ) assert keep_start is True assert keep_end is False new_ = lxml.etree.Element("finishcontainer") start_parent = start.getparent() end_parent = end.getparent() start.getparent().remove(start) end.getparent().remove(end) move_siblings( start_parent, end_parent, new_, keep_start_boundary=keep_start, keep_end_boundary=keep_end, ) result_a = lxml.etree.tostring(test_xml, pretty_print=True).decode( "utf-8" ) result_e = open( pkg_resources.resource_filename( "py3o.template", "tests/templates/move_siblings_result_1.xml" ) ).read() result_a = result_a.replace("\n", "").replace(" ", "") result_e = result_e.replace("\n", "").replace(" ", "") assert result_a == result_e def test_move_siblings_2(self): template_xml = pkg_resources.resource_filename( "py3o.template", "tests/templates/move_siblings.xml" ) test_xml = lxml.etree.parse(template_xml) starts, ends = self.reference_template.find_instructions( [test_xml], self.reference_template.namespaces ) assert len(starts) == 1 assert len(ends) == 1 start, base = starts[0] end = ends[id(start)] keep_start, keep_end = detect_keep_boundary( start, end, self.reference_template.namespaces ) assert keep_start is True assert keep_end is False self.reference_template.handle_link(start, base, end) result_a = lxml.etree.tostring(test_xml, pretty_print=True).decode( "utf-8" ) result_e = open( pkg_resources.resource_filename( "py3o.template", "tests/templates/move_siblings_result_2.xml" ) ).read() result_a = result_a.replace("\n", "").replace(" ", "") result_e = result_e.replace("\n", "").replace(" ", "") assert result_a == result_e def test_content_tree_with_child_instruction(self): template_xml = pkg_resources.resource_filename( "py3o.template", "tests/templates/py3o_example_invalid_template.odt", ) t = Template(template_xml, get_secure_filename()) usr_insts = t.get_user_instructions() assert usr_insts == [ 'for="item in items"', "/for", 'for="item in items', "2", '"', "/for", ] def __load_and_convert_template(self, path): template_xml = pkg_resources.resource_filename("py3o.template", path) t = Template(template_xml, get_secure_filename()) expressions = t.get_all_user_python_expression() py_expr = t.convert_py3o_to_python_ast(expressions) return py_expr def test_access_global_variable_inside_loop(self): py_expr = self.__load_and_convert_template( "tests/templates/py3o_access_global_variable_inside_loop.odt" ) p = Py3oConvertor() res = p(py_expr) user_data = {"global_var": Mock(val=1), "my4list": [0, 1, 2, 3]} json_str = res.render(user_data) self.assertEquals( json_str, {"global_var": dict(val=1), "my4list": [0, 1, 2, 3]} ) def test_access_in_loop_variable(self): py_expr = self.__load_and_convert_template( "tests/templates/py3o_access_in_loop_variable.odt" ) p = Py3oConvertor() res = p(py_expr) user_data = {"my2list": [0, 1, 2, 3, 4]} json_str = res.render(user_data) assert json_str == {"my2list": [0, 1, 2, 3, 4]} def test_access_global_variable(self): py_expr = self.__load_and_convert_template( "tests/templates/py3o_access_global_variable.odt" ) p = Py3oConvertor() res = p(py_expr) user_data = {"var0": 0, "var1": 1, "var2": 2} json_str = res.render(user_data) assert json_str == {"var0": 0, "var1": 1, "var2": 2} def test_iterable_with_global_attribute(self): py_expr = self.__load_and_convert_template( "tests/templates/py3o_iterable_with_global_attribute.odt" ) p = Py3oConvertor() res = p(py_expr) user_data = {"foo": Mock(my2list=[0, 1, 2, 3, 4])} json_str = res.render(user_data) assert json_str == {"foo": {"my2list": [0, 1, 2, 3, 4]}} def test_two_for_list_on_same_attribute(self): py_expr = self.__load_and_convert_template( "tests/templates/py3o_two_for_list_on_same_attribute.odt" ) p = Py3oConvertor() res = p(py_expr) user_data = { "foo": Mock(my2list=[0, 1, 2, 3, 4], my3list=[5, 6, 7, 8]) } json_str = res.render(user_data) assert json_str == { "foo": {"my2list": [0, 1, 2, 3, 4], "my3list": [5, 6, 7, 8]} } def test_access_in_loop_variable_with_attribute(self): py_expr = self.__load_and_convert_template( "tests/templates/py3o_access_in_loop_variable_with_attribute.odt" ) p = Py3oConvertor() res = p(py_expr) user_data = {"my3list": [Mock(val=0), Mock(val=1), Mock(val=2)]} json_str = res.render(user_data) assert json_str == {"my3list": [{"val": 0}, {"val": 1}, {"val": 2}]} def test_access_in_loop_variable_with_multiple_attribute(self): py_expr = self.__load_and_convert_template( "tests/templates/" "py3o_access_in_loop_variable_with_multiple_attribute.odt" ) p = Py3oConvertor() res = p(py_expr) user_data = { "my3list": [ Mock(foo=Mock(val=0)), Mock(foo=Mock(val=1)), Mock(foo=Mock(val=2)), ] } json_str = res.render(user_data) assert json_str == { "my3list": [ {"foo": {"val": 0}}, {"foo": {"val": 1}}, {"foo": {"val": 2}}, ] } def test_access_parent_variable_in_nested_loop(self): py_expr = self.__load_and_convert_template( "tests/templates/py3o_access_parent_variable_in_nested_loop.odt" ) p = Py3oConvertor() res = p(py_expr) user_data = {"my9list": [Mock(val=10), Mock(val=11)]} json_str = res.render(user_data) assert json_str == {"my9list": [{"val": 10}, {"val": 11}]} def test_access_parent_variable_in_nested_loop_with_attribute(self): py_expr = self.__load_and_convert_template( "tests/templates/" "py3o_access_parent_variable_in_nested_loop_with_attribute.odt" ) p = Py3oConvertor() res = p(py_expr) user_data = { "my10list": [ Mock(my_list=[Mock(val=10), Mock(val=11)]), Mock(my_list=[Mock(val=20), Mock(val=21), Mock(val=22)]), ] } json_str = res.render(user_data) assert json_str == { "my10list": [ {"my_list": [{"val": 10}, {"val": 11}]}, {"my_list": [{"val": 20}, {"val": 21}, {"val": 22}]}, ] } def test_access_variable_in_nested_loop(self): py_expr = self.__load_and_convert_template( "tests/templates/" "py3o_access_variable_in_nested_loop.odt" ) p = Py3oConvertor() res = p(py_expr) user_data = {"my8list": [[10, 11, 12], [20, 21, 22, 23]]} json_str = res.render(user_data) assert json_str == {"my8list": [[10, 11, 12], [20, 21, 22, 23]]} def test_bad_user_data(self): py_expr = self.__load_and_convert_template( "tests/templates/py3o_access_global_variable_inside_loop.odt" ) p = Py3oConvertor() res = p(py_expr) user_data = {} with self.assertRaises(Py3oDataError): res.render(user_data) def test_test_statement(self): py_expr = self.__load_and_convert_template( "tests/templates/py3o_test_statement.odt" ) p = Py3oConvertor() res = p(py_expr) user_data = {"var0": 42, "myvar": Mock(var0=43, var1="val")} json_dict = res.render(user_data) assert json_dict == {"var0": 42, "myvar": {"var0": 43, "var1": "val"}} def test_double_loop_on_same_object(self): py_expr = self.__load_and_convert_template( "tests/templates/py3o_double_loop_on_same_object.odt" ) p = Py3oConvertor() res = p(py_expr) user_data = { "varlist": [Mock(var0=42, var1=-42), Mock(var0=170, var1=-170)] } json_dict = res.render(user_data) self.assertEqual( json_dict, { "varlist": [ {"var0": 42, "var1": -42}, {"var0": 170, "var1": -170}, ] }, ) def test_false_value(self): py_expr = self.__load_and_convert_template( "tests/templates/test_false_value.odt" ) p = Py3oConvertor() res = p(py_expr) false_mock = Mock() false_mock.__nonzero__ = lambda x: False false_mock.__bool__ = lambda x: False user_data = {"false_value": false_mock} json_dict = res.render(user_data) assert json_dict == {"false_value": u""} def test_enumerate(self): py_expr = self.__load_and_convert_template( "tests/templates/py3o_enumerate.odt" ) p = Py3oConvertor() res = p(py_expr) user_data = {"mylist": [10, 9, 8, 7, 6]} json_dict = res.render(user_data) assert json_dict == {"mylist": [10, 9, 8, 7, 6]} def test_enumerate_attribute_access(self): """For loop on enumerate: only attributes used in body are extracted. Since mylist is given as an argument to enumerate, a known builtin function, Py3oConvertor should be able to recognize that val refers to the elements of mylist. """ expressions = [ 'for="i, val in enumerate(mylist)"', "i", "val.var0", "val.var2", "/for", ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) user_data = { "mylist": [ Mock(var0="0", var1=1, var2=2.0), Mock(var0=0, var1=1.0, var2="2"), Mock(var0=0.0, var1="1", var2=2), ] } json_dict = res.render(user_data) self.assertEqual( json_dict, { "mylist": [ dict(var0="0", var2=2.0), dict(var0=0, var2="2"), dict(var0=0.0, var2=2), ] }, ) def test_unknown_iterable_call(self): """For loop on unknown function call: extract the entire object""" expressions = [ 'for="i, val in not_enumerate(mylist)"', "i", "val.var0", "val.var2", "/for", ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) user_data = { "mylist": [ Mock(var0="0", var1=1, var2=2.0), Mock(var0=0, var1=1.0, var2="2"), Mock(var0=0.0, var1="1", var2=2), ] } json_dict = res.render(user_data) self.assertEqual( json_dict, { "mylist": [ user_data["mylist"][0], user_data["mylist"][1], user_data["mylist"][2], ] }, ) def test_template_function_call(self): py_expr = self.__load_and_convert_template( "tests/templates/py3o_template_function_call.odt" ) p = Py3oConvertor() res = p(py_expr) user_data = {"amount": 32.123} json_dict = res.render(user_data) assert json_dict == {"amount": 32.123} def test_template_function_call_in_for_loop(self): expressions = [ 'for="item in object.list"', "item.test", "format_number(item.var)", "/for", ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) user_data = { "object": Mock( list=[Mock(var=32.123, test="2.3"), Mock(var=43.2, test="1.0")] ) } json_dict = res.render(user_data) self.assertEqual( json_dict, { "object": { "list": [ {"var": 32.123, "test": "2.3"}, {"var": 43.2, "test": "1.0"}, ] } }, ) def test_double_for_loop_on_same_attribute(self): expressions = [ 'for="item in root.object.list"', "item.var1", "/for", 'for="item in root.object.list"', "item.var0", "/for", "/for", ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) user_data = { "root": Mock( object=Mock( list=[Mock(var0=42, var1=-42), Mock(var0=170, var1=-170)] ) ) } json_dict = res.render(user_data) self.assertEqual( json_dict, { "root": { "object": { "list": [ dict(var0=42, var1=-42), dict(var0=170, var1=-170), ] } } }, ) def test_if(self): expressions = ['if="item.mytest"', "item.myvar", "item.myvar2", "/if"] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({"item": Mock(mytest=0, myvar=1, myvar2=2)}) assert json_dict == {"item": {"mytest": 0, "myvar": 1, "myvar2": 2}} def test_if_global(self): expressions = ['if="mytest"', "item.myvar", "item.myvar2", "/if"] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({"item": Mock(myvar=1, myvar2=2), "mytest": 0}) assert json_dict == {"mytest": 0, "item": {"myvar": 1, "myvar2": 2}} def test_if_global_array(self): expressions = [ 'for="var in myarray"', 'if="var"', "var", "/if", "/for", ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({"myarray": list(range(0, 5))}) assert json_dict == {"myarray": list(range(0, 5))} def test_if_in_for(self): expressions = [ 'for="item in object.mylist"', 'if="item.mytest"', "item.myvar", "item.myvar2", "/if", "/for", ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render( { "object": Mock( mylist=[ Mock(mytest=0, myvar=1, myvar2=2), Mock(mytest=3, myvar=4, myvar2=5), Mock(mytest=6, myvar=7, myvar2=8), ] ) } ) assert json_dict == { "object": { "mylist": [ {"mytest": 0, "myvar": 1, "myvar2": 2}, {"mytest": 3, "myvar": 4, "myvar2": 5}, {"mytest": 6, "myvar": 7, "myvar2": 8}, ] } } def test_if_comparator(self): expressions = ['if="a in b"', "/if"] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({"a": 1, "b": [0, 1, 2]}) assert json_dict == {"a": 1, "b": [0, 1, 2]} def test_if_comparator_literal(self): expressions = ['if="a == 1"', "/if"] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({"a": 1}) self.assertEqual(json_dict, {"a": 1}) # Test function def test_function_in_for(self): expressions = [ 'for="item in object.mylist"', "format_date(item.date)", "/for", ] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render( { "object": Mock( mylist=[ Mock(date="2015-12-13"), Mock(date="2015-12-14"), Mock(date="2015-12-15"), ] ) } ) assert json_dict == { "object": { "mylist": [ {"date": "2015-12-13"}, {"date": "2015-12-14"}, {"date": "2015-12-15"}, ] } } def test_function_keywords(self): expressions = ["myfunc(object.var, k=object.k)"] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({"object": Mock(var=0, k=1)}) assert json_dict == {"object": {"var": 0, "k": 1}} def test_function_array(self): expressions = ['for="var in myarray"', "myfunc(var)", "/for"] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) json_dict = res.render({"myarray": [0, 1, 2, 3]}) assert json_dict == {"myarray": [0, 1, 2, 3]} def test_empty_for_loop(self): u"""Test ast extraction on for loops whose body do not use any data""" expressions = ['for="var in myarray"', "/for"] py_expr = Template.convert_py3o_to_python_ast(expressions) self.assertEqual(py_expr.strip(), "for var in myarray:\n pass") p = Py3oConvertor() res = p(py_expr) data = {"myarray": [0, 1, 2, 3]} json_dict = res.render(data) self.assertEqual(json_dict, data) def test_unpack_from_data_source(self): expressions = ['for="a, b in myarray"', "a", "b.c", "/for"] py_expr = Template.convert_py3o_to_python_ast(expressions) p = Py3oConvertor() res = p(py_expr) data = {"myarray": [(1, Mock(c=2, d=3)), (4, Mock(c=5, d=6))]} json_dict = res.render(data) self.assertEqual( json_dict, {"myarray": [[1, {"c": 2}], [4, {"c": 5}]]} )