2 # -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
4 # This file is part of the LibreOffice project.
6 # This Source Code Form is subject to the terms of the Mozilla Public
7 # License, v. 2.0. If a copy of the MPL was not distributed with this
8 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 # This file incorporates work covered by the following license notice:
12 # Licensed to the Apache Software Foundation (ASF) under one or more
13 # contributor license agreements. See the NOTICE file distributed
14 # with this work for additional information regarding copyright
15 # ownership. The ASF licenses this file to you under the Apache
16 # License, Version 2.0 (the "License"); you may not use this file
17 # except in compliance with the License. You may obtain a copy of
18 # the License at http://www.apache.org/licenses/LICENSE-2.0.
24 from hashlib
import sha1
25 from tempfile
import TemporaryDirectory
26 from org
.libreoffice
.unotest
import UnoInProcess
, mkPropertyValues
, systemPathToFileUrl
27 from com
.sun
.star
.text
.ControlCharacter
import PARAGRAPH_BREAK
29 class CheckBookmarks(unittest
.TestCase
):
31 'nSetupHash': 0x8f88ee1a13a55d6024f58f470723b5174dfa21bb,
32 'nInsertRandomHash': 0x5f27e87e16d2cb3ff0bcb24237aa30da3b84cf24,
33 'nDeleteRandomHash': 0x1bdaa7773cbfc73a4dc0bb3e0f801b98f648e8e7,
34 'nLinebreakHash': 0x3f30a35f195efcfe0373a3e439de05087a2ad37c,
35 'nOdfReloadHash': 0x3f30a35f195efcfe0373a3e439de05087a2ad37c,
36 'nMsWordReloadHash': 0x3f30a35f195efcfe0373a3e439de05087a2ad37c,
41 cls
._uno
= UnoInProcess()
43 cls
._xDoc
= cls
._uno
.openEmptyWriterDoc()
44 smgr
= cls
._uno
.xContext
.ServiceManager
45 cls
._desktop
= smgr
.createInstanceWithContext("com.sun.star.frame.Desktop",
49 def tearDownClass(cls
):
51 # HACK in case cls._xDoc holds a UNO proxy to an SwXTextDocument (whose dtor calls
52 # Application::GetSolarMutex via sw::UnoImplPtrDeleter), which would potentially only be
53 # garbage-collected after VCL has already been deinitialized:
56 def test_bookmarks(self
):
57 self
.xDoc
= self
.__class
__._xDoc
58 self
.xText
= self
.xDoc
.getText()
60 ## setting and testing bookmarks
62 self
.assertEqual(self
.expectedHashes
['nSetupHash'],
63 self
.getBookmarksHash(self
.xDoc
))
65 ## modifying bookmarks and testing again
66 self
.insertRandomParts(200177)
67 self
.assertEqual(self
.expectedHashes
['nInsertRandomHash'],
68 self
.getBookmarksHash(self
.xDoc
))
70 ## modifying bookmarks and testing again
71 self
.deleteRandomParts(4711)
72 self
.assertEqual(self
.expectedHashes
['nDeleteRandomHash'],
73 self
.getBookmarksHash(self
.xDoc
))
75 ## adding line breaks and testing again
76 self
.insertLinebreaks(7)
77 self
.assertEqual(self
.expectedHashes
['nLinebreakHash'],
78 self
.getBookmarksHash(self
.xDoc
))
80 ## reloading document and testing again
81 with
TemporaryDirectory() as tempdir
:
82 xOdfReloadedDoc
= self
.reloadFrom(tempdir
, "writer8", "odt")
83 self
.assertEqual(self
.expectedHashes
['nOdfReloadHash'],
84 self
.getBookmarksHash(xOdfReloadedDoc
))
85 xOdfReloadedDoc
.close(True)
87 ## reloading document as MS Word 97 doc and testing again
88 ## MsWord Hash is unstable over different systems
89 # xMsWordReloadedDoc = self.reloadFrom(tempdir, "MS Word 97", "doc")
90 # self.assertEqual(self.expectedHashes['nMsWordReloadHash'],
91 # self.getBookmarksHash(xMsWordReloadedDoc))
92 # xMsWordReloadedDoc.close(True)
96 def setupBookmarks(self
):
97 xCursor
= self
.xText
.createTextCursor()
98 for nPara
in range(10):
99 for nBookmark
in range(100):
100 s
= "P{}word{}".format(nPara
, nBookmark
)
101 xCursor
.gotoEnd(False)
103 xBookmark
= self
.xDoc
.createInstance("com.sun.star.text.Bookmark")
105 self
.xText
.insertTextContent(xCursor
, xBookmark
, True)
106 xCursor
.End
.setString(" ")
108 self
.xText
.insertControlCharacter(xCursor
.End
, PARAGRAPH_BREAK
, False)
110 def getBookmarksHash(self
, doc
):
112 xBookmarks
= doc
.getBookmarks()
113 for xBookmark
in xBookmarks
:
114 s
= '{}:{};'.format(xBookmark
.Name
,
115 xBookmark
.getAnchor().getString().replace("\r\n", "\n"))
117 _hash
.update(str.encode(s
))
119 return int(_hash
.hexdigest(), 16)
121 def insertRandomParts(self
, seed
):
123 xCursor
= self
.xText
.createTextCursor()
126 xCursor
.goRight(random
.randrange(100), False)
127 xCursor
.setString(str(random
.getrandbits(64)))
129 def deleteRandomParts(self
, seed
):
131 xCursor
= self
.xText
.createTextCursor()
134 xCursor
.goRight(random
.randrange(100), False)
135 xCursor
.goRight(random
.randrange(20), True)
136 xCursor
.setString("")
138 def insertLinebreaks(self
, seed
):
140 xCursor
= self
.xText
.createTextCursor()
143 xCursor
.goRight(random
.randrange(300), False)
144 self
.xText
.insertControlCharacter(xCursor
, PARAGRAPH_BREAK
, False)
146 def reloadFrom(self
, tempdir
, sFilter
, sExtension
):
147 sFileUrl
= os
.path
.join(tempdir
, "Bookmarktest.{}".format(sExtension
))
148 sFileUrl
= systemPathToFileUrl(sFileUrl
)
149 store_props
= mkPropertyValues(Override
=True, FilterName
=sFilter
)
150 self
.xDoc
.storeToURL(sFileUrl
, store_props
)
151 desktop
= self
.__class
__._desktop
152 load_props
= mkPropertyValues(Hidden
=True, ReadOnly
=False)
153 return desktop
.loadComponentFromURL(sFileUrl
, "_default", 0, load_props
)
155 if __name__
== '__main__':