summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSeth M Morton <seth.m.morton@gmail.com>2018-08-12 11:07:58 -0400
committerSeth M Morton <seth.m.morton@gmail.com>2018-08-12 11:07:58 -0400
commit8749af2c6c0e81db679792b78eb6eafa953a2ead (patch)
tree76c2d186e1771562b99cb1a8d16a91a76fb0800e
parentef9f871304731ad4cfbe6c5cbf2bb9c93894229c (diff)
downloadnatsort-8749af2c6c0e81db679792b78eb6eafa953a2ead.tar.gz
Refactor test_natsort.compat into fixtures.
These have been moved to conftest.py, or now use the pytest-mocker third-party plugin. Some tests have been re-written to account for the change.
-rw-r--r--Pipfile4
-rw-r--r--natsort/compat/py23.py18
-rw-r--r--test_natsort/compat/__init__.py0
-rw-r--r--test_natsort/compat/locale.py40
-rw-r--r--test_natsort/compat/mock.py9
-rw-r--r--test_natsort/conftest.py38
-rw-r--r--test_natsort/test_input_string_transform_factory.py22
-rw-r--r--test_natsort/test_main.py252
-rw-r--r--test_natsort/test_natsort_cmp.py8
-rw-r--r--test_natsort/test_natsort_keygen.py18
-rw-r--r--test_natsort/test_natsorted.py23
-rw-r--r--test_natsort/test_string_component_transform_factory.py11
-rw-r--r--test_natsort/test_utils.py5
13 files changed, 212 insertions, 236 deletions
diff --git a/Pipfile b/Pipfile
index d8b814d..da66c26 100644
--- a/Pipfile
+++ b/Pipfile
@@ -1,13 +1,13 @@
[dev-packages]
coverage = "*"
-pytest = "*"
+pytest = ">=3.5"
pytest-cov = "*"
pytest-flakes = "*"
pytest-pep8 = "*"
+pytest-mock = ">=1.1"
hypothesis = ">=3.8.0"
astroid = "==1.5.3"
pytest-faulthandler = {version = "*", platform_python_implementation = "== 'CPython'"}
# These packages are standard on newer python versions.
pathlib = {version = "*", python_version = "< '3.4'"}
-mock = {version = "*", python_version = "< '3.3'"}
diff --git a/natsort/compat/py23.py b/natsort/compat/py23.py
index e7abb5e..df3eace 100644
--- a/natsort/compat/py23.py
+++ b/natsort/compat/py23.py
@@ -20,26 +20,29 @@ PY_VERSION = float(sys.version[:3])
NEWPY = PY_VERSION >= 3.3
# Assume all strings are Unicode in Python 2
-py23_str = str if sys.version[0] == "3" else unicode
+py23_str = str if PY_VERSION >= 3 else unicode
# Use the range iterator always
-py23_range = range if sys.version[0] == "3" else xrange
+py23_range = range if PY_VERSION >= 3 else xrange
# Uniform base string type
-py23_basestring = str if sys.version[0] == "3" else basestring
+py23_basestring = str if PY_VERSION >= 3 else basestring
# unichr function
-py23_unichr = chr if sys.version[0] == "3" else unichr
+py23_unichr = chr if PY_VERSION >= 3 else unichr
+
+# Proper lower-casing of letters.
+py23_lower = py23_str.casefold if NEWPY else py23_str.lower
def _py23_cmp(a, b):
return (a > b) - (a < b)
-py23_cmp = _py23_cmp if sys.version[0] == "3" else cmp
+py23_cmp = _py23_cmp if PY_VERSION >= 3 else cmp
# zip as an iterator
-if sys.version[0] == "3":
+if PY_VERSION >= 3:
py23_zip = zip
py23_map = map
py23_filter = filter
@@ -50,7 +53,6 @@ else:
py23_map = itertools.imap
py23_filter = itertools.ifilter
-
# cmp_to_key was not created till 2.7, so require this for 2.6
try:
from functools import cmp_to_key
@@ -113,7 +115,7 @@ def _modify_str_or_docstring(str_change_func):
# Properly modify a doctstring to either have the unicode literal or not.
-if sys.version[0] == "3":
+if PY_VERSION >= 3:
# Abstract u'abc' syntax:
@_modify_str_or_docstring
def u_format(s):
diff --git a/test_natsort/compat/__init__.py b/test_natsort/compat/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/test_natsort/compat/__init__.py
+++ /dev/null
diff --git a/test_natsort/compat/locale.py b/test_natsort/compat/locale.py
deleted file mode 100644
index 76e387c..0000000
--- a/test_natsort/compat/locale.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import print_function, division, unicode_literals, absolute_import
-
-# Std. lib imports.
-import locale
-
-# Local imports
-from natsort.compat.py23 import py23_str, py23_unichr, py23_range
-
-
-def load_locale(x):
- """ Convenience to load a locale, trying ISO8859-1 first."""
- try:
- locale.setlocale(locale.LC_ALL, str("{0}.ISO8859-1".format(x)))
- except locale.Error:
- locale.setlocale(locale.LC_ALL, str("{0}.UTF-8".format(x)))
-
-
-# Check if de_DE is installed.
-try:
- load_locale("de_DE")
- has_locale_de_DE = True
-except locale.Error:
- has_locale_de_DE = False
-
-# Depending on the python version, use lower or casefold
-# to make a string lowercase.
-try:
- low = py23_str.casefold
-except AttributeError:
- low = py23_str.lower
-
-# There are some unicode values that are known failures on BSD systems
-# that has nothing to do with natsort (a ValueError is raised by strxfrm).
-# Let's filter them out.
-try:
- bad_uni_chars = set(py23_unichr(x) for x in py23_range(0X10fefd, 0X10ffff + 1))
-except ValueError:
- # Narrow unicode build... no worries.
- bad_uni_chars = set()
diff --git a/test_natsort/compat/mock.py b/test_natsort/compat/mock.py
deleted file mode 100644
index 32d3a64..0000000
--- a/test_natsort/compat/mock.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# -*- coding: utf-8 -*-
-from __future__ import print_function, division, unicode_literals, absolute_import
-
-# Load mock functions from the right place.
-try:
- from unittest.mock import MagicMock, patch, call
-except ImportError:
- # noinspection PyUnresolvedReferences,PyPackageRequirements
- from mock import MagicMock, patch, call
diff --git a/test_natsort/conftest.py b/test_natsort/conftest.py
new file mode 100644
index 0000000..459e44e
--- /dev/null
+++ b/test_natsort/conftest.py
@@ -0,0 +1,38 @@
+"""
+Fixtures for pytest.
+"""
+
+import pytest
+import locale
+
+
+def load_locale(x):
+ """Convenience to load a locale, trying ISO8859-1 first."""
+ try:
+ locale.setlocale(locale.LC_ALL, str("{0}.ISO8859-1".format(x)))
+ except locale.Error:
+ locale.setlocale(locale.LC_ALL, str("{0}.UTF-8".format(x)))
+
+
+@pytest.fixture()
+def with_locale_en_us():
+ """Convenience to load the en_US locale - reset when complete."""
+ orig = locale.getlocale()
+ yield load_locale("en_US")
+ locale.setlocale(locale.LC_ALL, orig)
+
+
+@pytest.fixture()
+def with_locale_de_de():
+ """
+ Convenience to load the de_DE locale - reset when complete - skip if missing.
+ """
+ orig = locale.getlocale()
+ try:
+ load_locale("de_DE")
+ except locale.Error:
+ pytest.skip("requires de_DE locale to be installed")
+ else:
+ yield
+ finally:
+ locale.setlocale(locale.LC_ALL, orig)
diff --git a/test_natsort/test_input_string_transform_factory.py b/test_natsort/test_input_string_transform_factory.py
index 2453873..2c3e329 100644
--- a/test_natsort/test_input_string_transform_factory.py
+++ b/test_natsort/test_input_string_transform_factory.py
@@ -12,8 +12,6 @@ from natsort.compat.py23 import NEWPY
from natsort.ns_enum import ns, ns_DUMB
from natsort.utils import _input_string_transform_factory
-from compat.locale import has_locale_de_DE, load_locale
-
# Each test has an "example" version for demonstrative purposes,
# and a test that uses the hypothesis module.
@@ -105,8 +103,8 @@ def test_input_string_transform_factory_performs_swapcase_and_casefold_both_LOWE
)
+@pytest.mark.usefixtures("with_locale_en_us")
def test_input_string_transform_factory_removes_thousands_separator_with_LOCALE_example():
- load_locale("en_US")
x = "12,543,642,642.534,534,980" # Without FLOAT it does not account for decimal.
assert _input_string_transform_factory(ns.LOCALE)(x) == "12543642642.534534980"
x = (
@@ -120,8 +118,8 @@ def test_input_string_transform_factory_removes_thousands_separator_with_LOCALE_
@given(lists(elements=integers(), min_size=4, max_size=20))
+@pytest.mark.usefixtures("with_locale_en_us")
def test_input_string_transform_factory_removes_thousands_separator_with_LOCALE(x):
- load_locale("en_US")
t = "".join(
map(methodcaller("rstrip", "lL"), map(str, map(abs, x)))
) # Remove negative signs trailing L
@@ -146,10 +144,10 @@ def test_input_string_transform_factory_removes_thousands_separator_and_is_float
lists(elements=integers(), min_size=4, max_size=20),
lists(elements=integers(), min_size=4, max_size=20),
)
+@pytest.mark.usefixtures("with_locale_en_us")
def test_input_string_transform_factory_removes_thousands_separator_and_is_float_aware_with_LOCALE_and_FLOAT(
x, y
):
- load_locale("en_US")
t = "".join(
map(methodcaller("rstrip", "lL"), map(str, map(abs, x)))
) # Remove negative signs trailing L
@@ -181,8 +179,8 @@ def test_input_string_transform_factory_removes_thousands_separator_and_is_float
# These might be too much to test with hypothesis.
+@pytest.mark.usefixtures("with_locale_en_us")
def test_input_string_transform_factory_leaves_invalid_thousands_separator_with_LOCALE_example():
- load_locale("en_US")
x = "12,543,642642.5345,34980"
assert _input_string_transform_factory(ns.LOCALE)(x) == "12543,642642.5345,34980"
x = "12,59443,642,642.53,4534980"
@@ -192,12 +190,8 @@ def test_input_string_transform_factory_leaves_invalid_thousands_separator_with_
locale.setlocale(locale.LC_ALL, str(""))
-# @pytest.mark.skipif(not has_locale_de_DE or dumb_sort(), reason='requires de_DE locale and working locale')
-@pytest.mark.skipif(
- not has_locale_de_DE, reason="requires de_DE locale and working locale"
-)
+@pytest.mark.usefixtures("with_locale_de_de")
def test_input_string_transform_factory_replaces_decimal_separator_with_LOCALE_example():
- load_locale("de_DE")
x = "1543,753"
assert (
_input_string_transform_factory(ns.LOCALE)(x) == "1543,753"
@@ -209,12 +203,8 @@ def test_input_string_transform_factory_replaces_decimal_separator_with_LOCALE_e
locale.setlocale(locale.LC_ALL, str(""))
-# @pytest.mark.skipif(not has_locale_de_DE or dumb_sort(), reason='requires de_DE locale and working locale')
-@pytest.mark.skipif(
- not has_locale_de_DE, reason="requires de_DE locale and working locale"
-)
+@pytest.mark.usefixtures("with_locale_de_de")
def test_input_string_transform_factory_does_not_replace_invalid_decimal_separator_with_LOCALE_example():
- load_locale("de_DE")
x = "154s,t53"
assert _input_string_transform_factory(ns.LOCALE | ns.FLOAT)(x) == "154s,t53"
locale.setlocale(locale.LC_ALL, str(""))
diff --git a/test_natsort/test_main.py b/test_natsort/test_main.py
index 2971633..453dd1f 100644
--- a/test_natsort/test_main.py
+++ b/test_natsort/test_main.py
@@ -19,60 +19,58 @@ from natsort.__main__ import (
)
from pytest import raises
-from compat.mock import call, patch
-
-
-def test_main_passes_default_arguments_with_no_command_line_options():
- with patch("natsort.__main__.sort_and_print_entries") as p:
- sys.argv[1:] = ["num-2", "num-6", "num-1"]
- main()
- args = p.call_args[0][1]
- assert not args.paths
- assert args.filter is None
- assert args.reverse_filter is None
- assert args.exclude is None
- assert not args.reverse
- assert args.number_type == "int"
- assert not args.signed
- assert args.exp
- assert not args.locale
-
-
-def test_main_passes_arguments_with_all_command_line_options():
- with patch("natsort.__main__.sort_and_print_entries") as p:
- sys.argv[1:] = [
- "--paths",
- "--reverse",
- "--locale",
- "--filter",
- "4",
- "10",
- "--reverse-filter",
- "100",
- "110",
- "--number-type",
- "float",
- "--noexp",
- "--sign",
- "--exclude",
- "34",
- "--exclude",
- "35",
- "num-2",
- "num-6",
- "num-1",
- ]
- main()
- args = p.call_args[0][1]
- assert args.paths
- assert args.filter == [(4.0, 10.0)]
- assert args.reverse_filter == [(100.0, 110.0)]
- assert args.exclude == [34, 35]
- assert args.reverse
- assert args.number_type == "float"
- assert args.signed
- assert not args.exp
- assert args.locale
+
+def test_main_passes_default_arguments_with_no_command_line_options(mocker):
+ p = mocker.patch("natsort.__main__.sort_and_print_entries")
+ sys.argv[1:] = ["num-2", "num-6", "num-1"]
+ main()
+ args = p.call_args[0][1]
+ assert not args.paths
+ assert args.filter is None
+ assert args.reverse_filter is None
+ assert args.exclude is None
+ assert not args.reverse
+ assert args.number_type == "int"
+ assert not args.signed
+ assert args.exp
+ assert not args.locale
+
+
+def test_main_passes_arguments_with_all_command_line_options(mocker):
+ p = mocker.patch("natsort.__main__.sort_and_print_entries")
+ sys.argv[1:] = [
+ "--paths",
+ "--reverse",
+ "--locale",
+ "--filter",
+ "4",
+ "10",
+ "--reverse-filter",
+ "100",
+ "110",
+ "--number-type",
+ "float",
+ "--noexp",
+ "--sign",
+ "--exclude",
+ "34",
+ "--exclude",
+ "35",
+ "num-2",
+ "num-6",
+ "num-1",
+ ]
+ main()
+ args = p.call_args[0][1]
+ assert args.paths
+ assert args.filter == [(4.0, 10.0)]
+ assert args.reverse_filter == [(100.0, 110.0)]
+ assert args.exclude == [34, 35]
+ assert args.reverse
+ assert args.number_type == "float"
+ assert args.signed
+ assert not args.exp
+ assert args.locale
class Args:
@@ -103,79 +101,79 @@ entries = [
mock_print = "__builtin__.print" if sys.version[0] == "2" else "builtins.print"
-def test_sort_and_print_entries_uses_default_algorithm_with_all_options_false():
- with patch(mock_print) as p:
- # tmp/a1 (1)/path1
- # tmp/a1/path1
- # tmp/a23/path1
- # tmp/a57/path2
- # tmp/a64/path1
- # tmp/a64/path2
- # tmp/a130/path1
- sort_and_print_entries(entries, Args(None, None, False, False, False))
- e = [call(entries[i]) for i in [3, 2, 1, 0, 5, 6, 4]]
- p.assert_has_calls(e)
-
-
-def test_sort_and_print_entries_uses_PATH_algorithm_with_path_option_true_to_properly_sort_OS_generated_path_names():
- with patch(mock_print) as p:
- # tmp/a1/path1
- # tmp/a1 (1)/path1
- # tmp/a23/path1
- # tmp/a57/path2
- # tmp/a64/path1
- # tmp/a64/path2
- # tmp/a130/path1
- sort_and_print_entries(entries, Args(None, None, False, True, False))
- e = [call(entries[i]) for i in [2, 3, 1, 0, 5, 6, 4]]
- p.assert_has_calls(e)
-
-
-def test_sort_and_print_entries_keeps_only_paths_between_of_20_to_100_with_filter_option():
- with patch(mock_print) as p:
- # tmp/a23/path1
- # tmp/a57/path2
- # tmp/a64/path1
- # tmp/a64/path2
- sort_and_print_entries(entries, Args([(20, 100)], None, False, False, False))
- e = [call(entries[i]) for i in [1, 0, 5, 6]]
- p.assert_has_calls(e)
-
-
-def test_sort_and_print_entries_excludes_paths_between_of_20_to_100_with_reverse_filter_option():
- with patch(mock_print) as p:
- # tmp/a1/path1
- # tmp/a1 (1)/path1
- # tmp/a130/path1
- sort_and_print_entries(entries, Args(None, [(20, 100)], False, True, False))
- e = [call(entries[i]) for i in [2, 3, 4]]
- p.assert_has_calls(e)
-
-
-def test_sort_and_print_entries_excludes_paths_23_or_130_with_exclude_option_list():
- with patch(mock_print) as p:
- # tmp/a1/path1
- # tmp/a1 (1)/path1
- # tmp/a57/path2
- # tmp/a64/path1
- # tmp/a64/path2
- sort_and_print_entries(entries, Args(None, None, [23, 130], True, False))
- e = [call(entries[i]) for i in [2, 3, 0, 5, 6]]
- p.assert_has_calls(e)
-
-
-def test_sort_and_print_entries_reverses_order_with_reverse_option():
- with patch(mock_print) as p:
- # tmp/a130/path1
- # tmp/a64/path2
- # tmp/a64/path1
- # tmp/a57/path2
- # tmp/a23/path1
- # tmp/a1 (1)/path1
- # tmp/a1/path1
- sort_and_print_entries(entries, Args(None, None, False, True, True))
- e = [call(entries[i]) for i in reversed([2, 3, 1, 0, 5, 6, 4])]
- p.assert_has_calls(e)
+def test_sort_and_print_entries_uses_default_algorithm_with_all_options_false(mocker):
+ p = mocker.patch(mock_print)
+ # tmp/a1 (1)/path1
+ # tmp/a1/path1
+ # tmp/a23/path1
+ # tmp/a57/path2
+ # tmp/a64/path1
+ # tmp/a64/path2
+ # tmp/a130/path1
+ sort_and_print_entries(entries, Args(None, None, False, False, False))
+ e = [mocker.call(entries[i]) for i in [3, 2, 1, 0, 5, 6, 4]]
+ p.assert_has_calls(e)
+
+
+def test_sort_and_print_entries_uses_PATH_algorithm_with_path_option_true_to_properly_sort_OS_generated_path_names(mocker):
+ p = mocker.patch(mock_print)
+ # tmp/a1/path1
+ # tmp/a1 (1)/path1
+ # tmp/a23/path1
+ # tmp/a57/path2
+ # tmp/a64/path1
+ # tmp/a64/path2
+ # tmp/a130/path1
+ sort_and_print_entries(entries, Args(None, None, False, True, False))
+ e = [mocker.call(entries[i]) for i in [2, 3, 1, 0, 5, 6, 4]]
+ p.assert_has_calls(e)
+
+
+def test_sort_and_print_entries_keeps_only_paths_between_of_20_to_100_with_filter_option(mocker):
+ p = mocker.patch(mock_print)
+ # tmp/a23/path1
+ # tmp/a57/path2
+ # tmp/a64/path1
+ # tmp/a64/path2
+ sort_and_print_entries(entries, Args([(20, 100)], None, False, False, False))
+ e = [mocker.call(entries[i]) for i in [1, 0, 5, 6]]
+ p.assert_has_calls(e)
+
+
+def test_sort_and_print_entries_excludes_paths_between_of_20_to_100_with_reverse_filter_option(mocker):
+ p = mocker.patch(mock_print)
+ # tmp/a1/path1
+ # tmp/a1 (1)/path1
+ # tmp/a130/path1
+ sort_and_print_entries(entries, Args(None, [(20, 100)], False, True, False))
+ e = [mocker.call(entries[i]) for i in [2, 3, 4]]
+ p.assert_has_calls(e)
+
+
+def test_sort_and_print_entries_excludes_paths_23_or_130_with_exclude_option_list(mocker):
+ p = mocker.patch(mock_print)
+ # tmp/a1/path1
+ # tmp/a1 (1)/path1
+ # tmp/a57/path2
+ # tmp/a64/path1
+ # tmp/a64/path2
+ sort_and_print_entries(entries, Args(None, None, [23, 130], True, False))
+ e = [mocker.call(entries[i]) for i in [2, 3, 0, 5, 6]]
+ p.assert_has_calls(e)
+
+
+def test_sort_and_print_entries_reverses_order_with_reverse_option(mocker):
+ p = mocker.patch(mock_print)
+ # tmp/a130/path1
+ # tmp/a64/path2
+ # tmp/a64/path1
+ # tmp/a57/path2
+ # tmp/a23/path1
+ # tmp/a1 (1)/path1
+ # tmp/a1/path1
+ sort_and_print_entries(entries, Args(None, None, False, True, True))
+ e = [mocker.call(entries[i]) for i in reversed([2, 3, 1, 0, 5, 6, 4])]
+ p.assert_has_calls(e)
# Each test has an "example" version for demonstrative purposes,
diff --git a/test_natsort/test_natsort_cmp.py b/test_natsort/test_natsort_cmp.py
index 4478049..d5e8e0f 100644
--- a/test_natsort/test_natsort_cmp.py
+++ b/test_natsort/test_natsort_cmp.py
@@ -13,8 +13,6 @@ from hypothesis.strategies import floats, integers, lists
from natsort import ns
from natsort.compat.py23 import py23_cmp
-from compat.mock import patch
-
PY_VERSION = float(sys.version[:3])
if PY_VERSION < 3:
@@ -42,7 +40,7 @@ def test__classes_can_be_compared():
@pytest.mark.skipif(PY_VERSION >= 3.0, reason="cmp() deprecated in Python 3")
-def test__keys_are_being_cached():
+def test__keys_are_being_cached(mocker):
natcmp.cached_keys = {}
assert len(natcmp.cached_keys) == 0
natcmp(0, 0)
@@ -50,13 +48,13 @@ def test__keys_are_being_cached():
natcmp(0, 0)
assert len(natcmp.cached_keys) == 1
- with patch("natsort.compat.locale.dumb_sort", return_value=False):
+ with mocker.patch("natsort.compat.locale.dumb_sort", return_value=False):
natcmp(0, 0, alg=ns.L)
assert len(natcmp.cached_keys) == 2
natcmp(0, 0, alg=ns.L)
assert len(natcmp.cached_keys) == 2
- with patch("natsort.compat.locale.dumb_sort", return_value=True):
+ with mocker.patch("natsort.compat.locale.dumb_sort", return_value=True):
natcmp(0, 0, alg=ns.L)
assert len(natcmp.cached_keys) == 3
natcmp(0, 0, alg=ns.L)
diff --git a/test_natsort/test_natsort_keygen.py b/test_natsort/test_natsort_keygen.py
index 89f30ff..d070b9a 100644
--- a/test_natsort/test_natsort_keygen.py
+++ b/test_natsort/test_natsort_keygen.py
@@ -8,14 +8,12 @@ from __future__ import print_function, unicode_literals
import locale
import warnings
+import pytest
from natsort import natsort_key, natsort_keygen, natsorted, ns
from natsort.compat.locale import get_strxfrm, null_string_locale
from natsort.compat.py23 import PY_VERSION
from pytest import raises
-from compat.locale import load_locale
-from compat.mock import patch
-
INPUT = ["6A-5.034e+1", "/Folder (1)/Foo", 56.7]
@@ -92,10 +90,10 @@ def test_natsort_keygen_splits_input_with_lowercasefirst_noexp_float():
)
-def test_natsort_keygen_splits_input_with_locale():
- load_locale("en_US")
+@pytest.mark.usefixtures("with_locale_en_us")
+def test_natsort_keygen_splits_input_with_locale(mocker):
strxfrm = get_strxfrm()
- with patch("natsort.compat.locale.dumb_sort", return_value=False):
+ with mocker.patch("natsort.compat.locale.dumb_sort", return_value=False):
assert natsort_keygen(alg=ns.L)(INPUT) == (
(
null_string_locale,
@@ -110,7 +108,7 @@ def test_natsort_keygen_splits_input_with_locale():
(strxfrm("/Folder ("), 1, strxfrm(")/Foo")),
(null_string_locale, 56.7),
)
- with patch("natsort.compat.locale.dumb_sort", return_value=True):
+ with mocker.patch("natsort.compat.locale.dumb_sort", return_value=True):
assert natsort_keygen(alg=ns.L)(INPUT) == (
(
null_string_locale,
@@ -130,10 +128,10 @@ def test_natsort_keygen_splits_input_with_locale():
locale.setlocale(locale.LC_ALL, str(""))
-def test_natsort_keygen_splits_input_with_locale_and_capitalfirst():
- load_locale("en_US")
+@pytest.mark.usefixtures("with_locale_en_us")
+def test_natsort_keygen_splits_input_with_locale_and_capitalfirst(mocker):
strxfrm = get_strxfrm()
- with patch("natsort.compat.locale.dumb_sort", return_value=False):
+ with mocker.patch("natsort.compat.locale.dumb_sort", return_value=False):
assert natsort_keygen(alg=ns.LA | ns.C)(INPUT) == (
(
("",),
diff --git a/test_natsort/test_natsorted.py b/test_natsort/test_natsorted.py
index 472c193..382403f 100644
--- a/test_natsort/test_natsorted.py
+++ b/test_natsort/test_natsorted.py
@@ -13,8 +13,6 @@ from natsort import natsorted, ns
from natsort.compat.py23 import PY_VERSION
from pytest import raises
-from compat.locale import has_locale_de_DE, load_locale
-
def test_natsorted_returns_strings_with_numbers_in_ascending_order():
a = ["a2", "a5", "a9", "a1", "a4", "a10", "a6"]
@@ -305,9 +303,9 @@ def test_natsorted_with_IGNORECASE_sorts_without_regard_to_case_for_nested_input
assert natsorted(b, alg=ns.IGNORECASE) == [("a3", "a1"), ("A5", "a6")]
+@pytest.mark.usefixtures("with_locale_en_us")
def test_natsorted_with_LOCALE_returns_results_sorted_by_lowercase_first_and_grouped_letters():
a = ["Apple", "corn", "Corn", "Banana", "apple", "banana"]
- load_locale("en_US")
assert natsorted(a, alg=ns.LOCALE) == [
"apple",
"Apple",
@@ -319,9 +317,9 @@ def test_natsorted_with_LOCALE_returns_results_sorted_by_lowercase_first_and_gro
locale.setlocale(locale.LC_ALL, str(""))
+@pytest.mark.usefixtures("with_locale_en_us")
def test_natsorted_with_LOCALE_and_CAPITALFIRST_returns_results_sorted_by_capital_first_and_ungrouped():
a = ["Apple", "corn", "Corn", "Banana", "apple", "banana"]
- load_locale("en_US")
assert natsorted(a, alg=ns.LOCALE | ns.CAPITALFIRST) == [
"Apple",
"Banana",
@@ -333,9 +331,9 @@ def test_natsorted_with_LOCALE_and_CAPITALFIRST_returns_results_sorted_by_capita
locale.setlocale(locale.LC_ALL, str(""))
+@pytest.mark.usefixtures("with_locale_en_us")
def test_natsorted_with_LOCALE_and_LOWERCASEFIRST_returns_results_sorted_by_uppercase_first_and_grouped_letters():
a = ["Apple", "corn", "Corn", "Banana", "apple", "banana"]
- load_locale("en_US")
assert natsorted(a, alg=ns.LOCALE | ns.LOWERCASEFIRST) == [
"Apple",
"apple",
@@ -347,9 +345,9 @@ def test_natsorted_with_LOCALE_and_LOWERCASEFIRST_returns_results_sorted_by_uppe
locale.setlocale(locale.LC_ALL, str(""))
+@pytest.mark.usefixtures("with_locale_en_us")
def test_natsorted_with_LOCALE_and_CAPITALFIRST_and_LOWERCASE_returns_results_sorted_by_capital_last_and_ungrouped():
a = ["Apple", "corn", "Corn", "Banana", "apple", "banana"]
- load_locale("en_US")
assert natsorted(a, alg=ns.LOCALE | ns.CAPITALFIRST | ns.LOWERCASEFIRST) == [
"apple",
"banana",
@@ -361,8 +359,8 @@ def test_natsorted_with_LOCALE_and_CAPITALFIRST_and_LOWERCASE_returns_results_so
locale.setlocale(locale.LC_ALL, str(""))
+@pytest.mark.usefixtures("with_locale_en_us")
def test_natsorted_with_LOCALE_and_en_setting_returns_results_sorted_by_en_language():
- load_locale("en_US")
a = ["c", "a5,467.86", "ä", "b", "a5367.86", "a5,6", "a5,50"]
assert natsorted(a, alg=ns.LOCALE | ns.F) == [
"a5,6",
@@ -376,11 +374,8 @@ def test_natsorted_with_LOCALE_and_en_setting_returns_results_sorted_by_en_langu
locale.setlocale(locale.LC_ALL, str(""))
-@pytest.mark.skipif(
- not has_locale_de_DE, reason="requires de_DE locale and working locale"
-)
+@pytest.mark.usefixtures("with_locale_de_de")
def test_natsorted_with_LOCALE_and_de_setting_returns_results_sorted_by_de_language():
- load_locale("de_DE")
a = ["c", "a5.467,86", "ä", "b", "a5367.86", "a5,6", "a5,50"]
assert natsorted(a, alg=ns.LOCALE | ns.F) == [
"a5,50",
@@ -394,8 +389,8 @@ def test_natsorted_with_LOCALE_and_de_setting_returns_results_sorted_by_de_langu
locale.setlocale(locale.LC_ALL, str(""))
+@pytest.mark.usefixtures("with_locale_en_us")
def test_natsorted_with_LOCALE_and_mixed_input_returns_sorted_results_without_error():
- load_locale("en_US")
a = ["0", "Á", "2", "Z"]
assert natsorted(a, alg=ns.LOCALE) == ["0", "2", "Á", "Z"]
assert natsorted(a, alg=ns.LOCALE | ns.NUMAFTER) == ["Á", "Z", "0", "2"]
@@ -405,8 +400,8 @@ def test_natsorted_with_LOCALE_and_mixed_input_returns_sorted_results_without_er
locale.setlocale(locale.LC_ALL, str(""))
+@pytest.mark.usefixtures("with_locale_en_us")
def test_natsorted_with_LOCALE_and_UNGROUPLETTERS_and_mixed_input_returns_sorted_results_without_error():
- load_locale("en_US")
a = ["0", "Á", "2", "Z"]
assert natsorted(a, alg=ns.LOCALE | ns.UNGROUPLETTERS) == ["0", "2", "Á", "Z"]
assert natsorted(a, alg=ns.LOCALE | ns.UNGROUPLETTERS | ns.NUMAFTER) == [
@@ -427,8 +422,8 @@ def test_natsorted_with_LOCALE_and_UNGROUPLETTERS_and_mixed_input_returns_sorted
locale.setlocale(locale.LC_ALL, str(""))
+@pytest.mark.usefixtures("with_locale_en_us")
def test_natsorted_with_PATH_and_LOCALE_and_UNGROUPLETTERS_and_mixed_input_returns_sorted_results_without_error():
- load_locale("en_US")
a = ["0", "Á", "2", "Z"]
assert natsorted(a, alg=ns.PATH | ns.LOCALE | ns.UNGROUPLETTERS) == [
"0",
diff --git a/test_natsort/test_string_component_transform_factory.py b/test_natsort/test_string_component_transform_factory.py
index aa506c3..4f3eb38 100644
--- a/test_natsort/test_string_component_transform_factory.py
+++ b/test_natsort/test_string_component_transform_factory.py
@@ -6,11 +6,18 @@ from hypothesis import given
from hypothesis.strategies import floats, integers, text
from natsort.compat.fastnumbers import fast_float, fast_int
from natsort.compat.locale import get_strxfrm
-from natsort.compat.py23 import py23_str
+from natsort.compat.py23 import py23_str, py23_unichr, py23_range
from natsort.ns_enum import ns, ns_DUMB
from natsort.utils import _groupletters, _string_component_transform_factory
-from compat.locale import bad_uni_chars
+# There are some unicode values that are known failures with the builtin locale
+# library on BSD systems that has nothing to do with natsort (a ValueError is
+# raised by strxfrm). Let's filter them out.
+try:
+ bad_uni_chars = set(py23_unichr(x) for x in py23_range(0X10fefd, 0X10ffff + 1))
+except ValueError:
+ # Narrow unicode build... no worries.
+ bad_uni_chars = set()
def no_null(x):
diff --git a/test_natsort/test_utils.py b/test_natsort/test_utils.py
index b729adf..9f7c4bc 100644
--- a/test_natsort/test_utils.py
+++ b/test_natsort/test_utils.py
@@ -10,7 +10,7 @@ from operator import neg as op_neg
from hypothesis import given
from hypothesis.strategies import integers, lists, sampled_from, text
from natsort.compat.locale import null_string_locale
-from natsort.compat.py23 import py23_cmp, py23_str
+from natsort.compat.py23 import py23_cmp, py23_str, py23_lower
from natsort.ns_enum import ns
from natsort.utils import (
_args_to_enum,
@@ -24,7 +24,6 @@ from natsort.utils import (
)
from pytest import raises
-from compat.locale import low
from slow_splitters import add_leading_space_if_first_is_num, sep_inserter
@@ -172,7 +171,7 @@ def test_groupletters_returns_letters_with_lowercase_transform_of_letter_example
@given(text().filter(bool))
def test_groupeletters_returns_letters_with_lowercase_transform_of_letter(x):
- assert _groupletters(x) == "".join(chain.from_iterable([low(y), y] for y in x))
+ assert _groupletters(x) == "".join(chain.from_iterable([py23_lower(y), y] for y in x))
def test_sep_inserter_does_nothing_if_no_numbers_example():