summaryrefslogtreecommitdiffstats
path: root/sw/qa/python/text_portion_enumeration_test.py
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
commit940b4d1848e8c70ab7642901a68594e8016caffc (patch)
treeeb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /sw/qa/python/text_portion_enumeration_test.py
parentInitial commit. (diff)
downloadlibreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.tar.xz
libreoffice-940b4d1848e8c70ab7642901a68594e8016caffc.zip
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'sw/qa/python/text_portion_enumeration_test.py')
-rw-r--r--sw/qa/python/text_portion_enumeration_test.py3510
1 files changed, 3510 insertions, 0 deletions
diff --git a/sw/qa/python/text_portion_enumeration_test.py b/sw/qa/python/text_portion_enumeration_test.py
new file mode 100644
index 000000000..c379138db
--- /dev/null
+++ b/sw/qa/python/text_portion_enumeration_test.py
@@ -0,0 +1,3510 @@
+# -*- coding: utf-8 -*-
+
+'''
+This file is part of the LibreOffice project.
+
+This Source Code Form is subject to the terms of the Mozilla Public
+License, v. 2.0. If a copy of the MPL was not distributed with this
+file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+This file incorporates work covered by the following license notice:
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed
+ with this work for additional information regarding copyright
+ ownership. The ASF licenses this file to you under the Apache
+ License, Version 2.0 (the "License"); you may not use this file
+ except in compliance with the License. You may obtain a copy of
+ the License at http://www.apache.org/licenses/LICENSE-2.0 .
+'''
+import uno
+import unittest
+import os.path
+from org.libreoffice.unotest import UnoInProcess, mkPropertyValue
+from tempfile import TemporaryDirectory
+from com.sun.star.uno import RuntimeException
+from com.sun.star.lang import IllegalArgumentException, NoSupportException
+from com.sun.star.beans import PropertyValue, StringPair
+from com.sun.star.rdf.URIs import ODF_PREFIX, ODF_SUFFIX
+from com.sun.star.i18n.NumberFormatIndex import NUMBER_INT
+from com.sun.star.text.ControlCharacter import PARAGRAPH_BREAK, HARD_HYPHEN
+from com.sun.star.text.TextContentAnchorType import (
+ AT_CHARACTER, AS_CHARACTER, AT_PARAGRAPH, AT_PAGE, AT_FRAME)
+
+
+class TreeNode():
+ '''base class for tree nodes. only instance: root of tree.'''
+
+ def __init__(self, content=None):
+ self.content = content
+ self._children = []
+ self.nodetype = "__ROOT__"
+ self.isnesting = False
+
+ def __str__(self):
+ return "<{}>".format(self.nodetype)
+
+ def __eq__(self, other):
+ return type(self) == type(other)
+
+ def __ne__(self, other):
+ return not self == other
+
+ def _dup(self, nodetype, *args):
+ try:
+ return nodetype(*args)
+ except Exception as e:
+ raise RuntimeError("TreeNode.dup") from e
+
+ def createenumeration(self):
+ return iter(self._children)
+
+ def appendchild(self, child):
+ self._children.append(child)
+ return self
+
+
+class ContentNode(TreeNode):
+
+ def __init__(self, content):
+ super().__init__(content)
+
+ def __str__(self):
+ return "{}\tcontent: {}".format(super().__str__(), self.content)
+
+ def __eq__(self, other):
+ try:
+ return other.content == self.content and super().__eq__(other)
+ except AttributeError:
+ return False
+
+ def appendchild(self, child):
+ try:
+ self._children.append(child)
+ return self
+ except Exception as e:
+ raise RuntimeError("ContentNode.appendchild") from e
+
+
+class TextNode(ContentNode):
+
+ def __init__(self, content):
+ super().__init__(content)
+ self.nodetype = "Text"
+
+ def dup(self):
+ return self._dup(TextNode, self.content)
+
+
+class TextFieldNode(ContentNode):
+
+ def __init__(self, content):
+ super().__init__(content)
+ self.nodetype = "TextField"
+
+ def dup(self):
+ return self._dup(TextFieldNode, self.content)
+
+
+class ControlCharacterNode(TreeNode):
+ def __init__(self, char):
+ super().__init__()
+ self.char = char
+ self.nodetype = "ControlCharacter"
+
+ def __str__(self):
+ return "{}\tcontent: {}".format(super().__str__(), self.char)
+
+ def __eq__(self, other):
+ try:
+ return other.char == self.char and super().__eq__(other)
+ except AttributeError:
+ return False
+
+ def dup(self):
+ return self._dup(ControlCharacterNode, self.char)
+
+
+class FootnoteNode(TreeNode):
+
+ def __init__(self, label):
+ super().__init__()
+ self.label = label
+ self.nodetype = "Footnote"
+
+ def __str__(self):
+ return "{}\tlabel: {}".format(super().__str__(), self.label)
+
+ def __eq__(self, other):
+ try:
+ return other.label == self.label and super().__eq__(other)
+ except AttributeError:
+ return False
+
+ def dup(self):
+ return self._dup(FootnoteNode, self.label)
+
+
+class FrameNode(TreeNode):
+ def __init__(self, name, anchor):
+ super().__init__()
+ self.name = name
+ self.anchor = anchor
+ self.nodetype = "Frame"
+
+ def __str__(self):
+ return "{}\tname: {}\tanchor: {}".format(
+ super().__str__(),self.name, self.str_anchor(self.anchor))
+
+ def __eq__(self, other):
+ try:
+ return (other.name == self.name and
+ other.anchor == self.anchor and
+ super().__eq__(other))
+ except AttributeError:
+ return False
+
+ def dup(self):
+ return self._dup(FrameNode, self.name, self.anchor)
+
+ def str_anchor(self, anchor):
+ anchors = {str(AS_CHARACTER): "AS_CHARACTER",
+ str(AT_CHARACTER): "AT_CHARACTER",
+ str(AT_PARAGRAPH): "AT_PARAGRAPH",
+ str(AT_PAGE): "AT_PAGE",
+ str(AT_FRAME): "AT_FRAME"}
+ try:
+ return anchors[str(anchor)]
+ except KeyError:
+ raise RuntimeError("unknown anchor")
+
+
+class MetaNode(TreeNode):
+ def __init__(self, xmlid):
+ super().__init__()
+ self.xmlid = xmlid
+ self.nodetype = "InContentMetadata"
+ self.isnesting = True
+
+ def __str__(self):
+ return "{}\txmlid: {}#{}".format(
+ super().__str__(), self.xmlid.First, self.xmlid.Second)
+
+ def __eq__(self, other):
+ try:
+ return (type(other) == type(self) and
+ MetaNode.eq(other.xmlid, self.xmlid))
+ except AttributeError:
+ return False
+
+ @classmethod
+ def eq(cls, left, right):
+ return left.First == right.First and left.Second == right.Second
+
+ def dup(self):
+ return self._dup(MetaNode, self.xmlid)
+
+
+class MarkNode(TreeNode):
+ def __init__(self, name, ispoint=True):
+ super().__init__()
+ self.name = name
+ self.ispoint = ispoint
+ self.isstart = False
+
+ def __str__(self):
+ return "{}\tisPoint: {}\tisStart: {}".format(
+ super().__str__(), self.ispoint, self.isstart)
+
+ def __eq__(self, other):
+ try:
+ return (other.name == self.name and
+ other.ispoint == self.ispoint and
+ other.isstart == self.isstart)
+ except AttributeError:
+ return False
+
+
+class BookmarkNode(MarkNode):
+ def __init__(self, name, xmlid=StringPair()):
+ super().__init__(name)
+ self.xmlid = xmlid
+ self.nodetype = "Bookmark"
+
+ def __str__(self):
+ return "{}\txmlid: {}#{}".format(
+ super().__str__(), self.xmlid.First, self.xmlid.Second)
+
+ def __eq__(self, other):
+ try:
+ return (type(other) == type(self) and
+ super().__eq__(other) and
+ MetaNode.eq(other.xmlid, self.xmlid))
+ except AttributeError:
+ return False
+
+ def dup(self):
+ return self._dup(BookmarkNode, self.name, self.xmlid)
+
+
+class BookmarkStartNode(BookmarkNode):
+
+ def __init__(self, name, xmlid=StringPair()):
+ super().__init__(name, xmlid)
+ self.ispoint = False
+ self.isstart = True
+
+ def dup(self):
+ return self._dup(BookmarkStartNode, self.name)
+
+
+class BookmarkEndNode(BookmarkNode):
+
+ def __init__(self, name, xmlid=StringPair()):
+ super().__init__(name, xmlid)
+ self.ispoint = False
+ self.isstart = False
+
+ def dup(self):
+ return self._dup(BookmarkEndNode, self.name)
+
+
+class ReferenceMarkNode(MarkNode):
+ def __init__(self, name):
+ super().__init__(name)
+ self.nodetype = "ReferenceMark"
+
+ def __eq__(self, other):
+ return (type(other) == type(self) and super().__eq__(other))
+
+ def dup(self):
+ return self._dup(ReferenceMarkNode, self.name)
+
+
+class ReferenceMarkStartNode(ReferenceMarkNode):
+ def __init__(self, name):
+ super().__init__(name)
+ self.ispoint = False
+ self.isstart = True
+
+ def dup(self):
+ return self._dup(ReferenceMarkStartNode, self.name)
+
+
+class ReferenceMarkEndNode(ReferenceMarkNode):
+ def __init__(self, name):
+ super().__init__(name)
+ self.ispoint = False
+ self.isstart = False
+
+ def dup(self):
+ return self._dup(ReferenceMarkEndNode, self.name)
+
+
+class DocumentIndexMarkNode(MarkNode):
+ def __init__(self, name):
+ super().__init__(name)
+ self.nodetype = "DocumentIndexMark"
+
+ def __eq__(self, other):
+ return (type(other) == type(self) and super().__eq__(other))
+
+ def dup(self):
+ return self._dup(DocumentIndexMarkNode, self.name)
+
+
+class DocumentIndexMarkStartNode(DocumentIndexMarkNode):
+ def __init__(self, name):
+ super().__init__(name)
+ self.ispoint = False
+ self.isstart = True
+
+ def dup(self):
+ return self._dup(DocumentIndexMarkStartNode, self.name)
+
+
+class DocumentIndexMarkEndNode(DocumentIndexMarkNode):
+ def __init__(self, name):
+ super().__init__(name)
+ self.ispoint = False
+ self.isstart = False
+
+ def dup(self):
+ return self._dup(DocumentIndexMarkEndNode, self.name)
+
+
+class HyperlinkNode(TreeNode):
+ def __init__(self, url):
+ super().__init__()
+ self.nodetype = "Hyperlink"
+ self.isnesting = True
+ if url:
+ self.url = url
+ else:
+ raise RuntimeError("HyperlinkNode")
+
+ def __str__(self):
+ return "{}\turl: {}".format(super().__str__(), self.url)
+
+ def __eq__(self, other):
+ try:
+ return other.url == self.url and super().__eq__(other)
+ except AttributeError:
+ return False
+
+ def dup(self):
+ return self._dup(HyperlinkNode, self.url)
+
+
+class RubyNode(TreeNode):
+ def __init__(self, ruby):
+ super().__init__()
+ self.nodetype = "Ruby"
+ self.isnesting = True
+ if ruby:
+ self.ruby = ruby
+ else:
+ raise RuntimeError("RubyNode")
+
+ def __str__(self):
+ return "{}\trubytext: {}".format(super().__str__(), self.ruby)
+
+ def __eq__(self, other):
+ try:
+ return other.ruby == self.ruby and super().__eq__(other)
+ except AttributeError:
+ return False
+
+ def dup(self):
+ return self._dup(RubyNode, self.ruby)
+
+
+class MetaFieldNode(MetaNode):
+ def __init__(self, xmlid):
+ super().__init__(xmlid)
+ self.nodetype = "MetadataField"
+
+ def dup(self):
+ return self._dup(MetaFieldNode, self.xmlid)
+
+
+class Range():
+ def __init__(self, start, end, node):
+ self.start = start
+ self.end = end
+ self.node = node
+ self.extent = end - start
+
+
+class Inserter():
+
+ def __init__(self, xDoc):
+ self.xDoc = xDoc
+ self.xText = xDoc.getText()
+ self.xCursor = self.xText.createTextCursor()
+
+ def initparagraph(self):
+ ## we split the first (empty) paragraph, and then insert into the
+ ## second (empty) paragraph; this ensures first is always empty!
+ self.xCursor.gotoStartOfParagraph(False)
+ self.xText.insertControlCharacter(self.xCursor, PARAGRAPH_BREAK, False)
+
+ def inserttext(self, xCursor, text):
+ xCursor.setString(text)
+
+ def inserttextfield(self, xCursor, content):
+ xContent = self.maketextfield(content)
+ xContent.attach(xCursor)
+
+ def maketextfield(self, content):
+ xField = self.xDoc.createInstance("com.sun.star.text.textfield.Author")
+ xField.IsFixed = True
+ xField.FullName = False
+ xField.Content = content
+ return xField
+
+ def insertcontrolcharacter(self, xCursor, cchar):
+ self.xText.insertControlCharacter(xCursor, cchar, False)
+
+ def insertframe(self, xCursor, name, anchor):
+ xContent = self.makeframe(name, anchor)
+ xContent.attach(xCursor)
+
+ def makeframe(self, name, anchor):
+ xFrame = self.xDoc.createInstance("com.sun.star.text.TextFrame")
+ xFrame.AnchorType = anchor
+ xFrame.setName(name)
+ return xFrame
+
+ def insertfootnote(self, xCursor, label):
+ xContent = self.makefootnote(label)
+ xContent.attach(xCursor)
+
+ def makefootnote(self, label):
+ xFootNote = self.xDoc.createInstance("com.sun.star.text.Footnote")
+ xFootNote.setLabel(label)
+ return xFootNote
+
+ def insertbookmark(self, xCursor, name, xmlid):
+ xContent = self.makebookmark(name)
+ xContent.attach(xCursor)
+ if xmlid.First != "":
+ xContent.MetadataReference = xmlid
+
+ def makebookmark(self, name):
+ xBookmark = self.xDoc.createInstance("com.sun.star.text.Bookmark")
+ xBookmark.setName(name)
+ return xBookmark
+
+ def insertreferencemark(self, xCursor, name):
+ xContent = self.makereferencemark(name)
+ xContent.attach(xCursor)
+
+ def makereferencemark(self, name):
+ xMark = self.xDoc.createInstance("com.sun.star.text.ReferenceMark")
+ xMark.setName(name)
+ return xMark
+
+ def insertdocumentindexmark(self, xCursor, key):
+ xContent = self.makedocumentindexmark(key)
+ xContent.attach(xCursor)
+
+ def makedocumentindexmark(self, key):
+ xMark = self.xDoc.createInstance("com.sun.star.text.DocumentIndexMark")
+ xMark.PrimaryKey = key
+ return xMark
+
+ def inserthyperlink(self, xCursor, url):
+ xCursor.HyperLinkURL = url
+
+ def insertruby(self, xCursor, rubytext):
+ xCursor.RubyText = rubytext
+
+ def insertmeta(self, xCursor, xmlid):
+ xContent = self.makemeta()
+ xContent.attach(xCursor)
+ xContent.MetadataReference = xmlid
+ return xContent
+
+ def makemeta(self):
+ xMeta = self.xDoc.createInstance("com.sun.star.text.InContentMetadata")
+ return xMeta
+
+ def insertmetafield(self, xCursor, xmlid):
+ xContent = self.makemetafield()
+ xContent.attach(xCursor)
+ xContent.MetadataReference = xmlid
+ return xContent
+
+ def makemetafield(self):
+ xMeta = self.xDoc.createInstance(
+ "com.sun.star.text.textfield.MetadataField")
+ return xMeta
+
+
+class TreeInserter(Inserter):
+
+ def __init__(self, xDoc):
+ super().__init__(xDoc)
+ self._bookmarkstarts = {}
+ self._referencemarkstarts = {}
+ self._documentindexmarkstarts = {}
+ self._framehints = []
+
+ def inserttree(self, tree):
+ if tree.nodetype != "__ROOT__":
+ raise RuntimeError("insertTree: test error: no root")
+ self.initparagraph()
+ self.insertchildren(tree.createenumeration())
+ for p in self._framehints:
+ self.insertframe(p[0], p[1].name, p[1].anchor)
+
+ def insertchildren(self, children):
+ xCursor = self.xCursor
+ for node in children:
+ xCursor.gotoEndOfParagraph(False)
+ type_ = node.nodetype
+ if type_ == "Text":
+ self.inserttext(xCursor, node.content)
+ elif type_ == "TextField":
+ self.inserttextfield(xCursor, node.content)
+ elif type_ == "ControlCharacter":
+ self.insertcontrolcharacter(xCursor, node.char)
+ elif type_ == "Footnote":
+ self.insertfootnote(xCursor, node.label)
+ elif type_ == "Frame":
+ if node.anchor == AT_CHARACTER:
+ self._framehints.append((xCursor.getStart(), node))
+ else:
+ self.insertframe(xCursor, node.name, node.anchor)
+ elif type_ == "Bookmark":
+ name = node.name
+ id_ = node.xmlid
+ if node.ispoint:
+ self.insertbookmark(xCursor, name, id_)
+ elif node.isstart:
+ self._bookmarkstarts[name] = xCursor.getStart()
+ else:
+ xRange = self._bookmarkstarts[name]
+ xParaCursor = self.mkcursor(xRange)
+ self.insertbookmark(xParaCursor, name, id_)
+ elif type_ == "ReferenceMark":
+ name = node.name
+ if node.ispoint:
+ self.insertreferencemark(xCursor, name)
+ elif node.isstart:
+ self._referencemarkstarts[name] = xCursor.getStart()
+ else:
+ xRange = self._referencemarkstarts[name]
+ xParaCursor = self.mkcursor(xRange)
+ self.insertreferencemark(xParaCursor, name)
+ elif type_ == "DocumentIndexMark":
+ name = node.name
+ if node.ispoint:
+ self.insertdocumentindexmark(xCursor, name)
+ elif node.isstart:
+ self._documentindexmarkstarts[name] = xCursor.getStart()
+ else:
+ xRange = self._documentindexmarkstarts[name]
+ xParaCursor = self.mkcursor(xRange)
+ self.insertdocumentindexmark(xParaCursor, name)
+ elif type_ == "Hyperlink":
+ xRange = xCursor.getStart()
+ self.insertchildren(node.createenumeration())
+ xParaCursor = self.mkcursor(xRange)
+ self.inserthyperlink(xParaCursor, node.url)
+ elif type_ == "Ruby":
+ xRange = xCursor.getStart()
+ self.insertchildren(node.createenumeration())
+ xParaCursor = self.mkcursor(xRange)
+ self.insertruby(xParaCursor, node.ruby)
+ elif type_ == "InContentMetadata":
+ xRange = xCursor.getStart()
+ self.insertchildren(node.createenumeration())
+ xParaCursor = self.mkcursor(xRange)
+ self.insertmeta(xParaCursor, node.xmlid)
+ elif type_ == "MetadataField":
+ xRange = xCursor.getStart()
+ self.insertchildren(node.createenumeration())
+ xParaCursor = self.mkcursor(xRange)
+ self.insertmetafield(xParaCursor, node.xmlid)
+ elif type_ == "SoftPageBreak":
+ raise RuntimeError("sorry, cannot test SoftPageBreak")
+ else:
+ raise RuntimeError("unexpected type: {}".format(type_))
+
+ def mkcursor(self, xRange):
+ xCursor = self.xText.createTextCursorByRange(xRange)
+ xCursor.gotoEndOfParagraph(True)
+ return xCursor
+
+
+# FIXME: this does not account for inserted dummy characters!
+class RangeInserter(Inserter):
+ def __init__(self, xDoc):
+ super().__init__(xDoc)
+ self.initparagraph()
+
+ # def inserttext(self, pos, text):
+ # self.xCursor.gotoStartOfParagraph(False)
+ # self.xCursor.goRight(pos, False)
+ # self.inserttext(self.xCursor, text)
+
+ def insertrange(self, range):
+ self.xCursor.gotoStartOfParagraph(False)
+ self.xCursor.goRight(range.start, False)
+ self.xCursor.goRight(range.extent, True)
+ return self.insertnode(self.xCursor, range.node)
+
+ def insertnode(self, xParaCursor, node):
+ nodetype = node.nodetype
+ if nodetype == "Text":
+ text = node
+ self.inserttext(xParaCursor, text.content)
+ elif nodetype == "Hyperlink":
+ href = node
+ self.inserthyperlink(xParaCursor, href.url)
+ elif nodetype == "Ruby":
+ ruby = node
+ self.insertruby(xParaCursor, ruby.ruby)
+ elif nodetype == "InContentMetadata":
+ meta = node
+ return self.insertmeta(xParaCursor, meta.xmlid)
+ elif nodetype == "MetadataField":
+ meta = node
+ return self.insertmetafield(xParaCursor, meta.xmlid)
+ elif nodetype == "Bookmark":
+ bkmk = node
+ if bkmk.ispoint:
+ raise RuntimeError("range only")
+ self.insertbookmark(xParaCursor, bkmk.name, bkmk.xmlid)
+ elif nodetype == "ReferenceMark":
+ mark = node
+ if mark.ispoint:
+ raise RuntimeError("range only")
+ self.insertreferencemark(xParaCursor, mark.name)
+ elif nodetype == "DocumentIndexMark":
+ mark = node
+ if mark.ispoint:
+ raise RuntimeError("range only")
+ self.insertdocumentindexmark(xParaCursor, mark.name)
+ elif nodetype == "TextField":
+ field = node
+ self.inserttextfield(self.xCursor, field.content)
+ elif nodetype == "Footnote":
+ note = node
+ self.insertfootnote(self.xCursor, note.label)
+ elif nodetype == "Frame":
+ frame = node
+ self.insertframe(xParaCursor, frame.name, frame.anchor)
+ elif nodetype == "ControlCharacter":
+ cchar = node
+ self.insertcontrolcharacter(self.xCursor, cchar.char)
+ elif nodetype == "SoftPageBreak":
+ raise RuntimeError("sorry, cannot test SoftPageBreak")
+ else:
+ raise RuntimeError("unexpected nodetype: {}".format(nodetype))
+ return None
+
+
+class EnumConverter():
+
+ def __init__(self):
+ self._stack = []
+
+ def convert(self, xEnum):
+ root = TreeNode()
+ self._stack.append(root)
+ ret = self.convertchildren(xEnum)
+ assert (len(self._stack)==0), "EnumConverter.convert: stack is not empty"
+ return ret
+
+ def convertchildren(self, xEnum):
+ for xPortion in xEnum:
+ type_ = xPortion.TextPortionType
+ if type_ == "Text":
+ text = xPortion.getString()
+ node = TextNode(text)
+ url = xPortion.HyperLinkURL
+ if len(url) > 0:
+ temp = node
+ node = HyperlinkNode(url)
+ node.appendchild(temp)
+ elif type_ == "TextField":
+ xField = xPortion.TextField
+ if xField.supportsService("com.sun.star.text.textfield.MetadataField"):
+ xmlid = xField.MetadataReference
+ node = MetaFieldNode(xmlid)
+ self._stack.append(node)
+ xEnumChildren = xField.createEnumeration()
+ node2 = self.convertchildren(xEnumChildren)
+ print(node)
+ print(node2)
+ assert (node2 is node), "stack error: meta-field"
+ else:
+ content = xField.Content
+ isFixed = xField.IsFixed
+ assert isFixed, "field not fixed?"
+ node = TextFieldNode(content)
+ elif type_ == "ControlCharacter":
+ c = xPortion.ControlCharacter
+ node = ControlCharacterNode(c)
+ elif type_ == "Footnote":
+ xFootnote = xPortion.Footnote
+ label = xFootnote.getLabel()
+ node = FootnoteNode(label)
+ elif type_ == "Frame":
+ xCEA = xPortion.createContentEnumeration('')
+ while xCEA.hasMoreElements():
+ xFrame = xCEA.nextElement()
+ anchor = xFrame.AnchorType
+ name = xFrame.getName()
+ node = FrameNode(name, anchor)
+ self._stack[-1].appendchild(node)
+ continue
+ elif type_ == "Bookmark":
+ xMark = xPortion.Bookmark
+ name = xMark.getName()
+ xmlid = xMark.MetadataReference
+ isCollapsed = xPortion.IsCollapsed
+ if isCollapsed:
+ node = BookmarkNode(name, xmlid)
+ else:
+ isStart = xPortion.IsStart
+ if isStart:
+ node = BookmarkStartNode(name, xmlid)
+ else:
+ node = BookmarkEndNode(name, xmlid)
+ elif type_ == "ReferenceMark":
+ xMark = xPortion.ReferenceMark
+ name = xMark.getName()
+ isCollapsed = xPortion.IsCollapsed
+ if isCollapsed:
+ node = ReferenceMarkNode(name)
+ else:
+ isStart = xPortion.IsStart
+ if isStart:
+ node = ReferenceMarkStartNode(name)
+ else:
+ node = ReferenceMarkEndNode(name)
+ elif type_ == "DocumentIndexMark":
+ xMark = xPortion.DocumentIndexMark
+ name = xMark.PrimaryKey
+ isCollapsed = xPortion.IsCollapsed
+ if isCollapsed:
+ node = DocumentIndexMarkNode(name)
+ else:
+ isStart = xPortion.IsStart
+ if isStart:
+ node = DocumentIndexMarkStartNode(name)
+ else:
+ node = DocumentIndexMarkEndNode(name)
+ elif type_ == "Ruby":
+ isStart = xPortion.IsStart
+ if isStart:
+ # ARRGH!!! stupid api...
+ # the text is ONLY at the start!
+ ruby = xPortion.RubyText
+ node = RubyNode(ruby)
+ self._stack.append(node)
+ continue
+ else:
+ node = self._stack.pop()
+ assert (isinstance(node, RubyNode)), "stack error: Ruby expected; is: {}".format(str(node))
+ elif type_ == "InContentMetadata":
+ xMeta = xPortion.InContentMetadata
+ xmlid = xMeta.MetadataReference
+ node = MetaNode(xmlid)
+ self._stack.append(node)
+ xEnumChildren = xMeta.createEnumeration()
+ node2 = self.convertchildren(xEnumChildren)
+ assert (node2 is node), "stack error: meta"
+ elif type_ == "SoftPageBreak":
+ node = SoftPageBreakNode()
+ else:
+ raise RuntimeError("unexpected type: {}".format(type_))
+ self._stack[-1].appendchild(node)
+ ret = self._stack.pop()
+ return ret
+
+
+class FuzzyTester():
+ '''this is where we nail the pudding to the wall'''
+ def __init__(self):
+ self.diffcontent = 0
+ self.diffmissing = 0
+ self.diffnesting = 0
+ self.diffspuriousemptytext = 0
+ self.diffsequence = 0 # ignored?
+ self.stackexpected = []
+ self.stackactual = []
+ self.bufferexpected = []
+ self.bufferactual = []
+
+ def dotest(self, expected, actual):
+ '''idea: traverse both trees, enumerate nodes, stopping at content nodes.
+ then compare buffers.'''
+ assert "__ROOT__" == expected.nodetype
+ assert "__ROOT__" == actual.nodetype
+ self.stackexpected.append((expected, expected.createenumeration()))
+ self.stackactual.append((actual, actual.createenumeration()))
+ while self.stackexpected or self.stackactual:
+ self.traverse(self.stackexpected, self.bufferexpected)
+ self.traverse(self.stackactual, self.bufferactual)
+ self.testbuffer()
+ if self.diffsequence:
+ print("warning: {} differences in sequence".format(
+ self.diffsequence))
+ if self.diffspuriousemptytext:
+ print("warning: {} spurious empty text nodes".format(
+ self.diffspuriousemptytext))
+ if self.diffnesting:
+ print("WARNING: {} differences in nesting".format(
+ self.diffnesting))
+ assert self.diffcontent == 0
+ assert self.diffmissing == 0
+
+ def traverse(self, stack, buffer):
+ while stack:
+ topenum = stack[-1][1]
+ try:
+ node = next(topenum)
+ buffer.append(node)
+ if node._children:
+ node_enum = node.createenumeration()
+ stack.append((node, node_enum))
+ if node.content:
+ if not (isinstance(node, TextNode) and # spurious empty text?
+ len(node.content) == 0):
+ return # break here
+ except StopIteration:
+ buffer.append(stack[-1][0])
+ stack.pop()
+
+ def testterminatingnode(self):
+ lenexpected = len(self.bufferexpected)
+ lenactual = len(self.bufferactual)
+ if lenexpected == 0 or lenactual == 0:
+ return
+ expected = self.bufferexpected[-1]
+ actual = self.bufferactual[-1]
+ eroot = expected.nodetype == "__ROOT__"
+ aroot = actual.nodetype == "__ROOT__"
+ if eroot or aroot:
+ if not (eroot and aroot):
+ if aroot:
+ self.printmissing(expected)
+ else:
+ self.printunexpected(actual)
+ self.diffmissing += 1
+ return
+ self.testcontentnode(expected, actual)
+ self.bufferexpected[-1] = None
+ self.bufferactual[-1] = None
+
+ def testcontentnode(self, expected, actual):
+ contentexpected = expected.content
+ contentactual = actual.content
+ if expected != actual:
+ self.printdiff("text content differs", contentexpected, contentactual)
+ self.diffcontent += 1
+
+ def testbuffer(self):
+ lenactual = len(self.bufferactual)
+ tmp_bufferactual = self.bufferactual[:]
+ for i, node in enumerate(self.bufferexpected):
+ try:
+ j = tmp_bufferactual.index(node)
+ if j != i:
+ # FIXME how bad is this?
+ self.printdiff("position differs", i, j)
+ # a hacky hack
+ min_ = min(i,j)
+ max_ = max(min(lenactual-1, i),j)
+ for k in range(min_, max_):
+ tmp = tmp_bufferactual[k]
+ if tmp and tmp.isnesting:
+ self.printnesting(node, tmp)
+ self.diffnesting += 1
+ self.diffsequence += 1
+ tmp_bufferactual[j] = None
+ except ValueError:
+ print('perdrix')
+ self.printmissing(node)
+ self.diffmissing += 1
+ for j, node in enumerate(tmp_bufferactual):
+ if node:
+ self.printunexpected(node)
+ if isinstance(node, TextNode) and len(node.content) == 0:
+ self.diffspuriousemptytext += 1
+ else:
+ print('renard')
+ self.diffmissing += 1
+ self.testterminatingnode()
+ self.bufferexpected[:] = []
+ self.bufferactual[:] = []
+
+ def printdiff(self, prefix, expected, actual):
+ print("{}:\texpected: {}\tactual: {}".format(prefix, expected, actual))
+
+ def printnesting(self, node, nesting):
+ print("node: {} possibly moved across nesting {}".format(
+ str(node), str(nesting)))
+
+ def printmissing(self, node):
+ print(" missing node: {}".format(str(node)))
+
+ def printunexpected(self, node):
+ print("unexpected node: {}".format(str(node)))
+
+
+class TextPortionEnumerationTest(unittest.TestCase):
+
+ xMSF = None
+ xContext = None
+ tempdir = None
+
+ @classmethod
+ def setUpClass(cls):
+ cls._uno = UnoInProcess()
+ cls._uno.setUp()
+ cls.xDoc = cls._uno.openEmptyWriterDoc()
+ cls.count = 0
+
+ @classmethod
+ def tearDownClass(cls):
+ cls.xDoc.close(True)
+ cls._uno.tearDown()
+ # HACK in case cls.xDoc holds a UNO proxy to an SwXTextDocument (whose dtor calls
+ # Application::GetSolarMutex via sw::UnoImplPtrDeleter), which would potentially only be
+ # garbage-collected after VCL has already been deinitialized:
+ cls.xDoc = None
+
+ def test_text(self):
+ root = TreeNode()
+ text = TextNode("abc")
+ root.appendchild(text)
+ self.dotest(root)
+
+ def test_text_field(self):
+ self.mkname("ruby")
+ root = TreeNode()
+ txtf = TextFieldNode("abc")
+ root.appendchild(txtf)
+ self.dotest(root)
+
+ @unittest.skip("FIXME this is converted to a text portion: ControlCharacter is obsolete")
+ def test_control_char(self):
+ root = TreeNode()
+ cchr = ControlCharacterNode(HARD_HYPHEN)
+ root.appendchild(cchr)
+ self.dotest(root)
+
+ @unittest.skip("FIXME: insert a soft page break: not done")
+ def test_soft_page_break(self):
+ root = TreeNode()
+ spbk =SoftPageBreakNode()
+ text = TextNode("abc")
+ root.appendchild(spbk)
+ root.appendchild(text)
+ self.dotest(root)
+
+ def test_footnote(self):
+ name = self.mkname("ftn")
+ root = TreeNode()
+ ftnd = FootnoteNode(name)
+ root.appendchild(ftnd)
+ self.dotest(root)
+
+ def test_frame_as(self):
+ name = self.mkname("frame")
+ root = TreeNode()
+ fram = FrameNode(name, AS_CHARACTER)
+ root.appendchild(fram)
+ self.dotest(root)
+
+ def test_frame_at(self):
+ name = self.mkname("frame")
+ root = TreeNode()
+ fram = FrameNode(name, AT_CHARACTER)
+ root.appendchild(fram)
+ self.dotest(root)
+
+ def test_bookmark_point(self):
+ name = self.mkname("mark")
+ root = TreeNode()
+ bkmk = BookmarkNode(name)
+ text = TextNode("abc")
+ root.appendchild(bkmk)
+ root.appendchild(text)
+ self.dotest(root)
+
+ def test_bookmark(self):
+ name = self.mkname("mark")
+ root = TreeNode()
+ bkm1 = BookmarkStartNode(name)
+ text = TextNode("abc")
+ bkm2 = BookmarkEndNode(name)
+ root.appendchild(bkm1)
+ root.appendchild(text)
+ root.appendchild(bkm2)
+ self.dotest(root)
+
+ def test_bookmark_point_xmlid(self):
+ name = self.mkname("mark")
+ id = self.mkid("id")
+ root = TreeNode()
+ bkmk = BookmarkNode(name, id)
+ text = TextNode("abc")
+ root.appendchild(bkmk)
+ root.appendchild(text)
+ self.dotest(root)
+
+ def test_bookmark_xmlid(self):
+ name = self.mkname("mark")
+ id = self.mkid("id")
+ root = TreeNode()
+ bkm1 = BookmarkStartNode(name, id)
+ text = TextNode("abc")
+ bkm2 = BookmarkEndNode(name, id)
+ root.appendchild(bkm1)
+ root.appendchild(text)
+ root.appendchild(bkm2)
+ self.dotest(root)
+
+ def test_refmark_point(self):
+ name = self.mkname("refmark")
+ root = TreeNode()
+ rfmk = ReferenceMarkNode(name)
+ text = TextNode("abc")
+ root.appendchild(rfmk)
+ root.appendchild(text)
+ self.dotest(root)
+
+ def test_refmark(self):
+ name = self.mkname("refmark")
+ root = TreeNode()
+ rfm1 = ReferenceMarkStartNode(name)
+ text = TextNode("abc")
+ rfm2 = ReferenceMarkEndNode(name)
+ root.appendchild(rfm1)
+ root.appendchild(text)
+ root.appendchild(rfm2)
+ self.dotest(root)
+
+ def test_toxmark_point(self):
+ name = self.mkname("toxmark")
+ root = TreeNode()
+ txmk = DocumentIndexMarkNode(name)
+ text = TextNode("abc")
+ root.appendchild(txmk)
+ root.appendchild(text)
+ self.dotest(root)
+
+ def test_toxmark(self):
+ name = self.mkname("toxmark")
+ root = TreeNode()
+ txm1 = DocumentIndexMarkStartNode(name)
+ text = TextNode("abc")
+ txm2 = DocumentIndexMarkEndNode(name)
+ root.appendchild(txm1)
+ root.appendchild(text)
+ root.appendchild(txm2)
+ self.dotest(root)
+
+ def test_hyperlink(self):
+ name = self.mkname("url")
+ root = TreeNode()
+ href = HyperlinkNode(name)
+ text = TextNode("abc")
+ href.appendchild(text)
+ root.appendchild(href)
+ self.dotest(root)
+
+ def test_hyperlink_empty(self):
+ name = self.mkname("url")
+ root = TreeNode()
+ href = HyperlinkNode(name)
+ text = TextNode("")
+ href.appendchild(text)
+ root.appendchild(href)
+ self.dotest(root)
+
+ def test_ruby(self):
+ name = self.mkname("ruby")
+ root = TreeNode()
+ ruby = RubyNode(name)
+ text = TextNode("abc")
+ ruby.appendchild(text)
+ root.appendchild(ruby)
+ self.dotest(root)
+
+ def test_ruby_empty(self):
+ # BUG: #i91534#
+ name = self.mkname("ruby")
+ root = TreeNode()
+ ruby = RubyNode(name)
+ root.appendchild(ruby)
+ self.dotest(root)
+
+ def test_meta(self):
+ id = StringPair("content.xml", self.mkname("id"))
+ root = TreeNode()
+ meta = MetaNode(id)
+ text = TextNode("abc")
+ root.appendchild(TextNode("123"))
+ meta.appendchild(text)
+ root.appendchild(meta)
+ self.dotest(root)
+
+ def test_meta_empty(self):
+ id = StringPair("content.xml", self.mkname("id"))
+ root = TreeNode()
+ meta = MetaNode(id)
+ root.appendchild(meta)
+ self.dotest(root)
+
+ def test_meta_field(self):
+ id = StringPair("content.xml", self.mkname("id"))
+ root = TreeNode()
+ meta = MetaFieldNode(id)
+ text = TextNode("abc")
+ root.appendchild(TextNode("123"))
+ meta.appendchild(text)
+ root.appendchild(meta)
+ self.dotest(root)
+
+ def test_meta_field_empty(self):
+ id = StringPair("content.xml", self.mkname("id"))
+ root = TreeNode()
+ meta = MetaFieldNode(id)
+ root.appendchild(meta)
+ self.dotest(root)
+
+ def test_bookmark1(self):
+ name1 = self.mkname("mark")
+ name2 = self.mkname("mark")
+ name3 = self.mkname("mark")
+ root = TreeNode()
+ root.appendchild(BookmarkStartNode(name1))
+ root.appendchild(BookmarkNode(name2))
+ root.appendchild(BookmarkStartNode(name3))
+ root.appendchild(TextNode("abc"))
+ root.appendchild(BookmarkEndNode(name1))
+ root.appendchild(TextNode("de"))
+ root.appendchild(BookmarkEndNode(name3))
+ self.dotest(root)
+
+ def test_bookmark2(self):
+ name1 = self.mkname("mark")
+ name2 = self.mkname("mark")
+ name3 = self.mkname("mark")
+ root = TreeNode()
+ root.appendchild(BookmarkStartNode(name1))
+ root.appendchild(TextNode("abc"))
+ root.appendchild(BookmarkNode(name2))
+ root.appendchild(BookmarkStartNode(name3))
+ root.appendchild(BookmarkEndNode(name1))
+ root.appendchild(TextNode("de"))
+ root.appendchild(BookmarkEndNode(name3))
+ self.dotest(root)
+
+ def test_refmark2(self):
+ name1 = self.mkname("refmark")
+ root = TreeNode()
+ root.appendchild(ReferenceMarkStartNode(name1))
+ root.appendchild(TextNode("abc"))
+ # BUG: #i102541# (this is actually not unoportenum's fault)
+ root.appendchild(ReferenceMarkEndNode(name1))
+ root.appendchild(TextNode("de"))
+ self.dotest(root)
+
+ def test_refmark3(self):
+ # BUG: #i107672# (non-deterministic; depends on pointer ordering)
+ name1 = self.mkname("refmark")
+ name2 = self.mkname("refmark")
+ name3 = self.mkname("refmark")
+ name4 = self.mkname("refmark")
+ name5 = self.mkname("refmark")
+ name6 = self.mkname("refmark")
+ name7 = self.mkname("refmark")
+ root = TreeNode()
+ root.appendchild(ReferenceMarkStartNode(name1))
+ root.appendchild(ReferenceMarkStartNode(name2))
+ root.appendchild(ReferenceMarkStartNode(name3))
+ root.appendchild(ReferenceMarkStartNode(name4))
+ root.appendchild(ReferenceMarkStartNode(name5))
+ root.appendchild(ReferenceMarkStartNode(name6))
+ root.appendchild(ReferenceMarkStartNode(name7))
+ root.appendchild(TextNode("abc"))
+ root.appendchild(ReferenceMarkEndNode(name7))
+ root.appendchild(ReferenceMarkEndNode(name6))
+ root.appendchild(ReferenceMarkEndNode(name5))
+ root.appendchild(ReferenceMarkEndNode(name4))
+ root.appendchild(ReferenceMarkEndNode(name3))
+ root.appendchild(ReferenceMarkEndNode(name2))
+ root.appendchild(ReferenceMarkEndNode(name1))
+ root.appendchild(TextNode("de"))
+ self.dotest(root)
+
+ def test_toxmark2(self):
+ name1 = self.mkname("toxmark")
+ root = TreeNode()
+ root.appendchild(DocumentIndexMarkStartNode(name1))
+ root.appendchild(TextNode("abc"))
+ root.appendchild(DocumentIndexMarkEndNode(name1))
+ root.appendchild(TextNode("de"))
+ self.dotest(root)
+
+ def test_toxmark3(self):
+ # BUG: #i107672# (non-deterministic; depends on pointer ordering)
+ name1 = self.mkname("toxmark")
+ name2 = self.mkname("toxmark")
+ name3 = self.mkname("toxmark")
+ name4 = self.mkname("toxmark")
+ name5 = self.mkname("toxmark")
+ name6 = self.mkname("toxmark")
+ name7 = self.mkname("toxmark")
+ root = TreeNode()
+ root.appendchild(DocumentIndexMarkStartNode(name1))
+ root.appendchild(DocumentIndexMarkStartNode(name2))
+ root.appendchild(DocumentIndexMarkStartNode(name3))
+ root.appendchild(DocumentIndexMarkStartNode(name4))
+ root.appendchild(DocumentIndexMarkStartNode(name5))
+ root.appendchild(DocumentIndexMarkStartNode(name6))
+ root.appendchild(DocumentIndexMarkStartNode(name7))
+ root.appendchild(TextNode("abc"))
+ root.appendchild(DocumentIndexMarkEndNode(name7))
+ root.appendchild(DocumentIndexMarkEndNode(name6))
+ root.appendchild(DocumentIndexMarkEndNode(name5))
+ root.appendchild(DocumentIndexMarkEndNode(name4))
+ root.appendchild(DocumentIndexMarkEndNode(name3))
+ root.appendchild(DocumentIndexMarkEndNode(name2))
+ root.appendchild(DocumentIndexMarkEndNode(name1))
+ root.appendchild(TextNode("de"))
+ self.dotest(root)
+
+ def test_marks1(self):
+ name1 = self.mkname("bookmark")
+ name2 = self.mkname("toxmark")
+ name3 = self.mkname("refmark")
+ name4 = self.mkname("toxmark")
+ root = TreeNode()
+ root.appendchild(BookmarkStartNode(name1))
+ root.appendchild(DocumentIndexMarkNode(name2))
+ root.appendchild(ReferenceMarkStartNode(name3))
+ root.appendchild(TextNode("abc"))
+ root.appendchild(BookmarkEndNode(name1))
+ root.appendchild(DocumentIndexMarkStartNode(name4))
+ root.appendchild(TextNode("de"))
+ root.appendchild(DocumentIndexMarkEndNode(name4))
+ root.appendchild(ReferenceMarkEndNode(name3))
+ self.dotest(root)
+
+ def test_marks2(self):
+ name1 = self.mkname("bookmark")
+ name2 = self.mkname("refmark")
+ name3 = self.mkname("refmark")
+ name4 = self.mkname("toxmark")
+ name5 = self.mkname("refmark")
+ root = TreeNode()
+ root.appendchild(BookmarkStartNode(name1))
+ root.appendchild(ReferenceMarkNode(name2))
+ root.appendchild(ReferenceMarkStartNode(name3))
+ root.appendchild(TextNode("abc"))
+ root.appendchild(DocumentIndexMarkStartNode(name4))
+ root.appendchild(ReferenceMarkStartNode(name5))
+ # BUG: #i102541# (this is actually not unoportenum's fault)
+ root.appendchild(ReferenceMarkEndNode(name3))
+ root.appendchild(TextNode("de"))
+ root.appendchild(DocumentIndexMarkEndNode(name4))
+ root.appendchild(BookmarkEndNode(name1))
+ root.appendchild(ReferenceMarkEndNode(name5))
+ self.dotest(root)
+
+ def test_marks3(self):
+ name1 = self.mkname("bookmark")
+ name2 = self.mkname("refmark")
+ name3 = self.mkname("refmark")
+ name4 = self.mkname("toxmark")
+ name5 = self.mkname("refmark")
+ root = TreeNode()
+ root.appendchild(BookmarkStartNode(name1))
+ root.appendchild(DocumentIndexMarkNode(name2))
+ root.appendchild(DocumentIndexMarkStartNode(name3))
+ root.appendchild(TextNode("abc"))
+ root.appendchild(ReferenceMarkStartNode(name4))
+ root.appendchild(DocumentIndexMarkStartNode(name5))
+ root.appendchild(DocumentIndexMarkEndNode(name3))
+ root.appendchild(TextNode("de"))
+ root.appendchild(ReferenceMarkEndNode(name4))
+ root.appendchild(BookmarkEndNode(name1))
+ root.appendchild(DocumentIndexMarkEndNode(name5))
+ self.dotest(root)
+
+ def test_frame_mark1(self):
+ name1 = self.mkname("bookmark")
+ name2 = self.mkname("frame")
+ root = TreeNode()
+ root.appendchild(TextNode("abc"))
+ root.appendchild(BookmarkNode(name1))
+ root.appendchild(TextNode("de"))
+ root.appendchild(FrameNode(name2, AS_CHARACTER))
+ self.dotest(root)
+
+ def test_frame_mark2(self):
+ # BUG: #i98530#
+ name1 = self.mkname("bookmark")
+ name2 = self.mkname("frame")
+ root = TreeNode()
+ root.appendchild(TextNode("abc"))
+ root.appendchild(BookmarkNode(name1))
+ root.appendchild(TextNode("de"))
+ root.appendchild(FrameNode(name2, AT_CHARACTER))
+ self.dotest(root)
+
+ def test_frame_mark3(self):
+ name1 = self.mkname("frame")
+ name2 = self.mkname("bookmark")
+ root = TreeNode()
+ root.appendchild(TextNode("abc"))
+ root.appendchild(FrameNode(name1, AS_CHARACTER))
+ root.appendchild(TextNode("de"))
+ root.appendchild(BookmarkNode(name2))
+ self.dotest(root)
+
+ def test_frame_mark4(self):
+ name1 = self.mkname("frame")
+ name2 = self.mkname("bookmark")
+ root = TreeNode()
+ root.appendchild(TextNode("abc"))
+ root.appendchild(FrameNode(name1, AT_CHARACTER))
+ root.appendchild(TextNode("de"))
+ root.appendchild(BookmarkNode(name2))
+ self.dotest(root)
+
+ def test_frames1(self):
+ name1 = self.mkname("frame")
+ name2 = self.mkname("frame")
+ name3 = self.mkname("frame")
+ root = TreeNode()
+ root.appendchild(FrameNode(name1, AT_CHARACTER))
+ root.appendchild(FrameNode(name2, AT_CHARACTER))
+ root.appendchild(FrameNode(name3, AT_CHARACTER))
+ self.dotest(root)
+
+ def test_frames2(self):
+ name1 = self.mkname("frame")
+ name2 = self.mkname("frame")
+ name3 = self.mkname("frame")
+ root = TreeNode()
+ root.appendchild(FrameNode(name1, AS_CHARACTER))
+ root.appendchild(FrameNode(name2, AS_CHARACTER))
+ root.appendchild(FrameNode(name3, AS_CHARACTER))
+ self.dotest(root)
+
+ def test_frames3(self):
+ name1 = self.mkname("frame")
+ name2 = self.mkname("frame")
+ name3 = self.mkname("frame")
+ root = TreeNode()
+ root.appendchild(FrameNode(name1, AT_CHARACTER))
+ root.appendchild(FrameNode(name2, AS_CHARACTER))
+ root.appendchild(FrameNode(name3, AT_CHARACTER))
+ self.dotest(root)
+
+ def test_frames4(self):
+ name1 = self.mkname("frame")
+ name2 = self.mkname("frame")
+ name3 = self.mkname("frame")
+ root = TreeNode()
+ root.appendchild(FrameNode(name1, AT_CHARACTER))
+ root.appendchild(FrameNode(name2, AT_CHARACTER))
+ root.appendchild(FrameNode(name3, AS_CHARACTER))
+ self.dotest(root)
+
+ def test_frames5(self):
+ name1 = self.mkname("frame")
+ name2 = self.mkname("frame")
+ name3 = self.mkname("frame")
+ root = TreeNode()
+ root.appendchild(FrameNode(name1, AS_CHARACTER))
+ root.appendchild(FrameNode(name2, AT_CHARACTER))
+ root.appendchild(FrameNode(name3, AT_CHARACTER))
+ self.dotest(root)
+
+ def test_ruby_hyperlink1(self):
+ name1 = self.mkname("ruby")
+ name2 = self.mkname("url")
+ root = TreeNode()
+ ruby = RubyNode(name1)
+ href = HyperlinkNode(name2)
+ href.appendchild(TextNode("abc"))
+ ruby.appendchild(href)
+ root.appendchild(ruby)
+ self.dotest(root)
+
+ def test_ruby_hyperlink2(self):
+ name1 = self.mkname("url")
+ name2 = self.mkname("ruby")
+ root = TreeNode()
+ href = HyperlinkNode(name1)
+ ruby = RubyNode(name2)
+ ruby.appendchild(TextNode("abc"))
+ href.appendchild(ruby)
+ root.appendchild(href)
+ self.dotest(root)
+
+ def test_end1(self):
+ name1 = self.mkname("bookmark")
+ name2 = self.mkname("toxmark")
+ name3 = self.mkname("refmark")
+ root = TreeNode()
+ root.appendchild(TextNode("abc"))
+ root.appendchild(BookmarkNode(name1))
+ root.appendchild(DocumentIndexMarkNode(name2))
+ root.appendchild(ReferenceMarkNode(name3))
+ self.dotest(root)
+
+ def test_end2(self):
+ name1 = self.mkname("bookmark")
+ name2 = self.mkname("frame")
+ name3 = self.mkname("refmark")
+ name4 = self.mkname("frame")
+ name5 = self.mkname("frame")
+ root = TreeNode()
+ root.appendchild(TextNode("abc"))
+ root.appendchild(BookmarkStartNode(name1))
+ root.appendchild(FrameNode(name2, AT_CHARACTER))
+ root.appendchild(BookmarkEndNode(name1))
+ root.appendchild(ReferenceMarkNode(name3))
+ root.appendchild(FrameNode(name4, AT_CHARACTER))
+ root.appendchild(FrameNode(name5, AT_CHARACTER))
+ self.dotest(root)
+
+ def test_end3(self):
+ name1 = self.mkname("ftn")
+ name2 = self.mkname("toxmark")
+ root = TreeNode()
+ root.appendchild(TextNode("abc"))
+ root.appendchild(FootnoteNode(name1))
+ root.appendchild(DocumentIndexMarkNode(name2))
+ self.dotest(root)
+
+ def test_end4(self):
+ name1 = self.mkname("bookmark")
+ name2 = self.mkname("frame")
+ root = TreeNode()
+ root.appendchild(BookmarkStartNode(name1))
+ root.appendchild(TextNode("abc"))
+ root.appendchild(FrameNode(name2, AS_CHARACTER))
+ root.appendchild(BookmarkEndNode(name1))
+ self.dotest(root)
+
+ def test_end5(self):
+ name1 = self.mkname("refmark")
+ name2 = self.mkname("ruby")
+ root = TreeNode()
+ root.appendchild(ReferenceMarkStartNode(name1))
+ root.appendchild(TextNode("abc"))
+ ruby = RubyNode(name2)
+ ruby.appendchild(TextFieldNode("de"))
+ root.appendchild(ruby)
+ root.appendchild(ReferenceMarkEndNode(name1))
+ self.dotest(root)
+
+ def test_empty1(self):
+ name1 = self.mkname("refmark")
+ name2 = self.mkname("toxmark")
+ name3 = self.mkname("bookmark")
+ name4 = self.mkname("frame")
+ name7 = self.mkname("refmark")
+ name8 = self.mkname("toxmark")
+ name9 = self.mkname("bookmark")
+ nameA = self.mkname("frame")
+ root = TreeNode()
+ root.appendchild(ReferenceMarkNode(name1))
+ root.appendchild(DocumentIndexMarkNode(name2))
+ root.appendchild(BookmarkStartNode(name3))
+ root.appendchild(FrameNode(name4, AT_CHARACTER))
+ root.appendchild(BookmarkEndNode(name3))
+ root.appendchild(ReferenceMarkNode(name7))
+ root.appendchild(DocumentIndexMarkNode(name8))
+ root.appendchild(BookmarkStartNode(name9))
+ root.appendchild(FrameNode(nameA, AT_CHARACTER))
+ root.appendchild(BookmarkEndNode(name9))
+ self.dotest(root)
+
+ def test_empty2(self):
+ name3 = self.mkname("bookmark")
+ name4 = self.mkname("frame")
+ name9 = self.mkname("bookmark")
+ nameA = self.mkname("frame")
+ root = TreeNode()
+ root.appendchild(BookmarkStartNode(name3))
+ root.appendchild(FrameNode(name4, AT_CHARACTER))
+ root.appendchild(BookmarkEndNode(name3))
+ root.appendchild(BookmarkStartNode(name9))
+ root.appendchild(FrameNode(nameA, AT_CHARACTER))
+ root.appendchild(BookmarkEndNode(name9))
+ self.dotest(root)
+
+ def test_empty3(self):
+ name1 = self.mkname("refmark")
+ name2 = self.mkname("toxmark")
+ name3 = self.mkname("bookmark")
+ name4 = self.mkname("frame")
+ name5 = self.mkname("url")
+ name6 = self.mkname("ruby")
+ name7 = self.mkname("refmark")
+ name8 = self.mkname("toxmark")
+ name9 = self.mkname("bookmark")
+ nameA = self.mkname("frame")
+ root = TreeNode()
+ root.appendchild(ReferenceMarkNode(name1))
+ root.appendchild(DocumentIndexMarkNode(name2))
+ root.appendchild(BookmarkStartNode(name3))
+ root.appendchild(FrameNode(name4, AT_CHARACTER))
+ root.appendchild(BookmarkEndNode(name3))
+ ## currently empty hyperlinks may get eaten...
+ # href = HyperlinkNode(name5)
+ # href.appendchild(TextNode(""))
+ # root.appendchild(href)
+ ruby = RubyNode(name6)
+ root.appendchild(ruby)
+ root.appendchild(ReferenceMarkNode(name7))
+ root.appendchild(DocumentIndexMarkNode(name8))
+ root.appendchild(BookmarkStartNode(name9))
+ root.appendchild(FrameNode(nameA, AT_CHARACTER))
+ root.appendchild(BookmarkEndNode(name9))
+ self.dotest(root)
+
+ def test1(self):
+ name1 = self.mkname("frame")
+ name2 = self.mkname("bookmark")
+ name3 = self.mkname("ruby")
+ name4 = self.mkname("ftn")
+ name5 = self.mkname("frame")
+ root = TreeNode()
+ root.appendchild(FrameNode(name1, AT_CHARACTER))
+ root.appendchild(BookmarkStartNode(name2))
+ root.appendchild(TextNode("abc"))
+ ruby = RubyNode(name3)
+ ruby.appendchild(TextNode("de"))
+ ruby.appendchild(FootnoteNode(name4))
+ ruby.appendchild(BookmarkEndNode(name2))
+ root.appendchild(ruby)
+ root.appendchild(TextNode("fg"))
+ root.appendchild(FrameNode(name5, AT_CHARACTER))
+ root.appendchild(TextFieldNode("h"))
+ self.dotest(root)
+
+ # some range tests for the insertion: these are for the current
+ # API which treats hyperlinks and rubys not as entities, but as formatting
+ # attributes; if these ever become entities, they should not be split!'''
+
+ def test_range1(self):
+ name1 = self.mkname("url")
+ inserter = RangeInserter(self.__class__.xDoc)
+ text = TextNode("12345")
+ inserter.insertrange(Range(0, 0, text))
+ url1 = HyperlinkNode(name1)
+ range1 = Range(0, 5, url1)
+ inserter.insertrange(range1)
+ root = TreeNode()
+ root.appendchild(url1)
+ url1.appendchild(text)
+ self.dotest(root, False)
+
+ def test_range_hyperlink_hyperlink(self):
+ inserter = RangeInserter(self.__class__.xDoc)
+ text = TextNode("123456789")
+ inserter.insertrange(Range(0, 0, text))
+ url1 = HyperlinkNode(self.mkname("url"))
+ inserter.insertrange(Range(1, 4, url1))
+ ## overlap left
+ url2 = HyperlinkNode(self.mkname("url"))
+ inserter.insertrange(Range(0, 2, url2))
+ root = TreeNode()
+ root.appendchild(url2.dup().appendchild(TextNode("12")))
+ root.appendchild(url1.dup().appendchild(TextNode("34")))
+ root.appendchild(TextNode("56789"))
+ self.dotest(root, False)
+ ## overlap right
+ url3 = HyperlinkNode(self.mkname("url"))
+ inserter.insertrange(Range(3, 7, url3))
+ root = TreeNode()
+ root.appendchild(url2.dup().appendchild(TextNode("12")))
+ root.appendchild(url1.dup().appendchild(TextNode("3")))
+ root.appendchild(url3.dup().appendchild(TextNode("4567")))
+ root.appendchild(TextNode("89"))
+ self.dotest(root, False)
+ ## around
+ url4 = HyperlinkNode(self.mkname("url"))
+ inserter.insertrange(Range(3, 7, url4))
+ root = TreeNode()
+ root.appendchild(url2.dup().appendchild(TextNode("12")))
+ root.appendchild(url1.dup().appendchild(TextNode("3")))
+ root.appendchild(url4.dup().appendchild(TextNode("4567")))
+ root.appendchild(TextNode("89"))
+ self.dotest(root, False)
+ ## inside
+ url5 = HyperlinkNode(self.mkname("url"))
+ inserter.insertrange(Range(4, 6, url5))
+ root = TreeNode()
+ root.appendchild(url2.dup().appendchild(TextNode("12")))
+ root.appendchild(url1.dup().appendchild(TextNode("3")))
+ root.appendchild(url4.dup().appendchild(TextNode("4")))
+ root.appendchild(url5.dup().appendchild(TextNode("56")))
+ root.appendchild(url4.dup().appendchild(TextNode("7")))
+ root.appendchild(TextNode("89"))
+ self.dotest(root, False)
+ ## empty
+ url6 = HyperlinkNode(self.mkname("url"))
+ inserter.insertrange(Range(7, 7, url6))
+ root = TreeNode()
+ root.appendchild(url2.dup().appendchild(TextNode("12")))
+ root.appendchild(url1.dup().appendchild(TextNode("3")))
+ root.appendchild(url4.dup().appendchild(TextNode("4")))
+ root.appendchild(url5.dup().appendchild(TextNode("56")))
+ root.appendchild(url4.dup().appendchild(TextNode("7")))
+ ## this one gets eaten, but we still need to test inserting it (#i106930#)
+ # root.appendchild(url6.dup().appendchild(TextNode("")))
+ root.appendchild(TextNode("89"))
+ ## inside (left-edge)
+ url7 = HyperlinkNode(self.mkname("url"))
+ inserter.insertrange(Range(0, 1, url7))
+ root = TreeNode()
+ root.appendchild(url7.dup().appendchild(TextNode("1")))
+ root.appendchild(url2.dup().appendchild(TextNode("2")))
+ root.appendchild(url1.dup().appendchild(TextNode("3")))
+ root.appendchild(url4.dup().appendchild(TextNode("4")))
+ root.appendchild(url5.dup().appendchild(TextNode("56")))
+ root.appendchild(url4.dup().appendchild(TextNode("7")))
+ root.appendchild(TextNode("89"))
+ ## inside (right-edge)
+ url8 = HyperlinkNode(self.mkname("url"))
+ inserter.insertrange(Range(5, 6, url8))
+ root = TreeNode()
+ root.appendchild(url7.dup().appendchild(TextNode("1")))
+ root.appendchild(url2.dup().appendchild(TextNode("2")))
+ root.appendchild(url1.dup().appendchild(TextNode("3")))
+ root.appendchild(url4.dup().appendchild(TextNode("4")))
+ root.appendchild(url5.dup().appendchild(TextNode("5")))
+ root.appendchild(url8.dup().appendchild(TextNode("6")))
+ root.appendchild(url4.dup().appendchild(TextNode("7")))
+ root.appendchild(TextNode("89"))
+ self.dotest(root, False)
+
+ def test_range_hyperlink_ruby(self):
+ inserter = RangeInserter(self.__class__.xDoc)
+ text = TextNode("123456789")
+ inserter.insertrange(Range(0, 0, text))
+ url1 = HyperlinkNode(self.mkname("url"))
+ inserter.insertrange(Range(1, 4, url1))
+ # overlap left
+ rby2 = RubyNode(self.mkname("ruby"))
+ inserter.insertrange(Range(0, 2, rby2))
+ root = TreeNode()
+ root.appendchild(rby2.dup()
+ .appendchild(TextNode("1"))
+ .appendchild(url1.dup().appendchild(TextNode("2"))))
+ root.appendchild(url1.dup().appendchild(TextNode("34")))
+ root.appendchild(TextNode("56789"))
+ self.dotest(root, False)
+ # overlap right
+ rby3 = RubyNode(self.mkname("ruby"))
+ inserter.insertrange(Range(3, 5, rby3))
+ root = TreeNode()
+ root.appendchild(rby2.dup()
+ .appendchild(TextNode("1"))
+ .appendchild(url1.dup().appendchild(TextNode("2"))))
+ root.appendchild(url1.dup().appendchild(TextNode("3")))
+ root.appendchild(rby3.dup()
+ .appendchild(url1.dup().appendchild(TextNode("4")))
+ .appendchild(TextNode("5")))
+ root.appendchild(TextNode("6789"))
+ self.dotest(root, False)
+ # around
+ rby4 = RubyNode(self.mkname("ruby"))
+ inserter.insertrange(Range(2, 3, rby4))
+ root = TreeNode()
+ root.appendchild(rby2.dup()
+ .appendchild(TextNode("1"))
+ .appendchild(url1.dup().appendchild(TextNode("2"))))
+ root.appendchild(rby4.dup()
+ .appendchild(url1.dup().appendchild(TextNode("3"))))
+ root.appendchild(rby3.dup()
+ .appendchild(url1.dup().appendchild(TextNode("4")))
+ .appendchild(TextNode("5")))
+ root.appendchild(TextNode("6789"))
+ self.dotest(root, False)
+ # inside
+ url5 = HyperlinkNode(self.mkname("url"))
+ inserter.insertrange(Range(6, 9, url5))
+ rby6 = RubyNode(self.mkname("ruby"))
+ inserter.insertrange(Range(7, 8, rby6))
+ root = TreeNode()
+ root.appendchild(rby2.dup()
+ .appendchild(TextNode("1"))
+ .appendchild(url1.dup().appendchild(TextNode("2"))))
+ root.appendchild(rby4.dup()
+ .appendchild(url1.dup().appendchild(TextNode("3"))))
+ root.appendchild(rby3.dup()
+ .appendchild(url1.dup().appendchild(TextNode("4")))
+ .appendchild(TextNode("5")))
+ root.appendchild(TextNode("6"))
+ root.appendchild(url5.dup().appendchild(TextNode("7")))
+ root.appendchild(rby6.dup()
+ .appendchild(url5.dup().appendchild(TextNode("8"))))
+ root.appendchild(url5.dup().appendchild(TextNode("9")))
+ self.dotest(root, False)
+
+ def test_range_ruby_hyperlink(self):
+ inserter = RangeInserter(self.__class__.xDoc)
+ text = TextNode("123456789")
+ inserter.insertrange(Range(0, 0, text))
+ rby1 = RubyNode(self.mkname("ruby"))
+ inserter.insertrange(Range(1, 6, rby1))
+ ## overlap left
+ url2 = HyperlinkNode(self.mkname("url"))
+ inserter.insertrange(Range(0, 3, url2))
+ root = TreeNode()
+ root.appendchild(url2.dup().appendchild(TextNode("1")))
+ root.appendchild(rby1.dup()
+ .appendchild(url2.dup().appendchild(TextNode("23")))
+ .appendchild(TextNode("456")))
+ root.appendchild(TextNode("789"))
+ self.dotest(root, False)
+ ## overlap right
+ url3 = HyperlinkNode(self.mkname("url"))
+ inserter.insertrange(Range(5, 7, url3))
+ root = TreeNode()
+ root.appendchild(url2.dup().appendchild(TextNode("1")))
+ root.appendchild(rby1.dup()
+ .appendchild(url2.dup().appendchild(TextNode("23")))
+ .appendchild(TextNode("45"))
+ .appendchild(url3.dup().appendchild(TextNode("6"))))
+ root.appendchild(url3.dup().appendchild(TextNode("7")))
+ root.appendchild(TextNode("89"))
+ self.dotest(root, False)
+ ## around (not quite, due to API)
+ url4 = HyperlinkNode(self.mkname("url"))
+ inserter.insertrange(Range(1, 8, url4))
+ root = TreeNode()
+ root.appendchild(url2.dup().appendchild(TextNode("1")))
+ root.appendchild(rby1.dup()
+ .appendchild(url4.dup()
+ .appendchild(TextNode("23456"))))
+ root.appendchild(url4.dup().appendchild(TextNode("78")))
+ root.appendchild(TextNode("9"))
+ self.dotest(root, False)
+ ## inside
+ url5 = HyperlinkNode(self.mkname("url"))
+ inserter.insertrange(Range(3, 5, url5))
+ root = TreeNode()
+ root.appendchild(url2.dup().appendchild(TextNode("1")))
+ root.appendchild(rby1.dup()
+ .appendchild(url4.dup()
+ .appendchild(TextNode("23")))
+ .appendchild(url5.dup()
+ .appendchild(TextNode("45")))
+ .appendchild(url4.dup()
+ .appendchild(TextNode("6"))))
+ root.appendchild(url4.dup().appendchild(TextNode("78")))
+ root.appendchild(TextNode("9"))
+ self.dotest(root, False)
+
+ def test_range_ruby_ruby(self):
+ inserter = RangeInserter(self.__class__.xDoc)
+ text = TextNode("123456789")
+ inserter.insertrange(Range(0, 0, text))
+ rby1 = RubyNode(self.mkname("ruby"))
+ inserter.insertrange(Range(1, 4, rby1))
+ ## overlap left
+ rby2 = RubyNode(self.mkname("ruby"))
+ inserter.insertrange(Range(0, 2, rby2))
+ root = TreeNode()
+ root.appendchild(rby2.dup().appendchild(TextNode("12")))
+ root.appendchild(rby1.dup().appendchild(TextNode("34")))
+ root.appendchild(TextNode("56789"))
+ self.dotest(root, False)
+ ## overlap right
+ rby3 = RubyNode(self.mkname("ruby"))
+ inserter.insertrange(Range(3, 7, rby3))
+ root = TreeNode()
+ root.appendchild(rby2.dup().appendchild(TextNode("12")))
+ root.appendchild(rby1.dup().appendchild(TextNode("3")))
+ root.appendchild(rby3.dup().appendchild(TextNode("4567")))
+ root.appendchild(TextNode("89"))
+ self.dotest(root, False)
+ ## around
+ rby4 = RubyNode(self.mkname("ruby"))
+ inserter.insertrange(Range(3, 7, rby4))
+ root = TreeNode()
+ root.appendchild(rby2.dup().appendchild(TextNode("12")))
+ root.appendchild(rby1.dup().appendchild(TextNode("3")))
+ root.appendchild(rby4.dup().appendchild(TextNode("4567")))
+ root.appendchild(TextNode("89"))
+ self.dotest(root, False)
+ ## inside
+ rby5 = RubyNode(self.mkname("ruby"))
+ inserter.insertrange(Range(4, 6, rby5))
+ root = TreeNode()
+ root.appendchild(rby2.dup().appendchild(TextNode("12")))
+ root.appendchild(rby1.dup().appendchild(TextNode("3")))
+ root.appendchild(rby4.dup().appendchild(TextNode("4")))
+ root.appendchild(rby5.dup().appendchild(TextNode("56")))
+ root.appendchild(rby4.dup().appendchild(TextNode("7")))
+ root.appendchild(TextNode("89"))
+ self.dotest(root, False)
+
+ def test_range_hyperlink_meta(self):
+ inserter = RangeInserter(self.__class__.xDoc)
+ text = TextNode("123456789")
+ inserter.insertrange(Range(0, 0, text))
+ url1 = HyperlinkNode(self.mkname("url"))
+ inserter.insertrange(Range(1, 4, url1))
+ ## overlap left
+ met2 = MetaNode(self.mkid("id"))
+ inserter.insertrange(Range(0, 2, met2))
+ root = TreeNode()
+ root.appendchild(met2.dup()
+ .appendchild(TextNode("1"))
+ .appendchild(url1.dup().appendchild(TextNode("2"))))
+ root.appendchild(url1.dup().appendchild(TextNode("34")))
+ root.appendchild(TextNode("56789"))
+ self.dotest(root, False)
+ ## overlap right
+ met3 = MetaNode(self.mkid("id"))
+ # inserter.insertrange(Range(4-1, 6-1, met3))
+ inserter.insertrange(Range(4, 6, met3))
+ root = TreeNode()
+ root.appendchild(met2.dup()
+ .appendchild(TextNode("1"))
+ .appendchild(url1.dup().appendchild(TextNode("2"))))
+ root.appendchild(url1.dup().appendchild(TextNode("3")))
+ root.appendchild(met3.dup()
+ .appendchild(url1.dup().appendchild(TextNode("4")))
+ .appendchild(TextNode("5")))
+ root.appendchild(TextNode("6789"))
+ self.dotest(root, False)
+ ## around
+ met4 = MetaNode(self.mkid("id"))
+ # inserter.insertrange(Range(3-1, 4-1, met4))
+ inserter.insertrange(Range(3, 4, met4))
+ root = TreeNode()
+ root.appendchild(met2.dup()
+ .appendchild(TextNode("1"))
+ .appendchild(url1.dup().appendchild(TextNode("2"))))
+ root.appendchild(met4.dup()
+ .appendchild(url1.dup().appendchild(TextNode("3"))))
+ root.appendchild(met3.dup()
+ .appendchild(url1.dup().appendchild(TextNode("4")))
+ .appendchild(TextNode("5")))
+ root.appendchild(TextNode("6789"))
+ self.dotest(root, False)
+ ## inside
+ url5 = HyperlinkNode(self.mkname("url"))
+ # inserter.insertrange(Range(9-3, 12-3, url5))
+ inserter.insertrange(Range(9, 12, url5))
+ met6 = MetaNode(self.mkid("id"))
+ # inserter.insertrange(Range(10-3, 11-3, met6))
+ inserter.insertrange(Range(10, 11, met6))
+ root = TreeNode()
+ root.appendchild(met2.dup()
+ .appendchild(TextNode("1"))
+ .appendchild(url1.dup().appendchild(TextNode("2"))))
+ root.appendchild(met4.dup()
+ .appendchild(url1.dup().appendchild(TextNode("3"))))
+ root.appendchild(met3.dup()
+ .appendchild(url1.dup().appendchild(TextNode("4")))
+ .appendchild(TextNode("5")))
+ root.appendchild(TextNode("6"))
+ root.appendchild(url5.dup().appendchild(TextNode("7")))
+ root.appendchild(met6.dup()
+ .appendchild(url5.dup().appendchild(TextNode("8"))))
+ root.appendchild(url5.dup().appendchild(TextNode("9")))
+ self.dotest(root, False)
+
+ def test_range_ruby_meta(self):
+ inserter = RangeInserter(self.__class__.xDoc)
+ text = TextNode("123456789")
+ inserter.insertrange(Range(0, 0, text))
+ rby1 = RubyNode(self.mkname("ruby"))
+ inserter.insertrange(Range(1, 4, rby1))
+ ## overlap left
+ met2 = MetaNode(self.mkid("id"))
+ inserter.insertrange(Range(0, 2, met2))
+ root = TreeNode()
+ root.appendchild(met2.dup()
+ .appendchild(TextNode("1"))
+ .appendchild(rby1.dup().appendchild(TextNode("2"))))
+ root.appendchild(rby1.dup().appendchild(TextNode("34")))
+ root.appendchild(TextNode("56789"))
+ self.dotest(root, False)
+ ## overlap right
+ met3 = MetaNode(self.mkid("id"))
+ # inserter.insertrange(Range(4-1, 6-1, met3))
+ inserter.insertrange(Range(4, 6, met3))
+ root = TreeNode()
+ root.appendchild(met2.dup()
+ .appendchild(TextNode("1"))
+ .appendchild(rby1.dup().appendchild(TextNode("2"))))
+ root.appendchild(rby1.dup().appendchild(TextNode("3")))
+ root.appendchild(met3.dup()
+ .appendchild(rby1.dup().appendchild(TextNode("4")))
+ .appendchild(TextNode("5")))
+ root.appendchild(TextNode("6789"))
+ self.dotest(root, False)
+ ## around
+ met4 = MetaNode(self.mkid("id"))
+ # inserter.insertrange(Range(3-1, 4-1, met4))
+ inserter.insertrange(Range(3, 4, met4))
+ root = TreeNode()
+ root.appendchild(met2.dup()
+ .appendchild(TextNode("1"))
+ .appendchild(rby1.dup().appendchild(TextNode("2"))))
+ root.appendchild(met4.dup()
+ .appendchild(rby1.dup().appendchild(TextNode("3"))))
+ root.appendchild(met3.dup()
+ .appendchild(rby1.dup().appendchild(TextNode("4")))
+ .appendchild(TextNode("5")))
+ root.appendchild(TextNode("6789"))
+ self.dotest(root, False)
+ ## inside
+ rby5 = RubyNode(self.mkname("ruby"))
+ # inserter.insertrange(Range(9-3, 12-3, rby5))
+ inserter.insertrange(Range(9, 12, rby5))
+ met6 = MetaNode(self.mkid("id"))
+ # inserter.insertrange(Range(10-3, 11-3, met6))
+ inserter.insertrange(Range(10, 11, met6))
+ root = TreeNode()
+ root.appendchild(met2.dup()
+ .appendchild(TextNode("1"))
+ .appendchild(rby1.dup().appendchild(TextNode("2"))))
+ root.appendchild(met4.dup()
+ .appendchild(rby1.dup().appendchild(TextNode("3"))))
+ root.appendchild(met3.dup()
+ .appendchild(rby1.dup().appendchild(TextNode("4")))
+ .appendchild(TextNode("5")))
+ root.appendchild(TextNode("6"))
+ root.appendchild(rby5.dup()
+ .appendchild(TextNode("7"))
+ .appendchild(met6.dup()
+ .appendchild(TextNode("8")))
+ .appendchild(TextNode("9")))
+ self.dotest(root, False)
+
+ def test_range_meta_hyperlink(self):
+ inserter = RangeInserter(self.__class__.xDoc)
+ text = TextNode("123456789")
+ inserter.insertrange(Range(0, 0, text))
+ met1 = MetaNode(self.mkid("id"))
+ inserter.insertrange(Range(1, 6, met1))
+ ## overlap left
+ url2 = HyperlinkNode(self.mkname("url"))
+ # inserter.insertrange(Range(0, 4-1, url2))
+ inserter.insertrange(Range(0, 4, url2))
+ root = TreeNode()
+ root.appendchild(url2.dup().appendchild(TextNode("1")))
+ root.appendchild(met1.dup()
+ .appendchild(url2.dup().appendchild(TextNode("23")))
+ .appendchild(TextNode("456")))
+ root.appendchild(TextNode("789"))
+ self.dotest(root, False)
+ ## overlap right
+ url3 = HyperlinkNode(self.mkname("url"))
+ # inserter.insertrange(Range(6-1, 8-1, url3))
+ inserter.insertrange(Range(6, 8, url3))
+ root = TreeNode()
+ root.appendchild(url2.dup().appendchild(TextNode("1")))
+ root.appendchild(met1.dup()
+ .appendchild(url2.dup().appendchild(TextNode("23")))
+ .appendchild(TextNode("45"))
+ .appendchild(url3.dup().appendchild(TextNode("6"))))
+ root.appendchild(url3.dup().appendchild(TextNode("7")))
+ root.appendchild(TextNode("89"))
+ self.dotest(root, False)
+ ## around (not quite, due to API)
+ url4 = HyperlinkNode(self.mkname("url"))
+ # inserter.insertrange(Range(1, 9-1, url4))
+ inserter.insertrange(Range(1, 9, url4))
+ root = TreeNode()
+ root.appendchild(url2.dup().appendchild(TextNode("1")))
+ root.appendchild(met1.dup()
+ .appendchild(url4.dup()
+ .appendchild(TextNode("23456"))))
+ root.appendchild(url4.dup().appendchild(TextNode("78")))
+ root.appendchild(TextNode("9"))
+ self.dotest(root, False)
+ ## inside
+ url5 = HyperlinkNode(self.mkname("url"))
+ # inserter.insertrange(Range(4-1, 6-1, url5))
+ inserter.insertrange(Range(4, 6, url5))
+ root = TreeNode()
+ root.appendchild(url2.dup().appendchild(TextNode("1")))
+ root.appendchild(met1.dup()
+ .appendchild(url4.dup()
+ .appendchild(TextNode("23")))
+ .appendchild(url5.dup()
+ .appendchild(TextNode("45")))
+ .appendchild(url4.dup()
+ .appendchild(TextNode("6"))))
+ root.appendchild(url4.dup().appendchild(TextNode("78")))
+ root.appendchild(TextNode("9"))
+ self.dotest(root, False)
+
+ def test_range_meta_ruby(self):
+ inserter = RangeInserter(self.__class__.xDoc)
+ text = TextNode("123456789")
+ inserter.insertrange(Range(0, 0, text))
+ met1 = MetaNode(self.mkid("id"))
+ inserter.insertrange(Range(1, 5, met1))
+ ## overlap left
+ rby2 = RubyNode(self.mkname("ruby"))
+ # inserter.insertrange(Range(0, 3-1, rby2))
+ inserter.insertrange(Range(0, 3, rby2))
+ root = TreeNode()
+ root.appendchild(rby2.dup().appendchild(TextNode("1")))
+ root.appendchild(met1.dup()
+ .appendchild(rby2.dup().appendchild(TextNode("2")))
+ .appendchild(TextNode("345")))
+ root.appendchild(TextNode("6789"))
+ self.dotest(root, False)
+ ## overlap right
+ rby3 = RubyNode(self.mkname("ruby"))
+ # inserter.insertrange(Range(5-1, 7-1, rby3))
+ inserter.insertrange(Range(5, 7, rby3))
+ root = TreeNode()
+ root.appendchild(rby2.dup().appendchild(TextNode("1")))
+ root.appendchild(met1.dup()
+ .appendchild(rby2.dup().appendchild(TextNode("2")))
+ .appendchild(TextNode("34"))
+ .appendchild(rby3.dup().appendchild(TextNode("5"))))
+ root.appendchild(rby3.dup().appendchild(TextNode("6")))
+ root.appendchild(TextNode("789"))
+ self.dotest(root, False)
+ ## // around
+ rby4 = RubyNode(self.mkname("ruby"))
+ # inserter.insertrange(Range(1, 7-1, rby4))
+ inserter.insertrange(Range(1, 7, rby4))
+ root = TreeNode()
+ root.appendchild(rby2.dup().appendchild(TextNode("1")))
+ root.appendchild(rby4.dup()
+ .appendchild(met1.dup()
+ .appendchild(TextNode("2345")))
+ .appendchild(TextNode("6")))
+ root.appendchild(TextNode("789"))
+ self.dotest(root, False)
+ ## inside
+ met5 = MetaNode(self.mkid("id"))
+ # inserter.insertrange(Range(7-1, 9-1, met5))
+ inserter.insertrange(Range(7, 9, met5))
+ rby6 = RubyNode(self.mkname("ruby"))
+ # inserter.insertrange(Range(9-2, 10/-2, rby6))
+ inserter.insertrange(Range(9, 10, rby6))
+ root = TreeNode()
+ root.appendchild(rby2.dup().appendchild(TextNode("1")))
+ root.appendchild(rby4.dup()
+ .appendchild(met1.dup()
+ .appendchild(TextNode("2345")))
+ .appendchild(TextNode("6")))
+ root.appendchild(met5.dup()
+ .appendchild(TextNode("7"))
+ .appendchild(rby6.dup()
+ .appendchild(TextNode("8"))))
+ root.appendchild(TextNode("9"))
+ self.dotest(root, False)
+ ## inside, with invalid range that includes the dummy char
+ rby7 = RubyNode(self.mkname("ruby"))
+ # inserter.insertrange(Range(7-1, 9-2, rby7))
+ inserter.insertrange(Range(7, 9, rby7))
+ root = TreeNode()
+ root.appendchild(rby2.dup().appendchild(TextNode("1")))
+ root.appendchild(rby4.dup()
+ .appendchild(met1.dup()
+ .appendchild(TextNode("2345")))
+ .appendchild(TextNode("6")))
+ root.appendchild(met5.dup()
+ .appendchild(rby7.dup()
+ .appendchild(TextNode("7")))
+ .appendchild(rby6.dup()
+ .appendchild(TextNode("8"))))
+ root.appendchild(TextNode("9"))
+ self.dotest(root, False)
+ ## around, at same position as meta
+ rby8 = RubyNode(self.mkname("ruby"))
+ # inserter.insertrange(Range(7-1, 10-2, rby8))
+ inserter.insertrange(Range(7, 10, rby8))
+ root = TreeNode()
+ root.appendchild(rby2.dup().appendchild(TextNode("1")))
+ root.appendchild(rby4.dup()
+ .appendchild(met1.dup()
+ .appendchild(TextNode("2345")))
+ .appendchild(TextNode("6")))
+ root.appendchild(rby8.dup()
+ .appendchild(met5.dup()
+ .appendchild(TextNode("78"))))
+ root.appendchild(TextNode("9"))
+ self.dotest(root, False)
+
+ def test_range_meta_meta(self):
+ inserter = RangeInserter(self.__class__.xDoc)
+ text = TextNode("123456789")
+ inserter.insertrange(Range(0, 0, text))
+ met1 = MetaNode(self.mkid("id"))
+ inserter.insertrange(Range(3, 6, met1))
+ ## overlap left
+ met2 = MetaNode(self.mkid("id"))
+ try:
+ inserter.insertrange(Range(0, 4, met2))
+ fail("testRangeMetaMeta: overlap left allowed")
+ except IllegalArgumentException:
+ pass
+ root = TreeNode()
+ root.appendchild(TextNode("123"))
+ root.appendchild(met1.dup().appendchild(TextNode("456")))
+ root.appendchild(TextNode("789"))
+ self.dotest(root, False)
+ ## overlap right
+ met3 = MetaNode(self.mkid("id"))
+
+ try:
+ # inserter.insertrange(Range(5-1, 8-1, met3))
+ inserter.insertrange(Range(5, 8, met3))
+ self.fail("testRangeMetaMeta: overlap right allowed")
+ except IllegalArgumentException:
+ pass
+
+ root = TreeNode()
+ root.appendchild(TextNode("123"))
+ root.appendchild(met1.dup().appendchild(TextNode("456")))
+ root.appendchild(TextNode("789"))
+ self.dotest(root, False)
+ ## around
+ met4 = MetaNode(self.mkid("id"))
+ # inserter.insertrange(Range(3, 7-1, met4))
+ inserter.insertrange(Range(3, 7, met4))
+ root = TreeNode()
+ root.appendchild(TextNode("123"))
+ root.appendchild(met4.dup()
+ .appendchild(met1.dup().appendchild(TextNode("456"))))
+ root.appendchild(TextNode("789"))
+ self.dotest(root, False)
+ ## inside
+ met5 = MetaNode(self.mkid("id"))
+ # inserter.insertrange(Range(6-2, 8-2, met5))
+ inserter.insertrange(Range(6, 8, met5))
+ root = TreeNode()
+ root.appendchild(TextNode("123"))
+ root.appendchild(met4.dup()
+ .appendchild(met1.dup()
+ .appendchild(TextNode("4"))
+ .appendchild(met5.dup()
+ .appendchild(TextNode("56")))))
+ root.appendchild(TextNode("789"))
+ self.dotest(root, False)
+
+ def test_range2(self):
+ inserter = RangeInserter(self.__class__.xDoc)
+ text = TextNode("123456789")
+ inserter.insertrange(Range(0, 0, text))
+ met1 = MetaNode(self.mkid("id"))
+ inserter.insertrange(Range(1, 8, met1))
+ met2 = MetaNode(self.mkid("id"))
+ # inserter.insertrange(Range(3-1, 8-1, met2))
+ inserter.insertrange(Range(3, 8, met2))
+ met3 = MetaNode(self.mkid("id"))
+ # inserter.insertrange(Range(5-2, 8-2, met3))
+ inserter.insertrange(Range(5, 8, met3))
+ root = TreeNode()
+ root.appendchild(TextNode("1"))
+ root.appendchild(met1.dup()
+ .appendchild(TextNode("2"))
+ .appendchild(met2.dup()
+ .appendchild(TextNode("3"))
+ .appendchild(met3.dup()
+ .appendchild(TextNode("456")))
+ .appendchild(TextNode("7")))
+ .appendchild(TextNode("8")))
+ root.appendchild(TextNode("9"))
+ self.dotest(root, False)
+ ## split ruby at every meta start!
+ rby4 = RubyNode(self.mkname("ruby"))
+ # inserter.insertrange(Range(0, 7-3, rby4))
+ inserter.insertrange(Range(0, 7, rby4))
+ root = TreeNode()
+ root.appendchild(rby4.dup()
+ .appendchild(TextNode("1")))
+ root.appendchild(met1.dup()
+ .appendchild(rby4.dup()
+ .appendchild(TextNode("2")))
+ .appendchild(met2.dup()
+ .appendchild(rby4.dup()
+ .appendchild(TextNode("3")))
+ .appendchild(met3.dup()
+ .appendchild(rby4.dup()
+ .appendchild(TextNode("4")))
+ .appendchild(TextNode("56")))
+ .appendchild(TextNode("7")))
+ .appendchild(TextNode("8")))
+ root.appendchild(TextNode("9"))
+ self.dotest(root, False)
+ ## split ruby at every meta end!
+ rby5 = RubyNode(self.mkname("ruby"))
+ # inserter.insertrange(Range(8-3, 12-3, rby5))
+ inserter.insertrange(Range(8, 12, rby5))
+ root = TreeNode()
+ root.appendchild(rby4.dup()
+ .appendchild(TextNode("1")))
+ root.appendchild(met1.dup()
+ .appendchild(rby4.dup()
+ .appendchild(TextNode("2")))
+ .appendchild(met2.dup()
+ .appendchild(rby4.dup()
+ .appendchild(TextNode("3")))
+ .appendchild(met3.dup()
+ .appendchild(rby4.dup()
+ .appendchild(TextNode("4")))
+ .appendchild(TextNode("5"))
+ .appendchild(rby5.dup()
+ .appendchild(TextNode("6"))))
+ .appendchild(rby5.dup()
+ .appendchild(TextNode("7"))))
+ .appendchild(rby5.dup()
+ .appendchild(TextNode("8"))))
+ root.appendchild(rby5.dup()
+ .appendchild(TextNode("9")))
+ self.dotest(root, False)
+
+ def test_range3(self):
+ inserter = RangeInserter(self.__class__.xDoc)
+ text = TextNode("123456789")
+ inserter.insertrange(Range(0, 0, text))
+ rby1 = RubyNode(self.mkname("ruby"))
+ inserter.insertrange(Range(0, 9, rby1))
+ met2 = MetaNode(self.mkid("id"))
+ inserter.insertrange(Range(2, 7, met2))
+ root = TreeNode()
+ root.appendchild(rby1.dup()
+ .appendchild(TextNode("12"))
+ .appendchild(met2.dup()
+ .appendchild(TextNode("34567")))
+ .appendchild(TextNode("89")))
+ self.dotest(root, False)
+ ## overwrite outer ruby, split remains at inner meta!
+ rby3 = RubyNode(self.mkname("ruby"))
+ # inserter.insertrange(Range(5-1, 6-1, rby3))
+ inserter.insertrange(Range(5, 6, rby3))
+ root = TreeNode()
+ root.appendchild(rby1.dup()
+ .appendchild(TextNode("12")))
+ root.appendchild(met2.dup()
+ .appendchild(rby1.dup()
+ .appendchild(TextNode("34")))
+ .appendchild(rby3.dup()
+ .appendchild(TextNode("5")))
+ .appendchild(rby1.dup()
+ .appendchild(TextNode("67"))))
+ root.appendchild(rby1.dup()
+ .appendchild(TextNode("89")))
+ self.dotest(root, False)
+
+ def test_range4(self):
+ inserter = RangeInserter(self.__class__.xDoc)
+ text = TextNode("123456789")
+ inserter.insertrange(Range(0, 0, text))
+ rby1 = RubyNode(self.mkname("ruby"))
+ inserter.insertrange(Range(0, 9, rby1))
+ met2 = MetaNode(self.mkid("id"))
+ inserter.insertrange(Range(1, 8, met2))
+ met3 = MetaNode(self.mkid("id"))
+ # inserter.insertrange(Range(3-1, 8-1, met3))
+ inserter.insertrange(Range(3, 8, met3))
+ met4 = MetaNode(self.mkid("id"))
+ # inserter.insertrange(Range(5-2, 8-2, met4))
+ inserter.insertrange(Range(5, 8, met4))
+ root = TreeNode()
+ root.appendchild(rby1.dup()
+ .appendchild(TextNode("1"))
+ .appendchild(met2.dup()
+ .appendchild(TextNode("2"))
+ .appendchild(met3.dup()
+ .appendchild(TextNode("3"))
+ .appendchild(met4.dup()
+ .appendchild(TextNode("456")))
+ .appendchild(TextNode("7")))
+ .appendchild(TextNode("8")))
+ .appendchild(TextNode("9")))
+ self.dotest(root, False)
+ ## overwrite outer ruby, split remains at every inner meta!
+ rby5 = RubyNode(self.mkname("ruby"))
+ # inserter.insertrange(Range(7-3, 8-3, rby5))
+ inserter.insertrange(Range(7, 8, rby5))
+ root = TreeNode()
+ root.appendchild(rby1.dup()
+ .appendchild(TextNode("1")))
+ root.appendchild(met2.dup()
+ .appendchild(rby1.dup()
+ .appendchild(TextNode("2")))
+ .appendchild(met3.dup()
+ .appendchild(rby1.dup()
+ .appendchild(TextNode("3")))
+ .appendchild(met4.dup()
+ .appendchild(rby1.dup()
+ .appendchild(TextNode("4")))
+ .appendchild(rby5.dup()
+ .appendchild(TextNode("5")))
+ .appendchild(rby1.dup()
+ .appendchild(TextNode("6"))))
+ .appendchild(rby1.dup()
+ .appendchild(TextNode("7"))))
+ .appendchild(rby1.dup()
+ .appendchild(TextNode("8"))))
+ root.appendchild(rby1.dup()
+ .appendchild(TextNode("9")))
+ self.dotest(root, False)
+
+ def test_range5(self):
+ inserter = RangeInserter(self.__class__.xDoc)
+ text = TextNode("123456789")
+ inserter.insertrange(Range(0, 0, text))
+ rby1 = RubyNode(self.mkname("ruby"))
+ inserter.insertrange(Range(0, 9, rby1))
+ met2 = MetaNode(self.mkid("id"))
+ inserter.insertrange(Range(1, 3, met2))
+ met3 = MetaNode(self.mkid("id"))
+ # inserter.insertrange(Range(5-1, 6-1, met3))
+ inserter.insertrange(Range(5, 6, met3))
+ met4 = MetaNode(self.mkid("id"))
+ # inserter.insertrange(Range(8-2, 10-2, met4))
+ inserter.insertrange(Range(8, 10, met4))
+ root = TreeNode()
+ root.appendchild(rby1.dup()
+ .appendchild(TextNode("1"))
+ .appendchild(met2.dup().appendchild(TextNode("23")))
+ .appendchild(TextNode("4"))
+ .appendchild(met3.dup().appendchild(TextNode("5")))
+ .appendchild(TextNode("6"))
+ .appendchild(met4.dup().appendchild(TextNode("78")))
+ .appendchild(TextNode("9")))
+ self.dotest(root, False)
+ ## overwrite outer ruby, but split at inner metas!
+ rby5 = RubyNode(self.mkname("ruby"))
+ # inserter.insertrange(Range(3-1, 10-3, rby5))
+ inserter.insertrange(Range(3, 10, rby5))
+ root = TreeNode()
+ root.appendchild(rby1.dup()
+ .appendchild(TextNode("1")))
+ root.appendchild(met2.dup()
+ .appendchild(rby1.dup()
+ .appendchild(TextNode("2")))
+ .appendchild(rby5.dup()
+ .appendchild(TextNode("3"))))
+ root.appendchild(rby5.dup()
+ .appendchild(TextNode("4"))
+ .appendchild(met3.dup()
+ .appendchild(TextNode("5")))
+ .appendchild(TextNode("6")))
+ root.appendchild(met4.dup()
+ .appendchild(rby5.dup()
+ .appendchild(TextNode("7")))
+ .appendchild(rby1.dup()
+ .appendchild(TextNode("8"))))
+ root.appendchild(rby1.dup()
+ .appendchild(TextNode("9")))
+ self.dotest(root, False)
+
+ def test_range6(self):
+ inserter = RangeInserter(self.__class__.xDoc)
+ text = TextNode("123456789")
+ inserter.insertrange(Range(0, 0, text))
+ met1 = MetaNode(self.mkid("id"))
+ inserter.insertrange(Range(1, 5, met1))
+ met2 = MetaNode(self.mkid("id"))
+ # inserter.insertrange(Range(3-1, 6-1, met2))
+ inserter.insertrange(Range(3, 6, met2))
+ met3 = MetaNode(self.mkid("id"))
+ # inserter.insertrange(Range(5-2, 7-2, met3))
+ inserter.insertrange(Range(5, 7, met3))
+ root = TreeNode()
+ root.appendchild(TextNode("1"))
+ root.appendchild(met1.dup()
+ .appendchild(TextNode("2"))
+ .appendchild(met2.dup()
+ .appendchild(TextNode("3"))
+ .appendchild(met3.dup()
+ .appendchild(TextNode("45")))))
+ root.appendchild(TextNode("6789"))
+ self.dotest(root, False)
+ ## split at 3 metas, all at same position
+ rby4 = RubyNode(self.mkname("ruby"))
+ # inserter.insertrange(Range(7-3, 10-3, rby4))
+ inserter.insertrange(Range(7, 10, rby4))
+ root = TreeNode()
+ root.appendchild(TextNode("1"))
+ root.appendchild(met1.dup()
+ .appendchild(TextNode("2"))
+ .appendchild(met2.dup()
+ .appendchild(TextNode("3"))
+ .appendchild(met3.dup()
+ .appendchild(TextNode("4"))
+ .appendchild(rby4.dup()
+ .appendchild(TextNode("5"))))))
+ root.appendchild(rby4.dup()
+ .appendchild(TextNode("67")))
+ root.appendchild(TextNode("89"))
+ self.dotest(root, False)
+
+ def test_range7(self):
+ inserter = RangeInserter(self.__class__.xDoc)
+ text = TextNode("123456789")
+ inserter.insertrange(Range(0, 0, text))
+ url1 = HyperlinkNode(self.mkname("url"))
+ inserter.insertrange(Range(1, 5, url1))
+ met2 = MetaNode(self.mkid("id"))
+ inserter.insertrange(Range(3, 5, met2))
+ root = TreeNode()
+ root.appendchild(TextNode("1"))
+ root.appendchild(url1.dup()
+ .appendchild(TextNode("23")))
+ root.appendchild(met2.dup()
+ .appendchild(url1.dup()
+ .appendchild(TextNode("45"))))
+ root.appendchild(TextNode("6789"))
+ self.dotest(root, False)
+ ## this should result in not splitting the hyperlink, but due to API
+ ## we can't tell :(
+ rby3 = RubyNode(self.mkname("ruby"))
+ # inserter.insertrange(Range(5-1, 8-1, rby3))
+ inserter.insertrange(Range(5, 8, rby3))
+ root = TreeNode()
+ root.appendchild(TextNode("1"))
+ root.appendchild(url1.dup()
+ .appendchild(TextNode("23")))
+ root.appendchild(met2.dup()
+ .appendchild(url1.dup()
+ .appendchild(TextNode("4")))
+ .appendchild(rby3.dup()
+ .appendchild(url1.dup()
+ .appendchild(TextNode("5")))))
+ root.appendchild(rby3.dup()
+ .appendchild(TextNode("67")))
+ root.appendchild(TextNode("89"))
+ self.dotest(root, False)
+
+ # TODO: test partial selection, test UNDO/REDO
+
+ ##i109601# NestedTextContent and XChild
+ def test_meta_xchild(self):
+ xDoc = self.__class__.xDoc
+ id1 = StringPair("content.xml", self.mkname("id"))
+ id2 = StringPair("content.xml", self.mkname("id"))
+ id3 = StringPair("content.xml", self.mkname("id"))
+ id4 = StringPair("content.xml", self.mkname("id"))
+ id5 = StringPair("content.xml", self.mkname("id"))
+ id6 = StringPair("content.xml", self.mkname("id"))
+ meta1 = MetaNode(id1)
+ meta2 = MetaNode(id2)
+ meta3 = MetaFieldNode(id3)
+ meta4 = MetaNode(id4)
+ meta5 = MetaNode(id5)
+ meta6 = MetaFieldNode(id6)
+ root = TreeNode()
+ root.appendchild(meta1.dup()
+ .appendchild(TextNode("1")))
+ root.appendchild(TextNode("2"))
+ root.appendchild(meta2.dup()
+ .appendchild(meta3.dup()
+ .appendchild(TextNode("34"))
+ .appendchild(meta4.dup()
+ .appendchild(TextNode("56")))
+ .appendchild(meta5.dup())
+ .appendchild(TextNode("7"))))
+ root.appendchild(TextNode("8"))
+ root.appendchild(meta6.dup()
+ .appendchild(TextNode("9")))
+
+ inserter = RangeInserter(xDoc)
+ text = TextNode("123456789")
+ inserter.insertrange(Range(0, 0, text))
+ xMeta1 = inserter.insertrange(Range(0, 1, meta1))
+ xMeta2 = inserter.insertrange(Range(3, 8, meta2))
+ xMeta3 = inserter.insertrange(Range(4, 9, meta3))
+ xMeta4 = inserter.insertrange(Range(7, 9, meta4))
+ xMeta5 = inserter.insertrange(Range(10, 10, meta5))
+ xMeta6 = inserter.insertrange(Range(13, 14, meta6))
+
+ self.dotest(root, False)
+
+ xDocText = xDoc.getText()
+ xDocTextCursor = xDocText.createTextCursor()
+ xDocTextCursor.gotoNextParagraph(False) # second paragraph
+ # X12XX34X56X78X9
+ # 1 23 4 5 6
+ # 1 452 6
+ # 3
+ nestedTextContent = (
+ None,
+ id1,
+ id1,
+ None,
+ id2,
+ id3,
+ id3,
+ id3,
+ id4,
+ id4,
+ id4,
+ id5,
+ id3,
+ None,
+ id6,
+ id6)
+ for i, ntc in enumerate(nestedTextContent):
+ oNTC = xDocTextCursor.NestedTextContent
+ if ntc is None:
+ self.assertIsNone(oNTC,
+ "unexpected NestedTextContent at: {}".format(i))
+ else:
+ xmlid = oNTC.MetadataReference
+ self.assertTrue(MetaNode.eq(ntc, xmlid),
+ "wrong NestedTextContent at: {}".format(i))
+ xDocTextCursor.goRight(1, False)
+
+ try:
+ xMeta1.setParent(xMeta4)
+ fail("setParent(): allowed?")
+ except NoSupportException:
+ pass
+ self.assertIsNone(xMeta1.getParent(), "getParent(): not None")
+ self.assertIsNone(xMeta2.getParent(), "getParent(): not None")
+ self.assertIsNone(xMeta6.getParent(), "getParent(): not None")
+
+ xParent3 = xMeta3.getParent()
+ self.assertIsNotNone(xParent3, "getParent(): None")
+ xmlid = xParent3.MetadataReference
+ self.assertTrue(MetaNode.eq(xmlid, id2), "getParent(): wrong")
+
+ xParent4 = xMeta4.getParent()
+ self.assertIsNotNone(xParent4, "getParent(): None")
+ xmlid = xParent4.MetadataReference
+ self. assertTrue(MetaNode.eq(xmlid, id3), "getParent(): wrong")
+
+ xParent5 = xMeta5.getParent()
+ self.assertIsNotNone(xParent5, "getParent(): None")
+ xmlid = xParent5.MetadataReference
+ self.assertTrue(MetaNode.eq(xmlid, id3), "getParent(): wrong")
+
+ # test SwXMeta XText interface
+ def test_meta_xtext(self):
+ xDoc = self.__class__.xDoc
+ inserter = RangeInserter(xDoc)
+ text = TextNode("12AB6789")
+ inserter.insertrange(Range(0, 0, text))
+ meta = MetaNode(self.mkid("id"))
+ xMeta = inserter.makemeta()
+
+ xDocText = xDoc.getText()
+ xDocTextCursor = xDocText.createTextCursor()
+ xDocTextCursor.goRight(3, False)
+ xDocTextCursor.goRight(2, True)
+ xDocText.insertTextContent(xDocTextCursor, xMeta, True)
+
+ xMeta.MetadataReference = meta.xmlid
+ xParentText = xMeta.getText()
+ self.assertIsNotNone(xParentText, "getText(): no parent")
+
+ xStart = xMeta.getStart()
+ self.assertIsNotNone(xStart, "getStart(): no start")
+
+ xEnd = xMeta.getEnd()
+ self.assertIsNotNone(xEnd, "getEnd(): no end")
+
+ xMeta.setString("45")
+
+ string = xMeta.getString()
+ self.assertEqual("45", string, "getString(): invalid string returned")
+
+ xTextCursor = xMeta.createTextCursor()
+ self.assertIsNotNone(xTextCursor, "createTextCursor(): failed")
+
+ try:
+ xMeta.createTextCursorByRange(None)
+ fail("createTextCursorByRange(): None allowed?")
+ except RuntimeException:
+ pass
+
+ xTextCursorStart = xMeta.createTextCursorByRange(xStart)
+ self.assertIsNotNone(xTextCursorStart,
+ "createTextCursorByRange(): failed for start")
+
+ xTextCursorEnd = xMeta.createTextCursorByRange(xEnd)
+ self.assertIsNotNone(xTextCursorEnd,
+ "createTextCursorByRange(): failed for end")
+
+ ## move outside meta
+ xDocTextCursor.gotoStart(False)
+
+ try:
+ xMeta.insertString(None, "foo", False)
+ fail("insertString(): None allowed?")
+ except RuntimeException:
+ pass
+
+ try:
+ xMeta.insertString(xDocTextCursor, "foo", False)
+ fail("insertString(): cursor outside allowed?")
+ except RuntimeException:
+ pass
+
+ xStart = xMeta.getStart()
+ xMeta.insertString(xStart, "A", False)
+ string = xMeta.getString()
+ self.assertEqual("A45", string, "getString(): invalid string returned")
+
+ xMeta.insertString(xEnd, "B", False)
+ string = xMeta.getString()
+ self.assertEqual("A45B", string, "getString(): invalid string returned")
+
+ try:
+ xMeta.insertControlCharacter(None, HARD_HYPHEN, False)
+ fail("insertControlCharacter(): None allowed?")
+ except IllegalArgumentException:
+ pass
+
+ xStart = xMeta.getStart()
+ try:
+ xMeta.insertControlCharacter(xDocTextCursor, HARD_HYPHEN, False)
+ fail("insertControlCharacter(): cursor outside allowed?")
+ except IllegalArgumentException:
+ pass
+
+ xMeta.insertControlCharacter(xStart, HARD_HYPHEN, False)
+ string = xMeta.getString()
+ self.assertEqual('\u2011' + 'A45B', string,
+ "getString(): invalid string returned")
+
+ xMeta.insertControlCharacter(xEnd, HARD_HYPHEN, False)
+ string = xMeta.getString()
+ self.assertEqual('\u2011' + 'A45B' + '\u2011', string,
+ "getString(): invalid string returned")
+
+ xMeta.setString("45")
+ try:
+ xMeta.insertTextContent(None, xMeta, False)
+ fail("insertTextContent(): None range allowed?")
+ except IllegalArgumentException:
+ pass
+
+ try:
+ xMeta.insertTextContent(xStart, None, False)
+ fail("insertTextContent(): None content allowed?")
+ except IllegalArgumentException:
+ pass
+
+ try:
+ xMeta.insertTextContent(xDocTextCursor, xMeta, False)
+ fail("insertTextContent(): cursor outside allowed?")
+ except IllegalArgumentException:
+ pass
+
+ field1 = TextFieldNode("f1")
+ field2 = TextFieldNode("f2")
+ xField1 = inserter.maketextfield(field1.content)
+ xField2 = inserter.maketextfield(field2.content)
+
+ xStart = xMeta.getStart()
+ xMeta.insertTextContent(xStart, xField1, False)
+
+ root = TreeNode()
+ root.appendchild(TextNode("12"))
+ root.appendchild(meta.dup()
+ .appendchild(field1.dup())
+ .appendchild(TextNode("45")))
+ root.appendchild(TextNode("6789"))
+ self.dotest(root, False)
+
+ xMeta.insertTextContent(xEnd, xField2, False)
+
+ root = TreeNode()
+ root.appendchild(TextNode("12"))
+ root.appendchild(meta.dup()
+ .appendchild(field1.dup())
+ .appendchild(TextNode("45"))
+ .appendchild(field2.dup()))
+ root.appendchild(TextNode("6789"))
+ self.dotest(root, False)
+
+ try:
+ xMeta.removeTextContent(None)
+ fail("removeTextContent(): None content allowed?")
+ except RuntimeException:
+ pass
+
+ xMeta.removeTextContent(xField1)
+
+ xAnchor = xMeta.getAnchor()
+ self.assertIsNotNone(xAnchor, "getAnchor(): None")
+
+ ## evil test case: insert ruby around meta
+ ruby = RubyNode(self.mkname("ruby"))
+ inserter.insertrange(Range(2, 6, ruby))
+
+ ## prevent caching...
+ # root = TreeNode()
+ # root.appendchild(TextNode("12"))
+ # root.appendchild(ruby.dup()
+ # .appendchild(meta.dup()
+ # .appendchild(TextNode("45"))
+ # .appendchild(field2.dup())))
+ # root.appendchild(TextNode("6789"))
+ # self.dotest(root, False)
+
+ xEnum = xMeta.createEnumeration()
+ self.assertIsNotNone("createEnumeration(): returns None", xEnum)
+
+ self.assertTrue(xEnum.hasMoreElements(),"hasNext(): first missing")
+ xPortion = xEnum.nextElement()
+ type_ = xPortion.TextPortionType
+ self.assertEqual("Text", type_, "first: not text")
+ txt = xPortion.getString()
+ self.assertEqual("45", txt, "first: text differs")
+
+ self.assertTrue(xEnum.hasMoreElements(),"hasNext(): second missing")
+ xPortion = xEnum.nextElement()
+ type_ = xPortion.TextPortionType
+ self.assertEqual("TextField", type_, "second: not text")
+
+ ## no ruby end here!!!
+ self.assertFalse(xEnum.hasMoreElements(), "hasNext(): more elements?")
+
+ xMeta.dispose()
+
+ try:
+ xCursor = xMeta.createTextCursor()
+ self.assertIsNone(xCursor,
+ "createTextCursor(): succeeds on disposed object?")
+ except RuntimeException:
+ pass
+
+ # check that cursor move methods move to positions in the meta,
+ # but do not move to positions outside the meta.
+ def test_meta_xtextcursor(self):
+ xDoc = self.__class__.xDoc
+ inserter = RangeInserter(xDoc)
+ text = TextNode("Text. 12 More text here.")
+ inserter.insertrange(Range(0, 0, text))
+ met1 = MetaNode(self.mkid("id"))
+ xMeta = inserter.makemeta()
+
+ xDocText = xDoc.getText()
+ xDocTextCursor = xDocText.createTextCursor()
+ xDocTextCursor.goRight(7, False)
+ xDocTextCursor.goRight(2, True)
+ xDocText.insertTextContent(xDocTextCursor, xMeta, True)
+ xDocTextCursor.gotoStart(True)
+
+ xMeta.MetadataReference = met1.xmlid
+ xStart = xMeta.getStart()
+ self.assertIsNotNone(xStart, "getStart(): no start")
+ xEnd = xMeta.getEnd()
+ self.assertIsNotNone(xEnd, "getEnd(): no end")
+
+ ## XTextCursor
+ xMetaCursor = xMeta.createTextCursor()
+ self.assertIsNotNone(xMetaCursor, "createTextCursor(): no cursor")
+ bSuccess = False
+ xMetaCursor.gotoStart(False)
+ xMetaCursor.gotoEnd(False)
+ bSuccess = xMetaCursor.goLeft(1, False)
+ self.assertTrue(bSuccess, "goLeft(): failed")
+ bSuccess = xMetaCursor.goLeft(1000, False)
+ self.assertFalse(bSuccess, "goLeft(): succeeded")
+ bSuccess = xMetaCursor.goRight(1, False)
+ self.assertTrue(bSuccess, "goRight(): failed")
+ bSuccess = xMetaCursor.goRight(1000, False)
+ self.assertFalse(bSuccess, "goRight(): succeeded")
+ xMetaCursor.gotoRange(xStart, False)
+ xMetaCursor.gotoRange(xEnd, False)
+ try:
+ xMetaCursor.gotoRange(xDocTextCursor, False)
+ fail("gotoRange(): succeeded")
+ except RuntimeException:
+ pass
+
+ ## XWordCursor
+ xMeta.setString("Two words")
+ xMetaCursor.gotoStart(False)
+
+ bSuccess = xMetaCursor.gotoNextWord(True) # at start of "words"
+ self.assertTrue(bSuccess, "gotoNextWord(): failed")
+
+ string = xMetaCursor.getString()
+ self.assertEqual("Two ", string, "gotoNextWord(): wrong string")
+
+ bSuccess = xMetaCursor.gotoNextWord(False) # at end of "words", cannot leave metafield
+ self.assertFalse(bSuccess,"gotoNextWord(): succeeded")
+ xMetaCursor.collapseToEnd()
+ bSuccess = xMetaCursor.gotoPreviousWord(True) # at start of "words"
+ self.assertTrue(bSuccess, "gotoPreviousWord(): failed")
+
+ string = xMetaCursor.getString()
+ self.assertEqual("words", string, "gotoPreviousWord(): wrong string")
+
+ bSuccess = xMetaCursor.gotoPreviousWord(False) # at start of "Two"
+ self.assertTrue(bSuccess, "gotoPreviousWord(): failed")
+
+ bSuccess = xMetaCursor.gotoPreviousWord(False) # cannot leave metafield
+ self.assertFalse(bSuccess, "gotoPreviousWord(): succeeded")
+
+ bSuccess = xMetaCursor.gotoEndOfWord(True) # at end of "Two"
+ self.assertTrue(bSuccess, "gotoEndOfWord(): failed")
+
+ string = xMetaCursor.getString()
+ self.assertEqual("Two", string, "gotoEndOfWord(): wrong string")
+
+ xMetaCursor.gotoEnd(False)
+ bSuccess = xMetaCursor.gotoStartOfWord(True)
+ self.assertTrue(bSuccess, "gotoStartOfWord(): failed")
+
+ string = xMetaCursor.getString()
+ self.assertEqual("words", string, "gotoStartOfWord(): wrong string")
+
+ xMeta.setString("")
+ bSuccess = xMetaCursor.gotoEndOfWord(False)
+ self.assertFalse(bSuccess, "gotoEndOfWord(): succeeded")
+ bSuccess = xMetaCursor.gotoStartOfWord(False)
+ self.assertFalse(bSuccess, "gotoStartOfWord(): succeeded")
+
+ ## XSentenceCursor
+ xMeta.setString("This is a sentence. Another sentence.")
+ xMetaCursor.gotoStart(False)
+
+ bSuccess = xMetaCursor.gotoNextSentence(True)
+ self.assertTrue(bSuccess,"gotoNextSentence(): failed")
+
+ string = xMetaCursor.getString()
+ self.assertEqual("This is a sentence. ", string,
+ "gotoNextSentence(): wrong string")
+
+ bSuccess = xMetaCursor.gotoNextSentence(False)
+ self.assertFalse(bSuccess, "gotoNextSentence(): succeeded")
+ ## FIXME:
+ ## the sentence cursor seems to work differently than the word cursor
+ xMeta.setString("This is a sentence. Another sentence. Sentence 3.")
+ xMetaCursor.gotoEnd(False)
+ bSuccess = xMetaCursor.gotoPreviousSentence(True)
+ self.assertTrue(bSuccess, "gotoPreviousSentence(): failed")
+
+ string = xMetaCursor.getString()
+ self.assertEqual("Another sentence. Sentence 3.", string,
+ "gotoPreviousSentence(): wrong string")
+
+ bSuccess = xMetaCursor.gotoPreviousSentence(False)
+ self.assertFalse(bSuccess, "gotoPreviousSentence(): succeeded")
+ bSuccess = xMetaCursor.gotoEndOfSentence(True)
+ self.assertTrue(bSuccess, "gotoEndOfSentence(): failed")
+
+ string = xMetaCursor.getString()
+ self.assertEqual("This is a sentence.", string,
+ "gotoEndOfSentence(): wrong string")
+
+ xMetaCursor.gotoEnd(False)
+ bSuccess = xMetaCursor.gotoStartOfSentence(True)
+ self.assertTrue(bSuccess,"gotoStartOfSentence(): failed")
+
+ string = xMetaCursor.getString()
+ self.assertEqual("Sentence 3.", string,
+ "gotoStartOfSentence(): wrong string")
+
+ xMeta.setString("")
+ bSuccess = xMetaCursor.gotoEndOfSentence(False)
+ self.assertFalse(bSuccess, "gotoEndOfSentence(): succeeded")
+ bSuccess = xMetaCursor.gotoStartOfSentence(False)
+ self.assertFalse(bSuccess, "gotoStartOfSentence(): succeeded")
+
+ ## XParagraphCursor (does not make sense)
+ bSuccess = xMetaCursor.gotoNextParagraph(False)
+ self.assertFalse(bSuccess, "gotoNextParagraph(): succeeded")
+ bSuccess = xMetaCursor.gotoPreviousParagraph(False)
+ self.assertFalse(bSuccess, "gotoPreviousParagraph(): succeeded")
+ bSuccess = xMetaCursor.gotoStartOfParagraph(False)
+ self.assertFalse(bSuccess, "gotoStartOfParagraph(): succeeded")
+ bSuccess = xMetaCursor.gotoEndOfParagraph(False)
+ self.assertFalse(bSuccess, "gotoEndOfParagraph(): succeeded")
+
+ # See https://bugs.libreoffice.org/show_bug.cgi?id=49629
+ # ensure that gotoEndOfWord does not fail when footnote is at word end
+ def test_xtextcursor(self):
+ xDoc = self.__class__.xDoc
+ inserter = RangeInserter(xDoc)
+ xDocText = xDoc.getText()
+ xDocTextCursor = xDocText.createTextCursor()
+ xDocTextCursor.gotoNextParagraph(False)
+ inserter.inserttext(xDocTextCursor, "Text")
+ xDocTextCursor.gotoEndOfWord(False)
+ inserter.insertfootnote(xDocTextCursor, "footnote")
+ xDocTextCursor.gotoStartOfParagraph(False)
+ bSuccess = xDocTextCursor.gotoEndOfWord(True)
+ self.assertTrue(bSuccess, "gotoEndOfWord(): failed")
+ string = xDocTextCursor.getString()
+ self.assertEqual("Text", string, "gotoEndOfWord(): wrong string")
+ self.assertNotEqual("a","b")
+
+ class AttachHelper():
+ def isattribute(self): pass
+ def mktreenode(self): pass
+ def mktextcontent(self, inserter, node): pass
+ def postinserted(self, node, xContent): pass
+
+ def test_meta_xtextattach_toxmark(self):
+ class Helper(self.AttachHelper):
+ def isattribute(_):
+ return True
+ def mktreenode(_):
+ return DocumentIndexMarkNode(self.mkname("toxmark"))
+ def mktextcontent(_, inserter, node):
+ return inserter.makedocumentindexmark(node.name)
+ self.do_meta_xtextattach(Helper())
+
+ def test_meta_xtextattach_refmark(self):
+ class Helper(self.AttachHelper):
+ def isattribute(_):
+ return True
+ def mktreenode(_):
+ return ReferenceMarkNode(self.mkname("refmark"))
+ def mktextcontent(_, inserter, node):
+ return inserter.makereferencemark(node.name)
+ self.do_meta_xtextattach(Helper())
+
+ def test_meta_xtextattach_textfield(self):
+ class Helper(self.AttachHelper):
+ def isattribute(_):
+ return False
+ def mktreenode(_):
+ return TextFieldNode(self.mkname("field"))
+ def mktextcontent(_, inserter, node):
+ return inserter.maketextfield(node.content)
+ self.do_meta_xtextattach(Helper())
+
+ def test_meta_xtextattach_footnote(self):
+ class Helper(self.AttachHelper):
+ def isattribute(_):
+ return False
+ def mktreenode(_):
+ return FootnoteNode(self.mkname("ftn"))
+ def mktextcontent(_, inserter, node):
+ return inserter.makefootnote(node.label)
+ self.do_meta_xtextattach(Helper())
+
+ def test_meta_xtextattach_meta(self):
+ class Helper(self.AttachHelper):
+ def isattribute(_):
+ return True
+ def mktreenode(_):
+ return MetaNode(self.mkid("id"))
+ def mktextcontent(_, inserter, node):
+ return inserter.makemeta()
+ def postinserted(_, node, xContent):
+ xContent.MetadataReference = node.xmlid
+ self.do_meta_xtextattach(Helper())
+
+ def do_meta_xtextattach(self, helper):
+ xDoc = self.__class__.xDoc
+ inserter = RangeInserter(xDoc)
+ text = TextNode("12AB6789")
+ inserter.insertrange(Range(0, 0, text))
+ met1 = MetaNode(self.mkid("id"))
+ xMeta = inserter.makemeta()
+
+ xDocText = xDoc.getText()
+ xDocTextCursor = xDocText.createTextCursor()
+ xDocTextCursor.goRight(3, False)
+ xDocTextCursor.goRight(2, True)
+ xDocText.insertTextContent(xDocTextCursor, xMeta, True)
+
+ xMeta.MetadataReference = met1.xmlid
+ xStart = None
+ xEnd = None
+
+ xStart = xMeta.getStart()
+ xEnd = xMeta.getEnd()
+
+ nod1 = helper.mktreenode()
+ nod2 = helper.mktreenode()
+ xContent1 = helper.mktextcontent(inserter, nod1)
+ xContent2 = helper.mktextcontent(inserter, nod2)
+
+ ## insertTextContent with meta getStart()/getEnd()
+ xMeta.insertTextContent(xStart, xContent1, False)
+ xMeta.insertTextContent(xEnd, xContent2, False)
+
+ helper.postinserted(nod1, xContent1)
+ helper.postinserted(nod2, xContent2)
+
+ root = TreeNode()
+ root.appendchild(TextNode("12"))
+ root.appendchild(met1.dup()
+ .appendchild(nod1.dup())
+ .appendchild(TextNode("AB"))
+ .appendchild(nod2.dup()))
+ root.appendchild(TextNode("6789"))
+ self.dotest(root, False)
+
+ xMeta.setString("AB")
+ xStart = xMeta.getStart()
+ xEnd = xMeta.getEnd()
+
+ nod1 = helper.mktreenode()
+ nod2 = helper.mktreenode()
+ xContent1 = helper.mktextcontent(inserter, nod1)
+ xContent2 = helper.mktextcontent(inserter, nod2)
+
+ xTextCursor = xMeta.createTextCursor()
+ xTextCursor.gotoStart(False)
+
+ ## insertTextContent with meta cursor
+ xMeta.insertTextContent(xTextCursor, xContent1, False)
+ xTextCursor.gotoEnd(False)
+ xMeta.insertTextContent(xTextCursor, xContent2, False)
+
+ helper.postinserted(nod1, xContent1)
+ helper.postinserted(nod2, xContent2)
+
+ root = TreeNode()
+ root.appendchild(TextNode("12"))
+ root.appendchild(met1.dup()
+ .appendchild(nod1.dup())
+ .appendchild(TextNode("AB"))
+ .appendchild(nod2.dup()))
+ root.appendchild(TextNode("6789"))
+ self.dotest(root, False)
+
+ if not helper.isattribute():
+ # xMeta.setString("AB")
+ xStart = xMeta.getStart()
+ xEnd = xMeta.getEnd()
+
+ nod1 = helper.mktreenode()
+ nod2 = helper.mktreenode()
+ xContent1 = helper.mktextcontent(inserter, nod1)
+ xContent2 = helper.mktextcontent(inserter, nod2)
+
+ xTextCursor = xMeta.createTextCursor()
+ xTextCursor.gotoStart(False)
+ xTextCursor.goRight(1, True)
+
+ ## insertTextContent with meta cursor and absorb
+ xMeta.insertTextContent(xTextCursor, xContent1, True)
+ xTextCursor.gotoEnd(False)
+ xTextCursor.goLeft(1, True)
+ xMeta.insertTextContent(xTextCursor, xContent2, True)
+
+ helper.postinserted(nod1, xContent1)
+ helper.postinserted(nod2, xContent2)
+
+ root = TreeNode()
+ root.appendchild(TextNode("12"))
+ root.appendchild(met1.dup()
+ .appendchild(nod1.dup())
+ .appendchild(TextNode("AB"))
+ .appendchild(nod2.dup()))
+ root.appendchild(TextNode("6789"))
+ self.dotest(root, False)
+
+ xMeta.setString("AB")
+ xStart = xMeta.getStart()
+ xEnd = xMeta.getEnd()
+
+ nod1 = helper.mktreenode()
+ nod2 = helper.mktreenode()
+ xContent1 = helper.mktextcontent(inserter, nod1)
+ xContent2 = helper.mktextcontent(inserter, nod2)
+
+ xDocTextCursor.gotoRange(xStart, False)
+
+ ## insertTextContent with document cursor
+ xMeta.insertTextContent(xDocTextCursor, xContent1, False)
+ xDocTextCursor.gotoRange(xEnd, False)
+ xMeta.insertTextContent(xDocTextCursor, xContent2, False)
+
+ helper.postinserted(nod1, xContent1)
+ helper.postinserted(nod2, xContent2)
+
+ root = TreeNode()
+ root.appendchild(TextNode("12"))
+ root.appendchild(met1.dup()
+ .appendchild(nod1.dup())
+ .appendchild(TextNode("AB"))
+ .appendchild(nod2.dup()))
+ root.appendchild(TextNode("6789"))
+ self.dotest(root, False)
+
+ if not helper.isattribute():
+ xStart = xMeta.getStart()
+ xEnd = xMeta.getEnd()
+
+ nod1 = helper.mktreenode()
+ nod2 = helper.mktreenode()
+ xContent1 = helper.mktextcontent(inserter, nod1)
+ xContent2 = helper.mktextcontent(inserter, nod2)
+
+ xDocTextCursor.gotoRange(xStart, False)
+ xDocTextCursor.goRight(1, True)
+
+ ## insertTextContent with document cursor and absorb
+ xMeta.insertTextContent(xDocTextCursor, xContent1, True)
+ xDocTextCursor.gotoRange(xEnd, False)
+ xDocTextCursor.goLeft(1, True)
+ xMeta.insertTextContent(xDocTextCursor, xContent2, True)
+
+ helper.postinserted(nod1, xContent1)
+ helper.postinserted(nod2, xContent2)
+
+ root = TreeNode()
+ root.appendchild(TextNode("12"))
+ root.appendchild(met1.dup()
+ .appendchild(nod1.dup())
+ .appendchild(TextNode("AB"))
+ .appendchild(nod2.dup()))
+ root.appendchild(TextNode("6789"))
+ self.dotest(root, False)
+
+ xMeta.setString("AB")
+ xStart = xMeta.getStart()
+ xEnd = xMeta.getEnd()
+
+ nod1 = helper.mktreenode()
+ nod2 = helper.mktreenode()
+ xContent1 = helper.mktextcontent(inserter, nod1)
+ xContent2 = helper.mktextcontent(inserter, nod2)
+
+ ## attach to range from meta getStart()/getEnd()
+ xContent1.attach(xStart)
+ xContent2.attach(xEnd)
+
+ helper.postinserted(nod1, xContent1)
+ helper.postinserted(nod2, xContent2)
+
+ root = TreeNode()
+ root.appendchild(TextNode("12"))
+ root.appendchild(met1.dup()
+ .appendchild(nod1.dup())
+ .appendchild(TextNode("AB"))
+ .appendchild(nod2.dup()))
+ root.appendchild(TextNode("6789"))
+ self.dotest(root, False)
+
+ xMeta.setString("AB")
+ xStart = xMeta.getStart()
+ xEnd = xMeta.getEnd()
+
+ nod1 = helper.mktreenode()
+ nod2 = helper.mktreenode()
+ xContent1 = helper.mktextcontent(inserter, nod1)
+ xContent2 = helper.mktextcontent(inserter, nod2)
+
+ xTextCursor = xMeta.createTextCursor()
+ xTextCursor.gotoStart(False)
+
+ ## attach to cursor from meta XText
+ xContent1.attach(xTextCursor)
+ xTextCursor.gotoEnd(False)
+ xContent2.attach(xTextCursor)
+
+ helper.postinserted(nod1, xContent1)
+ helper.postinserted(nod2, xContent2)
+
+ root = TreeNode()
+ root.appendchild(TextNode("12"))
+ root.appendchild(met1.dup()
+ .appendchild(nod1.dup())
+ .appendchild(TextNode("AB"))
+ .appendchild(nod2.dup()))
+ root.appendchild(TextNode("6789"))
+ self.dotest(root, False)
+
+ def test_metafield_xtextfield(self):
+ xDoc = self.__class__.xDoc
+ smgr = self.__class__._uno.xContext.ServiceManager
+ xRepo = xDoc.getRDFRepository()
+ ## for testing just add it to the first graph
+ Graphs = xRepo.getGraphNames()
+ xGraph = xRepo.getGraph(Graphs[0])
+ xOdfPrefix = smgr.createInstance("com.sun.star.rdf.URI")
+ xOdfPrefix.initialize((ODF_PREFIX,))
+ xOdfSuffix = smgr.createInstance("com.sun.star.rdf.URI")
+ xOdfSuffix.initialize((ODF_SUFFIX,))
+
+ xPrefix = smgr.createInstance("com.sun.star.rdf.Literal")
+ xPrefix.initialize(("foo",))
+ xSuffix = smgr.createInstance("com.sun.star.rdf.Literal")
+ xSuffix.initialize(("bar",))
+
+ inserter = RangeInserter(xDoc)
+ text = TextNode("abc")
+ inserter.insertrange(Range(0, 0, text))
+ xDocText = xDoc.getText()
+ xDocTextCursor = xDocText.createTextCursor()
+ xDocTextCursor.goRight(1, False)
+ xDocTextCursor.goRight(3, True)
+
+ xMetaField = inserter.makemetafield()
+
+ xDocText.insertTextContent(xDocTextCursor, xMetaField, True)
+
+ xMetaField.ensureMetadataReference
+
+ xGraph.addStatement(xMetaField, xOdfPrefix, xPrefix)
+ xGraph.addStatement(xMetaField, xOdfSuffix, xSuffix)
+ self.assertEqual("fooabcbar", xMetaField.getPresentation(False),
+ "getPresentation(): wrong")
+ inserter.insertrange(Range(0, 0, text))
+
+ def test_metafield_xpropertyset(self):
+ xDoc = self.__class__.xDoc
+ inserter = RangeInserter(xDoc)
+ text = TextNode("123")
+ inserter.insertrange(Range(0, 0, text))
+ xDocText = xDoc.getText()
+ xDocTextCursor = xDocText.createTextCursor()
+ xDocTextCursor.goRight(1, False)
+ xDocTextCursor.goRight(3, True)
+
+ xMetaField = inserter.makemetafield()
+
+ xDocText.insertTextContent(xDocTextCursor, xMetaField, True)
+
+ self.assertIsNotNone(xMetaField, "PropertySet: not supported?")
+ xPropertySetInfo = xMetaField.getPropertySetInfo()
+ self.assertTrue(xPropertySetInfo.hasPropertyByName("NumberFormat"),
+ 'hasPropertyByName("NumberFormat"):')
+ self.assertTrue(xPropertySetInfo.hasPropertyByName("IsFixedLanguage"),
+ 'hasPropertyByName("IsFixedLanguage"):')
+
+ def_ = xMetaField.NumberFormat
+ print("NumberFormat: default is {}".format(def_))
+ xMetaField.NumberFormat = NUMBER_INT
+ xMetaField.IsFixedLanguage = True
+ format = xMetaField.NumberFormat
+ self.assertEqual(NUMBER_INT, format, "NumberFormat: failed")
+ isfixed = xMetaField.IsFixedLanguage
+ self.assertTrue(isfixed, "IsFixedLanguage: failed")
+
+ def dostore(self, xComp, file):
+ print("Storing test document...")
+ file = uno.systemPathToFileUrl(file)
+ xComp.storeToURL(file, ())
+ print("...done")
+
+ def doload(self, file):
+ xComp = None
+ print("Loading test document...")
+ xComp = self.__class__._uno.openDocFromAbsolutePath(file)
+ self.assertIsNotNone(xComp, "cannot load: {}".format(file))
+ print("...done")
+ return xComp
+
+ def close(self, i_comp):
+ try:
+ if i_comp:
+ i_comp.close(True)
+ except Exception as e:
+ pass
+
+ def test_load_store(self):
+ xComp = None
+ filename = "TESTMETA.odt"
+ try:
+ xComp = self.__class__._uno.openDocFromTDOC(filename)
+ if xComp:
+ self.checkloadmeta(xComp)
+ with TemporaryDirectory() as tempdir:
+ if os.altsep: # we need URL so replace "\" with "/"
+ tempdir = tempdir.replace(os.sep, os.altsep)
+ file = tempdir + "/" + filename
+ self.dostore(xComp, file)
+ self.close(xComp)
+ xComp2 = None
+ try:
+ xComp2 = self.doload(file)
+ self.checkloadmeta(xComp2)
+ finally:
+ self.close(xComp2)
+ finally:
+ self.close(xComp)
+
+ def checkloadmeta(self, xTextDoc):
+ xText = xTextDoc.getText()
+ print("Checking meta(-field)s in loaded test document...")
+ root = TreeNode()
+ root.appendchild(RubyNode("ruby1")
+ .appendchild(TextNode("1")))
+ root.appendchild(MetaNode(self.mkid_("id1"))
+ .appendchild(TextNode("2")))
+ root.appendchild(MetaFieldNode(self.mkid_("id2"))
+ .appendchild(TextNode("3")))
+ root.appendchild(RubyNode("ruby2")
+ .appendchild(MetaNode(self.mkid_("id3"))
+ .appendchild(TextNode("4"))))
+ root.appendchild(RubyNode("ruby3")
+ .appendchild(MetaFieldNode(self.mkid_("id4"))
+ .appendchild(TextNode("5"))))
+ root.appendchild(MetaNode(self.mkid_("id5"))
+ .appendchild(RubyNode("ruby4")
+ .appendchild(TextNode("6"))))
+ root.appendchild(MetaFieldNode(self.mkid_("id6"))
+ .appendchild(RubyNode("ruby5")
+ .appendchild(TextNode("7"))))
+ root.appendchild(MetaNode(self.mkid_("id7"))
+ .appendchild(MetaNode(self.mkid_("id8"))
+ .appendchild(TextNode("8"))))
+ root.appendchild(MetaNode(self.mkid_("id9"))
+ .appendchild(MetaFieldNode(self.mkid_("id10"))
+ .appendchild(TextNode("9"))))
+ root.appendchild(MetaFieldNode(self.mkid_("id11"))
+ .appendchild(MetaNode(self.mkid_("id12"))
+ .appendchild(TextNode("10"))))
+ root.appendchild(MetaFieldNode(self.mkid_("id13"))
+ .appendchild(MetaFieldNode(self.mkid_("id14"))
+ .appendchild(TextNode("11"))))
+ root.appendchild(MetaNode(self.mkid_("id15"))
+ .appendchild(RubyNode("ruby6")
+ .appendchild(MetaFieldNode(self.mkid_("id16"))
+ .appendchild(TextNode("12")))))
+
+ class MetaNode_(MetaNode):
+ def __init__(self, id):
+ super().__init__(id)
+ def __eq__(self, other):
+ return isinstance(other, MetaNode)
+ root.appendchild(MetaNode_(self.mkid_(""))
+ .appendchild(TextNode("13")))
+ root.appendchild(TextNode(" X X "))
+ self._dotest(xTextDoc, root, False)
+ print("...done")
+
+ def test_load_store_xmlid(self):
+ xComp = None
+ filename = "TESTXMLID.odt"
+ try:
+ xComp = self.__class__._uno.openDocFromTDOC(filename)
+ if xComp:
+ self.checkloadxmlid(xComp)
+ with TemporaryDirectory() as tempdir:
+ if os.altsep: # we need URL so replace "\" with "/"
+ tempdir = tempdir.replace(os.sep, os.altsep)
+ file = tempdir + "/" + filename
+ self.dostore(xComp, file)
+ self.close(xComp)
+ xComp2 = None
+ try:
+ xComp2 = self.doload(file)
+ self.checkloadxmlid(xComp2)
+ finally:
+ self.close(xComp2)
+ finally:
+ self.close(xComp)
+
+ def checkloadxmlid(self, xTextDoc):
+ xText = xTextDoc.getText()
+ xRepo = xTextDoc.getRDFRepository()
+
+ print("Checking bookmarks in loaded test document...")
+ xBookmarks = xTextDoc.getBookmarks()
+ xMark1 = xBookmarks["mk1"]
+ self.assertTrue(self.eq(xMark1.MetadataReference,
+ StringPair("content.xml", "id90")), "mark1")
+ xMark2 = xBookmarks["mk2"]
+ result = xRepo.getStatementRDFa(xMark2)
+ self.assertTrue(len(result.First) == 1 and
+ result.First[0].Subject.StringValue == "uri:foo" and
+ result.First[0].Predicate.StringValue == "uri:bar" and
+ result.First[0].Object.Value == "a fooish bar",
+ "mark2")
+ xMark3 = xBookmarks["mk3"]
+ self.assertTrue(self.eq(xMark3.MetadataReference,
+ StringPair("content.xml", "id91")), "mark3")
+ print("...done")
+
+ print("Checking sections in loaded test document...")
+ xSections = xTextDoc.getTextSections()
+ xSection1 = xSections["Section 1"]
+ self.assertTrue(self.eq(xSection1.MetadataReference,
+ StringPair("content.xml", "idSection1")), "idsection1")
+ xSection2 = xSections["Section 2"]
+ self.assertTrue(self.eq(xSection2.MetadataReference,
+ StringPair("content.xml", "idSection2")),"idSection2")
+ xSection3 = xSections["Table of Contents1_Head"]
+ self.assertTrue(self.eq(xSection3.MetadataReference,
+ StringPair("content.xml", "idTOCTitle")), "idTOCTitle")
+ xSection4 = xSections["Alphabetical Index1_Head"]
+ self.assertTrue(self.eq(xSection4.MetadataReference,
+ StringPair("content.xml", "idAITitle")), "idAITitle")
+ xSection5 = xSections["Illustration Index1_Head"]
+ self.assertTrue(self.eq(xSection5.MetadataReference,
+ StringPair("content.xml", "idIITitle")), "idIITitle")
+ xSection6 = xSections["Index of Tables1_Head"]
+ self.assertTrue(self.eq(xSection6.MetadataReference,
+ StringPair("content.xml", "idIOTTitle")), "idIOTTitle")
+ xSection7 = xSections["User-Defined1_Head"]
+ self.assertTrue(self.eq(xSection7.MetadataReference,
+ StringPair("content.xml", "idUDTitle")), "idUDTitle")
+ xSection8 = xSections["Table of Objects1_Head"]
+ self.assertTrue(self.eq(xSection8.MetadataReference,
+ StringPair("content.xml", "idTOOTitle")), "idTOOTitle")
+ xSection9 = xSections["Bibliography1_Head"]
+ self.assertTrue(self.eq(xSection9.MetadataReference,
+ StringPair("content.xml", "idBibTitle")), "idBibTitle")
+ print("...done")
+
+ print("Checking indexes in loaded test document...")
+ xIndexes = xTextDoc.getDocumentIndexes()
+ xIndex1 = xIndexes["Table of Contents1"]
+ self.assertTrue(self.eq(xIndex1.MetadataReference,
+ StringPair("content.xml", "idTOC")), "idTOC")
+ xIndex1s = xSections["Table of Contents1"]
+ self.assertTrue(self.eq(xIndex1s.MetadataReference,
+ StringPair("content.xml", "idTOC")), "idTOC")
+ xIndex2 = xIndexes["Alphabetical Index1"]
+ self.assertTrue(self.eq(xIndex2.MetadataReference,
+ StringPair("content.xml", "idAI")), "idAI")
+ xIndex2s = xSections["Alphabetical Index1"]
+ self.assertTrue(self.eq(xIndex2s.MetadataReference,
+ StringPair("content.xml", "idAI")), "idAI")
+ xIndex3 = xIndexes["Illustration Index1"]
+ self.assertTrue(self.eq(xIndex3.MetadataReference,
+ StringPair("content.xml", "idII")), "idII")
+ xIndex3s = xSections["Table of Figures1"]
+ self.assertTrue(self.eq(xIndex3s.MetadataReference,
+ StringPair("content.xml", "idII")), "idII")
+ xIndex4 = xIndexes["Index of Tables1"]
+ self.assertTrue(self.eq(xIndex4.MetadataReference,
+ StringPair("content.xml", "idIOT")), "idIOT")
+ xIndex4s = xSections["Index of Tables1"]
+ self.assertTrue(self.eq(xIndex4s.MetadataReference,
+ StringPair("content.xml", "idIOT")), "idIOT")
+ xIndex5 = xIndexes["User-Defined1"]
+ self.assertTrue(self.eq(xIndex5.MetadataReference,
+ StringPair("content.xml", "idUD")), "idUD")
+ xIndex5s = xSections["User-Defined1"]
+ self.assertTrue(self.eq(xIndex5s.MetadataReference,
+ StringPair("content.xml", "idUD")), "idUD")
+ xIndex6 = xIndexes["Table of Objects1"]
+ self.assertTrue(self.eq(xIndex6.MetadataReference,
+ StringPair("content.xml", "idTOO")), "idTOO")
+ xIndex6s = xSections["Table of Objects1"]
+ self.assertTrue(self.eq(xIndex6s.MetadataReference,
+ StringPair("content.xml", "idTOO")), "idTOO")
+ xIndex7 = xIndexes["Bibliography1"]
+ self.assertTrue(self.eq(xIndex7.MetadataReference,
+ StringPair("content.xml", "idBib")), "idBib")
+ xIndex7s = xSections["Bibliography1"]
+ self.assertTrue(self.eq(xIndex7s.MetadataReference,
+ StringPair("content.xml", "idBib")), "idBib")
+ print("...done")
+
+ def dotest(self, intree, insert=True):
+ xDoc = self.__class__.xDoc
+ self._dotest(xDoc, intree, insert)
+
+ def _dotest(self, xDoc, intree, insert):
+ self._dumptree(intree, "I: ")
+ if insert:
+ TreeInserter(xDoc).inserttree(intree)
+ xText = xDoc.getText()
+ xTextEnum = xText.createEnumeration()
+ ## skip to right paragraph
+ xTextEnum.nextElement(); # skip first -- always empty!
+ xElement = xTextEnum.nextElement() # second contains test case
+ xEnum = xElement.createEnumeration()
+ outtree = EnumConverter().convert(xEnum)
+ self._dumptree(outtree, "O: ")
+ FuzzyTester().dotest(intree, outtree)
+
+ def _dumptree(self, tree, prefix):
+ print('{}{}'.format(prefix, str(tree)))
+ children = tree.createenumeration()
+ for node in children:
+ self._dumptree(node, "{} ".format(prefix))
+
+ def mkname(self, prefix):
+ self.__class__.count += 1
+ return "{}{}".format(prefix, self.__class__.count)
+
+ def mkid(self, prefix):
+ id = self.mkname(prefix)
+ return StringPair("content.xml", self.mkname(prefix))
+
+ def mkid_(self, id):
+ return StringPair("content.xml", id)
+
+ def eq(self, left, right):
+ return (left.First == right.First and
+ left.Second == right.Second)
+
+
+if __name__ == '__main__':
+ unittest.main()