def test_variadic_inputs(self): qiime_cli = RootCommand() command = qiime_cli.get_command(ctx=None, name='dummy-plugin') output_path = os.path.join(self.tempdir, 'output.qza') ints1 = Artifact.import_data('IntSequence1', [1, 2, 3]).save( os.path.join(self.tempdir, 'ints1.qza')) ints2 = Artifact.import_data('IntSequence2', [4, 5, 6]).save( os.path.join(self.tempdir, 'ints2.qza')) set1 = Artifact.import_data('SingleInt', 7).save( os.path.join(self.tempdir, 'set1.qza')) set2 = Artifact.import_data('SingleInt', 8).save( os.path.join(self.tempdir, 'set2.qza')) result = self.runner.invoke(command, [ 'variadic-input-method', '--i-ints', ints1, '--i-ints', ints2, '--i-int-set', set1, '--i-int-set', set2, '--p-nums', '9', '--p-nums', '10', '--p-opt-nums', '11', '--p-opt-nums', '12', '--p-opt-nums', '13', '--o-output', output_path, '--verbose' ]) self.assertEqual(result.exit_code, 0) self.assertTrue(os.path.exists(output_path)) output = Artifact.load(output_path) self.assertEqual(output.view(list), list(range(1, 14)))
def test_repeated_multiple_option(self): input_path = os.path.join(self.tempdir, 'ints.qza') artifact = Artifact.import_data(IntSequence1, [0, 42, 43], list) artifact.save(input_path) metadata_path1 = os.path.join(self.tempdir, 'metadata1.tsv') with open(metadata_path1, 'w') as f: f.write('id\tcol1\nid1\tfoo\nid2\tbar\n') metadata_path2 = os.path.join(self.tempdir, 'metadata2.tsv') with open(metadata_path2, 'w') as f: f.write('id\tcol2\nid1\tbaz\nid2\tbaa\n') output_path = os.path.join(self.tempdir, 'out.qza') qiime_cli = RootCommand() command = qiime_cli.get_command(ctx=None, name='dummy-plugin') result = self.runner.invoke(command, [ 'identity-with-metadata', '--i-ints', input_path, '--o-out', output_path, '--m-metadata-file', metadata_path1, '--m-metadata-file', metadata_path2, '--verbose' ]) self.assertEqual(result.exit_code, 0) self.assertTrue(os.path.exists(output_path)) self.assertEqual(Artifact.load(output_path).view(list), [0, 42, 43])
def test_list_commands(self): # top level commands, including a plugin, are present qiime_cli = RootCommand() commands = qiime_cli.list_commands(ctx=None) self.assertTrue('info' in commands) self.assertTrue('tools' in commands) self.assertTrue('dummy-plugin' in commands)
def test_split_ints(self): qiime_cli = RootCommand() command = qiime_cli.get_command(ctx=None, name='dummy-plugin') # build output file names left_path = os.path.join(self.tempdir, 'left.qza') right_path = os.path.join(self.tempdir, 'right.qza') # TODO: currently must pass `--verbose` to commands invoked by Click's # test runner because redirecting stdout/stderr raises an # "io.UnsupportedOperation: fileno" error. Likely related to Click # mocking a filesystem in the test runner. result = self.runner.invoke(command, [ 'split-ints', '--i-ints', self.artifact1_path, '--o-left', left_path, '--o-right', right_path, '--verbose' ]) # command completes successfully and creates the correct # output files self.assertEqual(result.exit_code, 0) self.assertTrue(os.path.exists(left_path)) self.assertTrue(os.path.exists(right_path)) # results are correct left = Artifact.load(left_path) right = Artifact.load(right_path) self.assertEqual(left.view(list), [0]) self.assertEqual(right.view(list), [42, 43])
def test_variadic_inputs(self): qiime_cli = RootCommand() command = qiime_cli.get_command(ctx=None, name='dummy-plugin') output_path = os.path.join(self.tempdir, 'output.qza') ints1 = Artifact.import_data('IntSequence1', [1, 2, 3]).save( os.path.join(self.tempdir, 'ints1.qza')) ints2 = Artifact.import_data('IntSequence2', [4, 5, 6]).save( os.path.join(self.tempdir, 'ints2.qza')) set1 = Artifact.import_data('SingleInt', 7).save( os.path.join(self.tempdir, 'set1.qza')) set2 = Artifact.import_data('SingleInt', 8).save( os.path.join(self.tempdir, 'set2.qza')) result = self.runner.invoke( command, ['variadic-input-method', '--i-ints', ints1, '--i-ints', ints2, '--i-int-set', set1, '--i-int-set', set2, '--p-nums', '9', '--p-nums', '10', '--p-opt-nums', '11', '--p-opt-nums', '12', '--p-opt-nums', '13', '--o-output', output_path, '--verbose']) self.assertEqual(result.exit_code, 0) self.assertTrue(os.path.exists(output_path)) output = Artifact.load(output_path) self.assertEqual(output.view(list), list(range(1, 14)))
def test_split_ints(self): qiime_cli = RootCommand() command = qiime_cli.get_command(ctx=None, name='dummy-plugin') # build output file names left_path = os.path.join(self.tempdir, 'left.qza') right_path = os.path.join(self.tempdir, 'right.qza') # TODO: currently must pass `--verbose` to commands invoked by Click's # test runner because redirecting stdout/stderr raises an # "io.UnsupportedOperation: fileno" error. Likely related to Click # mocking a filesystem in the test runner. result = self.runner.invoke( command, ['split-ints', '--i-ints', self.artifact1_path, '--o-left', left_path, '--o-right', right_path, '--verbose']) # command completes successfully and creates the correct # output files self.assertEqual(result.exit_code, 0) self.assertTrue(os.path.exists(left_path)) self.assertTrue(os.path.exists(right_path)) # results are correct left = Artifact.load(left_path) right = Artifact.load(right_path) self.assertEqual(left.view(list), [0]) self.assertEqual(right.view(list), [42, 43])
def test_repeated_multiple_option(self): input_path = os.path.join(self.tempdir, 'ints.qza') artifact = Artifact.import_data(IntSequence1, [0, 42, 43], list) artifact.save(input_path) metadata_path1 = os.path.join(self.tempdir, 'metadata1.tsv') with open(metadata_path1, 'w') as f: f.write('id\tcol1\nid1\tfoo\nid2\tbar\n') metadata_path2 = os.path.join(self.tempdir, 'metadata2.tsv') with open(metadata_path2, 'w') as f: f.write('id\tcol2\nid1\tbaz\nid2\tbaa\n') output_path = os.path.join(self.tempdir, 'out.qza') qiime_cli = RootCommand() command = qiime_cli.get_command(ctx=None, name='dummy-plugin') result = self.runner.invoke( command, ['identity-with-metadata', '--i-ints', input_path, '--o-out', output_path, '--m-metadata-file', metadata_path1, '--m-metadata-file', metadata_path2, '--verbose']) self.assertEqual(result.exit_code, 0) self.assertTrue(os.path.exists(output_path)) self.assertEqual(Artifact.load(output_path).view(list), [0, 42, 43])
def test_deprecated_help_text(self): qiime_cli = RootCommand() command = qiime_cli.get_command(ctx=None, name='dummy-plugin') result = self.runner.invoke(command, ['deprecated-method', '--help']) self.assertEqual(result.exit_code, 0) self.assertTrue('WARNING' in result.output) self.assertTrue('deprecated' in result.output)
def test_repeated_action_option(self): qiime_cli = RootCommand() command = qiime_cli.get_command(ctx=None, name='dummy-plugin') out_path = os.path.join(self.tempdir, 'out.qza') result = self.runner.invoke( command, ['no-input-method', '--o-out', out_path, '--o-out', out_path]) self._assertRepeatedOptionError(result, '--o-out')
def test_plugin_list_commands(self): # plugin commands are present including a method and visualizer qiime_cli = RootCommand() command = qiime_cli.get_command(ctx=None, name='dummy-plugin') commands = command.list_commands(ctx=None) self.assertTrue('split-ints' in commands) self.assertTrue('mapping-viz' in commands) self.assertFalse('split_ints' in commands) self.assertFalse('mapping_viz' in commands)
def test_verbose_shows_stacktrace(self): qiime_cli = RootCommand() command = qiime_cli.get_command(ctx=None, name='dummy-plugin') output = os.path.join(self.tempdir, 'never-happens.qza') result = self.runner.invoke(command, [ 'failing-pipeline', '--i-int-sequence', self.artifact1_path, '--o-mapping', output, '--p-break-from', 'internal', '--verbose' ]) self.assertEqual(result.exit_code, 1) self.assertIn('Traceback (most recent call last)', result.output)
def test_verbose_shows_stacktrace(self): qiime_cli = RootCommand() command = qiime_cli.get_command(ctx=None, name='dummy-plugin') output = os.path.join(self.tempdir, 'never-happens.qza') result = self.runner.invoke( command, ['failing-pipeline', '--i-int-sequence', self.artifact1_path, '--o-mapping', output, '--p-break-from', 'internal', '--verbose']) self.assertEqual(result.exit_code, 1) self.assertIn('Traceback (most recent call last)', result.output)
def test_without_inputs_or_parameters(self): qiime_cli = RootCommand() command = qiime_cli.get_command(ctx=None, name='dummy-plugin') output_path = os.path.join(self.tempdir, 'output.qza') result = self.runner.invoke( command, ['no-input-method', '--o-out', output_path, '--verbose']) self.assertEqual(result.exit_code, 0) self.assertTrue(os.path.exists(output_path)) artifact = Artifact.load(output_path) self.assertEqual(artifact.view(dict), {'foo': '42'})
def test_visualization(self): # make a viz first: qiime_cli = RootCommand() command = qiime_cli.get_command(ctx=None, name='dummy-plugin') # build output parameter arguments and expected output file names viz_path = os.path.join(self.tempdir, 'viz.qzv') result = self.runner.invoke( command, ['most-common-viz', '--i-ints', self.ints1, '--o-visualization', viz_path, '--verbose']) result = self.runner.invoke(tools, ['inspect-metadata', viz_path]) self.assertEqual(result.exit_code, 1) self.assertIn("Visualizations cannot be viewed as QIIME 2 metadata", result.output)
def setUp(self): get_dummy_plugin() self.runner = CliRunner() self.plugin_command = RootCommand().get_command(ctx=None, name='dummy-plugin') self.tempdir = tempfile.mkdtemp(prefix='qiime2-q2cli-test-temp-') self.input_artifact = os.path.join(self.tempdir, 'in.qza') Artifact.import_data(IntSequence1, [0, 42, 43], list).save(self.input_artifact) self.output_artifact = os.path.join(self.tempdir, 'out.qza') self.metadata_file1 = os.path.join(self.tempdir, 'metadata1.tsv') with open(self.metadata_file1, 'w') as f: f.write('id\tcol1\n0\tfoo\nid1\tbar\n') self.metadata_file_alt_id_header = os.path.join( self.tempdir, 'metadata-alt-id-header.tsv') with open(self.metadata_file_alt_id_header, 'w') as f: f.write('#SampleID\tcol1\n0\tfoo\nid1\tbar\n') self.metadata_file2 = os.path.join(self.tempdir, 'metadata2.tsv') with open(self.metadata_file2, 'w') as f: f.write('id\tcol2\n0\tbaz\nid1\tbaa\n') self.metadata_file_mixed_types = os.path.join( self.tempdir, 'metadata-mixed-types.tsv') with open(self.metadata_file_mixed_types, 'w') as f: f.write('id\tnumbers\tstrings\nid1\t42\tabc\nid2\t-1.5\tdef\n') self.metadata_artifact = os.path.join(self.tempdir, 'metadata.qza') Artifact.import_data('Mapping', { 'a': 'dog', 'b': 'cat' }).save(self.metadata_artifact)
def test_syntax_error_in_env(self): qiime_cli = RootCommand() command = qiime_cli.get_command(ctx=None, name='dummy-plugin') viz_path = os.path.join(self.tempdir, 'viz') with unittest.mock.patch('qiime2.sdk.Result.load', side_effect=SyntaxError): result = self.runner.invoke(command, [ 'most-common-viz', '--i-ints', self.artifact1_path, '--o-visualization', viz_path, '--verbose' ]) self.assertEqual(result.exit_code, 1) self.assertTrue('problem loading' in result.output) self.assertTrue(self.artifact1_path in result.output)
def test_run_deprecated_gets_warning_msg(self): qiime_cli = RootCommand() command = qiime_cli.get_command(ctx=None, name='dummy-plugin') output_path = os.path.join(self.tempdir, 'output.qza') result = self.runner.invoke( command, ['deprecated-method', '--o-out', output_path, '--verbose']) self.assertEqual(result.exit_code, 0) self.assertTrue(os.path.exists(output_path)) artifact = Artifact.load(output_path) # Just make sure that the command ran as expected self.assertEqual(artifact.view(dict), {'foo': '43'}) self.assertTrue('deprecated' in result.output)
def test_qzv_extension(self): qiime_cli = RootCommand() command = qiime_cli.get_command(ctx=None, name='dummy-plugin') # build output parameter arguments and expected output file names viz_path = os.path.join(self.tempdir, 'viz') expected_viz_path = os.path.join(self.tempdir, 'viz.qzv') result = self.runner.invoke( command, ['most-common-viz', '--i-ints', self.artifact1_path, '--o-visualization', viz_path, '--verbose']) # command completes successfully and creates the correct # output file self.assertEqual(result.exit_code, 0) self.assertTrue(os.path.exists(expected_viz_path)) # Visualization contains expected contents viz = Visualization.load(expected_viz_path) self.assertEqual(viz.get_index_paths(), {'html': 'data/index.html', 'tsv': 'data/index.tsv'})
def test_action_parameter_types(self): qiime_cli = RootCommand() command = qiime_cli.get_command(ctx=None, name='dummy-plugin') results = self.runner.invoke(command, ['typical-pipeline', '--help']) help_text = results.output # Check the help text to make sure the types are displayed correctly # boolean primitive self.assertIn('--p-do-extra-thing / --p-no-do-extra-thing', help_text) # int primitive self.assertIn('--p-add INTEGER', help_text) # Run it to make sure the types are converted correctly, the framework # will error if it recieves the wrong type from the interface. output_dir = os.path.join(self.tempdir, 'output-test') result = self.runner.invoke(command, [ 'typical-pipeline', '--i-int-sequence', self.artifact1_path, '--i-mapping', self.mapping_path, '--p-do-extra-thing', '--p-add', '10', '--output-dir', output_dir, '--verbose']) self.assertEqual(result.exit_code, 0)
def test_action_parameter_types(self): qiime_cli = RootCommand() command = qiime_cli.get_command(ctx=None, name='dummy-plugin') results = self.runner.invoke(command, ['typical-pipeline', '--help']) help_text = results.output # Check the help text to make sure the types are displayed correctly # boolean primitive self.assertIn('--p-do-extra-thing / --p-no-do-extra-thing', help_text) # int primitive self.assertIn('--p-add INTEGER', help_text) # Run it to make sure the types are converted correctly, the framework # will error if it recieves the wrong type from the interface. output_dir = os.path.join(self.tempdir, 'output-test') result = self.runner.invoke(command, [ 'typical-pipeline', '--i-int-sequence', self.artifact1_path, '--i-mapping', self.mapping_path, '--p-do-extra-thing', '--p-add', '10', '--output-dir', output_dir, '--verbose' ]) self.assertEqual(result.exit_code, 0)
def test_qzv_extension(self): qiime_cli = RootCommand() command = qiime_cli.get_command(ctx=None, name='dummy-plugin') # build output parameter arguments and expected output file names viz_path = os.path.join(self.tempdir, 'viz') expected_viz_path = os.path.join(self.tempdir, 'viz.qzv') result = self.runner.invoke(command, [ 'most-common-viz', '--i-ints', self.artifact1_path, '--o-visualization', viz_path, '--verbose' ]) # command completes successfully and creates the correct # output file self.assertEqual(result.exit_code, 0) self.assertTrue(os.path.exists(expected_viz_path)) # Visualization contains expected contents viz = Visualization.load(expected_viz_path) self.assertEqual(viz.get_index_paths(), { 'html': 'data/index.html', 'tsv': 'data/index.tsv' })
def test_qza_extension(self): qiime_cli = RootCommand() command = qiime_cli.get_command(ctx=None, name='dummy-plugin') # build output parameter arguments and expected output file names left_path = os.path.join(self.tempdir, 'left') expected_left_path = os.path.join(self.tempdir, 'left.qza') right_path = os.path.join(self.tempdir, 'right') expected_right_path = os.path.join(self.tempdir, 'right.qza') result = self.runner.invoke( command, ['split-ints', '--i-ints', self.artifact1_path, '--o-left', left_path, '--o-right', right_path, '--verbose']) # command completes successfully and creates the correct # output files self.assertEqual(result.exit_code, 0) self.assertTrue(os.path.exists(expected_left_path)) self.assertTrue(os.path.exists(expected_right_path)) # results are correct left = Artifact.load(expected_left_path) right = Artifact.load(expected_right_path) self.assertEqual(left.view(list), [0]) self.assertEqual(right.view(list), [42, 43])
def setUp(self): get_dummy_plugin() self.runner = CliRunner() self.plugin_command = RootCommand().get_command(ctx=None, name='dummy-plugin') self.tempdir = tempfile.mkdtemp(prefix='qiime2-q2cli-test-temp-') self.ints1 = os.path.join(self.tempdir, 'ints1.qza') Artifact.import_data(IntSequence1, [0, 42, 43], list).save(self.ints1) self.ints2 = os.path.join(self.tempdir, 'ints2.qza') Artifact.import_data(IntSequence1, [99, -22], list).save(self.ints2) self.ints3 = os.path.join(self.tempdir, 'ints3.qza') Artifact.import_data(IntSequence2, [43, 43], list).save(self.ints3) self.output = os.path.join(self.tempdir, 'output.qza')
def test_qza_extension(self): qiime_cli = RootCommand() command = qiime_cli.get_command(ctx=None, name='dummy-plugin') # build output parameter arguments and expected output file names left_path = os.path.join(self.tempdir, 'left') expected_left_path = os.path.join(self.tempdir, 'left.qza') right_path = os.path.join(self.tempdir, 'right') expected_right_path = os.path.join(self.tempdir, 'right.qza') result = self.runner.invoke(command, [ 'split-ints', '--i-ints', self.artifact1_path, '--o-left', left_path, '--o-right', right_path, '--verbose' ]) # command completes successfully and creates the correct # output files self.assertEqual(result.exit_code, 0) self.assertTrue(os.path.exists(expected_left_path)) self.assertTrue(os.path.exists(expected_right_path)) # results are correct left = Artifact.load(expected_left_path) right = Artifact.load(expected_right_path) self.assertEqual(left.view(list), [0]) self.assertEqual(right.view(list), [42, 43])
def setUp(self): get_dummy_plugin() self.runner = CliRunner() self.plugin_command = RootCommand().get_command(ctx=None, name='dummy-plugin') self.tempdir = tempfile.mkdtemp(prefix='qiime2-q2cli-test-temp-') self.input_artifact = os.path.join(self.tempdir, 'in.qza') Artifact.import_data(IntSequence1, [0, 42, 43], list).save(self.input_artifact) self.output_artifact = os.path.join(self.tempdir, 'out.qza') self.metadata_file1 = os.path.join(self.tempdir, 'metadata1.tsv') with open(self.metadata_file1, 'w') as f: f.write('id\tcol1\n0\tfoo\nid1\tbar\n') self.metadata_file2 = os.path.join(self.tempdir, 'metadata2.tsv') with open(self.metadata_file2, 'w') as f: f.write('id\tcol2\n0\tbaz\nid1\tbaa\n') self.metadata_artifact = os.path.join(self.tempdir, 'metadata.qza') Artifact.import_data('Mapping', { 'a': 'dog', 'b': 'cat' }).save(self.metadata_artifact) self.cmd_config = os.path.join(self.tempdir, 'conf.ini') with open(self.cmd_config, 'w') as f: f.write('[dummy-plugin.identity-with-metadata]\n' 'm-metadata-file=%s\n' % self.metadata_file1) f.write('[dummy-plugin.identity-with-optional-metadata]\n' 'm-metadata-file=%s\n' % self.metadata_file1) f.write('[dummy-plugin.identity-with-metadata-category]\n' 'm-metadata-file=%s\n' 'm-metadata-category=col1\n' % self.metadata_file1) f.write('[dummy-plugin.identity-with-optional-metadata-category]\n' 'm-metadata-file=%s\n' 'm-metadata-category=col1\n' % self.metadata_file1)