Hello community,

here is the log from the commit of package python-pytest-spec for 
openSUSE:Factory checked in at 2019-12-18 14:47:07
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-pytest-spec (Old)
 and      /work/SRC/openSUSE:Factory/.python-pytest-spec.new.4691 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-pytest-spec"

Wed Dec 18 14:47:07 2019 rev:3 rq:757721 version:2.0.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-pytest-spec/python-pytest-spec.changes    
2019-08-22 15:17:57.590341467 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-pytest-spec.new.4691/python-pytest-spec.changes
  2019-12-18 14:48:52.733953999 +0100
@@ -1,0 +2,10 @@
+Wed Dec 18 04:32:03 UTC 2019 - John Vandenberg <[email protected]>
+
+- Dropped no longer necessary pytest4.patch
+- Update to v2.0.0
+  * Update documentation
+  * New format of output
+  * Fix small warnings
+  * Generate the package in wheel format
+
+-------------------------------------------------------------------

Old:
----
  pytest-spec-1.1.0.tar.gz
  pytest4.patch

New:
----
  pytest-spec-2.0.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-pytest-spec.spec ++++++
--- /var/tmp/diff_new_pack.W600rG/_old  2019-12-18 14:48:54.509954812 +0100
+++ /var/tmp/diff_new_pack.W600rG/_new  2019-12-18 14:48:54.533954822 +0100
@@ -18,7 +18,7 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-pytest-spec
-Version:        1.1.0
+Version:        2.0.0
 Release:        0
 Summary:        Plugin to display pytest execution output like a specification
 License:        GPL-2.0-only
@@ -26,7 +26,6 @@
 URL:            https://github.com/pchomik/pytest-spec
 Source:         
https://files.pythonhosted.org/packages/source/p/pytest-spec/pytest-spec-%{version}.tar.gz
 Source1:        
https://raw.githubusercontent.com/pchomik/pytest-spec/master/LICENSE.txt
-Patch0:         pytest4.patch
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
@@ -43,7 +42,6 @@
 
 %prep
 %setup -q -n pytest-spec-%{version}
-%patch0 -p1
 cp %{SOURCE1} .
 
 %build

++++++ pytest-spec-1.1.0.tar.gz -> pytest-spec-2.0.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-spec-1.1.0/PKG-INFO 
new/pytest-spec-2.0.0/PKG-INFO
--- old/pytest-spec-1.1.0/PKG-INFO      2016-12-06 22:47:11.000000000 +0100
+++ new/pytest-spec-2.0.0/PKG-INFO      2019-12-17 22:10:35.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.0
 Name: pytest-spec
-Version: 1.1.0
+Version: 2.0.0
 Summary: pytest plugin to display test execution output like a SPECIFICATION
 Home-page: https://github.com/pchomik/pytest-spec
 Author: Pawel Chomicki
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-spec-1.1.0/README.rst 
new/pytest-spec-2.0.0/README.rst
--- old/pytest-spec-1.1.0/README.rst    2016-12-06 21:10:46.000000000 +0100
+++ new/pytest-spec-2.0.0/README.rst    2019-12-17 22:09:46.000000000 +0100
@@ -9,6 +9,8 @@
 * Group tests by classes and files
 * Failed, passed and skipped are marked and colored.
 * Remove test\_ and underscores for every test.
+* Supports function based, class based test.
+* Supports describe like tests.
 
 
 Output example
@@ -18,15 +20,17 @@
 
     py.test --spec
 
-    test/test_results/test_as_class.py::TestResults
-        [SKIP]  Some method return none
-        [FAIL]  Some method returns false
-        [PASS]  Some method returns true
-
-    test/test_results/test_as_functions.py
-        [PASS]  Some method returns true
-        [FAIL]  Some method returns false
-        [SKIP]  Some method return none
+    test/test_results/test_as_class.py:
+
+    Results:
+        ✗ Some method return none
+        ? Some method returns false
+        ✓ Some method returns true
+
+    test/test_results/test_as_functions.py:
+    ✗ Some method returns false
+    ? Some method return none
+    ✓ Some method returns true
 
 
 Configuration
@@ -57,12 +61,12 @@
 
 Continuous Integration
 ======================
-.. image:: https://drone.io/github.com/pchomik/pytest-spec/status.png
-     :target: https://drone.io/github.com/pchomik/pytest-spec/latest
+.. image:: https://api.travis-ci.org/pchomik/pytest-spec.svg?branch=master
+     :target: https://travis-ci.org/pchomik/pytest-spec
 
 Download
 ========
-Latest version of plugin is available in `drone.io project artifacts 
<https://drone.io/github.com/pchomik/pytest-spec/files>`_.
+All versions of library are available on official `pypi server 
<https://pypi.org/project/pytest-spec/#history>`_.
 
 Install
 =======
@@ -76,8 +80,12 @@
 
 Contributors
 ============
-* dtk
-* Eric Carmichael
+* @0x64746b
+* @lucasmarshall
+* @amcgregor
+* @jhermann
+* @frenzymadness
+* @chrischambers
 
 Future plans
 ============
@@ -88,7 +96,7 @@
 =======
 pytest-spec - pytest plugin to display test execution output like a 
SPECIFICATION.
 
-Copyright (C) 2014-2016 Pawel Chomicki
+Copyright (C) 2014-2019 Pawel Chomicki
 
 This program is free software; you can redistribute it and/or modify it under 
the terms of the GNU General Public License as published by the Free Software 
Foundation; either version 2 of the License, or (at your option) any later 
version.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-spec-1.1.0/pytest_spec/patch.py 
new/pytest-spec-2.0.0/pytest_spec/patch.py
--- old/pytest-spec-1.1.0/pytest_spec/patch.py  2016-12-06 21:02:09.000000000 
+0100
+++ new/pytest-spec-2.0.0/pytest_spec/patch.py  2019-12-17 21:45:06.000000000 
+0100
@@ -11,16 +11,51 @@
 def pytest_runtest_logstart(self, nodeid, location):
     """Signal the start of running a single test item.
 
-    Hook has to be disabled because additional information may break output 
formatting.
+    Hook has to be disabled because additional information may break output
+    formatting.
     """
+    pass
+
+
+def pytest_collection_modifyitems(session, config, items):
+    def depth(f):
+        return len(f.listchain()) - 1
+
+    def get_module_name(f):
+        return f.listchain()[1].name
+    items.sort(key=depth)
+    items.sort(key=get_module_name)
+    return items
+
+
+def get_report_scopes(report):
+    """
+    Returns a list of the report's nested scopes, excluding the module.
+
+    >>> report = lambda s: s
+    >>> report.nodeid = (
+        "specs/user.py::describe_a_user::"
+        "describe_email_address::cannot_be_hotmail"
+    )
+    >>> get_report_scopes(report)
+    ['describe_a_user', 'describe_email_address']
+    """
+    return [i for i in report.nodeid.split('::')[1:-1] if i != '()']
 
 
 def pytest_runtest_logreport(self, report):
-    """Process a test setup/call/teardown report relating to the respective 
phase of executing a test.
+    """
+    Process a test setup/call/teardown report relating to the respective phase
+    of executing a test.
 
-    Hook changed to define SPECIFICATION like output format. This hook will 
overwrite also VERBOSE option.
+    Hook changed to define SPECIFICATION like output format. This hook will
+    overwrite also VERBOSE option.
     """
-    res = self.config.hook.pytest_report_teststatus(report=report)
+    self.previous_scopes = getattr(self, 'previous_scopes', [])
+    self.current_scopes = get_report_scopes(report)
+    indent = self.config.getini('spec_indent')
+
+    res = self.config.hook.pytest_report_teststatus(report=report, 
config=self.config)
     cat, letter, word = res
     self.stats.setdefault(cat, []).append(report)
     if not letter and not word:
@@ -30,11 +65,21 @@
     test_path = _get_test_path(report.nodeid, 
self.config.getini('spec_header_format'))
     if test_path != self.currentfspath:
         self.currentfspath = test_path
-        _print_class_information(self)
+        _print_description(self)
+
+    if self.previous_scopes != self.current_scopes:
+        msg = [i for i in self.current_scopes if i not in self.previous_scopes]
+        msg = [indent * ind + prettify_description(item)
+               for ind, item in enumerate(msg, len(self.current_scopes) - 1)]
+        msg = "\n".join(msg)
+        if msg:
+            _print_description(self, msg)
+        self.previous_scopes = self.current_scopes
     if not isinstance(word, tuple):
         test_name = _get_test_name(report.nodeid)
-        markup, test_status = _format_results(report)
-        _print_test_result(self, test_name, test_status, markup)
+        markup, test_status = _format_results(report, self.config)
+        depth = len(self.current_scopes)
+        _print_test_result(self, test_name, test_status, markup, depth)
 
 
 def _is_nodeid_has_test(nodeid):
@@ -43,34 +88,55 @@
     return False
 
 
+def prettify(string):
+    return _capitalize_first_letter(
+        _replace_underscores(
+            _remove_test_container_prefix(
+                _remove_file_extension(string))))
+
+
+def prettify_test(string):
+    return prettify(_remove_test_prefix(string))
+
+
+def prettify_description(string):
+    return prettify(_append_colon(_remove_test_container_prefix(string)))
+
+
 def _get_test_path(nodeid, header):
     levels = nodeid.split("::")
 
+    module_path = levels[0]
+    module_name = os.path.split(levels[0])[1]
+
     if len(levels) > 2:
         class_name = levels[1]
-        test_case = _split_words(_remove_class_prefix(class_name))
+        test_case = prettify(class_name)
     else:
-        module_name = os.path.split(levels[0])[1]
         class_name = ''
-        test_case = 
_capitalize_first_letter(_replace_underscores(_remove_test_prefix(_remove_file_extension(module_name))))
+        test_case = prettify(module_name)
 
-    return header.format(path=levels[0], class_name=class_name, 
test_case=test_case)
+    return header.format(
+        path=levels[0],
+        module_name=module_name,
+        module_path=module_path,
+        class_name=class_name,
+        test_case=test_case
+    )
 
 
-def _print_class_information(self):
+def _print_description(self, msg=None):
+    if msg is None:
+        msg = self.currentfspath
     if hasattr(self, '_first_triggered'):
         self._tw.line()
     self._tw.line()
-    self._tw.write(self.currentfspath)
+    self._tw.write(msg)
     self._first_triggered = True
 
 
-def _remove_class_prefix(nodeid):
-    return re.sub("^Test", "", nodeid)
-
-
-def _split_words(nodeid):
-    return re.sub(r"([A-Z])", r" \1", nodeid).strip()
+def _remove_test_container_prefix(nodeid):
+    return re.sub("^(Test)|(describe)", "", nodeid)
 
 
 def _remove_file_extension(nodeid):
@@ -93,8 +159,12 @@
     return s[:1].capitalize() + s[1:]
 
 
+def _append_colon(string):
+    return "{}:".format(string)
+
+
 def _get_test_name(nodeid):
-    test_name = 
_capitalize_first_letter(_replace_underscores(_remove_test_prefix(_remove_module_name(nodeid))))
+    test_name = prettify_test(_remove_module_name(nodeid))
     if test_name[:1] is ' ':
         test_name_parts = test_name.split('  ')
         if len(test_name_parts) == 1:
@@ -103,15 +173,23 @@
     return test_name
 
 
-def _format_results(report):
+def _format_results(report, config):
+    success_indicator = config.getini('spec_success_indicator')
+    failure_indicator = config.getini('spec_failure_indicator')
+    skipped_indicator = config.getini('spec_skipped_indicator')
     if report.passed:
-        return {'green': True}, 'PASS'
+        return {'green': True}, success_indicator
     elif report.failed:
-        return {'red': True}, 'FAIL'
+        return {'red': True}, failure_indicator
     elif report.skipped:
-        return {'yellow': True}, 'SKIP'
+        return {'yellow': True}, skipped_indicator
 
 
-def _print_test_result(self, test_name, test_status, markup):
+def _print_test_result(self, test_name, test_status, markup, depth):
+    indent = self.config.getini('spec_indent')
     self._tw.line()
-    self._tw.write("    
"+self.config.getini('spec_test_format').format(result=test_status, 
name=test_name), **markup)
+    self._tw.write(
+        indent * depth + self.config.getini('spec_test_format').format(
+            result=test_status, name=test_name
+        ), **markup
+    )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-spec-1.1.0/pytest_spec/plugin.py 
new/pytest-spec-2.0.0/pytest_spec/plugin.py
--- old/pytest-spec-1.1.0/pytest_spec/plugin.py 2016-12-06 21:02:37.000000000 
+0100
+++ new/pytest-spec-2.0.0/pytest_spec/plugin.py 2019-12-17 20:42:00.000000000 
+0100
@@ -3,7 +3,7 @@
 
 :author: Pawel Chomicki
 """
-from .replacer import logstart_replacer, report_replacer
+from .replacer import logstart_replacer, report_replacer, modifyitems_replacer
 
 
 def pytest_addoption(parser):
@@ -18,14 +18,34 @@
     # register config options
     parser.addini(
         'spec_header_format',
-        default='{path}::{class_name}',
+        default='{module_path}:',
         help='The format of the test headers when using the spec plugin'
     )
     parser.addini(
         'spec_test_format',
-        default='[{result}]  {name}',
+        default='{result} {name}',
         help='The format of the test results when using the spec plugin'
     )
+    parser.addini(
+        'spec_success_indicator',
+        default='✓',
+        help='The indicator displayed when a test passes'
+    )
+    parser.addini(
+        'spec_failure_indicator',
+        default='✗',
+        help='The indicator displayed when a test fails'
+    )
+    parser.addini(
+        'spec_skipped_indicator',
+        default='?',
+        help='The indicator displayed when a test is skipped'
+    )
+    parser.addini(
+        'spec_indent',
+        default='  ',
+        help='The string used for indentation in the spec output'
+    )
 
 
 def pytest_configure(config):
@@ -34,4 +54,5 @@
         import _pytest
         _pytest.terminal.TerminalReporter.pytest_runtest_logstart = 
logstart_replacer
         _pytest.terminal.TerminalReporter.pytest_runtest_logreport = 
report_replacer
+        _pytest.terminal.TerminalReporter.pytest_collection_modifyitems = 
modifyitems_replacer
         imp.reload(_pytest)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-spec-1.1.0/pytest_spec/replacer.py 
new/pytest-spec-2.0.0/pytest_spec/replacer.py
--- old/pytest-spec-1.1.0/pytest_spec/replacer.py       2016-12-01 
21:58:19.000000000 +0100
+++ new/pytest-spec-2.0.0/pytest_spec/replacer.py       2019-12-17 
20:42:00.000000000 +0100
@@ -1,11 +1,16 @@
 # -*- coding: utf-8 -*-
 """Module contains method for replace operation.
 
-Additional method are necessary because self is not yet defined and module 
doesn't have access to it.
+Additional method are necessary because self is not yet defined and module
+doesn't have access to it.
 
 :author: Pawel Chomicki
 """
-from .patch import pytest_runtest_logstart, pytest_runtest_logreport
+from .patch import (
+    pytest_runtest_logstart,
+    pytest_runtest_logreport,
+    pytest_collection_modifyitems
+)
 
 
 def logstart_replacer(self, nodeid, location):
@@ -18,3 +23,9 @@
     def wrapper():
         return pytest_runtest_logreport(self, report)
     return wrapper()
+
+
+def modifyitems_replacer(session, config, items):
+    def wrapper():
+        return pytest_collection_modifyitems(session, config, items)
+    return wrapper()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-spec-1.1.0/pytest_spec.egg-info/PKG-INFO 
new/pytest-spec-2.0.0/pytest_spec.egg-info/PKG-INFO
--- old/pytest-spec-1.1.0/pytest_spec.egg-info/PKG-INFO 2016-12-06 
22:47:10.000000000 +0100
+++ new/pytest-spec-2.0.0/pytest_spec.egg-info/PKG-INFO 2019-12-17 
22:10:35.000000000 +0100
@@ -1,6 +1,6 @@
 Metadata-Version: 1.0
 Name: pytest-spec
-Version: 1.1.0
+Version: 2.0.0
 Summary: pytest plugin to display test execution output like a SPECIFICATION
 Home-page: https://github.com/pchomik/pytest-spec
 Author: Pawel Chomicki
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-spec-1.1.0/setup.cfg 
new/pytest-spec-2.0.0/setup.cfg
--- old/pytest-spec-1.1.0/setup.cfg     2016-12-06 22:47:11.000000000 +0100
+++ new/pytest-spec-2.0.0/setup.cfg     2019-12-17 22:10:35.000000000 +0100
@@ -1,8 +1,7 @@
-[pytest]
+[tool:pytest]
 pep8maxlinelength = 150
 
 [egg_info]
 tag_build = 
 tag_date = 0
-tag_svn_revision = 0
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-spec-1.1.0/setup.py 
new/pytest-spec-2.0.0/setup.py
--- old/pytest-spec-1.1.0/setup.py      2016-12-06 21:05:33.000000000 +0100
+++ new/pytest-spec-2.0.0/setup.py      2019-12-17 21:46:33.000000000 +0100
@@ -13,7 +13,7 @@
 setup(
     name="pytest-spec",
     packages=['pytest_spec'],
-    version="1.1.0",
+    version="2.0.0",
     entry_points={'pytest11': ['pytest_spec = pytest_spec.plugin']},
     description="pytest plugin to display test execution output like a 
SPECIFICATION",
     author="Pawel Chomicki",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pytest-spec-1.1.0/test/test_patch.py 
new/pytest-spec-2.0.0/test/test_patch.py
--- old/pytest-spec-1.1.0/test/test_patch.py    2016-12-06 21:05:28.000000000 
+0100
+++ new/pytest-spec-2.0.0/test/test_patch.py    2019-12-17 21:45:53.000000000 
+0100
@@ -14,7 +14,7 @@
         self.letter = kwargs.get('letter', ' ')
         self.word = kwargs.get('word', ' ')
 
-    def pytest_report_teststatus(self, report):
+    def pytest_report_teststatus(self, report, config):
         return self.cat, self.letter, self.word
 
 
@@ -23,12 +23,20 @@
         self.hook = FakeHook(*args, **kwargs)
 
     def getini(self, option):
-        if option == 'spec_header_format':
-            return '{path}::{class_name}'
-        elif option == 'spec_test_format':
-            return '[{result}]  {name}'
-        else:
-            raise TypeError('Option {} is not supported in the 
test'.format(option))
+        mapping = {
+            'spec_header_format': '{module_path}:',
+            'spec_test_format': '{result} {name}',
+            'spec_success_indicator': '✓',
+            'spec_failure_indicator': '✗',
+            'spec_skipped_indicator': '?',
+            'spec_indent': '  ',
+        }
+        result = mapping.get(option, None)
+        if not result:
+            raise TypeError('Option {} is not supported in the test'.format(
+                option)
+            )
+        return result
 
 
 class FakeStats(object):
@@ -71,22 +79,31 @@
     def 
test__pytest_runtest_logreport__prints_class_name_before_first_test_result(self):
         fake_self = FakeSelf()
         pytest_runtest_logreport(fake_self, 
FakeReport('Test::Second::Test_example_demo'))
-        fake_self._tw.write.assert_has_calls([call('Test::Second')])
+        fake_self._tw.write.assert_has_calls([call('Second:')])
 
     def 
test__pytest_runtest_logreport__prints_test_name_and_passed_status(self):
         fake_self = FakeSelf()
         pytest_runtest_logreport(fake_self, 
FakeReport('Test::Second::test_example_demo'))
-        fake_self._tw.write.assert_has_calls([call('    [PASS]  Example demo', 
green=True)])
+        fake_self._tw.write.assert_has_calls([
+            call('Second:'),
+            call('  ✓ Example demo', green=True)
+        ])
 
     def 
test__pytest_runtest_logreport__prints_test_name_and_failed_status(self):
         fake_self = FakeSelf()
         pytest_runtest_logreport(fake_self, 
FakeReport('Test::Second::test_example_demo', passed=False, failed=True))
-        fake_self._tw.write.assert_has_calls([call('    [FAIL]  Example demo', 
red=True)])
+        fake_self._tw.write.assert_has_calls([
+            call('Second:'),
+            call('  ✗ Example demo', red=True)
+        ])
 
     def 
test__pytest_runtest_logreport__prints_test_name_and_skipped_status(self):
         fake_self = FakeSelf()
         pytest_runtest_logreport(fake_self, 
FakeReport('Test::Second::test_example_demo', passed=False, skipped=True))
-        fake_self._tw.write.assert_has_calls([call('    [SKIP]  Example demo', 
yellow=True)])
+        fake_self._tw.write.assert_has_calls([
+            call('Second:'),
+            call('  ? Example demo', yellow=True)
+        ])
 
     def test__pytest_runtest_logreport__skips_empty_line_for_first_test(self):
         fake_self = FakeSelf()
@@ -97,17 +114,26 @@
     def 
test__pytest_runtest_logreport__marks_method_marked_by_double_underscores(self):
         fake_self = FakeSelf()
         pytest_runtest_logreport(fake_self, 
FakeReport('Test::Second::test__example__demo'))
-        fake_self._tw.write.assert_has_calls([call('    [PASS]  Example demo', 
green=True)])
+        fake_self._tw.write.assert_has_calls([
+            call('Second:'),
+            call('  ✓ Example demo', green=True)
+        ])
 
     def 
test__pytest_runtest_logreport__prints_test_name_and_handle_only_single_marker(self):
         fake_self = FakeSelf()
         pytest_runtest_logreport(fake_self, 
FakeReport('Test::Second::test__example'))
-        fake_self._tw.write.assert_has_calls([call('    [PASS]  Example', 
green=True)])
+        fake_self._tw.write.assert_has_calls([
+            call('Second:'),
+            call('  ✓ Example', green=True)
+        ])
 
     def 
test__pytest_runtest_logreport__honors_capitalization_of_words_in_test_name(self):
         fake_self = FakeSelf()
         pytest_runtest_logreport(fake_self, 
FakeReport('Test::Second::test_example_Demo_CamelCase'))
-        fake_self._tw.write.assert_has_calls([call('    [PASS]  Example Demo 
CamelCase', green=True)])
+        fake_self._tw.write.assert_has_calls([
+            call('Second:'),
+            call('  ✓ Example Demo CamelCase', green=True)
+        ])
 
 
 if __name__ == '__main__':


Reply via email to