text: # ----------------------------------------------------------------------------
  # Copyright (c) 2016-2021, QIIME 2 development team.
  #
  # Distributed under the terms of the Modified BSD License.
  #
  # The full license is in the file LICENSE, distributed with this software.
  # ----------------------------------------------------------------------------
  
  import importlib
  import sys
  import tempfile
  import types
  import unittest
  
  import qiime2.sdk
  from qiime2.core.testing.util import get_dummy_plugin
  from qiime2.plugins import ArtifactAPIUsage
  
  
  class TestImports(unittest.TestCase):
      def setUp(self):
          self._sys_modules = sys.modules.copy()
          # Ignore the returned dummy plugin object, just run this to verify the
          # plugin exists as the tests rely on it being loaded.
          get_dummy_plugin()
  
      def tearDown(self):
          # This allows us to reset the state of our imports to test different
          # expressions to make sure they work independently.
          remove = []
          for key in sys.modules:
              if key not in self._sys_modules:
                  remove.append(key)  # can't delete in place while we iterate
  
          for key in remove:
              del sys.modules[key]
  
      def _check_spec(self, module, name, is_package):
          self.assertIsInstance(module, types.ModuleType)
          self.assertEqual(module.__name__, name)
          self.assertEqual(module.__spec__.name, name)
          self.assertEqual(module.__spec__.submodule_search_locations,
                           [] if is_package else None)
          self.assertFalse(module.__spec__.has_location)
          self.assertIn('generated QIIME 2 API', repr(module))
  
      def _check_plugin(self, module):
          self._check_spec(module, 'qiime2.plugins.dummy_plugin', True)
          self._check_methods(module.methods)
          self._check_visualizers(module.visualizers)
          self.assertEqual(set(x for x in dir(module) if not x.startswith('_')),
                           {'visualizers', 'methods', 'actions', 'pipelines'})
  
      def _check_methods(self, module):
          self._check_spec(module, 'qiime2.plugins.dummy_plugin.methods', False)
          self.assertTrue(hasattr(module, 'concatenate_ints'))
          self.assertFalse(hasattr(module, 'most_common_viz'))
  
          self.assertIsInstance(module.concatenate_ints, qiime2.sdk.Action)
  
      def _check_visualizers(self, module):
          self._check_spec(
              module, 'qiime2.plugins.dummy_plugin.visualizers', False)
          self.assertTrue(hasattr(module, 'most_common_viz'))
          self.assertFalse(hasattr(module, 'concatenate_ints'))
          self.assertIsInstance(module.most_common_viz, qiime2.sdk.Action)
  
      def test_import_root(self):
          import qiime2.plugins.dummy_plugin
          self._check_plugin(qiime2.plugins.dummy_plugin)
  
      def test_import_root_from(self):
          from qiime2.plugins import dummy_plugin
          self._check_plugin(dummy_plugin)
  
      def test_import_methods(self):
          import qiime2.plugins.dummy_plugin.methods
          self._check_methods(qiime2.plugins.dummy_plugin.methods)
  
      def test_import_visualizers(self):
          import qiime2.plugins.dummy_plugin.visualizers
          self._check_visualizers(qiime2.plugins.dummy_plugin.visualizers)
  
      def test_import_methods_from(self):
          from qiime2.plugins.dummy_plugin import methods
          self._check_methods(methods)
  
      def test_import_visualizers_from(self):
          from qiime2.plugins.dummy_plugin import visualizers
          self._check_visualizers(visualizers)
  
      def test_import_non_plugin(self):
          with self.assertRaises(ImportError):
              import qiime2.plugins.dummy_not_plugin  # noqa
  
      def test_import_non_action(self):
          with self.assertRaises(ImportError):
              import qiime2.plugins.dummy_plugin.non_action  # noqa
  
      def test_import_side_module(self):
          # Certain implementations of __PATH__ can cause a module to load
          # siblings (__PATH__ = ['.'] for example)
          import qiime2.metadata
          self.assertIsInstance(qiime2.metadata, types.ModuleType)
          with self.assertRaises(ImportError):
              import qiime2.plugins.metadata  # noqa
  
      def test_import_too_deep(self):
          with self.assertRaises(ImportError):
              import qiime2.plugins.dummy_plugin.methods.too_deep  # noqa
  
      def test_import_non_module(self):
          with self.assertRaises(ImportError):
              import qiime2.plugins.dummy_plugin.methods.concatenate_ints  # noqa
  
      def test_reload_fails(self):
          import qiime2.plugins.dummy_plugin
          with self.assertRaises(ImportError):
              importlib.reload(qiime2.plugins.dummy_plugin)
  
  
  class TestArtifactAPIUsage(unittest.TestCase):
      def setUp(self):
          # TODO standardize temporary directories created by QIIME 2
          self.test_dir = tempfile.TemporaryDirectory(prefix='qiime2-test-temp-')
          self.plugin = get_dummy_plugin()
  
      def tearDown(self):
          self.test_dir.cleanup()
  
      def test_basic(self):
          action = self.plugin.actions['concatenate_ints']
          use = ArtifactAPIUsage()
          action.examples['concatenate_ints_simple'](use)
          exp = """\
  from qiime2.plugins.dummy_plugin.methods import concatenate_ints
  
  # This example demonstrates basic usage.
  ints_d, = concatenate_ints(
      ints1=ints_a,
      ints2=ints_b,
      ints3=ints_c,
      int1=4,
      int2=2,
  )
  """
          self.assertEqual(exp, use.render())
  
      def test_chained(self):
          action = self.plugin.actions['concatenate_ints']
          use = ArtifactAPIUsage()
          action.examples['concatenate_ints_complex'](use)
          exp = """\
  from qiime2.plugins.dummy_plugin.methods import concatenate_ints
  
  # This example demonstrates chained usage (pt 1).
  ints_d, = concatenate_ints(
      ints1=ints_a,
      ints2=ints_b,
      ints3=ints_c,
      int1=4,
      int2=2,
  )
  
  # This example demonstrates chained usage (pt 2).
  concatenated_ints, = concatenate_ints(
      ints1=ints_d,
      ints2=ints_b,
      ints3=ints_c,
      int1=41,
      int2=0,
  )
  """
          self.assertEqual(exp, use.render())
  
      def test_dereferencing(self):
          action = self.plugin.actions['typical_pipeline']
          use = ArtifactAPIUsage()
          action.examples['typical_pipeline_simple'](use)
          exp = """\
  from qiime2.plugins.dummy_plugin.pipelines import typical_pipeline
  
  out_map, left, right, left_viz, right_viz = typical_pipeline(
      int_sequence=ints,
      mapping=mapper,
      do_extra_thing=True,
  )
  """
          self.assertEqual(exp, use.render())
  
      def test_chained_dereferencing(self):
          action = self.plugin.actions['typical_pipeline']
          use = ArtifactAPIUsage()
          action.examples['typical_pipeline_complex'](use)
          exp = """\
  from qiime2.plugins.dummy_plugin.pipelines import typical_pipeline
  
  out_map1, left1, right1, left_viz1, right_viz1 = typical_pipeline(
      int_sequence=ints1,
      mapping=mapper1,
      do_extra_thing=True,
  )
  
  out_map2, left2, right2, left_viz2, right_viz2 = typical_pipeline(
      int_sequence=left1,
      mapping=out_map1,
      do_extra_thing=False,
  )
  """
          self.assertEqual(exp, use.render())
  
      def test_metadata_merging(self):
          action = self.plugin.actions['identity_with_metadata']
          use = ArtifactAPIUsage()
          action.examples['identity_with_metadata_merging'](use)
          exp = """\
  from qiime2.plugins.dummy_plugin.methods import identity_with_metadata
  
  md3 = md1.merge(md2)
  
  out, = identity_with_metadata(
      ints=ints,
      metadata=md3,
  )
  """
          self.assertEqual(exp, use.render())
  
      def test_metadata_column_from_helper(self):
          action = self.plugin.actions['identity_with_metadata_column']
          use = ArtifactAPIUsage()
          action.examples['identity_with_metadata_column_get_mdc'](use)
          exp = """\
  from qiime2.plugins.dummy_plugin.methods import identity_with_metadata_column
  
  a = md.get_column('a')
  
  out, = identity_with_metadata_column(
      ints=ints,
      metadata=a,
  )
  """
          self.assertEqual(exp, use.render())
  
      def test_use_init_collection_data(self):
          action = self.plugin.actions['variadic_input_method']
          use = ArtifactAPIUsage()
          action.examples['variadic_input_simple'](use)
  
          exp = """\
  from qiime2.plugins.dummy_plugin.methods import variadic_input_method
  
  out, = variadic_input_method(
      ints=[ints_a, ints_b],
      int_set={single_int1, single_int2},
      nums={8, 9, 7},
  )
  """
          self.assertEqual(exp, use.render())
  
      def test_optional_inputs(self):
          action = self.plugin.actions['optional_artifacts_method']
          use = ArtifactAPIUsage()
          action.examples['optional_inputs'](use)
          exp = """\
  from qiime2.plugins.dummy_plugin.methods import optional_artifacts_method
  
  output, = optional_artifacts_method(
      ints=ints,
      num1=1,
  )
  
  output, = optional_artifacts_method(
      ints=ints,
      num1=1,
      num2=2,
  )
  
  ints_b, = optional_artifacts_method(
      ints=ints,
      num1=1,
      num2=None,
  )
  
  output, = optional_artifacts_method(
      ints=ints,
      num1=3,
      optional1=ints_b,
      num2=4,
  )
  """
  
          self.assertEqual(exp, use.render())
  
  
  if __name__ == '__main__':
      unittest.main()
  