Merge branch 'main' into release_1.0b1

This commit is contained in:
Veronica K. Berglyd Olsen
2020-08-20 21:28:18 +02:00
committed by GitHub
7 changed files with 201 additions and 83 deletions
+58
View File
@@ -0,0 +1,58 @@
name: PyTest
on:
pull_request:
branches: [ main, dev ]
jobs:
pyTestCov:
runs-on: ubuntu-latest
steps:
- name: Python Setup
uses: actions/setup-python@v1
with:
python-version: 3.8
architecture: x64
- name: Install Packages
run: sudo apt install xvfb libenchant-dev qt5-default
- name: Checkout Source
uses: actions/checkout@v2
- name: Install Dependencies
run: |
pip install --upgrade pip
pip install -r requirements.txt
pip install PyVirtualDisplay
pip install pytest-cov
pip install pytest-xvfb
pip install pytest-qt
pip install codecov
- name: Run Tests
run: xvfb-run pytest -v --cov=nw
- name: Upload to Codecov
uses: codecov/codecov-action@v1
pyTest:
needs: pyTestCov
strategy:
matrix:
python-version: [3.6, 3.7]
runs-on: ubuntu-latest
steps:
- name: Python Setup
uses: actions/setup-python@v1
with:
python-version: ${{ matrix.python-version }}
architecture: x64
- name: Install Packages
run: sudo apt install xvfb libenchant-dev qt5-default
- name: Checkout Source
uses: actions/checkout@v2
- name: Install Dependencies
run: |
pip install --upgrade pip
pip install -r requirements.txt
pip install PyVirtualDisplay
pip install pytest-xvfb
pip install pytest-qt
- name: Run Tests
run: xvfb-run pytest -v
+11 -9
View File
@@ -2,9 +2,9 @@ name: Flake8 Checks
on:
push:
branches: [ main ]
branches: [ main, dev ]
pull_request:
branches: [ main ]
branches: [ main, dev ]
jobs:
checkSyntax:
@@ -15,13 +15,15 @@ jobs:
with:
python-version: 3.7
architecture: x64
- name: Checkout novelWriter
- name: Checkout Source
uses: actions/checkout@v2
- name: Install flake8
run: pip install flake8
- name: Check for Syntax Error in novelWriter
run: flake8 nw --count --select=E9,F63,F7,F82 --show-source --statistics
- name: Check for Syntax Error in Tests
run: flake8 tests --count --select=E9,F63,F7,F82 --show-source --statistics
- name: Check for Code Style Violations
run: flake8 nw --count --max-line-length=99 --ignore E203,E221,E226,E241,E251,E261,E266,E302,E305 --show-source --statistics
- name: Syntax Error Check
run: |
flake8 nw --count --select=E9,F63,F7,F82 --show-source --statistics
flake8 tests --count --select=E9,F63,F7,F82 --show-source --statistics
- name: Coding Style Violations
run: |
flake8 nw --count --max-line-length=99 --ignore E203,E221,E226,E241,E251,E261,E266,E302,E305 --show-source --statistics
flake8 tests --count --max-line-length=99 --ignore E203,E221,E226,E241,E251,E261,E266,E302,E305 --show-source --statistics
-57
View File
@@ -1,57 +0,0 @@
os: linux
dist: focal
services:
- xvfb
language: python
cache:
- bundler
addons:
apt:
packages:
- libenchant-dev
- python3-pyqt5
- python3-pyqt5.qtsvg
- python3-lxml
install:
# - pip install --upgrade pip
- pip install -r requirements.txt
- pip install PyVirtualDisplay
- pip install pytest-cov
- pip install pytest-xvfb
- pip install pytest-qt
- pip install codecov
stages:
- name: Main
- name: Supported
# - name: Future
# if: branch = main
jobs:
include:
- stage: Main
python: 3.8
script:
- python -m pytest --cov=nw -v
after_success:
- codecov
after_failure:
- cat /sys/fs/cgroup/memory/memory.max_usage_in_bytes
- stage: Supported
python: 3.6
script:
- python -m pytest -v
- python: 3.7
script:
- python -m pytest -v
# - stage:
# - Future
# python:
# - 3.9-dev
# script:
# - python -m pytest -v
+1 -1
View File
@@ -1,6 +1,6 @@
# novelWriter
[![Build Status](https://travis-ci.com/vkbo/novelWriter.svg?branch=main)](https://travis-ci.com/vkbo/novelWriter)
[![PyTest + Coverage](https://github.com/vkbo/novelWriter/workflows/PyTest%20+%20Coverage/badge.svg?branch=main)](https://github.com/vkbo/novelWriter/actions)
[![codecov](https://codecov.io/gh/vkbo/novelWriter/branch/main/graph/badge.svg)](https://codecov.io/gh/vkbo/novelWriter)
[![Documentation Status](https://readthedocs.org/projects/novelwriter/badge/?version=latest)](https://novelwriter.readthedocs.io/en/latest/?badge=latest)
[![Flake8 Checks](https://github.com/vkbo/novelWriter/workflows/Flake8%20Checks/badge.svg)](https://github.com/vkbo/novelWriter/actions)
+2 -2
View File
@@ -249,8 +249,8 @@ class GuiOutlineDetails(QScrollArea):
self.itemValue.setText(nwItem.itemStatus)
self.cCValue.setText("{:n}".format(checkInt(novIdx["cCount"], 0)))
self.wCValue.setText("{:n}".format(checkInt(novIdx["pCount"], 0)))
self.pCValue.setText("{:n}".format(checkInt(novIdx["wCount"], 0)))
self.wCValue.setText("{:n}".format(checkInt(novIdx["wCount"], 0)))
self.pCValue.setText("{:n}".format(checkInt(novIdx["pCount"], 0)))
self.synopValue.setText(novIdx["synopsis"])
+1 -1
View File
@@ -48,7 +48,7 @@
<expanded>True</expanded>
</item>
<item handle="7a992350f3eb6" order="0" parent="b3643d0f92e32">
<name>Lorem Ipusm</name>
<name>Lorem Ipsum</name>
<type>FILE</type>
<class>NOVEL</class>
<status>Finished</status>
+128 -13
View File
@@ -8,14 +8,17 @@ import json
from nwtools import cmpFiles
from os import path
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QAction
from PyQt5.QtCore import Qt, QPoint
from PyQt5.QtWidgets import QAction, QDialogButtonBox, QTreeWidgetItem
from nw.gui import (
GuiProjectSettings, GuiItemEditor, GuiAbout, GuiBuildNovel,
GuiDocMerge, GuiDocSplit, GuiWritingStats, GuiProjectWizard
GuiDocMerge, GuiDocSplit, GuiWritingStats, GuiProjectWizard,
GuiProjectLoad
)
from nw.constants import (
nwItemType, nwItemLayout, nwItemClass, nwDocAction, nwUnicode, nwOutline
)
from nw.constants import nwItemType, nwItemLayout, nwItemClass, nwDocAction, nwUnicode
keyDelay = 2
stepDelay = 20
@@ -294,6 +297,7 @@ def testProjectEditor(qtbot, nwTempGUI, nwRef, nwTemp):
projEdit.show()
qtbot.addWidget(projEdit)
qtbot.wait(stepDelay)
projEdit.tabMain.editName.setText("")
for c in "Project Name":
qtbot.keyClick(projEdit.tabMain.editName, c, delay=keyDelay)
@@ -306,6 +310,7 @@ def testProjectEditor(qtbot, nwTempGUI, nwRef, nwTemp):
qtbot.keyClick(projEdit.tabMain.editAuthors, c, delay=keyDelay)
# Test Status Tab
qtbot.wait(stepDelay)
projEdit._tabBox.setCurrentWidget(projEdit.tabStatus)
projEdit.tabStatus.listBox.item(2).setSelected(True)
qtbot.mouseClick(projEdit.tabStatus.delButton, Qt.LeftButton)
@@ -318,6 +323,7 @@ def testProjectEditor(qtbot, nwTempGUI, nwRef, nwTemp):
qtbot.mouseClick(projEdit.tabStatus.saveButton, Qt.LeftButton)
# Auto-Replace Tab
qtbot.wait(stepDelay)
projEdit._tabBox.setCurrentWidget(projEdit.tabReplace)
qtbot.mouseClick(projEdit.tabReplace.addButton, Qt.LeftButton)
@@ -328,19 +334,22 @@ def testProjectEditor(qtbot, nwTempGUI, nwRef, nwTemp):
qtbot.keyClick(projEdit.tabReplace.editValue, c, delay=keyDelay)
qtbot.mouseClick(projEdit.tabReplace.saveButton, Qt.LeftButton)
qtbot.wait(stepDelay)
projEdit.tabReplace.listBox.clearSelection()
qtbot.mouseClick(projEdit.tabReplace.addButton, Qt.LeftButton)
projEdit.tabReplace.listBox.topLevelItem(0).setSelected(True)
for c in "Delete":
qtbot.keyClick(projEdit.tabReplace.editKey, c, delay=keyDelay)
for c in "This Stuff":
qtbot.keyClick(projEdit.tabReplace.editValue, c, delay=keyDelay)
qtbot.mouseClick(projEdit.tabReplace.saveButton, Qt.LeftButton)
projEdit.tabReplace.listBox.clearSelection()
projEdit.tabReplace.listBox.topLevelItem(0).setSelected(True)
newIdx = -1
for i in range(projEdit.tabReplace.listBox.topLevelItemCount()):
if projEdit.tabReplace.listBox.topLevelItem(i).text(0) == "<keyword2>":
newIdx = i
break
assert newIdx >= 0
newItem = projEdit.tabReplace.listBox.topLevelItem(newIdx)
projEdit.tabReplace.listBox.setCurrentItem(newItem)
qtbot.mouseClick(projEdit.tabReplace.delButton, Qt.LeftButton)
qtbot.wait(stepDelay)
projEdit._doSave()
# Open again, and check project settings
@@ -363,8 +372,8 @@ def testProjectEditor(qtbot, nwTempGUI, nwRef, nwTemp):
projFile = path.join(nwTempGUI, "nwProject.nwx")
assert cmpFiles(projFile, path.join(nwRef, "gui", "2_nwProject.nwx"), [2, 8, 9, 10])
nwGUI.closeMain()
# qtbot.stopForInteraction()
nwGUI.closeMain()
@pytest.mark.gui
def testItemEditor(qtbot, nwTempGUI, nwRef, nwTemp):
@@ -1064,3 +1073,109 @@ def testInsertMenu(qtbot, nwTempGUI, nwFuncTemp, nwTemp):
# qtbot.stopForInteraction()
nwGUI.closeMain()
@pytest.mark.gui
def testLoadProject(qtbot, nwTempGUI, nwTemp):
nwGUI = nw.main(["--testmode", "--config=%s" % nwTempGUI, "--data=%s" % nwTemp])
qtbot.addWidget(nwGUI)
nwGUI.show()
qtbot.waitForWindowShown(nwGUI)
qtbot.wait(stepDelay)
nwLoad = GuiProjectLoad(nwGUI)
nwLoad.show()
recentCount = nwLoad.listBox.topLevelItemCount()
assert recentCount > 1
selItem = nwLoad.listBox.topLevelItem(1)
selPath = selItem.data(nwLoad.C_NAME, Qt.UserRole)
nwLoad.selPath.setText("")
nwLoad.listBox.setCurrentItem(selItem)
assert nwLoad.selPath.text() == selPath
qtbot.mouseClick(nwLoad.buttonBox.button(QDialogButtonBox.Open), Qt.LeftButton)
assert nwLoad.openPath == selPath
assert nwLoad.openState == nwLoad.OPEN_STATE
del nwLoad
nwLoad = GuiProjectLoad(nwGUI)
nwLoad.show()
qtbot.mouseClick(nwLoad.buttonBox.button(QDialogButtonBox.Cancel), Qt.LeftButton)
assert nwLoad.openPath is None
assert nwLoad.openState == nwLoad.NONE_STATE
nwLoad.show()
qtbot.mouseClick(nwLoad.newButton, Qt.LeftButton)
assert nwLoad.openPath is None
assert nwLoad.openState == nwLoad.NEW_STATE
nwLoad.show()
nwLoad._keyPressDelete()
assert nwLoad.listBox.topLevelItemCount() == recentCount - 1
nwLoad.close()
# qtbot.stopForInteraction()
nwGUI.closeMain()
@pytest.mark.gui
def testOutline(qtbot, nwTempBuild, nwLipsum, nwTemp):
nwGUI = nw.main(["--testmode", "--config=%s" % nwTempBuild, "--data=%s" % nwTemp])
qtbot.addWidget(nwGUI)
nwGUI.show()
qtbot.waitForWindowShown(nwGUI)
qtbot.wait(stepDelay)
assert nwGUI.openProject(nwLipsum)
nwGUI.mainConf.lastPath = nwTempBuild
nwGUI.rebuildIndex()
nwGUI.tabWidget.setCurrentIndex(nwGUI.idxTabProj)
assert nwGUI.projView.topLevelItemCount() > 0
# Context Menu
nwGUI.projView._headerRightClick(QPoint(1, 1))
nwGUI.projView.headerMenu.actionMap[nwOutline.CCOUNT].activate(QAction.Trigger)
nwGUI.projView.headerMenu.close()
qtbot.mouseClick(nwGUI.projView, Qt.LeftButton)
nwGUI.projView._loadHeaderState()
assert not nwGUI.projView.colHidden[nwOutline.CCOUNT]
# First Item
nwGUI.rebuildOutline()
selItem = nwGUI.projView.topLevelItem(0)
assert isinstance(selItem, QTreeWidgetItem)
nwGUI.projView.setCurrentItem(selItem)
assert nwGUI.projMeta.titleLabel.text() == "<b>Title</b>"
assert nwGUI.projMeta.titleValue.text() == "Lorem Ipsum"
assert nwGUI.projMeta.fileValue.text() == "Lorem Ipsum"
assert nwGUI.projMeta.itemValue.text() == "Finished"
assert nwGUI.projMeta.cCValue.text() == "122"
assert nwGUI.projMeta.wCValue.text() == "18"
assert nwGUI.projMeta.pCValue.text() == "2"
# Scene One
actItem = nwGUI.projView.topLevelItem(1)
chpItem = actItem.child(0)
selItem = chpItem.child(0)
nwGUI.projView.setCurrentItem(selItem)
assert nwGUI.projMeta.titleLabel.text() == "<b>Scene</b>"
assert nwGUI.projMeta.titleValue.text() == "Scene One"
assert nwGUI.projMeta.fileValue.text() == "Scene One"
assert nwGUI.projMeta.itemValue.text() == "Finished"
# Click POV Link
assert nwGUI.projMeta.povKeyValue.text() == "<a href='#pov=Bod'>Bod</a>"
nwGUI.projMeta._tagClicked("#pov=Bod")
assert nwGUI.docViewer.theHandle == "4c4f28287af27"
# qtbot.stopForInteraction()
nwGUI.closeMain()