| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276 |
- #!/usr/bin/env python
- import unittest
- from unittest import mock
- import os
- from mkdocs import plugins
- from mkdocs import config
- class DummyPlugin(plugins.BasePlugin):
- config_scheme = (
- ('foo', config.config_options.Type(str, default='default foo')),
- ('bar', config.config_options.Type(int, default=0)),
- ('dir', config.config_options.Dir(exists=False)),
- )
- def on_pre_page(self, content, **kwargs):
- """ modify page content by prepending `foo` config value. """
- return '{} {}'.format(self.config['foo'], content)
- def on_nav(self, item, **kwargs):
- """ do nothing (return None) to not modify item. """
- return None
- def on_page_read_source(self, **kwargs):
- """ create new source by prepending `foo` config value to 'source'. """
- return '{} {}'.format(self.config['foo'], 'source')
- def on_pre_build(self, **kwargs):
- """ do nothing (return None). """
- return None
- class TestPluginClass(unittest.TestCase):
- def test_valid_plugin_options(self):
- test_dir = 'test'
- options = {
- 'foo': 'some value',
- 'dir': test_dir,
- }
- cfg_fname = os.path.join('tmp', 'test', 'fname.yml')
- cfg_fname = os.path.abspath(cfg_fname)
- cfg_dirname = os.path.dirname(cfg_fname)
- expected = os.path.join(cfg_dirname, test_dir)
- expected = {
- 'foo': 'some value',
- 'bar': 0,
- 'dir': expected,
- }
- plugin = DummyPlugin()
- errors, warnings = plugin.load_config(options, config_file_path=cfg_fname)
- self.assertEqual(plugin.config, expected)
- self.assertEqual(errors, [])
- self.assertEqual(warnings, [])
- def test_invalid_plugin_options(self):
- plugin = DummyPlugin()
- errors, warnings = plugin.load_config({'foo': 42})
- self.assertEqual(len(errors), 1)
- self.assertIn('foo', errors[0])
- self.assertEqual(warnings, [])
- errors, warnings = plugin.load_config({'bar': 'a string'})
- self.assertEqual(len(errors), 1)
- self.assertIn('bar', errors[0])
- self.assertEqual(warnings, [])
- errors, warnings = plugin.load_config({'invalid_key': 'value'})
- self.assertEqual(errors, [])
- self.assertEqual(len(warnings), 1)
- self.assertIn('invalid_key', warnings[0])
- class TestPluginCollection(unittest.TestCase):
- def test_set_plugin_on_collection(self):
- collection = plugins.PluginCollection()
- plugin = DummyPlugin()
- collection['foo'] = plugin
- self.assertEqual([(k, v) for k, v in collection.items()], [('foo', plugin)])
- def test_set_multiple_plugins_on_collection(self):
- collection = plugins.PluginCollection()
- plugin1 = DummyPlugin()
- collection['foo'] = plugin1
- plugin2 = DummyPlugin()
- collection['bar'] = plugin2
- self.assertEqual([(k, v) for k, v in collection.items()], [('foo', plugin1), ('bar', plugin2)])
- def test_run_event_on_collection(self):
- collection = plugins.PluginCollection()
- plugin = DummyPlugin()
- plugin.load_config({'foo': 'new'})
- collection['foo'] = plugin
- self.assertEqual(collection.run_event('pre_page', 'page content'), 'new page content')
- def test_run_event_twice_on_collection(self):
- collection = plugins.PluginCollection()
- plugin1 = DummyPlugin()
- plugin1.load_config({'foo': 'new'})
- collection['foo'] = plugin1
- plugin2 = DummyPlugin()
- plugin2.load_config({'foo': 'second'})
- collection['bar'] = plugin2
- self.assertEqual(collection.run_event('pre_page', 'page content'),
- 'second new page content')
- def test_event_returns_None(self):
- collection = plugins.PluginCollection()
- plugin = DummyPlugin()
- plugin.load_config({'foo': 'new'})
- collection['foo'] = plugin
- self.assertEqual(collection.run_event('nav', 'nav item'), 'nav item')
- def test_event_empty_item(self):
- collection = plugins.PluginCollection()
- plugin = DummyPlugin()
- plugin.load_config({'foo': 'new'})
- collection['foo'] = plugin
- self.assertEqual(collection.run_event('page_read_source'), 'new source')
- def test_event_empty_item_returns_None(self):
- collection = plugins.PluginCollection()
- plugin = DummyPlugin()
- plugin.load_config({'foo': 'new'})
- collection['foo'] = plugin
- self.assertEqual(collection.run_event('pre_build'), None)
- def test_run_undefined_event_on_collection(self):
- collection = plugins.PluginCollection()
- self.assertEqual(collection.run_event('pre_page', 'page content'), 'page content')
- def test_run_unknown_event_on_collection(self):
- collection = plugins.PluginCollection()
- self.assertRaises(KeyError, collection.run_event, 'unknown', 'page content')
- MockEntryPoint = mock.Mock()
- MockEntryPoint.configure_mock(**{'name': 'sample', 'load.return_value': DummyPlugin})
- @mock.patch('pkg_resources.iter_entry_points', return_value=[MockEntryPoint])
- class TestPluginConfig(unittest.TestCase):
- def test_plugin_config_without_options(self, mock_class):
- cfg = {'plugins': ['sample']}
- option = config.config_options.Plugins()
- cfg['plugins'] = option.validate(cfg['plugins'])
- self.assertIsInstance(cfg['plugins'], plugins.PluginCollection)
- self.assertIn('sample', cfg['plugins'])
- self.assertIsInstance(cfg['plugins']['sample'], plugins.BasePlugin)
- expected = {
- 'foo': 'default foo',
- 'bar': 0,
- 'dir': None,
- }
- self.assertEqual(cfg['plugins']['sample'].config, expected)
- def test_plugin_config_with_options(self, mock_class):
- cfg = {
- 'plugins': [{
- 'sample': {
- 'foo': 'foo value',
- 'bar': 42
- }
- }]
- }
- option = config.config_options.Plugins()
- cfg['plugins'] = option.validate(cfg['plugins'])
- self.assertIsInstance(cfg['plugins'], plugins.PluginCollection)
- self.assertIn('sample', cfg['plugins'])
- self.assertIsInstance(cfg['plugins']['sample'], plugins.BasePlugin)
- expected = {
- 'foo': 'foo value',
- 'bar': 42,
- 'dir': None,
- }
- self.assertEqual(cfg['plugins']['sample'].config, expected)
- def test_plugin_config_empty_list_with_empty_default(self, mock_class):
- cfg = {'plugins': []}
- option = config.config_options.Plugins(default=[])
- cfg['plugins'] = option.validate(cfg['plugins'])
- self.assertIsInstance(cfg['plugins'], plugins.PluginCollection)
- self.assertEqual(len(cfg['plugins']), 0)
- def test_plugin_config_empty_list_with_default(self, mock_class):
- # Default is ignored
- cfg = {'plugins': []}
- option = config.config_options.Plugins(default=['sample'])
- cfg['plugins'] = option.validate(cfg['plugins'])
- self.assertIsInstance(cfg['plugins'], plugins.PluginCollection)
- self.assertEqual(len(cfg['plugins']), 0)
- def test_plugin_config_none_with_empty_default(self, mock_class):
- cfg = {'plugins': None}
- option = config.config_options.Plugins(default=[])
- cfg['plugins'] = option.validate(cfg['plugins'])
- self.assertIsInstance(cfg['plugins'], plugins.PluginCollection)
- self.assertEqual(len(cfg['plugins']), 0)
- def test_plugin_config_none_with_default(self, mock_class):
- # Default is used.
- cfg = {'plugins': None}
- option = config.config_options.Plugins(default=['sample'])
- cfg['plugins'] = option.validate(cfg['plugins'])
- self.assertIsInstance(cfg['plugins'], plugins.PluginCollection)
- self.assertIn('sample', cfg['plugins'])
- self.assertIsInstance(cfg['plugins']['sample'], plugins.BasePlugin)
- expected = {
- 'foo': 'default foo',
- 'bar': 0,
- 'dir': None,
- }
- self.assertEqual(cfg['plugins']['sample'].config, expected)
- def test_plugin_config_uninstalled(self, mock_class):
- cfg = {'plugins': ['uninstalled']}
- option = config.config_options.Plugins()
- self.assertRaises(config.base.ValidationError, option.validate, cfg['plugins'])
- def test_plugin_config_not_list(self, mock_class):
- cfg = {'plugins': 'sample'} # should be a list
- option = config.config_options.Plugins()
- self.assertRaises(config.base.ValidationError, option.validate, cfg['plugins'])
- def test_plugin_config_multivalue_dict(self, mock_class):
- cfg = {
- 'plugins': [{
- 'sample': {
- 'foo': 'foo value',
- 'bar': 42
- },
- 'extra_key': 'baz'
- }]
- }
- option = config.config_options.Plugins()
- self.assertRaises(config.base.ValidationError, option.validate, cfg['plugins'])
- def test_plugin_config_not_string_or_dict(self, mock_class):
- cfg = {
- 'plugins': [('not a string or dict',)]
- }
- option = config.config_options.Plugins()
- self.assertRaises(config.base.ValidationError, option.validate, cfg['plugins'])
- def test_plugin_config_options_not_dict(self, mock_class):
- cfg = {
- 'plugins': [{
- 'sample': 'not a dict'
- }]
- }
- option = config.config_options.Plugins()
- self.assertRaises(config.base.ValidationError, option.validate, cfg['plugins'])
|