1from pathlib import Path
2import runpy
3import shutil
4from tempfile import TemporaryDirectory
5import unittest
6import uuid
7import xml.etree.ElementTree as ET
8
9from native_xml import ns
10
11ROOT = Path(__file__).resolve().parent.parent
12FIXTURE = ROOT / 'corpus/notebook-edit'
13compare = runpy.run_path(str(ROOT / 'tools/verify-document.py'))['compare']
14
15
16def file_identity(path):
17 return uuid.UUID(bytes_le=path.read_bytes()[16:32])
18
19
20def entries(node):
21 return [(child.tag.rsplit('}', 1)[-1], child.get('name'), child.get('color'), entries(child))
22 for child in node if child.tag.rsplit('}', 1)[-1] in ('Section', 'SectionGroup')]
23
24
25class NotebookEditTest(unittest.TestCase):
26 def check(self, row, expected):
27 with TemporaryDirectory() as temporary:
28 read = Path(temporary) / 'read'
29 shutil.copytree(FIXTURE / row / 'cold/read', read)
30 compare(FIXTURE / row / 'candidate', read)
31 hierarchy = ET.parse(FIXTURE / row / 'cold/read/hierarchy.xml').getroot()
32 self.assertEqual(entries(hierarchy), expected)
33 for candidate in sorted((FIXTURE / row / 'candidate').rglob('*.one*')):
34 relative = candidate.relative_to(FIXTURE / row / 'candidate')
35 self.assertEqual(file_identity(FIXTURE / row / 'cold/notebook' / relative), file_identity(candidate), str(relative))
36
37 def test_rust_sections_and_groups_open_natively_in_the_written_order(self):
38 self.check('structured', [
39 ('Section', 'Renamed', '#FFD75E', []),
40 ('Section', 'First', '#8AA8E4', []),
41 ('SectionGroup', 'Kept', None, [('Section', 'Inner', '#8AA8E4', [])]),
42 ])
43
44 def test_a_rust_deleted_section_sits_in_the_native_recycle_bin(self):
45 self.check('deleted', [
46 ('Section', 'Renamed', '#FFD75E', []),
47 ('SectionGroup', 'Kept', None, [('Section', 'First', '#8AA8E4', [])]),
48 ('SectionGroup', 'OneNote_RecycleBin', None, [('Section', 'First', '#8AA8E4', [])]),
49 ])
50 hierarchy = ET.parse(FIXTURE / 'deleted/cold/read/hierarchy.xml').getroot()
51 bin = hierarchy.find("one:SectionGroup[@name='OneNote_RecycleBin']", ns)
52 self.assertEqual(bin.get('isRecycleBin'), 'true')
53 self.assertEqual(bin.find('one:Section', ns).get('isInRecycleBin'), 'true')
54
55 def test_onenote_re_identifies_files_whose_header_disagrees_with_their_place(self):
56 # The native session lists a Rust section created with a zero ancestor twice: once
57 # under the identity Rust wrote and once under the identity OneNote assigned.
58 toc = (FIXTURE / 'native-structure/notebook/Open Notebook.onetoc2').read_bytes()
59 links = FIXTURE / 'native-structure/notebook/links.one'
60 self.assertEqual(uuid.UUID(bytes_le=links.read_bytes()[128:144]), file_identity(FIXTURE / 'native-structure/notebook/Open Notebook.onetoc2'))
61 self.assertIn(file_identity(links).bytes_le, toc)
62
63
64if __name__ == '__main__':
65 unittest.main()