From 94bb11bfe6a9583896de6d54861af68e9ce6b957 Mon Sep 17 00:00:00 2001 From: Jeff Forcier Date: Fri, 17 Jan 2020 15:16:49 -0500 Subject: [PATCH] Migrate to pytest-relaxed from spec --- dev-requirements.txt | 3 +- docs/changelog.rst | 2 ++ integration/integration.py | 6 ++-- integration/util.py | 66 ++++++++++++++++++++------------------ setup.cfg | 4 +++ tasks.py | 7 ++-- tests/_util.py | 6 ++-- tests/organization.py | 35 ++++++++++---------- tests/presentation.py | 25 +++++++-------- 9 files changed, 80 insertions(+), 74 deletions(-) Index: releases-1.6.3/dev-requirements.txt =================================================================== --- releases-1.6.3.orig/dev-requirements.txt +++ releases-1.6.3/dev-requirements.txt @@ -2,7 +2,7 @@ invoke>=0.6.0,<2.0 invocations>=0.14,<2.0 # Tests (N.B. integration suite also uses Invoke as above) -spec>=0.11.3,<2.0 +pytest==4.6.9 mock==1.0.1 # Just for tests...heh six>=1.4.1,<2.0 Index: releases-1.6.3/docs/changelog.rst =================================================================== --- releases-1.6.3.orig/docs/changelog.rst +++ releases-1.6.3/docs/changelog.rst @@ -2,6 +2,7 @@ Changelog ========= +- :support:`-` Migrated the test suite to use ``pytest`` - :release:`1.6.3 <2020-01-10>` - :support:`87 backported` (via :issue:`88`) Our upper Sphinx version limit was mostly defensive and at this point is just too old to even build on Index: releases-1.6.3/tasks.py =================================================================== --- releases-1.6.3.orig/tasks.py +++ releases-1.6.3/tasks.py @@ -1,17 +1,14 @@ from os.path import join from invocations import docs -from invocations.testing import test, integration, watch_tests +from invocations.pytest import test, integration from invocations.packaging import release from invoke import Collection -ns = Collection(test, integration, watch_tests, release, docs) +ns = Collection(test, integration, release, docs) ns.configure({ - 'tests': { - 'package': 'releases', - }, 'packaging': { 'sign': True, 'wheel': True, Index: releases-1.6.3/tests/_util.py =================================================================== --- releases-1.6.3.orig/tests/_util.py +++ releases-1.6.3/tests/_util.py @@ -2,7 +2,6 @@ from docutils.nodes import ( list_item, paragraph, ) from mock import Mock -from spec import eq_, ok_ import six from releases import ( @@ -108,9 +107,10 @@ def expect_releases(entries, release_map err += "\nFull changelog: {!r}\n" for rel, issues in six.iteritems(release_map): found = changelog.pop(rel) - eq_(set(found), set(issues), err.format(rel, issues, found, snapshot)) + msg = err.format(rel, issues, found, snapshot) + assert set(found) == set(issues), msg # Sanity: ensure no leftover issue lists exist (empty ones are OK) for key in list(changelog.keys()): if not changelog[key]: del changelog[key] - ok_(not changelog, "Found leftovers: {}".format(changelog)) + assert not changelog, "Found leftovers: {}".format(changelog) Index: releases-1.6.3/tests/organization.py =================================================================== --- releases-1.6.3.orig/tests/organization.py +++ releases-1.6.3/tests/organization.py @@ -1,5 +1,6 @@ import six -from spec import Spec, eq_, raises, skip +from pytest import skip, raises +from unittest import TestCase from docutils.nodes import ( list_item, raw, paragraph, Text, ) @@ -20,58 +21,58 @@ from _util import ( ) -class organization(Spec): +class organization(TestCase): """ Organization of issues into releases (parsing) """ - def setup(self): + def setUp(self): setup_issues(self) def _expect_entries(self, all_entries, in_, not_in): # Grab 2nd release as 1st is the empty 'beginning of time' one entries = releases(*all_entries)[1]['entries'] - eq_(len(entries), len(in_)) + assert len(entries) == len(in_) for x in in_: assert x in entries for x in not_in: assert x not in entries - def feature_releases_include_features_and_support_not_bugs(self): + def test_feature_releases_include_features_and_support_not_bugs(self): self._expect_entries( ['1.1.0', self.f, self.b, self.s], [self.f, self.s], [self.b] ) - def feature_releases_include_major_bugs(self): + def test_feature_releases_include_major_bugs(self): self._expect_entries( ['1.1.0', self.f, self.b, self.mb], [self.f, self.mb], [self.b] ) - def bugfix_releases_include_bugs(self): + def test_bugfix_releases_include_bugs(self): self._expect_entries( ['1.0.2', self.f, self.b, self.mb], [self.b], [self.mb, self.f], ) - def bugfix_releases_include_backported_features(self): + def test_bugfix_releases_include_backported_features(self): self._expect_entries( ['1.0.2', self.bf, self.b, self.s], [self.b, self.bf], [self.s] ) - def bugfix_releases_include_backported_support(self): + def test_bugfix_releases_include_backported_support(self): self._expect_entries( ['1.0.2', self.f, self.b, self.s, self.bs], [self.b, self.bs], [self.s, self.f] ) - def backported_features_also_appear_in_feature_releases(self): + def test_backported_features_also_appear_in_feature_releases(self): entries = ( '1.1.0', '1.0.2', self.bf, self.b, self.s, ) @@ -82,35 +83,35 @@ class organization(Spec): } expect_releases(entries, expected) - def unmarked_bullet_list_items_treated_as_bugs(self): + def test_unmarked_bullet_list_items_treated_as_bugs(self): fake = list_item('', paragraph('', '', raw('', 'whatever'))) changelog = releases('1.0.2', self.f, fake) entries = changelog[1]['entries'] - eq_(len(entries), 1) + assert len(entries) == 1 assert self.f not in entries assert isinstance(entries[0], Issue) - eq_(entries[0].number, None) + assert entries[0].number is None - def unreleased_items_go_in_unreleased_releases(self): + def test_unreleased_items_go_in_unreleased_releases(self): changelog = releases(self.f, self.b) # Should have two unreleased lists, one feature w/ feature, one bugfix # w/ bugfix. bugfix, feature = changelog[1:] - eq_(len(feature['entries']), 1) - eq_(len(bugfix['entries']), 1) + assert len(feature['entries']) == 1 + assert len(bugfix['entries']) == 1 assert self.f in feature['entries'] assert self.b in bugfix['entries'] - eq_(feature['obj'].number, 'unreleased_1.x_feature') - eq_(bugfix['obj'].number, 'unreleased_1.x_bugfix') + assert feature['obj'].number == 'unreleased_1.x_feature' + assert bugfix['obj'].number == 'unreleased_1.x_bugfix' - def issues_consumed_by_releases_are_not_in_unreleased(self): + def test_issues_consumed_by_releases_are_not_in_unreleased(self): changelog = releases('1.0.2', self.f, self.b, self.s, self.bs) release = changelog[1]['entries'] unreleased = changelog[-1]['entries'] assert self.b in release assert self.b not in unreleased - def oddly_ordered_bugfix_releases_and_unreleased_list(self): + def test_oddly_ordered_bugfix_releases_and_unreleased_list(self): # Release set up w/ non-contiguous feature+bugfix releases; catches # funky problems with 'unreleased' buckets b2 = b(2) @@ -122,7 +123,7 @@ class organization(Spec): assert b2 in changelog[2]['entries'] assert b2 in changelog[3]['entries'] - def release_line_bugfix_specifier(self): + def test_release_line_bugfix_specifier(self): b50 = b(50) b42 = b(42, spec='1.1+') f25 = f(25) @@ -148,9 +149,9 @@ class organization(Spec): ('1.1.2', [b50, b42]), ('1.2.1', [b50, b42]), ): - eq_(set(c[rel]), set(issues)) + assert set(c[rel]) == set(issues) - def releases_can_specify_issues_explicitly(self): + def test_releases_can_specify_issues_explicitly(self): # Build regular list-o-entries b2 = b(2) b3 = b(3) @@ -172,13 +173,13 @@ class organization(Spec): assert b2 in one_1_1 assert b3 in one_1_1 - def explicit_release_list_split_works_with_unicode(self): + def test_explicit_release_list_split_works_with_unicode(self): changelog = release_list('1.0.1', b(17)) changelog[0][0].append(Text(six.text_type('17'))) # When using naive method calls, this explodes construct_releases(changelog, make_app()) - def explicit_feature_release_features_are_removed_from_unreleased(self): + def test_explicit_feature_release_features_are_removed_from_unreleased(self): f1 = f(1) f2 = f(2) changelog = release_list('1.1.0', f1, f2) @@ -193,7 +194,7 @@ class organization(Spec): # now-released feature 2 should not be in unreleased_feature assert f2 not in rendered['unreleased_1.x_feature'] - def explicit_bugfix_releases_get_removed_from_unreleased(self): + def test_explicit_bugfix_releases_get_removed_from_unreleased(self): b1 = b(1) b2 = b(2) changelog = release_list('1.0.1', b1, b2) @@ -205,27 +206,27 @@ class organization(Spec): assert b1 not in rendered[1]['entries'] # unreleased bug list should still get/see bug 1 assert b1 in rendered[2]['entries'] + + def test_explicit_releases_error_on_unfound_issues(self): + with raises(ValueError): + # Just a release - result will have 1.0.0, 1.0.1, and unreleased + changelog = release_list('1.0.1') + # No issues listed -> this clearly doesn't exist in any buckets + changelog[1][0].append(Text("25")) + # This should asplode + construct_releases(changelog, make_app()) - @raises(ValueError) - def explicit_releases_error_on_unfound_issues(self): - # Just a release - result will have 1.0.0, 1.0.1, and unreleased - changelog = release_list('1.0.1') - # No issues listed -> this clearly doesn't exist in any buckets - changelog[1][0].append(Text("25")) - # This should asplode - construct_releases(changelog, make_app()) - - def duplicate_issue_numbers_adds_two_issue_items(self): + def test_duplicate_issue_numbers_adds_two_issue_items(self): test_changelog = releases('1.0.1', self.b, self.b) test_changelog = changelog2dict(test_changelog) - eq_(len(test_changelog['1.0.1']), 2) + assert len(test_changelog['1.0.1']) == 2 - def duplicate_zeroes_dont_error(self): + def test_duplicate_zeroes_dont_error(self): cl = releases('1.0.1', b(0), b(0)) cl = changelog2dict(cl) assert len(cl['1.0.1']) == 2 - def issues_are_sorted_by_type_within_releases(self): + def test_issues_are_sorted_by_type_within_releases(self): b1 = b(123, major=True) b2 = b(124, major=True) s1 = s(25) @@ -239,9 +240,9 @@ class organization(Spec): # Order should be feature, bug, support. While it doesn't REALLY # matter, assert that within each category the order matches the old # 'reverse chronological' order. - eq_(changelog['1.1'], [f2, f1, b2, b1, s2, s1]) + assert changelog['1.1'], [f2, f1, b2, b1, s2 == s1] - def rolling_release_works_without_annotation(self): + def test_rolling_release_works_without_annotation(self): b1 = b(1) b2 = b(2) f3 = f(3) @@ -262,7 +263,7 @@ class organization(Spec): } expect_releases(entries, expected) - def plus_annotations_let_old_lines_continue_getting_released(self): + def test_plus_annotations_let_old_lines_continue_getting_released(self): b9 = b(9) f8 = f(8) f7 = f(7, spec="1.0+") @@ -288,7 +289,7 @@ class organization(Spec): } expect_releases(entries, expected) - def semver_spec_annotations_allow_preventing_forward_porting(self): + def test_semver_spec_annotations_allow_preventing_forward_porting(self): f9 = f(9, spec=">=1.0") f8 = f(8) b7 = b(7, spec="<2.0") @@ -331,7 +332,7 @@ class organization(Spec): } expect_releases(entries, expected) - def bugs_before_major_releases_associate_with_previous_release_only(self): + def test_bugs_before_major_releases_associate_with_previous_release_only(self): b1 = b(1) b2 = b(2) f3 = f(3) @@ -362,13 +363,13 @@ class organization(Spec): } expect_releases(entries, expected) - def semver_double_ended_specs_work_when_more_than_two_major_versions(self): + def test_semver_double_ended_specs_work_when_more_than_two_major_versions(self): skip() - def can_disable_default_pin_to_latest_major_version(self): + def test_can_disable_default_pin_to_latest_major_version(self): skip() - def features_before_first_release_function_correctly(self): + def test_features_before_first_release_function_correctly(self): f0 = f(0) b1 = b(1) f2 = f(2) @@ -384,7 +385,7 @@ class organization(Spec): # TODO: consider removing that entirely; arguably needing it is a bug? expect_releases(entries, expected, skip_initial=True) - def all_bugs_before_first_release_act_featurelike(self): + def test_all_bugs_before_first_release_act_featurelike(self): b1 = b(1) f2 = f(2) b3 = b(3) @@ -397,10 +398,10 @@ class organization(Spec): second = changelog['0.1.1'] assert b1 in first assert f2 in first - eq_(len(first), 3) # Meh, hard to assert about the implicit one - eq_(second, [b3]) + assert len(first) == 3 # Meh, hard to assert about the implicit one + assert second == [b3] - def specs_and_keywords_play_together_nicely(self): + def test_specs_and_keywords_play_together_nicely(self): b1 = b(1) b2 = b(2, major=True, spec='1.0+') f3 = f(3) @@ -426,18 +427,18 @@ class organization(Spec): } expect_releases(entries, expected) - def changelogs_without_any_releases_display_unreleased_normally(self): + def test_changelogs_without_any_releases_display_unreleased_normally(self): changelog = releases(self.f, self.b, skip_initial=True) # Ensure only the two unreleased 'releases' showed up - eq_(len(changelog), 2) + assert len(changelog) == 2 # And assert that both items appeared in one of them (since there's no # real releases at all, the bugfixes are treated as 'major' bugs, as # per concepts doc.) bugfix, feature = changelog - eq_(len(feature['entries']), 2) - eq_(len(bugfix['entries']), 0) + assert len(feature['entries']) == 2 + assert len(bugfix['entries']) == 0 - class unstable_prehistory: + class unstable_prehistory(TestCase): def _expect_releases(self, *args, **kwargs): """ expect_releases() wrapper setting unstable_prehistory by default @@ -445,7 +446,7 @@ class organization(Spec): kwargs['app'] = make_app(unstable_prehistory=True) return expect_releases(*args, **kwargs) - def all_issue_types_rolled_up_together(self): + def test_all_issue_types_rolled_up_together(self): # Pre-1.0-only base case entries = ( '0.1.1', @@ -461,7 +462,7 @@ class organization(Spec): } self._expect_releases(entries, expected, skip_initial=True) - def does_not_affect_releases_after_1_0(self): + def test_does_not_affect_releases_after_1_0(self): # Mixed changelog crossing 1.0 boundary entries = ( '1.1.0', @@ -483,7 +484,7 @@ class organization(Spec): } self._expect_releases(entries, expected, skip_initial=True) - def doesnt_care_if_you_skipped_1_0_entirely(self): + def test_doesnt_care_if_you_skipped_1_0_entirely(self): # Mixed changelog where 1.0 is totally skipped and one goes to 2.0 entries = ( '2.1.0', @@ -505,7 +506,7 @@ class organization(Spec): } self._expect_releases(entries, expected, skip_initial=True) - def explicit_unstable_releases_still_eat_their_issues(self): + def test_explicit_unstable_releases_still_eat_their_issues(self): # I.e. an 0.x.y releases using explicit issue listings, works # correctly - the explicitly listed issues don't appear in nearby # implicit releases. Index: releases-1.6.3/tests/presentation.py =================================================================== --- releases-1.6.3.orig/tests/presentation.py +++ releases-1.6.3/tests/presentation.py @@ -1,4 +1,3 @@ -from spec import Spec, eq_ from docutils.nodes import ( reference, bullet_list, list_item, literal, raw, paragraph, Text ) @@ -18,6 +17,7 @@ from _util import ( setup_issues, ) +from unittest import TestCase def _obj2name(obj): cls = obj if isinstance(obj, type) else obj.__class__ @@ -30,11 +30,11 @@ def _expect_type(node, cls): assert isinstance(node, cls), msg -class presentation(Spec): +class presentation(TestCase): """ Expansion/extension of docutils nodes (rendering) """ - def setup(self): + def setUp(self): setup_issues(self) def _generate(self, *entries, **kwargs): @@ -58,17 +58,17 @@ class presentation(Spec): assert expected in header elif type_ == 'issue': link = nodes[0][1][0][0][2] - eq_(link['refuri'], expected) + assert link['refuri'] == expected else: raise Exception("Gave unknown type_ kwarg to _test_link()!") - def issues_with_numbers_appear_as_number_links(self): + def test_test_issues_with_numbers_appear_as_number_links(self): self._test_link({}, 'issue', 'bar_15') - def releases_appear_as_header_links(self): + def test_test_releases_appear_as_header_links(self): self._test_link({}, 'release', 'foo_1.0.2') - def links_will_use_github_option_if_defined(self): + def test_links_will_use_github_option_if_defined(self): kwargs = { 'release_uri': None, 'issue_uri': None, @@ -80,7 +80,7 @@ class presentation(Spec): ): self._test_link(kwargs, type_, expected) - def issue_links_prefer_explicit_setting_over_github_setting(self): + def test_issue_links_prefer_explicit_setting_over_github_setting(self): kwargs = { 'release_uri': None, 'issue_uri': 'explicit_issue_%s', @@ -88,7 +88,7 @@ class presentation(Spec): } self._test_link(kwargs, 'issue', 'explicit_issue_15') - def release_links_prefer_explicit_setting_over_github_setting(self): + def test_release_links_prefer_explicit_setting_over_github_setting(self): kwargs = { 'release_uri': 'explicit_release_%s', 'issue_uri': None, @@ -96,7 +96,7 @@ class presentation(Spec): } self._test_link(kwargs, 'release', 'explicit_release_1.0.2') - def completely_blank_uri_settings_does_not_asplode(self): + def test_completely_blank_uri_settings_does_not_asplode(self): kwargs = { 'release_uri': None, 'issue_uri': None, @@ -117,48 +117,48 @@ class presentation(Spec): def _assert_prefix(self, entries, expectation): assert expectation in self._generate(*entries)[0][0][0] - def bugs_marked_as_bugs(self): + def test_bugs_marked_as_bugs(self): self._assert_prefix(['1.0.2', self.b], 'Bug') - def features_marked_as_features(self): + def test_features_marked_as_features(self): self._assert_prefix(['1.1.0', self.f], 'Feature') - def support_marked_as_support(self): + def test_support_marked_as_support(self): self._assert_prefix(['1.1.0', self.s], 'Support') - def dashed_issues_appear_as_unlinked_issues(self): + def test_dashed_issues_appear_as_unlinked_issues(self): node = self._generate('1.0.2', b('-')) assert not isinstance(node[0][2], reference) - def zeroed_issues_appear_as_unlinked_issues(self): + def test_zeroed_issues_appear_as_unlinked_issues(self): node = self._generate('1.0.2', b(0)) assert not isinstance(node[0][2], reference) - def un_prefixed_list_items_appear_as_unlinked_bugs(self): + def test_un_prefixed_list_items_appear_as_unlinked_bugs(self): fake = list_item('', paragraph('', '', Text("fixes an issue in "), literal('', 'methodname'))) node = self._generate('1.0.2', fake) # [, , , , ] - eq_(len(node[0]), 5) + assert len(node[0]) == 5 assert 'Bug' in str(node[0][0]) assert 'fixes an issue' in str(node[0][3]) assert 'methodname' in str(node[0][4]) - def un_prefixed_list_items_get_no_prefix_under_unstable_prehistory(self): + def test_un_prefixed_list_items_get_no_prefix_under_unstable_prehistory(self): app = make_app(unstable_prehistory=True) fake = list_item('', paragraph('', '', raw('', 'whatever'))) node = self._generate('0.1.0', fake, app=app, skip_initial=True) # [] - eq_(len(node[0]), 1) + assert len(node[0]) == 1 assert 'Bug' not in str(node[0][0]) assert 'whatever' in str(node[0][0]) - def issues_remain_wrapped_in_unordered_list_nodes(self): + def test_issues_remain_wrapped_in_unordered_list_nodes(self): node = self._generate('1.0.2', self.b, raw=True)[0][1] _expect_type(node, bullet_list) _expect_type(node[0], list_item) - def release_headers_have_local_style_tweaks(self): + def test_release_headers_have_local_style_tweaks(self): node = self._generate('1.0.2', self.b, raw=True)[0][0] _expect_type(node, raw) # Header w/ bottom margin @@ -166,18 +166,18 @@ class presentation(Spec): # Date span w/ font-size assert '