forked from pool/i18nspector
0ba5a3e9ed
- Add patch switch-to-pytest.patch: * Use pytest to run tests, rather than nose. OBS-URL: https://build.opensuse.org/request/show/932847 OBS-URL: https://build.opensuse.org/package/show/M17N/i18nspector?expand=0&rev=59
4673 lines
146 KiB
Diff
4673 lines
146 KiB
Diff
From b84035ee74cc646ddbabbb99d565e50973fe7b1d Mon Sep 17 00:00:00 2001
|
|
From: Stuart Prescott <stuart@debian.org>
|
|
Date: Thu, 28 Oct 2021 16:39:36 +1100
|
|
Subject: [PATCH 01/10] Change tests from nose to pytest
|
|
|
|
Some of the 'yield' tests are easy to refactor into parameterised tests
|
|
while others would take a fair amount of rethinking and/or additional
|
|
helper functions. At this stage, the relevant functions are simply decorated
|
|
with a 'collect_yielded' decorator that collects all the yield tests at
|
|
collection time and sets them up as a parameterised test to be run later.
|
|
---
|
|
pytest.ini | 4 +
|
|
tests/conftest.py | 21 ++
|
|
tests/run-tests | 21 +-
|
|
tests/test_changelog.py | 33 +-
|
|
tests/test_domains.py | 23 +-
|
|
tests/test_encodings.py | 117 +++---
|
|
tests/test_gettext.py | 134 ++++---
|
|
tests/test_iconv.py | 11 +-
|
|
tests/test_ling.py | 566 +++++++++++++++---------------
|
|
tests/test_misc.py | 49 ++-
|
|
tests/test_moparser.py | 21 +-
|
|
tests/test_polib4us.py | 14 +-
|
|
tests/test_strformat_c.py | 404 +++++++++++----------
|
|
tests/test_strformat_perlbrace.py | 19 +-
|
|
tests/test_strformat_pybrace.py | 99 +++---
|
|
tests/test_strformat_python.py | 198 ++++++-----
|
|
tests/test_tags.py | 27 +-
|
|
tests/test_terminal.py | 8 +-
|
|
tests/test_version.py | 8 +-
|
|
tests/test_xml.py | 12 +-
|
|
tests/tools.py | 41 ++-
|
|
21 files changed, 935 insertions(+), 895 deletions(-)
|
|
create mode 100644 pytest.ini
|
|
create mode 100644 tests/conftest.py
|
|
|
|
Index: i18nspector-0.26/pytest.ini
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ i18nspector-0.26/pytest.ini
|
|
@@ -0,0 +1,4 @@
|
|
+[pytest]
|
|
+testpaths = tests
|
|
+python_classes = test_*
|
|
+python_functions = test *_test test_*
|
|
Index: i18nspector-0.26/tests/conftest.py
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ i18nspector-0.26/tests/conftest.py
|
|
@@ -0,0 +1,19 @@
|
|
+
|
|
+import os
|
|
+import tempfile
|
|
+
|
|
+
|
|
+def pytest_sessionstart(session):
|
|
+ envvar = 'XDG_CACHE_HOME'
|
|
+ old_xdg_cache_home = os.environ.get(envvar, None)
|
|
+ xdg_temp_dir = tempfile.TemporaryDirectory(prefix='i18nspector.tests.') # pylint: disable=consider-using-with
|
|
+ os.environ[envvar] = xdg_temp_dir.name
|
|
+
|
|
+ def cleanup():
|
|
+ xdg_temp_dir.cleanup()
|
|
+ if old_xdg_cache_home is None:
|
|
+ del os.environ[envvar]
|
|
+ else:
|
|
+ os.environ[envvar] = old_xdg_cache_home
|
|
+
|
|
+ session.config.add_cleanup(cleanup)
|
|
Index: i18nspector-0.26/tests/run-tests
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/tests/run-tests
|
|
+++ i18nspector-0.26/tests/run-tests
|
|
@@ -1,6 +1,6 @@
|
|
-#!/usr/bin/env python3
|
|
+#!/bin/bash
|
|
|
|
-# Copyright © 2013-2016 Jakub Wilk <jwilk@jwilk.net>
|
|
+# Copyright © 2021 Stuart Prescott <stuart@debian.org>
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
# of this software and associated documentation files (the “Software”), to deal
|
|
@@ -20,19 +20,6 @@
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
# SOFTWARE.
|
|
|
|
-import os
|
|
-import sys
|
|
-import tempfile
|
|
+set -e
|
|
|
|
-import nose
|
|
-
|
|
-sys.path[0] += '/..'
|
|
-
|
|
-from tests import blackbox_tests
|
|
-
|
|
-if __name__ == '__main__':
|
|
- with tempfile.TemporaryDirectory(prefix='i18nspector.tests.') as tmpdir:
|
|
- os.environ['XDG_CACHE_HOME'] = tmpdir
|
|
- nose.main(addplugins=[blackbox_tests.Plugin()])
|
|
-
|
|
-# vim:ts=4 sts=4 sw=4 et
|
|
+pytest -rsx "$@"
|
|
Index: i18nspector-0.26/tests/test_changelog.py
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/tests/test_changelog.py
|
|
+++ i18nspector-0.26/tests/test_changelog.py
|
|
@@ -21,11 +21,9 @@
|
|
import os
|
|
import re
|
|
|
|
-from nose.tools import (
|
|
- assert_not_equal,
|
|
-)
|
|
-
|
|
import lib.tags
|
|
+from . import tools
|
|
+
|
|
|
|
here = os.path.dirname(__file__)
|
|
docdir = os.path.join(here, os.pardir, 'doc')
|
|
@@ -52,32 +50,39 @@ rename_re = re.compile(
|
|
r'([\w-]+) [(]from ([\w-]+)[)]'
|
|
)
|
|
|
|
-def test_tags():
|
|
- path = os.path.join(docdir, 'changelog')
|
|
- with open(path, 'rt', encoding='UTF-8') as file:
|
|
- changelog = file.read()
|
|
- summaries = summary_re.findall(changelog)
|
|
- changelog_tags = set()
|
|
+
|
|
+@tools.collect_yielded
|
|
+def test_tag_paramerisation():
|
|
def add(info, tag):
|
|
del info
|
|
if tag in changelog_tags:
|
|
raise AssertionError('changelog adds tag twice: ' + tag)
|
|
changelog_tags.add(tag)
|
|
+
|
|
def remove(info, tag):
|
|
del info
|
|
if tag not in changelog_tags:
|
|
raise AssertionError('changelog removes non-existent tag: ' + tag)
|
|
changelog_tags.remove(tag)
|
|
+
|
|
def rename(info, removed_tag, added_tag):
|
|
- assert_not_equal(removed_tag, added_tag)
|
|
+ assert removed_tag != added_tag
|
|
remove(info, removed_tag)
|
|
add(info, added_tag)
|
|
+
|
|
def check(info, tag):
|
|
del info
|
|
if tag not in changelog_tags:
|
|
raise AssertionError('tag not in changelog: ' + tag)
|
|
if tag not in data_tags:
|
|
raise AssertionError('changelog adds unknown tag: ' + tag)
|
|
+
|
|
+ path = os.path.join(docdir, 'changelog')
|
|
+ with open(path, 'rt', encoding='UTF-8') as file:
|
|
+ changelog = file.read()
|
|
+ summaries = summary_re.findall(changelog)
|
|
+ changelog_tags = set()
|
|
+
|
|
for summary in reversed(summaries):
|
|
match = summary_details_re.match(summary)
|
|
for key, lines in match.groupdict().items():
|
|
@@ -86,16 +91,17 @@ def test_tags():
|
|
lines = [l[8:] for l in lines.splitlines()]
|
|
if key == 'added':
|
|
for tag in lines:
|
|
- yield add, 'add', tag
|
|
+ yield add, ('add', tag)
|
|
elif key == 'renamed':
|
|
for line in lines:
|
|
added_tag, removed_tag = rename_re.match(line).groups()
|
|
- yield rename, 'rename', removed_tag, added_tag
|
|
+ yield rename, ('rename', removed_tag, added_tag)
|
|
else:
|
|
assert False
|
|
data_tags = frozenset(tag.name for tag in lib.tags.iter_tags())
|
|
for tag in sorted(changelog_tags | data_tags):
|
|
- yield check, 'check', tag
|
|
+ yield check, ('check', tag)
|
|
+
|
|
|
|
def test_trailing_whitespace():
|
|
path = os.path.join(docdir, 'changelog')
|
|
Index: i18nspector-0.26/tests/test_domains.py
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/tests/test_domains.py
|
|
+++ i18nspector-0.26/tests/test_domains.py
|
|
@@ -18,12 +18,7 @@
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
# SOFTWARE.
|
|
|
|
-from nose.tools import (
|
|
- assert_false,
|
|
- assert_is,
|
|
- assert_raises,
|
|
- assert_true,
|
|
-)
|
|
+import pytest
|
|
|
|
import lib.domains as M
|
|
|
|
@@ -32,9 +27,9 @@ class test_special_domains:
|
|
def t(self, domain, special=True):
|
|
result = M.is_special_domain(domain)
|
|
if special:
|
|
- assert_true(result)
|
|
+ assert result
|
|
else:
|
|
- assert_false(result)
|
|
+ assert not result
|
|
|
|
def test_ok(self):
|
|
self.t('test.jwilk.net', False)
|
|
@@ -68,9 +63,9 @@ class test_special_domain_emails:
|
|
def t(self, email, special=True):
|
|
result = M.is_email_in_special_domain(email)
|
|
if special:
|
|
- assert_true(result)
|
|
+ assert result
|
|
else:
|
|
- assert_false(result)
|
|
+ assert not result
|
|
|
|
def test_valid(self):
|
|
self.t('jwilk@test.jwilk.net', False)
|
|
@@ -79,14 +74,14 @@ class test_special_domain_emails:
|
|
self.t('jwilk@example.net')
|
|
|
|
def test_no_at(self):
|
|
- with assert_raises(ValueError):
|
|
+ with pytest.raises(ValueError):
|
|
self.t('jwilk%jwilk.net')
|
|
|
|
class test_dotless_domains:
|
|
|
|
def t(self, domain, dotless=True):
|
|
result = M.is_dotless_domain(domain)
|
|
- assert_is(result, dotless)
|
|
+ assert result is dotless
|
|
|
|
def test_dotless(self):
|
|
self.t('net')
|
|
@@ -99,7 +94,7 @@ class test_dotless_emails:
|
|
|
|
def t(self, email, dotless=True):
|
|
result = M.is_email_in_dotless_domain(email)
|
|
- assert_is(result, dotless)
|
|
+ assert result is dotless
|
|
|
|
def test_dotless(self):
|
|
self.t('jwilk@net')
|
|
@@ -108,7 +103,7 @@ class test_dotless_emails:
|
|
self.t('jwilk@example.net', False)
|
|
|
|
def test_no_at(self):
|
|
- with assert_raises(ValueError):
|
|
+ with pytest.raises(ValueError):
|
|
self.t('jwilk%jwilk.net')
|
|
|
|
# vim:ts=4 sts=4 sw=4 et
|
|
Index: i18nspector-0.26/tests/test_encodings.py
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/tests/test_encodings.py
|
|
+++ i18nspector-0.26/tests/test_encodings.py
|
|
@@ -20,79 +20,85 @@
|
|
|
|
import curses.ascii
|
|
import sys
|
|
+import unittest
|
|
|
|
-import nose
|
|
-from nose.tools import (
|
|
- assert_equal,
|
|
- assert_false,
|
|
- assert_is_none,
|
|
- assert_not_in,
|
|
- assert_raises,
|
|
- assert_true,
|
|
-)
|
|
+import pytest
|
|
|
|
import lib.encodings as E
|
|
|
|
from . import tools
|
|
|
|
+
|
|
+# methods using the tools.collect_yielded decorator don't have a 'self'
|
|
+# since they end up being run before 'self' exists. pylint doesn't
|
|
+# understand this unusual situation
|
|
+# pylint: disable=no-method-argument
|
|
+
|
|
+
|
|
class test_is_portable_encoding:
|
|
|
|
def test_found(self):
|
|
- assert_true(E.is_portable_encoding('ISO-8859-2'))
|
|
+ assert E.is_portable_encoding('ISO-8859-2')
|
|
|
|
def test_found_(self):
|
|
- assert_true(E.is_portable_encoding('ISO_8859-2'))
|
|
+ assert E.is_portable_encoding('ISO_8859-2')
|
|
|
|
def test_found_nonpython(self):
|
|
- assert_false(E.is_portable_encoding('KOI8-T'))
|
|
- assert_true(E.is_portable_encoding('KOI8-T', python=False))
|
|
+ assert not E.is_portable_encoding('KOI8-T')
|
|
+ assert E.is_portable_encoding('KOI8-T', python=False)
|
|
|
|
def test_notfound(self):
|
|
- assert_false(E.is_portable_encoding('ISO-8859-16'))
|
|
- assert_false(E.is_portable_encoding('ISO-8859-16', python=False))
|
|
+ assert not E.is_portable_encoding('ISO-8859-16')
|
|
+ assert not E.is_portable_encoding('ISO-8859-16', python=False)
|
|
|
|
class test_propose_portable_encoding:
|
|
|
|
def test_identity(self):
|
|
encoding = 'ISO-8859-2'
|
|
portable_encoding = E.propose_portable_encoding(encoding)
|
|
- assert_equal(portable_encoding, encoding)
|
|
+ assert portable_encoding == encoding
|
|
|
|
- def test_found(self):
|
|
+ @tools.collect_yielded
|
|
+ def test_found():
|
|
def t(encoding, expected_portable_encoding):
|
|
portable_encoding = E.propose_portable_encoding(encoding)
|
|
- assert_equal(portable_encoding, expected_portable_encoding)
|
|
- yield t, 'ISO8859-2', 'ISO-8859-2'
|
|
- yield t, 'ISO_8859-2', 'ISO-8859-2'
|
|
- yield t, 'Windows-1250', 'CP1250'
|
|
+ assert portable_encoding == expected_portable_encoding
|
|
+ yield t, ('ISO8859-2', 'ISO-8859-2')
|
|
+ yield t, ('ISO_8859-2', 'ISO-8859-2')
|
|
+ yield t, ('Windows-1250', 'CP1250')
|
|
|
|
def test_notfound(self):
|
|
portable_encoding = E.propose_portable_encoding('ISO-8859-16')
|
|
- assert_is_none(portable_encoding)
|
|
+ assert portable_encoding is None
|
|
+
|
|
+
|
|
+def _test_missing(encoding):
|
|
+ assert not E.is_ascii_compatible_encoding(encoding)
|
|
+ with pytest.raises(E.EncodingLookupError):
|
|
+ E.is_ascii_compatible_encoding(encoding, missing_ok=False)
|
|
+
|
|
|
|
class test_ascii_compatibility:
|
|
|
|
- def test_portable(self):
|
|
+ @tools.collect_yielded
|
|
+ def test_portable():
|
|
def t(encoding):
|
|
- assert_true(E.is_ascii_compatible_encoding(encoding))
|
|
- assert_true(E.is_ascii_compatible_encoding(encoding, missing_ok=False))
|
|
+ assert E.is_ascii_compatible_encoding(encoding)
|
|
+ assert E.is_ascii_compatible_encoding(encoding, missing_ok=False)
|
|
for encoding in E.get_portable_encodings():
|
|
yield t, encoding
|
|
|
|
- def test_incompatible(self):
|
|
+ @tools.collect_yielded
|
|
+ def test_incompatible():
|
|
def t(encoding):
|
|
- assert_false(E.is_ascii_compatible_encoding(encoding))
|
|
- assert_false(E.is_ascii_compatible_encoding(encoding, missing_ok=False))
|
|
+ assert not E.is_ascii_compatible_encoding(encoding)
|
|
+ assert not E.is_ascii_compatible_encoding(encoding, missing_ok=False)
|
|
yield t, 'UTF-7'
|
|
yield t, 'UTF-16'
|
|
|
|
- def _test_missing(self, encoding):
|
|
- assert_false(E.is_ascii_compatible_encoding(encoding))
|
|
- with assert_raises(E.EncodingLookupError):
|
|
- E.is_ascii_compatible_encoding(encoding, missing_ok=False)
|
|
-
|
|
- def test_non_text(self):
|
|
- t = self._test_missing
|
|
+ @tools.collect_yielded
|
|
+ def test_non_text():
|
|
+ t = _test_missing
|
|
yield t, 'base64_codec'
|
|
yield t, 'bz2_codec'
|
|
yield t, 'hex_codec'
|
|
@@ -102,7 +108,8 @@ class test_ascii_compatibility:
|
|
yield t, 'zlib_codec'
|
|
|
|
def test_missing(self):
|
|
- self._test_missing('eggs')
|
|
+ _test_missing('eggs')
|
|
+
|
|
|
|
class test_get_character_name:
|
|
|
|
@@ -110,44 +117,44 @@ class test_get_character_name:
|
|
for i in range(ord('a'), ord('z')):
|
|
u = chr(i)
|
|
name = E.get_character_name(u)
|
|
- assert_equal(name, 'LATIN SMALL LETTER ' + u.upper())
|
|
+ assert name == 'LATIN SMALL LETTER ' + u.upper()
|
|
u = chr(i).upper()
|
|
name = E.get_character_name(u)
|
|
- assert_equal(name, 'LATIN CAPITAL LETTER ' + u)
|
|
+ assert name == 'LATIN CAPITAL LETTER ' + u
|
|
|
|
def test_c0(self):
|
|
for i, curses_name in zip(range(0, 0x20), curses.ascii.controlnames):
|
|
u = chr(i)
|
|
name = E.get_character_name(u)
|
|
expected_name = 'control character ' + curses_name
|
|
- assert_equal(name, expected_name)
|
|
+ assert name == expected_name
|
|
|
|
def test_del(self):
|
|
name = E.get_character_name('\x7F')
|
|
- assert_equal(name, 'control character DEL')
|
|
+ assert name == 'control character DEL'
|
|
|
|
def test_c1(self):
|
|
for i in range(0x80, 0xA0):
|
|
u = chr(i)
|
|
name = E.get_character_name(u)
|
|
- assert_true(name.startswith('control character '))
|
|
+ assert name.startswith('control character ')
|
|
|
|
def test_uniqueness(self):
|
|
names = set()
|
|
for i in range(0, 0x100):
|
|
u = chr(i)
|
|
name = E.get_character_name(u)
|
|
- assert_not_in(name, names)
|
|
+ assert name not in names
|
|
names.add(name)
|
|
|
|
def test_non_character(self):
|
|
name = E.get_character_name('\uFFFE')
|
|
- assert_equal(name, 'non-character')
|
|
+ assert name == 'non-character'
|
|
name = E.get_character_name('\uFFFF')
|
|
- assert_equal(name, 'non-character')
|
|
+ assert name == 'non-character'
|
|
|
|
def test_lookup_error(self):
|
|
- with assert_raises(ValueError):
|
|
+ with pytest.raises(ValueError):
|
|
E.get_character_name('\uE000')
|
|
|
|
class test_extra_encoding:
|
|
@@ -164,13 +171,13 @@ class test_extra_encoding:
|
|
except LookupError:
|
|
pass
|
|
else:
|
|
- raise nose.SkipTest(
|
|
+ raise unittest.SkipTest(
|
|
'python{ver[0]}.{ver[1]} supports the {enc} encoding'.format(
|
|
ver=sys.version_info,
|
|
enc=encoding
|
|
)
|
|
)
|
|
- with assert_raises(LookupError):
|
|
+ with pytest.raises(LookupError):
|
|
dec()
|
|
E.install_extra_encodings()
|
|
enc()
|
|
@@ -181,7 +188,7 @@ class test_extra_encoding:
|
|
E.install_extra_encodings()
|
|
encoding = '8859-2'
|
|
portable_encoding = E.propose_portable_encoding(encoding)
|
|
- assert_equal('ISO-' + encoding, portable_encoding)
|
|
+ assert 'ISO-' + encoding == portable_encoding
|
|
|
|
@tools.fork_isolation
|
|
def test_not_allowed(self):
|
|
@@ -193,14 +200,14 @@ class test_extra_encoding:
|
|
except LookupError:
|
|
pass
|
|
else:
|
|
- raise nose.SkipTest(
|
|
+ raise unittest.SkipTest(
|
|
'python{ver[0]}.{ver[1]} supports the {enc} encoding'.format(
|
|
ver=sys.version_info,
|
|
enc=encoding
|
|
)
|
|
)
|
|
E.install_extra_encodings()
|
|
- with assert_raises(LookupError):
|
|
+ with pytest.raises(LookupError):
|
|
enc()
|
|
|
|
_viscii_unicode = 'Ti\u1EBFng Vi\u1EC7t'
|
|
@@ -211,13 +218,13 @@ class test_extra_encoding:
|
|
E.install_extra_encodings()
|
|
u = self._viscii_unicode
|
|
b = u.encode('VISCII')
|
|
- assert_equal(b, self._viscii_bytes)
|
|
+ assert b == self._viscii_bytes
|
|
|
|
@tools.fork_isolation
|
|
def test_8b_encode_error(self):
|
|
E.install_extra_encodings()
|
|
u = self._viscii_unicode
|
|
- with assert_raises(UnicodeEncodeError):
|
|
+ with pytest.raises(UnicodeEncodeError):
|
|
u.encode('KOI8-RU')
|
|
|
|
@tools.fork_isolation
|
|
@@ -225,13 +232,13 @@ class test_extra_encoding:
|
|
E.install_extra_encodings()
|
|
b = self._viscii_bytes
|
|
u = b.decode('VISCII')
|
|
- assert_equal(u, self._viscii_unicode)
|
|
+ assert u == self._viscii_unicode
|
|
|
|
@tools.fork_isolation
|
|
def test_8b_decode_error(self):
|
|
E.install_extra_encodings()
|
|
b = self._viscii_bytes
|
|
- with assert_raises(UnicodeDecodeError):
|
|
+ with pytest.raises(UnicodeDecodeError):
|
|
b.decode('KOI8-T')
|
|
|
|
_euc_tw_unicode = '\u4E2D\u6587'
|
|
@@ -242,13 +249,13 @@ class test_extra_encoding:
|
|
E.install_extra_encodings()
|
|
u = self._euc_tw_unicode
|
|
b = u.encode('EUC-TW')
|
|
- assert_equal(b, self._euc_tw_bytes)
|
|
+ assert b == self._euc_tw_bytes
|
|
|
|
@tools.fork_isolation
|
|
def test_mb_encode_error(self):
|
|
E.install_extra_encodings()
|
|
u = self._viscii_unicode
|
|
- with assert_raises(UnicodeEncodeError):
|
|
+ with pytest.raises(UnicodeEncodeError):
|
|
u.encode('EUC-TW')
|
|
|
|
@tools.fork_isolation
|
|
@@ -256,13 +263,13 @@ class test_extra_encoding:
|
|
E.install_extra_encodings()
|
|
b = self._euc_tw_bytes
|
|
u = b.decode('EUC-TW')
|
|
- assert_equal(u, self._euc_tw_unicode)
|
|
+ assert u == self._euc_tw_unicode
|
|
|
|
@tools.fork_isolation
|
|
def test_mb_decode_error(self):
|
|
E.install_extra_encodings()
|
|
b = self._viscii_bytes
|
|
- with assert_raises(UnicodeDecodeError):
|
|
+ with pytest.raises(UnicodeDecodeError):
|
|
b.decode('EUC-TW')
|
|
|
|
# vim:ts=4 sts=4 sw=4 et
|
|
Index: i18nspector-0.26/tests/test_gettext.py
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/tests/test_gettext.py
|
|
+++ i18nspector-0.26/tests/test_gettext.py
|
|
@@ -20,16 +20,7 @@
|
|
|
|
import datetime
|
|
|
|
-from nose.tools import (
|
|
- assert_equal,
|
|
- assert_false,
|
|
- assert_is_instance,
|
|
- assert_is_none,
|
|
- assert_is_not_none,
|
|
- assert_less,
|
|
- assert_raises,
|
|
- assert_true,
|
|
-)
|
|
+import pytest
|
|
|
|
import lib.gettext as M
|
|
|
|
@@ -38,21 +29,21 @@ class test_header_fields:
|
|
def test_nonempty(self):
|
|
# XXX Update this number after editing data/header-fields:
|
|
expected = 12
|
|
- assert_equal(len(M.header_fields), expected)
|
|
+ assert len(M.header_fields) == expected
|
|
|
|
def test_no_x(self):
|
|
for field in M.header_fields:
|
|
- assert_false(field.startswith('X-'))
|
|
+ assert not field.startswith('X-')
|
|
|
|
def test_valid(self):
|
|
for field in M.header_fields:
|
|
- assert_true(M.is_valid_field_name(field))
|
|
+ assert M.is_valid_field_name(field)
|
|
|
|
class test_header_parser:
|
|
|
|
def t(self, message, expected):
|
|
parsed = list(M.parse_header(message))
|
|
- assert_equal(parsed, expected)
|
|
+ assert parsed == expected
|
|
|
|
def test_ok(self):
|
|
self.t(
|
|
@@ -91,8 +82,8 @@ class test_plural_exp:
|
|
def t(self, s, n=None, fn=None):
|
|
f = M.parse_plural_expression(s)
|
|
if n is not None:
|
|
- assert_is_not_none(fn)
|
|
- assert_equal(f(n), fn)
|
|
+ assert fn is not None
|
|
+ assert f(n) == fn
|
|
|
|
def test_const(self):
|
|
n = 42
|
|
@@ -101,7 +92,7 @@ class test_plural_exp:
|
|
def test_const_overflow(self):
|
|
m = (1 << 32) - 1
|
|
self.t(str(m), m, m)
|
|
- with assert_raises(OverflowError):
|
|
+ with pytest.raises(OverflowError):
|
|
self.t(str(m + 1), m + 1, False)
|
|
self.t(str(m + 1), m + 42, False)
|
|
|
|
@@ -112,7 +103,7 @@ class test_plural_exp:
|
|
def test_var_overflow(self):
|
|
m = (1 << 32) - 1
|
|
self.t('n', m, m)
|
|
- with assert_raises(OverflowError):
|
|
+ with pytest.raises(OverflowError):
|
|
self.t('n', m + 1, False)
|
|
self.t('42', m + 1, 42)
|
|
|
|
@@ -122,7 +113,7 @@ class test_plural_exp:
|
|
def test_add_overflow(self):
|
|
m = (1 << 32) - 1
|
|
self.t('n + 42', m - 42, m)
|
|
- with assert_raises(OverflowError):
|
|
+ with pytest.raises(OverflowError):
|
|
self.t('n + 42', m - 41, False)
|
|
self.t('n + 42', m - 23, False)
|
|
|
|
@@ -130,7 +121,7 @@ class test_plural_exp:
|
|
self.t('n - 23', 37, 14)
|
|
|
|
def test_sub_overflow(self):
|
|
- with assert_raises(OverflowError):
|
|
+ with pytest.raises(OverflowError):
|
|
self.t('n - 23', 6, False)
|
|
|
|
def test_mul(self):
|
|
@@ -140,7 +131,7 @@ class test_plural_exp:
|
|
m = (1 << 32) - 1
|
|
assert m % 17 == 0
|
|
self.t('n * 17', m / 17, m)
|
|
- with assert_raises(OverflowError):
|
|
+ with pytest.raises(OverflowError):
|
|
self.t('n * 17', (m / 17) + 1, False)
|
|
self.t('n * 2', (m + 1) / 2, False)
|
|
|
|
@@ -148,14 +139,14 @@ class test_plural_exp:
|
|
self.t('105 / n', 17, 6)
|
|
|
|
def test_div_by_0(self):
|
|
- with assert_raises(ZeroDivisionError):
|
|
+ with pytest.raises(ZeroDivisionError):
|
|
self.t('105 / n', 0, False)
|
|
|
|
def test_mod(self):
|
|
self.t('105 % n', 17, 3)
|
|
|
|
def test_mod_by_0(self):
|
|
- with assert_raises(ZeroDivisionError):
|
|
+ with pytest.raises(ZeroDivisionError):
|
|
self.t('105 % n', 0, False)
|
|
|
|
def test_and(self):
|
|
@@ -228,75 +219,75 @@ class test_plural_exp:
|
|
self.t('(2 ? 3 : 7) ? 23 : 37')
|
|
|
|
def test_badly_nested_conditional(self):
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t('2 ? (3 : 7 ? ) : 23')
|
|
|
|
def test_unary_minus(self):
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t('-37')
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t('23 + (-37)')
|
|
|
|
def test_unary_plus(self):
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t('+42')
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t('23 + (+37)')
|
|
|
|
def test_func_call(self):
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t('n(42)')
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t('42(n)')
|
|
|
|
def test_unbalanced_parentheses(self):
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t('(6 * 7')
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t('6 * 7)')
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t('6) * (7')
|
|
|
|
def test_dangling_binop(self):
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t('6 +')
|
|
|
|
def test_junk_token(self):
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t('6 # 7')
|
|
|
|
def test_shift(self):
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t('6 << 7')
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t('6 >> 7')
|
|
|
|
def test_pow(self):
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t('6 ** 7')
|
|
|
|
def test_floor_div(self):
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t('6 // 7')
|
|
|
|
def test_tuple(self):
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t('()')
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t('(6, 7)')
|
|
|
|
def test_starred(self):
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t('*42')
|
|
|
|
def test_exotic_whitespace(self):
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t('6 *\xA07')
|
|
|
|
def test_empty(self):
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t('')
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t(' ')
|
|
|
|
class test_codomain:
|
|
@@ -308,9 +299,9 @@ class test_codomain:
|
|
cd = f.codomain()
|
|
if min_ is None:
|
|
assert max_ is None
|
|
- assert_is_none(cd)
|
|
+ assert cd is None
|
|
else:
|
|
- assert_equal(cd, (min_, max_))
|
|
+ assert cd == (min_, max_)
|
|
|
|
def test_num(self):
|
|
self.t('0', 0, 0)
|
|
@@ -530,9 +521,9 @@ class test_period:
|
|
op = f.period()
|
|
if offset is None:
|
|
assert period is None
|
|
- assert_is_none(op)
|
|
+ assert op is None
|
|
else:
|
|
- assert_equal(op, (offset, period))
|
|
+ assert op == (offset, period)
|
|
|
|
def test_num(self):
|
|
self.t('42', 0, 1)
|
|
@@ -619,20 +610,20 @@ class test_plural_forms:
|
|
|
|
def t(self, s, *, n, ljunk='', rjunk=''):
|
|
if ljunk or rjunk:
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
M.parse_plural_forms(s)
|
|
else:
|
|
(n0, expr0) = M.parse_plural_forms(s)
|
|
del expr0
|
|
- assert_equal(n0, n)
|
|
+ assert n0 == n
|
|
(n1, expr1, ljunk1, rjunk1) = M.parse_plural_forms(s, strict=False) # pylint: disable=unbalanced-tuple-unpacking
|
|
del expr1
|
|
- assert_equal(n1, n)
|
|
- assert_equal(ljunk1, ljunk)
|
|
- assert_equal(rjunk1, rjunk)
|
|
+ assert n1 == n
|
|
+ assert ljunk1 == ljunk
|
|
+ assert rjunk1 == rjunk
|
|
|
|
def test_nplurals_0(self):
|
|
- with assert_raises(self.error):
|
|
+ with pytest.raises(self.error):
|
|
self.t('nplurals=0; plural=0;', n=0)
|
|
|
|
def test_nplurals_positive(self):
|
|
@@ -651,15 +642,15 @@ class test_fix_date_format:
|
|
|
|
def t(self, old, expected):
|
|
if expected is None:
|
|
- with assert_raises(M.DateSyntaxError):
|
|
+ with pytest.raises(M.DateSyntaxError):
|
|
M.fix_date_format(old)
|
|
else:
|
|
new = M.fix_date_format(old)
|
|
- assert_is_not_none(new)
|
|
- assert_equal(new, expected)
|
|
+ assert new is not None
|
|
+ assert new == expected
|
|
|
|
def tbp(self, old):
|
|
- with assert_raises(M.BoilerplateDate):
|
|
+ with pytest.raises(M.BoilerplateDate):
|
|
M.fix_date_format(old)
|
|
|
|
def test_boilerplate(self):
|
|
@@ -710,10 +701,9 @@ class test_fix_date_format:
|
|
self.t('2002-01-01 03:05', None)
|
|
|
|
def test_tz_hint(self):
|
|
- assert_equal(
|
|
- M.fix_date_format('2002-01-01 03:05', tz_hint='+0900'),
|
|
- '2002-01-01 03:05+0900',
|
|
- )
|
|
+ assert (
|
|
+ M.fix_date_format('2002-01-01 03:05', tz_hint='+0900') ==
|
|
+ '2002-01-01 03:05+0900')
|
|
|
|
def test_gmt_before_tz(self):
|
|
self.t(
|
|
@@ -762,30 +752,30 @@ class test_parse_date:
|
|
t = staticmethod(M.parse_date)
|
|
|
|
def test_nonexistent(self):
|
|
- with assert_raises(M.DateSyntaxError):
|
|
+ with pytest.raises(M.DateSyntaxError):
|
|
self.t('2010-02-29 19:49+0200')
|
|
|
|
def test_existent(self):
|
|
d = self.t('2003-09-08 21:26+0200')
|
|
- assert_equal(d.second, 0)
|
|
- assert_is_instance(d, datetime.datetime)
|
|
- assert_equal(str(d), '2003-09-08 21:26:00+02:00')
|
|
+ assert d.second == 0
|
|
+ assert isinstance(d, datetime.datetime)
|
|
+ assert str(d) == '2003-09-08 21:26:00+02:00'
|
|
|
|
def test_epoch(self):
|
|
d = self.t('2008-04-03 16:06+0300')
|
|
- assert_less(M.epoch, d)
|
|
+ assert M.epoch < d
|
|
|
|
class test_string_formats:
|
|
|
|
def test_nonempty(self):
|
|
# XXX Update this number after editing data/string-formats:
|
|
expected = 28
|
|
- assert_equal(len(M.string_formats), expected)
|
|
+ assert len(M.string_formats) == expected
|
|
|
|
def test_lowercase(self):
|
|
for s in M.string_formats:
|
|
- assert_is_instance(s, str)
|
|
- assert_true(s)
|
|
- assert_equal(s, s.lower())
|
|
+ assert isinstance(s, str)
|
|
+ assert s
|
|
+ assert s == s.lower()
|
|
|
|
# vim:ts=4 sts=4 sw=4 et
|
|
Index: i18nspector-0.26/tests/test_iconv.py
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/tests/test_iconv.py
|
|
+++ i18nspector-0.26/tests/test_iconv.py
|
|
@@ -18,10 +18,7 @@
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
# SOFTWARE.
|
|
|
|
-from nose.tools import (
|
|
- assert_equal,
|
|
- assert_raises,
|
|
-)
|
|
+import pytest
|
|
|
|
import lib.iconv as M
|
|
|
|
@@ -32,11 +29,11 @@ class _test:
|
|
|
|
def test_encode(self):
|
|
b = M.encode(self.u, self.e)
|
|
- assert_equal(b, self.b)
|
|
+ assert b == self.b
|
|
|
|
def test_decode(self):
|
|
u = M.decode(self.b, self.e)
|
|
- assert_equal(u, self.u)
|
|
+ assert u == self.u
|
|
|
|
class test_iso2(_test):
|
|
u = 'Żrą łódź? Część miń!'
|
|
@@ -50,7 +47,7 @@ class test_tcvn(_test):
|
|
|
|
def test_incomplete_char():
|
|
b = 'Ę'.encode('UTF-8')[:1]
|
|
- with assert_raises(UnicodeDecodeError):
|
|
+ with pytest.raises(UnicodeDecodeError):
|
|
M.decode(b, 'UTF-8')
|
|
|
|
# vim:ts=4 sts=4 sw=4 et
|
|
Index: i18nspector-0.26/tests/test_ling.py
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/tests/test_ling.py
|
|
+++ i18nspector-0.26/tests/test_ling.py
|
|
@@ -18,19 +18,9 @@
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
# SOFTWARE.
|
|
|
|
-import nose
|
|
-from nose.tools import (
|
|
- assert_equal,
|
|
- assert_false,
|
|
- assert_in,
|
|
- assert_is,
|
|
- assert_is_instance,
|
|
- assert_is_none,
|
|
- assert_not_equal,
|
|
- assert_not_in,
|
|
- assert_raises,
|
|
- assert_true,
|
|
-)
|
|
+import unittest
|
|
+
|
|
+import pytest
|
|
|
|
import lib.encodings
|
|
import lib.ling
|
|
@@ -45,12 +35,12 @@ class test_fix_codes:
|
|
|
|
def t(self, l1, l2):
|
|
lang = L.parse_language(l1)
|
|
- assert_equal(str(lang), l1)
|
|
+ assert str(lang) == l1
|
|
if l1 == l2:
|
|
- assert_is_none(lang.fix_codes())
|
|
+ assert lang.fix_codes() is None
|
|
else:
|
|
- assert_is(lang.fix_codes(), True)
|
|
- assert_equal(str(lang), l2)
|
|
+ assert lang.fix_codes() is True
|
|
+ assert str(lang) == l2
|
|
|
|
def test_2_to_2(self):
|
|
self.t('grc', 'grc')
|
|
@@ -69,18 +59,18 @@ class test_fix_codes:
|
|
self.t('gre_GR', 'el_GR')
|
|
|
|
def test_ll_not_found(self):
|
|
- with assert_raises(L.FixingLanguageCodesFailed):
|
|
+ with pytest.raises(L.FixingLanguageCodesFailed):
|
|
self.t('ry', '')
|
|
|
|
def test_cc_not_found(self):
|
|
- with assert_raises(L.FixingLanguageCodesFailed):
|
|
+ with pytest.raises(L.FixingLanguageCodesFailed):
|
|
self.t('el_RY', '')
|
|
|
|
def test_language_repr():
|
|
# Language.__repr__() is never used by i18nspector itself,
|
|
# but it's useful for debugging test failures.
|
|
lng = T('el')
|
|
- assert_equal(repr(lng), '<Language el>')
|
|
+ assert repr(lng) == '<Language el>'
|
|
|
|
class test_language_equality:
|
|
|
|
@@ -89,47 +79,47 @@ class test_language_equality:
|
|
def test_eq(self):
|
|
l1 = T('el', 'GR')
|
|
l2 = T('el', 'GR')
|
|
- assert_equal(l1, l2)
|
|
- assert_equal(l2, l1)
|
|
+ assert l1 == l2
|
|
+ assert l2 == l1
|
|
|
|
def test_ne(self):
|
|
l1 = T('el')
|
|
l2 = T('el', 'GR')
|
|
- assert_not_equal(l1, l2)
|
|
- assert_not_equal(l2, l1)
|
|
+ assert l1 != l2
|
|
+ assert l2 != l1
|
|
|
|
def test_ne_other_type(self):
|
|
l1 = T('el')
|
|
- assert_not_equal(l1, 42)
|
|
- assert_not_equal(42, l1)
|
|
+ assert l1 != 42
|
|
+ assert 42 != l1 # pylint: disable=misplaced-comparison-constant
|
|
|
|
def test_almost_equal(self):
|
|
l1 = T('el')
|
|
l2 = T('el', 'GR')
|
|
- assert_true(l1.is_almost_equal(l2))
|
|
- assert_true(l2.is_almost_equal(l1))
|
|
+ assert l1.is_almost_equal(l2)
|
|
+ assert l2.is_almost_equal(l1)
|
|
|
|
def test_not_almost_equal(self):
|
|
l1 = T('el', 'GR')
|
|
l2 = T('grc', 'GR')
|
|
- assert_false(l1.is_almost_equal(l2))
|
|
- assert_false(l2.is_almost_equal(l1))
|
|
+ assert not l1.is_almost_equal(l2)
|
|
+ assert not l2.is_almost_equal(l1)
|
|
|
|
def test_not_almost_equal_other_type(self):
|
|
l1 = T('el')
|
|
- with assert_raises(TypeError):
|
|
+ with pytest.raises(TypeError):
|
|
l1.is_almost_equal(42)
|
|
|
|
class test_remove_encoding:
|
|
|
|
def t(self, l1, l2):
|
|
lang = L.parse_language(l1)
|
|
- assert_equal(str(lang), l1)
|
|
+ assert str(lang) == l1
|
|
if l1 == l2:
|
|
- assert_is_none(lang.remove_encoding())
|
|
+ assert lang.remove_encoding() is None
|
|
else:
|
|
- assert_is(lang.remove_encoding(), True)
|
|
- assert_equal(str(lang), l2)
|
|
+ assert lang.remove_encoding() is True
|
|
+ assert str(lang) == l2
|
|
|
|
def test_without_encoding(self):
|
|
self.t('el', 'el')
|
|
@@ -141,12 +131,12 @@ class test_remove_nonlinguistic_modifier
|
|
|
|
def t(self, l1, l2):
|
|
lang = L.parse_language(l1)
|
|
- assert_equal(str(lang), l1)
|
|
+ assert str(lang) == l1
|
|
if l1 == l2:
|
|
- assert_is_none(lang.remove_nonlinguistic_modifier())
|
|
+ assert lang.remove_nonlinguistic_modifier() is None
|
|
else:
|
|
- assert_is(lang.remove_nonlinguistic_modifier(), True)
|
|
- assert_equal(str(lang), l2)
|
|
+ assert lang.remove_nonlinguistic_modifier() is True
|
|
+ assert str(lang) == l2
|
|
|
|
def test_quot(self):
|
|
self.t('en@quot', 'en@quot')
|
|
@@ -162,18 +152,18 @@ class test_lookup_territory_code:
|
|
|
|
def test_found(self):
|
|
cc = L.lookup_territory_code('GR')
|
|
- assert_equal(cc, 'GR')
|
|
+ assert cc == 'GR'
|
|
|
|
def test_not_found(self):
|
|
cc = L.lookup_territory_code('RG')
|
|
- assert_is_none(cc)
|
|
+ assert cc is None
|
|
|
|
class test_get_language_for_name:
|
|
|
|
def t(self, name, expected):
|
|
lang = L.get_language_for_name(name)
|
|
- assert_is_instance(lang, T)
|
|
- assert_equal(str(lang), expected)
|
|
+ assert isinstance(lang, T)
|
|
+ assert str(lang) == expected
|
|
|
|
def test_found(self):
|
|
self.t('Greek', 'el')
|
|
@@ -194,69 +184,75 @@ class test_get_language_for_name:
|
|
self.t('Pashto, Pushto', 'ps')
|
|
|
|
def test_lone_comma(self):
|
|
- with assert_raises(LookupError):
|
|
+ with pytest.raises(LookupError):
|
|
self.t(',', None)
|
|
|
|
def test_not_found(self):
|
|
- with assert_raises(LookupError):
|
|
+ with pytest.raises(LookupError):
|
|
self.t('Nadsat', None)
|
|
|
|
class test_parse_language:
|
|
|
|
def test_ll(self):
|
|
lang = L.parse_language('el')
|
|
- assert_equal(lang.language_code, 'el')
|
|
- assert_is_none(lang.territory_code)
|
|
- assert_is_none(lang.encoding)
|
|
- assert_is_none(lang.modifier)
|
|
+ assert lang.language_code == 'el'
|
|
+ assert lang.territory_code is None
|
|
+ assert lang.encoding is None
|
|
+ assert lang.modifier is None
|
|
|
|
def test_lll(self):
|
|
lang = L.parse_language('ell')
|
|
- assert_equal(lang.language_code, 'ell')
|
|
- assert_is_none(lang.territory_code)
|
|
- assert_is_none(lang.encoding)
|
|
- assert_is_none(lang.modifier)
|
|
+ assert lang.language_code == 'ell'
|
|
+ assert lang.territory_code is None
|
|
+ assert lang.encoding is None
|
|
+ assert lang.modifier is None
|
|
|
|
def test_ll_cc(self):
|
|
lang = L.parse_language('el_GR')
|
|
- assert_equal(lang.language_code, 'el')
|
|
- assert_equal(lang.territory_code, 'GR')
|
|
- assert_is_none(lang.encoding)
|
|
- assert_is_none(lang.modifier)
|
|
+ assert lang.language_code == 'el'
|
|
+ assert lang.territory_code == 'GR'
|
|
+ assert lang.encoding is None
|
|
+ assert lang.modifier is None
|
|
|
|
def test_ll_cc_enc(self):
|
|
lang = L.parse_language('el_GR.UTF-8')
|
|
- assert_equal(lang.language_code, 'el')
|
|
- assert_equal(lang.territory_code, 'GR')
|
|
- assert_equal(lang.encoding, 'UTF-8')
|
|
- assert_is_none(lang.modifier)
|
|
+ assert lang.language_code == 'el'
|
|
+ assert lang.territory_code == 'GR'
|
|
+ assert lang.encoding == 'UTF-8'
|
|
+ assert lang.modifier is None
|
|
|
|
def test_ll_cc_modifier(self):
|
|
lang = L.parse_language('en_US@quot')
|
|
- assert_equal(lang.language_code, 'en')
|
|
- assert_equal(lang.territory_code, 'US')
|
|
- assert_is_none(lang.encoding)
|
|
- assert_equal(lang.modifier, 'quot')
|
|
+ assert lang.language_code == 'en'
|
|
+ assert lang.territory_code == 'US'
|
|
+ assert lang.encoding is None
|
|
+ assert lang.modifier == 'quot'
|
|
|
|
def test_syntax_error(self):
|
|
- with assert_raises(L.LanguageSyntaxError):
|
|
+ with pytest.raises(L.LanguageSyntaxError):
|
|
L.parse_language('GR')
|
|
|
|
class test_get_primary_languages:
|
|
|
|
def test_found(self):
|
|
langs = L.get_primary_languages()
|
|
- assert_in('el', langs)
|
|
+ assert 'el' in langs
|
|
|
|
def test_not_found(self):
|
|
langs = L.get_primary_languages()
|
|
- assert_not_in('ry', langs)
|
|
+ assert 'ry' not in langs
|
|
|
|
- def test_iso_639(self):
|
|
+ # methods using the tools.collect_yielded decorator don't have a 'self'
|
|
+ # since they end up being run before 'self' exists. pylint doesn't
|
|
+ # understand this unusual situation
|
|
+
|
|
+ @tools.collect_yielded
|
|
+ def test_iso_639():
|
|
+ # pylint: disable=no-method-argument
|
|
def t(lang_str):
|
|
lang = L.parse_language(lang_str)
|
|
- assert_is_none(lang.fix_codes())
|
|
- assert_equal(str(lang), lang_str)
|
|
+ assert lang.fix_codes() is None
|
|
+ assert str(lang) == lang_str
|
|
for lang_str in L.get_primary_languages():
|
|
yield t, lang_str
|
|
|
|
@@ -267,34 +263,30 @@ class test_get_plural_forms:
|
|
return lang.get_plural_forms()
|
|
|
|
def test_found_ll(self):
|
|
- assert_equal(
|
|
- self.t('el'),
|
|
- ['nplurals=2; plural=n != 1;']
|
|
- )
|
|
+ assert (
|
|
+ self.t('el') ==
|
|
+ ['nplurals=2; plural=n != 1;'])
|
|
|
|
def test_found_ll_cc(self):
|
|
- assert_equal(
|
|
- self.t('el_GR'),
|
|
- ['nplurals=2; plural=n != 1;']
|
|
- )
|
|
+ assert (
|
|
+ self.t('el_GR') ==
|
|
+ ['nplurals=2; plural=n != 1;'])
|
|
|
|
def test_en_ca(self):
|
|
- assert_equal(
|
|
- self.t('en'),
|
|
- self.t('en_CA'),
|
|
- )
|
|
+ assert (
|
|
+ self.t('en') ==
|
|
+ self.t('en_CA'))
|
|
|
|
def test_pt_br(self):
|
|
- assert_not_equal(
|
|
- self.t('pt'),
|
|
- self.t('pt_BR'),
|
|
- )
|
|
+ assert (
|
|
+ self.t('pt') !=
|
|
+ self.t('pt_BR'))
|
|
|
|
def test_not_known(self):
|
|
- assert_is_none(self.t('la'))
|
|
+ assert self.t('la') is None
|
|
|
|
def test_not_found(self):
|
|
- assert_is_none(self.t('ry'))
|
|
+ assert self.t('ry') is None
|
|
|
|
class test_principal_territory:
|
|
|
|
@@ -302,115 +294,116 @@ class test_principal_territory:
|
|
# el -> el_GR
|
|
lang = L.parse_language('el')
|
|
cc = lang.get_principal_territory_code()
|
|
- assert_equal(cc, 'GR')
|
|
+ assert cc == 'GR'
|
|
|
|
def test_remove_2(self):
|
|
# el_GR -> el
|
|
lang = L.parse_language('el_GR')
|
|
- assert_equal(str(lang), 'el_GR')
|
|
+ assert str(lang) == 'el_GR'
|
|
rc = lang.remove_principal_territory_code()
|
|
- assert_is(rc, True)
|
|
- assert_equal(str(lang), 'el')
|
|
+ assert rc is True
|
|
+ assert str(lang) == 'el'
|
|
|
|
def test_found_3(self):
|
|
# ang -> ang_GB
|
|
lang = L.parse_language('ang')
|
|
cc = lang.get_principal_territory_code()
|
|
- assert_equal(cc, 'GB')
|
|
+ assert cc == 'GB'
|
|
|
|
def test_remove_3(self):
|
|
# ang_GB -> ang
|
|
lang = L.parse_language('ang_GB')
|
|
- assert_equal(str(lang), 'ang_GB')
|
|
+ assert str(lang) == 'ang_GB'
|
|
rc = lang.remove_principal_territory_code()
|
|
- assert_is(rc, True)
|
|
- assert_equal(str(lang), 'ang')
|
|
+ assert rc is True
|
|
+ assert str(lang) == 'ang'
|
|
|
|
def test_no_principal_territory_code(self):
|
|
# en -/-> en_US
|
|
lang = L.parse_language('en')
|
|
cc = lang.get_principal_territory_code()
|
|
- assert_is_none(cc)
|
|
+ assert cc is None
|
|
|
|
def test_no_remove_principal_territory_code(self):
|
|
# en_US -/-> en
|
|
lang = L.parse_language('en_US')
|
|
- assert_equal(str(lang), 'en_US')
|
|
+ assert str(lang) == 'en_US'
|
|
rc = lang.remove_principal_territory_code()
|
|
- assert_is_none(rc)
|
|
- assert_equal(str(lang), 'en_US')
|
|
+ assert rc is None
|
|
+ assert str(lang) == 'en_US'
|
|
|
|
def test_not_found(self):
|
|
lang = L.parse_language('ry')
|
|
cc = lang.get_principal_territory_code()
|
|
- assert_equal(cc, None)
|
|
+ assert cc is None
|
|
|
|
class test_unrepresentable_characters:
|
|
|
|
def test_ll_bad(self):
|
|
lang = L.parse_language('pl')
|
|
result = lang.get_unrepresentable_characters('ISO-8859-1')
|
|
- assert_not_equal(result, [])
|
|
+ assert result != []
|
|
|
|
def test_ll_ok(self):
|
|
lang = L.parse_language('pl')
|
|
result = lang.get_unrepresentable_characters('ISO-8859-2')
|
|
- assert_equal(result, [])
|
|
+ assert result == []
|
|
|
|
def test_ll_cc_bad(self):
|
|
lang = L.parse_language('pl_PL')
|
|
result = lang.get_unrepresentable_characters('ISO-8859-1')
|
|
- assert_not_equal(result, [])
|
|
+ assert result != []
|
|
|
|
def test_ll_cc_ok(self):
|
|
lang = L.parse_language('pl_PL')
|
|
result = lang.get_unrepresentable_characters('ISO-8859-2')
|
|
- assert_equal(result, [])
|
|
+ assert result == []
|
|
|
|
def test_ll_mod_bad(self):
|
|
lang = L.parse_language('en@quot')
|
|
result = lang.get_unrepresentable_characters('ISO-8859-1')
|
|
- assert_not_equal(result, [])
|
|
+ assert result != []
|
|
|
|
def test_ll_mod_ok(self):
|
|
lang = L.parse_language('en@quot')
|
|
result = lang.get_unrepresentable_characters('UTF-8')
|
|
- assert_equal(result, [])
|
|
+ assert result == []
|
|
|
|
def test_ll_cc_mod_bad(self):
|
|
lang = L.parse_language('en_US@quot')
|
|
result = lang.get_unrepresentable_characters('ISO-8859-1')
|
|
- assert_not_equal(result, [])
|
|
+ assert result != []
|
|
|
|
def test_ll_cc_mod_ok(self):
|
|
lang = L.parse_language('en_US@quot')
|
|
result = lang.get_unrepresentable_characters('UTF-8')
|
|
- assert_equal(result, [])
|
|
+ assert result == []
|
|
|
|
def test_ll_optional(self):
|
|
# U+0178 (LATIN CAPITAL LETTER Y WITH DIAERESIS) is not representable
|
|
# in ISO-8859-1, but we normally turn a blind eye to this.
|
|
lang = L.parse_language('fr')
|
|
result = lang.get_unrepresentable_characters('ISO-8859-1')
|
|
- assert_equal(result, [])
|
|
+ assert result == []
|
|
result = lang.get_unrepresentable_characters('ISO-8859-1', strict=True)
|
|
- assert_not_equal(result, [])
|
|
+ assert result != []
|
|
|
|
def test_ll_not_found(self):
|
|
lang = L.parse_language('ry')
|
|
result = lang.get_unrepresentable_characters('ISO-8859-1')
|
|
- assert_is_none(result)
|
|
+ assert result is None
|
|
|
|
@tools.fork_isolation
|
|
def test_extra_encoding(self):
|
|
encoding = 'GEORGIAN-PS'
|
|
lang = L.parse_language('pl')
|
|
- with assert_raises(LookupError):
|
|
+ with pytest.raises(LookupError):
|
|
''.encode(encoding)
|
|
E.install_extra_encodings()
|
|
result = lang.get_unrepresentable_characters(encoding)
|
|
- assert_not_equal(result, [])
|
|
+ assert result != []
|
|
|
|
+@tools.collect_yielded
|
|
def test_glibc_supported():
|
|
def t(l):
|
|
lang = L.parse_language(l)
|
|
@@ -419,16 +412,16 @@ def test_glibc_supported():
|
|
except L.FixingLanguageCodesFailed:
|
|
# FIXME: some ISO-639-3 codes are not recognized yet
|
|
if len(l.split('_')[0]) == 3:
|
|
- raise nose.SkipTest('expected failure')
|
|
+ raise unittest.SkipTest('expected failure')
|
|
reason = locales_to_skip.get(l)
|
|
if reason is not None:
|
|
- raise nose.SkipTest(reason)
|
|
+ raise unittest.SkipTest(reason)
|
|
raise
|
|
assert_equal(str(lang), l)
|
|
try:
|
|
file = open('/usr/share/i18n/SUPPORTED', encoding='ASCII')
|
|
except OSError as exc:
|
|
- raise nose.SkipTest(exc)
|
|
+ raise unittest.SkipTest(exc)
|
|
locales = set()
|
|
with file:
|
|
for line in file:
|
|
@@ -452,6 +445,7 @@ def test_glibc_supported():
|
|
for l in sorted(locales):
|
|
yield t, l
|
|
|
|
+@tools.collect_yielded
|
|
def test_poedit():
|
|
# https://github.com/vslavik/poedit/blob/v1.8.1-oss/src/language_impl_legacy.h
|
|
# There won't be any new names in this table,
|
|
@@ -459,178 +453,178 @@ def test_poedit():
|
|
def t(name, poedit_ll):
|
|
poedit_ll = L.parse_language(poedit_ll)
|
|
ll = L.get_language_for_name(name)
|
|
- assert_equal(ll, poedit_ll)
|
|
+ assert ll == poedit_ll
|
|
def x(name, poedit_ll):
|
|
poedit_ll = L.parse_language(poedit_ll)
|
|
- with assert_raises(LookupError):
|
|
+ with pytest.raises(LookupError):
|
|
L.get_language_for_name(name)
|
|
- raise nose.SkipTest('expected failure')
|
|
- yield t, 'Abkhazian', 'ab'
|
|
- yield t, 'Afar', 'aa'
|
|
- yield t, 'Afrikaans', 'af'
|
|
- yield t, 'Albanian', 'sq'
|
|
- yield t, 'Amharic', 'am'
|
|
- yield t, 'Arabic', 'ar'
|
|
- yield t, 'Armenian', 'hy'
|
|
- yield t, 'Assamese', 'as'
|
|
- yield t, 'Avestan', 'ae'
|
|
- yield t, 'Aymara', 'ay'
|
|
- yield t, 'Azerbaijani', 'az'
|
|
- yield t, 'Bashkir', 'ba'
|
|
- yield t, 'Basque', 'eu'
|
|
- yield t, 'Belarusian', 'be'
|
|
- yield t, 'Bengali', 'bn'
|
|
- yield t, 'Bislama', 'bi'
|
|
- yield t, 'Bosnian', 'bs'
|
|
- yield t, 'Breton', 'br'
|
|
- yield t, 'Bulgarian', 'bg'
|
|
- yield t, 'Burmese', 'my'
|
|
- yield t, 'Catalan', 'ca'
|
|
- yield t, 'Chamorro', 'ch'
|
|
- yield t, 'Chechen', 'ce'
|
|
- yield t, 'Chichewa; Nyanja', 'ny'
|
|
- yield t, 'Chinese', 'zh'
|
|
- yield t, 'Church Slavic', 'cu'
|
|
- yield t, 'Chuvash', 'cv'
|
|
- yield t, 'Cornish', 'kw'
|
|
- yield t, 'Corsican', 'co'
|
|
- yield t, 'Croatian', 'hr'
|
|
- yield t, 'Czech', 'cs'
|
|
- yield t, 'Danish', 'da'
|
|
- yield t, 'Dutch', 'nl'
|
|
- yield t, 'Dzongkha', 'dz'
|
|
- yield t, 'English', 'en'
|
|
- yield t, 'Esperanto', 'eo'
|
|
- yield t, 'Estonian', 'et'
|
|
- yield t, 'Faroese', 'fo'
|
|
- yield t, 'Fijian', 'fj'
|
|
- yield t, 'Finnish', 'fi'
|
|
- yield t, 'French', 'fr'
|
|
- yield t, 'Frisian', 'fy'
|
|
- yield t, 'Friulian', 'fur'
|
|
- yield t, 'Gaelic', 'gd'
|
|
- yield t, 'Galician', 'gl'
|
|
- yield t, 'Georgian', 'ka'
|
|
- yield t, 'German', 'de'
|
|
- yield t, 'Greek', 'el'
|
|
- yield t, 'Guarani', 'gn'
|
|
- yield t, 'Gujarati', 'gu'
|
|
- yield t, 'Hausa', 'ha'
|
|
- yield t, 'Hebrew', 'he'
|
|
- yield t, 'Herero', 'hz'
|
|
- yield t, 'Hindi', 'hi'
|
|
- yield t, 'Hiri Motu', 'ho'
|
|
- yield t, 'Hungarian', 'hu'
|
|
- yield t, 'Icelandic', 'is'
|
|
- yield t, 'Indonesian', 'id'
|
|
- yield t, 'Interlingua', 'ia'
|
|
- yield t, 'Interlingue', 'ie'
|
|
- yield t, 'Inuktitut', 'iu'
|
|
- yield t, 'Inupiaq', 'ik'
|
|
- yield t, 'Irish', 'ga'
|
|
- yield t, 'Italian', 'it'
|
|
- yield t, 'Japanese', 'ja'
|
|
- yield t, 'Javanese', 'jv' # https://github.com/vslavik/poedit/pull/193
|
|
- yield t, 'Kalaallisut', 'kl'
|
|
- yield t, 'Kannada', 'kn'
|
|
- yield t, 'Kashmiri', 'ks'
|
|
- yield t, 'Kazakh', 'kk'
|
|
- yield t, 'Khmer', 'km'
|
|
- yield t, 'Kikuyu', 'ki'
|
|
- yield t, 'Kinyarwanda', 'rw'
|
|
- yield t, 'Komi', 'kv'
|
|
- yield t, 'Korean', 'ko'
|
|
- yield t, 'Kuanyama', 'kj'
|
|
- yield t, 'Kurdish', 'ku'
|
|
- yield t, 'Kyrgyz', 'ky'
|
|
- yield t, 'Lao', 'lo'
|
|
- yield t, 'Latin', 'la'
|
|
- yield t, 'Latvian', 'lv'
|
|
- yield t, 'Letzeburgesch', 'lb'
|
|
- yield t, 'Lingala', 'ln'
|
|
- yield t, 'Lithuanian', 'lt'
|
|
- yield t, 'Macedonian', 'mk'
|
|
- yield t, 'Malagasy', 'mg'
|
|
- yield t, 'Malay', 'ms'
|
|
- yield t, 'Malayalam', 'ml'
|
|
- yield t, 'Maltese', 'mt'
|
|
- yield t, 'Maori', 'mi'
|
|
- yield t, 'Marathi', 'mr'
|
|
- yield t, 'Marshall', 'mh'
|
|
- yield t, 'Moldavian', 'ro_MD' # XXX poedit uses deprecated "mo"
|
|
- yield t, 'Mongolian', 'mn'
|
|
- yield t, 'Nauru', 'na'
|
|
- yield t, 'Navajo', 'nv'
|
|
- yield t, 'Ndebele, South', 'nr'
|
|
- yield t, 'Ndonga', 'ng'
|
|
- yield t, 'Nepali', 'ne'
|
|
- yield t, 'Northern Sami', 'se'
|
|
- yield t, 'Norwegian Bokmal', 'nb'
|
|
- yield t, 'Norwegian Nynorsk', 'nn'
|
|
- yield t, 'Occitan', 'oc'
|
|
- yield t, 'Oriya', 'or'
|
|
- yield t, 'Ossetian; Ossetic', 'os'
|
|
- yield t, 'Pali', 'pi'
|
|
- yield t, 'Panjabi', 'pa'
|
|
- yield t, 'Pashto, Pushto', 'ps'
|
|
- yield t, 'Persian', 'fa'
|
|
- yield t, 'Polish', 'pl'
|
|
- yield t, 'Portuguese', 'pt'
|
|
- yield t, 'Quechua', 'qu'
|
|
- yield t, 'Rhaeto-Romance', 'rm'
|
|
- yield t, 'Romanian', 'ro'
|
|
- yield t, 'Rundi', 'rn'
|
|
- yield t, 'Russian', 'ru'
|
|
- yield t, 'Samoan', 'sm'
|
|
- yield t, 'Sangro', 'sg'
|
|
- yield t, 'Sanskrit', 'sa'
|
|
- yield t, 'Sardinian', 'sc'
|
|
- yield t, 'Serbian', 'sr'
|
|
- yield t, 'Sesotho', 'st'
|
|
- yield t, 'Setswana', 'tn'
|
|
- yield t, 'Shona', 'sn'
|
|
- yield t, 'Sindhi', 'sd'
|
|
- yield t, 'Sinhalese', 'si'
|
|
- yield t, 'Siswati', 'ss'
|
|
- yield t, 'Slovak', 'sk'
|
|
- yield t, 'Slovenian', 'sl'
|
|
- yield t, 'Somali', 'so'
|
|
- yield t, 'Spanish', 'es'
|
|
- yield t, 'Sundanese', 'su'
|
|
- yield t, 'Swahili', 'sw'
|
|
- yield t, 'Swedish', 'sv'
|
|
- yield t, 'Tagalog', 'tl'
|
|
- yield t, 'Tahitian', 'ty'
|
|
- yield t, 'Tajik', 'tg'
|
|
- yield t, 'Tamil', 'ta'
|
|
- yield t, 'Tatar', 'tt'
|
|
- yield t, 'Telugu', 'te'
|
|
- yield t, 'Thai', 'th'
|
|
- yield t, 'Tibetan', 'bo'
|
|
- yield t, 'Tigrinya', 'ti'
|
|
- yield t, 'Tonga', 'to'
|
|
- yield t, 'Tsonga', 'ts'
|
|
- yield t, 'Turkish', 'tr'
|
|
- yield t, 'Turkmen', 'tk'
|
|
- yield t, 'Twi', 'tw'
|
|
- yield t, 'Ukrainian', 'uk'
|
|
- yield t, 'Urdu', 'ur'
|
|
- yield t, 'Uyghur', 'ug'
|
|
- yield t, 'Uzbek', 'uz'
|
|
- yield t, 'Vietnamese', 'vi'
|
|
- yield t, 'Volapuk', 'vo'
|
|
- yield t, 'Walloon', 'wa'
|
|
- yield t, 'Welsh', 'cy'
|
|
- yield t, 'Wolof', 'wo'
|
|
- yield t, 'Xhosa', 'xh'
|
|
- yield t, 'Yiddish', 'yi'
|
|
- yield t, 'Yoruba', 'yo'
|
|
- yield t, 'Zhuang', 'za'
|
|
- yield t, 'Zulu', 'zu'
|
|
+ raise unittest.SkipTest('expected failure')
|
|
+ yield t, ('Abkhazian', 'ab')
|
|
+ yield t, ('Afar', 'aa')
|
|
+ yield t, ('Afrikaans', 'af')
|
|
+ yield t, ('Albanian', 'sq')
|
|
+ yield t, ('Amharic', 'am')
|
|
+ yield t, ('Arabic', 'ar')
|
|
+ yield t, ('Armenian', 'hy')
|
|
+ yield t, ('Assamese', 'as')
|
|
+ yield t, ('Avestan', 'ae')
|
|
+ yield t, ('Aymara', 'ay')
|
|
+ yield t, ('Azerbaijani', 'az')
|
|
+ yield t, ('Bashkir', 'ba')
|
|
+ yield t, ('Basque', 'eu')
|
|
+ yield t, ('Belarusian', 'be')
|
|
+ yield t, ('Bengali', 'bn')
|
|
+ yield t, ('Bislama', 'bi')
|
|
+ yield t, ('Bosnian', 'bs')
|
|
+ yield t, ('Breton', 'br')
|
|
+ yield t, ('Bulgarian', 'bg')
|
|
+ yield t, ('Burmese', 'my')
|
|
+ yield t, ('Catalan', 'ca')
|
|
+ yield t, ('Chamorro', 'ch')
|
|
+ yield t, ('Chechen', 'ce')
|
|
+ yield t, ('Chichewa; Nyanja', 'ny')
|
|
+ yield t, ('Chinese', 'zh')
|
|
+ yield t, ('Church Slavic', 'cu')
|
|
+ yield t, ('Chuvash', 'cv')
|
|
+ yield t, ('Cornish', 'kw')
|
|
+ yield t, ('Corsican', 'co')
|
|
+ yield t, ('Croatian', 'hr')
|
|
+ yield t, ('Czech', 'cs')
|
|
+ yield t, ('Danish', 'da')
|
|
+ yield t, ('Dutch', 'nl')
|
|
+ yield t, ('Dzongkha', 'dz')
|
|
+ yield t, ('English', 'en')
|
|
+ yield t, ('Esperanto', 'eo')
|
|
+ yield t, ('Estonian', 'et')
|
|
+ yield t, ('Faroese', 'fo')
|
|
+ yield t, ('Fijian', 'fj')
|
|
+ yield t, ('Finnish', 'fi')
|
|
+ yield t, ('French', 'fr')
|
|
+ yield t, ('Frisian', 'fy')
|
|
+ yield t, ('Friulian', 'fur')
|
|
+ yield t, ('Gaelic', 'gd')
|
|
+ yield t, ('Galician', 'gl')
|
|
+ yield t, ('Georgian', 'ka')
|
|
+ yield t, ('German', 'de')
|
|
+ yield t, ('Greek', 'el')
|
|
+ yield t, ('Guarani', 'gn')
|
|
+ yield t, ('Gujarati', 'gu')
|
|
+ yield t, ('Hausa', 'ha')
|
|
+ yield t, ('Hebrew', 'he')
|
|
+ yield t, ('Herero', 'hz')
|
|
+ yield t, ('Hindi', 'hi')
|
|
+ yield t, ('Hiri Motu', 'ho')
|
|
+ yield t, ('Hungarian', 'hu')
|
|
+ yield t, ('Icelandic', 'is')
|
|
+ yield t, ('Indonesian', 'id')
|
|
+ yield t, ('Interlingua', 'ia')
|
|
+ yield t, ('Interlingue', 'ie')
|
|
+ yield t, ('Inuktitut', 'iu')
|
|
+ yield t, ('Inupiaq', 'ik')
|
|
+ yield t, ('Irish', 'ga')
|
|
+ yield t, ('Italian', 'it')
|
|
+ yield t, ('Japanese', 'ja')
|
|
+ yield t, ('Javanese', 'jv') # https://github.com/vslavik/poedit/pull/193
|
|
+ yield t, ('Kalaallisut', 'kl')
|
|
+ yield t, ('Kannada', 'kn')
|
|
+ yield t, ('Kashmiri', 'ks')
|
|
+ yield t, ('Kazakh', 'kk')
|
|
+ yield t, ('Khmer', 'km')
|
|
+ yield t, ('Kikuyu', 'ki')
|
|
+ yield t, ('Kinyarwanda', 'rw')
|
|
+ yield t, ('Komi', 'kv')
|
|
+ yield t, ('Korean', 'ko')
|
|
+ yield t, ('Kuanyama', 'kj')
|
|
+ yield t, ('Kurdish', 'ku')
|
|
+ yield t, ('Kyrgyz', 'ky')
|
|
+ yield t, ('Lao', 'lo')
|
|
+ yield t, ('Latin', 'la')
|
|
+ yield t, ('Latvian', 'lv')
|
|
+ yield t, ('Letzeburgesch', 'lb')
|
|
+ yield t, ('Lingala', 'ln')
|
|
+ yield t, ('Lithuanian', 'lt')
|
|
+ yield t, ('Macedonian', 'mk')
|
|
+ yield t, ('Malagasy', 'mg')
|
|
+ yield t, ('Malay', 'ms')
|
|
+ yield t, ('Malayalam', 'ml')
|
|
+ yield t, ('Maltese', 'mt')
|
|
+ yield t, ('Maori', 'mi')
|
|
+ yield t, ('Marathi', 'mr')
|
|
+ yield t, ('Marshall', 'mh')
|
|
+ yield t, ('Moldavian', 'ro_MD') # XXX poedit uses deprecated "mo"
|
|
+ yield t, ('Mongolian', 'mn')
|
|
+ yield t, ('Nauru', 'na')
|
|
+ yield t, ('Navajo', 'nv')
|
|
+ yield t, ('Ndebele, South', 'nr')
|
|
+ yield t, ('Ndonga', 'ng')
|
|
+ yield t, ('Nepali', 'ne')
|
|
+ yield t, ('Northern Sami', 'se')
|
|
+ yield t, ('Norwegian Bokmal', 'nb')
|
|
+ yield t, ('Norwegian Nynorsk', 'nn')
|
|
+ yield t, ('Occitan', 'oc')
|
|
+ yield t, ('Oriya', 'or')
|
|
+ yield t, ('Ossetian; Ossetic', 'os')
|
|
+ yield t, ('Pali', 'pi')
|
|
+ yield t, ('Panjabi', 'pa')
|
|
+ yield t, ('Pashto, Pushto', 'ps')
|
|
+ yield t, ('Persian', 'fa')
|
|
+ yield t, ('Polish', 'pl')
|
|
+ yield t, ('Portuguese', 'pt')
|
|
+ yield t, ('Quechua', 'qu')
|
|
+ yield t, ('Rhaeto-Romance', 'rm')
|
|
+ yield t, ('Romanian', 'ro')
|
|
+ yield t, ('Rundi', 'rn')
|
|
+ yield t, ('Russian', 'ru')
|
|
+ yield t, ('Samoan', 'sm')
|
|
+ yield t, ('Sangro', 'sg')
|
|
+ yield t, ('Sanskrit', 'sa')
|
|
+ yield t, ('Sardinian', 'sc')
|
|
+ yield t, ('Serbian', 'sr')
|
|
+ yield t, ('Sesotho', 'st')
|
|
+ yield t, ('Setswana', 'tn')
|
|
+ yield t, ('Shona', 'sn')
|
|
+ yield t, ('Sindhi', 'sd')
|
|
+ yield t, ('Sinhalese', 'si')
|
|
+ yield t, ('Siswati', 'ss')
|
|
+ yield t, ('Slovak', 'sk')
|
|
+ yield t, ('Slovenian', 'sl')
|
|
+ yield t, ('Somali', 'so')
|
|
+ yield t, ('Spanish', 'es')
|
|
+ yield t, ('Sundanese', 'su')
|
|
+ yield t, ('Swahili', 'sw')
|
|
+ yield t, ('Swedish', 'sv')
|
|
+ yield t, ('Tagalog', 'tl')
|
|
+ yield t, ('Tahitian', 'ty')
|
|
+ yield t, ('Tajik', 'tg')
|
|
+ yield t, ('Tamil', 'ta')
|
|
+ yield t, ('Tatar', 'tt')
|
|
+ yield t, ('Telugu', 'te')
|
|
+ yield t, ('Thai', 'th')
|
|
+ yield t, ('Tibetan', 'bo')
|
|
+ yield t, ('Tigrinya', 'ti')
|
|
+ yield t, ('Tonga', 'to')
|
|
+ yield t, ('Tsonga', 'ts')
|
|
+ yield t, ('Turkish', 'tr')
|
|
+ yield t, ('Turkmen', 'tk')
|
|
+ yield t, ('Twi', 'tw')
|
|
+ yield t, ('Ukrainian', 'uk')
|
|
+ yield t, ('Urdu', 'ur')
|
|
+ yield t, ('Uyghur', 'ug')
|
|
+ yield t, ('Uzbek', 'uz')
|
|
+ yield t, ('Vietnamese', 'vi')
|
|
+ yield t, ('Volapuk', 'vo')
|
|
+ yield t, ('Walloon', 'wa')
|
|
+ yield t, ('Welsh', 'cy')
|
|
+ yield t, ('Wolof', 'wo')
|
|
+ yield t, ('Xhosa', 'xh')
|
|
+ yield t, ('Yiddish', 'yi')
|
|
+ yield t, ('Yoruba', 'yo')
|
|
+ yield t, ('Zhuang', 'za')
|
|
+ yield t, ('Zulu', 'zu')
|
|
# TODO:
|
|
- yield x, '(Afan) Oromo', 'om'
|
|
- yield x, 'Bihari', 'bh' # "bh" is marked as collective in ISO-639-2
|
|
- yield x, 'Serbian (Latin)', 'sr_RS@latin'
|
|
- yield x, 'Serbo-Croatian', 'sh' # "sh" is deprecated in favor of "sr", "hr", "bs"
|
|
+ yield x, ('(Afan) Oromo', 'om')
|
|
+ yield x, ('Bihari', 'bh') # "bh" is marked as collective in ISO-639-2
|
|
+ yield x, ('Serbian (Latin)', 'sr_RS@latin')
|
|
+ yield x, ('Serbo-Croatian', 'sh') # "sh" is deprecated in favor of "sr", "hr", "bs"
|
|
|
|
# vim:ts=4 sts=4 sw=4 et
|
|
Index: i18nspector-0.26/tests/test_misc.py
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/tests/test_misc.py
|
|
+++ i18nspector-0.26/tests/test_misc.py
|
|
@@ -24,14 +24,7 @@ import stat
|
|
import tempfile
|
|
import time
|
|
|
|
-from nose.tools import (
|
|
- assert_almost_equal,
|
|
- assert_equal,
|
|
- assert_is_instance,
|
|
- assert_is_not_none,
|
|
- assert_raises,
|
|
- assert_true,
|
|
-)
|
|
+import pytest
|
|
|
|
import lib.misc as M
|
|
|
|
@@ -40,11 +33,11 @@ from . import tools
|
|
class test_unsorted:
|
|
|
|
def t(self, lst, expected):
|
|
- assert_is_instance(lst, list)
|
|
+ assert isinstance(lst, list)
|
|
r = M.unsorted(lst)
|
|
- assert_equal(r, expected)
|
|
+ assert r == expected
|
|
r = M.unsorted(x for x in lst)
|
|
- assert_equal(r, expected)
|
|
+ assert r == expected
|
|
|
|
def test_0(self):
|
|
self.t([], None)
|
|
@@ -71,7 +64,7 @@ class test_unsorted:
|
|
while True:
|
|
yield 23
|
|
r = M.unsorted(iterable())
|
|
- assert_equal(r, (37, 23))
|
|
+ assert r == (37, 23)
|
|
|
|
class test_check_sorted:
|
|
|
|
@@ -79,25 +72,24 @@ class test_check_sorted:
|
|
M.check_sorted([17, 23, 37])
|
|
|
|
def test_unsorted(self):
|
|
- with assert_raises(M.DataIntegrityError) as cm:
|
|
+ with pytest.raises(M.DataIntegrityError) as cm:
|
|
M.check_sorted([23, 37, 17])
|
|
- assert_equal(str(cm.exception), '37 > 17')
|
|
+ assert str(cm.value) == '37 > 17'
|
|
|
|
def test_sorted_vk():
|
|
lst = ['eggs', 'spam', 'ham']
|
|
d = dict(enumerate(lst))
|
|
- assert_equal(
|
|
- lst,
|
|
- list(M.sorted_vk(d))
|
|
- )
|
|
+ assert (
|
|
+ lst ==
|
|
+ list(M.sorted_vk(d)))
|
|
|
|
class test_utc_now:
|
|
|
|
def test_types(self):
|
|
now = M.utc_now()
|
|
- assert_is_instance(now, datetime.datetime)
|
|
- assert_is_not_none(now.tzinfo)
|
|
- assert_equal(now.tzinfo.utcoffset(now), datetime.timedelta(0))
|
|
+ assert isinstance(now, datetime.datetime)
|
|
+ assert now.tzinfo is not None
|
|
+ assert now.tzinfo.utcoffset(now) == datetime.timedelta(0)
|
|
|
|
@tools.fork_isolation
|
|
def test_tz_resistance(self):
|
|
@@ -108,18 +100,17 @@ class test_utc_now:
|
|
now1 = t('Etc/GMT-4')
|
|
now2 = t('Etc/GMT+2')
|
|
tdelta = (now1 - now2).total_seconds()
|
|
- assert_almost_equal(tdelta, 0, delta=0.75)
|
|
+ assert abs(tdelta - 0) <= 0.75
|
|
|
|
class test_format_range:
|
|
|
|
def t(self, x, y, max, expected): # pylint: disable=redefined-builtin
|
|
- assert_equal(
|
|
- M.format_range(range(x, y), max=max),
|
|
- expected
|
|
- )
|
|
+ assert (
|
|
+ M.format_range(range(x, y), max=max) ==
|
|
+ expected)
|
|
|
|
def test_max_is_lt_4(self):
|
|
- with assert_raises(ValueError):
|
|
+ with pytest.raises(ValueError):
|
|
self.t(5, 10, 3, None)
|
|
|
|
def test_len_lt_max(self):
|
|
@@ -139,7 +130,7 @@ def test_throwaway_tempdir():
|
|
with M.throwaway_tempdir('test'):
|
|
d = tempfile.gettempdir()
|
|
st = os.stat(d)
|
|
- assert_equal(stat.S_IMODE(st.st_mode), 0o700)
|
|
- assert_true(stat.S_ISDIR(st.st_mode))
|
|
+ assert stat.S_IMODE(st.st_mode) == 0o700
|
|
+ assert stat.S_ISDIR(st.st_mode)
|
|
|
|
# vim:ts=4 sts=4 sw=4 et
|
|
Index: i18nspector-0.26/tests/test_moparser.py
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/tests/test_moparser.py
|
|
+++ i18nspector-0.26/tests/test_moparser.py
|
|
@@ -20,10 +20,7 @@
|
|
|
|
import random
|
|
|
|
-from nose.tools import (
|
|
- assert_equal,
|
|
- assert_raises,
|
|
-)
|
|
+import pytest
|
|
|
|
import lib.moparser as M
|
|
|
|
@@ -38,21 +35,21 @@ def parser_for_bytes(data):
|
|
class test_magic:
|
|
|
|
def test_value(self):
|
|
- assert_equal(M.little_endian_magic, b'\xDE\x12\x04\x95')
|
|
- assert_equal(M.big_endian_magic, b'\x95\x04\x12\xDE')
|
|
+ assert M.little_endian_magic == b'\xDE\x12\x04\x95'
|
|
+ assert M.big_endian_magic == b'\x95\x04\x12\xDE'
|
|
|
|
def test_short(self):
|
|
for j in range(0, 3):
|
|
data = M.little_endian_magic[:j]
|
|
- with assert_raises(M.SyntaxError) as cm:
|
|
+ with pytest.raises(M.SyntaxError) as cm:
|
|
parser_for_bytes(data)
|
|
- assert_equal(str(cm.exception), 'unexpected magic')
|
|
+ assert str(cm.value) == 'unexpected magic'
|
|
|
|
def test_full(self):
|
|
for magic in {M.little_endian_magic, M.big_endian_magic}:
|
|
- with assert_raises(M.SyntaxError) as cm:
|
|
+ with pytest.raises(M.SyntaxError) as cm:
|
|
parser_for_bytes(magic)
|
|
- assert_equal(str(cm.exception), 'truncated file')
|
|
+ assert str(cm.value) == 'truncated file'
|
|
|
|
def test_random(self):
|
|
while True:
|
|
@@ -62,8 +59,8 @@ class test_magic:
|
|
if random_magic in {M.little_endian_magic, M.big_endian_magic}:
|
|
continue
|
|
break
|
|
- with assert_raises(M.SyntaxError) as cm:
|
|
+ with pytest.raises(M.SyntaxError) as cm:
|
|
parser_for_bytes(random_magic)
|
|
- assert_equal(str(cm.exception), 'unexpected magic')
|
|
+ assert str(cm.value) == 'unexpected magic'
|
|
|
|
# vim:ts=4 sts=4 sw=4 et
|
|
Index: i18nspector-0.26/tests/test_polib4us.py
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/tests/test_polib4us.py
|
|
+++ i18nspector-0.26/tests/test_polib4us.py
|
|
@@ -20,11 +20,6 @@
|
|
|
|
import polib
|
|
|
|
-from nose.tools import (
|
|
- assert_list_equal,
|
|
- assert_true,
|
|
-)
|
|
-
|
|
import lib.polib4us as M
|
|
|
|
from . import tools
|
|
@@ -50,7 +45,7 @@ msgstr "b"
|
|
file.write(s)
|
|
file.flush()
|
|
po = polib.pofile(file.name)
|
|
- assert_true(po[-1].obsolete)
|
|
+ assert po[-1].obsolete
|
|
t()
|
|
M.install_patches()
|
|
t()
|
|
@@ -60,9 +55,8 @@ def test_flag_splitting():
|
|
M.install_patches()
|
|
e = polib.POEntry()
|
|
e.flags = ['fuzzy,c-format']
|
|
- assert_list_equal(
|
|
- e.flags,
|
|
- ['fuzzy', 'c-format']
|
|
- )
|
|
+ assert (
|
|
+ e.flags ==
|
|
+ ['fuzzy', 'c-format'])
|
|
|
|
# vim:ts=4 sts=4 sw=4 et
|
|
Index: i18nspector-0.26/tests/test_strformat_c.py
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/tests/test_strformat_c.py
|
|
+++ i18nspector-0.26/tests/test_strformat_c.py
|
|
@@ -21,22 +21,25 @@
|
|
import os
|
|
import struct
|
|
import sys
|
|
+import unittest
|
|
import unittest.mock
|
|
|
|
-import nose
|
|
-from nose.tools import (
|
|
- assert_equal,
|
|
- assert_greater,
|
|
- assert_is_instance,
|
|
- assert_raises,
|
|
- assert_sequence_equal,
|
|
-)
|
|
+import pytest
|
|
|
|
import lib.strformat.c as M
|
|
|
|
+from . import tools
|
|
+
|
|
+
|
|
+# methods using the tools.collect_yielded decorator don't have a 'self'
|
|
+# since they end up being run before 'self' exists. pylint doesn't
|
|
+# understand this unusual situation
|
|
+# pylint: disable=no-method-argument
|
|
+
|
|
+
|
|
def test_INT_MAX():
|
|
struct.pack('=i', M.INT_MAX)
|
|
- with assert_raises(struct.error):
|
|
+ with pytest.raises(struct.error):
|
|
struct.pack('=i', M.INT_MAX + 1)
|
|
|
|
def is_glibc():
|
|
@@ -49,121 +52,134 @@ def is_glibc():
|
|
def test_NL_ARGMAX():
|
|
plat = sys.platform
|
|
if plat.startswith('linux') and is_glibc():
|
|
- assert_equal(
|
|
- M.NL_ARGMAX,
|
|
- os.sysconf('SC_NL_ARGMAX')
|
|
- )
|
|
+ assert (
|
|
+ M.NL_ARGMAX ==
|
|
+ os.sysconf('SC_NL_ARGMAX'))
|
|
else:
|
|
- raise nose.SkipTest('Test specific to Linux with glibc')
|
|
+ raise unittest.SkipTest('Test specific to Linux with glibc')
|
|
|
|
small_NL_ARGMAX = unittest.mock.patch('lib.strformat.c.NL_ARGMAX', 42)
|
|
# Setting NL_ARGMAX to a small number makes the *_index_out_of_range() tests
|
|
# much faster.
|
|
|
|
def test_lone_percent():
|
|
- with assert_raises(M.Error):
|
|
+ with pytest.raises(M.Error):
|
|
M.FormatString('%')
|
|
|
|
def test_invalid_conversion_spec():
|
|
- with assert_raises(M.Error):
|
|
+ with pytest.raises(M.Error):
|
|
M.FormatString('%!')
|
|
|
|
def test_add_argument():
|
|
fmt = M.FormatString('%s')
|
|
- with assert_raises(RuntimeError):
|
|
+ with pytest.raises(RuntimeError):
|
|
fmt.add_argument(2, None)
|
|
|
|
def test_text():
|
|
fmt = M.FormatString('eggs%dbacon%dspam')
|
|
- assert_equal(len(fmt), 5)
|
|
+ assert len(fmt) == 5
|
|
fmt = list(fmt)
|
|
- assert_equal(fmt[0], 'eggs')
|
|
- assert_equal(fmt[2], 'bacon')
|
|
- assert_equal(fmt[4], 'spam')
|
|
+ assert fmt[0] == 'eggs'
|
|
+ assert fmt[2] == 'bacon'
|
|
+ assert fmt[4] == 'spam'
|
|
|
|
class test_types:
|
|
|
|
- def t(self, s, tp, warn_type=None, integer=False):
|
|
+ @staticmethod
|
|
+ def t(s, tp, warn_type=None, integer=False):
|
|
fmt = M.FormatString(s)
|
|
[conv] = fmt
|
|
- assert_is_instance(conv, M.Conversion)
|
|
- assert_equal(conv.type, tp)
|
|
+ assert isinstance(conv, M.Conversion)
|
|
+ assert conv.type == tp
|
|
if tp == 'void':
|
|
- assert_sequence_equal(fmt.arguments, [])
|
|
+ assert fmt.arguments == []
|
|
else:
|
|
[[arg]] = fmt.arguments
|
|
- assert_equal(arg.type, tp)
|
|
+ assert arg.type == tp
|
|
if warn_type is None:
|
|
- assert_sequence_equal(fmt.warnings, [])
|
|
+ assert fmt.warnings == []
|
|
else:
|
|
[warning] = fmt.warnings
|
|
- assert_is_instance(warning, warn_type)
|
|
- assert_equal(conv.integer, integer)
|
|
+ assert isinstance(warning, warn_type)
|
|
+ assert conv.integer == integer
|
|
|
|
- def test_integer(self):
|
|
- def t(s, tp, warn_type=None):
|
|
+ @tools.collect_yielded
|
|
+ def test_integer():
|
|
+ def t(s, tp, suffix, warn_type=None):
|
|
integer = not suffix
|
|
- self.t(s, tp + suffix, warn_type, integer)
|
|
+ test_types.t(s, tp + suffix, warn_type, integer)
|
|
for c in 'din':
|
|
suffix = ''
|
|
if c == 'n':
|
|
suffix = ' *'
|
|
- yield t, ('%hh' + c), 'signed char'
|
|
- yield t, ('%h' + c), 'short int'
|
|
- yield t, ('%' + c), 'int'
|
|
- yield t, ('%l' + c), 'long int'
|
|
- yield t, ('%ll' + c), 'long long int'
|
|
- yield t, ('%L' + c), 'long long int', M.NonPortableConversion
|
|
- yield t, ('%q' + c), 'long long int', M.NonPortableConversion
|
|
- yield t, ('%j' + c), 'intmax_t'
|
|
- yield t, ('%z' + c), 'ssize_t'
|
|
- yield t, ('%Z' + c), 'ssize_t', M.NonPortableConversion
|
|
- yield t, ('%t' + c), 'ptrdiff_t'
|
|
+ yield t, (('%hh' + c), 'signed char', suffix)
|
|
+ yield t, (('%h' + c), 'short int', suffix)
|
|
+ yield t, (('%' + c), 'int', suffix)
|
|
+ yield t, (('%l' + c), 'long int', suffix)
|
|
+ yield t, (('%ll' + c), 'long long int', suffix)
|
|
+ yield t, (('%L' + c), 'long long int', suffix, M.NonPortableConversion)
|
|
+ yield t, (('%q' + c), 'long long int', suffix, M.NonPortableConversion)
|
|
+ yield t, (('%j' + c), 'intmax_t', suffix)
|
|
+ yield t, (('%z' + c), 'ssize_t', suffix)
|
|
+ yield t, (('%Z' + c), 'ssize_t', suffix, M.NonPortableConversion)
|
|
+ yield t, (('%t' + c), 'ptrdiff_t', suffix)
|
|
for c in 'ouxX':
|
|
suffix = ''
|
|
- yield t, ('%hh' + c), 'unsigned char'
|
|
- yield t, ('%h' + c), 'unsigned short int'
|
|
- yield t, ('%' + c), 'unsigned int'
|
|
- yield t, ('%l' + c), 'unsigned long int'
|
|
- yield t, ('%ll' + c), 'unsigned long long int'
|
|
- yield t, ('%L' + c), 'unsigned long long int', M.NonPortableConversion
|
|
- yield t, ('%q' + c), 'unsigned long long int', M.NonPortableConversion
|
|
- yield t, ('%j' + c), 'uintmax_t'
|
|
- yield t, ('%z' + c), 'size_t'
|
|
- yield t, ('%Z' + c), 'size_t', M.NonPortableConversion
|
|
- yield t, ('%t' + c), '[unsigned ptrdiff_t]'
|
|
+ yield t, (('%hh' + c), 'unsigned char', suffix)
|
|
+ yield t, (('%h' + c), 'unsigned short int', suffix)
|
|
+ yield t, (('%' + c), 'unsigned int', suffix)
|
|
+ yield t, (('%l' + c), 'unsigned long int', suffix)
|
|
+ yield t, (('%ll' + c), 'unsigned long long int', suffix)
|
|
+ yield t, (('%L' + c), 'unsigned long long int', suffix, M.NonPortableConversion)
|
|
+ yield t, (('%q' + c), 'unsigned long long int', suffix, M.NonPortableConversion)
|
|
+ yield t, (('%j' + c), 'uintmax_t', suffix)
|
|
+ yield t, (('%z' + c), 'size_t', suffix)
|
|
+ yield t, (('%Z' + c), 'size_t', suffix, M.NonPortableConversion)
|
|
+ yield t, (('%t' + c), '[unsigned ptrdiff_t]', suffix)
|
|
+
|
|
+ @tools.collect_yielded
|
|
+ def test_double():
|
|
+ def t(*args):
|
|
+ test_types.t(*args)
|
|
|
|
- def test_double(self):
|
|
- t = self.t
|
|
for c in 'aefgAEFG':
|
|
- yield t, ('%' + c), 'double'
|
|
- yield t, ('%l' + c), 'double', M.NonPortableConversion
|
|
- yield t, ('%L' + c), 'long double'
|
|
-
|
|
- def test_char(self):
|
|
- t = self.t
|
|
- yield t, '%c', 'char'
|
|
- yield t, '%lc', 'wint_t'
|
|
- yield t, '%C', 'wint_t', M.NonPortableConversion
|
|
- yield t, '%s', 'const char *'
|
|
- yield t, '%ls', 'const wchar_t *'
|
|
- yield t, '%S', 'const wchar_t *', M.NonPortableConversion
|
|
-
|
|
- def test_void(self):
|
|
- t = self.t
|
|
- yield t, '%p', 'void *'
|
|
- yield t, '%m', 'void'
|
|
- yield t, '%%', 'void'
|
|
+ yield t, (('%' + c), 'double')
|
|
+ yield t, (('%l' + c), 'double', M.NonPortableConversion)
|
|
+ yield t, (('%L' + c), 'long double')
|
|
+
|
|
+ @tools.collect_yielded
|
|
+ def test_char():
|
|
+ def t(*args):
|
|
+ test_types.t(*args)
|
|
+
|
|
+ yield t, ('%c', 'char')
|
|
+ yield t, ('%lc', 'wint_t')
|
|
+ yield t, ('%C', 'wint_t', M.NonPortableConversion)
|
|
+ yield t, ('%s', 'const char *')
|
|
+ yield t, ('%ls', 'const wchar_t *')
|
|
+ yield t, ('%S', 'const wchar_t *', M.NonPortableConversion)
|
|
+
|
|
+ @tools.collect_yielded
|
|
+ def test_void():
|
|
+ def t(*args):
|
|
+ test_types.t(*args)
|
|
+
|
|
+ yield t, ('%p', 'void *')
|
|
+ yield t, ('%m', 'void')
|
|
+ yield t, ('%%', 'void')
|
|
|
|
- def test_c99_macros(self):
|
|
+ @tools.collect_yielded
|
|
+ def test_c99_macros():
|
|
# pylint: disable=undefined-loop-variable
|
|
def _t(s, tp):
|
|
- return self.t(s, tp, integer=True)
|
|
+ return test_types.t(s, tp, integer=True)
|
|
def t(s, tp):
|
|
return (
|
|
_t,
|
|
- '%<{macro}>'.format(macro=s.format(c=c, n=n)),
|
|
- ('u' if unsigned else '') + tp.format(n=n)
|
|
+ (
|
|
+ '%<{macro}>'.format(macro=s.format(c=c, n=n)),
|
|
+ ('u' if unsigned else '') + tp.format(n=n)
|
|
+ )
|
|
)
|
|
# pylint: enable=undefined-loop-variable
|
|
for c in 'diouxX':
|
|
@@ -175,64 +191,71 @@ class test_types:
|
|
yield t('PRI{c}MAX', 'intmax_t')
|
|
yield t('PRI{c}PTR', 'intptr_t')
|
|
|
|
+_lengths = ['hh', 'h', 'l', 'll', 'q', 'j', 'z', 't', 'L']
|
|
+
|
|
class test_invalid_length:
|
|
- def t(self, s):
|
|
- with assert_raises(M.LengthError):
|
|
+ @staticmethod
|
|
+ def t(s):
|
|
+ with pytest.raises(M.LengthError):
|
|
M.FormatString(s)
|
|
|
|
- _lengths = ['hh', 'h', 'l', 'll', 'q', 'j', 'z', 't', 'L']
|
|
-
|
|
- def test_double(self):
|
|
- t = self.t
|
|
+ @tools.collect_yielded
|
|
+ def test_double():
|
|
+ def t(*args):
|
|
+ test_invalid_length.t(*args)
|
|
for c in 'aefgAEFG':
|
|
- for l in self._lengths:
|
|
+ for l in _lengths:
|
|
if l in 'lL':
|
|
continue
|
|
yield t, ('%' + l + c)
|
|
|
|
- def test_char(self):
|
|
- t = self.t
|
|
+ @tools.collect_yielded
|
|
+ def test_char():
|
|
+ def t(*args):
|
|
+ test_invalid_length.t(*args)
|
|
for c in 'cs':
|
|
- for l in self._lengths:
|
|
+ for l in _lengths:
|
|
if l != 'l':
|
|
yield t, '%' + l + c
|
|
yield t, ('%' + l + c.upper())
|
|
|
|
- def test_void(self):
|
|
- t = self.t
|
|
+ @tools.collect_yielded
|
|
+ def test_void():
|
|
+ def t(*args):
|
|
+ test_invalid_length.t(*args)
|
|
for c in 'pm%':
|
|
- for l in self._lengths:
|
|
+ for l in _lengths:
|
|
yield t, ('%' + l + c)
|
|
|
|
class test_numeration:
|
|
|
|
def test_percent(self):
|
|
- with assert_raises(M.ForbiddenArgumentIndex):
|
|
+ with pytest.raises(M.ForbiddenArgumentIndex):
|
|
M.FormatString('%1$%')
|
|
|
|
def test_errno(self):
|
|
# FIXME?
|
|
fmt = M.FormatString('%1$m')
|
|
- assert_equal(len(fmt), 1)
|
|
- assert_equal(len(fmt.arguments), 0)
|
|
+ assert len(fmt) == 1
|
|
+ assert len(fmt.arguments) == 0
|
|
|
|
def test_swapped(self):
|
|
fmt = M.FormatString('%2$s%1$d')
|
|
- assert_equal(len(fmt), 2)
|
|
+ assert len(fmt) == 2
|
|
[a1], [a2] = fmt.arguments
|
|
- assert_equal(a1.type, 'int')
|
|
- assert_equal(a2.type, 'const char *')
|
|
+ assert a1.type == 'int'
|
|
+ assert a2.type == 'const char *'
|
|
|
|
def test_numbering_mixture(self):
|
|
def t(s):
|
|
- with assert_raises(M.ArgumentNumberingMixture):
|
|
+ with pytest.raises(M.ArgumentNumberingMixture):
|
|
M.FormatString(s)
|
|
t('%s%2$s')
|
|
t('%2$s%s')
|
|
|
|
@small_NL_ARGMAX
|
|
def test_index_out_of_range(self):
|
|
- with assert_raises(M.ArgumentRangeError):
|
|
+ with pytest.raises(M.ArgumentRangeError):
|
|
M.FormatString('%0$d')
|
|
def fs(n):
|
|
s = ''.join(
|
|
@@ -241,17 +264,17 @@ class test_numeration:
|
|
)
|
|
return M.FormatString(s)
|
|
fmt = fs(M.NL_ARGMAX)
|
|
- assert_equal(len(fmt), M.NL_ARGMAX)
|
|
- assert_equal(len(fmt.arguments), M.NL_ARGMAX)
|
|
- with assert_raises(M.ArgumentRangeError):
|
|
+ assert len(fmt) == M.NL_ARGMAX
|
|
+ assert len(fmt.arguments) == M.NL_ARGMAX
|
|
+ with pytest.raises(M.ArgumentRangeError):
|
|
fs(M.NL_ARGMAX + 1)
|
|
|
|
def test_initial_gap(self):
|
|
- with assert_raises(M.MissingArgument):
|
|
+ with pytest.raises(M.MissingArgument):
|
|
M.FormatString('%2$d')
|
|
|
|
def test_gap(self):
|
|
- with assert_raises(M.MissingArgument):
|
|
+ with pytest.raises(M.MissingArgument):
|
|
M.FormatString('%3$d%1$d')
|
|
|
|
class test_redundant_flag:
|
|
@@ -259,7 +282,7 @@ class test_redundant_flag:
|
|
def t(self, s):
|
|
fmt = M.FormatString(s)
|
|
[exc] = fmt.warnings
|
|
- assert_is_instance(exc, M.RedundantFlag)
|
|
+ assert isinstance(exc, M.RedundantFlag)
|
|
|
|
def test_duplicate(self):
|
|
self.t('%--17d')
|
|
@@ -274,87 +297,114 @@ class test_redundant_flag:
|
|
|
|
class test_expected_flag:
|
|
|
|
- def t(self, s):
|
|
+ @staticmethod
|
|
+ def t(s):
|
|
fmt = M.FormatString(s)
|
|
- assert_equal(len(fmt), 1)
|
|
+ assert len(fmt) == 1
|
|
|
|
- def test_hash(self):
|
|
+ @tools.collect_yielded
|
|
+ def test_hash():
|
|
+ def t(*args):
|
|
+ test_expected_flag.t(*args)
|
|
for c in 'oxXaAeEfFgG':
|
|
- yield self.t, ('%#' + c)
|
|
+ yield t, ('%#' + c)
|
|
|
|
- def test_zero(self):
|
|
+ @tools.collect_yielded
|
|
+ def test_zero():
|
|
+ def t(*args):
|
|
+ test_expected_flag.t(*args)
|
|
for c in 'diouxXaAeEfFgG':
|
|
- yield self.t, ('%0' + c)
|
|
+ yield t, ('%0' + c)
|
|
|
|
- def test_apos(self):
|
|
+ @tools.collect_yielded
|
|
+ def test_apos():
|
|
+ def t(*args):
|
|
+ test_expected_flag.t(*args)
|
|
for c in 'diufFgG':
|
|
- yield self.t, ("%'" + c)
|
|
+ yield t, ("%'" + c)
|
|
|
|
- def test_other(self):
|
|
+ @tools.collect_yielded
|
|
+ def test_other():
|
|
+ def t(*args):
|
|
+ test_expected_flag.t(*args)
|
|
for flag in '- +I':
|
|
for c in 'diouxXaAeEfFgGcCsSpm':
|
|
- yield self.t, ('%' + flag + c)
|
|
+ yield t, ('%' + flag + c)
|
|
|
|
class test_unexpected_flag:
|
|
|
|
- def t(self, s):
|
|
- with assert_raises(M.FlagError):
|
|
+ @staticmethod
|
|
+ def t(s):
|
|
+ with pytest.raises(M.FlagError):
|
|
M.FormatString(s)
|
|
|
|
- def test_hash(self):
|
|
+ @tools.collect_yielded
|
|
+ def test_hash():
|
|
+ def t(*args):
|
|
+ test_unexpected_flag.t(*args)
|
|
for c in 'dicCsSnpm%':
|
|
- yield self.t, ('%#' + c)
|
|
+ yield t, ('%#' + c)
|
|
|
|
- def test_zero(self):
|
|
+ @tools.collect_yielded
|
|
+ def test_zero():
|
|
+ def t(*args):
|
|
+ test_unexpected_flag.t(*args)
|
|
for c in 'cCsSnpm%':
|
|
- yield self.t, ('%0' + c)
|
|
+ yield t, ('%0' + c)
|
|
|
|
- def test_apos(self):
|
|
+ @tools.collect_yielded
|
|
+ def test_apos():
|
|
+ def t(*args):
|
|
+ test_unexpected_flag.t(*args)
|
|
for c in 'oxXaAeEcCsSnpm%':
|
|
- yield self.t, ("%'" + c)
|
|
+ yield t, ("%'" + c)
|
|
|
|
- def test_other(self):
|
|
+ @tools.collect_yielded
|
|
+ def test_other():
|
|
+ def t(*args):
|
|
+ test_unexpected_flag.t(*args)
|
|
for c in '%n':
|
|
for flag in '- +I':
|
|
- yield self.t, ('%' + flag + c)
|
|
+ yield t, ('%' + flag + c)
|
|
|
|
class test_width:
|
|
|
|
- def test_ok(self):
|
|
+ @tools.collect_yielded
|
|
+ def test_ok():
|
|
def t(s):
|
|
fmt = M.FormatString(s)
|
|
- assert_equal(len(fmt), 1)
|
|
+ assert len(fmt) == 1
|
|
for c in 'diouxXaAeEfFgGcCsSp':
|
|
yield t, ('%1' + c)
|
|
yield t, '%1m' # FIXME?
|
|
|
|
def test_invalid(self):
|
|
for c in '%n':
|
|
- with assert_raises(M.WidthError):
|
|
+ with pytest.raises(M.WidthError):
|
|
M.FormatString('%1' + c)
|
|
|
|
def test_too_large(self):
|
|
fmt = M.FormatString('%{0}d'.format(M.INT_MAX))
|
|
- assert_equal(len(fmt), 1)
|
|
- assert_equal(len(fmt.arguments), 1)
|
|
- with assert_raises(M.WidthRangeError):
|
|
+ assert len(fmt) == 1
|
|
+ assert len(fmt.arguments) == 1
|
|
+ with pytest.raises(M.WidthRangeError):
|
|
M.FormatString('%{0}d'.format(M.INT_MAX + 1))
|
|
|
|
def test_variable(self):
|
|
fmt = M.FormatString('%*s')
|
|
- assert_equal(len(fmt), 1)
|
|
- assert_equal(len(fmt.arguments), 2)
|
|
+ assert len(fmt) == 1
|
|
+ assert len(fmt.arguments) == 2
|
|
[a1], [a2] = fmt.arguments
|
|
- assert_equal(a1.type, 'int')
|
|
- assert_equal(a2.type, 'const char *')
|
|
+ assert a1.type == 'int'
|
|
+ assert a2.type == 'const char *'
|
|
|
|
def _test_index(self, i):
|
|
fmt = M.FormatString('%2$*{0}$s'.format(i))
|
|
- assert_equal(len(fmt), 1)
|
|
- assert_equal(len(fmt.arguments), 2)
|
|
+ assert len(fmt) == 1
|
|
+ assert len(fmt.arguments) == 2
|
|
[a1], [a2] = fmt.arguments
|
|
- assert_equal(a1.type, 'int')
|
|
- assert_equal(a2.type, 'const char *')
|
|
+ assert a1.type == 'int'
|
|
+ assert a2.type == 'const char *'
|
|
|
|
def test_index(self):
|
|
self._test_index(1)
|
|
@@ -365,7 +415,7 @@ class test_width:
|
|
|
|
@small_NL_ARGMAX
|
|
def test_index_out_of_range(self):
|
|
- with assert_raises(M.ArgumentRangeError):
|
|
+ with pytest.raises(M.ArgumentRangeError):
|
|
M.FormatString('%1$*0$s')
|
|
def fs(n):
|
|
s = ''.join(
|
|
@@ -374,14 +424,14 @@ class test_width:
|
|
) + '%1$*{0}$s'.format(n)
|
|
return M.FormatString(s)
|
|
fmt = fs(M.NL_ARGMAX)
|
|
- assert_equal(len(fmt), M.NL_ARGMAX - 1)
|
|
- assert_equal(len(fmt.arguments), M.NL_ARGMAX)
|
|
- with assert_raises(M.ArgumentRangeError):
|
|
+ assert len(fmt) == M.NL_ARGMAX - 1
|
|
+ assert len(fmt.arguments) == M.NL_ARGMAX
|
|
+ with pytest.raises(M.ArgumentRangeError):
|
|
fs(M.NL_ARGMAX + 1)
|
|
|
|
def test_numbering_mixture(self):
|
|
def t(s):
|
|
- with assert_raises(M.ArgumentNumberingMixture):
|
|
+ with pytest.raises(M.ArgumentNumberingMixture):
|
|
M.FormatString(s)
|
|
t('%1$*s')
|
|
t('%*1$s')
|
|
@@ -390,58 +440,62 @@ class test_width:
|
|
|
|
class test_precision:
|
|
|
|
- def test_ok(self):
|
|
+ @tools.collect_yielded
|
|
+ def test_ok():
|
|
def t(s):
|
|
fmt = M.FormatString(s)
|
|
- assert_equal(len(fmt), 1)
|
|
+ assert len(fmt) == 1
|
|
for c in 'diouxXaAeEfFgGsS':
|
|
yield t, ('%.1' + c)
|
|
|
|
- def test_redundant_0(self):
|
|
+ @tools.collect_yielded
|
|
+ def test_redundant_0():
|
|
def t(s):
|
|
fmt = M.FormatString(s)
|
|
- assert_equal(len(fmt), 1)
|
|
+ assert len(fmt) == 1
|
|
[warning] = fmt.warnings
|
|
- assert_is_instance(warning, M.RedundantFlag)
|
|
+ assert isinstance(warning, M.RedundantFlag)
|
|
for c in 'diouxX':
|
|
yield t, ('%0.1' + c)
|
|
|
|
- def test_non_redundant_0(self):
|
|
+ @tools.collect_yielded
|
|
+ def test_non_redundant_0():
|
|
def t(s):
|
|
fmt = M.FormatString(s)
|
|
- assert_equal(len(fmt), 1)
|
|
- assert_sequence_equal(fmt.warnings, [])
|
|
+ assert len(fmt) == 1
|
|
+ assert fmt.warnings == []
|
|
for c in 'aAeEfFgG':
|
|
yield t, ('%0.1' + c)
|
|
|
|
- def test_unexpected(self):
|
|
+ @tools.collect_yielded
|
|
+ def test_unexpected():
|
|
def t(s):
|
|
- with assert_raises(M.PrecisionError):
|
|
+ with pytest.raises(M.PrecisionError):
|
|
M.FormatString(s)
|
|
for c in 'cCpnm%':
|
|
yield t, ('%.1' + c)
|
|
|
|
def test_too_large(self):
|
|
fmt = M.FormatString('%.{0}f'.format(M.INT_MAX))
|
|
- assert_equal(len(fmt), 1)
|
|
- with assert_raises(M.PrecisionRangeError):
|
|
+ assert len(fmt) == 1
|
|
+ with pytest.raises(M.PrecisionRangeError):
|
|
M.FormatString('%.{0}f'.format(M.INT_MAX + 1))
|
|
|
|
def test_variable(self):
|
|
fmt = M.FormatString('%.*f')
|
|
- assert_equal(len(fmt), 1)
|
|
- assert_equal(len(fmt.arguments), 2)
|
|
+ assert len(fmt) == 1
|
|
+ assert len(fmt.arguments) == 2
|
|
[a1], [a2] = fmt.arguments
|
|
- assert_equal(a1.type, 'int')
|
|
- assert_equal(a2.type, 'double')
|
|
+ assert a1.type == 'int'
|
|
+ assert a2.type == 'double'
|
|
|
|
def _test_index(self, i):
|
|
fmt = M.FormatString('%2$.*{0}$f'.format(i))
|
|
- assert_equal(len(fmt), 1)
|
|
- assert_equal(len(fmt.arguments), 2)
|
|
+ assert len(fmt) == 1
|
|
+ assert len(fmt.arguments) == 2
|
|
[a1], [a2] = fmt.arguments
|
|
- assert_equal(a1.type, 'int')
|
|
- assert_equal(a2.type, 'double')
|
|
+ assert a1.type == 'int'
|
|
+ assert a2.type == 'double'
|
|
|
|
def test_index(self):
|
|
self._test_index(1)
|
|
@@ -452,7 +506,7 @@ class test_precision:
|
|
|
|
@small_NL_ARGMAX
|
|
def test_index_out_of_range(self):
|
|
- with assert_raises(M.ArgumentRangeError):
|
|
+ with pytest.raises(M.ArgumentRangeError):
|
|
M.FormatString('%1$.*0$f')
|
|
def fs(n):
|
|
s = ''.join(
|
|
@@ -461,14 +515,14 @@ class test_precision:
|
|
) + '%1$.*{0}$f'.format(n)
|
|
return M.FormatString(s)
|
|
fmt = fs(M.NL_ARGMAX)
|
|
- assert_equal(len(fmt), M.NL_ARGMAX - 1)
|
|
- assert_equal(len(fmt.arguments), M.NL_ARGMAX)
|
|
- with assert_raises(M.ArgumentRangeError):
|
|
+ assert len(fmt) == M.NL_ARGMAX - 1
|
|
+ assert len(fmt.arguments) == M.NL_ARGMAX
|
|
+ with pytest.raises(M.ArgumentRangeError):
|
|
fs(M.NL_ARGMAX + 1)
|
|
|
|
def test_numbering_mixture(self):
|
|
def t(s):
|
|
- with assert_raises(M.ArgumentNumberingMixture):
|
|
+ with pytest.raises(M.ArgumentNumberingMixture):
|
|
M.FormatString(s)
|
|
t('%1$.*f')
|
|
t('%.*1$f')
|
|
@@ -481,15 +535,15 @@ class test_type_compatibility:
|
|
def t(s, tp):
|
|
fmt = M.FormatString(s)
|
|
[args] = fmt.arguments
|
|
- assert_greater(len(args), 1)
|
|
+ assert len(args) > 1
|
|
for arg in args:
|
|
- assert_equal(arg.type, tp)
|
|
+ assert arg.type == tp
|
|
t('%1$d%1$d', 'int')
|
|
t('%1$d%1$i', 'int')
|
|
|
|
def test_mismatch(self):
|
|
def t(s):
|
|
- with assert_raises(M.ArgumentTypeMismatch):
|
|
+ with pytest.raises(M.ArgumentTypeMismatch):
|
|
M.FormatString(s)
|
|
t('%1$d%1$hd')
|
|
t('%1$d%1$u')
|
|
@@ -498,11 +552,11 @@ class test_type_compatibility:
|
|
@small_NL_ARGMAX
|
|
def test_too_many_conversions():
|
|
def t(s):
|
|
- with assert_raises(M.ArgumentRangeError):
|
|
+ with pytest.raises(M.ArgumentRangeError):
|
|
M.FormatString(s)
|
|
s = M.NL_ARGMAX * '%d'
|
|
fmt = M.FormatString(s)
|
|
- assert_equal(len(fmt), M.NL_ARGMAX)
|
|
+ assert len(fmt) == M.NL_ARGMAX
|
|
t(s + '%f')
|
|
t(s + '%*f')
|
|
t(s + '%.*f')
|
|
@@ -512,7 +566,7 @@ class test_get_last_integer_conversion:
|
|
def test_overflow(self):
|
|
fmt = M.FormatString('%s%d')
|
|
for n in [-1, 0, 3]:
|
|
- with assert_raises(IndexError):
|
|
+ with pytest.raises(IndexError):
|
|
fmt.get_last_integer_conversion(n=n)
|
|
|
|
def t(self, s, n, tp=M.Conversion):
|
|
@@ -520,7 +574,7 @@ class test_get_last_integer_conversion:
|
|
conv = fmt.get_last_integer_conversion(n=n)
|
|
if tp is None:
|
|
tp = type(tp)
|
|
- assert_is_instance(conv, tp)
|
|
+ assert isinstance(conv, tp)
|
|
return conv
|
|
|
|
def test_okay(self):
|
|
Index: i18nspector-0.26/tests/test_strformat_perlbrace.py
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/tests/test_strformat_perlbrace.py
|
|
+++ i18nspector-0.26/tests/test_strformat_perlbrace.py
|
|
@@ -18,40 +18,37 @@
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
# SOFTWARE.
|
|
|
|
-from nose.tools import (
|
|
- assert_equal,
|
|
- assert_raises,
|
|
-)
|
|
+import pytest
|
|
|
|
import lib.strformat.perlbrace as M
|
|
|
|
def test_lone_lcb():
|
|
- with assert_raises(M.Error):
|
|
+ with pytest.raises(M.Error):
|
|
M.FormatString('{')
|
|
|
|
def test_lone_rcb():
|
|
M.FormatString('}')
|
|
|
|
def test_invalid_field():
|
|
- with assert_raises(M.Error):
|
|
+ with pytest.raises(M.Error):
|
|
M.FormatString('{@}')
|
|
|
|
def test_text():
|
|
fmt = M.FormatString('bacon')
|
|
- assert_equal(len(fmt), 1)
|
|
+ assert len(fmt) == 1
|
|
[fld] = fmt
|
|
- assert_equal(fld, 'bacon')
|
|
+ assert fld == 'bacon'
|
|
|
|
class test_named_arguments:
|
|
|
|
def test_good(self):
|
|
fmt = M.FormatString('{spam}')
|
|
- assert_equal(len(fmt), 1)
|
|
+ assert len(fmt) == 1
|
|
[fld] = fmt
|
|
- assert_equal(fld, '{spam}')
|
|
+ assert fld == '{spam}'
|
|
|
|
def test_bad(self):
|
|
- with assert_raises(M.Error):
|
|
+ with pytest.raises(M.Error):
|
|
M.FormatString('{3ggs}')
|
|
|
|
# vim:ts=4 sts=4 sw=4 et
|
|
Index: i18nspector-0.26/tests/test_strformat_pybrace.py
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/tests/test_strformat_pybrace.py
|
|
+++ i18nspector-0.26/tests/test_strformat_pybrace.py
|
|
@@ -21,18 +21,13 @@
|
|
import struct
|
|
import unittest.mock
|
|
|
|
-from nose.tools import (
|
|
- assert_equal,
|
|
- assert_is,
|
|
- assert_is_instance,
|
|
- assert_raises,
|
|
-)
|
|
+import pytest
|
|
|
|
import lib.strformat.pybrace as M
|
|
|
|
def test_SSIZE_MAX():
|
|
struct.pack('=i', M.SSIZE_MAX)
|
|
- with assert_raises(struct.error):
|
|
+ with pytest.raises(struct.error):
|
|
struct.pack('=i', M.SSIZE_MAX + 1)
|
|
|
|
small_SSIZE_MAX = unittest.mock.patch('lib.strformat.pybrace.SSIZE_MAX', 42)
|
|
@@ -40,31 +35,31 @@ small_SSIZE_MAX = unittest.mock.patch('l
|
|
# a very large number of arguments without running out of memory.
|
|
|
|
def test_lone_lcb():
|
|
- with assert_raises(M.Error):
|
|
+ with pytest.raises(M.Error):
|
|
M.FormatString('{')
|
|
|
|
def test_lone_rcb():
|
|
- with assert_raises(M.Error):
|
|
+ with pytest.raises(M.Error):
|
|
M.FormatString('}')
|
|
|
|
def test_invalid_field():
|
|
- with assert_raises(M.Error):
|
|
+ with pytest.raises(M.Error):
|
|
M.FormatString('{@}')
|
|
|
|
def test_add_argument():
|
|
fmt = M.FormatString('{}')
|
|
- with assert_raises(RuntimeError):
|
|
+ with pytest.raises(RuntimeError):
|
|
fmt.add_argument(None, None)
|
|
- with assert_raises(RuntimeError):
|
|
+ with pytest.raises(RuntimeError):
|
|
fmt.add_argument('eggs', None)
|
|
|
|
def test_text():
|
|
fmt = M.FormatString('eggs{}bacon{}spam')
|
|
- assert_equal(len(fmt), 5)
|
|
+ assert len(fmt) == 5
|
|
fmt = list(fmt)
|
|
- assert_equal(fmt[0], 'eggs')
|
|
- assert_equal(fmt[2], 'bacon')
|
|
- assert_equal(fmt[4], 'spam')
|
|
+ assert fmt[0] == 'eggs'
|
|
+ assert fmt[2] == 'bacon'
|
|
+ assert fmt[4] == 'spam'
|
|
|
|
class test_types:
|
|
|
|
@@ -72,12 +67,12 @@ class test_types:
|
|
types = frozenset(tp.__name__ for tp in types)
|
|
fmt = M.FormatString('{:' + k + '}')
|
|
[fld] = fmt
|
|
- assert_is_instance(fld, M.Field)
|
|
- assert_equal(fld.types, types)
|
|
- assert_equal(len(fmt.argument_map), 1)
|
|
+ assert isinstance(fld, M.Field)
|
|
+ assert fld.types == types
|
|
+ assert len(fmt.argument_map) == 1
|
|
[(key, [afld])] = fmt.argument_map.items()
|
|
- assert_equal(key, 0)
|
|
- assert_is(fld, afld)
|
|
+ assert key == 0
|
|
+ assert fld is afld
|
|
|
|
def test_default(self):
|
|
self.t('', int, float, str)
|
|
@@ -102,12 +97,12 @@ class test_conversion:
|
|
types = frozenset(tp.__name__ for tp in types)
|
|
fmt = M.FormatString('{!' + c + ':' + k + '}')
|
|
[fld] = fmt
|
|
- assert_is_instance(fld, M.Field)
|
|
- assert_equal(fld.types, types)
|
|
- assert_equal(len(fmt.argument_map), 1)
|
|
+ assert isinstance(fld, M.Field)
|
|
+ assert fld.types == types
|
|
+ assert len(fmt.argument_map) == 1
|
|
[(key, [afld])] = fmt.argument_map.items()
|
|
- assert_equal(key, 0)
|
|
- assert_is(fld, afld)
|
|
+ assert key == 0
|
|
+ assert fld is afld
|
|
|
|
def test_default(self):
|
|
for c in 'sra':
|
|
@@ -120,11 +115,11 @@ class test_conversion:
|
|
def test_numeric(self):
|
|
for c in 'sra':
|
|
for k in 'bcdoxXneEfFgG':
|
|
- with assert_raises(M.FormatTypeMismatch):
|
|
+ with pytest.raises(M.FormatTypeMismatch):
|
|
self.t(c, k, int)
|
|
|
|
def test_bad(self):
|
|
- with assert_raises(M.ConversionError):
|
|
+ with pytest.raises(M.ConversionError):
|
|
self.t('z', '')
|
|
|
|
class test_numbered_arguments:
|
|
@@ -134,12 +129,12 @@ class test_numbered_arguments:
|
|
|
|
def t(self, s, *types):
|
|
fmt = M.FormatString(s)
|
|
- assert_equal(len(fmt), len(types))
|
|
- assert_equal(len(fmt.argument_map), len(types))
|
|
+ assert len(fmt) == len(types)
|
|
+ assert len(fmt.argument_map) == len(types)
|
|
for (key, args), (xkey, xtype) in zip(sorted(fmt.argument_map.items()), enumerate(types)):
|
|
[arg] = args
|
|
- assert_equal(key, xkey)
|
|
- assert_equal(arg.types, frozenset({xtype.__name__}))
|
|
+ assert key == xkey
|
|
+ assert arg.types == frozenset({xtype.__name__})
|
|
|
|
def test_unnumbered(self):
|
|
self.t('{:d}{:f}', int, float)
|
|
@@ -151,9 +146,9 @@ class test_numbered_arguments:
|
|
self.t('{1:d}{0:f}', float, int)
|
|
|
|
def test_mixed(self):
|
|
- with assert_raises(M.ArgumentNumberingMixture):
|
|
+ with pytest.raises(M.ArgumentNumberingMixture):
|
|
self.t('{0:d}{:f}')
|
|
- with assert_raises(M.ArgumentNumberingMixture):
|
|
+ with pytest.raises(M.ArgumentNumberingMixture):
|
|
self.t('{:d}{0:f}')
|
|
|
|
def test_numbered_out_of_range(self):
|
|
@@ -161,7 +156,7 @@ class test_numbered_arguments:
|
|
s = ('{' + str(i) + '}')
|
|
M.FormatString(s)
|
|
t(M.SSIZE_MAX)
|
|
- with assert_raises(M.ArgumentRangeError):
|
|
+ with pytest.raises(M.ArgumentRangeError):
|
|
t(M.SSIZE_MAX + 1)
|
|
|
|
@small_SSIZE_MAX
|
|
@@ -170,7 +165,7 @@ class test_numbered_arguments:
|
|
s = '{}' * i
|
|
M.FormatString(s)
|
|
t(M.SSIZE_MAX + 1)
|
|
- with assert_raises(M.ArgumentRangeError):
|
|
+ with pytest.raises(M.ArgumentRangeError):
|
|
t(M.SSIZE_MAX + 2)
|
|
|
|
class test_named_arguments:
|
|
@@ -179,21 +174,21 @@ class test_named_arguments:
|
|
fmt = M.FormatString('{spam}')
|
|
[fld] = fmt
|
|
[(aname, [afld])] = fmt.argument_map.items()
|
|
- assert_equal(aname, 'spam')
|
|
- assert_is(fld, afld)
|
|
+ assert aname == 'spam'
|
|
+ assert fld is afld
|
|
|
|
def test_bad(self):
|
|
- with assert_raises(M.Error):
|
|
+ with pytest.raises(M.Error):
|
|
M.FormatString('{3ggs}')
|
|
|
|
class test_format_spec:
|
|
|
|
def test_bad_char(self):
|
|
- with assert_raises(M.Error):
|
|
+ with pytest.raises(M.Error):
|
|
M.FormatString('{:@}')
|
|
|
|
def test_bad_letter(self):
|
|
- with assert_raises(M.Error):
|
|
+ with pytest.raises(M.Error):
|
|
M.FormatString('{:Z}')
|
|
|
|
def test_comma(self):
|
|
@@ -203,7 +198,7 @@ class test_format_spec:
|
|
for k in 'bcdoxXeEfFgG':
|
|
t(k)
|
|
for k in 'ns':
|
|
- with assert_raises(M.Error):
|
|
+ with pytest.raises(M.Error):
|
|
t(k)
|
|
|
|
def test_alt_sign(self):
|
|
@@ -213,7 +208,7 @@ class test_format_spec:
|
|
t(c, '')
|
|
for k in 'bcdoxXneEfFgG':
|
|
t(c, k)
|
|
- with assert_raises(M.Error):
|
|
+ with pytest.raises(M.Error):
|
|
t(c, 's')
|
|
|
|
def test_align(self):
|
|
@@ -228,7 +223,7 @@ class test_format_spec:
|
|
t(c, '')
|
|
for k in 'bcdoxXneEfFgG':
|
|
t(c, k)
|
|
- with assert_raises(M.Error):
|
|
+ with pytest.raises(M.Error):
|
|
t(c, 's')
|
|
|
|
def test_width(self):
|
|
@@ -239,7 +234,7 @@ class test_format_spec:
|
|
for k in 'bcdoxXneEfFgGs\0':
|
|
for i in 4, 37, M.SSIZE_MAX:
|
|
t(i, k)
|
|
- with assert_raises(M.Error):
|
|
+ with pytest.raises(M.Error):
|
|
t(M.SSIZE_MAX + 1, k)
|
|
|
|
def test_precision(self):
|
|
@@ -250,11 +245,11 @@ class test_format_spec:
|
|
for k in 'neEfFgGs\0':
|
|
for i in {4, 37, M.SSIZE_MAX}:
|
|
t(i, k)
|
|
- with assert_raises(M.Error):
|
|
+ with pytest.raises(M.Error):
|
|
t(M.SSIZE_MAX + 1, k)
|
|
for k in 'bcdoxX':
|
|
for i in {4, 37, M.SSIZE_MAX, M.SSIZE_MAX + 1}:
|
|
- with assert_raises(M.Error):
|
|
+ with pytest.raises(M.Error):
|
|
t(i, k)
|
|
|
|
def test_type_compat(self):
|
|
@@ -262,7 +257,7 @@ class test_format_spec:
|
|
s = '{0:' + k1 + '}{0:' + k2 + '}'
|
|
M.FormatString(s)
|
|
def e(k1, k2):
|
|
- with assert_raises(M.ArgumentTypeMismatch):
|
|
+ with pytest.raises(M.ArgumentTypeMismatch):
|
|
t(k1, k2)
|
|
ks = 'bcdoxXneEfFgGs'
|
|
compat = [
|
|
@@ -291,13 +286,13 @@ class test_format_spec:
|
|
s = '{' + str(v) + ':{' + str(f) + '}}'
|
|
return M.FormatString(s)
|
|
fmt = t()
|
|
- assert_equal(len(fmt.argument_map), 2)
|
|
+ assert len(fmt.argument_map) == 2
|
|
t(v=0, f=M.SSIZE_MAX)
|
|
- with assert_raises(M.ArgumentRangeError):
|
|
+ with pytest.raises(M.ArgumentRangeError):
|
|
t(v=0, f=(M.SSIZE_MAX + 1))
|
|
- with assert_raises(M.ArgumentNumberingMixture):
|
|
+ with pytest.raises(M.ArgumentNumberingMixture):
|
|
t(v=0)
|
|
- with assert_raises(M.ArgumentNumberingMixture):
|
|
+ with pytest.raises(M.ArgumentNumberingMixture):
|
|
t(f=0)
|
|
|
|
# vim:ts=4 sts=4 sw=4 et
|
|
Index: i18nspector-0.26/tests/test_strformat_python.py
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/tests/test_strformat_python.py
|
|
+++ i18nspector-0.26/tests/test_strformat_python.py
|
|
@@ -20,53 +20,55 @@
|
|
|
|
import struct
|
|
|
|
-from nose.tools import (
|
|
- assert_equal,
|
|
- assert_greater,
|
|
- assert_is_instance,
|
|
- assert_raises,
|
|
- assert_sequence_equal,
|
|
-)
|
|
+import pytest
|
|
|
|
import lib.strformat.python as M
|
|
+from . import tools
|
|
+
|
|
+
|
|
+# methods using the tools.collect_yielded decorator don't have a 'self'
|
|
+# since they end up being run before 'self' exists. pylint doesn't
|
|
+# understand this unusual situation
|
|
+# pylint: disable=no-method-argument
|
|
+
|
|
|
|
def test_SSIZE_MAX():
|
|
struct.pack('=i', M.SSIZE_MAX)
|
|
- with assert_raises(struct.error):
|
|
+ with pytest.raises(struct.error):
|
|
struct.pack('=i', M.SSIZE_MAX + 1)
|
|
|
|
def test_lone_percent():
|
|
- with assert_raises(M.Error):
|
|
+ with pytest.raises(M.Error):
|
|
M.FormatString('%')
|
|
|
|
def test_invalid_conversion_spec():
|
|
- with assert_raises(M.Error):
|
|
+ with pytest.raises(M.Error):
|
|
M.FormatString('%!')
|
|
|
|
def test_add_argument():
|
|
fmt = M.FormatString('%s')
|
|
- with assert_raises(RuntimeError):
|
|
+ with pytest.raises(RuntimeError):
|
|
fmt.add_argument(None, None)
|
|
- with assert_raises(RuntimeError):
|
|
+ with pytest.raises(RuntimeError):
|
|
fmt.add_argument('eggs', None)
|
|
|
|
def test_text():
|
|
fmt = M.FormatString('eggs%dbacon%dspam')
|
|
- assert_equal(len(fmt), 5)
|
|
+ assert len(fmt) == 5
|
|
fmt = list(fmt)
|
|
- assert_equal(fmt[0], 'eggs')
|
|
- assert_equal(fmt[2], 'bacon')
|
|
- assert_equal(fmt[4], 'spam')
|
|
+ assert fmt[0] == 'eggs'
|
|
+ assert fmt[2] == 'bacon'
|
|
+ assert fmt[4] == 'spam'
|
|
|
|
class test_map:
|
|
|
|
def t(self, key):
|
|
s = '%(' + key + ')s'
|
|
fmt = M.FormatString(s)
|
|
- assert_equal(len(fmt), 1)
|
|
- assert_sequence_equal(fmt.seq_arguments, [])
|
|
+ assert len(fmt) == 1
|
|
+ assert fmt.seq_arguments == []
|
|
[pkey] = fmt.map_arguments.keys()
|
|
- assert_equal(key, pkey)
|
|
+ assert key == pkey
|
|
|
|
def test_simple(self):
|
|
self.t('eggs')
|
|
@@ -75,69 +77,82 @@ class test_map:
|
|
self.t('eggs(ham)spam')
|
|
|
|
def test_unbalanced_parens(self):
|
|
- with assert_raises(M.Error):
|
|
+ with pytest.raises(M.Error):
|
|
self.t('eggs(ham')
|
|
|
|
class test_types:
|
|
|
|
- def t(self, s, tp, warn_type=None):
|
|
+ @staticmethod
|
|
+ def t( s, tp, warn_type=None):
|
|
fmt = M.FormatString(s)
|
|
[conv] = fmt
|
|
- assert_is_instance(conv, M.Conversion)
|
|
- assert_equal(conv.type, tp)
|
|
- assert_equal(len(fmt.map_arguments), 0)
|
|
+ assert isinstance(conv, M.Conversion)
|
|
+ assert conv.type == tp
|
|
+ assert len(fmt.map_arguments) == 0
|
|
if tp == 'None':
|
|
- assert_sequence_equal(fmt.seq_arguments, [])
|
|
+ assert fmt.seq_arguments == []
|
|
else:
|
|
[arg] = fmt.seq_arguments
|
|
- assert_equal(arg.type, tp)
|
|
+ assert arg.type == tp
|
|
if warn_type is None:
|
|
- assert_equal(len(fmt.warnings), 0)
|
|
+ assert len(fmt.warnings) == 0
|
|
else:
|
|
[warning] = fmt.warnings
|
|
- assert_is_instance(warning, warn_type)
|
|
+ assert isinstance(warning, warn_type)
|
|
|
|
- def test_integer(self):
|
|
- t = self.t
|
|
+ @tools.collect_yielded
|
|
+ def test_integer():
|
|
+ def t(*args):
|
|
+ test_types.t(*args)
|
|
for c in 'oxXdi':
|
|
- yield t, '%' + c, 'int'
|
|
- yield t, '%u', 'int', M.ObsoleteConversion
|
|
+ yield t, ('%' + c, 'int')
|
|
+ yield t, ('%u', 'int', M.ObsoleteConversion)
|
|
|
|
- def test_float(self):
|
|
- t = self.t
|
|
+ @tools.collect_yielded
|
|
+ def test_float():
|
|
+ def t(*args):
|
|
+ test_types.t(*args)
|
|
for c in 'eEfFgG':
|
|
- yield t, '%' + c, 'float'
|
|
-
|
|
- def test_str(self):
|
|
- t = self.t
|
|
- yield t, '%c', 'chr'
|
|
- yield t, '%s', 'str'
|
|
+ yield t, ('%' + c, 'float')
|
|
|
|
- def test_repr(self):
|
|
- t = self.t
|
|
+ @tools.collect_yielded
|
|
+ def test_str():
|
|
+ def t(*args):
|
|
+ test_types.t(*args)
|
|
+ yield t, ('%c', 'chr')
|
|
+ yield t, ('%s', 'str')
|
|
+
|
|
+ @tools.collect_yielded
|
|
+ def test_repr():
|
|
+ def t(*args):
|
|
+ test_types.t(*args)
|
|
for c in 'ra':
|
|
- yield t, '%' + c, 'object'
|
|
+ yield t, ('%' + c, 'object')
|
|
|
|
- def test_void(self):
|
|
- yield self.t, '%%', 'None'
|
|
+ @tools.collect_yielded
|
|
+ def test_void():
|
|
+ def t(*args):
|
|
+ test_types.t(*args)
|
|
+ yield t, ('%%', 'None')
|
|
|
|
+@tools.collect_yielded
|
|
def test_length():
|
|
def t(l):
|
|
fmt = M.FormatString('%' + l + 'd')
|
|
[warning] = fmt.warnings
|
|
- assert_is_instance(warning, M.RedundantLength)
|
|
+ assert isinstance(warning, M.RedundantLength)
|
|
for l in 'hlL':
|
|
yield t, l
|
|
|
|
class test_indexing:
|
|
|
|
def test_percent(self):
|
|
- with assert_raises(M.ForbiddenArgumentKey):
|
|
+ with pytest.raises(M.ForbiddenArgumentKey):
|
|
M.FormatString('%(eggs)%')
|
|
|
|
def test_indexing_mixture(self):
|
|
def t(s):
|
|
- with assert_raises(M.ArgumentIndexingMixture):
|
|
+ with pytest.raises(M.ArgumentIndexingMixture):
|
|
M.FormatString(s)
|
|
t('%s%(eggs)s')
|
|
t('%(eggs)s%s')
|
|
@@ -149,7 +164,7 @@ class test_multiple_flags:
|
|
def t(self, s):
|
|
fmt = M.FormatString(s)
|
|
[exc] = fmt.warnings
|
|
- assert_is_instance(exc, M.RedundantFlag)
|
|
+ assert isinstance(exc, M.RedundantFlag)
|
|
|
|
def test_duplicate(self):
|
|
self.t('%--17d')
|
|
@@ -160,108 +175,114 @@ class test_multiple_flags:
|
|
def test_plus_space(self):
|
|
self.t('%+ d')
|
|
|
|
+@tools.collect_yielded
|
|
def test_single_flag():
|
|
|
|
def t(s, expected):
|
|
fmt = M.FormatString(s)
|
|
- assert_equal(len(fmt), 1)
|
|
+ assert len(fmt) == 1
|
|
if expected:
|
|
- assert_sequence_equal(fmt.warnings, [])
|
|
+ assert fmt.warnings == []
|
|
else:
|
|
[exc] = fmt.warnings
|
|
- assert_is_instance(exc, M.RedundantFlag)
|
|
+ assert isinstance(exc, M.RedundantFlag)
|
|
|
|
for c in 'dioxXeEfFgGcrsa%':
|
|
- yield t, ('%#' + c), (c in 'oxXeEfFgG')
|
|
+ yield t, (('%#' + c), (c in 'oxXeEfFgG'))
|
|
for flag in '0 +':
|
|
- yield t, ('%' + flag + c), (c in 'dioxXeEfFgG')
|
|
- yield t, ('%-' + c), True
|
|
+ yield t, (('%' + flag + c), (c in 'dioxXeEfFgG'))
|
|
+ yield t, (('%-' + c), True)
|
|
|
|
class test_width:
|
|
|
|
- def test_ok(self):
|
|
+ @tools.collect_yielded
|
|
+ def test_ok():
|
|
def t(s):
|
|
fmt = M.FormatString(s)
|
|
- assert_equal(len(fmt), 1)
|
|
- assert_sequence_equal(fmt.warnings, [])
|
|
+ assert len(fmt) == 1
|
|
+ assert fmt.warnings == []
|
|
for c in 'dioxXeEfFgGcrsa%':
|
|
yield t, ('%1' + c)
|
|
|
|
def test_too_large(self):
|
|
fmt = M.FormatString('%{0}d'.format(M.SSIZE_MAX))
|
|
- assert_equal(len(fmt), 1)
|
|
- assert_equal(len(fmt.seq_arguments), 1)
|
|
- assert_equal(len(fmt.map_arguments), 0)
|
|
- with assert_raises(M.WidthRangeError):
|
|
+ assert len(fmt) == 1
|
|
+ assert len(fmt.seq_arguments) == 1
|
|
+ assert len(fmt.map_arguments) == 0
|
|
+ with pytest.raises(M.WidthRangeError):
|
|
M.FormatString('%{0}d'.format(M.SSIZE_MAX + 1))
|
|
|
|
def test_variable(self):
|
|
fmt = M.FormatString('%*s')
|
|
- assert_equal(len(fmt), 1)
|
|
- assert_equal(len(fmt.map_arguments), 0)
|
|
+ assert len(fmt) == 1
|
|
+ assert len(fmt.map_arguments) == 0
|
|
[a1, a2] = fmt.seq_arguments
|
|
- assert_equal(a1.type, 'int')
|
|
- assert_equal(a2.type, 'str')
|
|
+ assert a1.type == 'int'
|
|
+ assert a2.type == 'str'
|
|
|
|
def test_indexing_mixture(self):
|
|
def t(s):
|
|
- with assert_raises(M.ArgumentIndexingMixture):
|
|
+ with pytest.raises(M.ArgumentIndexingMixture):
|
|
M.FormatString(s)
|
|
t('%*s%(eggs)s')
|
|
t('%(eggs)s%*s')
|
|
|
|
class test_precision:
|
|
|
|
- def test_ok(self):
|
|
+ @tools.collect_yielded
|
|
+ def test_ok():
|
|
def t(s):
|
|
fmt = M.FormatString(s)
|
|
- assert_equal(len(fmt), 1)
|
|
+ assert len(fmt) == 1
|
|
for c in 'dioxXeEfFgGrsa':
|
|
yield t, ('%.1' + c)
|
|
|
|
- def test_redundant_0(self):
|
|
+ @tools.collect_yielded
|
|
+ def test_redundant_0():
|
|
def t(s):
|
|
fmt = M.FormatString(s)
|
|
- assert_equal(len(fmt), 1)
|
|
+ assert len(fmt) == 1
|
|
[warning] = fmt.warnings
|
|
- assert_is_instance(warning, M.RedundantFlag)
|
|
+ assert isinstance(warning, M.RedundantFlag)
|
|
for c in 'dioxX':
|
|
yield t, ('%0.1' + c)
|
|
|
|
- def test_non_redundant_0(self):
|
|
+ @tools.collect_yielded
|
|
+ def test_non_redundant_0():
|
|
def t(s):
|
|
fmt = M.FormatString(s)
|
|
- assert_equal(len(fmt), 1)
|
|
- assert_sequence_equal(fmt.warnings, [])
|
|
+ assert len(fmt) == 1
|
|
+ assert fmt.warnings == []
|
|
for c in 'eEfFgG':
|
|
yield t, ('%0.1' + c)
|
|
|
|
- def test_unexpected(self):
|
|
+ @tools.collect_yielded
|
|
+ def test_unexpected():
|
|
def t(s):
|
|
fmt = M.FormatString(s)
|
|
- assert_equal(len(fmt), 1)
|
|
+ assert len(fmt) == 1
|
|
[warning] = fmt.warnings
|
|
- assert_is_instance(warning, M.RedundantPrecision)
|
|
+ assert isinstance(warning, M.RedundantPrecision)
|
|
for c in 'c%':
|
|
yield t, ('%.1' + c)
|
|
|
|
def test_too_large(self):
|
|
fmt = M.FormatString('%.{0}f'.format(M.SSIZE_MAX))
|
|
- assert_equal(len(fmt), 1)
|
|
- with assert_raises(M.PrecisionRangeError):
|
|
+ assert len(fmt) == 1
|
|
+ with pytest.raises(M.PrecisionRangeError):
|
|
M.FormatString('%.{0}f'.format(M.SSIZE_MAX + 1))
|
|
|
|
def test_variable(self):
|
|
fmt = M.FormatString('%.*f')
|
|
- assert_equal(len(fmt), 1)
|
|
- assert_equal(len(fmt.map_arguments), 0)
|
|
+ assert len(fmt) == 1
|
|
+ assert len(fmt.map_arguments) == 0
|
|
[a1, a2] = fmt.seq_arguments
|
|
- assert_equal(a1.type, 'int')
|
|
- assert_equal(a2.type, 'float')
|
|
+ assert a1.type == 'int'
|
|
+ assert a2.type == 'float'
|
|
|
|
def test_indexing_mixture(self):
|
|
def t(s):
|
|
- with assert_raises(M.ArgumentIndexingMixture):
|
|
+ with pytest.raises(M.ArgumentIndexingMixture):
|
|
M.FormatString(s)
|
|
t('%.*f%(eggs)f')
|
|
t('%(eggs)f%.*f')
|
|
@@ -271,26 +292,26 @@ class test_type_compatibility:
|
|
def test_okay(self):
|
|
def t(s, tp):
|
|
fmt = M.FormatString(s)
|
|
- assert_equal(len(fmt.seq_arguments), 0)
|
|
+ assert len(fmt.seq_arguments) == 0
|
|
[args] = fmt.map_arguments.values()
|
|
- assert_greater(len(args), 1)
|
|
+ assert len(args) > 1
|
|
for arg in args:
|
|
- assert_equal(arg.type, tp)
|
|
+ assert arg.type == tp
|
|
t('%(eggs)d%(eggs)d', 'int')
|
|
t('%(eggs)d%(eggs)i', 'int')
|
|
|
|
def test_mismatch(self):
|
|
def t(s):
|
|
- with assert_raises(M.ArgumentTypeMismatch):
|
|
+ with pytest.raises(M.ArgumentTypeMismatch):
|
|
M.FormatString(s)
|
|
t('%(eggs)d%(eggs)s')
|
|
|
|
def test_seq_conversions():
|
|
def t(s, n):
|
|
fmt = M.FormatString(s)
|
|
- assert_equal(len(fmt.seq_conversions), n)
|
|
+ assert len(fmt.seq_conversions) == n
|
|
for arg in fmt.seq_conversions:
|
|
- assert_is_instance(arg, M.Conversion)
|
|
+ assert isinstance(arg, M.Conversion)
|
|
t('%d', 1)
|
|
t('%d%d', 2)
|
|
t('eggs%dham', 1)
|
|
Index: i18nspector-0.26/tests/test_tags.py
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/tests/test_tags.py
|
|
+++ i18nspector-0.26/tests/test_tags.py
|
|
@@ -24,26 +24,20 @@ import inspect
|
|
import operator
|
|
import pkgutil
|
|
|
|
-from nose.tools import (
|
|
- assert_equal,
|
|
- assert_false,
|
|
- assert_is_instance,
|
|
- assert_raises,
|
|
- assert_true,
|
|
-)
|
|
+import pytest
|
|
|
|
import lib.check
|
|
import lib.tags as M
|
|
+from . import tools
|
|
|
|
class test_escape:
|
|
|
|
def t(self, s, expected):
|
|
result = M.safe_format('{}', s)
|
|
- assert_is_instance(result, M.safestr)
|
|
- assert_equal(
|
|
- result,
|
|
- expected
|
|
- )
|
|
+ assert isinstance(result, M.safestr)
|
|
+ assert (
|
|
+ result ==
|
|
+ expected)
|
|
|
|
def test_safe(self):
|
|
s = 'fox'
|
|
@@ -75,6 +69,7 @@ def ast_to_tagnames(node):
|
|
if ok:
|
|
yield node.args[0].s
|
|
|
|
+@tools.collect_yielded
|
|
def test_consistency():
|
|
source_tagnames = set()
|
|
def visit_mod(modname):
|
|
@@ -117,13 +112,13 @@ class test_enums:
|
|
for op in operators:
|
|
for i, x in enumerate(keys):
|
|
for j, y in enumerate(keys):
|
|
- assert_equal(op(x, y), op(i, j))
|
|
+ assert op(x, y) == op(i, j)
|
|
if op is operator.eq:
|
|
- assert_false(op(x, j))
|
|
+ assert not op(x, j)
|
|
elif op is operator.ne:
|
|
- assert_true(op(x, j))
|
|
+ assert op(x, j)
|
|
else:
|
|
- with assert_raises(TypeError):
|
|
+ with pytest.raises(TypeError):
|
|
op(x, j)
|
|
|
|
def test_severities(self):
|
|
Index: i18nspector-0.26/tests/test_terminal.py
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/tests/test_terminal.py
|
|
+++ i18nspector-0.26/tests/test_terminal.py
|
|
@@ -23,17 +23,13 @@ import os
|
|
import pty
|
|
import sys
|
|
|
|
-from nose.tools import (
|
|
- assert_equal,
|
|
-)
|
|
-
|
|
import lib.terminal as T
|
|
|
|
from . import tools
|
|
|
|
def test_strip_delay():
|
|
def t(s, r=b''):
|
|
- assert_equal(T._strip_delay(s), r) # pylint: disable=protected-access
|
|
+ assert T._strip_delay(s) == r # pylint: disable=protected-access
|
|
t(b'$<1>')
|
|
t(b'$<2/>')
|
|
t(b'$<3*>')
|
|
@@ -56,7 +52,7 @@ def assert_tseq_equal(s, expected):
|
|
# but not their subclasses. We don't want detailed comparisons,
|
|
# because diff could contain control characters.
|
|
pass
|
|
- assert_equal(S(expected), S(s))
|
|
+ assert S(expected) == S(s)
|
|
|
|
def test_dummy():
|
|
t = assert_tseq_equal
|
|
Index: i18nspector-0.26/tests/test_version.py
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/tests/test_version.py
|
|
+++ i18nspector-0.26/tests/test_version.py
|
|
@@ -20,10 +20,6 @@
|
|
|
|
import os
|
|
|
|
-from nose.tools import (
|
|
- assert_equal,
|
|
-)
|
|
-
|
|
from lib.cli import __version__
|
|
|
|
here = os.path.dirname(__file__)
|
|
@@ -34,7 +30,7 @@ def test_changelog():
|
|
with open(path, 'rt', encoding='UTF-8') as file:
|
|
line = file.readline()
|
|
changelog_version = line.split()[1].strip('()')
|
|
- assert_equal(changelog_version, __version__)
|
|
+ assert changelog_version == __version__
|
|
|
|
def test_manpage():
|
|
path = os.path.join(docdir, 'manpage.rst')
|
|
@@ -44,6 +40,6 @@ def test_manpage():
|
|
if line.startswith(':version:'):
|
|
manpage_version = line.split()[-1]
|
|
break
|
|
- assert_equal(manpage_version, __version__)
|
|
+ assert manpage_version == __version__
|
|
|
|
# vim:ts=4 sts=4 sw=4 et
|
|
Index: i18nspector-0.26/tests/test_xml.py
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/tests/test_xml.py
|
|
+++ i18nspector-0.26/tests/test_xml.py
|
|
@@ -21,11 +21,7 @@
|
|
import re
|
|
import xml.etree.ElementTree as etree
|
|
|
|
-from nose.tools import (
|
|
- assert_is_none,
|
|
- assert_is_not_none,
|
|
- assert_raises,
|
|
-)
|
|
+import pytest
|
|
|
|
import lib.xml as M
|
|
|
|
@@ -44,7 +40,7 @@ class test_well_formed:
|
|
class test_malformed:
|
|
|
|
def t(self, s):
|
|
- with assert_raises(M.SyntaxError):
|
|
+ with pytest.raises(M.SyntaxError):
|
|
M.check_fragment(s)
|
|
|
|
def test_non_xml_character(self):
|
|
@@ -73,7 +69,7 @@ class test_name_re():
|
|
def test_good(self):
|
|
def t(s):
|
|
match = self.regexp.match(s)
|
|
- assert_is_not_none(match)
|
|
+ assert match is not None
|
|
t(':')
|
|
t('_')
|
|
t('e')
|
|
@@ -85,7 +81,7 @@ class test_name_re():
|
|
def test_bad(self):
|
|
def t(s):
|
|
match = self.regexp.match(s)
|
|
- assert_is_none(match)
|
|
+ assert match is None
|
|
t('')
|
|
t('0')
|
|
t('-')
|
|
Index: i18nspector-0.26/tests/tools.py
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/tests/tools.py
|
|
+++ i18nspector-0.26/tests/tools.py
|
|
@@ -1,4 +1,5 @@
|
|
# Copyright © 2012-2019 Jakub Wilk <jwilk@jwilk.net>
|
|
+# Copyright © 2021 Stuart Prescott <stuart@debian.org>
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
# of this software and associated documentation files (the “Software”), to deal
|
|
@@ -23,8 +24,9 @@ import os
|
|
import sys
|
|
import tempfile
|
|
import traceback
|
|
+import unittest
|
|
|
|
-import nose
|
|
+import pytest
|
|
|
|
temporary_file = functools.partial(
|
|
tempfile.NamedTemporaryFile,
|
|
@@ -52,8 +54,8 @@ def fork_isolation(f):
|
|
EXIT_SKIP_TEST = 102
|
|
|
|
exit = os._exit # pylint: disable=redefined-builtin,protected-access
|
|
- # sys.exit() can't be used here, because nose catches all exceptions,
|
|
- # including SystemExit
|
|
+ # sys.exit() can't be used here, because the test harness catches all
|
|
+ # exceptions, including SystemExit
|
|
|
|
# pylint:disable=consider-using-sys-exit
|
|
|
|
@@ -66,7 +68,7 @@ def fork_isolation(f):
|
|
os.close(readfd)
|
|
try:
|
|
f(*args, **kwargs)
|
|
- except nose.SkipTest as exc:
|
|
+ except unittest.SkipTest as exc:
|
|
s = str(exc).encode('UTF-8')
|
|
with os.fdopen(writefd, 'wb') as fp:
|
|
fp.write(s)
|
|
@@ -90,7 +92,7 @@ def fork_isolation(f):
|
|
if status == (EXIT_EXCEPTION << 8):
|
|
raise IsolatedException() from Exception('\n\n' + msg)
|
|
elif status == (EXIT_SKIP_TEST << 8):
|
|
- raise nose.SkipTest(msg)
|
|
+ raise unittest.SkipTest(msg)
|
|
elif status == 0 and msg == '':
|
|
pass
|
|
else:
|
|
@@ -100,6 +102,37 @@ def fork_isolation(f):
|
|
|
|
return wrapper
|
|
|
|
+
|
|
+def collect_yielded(collect_func):
|
|
+ # figure out if this is a function or method being wrapped
|
|
+ # as the wrapper needs a slightly different signature
|
|
+ if collect_func.__name__ != collect_func.__qualname__:
|
|
+ # method
|
|
+ @pytest.mark.parametrize("func, test_args",
|
|
+ list(collect_func()))
|
|
+ def yield_tester(self, func, test_args):
|
|
+ # pylint: disable=unused-argument
|
|
+ # self is unused here
|
|
+ if isinstance(test_args, (tuple, list)):
|
|
+ func(*test_args)
|
|
+ elif isinstance(test_args, (str, int, float)):
|
|
+ func(test_args)
|
|
+ else:
|
|
+ raise ValueError("args must be either a tuple or a str")
|
|
+ else:
|
|
+ # function
|
|
+ @pytest.mark.parametrize("func, test_args",
|
|
+ list(collect_func()))
|
|
+ def yield_tester(func, test_args):
|
|
+ if isinstance(test_args, (tuple, list)):
|
|
+ func(*test_args)
|
|
+ elif isinstance(test_args, (str, int, float)):
|
|
+ func(test_args)
|
|
+ else:
|
|
+ raise ValueError("args must be either a tuple or a str")
|
|
+ return yield_tester
|
|
+
|
|
+
|
|
basedir = os.path.join(
|
|
os.path.dirname(__file__),
|
|
os.pardir,
|
|
Index: i18nspector-0.26/.coveragerc
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/.coveragerc
|
|
+++ i18nspector-0.26/.coveragerc
|
|
@@ -1,5 +1,11 @@
|
|
[run]
|
|
branch = true
|
|
+omit =
|
|
+ *_boot*.py
|
|
+ */lib/python*/*
|
|
+ */dist-packages/*
|
|
+ */tests/*
|
|
+source = lib
|
|
|
|
[report]
|
|
show_missing = true
|
|
Index: i18nspector-0.26/private/update-branch-coverage
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/private/update-branch-coverage
|
|
+++ i18nspector-0.26/private/update-branch-coverage
|
|
@@ -1,6 +1,6 @@
|
|
-#!/usr/bin/env python3
|
|
+#!/bin/bash
|
|
|
|
-# Copyright © 2014-2018 Jakub Wilk <jwilk@jwilk.net>
|
|
+# Copyright © 2021 Stuart Prescott <stuart@debian.org>
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
# of this software and associated documentation files (the “Software”), to deal
|
|
@@ -20,55 +20,22 @@
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
# SOFTWARE.
|
|
|
|
-import glob
|
|
-import io
|
|
-import os
|
|
-import sys
|
|
-
|
|
-import nose
|
|
-import nose.plugins.cover
|
|
-
|
|
-class Coverage(nose.plugins.cover.Coverage):
|
|
-
|
|
- stream = None
|
|
-
|
|
- def report(self, stream):
|
|
- return super().report(self.stream)
|
|
-
|
|
-basedir = os.path.join(
|
|
- os.path.dirname(__file__),
|
|
- os.pardir,
|
|
-)
|
|
-
|
|
-def main():
|
|
- os.chdir(basedir)
|
|
- module_glob = os.path.join('tests', 'test_*.py')
|
|
- modules = glob.glob(module_glob)
|
|
- argv = [
|
|
- sys.argv[0],
|
|
- '--with-coverage',
|
|
- '--cover-package=lib',
|
|
- '--cover-erase',
|
|
- ] + modules
|
|
- path = os.path.join(
|
|
- 'tests',
|
|
- 'coverage'
|
|
- )
|
|
- plugin = Coverage()
|
|
- report_stream = plugin.stream = io.StringIO()
|
|
- print('Generated automatically by private/update-branch-coverage. '
|
|
- 'Do not edit.\n', file=report_stream)
|
|
- ok = nose.run(argv=argv, plugins=[plugin])
|
|
- if not ok:
|
|
- sys.exit(1)
|
|
- report_stream.seek(0)
|
|
- with open(path + '.tmp', 'wt', encoding='ASCII') as file:
|
|
- for line in report_stream:
|
|
- line = line.rstrip()
|
|
- print(line, file=file)
|
|
- os.rename(path + '.tmp', path)
|
|
|
|
-if __name__ == '__main__':
|
|
- main()
|
|
+set -e
|
|
+
|
|
+basedir=$(dirname "$0")
|
|
+
|
|
+cd "$basedir/.."
|
|
+
|
|
+pytest --cov lib/ --cov-branch -rsx -v tests --ignore tests/blackbox_tests
|
|
+
|
|
+(
|
|
+ set -e
|
|
+ echo 'Generated automatically by private/update-branch-coverage. Do not edit.'
|
|
+ echo
|
|
+ python3-coverage report
|
|
+) > tests/coverage.tmp
|
|
+
|
|
+mv tests/coverage.tmp tests/coverage
|
|
|
|
# vim:ts=4 sts=4 sw=4 et
|
|
Index: i18nspector-0.26/tests/blackbox_tests/__init__.py
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/tests/blackbox_tests/__init__.py
|
|
+++ i18nspector-0.26/tests/blackbox_tests/__init__.py
|
|
@@ -1,415 +0,0 @@
|
|
-# Copyright © 2012-2017 Jakub Wilk <jwilk@jwilk.net>
|
|
-#
|
|
-# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
-# of this software and associated documentation files (the “Software”), to deal
|
|
-# in the Software without restriction, including without limitation the rights
|
|
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
-# copies of the Software, and to permit persons to whom the Software is
|
|
-# furnished to do so, subject to the following conditions:
|
|
-#
|
|
-# The above copyright notice and this permission notice shall be included in
|
|
-# all copies or substantial portions of the Software.
|
|
-#
|
|
-# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
-# SOFTWARE.
|
|
-
|
|
-import difflib
|
|
-import inspect
|
|
-import io
|
|
-import multiprocessing as mp
|
|
-import os
|
|
-import re
|
|
-import shlex
|
|
-import signal
|
|
-import subprocess as ipc
|
|
-import sys
|
|
-import traceback
|
|
-import unittest
|
|
-
|
|
-import nose
|
|
-import nose.plugins
|
|
-
|
|
-from .. import tools
|
|
-
|
|
-here = os.path.dirname(__file__)
|
|
-
|
|
-# ----------------------------------------
|
|
-
|
|
-def this():
|
|
- '''
|
|
- Return function that called this function. (Hopefully!)
|
|
- '''
|
|
- return globals()[inspect.stack()[1][0].f_code.co_name]
|
|
-
|
|
-# ----------------------------------------
|
|
-
|
|
-_parse_etag = re.compile(r'([A-Z]): (([\w-]+).*)').match
|
|
-
|
|
-def parse_etag(contents, path):
|
|
- match = _parse_etag(contents)
|
|
- if match is None:
|
|
- return
|
|
- t = ETag(match.group(1), path, match.group(2))
|
|
- return t
|
|
-
|
|
-def etags_from_tagstring(obj, path):
|
|
- try:
|
|
- docstring = obj.tagstring
|
|
- except AttributeError:
|
|
- return
|
|
- for line in docstring.splitlines():
|
|
- line = line.lstrip()
|
|
- t = parse_etag(line, path)
|
|
- if t is not None:
|
|
- yield t
|
|
-
|
|
-def tagstring(s):
|
|
- def update(x):
|
|
- x.tagstring = s
|
|
- return x
|
|
- return update
|
|
-
|
|
-# ----------------------------------------
|
|
-
|
|
-class ETag():
|
|
-
|
|
- _ellipsis = '<...>'
|
|
- _split = re.compile('({})'.format(re.escape(_ellipsis))).split
|
|
-
|
|
- def __init__(self, code, path, rest):
|
|
- self._s = s = '{code}: {path}: {rest}'.format(
|
|
- code=code,
|
|
- path=path,
|
|
- rest=rest,
|
|
- )
|
|
- self.tag = rest.split(None, 1)[0]
|
|
- regexp = ''.join(
|
|
- '.*' if chunk == self._ellipsis else re.escape(chunk)
|
|
- for chunk in self._split(s)
|
|
- )
|
|
- self._regexp = re.compile('^{}$'.format(regexp))
|
|
-
|
|
- def __eq__(self, other):
|
|
- if isinstance(other, str):
|
|
- return self._regexp.match(other)
|
|
- else:
|
|
- return NotImplemented
|
|
-
|
|
- def __str__(self):
|
|
- return self._s
|
|
-
|
|
- def __repr__(self):
|
|
- return repr(self._s)
|
|
-
|
|
-# ----------------------------------------
|
|
-
|
|
-def _get_signal_names():
|
|
- data = dict(
|
|
- (name, getattr(signal, name))
|
|
- for name in dir(signal)
|
|
- if re.compile('^SIG[A-Z0-9]*$').match(name)
|
|
- )
|
|
- try:
|
|
- if data['SIGABRT'] == data['SIGIOT']:
|
|
- del data['SIGIOT']
|
|
- except KeyError:
|
|
- pass
|
|
- try:
|
|
- if data['SIGCHLD'] == data['SIGCLD']:
|
|
- del data['SIGCLD']
|
|
- except KeyError:
|
|
- pass
|
|
- for name, n in data.items():
|
|
- yield n, name
|
|
-
|
|
-_signal_names = dict(_get_signal_names())
|
|
-
|
|
-def get_signal_name(n):
|
|
- try:
|
|
- return _signal_names[n]
|
|
- except KeyError:
|
|
- return str(n)
|
|
-
|
|
-# ----------------------------------------
|
|
-
|
|
-test_file_extensions = ('.mo', '.po', '.pot', '.pop')
|
|
-# .pop is a special extension to trigger unknown-file-type
|
|
-
|
|
-class Plugin(nose.plugins.Plugin):
|
|
-
|
|
- name = 'po-plugin'
|
|
- enabled = True
|
|
-
|
|
- def options(self, parser, env):
|
|
- pass
|
|
-
|
|
- def wantFile(self, path):
|
|
- if path.endswith(test_file_extensions):
|
|
- if path.startswith(os.path.join(os.path.abspath(here), '')):
|
|
- return True
|
|
-
|
|
- def loadTestsFromFile(self, path):
|
|
- if self.wantFile(path):
|
|
- yield TestCase(path)
|
|
-
|
|
- def wantFunction(self, func):
|
|
- if getattr(func, 'redundant', False):
|
|
- return False
|
|
-
|
|
-class TestCase(unittest.TestCase):
|
|
-
|
|
- def __init__(self, path):
|
|
- super().__init__('_test')
|
|
- self.path = os.path.relpath(path)
|
|
-
|
|
- def _test(self):
|
|
- _test_file(self.path, basedir=None)
|
|
-
|
|
- def __str__(self):
|
|
- return self.path
|
|
-
|
|
-class SubprocessError(Exception):
|
|
- pass
|
|
-
|
|
-def queue_get(queue, process):
|
|
- '''
|
|
- Remove and return an item from the queue.
|
|
- Block until the process terminates.
|
|
- '''
|
|
- while True:
|
|
- try:
|
|
- return queue.get(timeout=1)
|
|
- # This semi-active waiting is ugly, but there doesn't seem be any
|
|
- # obvious better way.
|
|
- except mp.queues.Empty:
|
|
- if process.exitcode is None:
|
|
- continue
|
|
- else:
|
|
- raise
|
|
-
|
|
-def run_i18nspector(options, path):
|
|
- commandline = os.environ.get('I18NSPECTOR_COMMANDLINE')
|
|
- if commandline is None:
|
|
- # We cheat here a bit, because exec(3)ing is very expensive.
|
|
- # Let's load the needed Python modules, and use multiprocessing to
|
|
- # “emulate” the command execution.
|
|
- import lib.cli # pylint: disable=import-outside-toplevel
|
|
- assert lib.cli # make pyflakes happy
|
|
- prog = os.path.join(here, os.pardir, os.pardir, 'i18nspector')
|
|
- commandline = [sys.executable, prog]
|
|
- queue = mp.Queue()
|
|
- child = mp.Process(
|
|
- target=_mp_run_i18nspector,
|
|
- args=(prog, options, path, queue)
|
|
- )
|
|
- child.start()
|
|
- [stdout, stderr] = (
|
|
- s.splitlines()
|
|
- for s in queue_get(queue, child)
|
|
- )
|
|
- child.join()
|
|
- rc = child.exitcode
|
|
- else:
|
|
- commandline = shlex.split(commandline)
|
|
- commandline += options
|
|
- commandline += [path]
|
|
- fixed_env = dict(os.environ, PYTHONIOENCODING='UTF-8')
|
|
- child = ipc.Popen(commandline, stdout=ipc.PIPE, stderr=ipc.PIPE, env=fixed_env)
|
|
- stdout, stderr = (
|
|
- s.decode('UTF-8').splitlines()
|
|
- for s in child.communicate()
|
|
- )
|
|
- rc = child.poll()
|
|
- assert isinstance(rc, int)
|
|
- if rc == 0:
|
|
- return stdout
|
|
- if rc < 0:
|
|
- message = ['command was interrupted by signal {sig}'.format(sig=get_signal_name(-rc))] # pylint: disable=invalid-unary-operand-type
|
|
- else:
|
|
- message = ['command exited with status {rc}'.format(rc=rc)]
|
|
- message += ['']
|
|
- if stdout:
|
|
- message += ['stdout:']
|
|
- message += ['| ' + s for s in stdout] + ['']
|
|
- else:
|
|
- message += ['stdout: (empty)']
|
|
- if stderr:
|
|
- message += ['stderr:']
|
|
- message += ['| ' + s for s in stderr]
|
|
- else:
|
|
- message += ['stderr: (empty)']
|
|
- raise SubprocessError('\n'.join(message))
|
|
-
|
|
-def _mp_run_i18nspector(prog, options, path, queue):
|
|
- with open(prog, 'rt', encoding='UTF-8') as file:
|
|
- code = file.read()
|
|
- sys.argv = [prog] + list(options) + [path]
|
|
- orig_stdout = sys.stdout
|
|
- orig_stderr = sys.stderr
|
|
- code = compile(code, prog, 'exec')
|
|
- io_stdout = io.StringIO()
|
|
- io_stderr = io.StringIO()
|
|
- gvars = dict(
|
|
- __file__=prog,
|
|
- )
|
|
- (sys.stdout, sys.stderr) = (io_stdout, io_stderr)
|
|
- try:
|
|
- try:
|
|
- exec(code, gvars) # pylint: disable=exec-used
|
|
- finally:
|
|
- (sys.stdout, sys.stderr) = (orig_stdout, orig_stderr)
|
|
- stdout = io_stdout.getvalue()
|
|
- stderr = io_stderr.getvalue()
|
|
- except SystemExit:
|
|
- queue.put([stdout, stderr])
|
|
- raise
|
|
- except: # pylint: disable=bare-except
|
|
- exctp, exc, tb = sys.exc_info()
|
|
- stderr += ''.join(
|
|
- traceback.format_exception(exctp, exc, tb)
|
|
- )
|
|
- queue.put([stdout, stderr])
|
|
- sys.exit(1)
|
|
- raise # hi, pydiatra!
|
|
- else:
|
|
- queue.put([stdout, stderr])
|
|
- sys.exit(0)
|
|
-
|
|
-def assert_emit_tags(path, etags, *, options=()):
|
|
- etags = list(etags)
|
|
- stdout = run_i18nspector(options, path)
|
|
- expected_failure = os.path.basename(path).startswith('xfail-')
|
|
- if stdout != etags:
|
|
- if expected_failure:
|
|
- raise nose.SkipTest('expected failure')
|
|
- str_etags = [str(x) for x in etags]
|
|
- message = ['Tags differ:', '']
|
|
- diff = list(
|
|
- difflib.unified_diff(str_etags, stdout, n=9999)
|
|
- )
|
|
- message += diff[3:]
|
|
- raise AssertionError('\n'.join(message))
|
|
- elif expected_failure:
|
|
- raise AssertionError('unexpected success')
|
|
-
|
|
-class TestFileSyntaxError(Exception):
|
|
- pass
|
|
-
|
|
-def _parse_test_header_file(file, path, *, comments_only):
|
|
- etags = []
|
|
- options = []
|
|
- for n, line in enumerate(file):
|
|
- orig_line = line
|
|
- if comments_only:
|
|
- if n == 0 and line.startswith('#!'):
|
|
- continue
|
|
- if line.startswith('# '):
|
|
- line = line[2:]
|
|
- else:
|
|
- break
|
|
- if line.startswith('--'):
|
|
- options += shlex.split(line)
|
|
- else:
|
|
- etag = parse_etag(line, path)
|
|
- if etag is None:
|
|
- if comments_only:
|
|
- break
|
|
- else:
|
|
- raise TestFileSyntaxError(orig_line)
|
|
- etags += [etag]
|
|
- return etags, options
|
|
-
|
|
-def _parse_test_headers(path):
|
|
- # <path>.tags:
|
|
- try:
|
|
- file = open(path + '.tags', encoding='UTF-8')
|
|
- except FileNotFoundError:
|
|
- pass
|
|
- else:
|
|
- with file:
|
|
- return _parse_test_header_file(file, path, comments_only=False)
|
|
- # <path>.gen:
|
|
- try:
|
|
- file = open(path + '.gen', encoding='UTF-8', errors='ignore')
|
|
- except FileNotFoundError:
|
|
- pass
|
|
- else:
|
|
- with file:
|
|
- return _parse_test_header_file(file, path, comments_only=True)
|
|
- # <path>:
|
|
- with open(path, 'rt', encoding='UTF-8', errors='ignore') as file:
|
|
- return _parse_test_header_file(file, path, comments_only=True)
|
|
-
|
|
-def _test_file(path, basedir=here):
|
|
- if basedir is not None:
|
|
- path = os.path.relpath(os.path.join(basedir, path), start=os.getcwd())
|
|
- options = []
|
|
- etags, options = _parse_test_headers(path)
|
|
- assert_emit_tags(path, etags, options=options)
|
|
-
|
|
-def get_coverage_for_file(path):
|
|
- etags, options = _parse_test_headers(path)
|
|
- del options
|
|
- return (t.tag for t in etags)
|
|
-
|
|
-def get_coverage_for_function(fn):
|
|
- for etag in etags_from_tagstring(fn, ''):
|
|
- yield etag.tag
|
|
-
|
|
-def _get_test_filenames():
|
|
- for root, dirnames, filenames in os.walk(here):
|
|
- del dirnames
|
|
- for filename in filenames:
|
|
- if not filename.endswith(test_file_extensions):
|
|
- continue
|
|
- yield os.path.join(root, filename)
|
|
-
|
|
-def test_file():
|
|
- for filename in _get_test_filenames():
|
|
- path = os.path.relpath(filename, start=here)
|
|
- yield _test_file, path
|
|
-test_file.redundant = True # not needed if the plugin is enabled
|
|
-
|
|
-@tagstring('''
|
|
-E: os-error No such file or directory
|
|
-''')
|
|
-def test_os_error_no_such_file():
|
|
- with tools.temporary_directory() as tmpdir:
|
|
- path = os.path.join(tmpdir, 'nonexistent.po')
|
|
- expected = etags_from_tagstring(this(), path)
|
|
- assert_emit_tags(path, expected)
|
|
-
|
|
-@tagstring('''
|
|
-E: os-error Permission denied
|
|
-''')
|
|
-def test_os_error_permission_denied():
|
|
- if os.getuid() == 0:
|
|
- raise nose.SkipTest('this test must not be run as root')
|
|
- with tools.temporary_directory() as tmpdir:
|
|
- path = os.path.join(tmpdir, 'denied.po')
|
|
- with open(path, 'wb'):
|
|
- pass
|
|
- os.chmod(path, 0)
|
|
- expected = etags_from_tagstring(this(), path)
|
|
- assert_emit_tags(path, expected)
|
|
-
|
|
-# ----------------------------------------
|
|
-
|
|
-def get_coverage():
|
|
- coverage = set()
|
|
- for filename in _get_test_filenames():
|
|
- for tag in get_coverage_for_file(filename):
|
|
- coverage.add(tag)
|
|
- for objname, obj in globals().items():
|
|
- if not objname.startswith('test_'):
|
|
- continue
|
|
- for tag in get_coverage_for_function(obj):
|
|
- coverage.add(tag)
|
|
- return coverage
|
|
-
|
|
-# vim:ts=4 sts=4 sw=4 et
|
|
Index: i18nspector-0.26/tests/blackbox_tests/conftest.py
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ i18nspector-0.26/tests/blackbox_tests/conftest.py
|
|
@@ -0,0 +1,424 @@
|
|
+# Copyright © 2012-2021 Jakub Wilk <jwilk@jwilk.net>
|
|
+# Copyright © 2021 Stuart Prescott <stuart@debian.org>
|
|
+#
|
|
+# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
+# of this software and associated documentation files (the “Software”), to deal
|
|
+# in the Software without restriction, including without limitation the rights
|
|
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
+# copies of the Software, and to permit persons to whom the Software is
|
|
+# furnished to do so, subject to the following conditions:
|
|
+#
|
|
+# The above copyright notice and this permission notice shall be included in
|
|
+# all copies or substantial portions of the Software.
|
|
+#
|
|
+# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
+# SOFTWARE.
|
|
+
|
|
+import difflib
|
|
+import inspect
|
|
+import io
|
|
+import multiprocessing as mp
|
|
+import os
|
|
+import re
|
|
+import shlex
|
|
+import signal
|
|
+import subprocess as ipc
|
|
+import sys
|
|
+import traceback
|
|
+import unittest
|
|
+
|
|
+import pytest
|
|
+
|
|
+
|
|
+here = os.path.dirname(__file__)
|
|
+
|
|
+
|
|
+# ----------------------------------------
|
|
+
|
|
+def this():
|
|
+ '''
|
|
+ Return function that called this function. (Hopefully!)
|
|
+ '''
|
|
+ return globals()[inspect.stack()[1][0].f_code.co_name]
|
|
+
|
|
+# ----------------------------------------
|
|
+
|
|
+_parse_etag = re.compile(r'([A-Z]): (([\w-]+).*)').match
|
|
+
|
|
+def parse_etag(contents, path):
|
|
+ match = _parse_etag(contents)
|
|
+ if match is None:
|
|
+ return
|
|
+ t = ETag(match.group(1), path, match.group(2))
|
|
+ return t
|
|
+
|
|
+def etags_from_tagstring(obj, path):
|
|
+ try:
|
|
+ docstring = obj.tagstring
|
|
+ except AttributeError:
|
|
+ return
|
|
+ for line in docstring.splitlines():
|
|
+ line = line.lstrip()
|
|
+ t = parse_etag(line, path)
|
|
+ if t is not None:
|
|
+ yield t
|
|
+
|
|
+def tagstring(s):
|
|
+ def update(x):
|
|
+ x.tagstring = s
|
|
+ return x
|
|
+ return update
|
|
+
|
|
+# ----------------------------------------
|
|
+
|
|
+class ETag():
|
|
+
|
|
+ _ellipsis = '<...>'
|
|
+ _split = re.compile('({})'.format(re.escape(_ellipsis))).split
|
|
+
|
|
+ def __init__(self, code, path, rest):
|
|
+ self._s = s = '{code}: {path}: {rest}'.format(
|
|
+ code=code,
|
|
+ path=path,
|
|
+ rest=rest,
|
|
+ )
|
|
+ self.tag = rest.split(None, 1)[0]
|
|
+ regexp = ''.join(
|
|
+ '.*' if chunk == self._ellipsis else re.escape(chunk)
|
|
+ for chunk in self._split(s)
|
|
+ )
|
|
+ self._regexp = re.compile('^{}$'.format(regexp))
|
|
+
|
|
+ def __eq__(self, other):
|
|
+ if isinstance(other, str):
|
|
+ return self._regexp.match(other)
|
|
+ else:
|
|
+ return NotImplemented
|
|
+
|
|
+ def __str__(self):
|
|
+ return self._s
|
|
+
|
|
+ def __repr__(self):
|
|
+ return repr(self._s)
|
|
+
|
|
+# ----------------------------------------
|
|
+
|
|
+def _get_signal_names():
|
|
+ data = dict(
|
|
+ (name, getattr(signal, name))
|
|
+ for name in dir(signal)
|
|
+ if re.compile('^SIG[A-Z0-9]*$').match(name)
|
|
+ )
|
|
+ try:
|
|
+ if data['SIGABRT'] == data['SIGIOT']:
|
|
+ del data['SIGIOT']
|
|
+ except KeyError:
|
|
+ pass
|
|
+ try:
|
|
+ if data['SIGCHLD'] == data['SIGCLD']:
|
|
+ del data['SIGCLD']
|
|
+ except KeyError:
|
|
+ pass
|
|
+ for name, n in data.items():
|
|
+ yield n, name
|
|
+
|
|
+_signal_names = dict(_get_signal_names())
|
|
+
|
|
+def get_signal_name(n):
|
|
+ try:
|
|
+ return _signal_names[n]
|
|
+ except KeyError:
|
|
+ return str(n)
|
|
+
|
|
+# ----------------------------------------
|
|
+
|
|
+# Here, a pytest hook function (pytest_collect_file) is used to decide that
|
|
+# the .mo/.po/.pot files in the directory are actually test items.
|
|
+# For each file that is found, a PoTestFile is created. For each PoTestFile,
|
|
+# a testable item (PoTestItem) is created; if needed, there could be be
|
|
+# more than one PoTestItem per PoTestFile, but the code currently only
|
|
+# creates a single test.
|
|
+
|
|
+test_file_extensions = ('.mo', '.po', '.pot', '.pop')
|
|
+# .pop is a special extension to trigger unknown-file-type
|
|
+
|
|
+
|
|
+def pytest_collect_file(parent, path):
|
|
+ """hook function that decides that po files are actually tests"""
|
|
+ if path.ext in test_file_extensions:
|
|
+ return PoTestFile.from_parent(parent, fspath=path)
|
|
+
|
|
+
|
|
+class PoTestFile(pytest.File):
|
|
+ """Class to yield one or more test items that are contained in the file
|
|
+
|
|
+ In this implementation, only one test is yielded.
|
|
+ """
|
|
+ # pylint: disable=abstract-method
|
|
+ # pylint gets confused about this subclassing and emits warnings about
|
|
+ # (unneeded) abstract methods not being defined.
|
|
+ # https://github.com/pytest-dev/pytest/issues/7591
|
|
+
|
|
+ def collect(self):
|
|
+ # record the po file's basename and its full filesystem path as
|
|
+ # strings; pytest will happily use Path objects but the rest of
|
|
+ # stdlib on older Python versions only wants str not Path.
|
|
+ fname = str(self.fspath)
|
|
+ name = os.path.basename(fname)
|
|
+ yield PoTestItem.from_parent(self, name=name, filename=fname)
|
|
+
|
|
+
|
|
+class PoTestItem(pytest.Item):
|
|
+ """Class that represents a single test."""
|
|
+ # pylint: disable=abstract-method
|
|
+
|
|
+ def __init__(self, name, parent, filename):
|
|
+ super().__init__(name, parent)
|
|
+ self.filename = filename
|
|
+
|
|
+ def runtest(self):
|
|
+ """run the test
|
|
+
|
|
+ The intended i18nspector error tags are extracted from the file,
|
|
+ i18nspector is run on the file and the sets of tags are asserted
|
|
+ to be identical. Exceptions may also be raised for various failure
|
|
+ modes of i18nspector or other test harness failures.
|
|
+ """
|
|
+ etags, options = self.parse_test_headers()
|
|
+ assert_emit_tags(self.filename, etags, options=options)
|
|
+
|
|
+ def repr_failure(self, excinfo, style=None):
|
|
+ """Presentation of test failures for when self.runtest() raises an exception."""
|
|
+ if isinstance(excinfo.value, PoTestFileException):
|
|
+ return "\n".join(
|
|
+ [
|
|
+ "blackbox test failed for " + self.name,
|
|
+ str(excinfo.value),
|
|
+ ]
|
|
+ )
|
|
+ else:
|
|
+ return "\n".join(
|
|
+ [
|
|
+ "blackbox test error for " + self.name,
|
|
+ str(excinfo.value),
|
|
+ ]
|
|
+ )
|
|
+
|
|
+ def reportinfo(self):
|
|
+ """ header for test failure/error/stdout reporting """
|
|
+ return self.fspath, 0, "blackbox test: " + self.name
|
|
+
|
|
+ def _parse_test_header_file(self, fh, path, *, comments_only):
|
|
+ etags = []
|
|
+ options = []
|
|
+ for n, line in enumerate(fh):
|
|
+ orig_line = line
|
|
+ if comments_only:
|
|
+ if n == 0 and line.startswith('#!'):
|
|
+ continue
|
|
+ if line.startswith('# '):
|
|
+ line = line[2:]
|
|
+ else:
|
|
+ break
|
|
+ if line.startswith('--'):
|
|
+ options += shlex.split(line)
|
|
+ else:
|
|
+ etag = parse_etag(line, path)
|
|
+ if etag is None:
|
|
+ if comments_only:
|
|
+ break
|
|
+ else:
|
|
+ raise TestFileSyntaxError(orig_line)
|
|
+ etags += [etag]
|
|
+ return etags, options
|
|
+
|
|
+ def parse_test_headers(self):
|
|
+ path = self.filename
|
|
+ # <path>.tags:
|
|
+ try:
|
|
+ fh = open(path + '.tags', encoding='UTF-8') # pylint: disable=consider-using-with
|
|
+ except FileNotFoundError:
|
|
+ pass
|
|
+ else:
|
|
+ with fh:
|
|
+ return self._parse_test_header_file(fh, path, comments_only=False)
|
|
+ # <path>.gen:
|
|
+ try:
|
|
+ fh = open(path + '.gen', encoding='UTF-8', errors='ignore') # pylint: disable=consider-using-with
|
|
+ except FileNotFoundError:
|
|
+ pass
|
|
+ else:
|
|
+ with fh:
|
|
+ return self._parse_test_header_file(fh, path, comments_only=True)
|
|
+ # <path>:
|
|
+ with open(path, 'rt', encoding='UTF-8', errors='ignore') as fh:
|
|
+ return self._parse_test_header_file(fh, path, comments_only=True)
|
|
+
|
|
+
|
|
+class PoTestFileException(AssertionError):
|
|
+ """Custom exception for error reporting."""
|
|
+
|
|
+
|
|
+class TestFileSyntaxError(Exception):
|
|
+ pass
|
|
+
|
|
+
|
|
+def queue_get(queue, process):
|
|
+ '''
|
|
+ Remove and return an item from the queue.
|
|
+ Block until the process terminates.
|
|
+ '''
|
|
+ while True:
|
|
+ try:
|
|
+ return queue.get(timeout=1)
|
|
+ # This semi-active waiting is ugly, but there doesn't seem be any
|
|
+ # obvious better way.
|
|
+ except mp.queues.Empty:
|
|
+ if process.exitcode is None:
|
|
+ continue
|
|
+ else:
|
|
+ raise
|
|
+
|
|
+def run_i18nspector(options, path):
|
|
+ commandline = os.environ.get('I18NSPECTOR_COMMANDLINE')
|
|
+ if commandline is None:
|
|
+ # We cheat here a bit, because exec(3)ing is very expensive.
|
|
+ # Let's load the needed Python modules, and use multiprocessing to
|
|
+ # “emulate” the command execution.
|
|
+ import lib.cli # pylint: disable=import-outside-toplevel
|
|
+ assert lib.cli # make pyflakes happy
|
|
+ prog = os.path.join(here, os.pardir, os.pardir, 'i18nspector')
|
|
+ commandline = [sys.executable, prog]
|
|
+ queue = mp.Queue()
|
|
+ child = mp.Process(
|
|
+ target=_mp_run_i18nspector,
|
|
+ args=(prog, options, path, queue)
|
|
+ )
|
|
+ child.start()
|
|
+ [stdout, stderr] = (
|
|
+ s.splitlines()
|
|
+ for s in queue_get(queue, child)
|
|
+ )
|
|
+ child.join()
|
|
+ rc = child.exitcode
|
|
+ else:
|
|
+ commandline = shlex.split(commandline)
|
|
+ commandline += options
|
|
+ commandline += [path]
|
|
+ fixed_env = dict(os.environ, PYTHONIOENCODING='UTF-8')
|
|
+ with ipc.Popen(commandline, stdout=ipc.PIPE, stderr=ipc.PIPE, env=fixed_env) as child:
|
|
+ stdout, stderr = (
|
|
+ s.decode('UTF-8').splitlines()
|
|
+ for s in child.communicate()
|
|
+ )
|
|
+ rc = child.poll()
|
|
+ assert isinstance(rc, int)
|
|
+ if rc == 0:
|
|
+ return stdout
|
|
+ if rc < 0:
|
|
+ message = ['command was interrupted by signal {sig}'.format(sig=get_signal_name(-rc))] # pylint: disable=invalid-unary-operand-type
|
|
+ else:
|
|
+ message = ['command exited with status {rc}'.format(rc=rc)]
|
|
+ message += ['']
|
|
+ if stdout:
|
|
+ message += ['stdout:']
|
|
+ message += ['| ' + s for s in stdout] + ['']
|
|
+ else:
|
|
+ message += ['stdout: (empty)']
|
|
+ if stderr:
|
|
+ message += ['stderr:']
|
|
+ message += ['| ' + s for s in stderr]
|
|
+ else:
|
|
+ message += ['stderr: (empty)']
|
|
+ raise PoTestFileException('\n'.join(message))
|
|
+
|
|
+def _mp_run_i18nspector(prog, options, path, queue):
|
|
+ with open(prog, 'rt', encoding='UTF-8') as file:
|
|
+ code = file.read()
|
|
+ sys.argv = [prog] + list(options) + [path]
|
|
+ orig_stdout = sys.stdout
|
|
+ orig_stderr = sys.stderr
|
|
+ code = compile(code, prog, 'exec')
|
|
+ io_stdout = io.StringIO()
|
|
+ io_stderr = io.StringIO()
|
|
+ gvars = dict(
|
|
+ __file__=prog,
|
|
+ )
|
|
+ (sys.stdout, sys.stderr) = (io_stdout, io_stderr)
|
|
+ try:
|
|
+ try:
|
|
+ exec(code, gvars) # pylint: disable=exec-used
|
|
+ finally:
|
|
+ (sys.stdout, sys.stderr) = (orig_stdout, orig_stderr)
|
|
+ stdout = io_stdout.getvalue()
|
|
+ stderr = io_stderr.getvalue()
|
|
+ except SystemExit:
|
|
+ queue.put([stdout, stderr])
|
|
+ raise
|
|
+ except: # pylint: disable=bare-except
|
|
+ exctp, exc, tb = sys.exc_info()
|
|
+ stderr += ''.join(
|
|
+ traceback.format_exception(exctp, exc, tb)
|
|
+ )
|
|
+ queue.put([stdout, stderr])
|
|
+ sys.exit(1)
|
|
+ raise # hi, pydiatra!
|
|
+ else:
|
|
+ queue.put([stdout, stderr])
|
|
+ sys.exit(0)
|
|
+
|
|
+def assert_emit_tags(path, etags, *, options=()):
|
|
+ etags = list(etags)
|
|
+ stdout = run_i18nspector(options, path)
|
|
+ expected_failure = os.path.basename(path).startswith('xfail-')
|
|
+ if stdout != etags:
|
|
+ if expected_failure:
|
|
+ raise unittest.SkipTest('expected failure')
|
|
+ str_etags = [str(x) for x in etags]
|
|
+ message = ['Tags differ:', '']
|
|
+ diff = list(
|
|
+ difflib.unified_diff(str_etags, stdout, n=9999)
|
|
+ )
|
|
+ message += diff[3:]
|
|
+ raise PoTestFileException('\n'.join(message))
|
|
+ elif expected_failure:
|
|
+ raise PoTestFileException('unexpected success')
|
|
+
|
|
+
|
|
+# ----------------------------------------
|
|
+# Tag coverage recording code
|
|
+
|
|
+class PofileRecorderPlugin:
|
|
+ """pytest plugin to just record the test files that are collected"""
|
|
+ def __init__(self):
|
|
+ self.collected = []
|
|
+
|
|
+ def pytest_collection_modifyitems(self, items):
|
|
+ for item in items:
|
|
+ self.collected.append((item.nodeid, item))
|
|
+
|
|
+
|
|
+def get_coverage():
|
|
+ # ask pytest to enumerate the tests it knows of in this directory
|
|
+ directory = os.path.dirname(__file__)
|
|
+ pofile_recorder = PofileRecorderPlugin()
|
|
+ pytest.main(['--collect-only', '-p', 'no:terminal', directory], plugins=[pofile_recorder])
|
|
+
|
|
+ coverage = set()
|
|
+ for _, item in pofile_recorder.collected:
|
|
+ if isinstance(item, PoTestItem):
|
|
+ etags, _ = item.parse_test_headers()
|
|
+ for t in etags:
|
|
+ coverage.add(t.tag)
|
|
+ else:
|
|
+ for tag in etags_from_tagstring(item.function, ''):
|
|
+ coverage.add(tag.tag)
|
|
+
|
|
+ return coverage
|
|
+
|
|
+# vim:ts=4 sts=4 sw=4 et
|
|
Index: i18nspector-0.26/tests/blackbox_tests/test_errors.py
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ i18nspector-0.26/tests/blackbox_tests/test_errors.py
|
|
@@ -0,0 +1,36 @@
|
|
+import inspect
|
|
+import os.path
|
|
+import unittest
|
|
+
|
|
+from .conftest import tagstring, etags_from_tagstring, assert_emit_tags
|
|
+from .. import tools
|
|
+
|
|
+
|
|
+def this():
|
|
+ '''
|
|
+ Return function that called this function. (Hopefully!)
|
|
+ '''
|
|
+ return globals()[inspect.stack()[1][0].f_code.co_name]
|
|
+
|
|
+@tagstring('''
|
|
+E: os-error No such file or directory
|
|
+''')
|
|
+def test_os_error_no_such_file():
|
|
+ with tools.temporary_directory() as tmpdir:
|
|
+ path = os.path.join(tmpdir, 'nonexistent.po')
|
|
+ expected = etags_from_tagstring(this(), path)
|
|
+ assert_emit_tags(path, expected)
|
|
+
|
|
+@tagstring('''
|
|
+E: os-error Permission denied
|
|
+''')
|
|
+def test_os_error_permission_denied():
|
|
+ if os.getuid() == 0:
|
|
+ raise unittest.SkipTest('this test must not be run as root')
|
|
+ with tools.temporary_directory() as tmpdir:
|
|
+ path = os.path.join(tmpdir, 'denied.po')
|
|
+ with open(path, 'wb'):
|
|
+ pass
|
|
+ os.chmod(path, 0)
|
|
+ expected = etags_from_tagstring(this(), path)
|
|
+ assert_emit_tags(path, expected)
|
|
Index: i18nspector-0.26/private/update-tag-coverage
|
|
===================================================================
|
|
--- i18nspector-0.26.orig/private/update-tag-coverage
|
|
+++ i18nspector-0.26/private/update-tag-coverage
|
|
@@ -21,12 +21,14 @@
|
|
# SOFTWARE.
|
|
|
|
import os
|
|
+import os.path
|
|
import sys
|
|
|
|
sys.path[0] += '/..'
|
|
|
|
from lib import tags
|
|
-from tests import blackbox_tests
|
|
+from tests.blackbox_tests import conftest as blackbox_tests
|
|
+
|
|
|
|
def main():
|
|
coverage = blackbox_tests.get_coverage()
|