Review fixes

This commit is contained in:
Michal Siedlaczek 2017-10-03 19:54:54 -04:00
parent b840b8066b
commit 932e7a9ab9
14 changed files with 281 additions and 317 deletions

View File

@ -18,7 +18,6 @@ include tox.ini
include qutebrowser.py
include misc/cheatsheet.svg
include qutebrowser/config/configdata.yml
include qutebrowser/browser/webengine/langs.tsv
prune www
prune scripts/dev

View File

@ -1,9 +1,9 @@
# This file is automatically generated by scripts/dev/recompile_requirements.py
certifi==2017.4.17
certifi==2017.7.27.1
chardet==3.0.4
codecov==2.0.9
coverage==4.4.1
idna==2.5
requests==2.18.1
urllib3==1.21.1
idna==2.6
requests==2.18.4
urllib3==1.22

View File

@ -1,42 +0,0 @@
af-ZA Afrikaans (South Africa) af-ZA-3-0.bdic
bg-BG Bulgarian (Bulgaria) bg-BG-3-0.bdic
ca-ES Catalan (Spain) ca-ES-3-0.bdic
cs-CZ Czech (Czech Republic) cs-CZ-3-0.bdic
da-DK Danish (Denmark) da-DK-3-0.bdic
de-DE German (Germany) de-DE-3-0.bdic
el-GR Greek (Greece) el-GR-3-0.bdic
en-CA English (Canada) en-CA-7-1.bdic
en-GB English (United Kingdom) en-GB-7-1.bdic
en-US English (United States) en-US-7-1.bdic
es-ES Spanish (Spain) es-ES-3-0.bdic
et-EE Estonian (Estonia) et-EE-3-0.bdic
fa-IR Farsi (Iran) fa-IR-7-0.bdic
fo-FO Faroese (Faroe Islands) fo-FO-3-0.bdic
fr-FR French (France) fr-FR-3-0.bdic
he-IL Hebrew (Israel) he-IL-3-0.bdic
hi-IN Hindi (India) hi-IN-3-0.bdic
hr-HR Croatian (Croatia) hr-HR-3-0.bdic
hu-HU Hungarian (Hungary) hu-HU-3-0.bdic
id-ID Indonesian (Indonesia) id-ID-3-0.bdic
it-IT Italian (Italy) it-IT-3-0.bdic
ko Korean ko-3-0.bdic
lt-LT Lithuanian (Lithuania) lt-LT-3-0.bdic
lv-LV Latvian (Latvia) lv-LV-3-0.bdic
nb-NO Norwegian (Norway) nb-NO-3-0.bdic
nl-NL Dutch (Netherlands) nl-NL-3-0.bdic
pl-PL Polish (Poland) pl-PL-3-0.bdic
pt-BR Portuguese (Brazil) pt-BR-3-0.bdic
pt-PT Portuguese (Portugal) pt-PT-3-0.bdic
ro-RO Romanian (Romania) ro-RO-3-0.bdic
ru-RU Russian (Russia) ru-RU-3-0.bdic
sh Serbo-Croatian sh-3-0.bdic
sk-SK Slovak (Slovakia) sk-SK-3-0.bdic
sl-SI Slovenian (Slovenia) sl-SI-3-0.bdic
sq Albanian sq-3-0.bdic
sr Serbian sr-3-0.bdic
sv-SE Swedish (Sweden) sv-SE-3-0.bdic
ta-IN Tamil (India) ta-IN-3-0.bdic
tg-TG Tajik (Tajikistan) tg-TG-5-0.bdic
tr-TR Turkish (Turkey) tr-TR-4-0.bdic
uk-UA Ukrainian (Ukraine) uk-UA-3-0.bdic
vi-VN Vietnamese (Viet Nam) vi-VN-3-0.bdic
1 af-ZA Afrikaans (South Africa) af-ZA-3-0.bdic
2 bg-BG Bulgarian (Bulgaria) bg-BG-3-0.bdic
3 ca-ES Catalan (Spain) ca-ES-3-0.bdic
4 cs-CZ Czech (Czech Republic) cs-CZ-3-0.bdic
5 da-DK Danish (Denmark) da-DK-3-0.bdic
6 de-DE German (Germany) de-DE-3-0.bdic
7 el-GR Greek (Greece) el-GR-3-0.bdic
8 en-CA English (Canada) en-CA-7-1.bdic
9 en-GB English (United Kingdom) en-GB-7-1.bdic
10 en-US English (United States) en-US-7-1.bdic
11 es-ES Spanish (Spain) es-ES-3-0.bdic
12 et-EE Estonian (Estonia) et-EE-3-0.bdic
13 fa-IR Farsi (Iran) fa-IR-7-0.bdic
14 fo-FO Faroese (Faroe Islands) fo-FO-3-0.bdic
15 fr-FR French (France) fr-FR-3-0.bdic
16 he-IL Hebrew (Israel) he-IL-3-0.bdic
17 hi-IN Hindi (India) hi-IN-3-0.bdic
18 hr-HR Croatian (Croatia) hr-HR-3-0.bdic
19 hu-HU Hungarian (Hungary) hu-HU-3-0.bdic
20 id-ID Indonesian (Indonesia) id-ID-3-0.bdic
21 it-IT Italian (Italy) it-IT-3-0.bdic
22 ko Korean ko-3-0.bdic
23 lt-LT Lithuanian (Lithuania) lt-LT-3-0.bdic
24 lv-LV Latvian (Latvia) lv-LV-3-0.bdic
25 nb-NO Norwegian (Norway) nb-NO-3-0.bdic
26 nl-NL Dutch (Netherlands) nl-NL-3-0.bdic
27 pl-PL Polish (Poland) pl-PL-3-0.bdic
28 pt-BR Portuguese (Brazil) pt-BR-3-0.bdic
29 pt-PT Portuguese (Portugal) pt-PT-3-0.bdic
30 ro-RO Romanian (Romania) ro-RO-3-0.bdic
31 ru-RU Russian (Russia) ru-RU-3-0.bdic
32 sh Serbo-Croatian sh-3-0.bdic
33 sk-SK Slovak (Slovakia) sk-SK-3-0.bdic
34 sl-SI Slovenian (Slovenia) sl-SI-3-0.bdic
35 sq Albanian sq-3-0.bdic
36 sr Serbian sr-3-0.bdic
37 sv-SE Swedish (Sweden) sv-SE-3-0.bdic
38 ta-IN Tamil (India) ta-IN-3-0.bdic
39 tg-TG Tajik (Tajikistan) tg-TG-5-0.bdic
40 tr-TR Turkish (Turkey) tr-TR-4-0.bdic
41 uk-UA Ukrainian (Ukraine) uk-UA-3-0.bdic
42 vi-VN Vietnamese (Viet Nam) vi-VN-3-0.bdic

View File

@ -19,132 +19,29 @@
"""Installing and configuring spell-checking for QtWebEngine."""
import glob
import os
from urllib.parse import urljoin
from urllib.request import urlretrieve
from PyQt5.QtCore import QLibraryInfo
repository_url = 'https://redirector.gvt1.com/edgedl/chrome/dict/'
def dictionary_dir():
"""Return the path (str) to the QtWebEngine's dictionaries directory."""
datapath = QLibraryInfo.location(QLibraryInfo.DataPath)
return os.path.join(datapath, 'qtwebengine_dictionaries')
class Language:
def installed_file(code):
"""Return the installed dictionary for the given code.
"""Dictionary language specs."""
def __init__(self, code, name, file):
self.code = code
self.name = name
self.file = file
@staticmethod
def from_array(lang_array):
"""Create Language object from an array.
Args:
lang_array: an array of strings containing
the specs of the language in the following format:
[code, name, file]
"""
return Language.from_tuple(tuple(lang_array))
@staticmethod
def from_tuple(lang_tuple):
"""Create Language object from a tuple.
Args:
lang_tuple: a tuple of strings containing
the specs of the language in the following format:
(code, name, file)
"""
code, name, file = lang_tuple
return Language(code, name, file)
@staticmethod
def from_tsv_string(tsv_string):
"""Create Language object from a string in tab-separated values format.
Args:
tsv_string: a string containing
the specs of the language in the following format:
"code name file"
"""
lang_array = tsv_string.split('\t')
return Language.from_array(lang_array)
def __repr__(self):
return 'Language({}, {}, {})'.format(self.code, self.name, self.file)
def get_dictionary_dir():
"""Return the path to the QtWebEngine's dictionaries directory."""
return os.path.join(QLibraryInfo.location(QLibraryInfo.DataPath),
'qtwebengine_dictionaries')
def get_language_list_file():
"""Return the path to the file with the list of all available languages."""
package_dir = os.path.dirname(os.path.abspath(__file__))
return os.path.join(package_dir, 'langs.tsv')
def get_available_languages():
"""Return a list of Language objects of all available languages."""
with open(get_language_list_file(), 'r', encoding='UTF-8') as file:
return [Language.from_tsv_string(line[:-1]) for line in file]
def get_installed_languages():
"""Return a list of Language objects of all installed languages."""
if not os.path.isdir(get_dictionary_dir()):
return []
installed_files = [os.path.basename(file)
for file in os.listdir(get_dictionary_dir())]
all_languages = get_available_languages()
return filter_languages(all_languages, installed_files,
by=lambda lang: lang.file,
fail_on_unknown=False)
def filter_languages(languages, selected, by=lambda lang: lang.code,
fail_on_unknown=True):
"""Filter a list of languages based on an inclusion list.
Args:
languages: a list of languages to filter
selected: a list of keys to select
by: a function returning the selection key (code by default)
fail_on_unknown: whether to raise an error if there is an unknown
key in selected
Return the filename of the installed dictionary or None
if the dictionary is not installed.
"""
filtered_languages = []
for language in languages:
if by(language) in selected:
filtered_languages.append(language)
selected.remove(by(language))
if fail_on_unknown and selected:
unknown = ', '.join(selected)
raise ValueError('unknown languages found: {}'.format(unknown))
return filtered_languages
def download_dictionary(url, dest):
urlretrieve(url, dest)
def install(languages):
"""Install languages."""
for lang in languages:
try:
print('Installing {}: {}'.format(lang.code, lang.name))
lang_url = urljoin(repository_url, lang.file)
if not os.path.isdir(get_dictionary_dir()):
print('WARN: {} does not exist, creating the directory'.format(
get_dictionary_dir()))
os.makedirs(get_dictionary_dir())
print('Downloading {}'.format(lang_url))
download_dictionary(lang_url, os.path.join(get_dictionary_dir(),
lang.file))
print('Done.')
except PermissionError as e:
print(e)
pathname = os.path.join(dictionary_dir(), '{}*.bdic'.format(code))
print(pathname)
matching_dicts = glob.glob(pathname)
if matching_dicts:
with_extension = os.path.basename(matching_dicts[0])
return os.path.splitext(with_extension)[0]
else:
return None

View File

@ -36,7 +36,7 @@ from PyQt5.QtWebEngineWidgets import (QWebEngineSettings, QWebEngineProfile,
QWebEngineScript)
from qutebrowser.browser import shared
from qutebrowser.browser.webengine.spell import get_installed_languages
from qutebrowser.browser.webengine import spell
from qutebrowser.config import config, websettings
from qutebrowser.utils import utils, standarddir, javascript, qtutils, message
@ -134,20 +134,18 @@ class DictionaryLanguageSetter(DefaultProfileSetter):
def __init__(self):
super().__init__('setSpellCheckLanguages', default=[])
def _find_installed(self, code):
installed_file = spell.installed_file(code)
if not installed_file:
message.warning('Language {} is not installed.'.format(code))
return installed_file
def _set(self, value, settings=None):
if settings is not None:
raise ValueError("'settings' may not be set with "
"DictionaryLanguageSetter!")
installed_langs = dict([(lang.code, lang.file)
for lang in get_installed_languages()])
lang_files = []
for lang_code in value:
if lang_code in installed_langs:
lang_files.append(installed_langs[lang_code][:-5])
else:
message.warning('Language {} is not installed.'
.format(lang_code))
super()._set(lang_files, settings)
filenames = [self._find_installed(code) for code in value]
super()._set([f for f in filenames if f], settings)
def _init_stylesheet(profile):
@ -322,7 +320,6 @@ MAPPINGS = {
'scrolling.smooth':
Attribute(QWebEngineSettings.ScrollAnimatorEnabled),
}
try:
@ -334,8 +331,9 @@ except AttributeError:
if qtutils.version_check('5.8'):
MAPPINGS['spell'] = DefaultProfileSetter('setSpellCheckEnabled')
MAPPINGS['spell_languages'] = DictionaryLanguageSetter()
spellcheck_setter = DefaultProfileSetter('setSpellCheckEnabled')
MAPPINGS['spellcheck.enabled'] = spellcheck_setter
MAPPINGS['spellcheck.languages'] = DictionaryLanguageSetter()
if qtutils.version_check('5.9'):

View File

@ -977,7 +977,7 @@ scrolling.smooth:
## spell
spell:
spellcheck.enabled:
type: Bool
default: true
desc: Enable spell checking.
@ -985,7 +985,7 @@ spell:
QtWebKit: false
QtWebEngine: Qt 5.8
spell_languages:
spellcheck.languages:
type:
name: List
valtype:
@ -1035,7 +1035,11 @@ spell_languages:
- vi-VN: Vietnamese (Viet Nam)
none_ok: true
default:
desc: Spell checking languages.
desc: >-
Spell checking languages.
You can check for available languages and install dictionaries using
scripts/install_dict.py. Run the script with -h/--help for instructions.
backend:
QtWebKit: false
QtWebEngine: Qt 5.8

View File

@ -33,7 +33,6 @@ import sip
from PyQt5.QtCore import QUrl
# so it's available for :debug-pyeval
from PyQt5.QtWidgets import QApplication # pylint: disable=unused-import
from PyQt5.QtWebEngineWidgets import QWebEngineProfile # pylint: disable=unused-import
from qutebrowser.browser import qutescheme
from qutebrowser.utils import log, objreg, usertypes, message, debug, utils

View File

@ -27,6 +27,7 @@ import urllib.error
import shutil
import json
import os
import sys
def get_latest_pdfjs_url():
@ -110,7 +111,25 @@ def update_ace():
urllib.request.urlcleanup()
def run(ace=False, pdfjs=True, fancy_dmg=False, pdfjs_version=None):
def test_dicts():
"""Test available dictionaries."""
sys.path.insert(0, os.curdir)
from scripts import install_dict
from qutebrowser.config import configdata
configdata.init()
for lang in install_dict.available_languages():
sys.stdout.write('Testing dictionary {}... '.format(lang.code))
lang_url = urllib.parse.urljoin(install_dict.API_URL, lang.file_path)
request = urllib.request.Request(lang_url, method='HEAD')
response = urllib.request.urlopen(request)
if response.status == 200:
print('OK')
else:
print('ERROR: {}'.format(response.status))
def run(ace=False, pdfjs=True, fancy_dmg=False, pdfjs_version=None,
dicts=None):
"""Update components based on the given arguments."""
if pdfjs:
update_pdfjs(pdfjs_version)
@ -118,6 +137,8 @@ def run(ace=False, pdfjs=True, fancy_dmg=False, pdfjs_version=None):
update_ace()
if fancy_dmg:
update_dmg_makefile()
if dicts:
test_dicts()
def main():
@ -129,9 +150,14 @@ def main():
required=False, metavar='VERSION')
parser.add_argument('--fancy-dmg', help="Update fancy-dmg Makefile",
action='store_true')
parser.add_argument(
'--dicts', '-d',
help='Test whether all available dictionaries '
'can be reached at the remote repository.',
required=False, action='store_true')
args = parser.parse_args()
run(ace=True, pdfjs=True, fancy_dmg=args.fancy_dmg,
pdfjs_version=args.pdfjs)
pdfjs_version=args.pdfjs, dicts=args.dicts)
if __name__ == '__main__':

View File

@ -24,9 +24,34 @@ Use: python -m scripts.install_dict [--list] [lang [lang [...]]]
"""
import argparse
import base64
import json
import os
import sys
import re
import urllib.parse
import urllib.request
import attr
from qutebrowser.browser.webengine import spell
from qutebrowser.config import configdata
API_URL = 'https://chromium.googlesource.com/chromium/deps/hunspell_dictionaries.git/+/master/'
@attr.s
class Language:
"""Dictionary language specs."""
code = attr.ib(None)
name = attr.ib(None)
file_basename = attr.ib(None)
file_extension = attr.ib('bdic')
@property
def file_path(self):
return '.'.join([self.file_basename, self.file_extension])
def get_argparser():
@ -46,18 +71,105 @@ def print_list(languages):
print('{1}\t{0}'.format(lang.name, lang.code))
def valid_languages():
"""Return a mapping from valid language codes to their names."""
option = configdata.DATA['spellcheck.languages']
return option.typ.valtype.valid_values.descriptions
def language_list_from_api():
"""Return a JSON with a list of available languages from Google API."""
listurl = urllib.parse.urljoin(API_URL, '?format=JSON')
response = urllib.request.urlopen(listurl)
# TODO: what's up with the first 4 characters?
entries = json.loads(response.read().decode('utf-8')[4:])['entries']
return entries
def available_languages():
"""Return a list of Language objects of all available languages."""
lang_map = valid_languages()
api_list = language_list_from_api()
dict_re = re.compile(r"""
(?P<filename>(?P<dict>[a-z]{2}(-[A-Z]{2})?).*)\.bdic
""", re.VERBOSE)
code2file = {}
for lang in api_list:
match = dict_re.match(lang['name'])
if match is not None:
code2file[match.group('dict')] = match.group('filename')
return [
Language(code, name, code2file[code])
for code, name in lang_map.items()
]
def download_dictionary(url, dest):
"""Download a decoded dictionary file."""
response = urllib.request.urlopen(url)
decoded = base64.decodebytes(response.read())
with open(dest, 'bw') as dict_file:
dict_file.write(decoded)
def filter_languages(languages, selected):
"""Filter a list of languages based on an inclusion list.
Args:
languages: a list of languages to filter
selected: a list of keys to select
by: a function returning the selection key (code by default)
fail_on_unknown: whether to raise an error if there is an unknown
key in selected
"""
filtered_languages = []
for language in languages:
if language.code in selected:
filtered_languages.append(language)
selected.remove(language.code)
if selected:
unknown = ', '.join(selected)
raise ValueError('unknown languages found: {}'.format(unknown))
return filtered_languages
def install_lang(lang):
"""Install a single lang given by the argument."""
print('Installing {}: {}'.format(lang.code, lang.name))
lang_url = urllib.parse.urljoin(API_URL, lang.file_path, '?format=TEXT')
if not os.path.isdir(spell.dictionary_dir()):
warn_msg = 'WARN: {} does not exist, creating the directory'
print(warn_msg.format(spell.dictionary_dir()))
os.makedirs(spell.dictionary_dir())
print('Downloading {}'.format(lang_url))
dest = os.path.join(spell.dictionary_dir(), lang.file_path)
download_dictionary(lang_url, dest)
print('Done.')
def install(languages):
"""Install languages."""
for lang in languages:
try:
install_lang(lang)
except PermissionError as e:
print(e)
def main():
if configdata.DATA is None:
configdata.init()
parser = get_argparser()
argv = sys.argv[1:]
args = parser.parse_args(argv)
languages = spell.get_available_languages()
languages = available_languages()
if args.list:
print_list(languages)
elif not args.languages:
parser.print_usage()
else:
try:
spell.install(spell.filter_languages(languages, args.languages))
install(filter_languages(languages, args.languages))
except ValueError as e:
print(e)

View File

@ -29,7 +29,7 @@ import pstats
import os.path
import operator
from qutebrowser.browser.webengine.spell import get_installed_languages
from qutebrowser.browser.webengine import spell
import pytest
from PyQt5.QtCore import PYQT_VERSION
@ -120,18 +120,17 @@ def _get_backend_tag(tag):
def _get_dictionary_tag(tag):
"""Handle tags like must_have_dict=en-US for BDD tests."""
version_re = re.compile(r"""
dict_re = re.compile(r"""
(?P<event>must_have_dict|cannot_have_dict)=(?P<dict>[a-z]{2}-[A-Z]{2})
""", re.VERBOSE)
match = version_re.match(tag)
match = dict_re.match(tag)
if not match:
#return pytest.mark.skip
return None
event = match.group('event')
dictionary = match.group('dict')
has_dict = dictionary in [lang.code for lang in get_installed_languages()]
has_dict = spell.installed_file(dictionary) is not None
if event == 'must_have_dict':
return pytest.mark.skipif(not has_dict, reason=tag)
elif event == 'cannot_have_dict':

View File

@ -2,37 +2,29 @@
Feature: Setting spell checking for QtWebEngine
Background:
Given spell check languages are []
@qtwebkit_skip @qt>=5.8
Scenario: Turn spell check on
Given spell check is off
When I run :set spell true
Then the option spell should be set to true
Then spell check is on
Given I set spellcheck.enabled to false
When I run :set spellcheck.enabled true
Then the option spellcheck.enabled should be set to true
@qtwebkit_skip @qt>=5.8
Scenario: Turn spell check off
Given spell check is on
When I run :set spell false
Then the option spell should be set to false
Then spell check is off
Given I set spellcheck.enabled to true
When I run :set spellcheck.enabled false
Then the option spellcheck.enabled should be set to false
@qtwebkit_skip @qt>=5.8
Scenario: Set an invalid language
When I run :set spell_languages ['invalid-language'] (invalid command)
When I run :set spellcheck.languages ['invalid-language'] (invalid command)
Then the error "set: Invalid value 'invalid-language' *" should be shown
Then actual spell check languages are []
@qtwebkit_skip @qt>=5.8 @cannot_have_dict=af-ZA
Scenario: Set valid but not installed language
When I run :set spell_languages ['af-ZA']
When I run :set spellcheck.languages ['af-ZA']
Then the warning "Language af-ZA is not installed." should be shown
Then actual spell check languages are []
@qtwebkit_skip @qt>=5.8 @must_have_dict=en-US
Scenario: Set valid and installed language
When I run :set spell_languages ["en-US"]
Then the option spell_languages should be set to ["en-US"]
Then actual spell check languages are ['en-US-7-1']
When I run :set spellcheck.languages ["en-US"]
Then the option spellcheck.languages should be set to ["en-US"]

View File

@ -20,39 +20,3 @@
import pytest_bdd as bdd
bdd.scenarios('spell.feature')
@bdd.given(bdd.parsers.parse("spell check is {val}"))
def spellcheck_enabled_given(quteproc, val):
enabled = val == 'on'
quteproc.send_cmd(':debug-pyeval QWebEngineProfile.defaultProfile()' +
'.setSpellCheckEnabled({})'.format(enabled))
quteproc.wait_for_load_finished('qute://pyeval')
@bdd.given(bdd.parsers.parse("spell check languages are {langs}"))
def spellcheck_langs_given(quteproc, langs):
quteproc.send_cmd(':debug-pyeval QWebEngineProfile.defaultProfile()' +
'.setSpellCheckLanguages({})'.format(langs))
quteproc.wait_for_load_finished('qute://pyeval')
@bdd.then(bdd.parsers.parse("spell check is {val}"))
def spellcheck_enabled_then(quteproc, val):
quteproc.send_cmd(':debug-pyeval QWebEngineProfile.defaultProfile()' +
'.isSpellCheckEnabled()')
quteproc.wait_for_load_finished('qute://pyeval')
content = quteproc.get_content().strip()
if val == 'on':
assert content == 'True'
else:
assert content == 'False'
@bdd.then(bdd.parsers.parse("actual spell check languages are {langs}"))
def spellcheck_langs_then(quteproc, langs):
quteproc.send_cmd(':debug-pyeval QWebEngineProfile.defaultProfile()' +
'.spellCheckLanguages()')
quteproc.wait_for_load_finished('qute://pyeval')
actual_langs = quteproc.get_content().strip()
assert actual_langs == langs

View File

@ -18,78 +18,23 @@
# along with qutebrowser. If not, see <http://www.gnu.org/licenses/>.
from os.path import basename, join
import pytest
from qutebrowser.browser.webengine import spell
AFRIKAANS = spell.Language('af-ZA',
'Afrikaans (South Africa)',
'af-ZA-3-0.bdic')
ENGLISH = spell.Language('en-US',
'English (United States)',
'en-US-7-1.bdic')
POLISH = spell.Language('pl-PL',
'Polish (Poland)',
'pl-PL-3-0.bdic')
LANGUAGE_LIST = [AFRIKAANS, ENGLISH, POLISH]
def test_installed_file_dictionary_does_not_exist(tmpdir, monkeypatch):
monkeypatch.setattr(
spell, 'dictionary_dir', lambda: '/some-non-existing-dir')
assert not spell.installed_file('en-US')
def test_get_installed_languages_empty(tmpdir, mocker):
mocker.patch('qutebrowser.browser.webengine.spell.get_dictionary_dir',
lambda: '/some-non-existing-dir')
assert spell.get_installed_languages() == []
def test_installed_file_dictionary_not_installed(tmpdir, monkeypatch):
monkeypatch.setattr(spell, 'dictionary_dir', lambda: str(tmpdir))
assert not spell.installed_file('en-US')
def test_get_installed_languages_non_empty(tmpdir, mocker):
mocker.patch('qutebrowser.browser.webengine.spell.get_dictionary_dir',
lambda: str(tmpdir))
for lang in LANGUAGE_LIST:
open(join(str(tmpdir), lang.file), 'w', encoding='UTF-8').close()
for actual, expected in zip(spell.get_installed_languages(),
LANGUAGE_LIST):
assert (actual.code, actual.name, actual.file) ==\
(expected.code, expected.name, expected.file)
def test_get_available_languages():
language_list = spell.get_available_languages()
assert len(language_list) == 42
first_lang = language_list[0]
assert (first_lang.code, first_lang.name, first_lang.file) ==\
(AFRIKAANS.code, AFRIKAANS.name, AFRIKAANS.file)
def test_filter_languages():
filtered_languages = spell.filter_languages(LANGUAGE_LIST, ['af-ZA'])
assert filtered_languages == [AFRIKAANS]
filtered_languages = spell.filter_languages(LANGUAGE_LIST,
['pl-PL', 'en-US'])
assert filtered_languages == [ENGLISH, POLISH]
with pytest.raises(ValueError):
spell.filter_languages(LANGUAGE_LIST, ['pl-PL', 'en-GB'])
filtered_languages = spell.filter_languages(LANGUAGE_LIST,
['pl-PL-3-0.bdic'],
by=lambda lang: lang.file)
assert filtered_languages == [POLISH]
def test_install(tmpdir, mocker):
mocker.patch('qutebrowser.browser.webengine.spell.get_dictionary_dir',
lambda: str(tmpdir))
mocker.patch('qutebrowser.browser.webengine.spell.download_dictionary',
lambda url, dest: open(dest, 'w', encoding='UTF-8').close())
spell.install(LANGUAGE_LIST)
installed_files = [basename(str(file)) for file in tmpdir.listdir()]
expected_files = [lang.file for lang in LANGUAGE_LIST]
assert sorted(installed_files) == sorted(expected_files)
# TODO: move somewhere to be checked before a release
#def test_available_langs():
# for lang in spell.get_available_languages():
# lang_url = urljoin(spell.repository_url, lang.file)
# response = head(lang_url)
# assert response.status_code == 302
def test_installed_file_dictionary_installed(tmpdir, monkeypatch):
monkeypatch.setattr(spell, 'dictionary_dir', lambda: str(tmpdir))
for lang_file in ['en-US-7-1.bdic', 'pl-PL-3-0.bdic']:
(tmpdir / lang_file).ensure()
assert spell.installed_file('en-US') == 'en-US-7-1'
assert spell.installed_file('pl-PL') == 'pl-PL-3-0'

View File

@ -0,0 +1,71 @@
# vim: ft=python fileencoding=utf-8 sts=4 sw=4 et:
# Copyright 2017 Michal Siedlaczek <michal.siedlaczek@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/>.
import py.path # pylint: disable=no-name-in-module
import pytest
from qutebrowser.browser.webengine import spell
from scripts import install_dict
from qutebrowser.config import configdata
AFRIKAANS = install_dict.Language(
'af-ZA',
'Afrikaans (South Africa)',
'af-ZA-3-0')
ENGLISH = install_dict.Language(
'en-US',
'English (United States)',
'en-US-7-1')
POLISH = install_dict.Language(
'pl-PL',
'Polish (Poland)',
'pl-PL-3-0')
LANGUAGE_LIST = [AFRIKAANS, ENGLISH, POLISH]
@pytest.fixture(autouse=True)
def configdata_init():
"""Initialize configdata if needed."""
if configdata.DATA is None:
configdata.init()
def test_filter_languages():
filtered_langs = install_dict.filter_languages(LANGUAGE_LIST, ['af-ZA'])
assert filtered_langs == [AFRIKAANS]
filtered_langs = install_dict.filter_languages(
LANGUAGE_LIST, ['pl-PL', 'en-US'])
assert filtered_langs == [ENGLISH, POLISH]
with pytest.raises(ValueError):
install_dict.filter_languages(LANGUAGE_LIST, ['pl-PL', 'en-GB'])
def test_install(tmpdir, monkeypatch):
monkeypatch.setattr(spell, 'dictionary_dir', lambda: str(tmpdir))
monkeypatch.setattr(
install_dict, 'download_dictionary',
lambda _url, dest: py.path.local(dest).ensure()) # pylint: disable=no-member
install_dict.install(LANGUAGE_LIST)
installed_files = [f.basename for f in tmpdir.listdir()]
expected_files = [lang.file_path for lang in LANGUAGE_LIST]
assert sorted(installed_files) == sorted(expected_files)