diff options
Diffstat (limited to 'sw/qa/python/text_portion_enumeration_test.py')
-rw-r--r-- | sw/qa/python/text_portion_enumeration_test.py | 3504 |
1 files changed, 3504 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 0000000000..c183aaf41b --- /dev/null +++ b/sw/qa/python/text_portion_enumeration_test.py @@ -0,0 +1,3504 @@ +# -*- 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 +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 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: + 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: + file = os.path.join(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): + 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: + file = os.path.join(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): + 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): + 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() |