Skip to content

Commit 158d7dc

Browse files
hynekmofeing
andcommitted
Add support for URL-encoded filenames
Co-authored-by: Sergio Sánchez <mofeing@gmail.com>
1 parent cb55950 commit 158d7dc

3 files changed

Lines changed: 50 additions & 19 deletions

File tree

CHANGELOG.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@
33
Changelog
44
=========
55

6+
2.4.1 (2021-12-23)
7+
------------------
8+
9+
- Fix URL decoding of filenames.
10+
`#104 <https://github.com/hynek/doc2dash/pull/104>`_
11+
12+
13+
----
14+
15+
616
2.4.0 (2021-11-16)
717
------------------
818

src/doc2dash/parsers/utils.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import errno
44
import logging
55
import os
6+
import urllib
67

78
from collections import defaultdict
89

@@ -108,13 +109,14 @@ def patch_anchors(parser, show_progressbar):
108109

109110
def patch_files(files):
110111
for fname, entries in files:
112+
fname = urllib.parse.unquote(fname)
111113
full_path = os.path.join(parser.doc_path, fname)
112114
with codecs.open(full_path, mode="r", encoding="utf-8") as fp:
113115
soup = BeautifulSoup(fp, "html.parser")
114116
for entry in entries:
115117
if not parser.find_and_patch_entry(soup, entry):
116118
log.debug(
117-
"Can't find anchor '%s' (%s) in %s.",
119+
"Can't find anchor '%s' (%s) in %r.",
118120
entry.anchor,
119121
entry.type,
120122
click.format_filename(fname),

tests/parsers/test_utils.py

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from unittest.mock import patch
1+
import logging
22

33
import attr
44
import pytest
@@ -34,14 +34,21 @@ def find_and_patch_entry(self, soup, entry):
3434
return self._succeed_patching
3535

3636

37-
@pytest.fixture
38-
def entries():
37+
@pytest.fixture(name="doc_entries")
38+
def _doc_entries(tmpdir):
3939
"""
4040
Test `ParserEntry`s
4141
"""
42-
return [
43-
ParserEntry(name="foo", type="Method", path="bar.html#foo"),
42+
test_dir = tmpdir.mkdir("foo")
43+
test_dir.join("bar.html").write("docs!")
44+
test_dir.join("foo bar.html").write("docs too!")
45+
46+
return test_dir, [
47+
ParserEntry(name="foo", type="Method", path="bar.html#anchor-1"),
4448
ParserEntry(name="qux", type="Class", path="bar.html"),
49+
ParserEntry(
50+
name="foo-url", type="Method", path="foo%20bar.html#anchor-2"
51+
),
4552
]
4653

4754

@@ -55,35 +62,47 @@ def test_with_empty_db(self, progressbar):
5562
toc = patch_anchors(parser, show_progressbar=progressbar)
5663
toc.close()
5764

58-
def test_single_entry(self, monkeypatch, tmpdir, entries):
65+
def test_single_entry(self, doc_entries):
5966
"""
6067
Only entries with URL anchors get patched.
6168
"""
62-
foo = tmpdir.mkdir("foo")
63-
foo.join("bar.html").write("docs!")
64-
parser = FakeParser(doc_path=str(foo))
69+
path, entries = doc_entries
70+
parser = FakeParser(doc_path=str(path))
71+
6572
toc = patch_anchors(parser, show_progressbar=False)
6673
for e in entries:
67-
print(e)
6874
toc.send(e)
6975
toc.close()
76+
7077
assert [
71-
TOCEntry(name="foo", type="Method", anchor="foo")
78+
TOCEntry(name="foo", type="Method", anchor="anchor-1"),
79+
TOCEntry(name="foo-url", type="Method", anchor="anchor-2"),
7280
] == parser._patched_entries
7381

74-
def test_complains(self, entries, tmpdir):
82+
def test_complains(self, doc_entries, caplog):
7583
"""
7684
If patching fails, a debug message is logged.
7785
"""
78-
foo = tmpdir.mkdir("foo")
79-
foo.join("bar.html").write("docs!")
80-
parser = FakeParser(doc_path=str(foo), succeed_patching=False)
86+
from doc2dash.parsers.utils import log
87+
88+
old_level = log.getEffectiveLevel()
89+
log.setLevel(logging.DEBUG)
90+
91+
path, entries = doc_entries
92+
93+
parser = FakeParser(doc_path=str(path), succeed_patching=False)
8194
toc = patch_anchors(parser, show_progressbar=False)
8295
for e in entries:
8396
toc.send(e)
84-
with patch("doc2dash.parsers.utils.log.debug") as mock:
85-
toc.close()
86-
assert mock.call_count == 1
97+
98+
toc.close()
99+
100+
assert [
101+
"Can't find anchor 'anchor-1' (Method) in 'bar.html'.",
102+
"Can't find anchor 'anchor-2' (Method) in 'foo bar.html'.",
103+
] == caplog.messages
104+
105+
log.setLevel(old_level)
87106

88107

89108
class TestHasFileWith:

0 commit comments

Comments
 (0)