Total Complexity | 30 |
Total Lines | 246 |
Duplicated Lines | 13.01 % |
Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
1 | from __future__ import unicode_literals |
||
8 | class ModelAttributeTests(AppTestCase): |
||
9 | """ |
||
10 | Test model construction |
||
11 | """ |
||
12 | |||
13 | def test_untranslated_get(self): |
||
14 | """ |
||
15 | Test the metaclass of the model. |
||
16 | """ |
||
17 | try: |
||
18 | value = SimpleModel().tr_title |
||
19 | except Exception as e: |
||
20 | self.assertIsInstance(e, TranslationDoesNotExist) |
||
21 | self.assertIsInstance(e, AttributeError) |
||
22 | else: |
||
23 | self.fail("Expected exception from reading untranslated title, got {0}.".format(repr(value))) |
||
24 | |||
25 | # Raising attribute error gives some additional benefits: |
||
26 | self.assertEqual(getattr(SimpleModel(), 'tr_title', 'FOO'), 'FOO') |
||
27 | self.assertFalse(hasattr(SimpleModel(), 'tr_title')) |
||
28 | |||
29 | def test_default_language(self): |
||
30 | """ |
||
31 | Test whether simple language assignments work. |
||
32 | """ |
||
33 | with translation.override('ca-fr'): |
||
34 | x = SimpleModel(id=99) # uses get_language(), ID is to avoid reading cached items for 'en' |
||
35 | self.assertEqual(x.get_current_language(), translation.get_language()) |
||
36 | self.assertEqual(translation.get_language(), 'ca-fr') |
||
37 | |||
38 | x.shared = 'SHARED' |
||
39 | x.tr_title = 'TRANS_CA' |
||
40 | x.save() |
||
41 | |||
42 | # Refetch |
||
43 | with translation.override('en'): |
||
44 | x = SimpleModel.objects.get(pk=x.pk) |
||
45 | self.assertRaises(TranslationDoesNotExist, lambda: x.tr_title) |
||
46 | |||
47 | # Switch context |
||
48 | x.set_current_language('ca-fr') |
||
49 | self.assertEqual(x.tr_title, 'TRANS_CA') |
||
50 | |||
51 | def test_init_args(self): |
||
52 | """ |
||
53 | Test whether passing translated attributes to __init__() works. |
||
54 | """ |
||
55 | x = SimpleModel(tr_title='TRANS_TITLE') |
||
56 | self.assertEqual(x.tr_title, "TRANS_TITLE") |
||
57 | |||
58 | y = SimpleModel(tr_title='TRANS_TITLE', _current_language='nl') |
||
59 | self.assertEqual(y.get_current_language(), 'nl') |
||
60 | self.assertEqual(y.tr_title, "TRANS_TITLE") |
||
61 | |||
62 | def test_create_args(self): |
||
63 | y = SimpleModel.objects.language('nl').create(tr_title='TRANS_TITLE') |
||
64 | self.assertEqual(y.get_current_language(), 'nl') |
||
65 | self.assertEqual(y.tr_title, "TRANS_TITLE") |
||
66 | |||
67 | def test_save_multiple(self): |
||
68 | """ |
||
69 | Test the save_translations() function to store multiple languages. |
||
70 | """ |
||
71 | x = SimpleModel() |
||
72 | x.set_current_language('en') |
||
73 | x.tr_title = "TITLE_EN" |
||
74 | x.set_current_language('fr') |
||
75 | x.tr_title = "TITLE_FR" |
||
76 | x.set_current_language('es') |
||
77 | x.tr_title = "TITLE_ES" |
||
78 | x.set_current_language('nl') |
||
79 | x.tr_title = "TITLE_NL" |
||
80 | |||
81 | x.save() |
||
82 | |||
83 | # Check if all translations are saved. |
||
84 | self.assertEqual(sorted(x.translations.values_list('tr_title', flat=True)), ['TITLE_EN', 'TITLE_ES', 'TITLE_FR', 'TITLE_NL']) |
||
85 | self.assertEqual(sorted(x.get_available_languages()), ['en', 'es', 'fr', 'nl']) |
||
86 | self.assertTrue(x.has_translation('en')) |
||
87 | self.assertTrue(x.has_translation('es')) |
||
88 | self.assertFalse(x.has_translation('fi')) |
||
89 | |||
90 | # Update 2 translations. |
||
91 | # Only those should be updated in the database. |
||
92 | x.set_current_language('es') |
||
93 | x.tr_title = "TITLE_ES2" |
||
94 | x.set_current_language('nl') |
||
95 | x.tr_title = "TITLE_NL2" |
||
96 | |||
97 | self.assertNumQueries(2, x.save_translations()) |
||
98 | |||
99 | # Any unmodified language is not saved. |
||
100 | x.set_current_language('it', initialize=True) |
||
101 | self.assertTrue(x.has_translation('it')) # does return true for this object. |
||
102 | self.assertNumQueries(0, x.save_translations()) |
||
103 | self.assertEqual(sorted(x.get_available_languages()), ['en', 'es', 'fr', 'nl']) |
||
104 | |||
105 | def test_empty_model(self): |
||
106 | """ |
||
107 | Test whether a translated model without any fields still works. |
||
108 | """ |
||
109 | x = EmptyModel() |
||
110 | x.set_current_language('en', initialize=True) |
||
111 | x.set_current_language('fr', initialize=True) |
||
112 | x.set_current_language('es') |
||
113 | x.set_current_language('nl', initialize=True) |
||
114 | x.save() |
||
115 | |||
116 | self.assertEqual(sorted(x.get_available_languages()), ['en', 'fr', 'nl']) |
||
117 | |||
118 | def test_create_translation(self): |
||
119 | x = SimpleModel.objects.create() |
||
120 | x.create_translation('en', tr_title='TITLE_EN') |
||
121 | x.create_translation('fr', tr_title='TITLE_FR') |
||
122 | |||
123 | self.assertEqual(sorted(x.get_available_languages()), ['en', 'fr']) |
||
124 | |||
125 | def test_fallback_language(self): |
||
126 | """ |
||
127 | Test whether the fallback language will be returned. |
||
128 | """ |
||
129 | x = SimpleModel() |
||
130 | x.set_current_language(self.conf_fallback) |
||
131 | x.tr_title = "TITLE_FALLBACK" |
||
132 | |||
133 | x.set_current_language(self.other_lang1) |
||
134 | x.tr_title = 'TITLE_XX' |
||
135 | x.save() |
||
136 | |||
137 | with translation.override(self.other_lang2): |
||
138 | x = SimpleModel.objects.get(pk=x.pk) |
||
139 | self.assertEqual(x.tr_title, 'TITLE_FALLBACK') |
||
140 | |||
141 | def test_fallback_variant(self): |
||
142 | """Test de-us falls back to de""" |
||
143 | x = SimpleModel() |
||
144 | |||
145 | x.set_current_language('de') |
||
146 | x.tr_title = "Hallo-de" |
||
147 | |||
148 | x.set_current_language('en') |
||
149 | x.tr_title = "Hello-en" |
||
150 | |||
151 | x.save() |
||
152 | |||
153 | with translation.override('de-ch'): |
||
154 | x = SimpleModel.objects.get(pk=x.pk) |
||
155 | self.assertEqual(x.tr_title, 'Hallo-de') |
||
156 | |||
157 | def test_fallback_language_no_current(self): |
||
158 | """ |
||
159 | Test whether the fallback language will be returned, |
||
160 | even when the current language does not have a translation. |
||
161 | """ |
||
162 | x = SimpleModel() |
||
163 | x.set_current_language(self.conf_fallback) |
||
164 | x.tr_title = "TITLE_FALLBACK" |
||
165 | |||
166 | self.assertEqual( |
||
167 | x.safe_translation_getter('tr_title', language_code=self.other_lang1), |
||
168 | 'TITLE_FALLBACK') |
||
169 | |||
170 | View Code Duplication | def test_any_fallback_model(self): |
|
|
|||
171 | """ |
||
172 | Test whether a failure in the fallback language can return any saved language (if configured for it). |
||
173 | """ |
||
174 | x = AnyLanguageModel() |
||
175 | x.set_current_language(self.other_lang1) |
||
176 | x.tr_title = "TITLE_XX" |
||
177 | |||
178 | x.save() |
||
179 | |||
180 | with translation.override(self.other_lang2): |
||
181 | x = AnyLanguageModel.objects.get(pk=x.pk) |
||
182 | self.assertRaises(TranslationDoesNotExist, lambda: x._get_translated_model(use_fallback=True)) |
||
183 | self.assertEqual(x.tr_title, 'TITLE_XX') # Even though there is no current language, there is a value. |
||
184 | |||
185 | self.assertNumQueries(0, lambda: x._get_any_translated_model()) # Can fetch from cache next time. |
||
186 | self.assertEqual(x._get_any_translated_model().language_code, self.other_lang1) |
||
187 | |||
188 | View Code Duplication | def test_any_fallback_function(self): |
|
189 | x = SimpleModel() |
||
190 | x.set_current_language(self.other_lang1) |
||
191 | x.tr_title = "TITLE_XX" |
||
192 | |||
193 | x.save() |
||
194 | |||
195 | with translation.override(self.other_lang2): |
||
196 | x = SimpleModel.objects.get(pk=x.pk) |
||
197 | self.assertRaises(TranslationDoesNotExist, lambda: x._get_translated_model(use_fallback=True)) |
||
198 | self.assertIs(x.safe_translation_getter('tr_title', 'DEFAULT'), 'DEFAULT') # No lanuage, gives default |
||
199 | self.assertEqual(x.safe_translation_getter('tr_title', any_language=True), 'TITLE_XX') # Even though there is no current language, there is a value. |
||
200 | |||
201 | self.assertNumQueries(0, lambda: x._get_any_translated_model()) # Can fetch from cache next time. |
||
202 | self.assertEqual(x._get_any_translated_model().language_code, self.other_lang1) |
||
203 | |||
204 | def test_save_ignore_fallback_marker(self): |
||
205 | """ |
||
206 | Test whether the ``save_translations()`` method skips fallback languages |
||
207 | """ |
||
208 | x = SimpleModel() |
||
209 | x.set_current_language(self.other_lang1) |
||
210 | x.tr_title = "TITLE_XX" |
||
211 | x.set_current_language(self.other_lang2) |
||
212 | # try fetching, causing an fallback marker |
||
213 | x.safe_translation_getter('tr_title', any_language=True) |
||
214 | # Now save. This should not raise errors |
||
215 | x.save() |
||
216 | |||
217 | def test_model_with_zero_pk(self): |
||
218 | """ |
||
219 | tests that the translated model is returned also when the pk is 0 |
||
220 | """ |
||
221 | x = SimpleModel() |
||
222 | x.set_current_language(self.other_lang1) |
||
223 | x.pk = 0 |
||
224 | x.tr_title = "EMPTY_PK" |
||
225 | |||
226 | x.save() |
||
227 | |||
228 | # now fetch it from db |
||
229 | try: |
||
230 | SimpleModel.objects.get(pk=x.pk) |
||
231 | except TranslationDoesNotExist: |
||
232 | self.fail("zero pk is not supported!") |
||
233 | |||
234 | def test_translatedfieldsmodel_str(self): |
||
235 | """Test converting TranslatedFieldsModel to string""" |
||
236 | missing_language_code = 'xx' |
||
237 | obj = SimpleModel.objects.create(tr_title='Something') |
||
238 | |||
239 | # Adjust translation object to use language_code that is not |
||
240 | # configured. It is easier because various Django version behave |
||
241 | # differently if we try to use not configured language. |
||
242 | translation = obj.translations.get() |
||
243 | translation.language_code = missing_language_code |
||
244 | translation.save() |
||
245 | # Try to get str() of the TranslatedFieldsModel instance. |
||
246 | try: |
||
247 | translation_as_str = str(obj.translations.get()) |
||
248 | except KeyError: |
||
249 | self.fail("Converting translation to string raises KeyError") |
||
250 | |||
251 | # Check that we get language code as a fallback, when language is |
||
252 | # not configured. |
||
253 | self.assertEqual(translation_as_str, missing_language_code) |
||
254 |