Skip to content

Commit

Permalink
Add support for experimental tag
Browse files Browse the repository at this point in the history
  • Loading branch information
hoodmane committed May 9, 2024
1 parent a012f65 commit 125b367
Show file tree
Hide file tree
Showing 13 changed files with 154 additions and 28 deletions.
1 change: 1 addition & 0 deletions sphinx_js/ir.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@ class TopLevel:
line: int | None
#: Explanation of the deprecation (which implies True) or True or False
deprecated: Description | bool
experimental: Description | bool = field(kw_only=True, default=False)
#: List of preformatted textual examples
examples: Sequence[Description]
#: List of paths to also refer the reader to
Expand Down
10 changes: 9 additions & 1 deletion sphinx_js/js/call_typedoc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,15 @@ async function main() {
return ExitCodes.Ok;
}
app.extraData = {};
app.options.getValue("modifierTags").push("@hidetype");
const modifierTags = app.options.getValue("modifierTags");
modifierTags.push("@hidetype");
// We want to use @experimental as a block tag so take it out of modifierTags
// and stick it in blockTags
const experimentalIndex = modifierTags.indexOf("@experimental");
if (experimentalIndex !== -1) {
modifierTags.splice(experimentalIndex, 1);
}
app.options.getValue("blockTags").push("@experimental");
const userConfigPath = app.options.getValue("sphinxJsConfig");
const config = await loadConfig(userConfigPath);
app.logger.info(`Loaded user config from ${userConfigPath}`);
Expand Down
6 changes: 6 additions & 0 deletions sphinx_js/js/convertTopLevel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,11 @@ export class Converter {
if (deprecated && deprecated.length === 0) {
deprecated = true;
}
let experimental: Description | boolean =
block_tags["experimental"]?.[0] || false;
if (experimental && experimental.length === 0) {
experimental = true;
}
return {
name: refl.name,
path,
Expand All @@ -682,6 +687,7 @@ export class Converter {
modifier_tags: Array.from(refl.comment?.modifierTags || []),
block_tags,
deprecated,
experimental,
examples: block_tags["example"] || [],
properties: [],
see_alsos: [],
Expand Down
1 change: 1 addition & 0 deletions sphinx_js/js/ir.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export type TopLevel = {
block_tags: { [key: string]: Description[] };
line: number | null;
deprecated: Description | boolean;
experimental: Description | boolean;
examples: Description[];
see_alsos: string[];
properties: Attribute[];
Expand Down
15 changes: 14 additions & 1 deletion sphinx_js/renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,9 @@ def _template_vars(self, name: str, obj: Function) -> dict[str, Any]: # type: i
deprecated = obj.deprecated
if not isinstance(deprecated, bool):
deprecated = render_description(deprecated)
experimental = obj.experimental
if not isinstance(experimental, bool):
experimental = render_description(experimental)
return dict(
name=name,
type_params=self._type_params(obj),
Expand All @@ -564,6 +567,7 @@ def _template_vars(self, name: str, obj: Function) -> dict[str, Any]: # type: i
description=render_description(obj.description),
examples=[render_description(x) for x in obj.examples],
deprecated=deprecated,
experimental=experimental,
is_optional=obj.is_optional,
is_static=obj.is_static,
is_async=obj.is_async,
Expand Down Expand Up @@ -592,6 +596,7 @@ def _template_vars(self, name: str, obj: Class | Interface) -> dict[str, Any]:
description="",
line=0,
deprecated=False,
experimental=False,
examples=[],
see_alsos=[],
properties=[],
Expand All @@ -615,6 +620,7 @@ def _template_vars(self, name: str, obj: Class | Interface) -> dict[str, Any]:
fields=self._fields(constructor),
examples=[render_description(ex) for ex in constructor.examples],
deprecated=constructor.deprecated,
experimental=constructor.experimental,
see_also=constructor.see_alsos,
exported_from=obj.exported_from,
class_comment=render_description(obj.description),
Expand Down Expand Up @@ -672,6 +678,12 @@ def _template_vars(self, name: str, obj: Attribute | TypeAlias) -> dict[str, Any
if obj.readonly:
ty = "readonly " + ty
type_params = ""
deprecated = obj.deprecated
if not isinstance(deprecated, bool):
deprecated = render_description(deprecated)
experimental = obj.experimental
if not isinstance(experimental, bool):
experimental = render_description(experimental)
is_type_alias = isinstance(obj, TypeAlias)
fields: Iterator[tuple[list[str], str]] = iter([])
if isinstance(obj, TypeAlias):
Expand All @@ -683,7 +695,8 @@ def _template_vars(self, name: str, obj: Attribute | TypeAlias) -> dict[str, Any
type_params=type_params,
fields=fields,
description=render_description(obj.description),
deprecated=obj.deprecated,
deprecated=deprecated,
experimental=experimental,
is_optional=is_optional,
see_also=obj.see_alsos,
examples=[render_description(ex) for ex in obj.examples],
Expand Down
1 change: 1 addition & 0 deletions sphinx_js/templates/attribute.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@


{{ common.deprecated(deprecated)|indent(3) }}
{{ common.experimental(experimental)|indent(3) }}

{% if type -%}
.. rst-class:: js attribute type
Expand Down
1 change: 1 addition & 0 deletions sphinx_js/templates/class.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
{%- endif %}

{{ common.deprecated(deprecated)|indent(3) }}
{{ common.experimental(experimental)|indent(3) }}

{% if class_comment -%}
{{ class_comment|indent(3) }}
Expand Down
15 changes: 12 additions & 3 deletions sphinx_js/templates/common.rst
Original file line number Diff line number Diff line change
@@ -1,9 +1,18 @@
{% macro deprecated(message) %}
{% if message -%}
.. note::
.. admonition:: Deprecated
:class: warning

Deprecated
{%- if message is string -%}: {{ message }}{% else %}.{% endif -%}
{% if message is string -%} {{ message }} {%- else -%} .. Not empty {%- endif -%}
{%- endif %}
{% endmacro %}

{% macro experimental(message) %}
{% if message -%}
.. admonition:: Experimental
:class: warning

{% if message is string -%} {{ message }} {%- else -%} .. Not empty {%- endif -%}
{%- endif %}
{% endmacro %}

Expand Down
1 change: 1 addition & 0 deletions sphinx_js/templates/function.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
{% endif %}

{{ common.deprecated(deprecated)|indent(3) }}
{{ common.experimental(experimental)|indent(3) }}

{% if description -%}
{{ description|indent(3) }}
Expand Down
18 changes: 6 additions & 12 deletions tests/test_build_js/test_build_js.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,9 @@ def test_autofunction_deprecated(self):
self._file_contents_eq(
"autofunction_deprecated",
"deprecatedFunction()\n\n"
" Note:\n\n"
" Deprecated.\n\n"
" Deprecated:\n\n"
"deprecatedExplanatoryFunction()\n\n"
" Note:\n\n"
" Deprecated: don't use anymore\n",
" Deprecated: don't use anymore\n",
)

def test_autofunction_see(self):
Expand Down Expand Up @@ -278,11 +276,9 @@ def test_autoclass_deprecated(self):
self._file_contents_eq(
"autoclass_deprecated",
"class DeprecatedClass()\n\n"
" Note:\n\n"
" Deprecated.\n\n"
" Deprecated:\n\n"
"class DeprecatedExplanatoryClass()\n\n"
" Note:\n\n"
" Deprecated: don't use anymore\n",
" Deprecated: don't use anymore\n",
)

def test_autoclass_see(self):
Expand Down Expand Up @@ -316,11 +312,9 @@ def test_autoattribute_deprecated(self):
self._file_contents_eq(
"autoattribute_deprecated",
"DeprecatedAttribute\n\n"
" Note:\n\n"
" Deprecated.\n\n"
" Deprecated:\n\n"
"DeprecatedExplanatoryAttribute\n\n"
" Note:\n\n"
" Deprecated: don't use anymore\n",
" Deprecated: don't use anymore\n",
)

def test_autoattribute_see(self):
Expand Down
10 changes: 10 additions & 0 deletions tests/test_build_ts/source/class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,16 @@ export function deprecatedFunction1() {}
*/
export function deprecatedFunction2() {}

/**
* @experimental Not ready yet.
*/
export function experimentalFunction1() {}

/**
* @experimental
*/
export function experimentalFunction2() {}

/**
* @example This is an example.
* @example This is another example.
Expand Down
22 changes: 17 additions & 5 deletions tests/test_build_ts/test_build_ts.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,15 +111,27 @@ def test_deprecated(self):
"""\
deprecatedFunction1()
Note:
Deprecated: since v20!
Deprecated: since v20!
deprecatedFunction2()
Note:
Deprecated:
"""
),
)

def test_experimental(self):
self._file_contents_eq(
"experimental",
dedent(
"""\
experimentalFunction1()
Experimental: Not ready yet.
experimentalFunction2()
Deprecated.
Experimental:
"""
),
)
Expand Down
81 changes: 75 additions & 6 deletions tests/test_renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,16 +426,18 @@ def test_func_render_param_exceptions(function_render):
def test_func_render_callouts(function_render):
assert function_render(deprecated=True) == DEFAULT_RESULT + setindent(
"""
.. note::
.. admonition:: Deprecated
:class: warning
Deprecated.
.. Not empty
""",
)
assert function_render(deprecated="v0.24") == DEFAULT_RESULT + setindent(
"""
.. note::
.. admonition:: Deprecated
:class: warning
Deprecated: v0.24
v0.24
""",
)
assert function_render(see_alsos=["see", "this too"]) == DEFAULT_RESULT + setindent(
Expand All @@ -460,9 +462,10 @@ def test_all(function_render):
"""\
.. js:function:: blah(a)
.. note::
.. admonition:: Deprecated
:class: warning
Deprecated.
.. Not empty
description
Expand Down Expand Up @@ -562,3 +565,69 @@ def test_type_alias(type_alias_render):
:typeparam T: ABC (extends **number**)
"""
)


def admonition_test_content(first_line, admonition, extra=""):
return (
dedent(
f"""\
{first_line}
.. admonition:: {admonition}
:class: warning
{extra}
"""
).strip()
+ "\n"
)


@pytest.mark.parametrize(
"deprecated,expected",
[
(True, ".. Not empty"),
("Blah", "Blah"),
(
[DescriptionText("This is "), DescriptionCode("`some code`")],
"This is ``some code``",
),
],
)
def test_deprecated(
function_render, attribute_render, type_alias_render, deprecated, expected
):
assert function_render(deprecated=deprecated) == admonition_test_content(
".. js:function:: blah()", "Deprecated", expected
)
assert attribute_render(deprecated=deprecated) == admonition_test_content(
".. js:attribute:: blah", "Deprecated", expected
)
assert type_alias_render(deprecated=deprecated) == admonition_test_content(
".. js:typealias:: blah", "Deprecated", expected
)


@pytest.mark.parametrize(
"experimental,expected",
[
(True, ".. Not empty"),
("Blah", "Blah"),
(
[DescriptionText("This is "), DescriptionCode("`some code`")],
"This is ``some code``",
),
],
)
def test_experimental(
function_render, attribute_render, type_alias_render, experimental, expected
):
assert function_render(experimental=experimental) == admonition_test_content(
".. js:function:: blah()", "Experimental", expected
)
assert attribute_render(experimental=experimental) == admonition_test_content(
".. js:attribute:: blah", "Experimental", expected
)
assert type_alias_render(experimental=experimental) == admonition_test_content(
".. js:typealias:: blah", "Experimental", expected
)

0 comments on commit 125b367

Please sign in to comment.