# coding=utf-8
try:
from unittest import mock
except ImportError:
import mock
import pytest
from io import BytesIO
from lingua.extractors.xml import ChameleonExtractor
from lingua.extractors.xml import get_python_expressions
xml_extractor = ChameleonExtractor()
source = None
def _options(**kw):
options = mock.Mock()
options.domain = None
options.keywords = []
for (k, w) in kw.items():
setattr(options, k, w)
return options
@pytest.fixture
def fake_source(request):
patcher = mock.patch(
"lingua.extractors.xml._open", side_effect=lambda *a: BytesIO(source)
)
patcher.start()
request.addfinalizer(patcher.stop)
@pytest.mark.usefixtures("fake_source")
def test_abort_on_syntax_error():
global source
source = b"""\xff\xff\xff"""
with pytest.raises(SystemExit):
list(xml_extractor("filename", _options()))
@pytest.mark.usefixtures("fake_source")
def test_empty_xml():
global source
source = b"""
"""
assert list(xml_extractor("filename", _options())) == []
@pytest.mark.usefixtures("fake_source")
def test_attributes_plain():
global source
source = u"""
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert len(messages) == 1
assert messages[0].msgid == u"tést title"
assert messages[0].location[1] == 3
@pytest.mark.usefixtures("fake_source")
def test_custom_i18n_namespace():
global source
source = b"""
Foo
Foo
Foo
Foo
"""
messages = list(xml_extractor("filename", _options()))
assert len(messages) == 4
assert [m.msgid for m in messages] == [u"Foo"] * 4
assert [m.location[1] for m in messages] == [2, 5, 7, 8]
@pytest.mark.usefixtures("fake_source")
def test_attributes_explicit_MessageId():
global source
source = u"""
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert len(messages) == 1
assert messages[0].msgid == "msg_title"
assert messages[0].comment == u"Default: test tïtle"
assert messages[0].location[1] == 3
@pytest.mark.usefixtures("fake_source")
def test_attributes_no_domain_without_domain_filter():
global source
source = b"""
"""
messages = list(xml_extractor("filename", _options()))
assert len(messages) == 1
assert messages[0].location[1] == 2
@pytest.mark.usefixtures("fake_source")
def test_attributes_multiple_attributes():
global source
source = u"""
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert len(messages) == 2
assert [m.msgid for m in messages] == [u"tést title", u"test ålt"]
assert [m.location[1] for m in messages] == [3, 4]
@pytest.mark.usefixtures("fake_source")
def test_attributes_multiple_attributes_explicit_msgid():
global source
source = u"""
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert len(messages) == 2
assert messages[0].msgid == u"msg_title"
assert messages[0].comment == u"Default: test titlé"
assert messages[1].msgid == u"msg_alt"
assert messages[1].comment == u"Default: test ålt"
assert [m.location[1] for m in messages] == [4, 4]
@pytest.mark.usefixtures("fake_source")
def test_translate_minimal():
global source
source = u"""\
Dummy téxt
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert len(messages) == 1
assert messages[0].msgid == u"Dummy téxt"
assert messages[0].location[1] == 3
@pytest.mark.usefixtures("fake_source")
def test_translate_explicit_msgid():
global source
source = u"""\
Dummy téxt
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert len(messages) == 1
assert messages[0].msgid == u"msgid_dummy"
assert messages[0].comment == u"Default: Dummy téxt"
assert messages[0].location[1] == 3
@pytest.mark.usefixtures("fake_source")
def test_translate_subelement():
global source
source = u"""\
Dummy
text demø
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert len(messages) == 1
assert messages[0].msgid == u"msgid_dummy"
assert messages[0].comment == u"Default: Dummy demø"
assert messages[0].location[1] == 3
@pytest.mark.usefixtures("fake_source")
def test_translate_named_subelement():
global source
source = u"""\
Dummy
téxt demø
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert len(messages) == 1
assert messages[0].msgid == u"msgid_dummy"
assert messages[0].comment == u"Default: Dummy ${text} demø"
assert messages[0].location[1] == 3
@pytest.mark.usefixtures("fake_source")
def test_translate_translated_subelement():
global source
source = u"""\
Dummy
téxt
demø
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert len(messages) == 2
assert messages[0].msgid == u"téxt"
assert messages[0].comment == u'Used in sentence: "Dummy ${text} demø"'
assert messages[0].location[1] == 5
assert messages[1].msgid == u"Dummy ${text} demø"
assert messages[1].comment == u'Canonical text for ${text} is: "téxt"'
assert messages[1].location[1] == 3
@pytest.mark.usefixtures("fake_source")
def test_translate_translated_subelement_with_id():
global source
source = u"""\
Dummy
téxt
demø
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert len(messages) == 2
assert messages[0].msgid == u"msgid_text"
assert (
messages[0].comment == u'Default: téxt\nUsed in sentence: "Dummy ${text} demø"'
)
assert messages[0].location[1] == 5
assert messages[1].msgid == u"msgid_dummy"
assert (
messages[1].comment == u"Default: Dummy ${text} demø\n"
u'Canonical text for ${text} is: "téxt"'
)
assert messages[1].location[1] == 3
@pytest.mark.usefixtures("fake_source")
def test_strip_extra_whitespace():
global source
source = b"""\
Dummy
text
"""
messages = list(xml_extractor("filename", _options()))
assert messages[0].msgid == u"Dummy text"
assert messages[0].location[1] == 3
@pytest.mark.usefixtures("fake_source")
def test_strip_trailing_and_leading_whitespace():
global source
source = b"""\
Dummy text
"""
messages = list(xml_extractor("filename", _options()))
assert messages[0].msgid == u"Dummy text"
@pytest.mark.usefixtures("fake_source")
def test_html_entities():
global source
source = b"""\
"""
messages = list(xml_extractor("filename", _options()))
assert messages[0].msgid == u"Lock & load "
@pytest.mark.usefixtures("fake_source")
def test_ignore_undeclared_namespace():
global source
source = b"""\
Test
"""
messages = list(xml_extractor("filename", _options()))
assert messages[0].msgid == u"Test"
@pytest.mark.usefixtures("fake_source")
def test_ignore_dynamic_message():
global source
source = b"""\
${'dummy'}
"""
assert list(xml_extractor("filename", _options())) == []
@pytest.mark.usefixtures("fake_source")
def test_translate_call_in_python_expression_attribute():
global source
source = b"""\
Dummy
"""
messages = list(xml_extractor("filename", _options()))
assert messages[0].msgid == u"foo"
@pytest.mark.usefixtures("fake_source")
def test_translate_call_in_python_expression_repeat_attribute():
global source
source = b"""\
${label}
"""
messages = list(xml_extractor("filename", _options()))
assert messages[0].msgid == u"foo"
@pytest.mark.usefixtures("fake_source")
def test_translate_call_in_python_expression_in_char_data():
global source
source = b"""\
${_(u'foo')}
"""
messages = list(xml_extractor("filename", _options()))
assert messages[0].msgid == u"foo"
@pytest.mark.usefixtures("fake_source")
def test_translate_call_in_python_expression_in_attribute():
global source
source = b"""\
"""
messages = list(xml_extractor("filename", _options()))
assert messages[0].msgid == u"foo"
@pytest.mark.usefixtures("fake_source")
def test_multiple_expressions_with_translate_calls():
global source
source = b"""\
"""
messages = list(xml_extractor("filename", _options()))
assert messages[0].msgid == u"foo"
assert messages[1].msgid == u"bar"
@pytest.mark.usefixtures("fake_source")
def test_translate_multiple_defines():
global source
source = b"""\
"""
messages = list(xml_extractor("filename", _options()))
assert len(messages) == 2
assert messages[0].msgid == u"one"
assert messages[1].msgid == u"two"
@pytest.mark.usefixtures("fake_source")
def test_translate_explicit_python_expression_engine():
global source
source = b"""\
"""
messages = list(xml_extractor("filename", _options()))
assert len(messages) == 2
assert messages[0].msgid == u"one"
assert messages[1].msgid == u"two"
@pytest.mark.usefixtures("fake_source")
def test_translate_ignore_other_expression_engine():
global source
source = b"""\
"""
messages = list(xml_extractor("filename", _options()))
assert len(messages) == 1
assert messages[0].msgid == u"two"
@pytest.mark.usefixtures("fake_source")
def test_translate_ignore_other_expression_engine_with_numbers():
global source
source = b"""\
"""
messages = list(xml_extractor("filename", _options()))
assert len(messages) == 1
assert messages[0].msgid == u"two"
@pytest.mark.usefixtures("fake_source")
def test_translate_ignore_other_content_expression_engine_with_structure():
global source
source = b"""\
"""
messages = list(xml_extractor("filename", _options()))
assert len(messages) == 0
@pytest.mark.usefixtures("fake_source")
def test_translate_explicit_python_engine_with_structure():
global source
source = b"""\
"""
messages = list(xml_extractor("filename", _options()))
assert len(messages) == 1
assert messages[0].msgid == u"foo"
@pytest.mark.usefixtures("fake_source")
def test_translate_entities_in_python_expression():
global source
source = b"""\
"""
list(xml_extractor("filename", _options()))
@pytest.mark.usefixtures("fake_source")
def test_curly_brace_in_python_expression():
global source
source = b"""\
${request.route_url('set_locale', _query={'locale': 'de'})}
"""
list(xml_extractor("filename", _options()))
@pytest.mark.usefixtures("fake_source")
def test_curly_brace_in_python_attribute_expression():
global source
source = b"""\
"""
list(xml_extractor("filename", _options()))
@pytest.mark.usefixtures("fake_source")
def test_curly_brace_related_syntax_error():
global source
source = b"""\
"""
with pytest.raises(SystemExit):
list(xml_extractor("filename", _options()))
class Test_get_python_expression(object):
def test_no_expressions(self):
assert list(get_python_expressions("no python here", "python")) == []
def test_single_expression(self):
assert list(get_python_expressions("${some_python}", "python")) == [
"some_python"
]
def test_two_expressions(self):
assert list(get_python_expressions("${one} ${two}", "python")) == ["one", "two"]
def test_nested_braces(self):
assert list(
get_python_expressions(
"""${resource_url(_query={'one': 'one'})}""", "python"
)
) == ["""resource_url(_query={'one': 'one'})"""]
@pytest.mark.usefixtures("fake_source")
def test_python_expression_in_tales_expressions():
global source
source = u"""
Dummy
""".encode(
"utf-8"
)
assert list(xml_extractor("filename", _options())) == []
@pytest.mark.usefixtures("fake_source")
def test_ignore_structure_in_replace():
global source
source = u"""\
Dummy
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert messages[0].msgid == u"føo"
@pytest.mark.usefixtures("fake_source")
def test_repeat_multiple_assignment():
global source
source = u"""\
Dummy
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert messages[0].msgid == u"føo"
@pytest.mark.usefixtures("fake_source")
def test_carriage_return_in_define():
global source
source = u"""\
Dummy
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert messages[0].msgid == u"føo"
@pytest.mark.usefixtures("fake_source")
def test_multiline_replace():
global source
source = u"""\
Dummy
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert messages[0].msgid == u"føo"
@pytest.mark.usefixtures("fake_source")
def test_multiline_replace_with_structure():
global source
source = u"""\
Dummy
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert messages[0].msgid == u"føo"
@pytest.mark.usefixtures("fake_source")
def test_spaces_around_tal_pipe_symbol():
global source
source = u"""\
""".encode(
"utf-8"
)
list(xml_extractor("filename", _options()))
@pytest.mark.usefixtures("fake_source")
def test_empty_element():
global source
source = u"""\
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert len(messages) == 1
@pytest.mark.usefixtures("fake_source")
def test_brace_in_python_expression():
global source
source = u"""\
${some_method(_('abc'), {'a':'b'})}
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert len(messages) == 1
assert messages[0].msgid == u"abc"
@pytest.mark.usefixtures("fake_source")
def test_translation_context():
global source
source = u"""
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert messages[0].msgid == u"Save"
assert messages[0].msgctxt == u"form"
@pytest.mark.usefixtures("fake_source")
def test_translation_comment():
global source
source = u"""
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert messages[0].msgid == u"Save"
assert messages[0].comment == u"Generic save button"
@pytest.mark.usefixtures("fake_source")
def test_translation_comment_for_attribute():
global source
source = u"""
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert messages[0].msgid == u"Email address"
assert messages[0].comment == u"Placeholder text"
@pytest.mark.usefixtures("fake_source")
def test_translation_comment_and_msgid():
global source
source = u"""
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert messages[0].msgid == u"btn_save"
assert messages[0].comment == u"Generic save button\nDefault: Save"
@pytest.mark.usefixtures("fake_source")
def test_inherit_translation_comment():
global source
source = u"""
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert messages[0].msgid == u"Save"
assert messages[0].comment == u"Form buttons"
@pytest.mark.usefixtures("fake_source")
def test_linenumbers():
global source
source = u"""
Foo<
Foo
Foo
Foo ${value}
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
got = [(x.msgid, x.location[1]) for x in messages]
assert got == [("dummy1", 9), ("dummy2", 14), ("dummy3", 23), ("dummy4", 46)]
@pytest.mark.usefixtures("fake_source")
def test_domain_filter():
global source
source = u"""\
Dummy téxt
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options(domain="other")))
assert len(messages) == 0
@pytest.mark.usefixtures("fake_source")
def test_domain_filter_for_attribute():
global source
source = u"""\
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options(domain="other")))
assert len(messages) == 0
@pytest.mark.usefixtures("fake_source")
def test_domain_filter_for_expression():
global source
source = u"""\
${_(u'foo')}
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options(domain="other")))
assert len(messages) == 0
@pytest.mark.usefixtures("fake_source")
def test_context_for_attributes():
global source
source = u"""\
""".encode(
"utf-8"
)
messages = list(xml_extractor("filename", _options()))
assert len(messages) == 1
assert messages[0].msgctxt == "figure"