Merge remote-tracking branch 'upstream/master' into bdd_test_spawn_command
This commit is contained in:
commit
4a1ba45efa
@ -44,6 +44,8 @@ Changed
|
|||||||
- Improved detection of URLs/search terms when pasting multiple lines.
|
- Improved detection of URLs/search terms when pasting multiple lines.
|
||||||
- Don't remove `qutebrowser-editor-*` temporary file if editor subprocess crashed
|
- Don't remove `qutebrowser-editor-*` temporary file if editor subprocess crashed
|
||||||
- Userscripts are also searched in `/usr/share/qutebrowser/userscripts`.
|
- Userscripts are also searched in `/usr/share/qutebrowser/userscripts`.
|
||||||
|
- Blocked hosts are now also read from a `blocked-hosts` file in the config dir
|
||||||
|
(e.g. `~/.config/qutebrowser/blocked-hosts`).
|
||||||
|
|
||||||
Fixed
|
Fixed
|
||||||
~~~~~
|
~~~~~
|
||||||
@ -62,6 +64,7 @@ Fixed
|
|||||||
- Fixed very long filenames when downloading `data://`-URLs.
|
- Fixed very long filenames when downloading `data://`-URLs.
|
||||||
- Fixed ugly UI fonts on Windows when Liberation Mono is installed
|
- Fixed ugly UI fonts on Windows when Liberation Mono is installed
|
||||||
- Fixed crash when unbinding key from a section which doesn't exist in the config
|
- Fixed crash when unbinding key from a section which doesn't exist in the config
|
||||||
|
- Fixed report window after a segfault
|
||||||
|
|
||||||
v0.5.1
|
v0.5.1
|
||||||
------
|
------
|
||||||
|
@ -102,6 +102,12 @@ $ rm -r qutebrowser-git
|
|||||||
|
|
||||||
or you could use an AUR helper, e.g. `yaourt -S qutebrowser-git`.
|
or you could use an AUR helper, e.g. `yaourt -S qutebrowser-git`.
|
||||||
|
|
||||||
|
If video or sound don't seem to work, try installing the gstreamer plugins:
|
||||||
|
|
||||||
|
----
|
||||||
|
# pacman -S gst-plugins-{base,good,bad,ugly} gst-libav
|
||||||
|
----
|
||||||
|
|
||||||
On Gentoo
|
On Gentoo
|
||||||
---------
|
---------
|
||||||
|
|
||||||
@ -135,6 +141,21 @@ it with:
|
|||||||
$ nix-env -i qutebrowser
|
$ nix-env -i qutebrowser
|
||||||
----
|
----
|
||||||
|
|
||||||
|
On openSUSE
|
||||||
|
-----------
|
||||||
|
|
||||||
|
There are prebuilt RPMs available for Tumbleweed and Leap 42.1:
|
||||||
|
|
||||||
|
http://software.opensuse.org/download.html?project=home%3Aarpraher&package=qutebrowser[One Click Install]
|
||||||
|
|
||||||
|
Or add the repo manually:
|
||||||
|
|
||||||
|
----
|
||||||
|
# zypper addrepo http://download.opensuse.org/repositories/home:arpraher/openSUSE_Tumbleweed/home:arpraher.repo
|
||||||
|
# zypper refresh
|
||||||
|
# zypper install qutebrowser
|
||||||
|
----
|
||||||
|
|
||||||
On Windows
|
On Windows
|
||||||
----------
|
----------
|
||||||
|
|
||||||
@ -214,7 +235,16 @@ it as part of the packaging process.
|
|||||||
Installing qutebrowser with tox
|
Installing qutebrowser with tox
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
Run tox inside the qutebrowser repository to set up a
|
First of all, clone the repository using http://git-scm.org/[git] and switch
|
||||||
|
into the repository folder:
|
||||||
|
|
||||||
|
----
|
||||||
|
$ git clone https://github.com/The-Compiler/qutebrowser.git
|
||||||
|
$ cd qutebrowser
|
||||||
|
----
|
||||||
|
|
||||||
|
|
||||||
|
Then run tox inside the qutebrowser repository to set up a
|
||||||
https://docs.python.org/3/library/venv.html[virtual environment]:
|
https://docs.python.org/3/library/venv.html[virtual environment]:
|
||||||
|
|
||||||
----
|
----
|
||||||
|
@ -165,10 +165,12 @@ Contributors, sorted by the number of commits in descending order:
|
|||||||
* Thorsten Wißmann
|
* Thorsten Wißmann
|
||||||
* Austin Anderson
|
* Austin Anderson
|
||||||
* Alexey "Averrin" Nabrodov
|
* Alexey "Averrin" Nabrodov
|
||||||
|
* avk
|
||||||
* ZDarian
|
* ZDarian
|
||||||
* Milan Svoboda
|
* Milan Svoboda
|
||||||
* John ShaggyTwoDope Jenkins
|
* John ShaggyTwoDope Jenkins
|
||||||
* Peter Vilim
|
* Peter Vilim
|
||||||
|
* Clayton Craft
|
||||||
* Oliver Caldwell
|
* Oliver Caldwell
|
||||||
* Philipp Hansch
|
* Philipp Hansch
|
||||||
* Jonas Schürmann
|
* Jonas Schürmann
|
||||||
@ -191,7 +193,6 @@ Contributors, sorted by the number of commits in descending order:
|
|||||||
* Link
|
* Link
|
||||||
* Larry Hynes
|
* Larry Hynes
|
||||||
* Johannes Altmanninger
|
* Johannes Altmanninger
|
||||||
* avk
|
|
||||||
* Samir Benmendil
|
* Samir Benmendil
|
||||||
* Regina Hug
|
* Regina Hug
|
||||||
* Mathias Fussenegger
|
* Mathias Fussenegger
|
||||||
@ -199,9 +200,9 @@ Contributors, sorted by the number of commits in descending order:
|
|||||||
* Fritz V155 Reichwald
|
* Fritz V155 Reichwald
|
||||||
* Franz Fellner
|
* Franz Fellner
|
||||||
* Corentin Jule
|
* Corentin Jule
|
||||||
* Clayton Craft
|
|
||||||
* zwarag
|
* zwarag
|
||||||
* xd1le
|
* xd1le
|
||||||
|
* issue
|
||||||
* haxwithaxe
|
* haxwithaxe
|
||||||
* evan
|
* evan
|
||||||
* dylan araps
|
* dylan araps
|
||||||
|
@ -72,6 +72,8 @@
|
|||||||
=== adblock-update
|
=== adblock-update
|
||||||
Update the adblock block lists.
|
Update the adblock block lists.
|
||||||
|
|
||||||
|
This updates ~/.local/share/qutebrowser/blocked-hosts with downloaded host lists and re-reads ~/.config/qutebrowser/blocked-hosts.
|
||||||
|
|
||||||
[[back]]
|
[[back]]
|
||||||
=== back
|
=== back
|
||||||
Syntax: +:back [*--tab*] [*--bg*] [*--window*]+
|
Syntax: +:back [*--tab*] [*--bg*] [*--window*]+
|
||||||
|
@ -4,19 +4,15 @@ MAINTAINER Florian Bruhin <me@the-compiler.org>
|
|||||||
RUN echo 'Server = http://mirror.de.leaseweb.net/archlinux/$repo/os/$arch' > /etc/pacman.d/mirrorlist
|
RUN echo 'Server = http://mirror.de.leaseweb.net/archlinux/$repo/os/$arch' > /etc/pacman.d/mirrorlist
|
||||||
RUN pacman-key --init && pacman-key --populate archlinux && pacman -Sy --noconfirm archlinux-keyring
|
RUN pacman-key --init && pacman-key --populate archlinux && pacman -Sy --noconfirm archlinux-keyring
|
||||||
|
|
||||||
RUN pacman-key -r 0xD6A1C70FE80A0C82 && \
|
|
||||||
pacman-key --lsign-key 0xD6A1C70FE80A0C82 && \
|
|
||||||
echo -e '[qt-debug]\nServer = http://qutebrowser.org/qt-debug/$arch' >> /etc/pacman.conf
|
|
||||||
|
|
||||||
RUN pacman -Suyy --noconfirm
|
RUN pacman -Suyy --noconfirm
|
||||||
RUN pacman-db-upgrade
|
RUN pacman-db-upgrade
|
||||||
|
|
||||||
RUN pacman -S --noconfirm \
|
RUN pacman -S --noconfirm \
|
||||||
git \
|
git \
|
||||||
python-tox \
|
python-tox \
|
||||||
qt5-base-debug \
|
qt5-base \
|
||||||
qt5-webkit-debug \
|
qt5-webkit \
|
||||||
python-pyqt5-debug \
|
python-pyqt5 \
|
||||||
xorg-xinit \
|
xorg-xinit \
|
||||||
herbstluftwm \
|
herbstluftwm \
|
||||||
xorg-server-xvfb
|
xorg-server-xvfb
|
||||||
|
@ -92,9 +92,11 @@ class HostBlocker:
|
|||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
_blocked_hosts: A set of blocked hosts.
|
_blocked_hosts: A set of blocked hosts.
|
||||||
|
_config_blocked_hosts: A set of blocked hosts from ~/.config.
|
||||||
_in_progress: The DownloadItems which are currently downloading.
|
_in_progress: The DownloadItems which are currently downloading.
|
||||||
_done_count: How many files have been read successfully.
|
_done_count: How many files have been read successfully.
|
||||||
_hosts_file: The path to the blocked-hosts file.
|
_local_hosts_file: The path to the blocked-hosts file.
|
||||||
|
_config_hosts_file: The path to a blocked-hosts in ~/.config
|
||||||
|
|
||||||
Class attributes:
|
Class attributes:
|
||||||
WHITELISTED: Hosts which never should be blocked.
|
WHITELISTED: Hosts which never should be blocked.
|
||||||
@ -105,13 +107,22 @@ class HostBlocker:
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._blocked_hosts = set()
|
self._blocked_hosts = set()
|
||||||
|
self._config_blocked_hosts = set()
|
||||||
self._in_progress = []
|
self._in_progress = []
|
||||||
self._done_count = 0
|
self._done_count = 0
|
||||||
|
|
||||||
data_dir = standarddir.data()
|
data_dir = standarddir.data()
|
||||||
if data_dir is None:
|
if data_dir is None:
|
||||||
self._hosts_file = None
|
self._local_hosts_file = None
|
||||||
else:
|
else:
|
||||||
self._hosts_file = os.path.join(data_dir, 'blocked-hosts')
|
self._local_hosts_file = os.path.join(data_dir, 'blocked-hosts')
|
||||||
|
|
||||||
|
config_dir = standarddir.config()
|
||||||
|
if config_dir is None:
|
||||||
|
self._config_hosts_file = None
|
||||||
|
else:
|
||||||
|
self._config_hosts_file = os.path.join(config_dir, 'blocked-hosts')
|
||||||
|
|
||||||
objreg.get('config').changed.connect(self.on_config_changed)
|
objreg.get('config').changed.connect(self.on_config_changed)
|
||||||
|
|
||||||
def is_blocked(self, url):
|
def is_blocked(self, url):
|
||||||
@ -119,21 +130,46 @@ class HostBlocker:
|
|||||||
if not config.get('content', 'host-blocking-enabled'):
|
if not config.get('content', 'host-blocking-enabled'):
|
||||||
return False
|
return False
|
||||||
host = url.host()
|
host = url.host()
|
||||||
return host in self._blocked_hosts and not is_whitelisted_host(host)
|
return ((host in self._blocked_hosts or
|
||||||
|
host in self._config_blocked_hosts) and
|
||||||
|
not is_whitelisted_host(host))
|
||||||
|
|
||||||
|
def _read_hosts_file(self, filename, target):
|
||||||
|
"""Read hosts from the given filename.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
filename: The file to read.
|
||||||
|
target: The set to store the hosts in.
|
||||||
|
|
||||||
|
Return:
|
||||||
|
True if a read was attempted, False otherwise
|
||||||
|
"""
|
||||||
|
if filename is None or not os.path.exists(filename):
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(filename, 'r', encoding='utf-8') as f:
|
||||||
|
for line in f:
|
||||||
|
target.add(line.strip())
|
||||||
|
except OSError:
|
||||||
|
log.misc.exception("Failed to read host blocklist!")
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
def read_hosts(self):
|
def read_hosts(self):
|
||||||
"""Read hosts from the existing blocked-hosts file."""
|
"""Read hosts from the existing blocked-hosts file."""
|
||||||
self._blocked_hosts = set()
|
self._blocked_hosts = set()
|
||||||
if self._hosts_file is None:
|
|
||||||
|
if self._local_hosts_file is None:
|
||||||
return
|
return
|
||||||
if os.path.exists(self._hosts_file):
|
|
||||||
try:
|
self._read_hosts_file(self._config_hosts_file,
|
||||||
with open(self._hosts_file, 'r', encoding='utf-8') as f:
|
self._config_blocked_hosts)
|
||||||
for line in f:
|
|
||||||
self._blocked_hosts.add(line.strip())
|
found = self._read_hosts_file(self._local_hosts_file,
|
||||||
except OSError:
|
self._blocked_hosts)
|
||||||
log.misc.exception("Failed to read host blocklist!")
|
|
||||||
else:
|
if not found:
|
||||||
args = objreg.get('args')
|
args = objreg.get('args')
|
||||||
if (config.get('content', 'host-block-lists') is not None and
|
if (config.get('content', 'host-block-lists') is not None and
|
||||||
args.basedir is None):
|
args.basedir is None):
|
||||||
@ -142,8 +178,14 @@ class HostBlocker:
|
|||||||
|
|
||||||
@cmdutils.register(instance='host-blocker', win_id='win_id')
|
@cmdutils.register(instance='host-blocker', win_id='win_id')
|
||||||
def adblock_update(self, win_id):
|
def adblock_update(self, win_id):
|
||||||
"""Update the adblock block lists."""
|
"""Update the adblock block lists.
|
||||||
if self._hosts_file is None:
|
|
||||||
|
This updates ~/.local/share/qutebrowser/blocked-hosts with downloaded
|
||||||
|
host lists and re-reads ~/.config/qutebrowser/blocked-hosts.
|
||||||
|
"""
|
||||||
|
self._read_hosts_file(self._config_hosts_file,
|
||||||
|
self._config_blocked_hosts)
|
||||||
|
if self._local_hosts_file is None:
|
||||||
raise cmdexc.CommandError("No data storage is configured!")
|
raise cmdexc.CommandError("No data storage is configured!")
|
||||||
self._blocked_hosts = set()
|
self._blocked_hosts = set()
|
||||||
self._done_count = 0
|
self._done_count = 0
|
||||||
@ -221,7 +263,7 @@ class HostBlocker:
|
|||||||
|
|
||||||
def on_lists_downloaded(self):
|
def on_lists_downloaded(self):
|
||||||
"""Install block lists after files have been downloaded."""
|
"""Install block lists after files have been downloaded."""
|
||||||
with open(self._hosts_file, 'w', encoding='utf-8') as f:
|
with open(self._local_hosts_file, 'w', encoding='utf-8') as f:
|
||||||
for host in sorted(self._blocked_hosts):
|
for host in sorted(self._blocked_hosts):
|
||||||
f.write(host + '\n')
|
f.write(host + '\n')
|
||||||
message.info('current', "adblock: Read {} hosts from {} sources."
|
message.info('current', "adblock: Read {} hosts from {} sources."
|
||||||
@ -233,7 +275,7 @@ class HostBlocker:
|
|||||||
urls = config.get('content', 'host-block-lists')
|
urls = config.get('content', 'host-block-lists')
|
||||||
if urls is None:
|
if urls is None:
|
||||||
try:
|
try:
|
||||||
os.remove(self._hosts_file)
|
os.remove(self._local_hosts_file)
|
||||||
except OSError:
|
except OSError:
|
||||||
log.misc.exception("Failed to delete hosts file.")
|
log.misc.exception("Failed to delete hosts file.")
|
||||||
|
|
||||||
|
@ -23,8 +23,6 @@ import urllib.parse
|
|||||||
|
|
||||||
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QUrl
|
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject, QUrl
|
||||||
|
|
||||||
from qutebrowser.misc import httpclient
|
|
||||||
|
|
||||||
|
|
||||||
class PastebinClient(QObject):
|
class PastebinClient(QObject):
|
||||||
|
|
||||||
@ -47,11 +45,17 @@ class PastebinClient(QObject):
|
|||||||
success = pyqtSignal(str)
|
success = pyqtSignal(str)
|
||||||
error = pyqtSignal(str)
|
error = pyqtSignal(str)
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, client, parent=None):
|
||||||
|
"""Constructor.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
client: The HTTPClient to use. Will be reparented.
|
||||||
|
"""
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self._client = httpclient.HTTPClient(self)
|
client.setParent(self)
|
||||||
self._client.error.connect(self.error)
|
client.error.connect(self.error)
|
||||||
self._client.success.connect(self.on_client_success)
|
client.success.connect(self.on_client_success)
|
||||||
|
self._client = client
|
||||||
|
|
||||||
def paste(self, name, title, text, parent=None):
|
def paste(self, name, title, text, parent=None):
|
||||||
"""Paste the text into a pastebin and return the URL.
|
"""Paste the text into a pastebin and return the URL.
|
||||||
|
@ -219,14 +219,12 @@ class BrowserPage(QWebPage):
|
|||||||
def _show_pdfjs(self, reply):
|
def _show_pdfjs(self, reply):
|
||||||
"""Show the reply with pdfjs."""
|
"""Show the reply with pdfjs."""
|
||||||
try:
|
try:
|
||||||
page = pdfjs.generate_pdfjs_page(reply.url()).encode('utf-8')
|
page = pdfjs.generate_pdfjs_page(reply.url())
|
||||||
except pdfjs.PDFJSNotFound:
|
except pdfjs.PDFJSNotFound:
|
||||||
# pylint: disable=no-member
|
page = jinja.render('no_pdfjs.html',
|
||||||
# WORKAROUND for https://bitbucket.org/logilab/pylint/issue/490/
|
url=reply.url().toDisplayString())
|
||||||
page = (jinja.env.get_template('no_pdfjs.html')
|
self.mainFrame().setContent(page.encode('utf-8'), 'text/html',
|
||||||
.render(url=reply.url().toDisplayString())
|
reply.url())
|
||||||
.encode('utf-8'))
|
|
||||||
self.mainFrame().setContent(page, 'text/html', reply.url())
|
|
||||||
reply.deleteLater()
|
reply.deleteLater()
|
||||||
|
|
||||||
def shutdown(self):
|
def shutdown(self):
|
||||||
|
22
qutebrowser/html/undef_error.html
Normal file
22
qutebrowser/html/undef_error.html
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<!--
|
||||||
|
vim: ft=html fileencoding=utf-8 sts=4 sw=4 et:
|
||||||
|
-->
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>Error while rendering HTML</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Error while rendering internal qutebrowser page</h1>
|
||||||
|
<p>There was an error while rendering {pagename}.</p>
|
||||||
|
|
||||||
|
<p>This most likely happened because you updated qutebrowser but didn't restart yet.</p>
|
||||||
|
|
||||||
|
<p>If you believe this isn't the case and this is a bug, please do :report.<p>
|
||||||
|
|
||||||
|
<h2>Traceback</h2>
|
||||||
|
<pre>{traceback}</pre>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -36,7 +36,7 @@ from PyQt5.QtWidgets import (QDialog, QLabel, QTextEdit, QPushButton,
|
|||||||
|
|
||||||
import qutebrowser
|
import qutebrowser
|
||||||
from qutebrowser.utils import version, log, utils, objreg, qtutils
|
from qutebrowser.utils import version, log, utils, objreg, qtutils
|
||||||
from qutebrowser.misc import miscwidgets, autoupdate, msgbox
|
from qutebrowser.misc import miscwidgets, autoupdate, msgbox, httpclient
|
||||||
from qutebrowser.browser.network import pastebin
|
from qutebrowser.browser.network import pastebin
|
||||||
from qutebrowser.config import config
|
from qutebrowser.config import config
|
||||||
|
|
||||||
@ -141,7 +141,8 @@ class _CrashDialog(QDialog):
|
|||||||
self.setWindowTitle("Whoops!")
|
self.setWindowTitle("Whoops!")
|
||||||
self.resize(QSize(640, 600))
|
self.resize(QSize(640, 600))
|
||||||
self._vbox = QVBoxLayout(self)
|
self._vbox = QVBoxLayout(self)
|
||||||
self._paste_client = pastebin.PastebinClient(self)
|
http_client = httpclient.HTTPClient()
|
||||||
|
self._paste_client = pastebin.PastebinClient(http_client, self)
|
||||||
self._pypi_client = autoupdate.PyPIVersionClient(self)
|
self._pypi_client = autoupdate.PyPIVersionClient(self)
|
||||||
self._init_text()
|
self._init_text()
|
||||||
|
|
||||||
@ -508,11 +509,23 @@ class FatalCrashDialog(_CrashDialog):
|
|||||||
def _init_text(self):
|
def _init_text(self):
|
||||||
super()._init_text()
|
super()._init_text()
|
||||||
text = ("<b>qutebrowser was restarted after a fatal crash.</b><br/>"
|
text = ("<b>qutebrowser was restarted after a fatal crash.</b><br/>"
|
||||||
"<br/>Note: Crash reports for fatal crashes sometimes don't "
|
"QTWEBENGINE_NOTE"
|
||||||
|
"<br/>Crash reports for fatal crashes sometimes don't "
|
||||||
"contain the information necessary to fix an issue. Please "
|
"contain the information necessary to fix an issue. Please "
|
||||||
"follow the steps in <a href='https://github.com/The-Compiler/"
|
"follow the steps in <a href='https://github.com/The-Compiler/"
|
||||||
"qutebrowser/blob/master/doc/stacktrace.asciidoc'>"
|
"qutebrowser/blob/master/doc/stacktrace.asciidoc'>"
|
||||||
"stacktrace.asciidoc</a> to submit a stacktrace.<br/>")
|
"stacktrace.asciidoc</a> to submit a stacktrace.<br/>")
|
||||||
|
|
||||||
|
if datetime.datetime.now() < datetime.datetime(2016, 4, 23):
|
||||||
|
note = ("<br/>Fatal crashes like this are often caused by the "
|
||||||
|
"current QtWebKit backend.<br/><b>I'm currently running a "
|
||||||
|
"crowdfunding for the new QtWebEngine backend, based on "
|
||||||
|
"Chromium:</b> <a href='http://igg.me/at/qutebrowser'>"
|
||||||
|
"igg.me/at/qutebrowser</a><br/>")
|
||||||
|
text = text.replace('QTWEBENGINE_NOTE', note)
|
||||||
|
else:
|
||||||
|
text = text.replace('QTWEBENGINE_NOTE', '')
|
||||||
|
|
||||||
self._lbl.setText(text)
|
self._lbl.setText(text)
|
||||||
|
|
||||||
def _init_checkboxes(self):
|
def _init_checkboxes(self):
|
||||||
|
@ -72,7 +72,7 @@ class CrashHandler(QObject):
|
|||||||
|
|
||||||
def handle_segfault(self):
|
def handle_segfault(self):
|
||||||
"""Handle a segfault from a previous run."""
|
"""Handle a segfault from a previous run."""
|
||||||
data_dir = None
|
data_dir = standarddir.data()
|
||||||
if data_dir is None:
|
if data_dir is None:
|
||||||
return
|
return
|
||||||
logname = os.path.join(data_dir, 'crash.log')
|
logname = os.path.join(data_dir, 'crash.log')
|
||||||
|
@ -21,10 +21,12 @@
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
|
import traceback
|
||||||
|
|
||||||
import jinja2
|
import jinja2
|
||||||
|
import jinja2.exceptions
|
||||||
|
|
||||||
from qutebrowser.utils import utils
|
from qutebrowser.utils import utils, log
|
||||||
|
|
||||||
from PyQt5.QtCore import QUrl
|
from PyQt5.QtCore import QUrl
|
||||||
|
|
||||||
@ -74,8 +76,14 @@ def resource_url(path):
|
|||||||
|
|
||||||
def render(template, **kwargs):
|
def render(template, **kwargs):
|
||||||
"""Render the given template and pass the given arguments to it."""
|
"""Render the given template and pass the given arguments to it."""
|
||||||
return _env.get_template(template).render(**kwargs)
|
try:
|
||||||
|
return _env.get_template(template).render(**kwargs)
|
||||||
|
except jinja2.exceptions.UndefinedError:
|
||||||
|
log.misc.exception("UndefinedError while rendering " + template)
|
||||||
|
err_path = os.path.join('html', 'undef_error.html')
|
||||||
|
err_template = utils.read_file(err_path)
|
||||||
|
tb = traceback.format_exc()
|
||||||
|
return err_template.format(pagename=template, traceback=tb)
|
||||||
|
|
||||||
_env = jinja2.Environment(loader=Loader('html'), autoescape=_guess_autoescape)
|
_env = jinja2.Environment(loader=Loader('html'), autoescape=_guess_autoescape)
|
||||||
_env.globals['resource_url'] = resource_url
|
_env.globals['resource_url'] = resource_url
|
||||||
|
@ -65,6 +65,8 @@ PERFECT_FILES = [
|
|||||||
'qutebrowser/browser/network/filescheme.py'),
|
'qutebrowser/browser/network/filescheme.py'),
|
||||||
('tests/unit/browser/network/test_networkreply.py',
|
('tests/unit/browser/network/test_networkreply.py',
|
||||||
'qutebrowser/browser/network/networkreply.py'),
|
'qutebrowser/browser/network/networkreply.py'),
|
||||||
|
('tests/unit/browser/network/test_pastebin.py',
|
||||||
|
'qutebrowser/browser/network/pastebin.py'),
|
||||||
('tests/unit/browser/test_signalfilter.py',
|
('tests/unit/browser/test_signalfilter.py',
|
||||||
'qutebrowser/browser/signalfilter.py'),
|
'qutebrowser/browser/signalfilter.py'),
|
||||||
|
|
||||||
@ -102,6 +104,8 @@ PERFECT_FILES = [
|
|||||||
'qutebrowser/mainwindow/statusbar/textbase.py'),
|
'qutebrowser/mainwindow/statusbar/textbase.py'),
|
||||||
('tests/unit/mainwindow/statusbar/test_prompt.py',
|
('tests/unit/mainwindow/statusbar/test_prompt.py',
|
||||||
'qutebrowser/mainwindow/statusbar/prompt.py'),
|
'qutebrowser/mainwindow/statusbar/prompt.py'),
|
||||||
|
('tests/unit/mainwindow/statusbar/test_url.py',
|
||||||
|
'qutebrowser/mainwindow/statusbar/url.py'),
|
||||||
|
|
||||||
('tests/unit/config/test_configtypes.py',
|
('tests/unit/config/test_configtypes.py',
|
||||||
'qutebrowser/config/configtypes.py'),
|
'qutebrowser/config/configtypes.py'),
|
||||||
|
@ -31,23 +31,27 @@ import argparse
|
|||||||
def main():
|
def main():
|
||||||
args = get_args()
|
args = get_args()
|
||||||
if args.browser in ['chromium', 'firefox', 'ie']:
|
if args.browser in ['chromium', 'firefox', 'ie']:
|
||||||
import_netscape_bookmarks(args.bookmarks)
|
import_netscape_bookmarks(args.bookmarks, args.bookmark_format)
|
||||||
|
|
||||||
|
|
||||||
def get_args():
|
def get_args():
|
||||||
"""Get the argparse parser."""
|
"""Get the argparse parser."""
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
epilog="To import bookmarks from Chromium, Firefox or IE, "
|
epilog="To import bookmarks from Chromium, Firefox or IE, "
|
||||||
"export them to HTML in your browsers bookmark manager.")
|
"export them to HTML in your browsers bookmark manager. "
|
||||||
parser.add_argument('browser', help="Which browser?",
|
"By default, this script will output in a quickmarks format.")
|
||||||
|
parser.add_argument('browser', help="Which browser? (chromium, firefox)",
|
||||||
choices=['chromium', 'firefox', 'ie'],
|
choices=['chromium', 'firefox', 'ie'],
|
||||||
metavar='browser')
|
metavar='browser')
|
||||||
parser.add_argument('bookmarks', help="Bookmarks file")
|
parser.add_argument('-b', help="Output in bookmark format.",
|
||||||
|
dest='bookmark_format', action='store_true',
|
||||||
|
default=False, required=False)
|
||||||
|
parser.add_argument('bookmarks', help="Bookmarks file (html format)")
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
return args
|
return args
|
||||||
|
|
||||||
|
|
||||||
def import_netscape_bookmarks(bookmarks_file):
|
def import_netscape_bookmarks(bookmarks_file, is_bookmark_format):
|
||||||
"""Import bookmarks from a NETSCAPE-Bookmark-file v1.
|
"""Import bookmarks from a NETSCAPE-Bookmark-file v1.
|
||||||
|
|
||||||
Generated by Chromium, Firefox, IE and possibly more browsers
|
Generated by Chromium, Firefox, IE and possibly more browsers
|
||||||
@ -57,11 +61,15 @@ def import_netscape_bookmarks(bookmarks_file):
|
|||||||
soup = bs4.BeautifulSoup(f, 'html.parser')
|
soup = bs4.BeautifulSoup(f, 'html.parser')
|
||||||
|
|
||||||
html_tags = soup.findAll('a')
|
html_tags = soup.findAll('a')
|
||||||
|
if is_bookmark_format:
|
||||||
|
output_template = '{tag[href]} {tag.string}'
|
||||||
|
else:
|
||||||
|
output_template = '{tag.string} {tag[href]}'
|
||||||
|
|
||||||
bookmarks = []
|
bookmarks = []
|
||||||
for tag in html_tags:
|
for tag in html_tags:
|
||||||
if tag['href'] not in bookmarks:
|
if tag['href'] not in bookmarks:
|
||||||
bookmarks.append('{tag.string} {tag[href]}'.format(tag=tag))
|
bookmarks.append(output_template.format(tag=tag))
|
||||||
|
|
||||||
for bookmark in bookmarks:
|
for bookmark in bookmarks:
|
||||||
print(bookmark)
|
print(bookmark)
|
||||||
|
125
tests/unit/browser/network/test_pastebin.py
Normal file
125
tests/unit/browser/network/test_pastebin.py
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
|
||||||
|
|
||||||
|
# Copyright 2016 Anna Kobak (avk) <awerk@onet.eu>:
|
||||||
|
#
|
||||||
|
# This file is part of qutebrowser.
|
||||||
|
#
|
||||||
|
# qutebrowser is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# qutebrowser is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from PyQt5.QtCore import pyqtSignal, QUrl, QObject
|
||||||
|
|
||||||
|
from qutebrowser.browser.network import pastebin
|
||||||
|
from qutebrowser.misc import httpclient
|
||||||
|
|
||||||
|
|
||||||
|
class HTTPPostStub(QObject):
|
||||||
|
|
||||||
|
"""A stub class for HTTPClient.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
url: the last url send by post()
|
||||||
|
data: the last data send by post()
|
||||||
|
"""
|
||||||
|
|
||||||
|
success = pyqtSignal(str)
|
||||||
|
error = pyqtSignal(str)
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.url = None
|
||||||
|
self.data = None
|
||||||
|
|
||||||
|
def post(self, url, data=None):
|
||||||
|
self.url = url
|
||||||
|
self.data = data
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def pbclient():
|
||||||
|
http_stub = HTTPPostStub()
|
||||||
|
client = pastebin.PastebinClient(http_stub)
|
||||||
|
return client
|
||||||
|
|
||||||
|
|
||||||
|
def test_constructor(qapp):
|
||||||
|
http_client = httpclient.HTTPClient()
|
||||||
|
pbclient = pastebin.PastebinClient(http_client)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('data', [
|
||||||
|
{
|
||||||
|
"name": "XYZ",
|
||||||
|
"title": "hello world",
|
||||||
|
"text": "xyz. 123 \n 172ANB",
|
||||||
|
"reply": "abc"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "the name",
|
||||||
|
"title": "the title",
|
||||||
|
"text": "some Text",
|
||||||
|
"reply": "some parent"
|
||||||
|
}
|
||||||
|
])
|
||||||
|
def test_paste_with_parent(data, pbclient):
|
||||||
|
http_stub = pbclient._client
|
||||||
|
pbclient.paste(data["name"], data["title"], data["text"], data["reply"])
|
||||||
|
assert http_stub.data == data
|
||||||
|
assert http_stub.url == QUrl('http://paste.the-compiler.org/api/create')
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('data', [
|
||||||
|
{
|
||||||
|
"name": "XYZ",
|
||||||
|
"title": "hello world",
|
||||||
|
"text": "xyz. 123 \n 172ANB"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "the name",
|
||||||
|
"title": "the title",
|
||||||
|
"text": "some Text"
|
||||||
|
}
|
||||||
|
])
|
||||||
|
def test_paste_without_parent(data, pbclient):
|
||||||
|
http_stub = pbclient._client
|
||||||
|
pbclient.paste(data["name"], data["title"], data["text"])
|
||||||
|
assert pbclient._client.data == data
|
||||||
|
assert http_stub.url == QUrl('http://paste.the-compiler.org/api/create')
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('http', [
|
||||||
|
"http://paste.the-compiler.org/view/ges83nt3",
|
||||||
|
"http://paste.the-compiler.org/view/3gjnwg4"
|
||||||
|
])
|
||||||
|
def test_on_client_success(http, pbclient, qtbot):
|
||||||
|
with qtbot.assertNotEmitted(pbclient.error):
|
||||||
|
with qtbot.waitSignal(pbclient.success):
|
||||||
|
pbclient._client.success.emit(http)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('http', [
|
||||||
|
"http invalid",
|
||||||
|
"http:/invalid.org"
|
||||||
|
"http//invalid.com"
|
||||||
|
])
|
||||||
|
def test_client_success_invalid_http(http, pbclient, qtbot):
|
||||||
|
with qtbot.assertNotEmitted(pbclient.success):
|
||||||
|
with qtbot.waitSignal(pbclient.error):
|
||||||
|
pbclient._client.success.emit(http)
|
||||||
|
|
||||||
|
|
||||||
|
def test_client_error(pbclient, qtbot):
|
||||||
|
with qtbot.assertNotEmitted(pbclient.success):
|
||||||
|
with qtbot.waitSignal(pbclient.error):
|
||||||
|
pbclient._client.error.emit("msg")
|
146
tests/unit/mainwindow/statusbar/test_url.py
Normal file
146
tests/unit/mainwindow/statusbar/test_url.py
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
|
||||||
|
|
||||||
|
# Copyright 2016 Clayton Craft (craftyguy) <craftyguy@gmail.com>
|
||||||
|
#
|
||||||
|
# This file is part of qutebrowser.
|
||||||
|
#
|
||||||
|
# qutebrowser is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# qutebrowser is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
"""Test Statusbar url."""
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
import collections
|
||||||
|
|
||||||
|
from qutebrowser.browser import webview
|
||||||
|
from qutebrowser.mainwindow.statusbar import url
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def tab_widget():
|
||||||
|
"""Fixture providing a fake tab widget."""
|
||||||
|
tab = collections.namedtuple('Tab', 'cur_url load_status')
|
||||||
|
tab.cur_url = collections.namedtuple('cur_url', 'toDisplayString')
|
||||||
|
return tab
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def url_widget(qtbot, monkeypatch, config_stub):
|
||||||
|
"""Fixture providing a Url widget."""
|
||||||
|
config_stub.data = {
|
||||||
|
'colors': {
|
||||||
|
'statusbar.url.bg': 'white',
|
||||||
|
'statusbar.url.fg': 'black',
|
||||||
|
'statusbar.url.fg.success': 'yellow',
|
||||||
|
'statusbar.url.fg.success.https': 'green',
|
||||||
|
'statusbar.url.fg.error': 'red',
|
||||||
|
'statusbar.url.fg.warn': 'orange',
|
||||||
|
'statusbar.url.fg.hover': 'blue'
|
||||||
|
},
|
||||||
|
'fonts': {},
|
||||||
|
}
|
||||||
|
monkeypatch.setattr(
|
||||||
|
'qutebrowser.mainwindow.statusbar.url.style.config', config_stub)
|
||||||
|
widget = url.UrlText()
|
||||||
|
qtbot.add_widget(widget)
|
||||||
|
assert not widget.isVisible()
|
||||||
|
return widget
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('url_text', [
|
||||||
|
'http://abc123.com/this/awesome/url.html',
|
||||||
|
'https://supersecret.gov/nsa/files.txt',
|
||||||
|
'Th1$ i$ n0t @ n0rm@L uRL! P@n1c! <-->',
|
||||||
|
None
|
||||||
|
])
|
||||||
|
def test_set_url(url_widget, url_text):
|
||||||
|
"""Test text displayed by the widget."""
|
||||||
|
url_widget.set_url(url_text)
|
||||||
|
if url_text is not None:
|
||||||
|
assert url_widget.text() == url_text
|
||||||
|
else:
|
||||||
|
assert url_widget.text() == ""
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('url_text, title, text', [
|
||||||
|
('http://abc123.com/this/awesome/url.html', 'Awesome site', 'click me!'),
|
||||||
|
('https://supersecret.gov/nsa/files.txt', 'Secret area', None),
|
||||||
|
('Th1$ i$ n0t @ n0rm@L uRL! P@n1c! <-->', 'Probably spam', 'definitely'),
|
||||||
|
(None, None, 'did I break?!')
|
||||||
|
])
|
||||||
|
def test_set_hover_url(url_widget, url_text, title, text):
|
||||||
|
"""Test text when hovering over a link."""
|
||||||
|
url_widget.set_hover_url(url_text, title, text)
|
||||||
|
if url_text is not None:
|
||||||
|
assert url_widget.text() == url_text
|
||||||
|
assert url_widget._urltype == url.UrlType.hover
|
||||||
|
else:
|
||||||
|
assert url_widget.text() == ''
|
||||||
|
assert url_widget._urltype == url.UrlType.normal
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('status, expected', [
|
||||||
|
(webview.LoadStatus.success, url.UrlType.success),
|
||||||
|
(webview.LoadStatus.success_https, url.UrlType.success_https),
|
||||||
|
(webview.LoadStatus.error, url.UrlType.error),
|
||||||
|
(webview.LoadStatus.warn, url.UrlType.warn),
|
||||||
|
(webview.LoadStatus.loading, url.UrlType.normal),
|
||||||
|
(webview.LoadStatus.none, url.UrlType.normal)
|
||||||
|
])
|
||||||
|
def test_on_load_status_changed(url_widget, status, expected):
|
||||||
|
"""Test text when status is changed."""
|
||||||
|
url_widget.set_url('www.example.com')
|
||||||
|
url_widget.on_load_status_changed(status.name)
|
||||||
|
assert url_widget._urltype == expected
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('load_status, url_text', [
|
||||||
|
(url.UrlType.success, 'http://abc123.com/this/awesome/url.html'),
|
||||||
|
(url.UrlType.success, 'http://reddit.com/r/linux'),
|
||||||
|
(url.UrlType.success_https, 'www.google.com'),
|
||||||
|
(url.UrlType.success_https, 'https://supersecret.gov/nsa/files.txt'),
|
||||||
|
(url.UrlType.warn, 'www.shadysite.org/some/path/to/file/with/issues.htm'),
|
||||||
|
(url.UrlType.error, 'Th1$ i$ n0t @ n0rm@L uRL! P@n1c! <-->'),
|
||||||
|
(url.UrlType.error, None)
|
||||||
|
])
|
||||||
|
def test_on_tab_changed(url_widget, tab_widget, load_status, url_text):
|
||||||
|
tab_widget.load_status = load_status
|
||||||
|
tab_widget.cur_url.toDisplayString = lambda: url_text
|
||||||
|
url_widget.on_tab_changed(tab_widget)
|
||||||
|
if url_text is not None:
|
||||||
|
assert url_widget._urltype == load_status
|
||||||
|
assert url_widget.text() == url_text
|
||||||
|
else:
|
||||||
|
assert url_widget._urltype == url.UrlType.normal
|
||||||
|
assert url_widget.text() == ''
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('url_text, load_status, expected_status', [
|
||||||
|
('http://abc123.com/this/awesome/url.html', webview.LoadStatus.success,
|
||||||
|
url.UrlType.success),
|
||||||
|
('https://supersecret.gov/nsa/files.txt', webview.LoadStatus.success_https,
|
||||||
|
url.UrlType.success_https),
|
||||||
|
('Th1$ i$ n0t @ n0rm@L uRL! P@n1c! <-->', webview.LoadStatus.error,
|
||||||
|
url.UrlType.error),
|
||||||
|
('http://www.qutebrowser.org/CONTRIBUTING.html', webview.LoadStatus.loading,
|
||||||
|
url.UrlType.normal),
|
||||||
|
('www.whatisthisurl.com', webview.LoadStatus.warn, url.UrlType.warn)
|
||||||
|
])
|
||||||
|
def test_normal_url(url_widget, url_text, load_status, expected_status):
|
||||||
|
url_widget.set_url(url_text)
|
||||||
|
url_widget.on_load_status_changed(load_status.name)
|
||||||
|
url_widget.set_hover_url(url_text, "", "")
|
||||||
|
url_widget.set_hover_url("", "", "")
|
||||||
|
assert url_widget.text() == url_text
|
||||||
|
assert url_widget._urltype == expected_status
|
@ -23,21 +23,28 @@ import os
|
|||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
import logging
|
||||||
import jinja2
|
import jinja2
|
||||||
from PyQt5.QtCore import QUrl
|
from PyQt5.QtCore import QUrl
|
||||||
|
|
||||||
from qutebrowser.utils import jinja
|
from qutebrowser.utils import utils, jinja
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(autouse=True)
|
@pytest.fixture(autouse=True)
|
||||||
def patch_read_file(monkeypatch):
|
def patch_read_file(monkeypatch):
|
||||||
"""pytest fixture to patch utils.read_file."""
|
"""pytest fixture to patch utils.read_file."""
|
||||||
|
real_read_file = utils.read_file
|
||||||
|
|
||||||
def _read_file(path):
|
def _read_file(path):
|
||||||
"""A read_file which returns a simple template if the path is right."""
|
"""A read_file which returns a simple template if the path is right."""
|
||||||
if path == os.path.join('html', 'test.html'):
|
if path == os.path.join('html', 'test.html'):
|
||||||
return """Hello {{var}}"""
|
return """Hello {{var}}"""
|
||||||
elif path == os.path.join('html', 'test2.html'):
|
elif path == os.path.join('html', 'test2.html'):
|
||||||
return """{{ resource_url('utils/testfile') }}"""
|
return """{{ resource_url('utils/testfile') }}"""
|
||||||
|
elif path == os.path.join('html', 'undef.html'):
|
||||||
|
return """{{ does_not_exist() }}"""
|
||||||
|
elif path == os.path.join('html', 'undef_error.html'):
|
||||||
|
return real_read_file(path)
|
||||||
else:
|
else:
|
||||||
raise IOError("Invalid path {}!".format(path))
|
raise IOError("Invalid path {}!".format(path))
|
||||||
|
|
||||||
@ -87,6 +94,18 @@ def test_utf8():
|
|||||||
assert data == "Hello \u2603"
|
assert data == "Hello \u2603"
|
||||||
|
|
||||||
|
|
||||||
|
def test_undefined_function(caplog):
|
||||||
|
"""Make sure we don't crash if an undefined function is called."""
|
||||||
|
with caplog.at_level(logging.ERROR):
|
||||||
|
data = jinja.render('undef.html')
|
||||||
|
assert 'There was an error while rendering undef.html' in data
|
||||||
|
assert "'does_not_exist' is undefined" in data
|
||||||
|
assert data.startswith('<!DOCTYPE html>')
|
||||||
|
|
||||||
|
assert len(caplog.records) == 1
|
||||||
|
assert caplog.records[0].msg == "UndefinedError while rendering undef.html"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize('name, expected', [
|
@pytest.mark.parametrize('name, expected', [
|
||||||
(None, False),
|
(None, False),
|
||||||
('foo', False),
|
('foo', False),
|
||||||
|
12
tox.ini
12
tox.ini
@ -37,17 +37,17 @@ deps =
|
|||||||
pytest-instafail==0.3.0
|
pytest-instafail==0.3.0
|
||||||
pytest-travis-fold==1.2.0
|
pytest-travis-fold==1.2.0
|
||||||
pytest-repeat==0.2
|
pytest-repeat==0.2
|
||||||
pytest-rerunfailures==1.0.1
|
pytest-rerunfailures==1.0.2
|
||||||
pytest-xvfb==0.2.0
|
pytest-xvfb==0.2.0
|
||||||
six==1.10.0
|
six==1.10.0
|
||||||
termcolor==1.1.0
|
termcolor==1.1.0
|
||||||
vulture==0.8.1
|
vulture==0.8.1
|
||||||
Werkzeug==0.11.4
|
Werkzeug==0.11.5
|
||||||
wheel==0.29.0
|
wheel==0.29.0
|
||||||
cherrypy==5.1.0
|
cherrypy==5.1.0
|
||||||
commands =
|
commands =
|
||||||
{envpython} scripts/link_pyqt.py --tox {envdir}
|
{envpython} scripts/link_pyqt.py --tox {envdir}
|
||||||
{envpython} -m py.test {posargs:tests}
|
{envpython} -m pytest {posargs:tests}
|
||||||
|
|
||||||
[testenv:py35-cov]
|
[testenv:py35-cov]
|
||||||
basepython = python3.5
|
basepython = python3.5
|
||||||
@ -56,7 +56,7 @@ passenv = {[testenv]passenv}
|
|||||||
deps = {[testenv]deps}
|
deps = {[testenv]deps}
|
||||||
commands =
|
commands =
|
||||||
{envpython} scripts/link_pyqt.py --tox {envdir}
|
{envpython} scripts/link_pyqt.py --tox {envdir}
|
||||||
{envpython} -m py.test --cov --cov-report xml --cov-report=html --cov-report= {posargs:tests}
|
{envpython} -m pytest --cov --cov-report xml --cov-report=html --cov-report= {posargs:tests}
|
||||||
{envpython} scripts/dev/check_coverage.py {posargs}
|
{envpython} scripts/dev/check_coverage.py {posargs}
|
||||||
|
|
||||||
[testenv:py34-cov]
|
[testenv:py34-cov]
|
||||||
@ -66,7 +66,7 @@ passenv = {[testenv]passenv}
|
|||||||
deps = {[testenv]deps}
|
deps = {[testenv]deps}
|
||||||
commands =
|
commands =
|
||||||
{envpython} scripts/link_pyqt.py --tox {envdir}
|
{envpython} scripts/link_pyqt.py --tox {envdir}
|
||||||
{envpython} -m py.test --cov --cov-report xml --cov-report=html --cov-report= {posargs:tests}
|
{envpython} -m pytest --cov --cov-report xml --cov-report=html --cov-report= {posargs:tests}
|
||||||
{envpython} scripts/dev/check_coverage.py {posargs}
|
{envpython} scripts/dev/check_coverage.py {posargs}
|
||||||
|
|
||||||
[testenv:mkvenv]
|
[testenv:mkvenv]
|
||||||
@ -99,7 +99,7 @@ setenv =
|
|||||||
QUTE_NO_DISPLAY=1
|
QUTE_NO_DISPLAY=1
|
||||||
commands =
|
commands =
|
||||||
{envpython} scripts/link_pyqt.py --tox {envdir}
|
{envpython} scripts/link_pyqt.py --tox {envdir}
|
||||||
{envpython} -m py.test {posargs:tests}
|
{envpython} -m pytest {posargs:tests}
|
||||||
|
|
||||||
[testenv:misc]
|
[testenv:misc]
|
||||||
ignore_errors = true
|
ignore_errors = true
|
||||||
|
Loading…
Reference in New Issue
Block a user