Skip to content

Commit

Permalink
Tolerate ../ prefixes in suffix-tree paths. Fix #103. Fix #109.
Browse files Browse the repository at this point in the history
These occur when `root_for_relative_js_paths` is set inward of the JS code.
  • Loading branch information
erikrose committed Aug 6, 2020
1 parent 9205cab commit 63ec399
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 10 deletions.
24 changes: 15 additions & 9 deletions sphinx_js/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@
# Invalid JS symbol names and wild-and-crazy placement of slashes later in
# the path (after the FS path is over) will be caught at name-resolution
# time.
# Note that "." is a non-separator char only when used at the very front.
path = maybe_cur_dir middle_segments name
#
# Note that "." is a non-separator char only when used in ./ and ../
# prefixes.
path = relative_dir* middle_segments name
# A name is a series of non-separator (not ~#/.), non-(, and backslashed
# characters.
name = ~r"(?:[^(/#~.\\]|\\.)+"
sep = ~r"[#~/.]"
maybe_cur_dir = cur_dir?
cur_dir = "./"
relative_dir = "./" / "../"
middle_segments = name_and_sep*
name_and_sep = name sep
formal_params = ~r".*"
Expand All @@ -40,8 +41,8 @@ def visit_sep(self, node, children):
return node.text

def visit_path(self, node, children):
cur_dir, middle_segments, name = children
segments = cur_dir[:]
relative_dirs, middle_segments, name = children
segments = relative_dirs[:]
segments.extend(middle_segments)
segments.append(name)
return segments
Expand All @@ -53,16 +54,21 @@ def visit_name_and_sep(self, node, children):
def visit_formal_params(self, node, children):
return node.text

def visit_maybe_cur_dir(self, node, children):
"""Return ['./'] or []."""
return children
def visit_relative_dir(self, node, children):
"""Return './' or '../'."""
return node.text

def visit_cur_dir(self, node, children):
return node.text

def visit_middle_segments(self, node, children):
return children

def generic_visit(self, node, visited_children):
"""``relative_dir*`` has already turned each item of ``children`` into
'./' or '../'. Just pass the list of those through."""
return visited_children


def _backslash_unescape(str):
"""Return a string with backslash escape sequences replaced with their
Expand Down
5 changes: 5 additions & 0 deletions tests/test_dot_dot_paths/source/code.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
/**
* Bar function
*/
function bar(node) {
}
11 changes: 11 additions & 0 deletions tests/test_dot_dot_paths/source/docs/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
extensions = [
'sphinx_js'
]

# Minimal stuff needed for Sphinx to work:
source_suffix = '.rst'
master_doc = 'index'
author = u'Erik Rose'
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
root_for_relative_js_paths = './'
1 change: 1 addition & 0 deletions tests/test_dot_dot_paths/source/docs/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.. js:autofunction:: bar
16 changes: 16 additions & 0 deletions tests/test_dot_dot_paths/test_dot_dot_paths.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from tests.testing import SphinxBuildTestCase


class Tests(SphinxBuildTestCase):
def test_dot_dot(self):
"""Make sure the build doesn't explode with a parse error on
the "../more.bar" path that is constructed when the JSDoc doclets are
imbibed.
Also make sure it render correctly afterward.
"""
self._file_contents_eq(
'index',
'bar(node)\n\n'
' Bar function\n')
11 changes: 10 additions & 1 deletion tests/test_parsers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from sphinx_js.parsers import PathVisitor
from sphinx_js.parsers import PathVisitor, path_and_formal_params


def test_escapes():
Expand All @@ -8,3 +8,12 @@ def test_escapes():
[r'd.i:nr/', r'ut\ils.', 'max'],
'(whatever)',
]


def test_relative_dirs():
"""Make sure all sorts of relative-dir prefixes result in proper path
segment arrays."""
assert PathVisitor().visit(
path_and_formal_params['path'].parse('./hi')) == ['./', 'hi']
assert PathVisitor().visit(
path_and_formal_params['path'].parse('../../hi')) == ['../', '../', 'hi']

0 comments on commit 63ec399

Please sign in to comment.