migrate to gitea
This commit is contained in:
188
tests/test_xml_processor.py
Normal file
188
tests/test_xml_processor.py
Normal file
@@ -0,0 +1,188 @@
|
||||
"""
|
||||
Tests for XML processor module
|
||||
"""
|
||||
|
||||
import unittest
|
||||
import tempfile
|
||||
import os
|
||||
from lxml import etree
|
||||
from unittest.mock import patch, MagicMock
|
||||
from config import Config
|
||||
from models import TranslationItem
|
||||
from xml_processor import XMLProcessor
|
||||
|
||||
|
||||
class TestXMLProcessor(unittest.TestCase):
|
||||
"""Test cases for XMLProcessor class"""
|
||||
|
||||
def setUp(self):
|
||||
"""Set up test fixtures"""
|
||||
# Create a mock config
|
||||
self.mock_config = MagicMock(spec=Config)
|
||||
self.mock_config.output_config = {
|
||||
'create_backups': True,
|
||||
'backup_suffix': '.backup'
|
||||
}
|
||||
|
||||
self.processor = XMLProcessor(self.mock_config)
|
||||
|
||||
# Sample XML content (without XML declaration for testing)
|
||||
self.sample_xml = '''<resources>
|
||||
<string name="app_name">Test App</string>
|
||||
<string name="welcome_message">Welcome to our app!</string>
|
||||
<!-- This is a comment -->
|
||||
<string name="button_ok">OK</string>
|
||||
</resources>'''
|
||||
|
||||
def test_load_xml_file_success(self):
|
||||
"""Test successful XML file loading"""
|
||||
with tempfile.NamedTemporaryFile(mode='w', suffix='.xml', delete=False) as f:
|
||||
f.write(self.sample_xml)
|
||||
temp_path = f.name
|
||||
|
||||
try:
|
||||
root = self.processor.load_xml_file(temp_path)
|
||||
self.assertIsNotNone(root)
|
||||
self.assertEqual(root.tag, 'resources')
|
||||
self.assertEqual(len(root.findall('string')), 3)
|
||||
finally:
|
||||
os.unlink(temp_path)
|
||||
|
||||
def test_load_xml_file_error(self):
|
||||
"""Test error handling when loading invalid XML file"""
|
||||
with tempfile.NamedTemporaryFile(mode='w', suffix='.xml', delete=False) as f:
|
||||
f.write('invalid xml content')
|
||||
temp_path = f.name
|
||||
|
||||
try:
|
||||
root = self.processor.load_xml_file(temp_path)
|
||||
self.assertIsNone(root)
|
||||
finally:
|
||||
os.unlink(temp_path)
|
||||
|
||||
def test_extract_strings(self):
|
||||
"""Test extracting strings from XML"""
|
||||
root = etree.fromstring(self.sample_xml)
|
||||
strings = self.processor.extract_strings(root)
|
||||
|
||||
self.assertEqual(len(strings), 3)
|
||||
self.assertIn('app_name', strings)
|
||||
self.assertIn('welcome_message', strings)
|
||||
self.assertIn('button_ok', strings)
|
||||
|
||||
# Check string values
|
||||
self.assertEqual(strings['app_name'].value, 'Test App')
|
||||
self.assertEqual(strings['welcome_message'].value, 'Welcome to our app!')
|
||||
self.assertEqual(strings['button_ok'].value, 'OK')
|
||||
|
||||
# Check that all items are TranslationItem instances
|
||||
for item in strings.values():
|
||||
self.assertIsInstance(item, TranslationItem)
|
||||
|
||||
def test_add_missing_strings(self):
|
||||
"""Test adding missing strings to XML"""
|
||||
# Create target XML with one existing string
|
||||
target_xml = '''<resources>
|
||||
<string name="existing_key">Existing value</string>
|
||||
</resources>'''
|
||||
|
||||
target_root = etree.fromstring(target_xml)
|
||||
missing_strings = [
|
||||
('new_key1', 'New value 1', 'string', []),
|
||||
('new_key2', 'New value 2', 'string', []),
|
||||
('existing_key', 'Should not be added', 'string', []) # This should be ignored
|
||||
]
|
||||
|
||||
self.processor.add_missing_strings(target_root, missing_strings)
|
||||
|
||||
# Check that new strings were added
|
||||
strings = target_root.findall('string')
|
||||
self.assertEqual(len(strings), 3) # 1 existing + 2 new
|
||||
|
||||
# Check specific strings
|
||||
new_key1 = target_root.find(".//string[@name='new_key1']")
|
||||
self.assertIsNotNone(new_key1)
|
||||
self.assertEqual(new_key1.text, 'New value 1')
|
||||
|
||||
new_key2 = target_root.find(".//string[@name='new_key2']")
|
||||
self.assertIsNotNone(new_key2)
|
||||
self.assertEqual(new_key2.text, 'New value 2')
|
||||
|
||||
# Check existing string wasn't duplicated
|
||||
existing_strings = target_root.findall(".//string[@name='existing_key']")
|
||||
self.assertEqual(len(existing_strings), 1)
|
||||
|
||||
def test_extract_string_array(self):
|
||||
"""Test extracting string arrays from XML"""
|
||||
xml_with_array = '''<resources>
|
||||
<string name="app_name">Test App</string>
|
||||
<string-array name="vocabulary_hints">
|
||||
<item>Basic greetings</item>
|
||||
<item>Irregular verbs</item>
|
||||
<item>Vocabulary at the airport</item>
|
||||
</string-array>
|
||||
</resources>'''
|
||||
|
||||
root = etree.fromstring(xml_with_array)
|
||||
strings = self.processor.extract_strings(root)
|
||||
|
||||
self.assertEqual(len(strings), 2)
|
||||
self.assertIn('app_name', strings)
|
||||
self.assertIn('vocabulary_hints', strings)
|
||||
|
||||
# Check string array
|
||||
array_item = strings['vocabulary_hints']
|
||||
self.assertEqual(array_item.item_type, 'string-array')
|
||||
self.assertEqual(len(array_item.items), 3)
|
||||
self.assertEqual(array_item.items[0], 'Basic greetings')
|
||||
self.assertEqual(array_item.items[1], 'Irregular verbs')
|
||||
self.assertEqual(array_item.items[2], 'Vocabulary at the airport')
|
||||
self.assertEqual(array_item.value, 'Basic greetings | Irregular verbs | Vocabulary at the airport')
|
||||
|
||||
def test_add_missing_string_array(self):
|
||||
"""Test adding missing string arrays to XML"""
|
||||
target_xml = '''<resources>
|
||||
<string name="existing_key">Existing value</string>
|
||||
</resources>'''
|
||||
|
||||
target_root = etree.fromstring(target_xml)
|
||||
missing_strings = [
|
||||
('vocabulary_hints', '', 'string-array', ['Basic greetings', 'Irregular verbs'])
|
||||
]
|
||||
|
||||
self.processor.add_missing_strings(target_root, missing_strings)
|
||||
|
||||
# Check that string-array was added
|
||||
string_array = target_root.find(".//string-array[@name='vocabulary_hints']")
|
||||
self.assertIsNotNone(string_array)
|
||||
|
||||
# Check items
|
||||
items = string_array.findall('item')
|
||||
self.assertEqual(len(items), 2)
|
||||
self.assertEqual(items[0].text, 'Basic greetings')
|
||||
self.assertEqual(items[1].text, 'Irregular verbs')
|
||||
|
||||
def test_skip_non_translatable_string_array(self):
|
||||
"""Test that non-translatable string arrays are skipped"""
|
||||
xml_with_non_translatable = '''<resources>
|
||||
<string-array name="translatable_array" translatable="true">
|
||||
<item>Item 1</item>
|
||||
</string-array>
|
||||
<string-array name="non_translatable_array" translatable="false">
|
||||
<item>Item 2</item>
|
||||
</string-array>
|
||||
</resources>'''
|
||||
|
||||
root = etree.fromstring(xml_with_non_translatable)
|
||||
strings = self.processor.extract_strings(root)
|
||||
|
||||
self.assertEqual(len(strings), 1)
|
||||
self.assertIn('translatable_array', strings)
|
||||
self.assertNotIn('non_translatable_array', strings)
|
||||
|
||||
# Note: File saving tests are complex to mock properly due to lxml internals
|
||||
# The core functionality is tested through integration tests
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user