Version 6.1.0.2, tag libreoffice-6.1.0.2
[LibreOffice.git] / sw / qa / python / text_portion_enumeration_test.py
blob3a7e9d8586be79e9c819984ed5d6055f13fd4c37
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, mkPropertyValue
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 PropertyValue, 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)
938 def test_text(self):
939 root = TreeNode()
940 text = TextNode("abc")
941 root.appendchild(text)
942 self.dotest(root)
944 def test_text_field(self):
945 self.mkname("ruby")
946 root = TreeNode()
947 txtf = TextFieldNode("abc")
948 root.appendchild(txtf)
949 self.dotest(root)
951 @unittest.skip("FIXME this is converted to a text portion: ControlCharacter is obsolete")
952 def test_control_char(self):
953 root = TreeNode()
954 cchr = ControlCharacterNode(HARD_HYPHEN)
955 root.appendchild(cchr)
956 self.dotest(root)
958 @unittest.skip("FIXME: insert a soft page break: not done")
959 def test_soft_page_break(self):
960 root = TreeNode()
961 spbk =SoftPageBreakNode()
962 text = TextNode("abc")
963 root.appendchild(spbk)
964 root.appendchild(text)
965 self.dotest(root)
967 def test_footnote(self):
968 name = self.mkname("ftn")
969 root = TreeNode()
970 ftnd = FootnoteNode(name)
971 root.appendchild(ftnd)
972 self.dotest(root)
974 def test_frame_as(self):
975 name = self.mkname("frame")
976 root = TreeNode()
977 fram = FrameNode(name, AS_CHARACTER)
978 root.appendchild(fram)
979 self.dotest(root)
981 def test_frame_at(self):
982 name = self.mkname("frame")
983 root = TreeNode()
984 fram = FrameNode(name, AT_CHARACTER)
985 root.appendchild(fram)
986 self.dotest(root)
988 def test_bookmark_point(self):
989 name = self.mkname("mark")
990 root = TreeNode()
991 bkmk = BookmarkNode(name)
992 text = TextNode("abc")
993 root.appendchild(bkmk)
994 root.appendchild(text)
995 self.dotest(root)
997 def test_bookmark(self):
998 name = self.mkname("mark")
999 root = TreeNode()
1000 bkm1 = BookmarkStartNode(name)
1001 text = TextNode("abc")
1002 bkm2 = BookmarkEndNode(name)
1003 root.appendchild(bkm1)
1004 root.appendchild(text)
1005 root.appendchild(bkm2)
1006 self.dotest(root)
1008 def test_bookmark_point_xmlid(self):
1009 name = self.mkname("mark")
1010 id = self.mkid("id")
1011 root = TreeNode()
1012 bkmk = BookmarkNode(name, id)
1013 text = TextNode("abc")
1014 root.appendchild(bkmk)
1015 root.appendchild(text)
1016 self.dotest(root)
1018 def test_bookmark_xmlid(self):
1019 name = self.mkname("mark")
1020 id = self.mkid("id")
1021 root = TreeNode()
1022 bkm1 = BookmarkStartNode(name, id)
1023 text = TextNode("abc")
1024 bkm2 = BookmarkEndNode(name, id)
1025 root.appendchild(bkm1)
1026 root.appendchild(text)
1027 root.appendchild(bkm2)
1028 self.dotest(root)
1030 def test_refmark_point(self):
1031 name = self.mkname("refmark")
1032 root = TreeNode()
1033 rfmk = ReferenceMarkNode(name)
1034 text = TextNode("abc")
1035 root.appendchild(rfmk)
1036 root.appendchild(text)
1037 self.dotest(root)
1039 def test_refmark(self):
1040 name = self.mkname("refmark")
1041 root = TreeNode()
1042 rfm1 = ReferenceMarkStartNode(name)
1043 text = TextNode("abc")
1044 rfm2 = ReferenceMarkEndNode(name)
1045 root.appendchild(rfm1)
1046 root.appendchild(text)
1047 root.appendchild(rfm2)
1048 self.dotest(root)
1050 def test_toxmark_point(self):
1051 name = self.mkname("toxmark")
1052 root = TreeNode()
1053 txmk = DocumentIndexMarkNode(name)
1054 text = TextNode("abc")
1055 root.appendchild(txmk)
1056 root.appendchild(text)
1057 self.dotest(root)
1059 def test_toxmark(self):
1060 name = self.mkname("toxmark")
1061 root = TreeNode()
1062 txm1 = DocumentIndexMarkStartNode(name)
1063 text = TextNode("abc")
1064 txm2 = DocumentIndexMarkEndNode(name)
1065 root.appendchild(txm1)
1066 root.appendchild(text)
1067 root.appendchild(txm2)
1068 self.dotest(root)
1070 def test_hyperlink(self):
1071 name = self.mkname("url")
1072 root = TreeNode()
1073 href = HyperlinkNode(name)
1074 text = TextNode("abc")
1075 href.appendchild(text)
1076 root.appendchild(href)
1077 self.dotest(root)
1079 def test_hyperlink_empty(self):
1080 name = self.mkname("url")
1081 root = TreeNode()
1082 href = HyperlinkNode(name)
1083 text = TextNode("")
1084 href.appendchild(text)
1085 root.appendchild(href)
1086 self.dotest(root)
1088 def test_ruby(self):
1089 name = self.mkname("ruby")
1090 root = TreeNode()
1091 ruby = RubyNode(name)
1092 text = TextNode("abc")
1093 ruby.appendchild(text)
1094 root.appendchild(ruby)
1095 self.dotest(root)
1097 def test_ruby_empty(self):
1098 # BUG: #i91534#
1099 name = self.mkname("ruby")
1100 root = TreeNode()
1101 ruby = RubyNode(name)
1102 root.appendchild(ruby)
1103 self.dotest(root)
1105 def test_meta(self):
1106 id = StringPair("content.xml", self.mkname("id"))
1107 root = TreeNode()
1108 meta = MetaNode(id)
1109 text = TextNode("abc")
1110 root.appendchild(TextNode("123"))
1111 meta.appendchild(text)
1112 root.appendchild(meta)
1113 self.dotest(root)
1115 def test_meta_empty(self):
1116 id = StringPair("content.xml", self.mkname("id"))
1117 root = TreeNode()
1118 meta = MetaNode(id)
1119 root.appendchild(meta)
1120 self.dotest(root)
1122 def test_meta_field(self):
1123 id = StringPair("content.xml", self.mkname("id"))
1124 root = TreeNode()
1125 meta = MetaFieldNode(id)
1126 text = TextNode("abc")
1127 root.appendchild(TextNode("123"))
1128 meta.appendchild(text)
1129 root.appendchild(meta)
1130 self.dotest(root)
1132 def test_meta_field_empty(self):
1133 id = StringPair("content.xml", self.mkname("id"))
1134 root = TreeNode()
1135 meta = MetaFieldNode(id)
1136 root.appendchild(meta)
1137 self.dotest(root)
1139 def test_bookmark1(self):
1140 name1 = self.mkname("mark")
1141 name2 = self.mkname("mark")
1142 name3 = self.mkname("mark")
1143 root = TreeNode()
1144 root.appendchild(BookmarkStartNode(name1))
1145 root.appendchild(BookmarkNode(name2))
1146 root.appendchild(BookmarkStartNode(name3))
1147 root.appendchild(TextNode("abc"))
1148 root.appendchild(BookmarkEndNode(name1))
1149 root.appendchild(TextNode("de"))
1150 root.appendchild(BookmarkEndNode(name3))
1151 self.dotest(root)
1153 def test_bookmark2(self):
1154 name1 = self.mkname("mark")
1155 name2 = self.mkname("mark")
1156 name3 = self.mkname("mark")
1157 root = TreeNode()
1158 root.appendchild(BookmarkStartNode(name1))
1159 root.appendchild(TextNode("abc"))
1160 root.appendchild(BookmarkNode(name2))
1161 root.appendchild(BookmarkStartNode(name3))
1162 root.appendchild(BookmarkEndNode(name1))
1163 root.appendchild(TextNode("de"))
1164 root.appendchild(BookmarkEndNode(name3))
1165 self.dotest(root)
1167 def test_refmark2(self):
1168 name1 = self.mkname("refmark")
1169 root = TreeNode()
1170 root.appendchild(ReferenceMarkStartNode(name1))
1171 root.appendchild(TextNode("abc"))
1172 # BUG: #i102541# (this is actually not unoportenum's fault)
1173 root.appendchild(ReferenceMarkEndNode(name1))
1174 root.appendchild(TextNode("de"))
1175 self.dotest(root)
1177 def test_refmark3(self):
1178 # BUG: #i107672# (non-deterministic; depends on pointer ordering)
1179 name1 = self.mkname("refmark")
1180 name2 = self.mkname("refmark")
1181 name3 = self.mkname("refmark")
1182 name4 = self.mkname("refmark")
1183 name5 = self.mkname("refmark")
1184 name6 = self.mkname("refmark")
1185 name7 = self.mkname("refmark")
1186 root = TreeNode()
1187 root.appendchild(ReferenceMarkStartNode(name1))
1188 root.appendchild(ReferenceMarkStartNode(name2))
1189 root.appendchild(ReferenceMarkStartNode(name3))
1190 root.appendchild(ReferenceMarkStartNode(name4))
1191 root.appendchild(ReferenceMarkStartNode(name5))
1192 root.appendchild(ReferenceMarkStartNode(name6))
1193 root.appendchild(ReferenceMarkStartNode(name7))
1194 root.appendchild(TextNode("abc"))
1195 root.appendchild(ReferenceMarkEndNode(name7))
1196 root.appendchild(ReferenceMarkEndNode(name6))
1197 root.appendchild(ReferenceMarkEndNode(name5))
1198 root.appendchild(ReferenceMarkEndNode(name4))
1199 root.appendchild(ReferenceMarkEndNode(name3))
1200 root.appendchild(ReferenceMarkEndNode(name2))
1201 root.appendchild(ReferenceMarkEndNode(name1))
1202 root.appendchild(TextNode("de"))
1203 self.dotest(root)
1205 def test_toxmark2(self):
1206 name1 = self.mkname("toxmark")
1207 root = TreeNode()
1208 root.appendchild(DocumentIndexMarkStartNode(name1))
1209 root.appendchild(TextNode("abc"))
1210 root.appendchild(DocumentIndexMarkEndNode(name1))
1211 root.appendchild(TextNode("de"))
1212 self.dotest(root)
1214 def test_toxmark3(self):
1215 # BUG: #i107672# (non-deterministic; depends on pointer ordering)
1216 name1 = self.mkname("toxmark")
1217 name2 = self.mkname("toxmark")
1218 name3 = self.mkname("toxmark")
1219 name4 = self.mkname("toxmark")
1220 name5 = self.mkname("toxmark")
1221 name6 = self.mkname("toxmark")
1222 name7 = self.mkname("toxmark")
1223 root = TreeNode()
1224 root.appendchild(DocumentIndexMarkStartNode(name1))
1225 root.appendchild(DocumentIndexMarkStartNode(name2))
1226 root.appendchild(DocumentIndexMarkStartNode(name3))
1227 root.appendchild(DocumentIndexMarkStartNode(name4))
1228 root.appendchild(DocumentIndexMarkStartNode(name5))
1229 root.appendchild(DocumentIndexMarkStartNode(name6))
1230 root.appendchild(DocumentIndexMarkStartNode(name7))
1231 root.appendchild(TextNode("abc"))
1232 root.appendchild(DocumentIndexMarkEndNode(name7))
1233 root.appendchild(DocumentIndexMarkEndNode(name6))
1234 root.appendchild(DocumentIndexMarkEndNode(name5))
1235 root.appendchild(DocumentIndexMarkEndNode(name4))
1236 root.appendchild(DocumentIndexMarkEndNode(name3))
1237 root.appendchild(DocumentIndexMarkEndNode(name2))
1238 root.appendchild(DocumentIndexMarkEndNode(name1))
1239 root.appendchild(TextNode("de"))
1240 self.dotest(root)
1242 def test_marks1(self):
1243 name1 = self.mkname("bookmark")
1244 name2 = self.mkname("toxmark")
1245 name3 = self.mkname("refmark")
1246 name4 = self.mkname("toxmark")
1247 root = TreeNode()
1248 root.appendchild(BookmarkStartNode(name1))
1249 root.appendchild(DocumentIndexMarkNode(name2))
1250 root.appendchild(ReferenceMarkStartNode(name3))
1251 root.appendchild(TextNode("abc"))
1252 root.appendchild(BookmarkEndNode(name1))
1253 root.appendchild(DocumentIndexMarkStartNode(name4))
1254 root.appendchild(TextNode("de"))
1255 root.appendchild(DocumentIndexMarkEndNode(name4))
1256 root.appendchild(ReferenceMarkEndNode(name3))
1257 self.dotest(root)
1259 def test_marks2(self):
1260 name1 = self.mkname("bookmark")
1261 name2 = self.mkname("refmark")
1262 name3 = self.mkname("refmark")
1263 name4 = self.mkname("toxmark")
1264 name5 = self.mkname("refmark")
1265 root = TreeNode()
1266 root.appendchild(BookmarkStartNode(name1))
1267 root.appendchild(ReferenceMarkNode(name2))
1268 root.appendchild(ReferenceMarkStartNode(name3))
1269 root.appendchild(TextNode("abc"))
1270 root.appendchild(DocumentIndexMarkStartNode(name4))
1271 root.appendchild(ReferenceMarkStartNode(name5))
1272 # BUG: #i102541# (this is actually not unoportenum's fault)
1273 root.appendchild(ReferenceMarkEndNode(name3))
1274 root.appendchild(TextNode("de"))
1275 root.appendchild(DocumentIndexMarkEndNode(name4))
1276 root.appendchild(BookmarkEndNode(name1))
1277 root.appendchild(ReferenceMarkEndNode(name5))
1278 self.dotest(root)
1280 def test_marks3(self):
1281 name1 = self.mkname("bookmark")
1282 name2 = self.mkname("refmark")
1283 name3 = self.mkname("refmark")
1284 name4 = self.mkname("toxmark")
1285 name5 = self.mkname("refmark")
1286 root = TreeNode()
1287 root.appendchild(BookmarkStartNode(name1))
1288 root.appendchild(DocumentIndexMarkNode(name2))
1289 root.appendchild(DocumentIndexMarkStartNode(name3))
1290 root.appendchild(TextNode("abc"))
1291 root.appendchild(ReferenceMarkStartNode(name4))
1292 root.appendchild(DocumentIndexMarkStartNode(name5))
1293 root.appendchild(DocumentIndexMarkEndNode(name3))
1294 root.appendchild(TextNode("de"))
1295 root.appendchild(ReferenceMarkEndNode(name4))
1296 root.appendchild(BookmarkEndNode(name1))
1297 root.appendchild(DocumentIndexMarkEndNode(name5))
1298 self.dotest(root)
1300 def test_frame_mark1(self):
1301 name1 = self.mkname("bookmark")
1302 name2 = self.mkname("frame")
1303 root = TreeNode()
1304 root.appendchild(TextNode("abc"))
1305 root.appendchild(BookmarkNode(name1))
1306 root.appendchild(TextNode("de"))
1307 root.appendchild(FrameNode(name2, AS_CHARACTER))
1308 self.dotest(root)
1310 def test_frame_mark2(self):
1311 # BUG: #i98530#
1312 name1 = self.mkname("bookmark")
1313 name2 = self.mkname("frame")
1314 root = TreeNode()
1315 root.appendchild(TextNode("abc"))
1316 root.appendchild(BookmarkNode(name1))
1317 root.appendchild(TextNode("de"))
1318 root.appendchild(FrameNode(name2, AT_CHARACTER))
1319 self.dotest(root)
1321 def test_frame_mark3(self):
1322 name1 = self.mkname("frame")
1323 name2 = self.mkname("bookmark")
1324 root = TreeNode()
1325 root.appendchild(TextNode("abc"))
1326 root.appendchild(FrameNode(name1, AS_CHARACTER))
1327 root.appendchild(TextNode("de"))
1328 root.appendchild(BookmarkNode(name2))
1329 self.dotest(root)
1331 def test_frame_mark4(self):
1332 name1 = self.mkname("frame")
1333 name2 = self.mkname("bookmark")
1334 root = TreeNode()
1335 root.appendchild(TextNode("abc"))
1336 root.appendchild(FrameNode(name1, AT_CHARACTER))
1337 root.appendchild(TextNode("de"))
1338 root.appendchild(BookmarkNode(name2))
1339 self.dotest(root)
1341 def test_frames1(self):
1342 name1 = self.mkname("frame")
1343 name2 = self.mkname("frame")
1344 name3 = self.mkname("frame")
1345 root = TreeNode()
1346 root.appendchild(FrameNode(name1, AT_CHARACTER))
1347 root.appendchild(FrameNode(name2, AT_CHARACTER))
1348 root.appendchild(FrameNode(name3, AT_CHARACTER))
1349 self.dotest(root)
1351 def test_frames2(self):
1352 name1 = self.mkname("frame")
1353 name2 = self.mkname("frame")
1354 name3 = self.mkname("frame")
1355 root = TreeNode()
1356 root.appendchild(FrameNode(name1, AS_CHARACTER))
1357 root.appendchild(FrameNode(name2, AS_CHARACTER))
1358 root.appendchild(FrameNode(name3, AS_CHARACTER))
1359 self.dotest(root)
1361 def test_frames3(self):
1362 name1 = self.mkname("frame")
1363 name2 = self.mkname("frame")
1364 name3 = self.mkname("frame")
1365 root = TreeNode()
1366 root.appendchild(FrameNode(name1, AT_CHARACTER))
1367 root.appendchild(FrameNode(name2, AS_CHARACTER))
1368 root.appendchild(FrameNode(name3, AT_CHARACTER))
1369 self.dotest(root)
1371 def test_frames4(self):
1372 name1 = self.mkname("frame")
1373 name2 = self.mkname("frame")
1374 name3 = self.mkname("frame")
1375 root = TreeNode()
1376 root.appendchild(FrameNode(name1, AT_CHARACTER))
1377 root.appendchild(FrameNode(name2, AT_CHARACTER))
1378 root.appendchild(FrameNode(name3, AS_CHARACTER))
1379 self.dotest(root)
1381 def test_frames5(self):
1382 name1 = self.mkname("frame")
1383 name2 = self.mkname("frame")
1384 name3 = self.mkname("frame")
1385 root = TreeNode()
1386 root.appendchild(FrameNode(name1, AS_CHARACTER))
1387 root.appendchild(FrameNode(name2, AT_CHARACTER))
1388 root.appendchild(FrameNode(name3, AT_CHARACTER))
1389 self.dotest(root)
1391 def test_ruby_hyperlink1(self):
1392 name1 = self.mkname("ruby")
1393 name2 = self.mkname("url")
1394 root = TreeNode()
1395 ruby = RubyNode(name1)
1396 href = HyperlinkNode(name2)
1397 href.appendchild(TextNode("abc"))
1398 ruby.appendchild(href)
1399 root.appendchild(ruby)
1400 self.dotest(root)
1402 def test_ruby_hyperlink2(self):
1403 name1 = self.mkname("url")
1404 name2 = self.mkname("ruby")
1405 root = TreeNode()
1406 href = HyperlinkNode(name1)
1407 ruby = RubyNode(name2)
1408 ruby.appendchild(TextNode("abc"))
1409 href.appendchild(ruby)
1410 root.appendchild(href)
1411 self.dotest(root)
1413 def test_end1(self):
1414 name1 = self.mkname("bookmark")
1415 name2 = self.mkname("toxmark")
1416 name3 = self.mkname("refmark")
1417 root = TreeNode()
1418 root.appendchild(TextNode("abc"))
1419 root.appendchild(BookmarkNode(name1))
1420 root.appendchild(DocumentIndexMarkNode(name2))
1421 root.appendchild(ReferenceMarkNode(name3))
1422 self.dotest(root)
1424 def test_end2(self):
1425 name1 = self.mkname("bookmark")
1426 name2 = self.mkname("frame")
1427 name3 = self.mkname("refmark")
1428 name4 = self.mkname("frame")
1429 name5 = self.mkname("frame")
1430 root = TreeNode()
1431 root.appendchild(TextNode("abc"))
1432 root.appendchild(BookmarkStartNode(name1))
1433 root.appendchild(FrameNode(name2, AT_CHARACTER))
1434 root.appendchild(BookmarkEndNode(name1))
1435 root.appendchild(ReferenceMarkNode(name3))
1436 root.appendchild(FrameNode(name4, AT_CHARACTER))
1437 root.appendchild(FrameNode(name5, AT_CHARACTER))
1438 self.dotest(root)
1440 def test_end3(self):
1441 name1 = self.mkname("ftn")
1442 name2 = self.mkname("toxmark")
1443 root = TreeNode()
1444 root.appendchild(TextNode("abc"))
1445 root.appendchild(FootnoteNode(name1))
1446 root.appendchild(DocumentIndexMarkNode(name2))
1447 self.dotest(root)
1449 def test_end4(self):
1450 name1 = self.mkname("bookmark")
1451 name2 = self.mkname("frame")
1452 root = TreeNode()
1453 root.appendchild(BookmarkStartNode(name1))
1454 root.appendchild(TextNode("abc"))
1455 root.appendchild(FrameNode(name2, AS_CHARACTER))
1456 root.appendchild(BookmarkEndNode(name1))
1457 self.dotest(root)
1459 def test_end5(self):
1460 name1 = self.mkname("refmark")
1461 name2 = self.mkname("ruby")
1462 root = TreeNode()
1463 root.appendchild(ReferenceMarkStartNode(name1))
1464 root.appendchild(TextNode("abc"))
1465 ruby = RubyNode(name2)
1466 ruby.appendchild(TextFieldNode("de"))
1467 root.appendchild(ruby)
1468 root.appendchild(ReferenceMarkEndNode(name1))
1469 self.dotest(root)
1471 def test_empty1(self):
1472 name1 = self.mkname("refmark")
1473 name2 = self.mkname("toxmark")
1474 name3 = self.mkname("bookmark")
1475 name4 = self.mkname("frame")
1476 name7 = self.mkname("refmark")
1477 name8 = self.mkname("toxmark")
1478 name9 = self.mkname("bookmark")
1479 nameA = self.mkname("frame")
1480 root = TreeNode()
1481 root.appendchild(ReferenceMarkNode(name1))
1482 root.appendchild(DocumentIndexMarkNode(name2))
1483 root.appendchild(BookmarkStartNode(name3))
1484 root.appendchild(FrameNode(name4, AT_CHARACTER))
1485 root.appendchild(BookmarkEndNode(name3))
1486 root.appendchild(ReferenceMarkNode(name7))
1487 root.appendchild(DocumentIndexMarkNode(name8))
1488 root.appendchild(BookmarkStartNode(name9))
1489 root.appendchild(FrameNode(nameA, AT_CHARACTER))
1490 root.appendchild(BookmarkEndNode(name9))
1491 self.dotest(root)
1493 def test_empty2(self):
1494 name3 = self.mkname("bookmark")
1495 name4 = self.mkname("frame")
1496 name9 = self.mkname("bookmark")
1497 nameA = self.mkname("frame")
1498 root = TreeNode()
1499 root.appendchild(BookmarkStartNode(name3))
1500 root.appendchild(FrameNode(name4, AT_CHARACTER))
1501 root.appendchild(BookmarkEndNode(name3))
1502 root.appendchild(BookmarkStartNode(name9))
1503 root.appendchild(FrameNode(nameA, AT_CHARACTER))
1504 root.appendchild(BookmarkEndNode(name9))
1505 self.dotest(root)
1507 def test_empty3(self):
1508 name1 = self.mkname("refmark")
1509 name2 = self.mkname("toxmark")
1510 name3 = self.mkname("bookmark")
1511 name4 = self.mkname("frame")
1512 name5 = self.mkname("url")
1513 name6 = self.mkname("ruby")
1514 name7 = self.mkname("refmark")
1515 name8 = self.mkname("toxmark")
1516 name9 = self.mkname("bookmark")
1517 nameA = self.mkname("frame")
1518 root = TreeNode()
1519 root.appendchild(ReferenceMarkNode(name1))
1520 root.appendchild(DocumentIndexMarkNode(name2))
1521 root.appendchild(BookmarkStartNode(name3))
1522 root.appendchild(FrameNode(name4, AT_CHARACTER))
1523 root.appendchild(BookmarkEndNode(name3))
1524 ## currently empty hyperlinks may get eaten...
1525 # href = HyperlinkNode(name5)
1526 # href.appendchild(TextNode(""))
1527 # root.appendchild(href)
1528 ruby = RubyNode(name6)
1529 root.appendchild(ruby)
1530 root.appendchild(ReferenceMarkNode(name7))
1531 root.appendchild(DocumentIndexMarkNode(name8))
1532 root.appendchild(BookmarkStartNode(name9))
1533 root.appendchild(FrameNode(nameA, AT_CHARACTER))
1534 root.appendchild(BookmarkEndNode(name9))
1535 self.dotest(root)
1537 def test1(self):
1538 name1 = self.mkname("frame")
1539 name2 = self.mkname("bookmark")
1540 name3 = self.mkname("ruby")
1541 name4 = self.mkname("ftn")
1542 name5 = self.mkname("frame")
1543 root = TreeNode()
1544 root.appendchild(FrameNode(name1, AT_CHARACTER))
1545 root.appendchild(BookmarkStartNode(name2))
1546 root.appendchild(TextNode("abc"))
1547 ruby = RubyNode(name3)
1548 ruby.appendchild(TextNode("de"))
1549 ruby.appendchild(FootnoteNode(name4))
1550 ruby.appendchild(BookmarkEndNode(name2))
1551 root.appendchild(ruby)
1552 root.appendchild(TextNode("fg"))
1553 root.appendchild(FrameNode(name5, AT_CHARACTER))
1554 root.appendchild(TextFieldNode("h"))
1555 self.dotest(root)
1557 # some range tests for the insertion: these are for the current
1558 # API which treats hyperlinks and rubys not as entities, but as formatting
1559 # attributes; if these ever become entities, they should not be split!'''
1561 def test_range1(self):
1562 name1 = self.mkname("url")
1563 inserter = RangeInserter(self.__class__.xDoc)
1564 text = TextNode("12345")
1565 inserter.insertrange(Range(0, 0, text))
1566 url1 = HyperlinkNode(name1)
1567 range1 = Range(0, 5, url1)
1568 inserter.insertrange(range1)
1569 root = TreeNode()
1570 root.appendchild(url1)
1571 url1.appendchild(text)
1572 self.dotest(root, False)
1574 def test_range_hyperlink_hyperlink(self):
1575 inserter = RangeInserter(self.__class__.xDoc)
1576 text = TextNode("123456789")
1577 inserter.insertrange(Range(0, 0, text))
1578 url1 = HyperlinkNode(self.mkname("url"))
1579 inserter.insertrange(Range(1, 4, url1))
1580 ## overlap left
1581 url2 = HyperlinkNode(self.mkname("url"))
1582 inserter.insertrange(Range(0, 2, url2))
1583 root = TreeNode()
1584 root.appendchild(url2.dup().appendchild(TextNode("12")))
1585 root.appendchild(url1.dup().appendchild(TextNode("34")))
1586 root.appendchild(TextNode("56789"))
1587 self.dotest(root, False)
1588 ## overlap right
1589 url3 = HyperlinkNode(self.mkname("url"))
1590 inserter.insertrange(Range(3, 7, url3))
1591 root = TreeNode()
1592 root.appendchild(url2.dup().appendchild(TextNode("12")))
1593 root.appendchild(url1.dup().appendchild(TextNode("3")))
1594 root.appendchild(url3.dup().appendchild(TextNode("4567")))
1595 root.appendchild(TextNode("89"))
1596 self.dotest(root, False)
1597 ## around
1598 url4 = HyperlinkNode(self.mkname("url"))
1599 inserter.insertrange(Range(3, 7, url4))
1600 root = TreeNode()
1601 root.appendchild(url2.dup().appendchild(TextNode("12")))
1602 root.appendchild(url1.dup().appendchild(TextNode("3")))
1603 root.appendchild(url4.dup().appendchild(TextNode("4567")))
1604 root.appendchild(TextNode("89"))
1605 self.dotest(root, False)
1606 ## inside
1607 url5 = HyperlinkNode(self.mkname("url"))
1608 inserter.insertrange(Range(4, 6, url5))
1609 root = TreeNode()
1610 root.appendchild(url2.dup().appendchild(TextNode("12")))
1611 root.appendchild(url1.dup().appendchild(TextNode("3")))
1612 root.appendchild(url4.dup().appendchild(TextNode("4")))
1613 root.appendchild(url5.dup().appendchild(TextNode("56")))
1614 root.appendchild(url4.dup().appendchild(TextNode("7")))
1615 root.appendchild(TextNode("89"))
1616 self.dotest(root, False)
1617 ## empty
1618 url6 = HyperlinkNode(self.mkname("url"))
1619 inserter.insertrange(Range(7, 7, url6))
1620 root = TreeNode()
1621 root.appendchild(url2.dup().appendchild(TextNode("12")))
1622 root.appendchild(url1.dup().appendchild(TextNode("3")))
1623 root.appendchild(url4.dup().appendchild(TextNode("4")))
1624 root.appendchild(url5.dup().appendchild(TextNode("56")))
1625 root.appendchild(url4.dup().appendchild(TextNode("7")))
1626 ## this one gets eaten, but we still need to test inserting it (#i106930#)
1627 # root.appendchild(url6.dup().appendchild(TextNode("")))
1628 root.appendchild(TextNode("89"))
1629 ## inside (left-edge)
1630 url7 = HyperlinkNode(self.mkname("url"))
1631 inserter.insertrange(Range(0, 1, url7))
1632 root = TreeNode()
1633 root.appendchild(url7.dup().appendchild(TextNode("1")))
1634 root.appendchild(url2.dup().appendchild(TextNode("2")))
1635 root.appendchild(url1.dup().appendchild(TextNode("3")))
1636 root.appendchild(url4.dup().appendchild(TextNode("4")))
1637 root.appendchild(url5.dup().appendchild(TextNode("56")))
1638 root.appendchild(url4.dup().appendchild(TextNode("7")))
1639 root.appendchild(TextNode("89"))
1640 ## inside (right-edge)
1641 url8 = HyperlinkNode(self.mkname("url"))
1642 inserter.insertrange(Range(5, 6, url8))
1643 root = TreeNode()
1644 root.appendchild(url7.dup().appendchild(TextNode("1")))
1645 root.appendchild(url2.dup().appendchild(TextNode("2")))
1646 root.appendchild(url1.dup().appendchild(TextNode("3")))
1647 root.appendchild(url4.dup().appendchild(TextNode("4")))
1648 root.appendchild(url5.dup().appendchild(TextNode("5")))
1649 root.appendchild(url8.dup().appendchild(TextNode("6")))
1650 root.appendchild(url4.dup().appendchild(TextNode("7")))
1651 root.appendchild(TextNode("89"))
1652 self.dotest(root, False)
1654 def test_range_hyperlink_ruby(self):
1655 inserter = RangeInserter(self.__class__.xDoc)
1656 text = TextNode("123456789")
1657 inserter.insertrange(Range(0, 0, text))
1658 url1 = HyperlinkNode(self.mkname("url"))
1659 inserter.insertrange(Range(1, 4, url1))
1660 # overlap left
1661 rby2 = RubyNode(self.mkname("ruby"))
1662 inserter.insertrange(Range(0, 2, rby2))
1663 root = TreeNode()
1664 root.appendchild(rby2.dup()
1665 .appendchild(TextNode("1"))
1666 .appendchild(url1.dup().appendchild(TextNode("2"))))
1667 root.appendchild(url1.dup().appendchild(TextNode("34")))
1668 root.appendchild(TextNode("56789"))
1669 self.dotest(root, False)
1670 # overlap right
1671 rby3 = RubyNode(self.mkname("ruby"))
1672 inserter.insertrange(Range(3, 5, rby3))
1673 root = TreeNode()
1674 root.appendchild(rby2.dup()
1675 .appendchild(TextNode("1"))
1676 .appendchild(url1.dup().appendchild(TextNode("2"))))
1677 root.appendchild(url1.dup().appendchild(TextNode("3")))
1678 root.appendchild(rby3.dup()
1679 .appendchild(url1.dup().appendchild(TextNode("4")))
1680 .appendchild(TextNode("5")))
1681 root.appendchild(TextNode("6789"))
1682 self.dotest(root, False)
1683 # around
1684 rby4 = RubyNode(self.mkname("ruby"))
1685 inserter.insertrange(Range(2, 3, rby4))
1686 root = TreeNode()
1687 root.appendchild(rby2.dup()
1688 .appendchild(TextNode("1"))
1689 .appendchild(url1.dup().appendchild(TextNode("2"))))
1690 root.appendchild(rby4.dup()
1691 .appendchild(url1.dup().appendchild(TextNode("3"))))
1692 root.appendchild(rby3.dup()
1693 .appendchild(url1.dup().appendchild(TextNode("4")))
1694 .appendchild(TextNode("5")))
1695 root.appendchild(TextNode("6789"))
1696 self.dotest(root, False)
1697 # inside
1698 url5 = HyperlinkNode(self.mkname("url"))
1699 inserter.insertrange(Range(6, 9, url5))
1700 rby6 = RubyNode(self.mkname("ruby"))
1701 inserter.insertrange(Range(7, 8, rby6))
1702 root = TreeNode()
1703 root.appendchild(rby2.dup()
1704 .appendchild(TextNode("1"))
1705 .appendchild(url1.dup().appendchild(TextNode("2"))))
1706 root.appendchild(rby4.dup()
1707 .appendchild(url1.dup().appendchild(TextNode("3"))))
1708 root.appendchild(rby3.dup()
1709 .appendchild(url1.dup().appendchild(TextNode("4")))
1710 .appendchild(TextNode("5")))
1711 root.appendchild(TextNode("6"))
1712 root.appendchild(url5.dup().appendchild(TextNode("7")))
1713 root.appendchild(rby6.dup()
1714 .appendchild(url5.dup().appendchild(TextNode("8"))))
1715 root.appendchild(url5.dup().appendchild(TextNode("9")))
1716 self.dotest(root, False)
1718 def test_range_ruby_hyperlink(self):
1719 inserter = RangeInserter(self.__class__.xDoc)
1720 text = TextNode("123456789")
1721 inserter.insertrange(Range(0, 0, text))
1722 rby1 = RubyNode(self.mkname("ruby"))
1723 inserter.insertrange(Range(1, 6, rby1))
1724 ## overlap left
1725 url2 = HyperlinkNode(self.mkname("url"))
1726 inserter.insertrange(Range(0, 3, url2))
1727 root = TreeNode()
1728 root.appendchild(url2.dup().appendchild(TextNode("1")))
1729 root.appendchild(rby1.dup()
1730 .appendchild(url2.dup().appendchild(TextNode("23")))
1731 .appendchild(TextNode("456")))
1732 root.appendchild(TextNode("789"))
1733 self.dotest(root, False)
1734 ## overlap right
1735 url3 = HyperlinkNode(self.mkname("url"))
1736 inserter.insertrange(Range(5, 7, url3))
1737 root = TreeNode()
1738 root.appendchild(url2.dup().appendchild(TextNode("1")))
1739 root.appendchild(rby1.dup()
1740 .appendchild(url2.dup().appendchild(TextNode("23")))
1741 .appendchild(TextNode("45"))
1742 .appendchild(url3.dup().appendchild(TextNode("6"))))
1743 root.appendchild(url3.dup().appendchild(TextNode("7")))
1744 root.appendchild(TextNode("89"))
1745 self.dotest(root, False)
1746 ## around (not quite, due to API)
1747 url4 = HyperlinkNode(self.mkname("url"))
1748 inserter.insertrange(Range(1, 8, url4))
1749 root = TreeNode()
1750 root.appendchild(url2.dup().appendchild(TextNode("1")))
1751 root.appendchild(rby1.dup()
1752 .appendchild(url4.dup()
1753 .appendchild(TextNode("23456"))))
1754 root.appendchild(url4.dup().appendchild(TextNode("78")))
1755 root.appendchild(TextNode("9"))
1756 self.dotest(root, False)
1757 ## inside
1758 url5 = HyperlinkNode(self.mkname("url"))
1759 inserter.insertrange(Range(3, 5, url5))
1760 root = TreeNode()
1761 root.appendchild(url2.dup().appendchild(TextNode("1")))
1762 root.appendchild(rby1.dup()
1763 .appendchild(url4.dup()
1764 .appendchild(TextNode("23")))
1765 .appendchild(url5.dup()
1766 .appendchild(TextNode("45")))
1767 .appendchild(url4.dup()
1768 .appendchild(TextNode("6"))))
1769 root.appendchild(url4.dup().appendchild(TextNode("78")))
1770 root.appendchild(TextNode("9"))
1771 self.dotest(root, False)
1773 def test_range_ruby_ruby(self):
1774 inserter = RangeInserter(self.__class__.xDoc)
1775 text = TextNode("123456789")
1776 inserter.insertrange(Range(0, 0, text))
1777 rby1 = RubyNode(self.mkname("ruby"))
1778 inserter.insertrange(Range(1, 4, rby1))
1779 ## overlap left
1780 rby2 = RubyNode(self.mkname("ruby"))
1781 inserter.insertrange(Range(0, 2, rby2))
1782 root = TreeNode()
1783 root.appendchild(rby2.dup().appendchild(TextNode("12")))
1784 root.appendchild(rby1.dup().appendchild(TextNode("34")))
1785 root.appendchild(TextNode("56789"))
1786 self.dotest(root, False)
1787 ## overlap right
1788 rby3 = RubyNode(self.mkname("ruby"))
1789 inserter.insertrange(Range(3, 7, rby3))
1790 root = TreeNode()
1791 root.appendchild(rby2.dup().appendchild(TextNode("12")))
1792 root.appendchild(rby1.dup().appendchild(TextNode("3")))
1793 root.appendchild(rby3.dup().appendchild(TextNode("4567")))
1794 root.appendchild(TextNode("89"))
1795 self.dotest(root, False)
1796 ## around
1797 rby4 = RubyNode(self.mkname("ruby"))
1798 inserter.insertrange(Range(3, 7, rby4))
1799 root = TreeNode()
1800 root.appendchild(rby2.dup().appendchild(TextNode("12")))
1801 root.appendchild(rby1.dup().appendchild(TextNode("3")))
1802 root.appendchild(rby4.dup().appendchild(TextNode("4567")))
1803 root.appendchild(TextNode("89"))
1804 self.dotest(root, False)
1805 ## inside
1806 rby5 = RubyNode(self.mkname("ruby"))
1807 inserter.insertrange(Range(4, 6, rby5))
1808 root = TreeNode()
1809 root.appendchild(rby2.dup().appendchild(TextNode("12")))
1810 root.appendchild(rby1.dup().appendchild(TextNode("3")))
1811 root.appendchild(rby4.dup().appendchild(TextNode("4")))
1812 root.appendchild(rby5.dup().appendchild(TextNode("56")))
1813 root.appendchild(rby4.dup().appendchild(TextNode("7")))
1814 root.appendchild(TextNode("89"))
1815 self.dotest(root, False)
1817 def test_range_hyperlink_meta(self):
1818 inserter = RangeInserter(self.__class__.xDoc)
1819 text = TextNode("123456789")
1820 inserter.insertrange(Range(0, 0, text))
1821 url1 = HyperlinkNode(self.mkname("url"))
1822 inserter.insertrange(Range(1, 4, url1))
1823 ## overlap left
1824 met2 = MetaNode(self.mkid("id"))
1825 inserter.insertrange(Range(0, 2, met2))
1826 root = TreeNode()
1827 root.appendchild(met2.dup()
1828 .appendchild(TextNode("1"))
1829 .appendchild(url1.dup().appendchild(TextNode("2"))))
1830 root.appendchild(url1.dup().appendchild(TextNode("34")))
1831 root.appendchild(TextNode("56789"))
1832 self.dotest(root, False)
1833 ## overlap right
1834 met3 = MetaNode(self.mkid("id"))
1835 # inserter.insertrange(Range(4-1, 6-1, met3))
1836 inserter.insertrange(Range(4, 6, met3))
1837 root = TreeNode()
1838 root.appendchild(met2.dup()
1839 .appendchild(TextNode("1"))
1840 .appendchild(url1.dup().appendchild(TextNode("2"))))
1841 root.appendchild(url1.dup().appendchild(TextNode("3")))
1842 root.appendchild(met3.dup()
1843 .appendchild(url1.dup().appendchild(TextNode("4")))
1844 .appendchild(TextNode("5")))
1845 root.appendchild(TextNode("6789"))
1846 self.dotest(root, False)
1847 ## around
1848 met4 = MetaNode(self.mkid("id"))
1849 # inserter.insertrange(Range(3-1, 4-1, met4))
1850 inserter.insertrange(Range(3, 4, met4))
1851 root = TreeNode()
1852 root.appendchild(met2.dup()
1853 .appendchild(TextNode("1"))
1854 .appendchild(url1.dup().appendchild(TextNode("2"))))
1855 root.appendchild(met4.dup()
1856 .appendchild(url1.dup().appendchild(TextNode("3"))))
1857 root.appendchild(met3.dup()
1858 .appendchild(url1.dup().appendchild(TextNode("4")))
1859 .appendchild(TextNode("5")))
1860 root.appendchild(TextNode("6789"))
1861 self.dotest(root, False)
1862 ## inside
1863 url5 = HyperlinkNode(self.mkname("url"))
1864 # inserter.insertrange(Range(9-3, 12-3, url5))
1865 inserter.insertrange(Range(9, 12, url5))
1866 met6 = MetaNode(self.mkid("id"))
1867 # inserter.insertrange(Range(10-3, 11-3, met6))
1868 inserter.insertrange(Range(10, 11, met6))
1869 root = TreeNode()
1870 root.appendchild(met2.dup()
1871 .appendchild(TextNode("1"))
1872 .appendchild(url1.dup().appendchild(TextNode("2"))))
1873 root.appendchild(met4.dup()
1874 .appendchild(url1.dup().appendchild(TextNode("3"))))
1875 root.appendchild(met3.dup()
1876 .appendchild(url1.dup().appendchild(TextNode("4")))
1877 .appendchild(TextNode("5")))
1878 root.appendchild(TextNode("6"))
1879 root.appendchild(url5.dup().appendchild(TextNode("7")))
1880 root.appendchild(met6.dup()
1881 .appendchild(url5.dup().appendchild(TextNode("8"))))
1882 root.appendchild(url5.dup().appendchild(TextNode("9")))
1883 self.dotest(root, False)
1885 def test_range_ruby_meta(self):
1886 inserter = RangeInserter(self.__class__.xDoc)
1887 text = TextNode("123456789")
1888 inserter.insertrange(Range(0, 0, text))
1889 rby1 = RubyNode(self.mkname("ruby"))
1890 inserter.insertrange(Range(1, 4, rby1))
1891 ## overlap left
1892 met2 = MetaNode(self.mkid("id"))
1893 inserter.insertrange(Range(0, 2, met2))
1894 root = TreeNode()
1895 root.appendchild(met2.dup()
1896 .appendchild(TextNode("1"))
1897 .appendchild(rby1.dup().appendchild(TextNode("2"))))
1898 root.appendchild(rby1.dup().appendchild(TextNode("34")))
1899 root.appendchild(TextNode("56789"))
1900 self.dotest(root, False)
1901 ## overlap right
1902 met3 = MetaNode(self.mkid("id"))
1903 # inserter.insertrange(Range(4-1, 6-1, met3))
1904 inserter.insertrange(Range(4, 6, met3))
1905 root = TreeNode()
1906 root.appendchild(met2.dup()
1907 .appendchild(TextNode("1"))
1908 .appendchild(rby1.dup().appendchild(TextNode("2"))))
1909 root.appendchild(rby1.dup().appendchild(TextNode("3")))
1910 root.appendchild(met3.dup()
1911 .appendchild(rby1.dup().appendchild(TextNode("4")))
1912 .appendchild(TextNode("5")))
1913 root.appendchild(TextNode("6789"))
1914 self.dotest(root, False)
1915 ## around
1916 met4 = MetaNode(self.mkid("id"))
1917 # inserter.insertrange(Range(3-1, 4-1, met4))
1918 inserter.insertrange(Range(3, 4, met4))
1919 root = TreeNode()
1920 root.appendchild(met2.dup()
1921 .appendchild(TextNode("1"))
1922 .appendchild(rby1.dup().appendchild(TextNode("2"))))
1923 root.appendchild(met4.dup()
1924 .appendchild(rby1.dup().appendchild(TextNode("3"))))
1925 root.appendchild(met3.dup()
1926 .appendchild(rby1.dup().appendchild(TextNode("4")))
1927 .appendchild(TextNode("5")))
1928 root.appendchild(TextNode("6789"))
1929 self.dotest(root, False)
1930 ## inside
1931 rby5 = RubyNode(self.mkname("ruby"))
1932 # inserter.insertrange(Range(9-3, 12-3, rby5))
1933 inserter.insertrange(Range(9, 12, rby5))
1934 met6 = MetaNode(self.mkid("id"))
1935 # inserter.insertrange(Range(10-3, 11-3, met6))
1936 inserter.insertrange(Range(10, 11, met6))
1937 root = TreeNode()
1938 root.appendchild(met2.dup()
1939 .appendchild(TextNode("1"))
1940 .appendchild(rby1.dup().appendchild(TextNode("2"))))
1941 root.appendchild(met4.dup()
1942 .appendchild(rby1.dup().appendchild(TextNode("3"))))
1943 root.appendchild(met3.dup()
1944 .appendchild(rby1.dup().appendchild(TextNode("4")))
1945 .appendchild(TextNode("5")))
1946 root.appendchild(TextNode("6"))
1947 root.appendchild(rby5.dup()
1948 .appendchild(TextNode("7"))
1949 .appendchild(met6.dup()
1950 .appendchild(TextNode("8")))
1951 .appendchild(TextNode("9")))
1952 self.dotest(root, False)
1954 def test_range_meta_hyperlink(self):
1955 inserter = RangeInserter(self.__class__.xDoc)
1956 text = TextNode("123456789")
1957 inserter.insertrange(Range(0, 0, text))
1958 met1 = MetaNode(self.mkid("id"))
1959 inserter.insertrange(Range(1, 6, met1))
1960 ## overlap left
1961 url2 = HyperlinkNode(self.mkname("url"))
1962 # inserter.insertrange(Range(0, 4-1, url2))
1963 inserter.insertrange(Range(0, 4, url2))
1964 root = TreeNode()
1965 root.appendchild(url2.dup().appendchild(TextNode("1")))
1966 root.appendchild(met1.dup()
1967 .appendchild(url2.dup().appendchild(TextNode("23")))
1968 .appendchild(TextNode("456")))
1969 root.appendchild(TextNode("789"))
1970 self.dotest(root, False)
1971 ## overlap right
1972 url3 = HyperlinkNode(self.mkname("url"))
1973 # inserter.insertrange(Range(6-1, 8-1, url3))
1974 inserter.insertrange(Range(6, 8, url3))
1975 root = TreeNode()
1976 root.appendchild(url2.dup().appendchild(TextNode("1")))
1977 root.appendchild(met1.dup()
1978 .appendchild(url2.dup().appendchild(TextNode("23")))
1979 .appendchild(TextNode("45"))
1980 .appendchild(url3.dup().appendchild(TextNode("6"))))
1981 root.appendchild(url3.dup().appendchild(TextNode("7")))
1982 root.appendchild(TextNode("89"))
1983 self.dotest(root, False)
1984 ## around (not quite, due to API)
1985 url4 = HyperlinkNode(self.mkname("url"))
1986 # inserter.insertrange(Range(1, 9-1, url4))
1987 inserter.insertrange(Range(1, 9, url4))
1988 root = TreeNode()
1989 root.appendchild(url2.dup().appendchild(TextNode("1")))
1990 root.appendchild(met1.dup()
1991 .appendchild(url4.dup()
1992 .appendchild(TextNode("23456"))))
1993 root.appendchild(url4.dup().appendchild(TextNode("78")))
1994 root.appendchild(TextNode("9"))
1995 self.dotest(root, False)
1996 ## inside
1997 url5 = HyperlinkNode(self.mkname("url"))
1998 # inserter.insertrange(Range(4-1, 6-1, url5))
1999 inserter.insertrange(Range(4, 6, url5))
2000 root = TreeNode()
2001 root.appendchild(url2.dup().appendchild(TextNode("1")))
2002 root.appendchild(met1.dup()
2003 .appendchild(url4.dup()
2004 .appendchild(TextNode("23")))
2005 .appendchild(url5.dup()
2006 .appendchild(TextNode("45")))
2007 .appendchild(url4.dup()
2008 .appendchild(TextNode("6"))))
2009 root.appendchild(url4.dup().appendchild(TextNode("78")))
2010 root.appendchild(TextNode("9"))
2011 self.dotest(root, False)
2013 def test_range_meta_ruby(self):
2014 inserter = RangeInserter(self.__class__.xDoc)
2015 text = TextNode("123456789")
2016 inserter.insertrange(Range(0, 0, text))
2017 met1 = MetaNode(self.mkid("id"))
2018 inserter.insertrange(Range(1, 5, met1))
2019 ## overlap left
2020 rby2 = RubyNode(self.mkname("ruby"))
2021 # inserter.insertrange(Range(0, 3-1, rby2))
2022 inserter.insertrange(Range(0, 3, rby2))
2023 root = TreeNode()
2024 root.appendchild(rby2.dup().appendchild(TextNode("1")))
2025 root.appendchild(met1.dup()
2026 .appendchild(rby2.dup().appendchild(TextNode("2")))
2027 .appendchild(TextNode("345")))
2028 root.appendchild(TextNode("6789"))
2029 self.dotest(root, False)
2030 ## overlap right
2031 rby3 = RubyNode(self.mkname("ruby"))
2032 # inserter.insertrange(Range(5-1, 7-1, rby3))
2033 inserter.insertrange(Range(5, 7, rby3))
2034 root = TreeNode()
2035 root.appendchild(rby2.dup().appendchild(TextNode("1")))
2036 root.appendchild(met1.dup()
2037 .appendchild(rby2.dup().appendchild(TextNode("2")))
2038 .appendchild(TextNode("34"))
2039 .appendchild(rby3.dup().appendchild(TextNode("5"))))
2040 root.appendchild(rby3.dup().appendchild(TextNode("6")))
2041 root.appendchild(TextNode("789"))
2042 self.dotest(root, False)
2043 ## // around
2044 rby4 = RubyNode(self.mkname("ruby"))
2045 # inserter.insertrange(Range(1, 7-1, rby4))
2046 inserter.insertrange(Range(1, 7, rby4))
2047 root = TreeNode()
2048 root.appendchild(rby2.dup().appendchild(TextNode("1")))
2049 root.appendchild(rby4.dup()
2050 .appendchild(met1.dup()
2051 .appendchild(TextNode("2345")))
2052 .appendchild(TextNode("6")))
2053 root.appendchild(TextNode("789"))
2054 self.dotest(root, False)
2055 ## inside
2056 met5 = MetaNode(self.mkid("id"))
2057 # inserter.insertrange(Range(7-1, 9-1, met5))
2058 inserter.insertrange(Range(7, 9, met5))
2059 rby6 = RubyNode(self.mkname("ruby"))
2060 # inserter.insertrange(Range(9-2, 10/-2, rby6))
2061 inserter.insertrange(Range(9, 10, rby6))
2062 root = TreeNode()
2063 root.appendchild(rby2.dup().appendchild(TextNode("1")))
2064 root.appendchild(rby4.dup()
2065 .appendchild(met1.dup()
2066 .appendchild(TextNode("2345")))
2067 .appendchild(TextNode("6")))
2068 root.appendchild(met5.dup()
2069 .appendchild(TextNode("7"))
2070 .appendchild(rby6.dup()
2071 .appendchild(TextNode("8"))))
2072 root.appendchild(TextNode("9"))
2073 self.dotest(root, False)
2074 ## inside, with invalid range that includes the dummy char
2075 rby7 = RubyNode(self.mkname("ruby"))
2076 # inserter.insertrange(Range(7-1, 9-2, rby7))
2077 inserter.insertrange(Range(7, 9, rby7))
2078 root = TreeNode()
2079 root.appendchild(rby2.dup().appendchild(TextNode("1")))
2080 root.appendchild(rby4.dup()
2081 .appendchild(met1.dup()
2082 .appendchild(TextNode("2345")))
2083 .appendchild(TextNode("6")))
2084 root.appendchild(met5.dup()
2085 .appendchild(rby7.dup()
2086 .appendchild(TextNode("7")))
2087 .appendchild(rby6.dup()
2088 .appendchild(TextNode("8"))))
2089 root.appendchild(TextNode("9"))
2090 self.dotest(root, False)
2091 ## around, at same position as meta
2092 rby8 = RubyNode(self.mkname("ruby"))
2093 # inserter.insertrange(Range(7-1, 10-2, rby8))
2094 inserter.insertrange(Range(7, 10, rby8))
2095 root = TreeNode()
2096 root.appendchild(rby2.dup().appendchild(TextNode("1")))
2097 root.appendchild(rby4.dup()
2098 .appendchild(met1.dup()
2099 .appendchild(TextNode("2345")))
2100 .appendchild(TextNode("6")))
2101 root.appendchild(rby8.dup()
2102 .appendchild(met5.dup()
2103 .appendchild(TextNode("78"))))
2104 root.appendchild(TextNode("9"))
2105 self.dotest(root, False)
2107 def test_range_meta_meta(self):
2108 inserter = RangeInserter(self.__class__.xDoc)
2109 text = TextNode("123456789")
2110 inserter.insertrange(Range(0, 0, text))
2111 met1 = MetaNode(self.mkid("id"))
2112 inserter.insertrange(Range(3, 6, met1))
2113 ## overlap left
2114 met2 = MetaNode(self.mkid("id"))
2115 try:
2116 inserter.insertrange(Range(0, 4, met2))
2117 fail("testRangeMetaMeta: overlap left allowed")
2118 except IllegalArgumentException:
2119 pass
2120 root = TreeNode()
2121 root.appendchild(TextNode("123"))
2122 root.appendchild(met1.dup().appendchild(TextNode("456")))
2123 root.appendchild(TextNode("789"))
2124 self.dotest(root, False)
2125 ## overlap right
2126 met3 = MetaNode(self.mkid("id"))
2128 try:
2129 # inserter.insertrange(Range(5-1, 8-1, met3))
2130 inserter.insertrange(Range(5, 8, met3))
2131 self.fail("testRangeMetaMeta: overlap right allowed")
2132 except IllegalArgumentException:
2133 pass
2135 root = TreeNode()
2136 root.appendchild(TextNode("123"))
2137 root.appendchild(met1.dup().appendchild(TextNode("456")))
2138 root.appendchild(TextNode("789"))
2139 self.dotest(root, False)
2140 ## around
2141 met4 = MetaNode(self.mkid("id"))
2142 # inserter.insertrange(Range(3, 7-1, met4))
2143 inserter.insertrange(Range(3, 7, met4))
2144 root = TreeNode()
2145 root.appendchild(TextNode("123"))
2146 root.appendchild(met4.dup()
2147 .appendchild(met1.dup().appendchild(TextNode("456"))))
2148 root.appendchild(TextNode("789"))
2149 self.dotest(root, False)
2150 ## inside
2151 met5 = MetaNode(self.mkid("id"))
2152 # inserter.insertrange(Range(6-2, 8-2, met5))
2153 inserter.insertrange(Range(6, 8, met5))
2154 root = TreeNode()
2155 root.appendchild(TextNode("123"))
2156 root.appendchild(met4.dup()
2157 .appendchild(met1.dup()
2158 .appendchild(TextNode("4"))
2159 .appendchild(met5.dup()
2160 .appendchild(TextNode("56")))))
2161 root.appendchild(TextNode("789"))
2162 self.dotest(root, False)
2164 def test_range2(self):
2165 inserter = RangeInserter(self.__class__.xDoc)
2166 text = TextNode("123456789")
2167 inserter.insertrange(Range(0, 0, text))
2168 met1 = MetaNode(self.mkid("id"))
2169 inserter.insertrange(Range(1, 8, met1))
2170 met2 = MetaNode(self.mkid("id"))
2171 # inserter.insertrange(Range(3-1, 8-1, met2))
2172 inserter.insertrange(Range(3, 8, met2))
2173 met3 = MetaNode(self.mkid("id"))
2174 # inserter.insertrange(Range(5-2, 8-2, met3))
2175 inserter.insertrange(Range(5, 8, met3))
2176 root = TreeNode()
2177 root.appendchild(TextNode("1"))
2178 root.appendchild(met1.dup()
2179 .appendchild(TextNode("2"))
2180 .appendchild(met2.dup()
2181 .appendchild(TextNode("3"))
2182 .appendchild(met3.dup()
2183 .appendchild(TextNode("456")))
2184 .appendchild(TextNode("7")))
2185 .appendchild(TextNode("8")))
2186 root.appendchild(TextNode("9"))
2187 self.dotest(root, False)
2188 ## split ruby at every meta start!
2189 rby4 = RubyNode(self.mkname("ruby"))
2190 # inserter.insertrange(Range(0, 7-3, rby4))
2191 inserter.insertrange(Range(0, 7, rby4))
2192 root = TreeNode()
2193 root.appendchild(rby4.dup()
2194 .appendchild(TextNode("1")))
2195 root.appendchild(met1.dup()
2196 .appendchild(rby4.dup()
2197 .appendchild(TextNode("2")))
2198 .appendchild(met2.dup()
2199 .appendchild(rby4.dup()
2200 .appendchild(TextNode("3")))
2201 .appendchild(met3.dup()
2202 .appendchild(rby4.dup()
2203 .appendchild(TextNode("4")))
2204 .appendchild(TextNode("56")))
2205 .appendchild(TextNode("7")))
2206 .appendchild(TextNode("8")))
2207 root.appendchild(TextNode("9"))
2208 self.dotest(root, False)
2209 ## split ruby at every meta end!
2210 rby5 = RubyNode(self.mkname("ruby"))
2211 # inserter.insertrange(Range(8-3, 12-3, rby5))
2212 inserter.insertrange(Range(8, 12, rby5))
2213 root = TreeNode()
2214 root.appendchild(rby4.dup()
2215 .appendchild(TextNode("1")))
2216 root.appendchild(met1.dup()
2217 .appendchild(rby4.dup()
2218 .appendchild(TextNode("2")))
2219 .appendchild(met2.dup()
2220 .appendchild(rby4.dup()
2221 .appendchild(TextNode("3")))
2222 .appendchild(met3.dup()
2223 .appendchild(rby4.dup()
2224 .appendchild(TextNode("4")))
2225 .appendchild(TextNode("5"))
2226 .appendchild(rby5.dup()
2227 .appendchild(TextNode("6"))))
2228 .appendchild(rby5.dup()
2229 .appendchild(TextNode("7"))))
2230 .appendchild(rby5.dup()
2231 .appendchild(TextNode("8"))))
2232 root.appendchild(rby5.dup()
2233 .appendchild(TextNode("9")))
2234 self.dotest(root, False)
2236 def test_range3(self):
2237 inserter = RangeInserter(self.__class__.xDoc)
2238 text = TextNode("123456789")
2239 inserter.insertrange(Range(0, 0, text))
2240 rby1 = RubyNode(self.mkname("ruby"))
2241 inserter.insertrange(Range(0, 9, rby1))
2242 met2 = MetaNode(self.mkid("id"))
2243 inserter.insertrange(Range(2, 7, met2))
2244 root = TreeNode()
2245 root.appendchild(rby1.dup()
2246 .appendchild(TextNode("12"))
2247 .appendchild(met2.dup()
2248 .appendchild(TextNode("34567")))
2249 .appendchild(TextNode("89")))
2250 self.dotest(root, False)
2251 ## overwrite outer ruby, split remains at inner meta!
2252 rby3 = RubyNode(self.mkname("ruby"))
2253 # inserter.insertrange(Range(5-1, 6-1, rby3))
2254 inserter.insertrange(Range(5, 6, rby3))
2255 root = TreeNode()
2256 root.appendchild(rby1.dup()
2257 .appendchild(TextNode("12")))
2258 root.appendchild(met2.dup()
2259 .appendchild(rby1.dup()
2260 .appendchild(TextNode("34")))
2261 .appendchild(rby3.dup()
2262 .appendchild(TextNode("5")))
2263 .appendchild(rby1.dup()
2264 .appendchild(TextNode("67"))))
2265 root.appendchild(rby1.dup()
2266 .appendchild(TextNode("89")))
2267 self.dotest(root, False)
2269 def test_range4(self):
2270 inserter = RangeInserter(self.__class__.xDoc)
2271 text = TextNode("123456789")
2272 inserter.insertrange(Range(0, 0, text))
2273 rby1 = RubyNode(self.mkname("ruby"))
2274 inserter.insertrange(Range(0, 9, rby1))
2275 met2 = MetaNode(self.mkid("id"))
2276 inserter.insertrange(Range(1, 8, met2))
2277 met3 = MetaNode(self.mkid("id"))
2278 # inserter.insertrange(Range(3-1, 8-1, met3))
2279 inserter.insertrange(Range(3, 8, met3))
2280 met4 = MetaNode(self.mkid("id"))
2281 # inserter.insertrange(Range(5-2, 8-2, met4))
2282 inserter.insertrange(Range(5, 8, met4))
2283 root = TreeNode()
2284 root.appendchild(rby1.dup()
2285 .appendchild(TextNode("1"))
2286 .appendchild(met2.dup()
2287 .appendchild(TextNode("2"))
2288 .appendchild(met3.dup()
2289 .appendchild(TextNode("3"))
2290 .appendchild(met4.dup()
2291 .appendchild(TextNode("456")))
2292 .appendchild(TextNode("7")))
2293 .appendchild(TextNode("8")))
2294 .appendchild(TextNode("9")))
2295 self.dotest(root, False)
2296 ## overwrite outer ruby, split remains at every inner meta!
2297 rby5 = RubyNode(self.mkname("ruby"))
2298 # inserter.insertrange(Range(7-3, 8-3, rby5))
2299 inserter.insertrange(Range(7, 8, rby5))
2300 root = TreeNode()
2301 root.appendchild(rby1.dup()
2302 .appendchild(TextNode("1")))
2303 root.appendchild(met2.dup()
2304 .appendchild(rby1.dup()
2305 .appendchild(TextNode("2")))
2306 .appendchild(met3.dup()
2307 .appendchild(rby1.dup()
2308 .appendchild(TextNode("3")))
2309 .appendchild(met4.dup()
2310 .appendchild(rby1.dup()
2311 .appendchild(TextNode("4")))
2312 .appendchild(rby5.dup()
2313 .appendchild(TextNode("5")))
2314 .appendchild(rby1.dup()
2315 .appendchild(TextNode("6"))))
2316 .appendchild(rby1.dup()
2317 .appendchild(TextNode("7"))))
2318 .appendchild(rby1.dup()
2319 .appendchild(TextNode("8"))))
2320 root.appendchild(rby1.dup()
2321 .appendchild(TextNode("9")))
2322 self.dotest(root, False)
2324 def test_range5(self):
2325 inserter = RangeInserter(self.__class__.xDoc)
2326 text = TextNode("123456789")
2327 inserter.insertrange(Range(0, 0, text))
2328 rby1 = RubyNode(self.mkname("ruby"))
2329 inserter.insertrange(Range(0, 9, rby1))
2330 met2 = MetaNode(self.mkid("id"))
2331 inserter.insertrange(Range(1, 3, met2))
2332 met3 = MetaNode(self.mkid("id"))
2333 # inserter.insertrange(Range(5-1, 6-1, met3))
2334 inserter.insertrange(Range(5, 6, met3))
2335 met4 = MetaNode(self.mkid("id"))
2336 # inserter.insertrange(Range(8-2, 10-2, met4))
2337 inserter.insertrange(Range(8, 10, met4))
2338 root = TreeNode()
2339 root.appendchild(rby1.dup()
2340 .appendchild(TextNode("1"))
2341 .appendchild(met2.dup().appendchild(TextNode("23")))
2342 .appendchild(TextNode("4"))
2343 .appendchild(met3.dup().appendchild(TextNode("5")))
2344 .appendchild(TextNode("6"))
2345 .appendchild(met4.dup().appendchild(TextNode("78")))
2346 .appendchild(TextNode("9")))
2347 self.dotest(root, False)
2348 ## overwrite outer ruby, but split at inner metas!
2349 rby5 = RubyNode(self.mkname("ruby"))
2350 # inserter.insertrange(Range(3-1, 10-3, rby5))
2351 inserter.insertrange(Range(3, 10, rby5))
2352 root = TreeNode()
2353 root.appendchild(rby1.dup()
2354 .appendchild(TextNode("1")))
2355 root.appendchild(met2.dup()
2356 .appendchild(rby1.dup()
2357 .appendchild(TextNode("2")))
2358 .appendchild(rby5.dup()
2359 .appendchild(TextNode("3"))))
2360 root.appendchild(rby5.dup()
2361 .appendchild(TextNode("4"))
2362 .appendchild(met3.dup()
2363 .appendchild(TextNode("5")))
2364 .appendchild(TextNode("6")))
2365 root.appendchild(met4.dup()
2366 .appendchild(rby5.dup()
2367 .appendchild(TextNode("7")))
2368 .appendchild(rby1.dup()
2369 .appendchild(TextNode("8"))))
2370 root.appendchild(rby1.dup()
2371 .appendchild(TextNode("9")))
2372 self.dotest(root, False)
2374 def test_range6(self):
2375 inserter = RangeInserter(self.__class__.xDoc)
2376 text = TextNode("123456789")
2377 inserter.insertrange(Range(0, 0, text))
2378 met1 = MetaNode(self.mkid("id"))
2379 inserter.insertrange(Range(1, 5, met1))
2380 met2 = MetaNode(self.mkid("id"))
2381 # inserter.insertrange(Range(3-1, 6-1, met2))
2382 inserter.insertrange(Range(3, 6, met2))
2383 met3 = MetaNode(self.mkid("id"))
2384 # inserter.insertrange(Range(5-2, 7-2, met3))
2385 inserter.insertrange(Range(5, 7, met3))
2386 root = TreeNode()
2387 root.appendchild(TextNode("1"))
2388 root.appendchild(met1.dup()
2389 .appendchild(TextNode("2"))
2390 .appendchild(met2.dup()
2391 .appendchild(TextNode("3"))
2392 .appendchild(met3.dup()
2393 .appendchild(TextNode("45")))))
2394 root.appendchild(TextNode("6789"))
2395 self.dotest(root, False)
2396 ## split at 3 metas, all at same position
2397 rby4 = RubyNode(self.mkname("ruby"))
2398 # inserter.insertrange(Range(7-3, 10-3, rby4))
2399 inserter.insertrange(Range(7, 10, rby4))
2400 root = TreeNode()
2401 root.appendchild(TextNode("1"))
2402 root.appendchild(met1.dup()
2403 .appendchild(TextNode("2"))
2404 .appendchild(met2.dup()
2405 .appendchild(TextNode("3"))
2406 .appendchild(met3.dup()
2407 .appendchild(TextNode("4"))
2408 .appendchild(rby4.dup()
2409 .appendchild(TextNode("5"))))))
2410 root.appendchild(rby4.dup()
2411 .appendchild(TextNode("67")))
2412 root.appendchild(TextNode("89"))
2413 self.dotest(root, False)
2415 def test_range7(self):
2416 inserter = RangeInserter(self.__class__.xDoc)
2417 text = TextNode("123456789")
2418 inserter.insertrange(Range(0, 0, text))
2419 url1 = HyperlinkNode(self.mkname("url"))
2420 inserter.insertrange(Range(1, 5, url1))
2421 met2 = MetaNode(self.mkid("id"))
2422 inserter.insertrange(Range(3, 5, met2))
2423 root = TreeNode()
2424 root.appendchild(TextNode("1"))
2425 root.appendchild(url1.dup()
2426 .appendchild(TextNode("23")))
2427 root.appendchild(met2.dup()
2428 .appendchild(url1.dup()
2429 .appendchild(TextNode("45"))))
2430 root.appendchild(TextNode("6789"))
2431 self.dotest(root, False)
2432 ## this should result in not splitting the hyperlink, but due to API
2433 ## we can't tell :(
2434 rby3 = RubyNode(self.mkname("ruby"))
2435 # inserter.insertrange(Range(5-1, 8-1, rby3))
2436 inserter.insertrange(Range(5, 8, rby3))
2437 root = TreeNode()
2438 root.appendchild(TextNode("1"))
2439 root.appendchild(url1.dup()
2440 .appendchild(TextNode("23")))
2441 root.appendchild(met2.dup()
2442 .appendchild(url1.dup()
2443 .appendchild(TextNode("4")))
2444 .appendchild(rby3.dup()
2445 .appendchild(url1.dup()
2446 .appendchild(TextNode("5")))))
2447 root.appendchild(rby3.dup()
2448 .appendchild(TextNode("67")))
2449 root.appendchild(TextNode("89"))
2450 self.dotest(root, False)
2452 # TODO: test partial selection, test UNDO/REDO
2454 ##i109601# NestedTextContent and XChild
2455 def test_meta_xchild(self):
2456 xDoc = self.__class__.xDoc
2457 id1 = StringPair("content.xml", self.mkname("id"))
2458 id2 = StringPair("content.xml", self.mkname("id"))
2459 id3 = StringPair("content.xml", self.mkname("id"))
2460 id4 = StringPair("content.xml", self.mkname("id"))
2461 id5 = StringPair("content.xml", self.mkname("id"))
2462 id6 = StringPair("content.xml", self.mkname("id"))
2463 meta1 = MetaNode(id1)
2464 meta2 = MetaNode(id2)
2465 meta3 = MetaFieldNode(id3)
2466 meta4 = MetaNode(id4)
2467 meta5 = MetaNode(id5)
2468 meta6 = MetaFieldNode(id6)
2469 root = TreeNode()
2470 root.appendchild(meta1.dup()
2471 .appendchild(TextNode("1")))
2472 root.appendchild(TextNode("2"))
2473 root.appendchild(meta2.dup()
2474 .appendchild(meta3.dup()
2475 .appendchild(TextNode("34"))
2476 .appendchild(meta4.dup()
2477 .appendchild(TextNode("56")))
2478 .appendchild(meta5.dup())
2479 .appendchild(TextNode("7"))))
2480 root.appendchild(TextNode("8"))
2481 root.appendchild(meta6.dup()
2482 .appendchild(TextNode("9")))
2484 inserter = RangeInserter(xDoc)
2485 text = TextNode("123456789")
2486 inserter.insertrange(Range(0, 0, text))
2487 xMeta1 = inserter.insertrange(Range(0, 1, meta1))
2488 xMeta2 = inserter.insertrange(Range(3, 8, meta2))
2489 xMeta3 = inserter.insertrange(Range(4, 9, meta3))
2490 xMeta4 = inserter.insertrange(Range(7, 9, meta4))
2491 xMeta5 = inserter.insertrange(Range(10, 10, meta5))
2492 xMeta6 = inserter.insertrange(Range(13, 14, meta6))
2494 self.dotest(root, False)
2496 xDocText = xDoc.getText()
2497 xDocTextCursor = xDocText.createTextCursor()
2498 xDocTextCursor.gotoNextParagraph(False) # second paragraph
2499 # X12XX34X56X78X9
2500 # 1 23 4 5 6
2501 # 1 452 6
2503 nestedTextContent = (
2504 None,
2505 id1,
2506 id1,
2507 None,
2508 id2,
2509 id3,
2510 id3,
2511 id3,
2512 id4,
2513 id4,
2514 id4,
2515 id5,
2516 id3,
2517 None,
2518 id6,
2519 id6)
2520 for i, ntc in enumerate(nestedTextContent):
2521 oNTC = xDocTextCursor.NestedTextContent
2522 if ntc is None:
2523 self.assertIsNone(oNTC,
2524 "unexpected NestedTextContent at: {}".format(i))
2525 else:
2526 xmlid = oNTC.MetadataReference
2527 self.assertTrue(MetaNode.eq(ntc, xmlid),
2528 "wrong NestedTextContent at: {}".format(i))
2529 xDocTextCursor.goRight(1, False)
2531 try:
2532 xMeta1.setParent(xMeta4)
2533 fail("setParent(): allowed?")
2534 except NoSupportException:
2535 pass
2536 self.assertIsNone(xMeta1.getParent(), "getParent(): not None")
2537 self.assertIsNone(xMeta2.getParent(), "getParent(): not None")
2538 self.assertIsNone(xMeta6.getParent(), "getParent(): not None")
2540 xParent3 = xMeta3.getParent()
2541 self.assertIsNotNone(xParent3, "getParent(): None")
2542 xmlid = xParent3.MetadataReference
2543 self.assertTrue(MetaNode.eq(xmlid, id2), "getParent(): wrong")
2545 xParent4 = xMeta4.getParent()
2546 self.assertIsNotNone(xParent4, "getParent(): None")
2547 xmlid = xParent4.MetadataReference
2548 self. assertTrue(MetaNode.eq(xmlid, id3), "getParent(): wrong")
2550 xParent5 = xMeta5.getParent()
2551 self.assertIsNotNone(xParent5, "getParent(): None")
2552 xmlid = xParent5.MetadataReference
2553 self.assertTrue(MetaNode.eq(xmlid, id3), "getParent(): wrong")
2555 # test SwXMeta XText interface
2556 def test_meta_xtext(self):
2557 xDoc = self.__class__.xDoc
2558 inserter = RangeInserter(xDoc)
2559 text = TextNode("12AB6789")
2560 inserter.insertrange(Range(0, 0, text))
2561 meta = MetaNode(self.mkid("id"))
2562 xMeta = inserter.makemeta()
2564 xDocText = xDoc.getText()
2565 xDocTextCursor = xDocText.createTextCursor()
2566 xDocTextCursor.goRight(3, False)
2567 xDocTextCursor.goRight(2, True)
2568 xDocText.insertTextContent(xDocTextCursor, xMeta, True)
2570 xMeta.MetadataReference = meta.xmlid
2571 xParentText = xMeta.getText()
2572 self.assertIsNotNone(xParentText, "getText(): no parent")
2574 xStart = xMeta.getStart()
2575 self.assertIsNotNone(xStart, "getStart(): no start")
2577 xEnd = xMeta.getEnd()
2578 self.assertIsNotNone(xEnd, "getEnd(): no end")
2580 xMeta.setString("45")
2582 string = xMeta.getString()
2583 self.assertEqual("45", string, "getString(): invalid string returned")
2585 xTextCursor = xMeta.createTextCursor()
2586 self.assertIsNotNone(xTextCursor, "createTextCursor(): failed")
2588 try:
2589 xMeta.createTextCursorByRange(None)
2590 fail("createTextCursorByRange(): None allowed?")
2591 except RuntimeException:
2592 pass
2594 xTextCursorStart = xMeta.createTextCursorByRange(xStart)
2595 self.assertIsNotNone(xTextCursorStart,
2596 "createTextCursorByRange(): failed for start")
2598 xTextCursorEnd = xMeta.createTextCursorByRange(xEnd)
2599 self.assertIsNotNone(xTextCursorEnd,
2600 "createTextCursorByRange(): failed for end")
2602 ## move outside meta
2603 xDocTextCursor.gotoStart(False)
2605 try:
2606 xMeta.insertString(None, "foo", False)
2607 fail("insertString(): None allowed?")
2608 except RuntimeException:
2609 pass
2611 try:
2612 xMeta.insertString(xDocTextCursor, "foo", False)
2613 fail("insertString(): cursor outside allowed?")
2614 except RuntimeException:
2615 pass
2617 xStart = xMeta.getStart()
2618 xMeta.insertString(xStart, "A", False)
2619 string = xMeta.getString()
2620 self.assertEqual("A45", string, "getString(): invalid string returned")
2622 xMeta.insertString(xEnd, "B", False)
2623 string = xMeta.getString()
2624 self.assertEqual("A45B", string, "getString(): invalid string returned")
2626 try:
2627 xMeta.insertControlCharacter(None, HARD_HYPHEN, False)
2628 fail("insertControlCharacter(): None allowed?")
2629 except IllegalArgumentException:
2630 pass
2632 xStart = xMeta.getStart()
2633 try:
2634 xMeta.insertControlCharacter(xDocTextCursor, HARD_HYPHEN, False)
2635 fail("insertControlCharacter(): cursor outside allowed?")
2636 except IllegalArgumentException:
2637 pass
2639 xMeta.insertControlCharacter(xStart, HARD_HYPHEN, False)
2640 string = xMeta.getString()
2641 self.assertEqual('\u2011' + 'A45B', string,
2642 "getString(): invalid string returned")
2644 xMeta.insertControlCharacter(xEnd, HARD_HYPHEN, False)
2645 string = xMeta.getString()
2646 self.assertEqual('\u2011' + 'A45B' + '\u2011', string,
2647 "getString(): invalid string returned")
2649 xMeta.setString("45")
2650 try:
2651 xMeta.insertTextContent(None, xMeta, False)
2652 fail("insertTextContent(): None range allowed?")
2653 except IllegalArgumentException:
2654 pass
2656 try:
2657 xMeta.insertTextContent(xStart, None, False)
2658 fail("insertTextContent(): None content allowed?")
2659 except IllegalArgumentException:
2660 pass
2662 try:
2663 xMeta.insertTextContent(xDocTextCursor, xMeta, False)
2664 fail("insertTextContent(): cursor outside allowed?")
2665 except IllegalArgumentException:
2666 pass
2668 field1 = TextFieldNode("f1")
2669 field2 = TextFieldNode("f2")
2670 xField1 = inserter.maketextfield(field1.content)
2671 xField2 = inserter.maketextfield(field2.content)
2673 xStart = xMeta.getStart()
2674 xMeta.insertTextContent(xStart, xField1, False)
2676 root = TreeNode()
2677 root.appendchild(TextNode("12"))
2678 root.appendchild(meta.dup()
2679 .appendchild(field1.dup())
2680 .appendchild(TextNode("45")))
2681 root.appendchild(TextNode("6789"))
2682 self.dotest(root, False)
2684 xMeta.insertTextContent(xEnd, xField2, False)
2686 root = TreeNode()
2687 root.appendchild(TextNode("12"))
2688 root.appendchild(meta.dup()
2689 .appendchild(field1.dup())
2690 .appendchild(TextNode("45"))
2691 .appendchild(field2.dup()))
2692 root.appendchild(TextNode("6789"))
2693 self.dotest(root, False)
2695 try:
2696 xMeta.removeTextContent(None)
2697 fail("removeTextContent(): None content allowed?")
2698 except RuntimeException:
2699 pass
2701 xMeta.removeTextContent(xField1)
2703 xAnchor = xMeta.getAnchor()
2704 self.assertIsNotNone(xAnchor, "getAnchor(): None")
2706 ## evil test case: insert ruby around meta
2707 ruby = RubyNode(self.mkname("ruby"))
2708 inserter.insertrange(Range(2, 6, ruby))
2710 ## prevent caching...
2711 # root = TreeNode()
2712 # root.appendchild(TextNode("12"))
2713 # root.appendchild(ruby.dup()
2714 # .appendchild(meta.dup()
2715 # .appendchild(TextNode("45"))
2716 # .appendchild(field2.dup())))
2717 # root.appendchild(TextNode("6789"))
2718 # self.dotest(root, False)
2720 xEnum = xMeta.createEnumeration()
2721 self.assertIsNotNone("createEnumeration(): returns None", xEnum)
2723 self.assertTrue(xEnum.hasMoreElements(),"hasNext(): first missing")
2724 xPortion = xEnum.nextElement()
2725 type_ = xPortion.TextPortionType
2726 self.assertEqual("Text", type_, "first: not text")
2727 txt = xPortion.getString()
2728 self.assertEqual("45", txt, "first: text differs")
2730 self.assertTrue(xEnum.hasMoreElements(),"hasNext(): second missing")
2731 xPortion = xEnum.nextElement()
2732 type_ = xPortion.TextPortionType
2733 self.assertEqual("TextField", type_, "second: not text")
2735 ## no ruby end here!!!
2736 self.assertFalse(xEnum.hasMoreElements(), "hasNext(): more elements?")
2738 xMeta.dispose()
2740 try:
2741 xCursor = xMeta.createTextCursor()
2742 self.assertIsNone(xCursor,
2743 "createTextCursor(): succeeds on disposed object?")
2744 except RuntimeException:
2745 pass
2747 # check that cursor move methods move to positions in the meta,
2748 # but do not move to positions outside the meta.
2749 def test_meta_xtextcursor(self):
2750 xDoc = self.__class__.xDoc
2751 inserter = RangeInserter(xDoc)
2752 text = TextNode("Text. 12 More text here.")
2753 inserter.insertrange(Range(0, 0, text))
2754 met1 = MetaNode(self.mkid("id"))
2755 xMeta = inserter.makemeta()
2757 xDocText = xDoc.getText()
2758 xDocTextCursor = xDocText.createTextCursor()
2759 xDocTextCursor.goRight(7, False)
2760 xDocTextCursor.goRight(2, True)
2761 xDocText.insertTextContent(xDocTextCursor, xMeta, True)
2762 xDocTextCursor.gotoStart(True)
2764 xMeta.MetadataReference = met1.xmlid
2765 xStart = xMeta.getStart()
2766 self.assertIsNotNone(xStart, "getStart(): no start")
2767 xEnd = xMeta.getEnd()
2768 self.assertIsNotNone(xEnd, "getEnd(): no end")
2770 ## XTextCursor
2771 xMetaCursor = xMeta.createTextCursor()
2772 self.assertIsNotNone(xMetaCursor, "createTextCursor(): no cursor")
2773 bSuccess = False
2774 xMetaCursor.gotoStart(False)
2775 xMetaCursor.gotoEnd(False)
2776 bSuccess = xMetaCursor.goLeft(1, False)
2777 self.assertTrue(bSuccess, "goLeft(): failed")
2778 bSuccess = xMetaCursor.goLeft(1000, False)
2779 self.assertFalse(bSuccess, "goLeft(): succeeded")
2780 bSuccess = xMetaCursor.goRight(1, False)
2781 self.assertTrue(bSuccess, "goRight(): failed")
2782 bSuccess = xMetaCursor.goRight(1000, False)
2783 self.assertFalse(bSuccess, "goRight(): succeeded")
2784 xMetaCursor.gotoRange(xStart, False)
2785 xMetaCursor.gotoRange(xEnd, False)
2786 try:
2787 xMetaCursor.gotoRange(xDocTextCursor, False)
2788 fail("gotoRange(): succeeded")
2789 except RuntimeException:
2790 pass
2792 ## XWordCursor
2793 xMeta.setString("Two words")
2794 xMetaCursor.gotoStart(False)
2796 bSuccess = xMetaCursor.gotoNextWord(True) # at start of "words"
2797 self.assertTrue(bSuccess, "gotoNextWord(): failed")
2799 string = xMetaCursor.getString()
2800 self.assertEqual("Two ", string, "gotoNextWord(): wrong string")
2802 bSuccess = xMetaCursor.gotoNextWord(False) # at end of "words", cannot leave metafield
2803 self.assertFalse(bSuccess,"gotoNextWord(): succeeded")
2804 xMetaCursor.collapseToEnd()
2805 bSuccess = xMetaCursor.gotoPreviousWord(True) # at start of "words"
2806 self.assertTrue(bSuccess, "gotoPreviousWord(): failed")
2808 string = xMetaCursor.getString()
2809 self.assertEqual("words", string, "gotoPreviousWord(): wrong string")
2811 bSuccess = xMetaCursor.gotoPreviousWord(False) # at start of "Two"
2812 self.assertTrue(bSuccess, "gotoPreviousWord(): failed")
2814 bSuccess = xMetaCursor.gotoPreviousWord(False) # cannot leave metafield
2815 self.assertFalse(bSuccess, "gotoPreviousWord(): succeeded")
2817 bSuccess = xMetaCursor.gotoEndOfWord(True) # at end of "Two"
2818 self.assertTrue(bSuccess, "gotoEndOfWord(): failed")
2820 string = xMetaCursor.getString()
2821 self.assertEqual("Two", string, "gotoEndOfWord(): wrong string")
2823 xMetaCursor.gotoEnd(False)
2824 bSuccess = xMetaCursor.gotoStartOfWord(True)
2825 self.assertTrue(bSuccess, "gotoStartOfWord(): failed")
2827 string = xMetaCursor.getString()
2828 self.assertEqual("words", string, "gotoStartOfWord(): wrong string")
2830 xMeta.setString("")
2831 bSuccess = xMetaCursor.gotoEndOfWord(False)
2832 self.assertFalse(bSuccess, "gotoEndOfWord(): succeeded")
2833 bSuccess = xMetaCursor.gotoStartOfWord(False)
2834 self.assertFalse(bSuccess, "gotoStartOfWord(): succeeded")
2836 ## XSentenceCursor
2837 xMeta.setString("This is a sentence. Another sentence.")
2838 xMetaCursor.gotoStart(False)
2840 bSuccess = xMetaCursor.gotoNextSentence(True)
2841 self.assertTrue(bSuccess,"gotoNextSentence(): failed")
2843 string = xMetaCursor.getString()
2844 self.assertEqual("This is a sentence. ", string,
2845 "gotoNextSentence(): wrong string")
2847 bSuccess = xMetaCursor.gotoNextSentence(False)
2848 self.assertFalse(bSuccess, "gotoNextSentence(): succeeded")
2849 ## FIXME:
2850 ## the sentence cursor seems to work differently than the word cursor
2851 xMeta.setString("This is a sentence. Another sentence. Sentence 3.")
2852 xMetaCursor.gotoEnd(False)
2853 bSuccess = xMetaCursor.gotoPreviousSentence(True)
2854 self.assertTrue(bSuccess, "gotoPreviousSentence(): failed")
2856 string = xMetaCursor.getString()
2857 self.assertEqual("Another sentence. Sentence 3.", string,
2858 "gotoPreviousSentence(): wrong string")
2860 bSuccess = xMetaCursor.gotoPreviousSentence(False)
2861 self.assertFalse(bSuccess, "gotoPreviousSentence(): succeeded")
2862 bSuccess = xMetaCursor.gotoEndOfSentence(True)
2863 self.assertTrue(bSuccess, "gotoEndOfSentence(): failed")
2865 string = xMetaCursor.getString()
2866 self.assertEqual("This is a sentence.", string,
2867 "gotoEndOfSentence(): wrong string")
2869 xMetaCursor.gotoEnd(False)
2870 bSuccess = xMetaCursor.gotoStartOfSentence(True)
2871 self.assertTrue(bSuccess,"gotoStartOfSentence(): failed")
2873 string = xMetaCursor.getString()
2874 self.assertEqual("Sentence 3.", string,
2875 "gotoStartOfSentence(): wrong string")
2877 xMeta.setString("")
2878 bSuccess = xMetaCursor.gotoEndOfSentence(False)
2879 self.assertFalse(bSuccess, "gotoEndOfSentence(): succeeded")
2880 bSuccess = xMetaCursor.gotoStartOfSentence(False)
2881 self.assertFalse(bSuccess, "gotoStartOfSentence(): succeeded")
2883 ## XParagraphCursor (does not make sense)
2884 bSuccess = xMetaCursor.gotoNextParagraph(False)
2885 self.assertFalse(bSuccess, "gotoNextParagraph(): succeeded")
2886 bSuccess = xMetaCursor.gotoPreviousParagraph(False)
2887 self.assertFalse(bSuccess, "gotoPreviousParagraph(): succeeded")
2888 bSuccess = xMetaCursor.gotoStartOfParagraph(False)
2889 self.assertFalse(bSuccess, "gotoStartOfParagraph(): succeeded")
2890 bSuccess = xMetaCursor.gotoEndOfParagraph(False)
2891 self.assertFalse(bSuccess, "gotoEndOfParagraph(): succeeded")
2893 # See https://bugs.libreoffice.org/show_bug.cgi?id=49629
2894 # ensure that gotoEndOfWord does not fail when footnote is at word end
2895 def test_xtextcursor(self):
2896 xDoc = self.__class__.xDoc
2897 inserter = RangeInserter(xDoc)
2898 xDocText = xDoc.getText()
2899 xDocTextCursor = xDocText.createTextCursor()
2900 xDocTextCursor.gotoNextParagraph(False)
2901 inserter.inserttext(xDocTextCursor, "Text")
2902 xDocTextCursor.gotoEndOfWord(False)
2903 inserter.insertfootnote(xDocTextCursor, "footnote")
2904 xDocTextCursor.gotoStartOfParagraph(False)
2905 bSuccess = xDocTextCursor.gotoEndOfWord(True)
2906 self.assertTrue(bSuccess, "gotoEndOfWord(): failed")
2907 string = xDocTextCursor.getString()
2908 self.assertEqual("Text", string, "gotoEndOfWord(): wrong string")
2909 self.assertNotEqual("a","b")
2911 class AttachHelper():
2912 def isattribute(self): pass
2913 def mktreenode(self): pass
2914 def mktextcontent(self, inserter, node): pass
2915 def postinserted(self, node, xContent): pass
2917 def test_meta_xtextattach_toxmark(self):
2918 class Helper(self.AttachHelper):
2919 def isattribute(_):
2920 return True
2921 def mktreenode(_):
2922 return DocumentIndexMarkNode(self.mkname("toxmark"))
2923 def mktextcontent(_, inserter, node):
2924 return inserter.makedocumentindexmark(node.name)
2925 self.do_meta_xtextattach(Helper())
2927 def test_meta_xtextattach_refmark(self):
2928 class Helper(self.AttachHelper):
2929 def isattribute(_):
2930 return True
2931 def mktreenode(_):
2932 return ReferenceMarkNode(self.mkname("refmark"))
2933 def mktextcontent(_, inserter, node):
2934 return inserter.makereferencemark(node.name)
2935 self.do_meta_xtextattach(Helper())
2937 def test_meta_xtextattach_textfield(self):
2938 class Helper(self.AttachHelper):
2939 def isattribute(_):
2940 return False
2941 def mktreenode(_):
2942 return TextFieldNode(self.mkname("field"))
2943 def mktextcontent(_, inserter, node):
2944 return inserter.maketextfield(node.content)
2945 self.do_meta_xtextattach(Helper())
2947 def test_meta_xtextattach_footnote(self):
2948 class Helper(self.AttachHelper):
2949 def isattribute(_):
2950 return False
2951 def mktreenode(_):
2952 return FootnoteNode(self.mkname("ftn"))
2953 def mktextcontent(_, inserter, node):
2954 return inserter.makefootnote(node.label)
2955 self.do_meta_xtextattach(Helper())
2957 def test_meta_xtextattach_meta(self):
2958 class Helper(self.AttachHelper):
2959 def isattribute(_):
2960 return True
2961 def mktreenode(_):
2962 return MetaNode(self.mkid("id"))
2963 def mktextcontent(_, inserter, node):
2964 return inserter.makemeta()
2965 def postinserted(_, node, xContent):
2966 xContent.MetadataReference = node.xmlid
2967 self.do_meta_xtextattach(Helper())
2969 def do_meta_xtextattach(self, helper):
2970 xDoc = self.__class__.xDoc
2971 inserter = RangeInserter(xDoc)
2972 text = TextNode("12AB6789")
2973 inserter.insertrange(Range(0, 0, text))
2974 met1 = MetaNode(self.mkid("id"))
2975 xMeta = inserter.makemeta()
2977 xDocText = xDoc.getText()
2978 xDocTextCursor = xDocText.createTextCursor()
2979 xDocTextCursor.goRight(3, False)
2980 xDocTextCursor.goRight(2, True)
2981 xDocText.insertTextContent(xDocTextCursor, xMeta, True)
2983 xMeta.MetadataReference = met1.xmlid
2984 xStart = None
2985 xEnd = None
2987 xStart = xMeta.getStart()
2988 xEnd = xMeta.getEnd()
2990 nod1 = helper.mktreenode()
2991 nod2 = helper.mktreenode()
2992 xContent1 = helper.mktextcontent(inserter, nod1)
2993 xContent2 = helper.mktextcontent(inserter, nod2)
2995 ## insertTextContent with meta getStart()/getEnd()
2996 xMeta.insertTextContent(xStart, xContent1, False)
2997 xMeta.insertTextContent(xEnd, xContent2, False)
2999 helper.postinserted(nod1, xContent1)
3000 helper.postinserted(nod2, xContent2)
3002 root = TreeNode()
3003 root.appendchild(TextNode("12"))
3004 root.appendchild(met1.dup()
3005 .appendchild(nod1.dup())
3006 .appendchild(TextNode("AB"))
3007 .appendchild(nod2.dup()))
3008 root.appendchild(TextNode("6789"))
3009 self.dotest(root, False)
3011 xMeta.setString("AB")
3012 xStart = xMeta.getStart()
3013 xEnd = xMeta.getEnd()
3015 nod1 = helper.mktreenode()
3016 nod2 = helper.mktreenode()
3017 xContent1 = helper.mktextcontent(inserter, nod1)
3018 xContent2 = helper.mktextcontent(inserter, nod2)
3020 xTextCursor = xMeta.createTextCursor()
3021 xTextCursor.gotoStart(False)
3023 ## insertTextContent with meta cursor
3024 xMeta.insertTextContent(xTextCursor, xContent1, False)
3025 xTextCursor.gotoEnd(False)
3026 xMeta.insertTextContent(xTextCursor, xContent2, False)
3028 helper.postinserted(nod1, xContent1)
3029 helper.postinserted(nod2, xContent2)
3031 root = TreeNode()
3032 root.appendchild(TextNode("12"))
3033 root.appendchild(met1.dup()
3034 .appendchild(nod1.dup())
3035 .appendchild(TextNode("AB"))
3036 .appendchild(nod2.dup()))
3037 root.appendchild(TextNode("6789"))
3038 self.dotest(root, False)
3040 if not helper.isattribute():
3041 # xMeta.setString("AB")
3042 xStart = xMeta.getStart()
3043 xEnd = xMeta.getEnd()
3045 nod1 = helper.mktreenode()
3046 nod2 = helper.mktreenode()
3047 xContent1 = helper.mktextcontent(inserter, nod1)
3048 xContent2 = helper.mktextcontent(inserter, nod2)
3050 xTextCursor = xMeta.createTextCursor()
3051 xTextCursor.gotoStart(False)
3052 xTextCursor.goRight(1, True)
3054 ## insertTextContent with meta cursor and absorb
3055 xMeta.insertTextContent(xTextCursor, xContent1, True)
3056 xTextCursor.gotoEnd(False)
3057 xTextCursor.goLeft(1, True)
3058 xMeta.insertTextContent(xTextCursor, xContent2, True)
3060 helper.postinserted(nod1, xContent1)
3061 helper.postinserted(nod2, xContent2)
3063 root = TreeNode()
3064 root.appendchild(TextNode("12"))
3065 root.appendchild(met1.dup()
3066 .appendchild(nod1.dup())
3067 .appendchild(TextNode("AB"))
3068 .appendchild(nod2.dup()))
3069 root.appendchild(TextNode("6789"))
3070 self.dotest(root, False)
3072 xMeta.setString("AB")
3073 xStart = xMeta.getStart()
3074 xEnd = xMeta.getEnd()
3076 nod1 = helper.mktreenode()
3077 nod2 = helper.mktreenode()
3078 xContent1 = helper.mktextcontent(inserter, nod1)
3079 xContent2 = helper.mktextcontent(inserter, nod2)
3081 xDocTextCursor.gotoRange(xStart, False)
3083 ## insertTextContent with document cursor
3084 xMeta.insertTextContent(xDocTextCursor, xContent1, False)
3085 xDocTextCursor.gotoRange(xEnd, False)
3086 xMeta.insertTextContent(xDocTextCursor, xContent2, False)
3088 helper.postinserted(nod1, xContent1)
3089 helper.postinserted(nod2, xContent2)
3091 root = TreeNode()
3092 root.appendchild(TextNode("12"))
3093 root.appendchild(met1.dup()
3094 .appendchild(nod1.dup())
3095 .appendchild(TextNode("AB"))
3096 .appendchild(nod2.dup()))
3097 root.appendchild(TextNode("6789"))
3098 self.dotest(root, False)
3100 if not helper.isattribute():
3101 xStart = xMeta.getStart()
3102 xEnd = xMeta.getEnd()
3104 nod1 = helper.mktreenode()
3105 nod2 = helper.mktreenode()
3106 xContent1 = helper.mktextcontent(inserter, nod1)
3107 xContent2 = helper.mktextcontent(inserter, nod2)
3109 xDocTextCursor.gotoRange(xStart, False)
3110 xDocTextCursor.goRight(1, True)
3112 ## insertTextContent with document cursor and absorb
3113 xMeta.insertTextContent(xDocTextCursor, xContent1, True)
3114 xDocTextCursor.gotoRange(xEnd, False)
3115 xDocTextCursor.goLeft(1, True)
3116 xMeta.insertTextContent(xDocTextCursor, xContent2, True)
3118 helper.postinserted(nod1, xContent1)
3119 helper.postinserted(nod2, xContent2)
3121 root = TreeNode()
3122 root.appendchild(TextNode("12"))
3123 root.appendchild(met1.dup()
3124 .appendchild(nod1.dup())
3125 .appendchild(TextNode("AB"))
3126 .appendchild(nod2.dup()))
3127 root.appendchild(TextNode("6789"))
3128 self.dotest(root, False)
3130 xMeta.setString("AB")
3131 xStart = xMeta.getStart()
3132 xEnd = xMeta.getEnd()
3134 nod1 = helper.mktreenode()
3135 nod2 = helper.mktreenode()
3136 xContent1 = helper.mktextcontent(inserter, nod1)
3137 xContent2 = helper.mktextcontent(inserter, nod2)
3139 ## attach to range from meta getStart()/getEnd()
3140 xContent1.attach(xStart)
3141 xContent2.attach(xEnd)
3143 helper.postinserted(nod1, xContent1)
3144 helper.postinserted(nod2, xContent2)
3146 root = TreeNode()
3147 root.appendchild(TextNode("12"))
3148 root.appendchild(met1.dup()
3149 .appendchild(nod1.dup())
3150 .appendchild(TextNode("AB"))
3151 .appendchild(nod2.dup()))
3152 root.appendchild(TextNode("6789"))
3153 self.dotest(root, False)
3155 xMeta.setString("AB")
3156 xStart = xMeta.getStart()
3157 xEnd = xMeta.getEnd()
3159 nod1 = helper.mktreenode()
3160 nod2 = helper.mktreenode()
3161 xContent1 = helper.mktextcontent(inserter, nod1)
3162 xContent2 = helper.mktextcontent(inserter, nod2)
3164 xTextCursor = xMeta.createTextCursor()
3165 xTextCursor.gotoStart(False)
3167 ## attach to cursor from meta XText
3168 xContent1.attach(xTextCursor)
3169 xTextCursor.gotoEnd(False)
3170 xContent2.attach(xTextCursor)
3172 helper.postinserted(nod1, xContent1)
3173 helper.postinserted(nod2, xContent2)
3175 root = TreeNode()
3176 root.appendchild(TextNode("12"))
3177 root.appendchild(met1.dup()
3178 .appendchild(nod1.dup())
3179 .appendchild(TextNode("AB"))
3180 .appendchild(nod2.dup()))
3181 root.appendchild(TextNode("6789"))
3182 self.dotest(root, False)
3184 def test_metafield_xtextfield(self):
3185 xDoc = self.__class__.xDoc
3186 smgr = self.__class__._uno.xContext.ServiceManager
3187 xRepo = xDoc.getRDFRepository()
3188 ## for testing just add it to the first graph
3189 Graphs = xRepo.getGraphNames()
3190 xGraph = xRepo.getGraph(Graphs[0])
3191 xOdfPrefix = smgr.createInstance("com.sun.star.rdf.URI")
3192 xOdfPrefix.initialize((ODF_PREFIX,))
3193 xOdfSuffix = smgr.createInstance("com.sun.star.rdf.URI")
3194 xOdfSuffix.initialize((ODF_SUFFIX,))
3196 xPrefix = smgr.createInstance("com.sun.star.rdf.Literal")
3197 xPrefix.initialize(("foo",))
3198 xSuffix = smgr.createInstance("com.sun.star.rdf.Literal")
3199 xSuffix.initialize(("bar",))
3201 inserter = RangeInserter(xDoc)
3202 text = TextNode("abc")
3203 inserter.insertrange(Range(0, 0, text))
3204 xDocText = xDoc.getText()
3205 xDocTextCursor = xDocText.createTextCursor()
3206 xDocTextCursor.goRight(1, False)
3207 xDocTextCursor.goRight(3, True)
3209 xMetaField = inserter.makemetafield()
3211 xDocText.insertTextContent(xDocTextCursor, xMetaField, True)
3213 xMetaField.ensureMetadataReference
3215 xGraph.addStatement(xMetaField, xOdfPrefix, xPrefix)
3216 xGraph.addStatement(xMetaField, xOdfSuffix, xSuffix)
3217 self.assertEqual("fooabcbar", xMetaField.getPresentation(False),
3218 "getPresentation(): wrong")
3219 inserter.insertrange(Range(0, 0, text))
3221 def test_metafield_xpropertyset(self):
3222 xDoc = self.__class__.xDoc
3223 inserter = RangeInserter(xDoc)
3224 text = TextNode("123")
3225 inserter.insertrange(Range(0, 0, text))
3226 xDocText = xDoc.getText()
3227 xDocTextCursor = xDocText.createTextCursor()
3228 xDocTextCursor.goRight(1, False)
3229 xDocTextCursor.goRight(3, True)
3231 xMetaField = inserter.makemetafield()
3233 xDocText.insertTextContent(xDocTextCursor, xMetaField, True)
3235 self.assertIsNotNone(xMetaField, "PropertySet: not supported?")
3236 xPropertySetInfo = xMetaField.getPropertySetInfo()
3237 self.assertTrue(xPropertySetInfo.hasPropertyByName("NumberFormat"),
3238 'hasPropertyByName("NumberFormat"):')
3239 self.assertTrue(xPropertySetInfo.hasPropertyByName("IsFixedLanguage"),
3240 'hasPropertyByName("IsFixedLanguage"):')
3242 def_ = xMetaField.NumberFormat
3243 print("NumberFormat: default is {}".format(def_))
3244 xMetaField.NumberFormat = NUMBER_INT
3245 xMetaField.IsFixedLanguage = True
3246 format = xMetaField.NumberFormat
3247 self.assertEqual(NUMBER_INT, format, "NumberFormat: failed")
3248 isfixed = xMetaField.IsFixedLanguage
3249 self.assertTrue(isfixed, "IsFixedLanguage: failed")
3251 def dostore(self, xComp, file):
3252 print("Storing test document...")
3253 file = uno.systemPathToFileUrl(file)
3254 xComp.storeToURL(file, ())
3255 print("...done")
3257 def doload(self, file):
3258 xComp = None
3259 print("Loading test document...")
3260 xComp = self.__class__._uno.openDocFromAbsolutePath(file)
3261 self.assertIsNotNone(xComp, "cannot load: {}".format(file))
3262 print("...done")
3263 return xComp
3265 def close(self, i_comp):
3266 try:
3267 if i_comp:
3268 i_comp.close(True)
3269 except Exception as e:
3270 pass
3272 def test_load_store(self):
3273 xComp = None
3274 filename = "TESTMETA.odt"
3275 try:
3276 xComp = self.__class__._uno.openDocFromTDOC(filename)
3277 if xComp:
3278 self.checkloadmeta(xComp)
3279 with TemporaryDirectory() as tempdir:
3280 if os.altsep: # we need URL so replace "\" with "/"
3281 tempdir = tempdir.replace(os.sep, os.altsep)
3282 file = tempdir + "/" + filename
3283 self.dostore(xComp, file)
3284 self.close(xComp)
3285 xComp2 = None
3286 try:
3287 xComp2 = self.doload(file)
3288 self.checkloadmeta(xComp2)
3289 finally:
3290 self.close(xComp2)
3291 finally:
3292 self.close(xComp)
3294 def checkloadmeta(self, xTextDoc):
3295 xText = xTextDoc.getText()
3296 print("Checking meta(-field)s in loaded test document...")
3297 root = TreeNode()
3298 root.appendchild(RubyNode("ruby1")
3299 .appendchild(TextNode("1")))
3300 root.appendchild(MetaNode(self.mkid_("id1"))
3301 .appendchild(TextNode("2")))
3302 root.appendchild(MetaFieldNode(self.mkid_("id2"))
3303 .appendchild(TextNode("3")))
3304 root.appendchild(RubyNode("ruby2")
3305 .appendchild(MetaNode(self.mkid_("id3"))
3306 .appendchild(TextNode("4"))))
3307 root.appendchild(RubyNode("ruby3")
3308 .appendchild(MetaFieldNode(self.mkid_("id4"))
3309 .appendchild(TextNode("5"))))
3310 root.appendchild(MetaNode(self.mkid_("id5"))
3311 .appendchild(RubyNode("ruby4")
3312 .appendchild(TextNode("6"))))
3313 root.appendchild(MetaFieldNode(self.mkid_("id6"))
3314 .appendchild(RubyNode("ruby5")
3315 .appendchild(TextNode("7"))))
3316 root.appendchild(MetaNode(self.mkid_("id7"))
3317 .appendchild(MetaNode(self.mkid_("id8"))
3318 .appendchild(TextNode("8"))))
3319 root.appendchild(MetaNode(self.mkid_("id9"))
3320 .appendchild(MetaFieldNode(self.mkid_("id10"))
3321 .appendchild(TextNode("9"))))
3322 root.appendchild(MetaFieldNode(self.mkid_("id11"))
3323 .appendchild(MetaNode(self.mkid_("id12"))
3324 .appendchild(TextNode("10"))))
3325 root.appendchild(MetaFieldNode(self.mkid_("id13"))
3326 .appendchild(MetaFieldNode(self.mkid_("id14"))
3327 .appendchild(TextNode("11"))))
3328 root.appendchild(MetaNode(self.mkid_("id15"))
3329 .appendchild(RubyNode("ruby6")
3330 .appendchild(MetaFieldNode(self.mkid_("id16"))
3331 .appendchild(TextNode("12")))))
3333 class MetaNode_(MetaNode):
3334 def __init__(self, id):
3335 super().__init__(id)
3336 def __eq__(self, other):
3337 return isinstance(other, MetaNode)
3338 root.appendchild(MetaNode_(self.mkid_(""))
3339 .appendchild(TextNode("13")))
3340 root.appendchild(TextNode(" X X "))
3341 self._dotest(xTextDoc, root, False)
3342 print("...done")
3344 def test_load_store_xmlid(self):
3345 xComp = None
3346 filename = "TESTXMLID.odt"
3347 try:
3348 xComp = self.__class__._uno.openDocFromTDOC(filename)
3349 if xComp:
3350 self.checkloadxmlid(xComp)
3351 with TemporaryDirectory() as tempdir:
3352 if os.altsep: # we need URL so replace "\" with "/"
3353 tempdir = tempdir.replace(os.sep, os.altsep)
3354 file = 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 xText = xTextDoc.getText()
3368 xRepo = xTextDoc.getRDFRepository()
3370 print("Checking bookmarks in loaded test document...")
3371 xBookmarks = xTextDoc.getBookmarks()
3372 xMark1 = xBookmarks["mk1"]
3373 self.assertTrue(self.eq(xMark1.MetadataReference,
3374 StringPair("content.xml", "id90")), "mark1")
3375 xMark2 = xBookmarks["mk2"]
3376 result = xRepo.getStatementRDFa(xMark2)
3377 self.assertTrue(len(result.First) == 1 and
3378 result.First[0].Subject.StringValue == "uri:foo" and
3379 result.First[0].Predicate.StringValue == "uri:bar" and
3380 result.First[0].Object.Value == "a fooish bar",
3381 "mark2")
3382 xMark3 = xBookmarks["mk3"]
3383 self.assertTrue(self.eq(xMark3.MetadataReference,
3384 StringPair("content.xml", "id91")), "mark3")
3385 print("...done")
3387 print("Checking sections in loaded test document...")
3388 xSections = xTextDoc.getTextSections()
3389 xSection1 = xSections["Section 1"]
3390 self.assertTrue(self.eq(xSection1.MetadataReference,
3391 StringPair("content.xml", "idSection1")), "idsection1")
3392 xSection2 = xSections["Section 2"]
3393 self.assertTrue(self.eq(xSection2.MetadataReference,
3394 StringPair("content.xml", "idSection2")),"idSection2")
3395 xSection3 = xSections["Table of Contents1_Head"]
3396 self.assertTrue(self.eq(xSection3.MetadataReference,
3397 StringPair("content.xml", "idTOCTitle")), "idTOCTitle")
3398 xSection4 = xSections["Alphabetical Index1_Head"]
3399 self.assertTrue(self.eq(xSection4.MetadataReference,
3400 StringPair("content.xml", "idAITitle")), "idAITitle")
3401 xSection5 = xSections["Illustration Index1_Head"]
3402 self.assertTrue(self.eq(xSection5.MetadataReference,
3403 StringPair("content.xml", "idIITitle")), "idIITitle")
3404 xSection6 = xSections["Index of Tables1_Head"]
3405 self.assertTrue(self.eq(xSection6.MetadataReference,
3406 StringPair("content.xml", "idIOTTitle")), "idIOTTitle")
3407 xSection7 = xSections["User-Defined1_Head"]
3408 self.assertTrue(self.eq(xSection7.MetadataReference,
3409 StringPair("content.xml", "idUDTitle")), "idUDTitle")
3410 xSection8 = xSections["Table of Objects1_Head"]
3411 self.assertTrue(self.eq(xSection8.MetadataReference,
3412 StringPair("content.xml", "idTOOTitle")), "idTOOTitle")
3413 xSection9 = xSections["Bibliography1_Head"]
3414 self.assertTrue(self.eq(xSection9.MetadataReference,
3415 StringPair("content.xml", "idBibTitle")), "idBibTitle")
3416 print("...done")
3418 print("Checking indexes in loaded test document...")
3419 xIndexes = xTextDoc.getDocumentIndexes()
3420 xIndex1 = xIndexes["Table of Contents1"]
3421 self.assertTrue(self.eq(xIndex1.MetadataReference,
3422 StringPair("content.xml", "idTOC")), "idTOC")
3423 xIndex1s = xSections["Table of Contents1"]
3424 self.assertTrue(self.eq(xIndex1s.MetadataReference,
3425 StringPair("content.xml", "idTOC")), "idTOC")
3426 xIndex2 = xIndexes["Alphabetical Index1"]
3427 self.assertTrue(self.eq(xIndex2.MetadataReference,
3428 StringPair("content.xml", "idAI")), "idAI")
3429 xIndex2s = xSections["Alphabetical Index1"]
3430 self.assertTrue(self.eq(xIndex2s.MetadataReference,
3431 StringPair("content.xml", "idAI")), "idAI")
3432 xIndex3 = xIndexes["Illustration Index1"]
3433 self.assertTrue(self.eq(xIndex3.MetadataReference,
3434 StringPair("content.xml", "idII")), "idII")
3435 xIndex3s = xSections["Table of Figures1"]
3436 self.assertTrue(self.eq(xIndex3s.MetadataReference,
3437 StringPair("content.xml", "idII")), "idII")
3438 xIndex4 = xIndexes["Index of Tables1"]
3439 self.assertTrue(self.eq(xIndex4.MetadataReference,
3440 StringPair("content.xml", "idIOT")), "idIOT")
3441 xIndex4s = xSections["Index of Tables1"]
3442 self.assertTrue(self.eq(xIndex4s.MetadataReference,
3443 StringPair("content.xml", "idIOT")), "idIOT")
3444 xIndex5 = xIndexes["User-Defined1"]
3445 self.assertTrue(self.eq(xIndex5.MetadataReference,
3446 StringPair("content.xml", "idUD")), "idUD")
3447 xIndex5s = xSections["User-Defined1"]
3448 self.assertTrue(self.eq(xIndex5s.MetadataReference,
3449 StringPair("content.xml", "idUD")), "idUD")
3450 xIndex6 = xIndexes["Table of Objects1"]
3451 self.assertTrue(self.eq(xIndex6.MetadataReference,
3452 StringPair("content.xml", "idTOO")), "idTOO")
3453 xIndex6s = xSections["Table of Objects1"]
3454 self.assertTrue(self.eq(xIndex6s.MetadataReference,
3455 StringPair("content.xml", "idTOO")), "idTOO")
3456 xIndex7 = xIndexes["Bibliography1"]
3457 self.assertTrue(self.eq(xIndex7.MetadataReference,
3458 StringPair("content.xml", "idBib")), "idBib")
3459 xIndex7s = xSections["Bibliography1"]
3460 self.assertTrue(self.eq(xIndex7s.MetadataReference,
3461 StringPair("content.xml", "idBib")), "idBib")
3462 print("...done")
3464 def dotest(self, intree, insert=True):
3465 xDoc = self.__class__.xDoc
3466 self._dotest(xDoc, intree, insert)
3468 def _dotest(self, xDoc, intree, insert):
3469 self._dumptree(intree, "I: ")
3470 if insert:
3471 TreeInserter(xDoc).inserttree(intree)
3472 xText = xDoc.getText()
3473 xTextEnum = xText.createEnumeration()
3474 ## skip to right paragraph
3475 xTextEnum.nextElement(); # skip first -- always empty!
3476 xElement = xTextEnum.nextElement() # second contains test case
3477 xEnum = xElement.createEnumeration()
3478 outtree = EnumConverter().convert(xEnum)
3479 self._dumptree(outtree, "O: ")
3480 FuzzyTester().dotest(intree, outtree)
3482 def _dumptree(self, tree, prefix):
3483 print('{}{}'.format(prefix, str(tree)))
3484 children = tree.createenumeration()
3485 for node in children:
3486 self._dumptree(node, "{} ".format(prefix))
3488 def mkname(self, prefix):
3489 self.__class__.count += 1
3490 return "{}{}".format(prefix, self.__class__.count)
3492 def mkid(self, prefix):
3493 id = self.mkname(prefix)
3494 return StringPair("content.xml", self.mkname(prefix))
3496 def mkid_(self, id):
3497 return StringPair("content.xml", id)
3499 def eq(self, left, right):
3500 return (left.First == right.First and
3501 left.Second == right.Second)
3504 if __name__ == '__main__':
3505 unittest.main()