def test_template_parsing2(mock_find_files, mock_read, mock_push_strings):
    mock_find_files.return_value = [
        TranslatableFile('dir1/dir2', '1.html', 'locdir1'),
    ]
    mock_read.side_effect = [
        # 1.html
        HTML_TEMPLATE.replace(
            '{content}',
            u'<p>{% t "<b>Strong</b> {a}" a="A" _context="c1,c2" '
            u'_tags="t1,t2" _comment="comment1" _charlimit=22 '
            u'_key="first_key" %}</p>\n'

            u'<p>{% ut "παράδειγμα {b}" b="B" _context="c1,c2" '
            u'_tags="t1,t2" _comment="comment2" _charlimit=33 '
            u'_key="second_key" %}</p>'
        ),
    ]

    expected = [
        # 1.html
        SourceString(
            u'<b>Strong</b> {a}', 'c1,c2', _tags='t1,t2', _comment='comment1',
            _charlimit=22, _occurrences=['r1/dir2/1.html:4'],
            _key='first_key',
        ),
        SourceString(
            u'παράδειγμα {b}', 'c1,c2', _tags='t1,t2', _comment="comment2",
            _charlimit=33, _occurrences=['r1/dir2/1.html:5'],
            _key='second_key',
        ),
    ]
    run_and_compare(expected)
Exemplo n.º 2
0
 def test_push_strings_reaches_cds_handler(self, mock_push_strings):
     response = MagicMock()
     response.status_code = 200
     response.content = '{}'
     mock_push_strings.return_value = response
     strings = [SourceString('a'), SourceString('b')]
     mytx = self._get_tx()
     mytx.push_source_strings(strings, False)
     mock_push_strings.assert_called_once_with(strings, False)
Exemplo n.º 3
0
 def test_basic(self):
     src = TEMPLATE.replace(
         u'{{string1}}', u'{% t "A very important sentence" %}'
     ).replace(
         u'{{string2}}',
         u'{% t "I will look for {total} items" total=bucket.items|length %}'
     )
     strings = extract_transifex_template_strings(src)
     assert strings == [
         SourceString(u"A very important sentence"),
         SourceString(u"I will look for {total} items"),
     ]
def test_template_parsing(mock_find_files, mock_read, mock_push_strings):
    mock_find_files.return_value = [
        TranslatableFile('dir1/dir2', '1.html', 'locdir1'),
        TranslatableFile('dir4/dir5', '1.txt', 'locdir1'),
    ]
    mock_read.side_effect = [
        # 1.html
        HTML_TEMPLATE.replace(
            '{content}',
            u'<p>{% t "<b>Strong</b> {a}" a="A" _context="c1,c2" '
            u'_tags="t1,t2" _comment="comment1" _charlimit=22 %}</p>\n'

            u'<p>{% ut "παράδειγμα {b}" b="B" _context="c1,c2" '
            u'_tags="t1,t2" _comment="comment2" _charlimit=33 %}</p>'
        ),
        # 1.txt
        HTML_TEMPLATE.replace(
            '{content}',
            u'{% t _context="c1,c2" _tags="t1,t2" _comment="co1" _charlimit=22 %}\n'
            u'This is a short string\n'
            u'{% endt %}\n'

            u'{% t _context="c1,c2" _tags="t1,t2" _comment="co2" _charlimit=33 %}\n'
            u'This is not a shorter string\n'
            u'{% endt %}'
        ),
    ]

    expected = [
        # 1.html
        SourceString(
            u'<b>Strong</b> {a}', 'c1,c2', _tags='t1,t2', _comment="comment1",
            _charlimit=22, _occurrences=['r1/dir2/1.html:4'],
        ),
        SourceString(
            u'παράδειγμα {b}', 'c1,c2', _tags='t1,t2', _comment="comment2",
            _charlimit=33, _occurrences=['r1/dir2/1.html:5'],
        ),

        # 1.txt
        SourceString(
            u'\nThis is a short string\n', 'c1,c2', _tags='t1,t2',
            _comment="co1", _charlimit=22, _occurrences=['r4/dir5/1.txt:4'],
        ),
        SourceString(
            u'\nThis is not a shorter string\n', 'c1,c2', _tags='t1,t2',
            _comment="co2", _charlimit=33, _occurrences=['r4/dir5/1.txt:7'],
        ),
    ]
    run_and_compare(expected)
Exemplo n.º 5
0
    def test_registered_imports(self):
        # Test all combinations in multi-level imports
        # with a custom registered function
        ex = Extractor()
        ex.register_functions('module1.module2.module3.myfunc')

        src = TEMPLATE.format(
            _import=('from module1.module2 import module3 as m3\n'
                     'import module1.module2.module3 as _m3\n'),
            call1='m3.myfunc',
            call2='_m3.myfunc',
        )
        results = ex.extract_strings(src, 'myfile.py')
        assert results == self._strings()

        src = TEMPLATE.format(
            _import=('from module1 import module2 as m2\n'
                     'import module1.module2 as _m2\n'),
            call1='m2.module3.myfunc',
            call2='_m2.module3.myfunc',
        )
        results = ex.extract_strings(src, 'myfile.py')
        assert results == self._strings()

        src = TEMPLATE.format(
            _import='import module1 as _m1',
            call1='_m1.module2.module3.myfunc',
            call2='_m1.module2.module3.myfunc',
        )

        # mocking gets a little bit different here shifting occurrences
        expected = [
            SourceString(u'Le canapé',
                         u'désign',
                         param1='1',
                         param2=2,
                         param3=True,
                         _occurrences=['myfile.py:6']),
            SourceString(u'Les données',
                         u'opération',
                         _comment='comment',
                         _tags=['t1', 't2'],
                         _charlimit=33,
                         _occurrences=['myfile.py:7']),
        ]

        results = ex.extract_strings(src, 'myfile.py')
        assert results == expected
Exemplo n.º 6
0
    def test_push_strings_reaches_cds_handler(
        self, mock_push_strings, mock_get_status
    ):
        response = MagicMock()
        response.status_code = 202
        response.content = '{"data":{"links":{"job":"/job"}}}'
        mock_push_strings.return_value = response

        response = MagicMock()
        response.status_code = 200
        response.content = '{"data":{"status":"completed","details":{}}}'
        mock_get_status.return_value = response

        strings = [SourceString('a'), SourceString('b')]
        mytx = self._get_tx()
        mytx.push_source_strings(strings, False)
        mock_push_strings.assert_called_once_with(strings, False)
Exemplo n.º 7
0
 def test_default_values(self):
     string = SourceString('something')
     assert string.string == 'something'
     assert string.context is None
     assert string.meta == {}
     assert string.developer_comment is None
     assert string.character_limit is None
     assert string.tags == []
Exemplo n.º 8
0
    def test_push_source_strings(self, patched_logger):
        cds_host = 'https://some.host'
        cds_handler = CDSHandler(['el', 'en'],
                                 'some_token',
                                 secret='some_secret',
                                 host=cds_host)

        # test push no content
        responses.add(responses.POST,
                      cds_host + '/content/',
                      status=200,
                      json={'data': []})

        cds_handler.push_source_strings([], False)
        assert patched_logger.error.call_count == 0

        # test push with content
        responses.add(responses.POST,
                      cds_host + '/content/',
                      status=200,
                      json={'data': []})

        source_string = SourceString('some_string')
        cds_handler.push_source_strings([source_string], False)
        assert patched_logger.error.call_count == 0
        responses.reset()

        # test wrong data format
        responses.add(responses.POST,
                      cds_host + '/content/',
                      status=422,
                      json={
                          "status":
                          422,
                          "message":
                          "Invalid Payload",
                          "details": [{
                              "message": "\"string\" is required",
                              "path": ["some_key1", "string"],
                              "type": "any.required",
                              "context": {
                                  "key": "string",
                                  "label": "string"
                              }
                          }]
                      })
        # we don't care about the payload this time, just want to
        # see how the service handles the errors
        cds_handler.push_source_strings([], False)
        # The actual error message differs between Python 2 and Python 3
        messages = [
            'Error pushing source strings to CDS: UnknownError '
            '(`422 Client Error: {err} for url: '
            'https://some.host/content/`)'.format(err=x)
            for x in ('Unprocessable Entity', 'None')
        ]
        assert patched_logger.error.call_args[0][0] in messages
Exemplo n.º 9
0
 def _strings(self):
     return [
         SourceString(
             u'Le canapé',
             u'désign',
             param1='1',
             param2=2,
             param3=True,
             _occurrences=['myfile.py:8'],
         ),
         SourceString(
             u'Les données',
             u'opération',
             _comment='comment',
             _tags=['t1', 't2'],
             _charlimit=33,
             _occurrences=['myfile.py:9'],
         ),
     ]
Exemplo n.º 10
0
 def test_all_string_params(self):
     src = TEMPLATE.replace(
         u'{{string1}}', u'{%t "Le canapé" '
         u'_context="furniture" _comment="_comment" _charlimit=10 '
         u'_tags="t1,t2" %}')
     strings = extract_transifex_template_strings(src)
     assert strings == [
         SourceString(u"Le canapé",
                      _context=u'furniture',
                      _comment=u'_comment',
                      _charlimit=10,
                      _tags=['t1', 't2']),
     ]
Exemplo n.º 11
0
 def test_custom_meta(self):
     string = SourceString(
         'something',
         _context='one,two,three',
         _comment='A crucial comment',
         _charlimit=33,
         _tags=' t1,t2 ,  t3',
         custom='custom',
     )
     assert string.string == 'something'
     assert string.context == ['one', 'two', 'three']
     assert string.developer_comment == 'A crucial comment'
     assert string.character_limit == 33
     assert string.tags == ['t1', 't2', 't3']
     assert string.meta.get('custom') is None
Exemplo n.º 12
0
def tnode_to_source_string(tnode):
    """ Convert a parsed TNode to a SourceString instance.

        TNode is what the template tag implementation will return having
        processed the contents from the template. A SourceString is a data
        object which exposes information in a useful way for pushing to
        transifex.
    """
    if not isinstance(tnode.source_string.var, string_types):
        return None
    meta = {}
    for key, value in tnode.params.items():
        if len(value.filters) != 0:
            continue
        if isinstance(value.var, string_types):
            meta[key] = value.var
        elif getattr(value.var, 'literal', None) is not None:
            meta[key] = value.var.literal
    _context = meta.pop('_context', None)
    return SourceString(tnode.source_string.var, _context, **meta)
Exemplo n.º 13
0
    def test_multiline(self):
        src = TEMPLATE.replace(
            u'{{string1}}', u"""
{% t visit_type='first' username=user.name _context="stuff" _charlimit=10 %}
{visit_type, select,
    first {Welcome, {username}}
    returning {Welcome back, {username}}
}
{% endt %}""")
        strings = extract_transifex_template_strings(src)
        assert strings[0] == SourceString(
            u"""
{visit_type, select,
    first {Welcome, {username}}
    returning {Welcome back, {username}}
}
""",
            _context='stuff',
            _charlimit=10,
        )
def clone_string(source_string, new_tags=None):
    """Create a new SourceString instance, identical to the one given,
    by optionally replacing its tags with the ones given.

    :param SourceString source_string: the string to clone
    :param list new_tags: a list of strings to use as the tags
        for the new string
    :rtype: SourceString
    :return: a new SourceString instance
    """
    cloned_string = SourceString(
        source_string.string,
        _context=(
            ','.join(source_string.context)
            if source_string.context else ''
        ),
        **source_string.meta
    )
    if new_tags is not None:
        cloned_string.meta[consts.KEY_TAGS] = new_tags
    return cloned_string
Exemplo n.º 15
0
 def test_tag_list(self):
     string = SourceString(
         'something',
         _tags=['t1', 't2', 't3'],
     )
     assert string.tags == ['t1', 't2', 't3']
Exemplo n.º 16
0
def test_python_parsing_push_exception(mock_find_files, mock_read,
                                       mock_push_strings):
    mock_push_strings.return_value = 500, "content_to_trigger_exception"
    mock_find_files.return_value = [
        TranslatableFile('dir1', '1.py', 'locdir1'),
        TranslatableFile('dir1/dir2', '2.py', 'locdir1'),
        TranslatableFile('dir1/dir3', '3.py', 'locdir1'),
    ]
    mock_read.side_effect = [
        # 1.py
        PYTHON_TEMPLATE.format(
            _import='import transifex.native',
            call1='native.translate',
            call2='native.translate',
            string1=u'Le canapé',
            string2=u'Les données',
        ),
        # 2.py
        PYTHON_TEMPLATE.format(
            _import='import transifex.native as _n',
            call1='_n.translate',
            call2='_n.translate',
            string1=u'Le canapé 2',
            string2=u'Les données 2',
        ),
        # 3.py
        PYTHON_TEMPLATE.format(
            _import='from transifex.native import translate',
            call1='translate',
            call2='translate',
            string1=u'Le canapé 3',
            string2=u'Les données 3',
        ),
    ]

    expected = [
        # 1.py
        SourceString(
            u'Le canapé',
            u'désign1,désign2',
            _occurrences=['r1/1.py:6'],
        ),
        SourceString(
            u'Les données',
            u'opération',
            _comment='comment',
            _tags='t1,t2',
            _charlimit=33,
            _occurrences=['r1/1.py:7'],
        ),
        # 2.py
        SourceString(
            u'Le canapé 2',
            u'désign1,désign2',
            _occurrences=['r1/dir2/2.py:6'],
        ),
        SourceString(
            u'Les données 2',
            u'opération',
            _comment='comment',
            _tags='t1,t2',
            _charlimit=33,
            _occurrences=['r1/dir2/2.py:7'],
        ),
        # 3.py
        SourceString(
            u'Le canapé 3',
            u'désign1,désign2',
            _occurrences=['r1/dir3/3.py:6'],
        ),
        SourceString(
            u'Les données 3',
            u'opération',
            _comment='comment',
            _tags='t1,t2',
            _charlimit=33,
            _occurrences=['r1/dir3/3.py:7'],
        ),
    ]
    compare(expected)
        string1=u'Le canapé 2',
        string2=u'Les données 2',
    ),
    # 3.py
    PYTHON_TEMPLATE.format(
        _import='from transifex.native import translate',
        call1='translate',
        call2='translate',
        string1=u'Le canapé 3',
        string2=u'Les données 3',
    ),
]

SOURCE_STRINGS = [
    # 1.py
    SourceString(u'Le canapé', u'désign1,désign2',
                 _occurrences=['r1/1.py:6'],),
    SourceString(
        u'Les données', u'opération', _comment='comment', _tags='t1,t2',
        _charlimit=33, _occurrences=['r1/1.py:7'],
    ),
    # 2.py
    SourceString(u'Le canapé 2', u'désign1,désign2',
                 _occurrences=['r1/dir2/2.py:6'],),
    SourceString(
        u'Les données 2', u'opération', _comment='comment', _tags='t1,t2',
        _charlimit=33, _occurrences=['r1/dir2/2.py:7'],
    ),
    # 3.py
    SourceString(u'Le canapé 3', u'désign1,désign2',
                 _occurrences=['r1/dir3/3.py:6'],),
    SourceString(