summaryrefslogtreecommitdiff
path: root/tests/i18n/test_percents.py
blob: 412b01300116604776149613e4c977eb7e0ef82f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
import os

from django.template import Context, Template
from django.test import SimpleTestCase, override_settings
from django.utils.translation import activate, get_language, trans_real

from .utils import POFileAssertionMixin

SAMPLEPROJECT_DIR = os.path.join(
    os.path.dirname(os.path.abspath(__file__)), "sampleproject"
)
SAMPLEPROJECT_LOCALE = os.path.join(SAMPLEPROJECT_DIR, "locale")


@override_settings(LOCALE_PATHS=[SAMPLEPROJECT_LOCALE])
class FrenchTestCase(SimpleTestCase):
    """Tests using the French translations of the sampleproject."""

    PO_FILE = os.path.join(SAMPLEPROJECT_LOCALE, "fr", "LC_MESSAGES", "django.po")

    def setUp(self):
        self._language = get_language()
        self._translations = trans_real._translations
        activate("fr")

    def tearDown(self):
        trans_real._translations = self._translations
        activate(self._language)


class ExtractingStringsWithPercentSigns(POFileAssertionMixin, FrenchTestCase):
    """
    Tests the extracted string found in the gettext catalog.

    Percent signs are python formatted.

    These tests should all have an analogous translation tests below, ensuring
    the Python formatting does not persist through to a rendered template.
    """

    def setUp(self):
        super().setUp()
        with open(self.PO_FILE) as fp:
            self.po_contents = fp.read()

    def test_trans_tag_with_percent_symbol_at_the_end(self):
        self.assertMsgId(
            "Literal with a percent symbol at the end %%", self.po_contents
        )

    def test_trans_tag_with_percent_symbol_in_the_middle(self):
        self.assertMsgId(
            "Literal with a percent %% symbol in the middle", self.po_contents
        )
        self.assertMsgId("It is 100%%", self.po_contents)

    def test_trans_tag_with_string_that_look_like_fmt_spec(self):
        self.assertMsgId(
            "Looks like a str fmt spec %%s but should not be interpreted as such",
            self.po_contents,
        )
        self.assertMsgId(
            "Looks like a str fmt spec %% o but should not be interpreted as such",
            self.po_contents,
        )

    def test_adds_python_format_to_all_percent_signs(self):
        self.assertMsgId(
            "1 percent sign %%, 2 percent signs %%%%, 3 percent signs %%%%%%",
            self.po_contents,
        )
        self.assertMsgId(
            "%(name)s says: 1 percent sign %%, 2 percent signs %%%%", self.po_contents
        )


class RenderingTemplatesWithPercentSigns(FrenchTestCase):
    """
    Test rendering of templates that use percent signs.

    Ensures both translate and blocktranslate tags behave consistently.

    Refs #11240, #11966, #24257
    """

    def test_translates_with_a_percent_symbol_at_the_end(self):
        expected = "Littérale avec un symbole de pour cent à la fin %"

        trans_tpl = Template(
            "{% load i18n %}"
            '{% translate "Literal with a percent symbol at the end %" %}'
        )
        self.assertEqual(trans_tpl.render(Context({})), expected)

        block_tpl = Template(
            "{% load i18n %}{% blocktranslate %}Literal with a percent symbol at "
            "the end %{% endblocktranslate %}"
        )
        self.assertEqual(block_tpl.render(Context({})), expected)

    def test_translates_with_percent_symbol_in_the_middle(self):
        expected = "Pour cent littérale % avec un symbole au milieu"

        trans_tpl = Template(
            "{% load i18n %}"
            '{% translate "Literal with a percent % symbol in the middle" %}'
        )
        self.assertEqual(trans_tpl.render(Context({})), expected)

        block_tpl = Template(
            "{% load i18n %}{% blocktranslate %}Literal with a percent % symbol "
            "in the middle{% endblocktranslate %}"
        )
        self.assertEqual(block_tpl.render(Context({})), expected)

    def test_translates_with_percent_symbol_using_context(self):
        trans_tpl = Template('{% load i18n %}{% translate "It is 100%" %}')
        self.assertEqual(trans_tpl.render(Context({})), "Il est de 100%")
        trans_tpl = Template(
            '{% load i18n %}{% translate "It is 100%" context "female" %}'
        )
        self.assertEqual(trans_tpl.render(Context({})), "Elle est de 100%")

        block_tpl = Template(
            "{% load i18n %}{% blocktranslate %}It is 100%{% endblocktranslate %}"
        )
        self.assertEqual(block_tpl.render(Context({})), "Il est de 100%")
        block_tpl = Template(
            "{% load i18n %}"
            '{% blocktranslate context "female" %}It is 100%{% endblocktranslate %}'
        )
        self.assertEqual(block_tpl.render(Context({})), "Elle est de 100%")

    def test_translates_with_string_that_look_like_fmt_spec_with_trans(self):
        # tests "%s"
        expected = (
            "On dirait un spec str fmt %s mais ne devrait pas être interprété comme "
            "plus disponible"
        )
        trans_tpl = Template(
            '{% load i18n %}{% translate "Looks like a str fmt spec %s but '
            'should not be interpreted as such" %}'
        )
        self.assertEqual(trans_tpl.render(Context({})), expected)
        block_tpl = Template(
            "{% load i18n %}{% blocktranslate %}Looks like a str fmt spec %s but "
            "should not be interpreted as such{% endblocktranslate %}"
        )
        self.assertEqual(block_tpl.render(Context({})), expected)

        # tests "% o"
        expected = (
            "On dirait un spec str fmt % o mais ne devrait pas être interprété comme "
            "plus disponible"
        )
        trans_tpl = Template(
            "{% load i18n %}"
            '{% translate "Looks like a str fmt spec % o but should not be '
            'interpreted as such" %}'
        )
        self.assertEqual(trans_tpl.render(Context({})), expected)
        block_tpl = Template(
            "{% load i18n %}"
            "{% blocktranslate %}Looks like a str fmt spec % o but should not be "
            "interpreted as such{% endblocktranslate %}"
        )
        self.assertEqual(block_tpl.render(Context({})), expected)

    def test_translates_multiple_percent_signs(self):
        expected = (
            "1 % signe pour cent, signes %% 2 pour cent, trois signes de pourcentage "
            "%%%"
        )
        trans_tpl = Template(
            '{% load i18n %}{% translate "1 percent sign %, 2 percent signs %%, '
            '3 percent signs %%%" %}'
        )
        self.assertEqual(trans_tpl.render(Context({})), expected)
        block_tpl = Template(
            "{% load i18n %}{% blocktranslate %}1 percent sign %, 2 percent signs "
            "%%, 3 percent signs %%%{% endblocktranslate %}"
        )
        self.assertEqual(block_tpl.render(Context({})), expected)

        block_tpl = Template(
            "{% load i18n %}{% blocktranslate %}{{name}} says: 1 percent sign %, "
            "2 percent signs %%{% endblocktranslate %}"
        )
        self.assertEqual(
            block_tpl.render(Context({"name": "Django"})),
            "Django dit: 1 pour cent signe %, deux signes de pourcentage %%",
        )