Skip to content

Commit

Permalink
Seperate CLI app and class into two files
Browse files Browse the repository at this point in the history
  • Loading branch information
GDYendell committed Mar 13, 2017
1 parent 8447220 commit 2eb9790
Show file tree
Hide file tree
Showing 4 changed files with 242 additions and 228 deletions.
147 changes: 147 additions & 0 deletions tests/app_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import unittest
from pkg_resources import require

require("mock")
from mock import MagicMock, patch, call

from vdsgen import app

parser_patch_path = "argparse.ArgumentParser"
app_patch_path = "vdsgen.app"
VDSGenerator_patch_path = app_patch_path + ".VDSGenerator"


class ParseArgsTest(unittest.TestCase):

@patch(parser_patch_path + '.add_mutually_exclusive_group')
@patch(parser_patch_path + '.add_argument_group')
@patch(parser_patch_path + '.add_argument')
@patch(parser_patch_path + '.parse_args',
return_value=MagicMock(empty=False, files=None))
def test_parser(self, parse_mock, add_mock, add_group_mock,
add_exclusive_group_mock):
group_mock = add_group_mock.return_value
exclusive_group_mock = add_exclusive_group_mock.return_value

args = app.parse_args()

add_mock.assert_has_calls(
[call("path", type=str,
help="Root folder to create VDS in. Also where source "
"files are searched for if --prefix given."),
call("-o", "--output", type=str, default=None, dest="output",
help="Output file name. Default is input file prefix with "
"vds suffix."),
call("-e", "--empty", action="store_true", dest="empty",
help="Make empty VDS pointing to datasets "
"that don't exist, yet."),
call("-s", "--stripe_spacing", nargs="?", type=int, default=None,
dest="stripe_spacing",
help="Spacing between two stripes in a module."),
call("-m", "--module_spacing", nargs="?", type=int, default=None,
dest="module_spacing",
help="Spacing between two modules."),
call("--source_node", nargs="?", type=str, default=None,
dest="source_node",
help="Data node in source HDF5 files."),
call("--target_node", nargs="?", type=str, default=None,
dest="target_node",
help="Data node in VDS file.")])

add_group_mock.assert_called_with()
group_mock.add_argument.assert_has_calls(
[call("--frames", type=int, default=1, dest="frames",
help="Number of frames to combine into VDS."),
call("--height", type=int, default=256, dest="height",
help="Height of raw datasets."),
call("--width", type=int, default=1024, dest="width",
help="Width of raw datasets."),
call("--data_type", type=str, default="uint16", dest="data_type",
help="Data type of raw datasets.")])

add_exclusive_group_mock.assert_called_with(required=True)
exclusive_group_mock.add_argument.assert_has_calls(
[call("-p", "--prefix", type=str, default=None, dest="prefix",
help="Prefix of files - e.g 'stripe_' to combine the images "
"'stripe_1.hdf5', 'stripe_2.hdf5' and 'stripe_3.hdf5' "
"located at <path>."),
call("-f", "--files", nargs="*", type=str, default=None,
dest="files",
help="Manually define files to combine.")])

parse_mock.assert_called_once_with()
self.assertEqual(parse_mock.return_value, args)

@patch(parser_patch_path + '.error')
@patch(parser_patch_path + '.parse_args',
return_value=MagicMock(empty=True, files=None))
def test_empty_and_not_files_then_error(self, parse_mock, error_mock):

app.parse_args()

error_mock.assert_called_once_with(
"To make an empty VDS you must explicitly define --files for the "
"eventual raw datasets.")

@patch(parser_patch_path + '.error')
@patch(parser_patch_path + '.parse_args',
return_value=MagicMock(empty=True, files=["file"]))
def test_only_one_file_then_error(self, parse_mock, error_mock):

app.parse_args()

error_mock.assert_called_once_with(
"Must define at least two files to combine.")


class MainTest(unittest.TestCase):
@patch(VDSGenerator_patch_path)
@patch(app_patch_path + '.parse_args',
return_value=MagicMock(
path="/test/path", prefix="stripe_", empty=True,
files=["file1.hdf5", "file2.hdf5"], output="vds",
frames=3, height=256, width=2048, data_type="int16",
source_node="data", target_node="full_frame",
stripe_spacing=3, module_spacing=127))
def test_main_empty(self, parse_mock, init_mock):
gen_mock = init_mock.return_value
args_mock = parse_mock.return_value

app.main()

parse_mock.assert_called_once_with()
init_mock.assert_called_once_with(
args_mock.path,
prefix=args_mock.prefix, files=args_mock.files,
output=args_mock.output,
source=dict(frames=args_mock.frames, height=args_mock.height,
width=args_mock.width, dtype=args_mock.data_type),
source_node=args_mock.source_node,
target_node=args_mock.target_node,
stripe_spacing=args_mock.stripe_spacing,
module_spacing=args_mock.module_spacing)

gen_mock.generate_vds.assert_called_once_with()

@patch(VDSGenerator_patch_path)
@patch(app_patch_path + '.parse_args',
return_value=MagicMock(
path="/test/path", prefix="stripe_", empty=False,
files=["file1.hdf5", "file2.hdf5"], output="vds",
frames=3, height=256, width=2048, data_type="int16",
source_node="data", target_node="full_frame",
stripe_spacing=3, module_spacing=127))
def test_main_not_empty(self, parse_mock, generate_mock):
args_mock = parse_mock.return_value

app.main()

parse_mock.assert_called_once_with()
generate_mock.assert_called_once_with(
args_mock.path,
prefix=args_mock.prefix, output="vds", files=args_mock.files,
source=None,
source_node=args_mock.source_node,
stripe_spacing=args_mock.stripe_spacing,
target_node=args_mock.target_node,
module_spacing=args_mock.module_spacing)
137 changes: 0 additions & 137 deletions tests/vdsgen_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

vdsgen_patch_path = "vdsgen.vdsgen"
VDSGenerator_patch_path = vdsgen_patch_path + ".VDSGenerator"
parser_patch_path = "argparse.ArgumentParser"
h5py_patch_path = "h5py"

sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "h5py"))
Expand All @@ -31,88 +30,6 @@ def __init__(self, **kwargs):
self.__setattr__(attribute, value)


class ParseArgsTest(unittest.TestCase):

@patch(parser_patch_path + '.add_mutually_exclusive_group')
@patch(parser_patch_path + '.add_argument_group')
@patch(parser_patch_path + '.add_argument')
@patch(parser_patch_path + '.parse_args',
return_value=MagicMock(empty=False, files=None))
def test_parser(self, parse_mock, add_mock, add_group_mock,
add_exclusive_group_mock):
group_mock = add_group_mock.return_value
exclusive_group_mock = add_exclusive_group_mock.return_value

args = vdsgen.parse_args()

add_mock.assert_has_calls(
[call("path", type=str,
help="Root folder to create VDS in. Also where source "
"files are searched for if --prefix given."),
call("-o", "--output", type=str, default=None, dest="output",
help="Output file name. Default is input file prefix with "
"vds suffix."),
call("-e", "--empty", action="store_true", dest="empty",
help="Make empty VDS pointing to datasets "
"that don't exist, yet."),
call("-s", "--stripe_spacing", nargs="?", type=int, default=None,
dest="stripe_spacing",
help="Spacing between two stripes in a module."),
call("-m", "--module_spacing", nargs="?", type=int, default=None,
dest="module_spacing",
help="Spacing between two modules."),
call("--source_node", nargs="?", type=str, default=None,
dest="source_node",
help="Data node in source HDF5 files."),
call("--target_node", nargs="?", type=str, default=None,
dest="target_node",
help="Data node in VDS file.")])

add_group_mock.assert_called_with()
group_mock.add_argument.assert_has_calls(
[call("--frames", type=int, default=1, dest="frames",
help="Number of frames to combine into VDS."),
call("--height", type=int, default=256, dest="height",
help="Height of raw datasets."),
call("--width", type=int, default=1024, dest="width",
help="Width of raw datasets."),
call("--data_type", type=str, default="uint16", dest="data_type",
help="Data type of raw datasets.")])

add_exclusive_group_mock.assert_called_with(required=True)
exclusive_group_mock.add_argument.assert_has_calls(
[call("-p", "--prefix", type=str, default=None, dest="prefix",
help="Prefix of files - e.g 'stripe_' to combine the images "
"'stripe_1.hdf5', 'stripe_2.hdf5' and 'stripe_3.hdf5' "
"located at <path>."),
call("-f", "--files", nargs="*", type=str, default=None,
dest="files",
help="Manually define files to combine.")])

parse_mock.assert_called_once_with()
self.assertEqual(parse_mock.return_value, args)

@patch(parser_patch_path + '.error')
@patch(parser_patch_path + '.parse_args',
return_value=MagicMock(empty=True, files=None))
def test_empty_and_not_files_then_error(self, parse_mock, error_mock):

vdsgen.parse_args()

error_mock.assert_called_once_with(
"To make an empty VDS you must explicitly define --files for the "
"eventual raw datasets.")

@patch(parser_patch_path + '.error')
@patch(parser_patch_path + '.parse_args',
return_value=MagicMock(empty=True, files=["file"]))
def test_only_one_file_then_error(self, parse_mock, error_mock):
vdsgen.parse_args()

error_mock.assert_called_once_with(
"Must define at least two files to combine.")


class VDSGeneratorInitTest(unittest.TestCase):

@patch('os.path.isfile', return_value=True)
Expand Down Expand Up @@ -446,57 +363,3 @@ def test_generate_vds_node_exists_then_error(self, h5file_mock,

with self.assertRaises(IOError):
gen.generate_vds()


class MainTest(unittest.TestCase):

@patch(VDSGenerator_patch_path)
@patch(vdsgen_patch_path + '.parse_args',
return_value=MagicMock(
path="/test/path", prefix="stripe_", empty=True,
files=["file1.hdf5", "file2.hdf5"], output="vds",
frames=3, height=256, width=2048, data_type="int16",
source_node="data", target_node="full_frame",
stripe_spacing=3, module_spacing=127))
def test_main_empty(self, parse_mock, init_mock):
gen_mock = init_mock.return_value
args_mock = parse_mock.return_value

vdsgen.main()

parse_mock.assert_called_once_with()
init_mock.assert_called_once_with(
args_mock.path,
prefix=args_mock.prefix, files=args_mock.files,
output=args_mock.output,
source=dict(frames=args_mock.frames, height=args_mock.height,
width=args_mock.width, dtype=args_mock.data_type),
source_node=args_mock.source_node,
target_node=args_mock.target_node,
stripe_spacing=args_mock.stripe_spacing,
module_spacing=args_mock.module_spacing)

gen_mock.generate_vds.assert_called_once_with()

@patch(VDSGenerator_patch_path)
@patch(vdsgen_patch_path + '.parse_args',
return_value=MagicMock(
path="/test/path", prefix="stripe_", empty=False,
files=["file1.hdf5", "file2.hdf5"], output="vds",
frames=3, height=256, width=2048, data_type="int16",
source_node="data", target_node="full_frame",
stripe_spacing=3, module_spacing=127))
def test_main_not_empty(self, parse_mock, generate_mock):
args_mock = parse_mock.return_value

vdsgen.main()

parse_mock.assert_called_once_with()
generate_mock.assert_called_once_with(
args_mock.path,
prefix=args_mock.prefix, output="vds", files=args_mock.files,
source=None,
source_node=args_mock.source_node,
stripe_spacing=args_mock.stripe_spacing,
target_node=args_mock.target_node,
module_spacing=args_mock.module_spacing)
95 changes: 95 additions & 0 deletions vdsgen/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import sys
from argparse import ArgumentParser

from vdsgen import VDSGenerator


def parse_args():
"""Parse command line arguments."""
parser = ArgumentParser()
parser.add_argument("path", type=str,
help="Root folder to create VDS in. Also where source "
"files are searched for if --prefix given.")

# Definition of file names in <path> - Common prefix or explicit list
file_definition = parser.add_mutually_exclusive_group(required=True)
file_definition.add_argument(
"-p", "--prefix", type=str, default=None, dest="prefix",
help="Prefix of files - e.g 'stripe_' to combine the images "
"'stripe_1.hdf5', 'stripe_2.hdf5' and 'stripe_3.hdf5' located "
"at <path>.")
file_definition.add_argument(
"-f", "--files", nargs="*", type=str, default=None, dest="files",
help="Manually define files to combine.")
parser.add_argument(
"-o", "--output", type=str, default=None, dest="output",
help="Output file name. Default is input file prefix with vds suffix.")

# Arguments required to allow VDS to be created before raw files exist
parser.add_argument(
"-e", "--empty", action="store_true", dest="empty",
help="Make empty VDS pointing to datasets that don't exist, yet.")
source_metadata = parser.add_argument_group()
source_metadata.add_argument(
"--frames", type=int, default=1, dest="frames",
help="Number of frames to combine into VDS.")
source_metadata.add_argument(
"--height", type=int, default=256, dest="height",
help="Height of raw datasets.")
source_metadata.add_argument(
"--width", type=int, default=1024, dest="width",
help="Width of raw datasets.")
source_metadata.add_argument(
"--data_type", type=str, default="uint16", dest="data_type",
help="Data type of raw datasets.")

# Arguments to override defaults
parser.add_argument("-s", "--stripe_spacing", nargs="?", type=int,
default=None, dest="stripe_spacing",
help="Spacing between two stripes in a module.")
parser.add_argument("-m", "--module_spacing", nargs="?", type=int,
default=None, dest="module_spacing",
help="Spacing between two modules.")
parser.add_argument("--source_node", nargs="?", type=str, default=None,
dest="source_node",
help="Data node in source HDF5 files.")
parser.add_argument("--target_node", nargs="?", type=str, default=None,
dest="target_node",
help="Data node in VDS file.")

args = parser.parse_args()

if args.empty and args.files is None:
parser.error(
"To make an empty VDS you must explicitly define --files for the "
"eventual raw datasets.")
if args.files is not None and len(args.files) < 2:
parser.error("Must define at least two files to combine.")

return args


def main():
"""Run program."""
args = parse_args()

if args.empty:
source_metadata = dict(frames=args.frames, height=args.height,
width=args.width, dtype=args.data_type)
else:
source_metadata = None

gen = VDSGenerator(args.path,
prefix=args.prefix, files=args.files,
output=args.output,
source=source_metadata,
source_node=args.source_node,
target_node=args.target_node,
stripe_spacing=args.stripe_spacing,
module_spacing=args.module_spacing)

gen.generate_vds()


if __name__ == "__main__":
sys.exit(main())
Loading

0 comments on commit 2eb9790

Please sign in to comment.