Add test coverage of new features
This commit is contained in:
@@ -985,7 +985,7 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
pressed, check if we're clicking on a tag, and trigger the
|
||||
follow tag function.
|
||||
"""
|
||||
if QApplication.keyboardModifiers() == QtModCtrl:
|
||||
if event.modifiers() & QtModCtrl == QtModCtrl:
|
||||
cursor = self.cursorForPosition(event.pos())
|
||||
mData, mType = self._qDocument.metaDataAtPos(cursor.position())
|
||||
if mData and mType == "url":
|
||||
|
||||
@@ -291,6 +291,48 @@ def testFmtToDocX_ParagraphStyles(mockGUI):
|
||||
assert doc._pars == []
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testFmtToDocX_Links(mockGUI):
|
||||
"""Test formatting of links."""
|
||||
project = NWProject()
|
||||
doc = ToDocX(project)
|
||||
doc.initDocument()
|
||||
|
||||
# Register 2 links
|
||||
rd1 = doc._appendExternalRel("http://example.com")
|
||||
rd2 = doc._appendExternalRel("https://example.com")
|
||||
assert rd1 == "rId1"
|
||||
assert rd2 == "rId2"
|
||||
|
||||
# Link 1
|
||||
xTest = ET.Element(_wTag("body"))
|
||||
doc._text = "Foo http://example.com bar"
|
||||
doc.tokenizeText()
|
||||
doc.doConvert()
|
||||
doc._pars[-1].toXml(xTest)
|
||||
assert xmlToText(xTest) == (
|
||||
'<w:body><w:p><w:pPr><w:pStyle w:val="Normal" /></w:pPr>'
|
||||
'<w:r><w:rPr /><w:t xml:space="preserve">Foo </w:t></w:r>'
|
||||
'<w:hyperlink r:id="rId1"><w:r><w:rPr><w:rStyle w:val="InternetLink" /></w:rPr>'
|
||||
'<w:t>http://example.com</w:t></w:r></w:hyperlink>'
|
||||
'<w:r><w:rPr /><w:t xml:space="preserve"> bar</w:t></w:r></w:p></w:body>'
|
||||
)
|
||||
|
||||
# Link 2
|
||||
xTest = ET.Element(_wTag("body"))
|
||||
doc._text = "Foo https://example.com bar"
|
||||
doc.tokenizeText()
|
||||
doc.doConvert()
|
||||
doc._pars[-1].toXml(xTest)
|
||||
assert xmlToText(xTest) == (
|
||||
'<w:body><w:p><w:pPr><w:pStyle w:val="Normal" /></w:pPr>'
|
||||
'<w:r><w:rPr /><w:t xml:space="preserve">Foo </w:t></w:r>'
|
||||
'<w:hyperlink r:id="rId2"><w:r><w:rPr><w:rStyle w:val="InternetLink" /></w:rPr>'
|
||||
'<w:t>https://example.com</w:t></w:r></w:hyperlink>'
|
||||
'<w:r><w:rPr /><w:t xml:space="preserve"> bar</w:t></w:r></w:p></w:body>'
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testFmtToDocX_ParagraphFormatting(mockGUI):
|
||||
"""Test formatting of paragraphs."""
|
||||
|
||||
@@ -20,10 +20,15 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
from PyQt5.QtCore import QEvent, Qt, QThreadPool
|
||||
from PyQt5.QtGui import QClipboard, QFont, QMouseEvent, QTextBlock, QTextCursor, QTextOption
|
||||
from PyQt5.QtCore import QEvent, Qt, QThreadPool, QUrl
|
||||
from PyQt5.QtGui import (
|
||||
QClipboard, QDesktopServices, QFont, QMouseEvent, QTextBlock, QTextCursor,
|
||||
QTextOption
|
||||
)
|
||||
from PyQt5.QtWidgets import QAction, QApplication, QMenu
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
@@ -267,8 +272,9 @@ def testGuiEditor_ContextMenu(monkeypatch, qtbot, nwGUI, projPath, mockRnd):
|
||||
|
||||
docText = (
|
||||
"### A Scene\n\n"
|
||||
"@pov: Jane\n"
|
||||
"Some text ..."
|
||||
"@pov: Jane\n\n"
|
||||
"Some text ...\n\n"
|
||||
"... and a link to http://example.com\n\n"
|
||||
)
|
||||
docEditor.setPlainText(docText)
|
||||
assert docEditor.getText() == docText
|
||||
@@ -289,6 +295,17 @@ def testGuiEditor_ContextMenu(monkeypatch, qtbot, nwGUI, projPath, mockRnd):
|
||||
ctxMenu.setObjectName("")
|
||||
ctxMenu.deleteLater()
|
||||
|
||||
# Open Link
|
||||
ctxMenu = getMenuForPos(docEditor, 63)
|
||||
assert ctxMenu is not None
|
||||
actions = [x.text() for x in ctxMenu.actions() if x.text()]
|
||||
assert actions == [
|
||||
"Open URL", "Paste",
|
||||
"Select All", "Select Word", "Select Paragraph"
|
||||
]
|
||||
ctxMenu.setObjectName("")
|
||||
ctxMenu.deleteLater()
|
||||
|
||||
# Create Character
|
||||
ctxMenu = getMenuForPos(docEditor, 21)
|
||||
assert ctxMenu is not None
|
||||
@@ -1656,6 +1673,30 @@ def testGuiEditor_Tags(qtbot, nwGUI, projPath, ipsumText, mockRnd):
|
||||
# qtbot.stop()
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
def testGuiEditor_Links(qtbot, monkeypatch, nwGUI, projPath, ipsumText, mockRnd):
|
||||
"""Test the document editor links functionality."""
|
||||
buildTestProject(nwGUI, projPath)
|
||||
nwGUI.openDocument(C.hSceneDoc)
|
||||
docEditor = nwGUI.docEditor
|
||||
docEditor.replaceText("### Scene\n\nFoo http://www.example.com bar.\n\n")
|
||||
|
||||
docEditor.setCursorPosition(20)
|
||||
position = docEditor.cursorRect().center()
|
||||
event = QMouseEvent(
|
||||
QEvent.Type.MouseButtonPress, position, QtMouseLeft, QtMouseLeft, QtModCtrl
|
||||
)
|
||||
|
||||
with monkeypatch.context() as mp:
|
||||
openUrl = MagicMock()
|
||||
mp.setattr(QDesktopServices, "openUrl", openUrl)
|
||||
docEditor.mouseReleaseEvent(event)
|
||||
assert openUrl.called is True
|
||||
assert openUrl.call_args[0][0] == QUrl("http://www.example.com")
|
||||
|
||||
# qtbot.stop()
|
||||
|
||||
|
||||
@pytest.mark.gui
|
||||
def testGuiEditor_Completer(qtbot, nwGUI, projPath, mockRnd):
|
||||
"""Test the document editor meta completer functionality."""
|
||||
|
||||
@@ -20,10 +20,12 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
from PyQt5.QtCore import QEvent, QPoint, Qt, QUrl
|
||||
from PyQt5.QtGui import QMouseEvent, QTextCursor
|
||||
from PyQt5.QtGui import QDesktopServices, QMouseEvent, QTextCursor
|
||||
from PyQt5.QtWidgets import QAction, QApplication, QMenu
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
@@ -165,6 +167,14 @@ def testGuiViewer_Main(qtbot, monkeypatch, nwGUI, prjLipsum):
|
||||
docViewer._linkClicked(QUrl("#somewhere_else"))
|
||||
assert signal.args[0].url() == "#somewhere_else"
|
||||
|
||||
# Web links should trigger the browser
|
||||
with monkeypatch.context() as mp:
|
||||
openUrl = MagicMock()
|
||||
mp.setattr(QDesktopServices, "openUrl", openUrl)
|
||||
docViewer._linkClicked(QUrl("http://www.example.com"))
|
||||
assert openUrl.called is True
|
||||
assert openUrl.call_args[0][0] == QUrl("http://www.example.com")
|
||||
|
||||
# Click mouse nav buttons
|
||||
qtbot.mouseClick(docViewer.viewport(), Qt.BackButton, pos=rect.center(), delay=100)
|
||||
assert docViewer.docHandle == "88243afbe5ed8"
|
||||
|
||||
@@ -22,9 +22,12 @@ from __future__ import annotations
|
||||
|
||||
import sys
|
||||
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
|
||||
from PyQt5.QtCore import pyqtSlot
|
||||
from PyQt5.QtCore import QUrl, pyqtSlot
|
||||
from PyQt5.QtGui import QDesktopServices
|
||||
from PyQt5.QtPrintSupport import QPrintPreviewDialog
|
||||
from PyQt5.QtWidgets import QAction, QListWidgetItem
|
||||
|
||||
@@ -225,13 +228,26 @@ def testToolManuscript_Features(monkeypatch, qtbot, nwGUI, projPath, mockRnd):
|
||||
assert (item := listView.topLevelItem(3)) and item.data(0, keyRole) == "000000000000c:T0006"
|
||||
assert (item := listView.topLevelItem(4)) and item.data(0, keyRole) == "000000000000e:T0001"
|
||||
|
||||
# Click Outline
|
||||
# Click outline
|
||||
item = listView.topLevelItem(4)
|
||||
assert item is not None
|
||||
with qtbot.waitSignal(manus.buildOutline.outlineEntryClicked) as signal:
|
||||
manus.buildOutline._onItemClick(item)
|
||||
assert signal.args == ["000000000000e:T0001"]
|
||||
|
||||
# Preview Navigation
|
||||
assert manus.docPreview.source() == QUrl("#000000000000e:T0001")
|
||||
manus.docPreview.navigateTo("000000000000c:T0002")
|
||||
assert manus.docPreview.source() == QUrl("#000000000000c:T0002")
|
||||
manus.docPreview._linkClicked(QUrl("#000000000000c:T0003"))
|
||||
assert manus.docPreview.source() == QUrl("#000000000000c:T0003")
|
||||
with monkeypatch.context() as mp:
|
||||
openUrl = MagicMock()
|
||||
mp.setattr(QDesktopServices, "openUrl", openUrl)
|
||||
manus.docPreview._linkClicked(QUrl("http://www.example.com"))
|
||||
assert openUrl.called is True
|
||||
assert openUrl.call_args[0][0] == QUrl("http://www.example.com")
|
||||
|
||||
# Check Preview Stats
|
||||
assert manus.docStats.mainStack.currentWidget() == manus.docStats.minWidget
|
||||
assert manus.docStats.minWordCount.text() == "25"
|
||||
|
||||
Reference in New Issue
Block a user