Skip listing containers whose entries hold user cards or quotes
A thread without DiscussionForumPosting markup, where every poster writes once, still passed the teaser test: each post opens with a linked name that no other post repeats. On katzen-forum.net with the JSON-LD removed and one post per poster, recall took the whole container (3,573 chars, seven user cards instead of one). Teasers hold neither a description list nor a quote, while forum posts keep the poster's user card in one and quote each other, so an entry holding either now rules the container out.
This commit is contained in:
1 parent
77465a50e7
commit
06c7822f79
2 files changed
+23
-11
No files matched your search
+19
-10
@@ -2963,13 +2963,18 @@ def test_listing_page_with_links_keeps_every_entry_heading():
|
|||||||
assert text in result
|
assert text in result
|
||||||
|
|
||||||
|
|
||||||
def _forum_thread(posters, linked=True, forum_markup=False):
|
def _forum_thread(posters, linked=True, forum_markup=False, card_in_dl=False, quoting=False):
|
||||||
"Thread markup: sibling <article> posts, each opening with a user card that names its poster in a heading."
|
"Thread markup: sibling <article> posts, each opening with a user card that names its poster in a heading."
|
||||||
name_markup = '<a href="/members/{0}/">{0}</a>' if linked else "<span>{0}</span>"
|
name_markup = '<a href="/members/{0}/">{0}</a>' if linked else "<span>{0}</span>"
|
||||||
|
card = (
|
||||||
|
"<dl><dt>Joined</dt><dd>March 2015</dd><dt>Messages</dt><dd>1,447</dd></dl>"
|
||||||
|
if card_in_dl
|
||||||
|
else '<div class="user-title">Joined March 2015, 1,447 messages</div>'
|
||||||
|
)
|
||||||
posts = "".join(
|
posts = "".join(
|
||||||
f'<article><div class="poster"><h4>{name_markup.format(name)}</h4>'
|
f'<article><div class="poster"><h4>{name_markup.format(name)}</h4>{card}</div>'
|
||||||
"<dl><dt>Joined</dt><dd>March 2015</dd><dt>Messages</dt><dd>1,447</dd></dl></div>"
|
+ (f"<blockquote><p>{posters[i - 1]} wrote: see my reply above.</p></blockquote>" if quoting and i else "")
|
||||||
f"<div><p>Reply {i} from {name} carries enough prose to count as a post, running over a couple "
|
+ f"<div><p>Reply {i} from {name} carries enough prose to count as a post, running over a couple "
|
||||||
"of clauses so the thread reads as a real discussion between people.</p></div></article>"
|
"of clauses so the thread reads as a real discussion between people.</p></div></article>"
|
||||||
for i, name in enumerate(posters)
|
for i, name in enumerate(posters)
|
||||||
)
|
)
|
||||||
@@ -2986,20 +2991,24 @@ def _forum_thread(posters, linked=True, forum_markup=False):
|
|||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"posters,linked,forum_markup",
|
"posters,markup",
|
||||||
[
|
[
|
||||||
# the same poster comes back along the thread
|
# the same poster comes back along the thread
|
||||||
(["alice", "bob", "alice", "carol", "bob", "alice"], True, False),
|
(["alice", "bob", "alice", "carol", "bob", "alice"], {}),
|
||||||
# poster names without a link
|
# poster names without a link
|
||||||
(["alice", "bob", "carol", "dave", "erin", "frank"], False, False),
|
(["alice", "bob", "carol", "dave", "erin", "frank"], {"linked": False}),
|
||||||
# every poster different, but the page declares itself a forum thread
|
# every poster different, but the page declares itself a forum thread
|
||||||
(["alice", "bob", "carol", "dave", "erin", "frank"], True, True),
|
(["alice", "bob", "carol", "dave", "erin", "frank"], {"forum_markup": True}),
|
||||||
|
# every poster different and no forum markup, but the user card is a description list
|
||||||
|
(["alice", "bob", "carol", "dave", "erin", "frank"], {"card_in_dl": True}),
|
||||||
|
# every poster different and no forum markup, but the replies quote the post before them
|
||||||
|
(["alice", "bob", "carol", "dave", "erin", "frank"], {"quoting": True}),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
@pytest.mark.parametrize("settings", [{"favor_recall": True}, {"favor_recall": True, "fast": True}])
|
@pytest.mark.parametrize("settings", [{"favor_recall": True}, {"favor_recall": True, "fast": True}])
|
||||||
def test_forum_thread_is_not_a_listing(posters, linked, forum_markup, settings):
|
def test_forum_thread_is_not_a_listing(posters, markup, settings):
|
||||||
"forum posts line up like listing entries, but taking their container brings every user card along"
|
"forum posts line up like listing entries, but taking their container brings every user card along"
|
||||||
doc = _forum_thread(posters, linked, forum_markup)
|
doc = _forum_thread(posters, **markup)
|
||||||
with _without_listing_expression():
|
with _without_listing_expression():
|
||||||
expected = extract(doc, output_format="markdown", config=use_config(), **settings)
|
expected = extract(doc, output_format="markdown", config=use_config(), **settings)
|
||||||
result = extract(doc, output_format="markdown", config=use_config(), **settings) or ""
|
result = extract(doc, output_format="markdown", config=use_config(), **settings) or ""
|
||||||
|
|||||||
@@ -665,9 +665,12 @@ def _holds_most_of_the_text(tree: HtmlElement, expr: XPath) -> bool:
|
|||||||
def _entries_link_out(container: _Element) -> bool:
|
def _entries_link_out(container: _Element) -> bool:
|
||||||
"""Whether every entry of the container is a teaser: its first heading links to a page of its
|
"""Whether every entry of the container is a teaser: its first heading links to a page of its
|
||||||
own, which no other entry links to. Forum posts share the shape but open with the poster's
|
own, which no other entry links to. Forum posts share the shape but open with the poster's
|
||||||
name, which comes back along the thread or carries no link at all."""
|
name, which comes back along the thread or carries no link at all, and they hold user cards
|
||||||
|
(description lists) and quotes, which teasers do not."""
|
||||||
targets: set[str] = set()
|
targets: set[str] = set()
|
||||||
for entry in container.iterchildren("article"):
|
for entry in container.iterchildren("article"):
|
||||||
|
if entry.find(".//list[@rend='dl']") is not None or entry.find(".//quote") is not None:
|
||||||
|
return False
|
||||||
heading = entry.find(".//head")
|
heading = entry.find(".//head")
|
||||||
link = heading.find(".//ref") if heading is not None else None
|
link = heading.find(".//ref") if heading is not None else None
|
||||||
if link is None:
|
if link is None:
|
||||||
|
|||||||
Reference in new issue
Block a user