diff --git a/tests/app_test.py b/tests/app_test.py new file mode 100644 index 0000000..c53aa67 --- /dev/null +++ b/tests/app_test.py @@ -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 ."), + 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) \ No newline at end of file diff --git a/tests/vdsgen_test.py b/tests/vdsgen_test.py index 21933c4..c6b0321 100644 --- a/tests/vdsgen_test.py +++ b/tests/vdsgen_test.py @@ -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")) @@ -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 ."), - 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) @@ -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) diff --git a/vdsgen/app.py b/vdsgen/app.py new file mode 100644 index 0000000..3a6426e --- /dev/null +++ b/vdsgen/app.py @@ -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 - 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 .") + 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()) diff --git a/vdsgen/vdsgen.py b/vdsgen/vdsgen.py index 4e1ab7b..a2807c3 100644 --- a/vdsgen/vdsgen.py +++ b/vdsgen/vdsgen.py @@ -3,7 +3,6 @@ import os import sys -from argparse import ArgumentParser import re import logging @@ -17,71 +16,6 @@ VDS = namedtuple("VDS", ["shape", "spacing"]) -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 - 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 .") - 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 - - class VDSGenerator(object): """A class to generate Virtual Datasets from raw HDF5 files.""" @@ -339,28 +273,3 @@ def validate_node(self, vds_file): sub_group = self.target_node.rsplit("/", 1)[0] if vds_file.get(sub_group) is None: vds_file.create_group(sub_group) - - -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())