blob: 954c37d0a70a7aee8297db69674579e4189066ca [file]
# Copyright 2026 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import unittest
from scripts.docs import clr_converter
def _read_data_file(basename):
path = os.path.join(
os.getenv("TEST_SRCDIR"),
os.getenv("TEST_WORKSPACE"),
"scripts/docs/testdata",
basename,
)
with open(path, "rt", encoding="utf-8") as f:
return f.read()
class ConvertTest(unittest.TestCase):
def test_full_conversion(self):
html_content = _read_data_file("clr_input.html")
expected = _read_data_file("clr_expected.mdx")
actual = clr_converter.convert(html_content)
self.assertEqual(actual, expected)
def test_boolean_option(self):
html_input = """
<h2>Commands</h2>
<table></table>
<h2>Options</h2>
<dl>Category:
<dt id="opts-flag--batch"><code><a href="#opts-flag--batch">--[no]batch</a></code> default: "false"</dt>
<dd><p>Run in batch mode.</p></dd>
</dl>
"""
result = clr_converter.convert(html_input)
self.assertIn('path="--[no]batch"', result)
self.assertIn('type="boolean"', result)
self.assertIn('default="false"', result)
def test_typed_option(self):
html_input = """
<h2>Commands</h2>
<table></table>
<h2>Options</h2>
<dl>Category:
<dt id="opts-flag--jobs"><code><a href="#opts-flag--jobs">--jobs</a>=&lt;an integer&gt;</code> default: "auto"</dt>
<dd><p>Number of jobs.</p></dd>
</dl>
"""
result = clr_converter.convert(html_input)
self.assertIn('path="--jobs"', result)
self.assertIn('type="an integer"', result)
self.assertIn('default="auto"', result)
def test_void_expansion_option(self):
html_input = """
<h2>Commands</h2>
<table></table>
<h2>Options</h2>
<dl>Category:
<dt id="opts-flag--debug"><code><a href="#opts-flag--debug">--debug</a></code></dt>
<dd>
<p>Enable debug mode.</p>
<p>Expands to:
<br/>&nbsp;&nbsp;<code><a href="#flag--verbose">--verbose</a></code>
</p></dd>
</dl>
"""
result = clr_converter.convert(html_input)
self.assertIn('type="void"', result)
self.assertIn("Expands to:", result)
self.assertIn("`--verbose`", result)
self.assertNotIn("default=", result)
def test_allow_multiple_option(self):
html_input = """
<h2>Commands</h2>
<table></table>
<h2>Options</h2>
<dl>Category:
<dt id="opts-flag--rc"><code><a href="#opts-flag--rc">--rc</a>=&lt;path&gt;</code> multiple uses are accumulated</dt>
<dd><p>RC file location.</p></dd>
</dl>
"""
result = clr_converter.convert(html_input)
self.assertIn("May be used multiple times", result)
self.assertNotIn("default=", result)
def test_deprecated_option(self):
html_input = """
<h2>Commands</h2>
<table></table>
<h2>Options</h2>
<dl>Category:
<dt id="opts-flag--old"><code><a href="#opts-flag--old">--[no]old</a></code> default: "false"</dt>
<dd><p>Old flag.</p>
<p>Tags:
<a href="#metadata_tag_DEPRECATED"><code>deprecated</code></a>
</p></dd>
</dl>
"""
result = clr_converter.convert(html_input)
self.assertIn("deprecated", result)
def test_abbreviation(self):
html_input = """
<h2>Commands</h2>
<table></table>
<h2>Options</h2>
<dl>Category:
<dt id="opts-flag--jobs"><code><a href="#opts-flag--jobs">--jobs</a>=&lt;an integer&gt;</code> [<code>-j</code>] default: "8"</dt>
<dd><p>Number of jobs.</p></dd>
</dl>
"""
result = clr_converter.convert(html_input)
self.assertIn("Short form: `-j`", result)
def test_inherits_from(self):
html_input = """
<h2>Commands</h2>
<table></table>
<h2><a name="build">Build Options</a></h2>
<p>Inherits all options from <a href="#common">common</a> and <a href="#test">test</a>.</p>
<dl>Cat:
<dt id="build-flag--f"><code><a href="#build-flag--f">--[no]f</a></code> default: "true"</dt>
<dd><p>A flag.</p></dd>
</dl>
"""
result = clr_converter.convert(html_input)
self.assertIn(
"Inherits all options from [common](#common) and [test](#test)", result
)
self.assertIn("{#build}", result)
def test_enum_type_escaping(self):
html_input = """
<h2>Commands</h2>
<table></table>
<h2>Options</h2>
<dl>Category:
<dt id="opts-flag--level"><code><a href="#opts-flag--level">--level</a>={0,1,2}</code> default: "0"</dt>
<dd><p>Set level.</p></dd>
</dl>
"""
result = clr_converter.convert(html_input)
self.assertIn("&lcub;0,1,2&rcub;", result)
def test_quotes_in_type_description(self):
html_input = """
<h2>Commands</h2>
<table></table>
<h2>Options</h2>
<dl>Category:
<dt id="opts-flag--jobs"><code><a href="#opts-flag--jobs">--jobs</a>=&lt;an integer, or a keyword ("auto", "HOST_CPUS")&gt;</code> default: "auto"</dt>
<dd><p>Number of jobs.</p></dd>
</dl>
"""
result = clr_converter.convert(html_input)
self.assertNotIn('("auto"', result)
self.assertIn("&quot;auto&quot;", result)
def test_angle_brackets_in_type_description(self):
html_input = """
<h2>Commands</h2>
<table></table>
<h2>Options</h2>
<dl>Category:
<dt id="opts-flag--mem"><code><a href="#opts-flag--mem">--mem</a>=&lt;an integer or "HOST_RAM", followed by [-|*]&lt;float&gt;&gt;</code> default: "0"</dt>
<dd><p>Memory limit.</p></dd>
</dl>
"""
result = clr_converter.convert(html_input)
for line in result.split("\n"):
if "<ParamField" in line:
self.assertNotIn("*]<float", line)
self.assertIn("&lt;float&gt;", line)
break
def test_commands_table(self):
html_input = """
<h2>Commands</h2>
<table>
<tr>
<td><a href="#build"><code>build</code></a></td>
<td>Build targets.</td>
</tr>
</table>
<h2>Options</h2>
<dl>Cat:
<dt id="f"><code><a href="#f">--[no]f</a></code> default: "true"</dt>
<dd><p>Flag.</p></dd>
</dl>
"""
result = clr_converter.convert(html_input)
self.assertIn("## Commands", result)
self.assertIn("[`build`](#build)", result)
self.assertIn("Build targets.", result)
def test_tag_tables(self):
html_input = """
<h2>Commands</h2>
<table></table>
<h3>Option Effect Tags</h3>
<table>
<tr>
<td id="effect_tag_FOO"><code>foo</code></td>
<td>Foo description.</td>
</tr>
</table>
"""
result = clr_converter.convert(html_input)
self.assertIn("### Option Effect Tags", result)
self.assertIn('<span id="effect_tag_FOO">`foo`</span>', result)
self.assertIn("Foo description.", result)
if __name__ == "__main__":
unittest.main()