From 489a99a855db8e8da98b0129dcdb82fda7fef7a4 Mon Sep 17 00:00:00 2001 From: msftcangoblowme Date: Fri, 30 Aug 2024 10:59:11 +0000 Subject: [PATCH] ci adjustments need - ci: azure-pipelines coverage report omit setup.py - ci: azure-pipelines need --testall to get 100% coverage - ci: README.md affected by version. Update version - test: WorkDir - test: conftest fixture ensure_doc_scratch --- .coveragerc | 1 + CHANGELOG.md | 8 ++++++ README.md | 4 +-- azure-pipelines.yml | 2 +- conftest.py | 14 ++++----- tests/test_api_good.py | 14 +++++++-- tests/test_api_good_nonlocal.py | 7 ++--- tests/test_cli.py | 2 +- tests/test_cli_textconv.py | 4 +-- tests/test_cli_textconv_with_git.py | 44 +++++++++++++++++++++++++---- tests/test_fixture.py | 6 ++++ tests/wd_wrapper.py | 14 +++++---- 12 files changed, 89 insertions(+), 31 deletions(-) diff --git a/.coveragerc b/.coveragerc index d3b3b11b..38fa089d 100644 --- a/.coveragerc +++ b/.coveragerc @@ -5,6 +5,7 @@ source = omit = # Don't worry about covering vendored libraries src/sphobjinv/_vendored/* + setup.py [report] exclude_lines = diff --git a/CHANGELOG.md b/CHANGELOG.md index b39564e8..fd74bc16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,16 @@ changes. ### [2.4.1.11] - 2024-08-28 +#### Administrative + + * azure-pipelines coverage report omit setup.py + * README.md affected by version. Update version + * azure-pipelines need --testall to get 100% coverage + #### Tests + * test conftest fixture ensure_doc_scratch + * test WorkDir * fix inventory path must surround by single quotes * fix use git config to set textconv executable * add to WorkDir git config list/get/set support diff --git a/README.md b/README.md index f90a22a6..9e41df49 100644 --- a/README.md +++ b/README.md @@ -155,11 +155,11 @@ inventory creation/modification: >>> import sphobjinv as soi >>> inv = soi.Inventory('doc/build/html/objects.inv') >>> print(inv) - + >>> inv.project 'sphobjinv' >>> inv.version -'2.3' +'2.4' >>> inv.objects[0] DataObjStr(name='sphobjinv.cli.convert', domain='py', role='module', priority='0', uri='cli/implementation/convert.html#module-$', dispname='-') diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 64f0c2a2..0f3b31f4 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -247,7 +247,7 @@ stages: - script: cd doc; make html; mkdir scratch displayName: Build docset - - script: pytest --cov=. --nonloc --flake8_ext + - script: pytest --cov=. --nonloc --flake8_ext --testall displayName: Run pytest with coverage on the entire project tree - script: coverage report --include="tests/*" --fail-under=100 diff --git a/conftest.py b/conftest.py index f998fc2e..ff2ef048 100644 --- a/conftest.py +++ b/conftest.py @@ -198,7 +198,7 @@ def scratch_path(tmp_path, res_path, misc_info, is_win, unix2dos): # With the conversion of resources/objects_attrs.txt to Unix EOLs in order to # provide for a Unix-testable sdist, on Windows systems this resource needs # to be converted to DOS EOLs for consistency. - if is_win: + if is_win: # pragma: no cover win_path = tmp_path / f"{scr_base}{misc_info.Extensions.DEC.value}" win_path.write_bytes(unix2dos(win_path.read_bytes())) @@ -258,7 +258,7 @@ def func(path): """Perform the 'live' inventory load test.""" try: sphinx_ifile_load(path) - except Exception as e: # noqa: PIE786 + except Exception as e: # noqa: PIE786 # pragma: no cover # An exception here is a failing test, not a test error. pytest.fail(e) @@ -298,7 +298,7 @@ def func(arglist, *, expect=0): # , suffix=None): except SystemExit as e: retcode = e.args[0] ok = True - else: + else: # pragma: no cover ok = False # Do all pytesty stuff outside monkeypatch context @@ -331,7 +331,7 @@ def func(arglist, *, expect=0): # , suffix=None): except SystemExit as e: retcode = e.args[0] ok = True - else: + else: # pragma: no cover ok = False # Do all pytesty stuff outside monkeypatch context @@ -364,7 +364,7 @@ def func(arglist, *, prog="sphobjinv-textconv"): except SystemExit as e: retcode = e.args[0] is_system_exit = True - else: + else: # pragma: no cover is_system_exit = False return retcode, is_system_exit @@ -382,7 +382,7 @@ def func(path): res_bytes = Path(misc_info.res_decomp_path).read_bytes() tgt_bytes = Path(path).read_bytes() # .replace(b"\r\n", b"\n") - if is_win: + if is_win: # pragma: no cover # Have to explicitly convert these newlines, now that the # tests/resource/objects_attrs.txt file is marked 'binary' in # .gitattributes @@ -469,7 +469,7 @@ def func(path_cwd): path_f_dst = path_cwd / path_f_src.name path_f_dst.touch() assert path_f_dst.is_file() - if not path_f_src.exists(): + if not path_f_src.exists(): # pragma: no cover # workflow "Run test suite in sandbox" fails to find .gitattributes sep = os.linesep contents = ( diff --git a/tests/test_api_good.py b/tests/test_api_good.py index d5b12805..dcc0f30e 100644 --- a/tests/test_api_good.py +++ b/tests/test_api_good.py @@ -495,7 +495,12 @@ def test_api_inventory_datafile_gen_and_reimport( scr_fpath = scratch_path / fname # Drop most unless testall - if not pytestconfig.getoption("--testall") and fname != "objects_attrs.inv": + skips = ( + "objects_attrs.inv", + "objects_attrs_plus_one_entry.inv", + ) + is_not_test_all = not pytestconfig.getoption("--testall") + if is_not_test_all and fname not in skips: # pragma: no cover pytest.skip("'--testall' not specified") # Make Inventory @@ -529,7 +534,12 @@ def test_api_inventory_matches_sphinx_ifile( scr_fpath = scratch_path / fname # Drop most unless testall - if not pytestconfig.getoption("--testall") and fname != "objects_attrs.inv": + skips = ( + "objects_attrs.inv", + "objects_attrs_plus_one_entry.inv", + ) + is_not_test_all = not pytestconfig.getoption("--testall") + if is_not_test_all and fname not in skips: # pragma: no cover pytest.skip("'--testall' not specified") original_ifile_data = sphinx_ifile_load(testall_inv_path) diff --git a/tests/test_api_good_nonlocal.py b/tests/test_api_good_nonlocal.py index c4f61dab..94950db8 100644 --- a/tests/test_api_good_nonlocal.py +++ b/tests/test_api_good_nonlocal.py @@ -89,12 +89,9 @@ def test_api_inventory_many_url_imports( "objects_attrs_plus_one_entry.inv", ) is_not_testall = not pytestconfig.getoption("--testall") - if is_not_testall: - reason = "'--testall' not specified" - pytest.skip(reason) is_skip = fname in skips - if is_skip: - reason = f"skip online checks for theis inventory {fname}" + if is_not_testall or is_skip: # pragma: no cover + reason = "'--testall' not specified" pytest.skip(reason) # Construct inventories for comparison diff --git a/tests/test_cli.py b/tests/test_cli.py index 71f99b89..7c7250e9 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -222,7 +222,7 @@ def test_cli_convert_cycle_formats( if ( not pytestconfig.getoption("--testall") and testall_inv_path.name != "objects_attrs.inv" - ): + ): # pragma: no cover pytest.skip("'--testall' not specified") run_cmdline_test(["convert", "plain", str(res_src_path), str(plain_path)]) diff --git a/tests/test_cli_textconv.py b/tests/test_cli_textconv.py index d03f26a8..33894309 100644 --- a/tests/test_cli_textconv.py +++ b/tests/test_cli_textconv.py @@ -220,7 +220,7 @@ def test_cli_textconv_via_subprocess( text=True, capture_output=True, ) - except (sp.CalledProcessError, sp.TimeoutExpired): + except (sp.CalledProcessError, sp.TimeoutExpired): # pragma: no cover pytest.xfail() else: out = p_result.stdout @@ -280,7 +280,7 @@ def test_cli_textconv_zlib_inv_stdin( str_err = b_err.decode("utf-8") assert retcode == expected_retcode assert "Invalid plaintext or JSON inventory format." in str_err - else: + else: # pragma: no cover reason = ( "Piping in zlib inventory via stdin is not supported. " "Was expecting exit code 1" diff --git a/tests/test_cli_textconv_with_git.py b/tests/test_cli_textconv_with_git.py index e67d4f50..a8dcca37 100644 --- a/tests/test_cli_textconv_with_git.py +++ b/tests/test_cli_textconv_with_git.py @@ -85,11 +85,11 @@ def func(path_cwd): # On Windows, resolved executables paths resolved_soi_textconv_path = shutil.which(soi_textconv_path) - if resolved_soi_textconv_path is None: + if resolved_soi_textconv_path is None: # pragma: no cover resolved_soi_textconv_path = soi_textconv_path val = resolved_soi_textconv_path - if is_win: + if is_win: # pragma: no cover # On Windows, extensions Windows searches to find executables msg_info = f"""PATHEXT: {os.environ.get("PATHEXT", None)}""" logger_.info(msg_info) @@ -111,7 +111,7 @@ def func(path_cwd): reason = f"Unable to set git config setting {key} to {val}" assert is_success is True, reason - if is_win: + if is_win: # pragma: no cover # .git/config after update gc_contents = path_git_config_dst.read_text() msg_info = f""".git/config (after update):{os.linesep}{gc_contents}""" @@ -123,6 +123,38 @@ def func(path_cwd): class TestTextconvIntegration: """Prove git diff an compare |objects.inv| files.""" + def test_workdir( + self, + scratch_path, + ): + """Test interface of WorkDir.""" + path_cwd = scratch_path + wd = WorkDir(path_cwd) + + # __repr__ + assert len(repr(wd)) != 0 + + # run fail + cmd = "dsfsadfdsfsadfdsaf" + assert run(cmd) is None + + wd("git init") + wd("git config user.email test@example.com") + wd('git config user.name "a test"') + + # From .git/config get nonexistent key + invalid_key = "diff.sigfault.textconv" + assert wd.git_config_get(invalid_key) is None + + # Write bytes and str data to file + fname = "a.txt" + write_these = ( + b"aaaaa", + "aaaaa", + ) + for contents in write_these: + wd.write(fname, contents) + def test_textconv_git_diff( self, caplog, @@ -166,7 +198,7 @@ def test_textconv_git_diff( if is_win or is_linux: msg_info = f"cwd {wd.cwd!s}" logger.info(msg_info) - if is_win: + if is_win: # pragma: no cover from pathlib import WindowsPath soi_textconv_path = "sphobjinv-textconv" @@ -229,12 +261,12 @@ def test_textconv_git_diff( # Diagnostics before assertions # On error, not showing locals, so print source file and diff - if is_win or is_linux: + if is_win or is_linux: # pragma: no cover msg_info = f"cmd: {cmd}" logger.info(msg_info) msg_info = f"diff: {out}" logger.info(msg_info) - if retcode != 0: + if retcode != 0: # pragma: no cover msg_info = f"err: {err}" logger.info(msg_info) msg_info = f"regex: {expected_diff}" diff --git a/tests/test_fixture.py b/tests/test_fixture.py index 0a19aabe..f2063bef 100644 --- a/tests/test_fixture.py +++ b/tests/test_fixture.py @@ -73,3 +73,9 @@ def test_decomp_comp_fixture(misc_info, decomp_cmp_test, scratch_path): decomp_cmp_test( scratch_path / f"{misc_info.FNames.INIT.value}{misc_info.Extensions.DEC.value}" ) + + +def test_ensure_doc_scratch(scratch_path, ensure_doc_scratch): + """Test unused ensure_doc_scratch.""" + path_cwd = scratch_path + assert path_cwd.exists() and path_cwd.is_dir() diff --git a/tests/wd_wrapper.py b/tests/wd_wrapper.py index d43ea650..4f4f128e 100644 --- a/tests/wd_wrapper.py +++ b/tests/wd_wrapper.py @@ -50,7 +50,7 @@ def run( try: p_out = sp.run(cmd, cwd=cwd, text=True, capture_output=True) # noqa: S603 - except sp.CalledProcessError: + except (sp.CalledProcessError, FileNotFoundError): ret = None else: ret = p_out @@ -165,7 +165,7 @@ def _reason(self, given_reason: str | None) -> str: |str| -- formatted reason """ - if given_reason is None: + if given_reason is None: # pragma: no cover return f"number-{next(self.__counter)}" else: return given_reason @@ -218,7 +218,11 @@ def commit(self, reason: str | None = None, signed: bool = False) -> None: reason=reason, ) - def commit_testfile(self, reason: str | None = None, signed: bool = False) -> None: + def commit_testfile( + self, + reason: str | None = None, + signed: bool = False, + ) -> None: # pragma: no cover """Commit a test.txt file. Parameters @@ -340,7 +344,7 @@ def git_config_set( "config", dotted_key, ] - if is_path and is_win: + if is_path and is_win: # pragma: no cover # In Bash, single quotes protect (Windows path) backslashes # Does not deal with escaping spaces # `Path is Windows safe `_ @@ -353,7 +357,7 @@ def git_config_set( # git config diff.inv.textconv "sh -c 'sphobjinv co plain \"\$0\" -'" # git config diff.inv.textconv "sh -c 'sphobjinv-textconv \"\$0\"'" cp_out = run(cmd, cwd=self.cwd) - if cp_out is None or cp_out.returncode != 0: + if cp_out is None or cp_out.returncode != 0: # pragma: no cover ret = False else: ret = True