-
Notifications
You must be signed in to change notification settings - Fork 815
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Initial set of Markdown widget unit tests Noting too crazy or clever to start with, initially something to just test the basics and to ensure that the resulting Textual node list is what we'd expect. Really just the start of a testing framework for Markdown. * Allow handling of an unknown token This allow for a couple of things: 1. First and foremost this will let me test for unhandled tokens in testing. 2. This will also let applications support other token types. * Update the Markdown testing to get upset about unknown token types * Treat a code_block markdown token the same as a fence I believe this should be a fine way to solve this. I don't see anything that means that a `code_block` is in any way different than a fenced block that has no syntax specified. See #2781. * Add a test for a code_block within Markdown * Allow for inline fenced code and code blocks See #2676 Co-authored-by: TomJGooding <[email protected]> * Update the ChangeLog * Improve the external Markdown elements are added to the document * Improve the testing of Markdown Also add a test for the list inline code block * Remove the unnecessary pause * Stop list items in Markdown being added to the focus chain See #2380 * Remove hint to pyright/pylance/pylint that it's okay to ignore the arg --------- Co-authored-by: TomJGooding <[email protected]>
- Loading branch information
1 parent
bb9cc62
commit 038cdb2
Showing
4 changed files
with
128 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
from ._markdown import Markdown, MarkdownTableOfContents | ||
from ._markdown import Markdown, MarkdownBlock, MarkdownTableOfContents | ||
|
||
__all__ = ["MarkdownTableOfContents", "Markdown"] | ||
__all__ = ["MarkdownTableOfContents", "Markdown", "MarkdownBlock"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
"""Unit tests for the Markdown widget.""" | ||
|
||
from __future__ import annotations | ||
|
||
from typing import Iterator | ||
|
||
import pytest | ||
from markdown_it.token import Token | ||
|
||
import textual.widgets._markdown as MD | ||
from textual.app import App, ComposeResult | ||
from textual.widget import Widget | ||
from textual.widgets import Markdown | ||
from textual.widgets.markdown import MarkdownBlock | ||
|
||
|
||
class UnhandledToken(MarkdownBlock): | ||
def __init__(self, markdown: Markdown, token: Token) -> None: | ||
super().__init__(markdown) | ||
self._token = token | ||
|
||
def __repr___(self) -> str: | ||
return self._token.type | ||
|
||
|
||
class FussyMarkdown(Markdown): | ||
def unhandled_token(self, token: Token) -> MarkdownBlock | None: | ||
return UnhandledToken(self, token) | ||
|
||
|
||
class MarkdownApp(App[None]): | ||
def __init__(self, markdown: str) -> None: | ||
super().__init__() | ||
self._markdown = markdown | ||
|
||
def compose(self) -> ComposeResult: | ||
yield FussyMarkdown(self._markdown) | ||
|
||
|
||
@pytest.mark.parametrize( | ||
["document", "expected_nodes"], | ||
[ | ||
# Basic markup. | ||
("", []), | ||
("# Hello", [MD.MarkdownH1]), | ||
("## Hello", [MD.MarkdownH2]), | ||
("### Hello", [MD.MarkdownH3]), | ||
("#### Hello", [MD.MarkdownH4]), | ||
("##### Hello", [MD.MarkdownH5]), | ||
("###### Hello", [MD.MarkdownH6]), | ||
("---", [MD.MarkdownHorizontalRule]), | ||
("Hello", [MD.MarkdownParagraph]), | ||
("Hello\nWorld", [MD.MarkdownParagraph]), | ||
("> Hello", [MD.MarkdownBlockQuote, MD.MarkdownParagraph]), | ||
("- One\n-Two", [MD.MarkdownBulletList, MD.MarkdownParagraph]), | ||
( | ||
"1. One\n2. Two", | ||
[MD.MarkdownOrderedList, MD.MarkdownParagraph, MD.MarkdownParagraph], | ||
), | ||
(" 1", [MD.MarkdownFence]), | ||
("```\n1\n```", [MD.MarkdownFence]), | ||
("```python\n1\n```", [MD.MarkdownFence]), | ||
("""| One | Two |\n| :- | :- |\n| 1 | 2 |""", [MD.MarkdownTable]), | ||
# Test for https://github.com/Textualize/textual/issues/2676 | ||
( | ||
"- One\n```\nTwo\n```\n- Three\n", | ||
[ | ||
MD.MarkdownBulletList, | ||
MD.MarkdownParagraph, | ||
MD.MarkdownFence, | ||
MD.MarkdownBulletList, | ||
MD.MarkdownParagraph, | ||
], | ||
), | ||
], | ||
) | ||
async def test_markdown_nodes( | ||
document: str, expected_nodes: list[Widget | list[Widget]] | ||
) -> None: | ||
"""A Markdown document should parse into the expected Textual node list.""" | ||
|
||
def markdown_nodes(root: Widget) -> Iterator[MarkdownBlock]: | ||
for node in root.children: | ||
if isinstance(node, MarkdownBlock): | ||
yield node | ||
yield from markdown_nodes(node) | ||
|
||
async with MarkdownApp(document).run_test() as pilot: | ||
assert [ | ||
node.__class__ for node in markdown_nodes(pilot.app.query_one(Markdown)) | ||
] == expected_nodes |