Commit e57e2269 authored by Waylan Limberg's avatar Waylan Limberg
Browse files

Improve Markdown extension error messages.

Fixes #782. Note that we mock Markdown in the tests to ensure those
tests are not using Markdown to validate the extension names. We don't
mock Markdown in the tests which we do want Markdown to validate the
extension names.

Also ensure project-min has all relevant extensions.
parent d4c58328
......@@ -66,6 +66,7 @@ authors should review how [search and themes] interact.
### Other Changes and Additions to Development Version
* Improve Markdown extension error messages. (#782).
* Drop official support for Python 3.3 and set `tornado>=5.0` (#1427).
* Add support for GitLab edit links (#1435).
* Link to GitHub issues from release notes (#644).
......
......@@ -3,6 +3,7 @@ from __future__ import unicode_literals
from collections import Sequence
import os
from collections import namedtuple
import markdown
from mkdocs import utils, theme, plugins
from mkdocs.config.base import Config, ValidationError
......@@ -629,7 +630,16 @@ class MarkdownExtensions(OptionallyRequired):
extensions.append(item)
else:
raise ValidationError('Invalid Markdown Extensions configuration')
return utils.reduce_list(self.builtins + extensions)
extensions = utils.reduce_list(self.builtins + extensions)
# Confirm that Markdown considers extensions to be valid
try:
markdown.Markdown(extensions=extensions, extension_configs=self.configdata)
except Exception as e:
raise ValidationError(e.args[0])
return extensions
def post_validation(self, config, key_name):
config[self.configkey] = self.configdata
......
......@@ -2,6 +2,7 @@ from __future__ import unicode_literals
import os
import unittest
from mock import patch
import mkdocs
from mkdocs import utils
......@@ -491,7 +492,8 @@ class PrivateTest(unittest.TestCase):
class MarkdownExtensionsTest(unittest.TestCase):
def test_simple_list(self):
@patch('markdown.Markdown')
def test_simple_list(self, mockMd):
option = config_options.MarkdownExtensions()
config = {
'markdown_extensions': ['foo', 'bar']
......@@ -503,7 +505,8 @@ class MarkdownExtensionsTest(unittest.TestCase):
'mdx_configs': {}
}, config)
def test_list_dicts(self):
@patch('markdown.Markdown')
def test_list_dicts(self, mockMd):
option = config_options.MarkdownExtensions()
config = {
'markdown_extensions': [
......@@ -522,7 +525,8 @@ class MarkdownExtensionsTest(unittest.TestCase):
}
}, config)
def test_mixed_list(self):
@patch('markdown.Markdown')
def test_mixed_list(self, mockMd):
option = config_options.MarkdownExtensions()
config = {
'markdown_extensions': [
......@@ -539,7 +543,8 @@ class MarkdownExtensionsTest(unittest.TestCase):
}
}, config)
def test_builtins(self):
@patch('markdown.Markdown')
def test_builtins(self, mockMd):
option = config_options.MarkdownExtensions(builtins=['meta', 'toc'])
config = {
'markdown_extensions': ['foo', 'bar']
......@@ -577,7 +582,8 @@ class MarkdownExtensionsTest(unittest.TestCase):
'mdx_configs': {'toc': {'permalink': True}}
}, config)
def test_configkey(self):
@patch('markdown.Markdown')
def test_configkey(self, mockMd):
option = config_options.MarkdownExtensions(configkey='bar')
config = {
'markdown_extensions': [
......@@ -605,12 +611,14 @@ class MarkdownExtensionsTest(unittest.TestCase):
'mdx_configs': {}
}, config)
def test_not_list(self):
@patch('markdown.Markdown')
def test_not_list(self, mockMd):
option = config_options.MarkdownExtensions()
self.assertRaises(config_options.ValidationError,
option.validate, 'not a list')
def test_invalid_config_option(self):
@patch('markdown.Markdown')
def test_invalid_config_option(self, mockMd):
option = config_options.MarkdownExtensions()
config = {
'markdown_extensions': [
......@@ -622,7 +630,8 @@ class MarkdownExtensionsTest(unittest.TestCase):
option.validate, config['markdown_extensions']
)
def test_invalid_config_item(self):
@patch('markdown.Markdown')
def test_invalid_config_item(self, mockMd):
option = config_options.MarkdownExtensions()
config = {
'markdown_extensions': [
......@@ -634,7 +643,8 @@ class MarkdownExtensionsTest(unittest.TestCase):
option.validate, config['markdown_extensions']
)
def test_invalid_dict_item(self):
@patch('markdown.Markdown')
def test_invalid_dict_item(self, mockMd):
option = config_options.MarkdownExtensions()
config = {
'markdown_extensions': [
......@@ -645,3 +655,13 @@ class MarkdownExtensionsTest(unittest.TestCase):
config_options.ValidationError,
option.validate, config['markdown_extensions']
)
def test_unknown_extension(self):
option = config_options.MarkdownExtensions()
config = {
'markdown_extensions': ['unknown']
}
self.assertRaises(
config_options.ValidationError,
option.validate, config['markdown_extensions']
)
......@@ -4,3 +4,4 @@ livereload==2.5.1
Markdown==2.5
PyYAML==3.10
tornado==4.1
mdx_gh_links>=0.2
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment