diff --git a/.flake8 b/.flake8 index 5ab2db54..e05076ad 100644 --- a/.flake8 +++ b/.flake8 @@ -18,4 +18,4 @@ exclude = # some in test cases max-line-length = 115 # TODO: re-enable E501 error -ignore: E226,E402,E501,E741,F401,F403,F811,W503,W504 +ignore: E226,E231,E402,E501,E741,F401,F403,F811,W503,W504 diff --git a/.github/workflows/upload_new_tag_to_pypi.yml b/.github/workflows/upload_new_tag_to_pypi.yml index a5f103ce..d1b2310a 100644 --- a/.github/workflows/upload_new_tag_to_pypi.yml +++ b/.github/workflows/upload_new_tag_to_pypi.yml @@ -35,10 +35,9 @@ jobs: run: >- twine check dist/* - - - name: Publish distribution 📦 to PyPI + - name: Publish 📦 to PyPI if: startsWith(github.ref, 'refs/tags') - uses: pypa/gh-action-pypi-publish@master + uses: pypa/gh-action-pypi-publish@release/v1 with: user: __token__ password: ${{ secrets.PYPI_API_TOKEN }} diff --git a/docs/source/validate.rst b/docs/source/validate.rst index e4fe4392..aec23eb2 100644 --- a/docs/source/validate.rst +++ b/docs/source/validate.rst @@ -6,14 +6,14 @@ Validation .. toctree:: :hidden: - + data_file_validation nxdl_file_validation *Validation* is the process of comparing an object with a standard. An important aspect of validation is the report of each aspect tested and whether or not it complies with the standard. This is a useful and necessary step when -composing NeXus HDF5 data files or software that will read NeXus data files and when +composing NeXus HDF5 data files or software that will read NeXus data files and when building NeXus Definition Language (NXDL) files. In NeXus, three basic types of object can be validated: @@ -34,26 +34,19 @@ validate a NeXus file .. code-block:: console :linenos: - - usage: punx validate [-h] [--report REPORT] [-l [LOGFILE]] [-i INTEREST] - infile - + + usage: punx validate [-h] [--report REPORT] infile + positional arguments: - infile HDF5 or NXDL file name - + infile HDF5 or NXDL file name + optional arguments: - -h, --help show this help message and exit - --report REPORT select which validation findings to report, choices: - COMMENT,ERROR,NOTE,OK,TODO,UNUSED,WARN - -l [LOGFILE], --logfile [LOGFILE] - log output to file (default: no log file) - -i INTEREST, --interest INTEREST - logging interest level (1 - 50), default=1 (Level 1) + -h, --help show this help message and exit + --report REPORT select which validation findings to report, choices: COMMENT,ERROR,NOTE,OK,OPTIONAL,TODO,UNUSED,WARN (separate with comma if more + than one, do not use white space) The **REPORT** findings are as presented in the table above for each validation step. -The logging **INTEREST** levels are for output from the program, - .. For now, refer to the source code documentation: :ref:`source.validate`. diff --git a/punx/main.py b/punx/main.py index 3525c5ab..e8703d5f 100755 --- a/punx/main.py +++ b/punx/main.py @@ -222,7 +222,7 @@ def func_validate(args): report_choices, trouble = [], [] for c in args.report.upper().split(","): if c in finding.VALID_STATUS_DICT: - report_choices.append(finding.VALID_STATUS_DICT[c]) + report_choices.append(c) else: trouble.append(c) if len(trouble) > 0: @@ -244,7 +244,7 @@ def func_validate(args): exit_message(str(_exc)) # report the findings from the validation - validator.print_report() + validator.print_report(statuses=report_choices) def _install(cm, grr, ref, use_user_cache=True, force=False): @@ -430,8 +430,11 @@ def parse_command_line_arguments(): p_sub.add_argument("infile", help="HDF5 or NXDL file name") p_sub.set_defaults(func=func_validate) reporting_choices = ",".join(sorted(finding.VALID_STATUS_DICT.keys())) - help_text = "select which validation findings to report, choices: " - help_text += reporting_choices + help_text = ( + "select which validation findings to report, " + f"choices: {reporting_choices}" + " (separate with comma if more than one, do not use white space)" + ) p_sub.add_argument("--report", default=reporting_choices, help=help_text) # TODO: add_logging_argument(p_sub) diff --git a/punx/tests/test_validate.py b/punx/tests/test_validate.py index a92f3914..7375d3b9 100644 --- a/punx/tests/test_validate.py +++ b/punx/tests/test_validate.py @@ -440,7 +440,7 @@ def TODO_test_axes_attribute_2D__fail(hfile): ds = dg.create_dataset("y", data=vec) ds.attrs["units"] = "mm" - dg.attrs["axes"] = utils.string_list_to_hdf5(["x,y", ]) + dg.attrs["axes"] = utils.string_list_to_hdf5(["x,y",]) dg.attrs["x_indices"] = [0] dg.attrs["y_indices"] = [1] @@ -654,4 +654,54 @@ def TODO_test_default_plot_v1_fail(hfile): # TODO: +@pytest.mark.parametrize( + "infile, report, observations", + [ + ["writer_1_3.hdf5", "TODO", 7], + ["writer_1_3.hdf5", "NOTE", 1], + ["writer_1_3.hdf5", "NOTE,TODO", 7 + 1], + ["writer_2_1.hdf5", "note", 0], + ["writer_2_1.hdf5", "TODO", 11], + ["1998spheres.h5", "ERROR", 2], + ["02_03_setup.h5", "NOTE,OPTIONAL,ERROR", 98 + 70 + 0], + ["prj_test.nexus.hdf5", "", 121], + ], +) +def test_report_option(infile, report, observations, capsys): + full_file_name = os.path.join(EXAMPLE_DATA_DIR, infile) + assert os.path.exists(full_file_name) + + if report == "": + report = ",".join(finding.VALID_STATUS_DICT.keys()) + reported_statuses = report.upper().split(",") + for s in reported_statuses: + assert s in finding.VALID_STATUS_DICT + + validator = validate.Data_File_Validator() + validator.validate(full_file_name) + validator.print_report(statuses=reported_statuses) + captured = capsys.readouterr() + lines = captured.out.splitlines() + assert len(lines) > 17 # length of 2nd table + + count = 0 + for line in captured.out.splitlines()[6:]: + if ( + # only look at content lines in first table + len(line.strip()) == 0 + or line.startswith("==") + or line.startswith("data file") + or line.startswith("NeXus definitions") + or line.startswith("findings") + or line.startswith("address") + ): + continue + if line.startswith("summary statistics"): + # end when 2nd (summary) table starts + break + assert line.split()[1] in reported_statuses + count += 1 + assert count == observations + + # Note: class Test_Example_data is already handled by test_data_files.py diff --git a/punx/validate.py b/punx/validate.py index 5ccd327f..b4f1b20c 100644 --- a/punx/validate.py +++ b/punx/validate.py @@ -169,10 +169,12 @@ def finding_summary(self, report_statuses=None): summary[f.status] += 1 return summary - def print_report(self): + def print_report(self, statuses=None): """ - print a validation report + Print a validation report. """ + reported_statuses = statuses or list(finding.VALID_STATUS_DICT.keys()) + print("data file: " + self.fname) print( "NeXus definitions ({}): {}, dated {}, sha={}\n".format( @@ -195,14 +197,13 @@ def sort_validations(f): for label in "address status test comments".split(): t.addLabel(label) for f in sorted(self.validations, key=sort_validations): - if f.status == finding.OPTIONAL: - continue # enable if you like verbose reports - row = [] - row.append(f.h5_address) - row.append(f.status) - row.append(f.test_name) - row.append(f.comment) - t.addRow(row) + if str(f.status) in reported_statuses: + row = [] + row.append(f.h5_address) + row.append(f.status) + row.append(f.test_name) + row.append(f.comment) + t.addRow(row) print(str(t)) summary = self.finding_summary()