示例#1
0
    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)
示例#2
0
    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
示例#3
0
    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)
示例#4
0
    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"
示例#5
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
示例#6
0
 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']
示例#7
0
 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']
示例#8
0
    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"
示例#9
0
    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"
示例#10
0
    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
示例#11
0
    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"
示例#12
0
    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
示例#13
0
    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},
                ]
            }
        }
示例#14
0
    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"},
                ]
            }
        }
示例#15
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],
                ]
            })
示例#16
0
 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"},
                 ]
             }
         },
     )
示例#17
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],
                ]
            },
        )
示例#18
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),
                        ]
                    }
                }
            })
示例#19
0
    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'},
                ]
            }
        }
示例#20
0
    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),
                ]
            })
示例#21
0
    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},
                ]
            }
        }
示例#22
0
 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'
                     },
                 ]
             }
         })
示例#23
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}}
示例#24
0
    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]}
示例#25
0
    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}}
示例#26
0
    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]}
示例#27
0
    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})
示例#28
0
    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)
示例#29
0
    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)
示例#30
0
    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)
示例#31
0
 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)
示例#32
0
    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
示例#33
0
    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)
示例#34
0
    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="!"),
                ]
            },
        )
示例#35
0
    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)
示例#36
0
    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)
示例#37
0
    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}}
示例#38
0
    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)
示例#39
0
    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
示例#40
0
    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
示例#41
0
    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
示例#42
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
示例#43
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_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