|
7 | 7 |
|
8 | 8 | from __future__ import annotations |
9 | 9 |
|
| 10 | +import csv |
10 | 11 | import os.path |
11 | 12 | import shutil |
12 | 13 | from abc import ABC, abstractmethod |
|
27 | 28 | CatkeysFormat, |
28 | 29 | CSVFormat, |
29 | 30 | CSVSimpleFormat, |
| 31 | + CSVUtf8SimpleFormat, |
30 | 32 | DTDFormat, |
31 | 33 | FlatXMLFormat, |
32 | 34 | FluentFormat, |
|
69 | 71 | TEST_PO = get_test_file("cs.po") |
70 | 72 | TEST_CSV = get_test_file("cs-mono.csv") |
71 | 73 | TEST_CSV_NOHEAD = get_test_file("cs.csv") |
| 74 | +TEST_CSV_SIMPLE_EN = get_test_file("en-simple.csv") |
| 75 | +TEST_CSV_SIMPLE_PL = get_test_file("pl-simple.csv") |
72 | 76 | TEST_FLATXML = get_test_file("cs-flat.xml") |
73 | 77 | TEST_CUSTOM_FLATXML = get_test_file("cs-flat-custom.xml") |
74 | 78 | TEST_RESOURCEDICTIONARY = get_test_file("cs.xaml") |
@@ -1088,6 +1092,79 @@ class CSVSimpleFormatNoHeadTest(CSVFormatNoHeadTest): |
1088 | 1092 | EXPECTED_FLAGS: ClassVar[str | list[str]] = "" |
1089 | 1093 |
|
1090 | 1094 |
|
| 1095 | +class CSVUtf8SimpleFormatMonolingualTest(FixtureTestCase, TempDirMixin): |
| 1096 | + """Test for CSV Simple UTF-8 format with monolingual base file.""" |
| 1097 | + |
| 1098 | + def setUp(self) -> None: |
| 1099 | + super().setUp() |
| 1100 | + self.create_temp() |
| 1101 | + |
| 1102 | + def tearDown(self) -> None: |
| 1103 | + super().tearDown() |
| 1104 | + self.remove_temp() |
| 1105 | + |
| 1106 | + def test_save_preserves_source_field(self) -> None: |
| 1107 | + """ |
| 1108 | + Test that saving a CSV Simple file preserves source fields. |
| 1109 | +
|
| 1110 | + This reproduces the issue where translations are saved with empty source |
| 1111 | + fields instead of preserving the context/key from the base file. |
| 1112 | +
|
| 1113 | + Relies on translate-toolkit's monolingual CSV support (PR #5830). |
| 1114 | + See: https://github.com/WeblateOrg/weblate/issues/16835 |
| 1115 | + """ |
| 1116 | + # Create a temporary copy of the translation file |
| 1117 | + translation_file = os.path.join(self.tempdir, "pl.csv") |
| 1118 | + content = Path(TEST_CSV_SIMPLE_PL).read_bytes() |
| 1119 | + Path(translation_file).write_bytes(content) |
| 1120 | + |
| 1121 | + # Load the base file (template) |
| 1122 | + template_store = CSVUtf8SimpleFormat(TEST_CSV_SIMPLE_EN, is_template=True) |
| 1123 | + |
| 1124 | + # Load the translation file with the template |
| 1125 | + store = CSVUtf8SimpleFormat( |
| 1126 | + translation_file, template_store=template_store, language_code="pl" |
| 1127 | + ) |
| 1128 | + |
| 1129 | + # Verify we have the expected units |
| 1130 | + units = list(store.content_units) |
| 1131 | + self.assertEqual(len(units), 5) |
| 1132 | + |
| 1133 | + # Find units and add translations |
| 1134 | + for unit in units: |
| 1135 | + if unit.context == "objectAccessDenied": |
| 1136 | + pounit, add = store.find_unit(unit.context, unit.source) |
| 1137 | + self.assertTrue(add) |
| 1138 | + store.add_unit(pounit) |
| 1139 | + pounit.set_target("Nie masz uprawnien do modyfikowania obiektu '%s'") |
| 1140 | + elif unit.context == "propAccessDenied": |
| 1141 | + pounit, add = store.find_unit(unit.context, unit.source) |
| 1142 | + self.assertTrue(add) |
| 1143 | + store.add_unit(pounit) |
| 1144 | + pounit.set_target( |
| 1145 | + "Nie masz uprawnien do modyfikowania wlasciwosci: %s (tytul obiektu: %s)" |
| 1146 | + ) |
| 1147 | + elif unit.context == "noReadPermission": |
| 1148 | + pounit, add = store.find_unit(unit.context, unit.source) |
| 1149 | + self.assertTrue(add) |
| 1150 | + store.add_unit(pounit) |
| 1151 | + pounit.set_target("Nie masz uprawnien do odczytu obiektu '%s'") |
| 1152 | + |
| 1153 | + # Save the file |
| 1154 | + store.save() |
| 1155 | + |
| 1156 | + # Verify the saved content |
| 1157 | + with open(translation_file, encoding="utf-8") as handle: |
| 1158 | + reader = csv.reader(handle, delimiter=";", quotechar='"') |
| 1159 | + for row in reader: |
| 1160 | + self.assertEqual(len(row), 2) |
| 1161 | + self.assertNotEqual( |
| 1162 | + row[0], |
| 1163 | + "", |
| 1164 | + f"Source field is empty for target: {row[1]}", |
| 1165 | + ) |
| 1166 | + |
| 1167 | + |
1091 | 1168 | class FlatXMLFormatTest(BaseFormatTest): |
1092 | 1169 | format_class = FlatXMLFormat |
1093 | 1170 | FILE = TEST_FLATXML |
|
0 commit comments