Version 7.6.3.2-android, tag libreoffice-7.6.3.2-android
[LibreOffice.git] / sw / qa / python / text_portion_enumeration_test.py
blobc183aaf41b09e10aa5a061fcaad075d86e29b548
1 # -*- coding: utf-8 -*-
3 '''
4 This file is part of the LibreOffice project.
6 This Source Code Form is subject to the terms of the Mozilla Public
7 License, v. 2.0. If a copy of the MPL was not distributed with this
8 file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 This file incorporates work covered by the following license notice:
12 Licensed to the Apache Software Foundation (ASF) under one or more
13 contributor license agreements. See the NOTICE file distributed
14 with this work for additional information regarding copyright
15 ownership. The ASF licenses this file to you under the Apache
16 License, Version 2.0 (the "License"); you may not use this file
17 except in compliance with the License. You may obtain a copy of
18 the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 '''
20 import uno
21 import unittest
22 import os.path
23 from org.libreoffice.unotest import UnoInProcess
24 from tempfile import TemporaryDirectory
25 from com.sun.star.uno import RuntimeException
26 from com.sun.star.lang import IllegalArgumentException, NoSupportException
27 from com.sun.star.beans import StringPair
28 from com.sun.star.rdf.URIs import ODF_PREFIX, ODF_SUFFIX
29 from com.sun.star.i18n.NumberFormatIndex import NUMBER_INT
30 from com.sun.star.text.ControlCharacter import PARAGRAPH_BREAK, HARD_HYPHEN
31 from com.sun.star.text.TextContentAnchorType import (
32 AT_CHARACTER, AS_CHARACTER, AT_PARAGRAPH, AT_PAGE, AT_FRAME)
35 class TreeNode():
36 '''base class for tree nodes. only instance: root of tree.'''
38 def __init__(self, content=None):
39 self.content = content
40 self._children = []
41 self.nodetype = "__ROOT__"
42 self.isnesting = False
44 def __str__(self):
45 return "<{}>".format(self.nodetype)
47 def __eq__(self, other):
48 return type(self) == type(other)
50 def __ne__(self, other):
51 return not self == other
53 def _dup(self, nodetype, *args):
54 try:
55 return nodetype(*args)
56 except Exception as e:
57 raise RuntimeError("TreeNode.dup") from e
59 def createenumeration(self):
60 return iter(self._children)
62 def appendchild(self, child):
63 self._children.append(child)
64 return self
67 class ContentNode(TreeNode):
69 def __init__(self, content):
70 super().__init__(content)
72 def __str__(self):
73 return "{}\tcontent: {}".format(super().__str__(), self.content)
75 def __eq__(self, other):
76 try:
77 return other.content == self.content and super().__eq__(other)
78 except AttributeError:
79 return False
81 def appendchild(self, child):
82 try:
83 self._children.append(child)
84 return self
85 except Exception as e:
86 raise RuntimeError("ContentNode.appendchild") from e
89 class TextNode(ContentNode):
91 def __init__(self, content):
92 super().__init__(content)
93 self.nodetype = "Text"
95 def dup(self):
96 return self._dup(TextNode, self.content)
99 class TextFieldNode(ContentNode):
101 def __init__(self, content):
102 super().__init__(content)
103 self.nodetype = "TextField"
105 def dup(self):
106 return self._dup(TextFieldNode, self.content)
109 class ControlCharacterNode(TreeNode):
110 def __init__(self, char):
111 super().__init__()
112 self.char = char
113 self.nodetype = "ControlCharacter"
115 def __str__(self):
116 return "{}\tcontent: {}".format(super().__str__(), self.char)
118 def __eq__(self, other):
119 try:
120 return other.char == self.char and super().__eq__(other)
121 except AttributeError:
122 return False
124 def dup(self):
125 return self._dup(ControlCharacterNode, self.char)
128 class FootnoteNode(TreeNode):
130 def __init__(self, label):
131 super().__init__()
132 self.label = label
133 self.nodetype = "Footnote"
135 def __str__(self):
136 return "{}\tlabel: {}".format(super().__str__(), self.label)
138 def __eq__(self, other):
139 try:
140 return other.label == self.label and super().__eq__(other)
141 except AttributeError:
142 return False
144 def dup(self):
145 return self._dup(FootnoteNode, self.label)
148 class FrameNode(TreeNode):
149 def __init__(self, name, anchor):
150 super().__init__()
151 self.name = name
152 self.anchor = anchor
153 self.nodetype = "Frame"
155 def __str__(self):
156 return "{}\tname: {}\tanchor: {}".format(
157 super().__str__(),self.name, self.str_anchor(self.anchor))
159 def __eq__(self, other):
160 try:
161 return (other.name == self.name and
162 other.anchor == self.anchor and
163 super().__eq__(other))
164 except AttributeError:
165 return False
167 def dup(self):
168 return self._dup(FrameNode, self.name, self.anchor)
170 def str_anchor(self, anchor):
171 anchors = {str(AS_CHARACTER): "AS_CHARACTER",
172 str(AT_CHARACTER): "AT_CHARACTER",
173 str(AT_PARAGRAPH): "AT_PARAGRAPH",
174 str(AT_PAGE): "AT_PAGE",
175 str(AT_FRAME): "AT_FRAME"}
176 try:
177 return anchors[str(anchor)]
178 except KeyError:
179 raise RuntimeError("unknown anchor")
182 class MetaNode(TreeNode):
183 def __init__(self, xmlid):
184 super().__init__()
185 self.xmlid = xmlid
186 self.nodetype = "InContentMetadata"
187 self.isnesting = True
189 def __str__(self):
190 return "{}\txmlid: {}#{}".format(
191 super().__str__(), self.xmlid.First, self.xmlid.Second)
193 def __eq__(self, other):
194 try:
195 return (type(other) == type(self) and
196 MetaNode.eq(other.xmlid, self.xmlid))
197 except AttributeError:
198 return False
200 @classmethod
201 def eq(cls, left, right):
202 return left.First == right.First and left.Second == right.Second
204 def dup(self):
205 return self._dup(MetaNode, self.xmlid)
208 class MarkNode(TreeNode):
209 def __init__(self, name, ispoint=True):
210 super().__init__()
211 self.name = name
212 self.ispoint = ispoint
213 self.isstart = False
215 def __str__(self):
216 return "{}\tisPoint: {}\tisStart: {}".format(
217 super().__str__(), self.ispoint, self.isstart)
219 def __eq__(self, other):
220 try:
221 return (other.name == self.name and
222 other.ispoint == self.ispoint and
223 other.isstart == self.isstart)
224 except AttributeError:
225 return False
228 class BookmarkNode(MarkNode):
229 def __init__(self, name, xmlid=StringPair()):
230 super().__init__(name)
231 self.xmlid = xmlid
232 self.nodetype = "Bookmark"
234 def __str__(self):
235 return "{}\txmlid: {}#{}".format(
236 super().__str__(), self.xmlid.First, self.xmlid.Second)
238 def __eq__(self, other):
239 try:
240 return (type(other) == type(self) and
241 super().__eq__(other) and
242 MetaNode.eq(other.xmlid, self.xmlid))
243 except AttributeError:
244 return False
246 def dup(self):
247 return self._dup(BookmarkNode, self.name, self.xmlid)
250 class BookmarkStartNode(BookmarkNode):
252 def __init__(self, name, xmlid=StringPair()):
253 super().__init__(name, xmlid)
254 self.ispoint = False
255 self.isstart = True
257 def dup(self):
258 return self._dup(BookmarkStartNode, self.name)
261 class BookmarkEndNode(BookmarkNode):
263 def __init__(self, name, xmlid=StringPair()):
264 super().__init__(name, xmlid)
265 self.ispoint = False
266 self.isstart = False
268 def dup(self):
269 return self._dup(BookmarkEndNode, self.name)
272 class ReferenceMarkNode(MarkNode):
273 def __init__(self, name):
274 super().__init__(name)
275 self.nodetype = "ReferenceMark"
277 def __eq__(self, other):
278 return (type(other) == type(self) and super().__eq__(other))
280 def dup(self):
281 return self._dup(ReferenceMarkNode, self.name)
284 class ReferenceMarkStartNode(ReferenceMarkNode):
285 def __init__(self, name):
286 super().__init__(name)
287 self.ispoint = False
288 self.isstart = True
290 def dup(self):
291 return self._dup(ReferenceMarkStartNode, self.name)
294 class ReferenceMarkEndNode(ReferenceMarkNode):
295 def __init__(self, name):
296 super().__init__(name)
297 self.ispoint = False
298 self.isstart = False
300 def dup(self):
301 return self._dup(ReferenceMarkEndNode, self.name)
304 class DocumentIndexMarkNode(MarkNode):
305 def __init__(self, name):
306 super().__init__(name)
307 self.nodetype = "DocumentIndexMark"
309 def __eq__(self, other):
310 return (type(other) == type(self) and super().__eq__(other))
312 def dup(self):
313 return self._dup(DocumentIndexMarkNode, self.name)
316 class DocumentIndexMarkStartNode(DocumentIndexMarkNode):
317 def __init__(self, name):
318 super().__init__(name)
319 self.ispoint = False
320 self.isstart = True
322 def dup(self):
323 return self._dup(DocumentIndexMarkStartNode, self.name)
326 class DocumentIndexMarkEndNode(DocumentIndexMarkNode):
327 def __init__(self, name):
328 super().__init__(name)
329 self.ispoint = False
330 self.isstart = False
332 def dup(self):
333 return self._dup(DocumentIndexMarkEndNode, self.name)
336 class HyperlinkNode(TreeNode):
337 def __init__(self, url):
338 super().__init__()
339 self.nodetype = "Hyperlink"
340 self.isnesting = True
341 if url:
342 self.url = url
343 else:
344 raise RuntimeError("HyperlinkNode")
346 def __str__(self):
347 return "{}\turl: {}".format(super().__str__(), self.url)
349 def __eq__(self, other):
350 try:
351 return other.url == self.url and super().__eq__(other)
352 except AttributeError:
353 return False
355 def dup(self):
356 return self._dup(HyperlinkNode, self.url)
359 class RubyNode(TreeNode):
360 def __init__(self, ruby):
361 super().__init__()
362 self.nodetype = "Ruby"
363 self.isnesting = True
364 if ruby:
365 self.ruby = ruby
366 else:
367 raise RuntimeError("RubyNode")
369 def __str__(self):
370 return "{}\trubytext: {}".format(super().__str__(), self.ruby)
372 def __eq__(self, other):
373 try:
374 return other.ruby == self.ruby and super().__eq__(other)
375 except AttributeError:
376 return False
378 def dup(self):
379 return self._dup(RubyNode, self.ruby)
382 class MetaFieldNode(MetaNode):
383 def __init__(self, xmlid):
384 super().__init__(xmlid)
385 self.nodetype = "MetadataField"
387 def dup(self):
388 return self._dup(MetaFieldNode, self.xmlid)
391 class Range():
392 def __init__(self, start, end, node):
393 self.start = start
394 self.end = end
395 self.node = node
396 self.extent = end - start
399 class Inserter():
401 def __init__(self, xDoc):
402 self.xDoc = xDoc
403 self.xText = xDoc.getText()
404 self.xCursor = self.xText.createTextCursor()
406 def initparagraph(self):
407 ## we split the first (empty) paragraph, and then insert into the
408 ## second (empty) paragraph; this ensures first is always empty!
409 self.xCursor.gotoStartOfParagraph(False)
410 self.xText.insertControlCharacter(self.xCursor, PARAGRAPH_BREAK, False)
412 def inserttext(self, xCursor, text):
413 xCursor.setString(text)
415 def inserttextfield(self, xCursor, content):
416 xContent = self.maketextfield(content)
417 xContent.attach(xCursor)
419 def maketextfield(self, content):
420 xField = self.xDoc.createInstance("com.sun.star.text.textfield.Author")
421 xField.IsFixed = True
422 xField.FullName = False
423 xField.Content = content
424 return xField
426 def insertcontrolcharacter(self, xCursor, cchar):
427 self.xText.insertControlCharacter(xCursor, cchar, False)
429 def insertframe(self, xCursor, name, anchor):
430 xContent = self.makeframe(name, anchor)
431 xContent.attach(xCursor)
433 def makeframe(self, name, anchor):
434 xFrame = self.xDoc.createInstance("com.sun.star.text.TextFrame")
435 xFrame.AnchorType = anchor
436 xFrame.setName(name)
437 return xFrame
439 def insertfootnote(self, xCursor, label):
440 xContent = self.makefootnote(label)
441 xContent.attach(xCursor)
443 def makefootnote(self, label):
444 xFootNote = self.xDoc.createInstance("com.sun.star.text.Footnote")
445 xFootNote.setLabel(label)
446 return xFootNote
448 def insertbookmark(self, xCursor, name, xmlid):
449 xContent = self.makebookmark(name)
450 xContent.attach(xCursor)
451 if xmlid.First != "":
452 xContent.MetadataReference = xmlid
454 def makebookmark(self, name):
455 xBookmark = self.xDoc.createInstance("com.sun.star.text.Bookmark")
456 xBookmark.setName(name)
457 return xBookmark
459 def insertreferencemark(self, xCursor, name):
460 xContent = self.makereferencemark(name)
461 xContent.attach(xCursor)
463 def makereferencemark(self, name):
464 xMark = self.xDoc.createInstance("com.sun.star.text.ReferenceMark")
465 xMark.setName(name)
466 return xMark
468 def insertdocumentindexmark(self, xCursor, key):
469 xContent = self.makedocumentindexmark(key)
470 xContent.attach(xCursor)
472 def makedocumentindexmark(self, key):
473 xMark = self.xDoc.createInstance("com.sun.star.text.DocumentIndexMark")
474 xMark.PrimaryKey = key
475 return xMark
477 def inserthyperlink(self, xCursor, url):
478 xCursor.HyperLinkURL = url
480 def insertruby(self, xCursor, rubytext):
481 xCursor.RubyText = rubytext
483 def insertmeta(self, xCursor, xmlid):
484 xContent = self.makemeta()
485 xContent.attach(xCursor)
486 xContent.MetadataReference = xmlid
487 return xContent
489 def makemeta(self):
490 xMeta = self.xDoc.createInstance("com.sun.star.text.InContentMetadata")
491 return xMeta
493 def insertmetafield(self, xCursor, xmlid):
494 xContent = self.makemetafield()
495 xContent.attach(xCursor)
496 xContent.MetadataReference = xmlid
497 return xContent
499 def makemetafield(self):
500 xMeta = self.xDoc.createInstance(
501 "com.sun.star.text.textfield.MetadataField")
502 return xMeta
505 class TreeInserter(Inserter):
507 def __init__(self, xDoc):
508 super().__init__(xDoc)
509 self._bookmarkstarts = {}
510 self._referencemarkstarts = {}
511 self._documentindexmarkstarts = {}
512 self._framehints = []
514 def inserttree(self, tree):
515 if tree.nodetype != "__ROOT__":
516 raise RuntimeError("insertTree: test error: no root")
517 self.initparagraph()
518 self.insertchildren(tree.createenumeration())
519 for p in self._framehints:
520 self.insertframe(p[0], p[1].name, p[1].anchor)
522 def insertchildren(self, children):
523 xCursor = self.xCursor
524 for node in children:
525 xCursor.gotoEndOfParagraph(False)
526 type_ = node.nodetype
527 if type_ == "Text":
528 self.inserttext(xCursor, node.content)
529 elif type_ == "TextField":
530 self.inserttextfield(xCursor, node.content)
531 elif type_ == "ControlCharacter":
532 self.insertcontrolcharacter(xCursor, node.char)
533 elif type_ == "Footnote":
534 self.insertfootnote(xCursor, node.label)
535 elif type_ == "Frame":
536 if node.anchor == AT_CHARACTER:
537 self._framehints.append((xCursor.getStart(), node))
538 else:
539 self.insertframe(xCursor, node.name, node.anchor)
540 elif type_ == "Bookmark":
541 name = node.name
542 id_ = node.xmlid
543 if node.ispoint:
544 self.insertbookmark(xCursor, name, id_)
545 elif node.isstart:
546 self._bookmarkstarts[name] = xCursor.getStart()
547 else:
548 xRange = self._bookmarkstarts[name]
549 xParaCursor = self.mkcursor(xRange)
550 self.insertbookmark(xParaCursor, name, id_)
551 elif type_ == "ReferenceMark":
552 name = node.name
553 if node.ispoint:
554 self.insertreferencemark(xCursor, name)
555 elif node.isstart:
556 self._referencemarkstarts[name] = xCursor.getStart()
557 else:
558 xRange = self._referencemarkstarts[name]
559 xParaCursor = self.mkcursor(xRange)
560 self.insertreferencemark(xParaCursor, name)
561 elif type_ == "DocumentIndexMark":
562 name = node.name
563 if node.ispoint:
564 self.insertdocumentindexmark(xCursor, name)
565 elif node.isstart:
566 self._documentindexmarkstarts[name] = xCursor.getStart()
567 else:
568 xRange = self._documentindexmarkstarts[name]
569 xParaCursor = self.mkcursor(xRange)
570 self.insertdocumentindexmark(xParaCursor, name)
571 elif type_ == "Hyperlink":
572 xRange = xCursor.getStart()
573 self.insertchildren(node.createenumeration())
574 xParaCursor = self.mkcursor(xRange)
575 self.inserthyperlink(xParaCursor, node.url)
576 elif type_ == "Ruby":
577 xRange = xCursor.getStart()
578 self.insertchildren(node.createenumeration())
579 xParaCursor = self.mkcursor(xRange)
580 self.insertruby(xParaCursor, node.ruby)
581 elif type_ == "InContentMetadata":
582 xRange = xCursor.getStart()
583 self.insertchildren(node.createenumeration())
584 xParaCursor = self.mkcursor(xRange)
585 self.insertmeta(xParaCursor, node.xmlid)
586 elif type_ == "MetadataField":
587 xRange = xCursor.getStart()
588 self.insertchildren(node.createenumeration())
589 xParaCursor = self.mkcursor(xRange)
590 self.insertmetafield(xParaCursor, node.xmlid)
591 elif type_ == "SoftPageBreak":
592 raise RuntimeError("sorry, cannot test SoftPageBreak")
593 else:
594 raise RuntimeError("unexpected type: {}".format(type_))
596 def mkcursor(self, xRange):
597 xCursor = self.xText.createTextCursorByRange(xRange)
598 xCursor.gotoEndOfParagraph(True)
599 return xCursor
602 # FIXME: this does not account for inserted dummy characters!
603 class RangeInserter(Inserter):
604 def __init__(self, xDoc):
605 super().__init__(xDoc)
606 self.initparagraph()
608 # def inserttext(self, pos, text):
609 # self.xCursor.gotoStartOfParagraph(False)
610 # self.xCursor.goRight(pos, False)
611 # self.inserttext(self.xCursor, text)
613 def insertrange(self, range):
614 self.xCursor.gotoStartOfParagraph(False)
615 self.xCursor.goRight(range.start, False)
616 self.xCursor.goRight(range.extent, True)
617 return self.insertnode(self.xCursor, range.node)
619 def insertnode(self, xParaCursor, node):
620 nodetype = node.nodetype
621 if nodetype == "Text":
622 text = node
623 self.inserttext(xParaCursor, text.content)
624 elif nodetype == "Hyperlink":
625 href = node
626 self.inserthyperlink(xParaCursor, href.url)
627 elif nodetype == "Ruby":
628 ruby = node
629 self.insertruby(xParaCursor, ruby.ruby)
630 elif nodetype == "InContentMetadata":
631 meta = node
632 return self.insertmeta(xParaCursor, meta.xmlid)
633 elif nodetype == "MetadataField":
634 meta = node
635 return self.insertmetafield(xParaCursor, meta.xmlid)
636 elif nodetype == "Bookmark":
637 bkmk = node
638 if bkmk.ispoint:
639 raise RuntimeError("range only")
640 self.insertbookmark(xParaCursor, bkmk.name, bkmk.xmlid)
641 elif nodetype == "ReferenceMark":
642 mark = node
643 if mark.ispoint:
644 raise RuntimeError("range only")
645 self.insertreferencemark(xParaCursor, mark.name)
646 elif nodetype == "DocumentIndexMark":
647 mark = node
648 if mark.ispoint:
649 raise RuntimeError("range only")
650 self.insertdocumentindexmark(xParaCursor, mark.name)
651 elif nodetype == "TextField":
652 field = node
653 self.inserttextfield(self.xCursor, field.content)
654 elif nodetype == "Footnote":
655 note = node
656 self.insertfootnote(self.xCursor, note.label)
657 elif nodetype == "Frame":
658 frame = node
659 self.insertframe(xParaCursor, frame.name, frame.anchor)
660 elif nodetype == "ControlCharacter":
661 cchar = node
662 self.insertcontrolcharacter(self.xCursor, cchar.char)
663 elif nodetype == "SoftPageBreak":
664 raise RuntimeError("sorry, cannot test SoftPageBreak")
665 else:
666 raise RuntimeError("unexpected nodetype: {}".format(nodetype))
667 return None
670 class EnumConverter():
672 def __init__(self):
673 self._stack = []
675 def convert(self, xEnum):
676 root = TreeNode()
677 self._stack.append(root)
678 ret = self.convertchildren(xEnum)
679 assert (len(self._stack)==0), "EnumConverter.convert: stack is not empty"
680 return ret
682 def convertchildren(self, xEnum):
683 for xPortion in xEnum:
684 type_ = xPortion.TextPortionType
685 if type_ == "Text":
686 text = xPortion.getString()
687 node = TextNode(text)
688 url = xPortion.HyperLinkURL
689 if len(url) > 0:
690 temp = node
691 node = HyperlinkNode(url)
692 node.appendchild(temp)
693 elif type_ == "TextField":
694 xField = xPortion.TextField
695 if xField.supportsService("com.sun.star.text.textfield.MetadataField"):
696 xmlid = xField.MetadataReference
697 node = MetaFieldNode(xmlid)
698 self._stack.append(node)
699 xEnumChildren = xField.createEnumeration()
700 node2 = self.convertchildren(xEnumChildren)
701 print(node)
702 print(node2)
703 assert (node2 is node), "stack error: meta-field"
704 else:
705 content = xField.Content
706 isFixed = xField.IsFixed
707 assert isFixed, "field not fixed?"
708 node = TextFieldNode(content)
709 elif type_ == "ControlCharacter":
710 c = xPortion.ControlCharacter
711 node = ControlCharacterNode(c)
712 elif type_ == "Footnote":
713 xFootnote = xPortion.Footnote
714 label = xFootnote.getLabel()
715 node = FootnoteNode(label)
716 elif type_ == "Frame":
717 xCEA = xPortion.createContentEnumeration('')
718 while xCEA.hasMoreElements():
719 xFrame = xCEA.nextElement()
720 anchor = xFrame.AnchorType
721 name = xFrame.getName()
722 node = FrameNode(name, anchor)
723 self._stack[-1].appendchild(node)
724 continue
725 elif type_ == "Bookmark":
726 xMark = xPortion.Bookmark
727 name = xMark.getName()
728 xmlid = xMark.MetadataReference
729 isCollapsed = xPortion.IsCollapsed
730 if isCollapsed:
731 node = BookmarkNode(name, xmlid)
732 else:
733 isStart = xPortion.IsStart
734 if isStart:
735 node = BookmarkStartNode(name, xmlid)
736 else:
737 node = BookmarkEndNode(name, xmlid)
738 elif type_ == "ReferenceMark":
739 xMark = xPortion.ReferenceMark
740 name = xMark.getName()
741 isCollapsed = xPortion.IsCollapsed
742 if isCollapsed:
743 node = ReferenceMarkNode(name)
744 else:
745 isStart = xPortion.IsStart
746 if isStart:
747 node = ReferenceMarkStartNode(name)
748 else:
749 node = ReferenceMarkEndNode(name)
750 elif type_ == "DocumentIndexMark":
751 xMark = xPortion.DocumentIndexMark
752 name = xMark.PrimaryKey
753 isCollapsed = xPortion.IsCollapsed
754 if isCollapsed:
755 node = DocumentIndexMarkNode(name)
756 else:
757 isStart = xPortion.IsStart
758 if isStart:
759 node = DocumentIndexMarkStartNode(name)
760 else:
761 node = DocumentIndexMarkEndNode(name)
762 elif type_ == "Ruby":
763 isStart = xPortion.IsStart
764 if isStart:
765 # ARRGH!!! stupid api...
766 # the text is ONLY at the start!
767 ruby = xPortion.RubyText
768 node = RubyNode(ruby)
769 self._stack.append(node)
770 continue
771 else:
772 node = self._stack.pop()
773 assert (isinstance(node, RubyNode)), "stack error: Ruby expected; is: {}".format(str(node))
774 elif type_ == "InContentMetadata":
775 xMeta = xPortion.InContentMetadata
776 xmlid = xMeta.MetadataReference
777 node = MetaNode(xmlid)
778 self._stack.append(node)
779 xEnumChildren = xMeta.createEnumeration()
780 node2 = self.convertchildren(xEnumChildren)
781 assert (node2 is node), "stack error: meta"
782 elif type_ == "SoftPageBreak":
783 node = SoftPageBreakNode()
784 else:
785 raise RuntimeError("unexpected type: {}".format(type_))
786 self._stack[-1].appendchild(node)
787 ret = self._stack.pop()
788 return ret
791 class FuzzyTester():
792 '''this is where we nail the pudding to the wall'''
793 def __init__(self):
794 self.diffcontent = 0
795 self.diffmissing = 0
796 self.diffnesting = 0
797 self.diffspuriousemptytext = 0
798 self.diffsequence = 0 # ignored?
799 self.stackexpected = []
800 self.stackactual = []
801 self.bufferexpected = []
802 self.bufferactual = []
804 def dotest(self, expected, actual):
805 '''idea: traverse both trees, enumerate nodes, stopping at content nodes.
806 then compare buffers.'''
807 assert "__ROOT__" == expected.nodetype
808 assert "__ROOT__" == actual.nodetype
809 self.stackexpected.append((expected, expected.createenumeration()))
810 self.stackactual.append((actual, actual.createenumeration()))
811 while self.stackexpected or self.stackactual:
812 self.traverse(self.stackexpected, self.bufferexpected)
813 self.traverse(self.stackactual, self.bufferactual)
814 self.testbuffer()
815 if self.diffsequence:
816 print("warning: {} differences in sequence".format(
817 self.diffsequence))
818 if self.diffspuriousemptytext:
819 print("warning: {} spurious empty text nodes".format(
820 self.diffspuriousemptytext))
821 if self.diffnesting:
822 print("WARNING: {} differences in nesting".format(
823 self.diffnesting))
824 assert self.diffcontent == 0
825 assert self.diffmissing == 0
827 def traverse(self, stack, buffer):
828 while stack:
829 topenum = stack[-1][1]
830 try:
831 node = next(topenum)
832 buffer.append(node)
833 if node._children:
834 node_enum = node.createenumeration()
835 stack.append((node, node_enum))
836 if node.content:
837 if not (isinstance(node, TextNode) and # spurious empty text?
838 len(node.content) == 0):
839 return # break here
840 except StopIteration:
841 buffer.append(stack[-1][0])
842 stack.pop()
844 def testterminatingnode(self):
845 lenexpected = len(self.bufferexpected)
846 lenactual = len(self.bufferactual)
847 if lenexpected == 0 or lenactual == 0:
848 return
849 expected = self.bufferexpected[-1]
850 actual = self.bufferactual[-1]
851 eroot = expected.nodetype == "__ROOT__"
852 aroot = actual.nodetype == "__ROOT__"
853 if eroot or aroot:
854 if not (eroot and aroot):
855 if aroot:
856 self.printmissing(expected)
857 else:
858 self.printunexpected(actual)
859 self.diffmissing += 1
860 return
861 self.testcontentnode(expected, actual)
862 self.bufferexpected[-1] = None
863 self.bufferactual[-1] = None
865 def testcontentnode(self, expected, actual):
866 contentexpected = expected.content
867 contentactual = actual.content
868 if expected != actual:
869 self.printdiff("text content differs", contentexpected, contentactual)
870 self.diffcontent += 1
872 def testbuffer(self):
873 lenactual = len(self.bufferactual)
874 tmp_bufferactual = self.bufferactual[:]
875 for i, node in enumerate(self.bufferexpected):
876 try:
877 j = tmp_bufferactual.index(node)
878 if j != i:
879 # FIXME how bad is this?
880 self.printdiff("position differs", i, j)
881 # a hacky hack
882 min_ = min(i,j)
883 max_ = max(min(lenactual-1, i),j)
884 for k in range(min_, max_):
885 tmp = tmp_bufferactual[k]
886 if tmp and tmp.isnesting:
887 self.printnesting(node, tmp)
888 self.diffnesting += 1
889 self.diffsequence += 1
890 tmp_bufferactual[j] = None
891 except ValueError:
892 print('perdrix')
893 self.printmissing(node)
894 self.diffmissing += 1
895 for j, node in enumerate(tmp_bufferactual):
896 if node:
897 self.printunexpected(node)
898 if isinstance(node, TextNode) and len(node.content) == 0:
899 self.diffspuriousemptytext += 1
900 else:
901 print('renard')
902 self.diffmissing += 1
903 self.testterminatingnode()
904 self.bufferexpected[:] = []
905 self.bufferactual[:] = []
907 def printdiff(self, prefix, expected, actual):
908 print("{}:\texpected: {}\tactual: {}".format(prefix, expected, actual))
910 def printnesting(self, node, nesting):
911 print("node: {} possibly moved across nesting {}".format(
912 str(node), str(nesting)))
914 def printmissing(self, node):
915 print(" missing node: {}".format(str(node)))
917 def printunexpected(self, node):
918 print("unexpected node: {}".format(str(node)))
921 class TextPortionEnumerationTest(unittest.TestCase):
923 xMSF = None
924 xContext = None
925 tempdir = None
927 @classmethod
928 def setUpClass(cls):
929 cls._uno = UnoInProcess()
930 cls._uno.setUp()
931 cls.xDoc = cls._uno.openEmptyWriterDoc()
932 cls.count = 0
934 @classmethod
935 def tearDownClass(cls):
936 cls.xDoc.close(True)
937 cls._uno.tearDown()
938 # HACK in case cls.xDoc holds a UNO proxy to an SwXTextDocument (whose dtor calls
939 # Application::GetSolarMutex via sw::UnoImplPtrDeleter), which would potentially only be
940 # garbage-collected after VCL has already been deinitialized:
941 cls.xDoc = None
943 def test_text(self):
944 root = TreeNode()
945 text = TextNode("abc")
946 root.appendchild(text)
947 self.dotest(root)
949 def test_text_field(self):
950 self.mkname("ruby")
951 root = TreeNode()
952 txtf = TextFieldNode("abc")
953 root.appendchild(txtf)
954 self.dotest(root)
956 @unittest.skip("FIXME this is converted to a text portion: ControlCharacter is obsolete")
957 def test_control_char(self):
958 root = TreeNode()
959 cchr = ControlCharacterNode(HARD_HYPHEN)
960 root.appendchild(cchr)
961 self.dotest(root)
963 @unittest.skip("FIXME: insert a soft page break: not done")
964 def test_soft_page_break(self):
965 root = TreeNode()
966 spbk =SoftPageBreakNode()
967 text = TextNode("abc")
968 root.appendchild(spbk)
969 root.appendchild(text)
970 self.dotest(root)
972 def test_footnote(self):
973 name = self.mkname("ftn")
974 root = TreeNode()
975 ftnd = FootnoteNode(name)
976 root.appendchild(ftnd)
977 self.dotest(root)
979 def test_frame_as(self):
980 name = self.mkname("frame")
981 root = TreeNode()
982 fram = FrameNode(name, AS_CHARACTER)
983 root.appendchild(fram)
984 self.dotest(root)
986 def test_frame_at(self):
987 name = self.mkname("frame")
988 root = TreeNode()
989 fram = FrameNode(name, AT_CHARACTER)
990 root.appendchild(fram)
991 self.dotest(root)
993 def test_bookmark_point(self):
994 name = self.mkname("mark")
995 root = TreeNode()
996 bkmk = BookmarkNode(name)
997 text = TextNode("abc")
998 root.appendchild(bkmk)
999 root.appendchild(text)
1000 self.dotest(root)
1002 def test_bookmark(self):
1003 name = self.mkname("mark")
1004 root = TreeNode()
1005 bkm1 = BookmarkStartNode(name)
1006 text = TextNode("abc")
1007 bkm2 = BookmarkEndNode(name)
1008 root.appendchild(bkm1)
1009 root.appendchild(text)
1010 root.appendchild(bkm2)
1011 self.dotest(root)
1013 def test_bookmark_point_xmlid(self):
1014 name = self.mkname("mark")
1015 id = self.mkid("id")
1016 root = TreeNode()
1017 bkmk = BookmarkNode(name, id)
1018 text = TextNode("abc")
1019 root.appendchild(bkmk)
1020 root.appendchild(text)
1021 self.dotest(root)
1023 def test_bookmark_xmlid(self):
1024 name = self.mkname("mark")
1025 id = self.mkid("id")
1026 root = TreeNode()
1027 bkm1 = BookmarkStartNode(name, id)
1028 text = TextNode("abc")
1029 bkm2 = BookmarkEndNode(name, id)
1030 root.appendchild(bkm1)
1031 root.appendchild(text)
1032 root.appendchild(bkm2)
1033 self.dotest(root)
1035 def test_refmark_point(self):
1036 name = self.mkname("refmark")
1037 root = TreeNode()
1038 rfmk = ReferenceMarkNode(name)
1039 text = TextNode("abc")
1040 root.appendchild(rfmk)
1041 root.appendchild(text)
1042 self.dotest(root)
1044 def test_refmark(self):
1045 name = self.mkname("refmark")
1046 root = TreeNode()
1047 rfm1 = ReferenceMarkStartNode(name)
1048 text = TextNode("abc")
1049 rfm2 = ReferenceMarkEndNode(name)
1050 root.appendchild(rfm1)
1051 root.appendchild(text)
1052 root.appendchild(rfm2)
1053 self.dotest(root)
1055 def test_toxmark_point(self):
1056 name = self.mkname("toxmark")
1057 root = TreeNode()
1058 txmk = DocumentIndexMarkNode(name)
1059 text = TextNode("abc")
1060 root.appendchild(txmk)
1061 root.appendchild(text)
1062 self.dotest(root)
1064 def test_toxmark(self):
1065 name = self.mkname("toxmark")
1066 root = TreeNode()
1067 txm1 = DocumentIndexMarkStartNode(name)
1068 text = TextNode("abc")
1069 txm2 = DocumentIndexMarkEndNode(name)
1070 root.appendchild(txm1)
1071 root.appendchild(text)
1072 root.appendchild(txm2)
1073 self.dotest(root)
1075 def test_hyperlink(self):
1076 name = self.mkname("url")
1077 root = TreeNode()
1078 href = HyperlinkNode(name)
1079 text = TextNode("abc")
1080 href.appendchild(text)
1081 root.appendchild(href)
1082 self.dotest(root)
1084 def test_hyperlink_empty(self):
1085 name = self.mkname("url")
1086 root = TreeNode()
1087 href = HyperlinkNode(name)
1088 text = TextNode("")
1089 href.appendchild(text)
1090 root.appendchild(href)
1091 self.dotest(root)
1093 def test_ruby(self):
1094 name = self.mkname("ruby")
1095 root = TreeNode()
1096 ruby = RubyNode(name)
1097 text = TextNode("abc")
1098 ruby.appendchild(text)
1099 root.appendchild(ruby)
1100 self.dotest(root)
1102 def test_ruby_empty(self):
1103 # BUG: #i91534#
1104 name = self.mkname("ruby")
1105 root = TreeNode()
1106 ruby = RubyNode(name)
1107 root.appendchild(ruby)
1108 self.dotest(root)
1110 def test_meta(self):
1111 id = StringPair("content.xml", self.mkname("id"))
1112 root = TreeNode()
1113 meta = MetaNode(id)
1114 text = TextNode("abc")
1115 root.appendchild(TextNode("123"))
1116 meta.appendchild(text)
1117 root.appendchild(meta)
1118 self.dotest(root)
1120 def test_meta_empty(self):
1121 id = StringPair("content.xml", self.mkname("id"))
1122 root = TreeNode()
1123 meta = MetaNode(id)
1124 root.appendchild(meta)
1125 self.dotest(root)
1127 def test_meta_field(self):
1128 id = StringPair("content.xml", self.mkname("id"))
1129 root = TreeNode()
1130 meta = MetaFieldNode(id)
1131 text = TextNode("abc")
1132 root.appendchild(TextNode("123"))
1133 meta.appendchild(text)
1134 root.appendchild(meta)
1135 self.dotest(root)
1137 def test_meta_field_empty(self):
1138 id = StringPair("content.xml", self.mkname("id"))
1139 root = TreeNode()
1140 meta = MetaFieldNode(id)
1141 root.appendchild(meta)
1142 self.dotest(root)
1144 def test_bookmark1(self):
1145 name1 = self.mkname("mark")
1146 name2 = self.mkname("mark")
1147 name3 = self.mkname("mark")
1148 root = TreeNode()
1149 root.appendchild(BookmarkStartNode(name1))
1150 root.appendchild(BookmarkNode(name2))
1151 root.appendchild(BookmarkStartNode(name3))
1152 root.appendchild(TextNode("abc"))
1153 root.appendchild(BookmarkEndNode(name1))
1154 root.appendchild(TextNode("de"))
1155 root.appendchild(BookmarkEndNode(name3))
1156 self.dotest(root)
1158 def test_bookmark2(self):
1159 name1 = self.mkname("mark")
1160 name2 = self.mkname("mark")
1161 name3 = self.mkname("mark")
1162 root = TreeNode()
1163 root.appendchild(BookmarkStartNode(name1))
1164 root.appendchild(TextNode("abc"))
1165 root.appendchild(BookmarkNode(name2))
1166 root.appendchild(BookmarkStartNode(name3))
1167 root.appendchild(BookmarkEndNode(name1))
1168 root.appendchild(TextNode("de"))
1169 root.appendchild(BookmarkEndNode(name3))
1170 self.dotest(root)
1172 def test_refmark2(self):
1173 name1 = self.mkname("refmark")
1174 root = TreeNode()
1175 root.appendchild(ReferenceMarkStartNode(name1))
1176 root.appendchild(TextNode("abc"))
1177 # BUG: #i102541# (this is actually not unoportenum's fault)
1178 root.appendchild(ReferenceMarkEndNode(name1))
1179 root.appendchild(TextNode("de"))
1180 self.dotest(root)
1182 def test_refmark3(self):
1183 # BUG: #i107672# (non-deterministic; depends on pointer ordering)
1184 name1 = self.mkname("refmark")
1185 name2 = self.mkname("refmark")
1186 name3 = self.mkname("refmark")
1187 name4 = self.mkname("refmark")
1188 name5 = self.mkname("refmark")
1189 name6 = self.mkname("refmark")
1190 name7 = self.mkname("refmark")
1191 root = TreeNode()
1192 root.appendchild(ReferenceMarkStartNode(name1))
1193 root.appendchild(ReferenceMarkStartNode(name2))
1194 root.appendchild(ReferenceMarkStartNode(name3))
1195 root.appendchild(ReferenceMarkStartNode(name4))
1196 root.appendchild(ReferenceMarkStartNode(name5))
1197 root.appendchild(ReferenceMarkStartNode(name6))
1198 root.appendchild(ReferenceMarkStartNode(name7))
1199 root.appendchild(TextNode("abc"))
1200 root.appendchild(ReferenceMarkEndNode(name7))
1201 root.appendchild(ReferenceMarkEndNode(name6))
1202 root.appendchild(ReferenceMarkEndNode(name5))
1203 root.appendchild(ReferenceMarkEndNode(name4))
1204 root.appendchild(ReferenceMarkEndNode(name3))
1205 root.appendchild(ReferenceMarkEndNode(name2))
1206 root.appendchild(ReferenceMarkEndNode(name1))
1207 root.appendchild(TextNode("de"))
1208 self.dotest(root)
1210 def test_toxmark2(self):
1211 name1 = self.mkname("toxmark")
1212 root = TreeNode()
1213 root.appendchild(DocumentIndexMarkStartNode(name1))
1214 root.appendchild(TextNode("abc"))
1215 root.appendchild(DocumentIndexMarkEndNode(name1))
1216 root.appendchild(TextNode("de"))
1217 self.dotest(root)
1219 def test_toxmark3(self):
1220 # BUG: #i107672# (non-deterministic; depends on pointer ordering)
1221 name1 = self.mkname("toxmark")
1222 name2 = self.mkname("toxmark")
1223 name3 = self.mkname("toxmark")
1224 name4 = self.mkname("toxmark")
1225 name5 = self.mkname("toxmark")
1226 name6 = self.mkname("toxmark")
1227 name7 = self.mkname("toxmark")
1228 root = TreeNode()
1229 root.appendchild(DocumentIndexMarkStartNode(name1))
1230 root.appendchild(DocumentIndexMarkStartNode(name2))
1231 root.appendchild(DocumentIndexMarkStartNode(name3))
1232 root.appendchild(DocumentIndexMarkStartNode(name4))
1233 root.appendchild(DocumentIndexMarkStartNode(name5))
1234 root.appendchild(DocumentIndexMarkStartNode(name6))
1235 root.appendchild(DocumentIndexMarkStartNode(name7))
1236 root.appendchild(TextNode("abc"))
1237 root.appendchild(DocumentIndexMarkEndNode(name7))
1238 root.appendchild(DocumentIndexMarkEndNode(name6))
1239 root.appendchild(DocumentIndexMarkEndNode(name5))
1240 root.appendchild(DocumentIndexMarkEndNode(name4))
1241 root.appendchild(DocumentIndexMarkEndNode(name3))
1242 root.appendchild(DocumentIndexMarkEndNode(name2))
1243 root.appendchild(DocumentIndexMarkEndNode(name1))
1244 root.appendchild(TextNode("de"))
1245 self.dotest(root)
1247 def test_marks1(self):
1248 name1 = self.mkname("bookmark")
1249 name2 = self.mkname("toxmark")
1250 name3 = self.mkname("refmark")
1251 name4 = self.mkname("toxmark")
1252 root = TreeNode()
1253 root.appendchild(BookmarkStartNode(name1))
1254 root.appendchild(DocumentIndexMarkNode(name2))
1255 root.appendchild(ReferenceMarkStartNode(name3))
1256 root.appendchild(TextNode("abc"))
1257 root.appendchild(BookmarkEndNode(name1))
1258 root.appendchild(DocumentIndexMarkStartNode(name4))
1259 root.appendchild(TextNode("de"))
1260 root.appendchild(DocumentIndexMarkEndNode(name4))
1261 root.appendchild(ReferenceMarkEndNode(name3))
1262 self.dotest(root)
1264 def test_marks2(self):
1265 name1 = self.mkname("bookmark")
1266 name2 = self.mkname("refmark")
1267 name3 = self.mkname("refmark")
1268 name4 = self.mkname("toxmark")
1269 name5 = self.mkname("refmark")
1270 root = TreeNode()
1271 root.appendchild(BookmarkStartNode(name1))
1272 root.appendchild(ReferenceMarkNode(name2))
1273 root.appendchild(ReferenceMarkStartNode(name3))
1274 root.appendchild(TextNode("abc"))
1275 root.appendchild(DocumentIndexMarkStartNode(name4))
1276 root.appendchild(ReferenceMarkStartNode(name5))
1277 # BUG: #i102541# (this is actually not unoportenum's fault)
1278 root.appendchild(ReferenceMarkEndNode(name3))
1279 root.appendchild(TextNode("de"))
1280 root.appendchild(DocumentIndexMarkEndNode(name4))
1281 root.appendchild(BookmarkEndNode(name1))
1282 root.appendchild(ReferenceMarkEndNode(name5))
1283 self.dotest(root)
1285 def test_marks3(self):
1286 name1 = self.mkname("bookmark")
1287 name2 = self.mkname("refmark")
1288 name3 = self.mkname("refmark")
1289 name4 = self.mkname("toxmark")
1290 name5 = self.mkname("refmark")
1291 root = TreeNode()
1292 root.appendchild(BookmarkStartNode(name1))
1293 root.appendchild(DocumentIndexMarkNode(name2))
1294 root.appendchild(DocumentIndexMarkStartNode(name3))
1295 root.appendchild(TextNode("abc"))
1296 root.appendchild(ReferenceMarkStartNode(name4))
1297 root.appendchild(DocumentIndexMarkStartNode(name5))
1298 root.appendchild(DocumentIndexMarkEndNode(name3))
1299 root.appendchild(TextNode("de"))
1300 root.appendchild(ReferenceMarkEndNode(name4))
1301 root.appendchild(BookmarkEndNode(name1))
1302 root.appendchild(DocumentIndexMarkEndNode(name5))
1303 self.dotest(root)
1305 def test_frame_mark1(self):
1306 name1 = self.mkname("bookmark")
1307 name2 = self.mkname("frame")
1308 root = TreeNode()
1309 root.appendchild(TextNode("abc"))
1310 root.appendchild(BookmarkNode(name1))
1311 root.appendchild(TextNode("de"))
1312 root.appendchild(FrameNode(name2, AS_CHARACTER))
1313 self.dotest(root)
1315 def test_frame_mark2(self):
1316 # BUG: #i98530#
1317 name1 = self.mkname("bookmark")
1318 name2 = self.mkname("frame")
1319 root = TreeNode()
1320 root.appendchild(TextNode("abc"))
1321 root.appendchild(BookmarkNode(name1))
1322 root.appendchild(TextNode("de"))
1323 root.appendchild(FrameNode(name2, AT_CHARACTER))
1324 self.dotest(root)
1326 def test_frame_mark3(self):
1327 name1 = self.mkname("frame")
1328 name2 = self.mkname("bookmark")
1329 root = TreeNode()
1330 root.appendchild(TextNode("abc"))
1331 root.appendchild(FrameNode(name1, AS_CHARACTER))
1332 root.appendchild(TextNode("de"))
1333 root.appendchild(BookmarkNode(name2))
1334 self.dotest(root)
1336 def test_frame_mark4(self):
1337 name1 = self.mkname("frame")
1338 name2 = self.mkname("bookmark")
1339 root = TreeNode()
1340 root.appendchild(TextNode("abc"))
1341 root.appendchild(FrameNode(name1, AT_CHARACTER))
1342 root.appendchild(TextNode("de"))
1343 root.appendchild(BookmarkNode(name2))
1344 self.dotest(root)
1346 def test_frames1(self):
1347 name1 = self.mkname("frame")
1348 name2 = self.mkname("frame")
1349 name3 = self.mkname("frame")
1350 root = TreeNode()
1351 root.appendchild(FrameNode(name1, AT_CHARACTER))
1352 root.appendchild(FrameNode(name2, AT_CHARACTER))
1353 root.appendchild(FrameNode(name3, AT_CHARACTER))
1354 self.dotest(root)
1356 def test_frames2(self):
1357 name1 = self.mkname("frame")
1358 name2 = self.mkname("frame")
1359 name3 = self.mkname("frame")
1360 root = TreeNode()
1361 root.appendchild(FrameNode(name1, AS_CHARACTER))
1362 root.appendchild(FrameNode(name2, AS_CHARACTER))
1363 root.appendchild(FrameNode(name3, AS_CHARACTER))
1364 self.dotest(root)
1366 def test_frames3(self):
1367 name1 = self.mkname("frame")
1368 name2 = self.mkname("frame")
1369 name3 = self.mkname("frame")
1370 root = TreeNode()
1371 root.appendchild(FrameNode(name1, AT_CHARACTER))
1372 root.appendchild(FrameNode(name2, AS_CHARACTER))
1373 root.appendchild(FrameNode(name3, AT_CHARACTER))
1374 self.dotest(root)
1376 def test_frames4(self):
1377 name1 = self.mkname("frame")
1378 name2 = self.mkname("frame")
1379 name3 = self.mkname("frame")
1380 root = TreeNode()
1381 root.appendchild(FrameNode(name1, AT_CHARACTER))
1382 root.appendchild(FrameNode(name2, AT_CHARACTER))
1383 root.appendchild(FrameNode(name3, AS_CHARACTER))
1384 self.dotest(root)
1386 def test_frames5(self):
1387 name1 = self.mkname("frame")
1388 name2 = self.mkname("frame")
1389 name3 = self.mkname("frame")
1390 root = TreeNode()
1391 root.appendchild(FrameNode(name1, AS_CHARACTER))
1392 root.appendchild(FrameNode(name2, AT_CHARACTER))
1393 root.appendchild(FrameNode(name3, AT_CHARACTER))
1394 self.dotest(root)
1396 def test_ruby_hyperlink1(self):
1397 name1 = self.mkname("ruby")
1398 name2 = self.mkname("url")
1399 root = TreeNode()
1400 ruby = RubyNode(name1)
1401 href = HyperlinkNode(name2)
1402 href.appendchild(TextNode("abc"))
1403 ruby.appendchild(href)
1404 root.appendchild(ruby)
1405 self.dotest(root)
1407 def test_ruby_hyperlink2(self):
1408 name1 = self.mkname("url")
1409 name2 = self.mkname("ruby")
1410 root = TreeNode()
1411 href = HyperlinkNode(name1)
1412 ruby = RubyNode(name2)
1413 ruby.appendchild(TextNode("abc"))
1414 href.appendchild(ruby)
1415 root.appendchild(href)
1416 self.dotest(root)
1418 def test_end1(self):
1419 name1 = self.mkname("bookmark")
1420 name2 = self.mkname("toxmark")
1421 name3 = self.mkname("refmark")
1422 root = TreeNode()
1423 root.appendchild(TextNode("abc"))
1424 root.appendchild(BookmarkNode(name1))
1425 root.appendchild(DocumentIndexMarkNode(name2))
1426 root.appendchild(ReferenceMarkNode(name3))
1427 self.dotest(root)
1429 def test_end2(self):
1430 name1 = self.mkname("bookmark")
1431 name2 = self.mkname("frame")
1432 name3 = self.mkname("refmark")
1433 name4 = self.mkname("frame")
1434 name5 = self.mkname("frame")
1435 root = TreeNode()
1436 root.appendchild(TextNode("abc"))
1437 root.appendchild(BookmarkStartNode(name1))
1438 root.appendchild(FrameNode(name2, AT_CHARACTER))
1439 root.appendchild(BookmarkEndNode(name1))
1440 root.appendchild(ReferenceMarkNode(name3))
1441 root.appendchild(FrameNode(name4, AT_CHARACTER))
1442 root.appendchild(FrameNode(name5, AT_CHARACTER))
1443 self.dotest(root)
1445 def test_end3(self):
1446 name1 = self.mkname("ftn")
1447 name2 = self.mkname("toxmark")
1448 root = TreeNode()
1449 root.appendchild(TextNode("abc"))
1450 root.appendchild(FootnoteNode(name1))
1451 root.appendchild(DocumentIndexMarkNode(name2))
1452 self.dotest(root)
1454 def test_end4(self):
1455 name1 = self.mkname("bookmark")
1456 name2 = self.mkname("frame")
1457 root = TreeNode()
1458 root.appendchild(BookmarkStartNode(name1))
1459 root.appendchild(TextNode("abc"))
1460 root.appendchild(FrameNode(name2, AS_CHARACTER))
1461 root.appendchild(BookmarkEndNode(name1))
1462 self.dotest(root)
1464 def test_end5(self):
1465 name1 = self.mkname("refmark")
1466 name2 = self.mkname("ruby")
1467 root = TreeNode()
1468 root.appendchild(ReferenceMarkStartNode(name1))
1469 root.appendchild(TextNode("abc"))
1470 ruby = RubyNode(name2)
1471 ruby.appendchild(TextFieldNode("de"))
1472 root.appendchild(ruby)
1473 root.appendchild(ReferenceMarkEndNode(name1))
1474 self.dotest(root)
1476 def test_empty1(self):
1477 name1 = self.mkname("refmark")
1478 name2 = self.mkname("toxmark")
1479 name3 = self.mkname("bookmark")
1480 name4 = self.mkname("frame")
1481 name7 = self.mkname("refmark")
1482 name8 = self.mkname("toxmark")
1483 name9 = self.mkname("bookmark")
1484 nameA = self.mkname("frame")
1485 root = TreeNode()
1486 root.appendchild(ReferenceMarkNode(name1))
1487 root.appendchild(DocumentIndexMarkNode(name2))
1488 root.appendchild(BookmarkStartNode(name3))
1489 root.appendchild(FrameNode(name4, AT_CHARACTER))
1490 root.appendchild(BookmarkEndNode(name3))
1491 root.appendchild(ReferenceMarkNode(name7))
1492 root.appendchild(DocumentIndexMarkNode(name8))
1493 root.appendchild(BookmarkStartNode(name9))
1494 root.appendchild(FrameNode(nameA, AT_CHARACTER))
1495 root.appendchild(BookmarkEndNode(name9))
1496 self.dotest(root)
1498 def test_empty2(self):
1499 name3 = self.mkname("bookmark")
1500 name4 = self.mkname("frame")
1501 name9 = self.mkname("bookmark")
1502 nameA = self.mkname("frame")
1503 root = TreeNode()
1504 root.appendchild(BookmarkStartNode(name3))
1505 root.appendchild(FrameNode(name4, AT_CHARACTER))
1506 root.appendchild(BookmarkEndNode(name3))
1507 root.appendchild(BookmarkStartNode(name9))
1508 root.appendchild(FrameNode(nameA, AT_CHARACTER))
1509 root.appendchild(BookmarkEndNode(name9))
1510 self.dotest(root)
1512 def test_empty3(self):
1513 name1 = self.mkname("refmark")
1514 name2 = self.mkname("toxmark")
1515 name3 = self.mkname("bookmark")
1516 name4 = self.mkname("frame")
1517 # name5 = self.mkname("url")
1518 name6 = self.mkname("ruby")
1519 name7 = self.mkname("refmark")
1520 name8 = self.mkname("toxmark")
1521 name9 = self.mkname("bookmark")
1522 nameA = self.mkname("frame")
1523 root = TreeNode()
1524 root.appendchild(ReferenceMarkNode(name1))
1525 root.appendchild(DocumentIndexMarkNode(name2))
1526 root.appendchild(BookmarkStartNode(name3))
1527 root.appendchild(FrameNode(name4, AT_CHARACTER))
1528 root.appendchild(BookmarkEndNode(name3))
1529 ## currently empty hyperlinks may get eaten...
1530 # href = HyperlinkNode(name5)
1531 # href.appendchild(TextNode(""))
1532 # root.appendchild(href)
1533 ruby = RubyNode(name6)
1534 root.appendchild(ruby)
1535 root.appendchild(ReferenceMarkNode(name7))
1536 root.appendchild(DocumentIndexMarkNode(name8))
1537 root.appendchild(BookmarkStartNode(name9))
1538 root.appendchild(FrameNode(nameA, AT_CHARACTER))
1539 root.appendchild(BookmarkEndNode(name9))
1540 self.dotest(root)
1542 def test1(self):
1543 name1 = self.mkname("frame")
1544 name2 = self.mkname("bookmark")
1545 name3 = self.mkname("ruby")
1546 name4 = self.mkname("ftn")
1547 name5 = self.mkname("frame")
1548 root = TreeNode()
1549 root.appendchild(FrameNode(name1, AT_CHARACTER))
1550 root.appendchild(BookmarkStartNode(name2))
1551 root.appendchild(TextNode("abc"))
1552 ruby = RubyNode(name3)
1553 ruby.appendchild(TextNode("de"))
1554 ruby.appendchild(FootnoteNode(name4))
1555 ruby.appendchild(BookmarkEndNode(name2))
1556 root.appendchild(ruby)
1557 root.appendchild(TextNode("fg"))
1558 root.appendchild(FrameNode(name5, AT_CHARACTER))
1559 root.appendchild(TextFieldNode("h"))
1560 self.dotest(root)
1562 # some range tests for the insertion: these are for the current
1563 # API which treats hyperlinks and rubys not as entities, but as formatting
1564 # attributes; if these ever become entities, they should not be split!'''
1566 def test_range1(self):
1567 name1 = self.mkname("url")
1568 inserter = RangeInserter(self.__class__.xDoc)
1569 text = TextNode("12345")
1570 inserter.insertrange(Range(0, 0, text))
1571 url1 = HyperlinkNode(name1)
1572 range1 = Range(0, 5, url1)
1573 inserter.insertrange(range1)
1574 root = TreeNode()
1575 root.appendchild(url1)
1576 url1.appendchild(text)
1577 self.dotest(root, False)
1579 def test_range_hyperlink_hyperlink(self):
1580 inserter = RangeInserter(self.__class__.xDoc)
1581 text = TextNode("123456789")
1582 inserter.insertrange(Range(0, 0, text))
1583 url1 = HyperlinkNode(self.mkname("url"))
1584 inserter.insertrange(Range(1, 4, url1))
1585 ## overlap left
1586 url2 = HyperlinkNode(self.mkname("url"))
1587 inserter.insertrange(Range(0, 2, url2))
1588 root = TreeNode()
1589 root.appendchild(url2.dup().appendchild(TextNode("12")))
1590 root.appendchild(url1.dup().appendchild(TextNode("34")))
1591 root.appendchild(TextNode("56789"))
1592 self.dotest(root, False)
1593 ## overlap right
1594 url3 = HyperlinkNode(self.mkname("url"))
1595 inserter.insertrange(Range(3, 7, url3))
1596 root = TreeNode()
1597 root.appendchild(url2.dup().appendchild(TextNode("12")))
1598 root.appendchild(url1.dup().appendchild(TextNode("3")))
1599 root.appendchild(url3.dup().appendchild(TextNode("4567")))
1600 root.appendchild(TextNode("89"))
1601 self.dotest(root, False)
1602 ## around
1603 url4 = HyperlinkNode(self.mkname("url"))
1604 inserter.insertrange(Range(3, 7, url4))
1605 root = TreeNode()
1606 root.appendchild(url2.dup().appendchild(TextNode("12")))
1607 root.appendchild(url1.dup().appendchild(TextNode("3")))
1608 root.appendchild(url4.dup().appendchild(TextNode("4567")))
1609 root.appendchild(TextNode("89"))
1610 self.dotest(root, False)
1611 ## inside
1612 url5 = HyperlinkNode(self.mkname("url"))
1613 inserter.insertrange(Range(4, 6, url5))
1614 root = TreeNode()
1615 root.appendchild(url2.dup().appendchild(TextNode("12")))
1616 root.appendchild(url1.dup().appendchild(TextNode("3")))
1617 root.appendchild(url4.dup().appendchild(TextNode("4")))
1618 root.appendchild(url5.dup().appendchild(TextNode("56")))
1619 root.appendchild(url4.dup().appendchild(TextNode("7")))
1620 root.appendchild(TextNode("89"))
1621 self.dotest(root, False)
1622 ## empty
1623 url6 = HyperlinkNode(self.mkname("url"))
1624 inserter.insertrange(Range(7, 7, url6))
1625 root = TreeNode()
1626 root.appendchild(url2.dup().appendchild(TextNode("12")))
1627 root.appendchild(url1.dup().appendchild(TextNode("3")))
1628 root.appendchild(url4.dup().appendchild(TextNode("4")))
1629 root.appendchild(url5.dup().appendchild(TextNode("56")))
1630 root.appendchild(url4.dup().appendchild(TextNode("7")))
1631 ## this one gets eaten, but we still need to test inserting it (#i106930#)
1632 # root.appendchild(url6.dup().appendchild(TextNode("")))
1633 root.appendchild(TextNode("89"))
1634 ## inside (left-edge)
1635 url7 = HyperlinkNode(self.mkname("url"))
1636 inserter.insertrange(Range(0, 1, url7))
1637 root = TreeNode()
1638 root.appendchild(url7.dup().appendchild(TextNode("1")))
1639 root.appendchild(url2.dup().appendchild(TextNode("2")))
1640 root.appendchild(url1.dup().appendchild(TextNode("3")))
1641 root.appendchild(url4.dup().appendchild(TextNode("4")))
1642 root.appendchild(url5.dup().appendchild(TextNode("56")))
1643 root.appendchild(url4.dup().appendchild(TextNode("7")))
1644 root.appendchild(TextNode("89"))
1645 ## inside (right-edge)
1646 url8 = HyperlinkNode(self.mkname("url"))
1647 inserter.insertrange(Range(5, 6, url8))
1648 root = TreeNode()
1649 root.appendchild(url7.dup().appendchild(TextNode("1")))
1650 root.appendchild(url2.dup().appendchild(TextNode("2")))
1651 root.appendchild(url1.dup().appendchild(TextNode("3")))
1652 root.appendchild(url4.dup().appendchild(TextNode("4")))
1653 root.appendchild(url5.dup().appendchild(TextNode("5")))
1654 root.appendchild(url8.dup().appendchild(TextNode("6")))
1655 root.appendchild(url4.dup().appendchild(TextNode("7")))
1656 root.appendchild(TextNode("89"))
1657 self.dotest(root, False)
1659 def test_range_hyperlink_ruby(self):
1660 inserter = RangeInserter(self.__class__.xDoc)
1661 text = TextNode("123456789")
1662 inserter.insertrange(Range(0, 0, text))
1663 url1 = HyperlinkNode(self.mkname("url"))
1664 inserter.insertrange(Range(1, 4, url1))
1665 # overlap left
1666 rby2 = RubyNode(self.mkname("ruby"))
1667 inserter.insertrange(Range(0, 2, rby2))
1668 root = TreeNode()
1669 root.appendchild(rby2.dup()
1670 .appendchild(TextNode("1"))
1671 .appendchild(url1.dup().appendchild(TextNode("2"))))
1672 root.appendchild(url1.dup().appendchild(TextNode("34")))
1673 root.appendchild(TextNode("56789"))
1674 self.dotest(root, False)
1675 # overlap right
1676 rby3 = RubyNode(self.mkname("ruby"))
1677 inserter.insertrange(Range(3, 5, rby3))
1678 root = TreeNode()
1679 root.appendchild(rby2.dup()
1680 .appendchild(TextNode("1"))
1681 .appendchild(url1.dup().appendchild(TextNode("2"))))
1682 root.appendchild(url1.dup().appendchild(TextNode("3")))
1683 root.appendchild(rby3.dup()
1684 .appendchild(url1.dup().appendchild(TextNode("4")))
1685 .appendchild(TextNode("5")))
1686 root.appendchild(TextNode("6789"))
1687 self.dotest(root, False)
1688 # around
1689 rby4 = RubyNode(self.mkname("ruby"))
1690 inserter.insertrange(Range(2, 3, rby4))
1691 root = TreeNode()
1692 root.appendchild(rby2.dup()
1693 .appendchild(TextNode("1"))
1694 .appendchild(url1.dup().appendchild(TextNode("2"))))
1695 root.appendchild(rby4.dup()
1696 .appendchild(url1.dup().appendchild(TextNode("3"))))
1697 root.appendchild(rby3.dup()
1698 .appendchild(url1.dup().appendchild(TextNode("4")))
1699 .appendchild(TextNode("5")))
1700 root.appendchild(TextNode("6789"))
1701 self.dotest(root, False)
1702 # inside
1703 url5 = HyperlinkNode(self.mkname("url"))
1704 inserter.insertrange(Range(6, 9, url5))
1705 rby6 = RubyNode(self.mkname("ruby"))
1706 inserter.insertrange(Range(7, 8, rby6))
1707 root = TreeNode()
1708 root.appendchild(rby2.dup()
1709 .appendchild(TextNode("1"))
1710 .appendchild(url1.dup().appendchild(TextNode("2"))))
1711 root.appendchild(rby4.dup()
1712 .appendchild(url1.dup().appendchild(TextNode("3"))))
1713 root.appendchild(rby3.dup()
1714 .appendchild(url1.dup().appendchild(TextNode("4")))
1715 .appendchild(TextNode("5")))
1716 root.appendchild(TextNode("6"))
1717 root.appendchild(url5.dup().appendchild(TextNode("7")))
1718 root.appendchild(rby6.dup()
1719 .appendchild(url5.dup().appendchild(TextNode("8"))))
1720 root.appendchild(url5.dup().appendchild(TextNode("9")))
1721 self.dotest(root, False)
1723 def test_range_ruby_hyperlink(self):
1724 inserter = RangeInserter(self.__class__.xDoc)
1725 text = TextNode("123456789")
1726 inserter.insertrange(Range(0, 0, text))
1727 rby1 = RubyNode(self.mkname("ruby"))
1728 inserter.insertrange(Range(1, 6, rby1))
1729 ## overlap left
1730 url2 = HyperlinkNode(self.mkname("url"))
1731 inserter.insertrange(Range(0, 3, url2))
1732 root = TreeNode()
1733 root.appendchild(url2.dup().appendchild(TextNode("1")))
1734 root.appendchild(rby1.dup()
1735 .appendchild(url2.dup().appendchild(TextNode("23")))
1736 .appendchild(TextNode("456")))
1737 root.appendchild(TextNode("789"))
1738 self.dotest(root, False)
1739 ## overlap right
1740 url3 = HyperlinkNode(self.mkname("url"))
1741 inserter.insertrange(Range(5, 7, url3))
1742 root = TreeNode()
1743 root.appendchild(url2.dup().appendchild(TextNode("1")))
1744 root.appendchild(rby1.dup()
1745 .appendchild(url2.dup().appendchild(TextNode("23")))
1746 .appendchild(TextNode("45"))
1747 .appendchild(url3.dup().appendchild(TextNode("6"))))
1748 root.appendchild(url3.dup().appendchild(TextNode("7")))
1749 root.appendchild(TextNode("89"))
1750 self.dotest(root, False)
1751 ## around (not quite, due to API)
1752 url4 = HyperlinkNode(self.mkname("url"))
1753 inserter.insertrange(Range(1, 8, url4))
1754 root = TreeNode()
1755 root.appendchild(url2.dup().appendchild(TextNode("1")))
1756 root.appendchild(rby1.dup()
1757 .appendchild(url4.dup()
1758 .appendchild(TextNode("23456"))))
1759 root.appendchild(url4.dup().appendchild(TextNode("78")))
1760 root.appendchild(TextNode("9"))
1761 self.dotest(root, False)
1762 ## inside
1763 url5 = HyperlinkNode(self.mkname("url"))
1764 inserter.insertrange(Range(3, 5, url5))
1765 root = TreeNode()
1766 root.appendchild(url2.dup().appendchild(TextNode("1")))
1767 root.appendchild(rby1.dup()
1768 .appendchild(url4.dup()
1769 .appendchild(TextNode("23")))
1770 .appendchild(url5.dup()
1771 .appendchild(TextNode("45")))
1772 .appendchild(url4.dup()
1773 .appendchild(TextNode("6"))))
1774 root.appendchild(url4.dup().appendchild(TextNode("78")))
1775 root.appendchild(TextNode("9"))
1776 self.dotest(root, False)
1778 def test_range_ruby_ruby(self):
1779 inserter = RangeInserter(self.__class__.xDoc)
1780 text = TextNode("123456789")
1781 inserter.insertrange(Range(0, 0, text))
1782 rby1 = RubyNode(self.mkname("ruby"))
1783 inserter.insertrange(Range(1, 4, rby1))
1784 ## overlap left
1785 rby2 = RubyNode(self.mkname("ruby"))
1786 inserter.insertrange(Range(0, 2, rby2))
1787 root = TreeNode()
1788 root.appendchild(rby2.dup().appendchild(TextNode("12")))
1789 root.appendchild(rby1.dup().appendchild(TextNode("34")))
1790 root.appendchild(TextNode("56789"))
1791 self.dotest(root, False)
1792 ## overlap right
1793 rby3 = RubyNode(self.mkname("ruby"))
1794 inserter.insertrange(Range(3, 7, rby3))
1795 root = TreeNode()
1796 root.appendchild(rby2.dup().appendchild(TextNode("12")))
1797 root.appendchild(rby1.dup().appendchild(TextNode("3")))
1798 root.appendchild(rby3.dup().appendchild(TextNode("4567")))
1799 root.appendchild(TextNode("89"))
1800 self.dotest(root, False)
1801 ## around
1802 rby4 = RubyNode(self.mkname("ruby"))
1803 inserter.insertrange(Range(3, 7, rby4))
1804 root = TreeNode()
1805 root.appendchild(rby2.dup().appendchild(TextNode("12")))
1806 root.appendchild(rby1.dup().appendchild(TextNode("3")))
1807 root.appendchild(rby4.dup().appendchild(TextNode("4567")))
1808 root.appendchild(TextNode("89"))
1809 self.dotest(root, False)
1810 ## inside
1811 rby5 = RubyNode(self.mkname("ruby"))
1812 inserter.insertrange(Range(4, 6, rby5))
1813 root = TreeNode()
1814 root.appendchild(rby2.dup().appendchild(TextNode("12")))
1815 root.appendchild(rby1.dup().appendchild(TextNode("3")))
1816 root.appendchild(rby4.dup().appendchild(TextNode("4")))
1817 root.appendchild(rby5.dup().appendchild(TextNode("56")))
1818 root.appendchild(rby4.dup().appendchild(TextNode("7")))
1819 root.appendchild(TextNode("89"))
1820 self.dotest(root, False)
1822 def test_range_hyperlink_meta(self):
1823 inserter = RangeInserter(self.__class__.xDoc)
1824 text = TextNode("123456789")
1825 inserter.insertrange(Range(0, 0, text))
1826 url1 = HyperlinkNode(self.mkname("url"))
1827 inserter.insertrange(Range(1, 4, url1))
1828 ## overlap left
1829 met2 = MetaNode(self.mkid("id"))
1830 inserter.insertrange(Range(0, 2, met2))
1831 root = TreeNode()
1832 root.appendchild(met2.dup()
1833 .appendchild(TextNode("1"))
1834 .appendchild(url1.dup().appendchild(TextNode("2"))))
1835 root.appendchild(url1.dup().appendchild(TextNode("34")))
1836 root.appendchild(TextNode("56789"))
1837 self.dotest(root, False)
1838 ## overlap right
1839 met3 = MetaNode(self.mkid("id"))
1840 # inserter.insertrange(Range(4-1, 6-1, met3))
1841 inserter.insertrange(Range(4, 6, met3))
1842 root = TreeNode()
1843 root.appendchild(met2.dup()
1844 .appendchild(TextNode("1"))
1845 .appendchild(url1.dup().appendchild(TextNode("2"))))
1846 root.appendchild(url1.dup().appendchild(TextNode("3")))
1847 root.appendchild(met3.dup()
1848 .appendchild(url1.dup().appendchild(TextNode("4")))
1849 .appendchild(TextNode("5")))
1850 root.appendchild(TextNode("6789"))
1851 self.dotest(root, False)
1852 ## around
1853 met4 = MetaNode(self.mkid("id"))
1854 # inserter.insertrange(Range(3-1, 4-1, met4))
1855 inserter.insertrange(Range(3, 4, met4))
1856 root = TreeNode()
1857 root.appendchild(met2.dup()
1858 .appendchild(TextNode("1"))
1859 .appendchild(url1.dup().appendchild(TextNode("2"))))
1860 root.appendchild(met4.dup()
1861 .appendchild(url1.dup().appendchild(TextNode("3"))))
1862 root.appendchild(met3.dup()
1863 .appendchild(url1.dup().appendchild(TextNode("4")))
1864 .appendchild(TextNode("5")))
1865 root.appendchild(TextNode("6789"))
1866 self.dotest(root, False)
1867 ## inside
1868 url5 = HyperlinkNode(self.mkname("url"))
1869 # inserter.insertrange(Range(9-3, 12-3, url5))
1870 inserter.insertrange(Range(9, 12, url5))
1871 met6 = MetaNode(self.mkid("id"))
1872 # inserter.insertrange(Range(10-3, 11-3, met6))
1873 inserter.insertrange(Range(10, 11, met6))
1874 root = TreeNode()
1875 root.appendchild(met2.dup()
1876 .appendchild(TextNode("1"))
1877 .appendchild(url1.dup().appendchild(TextNode("2"))))
1878 root.appendchild(met4.dup()
1879 .appendchild(url1.dup().appendchild(TextNode("3"))))
1880 root.appendchild(met3.dup()
1881 .appendchild(url1.dup().appendchild(TextNode("4")))
1882 .appendchild(TextNode("5")))
1883 root.appendchild(TextNode("6"))
1884 root.appendchild(url5.dup().appendchild(TextNode("7")))
1885 root.appendchild(met6.dup()
1886 .appendchild(url5.dup().appendchild(TextNode("8"))))
1887 root.appendchild(url5.dup().appendchild(TextNode("9")))
1888 self.dotest(root, False)
1890 def test_range_ruby_meta(self):
1891 inserter = RangeInserter(self.__class__.xDoc)
1892 text = TextNode("123456789")
1893 inserter.insertrange(Range(0, 0, text))
1894 rby1 = RubyNode(self.mkname("ruby"))
1895 inserter.insertrange(Range(1, 4, rby1))
1896 ## overlap left
1897 met2 = MetaNode(self.mkid("id"))
1898 inserter.insertrange(Range(0, 2, met2))
1899 root = TreeNode()
1900 root.appendchild(met2.dup()
1901 .appendchild(TextNode("1"))
1902 .appendchild(rby1.dup().appendchild(TextNode("2"))))
1903 root.appendchild(rby1.dup().appendchild(TextNode("34")))
1904 root.appendchild(TextNode("56789"))
1905 self.dotest(root, False)
1906 ## overlap right
1907 met3 = MetaNode(self.mkid("id"))
1908 # inserter.insertrange(Range(4-1, 6-1, met3))
1909 inserter.insertrange(Range(4, 6, met3))
1910 root = TreeNode()
1911 root.appendchild(met2.dup()
1912 .appendchild(TextNode("1"))
1913 .appendchild(rby1.dup().appendchild(TextNode("2"))))
1914 root.appendchild(rby1.dup().appendchild(TextNode("3")))
1915 root.appendchild(met3.dup()
1916 .appendchild(rby1.dup().appendchild(TextNode("4")))
1917 .appendchild(TextNode("5")))
1918 root.appendchild(TextNode("6789"))
1919 self.dotest(root, False)
1920 ## around
1921 met4 = MetaNode(self.mkid("id"))
1922 # inserter.insertrange(Range(3-1, 4-1, met4))
1923 inserter.insertrange(Range(3, 4, met4))
1924 root = TreeNode()
1925 root.appendchild(met2.dup()
1926 .appendchild(TextNode("1"))
1927 .appendchild(rby1.dup().appendchild(TextNode("2"))))
1928 root.appendchild(met4.dup()
1929 .appendchild(rby1.dup().appendchild(TextNode("3"))))
1930 root.appendchild(met3.dup()
1931 .appendchild(rby1.dup().appendchild(TextNode("4")))
1932 .appendchild(TextNode("5")))
1933 root.appendchild(TextNode("6789"))
1934 self.dotest(root, False)
1935 ## inside
1936 rby5 = RubyNode(self.mkname("ruby"))
1937 # inserter.insertrange(Range(9-3, 12-3, rby5))
1938 inserter.insertrange(Range(9, 12, rby5))
1939 met6 = MetaNode(self.mkid("id"))
1940 # inserter.insertrange(Range(10-3, 11-3, met6))
1941 inserter.insertrange(Range(10, 11, met6))
1942 root = TreeNode()
1943 root.appendchild(met2.dup()
1944 .appendchild(TextNode("1"))
1945 .appendchild(rby1.dup().appendchild(TextNode("2"))))
1946 root.appendchild(met4.dup()
1947 .appendchild(rby1.dup().appendchild(TextNode("3"))))
1948 root.appendchild(met3.dup()
1949 .appendchild(rby1.dup().appendchild(TextNode("4")))
1950 .appendchild(TextNode("5")))
1951 root.appendchild(TextNode("6"))
1952 root.appendchild(rby5.dup()
1953 .appendchild(TextNode("7"))
1954 .appendchild(met6.dup()
1955 .appendchild(TextNode("8")))
1956 .appendchild(TextNode("9")))
1957 self.dotest(root, False)
1959 def test_range_meta_hyperlink(self):
1960 inserter = RangeInserter(self.__class__.xDoc)
1961 text = TextNode("123456789")
1962 inserter.insertrange(Range(0, 0, text))
1963 met1 = MetaNode(self.mkid("id"))
1964 inserter.insertrange(Range(1, 6, met1))
1965 ## overlap left
1966 url2 = HyperlinkNode(self.mkname("url"))
1967 # inserter.insertrange(Range(0, 4-1, url2))
1968 inserter.insertrange(Range(0, 4, url2))
1969 root = TreeNode()
1970 root.appendchild(url2.dup().appendchild(TextNode("1")))
1971 root.appendchild(met1.dup()
1972 .appendchild(url2.dup().appendchild(TextNode("23")))
1973 .appendchild(TextNode("456")))
1974 root.appendchild(TextNode("789"))
1975 self.dotest(root, False)
1976 ## overlap right
1977 url3 = HyperlinkNode(self.mkname("url"))
1978 # inserter.insertrange(Range(6-1, 8-1, url3))
1979 inserter.insertrange(Range(6, 8, url3))
1980 root = TreeNode()
1981 root.appendchild(url2.dup().appendchild(TextNode("1")))
1982 root.appendchild(met1.dup()
1983 .appendchild(url2.dup().appendchild(TextNode("23")))
1984 .appendchild(TextNode("45"))
1985 .appendchild(url3.dup().appendchild(TextNode("6"))))
1986 root.appendchild(url3.dup().appendchild(TextNode("7")))
1987 root.appendchild(TextNode("89"))
1988 self.dotest(root, False)
1989 ## around (not quite, due to API)
1990 url4 = HyperlinkNode(self.mkname("url"))
1991 # inserter.insertrange(Range(1, 9-1, url4))
1992 inserter.insertrange(Range(1, 9, url4))
1993 root = TreeNode()
1994 root.appendchild(url2.dup().appendchild(TextNode("1")))
1995 root.appendchild(met1.dup()
1996 .appendchild(url4.dup()
1997 .appendchild(TextNode("23456"))))
1998 root.appendchild(url4.dup().appendchild(TextNode("78")))
1999 root.appendchild(TextNode("9"))
2000 self.dotest(root, False)
2001 ## inside
2002 url5 = HyperlinkNode(self.mkname("url"))
2003 # inserter.insertrange(Range(4-1, 6-1, url5))
2004 inserter.insertrange(Range(4, 6, url5))
2005 root = TreeNode()
2006 root.appendchild(url2.dup().appendchild(TextNode("1")))
2007 root.appendchild(met1.dup()
2008 .appendchild(url4.dup()
2009 .appendchild(TextNode("23")))
2010 .appendchild(url5.dup()
2011 .appendchild(TextNode("45")))
2012 .appendchild(url4.dup()
2013 .appendchild(TextNode("6"))))
2014 root.appendchild(url4.dup().appendchild(TextNode("78")))
2015 root.appendchild(TextNode("9"))
2016 self.dotest(root, False)
2018 def test_range_meta_ruby(self):
2019 inserter = RangeInserter(self.__class__.xDoc)
2020 text = TextNode("123456789")
2021 inserter.insertrange(Range(0, 0, text))
2022 met1 = MetaNode(self.mkid("id"))
2023 inserter.insertrange(Range(1, 5, met1))
2024 ## overlap left
2025 rby2 = RubyNode(self.mkname("ruby"))
2026 # inserter.insertrange(Range(0, 3-1, rby2))
2027 inserter.insertrange(Range(0, 3, rby2))
2028 root = TreeNode()
2029 root.appendchild(rby2.dup().appendchild(TextNode("1")))
2030 root.appendchild(met1.dup()
2031 .appendchild(rby2.dup().appendchild(TextNode("2")))
2032 .appendchild(TextNode("345")))
2033 root.appendchild(TextNode("6789"))
2034 self.dotest(root, False)
2035 ## overlap right
2036 rby3 = RubyNode(self.mkname("ruby"))
2037 # inserter.insertrange(Range(5-1, 7-1, rby3))
2038 inserter.insertrange(Range(5, 7, rby3))
2039 root = TreeNode()
2040 root.appendchild(rby2.dup().appendchild(TextNode("1")))
2041 root.appendchild(met1.dup()
2042 .appendchild(rby2.dup().appendchild(TextNode("2")))
2043 .appendchild(TextNode("34"))
2044 .appendchild(rby3.dup().appendchild(TextNode("5"))))
2045 root.appendchild(rby3.dup().appendchild(TextNode("6")))
2046 root.appendchild(TextNode("789"))
2047 self.dotest(root, False)
2048 ## // around
2049 rby4 = RubyNode(self.mkname("ruby"))
2050 # inserter.insertrange(Range(1, 7-1, rby4))
2051 inserter.insertrange(Range(1, 7, rby4))
2052 root = TreeNode()
2053 root.appendchild(rby2.dup().appendchild(TextNode("1")))
2054 root.appendchild(rby4.dup()
2055 .appendchild(met1.dup()
2056 .appendchild(TextNode("2345")))
2057 .appendchild(TextNode("6")))
2058 root.appendchild(TextNode("789"))
2059 self.dotest(root, False)
2060 ## inside
2061 met5 = MetaNode(self.mkid("id"))
2062 # inserter.insertrange(Range(7-1, 9-1, met5))
2063 inserter.insertrange(Range(7, 9, met5))
2064 rby6 = RubyNode(self.mkname("ruby"))
2065 # inserter.insertrange(Range(9-2, 10/-2, rby6))
2066 inserter.insertrange(Range(9, 10, rby6))
2067 root = TreeNode()
2068 root.appendchild(rby2.dup().appendchild(TextNode("1")))
2069 root.appendchild(rby4.dup()
2070 .appendchild(met1.dup()
2071 .appendchild(TextNode("2345")))
2072 .appendchild(TextNode("6")))
2073 root.appendchild(met5.dup()
2074 .appendchild(TextNode("7"))
2075 .appendchild(rby6.dup()
2076 .appendchild(TextNode("8"))))
2077 root.appendchild(TextNode("9"))
2078 self.dotest(root, False)
2079 ## inside, with invalid range that includes the dummy char
2080 rby7 = RubyNode(self.mkname("ruby"))
2081 # inserter.insertrange(Range(7-1, 9-2, rby7))
2082 inserter.insertrange(Range(7, 9, rby7))
2083 root = TreeNode()
2084 root.appendchild(rby2.dup().appendchild(TextNode("1")))
2085 root.appendchild(rby4.dup()
2086 .appendchild(met1.dup()
2087 .appendchild(TextNode("2345")))
2088 .appendchild(TextNode("6")))
2089 root.appendchild(met5.dup()
2090 .appendchild(rby7.dup()
2091 .appendchild(TextNode("7")))
2092 .appendchild(rby6.dup()
2093 .appendchild(TextNode("8"))))
2094 root.appendchild(TextNode("9"))
2095 self.dotest(root, False)
2096 ## around, at same position as meta
2097 rby8 = RubyNode(self.mkname("ruby"))
2098 # inserter.insertrange(Range(7-1, 10-2, rby8))
2099 inserter.insertrange(Range(7, 10, rby8))
2100 root = TreeNode()
2101 root.appendchild(rby2.dup().appendchild(TextNode("1")))
2102 root.appendchild(rby4.dup()
2103 .appendchild(met1.dup()
2104 .appendchild(TextNode("2345")))
2105 .appendchild(TextNode("6")))
2106 root.appendchild(rby8.dup()
2107 .appendchild(met5.dup()
2108 .appendchild(TextNode("78"))))
2109 root.appendchild(TextNode("9"))
2110 self.dotest(root, False)
2112 def test_range_meta_meta(self):
2113 inserter = RangeInserter(self.__class__.xDoc)
2114 text = TextNode("123456789")
2115 inserter.insertrange(Range(0, 0, text))
2116 met1 = MetaNode(self.mkid("id"))
2117 inserter.insertrange(Range(3, 6, met1))
2118 ## overlap left
2119 met2 = MetaNode(self.mkid("id"))
2120 try:
2121 inserter.insertrange(Range(0, 4, met2))
2122 fail("testRangeMetaMeta: overlap left allowed")
2123 except IllegalArgumentException:
2124 pass
2125 root = TreeNode()
2126 root.appendchild(TextNode("123"))
2127 root.appendchild(met1.dup().appendchild(TextNode("456")))
2128 root.appendchild(TextNode("789"))
2129 self.dotest(root, False)
2130 ## overlap right
2131 met3 = MetaNode(self.mkid("id"))
2133 try:
2134 # inserter.insertrange(Range(5-1, 8-1, met3))
2135 inserter.insertrange(Range(5, 8, met3))
2136 self.fail("testRangeMetaMeta: overlap right allowed")
2137 except IllegalArgumentException:
2138 pass
2140 root = TreeNode()
2141 root.appendchild(TextNode("123"))
2142 root.appendchild(met1.dup().appendchild(TextNode("456")))
2143 root.appendchild(TextNode("789"))
2144 self.dotest(root, False)
2145 ## around
2146 met4 = MetaNode(self.mkid("id"))
2147 # inserter.insertrange(Range(3, 7-1, met4))
2148 inserter.insertrange(Range(3, 7, met4))
2149 root = TreeNode()
2150 root.appendchild(TextNode("123"))
2151 root.appendchild(met4.dup()
2152 .appendchild(met1.dup().appendchild(TextNode("456"))))
2153 root.appendchild(TextNode("789"))
2154 self.dotest(root, False)
2155 ## inside
2156 met5 = MetaNode(self.mkid("id"))
2157 # inserter.insertrange(Range(6-2, 8-2, met5))
2158 inserter.insertrange(Range(6, 8, met5))
2159 root = TreeNode()
2160 root.appendchild(TextNode("123"))
2161 root.appendchild(met4.dup()
2162 .appendchild(met1.dup()
2163 .appendchild(TextNode("4"))
2164 .appendchild(met5.dup()
2165 .appendchild(TextNode("56")))))
2166 root.appendchild(TextNode("789"))
2167 self.dotest(root, False)
2169 def test_range2(self):
2170 inserter = RangeInserter(self.__class__.xDoc)
2171 text = TextNode("123456789")
2172 inserter.insertrange(Range(0, 0, text))
2173 met1 = MetaNode(self.mkid("id"))
2174 inserter.insertrange(Range(1, 8, met1))
2175 met2 = MetaNode(self.mkid("id"))
2176 # inserter.insertrange(Range(3-1, 8-1, met2))
2177 inserter.insertrange(Range(3, 8, met2))
2178 met3 = MetaNode(self.mkid("id"))
2179 # inserter.insertrange(Range(5-2, 8-2, met3))
2180 inserter.insertrange(Range(5, 8, met3))
2181 root = TreeNode()
2182 root.appendchild(TextNode("1"))
2183 root.appendchild(met1.dup()
2184 .appendchild(TextNode("2"))
2185 .appendchild(met2.dup()
2186 .appendchild(TextNode("3"))
2187 .appendchild(met3.dup()
2188 .appendchild(TextNode("456")))
2189 .appendchild(TextNode("7")))
2190 .appendchild(TextNode("8")))
2191 root.appendchild(TextNode("9"))
2192 self.dotest(root, False)
2193 ## split ruby at every meta start!
2194 rby4 = RubyNode(self.mkname("ruby"))
2195 # inserter.insertrange(Range(0, 7-3, rby4))
2196 inserter.insertrange(Range(0, 7, rby4))
2197 root = TreeNode()
2198 root.appendchild(rby4.dup()
2199 .appendchild(TextNode("1")))
2200 root.appendchild(met1.dup()
2201 .appendchild(rby4.dup()
2202 .appendchild(TextNode("2")))
2203 .appendchild(met2.dup()
2204 .appendchild(rby4.dup()
2205 .appendchild(TextNode("3")))
2206 .appendchild(met3.dup()
2207 .appendchild(rby4.dup()
2208 .appendchild(TextNode("4")))
2209 .appendchild(TextNode("56")))
2210 .appendchild(TextNode("7")))
2211 .appendchild(TextNode("8")))
2212 root.appendchild(TextNode("9"))
2213 self.dotest(root, False)
2214 ## split ruby at every meta end!
2215 rby5 = RubyNode(self.mkname("ruby"))
2216 # inserter.insertrange(Range(8-3, 12-3, rby5))
2217 inserter.insertrange(Range(8, 12, rby5))
2218 root = TreeNode()
2219 root.appendchild(rby4.dup()
2220 .appendchild(TextNode("1")))
2221 root.appendchild(met1.dup()
2222 .appendchild(rby4.dup()
2223 .appendchild(TextNode("2")))
2224 .appendchild(met2.dup()
2225 .appendchild(rby4.dup()
2226 .appendchild(TextNode("3")))
2227 .appendchild(met3.dup()
2228 .appendchild(rby4.dup()
2229 .appendchild(TextNode("4")))
2230 .appendchild(TextNode("5"))
2231 .appendchild(rby5.dup()
2232 .appendchild(TextNode("6"))))
2233 .appendchild(rby5.dup()
2234 .appendchild(TextNode("7"))))
2235 .appendchild(rby5.dup()
2236 .appendchild(TextNode("8"))))
2237 root.appendchild(rby5.dup()
2238 .appendchild(TextNode("9")))
2239 self.dotest(root, False)
2241 def test_range3(self):
2242 inserter = RangeInserter(self.__class__.xDoc)
2243 text = TextNode("123456789")
2244 inserter.insertrange(Range(0, 0, text))
2245 rby1 = RubyNode(self.mkname("ruby"))
2246 inserter.insertrange(Range(0, 9, rby1))
2247 met2 = MetaNode(self.mkid("id"))
2248 inserter.insertrange(Range(2, 7, met2))
2249 root = TreeNode()
2250 root.appendchild(rby1.dup()
2251 .appendchild(TextNode("12"))
2252 .appendchild(met2.dup()
2253 .appendchild(TextNode("34567")))
2254 .appendchild(TextNode("89")))
2255 self.dotest(root, False)
2256 ## overwrite outer ruby, split remains at inner meta!
2257 rby3 = RubyNode(self.mkname("ruby"))
2258 # inserter.insertrange(Range(5-1, 6-1, rby3))
2259 inserter.insertrange(Range(5, 6, rby3))
2260 root = TreeNode()
2261 root.appendchild(rby1.dup()
2262 .appendchild(TextNode("12")))
2263 root.appendchild(met2.dup()
2264 .appendchild(rby1.dup()
2265 .appendchild(TextNode("34")))
2266 .appendchild(rby3.dup()
2267 .appendchild(TextNode("5")))
2268 .appendchild(rby1.dup()
2269 .appendchild(TextNode("67"))))
2270 root.appendchild(rby1.dup()
2271 .appendchild(TextNode("89")))
2272 self.dotest(root, False)
2274 def test_range4(self):
2275 inserter = RangeInserter(self.__class__.xDoc)
2276 text = TextNode("123456789")
2277 inserter.insertrange(Range(0, 0, text))
2278 rby1 = RubyNode(self.mkname("ruby"))
2279 inserter.insertrange(Range(0, 9, rby1))
2280 met2 = MetaNode(self.mkid("id"))
2281 inserter.insertrange(Range(1, 8, met2))
2282 met3 = MetaNode(self.mkid("id"))
2283 # inserter.insertrange(Range(3-1, 8-1, met3))
2284 inserter.insertrange(Range(3, 8, met3))
2285 met4 = MetaNode(self.mkid("id"))
2286 # inserter.insertrange(Range(5-2, 8-2, met4))
2287 inserter.insertrange(Range(5, 8, met4))
2288 root = TreeNode()
2289 root.appendchild(rby1.dup()
2290 .appendchild(TextNode("1"))
2291 .appendchild(met2.dup()
2292 .appendchild(TextNode("2"))
2293 .appendchild(met3.dup()
2294 .appendchild(TextNode("3"))
2295 .appendchild(met4.dup()
2296 .appendchild(TextNode("456")))
2297 .appendchild(TextNode("7")))
2298 .appendchild(TextNode("8")))
2299 .appendchild(TextNode("9")))
2300 self.dotest(root, False)
2301 ## overwrite outer ruby, split remains at every inner meta!
2302 rby5 = RubyNode(self.mkname("ruby"))
2303 # inserter.insertrange(Range(7-3, 8-3, rby5))
2304 inserter.insertrange(Range(7, 8, rby5))
2305 root = TreeNode()
2306 root.appendchild(rby1.dup()
2307 .appendchild(TextNode("1")))
2308 root.appendchild(met2.dup()
2309 .appendchild(rby1.dup()
2310 .appendchild(TextNode("2")))
2311 .appendchild(met3.dup()
2312 .appendchild(rby1.dup()
2313 .appendchild(TextNode("3")))
2314 .appendchild(met4.dup()
2315 .appendchild(rby1.dup()
2316 .appendchild(TextNode("4")))
2317 .appendchild(rby5.dup()
2318 .appendchild(TextNode("5")))
2319 .appendchild(rby1.dup()
2320 .appendchild(TextNode("6"))))
2321 .appendchild(rby1.dup()
2322 .appendchild(TextNode("7"))))
2323 .appendchild(rby1.dup()
2324 .appendchild(TextNode("8"))))
2325 root.appendchild(rby1.dup()
2326 .appendchild(TextNode("9")))
2327 self.dotest(root, False)
2329 def test_range5(self):
2330 inserter = RangeInserter(self.__class__.xDoc)
2331 text = TextNode("123456789")
2332 inserter.insertrange(Range(0, 0, text))
2333 rby1 = RubyNode(self.mkname("ruby"))
2334 inserter.insertrange(Range(0, 9, rby1))
2335 met2 = MetaNode(self.mkid("id"))
2336 inserter.insertrange(Range(1, 3, met2))
2337 met3 = MetaNode(self.mkid("id"))
2338 # inserter.insertrange(Range(5-1, 6-1, met3))
2339 inserter.insertrange(Range(5, 6, met3))
2340 met4 = MetaNode(self.mkid("id"))
2341 # inserter.insertrange(Range(8-2, 10-2, met4))
2342 inserter.insertrange(Range(8, 10, met4))
2343 root = TreeNode()
2344 root.appendchild(rby1.dup()
2345 .appendchild(TextNode("1"))
2346 .appendchild(met2.dup().appendchild(TextNode("23")))
2347 .appendchild(TextNode("4"))
2348 .appendchild(met3.dup().appendchild(TextNode("5")))
2349 .appendchild(TextNode("6"))
2350 .appendchild(met4.dup().appendchild(TextNode("78")))
2351 .appendchild(TextNode("9")))
2352 self.dotest(root, False)
2353 ## overwrite outer ruby, but split at inner metas!
2354 rby5 = RubyNode(self.mkname("ruby"))
2355 # inserter.insertrange(Range(3-1, 10-3, rby5))
2356 inserter.insertrange(Range(3, 10, rby5))
2357 root = TreeNode()
2358 root.appendchild(rby1.dup()
2359 .appendchild(TextNode("1")))
2360 root.appendchild(met2.dup()
2361 .appendchild(rby1.dup()
2362 .appendchild(TextNode("2")))
2363 .appendchild(rby5.dup()
2364 .appendchild(TextNode("3"))))
2365 root.appendchild(rby5.dup()
2366 .appendchild(TextNode("4"))
2367 .appendchild(met3.dup()
2368 .appendchild(TextNode("5")))
2369 .appendchild(TextNode("6")))
2370 root.appendchild(met4.dup()
2371 .appendchild(rby5.dup()
2372 .appendchild(TextNode("7")))
2373 .appendchild(rby1.dup()
2374 .appendchild(TextNode("8"))))
2375 root.appendchild(rby1.dup()
2376 .appendchild(TextNode("9")))
2377 self.dotest(root, False)
2379 def test_range6(self):
2380 inserter = RangeInserter(self.__class__.xDoc)
2381 text = TextNode("123456789")
2382 inserter.insertrange(Range(0, 0, text))
2383 met1 = MetaNode(self.mkid("id"))
2384 inserter.insertrange(Range(1, 5, met1))
2385 met2 = MetaNode(self.mkid("id"))
2386 # inserter.insertrange(Range(3-1, 6-1, met2))
2387 inserter.insertrange(Range(3, 6, met2))
2388 met3 = MetaNode(self.mkid("id"))
2389 # inserter.insertrange(Range(5-2, 7-2, met3))
2390 inserter.insertrange(Range(5, 7, met3))
2391 root = TreeNode()
2392 root.appendchild(TextNode("1"))
2393 root.appendchild(met1.dup()
2394 .appendchild(TextNode("2"))
2395 .appendchild(met2.dup()
2396 .appendchild(TextNode("3"))
2397 .appendchild(met3.dup()
2398 .appendchild(TextNode("45")))))
2399 root.appendchild(TextNode("6789"))
2400 self.dotest(root, False)
2401 ## split at 3 metas, all at same position
2402 rby4 = RubyNode(self.mkname("ruby"))
2403 # inserter.insertrange(Range(7-3, 10-3, rby4))
2404 inserter.insertrange(Range(7, 10, rby4))
2405 root = TreeNode()
2406 root.appendchild(TextNode("1"))
2407 root.appendchild(met1.dup()
2408 .appendchild(TextNode("2"))
2409 .appendchild(met2.dup()
2410 .appendchild(TextNode("3"))
2411 .appendchild(met3.dup()
2412 .appendchild(TextNode("4"))
2413 .appendchild(rby4.dup()
2414 .appendchild(TextNode("5"))))))
2415 root.appendchild(rby4.dup()
2416 .appendchild(TextNode("67")))
2417 root.appendchild(TextNode("89"))
2418 self.dotest(root, False)
2420 def test_range7(self):
2421 inserter = RangeInserter(self.__class__.xDoc)
2422 text = TextNode("123456789")
2423 inserter.insertrange(Range(0, 0, text))
2424 url1 = HyperlinkNode(self.mkname("url"))
2425 inserter.insertrange(Range(1, 5, url1))
2426 met2 = MetaNode(self.mkid("id"))
2427 inserter.insertrange(Range(3, 5, met2))
2428 root = TreeNode()
2429 root.appendchild(TextNode("1"))
2430 root.appendchild(url1.dup()
2431 .appendchild(TextNode("23")))
2432 root.appendchild(met2.dup()
2433 .appendchild(url1.dup()
2434 .appendchild(TextNode("45"))))
2435 root.appendchild(TextNode("6789"))
2436 self.dotest(root, False)
2437 ## this should result in not splitting the hyperlink, but due to API
2438 ## we can't tell :(
2439 rby3 = RubyNode(self.mkname("ruby"))
2440 # inserter.insertrange(Range(5-1, 8-1, rby3))
2441 inserter.insertrange(Range(5, 8, rby3))
2442 root = TreeNode()
2443 root.appendchild(TextNode("1"))
2444 root.appendchild(url1.dup()
2445 .appendchild(TextNode("23")))
2446 root.appendchild(met2.dup()
2447 .appendchild(url1.dup()
2448 .appendchild(TextNode("4")))
2449 .appendchild(rby3.dup()
2450 .appendchild(url1.dup()
2451 .appendchild(TextNode("5")))))
2452 root.appendchild(rby3.dup()
2453 .appendchild(TextNode("67")))
2454 root.appendchild(TextNode("89"))
2455 self.dotest(root, False)
2457 # TODO: test partial selection, test UNDO/REDO
2459 ##i109601# NestedTextContent and XChild
2460 def test_meta_xchild(self):
2461 xDoc = self.__class__.xDoc
2462 id1 = StringPair("content.xml", self.mkname("id"))
2463 id2 = StringPair("content.xml", self.mkname("id"))
2464 id3 = StringPair("content.xml", self.mkname("id"))
2465 id4 = StringPair("content.xml", self.mkname("id"))
2466 id5 = StringPair("content.xml", self.mkname("id"))
2467 id6 = StringPair("content.xml", self.mkname("id"))
2468 meta1 = MetaNode(id1)
2469 meta2 = MetaNode(id2)
2470 meta3 = MetaFieldNode(id3)
2471 meta4 = MetaNode(id4)
2472 meta5 = MetaNode(id5)
2473 meta6 = MetaFieldNode(id6)
2474 root = TreeNode()
2475 root.appendchild(meta1.dup()
2476 .appendchild(TextNode("1")))
2477 root.appendchild(TextNode("2"))
2478 root.appendchild(meta2.dup()
2479 .appendchild(meta3.dup()
2480 .appendchild(TextNode("34"))
2481 .appendchild(meta4.dup()
2482 .appendchild(TextNode("56")))
2483 .appendchild(meta5.dup())
2484 .appendchild(TextNode("7"))))
2485 root.appendchild(TextNode("8"))
2486 root.appendchild(meta6.dup()
2487 .appendchild(TextNode("9")))
2489 inserter = RangeInserter(xDoc)
2490 text = TextNode("123456789")
2491 inserter.insertrange(Range(0, 0, text))
2492 xMeta1 = inserter.insertrange(Range(0, 1, meta1))
2493 xMeta2 = inserter.insertrange(Range(3, 8, meta2))
2494 xMeta3 = inserter.insertrange(Range(4, 9, meta3))
2495 xMeta4 = inserter.insertrange(Range(7, 9, meta4))
2496 xMeta5 = inserter.insertrange(Range(10, 10, meta5))
2497 xMeta6 = inserter.insertrange(Range(13, 14, meta6))
2499 self.dotest(root, False)
2501 xDocText = xDoc.getText()
2502 xDocTextCursor = xDocText.createTextCursor()
2503 xDocTextCursor.gotoNextParagraph(False) # second paragraph
2504 # X12XX34X56X78X9
2505 # 1 23 4 5 6
2506 # 1 452 6
2508 nestedTextContent = (
2509 None,
2510 id1,
2511 id1,
2512 None,
2513 id2,
2514 id3,
2515 id3,
2516 id3,
2517 id4,
2518 id4,
2519 id4,
2520 id5,
2521 id3,
2522 None,
2523 id6,
2524 id6)
2525 for i, ntc in enumerate(nestedTextContent):
2526 oNTC = xDocTextCursor.NestedTextContent
2527 if ntc is None:
2528 self.assertIsNone(oNTC,
2529 "unexpected NestedTextContent at: {}".format(i))
2530 else:
2531 xmlid = oNTC.MetadataReference
2532 self.assertTrue(MetaNode.eq(ntc, xmlid),
2533 "wrong NestedTextContent at: {}".format(i))
2534 xDocTextCursor.goRight(1, False)
2536 try:
2537 xMeta1.setParent(xMeta4)
2538 fail("setParent(): allowed?")
2539 except NoSupportException:
2540 pass
2541 self.assertIsNone(xMeta1.getParent(), "getParent(): not None")
2542 self.assertIsNone(xMeta2.getParent(), "getParent(): not None")
2543 self.assertIsNone(xMeta6.getParent(), "getParent(): not None")
2545 xParent3 = xMeta3.getParent()
2546 self.assertIsNotNone(xParent3, "getParent(): None")
2547 xmlid = xParent3.MetadataReference
2548 self.assertTrue(MetaNode.eq(xmlid, id2), "getParent(): wrong")
2550 xParent4 = xMeta4.getParent()
2551 self.assertIsNotNone(xParent4, "getParent(): None")
2552 xmlid = xParent4.MetadataReference
2553 self. assertTrue(MetaNode.eq(xmlid, id3), "getParent(): wrong")
2555 xParent5 = xMeta5.getParent()
2556 self.assertIsNotNone(xParent5, "getParent(): None")
2557 xmlid = xParent5.MetadataReference
2558 self.assertTrue(MetaNode.eq(xmlid, id3), "getParent(): wrong")
2560 # test SwXMeta XText interface
2561 def test_meta_xtext(self):
2562 xDoc = self.__class__.xDoc
2563 inserter = RangeInserter(xDoc)
2564 text = TextNode("12AB6789")
2565 inserter.insertrange(Range(0, 0, text))
2566 meta = MetaNode(self.mkid("id"))
2567 xMeta = inserter.makemeta()
2569 xDocText = xDoc.getText()
2570 xDocTextCursor = xDocText.createTextCursor()
2571 xDocTextCursor.goRight(3, False)
2572 xDocTextCursor.goRight(2, True)
2573 xDocText.insertTextContent(xDocTextCursor, xMeta, True)
2575 xMeta.MetadataReference = meta.xmlid
2576 xParentText = xMeta.getText()
2577 self.assertIsNotNone(xParentText, "getText(): no parent")
2579 xStart = xMeta.getStart()
2580 self.assertIsNotNone(xStart, "getStart(): no start")
2582 xEnd = xMeta.getEnd()
2583 self.assertIsNotNone(xEnd, "getEnd(): no end")
2585 xMeta.setString("45")
2587 string = xMeta.getString()
2588 self.assertEqual("45", string, "getString(): invalid string returned")
2590 xTextCursor = xMeta.createTextCursor()
2591 self.assertIsNotNone(xTextCursor, "createTextCursor(): failed")
2593 try:
2594 xMeta.createTextCursorByRange(None)
2595 fail("createTextCursorByRange(): None allowed?")
2596 except RuntimeException:
2597 pass
2599 xTextCursorStart = xMeta.createTextCursorByRange(xStart)
2600 self.assertIsNotNone(xTextCursorStart,
2601 "createTextCursorByRange(): failed for start")
2603 xTextCursorEnd = xMeta.createTextCursorByRange(xEnd)
2604 self.assertIsNotNone(xTextCursorEnd,
2605 "createTextCursorByRange(): failed for end")
2607 ## move outside meta
2608 xDocTextCursor.gotoStart(False)
2610 try:
2611 xMeta.insertString(None, "foo", False)
2612 fail("insertString(): None allowed?")
2613 except RuntimeException:
2614 pass
2616 try:
2617 xMeta.insertString(xDocTextCursor, "foo", False)
2618 fail("insertString(): cursor outside allowed?")
2619 except RuntimeException:
2620 pass
2622 xStart = xMeta.getStart()
2623 xMeta.insertString(xStart, "A", False)
2624 string = xMeta.getString()
2625 self.assertEqual("A45", string, "getString(): invalid string returned")
2627 xMeta.insertString(xEnd, "B", False)
2628 string = xMeta.getString()
2629 self.assertEqual("A45B", string, "getString(): invalid string returned")
2631 try:
2632 xMeta.insertControlCharacter(None, HARD_HYPHEN, False)
2633 fail("insertControlCharacter(): None allowed?")
2634 except IllegalArgumentException:
2635 pass
2637 xStart = xMeta.getStart()
2638 try:
2639 xMeta.insertControlCharacter(xDocTextCursor, HARD_HYPHEN, False)
2640 fail("insertControlCharacter(): cursor outside allowed?")
2641 except IllegalArgumentException:
2642 pass
2644 xMeta.insertControlCharacter(xStart, HARD_HYPHEN, False)
2645 string = xMeta.getString()
2646 self.assertEqual('\u2011' + 'A45B', string,
2647 "getString(): invalid string returned")
2649 xMeta.insertControlCharacter(xEnd, HARD_HYPHEN, False)
2650 string = xMeta.getString()
2651 self.assertEqual('\u2011' + 'A45B' + '\u2011', string,
2652 "getString(): invalid string returned")
2654 xMeta.setString("45")
2655 try:
2656 xMeta.insertTextContent(None, xMeta, False)
2657 fail("insertTextContent(): None range allowed?")
2658 except IllegalArgumentException:
2659 pass
2661 try:
2662 xMeta.insertTextContent(xStart, None, False)
2663 fail("insertTextContent(): None content allowed?")
2664 except IllegalArgumentException:
2665 pass
2667 try:
2668 xMeta.insertTextContent(xDocTextCursor, xMeta, False)
2669 fail("insertTextContent(): cursor outside allowed?")
2670 except IllegalArgumentException:
2671 pass
2673 field1 = TextFieldNode("f1")
2674 field2 = TextFieldNode("f2")
2675 xField1 = inserter.maketextfield(field1.content)
2676 xField2 = inserter.maketextfield(field2.content)
2678 xStart = xMeta.getStart()
2679 xMeta.insertTextContent(xStart, xField1, False)
2681 root = TreeNode()
2682 root.appendchild(TextNode("12"))
2683 root.appendchild(meta.dup()
2684 .appendchild(field1.dup())
2685 .appendchild(TextNode("45")))
2686 root.appendchild(TextNode("6789"))
2687 self.dotest(root, False)
2689 xMeta.insertTextContent(xEnd, xField2, False)
2691 root = TreeNode()
2692 root.appendchild(TextNode("12"))
2693 root.appendchild(meta.dup()
2694 .appendchild(field1.dup())
2695 .appendchild(TextNode("45"))
2696 .appendchild(field2.dup()))
2697 root.appendchild(TextNode("6789"))
2698 self.dotest(root, False)
2700 try:
2701 xMeta.removeTextContent(None)
2702 fail("removeTextContent(): None content allowed?")
2703 except RuntimeException:
2704 pass
2706 xMeta.removeTextContent(xField1)
2708 xAnchor = xMeta.getAnchor()
2709 self.assertIsNotNone(xAnchor, "getAnchor(): None")
2711 ## evil test case: insert ruby around meta
2712 ruby = RubyNode(self.mkname("ruby"))
2713 inserter.insertrange(Range(2, 6, ruby))
2715 ## prevent caching...
2716 # root = TreeNode()
2717 # root.appendchild(TextNode("12"))
2718 # root.appendchild(ruby.dup()
2719 # .appendchild(meta.dup()
2720 # .appendchild(TextNode("45"))
2721 # .appendchild(field2.dup())))
2722 # root.appendchild(TextNode("6789"))
2723 # self.dotest(root, False)
2725 xEnum = xMeta.createEnumeration()
2726 self.assertIsNotNone("createEnumeration(): returns None", xEnum)
2728 self.assertTrue(xEnum.hasMoreElements(),"hasNext(): first missing")
2729 xPortion = xEnum.nextElement()
2730 type_ = xPortion.TextPortionType
2731 self.assertEqual("Text", type_, "first: not text")
2732 txt = xPortion.getString()
2733 self.assertEqual("45", txt, "first: text differs")
2735 self.assertTrue(xEnum.hasMoreElements(),"hasNext(): second missing")
2736 xPortion = xEnum.nextElement()
2737 type_ = xPortion.TextPortionType
2738 self.assertEqual("TextField", type_, "second: not text")
2740 ## no ruby end here!!!
2741 self.assertFalse(xEnum.hasMoreElements(), "hasNext(): more elements?")
2743 xMeta.dispose()
2745 try:
2746 xCursor = xMeta.createTextCursor()
2747 self.assertIsNone(xCursor,
2748 "createTextCursor(): succeeds on disposed object?")
2749 except RuntimeException:
2750 pass
2752 # check that cursor move methods move to positions in the meta,
2753 # but do not move to positions outside the meta.
2754 def test_meta_xtextcursor(self):
2755 xDoc = self.__class__.xDoc
2756 inserter = RangeInserter(xDoc)
2757 text = TextNode("Text. 12 More text here.")
2758 inserter.insertrange(Range(0, 0, text))
2759 met1 = MetaNode(self.mkid("id"))
2760 xMeta = inserter.makemeta()
2762 xDocText = xDoc.getText()
2763 xDocTextCursor = xDocText.createTextCursor()
2764 xDocTextCursor.goRight(7, False)
2765 xDocTextCursor.goRight(2, True)
2766 xDocText.insertTextContent(xDocTextCursor, xMeta, True)
2767 xDocTextCursor.gotoStart(True)
2769 xMeta.MetadataReference = met1.xmlid
2770 xStart = xMeta.getStart()
2771 self.assertIsNotNone(xStart, "getStart(): no start")
2772 xEnd = xMeta.getEnd()
2773 self.assertIsNotNone(xEnd, "getEnd(): no end")
2775 ## XTextCursor
2776 xMetaCursor = xMeta.createTextCursor()
2777 self.assertIsNotNone(xMetaCursor, "createTextCursor(): no cursor")
2778 bSuccess = False
2779 xMetaCursor.gotoStart(False)
2780 xMetaCursor.gotoEnd(False)
2781 bSuccess = xMetaCursor.goLeft(1, False)
2782 self.assertTrue(bSuccess, "goLeft(): failed")
2783 bSuccess = xMetaCursor.goLeft(1000, False)
2784 self.assertFalse(bSuccess, "goLeft(): succeeded")
2785 bSuccess = xMetaCursor.goRight(1, False)
2786 self.assertTrue(bSuccess, "goRight(): failed")
2787 bSuccess = xMetaCursor.goRight(1000, False)
2788 self.assertFalse(bSuccess, "goRight(): succeeded")
2789 xMetaCursor.gotoRange(xStart, False)
2790 xMetaCursor.gotoRange(xEnd, False)
2791 try:
2792 xMetaCursor.gotoRange(xDocTextCursor, False)
2793 fail("gotoRange(): succeeded")
2794 except RuntimeException:
2795 pass
2797 ## XWordCursor
2798 xMeta.setString("Two words")
2799 xMetaCursor.gotoStart(False)
2801 bSuccess = xMetaCursor.gotoNextWord(True) # at start of "words"
2802 self.assertTrue(bSuccess, "gotoNextWord(): failed")
2804 string = xMetaCursor.getString()
2805 self.assertEqual("Two ", string, "gotoNextWord(): wrong string")
2807 bSuccess = xMetaCursor.gotoNextWord(False) # at end of "words", cannot leave metafield
2808 self.assertFalse(bSuccess,"gotoNextWord(): succeeded")
2809 xMetaCursor.collapseToEnd()
2810 bSuccess = xMetaCursor.gotoPreviousWord(True) # at start of "words"
2811 self.assertTrue(bSuccess, "gotoPreviousWord(): failed")
2813 string = xMetaCursor.getString()
2814 self.assertEqual("words", string, "gotoPreviousWord(): wrong string")
2816 bSuccess = xMetaCursor.gotoPreviousWord(False) # at start of "Two"
2817 self.assertTrue(bSuccess, "gotoPreviousWord(): failed")
2819 bSuccess = xMetaCursor.gotoPreviousWord(False) # cannot leave metafield
2820 self.assertFalse(bSuccess, "gotoPreviousWord(): succeeded")
2822 bSuccess = xMetaCursor.gotoEndOfWord(True) # at end of "Two"
2823 self.assertTrue(bSuccess, "gotoEndOfWord(): failed")
2825 string = xMetaCursor.getString()
2826 self.assertEqual("Two", string, "gotoEndOfWord(): wrong string")
2828 xMetaCursor.gotoEnd(False)
2829 bSuccess = xMetaCursor.gotoStartOfWord(True)
2830 self.assertTrue(bSuccess, "gotoStartOfWord(): failed")
2832 string = xMetaCursor.getString()
2833 self.assertEqual("words", string, "gotoStartOfWord(): wrong string")
2835 xMeta.setString("")
2836 bSuccess = xMetaCursor.gotoEndOfWord(False)
2837 self.assertFalse(bSuccess, "gotoEndOfWord(): succeeded")
2838 bSuccess = xMetaCursor.gotoStartOfWord(False)
2839 self.assertFalse(bSuccess, "gotoStartOfWord(): succeeded")
2841 ## XSentenceCursor
2842 xMeta.setString("This is a sentence. Another sentence.")
2843 xMetaCursor.gotoStart(False)
2845 bSuccess = xMetaCursor.gotoNextSentence(True)
2846 self.assertTrue(bSuccess,"gotoNextSentence(): failed")
2848 string = xMetaCursor.getString()
2849 self.assertEqual("This is a sentence. ", string,
2850 "gotoNextSentence(): wrong string")
2852 bSuccess = xMetaCursor.gotoNextSentence(False)
2853 self.assertFalse(bSuccess, "gotoNextSentence(): succeeded")
2854 ## FIXME:
2855 ## the sentence cursor seems to work differently than the word cursor
2856 xMeta.setString("This is a sentence. Another sentence. Sentence 3.")
2857 xMetaCursor.gotoEnd(False)
2858 bSuccess = xMetaCursor.gotoPreviousSentence(True)
2859 self.assertTrue(bSuccess, "gotoPreviousSentence(): failed")
2861 string = xMetaCursor.getString()
2862 self.assertEqual("Another sentence. Sentence 3.", string,
2863 "gotoPreviousSentence(): wrong string")
2865 bSuccess = xMetaCursor.gotoPreviousSentence(False)
2866 self.assertFalse(bSuccess, "gotoPreviousSentence(): succeeded")
2867 bSuccess = xMetaCursor.gotoEndOfSentence(True)
2868 self.assertTrue(bSuccess, "gotoEndOfSentence(): failed")
2870 string = xMetaCursor.getString()
2871 self.assertEqual("This is a sentence.", string,
2872 "gotoEndOfSentence(): wrong string")
2874 xMetaCursor.gotoEnd(False)
2875 bSuccess = xMetaCursor.gotoStartOfSentence(True)
2876 self.assertTrue(bSuccess,"gotoStartOfSentence(): failed")
2878 string = xMetaCursor.getString()
2879 self.assertEqual("Sentence 3.", string,
2880 "gotoStartOfSentence(): wrong string")
2882 xMeta.setString("")
2883 bSuccess = xMetaCursor.gotoEndOfSentence(False)
2884 self.assertFalse(bSuccess, "gotoEndOfSentence(): succeeded")
2885 bSuccess = xMetaCursor.gotoStartOfSentence(False)
2886 self.assertFalse(bSuccess, "gotoStartOfSentence(): succeeded")
2888 ## XParagraphCursor (does not make sense)
2889 bSuccess = xMetaCursor.gotoNextParagraph(False)
2890 self.assertFalse(bSuccess, "gotoNextParagraph(): succeeded")
2891 bSuccess = xMetaCursor.gotoPreviousParagraph(False)
2892 self.assertFalse(bSuccess, "gotoPreviousParagraph(): succeeded")
2893 bSuccess = xMetaCursor.gotoStartOfParagraph(False)
2894 self.assertFalse(bSuccess, "gotoStartOfParagraph(): succeeded")
2895 bSuccess = xMetaCursor.gotoEndOfParagraph(False)
2896 self.assertFalse(bSuccess, "gotoEndOfParagraph(): succeeded")
2898 # See https://bugs.libreoffice.org/show_bug.cgi?id=49629
2899 # ensure that gotoEndOfWord does not fail when footnote is at word end
2900 def test_xtextcursor(self):
2901 xDoc = self.__class__.xDoc
2902 inserter = RangeInserter(xDoc)
2903 xDocText = xDoc.getText()
2904 xDocTextCursor = xDocText.createTextCursor()
2905 xDocTextCursor.gotoNextParagraph(False)
2906 inserter.inserttext(xDocTextCursor, "Text")
2907 xDocTextCursor.gotoEndOfWord(False)
2908 inserter.insertfootnote(xDocTextCursor, "footnote")
2909 xDocTextCursor.gotoStartOfParagraph(False)
2910 bSuccess = xDocTextCursor.gotoEndOfWord(True)
2911 self.assertTrue(bSuccess, "gotoEndOfWord(): failed")
2912 string = xDocTextCursor.getString()
2913 self.assertEqual("Text", string, "gotoEndOfWord(): wrong string")
2914 self.assertNotEqual("a","b")
2916 class AttachHelper():
2917 def isattribute(self): pass
2918 def mktreenode(self): pass
2919 def mktextcontent(self, inserter, node): pass
2920 def postinserted(self, node, xContent): pass
2922 def test_meta_xtextattach_toxmark(self):
2923 class Helper(self.AttachHelper):
2924 def isattribute(_):
2925 return True
2926 def mktreenode(_):
2927 return DocumentIndexMarkNode(self.mkname("toxmark"))
2928 def mktextcontent(_, inserter, node):
2929 return inserter.makedocumentindexmark(node.name)
2930 self.do_meta_xtextattach(Helper())
2932 def test_meta_xtextattach_refmark(self):
2933 class Helper(self.AttachHelper):
2934 def isattribute(_):
2935 return True
2936 def mktreenode(_):
2937 return ReferenceMarkNode(self.mkname("refmark"))
2938 def mktextcontent(_, inserter, node):
2939 return inserter.makereferencemark(node.name)
2940 self.do_meta_xtextattach(Helper())
2942 def test_meta_xtextattach_textfield(self):
2943 class Helper(self.AttachHelper):
2944 def isattribute(_):
2945 return False
2946 def mktreenode(_):
2947 return TextFieldNode(self.mkname("field"))
2948 def mktextcontent(_, inserter, node):
2949 return inserter.maketextfield(node.content)
2950 self.do_meta_xtextattach(Helper())
2952 def test_meta_xtextattach_footnote(self):
2953 class Helper(self.AttachHelper):
2954 def isattribute(_):
2955 return False
2956 def mktreenode(_):
2957 return FootnoteNode(self.mkname("ftn"))
2958 def mktextcontent(_, inserter, node):
2959 return inserter.makefootnote(node.label)
2960 self.do_meta_xtextattach(Helper())
2962 def test_meta_xtextattach_meta(self):
2963 class Helper(self.AttachHelper):
2964 def isattribute(_):
2965 return True
2966 def mktreenode(_):
2967 return MetaNode(self.mkid("id"))
2968 def mktextcontent(_, inserter, node):
2969 return inserter.makemeta()
2970 def postinserted(_, node, xContent):
2971 xContent.MetadataReference = node.xmlid
2972 self.do_meta_xtextattach(Helper())
2974 def do_meta_xtextattach(self, helper):
2975 xDoc = self.__class__.xDoc
2976 inserter = RangeInserter(xDoc)
2977 text = TextNode("12AB6789")
2978 inserter.insertrange(Range(0, 0, text))
2979 met1 = MetaNode(self.mkid("id"))
2980 xMeta = inserter.makemeta()
2982 xDocText = xDoc.getText()
2983 xDocTextCursor = xDocText.createTextCursor()
2984 xDocTextCursor.goRight(3, False)
2985 xDocTextCursor.goRight(2, True)
2986 xDocText.insertTextContent(xDocTextCursor, xMeta, True)
2988 xMeta.MetadataReference = met1.xmlid
2989 xStart = None
2990 xEnd = None
2992 xStart = xMeta.getStart()
2993 xEnd = xMeta.getEnd()
2995 nod1 = helper.mktreenode()
2996 nod2 = helper.mktreenode()
2997 xContent1 = helper.mktextcontent(inserter, nod1)
2998 xContent2 = helper.mktextcontent(inserter, nod2)
3000 ## insertTextContent with meta getStart()/getEnd()
3001 xMeta.insertTextContent(xStart, xContent1, False)
3002 xMeta.insertTextContent(xEnd, xContent2, False)
3004 helper.postinserted(nod1, xContent1)
3005 helper.postinserted(nod2, xContent2)
3007 root = TreeNode()
3008 root.appendchild(TextNode("12"))
3009 root.appendchild(met1.dup()
3010 .appendchild(nod1.dup())
3011 .appendchild(TextNode("AB"))
3012 .appendchild(nod2.dup()))
3013 root.appendchild(TextNode("6789"))
3014 self.dotest(root, False)
3016 xMeta.setString("AB")
3017 xStart = xMeta.getStart()
3018 xEnd = xMeta.getEnd()
3020 nod1 = helper.mktreenode()
3021 nod2 = helper.mktreenode()
3022 xContent1 = helper.mktextcontent(inserter, nod1)
3023 xContent2 = helper.mktextcontent(inserter, nod2)
3025 xTextCursor = xMeta.createTextCursor()
3026 xTextCursor.gotoStart(False)
3028 ## insertTextContent with meta cursor
3029 xMeta.insertTextContent(xTextCursor, xContent1, False)
3030 xTextCursor.gotoEnd(False)
3031 xMeta.insertTextContent(xTextCursor, xContent2, False)
3033 helper.postinserted(nod1, xContent1)
3034 helper.postinserted(nod2, xContent2)
3036 root = TreeNode()
3037 root.appendchild(TextNode("12"))
3038 root.appendchild(met1.dup()
3039 .appendchild(nod1.dup())
3040 .appendchild(TextNode("AB"))
3041 .appendchild(nod2.dup()))
3042 root.appendchild(TextNode("6789"))
3043 self.dotest(root, False)
3045 if not helper.isattribute():
3046 # xMeta.setString("AB")
3047 xStart = xMeta.getStart()
3048 xEnd = xMeta.getEnd()
3050 nod1 = helper.mktreenode()
3051 nod2 = helper.mktreenode()
3052 xContent1 = helper.mktextcontent(inserter, nod1)
3053 xContent2 = helper.mktextcontent(inserter, nod2)
3055 xTextCursor = xMeta.createTextCursor()
3056 xTextCursor.gotoStart(False)
3057 xTextCursor.goRight(1, True)
3059 ## insertTextContent with meta cursor and absorb
3060 xMeta.insertTextContent(xTextCursor, xContent1, True)
3061 xTextCursor.gotoEnd(False)
3062 xTextCursor.goLeft(1, True)
3063 xMeta.insertTextContent(xTextCursor, xContent2, True)
3065 helper.postinserted(nod1, xContent1)
3066 helper.postinserted(nod2, xContent2)
3068 root = TreeNode()
3069 root.appendchild(TextNode("12"))
3070 root.appendchild(met1.dup()
3071 .appendchild(nod1.dup())
3072 .appendchild(TextNode("AB"))
3073 .appendchild(nod2.dup()))
3074 root.appendchild(TextNode("6789"))
3075 self.dotest(root, False)
3077 xMeta.setString("AB")
3078 xStart = xMeta.getStart()
3079 xEnd = xMeta.getEnd()
3081 nod1 = helper.mktreenode()
3082 nod2 = helper.mktreenode()
3083 xContent1 = helper.mktextcontent(inserter, nod1)
3084 xContent2 = helper.mktextcontent(inserter, nod2)
3086 xDocTextCursor.gotoRange(xStart, False)
3088 ## insertTextContent with document cursor
3089 xMeta.insertTextContent(xDocTextCursor, xContent1, False)
3090 xDocTextCursor.gotoRange(xEnd, False)
3091 xMeta.insertTextContent(xDocTextCursor, xContent2, False)
3093 helper.postinserted(nod1, xContent1)
3094 helper.postinserted(nod2, xContent2)
3096 root = TreeNode()
3097 root.appendchild(TextNode("12"))
3098 root.appendchild(met1.dup()
3099 .appendchild(nod1.dup())
3100 .appendchild(TextNode("AB"))
3101 .appendchild(nod2.dup()))
3102 root.appendchild(TextNode("6789"))
3103 self.dotest(root, False)
3105 if not helper.isattribute():
3106 xStart = xMeta.getStart()
3107 xEnd = xMeta.getEnd()
3109 nod1 = helper.mktreenode()
3110 nod2 = helper.mktreenode()
3111 xContent1 = helper.mktextcontent(inserter, nod1)
3112 xContent2 = helper.mktextcontent(inserter, nod2)
3114 xDocTextCursor.gotoRange(xStart, False)
3115 xDocTextCursor.goRight(1, True)
3117 ## insertTextContent with document cursor and absorb
3118 xMeta.insertTextContent(xDocTextCursor, xContent1, True)
3119 xDocTextCursor.gotoRange(xEnd, False)
3120 xDocTextCursor.goLeft(1, True)
3121 xMeta.insertTextContent(xDocTextCursor, xContent2, True)
3123 helper.postinserted(nod1, xContent1)
3124 helper.postinserted(nod2, xContent2)
3126 root = TreeNode()
3127 root.appendchild(TextNode("12"))
3128 root.appendchild(met1.dup()
3129 .appendchild(nod1.dup())
3130 .appendchild(TextNode("AB"))
3131 .appendchild(nod2.dup()))
3132 root.appendchild(TextNode("6789"))
3133 self.dotest(root, False)
3135 xMeta.setString("AB")
3136 xStart = xMeta.getStart()
3137 xEnd = xMeta.getEnd()
3139 nod1 = helper.mktreenode()
3140 nod2 = helper.mktreenode()
3141 xContent1 = helper.mktextcontent(inserter, nod1)
3142 xContent2 = helper.mktextcontent(inserter, nod2)
3144 ## attach to range from meta getStart()/getEnd()
3145 xContent1.attach(xStart)
3146 xContent2.attach(xEnd)
3148 helper.postinserted(nod1, xContent1)
3149 helper.postinserted(nod2, xContent2)
3151 root = TreeNode()
3152 root.appendchild(TextNode("12"))
3153 root.appendchild(met1.dup()
3154 .appendchild(nod1.dup())
3155 .appendchild(TextNode("AB"))
3156 .appendchild(nod2.dup()))
3157 root.appendchild(TextNode("6789"))
3158 self.dotest(root, False)
3160 xMeta.setString("AB")
3161 xStart = xMeta.getStart()
3162 xEnd = xMeta.getEnd()
3164 nod1 = helper.mktreenode()
3165 nod2 = helper.mktreenode()
3166 xContent1 = helper.mktextcontent(inserter, nod1)
3167 xContent2 = helper.mktextcontent(inserter, nod2)
3169 xTextCursor = xMeta.createTextCursor()
3170 xTextCursor.gotoStart(False)
3172 ## attach to cursor from meta XText
3173 xContent1.attach(xTextCursor)
3174 xTextCursor.gotoEnd(False)
3175 xContent2.attach(xTextCursor)
3177 helper.postinserted(nod1, xContent1)
3178 helper.postinserted(nod2, xContent2)
3180 root = TreeNode()
3181 root.appendchild(TextNode("12"))
3182 root.appendchild(met1.dup()
3183 .appendchild(nod1.dup())
3184 .appendchild(TextNode("AB"))
3185 .appendchild(nod2.dup()))
3186 root.appendchild(TextNode("6789"))
3187 self.dotest(root, False)
3189 def test_metafield_xtextfield(self):
3190 xDoc = self.__class__.xDoc
3191 smgr = self.__class__._uno.xContext.ServiceManager
3192 xRepo = xDoc.getRDFRepository()
3193 ## for testing just add it to the first graph
3194 Graphs = xRepo.getGraphNames()
3195 xGraph = xRepo.getGraph(Graphs[0])
3196 xOdfPrefix = smgr.createInstance("com.sun.star.rdf.URI")
3197 xOdfPrefix.initialize((ODF_PREFIX,))
3198 xOdfSuffix = smgr.createInstance("com.sun.star.rdf.URI")
3199 xOdfSuffix.initialize((ODF_SUFFIX,))
3201 xPrefix = smgr.createInstance("com.sun.star.rdf.Literal")
3202 xPrefix.initialize(("foo",))
3203 xSuffix = smgr.createInstance("com.sun.star.rdf.Literal")
3204 xSuffix.initialize(("bar",))
3206 inserter = RangeInserter(xDoc)
3207 text = TextNode("abc")
3208 inserter.insertrange(Range(0, 0, text))
3209 xDocText = xDoc.getText()
3210 xDocTextCursor = xDocText.createTextCursor()
3211 xDocTextCursor.goRight(1, False)
3212 xDocTextCursor.goRight(3, True)
3214 xMetaField = inserter.makemetafield()
3216 xDocText.insertTextContent(xDocTextCursor, xMetaField, True)
3218 xMetaField.ensureMetadataReference
3220 xGraph.addStatement(xMetaField, xOdfPrefix, xPrefix)
3221 xGraph.addStatement(xMetaField, xOdfSuffix, xSuffix)
3222 self.assertEqual("fooabcbar", xMetaField.getPresentation(False),
3223 "getPresentation(): wrong")
3224 inserter.insertrange(Range(0, 0, text))
3226 def test_metafield_xpropertyset(self):
3227 xDoc = self.__class__.xDoc
3228 inserter = RangeInserter(xDoc)
3229 text = TextNode("123")
3230 inserter.insertrange(Range(0, 0, text))
3231 xDocText = xDoc.getText()
3232 xDocTextCursor = xDocText.createTextCursor()
3233 xDocTextCursor.goRight(1, False)
3234 xDocTextCursor.goRight(3, True)
3236 xMetaField = inserter.makemetafield()
3238 xDocText.insertTextContent(xDocTextCursor, xMetaField, True)
3240 self.assertIsNotNone(xMetaField, "PropertySet: not supported?")
3241 xPropertySetInfo = xMetaField.getPropertySetInfo()
3242 self.assertTrue(xPropertySetInfo.hasPropertyByName("NumberFormat"),
3243 'hasPropertyByName("NumberFormat"):')
3244 self.assertTrue(xPropertySetInfo.hasPropertyByName("IsFixedLanguage"),
3245 'hasPropertyByName("IsFixedLanguage"):')
3247 def_ = xMetaField.NumberFormat
3248 print("NumberFormat: default is {}".format(def_))
3249 xMetaField.NumberFormat = NUMBER_INT
3250 xMetaField.IsFixedLanguage = True
3251 format = xMetaField.NumberFormat
3252 self.assertEqual(NUMBER_INT, format, "NumberFormat: failed")
3253 isfixed = xMetaField.IsFixedLanguage
3254 self.assertTrue(isfixed, "IsFixedLanguage: failed")
3256 def dostore(self, xComp, file):
3257 print("Storing test document...")
3258 file = uno.systemPathToFileUrl(file)
3259 xComp.storeToURL(file, ())
3260 print("...done")
3262 def doload(self, file):
3263 xComp = None
3264 print("Loading test document...")
3265 xComp = self.__class__._uno.openDocFromAbsolutePath(file)
3266 self.assertIsNotNone(xComp, "cannot load: {}".format(file))
3267 print("...done")
3268 return xComp
3270 def close(self, i_comp):
3271 try:
3272 if i_comp:
3273 i_comp.close(True)
3274 except Exception:
3275 pass
3277 def test_load_store(self):
3278 xComp = None
3279 filename = "TESTMETA.odt"
3280 try:
3281 xComp = self.__class__._uno.openDocFromTDOC(filename)
3282 if xComp:
3283 self.checkloadmeta(xComp)
3284 with TemporaryDirectory() as tempdir:
3285 file = os.path.join(tempdir, filename)
3286 self.dostore(xComp, file)
3287 self.close(xComp)
3288 xComp2 = None
3289 try:
3290 xComp2 = self.doload(file)
3291 self.checkloadmeta(xComp2)
3292 finally:
3293 self.close(xComp2)
3294 finally:
3295 self.close(xComp)
3297 def checkloadmeta(self, xTextDoc):
3298 print("Checking meta(-field)s in loaded test document...")
3299 root = TreeNode()
3300 root.appendchild(RubyNode("ruby1")
3301 .appendchild(TextNode("1")))
3302 root.appendchild(MetaNode(self.mkid_("id1"))
3303 .appendchild(TextNode("2")))
3304 root.appendchild(MetaFieldNode(self.mkid_("id2"))
3305 .appendchild(TextNode("3")))
3306 root.appendchild(RubyNode("ruby2")
3307 .appendchild(MetaNode(self.mkid_("id3"))
3308 .appendchild(TextNode("4"))))
3309 root.appendchild(RubyNode("ruby3")
3310 .appendchild(MetaFieldNode(self.mkid_("id4"))
3311 .appendchild(TextNode("5"))))
3312 root.appendchild(MetaNode(self.mkid_("id5"))
3313 .appendchild(RubyNode("ruby4")
3314 .appendchild(TextNode("6"))))
3315 root.appendchild(MetaFieldNode(self.mkid_("id6"))
3316 .appendchild(RubyNode("ruby5")
3317 .appendchild(TextNode("7"))))
3318 root.appendchild(MetaNode(self.mkid_("id7"))
3319 .appendchild(MetaNode(self.mkid_("id8"))
3320 .appendchild(TextNode("8"))))
3321 root.appendchild(MetaNode(self.mkid_("id9"))
3322 .appendchild(MetaFieldNode(self.mkid_("id10"))
3323 .appendchild(TextNode("9"))))
3324 root.appendchild(MetaFieldNode(self.mkid_("id11"))
3325 .appendchild(MetaNode(self.mkid_("id12"))
3326 .appendchild(TextNode("10"))))
3327 root.appendchild(MetaFieldNode(self.mkid_("id13"))
3328 .appendchild(MetaFieldNode(self.mkid_("id14"))
3329 .appendchild(TextNode("11"))))
3330 root.appendchild(MetaNode(self.mkid_("id15"))
3331 .appendchild(RubyNode("ruby6")
3332 .appendchild(MetaFieldNode(self.mkid_("id16"))
3333 .appendchild(TextNode("12")))))
3335 class MetaNode_(MetaNode):
3336 def __init__(self, id):
3337 super().__init__(id)
3338 def __eq__(self, other):
3339 return isinstance(other, MetaNode)
3340 root.appendchild(MetaNode_(self.mkid_(""))
3341 .appendchild(TextNode("13")))
3342 root.appendchild(TextNode(" X X "))
3343 self._dotest(xTextDoc, root, False)
3344 print("...done")
3346 def test_load_store_xmlid(self):
3347 xComp = None
3348 filename = "TESTXMLID.odt"
3349 try:
3350 xComp = self.__class__._uno.openDocFromTDOC(filename)
3351 if xComp:
3352 self.checkloadxmlid(xComp)
3353 with TemporaryDirectory() as tempdir:
3354 file = os.path.join(tempdir, filename)
3355 self.dostore(xComp, file)
3356 self.close(xComp)
3357 xComp2 = None
3358 try:
3359 xComp2 = self.doload(file)
3360 self.checkloadxmlid(xComp2)
3361 finally:
3362 self.close(xComp2)
3363 finally:
3364 self.close(xComp)
3366 def checkloadxmlid(self, xTextDoc):
3367 xRepo = xTextDoc.getRDFRepository()
3369 print("Checking bookmarks in loaded test document...")
3370 xBookmarks = xTextDoc.getBookmarks()
3371 xMark1 = xBookmarks["mk1"]
3372 self.assertTrue(self.eq(xMark1.MetadataReference,
3373 StringPair("content.xml", "id90")), "mark1")
3374 xMark2 = xBookmarks["mk2"]
3375 result = xRepo.getStatementRDFa(xMark2)
3376 self.assertTrue(len(result.First) == 1 and
3377 result.First[0].Subject.StringValue == "uri:foo" and
3378 result.First[0].Predicate.StringValue == "uri:bar" and
3379 result.First[0].Object.Value == "a fooish bar",
3380 "mark2")
3381 xMark3 = xBookmarks["mk3"]
3382 self.assertTrue(self.eq(xMark3.MetadataReference,
3383 StringPair("content.xml", "id91")), "mark3")
3384 print("...done")
3386 print("Checking sections in loaded test document...")
3387 xSections = xTextDoc.getTextSections()
3388 xSection1 = xSections["Section 1"]
3389 self.assertTrue(self.eq(xSection1.MetadataReference,
3390 StringPair("content.xml", "idSection1")), "idsection1")
3391 xSection2 = xSections["Section 2"]
3392 self.assertTrue(self.eq(xSection2.MetadataReference,
3393 StringPair("content.xml", "idSection2")),"idSection2")
3394 xSection3 = xSections["Table of Contents1_Head"]
3395 self.assertTrue(self.eq(xSection3.MetadataReference,
3396 StringPair("content.xml", "idTOCTitle")), "idTOCTitle")
3397 xSection4 = xSections["Alphabetical Index1_Head"]
3398 self.assertTrue(self.eq(xSection4.MetadataReference,
3399 StringPair("content.xml", "idAITitle")), "idAITitle")
3400 xSection5 = xSections["Illustration Index1_Head"]
3401 self.assertTrue(self.eq(xSection5.MetadataReference,
3402 StringPair("content.xml", "idIITitle")), "idIITitle")
3403 xSection6 = xSections["Index of Tables1_Head"]
3404 self.assertTrue(self.eq(xSection6.MetadataReference,
3405 StringPair("content.xml", "idIOTTitle")), "idIOTTitle")
3406 xSection7 = xSections["User-Defined1_Head"]
3407 self.assertTrue(self.eq(xSection7.MetadataReference,
3408 StringPair("content.xml", "idUDTitle")), "idUDTitle")
3409 xSection8 = xSections["Table of Objects1_Head"]
3410 self.assertTrue(self.eq(xSection8.MetadataReference,
3411 StringPair("content.xml", "idTOOTitle")), "idTOOTitle")
3412 xSection9 = xSections["Bibliography1_Head"]
3413 self.assertTrue(self.eq(xSection9.MetadataReference,
3414 StringPair("content.xml", "idBibTitle")), "idBibTitle")
3415 print("...done")
3417 print("Checking indexes in loaded test document...")
3418 xIndexes = xTextDoc.getDocumentIndexes()
3419 xIndex1 = xIndexes["Table of Contents1"]
3420 self.assertTrue(self.eq(xIndex1.MetadataReference,
3421 StringPair("content.xml", "idTOC")), "idTOC")
3422 xIndex1s = xSections["Table of Contents1"]
3423 self.assertTrue(self.eq(xIndex1s.MetadataReference,
3424 StringPair("content.xml", "idTOC")), "idTOC")
3425 xIndex2 = xIndexes["Alphabetical Index1"]
3426 self.assertTrue(self.eq(xIndex2.MetadataReference,
3427 StringPair("content.xml", "idAI")), "idAI")
3428 xIndex2s = xSections["Alphabetical Index1"]
3429 self.assertTrue(self.eq(xIndex2s.MetadataReference,
3430 StringPair("content.xml", "idAI")), "idAI")
3431 xIndex3 = xIndexes["Illustration Index1"]
3432 self.assertTrue(self.eq(xIndex3.MetadataReference,
3433 StringPair("content.xml", "idII")), "idII")
3434 xIndex3s = xSections["Table of Figures1"]
3435 self.assertTrue(self.eq(xIndex3s.MetadataReference,
3436 StringPair("content.xml", "idII")), "idII")
3437 xIndex4 = xIndexes["Index of Tables1"]
3438 self.assertTrue(self.eq(xIndex4.MetadataReference,
3439 StringPair("content.xml", "idIOT")), "idIOT")
3440 xIndex4s = xSections["Index of Tables1"]
3441 self.assertTrue(self.eq(xIndex4s.MetadataReference,
3442 StringPair("content.xml", "idIOT")), "idIOT")
3443 xIndex5 = xIndexes["User-Defined1"]
3444 self.assertTrue(self.eq(xIndex5.MetadataReference,
3445 StringPair("content.xml", "idUD")), "idUD")
3446 xIndex5s = xSections["User-Defined1"]
3447 self.assertTrue(self.eq(xIndex5s.MetadataReference,
3448 StringPair("content.xml", "idUD")), "idUD")
3449 xIndex6 = xIndexes["Table of Objects1"]
3450 self.assertTrue(self.eq(xIndex6.MetadataReference,
3451 StringPair("content.xml", "idTOO")), "idTOO")
3452 xIndex6s = xSections["Table of Objects1"]
3453 self.assertTrue(self.eq(xIndex6s.MetadataReference,
3454 StringPair("content.xml", "idTOO")), "idTOO")
3455 xIndex7 = xIndexes["Bibliography1"]
3456 self.assertTrue(self.eq(xIndex7.MetadataReference,
3457 StringPair("content.xml", "idBib")), "idBib")
3458 xIndex7s = xSections["Bibliography1"]
3459 self.assertTrue(self.eq(xIndex7s.MetadataReference,
3460 StringPair("content.xml", "idBib")), "idBib")
3461 print("...done")
3463 def dotest(self, intree, insert=True):
3464 xDoc = self.__class__.xDoc
3465 self._dotest(xDoc, intree, insert)
3467 def _dotest(self, xDoc, intree, insert):
3468 self._dumptree(intree, "I: ")
3469 if insert:
3470 TreeInserter(xDoc).inserttree(intree)
3471 xText = xDoc.getText()
3472 xTextEnum = xText.createEnumeration()
3473 ## skip to right paragraph
3474 xTextEnum.nextElement(); # skip first -- always empty!
3475 xElement = xTextEnum.nextElement() # second contains test case
3476 xEnum = xElement.createEnumeration()
3477 outtree = EnumConverter().convert(xEnum)
3478 self._dumptree(outtree, "O: ")
3479 FuzzyTester().dotest(intree, outtree)
3481 def _dumptree(self, tree, prefix):
3482 print('{}{}'.format(prefix, str(tree)))
3483 children = tree.createenumeration()
3484 for node in children:
3485 self._dumptree(node, "{} ".format(prefix))
3487 def mkname(self, prefix):
3488 self.__class__.count += 1
3489 return "{}{}".format(prefix, self.__class__.count)
3491 def mkid(self, prefix):
3492 self.mkname(prefix)
3493 return StringPair("content.xml", self.mkname(prefix))
3495 def mkid_(self, id):
3496 return StringPair("content.xml", id)
3498 def eq(self, left, right):
3499 return (left.First == right.First and
3500 left.Second == right.Second)
3503 if __name__ == '__main__':
3504 unittest.main()