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_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 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_list_duplicate(self): """test duplicated listed get a unique id""" template_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_list_template.odt' ) outname = get_secure_filename() template = Template(template_name, outname) class Item(object): def __init__(self, val): self.val = val data_dict = { "items": [Item(1), Item(2), Item(3), Item(4)] } error = False template.set_image_path('logo', pkg_resources.resource_filename( 'py3o.template', 'tests/templates/images/new_logo.png' )) template.render(data_dict) outodt = zipfile.ZipFile(outname, 'r') try: content_list = [ lxml.etree.parse(BytesIO(outodt.read(filename))) for filename in template.templated_files ] except lxml.etree.XMLSyntaxError as e: error = True print( "List was not deduplicated->{}".format(e) ) # remove end file os.unlink(outname) assert error is False # first content is the content.xml content = content_list[0] list_expr = '//text:list' list_items = content.xpath( list_expr, namespaces=template.namespaces ) ids = [] for list_item in list_items: ids.append( list_item.get( '{}id'.format(XML_NS) ) ) assert ids, "this list of ids should not be empty" assert len(ids) == len(set(ids)), "all ids should have been unique"
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_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_invalid_template_1(self): """a template should not try to define a /for and a for on the same paragraph """ template_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_example_invalid_template.odt' ) outname = get_secure_filename() template = Template(template_name, outname) class Item(object): pass items = list() item1 = Item() item1.val1 = 'Item1 Value1' item1.val2 = 'Item1 Value2' item1.val3 = 'Item1 Value3' item1.Currency = 'EUR' item1.Amount = '12345.35' item1.InvoiceRef = '#1234' items.append(item1) # if you are using python 2.x you should use xrange for i in range(1000): item = Item() item.val1 = 'Item%s Value1' % i item.val2 = 'Item%s Value2' % i item.val3 = 'Item%s Value3' % i item.Currency = 'EUR' item.Amount = '6666.77' item.InvoiceRef = 'Reference #%04d' % i items.append(item) document = Item() document.total = '9999999999999.999' data = dict( items=items, items2=copy.copy(items), document=document ) error = False try: template.render(data) except TemplateException: error = True assert error is True, "This template should have been refused"
def test_example_1(self): template_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_example_template.odt' ) outname = get_secure_filename() template = Template(template_name, outname) template.set_image_path('logo', pkg_resources.resource_filename( 'py3o.template', 'tests/templates/images/new_logo.png' )) class Item(object): pass items = list() item1 = Item() item1.val1 = 'Item1 Value1' item1.val2 = 'Item1 Value2' item1.val3 = 'Item1 Value3' item1.Currency = 'EUR' item1.Amount = '12345.35' item1.InvoiceRef = '#1234' items.append(item1) # if you are using python 2.x you should use xrange for i in range(1000): item = Item() item.val1 = 'Item%s Value1' % i item.val2 = 'Item%s Value2' % i item.val3 = 'Item%s Value3' % i item.Currency = 'EUR' item.Amount = '6666.77' item.InvoiceRef = 'Reference #%04d' % i items.append(item) document = Item() document.total = '9999999999999.999' data = dict(items=items, document=document) error = False try: template.render(data) except ValueError as e: print('The template did not render properly...') traceback.print_exc() error = True assert error is False
def test_render_apply_style(self): template_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_style1_template.odt' ) outname = get_secure_filename() template = Template(template_name, outname) template.set_image_path('logo', pkg_resources.resource_filename( 'py3o.template', 'tests/templates/images/new_logo.png' )) class Item(object): pass items = list() item1 = Item() item1.val1 = 'Item1 Value1' item1.val2 = 'Item1 Value2' item1.val3 = 'Item1 Value3' item1.Currency = 'EUR' item1.Amount = 12345.35 item1.InvoiceRef = '#1234' items.append(item1) document = Item() document.total = '9999999999999.999' data = dict(items=items, document=document) template.render(data) # reuse the template engine just to open our odt file content... tempout = get_secure_filename() t2 = Template(outname, tempout) os.unlink(tempout) result_content = t2.content_trees[0] expr = "//text:p[contains(text(), 'Invoice')]" paragraphs = result_content.xpath( expr, namespaces=t2.namespaces ) assert len(paragraphs) == 1, "Only one paragraph should have been found" p = paragraphs[0] result_text = p.text print(result_text) assert result_text == "Invoice #1234 for a total of 12345,35 EUR"
def test_ignore_undefined_variables_1(self): template_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_undefined_variables_1.odt' ) outname = get_secure_filename() template = Template(template_name, outname) data = {} error = True try: template.render(data) print("Error: template contains variables that must be " "replaced") except TemplateError: error = False assert error is False template = Template(template_name, outname, ignore_undefined_variables=True) error = False try: template.render(data) except: traceback.print_exc() error = True assert error is False
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_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_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_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_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_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_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_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_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_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_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_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_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_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})
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_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_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_format_date(self): template_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_template_format_date.odt' ) outname = get_secure_filename() template = Template(template_name, outname) data_dict = { 'datestring': '2015-08-02', 'datetimestring': '2015-08-02 17:05:06', 'datestring2': '2015-10-15', 'datetime': datetime.datetime.strptime( '2015-11-13 17:00:20', '%Y-%m-%d %H:%M:%S' ), } template.render(data_dict) outodt = zipfile.ZipFile(outname, 'r') content_list = lxml.etree.parse( BytesIO(outodt.read(template.templated_files[0])) ) result_a = lxml.etree.tostring( content_list, pretty_print=True, ).decode('utf-8') result_e = open( pkg_resources.resource_filename( 'py3o.template', 'tests/templates/template_format_date_result.xml' ) ).read() result_a = result_a.replace("\n", "").replace(" ", "") result_e = result_e.replace("\n", "").replace(" ", "") assert result_a == result_e
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_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_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_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_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_missing_opening(self): """test orphaned /for raises a TemplateException""" template_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_missing_open_template.odt' ) outname = get_secure_filename() try: template = Template(template_name, outname) finally: os.remove(outname) class Item(object): def __init__(self, val): self.val = val data_dict = { "items": [Item(1), Item(2), Item(3), Item(4)] } template.set_image_path('logo', pkg_resources.resource_filename( 'py3o.template', 'tests/templates/images/new_logo.png' )) # this will raise a TemplateException... or the test will fail error_occured = False try: template.render(data_dict) except TemplateException as e: error_occured = True # make sure this is the correct TemplateException that pops assert e.message == "No open instruction for /for" # and make sure we raised assert error_occured is True
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_ignore_undefined_variables_2(self): """ Test ignore undefined variables for template with dotted variables like py3o.document.value """ template_name = pkg_resources.resource_filename( 'py3o.template', 'tests/templates/py3o_undefined_variables_2.odt' ) outname = get_secure_filename() template = Template(template_name, outname) data = {} error = True try: template.render(data) print("Error: template contains variables that must be " "replaced") except TemplateError: error = False assert error is False template = Template(template_name, outname, ignore_undefined_variables=True) error = True try: template.render(data) print("Error: template contains dotted variables that must be " "replaced") except TemplateError: error = False assert error is False
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