Skip to content

Commit

Permalink
Enhancements for adrienverge#315
Browse files Browse the repository at this point in the history
  • Loading branch information
adrienverge authored and ssato committed Oct 8, 2020
1 parent c2c8783 commit 6a1fead
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 87 deletions.
53 changes: 45 additions & 8 deletions tests/test_plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,22 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import unittest
import warnings

try:
from unittest import mock
except ImportError: # for python 2.7
except ImportError: # for Python 2.7
mock = False

from tests.yamllint_plugin_example import rules as example

import yamllint.plugins
import yamllint.rules


PLUGIN_RULES = dict(example.RULES)


class FakeEntryPoint(object):
Expand All @@ -45,7 +50,6 @@ def load(self):


class PluginFunctionsTestCase(unittest.TestCase):

def test_validate_rule_module(self):
fun = yamllint.plugins.validate_rule_module
rule_mod = example.forbid_comments
Expand All @@ -67,14 +71,47 @@ def test_validate_rule_module_using_mock(self):
with mock.patch.object(rule_mod, "check", True):
self.assertFalse(fun(rule_mod))

def test_load_plugin_rules_itr(self):
@unittest.skipIf(not mock, "unittest.mock is not available")
@mock.patch('pkg_resources.iter_entry_points')
def test_load_plugin_rules_itr(self, iter_entry_points):
fun = yamllint.plugins.load_plugin_rules_itr

self.assertEqual(list(fun([])), [])
self.assertEqual(sorted(fun([FakeEntryPoint(),
FakeEntryPoint()])),
sorted(FakeEntryPoint.RULES))
iter_entry_points.return_value = []
self.assertEqual(list(fun()), [])

iter_entry_points.return_value = [FakeEntryPoint(), FakeEntryPoint()]
self.assertEqual(sorted(fun()), sorted(FakeEntryPoint.RULES))

iter_entry_points.return_value = [BrokenEntryPoint()]
with warnings.catch_warnings():
warnings.simplefilter("ignore")
self.assertEqual(list(fun([BrokenEntryPoint()])), [])
self.assertEqual(list(fun()), [])


@unittest.skipIf(not mock, "unittest.mock is not available")
class RulesTestCase(unittest.TestCase):
def test_get_default_rule(self):
self.assertEqual(yamllint.rules.get(yamllint.rules.braces.ID),
yamllint.rules.braces)

def test_get_rule_does_not_exist(self):
with self.assertRaises(ValueError):
yamllint.rules.get('DOESNT_EXIST')

def test_get_default_rule_with_plugins(self):
with mock.patch.dict(yamllint.rules._EXTERNAL_RULES, PLUGIN_RULES):
self.assertEqual(yamllint.rules.get(yamllint.rules.braces.ID),
yamllint.rules.braces)

def test_get_plugin_rules(self):
plugin_rule_id = example.forbid_comments.ID
plugin_rule_mod = example.forbid_comments

with mock.patch.dict(yamllint.rules._EXTERNAL_RULES, PLUGIN_RULES):
self.assertEqual(yamllint.rules.get(plugin_rule_id),
plugin_rule_mod)

def test_get_rule_does_not_exist_with_plugins(self):
with mock.patch.dict(yamllint.rules._EXTERNAL_RULES, PLUGIN_RULES):
with self.assertRaises(ValueError):
yamllint.rules.get('DOESNT_EXIST')
64 changes: 0 additions & 64 deletions tests/test_rules.py

This file was deleted.

30 changes: 20 additions & 10 deletions tests/yamllint_plugin_example/README.rst
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
yamllint plugin example
=========================
=======================

This is a yamllint plugin example as a reference, contains the following rules.

* forbid-comments to forbid comments
* random-failure to fail randomly
- ``forbid-comments`` to forbid comments
- ``random-failure`` to fail randomly

To enable thes rules in yamllint, you must add them to your `yamllint config
file <https://yamllint.readthedocs.io/en/stable/configuration.html>`_:

.. code-block:: yaml
extends: default
rules:
forbid-comments: enable
random-failure: enable
How to develop rule plugins
------------------------------
---------------------------

yamllint rule plugins must satisfy the followings.

Expand All @@ -30,16 +41,15 @@ yamllint rule plugins must satisfy the followings.

#. It must contain custom yamllint rule modules:

- Each rule module must define a couple of global variables, ID and TYPE. ID
must not conflicts with other rules' IDs.
- Each rule module must define a couple of global variables, ``ID`` and
``TYPE``. ``ID`` must not conflicts with other rules' IDs.
- Each rule module must define a function named 'check' to test input data
complies with the rule.
- Each rule module may have other global variables.
- ``CONF`` to define its configuration parameters and those types.
- ``DEFAULT`` to provide default values for each configuration parameters.

- CONF to define its configuration parameters and those types.
- DEFAULT to provide default values for each configuration parameters.

#. It must define a global variable RULES to provide an iterable object, a
#. It must define a global variable ``RULES`` to provide an iterable object, a
tuple or a list for example, of tuples of rule ID and rule modules to
yamllint like this.
::
Expand Down
File renamed without changes.
9 changes: 4 additions & 5 deletions yamllint/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""
Plugin module utilizing setuptools (pkg_resources) to allow users to add their
own custom lint rules.
"""

import warnings

import pkg_resources
Expand All @@ -33,13 +35,10 @@ def validate_rule_module(rule_mod):
) and callable(getattr(rule_mod, "check", False))


def load_plugin_rules_itr(entry_points=None, group=PACKAGE_GROUP):
def load_plugin_rules_itr():
"""Load custom lint rule plugins."""
if not entry_points:
entry_points = pkg_resources.iter_entry_points(group)

rule_ids = set()
for entry in entry_points:
for entry in pkg_resources.iter_entry_points(PACKAGE_GROUP):
try:
rules = entry.load()
for rule_id, rule_mod in rules.RULES:
Expand Down

0 comments on commit 6a1fead

Please sign in to comment.