1import unittest
2import xml.etree.ElementTree as ET
3from native_format import compare_formats, native_characters, Runs
4from native_xml import ns, Text, project_text
5
6
7class FormatOracleTest(unittest.TestCase):
8 def test_native_omits_exactly_one_final_paragraph_break(self):
9 for stored, exported in [('A\r\r', 'A\n'), ('\rA\r', '\nA'), ('\r', ''), ('\r\r', '\n'), ('A\n', 'A\n')]:
10 with self.subTest(stored=stored):
11 node = {'format': {'bold': True}, 'kind': {'text': stored, 'paragraph_style': None,
12 'runs': [{'start': 0, 'end': len(stored), 'format': None}]}}
13 native = [[(c, {'bold': True}) for c in exported]]
14 self.assertEqual(compare_formats({'nodes': {}}, [node], native), (len(exported), []))
15 with self.assertRaisesRegex(AssertionError, 'Visible text runs differ'):
16 compare_formats({'nodes': {}}, [node], [[(c, {'bold': True}) for c in exported + '\n']])
17
18 def test_native_break_formatting_and_tabs_preserve_distinct_source_text(self):
19 html = '<b>A<br><br>\nB</b><br>\nC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;D'
20 expected = 'A\n\nB\nC' + '\u00a0' * 8 + 'D'
21 self.assertEqual(''.join(Text(html).parts), expected)
22 runs = Runs(html, {})
23 self.assertEqual(''.join(c for c, _ in runs.characters), expected)
24 self.assertTrue(runs.characters[2][1]['bold'])
25 self.assertNotIn('bold', runs.characters[4][1])
26 self.assertEqual(project_text('A\r\rB\rC\tD'), expected)
27 self.assertEqual(project_text('\u00a0' * 8), '\u00a0' * 8)
28
29 def test_utf16_run_boundaries_and_inherited_native_style(self):
30 page = ET.fromstring('''<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2010/onenote">
31 <one:QuickStyleDef index="0" font="Calibri" fontSize="14" bold="true" strikethrough="true"/>
32 <one:Outline><one:OE quickStyleIndex="0"><one:T>A&lt;span style="font-style:italic"&gt;😀&lt;/span&gt;B</one:T></one:OE></one:Outline>
33 </one:Page>''')
34 node = {'format': {}, 'kind': {'text': 'A😀B', 'paragraph_style': 'base', 'runs': [
35 {'start': 0, 'end': 1, 'format': None}, {'start': 1, 'end': 3, 'format': 'italic'},
36 {'start': 3, 'end': 4, 'format': None},
37 ]}}
38 space = {'nodes': {'base': {'format': {'bold': True, 'font': 'Calibri', 'font_size': 14.0}},
39 'italic': {'format': {'italic': True}}}}
40 expected = native_characters(page, page.findall('one:Outline', ns))
41 self.assertTrue(expected[0][0][1]['strike'])
42 count, differences = compare_formats(space, [node], expected)
43 self.assertEqual((count, differences), (10, []))
44 space['nodes']['italic']['format']['italic'] = False
45 _, differences = compare_formats(space, [node], expected)
46 self.assertEqual(differences, [{'paragraph': 0, 'field': 'italic', 'stored': False,
47 'native': True, 'characters': 1, 'positions': [1]}])
48
49 def test_partial_black_omission_is_reported_not_normalized_away(self):
50 node = {'format': {}, 'kind': {'text': 'ABA', 'paragraph_style': None, 'runs': [
51 {'start': 0, 'end': 1, 'format': None}, {'start': 1, 'end': 2, 'format': 'black'},
52 {'start': 2, 'end': 3, 'format': None},
53 ]}}
54 space = {'nodes': {'black': {'format': {'highlight': 0}}}}
55 _, differences = compare_formats(space, [node], [[(c, {'highlight': 'automatic'}) for c in 'ABA']])
56 self.assertEqual(differences, [{'paragraph': 0, 'field': 'highlight', 'stored': '#000000',
57 'native': 'automatic', 'characters': 1, 'positions': [1]}])
58
59
60if __name__ == '__main__':
61 unittest.main()