Ejemplo n.º 1
0
 def _add_plugin(self, plugin_dir):
     """
     Adds a plugin to the jig initialized Git repository.
     """
     config = get_jigconfig(self.gitrepodir)
     pm = PluginManager(config)
     pm.add(plugin_dir)
     set_jigconfig(self.gitrepodir, pm.config)
Ejemplo n.º 2
0
 def _add_plugin(self, plugin_dir):
     """
     Adds a plugin to the jig initialized Git repository.
     """
     config = get_jigconfig(self.gitrepodir)
     pm = PluginManager(config)
     pm.add(plugin_dir)
     set_jigconfig(self.gitrepodir, pm.config)
Ejemplo n.º 3
0
    def test_add_plugin_no_settings_section(self):
        """
        Adds a plugin if it has no settings.
        """
        pm = PluginManager(self.jigconfig)

        pm.add(join(self.fixturesdir, 'plugin05'))

        self.assertEqual(1, len(pm.plugins))
Ejemplo n.º 4
0
    def test_add_plugin_no_settings_section(self):
        """
        Adds a plugin if it has no settings.
        """
        pm = PluginManager(self.jigconfig)

        pm.add(join(self.fixturesdir, 'plugin05'))

        self.assertEqual(1, len(pm.plugins))
Ejemplo n.º 5
0
    def test_add_plugin_from_directory_of_plugins(self):
        """
        Adds all the plugins in a directory of plugins.
        """
        pm = PluginManager(self.jigconfig)

        pm.add(join(self.fixturesdir, 'plugin07'))

        self.assertEqual(2, len(pm.plugins))
Ejemplo n.º 6
0
    def test_add_plugin_from_directory_of_plugins(self):
        """
        Adds all the plugins in a directory of plugins.
        """
        pm = PluginManager(self.jigconfig)

        pm.add(join(self.fixturesdir, 'plugin07'))

        self.assertEqual(2, len(pm.plugins))
Ejemplo n.º 7
0
    def test_missing_bundle_and_name(self):
        """
        Will not add a plugin if it is missing a bundle or name.
        """
        pm = PluginManager(self.jigconfig)

        with self.assertRaises(PluginError) as ec:
            pm.add(join(self.fixturesdir, 'plugin06'))

        self.assertIn('Could not find the bundle or name', str(ec.exception))
Ejemplo n.º 8
0
    def test_contains_parsing_errors(self):
        """
        Adding a bad plugin catches parsing errors.
        """
        pm = PluginManager(self.jigconfig)

        with self.assertRaises(PluginError) as ec:
            pm.add(join(self.fixturesdir, 'plugin02'))

        self.assertIn('File contains parsing errors', str(ec.exception))
Ejemplo n.º 9
0
    def test_missing_bundle_and_name(self):
        """
        Will not add a plugin if it is missing a bundle or name.
        """
        pm = PluginManager(self.jigconfig)

        with self.assertRaises(PluginError) as ec:
            pm.add(join(self.fixturesdir, 'plugin06'))

        self.assertIn('Could not find the bundle or name', str(ec.exception))
Ejemplo n.º 10
0
    def test_contains_parsing_errors(self):
        """
        Adding a bad plugin catches parsing errors.
        """
        pm = PluginManager(self.jigconfig)

        with self.assertRaises(PluginError) as ec:
            pm.add(join(self.fixturesdir, 'plugin02'))

        self.assertIn('File contains parsing errors', str(ec.exception))
Ejemplo n.º 11
0
    def test_add_plugin_no_config_file(self):
        """
        Will handle a plugin that has no config file.
        """
        pm = PluginManager(self.jigconfig)

        with self.assertRaises(PluginError) as ec:
            pm.add(join(self.fixturesdir, 'plugin03'))

        self.assertIn('The plugin file', str(ec.exception))
        self.assertIn('is missing', str(ec.exception))
Ejemplo n.º 12
0
    def test_add_plugin_no_config_file(self):
        """
        Will handle a plugin that has no config file.
        """
        pm = PluginManager(self.jigconfig)

        with self.assertRaises(PluginError) as ec:
            pm.add(join(self.fixturesdir, 'plugin03'))

        self.assertIn('The plugin file', str(ec.exception))
        self.assertIn('is missing', str(ec.exception))
Ejemplo n.º 13
0
    def test_cannot_add_plugin_twice(self):
        """
        After a plugin has been added, it can't be added again.
        """
        pm = PluginManager(self.jigconfig)

        with self.assertRaises(PluginError) as ec:
            pm.add(join(self.fixturesdir, 'plugin01'))
            # And the second time
            pm.add(join(self.fixturesdir, 'plugin01'))

        self.assertEqual('The plugin is already installed.', str(ec.exception))
Ejemplo n.º 14
0
    def test_add_plugin_no_plugin_section(self):
        """
        Will not add a plugin with missing plugin section.
        """
        pm = PluginManager(self.jigconfig)

        with self.assertRaises(PluginError) as ec:
            pm.add(join(self.fixturesdir, 'plugin04'))

        self.assertEqual(
            'The plugin config does not contain a [plugin] section.',
            str(ec.exception))
Ejemplo n.º 15
0
    def test_add_plugin_no_plugin_section(self):
        """
        Will not add a plugin with missing plugin section.
        """
        pm = PluginManager(self.jigconfig)

        with self.assertRaises(PluginError) as ec:
            pm.add(join(self.fixturesdir, 'plugin04'))

        self.assertEqual(
            'The plugin config does not contain a [plugin] section.',
            str(ec.exception))
Ejemplo n.º 16
0
    def test_cannot_add_plugin_twice(self):
        """
        After a plugin has been added, it can't be added again.
        """
        pm = PluginManager(self.jigconfig)

        with self.assertRaises(PluginError) as ec:
            pm.add(join(self.fixturesdir, 'plugin01'))
            # And the second time
            pm.add(join(self.fixturesdir, 'plugin01'))

        self.assertEqual('The plugin is already installed.',
            str(ec.exception))
Ejemplo n.º 17
0
    def test_new_plugin_compat_plugin_manager(self):
        """
        New plugins are compatible with the :py:class:`PluginManager`
        """
        plugin_dir = create_plugin(
            self.plugindir, template='python',
            bundle='test', name='plugin')

        pm = PluginManager(self.jigconfig)

        pm.add(plugin_dir)

        self.assertEqual(1, len(pm.plugins))
        self.assertEqual('plugin', pm.plugins[0].name)
Ejemplo n.º 18
0
    def test_remove_plugin(self):
        """
        Remove a plugin.
        """
        pm = PluginManager(self.jigconfig)

        pm.add(join(self.fixturesdir, 'plugin01'))

        self.assertTrue(pm.config.has_section('plugin:test01:plugin01'))

        pm.remove('test01', 'plugin01')

        self.assertFalse(pm.config.has_section('plugin:test01:plugin01'))
        self.assertEqual([], pm.plugins)
Ejemplo n.º 19
0
    def test_remove_plugin(self):
        """
        Remove a plugin.
        """
        pm = PluginManager(self.jigconfig)

        pm.add(join(self.fixturesdir, 'plugin01'))

        self.assertTrue(pm.config.has_section('plugin:test01:plugin01'))

        pm.remove('test01', 'plugin01')

        self.assertFalse(pm.config.has_section('plugin:test01:plugin01'))
        self.assertEqual([], pm.plugins)
Ejemplo n.º 20
0
    def test_unicode_in_stream(self):
        """
        UTF-8 encoded streams get converted back to unicode.
        """
        pm = PluginManager(self.jigconfig)

        pm.add(join(self.fixturesdir, 'plugin01'))
        gdi = self.git_diff_index(self.testrepo, self.testdiffs[0])

        with patch.object(Popen, 'communicate'):
            # Send it encoded unicode to see if it will convert it back
            Popen.communicate.return_value = (u'å∫ç'.encode('utf-8'), '')

            retcode, stdout, stderr = pm.plugins[0].pre_commit(gdi)

        self.assertEqual(u'å∫ç', stdout)
        self.assertEqual(u'', stderr)
Ejemplo n.º 21
0
    def test_unicode_in_stream(self):
        """
        UTF-8 encoded streams get converted back to unicode.
        """
        pm = PluginManager(self.jigconfig)

        pm.add(join(self.fixturesdir, 'plugin01'))
        gdi = self.git_diff_index(self.testrepo, self.testdiffs[0])

        with patch.object(Popen, 'communicate'):
            # Send it encoded unicode to see if it will convert it back
            Popen.communicate.return_value = (u'å∫ç'.encode('utf-8'), '')

            retcode, stdout, stderr = pm.plugins[0].pre_commit(gdi)

        self.assertEqual(u'å∫ç', stdout)
        self.assertEqual(u'', stderr)
Ejemplo n.º 22
0
    def test_oserror(self):
        """
        If a generic OSError is received, don't blow up either.
        """
        pm = PluginManager(self.jigconfig)

        pm.add(join(self.fixturesdir, 'plugin01'))
        gdi = self.git_diff_index(self.testrepo, self.testdiffs[0])

        with patch.object(Popen, 'communicate'):
            ose = OSError('Gazoonkle was discombobulated')
            ose.errno = 1

            Popen.communicate.side_effect = ose

            retcode, stdout, stderr = pm.plugins[0].pre_commit(gdi)

        self.assertEqual(1, retcode)
        self.assertEqual('', stdout)
        self.assertEqual('Gazoonkle was discombobulated', stderr)
Ejemplo n.º 23
0
    def test_sigpipe_error(self):
        """
        If a SIGPIPE is received, handle it without blowing up.
        """
        pm = PluginManager(self.jigconfig)

        pm.add(join(self.fixturesdir, 'plugin01'))
        gdi = self.git_diff_index(self.testrepo, self.testdiffs[0])

        with patch.object(Popen, 'communicate'):
            ose = OSError('SIGPIPE')
            ose.errno = 32

            Popen.communicate.side_effect = ose

            retcode, stdout, stderr = pm.plugins[0].pre_commit(gdi)

        self.assertEqual(1, retcode)
        self.assertEqual('', stdout)
        self.assertEqual('Error: received SIGPIPE from the command', stderr)
Ejemplo n.º 24
0
    def test_new_file_pre_commit(self):
        """
        Test a new file pre-commit.
        """
        pm = PluginManager(self.jigconfig)

        pm.add(join(self.fixturesdir, 'plugin01'))
        gdi = self.git_diff_index(self.testrepo, self.testdiffs[0])

        retcode, stdout, stderr = pm.plugins[0].pre_commit(gdi)

        data = json.loads(stdout)

        # Everything should have gone splendidly
        self.assertEqual(0, retcode)
        # Should contain our file that was added
        self.assertIn('argument.txt', data)
        # And our first line should be a warning
        self.assertEqual([1, u'warn', u'The cast: is +'],
                         data['argument.txt'][0])
Ejemplo n.º 25
0
    def test_sigpipe_error(self):
        """
        If a SIGPIPE is received, handle it without blowing up.
        """
        pm = PluginManager(self.jigconfig)

        pm.add(join(self.fixturesdir, 'plugin01'))
        gdi = self.git_diff_index(self.testrepo, self.testdiffs[0])

        with patch.object(Popen, 'communicate'):
            ose = OSError('SIGPIPE')
            ose.errno = 32

            Popen.communicate.side_effect = ose

            retcode, stdout, stderr = pm.plugins[0].pre_commit(gdi)

        self.assertEqual(1, retcode)
        self.assertEqual('', stdout)
        self.assertEqual('Error: received SIGPIPE from the command', stderr)
Ejemplo n.º 26
0
    def test_oserror(self):
        """
        If a generic OSError is received, don't blow up either.
        """
        pm = PluginManager(self.jigconfig)

        pm.add(join(self.fixturesdir, 'plugin01'))
        gdi = self.git_diff_index(self.testrepo, self.testdiffs[0])

        with patch.object(Popen, 'communicate'):
            ose = OSError('Gazoonkle was discombobulated')
            ose.errno = 1

            Popen.communicate.side_effect = ose

            retcode, stdout, stderr = pm.plugins[0].pre_commit(gdi)

        self.assertEqual(1, retcode)
        self.assertEqual('', stdout)
        self.assertEqual('Gazoonkle was discombobulated', stderr)
Ejemplo n.º 27
0
    def test_new_file_pre_commit(self):
        """
        Test a new file pre-commit.
        """
        pm = PluginManager(self.jigconfig)

        pm.add(join(self.fixturesdir, 'plugin01'))
        gdi = self.git_diff_index(self.testrepo, self.testdiffs[0])

        retcode, stdout, stderr = pm.plugins[0].pre_commit(gdi)

        data = json.loads(stdout)

        # Everything should have gone splendidly
        self.assertEqual(0, retcode)
        # Should contain our file that was added
        self.assertIn('argument.txt', data)
        # And our first line should be a warning
        self.assertEqual(
            [1, u'warn', u'The cast: is +'],
            data['argument.txt'][0])
Ejemplo n.º 28
0
    def test_add_plugin(self):
        """
        Test the add method on the plugin manager.
        """
        # Config is empty
        pm = PluginManager(self.jigconfig)

        plugin = pm.add(join(self.fixturesdir, 'plugin01'))[0]

        self.assertEqual(1, len(pm.plugins))
        self.assertTrue(pm.config.has_section('plugin:test01:plugin01'))
        self.assertEqual('plugin01', plugin.name)
        self.assertEqual('test01', plugin.bundle)
Ejemplo n.º 29
0
    def test_add_plugin(self):
        """
        Test the add method on the plugin manager.
        """
        # Config is empty
        pm = PluginManager(self.jigconfig)

        plugin = pm.add(join(self.fixturesdir, 'plugin01'))[0]

        self.assertEqual(1, len(pm.plugins))
        self.assertTrue(pm.config.has_section('plugin:test01:plugin01'))
        self.assertEqual('plugin01', plugin.name)
        self.assertEqual('test01', plugin.bundle)
Ejemplo n.º 30
0
    def run(self, test_range=None):
        """
        Run the tests for this plugin.

        Returns a list of :py:class:`Result` objects which represent the
        results from the test run.

        :param list test_range: None or the parsed range from
            :function:`parse_range`
        """
        # Use an empty config, we are not going to save this to disk
        pm = PluginManager(SafeConfigParser())

        # Add the plugin we are testing
        pm.add(self.plugin_dir)

        # The instance of our plugin we will run the pre_commit test on
        plugin = pm.plugins[0]

        # Capture the default plugin config for resets while testing
        default_settings = plugin.config

        results = []

        for exp in self.expectations:
            # Make sure that the range is off by 1
            assert exp.range[1] == exp.range[0] + 1

            # Is this expectation in the specified test range?
            if test_range and (exp.range not in test_range):
                # Skip this one, it's not one of the tests we should be running
                continue

            # Update the plugin config (settings) if available
            if exp.settings:
                plugin.config = exp.settings
            else:
                plugin.config = default_settings

            # View to help us create the output
            view = ConsoleView(collect_output=True, exit_on_exception=False)

            # Get a GitDiffIndex object from
            gdi = InstrumentedGitDiffIndex(
                self.timeline.repo.working_dir,
                self.timeline.diffs()[exp.range[0] - 1])

            # What is the numbered test directory reprsenting our commit?
            wd = abspath(join(
                self.plugin_dir, PLUGIN_TESTS_DIRECTORY,
                '{0:02d}'.format(exp.range[1])))

            with cwd_bounce(wd):
                # Patch up the filename to be within our numbered directory
                # instead of the Git repository
                gdi.replace_path = (self.timeline.repo.working_dir, wd)

                # Gather up the input to the plugin for logging
                stdin = json.dumps({
                    'config': plugin.config,
                    'files': gdi},
                    indent=2, cls=PluginDataJSONEncoder)

                # Now run the actual pre_commit hook for this plugin
                res = plugin.pre_commit(gdi)
                # Break apart into its pieces
                retcode, stdout, stderr = res   # pragma: no branch

            try:
                # Is it JSON data?
                data = json.loads(stdout)
            except ValueError:
                # Not JSON
                data = stdout

            if retcode == 0:
                # Format the results according to what you normally see in the
                # console.
                view.print_results({plugin: (retcode, data, stderr)})
            else:
                results.append(FailureResult(
                    exp,
                    'Exit code: {0}\n\nStd out:\n{1}\n\nStd err:\n{2}'.format(
                        retcode, stdout or '(none)', stderr or '(none)'),
                    plugin))
                continue

            # Now remove the color character sequences to make things a little
            # easier to read, copy, and paste.
            actual = strip_paint(
                view._collect['stdout'].getvalue() or
                view._collect['stderr'].getvalue())

            # Also remove the summary and count at the end, these are not
            # really all that useful to test and just end up making the
            # expect.rst files overly verbose
            actual = RESULTS_SUMMARY_SIGNATURE_RE.sub('', actual)
            actual = RESULTS_SUMMARY_COUNT_RE.sub('', actual)

            resargs = (exp, actual, plugin, stdin, stdout)
            if actual.strip() != exp.output.strip():
                results.append(FailureResult(*resargs))
            else:
                results.append(SuccessResult(*resargs))

        return results
Ejemplo n.º 31
0
    def run(self, test_range=None):
        """
        Run the tests for this plugin.

        Returns a list of :py:class:`Result` objects which represent the
        results from the test run.

        :param list test_range: None or the parsed range from
            :function:`parse_range`
        """
        # Use an empty config, we are not going to save this to disk
        pm = PluginManager(SafeConfigParser())

        # Add the plugin we are testing
        pm.add(self.plugin_dir)

        # The instance of our plugin we will run the pre_commit test on
        plugin = pm.plugins[0]

        # Capture the default plugin config for resets while testing
        default_settings = plugin.config

        results = []

        for exp in self.expectations:
            # Make sure that the range is off by 1
            assert exp.range[1] == exp.range[0] + 1

            # Is this expectation in the specified test range?
            if test_range and (exp.range not in test_range):
                # Skip this one, it's not one of the tests we should be running
                continue

            # Update the plugin config (settings) if available
            if exp.settings:
                plugin.config = exp.settings
            else:
                plugin.config = default_settings

            # View to help us create the output
            view = ConsoleView(collect_output=True, exit_on_exception=False)

            # Get a GitDiffIndex object from
            gdi = InstrumentedGitDiffIndex(
                self.timeline.repo.working_dir,
                self.timeline.diffs()[exp.range[0] - 1])

            # What is the numbered test directory reprsenting our commit?
            wd = abspath(
                join(self.plugin_dir, PLUGIN_TESTS_DIRECTORY,
                     '{0:02d}'.format(exp.range[1])))

            with cwd_bounce(wd):
                # Patch up the filename to be within our numbered directory
                # instead of the Git repository
                gdi.replace_path = (self.timeline.repo.working_dir, wd)

                # Gather up the input to the plugin for logging
                stdin = json.dumps({
                    'config': plugin.config,
                    'files': gdi
                },
                                   indent=2,
                                   cls=PluginDataJSONEncoder)

                # Now run the actual pre_commit hook for this plugin
                res = plugin.pre_commit(gdi)
                # Break apart into its pieces
                retcode, stdout, stderr = res  # pragma: no branch

            try:
                # Is it JSON data?
                data = json.loads(stdout)
            except ValueError:
                # Not JSON
                data = stdout

            if retcode == 0:
                # Format the results according to what you normally see in the
                # console.
                view.print_results({plugin: (retcode, data, stderr)})
            else:
                results.append(
                    FailureResult(
                        exp,
                        'Exit code: {0}\n\nStd out:\n{1}\n\nStd err:\n{2}'.
                        format(retcode, stdout or '(none)', stderr
                               or '(none)'), plugin))
                continue

            # Now remove the color character sequences to make things a little
            # easier to read, copy, and paste.
            actual = strip_paint(view._collect['stdout'].getvalue()
                                 or view._collect['stderr'].getvalue())

            # Also remove the summary and count at the end, these are not
            # really all that useful to test and just end up making the
            # expect.rst files overly verbose
            actual = RESULTS_SUMMARY_SIGNATURE_RE.sub('', actual)
            actual = RESULTS_SUMMARY_COUNT_RE.sub('', actual)

            resargs = (exp, actual, plugin, stdin, stdout)
            if actual.strip() != exp.output.strip():
                results.append(FailureResult(*resargs))
            else:
                results.append(SuccessResult(*resargs))

        return results