Accepting request 691614 from devel:languages:python

OBS-URL: https://build.opensuse.org/request/show/691614
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/python-jmespath?expand=0&rev=15
This commit is contained in:
Dominique Leuenberger 2019-04-08 08:30:46 +00:00 committed by Git OBS Bridge
commit 2539fe4dfb
3 changed files with 156 additions and 3 deletions

View File

@ -5,6 +5,15 @@ Tue Mar 26 14:43:27 UTC 2019 - Tomáš Chvátal <tchvatal@suse.com>
* Fix min_by/max_by with empty lists (`issue 151) * Fix min_by/max_by with empty lists (`issue 151)
* Fix reverse type for null type (issue 145) * Fix reverse type for null type (issue 145)
-------------------------------------------------------------------
Mon Mar 18 06:06:26 UTC 2019 - John Vandenberg <jayvdb@gmail.com>
- Add extra testing with hypothesis
- Remove unnecessary dependency on python-base
- Update to v0.9.4
* Fix min_by/max_by with empty lists
* Fix reverse type for null type
------------------------------------------------------------------- -------------------------------------------------------------------
Tue Dec 4 12:49:31 UTC 2018 - Matej Cepl <mcepl@suse.com> Tue Dec 4 12:49:31 UTC 2018 - Matej Cepl <mcepl@suse.com>

View File

@ -23,16 +23,17 @@ Release: 0
Summary: Python module for declarative JSON document element extraction Summary: Python module for declarative JSON document element extraction
License: MIT License: MIT
Group: Development/Languages/Python Group: Development/Languages/Python
URL: https://github.com/boto/jmespath URL: https://github.com/jmespath/jmespath.py
Source: https://files.pythonhosted.org/packages/source/j/jmespath/jmespath-%{version}.tar.gz Source: https://files.pythonhosted.org/packages/source/j/jmespath/jmespath-%{version}.tar.gz
Source1: https://raw.githubusercontent.com/jmespath/jmespath.py/develop/extra/test_hypothesis.py
# Testing # Testing
BuildRequires: %{python_module hypothesis}
BuildRequires: %{python_module nose} BuildRequires: %{python_module nose}
BuildRequires: %{python_module ply >= 3.4} BuildRequires: %{python_module ply >= 3.4}
BuildRequires: %{python_module setuptools} BuildRequires: %{python_module setuptools}
BuildRequires: %{python_module simplejson} BuildRequires: %{python_module simplejson}
BuildRequires: fdupes BuildRequires: fdupes
BuildRequires: python-rpm-macros BuildRequires: python-rpm-macros
Requires: python-base
Requires: python-ply >= 3.4 Requires: python-ply >= 3.4
Requires: python-simplejson Requires: python-simplejson
Requires(post): update-alternatives Requires(post): update-alternatives
@ -73,6 +74,7 @@ The expression: foo.*.name will return ["one", "two"].
%prep %prep
%setup -q -n jmespath-%{version} %setup -q -n jmespath-%{version}
cp %{SOURCE1} .
%build %build
%python_build %python_build
@ -84,7 +86,9 @@ mv %{buildroot}%{_bindir}/jp.py %{buildroot}%{_bindir}/jp
%python_expand %fdupes %{buildroot}%{$python_sitelib} %python_expand %fdupes %{buildroot}%{$python_sitelib}
%check %check
%python_expand nosetests-%{$python_bin_suffix} tests %{python_expand $python setup.py test
$python test_hypothesis.py
}
%post %post
%python_install_alternative jp %python_install_alternative jp

140
test_hypothesis.py Normal file
View File

@ -0,0 +1,140 @@
# Test suite using hypothesis to generate test cases.
# This is in a standalone module so that these tests
# can a) be run separately and b) allow for customization
# via env var for longer runs in travis.
import os
import sys
import numbers
from nose.plugins.skip import SkipTest
from hypothesis import given, settings, assume, HealthCheck
import hypothesis.strategies as st
from jmespath import lexer
from jmespath import parser
from jmespath import exceptions
from jmespath.functions import Functions
if sys.version_info[:2] == (2, 6):
raise RuntimeError("Hypothesis tests are not supported on python2.6. "
"Use python2.7, or python3.3 and greater.")
JSON_NUMBERS = (st.integers() | st.floats(allow_nan=False,
allow_infinity=False))
RANDOM_JSON = st.recursive(
JSON_NUMBERS | st.booleans() | st.text() | st.none(),
lambda children: st.lists(children) | st.dictionaries(st.text(), children)
)
MAX_EXAMPLES = int(os.environ.get('JP_MAX_EXAMPLES', 1000))
BASE_SETTINGS = {
'max_examples': MAX_EXAMPLES,
'suppress_health_check': [HealthCheck.too_slow],
}
# For all of these tests they verify these properties:
# either the operation succeeds or it raises a JMESPathError.
# If any other exception is raised then we error out.
@settings(**BASE_SETTINGS)
@given(st.text())
def test_lexer_api(expr):
try:
tokens = list(lexer.Lexer().tokenize(expr))
except exceptions.EmptyExpressionError:
return
except exceptions.LexerError as e:
assert e.lex_position >= 0, e.lex_position
assert e.lex_position < len(expr), e.lex_position
if expr:
assert expr[e.lex_position] == e.token_value[0], (
"Lex position does not match first token char.\n"
"Expression: %s\n%s != %s" % (expr, expr[e.lex_position],
e.token_value[0])
)
return
except Exception as e:
raise AssertionError("Non JMESPathError raised: %s" % e)
assert isinstance(tokens, list)
# Token starting positions must be unique, can't have two
# tokens with the same start position.
start_locations = [t['start'] for t in tokens]
assert len(set(start_locations)) == len(start_locations), (
"Tokens must have unique starting locations.")
# Starting positions must be increasing (i.e sorted).
assert sorted(start_locations) == start_locations, (
"Tokens must have increasing start locations.")
# Last token is always EOF.
assert tokens[-1]['type'] == 'eof'
@settings(**BASE_SETTINGS)
@given(st.text())
def test_parser_api_from_str(expr):
# Same a lexer above with the assumption that we're parsing
# a valid sequence of tokens.
try:
list(lexer.Lexer().tokenize(expr))
except exceptions.JMESPathError as e:
# We want to try to parse things that tokenize
# properly.
assume(False)
try:
ast = parser.Parser().parse(expr)
except exceptions.JMESPathError as e:
return
except Exception as e:
raise AssertionError("Non JMESPathError raised: %s" % e)
assert isinstance(ast.parsed, dict)
assert 'type' in ast.parsed
assert 'children' in ast.parsed
assert isinstance(ast.parsed['children'], list)
@settings(**BASE_SETTINGS)
@given(expr=st.text(), data=RANDOM_JSON)
def test_search_api(expr, data):
try:
ast = parser.Parser().parse(expr)
except exceptions.JMESPathError as e:
# We want to try to parse things that tokenize
# properly.
assume(False)
try:
ast.search(data)
except exceptions.JMESPathError as e:
return
except Exception as e:
raise AssertionError("Non JMESPathError raised: %s" % e)
# Additional property tests for functions.
@given(arg=JSON_NUMBERS)
def test_abs(arg):
assert Functions().call_function('abs', [arg]) >= 0
@given(arg=st.lists(JSON_NUMBERS))
def test_avg(arg):
result = Functions().call_function('avg', [arg])
if result is not None:
assert isinstance(result, numbers.Number)
@given(arg=st.lists(st.floats() | st.booleans() | st.text() | st.none(),
min_size=1))
def test_not_null(arg):
result = Functions().call_function('not_null', arg)
if result is not None:
assert result in arg
@given(arg=RANDOM_JSON)
def test_to_number(arg):
result = Functions().call_function('to_number', [arg])
if result is not None:
assert isinstance(result, numbers.Number)