From 4b0104cea9327e72f640b8ef25afb155bb085799 Mon Sep 17 00:00:00 2001 From: IAlibay Date: Wed, 15 Jul 2020 13:50:24 +0100 Subject: [PATCH] stringio tests --- propka/input.py | 4 +- tests/__init__.py | 1 + tests/test_basic_regression.py | 14 +++-- tests/test_streamio.py | 108 +++++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+), 8 deletions(-) create mode 100644 tests/__init__.py create mode 100644 tests/test_streamio.py diff --git a/propka/input.py b/propka/input.py index 2f425fe..2929ae3 100644 --- a/propka/input.py +++ b/propka/input.py @@ -20,7 +20,7 @@ def open_file_for_reading(input_file): Args: input_file: path to file or file-like object. If file-like object, - then will attempt fseek(0). + then will attempt seek(0). """ try: input_file.seek(0) @@ -36,7 +36,7 @@ def open_file_for_reading(input_file): def read_molecule_file(input_file, mol_container, filename=None): - """Read input file (PDB or PROPKA) for a molecular container + """Read input file or stream (PDB or PROPKA) for a molecular container Args input_file: input file to read diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1 @@ + diff --git a/tests/test_basic_regression.py b/tests/test_basic_regression.py index da8690e..c63785f 100644 --- a/tests/test_basic_regression.py +++ b/tests/test_basic_regression.py @@ -3,6 +3,7 @@ import logging import os import re from pathlib import Path +from io import StringIO import pytest from numpy.testing import assert_almost_equal from propka.parameters import Parameters @@ -154,7 +155,7 @@ def test_regression(pdb, options, tmp_path): compare_output(pdb, tmp_path, ref_path) -def run_propka_stream(options, input_file, tmp_path): +def run_propka_stream(options, input_file, filename, tmp_path): """Run PROPKA software. Args: @@ -162,7 +163,7 @@ def run_propka_stream(options, input_file, tmp_path): input_file: file-like PDB object tmp_path: path for working directory """ - options += [input_file.name] + options += [filename] args = loadOptions(options) try: _LOGGER.warning( @@ -173,7 +174,7 @@ def run_propka_stream(options, input_file, tmp_path): parameters = read_parameter_file(args.parameters, Parameters()) molecule = MolecularContainer(parameters, args) molecule = read_molecule_file(input_file, molecule, - filename=input_file.name) + filename=filename) molecule.calculate_pka() molecule.write_pka() if args.generate_propka_input: @@ -205,14 +206,15 @@ def test_filestream_regression(pdb, options, tmp_path): pdb_path = path_dict["pdbs"] / ("{0:s}.pdb".format(pdb)) if pdb_path.is_file(): pdb_path = pdb_path.resolve() - input_file = open(pdb_path) + #input_file = open(pdb_path) + with open(pdb_path, 'r') as writer: + io_file = StringIO(writer.read()) else: errstr = "Missing PDB file: {0:s}".format(pdb_path) raise FileNotFoundError(errstr) tmp_path = Path(tmp_path).resolve() - run_propka_stream(options, input_file, tmp_path) + run_propka_stream(options, io_file, f"{pdb}.pdb", tmp_path) if ref_path is not None: compare_output(pdb, tmp_path, ref_path) - input_file.close() diff --git a/tests/test_streamio.py b/tests/test_streamio.py new file mode 100644 index 0000000..d5b49f2 --- /dev/null +++ b/tests/test_streamio.py @@ -0,0 +1,108 @@ +"""Tests for PROPKA stream io""" +import logging +from pathlib import Path +from io import StringIO +import pytest +from propka.parameters import Parameters +from propka.molecular_container import MolecularContainer +from propka.input import read_parameter_file, read_molecule_file +from propka.lib import loadOptions + +from .test_basic_regression import get_test_dirs, compare_output + + +_LOGGER = logging.getLogger(__name__) + + +def get_paths(pdb): + """Helper function to get the path to the input and reference files""" + path_dict = get_test_dirs() + ref_path = path_dict["results"] / ("{0:s}.dat".format(pdb)) + pdb_path = path_dict["pdbs"] / ("{0:s}.pdb".format(pdb)) + + return ref_path.resolve(), pdb_path.resolve() + + +def run_propka_stream(options, input_file, filename): + """Run PROPKA software. + + Args: + options: list of PROPKA options + input_file: file-like PDB object + filename: filename for the file-like PDB object + tmp_path: path for working directory + """ + options += [filename] + args = loadOptions(options) + parameters = read_parameter_file(args.parameters, Parameters()) + molecule = MolecularContainer(parameters, args) + molecule = read_molecule_file(input_file, molecule, filename) + molecule.calculate_pka() + molecule.write_pka() + if args.generate_propka_input: + molecule.write_propka() + + +@pytest.mark.parametrize("pdb, options", [ + pytest.param("1FTJ-Chain-A", [], id="1FTJ-Chain-A: no options"), + pytest.param('3SGB-subset', [ + "--titrate_only", + "E:17,E:18,E:19,E:29,E:44,E:45,E:46,E:118,E:119,E:120,E:139"], + id="3SGB: --titrate_only"), + pytest.param('1HPX-warn', ['--quiet'], id="1HPX-warn: --quiet"), +]) +def test_textio_filestream(tmpdir, pdb, options): + """Basic regression test using TextIO streams for the input PDB file""" + # Get the relevant paths + ref_path, pdb_path = get_paths(pdb) + filename = f"{pdb}.pdb" + + filestream = open(pdb_path, 'r') + + with tmpdir.as_cwd(): + run_propka_stream(options, filestream, filename) + compare_output(pdb, Path.cwd(), ref_path) + + filestream.close() + + +@pytest.mark.parametrize("pdb, options", [ + pytest.param("1FTJ-Chain-A", [], id="1FTJ-Chain-A: no options"), + pytest.param('3SGB-subset', [ + "--titrate_only", + "E:17,E:18,E:19,E:29,E:44,E:45,E:46,E:118,E:119,E:120,E:139"], + id="3SGB: --titrate_only"), + pytest.param('1HPX-warn', ['--quiet'], id="1HPX-warn: --quiet"), +]) +def test_stringio_filestream(tmpdir, pdb, options): + """Basic regression test using StringIO streams for the input PDB file""" + # Get the relevant paths + ref_path, pdb_path = get_paths(pdb) + filename = f"{pdb}.pdb" + + with open(pdb_path, 'r') as writer: + filestream = StringIO(writer.read()) + + with tmpdir.as_cwd(): + run_propka_stream(options, filestream, filename) + compare_output(pdb, Path.cwd(), ref_path) + + filestream.close() + + +def test_typerror_nofilename(tmpdir): + """Tests for raised TypeError when not passing a filename to + read_molecule_file and using a file-like object without a name""" + pdb = "1FTJ-Chain-A" + options = [] + + ref_path, pdb_path = get_paths(pdb) + + with open(pdb_path, 'r') as writer: + filestream = StringIO(writer.read()) + + with tmpdir.as_cwd(): + errmsg = "Path of provided input_file could not be determined" + with pytest.raises(TypeError, match=errmsg): + # default value of filename is None + run_propka_stream(options, filestream, filename=None)