aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorc-parsons <cparsons@google.com>2019-08-30 16:16:25 -0400
committerGitHub <noreply@github.com>2019-08-30 16:16:25 -0400
commit2c81ab8f05a0d89fcb926b8aa7d8345c3b643faf (patch)
treefe02510f698cc91f118f91afacf1ae348f10b8a4
parentc7bbde2950769aac9a99364b0926230060a3ce04 (diff)
downloadstardoc-2c81ab8f05a0d89fcb926b8aa7d8345c3b643faf.tar.gz
Update release jars and introduce e2e tests (#230)
]
-rw-r--r--WORKSPACE2
-rwxr-xr-xstardoc/renderer_binary.jarbin9258776 -> 9247130 bytes
-rwxr-xr-xstardoc/stardoc_binary.jarbin9629358 -> 9620394 bytes
-rw-r--r--test/BUILD234
-rw-r--r--test/stardoc_test.bzl121
-rw-r--r--test/testdata/android_basic_test/golden.txt57
-rw-r--r--test/testdata/android_basic_test/input.bzl27
-rw-r--r--test/testdata/angle_bracket_test/golden.txt116
-rw-r--r--test/testdata/angle_bracket_test/input.bzl38
-rw-r--r--test/testdata/apple_basic_test/golden.txt57
-rw-r--r--test/testdata/apple_basic_test/input.bzl22
-rw-r--r--test/testdata/aspect_test/golden.txt148
-rw-r--r--test/testdata/aspect_test/input.bzl24
-rw-r--r--test/testdata/attribute_types_test/golden.txt141
-rw-r--r--test/testdata/attribute_types_test/input.bzl23
-rw-r--r--test/testdata/cc_api_test/golden.txt97
-rw-r--r--test/testdata/cc_api_test/input.bzl20
-rw-r--r--test/testdata/config_apis_test/golden.txt104
-rw-r--r--test/testdata/config_apis_test/input.bzl25
-rw-r--r--test/testdata/cpp_basic_test/golden.txt57
-rw-r--r--test/testdata/cpp_basic_test/input.bzl20
-rw-r--r--test/testdata/filter_rules_test/dep.bzl16
-rw-r--r--test/testdata/filter_rules_test/golden.txt94
-rw-r--r--test/testdata/filter_rules_test/input.bzl40
-rw-r--r--test/testdata/function_basic_test/golden.txt128
-rw-r--r--test/testdata/function_basic_test/input.bzl38
-rw-r--r--test/testdata/generated_bzl_test/dep.bzl.tpl4
-rw-r--r--test/testdata/generated_bzl_test/golden.txt48
-rw-r--r--test/testdata/generated_bzl_test/input.bzl16
-rw-r--r--test/testdata/input_template_test/aspect.vm32
-rw-r--r--test/testdata/input_template_test/func.vm29
-rw-r--r--test/testdata/input_template_test/golden.txt138
-rw-r--r--test/testdata/input_template_test/header.vm3
-rw-r--r--test/testdata/input_template_test/input.bzl47
-rw-r--r--test/testdata/input_template_test/provider.vm22
-rw-r--r--test/testdata/input_template_test/rule.vm28
-rw-r--r--test/testdata/java_basic_test/golden.txt57
-rw-r--r--test/testdata/java_basic_test/input.bzl22
-rw-r--r--test/testdata/macro_kwargs_test/golden.txt168
-rw-r--r--test/testdata/macro_kwargs_test/input.bzl52
-rw-r--r--test/testdata/misc_apis_test/golden.txt152
-rw-r--r--test/testdata/misc_apis_test/input.bzl57
-rw-r--r--test/testdata/multi_level_namespace_test/golden.txt119
-rw-r--r--test/testdata/multi_level_namespace_test/input.bzl32
-rw-r--r--test/testdata/multi_level_namespace_test_with_whitelist/golden.txt70
-rw-r--r--test/testdata/multi_level_namespace_test_with_whitelist/input.bzl23
-rw-r--r--test/testdata/multiple_files_test/dep.bzl17
-rw-r--r--test/testdata/multiple_files_test/golden.txt171
-rw-r--r--test/testdata/multiple_files_test/inner_dep.bzl9
-rw-r--r--test/testdata/multiple_files_test/input.bzl41
-rw-r--r--test/testdata/multiple_rules_test/golden.txt153
-rw-r--r--test/testdata/multiple_rules_test/input.bzl31
-rw-r--r--test/testdata/namespace_test/golden.txt113
-rw-r--r--test/testdata/namespace_test/input.bzl43
-rw-r--r--test/testdata/proto_format_test/golden.raw16
-rw-r--r--test/testdata/proto_format_test/input.bzl35
-rw-r--r--test/testdata/provider_basic_test/golden.txt85
-rw-r--r--test/testdata/provider_basic_test/input.bzl18
-rw-r--r--test/testdata/providers_for_attributes_test/dep.bzl5
-rw-r--r--test/testdata/providers_for_attributes_test/golden.txt164
-rw-r--r--test/testdata/providers_for_attributes_test/input.bzl42
-rw-r--r--test/testdata/pure_markdown_template_test/golden.txt90
-rw-r--r--test/testdata/pure_markdown_template_test/input.bzl44
-rw-r--r--test/testdata/py_rule_test/golden.txt81
-rw-r--r--test/testdata/py_rule_test/input.bzl32
-rw-r--r--test/testdata/repo_rules_test/golden.txt42
-rw-r--r--test/testdata/repo_rules_test/input.bzl14
-rw-r--r--test/testdata/same_level_file_test/BUILD14
-rw-r--r--test/testdata/same_level_file_test/dep.bzl5
-rw-r--r--test/testdata/same_level_file_test/golden.txt48
-rw-r--r--test/testdata/same_level_file_test/input.bzl15
-rw-r--r--test/testdata/simple_test/golden.txt63
-rw-r--r--test/testdata/simple_test/input.bzl19
-rw-r--r--test/testdata/struct_default_value_test/golden.txt69
-rw-r--r--test/testdata/struct_default_value_test/input.bzl22
-rw-r--r--test/testdata/unknown_name_test/golden.txt30
-rw-r--r--test/testdata/unknown_name_test/input.bzl13
77 files changed, 4311 insertions, 1 deletions
diff --git a/WORKSPACE b/WORKSPACE
index 648965e..a1b0395 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -33,7 +33,7 @@ git_repository(
# Needed for generating the Stardoc release binary.
git_repository(
name = "io_bazel",
- commit = "858412781d76b7d27c39dc58b7f24cf645bdf035", # Aug 7, 2019
+ commit = "4ba404f7ed0473df3f0effa016c107ef677464f6", # Aug 23, 2019
remote = "https://github.com/bazelbuild/bazel.git",
)
diff --git a/stardoc/renderer_binary.jar b/stardoc/renderer_binary.jar
index 40ecbe3..448a908 100755
--- a/stardoc/renderer_binary.jar
+++ b/stardoc/renderer_binary.jar
Binary files differ
diff --git a/stardoc/stardoc_binary.jar b/stardoc/stardoc_binary.jar
index 44d8148..6a042cf 100755
--- a/stardoc/stardoc_binary.jar
+++ b/stardoc/stardoc_binary.jar
Binary files differ
diff --git a/test/BUILD b/test/BUILD
index 7102640..c76f0ba 100644
--- a/test/BUILD
+++ b/test/BUILD
@@ -1,3 +1,5 @@
+load(":stardoc_test.bzl", "stardoc_test")
+
licenses(["notice"]) # Apache 2.0
sh_test(
@@ -12,3 +14,235 @@ sh_test(
"//stardoc:stardoc_doc.md",
],
)
+
+stardoc_test(
+ name = "input_template_test",
+ aspect_template = "testdata/input_template_test/aspect.vm",
+ func_template = "testdata/input_template_test/func.vm",
+ golden_file = "testdata/input_template_test/golden.txt",
+ header_template = "testdata/input_template_test/header.vm",
+ input_file = "testdata/input_template_test/input.bzl",
+ provider_template = "testdata/input_template_test/provider.vm",
+ rule_template = "testdata/input_template_test/rule.vm",
+)
+
+stardoc_test(
+ name = "angle_bracket_test",
+ golden_file = "testdata/angle_bracket_test/golden.txt",
+ input_file = "testdata/angle_bracket_test/input.bzl",
+)
+
+stardoc_test(
+ name = "proto_format_test",
+ format = "proto",
+ golden_file = "testdata/proto_format_test/golden.raw",
+ input_file = "testdata/proto_format_test/input.bzl",
+)
+
+stardoc_test(
+ name = "cc_api_test",
+ golden_file = "testdata/cc_api_test/golden.txt",
+ input_file = "testdata/cc_api_test/input.bzl",
+)
+
+stardoc_test(
+ name = "simple_test",
+ golden_file = "testdata/simple_test/golden.txt",
+ input_file = "testdata/simple_test/input.bzl",
+ symbol_names = ["my_rule"],
+)
+
+stardoc_test(
+ name = "repo_rule_test",
+ golden_file = "testdata/repo_rules_test/golden.txt",
+ input_file = "testdata/repo_rules_test/input.bzl",
+)
+
+stardoc_test(
+ name = "unknown_name",
+ golden_file = "testdata/unknown_name_test/golden.txt",
+ input_file = "testdata/unknown_name_test/input.bzl",
+)
+
+stardoc_test(
+ name = "multiple_rules_test",
+ golden_file = "testdata/multiple_rules_test/golden.txt",
+ input_file = "testdata/multiple_rules_test/input.bzl",
+)
+
+stardoc_test(
+ name = "android_basic_test",
+ golden_file = "testdata/android_basic_test/golden.txt",
+ input_file = "testdata/android_basic_test/input.bzl",
+ semantic_flags = [
+ "--experimental_google_legacy_api",
+ ],
+ symbol_names = ["android_related_rule"],
+)
+
+stardoc_test(
+ name = "apple_basic_test",
+ golden_file = "testdata/apple_basic_test/golden.txt",
+ input_file = "testdata/apple_basic_test/input.bzl",
+ symbol_names = ["apple_related_rule"],
+)
+
+stardoc_test(
+ name = "cpp_basic_test",
+ golden_file = "testdata/cpp_basic_test/golden.txt",
+ input_file = "testdata/cpp_basic_test/input.bzl",
+ symbol_names = ["cpp_related_rule"],
+)
+
+stardoc_test(
+ name = "java_basic_test",
+ golden_file = "testdata/java_basic_test/golden.txt",
+ input_file = "testdata/java_basic_test/input.bzl",
+ symbol_names = ["java_related_rule"],
+)
+
+stardoc_test(
+ name = "multiple_files_test",
+ golden_file = "testdata/multiple_files_test/golden.txt",
+ input_file = "testdata/multiple_files_test/input.bzl",
+ deps = [
+ "testdata/multiple_files_test/dep.bzl",
+ "testdata/multiple_files_test/inner_dep.bzl",
+ ],
+)
+
+stardoc_test(
+ name = "same_level_file_test",
+ golden_file = "//test/testdata/same_level_file_test:golden.txt",
+ input_file = "//test/testdata/same_level_file_test:input.bzl",
+ symbol_names = ["my_rule"],
+ deps = [
+ "//test/testdata/same_level_file_test:dep.bzl",
+ ],
+)
+
+stardoc_test(
+ name = "misc_apis_test",
+ golden_file = "testdata/misc_apis_test/golden.txt",
+ input_file = "testdata/misc_apis_test/input.bzl",
+)
+
+stardoc_test(
+ name = "attribute_types_test",
+ golden_file = "testdata/attribute_types_test/golden.txt",
+ input_file = "testdata/attribute_types_test/input.bzl",
+ symbol_names = ["my_rule"],
+)
+
+stardoc_test(
+ name = "filter_rules_test",
+ golden_file = "testdata/filter_rules_test/golden.txt",
+ input_file = "testdata/filter_rules_test/input.bzl",
+ symbol_names = [
+ "my_rule",
+ "whitelisted_dep_rule",
+ ],
+ deps = [
+ "testdata/filter_rules_test/dep.bzl",
+ ],
+)
+
+stardoc_test(
+ name = "provider_basic_test",
+ golden_file = "testdata/provider_basic_test/golden.txt",
+ input_file = "testdata/provider_basic_test/input.bzl",
+)
+
+stardoc_test(
+ name = "function_basic_test",
+ golden_file = "testdata/function_basic_test/golden.txt",
+ input_file = "testdata/function_basic_test/input.bzl",
+)
+
+stardoc_test(
+ name = "namespace_test",
+ golden_file = "testdata/namespace_test/golden.txt",
+ input_file = "testdata/namespace_test/input.bzl",
+)
+
+stardoc_test(
+ name = "namespace_test_with_whitelist",
+ golden_file = "testdata/namespace_test/golden.txt",
+ input_file = "testdata/namespace_test/input.bzl",
+ symbol_names = [
+ "my_namespace",
+ ],
+)
+
+stardoc_test(
+ name = "multi_level_namespace_test",
+ golden_file = "testdata/multi_level_namespace_test/golden.txt",
+ input_file = "testdata/multi_level_namespace_test/input.bzl",
+)
+
+stardoc_test(
+ name = "multi_level_namespace_test_with_whitelist",
+ golden_file = "testdata/multi_level_namespace_test_with_whitelist/golden.txt",
+ input_file = "testdata/multi_level_namespace_test_with_whitelist/input.bzl",
+ symbol_names = [
+ "my_namespace",
+ "other_namespace.foo.nothing",
+ ],
+)
+
+stardoc_test(
+ name = "macro_kwargs_test",
+ golden_file = "testdata/macro_kwargs_test/golden.txt",
+ input_file = "testdata/macro_kwargs_test/input.bzl",
+)
+
+stardoc_test(
+ name = "py_rule_test",
+ golden_file = "testdata/py_rule_test/golden.txt",
+ input_file = "testdata/py_rule_test/input.bzl",
+ symbol_names = ["py_related_rule"],
+)
+
+stardoc_test(
+ name = "struct_default_value_test",
+ golden_file = "testdata/struct_default_value_test/golden.txt",
+ input_file = "testdata/struct_default_value_test/input.bzl",
+)
+
+stardoc_test(
+ name = "aspect_test",
+ golden_file = "testdata/aspect_test/golden.txt",
+ input_file = "testdata/aspect_test/input.bzl",
+)
+
+stardoc_test(
+ name = "providers_for_attributes_test",
+ golden_file = "testdata/providers_for_attributes_test/golden.txt",
+ input_file = "testdata/providers_for_attributes_test/input.bzl",
+ deps = [
+ "testdata/providers_for_attributes_test/dep.bzl",
+ ],
+)
+
+stardoc_test(
+ name = "pure_markdown_template_test",
+ golden_file = "testdata/pure_markdown_template_test/golden.txt",
+ input_file = "testdata/pure_markdown_template_test/input.bzl",
+ test = "pure_markdown",
+)
+
+genrule(
+ name = "generate_bzl_test_dep",
+ srcs = ["testdata/generated_bzl_test/dep.bzl.tpl"],
+ outs = ["testdata/generated_bzl_test/dep.bzl"],
+ cmd = "cp $< $@",
+)
+
+stardoc_test(
+ name = "generated_bzl_test",
+ golden_file = "testdata/generated_bzl_test/golden.txt",
+ input_file = "testdata/generated_bzl_test/input.bzl",
+ deps = [
+ "testdata/generated_bzl_test/dep.bzl",
+ ],
+)
diff --git a/test/stardoc_test.bzl b/test/stardoc_test.bzl
new file mode 100644
index 0000000..5cfda3b
--- /dev/null
+++ b/test/stardoc_test.bzl
@@ -0,0 +1,121 @@
+# Copyright 2019 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.
+"""Convenience macro for stardoc e2e tests."""
+
+load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
+load("//stardoc:pure_markdown_stardoc.bzl", "pure_markdown_stardoc")
+load("//stardoc:stardoc.bzl", "stardoc")
+
+def stardoc_test(
+ name,
+ input_file,
+ golden_file,
+ deps = [],
+ test = "default",
+ **kwargs):
+ """Convenience macro for stardoc e2e test suites.
+
+ Each invocation creates four targets:
+
+ 1. A sh_test target which verifies that stardoc-built-from-source, when run on an input file,
+ creates output matching the contents of a golden file, named "{name}_e2e_test".
+ 2. A `stardoc` target which will generate a new golden file given an input file
+ with stardoc-built-from-source. This target should be used to regenerate
+ the golden file when updating stardoc, named "regenerate_{name}_golden".
+ 3 & 4. Targets identical to (1) and (2) except they use the prebuilt-stardoc jar, and
+ are named "{name}_e2e_jar_test" and "regenerate_with_jar_{name}_golden".
+ 5. A bzl_library target for convenient wrapping of input bzl files, named "{name}_lib".
+
+ Args:
+ name: A unique name to qualify the created targets.
+ input_file: The label string of the Starlark input file for which documentation is generated
+ in this test.
+ golden_file: The label string of the golden file containing the documentation when stardoc
+ is run on the input file.
+ deps: A list of label strings of starlark file dependencies of the input_file.
+ test: The type of test (default or pure_markdown).
+ **kwargs: A dictionary of input template names mapped to template file path for which documentation is generated.
+ """
+
+ bzl_library(
+ name = "%s_lib" % name,
+ srcs = [input_file],
+ deps = deps,
+ )
+ _create_test_targets(test_name = "%s_e2e_test" % name,
+ genrule_name = "regenerate_%s_golden" % name,
+ lib_name = "%s_lib" % name,
+ input_file = input_file,
+ golden_file = golden_file,
+ stardoc_bin = "@io_bazel//src/main/java/com/google/devtools/build/skydoc",
+ renderer_bin = "@io_bazel//src/main/java/com/google/devtools/build/skydoc/renderer",
+ test = test,
+ **kwargs)
+ _create_test_targets(test_name = "%s_e2e_jar_test" % name,
+ genrule_name = "regenerate_with_jar_%s_golden" % name,
+ lib_name = "%s_lib" % name,
+ input_file = input_file,
+ golden_file = golden_file,
+ stardoc_bin = "@io_bazel//src/main/java/com/google/devtools/build/skydoc",
+ renderer_bin = "@io_bazel//src/main/java/com/google/devtools/build/skydoc/renderer",
+ test = test,
+ **kwargs)
+
+def _create_test_targets(test_name,
+ genrule_name,
+ lib_name,
+ input_file,
+ golden_file,
+ stardoc_bin,
+ renderer_bin,
+ test,
+ **kwargs):
+ actual_generated_doc = "%s.out" % genrule_name
+
+ native.sh_test(
+ name = test_name,
+ srcs = ["diff_test_runner.sh"],
+ args = [
+ "$(location %s)" % actual_generated_doc,
+ "$(location %s)" % golden_file,
+ ],
+ data = [
+ actual_generated_doc,
+ golden_file,
+ ],
+ )
+
+ if test == "default":
+ stardoc(
+ name = genrule_name,
+ out = actual_generated_doc,
+ input = input_file,
+ deps = [lib_name],
+ renderer = renderer_bin,
+ stardoc = stardoc_bin,
+ **kwargs
+ )
+ elif test == "pure_markdown":
+ pure_markdown_stardoc(
+ name = genrule_name,
+ out = actual_generated_doc,
+ input = input_file,
+ deps = [lib_name],
+ renderer = renderer_bin,
+ stardoc = stardoc_bin,
+ **kwargs
+ )
+ else:
+ fail("parameter 'test' must either be 'default' or 'pure_markdown', but was " + test)
+
diff --git a/test/testdata/android_basic_test/golden.txt b/test/testdata/android_basic_test/golden.txt
new file mode 100644
index 0000000..2bcabb0
--- /dev/null
+++ b/test/testdata/android_basic_test/golden.txt
@@ -0,0 +1,57 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#android_related_rule"></a>
+
+## android_related_rule
+
+<pre>
+android_related_rule(<a href="#android_related_rule-name">name</a>, <a href="#android_related_rule-first">first</a>, <a href="#android_related_rule-fourth">fourth</a>, <a href="#android_related_rule-second">second</a>, <a href="#android_related_rule-third">third</a>)
+</pre>
+
+This rule does android-related things.
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="android_related_rule-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="android_related_rule-first">
+ <td><code>first</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ </td>
+ </tr>
+ <tr id="android_related_rule-fourth">
+ <td><code>fourth</code></td>
+ <td>
+ Boolean; optional
+ </td>
+ </tr>
+ <tr id="android_related_rule-second">
+ <td><code>second</code></td>
+ <td>
+ <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a>; required
+ </td>
+ </tr>
+ <tr id="android_related_rule-third">
+ <td><code>third</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/android_basic_test/input.bzl b/test/testdata/android_basic_test/input.bzl
new file mode 100644
index 0000000..11feec1
--- /dev/null
+++ b/test/testdata/android_basic_test/input.bzl
@@ -0,0 +1,27 @@
+# buildifier: disable=module-docstring
+# buildifier: disable=function-docstring
+def exercise_the_api():
+ _var1 = android_common.create_device_broker_info("")
+ _var2 = ApkInfo
+ _var3 = AndroidInstrumentationInfo
+ _var4 = AndroidDeviceBrokerInfo
+ _var5 = AndroidResourcesInfo
+ _var6 = AndroidNativeLibsInfo
+ _var7 = AndroidSdkInfo
+ _var8 = android_data
+
+exercise_the_api()
+
+def my_rule_impl(ctx):
+ return []
+
+android_related_rule = rule(
+ implementation = my_rule_impl,
+ doc = "This rule does android-related things.",
+ attrs = {
+ "first": attr.label(mandatory = True, allow_single_file = True),
+ "second": attr.string_dict(mandatory = True),
+ "third": attr.output(mandatory = True),
+ "fourth": attr.bool(default = False, mandatory = False),
+ },
+)
diff --git a/test/testdata/angle_bracket_test/golden.txt b/test/testdata/angle_bracket_test/golden.txt
new file mode 100644
index 0000000..88daa40
--- /dev/null
+++ b/test/testdata/angle_bracket_test/golden.txt
@@ -0,0 +1,116 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#my_anglebrac"></a>
+
+## my_anglebrac
+
+<pre>
+my_anglebrac(<a href="#my_anglebrac-name">name</a>, <a href="#my_anglebrac-useless">useless</a>)
+</pre>
+
+Rule with &lt;brackets&gt;
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_anglebrac-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="my_anglebrac-useless">
+ <td><code>useless</code></td>
+ <td>
+ String; optional
+ <p>
+ Args with some <b>formatting</b>
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#bracketuse"></a>
+
+## bracketuse
+
+<pre>
+bracketuse(<a href="#bracketuse-foo">foo</a>, <a href="#bracketuse-bar">bar</a>, <a href="#bracketuse-baz">baz</a>)
+</pre>
+
+Information with &lt;brackets&gt;
+
+### Fields
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="bracketuse-foo">
+ <td><code>foo</code></td>
+ <td>
+ <p>A string representing foo</p>
+ </td>
+ </tr>
+ <tr id="bracketuse-bar">
+ <td><code>bar</code></td>
+ <td>
+ <p>A string representing bar</p>
+ </td>
+ </tr>
+ <tr id="bracketuse-baz">
+ <td><code>baz</code></td>
+ <td>
+ <p>A string representing baz</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#bracket_function"></a>
+
+## bracket_function
+
+<pre>
+bracket_function(<a href="#bracket_function-name">name</a>)
+</pre>
+
+Dummy docstring with &lt;brackets&gt;.
+
+This rule runs checks on &lt;angle brackets&gt;.
+
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="bracket_function-name">
+ <td><code>name</code></td>
+ <td>
+ required.
+ <p>
+ an arg with <b>formatted</b> docstring.
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/angle_bracket_test/input.bzl b/test/testdata/angle_bracket_test/input.bzl
new file mode 100644
index 0000000..ac9736a
--- /dev/null
+++ b/test/testdata/angle_bracket_test/input.bzl
@@ -0,0 +1,38 @@
+"""Input file to test angle bracket bug (https://github.com/bazelbuild/skydoc/issues/186)"""
+
+def bracket_function(name):
+ """Dummy docstring with <brackets>.
+
+ This rule runs checks on <angle brackets>.
+
+ Args:
+ name: an arg with <b>formatted</b> docstring.
+
+ Returns:
+ some <angled> brackets
+
+ """
+ pass
+
+bracketuse = provider(
+ doc = "Information with <brackets>",
+ fields = {
+ "foo": "A string representing foo",
+ "bar": "A string representing bar",
+ "baz": "A string representing baz",
+ },
+)
+
+def _rule_impl(ctx):
+ return []
+
+my_anglebrac = rule(
+ implementation = _rule_impl,
+ doc = "Rule with <brackets>",
+ attrs = {
+ "useless": attr.string(
+ doc = "Args with some <b>formatting</b>",
+ default = "Find brackets",
+ ),
+ },
+)
diff --git a/test/testdata/apple_basic_test/golden.txt b/test/testdata/apple_basic_test/golden.txt
new file mode 100644
index 0000000..c236b56
--- /dev/null
+++ b/test/testdata/apple_basic_test/golden.txt
@@ -0,0 +1,57 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#apple_related_rule"></a>
+
+## apple_related_rule
+
+<pre>
+apple_related_rule(<a href="#apple_related_rule-name">name</a>, <a href="#apple_related_rule-first">first</a>, <a href="#apple_related_rule-fourth">fourth</a>, <a href="#apple_related_rule-second">second</a>, <a href="#apple_related_rule-third">third</a>)
+</pre>
+
+This rule does apple-related things.
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="apple_related_rule-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="apple_related_rule-first">
+ <td><code>first</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ </td>
+ </tr>
+ <tr id="apple_related_rule-fourth">
+ <td><code>fourth</code></td>
+ <td>
+ Boolean; optional
+ </td>
+ </tr>
+ <tr id="apple_related_rule-second">
+ <td><code>second</code></td>
+ <td>
+ <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a>; required
+ </td>
+ </tr>
+ <tr id="apple_related_rule-third">
+ <td><code>third</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/apple_basic_test/input.bzl b/test/testdata/apple_basic_test/input.bzl
new file mode 100644
index 0000000..c5801ba
--- /dev/null
+++ b/test/testdata/apple_basic_test/input.bzl
@@ -0,0 +1,22 @@
+# buildifier: disable=module-docstring
+# buildifier: disable=function-docstring
+def exercise_the_api():
+ var1 = apple_common.platform_type
+ var2 = apple_common.AppleDynamicFramework
+
+exercise_the_api()
+
+# buildifier: disable=rule-impl-return
+def my_rule_impl(ctx):
+ return struct()
+
+apple_related_rule = rule(
+ implementation = my_rule_impl,
+ doc = "This rule does apple-related things.",
+ attrs = {
+ "first": attr.label(mandatory = True, allow_single_file = True),
+ "second": attr.string_dict(mandatory = True),
+ "third": attr.output(mandatory = True),
+ "fourth": attr.bool(default = False, mandatory = False),
+ },
+)
diff --git a/test/testdata/aspect_test/golden.txt b/test/testdata/aspect_test/golden.txt
new file mode 100644
index 0000000..a4d2093
--- /dev/null
+++ b/test/testdata/aspect_test/golden.txt
@@ -0,0 +1,148 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#my_aspect_impl"></a>
+
+## my_aspect_impl
+
+<pre>
+my_aspect_impl(<a href="#my_aspect_impl-ctx">ctx</a>)
+</pre>
+
+
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_aspect_impl-ctx">
+ <td><code>ctx</code></td>
+ <td>
+ required.
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#my_aspect"></a>
+
+## my_aspect
+
+<pre>
+my_aspect(<a href="#my_aspect-name">name</a>, <a href="#my_aspect-first">first</a>, <a href="#my_aspect-second">second</a>)
+</pre>
+
+This is my aspect. It does stuff.
+
+### Aspect Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_aspect-deps">
+ <td><code>deps</code></td>
+ <td>
+ String; required.
+ <tr id="my_aspect-attr_aspect">
+ <td><code>attr_aspect</code></td>
+ <td>
+ String; required.
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_aspect-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="my_aspect-first">
+ <td><code>first</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ </td>
+ </tr>
+ <tr id="my_aspect-second">
+ <td><code>second</code></td>
+ <td>
+ <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a>; required
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#other_aspect"></a>
+
+## other_aspect
+
+<pre>
+other_aspect(<a href="#other_aspect-name">name</a>, <a href="#other_aspect-third">third</a>)
+</pre>
+
+This is another aspect.
+
+### Aspect Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="other_aspect-*">
+ <td><code>*</code></td>
+ <td>
+ String; required.
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="other_aspect-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="other_aspect-third">
+ <td><code>third</code></td>
+ <td>
+ Integer; required
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/aspect_test/input.bzl b/test/testdata/aspect_test/input.bzl
new file mode 100644
index 0000000..1ffedb4
--- /dev/null
+++ b/test/testdata/aspect_test/input.bzl
@@ -0,0 +1,24 @@
+"""The input file for the aspect test"""
+
+def my_aspect_impl(ctx):
+ return []
+
+my_aspect = aspect(
+ implementation = my_aspect_impl,
+ doc = "This is my aspect. It does stuff.",
+ attr_aspects = ["deps", "attr_aspect"],
+ attrs = {
+ "first": attr.label(mandatory = True, allow_single_file = True),
+ "second": attr.string_dict(mandatory = True),
+ },
+)
+
+other_aspect = aspect(
+ implementation = my_aspect_impl,
+ doc = "This is another aspect.",
+ attr_aspects = ["*"],
+ attrs = {
+ "_hidden": attr.string(),
+ "third": attr.int(mandatory = True),
+ },
+)
diff --git a/test/testdata/attribute_types_test/golden.txt b/test/testdata/attribute_types_test/golden.txt
new file mode 100644
index 0000000..221c872
--- /dev/null
+++ b/test/testdata/attribute_types_test/golden.txt
@@ -0,0 +1,141 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#my_rule"></a>
+
+## my_rule
+
+<pre>
+my_rule(<a href="#my_rule-name">name</a>, <a href="#my_rule-a">a</a>, <a href="#my_rule-b">b</a>, <a href="#my_rule-c">c</a>, <a href="#my_rule-d">d</a>, <a href="#my_rule-e">e</a>, <a href="#my_rule-f">f</a>, <a href="#my_rule-g">g</a>, <a href="#my_rule-h">h</a>, <a href="#my_rule-i">i</a>, <a href="#my_rule-j">j</a>, <a href="#my_rule-k">k</a>, <a href="#my_rule-l">l</a>)
+</pre>
+
+This is my rule. It does stuff.
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_rule-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-a">
+ <td><code>a</code></td>
+ <td>
+ Boolean; required
+ <p>
+ Some bool
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-b">
+ <td><code>b</code></td>
+ <td>
+ Integer; required
+ <p>
+ Some int
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-c">
+ <td><code>c</code></td>
+ <td>
+ List of integers; required
+ <p>
+ Some int_list
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-d">
+ <td><code>d</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ <p>
+ Some label
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-e">
+ <td><code>e</code></td>
+ <td>
+ <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: Label -> String</a>; required
+ <p>
+ Some label_keyed_string_dict
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-f">
+ <td><code>f</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a>; required
+ <p>
+ Some label_list
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-g">
+ <td><code>g</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; optional
+ <p>
+ Some output
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-h">
+ <td><code>h</code></td>
+ <td>
+ List of labels; optional
+ <p>
+ Some output_list
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-i">
+ <td><code>i</code></td>
+ <td>
+ String; required
+ <p>
+ Some string
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-j">
+ <td><code>j</code></td>
+ <td>
+ <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a>; required
+ <p>
+ Some string_dict
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-k">
+ <td><code>k</code></td>
+ <td>
+ List of strings; required
+ <p>
+ Some string_list
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-l">
+ <td><code>l</code></td>
+ <td>
+ <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> List of strings</a>; optional
+ <p>
+ Some string_list_dict
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/attribute_types_test/input.bzl b/test/testdata/attribute_types_test/input.bzl
new file mode 100644
index 0000000..adbe695
--- /dev/null
+++ b/test/testdata/attribute_types_test/input.bzl
@@ -0,0 +1,23 @@
+# buildifier: disable=module-docstring
+# buildifier: disable=function-docstring
+def my_rule_impl(ctx):
+ return []
+
+my_rule = rule(
+ implementation = my_rule_impl,
+ doc = "This is my rule. It does stuff.",
+ attrs = {
+ "a": attr.bool(mandatory = True, doc = "Some bool"),
+ "b": attr.int(mandatory = True, doc = "Some int"),
+ "c": attr.int_list(mandatory = True, doc = "Some int_list"),
+ "d": attr.label(mandatory = True, doc = "Some label"),
+ "e": attr.label_keyed_string_dict(mandatory = True, doc = "Some label_keyed_string_dict"),
+ "f": attr.label_list(mandatory = True, doc = "Some label_list"),
+ "g": attr.output(mandatory = False, doc = "Some output"),
+ "h": attr.output_list(mandatory = False, doc = "Some output_list"),
+ "i": attr.string(mandatory = True, doc = "Some string"),
+ "j": attr.string_dict(mandatory = True, doc = "Some string_dict"),
+ "k": attr.string_list(mandatory = True, doc = "Some string_list"),
+ "l": attr.string_list_dict(mandatory = False, doc = "Some string_list_dict"),
+ },
+)
diff --git a/test/testdata/cc_api_test/golden.txt b/test/testdata/cc_api_test/golden.txt
new file mode 100644
index 0000000..29bcab5
--- /dev/null
+++ b/test/testdata/cc_api_test/golden.txt
@@ -0,0 +1,97 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#cpp_related_rule"></a>
+
+## cpp_related_rule
+
+<pre>
+cpp_related_rule(<a href="#cpp_related_rule-name">name</a>, <a href="#cpp_related_rule-first">first</a>, <a href="#cpp_related_rule-fourth">fourth</a>, <a href="#cpp_related_rule-second">second</a>, <a href="#cpp_related_rule-third">third</a>)
+</pre>
+
+This rule does C++-related things.
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="cpp_related_rule-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="cpp_related_rule-first">
+ <td><code>first</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ </td>
+ </tr>
+ <tr id="cpp_related_rule-fourth">
+ <td><code>fourth</code></td>
+ <td>
+ Boolean; optional
+ </td>
+ </tr>
+ <tr id="cpp_related_rule-second">
+ <td><code>second</code></td>
+ <td>
+ <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a>; required
+ </td>
+ </tr>
+ <tr id="cpp_related_rule-third">
+ <td><code>third</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#exercise_the_api"></a>
+
+## exercise_the_api
+
+<pre>
+exercise_the_api()
+</pre>
+
+
+
+
+
+<a name="#my_rule_impl"></a>
+
+## my_rule_impl
+
+<pre>
+my_rule_impl(<a href="#my_rule_impl-ctx">ctx</a>)
+</pre>
+
+
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_rule_impl-ctx">
+ <td><code>ctx</code></td>
+ <td>
+ required.
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/cc_api_test/input.bzl b/test/testdata/cc_api_test/input.bzl
new file mode 100644
index 0000000..17462fd
--- /dev/null
+++ b/test/testdata/cc_api_test/input.bzl
@@ -0,0 +1,20 @@
+"""Input file for C++ api test """
+
+def exercise_the_api():
+ var1 = CcInfo
+
+exercise_the_api()
+
+def my_rule_impl(ctx):
+ return []
+
+cpp_related_rule = rule(
+ implementation = my_rule_impl,
+ doc = "This rule does C++-related things.",
+ attrs = {
+ "first": attr.label(mandatory = True, allow_single_file = True),
+ "second": attr.string_dict(mandatory = True),
+ "third": attr.output(mandatory = True),
+ "fourth": attr.bool(default = False, mandatory = False),
+ },
+)
diff --git a/test/testdata/config_apis_test/golden.txt b/test/testdata/config_apis_test/golden.txt
new file mode 100644
index 0000000..11e0829
--- /dev/null
+++ b/test/testdata/config_apis_test/golden.txt
@@ -0,0 +1,104 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#int_setting"></a>
+
+## int_setting
+
+<pre>
+int_setting(<a href="#int_setting-name">name</a>)
+</pre>
+
+
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="int_setting-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#string_flag"></a>
+
+## string_flag
+
+<pre>
+string_flag(<a href="#string_flag-name">name</a>)
+</pre>
+
+
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="string_flag-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#exercise_the_api"></a>
+
+## exercise_the_api
+
+<pre>
+exercise_the_api()
+</pre>
+
+
+
+
+
+<a name="#transition_func"></a>
+
+## transition_func
+
+<pre>
+transition_func(<a href="#transition_func-settings">settings</a>)
+</pre>
+
+A no-op transition function.
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="transition_func-settings">
+ <td><code>settings</code></td>
+ <td>
+ required.
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/config_apis_test/input.bzl b/test/testdata/config_apis_test/input.bzl
new file mode 100644
index 0000000..5519711
--- /dev/null
+++ b/test/testdata/config_apis_test/input.bzl
@@ -0,0 +1,25 @@
+# buildifier: disable=module-docstring
+# buildifier: disable=function-docstring
+def exercise_the_api():
+ _var6 = configuration_field("foo", "bar")
+
+exercise_the_api()
+
+def transition_func(settings):
+ """A no-op transition function."""
+ return settings
+
+my_transition = transition(implementation = transition_func, inputs = [], outputs = [])
+
+def _build_setting_impl(ctx):
+ return []
+
+string_flag = rule(
+ implementation = _build_setting_impl,
+ build_setting = config.string(flag = True),
+)
+
+int_setting = rule(
+ implementation = _build_setting_impl,
+ build_setting = config.int(flag = False),
+)
diff --git a/test/testdata/cpp_basic_test/golden.txt b/test/testdata/cpp_basic_test/golden.txt
new file mode 100644
index 0000000..79f10b6
--- /dev/null
+++ b/test/testdata/cpp_basic_test/golden.txt
@@ -0,0 +1,57 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#cpp_related_rule"></a>
+
+## cpp_related_rule
+
+<pre>
+cpp_related_rule(<a href="#cpp_related_rule-name">name</a>, <a href="#cpp_related_rule-first">first</a>, <a href="#cpp_related_rule-fourth">fourth</a>, <a href="#cpp_related_rule-second">second</a>, <a href="#cpp_related_rule-third">third</a>)
+</pre>
+
+This rule does cpp-related things.
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="cpp_related_rule-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="cpp_related_rule-first">
+ <td><code>first</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ </td>
+ </tr>
+ <tr id="cpp_related_rule-fourth">
+ <td><code>fourth</code></td>
+ <td>
+ Boolean; optional
+ </td>
+ </tr>
+ <tr id="cpp_related_rule-second">
+ <td><code>second</code></td>
+ <td>
+ <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a>; required
+ </td>
+ </tr>
+ <tr id="cpp_related_rule-third">
+ <td><code>third</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/cpp_basic_test/input.bzl b/test/testdata/cpp_basic_test/input.bzl
new file mode 100644
index 0000000..b927e42
--- /dev/null
+++ b/test/testdata/cpp_basic_test/input.bzl
@@ -0,0 +1,20 @@
+# buildifier: disable=module-docstring
+# buildifier: disable=function-docstring
+def exercise_the_api():
+ var1 = cc_common.CcToolchainInfo
+
+exercise_the_api()
+
+def my_rule_impl(ctx):
+ return []
+
+cpp_related_rule = rule(
+ implementation = my_rule_impl,
+ doc = "This rule does cpp-related things.",
+ attrs = {
+ "first": attr.label(mandatory = True, allow_single_file = True),
+ "second": attr.string_dict(mandatory = True),
+ "third": attr.output(mandatory = True),
+ "fourth": attr.bool(default = False, mandatory = False),
+ },
+)
diff --git a/test/testdata/filter_rules_test/dep.bzl b/test/testdata/filter_rules_test/dep.bzl
new file mode 100644
index 0000000..5c5da10
--- /dev/null
+++ b/test/testdata/filter_rules_test/dep.bzl
@@ -0,0 +1,16 @@
+# buildifier: disable=module-docstring
+def my_rule_impl(ctx):
+ return []
+
+my_rule = rule(
+ implementation = my_rule_impl,
+ doc = "This is the dep rule. It does stuff.",
+ attrs = {
+ "first": attr.label(
+ mandatory = True,
+ doc = "dep's my_rule doc string",
+ allow_single_file = True,
+ ),
+ "second": attr.string_dict(mandatory = True),
+ },
+)
diff --git a/test/testdata/filter_rules_test/golden.txt b/test/testdata/filter_rules_test/golden.txt
new file mode 100644
index 0000000..eadcdb8
--- /dev/null
+++ b/test/testdata/filter_rules_test/golden.txt
@@ -0,0 +1,94 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#my_rule"></a>
+
+## my_rule
+
+<pre>
+my_rule(<a href="#my_rule-name">name</a>, <a href="#my_rule-first">first</a>, <a href="#my_rule-second">second</a>)
+</pre>
+
+This is my rule. It does stuff.
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_rule-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-first">
+ <td><code>first</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ <p>
+ first my_rule doc string
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-second">
+ <td><code>second</code></td>
+ <td>
+ <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a>; required
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#whitelisted_dep_rule"></a>
+
+## whitelisted_dep_rule
+
+<pre>
+whitelisted_dep_rule(<a href="#whitelisted_dep_rule-name">name</a>, <a href="#whitelisted_dep_rule-first">first</a>, <a href="#whitelisted_dep_rule-second">second</a>)
+</pre>
+
+This is the dep rule. It does stuff.
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="whitelisted_dep_rule-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="whitelisted_dep_rule-first">
+ <td><code>first</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ <p>
+ dep's my_rule doc string
+ </p>
+ </td>
+ </tr>
+ <tr id="whitelisted_dep_rule-second">
+ <td><code>second</code></td>
+ <td>
+ <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a>; required
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/filter_rules_test/input.bzl b/test/testdata/filter_rules_test/input.bzl
new file mode 100644
index 0000000..5b8679c
--- /dev/null
+++ b/test/testdata/filter_rules_test/input.bzl
@@ -0,0 +1,40 @@
+# buildifier: disable=module-docstring
+load(
+ ":testdata/filter_rules_test/dep.bzl",
+ "my_rule_impl",
+ dep_rule = "my_rule",
+)
+
+def my_rule_impl(ctx):
+ return []
+
+my_rule = rule(
+ implementation = my_rule_impl,
+ doc = "This is my rule. It does stuff.",
+ attrs = {
+ "first": attr.label(
+ mandatory = True,
+ doc = "first my_rule doc string",
+ allow_single_file = True,
+ ),
+ "second": attr.string_dict(mandatory = True),
+ },
+)
+
+other_rule = rule(
+ implementation = my_rule_impl,
+ doc = "This is another rule.",
+ attrs = {
+ "test": attr.string_dict(mandatory = True),
+ },
+)
+
+whitelisted_dep_rule = dep_rule
+
+yet_another_rule = rule(
+ implementation = my_rule_impl,
+ doc = "This is yet another rule",
+ attrs = {
+ "test": attr.string_dict(mandatory = True),
+ },
+)
diff --git a/test/testdata/function_basic_test/golden.txt b/test/testdata/function_basic_test/golden.txt
new file mode 100644
index 0000000..5719b1b
--- /dev/null
+++ b/test/testdata/function_basic_test/golden.txt
@@ -0,0 +1,128 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#check_sources"></a>
+
+## check_sources
+
+<pre>
+check_sources(<a href="#check_sources-name">name</a>, <a href="#check_sources-required_param">required_param</a>, <a href="#check_sources-bool_param">bool_param</a>, <a href="#check_sources-srcs">srcs</a>, <a href="#check_sources-string_param">string_param</a>, <a href="#check_sources-int_param">int_param</a>, <a href="#check_sources-dict_param">dict_param</a>, <a href="#check_sources-struct_param">struct_param</a>)
+</pre>
+
+Runs some checks on the given source files.
+
+This rule runs checks on a given set of source files.
+Use `bazel build` to run the check.
+
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="check_sources-name">
+ <td><code>name</code></td>
+ <td>
+ required.
+ <p>
+ A unique name for this rule.
+ </p>
+ </td>
+ </tr>
+ <tr id="check_sources-required_param">
+ <td><code>required_param</code></td>
+ <td>
+ required.
+ <p>
+ Use your imagination.
+ </p>
+ </td>
+ </tr>
+ <tr id="check_sources-bool_param">
+ <td><code>bool_param</code></td>
+ <td>
+ optional. default is <code>True</code>
+ </td>
+ </tr>
+ <tr id="check_sources-srcs">
+ <td><code>srcs</code></td>
+ <td>
+ optional. default is <code>[]</code>
+ <p>
+ Source files to run the checks against.
+ </p>
+ </td>
+ </tr>
+ <tr id="check_sources-string_param">
+ <td><code>string_param</code></td>
+ <td>
+ optional. default is <code>""</code>
+ </td>
+ </tr>
+ <tr id="check_sources-int_param">
+ <td><code>int_param</code></td>
+ <td>
+ optional. default is <code>2</code>
+ <p>
+ Your favorite number.
+ </p>
+ </td>
+ </tr>
+ <tr id="check_sources-dict_param">
+ <td><code>dict_param</code></td>
+ <td>
+ optional. default is <code>{}</code>
+ </td>
+ </tr>
+ <tr id="check_sources-struct_param">
+ <td><code>struct_param</code></td>
+ <td>
+ optional. default is <code>struct(foo = "bar")</code>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#undocumented_function"></a>
+
+## undocumented_function
+
+<pre>
+undocumented_function(<a href="#undocumented_function-a">a</a>, <a href="#undocumented_function-b">b</a>, <a href="#undocumented_function-c">c</a>)
+</pre>
+
+
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="undocumented_function-a">
+ <td><code>a</code></td>
+ <td>
+ required.
+ </td>
+ </tr>
+ <tr id="undocumented_function-b">
+ <td><code>b</code></td>
+ <td>
+ required.
+ </td>
+ </tr>
+ <tr id="undocumented_function-c">
+ <td><code>c</code></td>
+ <td>
+ required.
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/function_basic_test/input.bzl b/test/testdata/function_basic_test/input.bzl
new file mode 100644
index 0000000..721e1d3
--- /dev/null
+++ b/test/testdata/function_basic_test/input.bzl
@@ -0,0 +1,38 @@
+"""A test that verifies basic user function documentation."""
+
+def check_sources(
+ name,
+ required_param,
+ bool_param = True,
+ srcs = [],
+ string_param = "",
+ int_param = 2,
+ dict_param = {},
+ struct_param = struct(foo = "bar")):
+ # buildifier: disable=function-docstring-args
+ """Runs some checks on the given source files.
+
+ This rule runs checks on a given set of source files.
+ Use `bazel build` to run the check.
+
+ Args:
+ name: A unique name for this rule.
+ required_param: Use your imagination.
+ srcs: Source files to run the checks against.
+ doesnt_exist: A param that doesn't exist (lets hope we still get *some* documentation)
+ int_param: Your favorite number.
+ """
+ _ignore = [
+ name,
+ required_param,
+ bool_param,
+ srcs,
+ string_param,
+ int_param,
+ dict_param,
+ struct_param,
+ ]
+ x = ("Hah. All that documentation but nothing really to see here")
+
+def undocumented_function(a, b, c):
+ pass
diff --git a/test/testdata/generated_bzl_test/dep.bzl.tpl b/test/testdata/generated_bzl_test/dep.bzl.tpl
new file mode 100644
index 0000000..4c8bd78
--- /dev/null
+++ b/test/testdata/generated_bzl_test/dep.bzl.tpl
@@ -0,0 +1,4 @@
+"""Used to generate dep.bzl"""
+
+def my_rule_impl(ctx):
+ return []
diff --git a/test/testdata/generated_bzl_test/golden.txt b/test/testdata/generated_bzl_test/golden.txt
new file mode 100644
index 0000000..cf02e4c
--- /dev/null
+++ b/test/testdata/generated_bzl_test/golden.txt
@@ -0,0 +1,48 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#my_rule"></a>
+
+## my_rule
+
+<pre>
+my_rule(<a href="#my_rule-name">name</a>, <a href="#my_rule-first">first</a>, <a href="#my_rule-second">second</a>)
+</pre>
+
+This is my rule. It does stuff.
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_rule-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-first">
+ <td><code>first</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ <p>
+ first my_rule doc string
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-second">
+ <td><code>second</code></td>
+ <td>
+ <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a>; required
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/generated_bzl_test/input.bzl b/test/testdata/generated_bzl_test/input.bzl
new file mode 100644
index 0000000..bad15f6
--- /dev/null
+++ b/test/testdata/generated_bzl_test/input.bzl
@@ -0,0 +1,16 @@
+"""A direct dependency file of the input file."""
+
+load(":testdata/generated_bzl_test/dep.bzl", "my_rule_impl")
+
+my_rule = rule(
+ implementation = my_rule_impl,
+ doc = "This is my rule. It does stuff.",
+ attrs = {
+ "first": attr.label(
+ mandatory = True,
+ doc = "first my_rule doc string",
+ allow_single_file = True,
+ ),
+ "second": attr.string_dict(mandatory = True),
+ },
+)
diff --git a/test/testdata/input_template_test/aspect.vm b/test/testdata/input_template_test/aspect.vm
new file mode 100644
index 0000000..41b08e5
--- /dev/null
+++ b/test/testdata/input_template_test/aspect.vm
@@ -0,0 +1,32 @@
+<a name="#${aspectName}"></a>
+
+#[[##]]# ${aspectName}
+
+<pre>
+${util.aspectSummary($aspectName, $aspectInfo)}
+</pre>
+
+$aspectInfo.getDocString()
+
+#[[###]]# Aspect Attributes
+
+#if (!$aspectInfo.getAspectAttributeList().isEmpty())
+#foreach ($aspectAttribute in $aspectInfo.getAspectAttributeList())
+ $aspectAttribute
+ String; required.
+#end
+#end
+
+#[[###]]# Attributes
+
+#foreach ($attribute in $aspectInfo.getAttributeList())
+<b>
+ <code>${attribute.name}</code>
+ ${util.attributeTypeString($attribute)}; ${util.mandatoryString($attribute)}
+</b>
+#if (!$attribute.docString.isEmpty())
+ <p>
+ ${attribute.docString.trim()}
+ </p>
+#end
+#end \ No newline at end of file
diff --git a/test/testdata/input_template_test/func.vm b/test/testdata/input_template_test/func.vm
new file mode 100644
index 0000000..80ef25c
--- /dev/null
+++ b/test/testdata/input_template_test/func.vm
@@ -0,0 +1,29 @@
+<a name="#${funcInfo.functionName}"></a>
+
+#[[##]]# ${funcInfo.functionName}
+
+<pre>
+${util.funcSummary($funcInfo)}
+</pre>
+
+${funcInfo.docString}
+
+<b>input_template_test BOLD PARAMETERS</b>
+
+#if (!$funcInfo.getParameterList().isEmpty())
+#[[###]]# Parameters
+
+#foreach ($param in $funcInfo.getParameterList())
+<b>
+ <code>${param.name}</code>
+ ${util.mandatoryString($param)}.#if(!$param.getDefaultValue().isEmpty()) default is
+ <code>$param.getDefaultValue()</code>
+ </b>
+ #end
+#if (!$param.docString.isEmpty())
+ <p>
+ ${param.docString.trim()}
+ </p>
+#end
+#end
+#end
diff --git a/test/testdata/input_template_test/golden.txt b/test/testdata/input_template_test/golden.txt
new file mode 100644
index 0000000..aff43e1
--- /dev/null
+++ b/test/testdata/input_template_test/golden.txt
@@ -0,0 +1,138 @@
+<!-- THIS HEADER IS FOR input_template_test ONLY -->
+
+Module Docstring: "Input file for input template test"
+
+<a name="#my_example"></a>
+
+## my_example
+
+<pre>
+my_example(<a href="#my_example-name">name</a>, <a href="#my_example-useless">useless</a>)
+</pre>
+
+Small example of rule using chosen template.
+
+<b>input_template_test BOLD ATTRIBUTES</b>
+
+### Attributes
+
+
+<b>
+ <code>name</code>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+</b>
+ <p>
+ A unique name for this target.
+ </p>
+<b>
+ <code>useless</code>
+ String; optional
+</b>
+ <p>
+ This argument will be ignored.
+ </p>
+
+
+<a name="#example"></a>
+
+## example
+
+<pre>
+example(<a href="#example-foo">foo</a>, <a href="#example-bar">bar</a>, <a href="#example-baz">baz</a>)
+</pre>
+
+Stores information about an example in chosen template.
+
+<b>input_template_test BOLD FIELDS</b>
+
+### Fields
+
+<b>
+ <code>foo</code>
+</b>
+ <p>A string representing foo</p>
+<b>
+ <code>bar</code>
+</b>
+ <p>A string representing bar</p>
+<b>
+ <code>baz</code>
+</b>
+ <p>A string representing baz</p>
+
+
+<a name="#my_aspect_impl"></a>
+
+## my_aspect_impl
+
+<pre>
+my_aspect_impl(<a href="#my_aspect_impl-ctx">ctx</a>)
+</pre>
+
+
+
+<b>input_template_test BOLD PARAMETERS</b>
+
+### Parameters
+
+<b>
+ <code>ctx</code>
+ required.
+
+<a name="#template_function"></a>
+
+## template_function
+
+<pre>
+template_function(<a href="#template_function-foo">foo</a>)
+</pre>
+
+Runs some checks on the given function parameter.
+
+This rule runs checks on a given function parameter in chosen template.
+Use `bazel build` to run the check.
+
+
+<b>input_template_test BOLD PARAMETERS</b>
+
+### Parameters
+
+<b>
+ <code>foo</code>
+ required. <p>
+ A unique name for this function.
+ </p>
+
+
+<a name="#my_aspect"></a>
+
+## my_aspect
+
+<pre>
+my_aspect(<a href="#my_aspect-name">name</a>, <a href="#my_aspect-first">first</a>)
+</pre>
+
+This is my aspect. It does stuff.
+
+### Aspect Attributes
+
+ deps
+ String; required.
+ attr_aspect
+ String; required.
+
+### Attributes
+
+<b>
+ <code>name</code>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+</b>
+ <p>
+ A unique name for this target.
+ </p>
+<b>
+ <code>first</code>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+</b>
+
+
diff --git a/test/testdata/input_template_test/header.vm b/test/testdata/input_template_test/header.vm
new file mode 100644
index 0000000..2203c76
--- /dev/null
+++ b/test/testdata/input_template_test/header.vm
@@ -0,0 +1,3 @@
+<!-- THIS HEADER IS FOR input_template_test ONLY -->
+
+Module Docstring: "${moduleDocstring}"
diff --git a/test/testdata/input_template_test/input.bzl b/test/testdata/input_template_test/input.bzl
new file mode 100644
index 0000000..37fee12
--- /dev/null
+++ b/test/testdata/input_template_test/input.bzl
@@ -0,0 +1,47 @@
+"""Input file for input template test"""
+
+def template_function(foo):
+ """Runs some checks on the given function parameter.
+
+ This rule runs checks on a given function parameter in chosen template.
+ Use `bazel build` to run the check.
+
+ Args:
+ foo: A unique name for this function.
+ """
+ pass
+
+example = provider(
+ doc = "Stores information about an example in chosen template.",
+ fields = {
+ "foo": "A string representing foo",
+ "bar": "A string representing bar",
+ "baz": "A string representing baz",
+ },
+)
+
+def _rule_impl(ctx):
+ return []
+
+my_example = rule(
+ implementation = _rule_impl,
+ doc = "Small example of rule using chosen template.",
+ attrs = {
+ "useless": attr.string(
+ doc = "This argument will be ignored.",
+ default = "word",
+ ),
+ },
+)
+
+def my_aspect_impl(ctx):
+ return []
+
+my_aspect = aspect(
+ implementation = my_aspect_impl,
+ doc = "This is my aspect. It does stuff.",
+ attr_aspects = ["deps", "attr_aspect"],
+ attrs = {
+ "first": attr.label(mandatory = True, allow_single_file = True),
+ },
+)
diff --git a/test/testdata/input_template_test/provider.vm b/test/testdata/input_template_test/provider.vm
new file mode 100644
index 0000000..269a894
--- /dev/null
+++ b/test/testdata/input_template_test/provider.vm
@@ -0,0 +1,22 @@
+<a name="#${providerName}"></a>
+
+#[[##]]# ${providerName}
+
+<pre>
+${util.providerSummary($providerName, $providerInfo)}
+</pre>
+
+${providerInfo.docString}
+
+<b>input_template_test BOLD FIELDS</b>
+
+#if (!$providerInfo.fieldInfoList.isEmpty())
+#[[###]]# Fields
+
+#foreach ($field in $providerInfo.fieldInfoList)
+<b>
+ <code>${field.name}</code>
+</b>
+ <p>${field.docString}</p>
+#end
+#end
diff --git a/test/testdata/input_template_test/rule.vm b/test/testdata/input_template_test/rule.vm
new file mode 100644
index 0000000..2227637
--- /dev/null
+++ b/test/testdata/input_template_test/rule.vm
@@ -0,0 +1,28 @@
+<a name="#${ruleName}"></a>
+
+#[[##]]# ${ruleName}
+
+<pre>
+${util.ruleSummary($ruleName, $ruleInfo)}
+</pre>
+
+${ruleInfo.docString}
+
+<b>input_template_test BOLD ATTRIBUTES</b>
+
+#[[###]]# Attributes
+
+#if (!$ruleInfo.getAttributeList().isEmpty())
+
+#foreach ($attribute in $ruleInfo.getAttributeList())
+<b>
+ <code>${attribute.name}</code>
+ ${util.attributeTypeString($attribute)}; ${util.mandatoryString($attribute)}
+</b>
+#if (!$attribute.docString.isEmpty())
+ <p>
+ ${attribute.docString.trim()}
+ </p>
+#end
+#end
+#end
diff --git a/test/testdata/java_basic_test/golden.txt b/test/testdata/java_basic_test/golden.txt
new file mode 100644
index 0000000..f165dca
--- /dev/null
+++ b/test/testdata/java_basic_test/golden.txt
@@ -0,0 +1,57 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#java_related_rule"></a>
+
+## java_related_rule
+
+<pre>
+java_related_rule(<a href="#java_related_rule-name">name</a>, <a href="#java_related_rule-first">first</a>, <a href="#java_related_rule-fourth">fourth</a>, <a href="#java_related_rule-second">second</a>, <a href="#java_related_rule-third">third</a>)
+</pre>
+
+This rule does java-related things.
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="java_related_rule-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="java_related_rule-first">
+ <td><code>first</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ </td>
+ </tr>
+ <tr id="java_related_rule-fourth">
+ <td><code>fourth</code></td>
+ <td>
+ Boolean; optional
+ </td>
+ </tr>
+ <tr id="java_related_rule-second">
+ <td><code>second</code></td>
+ <td>
+ <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a>; required
+ </td>
+ </tr>
+ <tr id="java_related_rule-third">
+ <td><code>third</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/java_basic_test/input.bzl b/test/testdata/java_basic_test/input.bzl
new file mode 100644
index 0000000..db0d064
--- /dev/null
+++ b/test/testdata/java_basic_test/input.bzl
@@ -0,0 +1,22 @@
+# buildifier: disable=module-docstring
+# buildifier: disable=function-docstring
+def exercise_the_api():
+ var1 = java_common.JavaRuntimeInfo
+ var2 = JavaInfo
+ var3 = java_proto_common
+
+exercise_the_api()
+
+def my_rule_impl(ctx):
+ return []
+
+java_related_rule = rule(
+ implementation = my_rule_impl,
+ doc = "This rule does java-related things.",
+ attrs = {
+ "first": attr.label(mandatory = True, allow_single_file = True),
+ "second": attr.string_dict(mandatory = True),
+ "third": attr.output(mandatory = True),
+ "fourth": attr.bool(default = False, mandatory = False),
+ },
+)
diff --git a/test/testdata/macro_kwargs_test/golden.txt b/test/testdata/macro_kwargs_test/golden.txt
new file mode 100644
index 0000000..6391577
--- /dev/null
+++ b/test/testdata/macro_kwargs_test/golden.txt
@@ -0,0 +1,168 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#macro_with_args"></a>
+
+## macro_with_args
+
+<pre>
+macro_with_args(<a href="#macro_with_args-name">name</a>, <a href="#macro_with_args-args">args</a>)
+</pre>
+
+My args macro is OK.
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="macro_with_args-name">
+ <td><code>name</code></td>
+ <td>
+ required.
+ <p>
+ The name of the test rule.
+ </p>
+ </td>
+ </tr>
+ <tr id="macro_with_args-args">
+ <td><code>args</code></td>
+ <td>
+ optional.
+ <p>
+ Other arguments to include
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#macro_with_both"></a>
+
+## macro_with_both
+
+<pre>
+macro_with_both(<a href="#macro_with_both-name">name</a>, <a href="#macro_with_both-number">number</a>, <a href="#macro_with_both-args">args</a>, <a href="#macro_with_both-kwargs">kwargs</a>)
+</pre>
+
+Oh wow this macro has both.
+
+Not much else to say.
+
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="macro_with_both-name">
+ <td><code>name</code></td>
+ <td>
+ required.
+ <p>
+ The name of the test rule.
+ </p>
+ </td>
+ </tr>
+ <tr id="macro_with_both-number">
+ <td><code>number</code></td>
+ <td>
+ optional. default is <code>3</code>
+ <p>
+ Some number used for important things
+ </p>
+ </td>
+ </tr>
+ <tr id="macro_with_both-args">
+ <td><code>args</code></td>
+ <td>
+ optional.
+ <p>
+ Other arguments to include
+ </p>
+ </td>
+ </tr>
+ <tr id="macro_with_both-kwargs">
+ <td><code>kwargs</code></td>
+ <td>
+ optional.
+ <p>
+ Other attributes to include
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#macro_with_kwargs"></a>
+
+## macro_with_kwargs
+
+<pre>
+macro_with_kwargs(<a href="#macro_with_kwargs-name">name</a>, <a href="#macro_with_kwargs-config">config</a>, <a href="#macro_with_kwargs-deps">deps</a>, <a href="#macro_with_kwargs-kwargs">kwargs</a>)
+</pre>
+
+My kwargs macro is the best.
+
+This is a long multi-line doc string.
+Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer
+elementum, diam vitae tincidunt pulvinar, nunc tortor volutpat dui,
+vitae facilisis odio ligula a tortor. Donec ullamcorper odio eget ipsum tincidunt,
+vel mollis eros pellentesque.
+
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="macro_with_kwargs-name">
+ <td><code>name</code></td>
+ <td>
+ required.
+ <p>
+ The name of the test rule.
+ </p>
+ </td>
+ </tr>
+ <tr id="macro_with_kwargs-config">
+ <td><code>config</code></td>
+ <td>
+ required.
+ <p>
+ Config to use for my macro
+ </p>
+ </td>
+ </tr>
+ <tr id="macro_with_kwargs-deps">
+ <td><code>deps</code></td>
+ <td>
+ optional. default is <code>[]</code>
+ <p>
+ List of my macro's dependencies
+ </p>
+ </td>
+ </tr>
+ <tr id="macro_with_kwargs-kwargs">
+ <td><code>kwargs</code></td>
+ <td>
+ optional.
+ <p>
+ Other attributes to include
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/macro_kwargs_test/input.bzl b/test/testdata/macro_kwargs_test/input.bzl
new file mode 100644
index 0000000..0f6268d
--- /dev/null
+++ b/test/testdata/macro_kwargs_test/input.bzl
@@ -0,0 +1,52 @@
+"""Tests for functions which use *args or **kwargs"""
+
+def macro_with_kwargs(name, config, deps = [], **kwargs):
+ """My kwargs macro is the best.
+
+ This is a long multi-line doc string.
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer
+ elementum, diam vitae tincidunt pulvinar, nunc tortor volutpat dui,
+ vitae facilisis odio ligula a tortor. Donec ullamcorper odio eget ipsum tincidunt,
+ vel mollis eros pellentesque.
+
+ Args:
+ name: The name of the test rule.
+ config: Config to use for my macro
+ deps: List of my macro's dependencies
+ **kwargs: Other attributes to include
+
+ Returns:
+ An empty list.
+ """
+ _ignore = [name, config, deps, kwargs]
+ return []
+
+def macro_with_args(name, *args):
+ """My args macro is OK.
+
+ Args:
+ name: The name of the test rule.
+ *args: Other arguments to include
+
+ Returns:
+ An empty list.
+ """
+ _ignore = [name, args]
+ return []
+
+def macro_with_both(name, number = 3, *args, **kwargs):
+ """Oh wow this macro has both.
+
+ Not much else to say.
+
+ Args:
+ name: The name of the test rule.
+ number: Some number used for important things
+ *args: Other arguments to include
+ **kwargs: Other attributes to include
+
+ Returns:
+ An empty list.
+ """
+ _ignore = [name, number, args, kwargs]
+ return []
diff --git a/test/testdata/misc_apis_test/golden.txt b/test/testdata/misc_apis_test/golden.txt
new file mode 100644
index 0000000..cfae4f5
--- /dev/null
+++ b/test/testdata/misc_apis_test/golden.txt
@@ -0,0 +1,152 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#my_rule"></a>
+
+## my_rule
+
+<pre>
+my_rule(<a href="#my_rule-name">name</a>, <a href="#my_rule-deps">deps</a>, <a href="#my_rule-extra_arguments">extra_arguments</a>, <a href="#my_rule-out">out</a>, <a href="#my_rule-src">src</a>, <a href="#my_rule-tool">tool</a>)
+</pre>
+
+This rule exercises some of the build API.
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_rule-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-deps">
+ <td><code>deps</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a>; optional
+ <p>
+ A list of dependencies.
+ </p>
+ <p>
+ The dependencies of this attribute must provide: MyInfo
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-extra_arguments">
+ <td><code>extra_arguments</code></td>
+ <td>
+ List of strings; optional
+ </td>
+ </tr>
+ <tr id="my_rule-out">
+ <td><code>out</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ <p>
+ The output file.
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-src">
+ <td><code>src</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; optional
+ <p>
+ The source file.
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-tool">
+ <td><code>tool</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; optional
+ <p>
+ The location of the tool to use.
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#MyInfo"></a>
+
+## MyInfo
+
+<pre>
+MyInfo(<a href="#MyInfo-foo">foo</a>, <a href="#MyInfo-bar">bar</a>)
+</pre>
+
+
+
+### Fields
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="MyInfo-foo">
+ <td><code>foo</code></td>
+ <td>
+ <p>Something foo-related.</p>
+ </td>
+ </tr>
+ <tr id="MyInfo-bar">
+ <td><code>bar</code></td>
+ <td>
+ <p>Something bar-related.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#exercise_the_api"></a>
+
+## exercise_the_api
+
+<pre>
+exercise_the_api()
+</pre>
+
+
+
+
+
+<a name="#my_rule_impl"></a>
+
+## my_rule_impl
+
+<pre>
+my_rule_impl(<a href="#my_rule_impl-ctx">ctx</a>)
+</pre>
+
+
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_rule_impl-ctx">
+ <td><code>ctx</code></td>
+ <td>
+ required.
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/misc_apis_test/input.bzl b/test/testdata/misc_apis_test/input.bzl
new file mode 100644
index 0000000..943442f
--- /dev/null
+++ b/test/testdata/misc_apis_test/input.bzl
@@ -0,0 +1,57 @@
+# This is here to test that built-in names can be shadowed by global names.
+# (Regression test for http://b/35984389).
+# buildifier: disable=module-docstring
+config = "value for global config variable"
+
+def my_rule_impl(ctx):
+ return []
+
+def exercise_the_api():
+ var1 = config_common.FeatureFlagInfo
+ var2 = platform_common.TemplateVariableInfo
+ var3 = repository_rule(
+ implementation = my_rule_impl,
+ doc = "This repository rule has documentation.",
+ )
+ var4 = testing.ExecutionInfo({})
+
+exercise_the_api()
+
+MyInfo = provider(
+ fields = {
+ "foo": "Something foo-related.",
+ "bar": "Something bar-related.",
+ },
+)
+
+my_info = MyInfo(foo = "x", bar = "y")
+
+my_rule = rule(
+ implementation = my_rule_impl,
+ doc = "This rule exercises some of the build API.",
+ attrs = {
+ "src": attr.label(
+ doc = "The source file.",
+ allow_files = [".bzl"],
+ ),
+ "deps": attr.label_list(
+ doc = """
+A list of dependencies.
+""",
+ providers = [MyInfo],
+ allow_files = False,
+ ),
+ "tool": attr.label(
+ doc = "The location of the tool to use.",
+ allow_files = True,
+ default = Label("//foo/bar/baz:target"),
+ cfg = "host",
+ executable = True,
+ ),
+ "out": attr.output(
+ doc = "The output file.",
+ mandatory = True,
+ ),
+ "extra_arguments": attr.string_list(default = []),
+ },
+)
diff --git a/test/testdata/multi_level_namespace_test/golden.txt b/test/testdata/multi_level_namespace_test/golden.txt
new file mode 100644
index 0000000..58f662a
--- /dev/null
+++ b/test/testdata/multi_level_namespace_test/golden.txt
@@ -0,0 +1,119 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#my_namespace.min"></a>
+
+## my_namespace.min
+
+<pre>
+my_namespace.min(<a href="#my_namespace.min-integers">integers</a>)
+</pre>
+
+Returns the minimum of given elements.
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_namespace.min-integers">
+ <td><code>integers</code></td>
+ <td>
+ required.
+ <p>
+ A list of integers. Must not be empty.
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#my_namespace.math.min"></a>
+
+## my_namespace.math.min
+
+<pre>
+my_namespace.math.min(<a href="#my_namespace.math.min-integers">integers</a>)
+</pre>
+
+Returns the minimum of given elements.
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_namespace.math.min-integers">
+ <td><code>integers</code></td>
+ <td>
+ required.
+ <p>
+ A list of integers. Must not be empty.
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#my_namespace.foo.bar.baz"></a>
+
+## my_namespace.foo.bar.baz
+
+<pre>
+my_namespace.foo.bar.baz()
+</pre>
+
+This function does nothing.
+
+
+
+<a name="#my_namespace.one.two.min"></a>
+
+## my_namespace.one.two.min
+
+<pre>
+my_namespace.one.two.min(<a href="#my_namespace.one.two.min-integers">integers</a>)
+</pre>
+
+Returns the minimum of given elements.
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_namespace.one.two.min-integers">
+ <td><code>integers</code></td>
+ <td>
+ required.
+ <p>
+ A list of integers. Must not be empty.
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#my_namespace.one.three.does_nothing"></a>
+
+## my_namespace.one.three.does_nothing
+
+<pre>
+my_namespace.one.three.does_nothing()
+</pre>
+
+This function does nothing.
+
+
+
diff --git a/test/testdata/multi_level_namespace_test/input.bzl b/test/testdata/multi_level_namespace_test/input.bzl
new file mode 100644
index 0000000..8b0b436
--- /dev/null
+++ b/test/testdata/multi_level_namespace_test/input.bzl
@@ -0,0 +1,32 @@
+"""A test that verifies documenting a multi-leveled namespace of functions."""
+
+def _min(integers):
+ """Returns the minimum of given elements.
+
+ Args:
+ integers: A list of integers. Must not be empty.
+
+ Returns:
+ The minimum integer in the given list.
+ """
+ _ignore = [integers]
+ return 42
+
+def _does_nothing():
+ """This function does nothing."""
+ pass
+
+my_namespace = struct(
+ dropped_field = "Note this field should not be documented",
+ min = _min,
+ math = struct(min = _min),
+ foo = struct(
+ bar = struct(baz = _does_nothing),
+ num = 12,
+ string = "Hello!",
+ ),
+ one = struct(
+ two = struct(min = _min),
+ three = struct(does_nothing = _does_nothing),
+ ),
+)
diff --git a/test/testdata/multi_level_namespace_test_with_whitelist/golden.txt b/test/testdata/multi_level_namespace_test_with_whitelist/golden.txt
new file mode 100644
index 0000000..3eaf093
--- /dev/null
+++ b/test/testdata/multi_level_namespace_test_with_whitelist/golden.txt
@@ -0,0 +1,70 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#my_namespace.min"></a>
+
+## my_namespace.min
+
+<pre>
+my_namespace.min(<a href="#my_namespace.min-integers">integers</a>)
+</pre>
+
+Returns the minimum of given elements.
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_namespace.min-integers">
+ <td><code>integers</code></td>
+ <td>
+ required.
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#my_namespace.math.min"></a>
+
+## my_namespace.math.min
+
+<pre>
+my_namespace.math.min(<a href="#my_namespace.math.min-integers">integers</a>)
+</pre>
+
+Returns the minimum of given elements.
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_namespace.math.min-integers">
+ <td><code>integers</code></td>
+ <td>
+ required.
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#other_namespace.foo.nothing"></a>
+
+## other_namespace.foo.nothing
+
+<pre>
+other_namespace.foo.nothing()
+</pre>
+
+This function does nothing.
+
+
+
diff --git a/test/testdata/multi_level_namespace_test_with_whitelist/input.bzl b/test/testdata/multi_level_namespace_test_with_whitelist/input.bzl
new file mode 100644
index 0000000..34eb87b
--- /dev/null
+++ b/test/testdata/multi_level_namespace_test_with_whitelist/input.bzl
@@ -0,0 +1,23 @@
+"""A test that verifies documenting a multi-leveled namespace of functions with whitelist symbols.
+The whitelist symbols should cause everything in my_namespace to to be documented, but only a
+specific symbol in other_namespace to be documented."""
+
+def _min(integers):
+ """Returns the minimum of given elements."""
+ _ignore = [integers]
+ return 42
+
+def _does_nothing():
+ """This function does nothing."""
+ pass
+
+my_namespace = struct(
+ dropped_field = "Note this field should not be documented",
+ min = _min,
+ math = struct(min = _min),
+)
+
+other_namespace = struct(
+ foo = struct(nothing = _does_nothing),
+ min = _min,
+)
diff --git a/test/testdata/multiple_files_test/dep.bzl b/test/testdata/multiple_files_test/dep.bzl
new file mode 100644
index 0000000..b1beece
--- /dev/null
+++ b/test/testdata/multiple_files_test/dep.bzl
@@ -0,0 +1,17 @@
+"""A dependency file for multiple_files_test."""
+
+load(":testdata/multiple_files_test/inner_dep.bzl", "inner_rule_impl", "prep_work")
+
+def some_cool_function(name, srcs = [], beef = ""):
+ """A pretty cool function. You should call it.
+
+ Args:
+ name: Some sort of name.
+ srcs: What sources you want cool stuff to happen to.
+ beef: Your opinion on beef.
+ """
+ x = (name, srcs, beef)
+
+prep_work()
+
+my_rule_impl = inner_rule_impl
diff --git a/test/testdata/multiple_files_test/golden.txt b/test/testdata/multiple_files_test/golden.txt
new file mode 100644
index 0000000..d80a950
--- /dev/null
+++ b/test/testdata/multiple_files_test/golden.txt
@@ -0,0 +1,171 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#my_rule"></a>
+
+## my_rule
+
+<pre>
+my_rule(<a href="#my_rule-name">name</a>, <a href="#my_rule-first">first</a>, <a href="#my_rule-second">second</a>)
+</pre>
+
+This is my rule. It does stuff.
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_rule-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-first">
+ <td><code>first</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ <p>
+ first my_rule doc string
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-second">
+ <td><code>second</code></td>
+ <td>
+ <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a>; required
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#other_rule"></a>
+
+## other_rule
+
+<pre>
+other_rule(<a href="#other_rule-name">name</a>, <a href="#other_rule-fourth">fourth</a>, <a href="#other_rule-third">third</a>)
+</pre>
+
+This is another rule.
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="other_rule-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="other_rule-fourth">
+ <td><code>fourth</code></td>
+ <td>
+ <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a>; required
+ </td>
+ </tr>
+ <tr id="other_rule-third">
+ <td><code>third</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ <p>
+ third other_rule doc string
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#yet_another_rule"></a>
+
+## yet_another_rule
+
+<pre>
+yet_another_rule(<a href="#yet_another_rule-name">name</a>, <a href="#yet_another_rule-fifth">fifth</a>)
+</pre>
+
+This is yet another rule
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="yet_another_rule-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="yet_another_rule-fifth">
+ <td><code>fifth</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#top_fun"></a>
+
+## top_fun
+
+<pre>
+top_fun(<a href="#top_fun-a">a</a>, <a href="#top_fun-b">b</a>, <a href="#top_fun-c">c</a>)
+</pre>
+
+
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="top_fun-a">
+ <td><code>a</code></td>
+ <td>
+ required.
+ </td>
+ </tr>
+ <tr id="top_fun-b">
+ <td><code>b</code></td>
+ <td>
+ required.
+ </td>
+ </tr>
+ <tr id="top_fun-c">
+ <td><code>c</code></td>
+ <td>
+ required.
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/multiple_files_test/inner_dep.bzl b/test/testdata/multiple_files_test/inner_dep.bzl
new file mode 100644
index 0000000..16d4361
--- /dev/null
+++ b/test/testdata/multiple_files_test/inner_dep.bzl
@@ -0,0 +1,9 @@
+"""A deep dependency file."""
+
+def prep_work():
+ """Does some prep work. Nothing to see here."""
+ return 1
+
+def inner_rule_impl(ctx):
+ _ignore = [ctx]
+ return struct()
diff --git a/test/testdata/multiple_files_test/input.bzl b/test/testdata/multiple_files_test/input.bzl
new file mode 100644
index 0000000..5b46c54
--- /dev/null
+++ b/test/testdata/multiple_files_test/input.bzl
@@ -0,0 +1,41 @@
+"""A direct dependency file of the input file."""
+
+load(":testdata/multiple_files_test/dep.bzl", "my_rule_impl", "some_cool_function")
+
+my_rule = rule(
+ implementation = my_rule_impl,
+ doc = "This is my rule. It does stuff.",
+ attrs = {
+ "first": attr.label(
+ mandatory = True,
+ doc = "first my_rule doc string",
+ allow_single_file = True,
+ ),
+ "second": attr.string_dict(mandatory = True),
+ },
+)
+
+def top_fun(a, b, c):
+ some_cool_function(a, b, c)
+ return 6
+
+other_rule = rule(
+ implementation = my_rule_impl,
+ doc = "This is another rule.",
+ attrs = {
+ "third": attr.label(
+ mandatory = True,
+ doc = "third other_rule doc string",
+ allow_single_file = True,
+ ),
+ "fourth": attr.string_dict(mandatory = True),
+ },
+)
+
+yet_another_rule = rule(
+ implementation = my_rule_impl,
+ doc = "This is yet another rule",
+ attrs = {
+ "fifth": attr.label(mandatory = True, allow_single_file = True),
+ },
+)
diff --git a/test/testdata/multiple_rules_test/golden.txt b/test/testdata/multiple_rules_test/golden.txt
new file mode 100644
index 0000000..4637afa
--- /dev/null
+++ b/test/testdata/multiple_rules_test/golden.txt
@@ -0,0 +1,153 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#my_rule"></a>
+
+## my_rule
+
+<pre>
+my_rule(<a href="#my_rule-name">name</a>, <a href="#my_rule-first">first</a>, <a href="#my_rule-second">second</a>)
+</pre>
+
+This is my rule. It does stuff.
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_rule-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-first">
+ <td><code>first</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ </td>
+ </tr>
+ <tr id="my_rule-second">
+ <td><code>second</code></td>
+ <td>
+ <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a>; required
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#other_rule"></a>
+
+## other_rule
+
+<pre>
+other_rule(<a href="#other_rule-name">name</a>, <a href="#other_rule-fourth">fourth</a>, <a href="#other_rule-third">third</a>)
+</pre>
+
+This is another rule.
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="other_rule-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="other_rule-fourth">
+ <td><code>fourth</code></td>
+ <td>
+ <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a>; required
+ </td>
+ </tr>
+ <tr id="other_rule-third">
+ <td><code>third</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#yet_another_rule"></a>
+
+## yet_another_rule
+
+<pre>
+yet_another_rule(<a href="#yet_another_rule-name">name</a>, <a href="#yet_another_rule-fifth">fifth</a>)
+</pre>
+
+This is yet another rule
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="yet_another_rule-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="yet_another_rule-fifth">
+ <td><code>fifth</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#my_rule_impl"></a>
+
+## my_rule_impl
+
+<pre>
+my_rule_impl(<a href="#my_rule_impl-ctx">ctx</a>)
+</pre>
+
+
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_rule_impl-ctx">
+ <td><code>ctx</code></td>
+ <td>
+ required.
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/multiple_rules_test/input.bzl b/test/testdata/multiple_rules_test/input.bzl
new file mode 100644
index 0000000..7a2d314
--- /dev/null
+++ b/test/testdata/multiple_rules_test/input.bzl
@@ -0,0 +1,31 @@
+# buildifier: disable=module-docstring
+def my_rule_impl(ctx):
+ return []
+
+my_rule = rule(
+ implementation = my_rule_impl,
+ doc = "This is my rule. It does stuff.",
+ attrs = {
+ "first": attr.label(mandatory = True, allow_single_file = True),
+ "second": attr.string_dict(mandatory = True),
+ },
+)
+
+other_rule = rule(
+ implementation = my_rule_impl,
+ doc = "This is another rule.",
+ attrs = {
+ "third": attr.label(mandatory = True, allow_single_file = True),
+ "_hidden": attr.string(),
+ "fourth": attr.string_dict(mandatory = True),
+ },
+)
+
+yet_another_rule = rule(
+ implementation = my_rule_impl,
+ doc = "This is yet another rule",
+ attrs = {
+ "_hidden": attr.string(),
+ "fifth": attr.label(mandatory = True, allow_single_file = True),
+ },
+)
diff --git a/test/testdata/namespace_test/golden.txt b/test/testdata/namespace_test/golden.txt
new file mode 100644
index 0000000..6fd6bdd
--- /dev/null
+++ b/test/testdata/namespace_test/golden.txt
@@ -0,0 +1,113 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#my_namespace.assert_non_empty"></a>
+
+## my_namespace.assert_non_empty
+
+<pre>
+my_namespace.assert_non_empty(<a href="#my_namespace.assert_non_empty-some_list">some_list</a>, <a href="#my_namespace.assert_non_empty-other_list">other_list</a>)
+</pre>
+
+Asserts the two given lists are not empty.
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_namespace.assert_non_empty-some_list">
+ <td><code>some_list</code></td>
+ <td>
+ required.
+ <p>
+ The first list
+ </p>
+ </td>
+ </tr>
+ <tr id="my_namespace.assert_non_empty-other_list">
+ <td><code>other_list</code></td>
+ <td>
+ required.
+ <p>
+ The second list
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#my_namespace.min"></a>
+
+## my_namespace.min
+
+<pre>
+my_namespace.min(<a href="#my_namespace.min-integers">integers</a>)
+</pre>
+
+Returns the minimum of given elements.
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_namespace.min-integers">
+ <td><code>integers</code></td>
+ <td>
+ required.
+ <p>
+ A list of integers. Must not be empty.
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#my_namespace.join_strings"></a>
+
+## my_namespace.join_strings
+
+<pre>
+my_namespace.join_strings(<a href="#my_namespace.join_strings-strings">strings</a>, <a href="#my_namespace.join_strings-delimiter">delimiter</a>)
+</pre>
+
+Joins the given strings with a delimiter.
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_namespace.join_strings-strings">
+ <td><code>strings</code></td>
+ <td>
+ required.
+ <p>
+ A list of strings to join.
+ </p>
+ </td>
+ </tr>
+ <tr id="my_namespace.join_strings-delimiter">
+ <td><code>delimiter</code></td>
+ <td>
+ optional. default is <code>", "</code>
+ <p>
+ The delimiter to use
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/namespace_test/input.bzl b/test/testdata/namespace_test/input.bzl
new file mode 100644
index 0000000..69cad64
--- /dev/null
+++ b/test/testdata/namespace_test/input.bzl
@@ -0,0 +1,43 @@
+"""A test that verifies documenting a namespace of functions."""
+
+def _min(integers):
+ """Returns the minimum of given elements.
+
+ Args:
+ integers: A list of integers. Must not be empty.
+
+ Returns:
+ The minimum integer in the given list.
+ """
+ _ignore = [integers]
+ return 42
+
+def _assert_non_empty(some_list, other_list):
+ """Asserts the two given lists are not empty.
+
+ Args:
+ some_list: The first list
+ other_list: The second list
+ """
+ _ignore = [some_list, other_list]
+ fail("Not implemented")
+
+def _join_strings(strings, delimiter = ", "):
+ """Joins the given strings with a delimiter.
+
+ Args:
+ strings: A list of strings to join.
+ delimiter: The delimiter to use
+
+ Returns:
+ The joined string.
+ """
+ _ignore = [strings, delimiter]
+ return ""
+
+my_namespace = struct(
+ dropped_field = "Note this field should not be documented",
+ assert_non_empty = _assert_non_empty,
+ min = _min,
+ join_strings = _join_strings,
+)
diff --git a/test/testdata/proto_format_test/golden.raw b/test/testdata/proto_format_test/golden.raw
new file mode 100644
index 0000000..3c7d256
--- /dev/null
+++ b/test/testdata/proto_format_test/golden.raw
@@ -0,0 +1,16 @@
+
+}
+
+my_exampleSmall example of rule.*
+nameA unique name for this target. +
+uselessThis argument will be ignored.•
+example$Stores information about an example.
+fooA string representing foo
+barA string representing bar
+bazA string representing bazÆ
+check_function%
+fooA unique name for this rule. ŒRuns some checks on the given function parameter.
+
+This rule runs checks on a given function parameter.
+Use `bazel build` to run the check.
+* Input file for proto format test \ No newline at end of file
diff --git a/test/testdata/proto_format_test/input.bzl b/test/testdata/proto_format_test/input.bzl
new file mode 100644
index 0000000..aee171e
--- /dev/null
+++ b/test/testdata/proto_format_test/input.bzl
@@ -0,0 +1,35 @@
+"""Input file for proto format test"""
+
+def check_function(foo):
+ """Runs some checks on the given function parameter.
+
+ This rule runs checks on a given function parameter.
+ Use `bazel build` to run the check.
+
+ Args:
+ foo: A unique name for this rule.
+ """
+ pass
+
+example = provider(
+ doc = "Stores information about an example.",
+ fields = {
+ "foo": "A string representing foo",
+ "bar": "A string representing bar",
+ "baz": "A string representing baz",
+ },
+)
+
+def _rule_impl(ctx):
+ return []
+
+my_example = rule(
+ implementation = _rule_impl,
+ doc = "Small example of rule.",
+ attrs = {
+ "useless": attr.string(
+ doc = "This argument will be ignored.",
+ default = "ignoreme",
+ ),
+ },
+)
diff --git a/test/testdata/provider_basic_test/golden.txt b/test/testdata/provider_basic_test/golden.txt
new file mode 100644
index 0000000..190594c
--- /dev/null
+++ b/test/testdata/provider_basic_test/golden.txt
@@ -0,0 +1,85 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#MyFooInfo"></a>
+
+## MyFooInfo
+
+<pre>
+MyFooInfo(<a href="#MyFooInfo-bar">bar</a>, <a href="#MyFooInfo-baz">baz</a>)
+</pre>
+
+Stores information about a foo.
+
+### Fields
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="MyFooInfo-bar">
+ <td><code>bar</code></td>
+ <td>
+ <p>(Undocumented)</p>
+ </td>
+ </tr>
+ <tr id="MyFooInfo-baz">
+ <td><code>baz</code></td>
+ <td>
+ <p>(Undocumented)</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#MyPoorlyDocumentedInfo"></a>
+
+## MyPoorlyDocumentedInfo
+
+<pre>
+MyPoorlyDocumentedInfo()
+</pre>
+
+
+
+
+
+<a name="#MyVeryDocumentedInfo"></a>
+
+## MyVeryDocumentedInfo
+
+<pre>
+MyVeryDocumentedInfo(<a href="#MyVeryDocumentedInfo-favorite_food">favorite_food</a>, <a href="#MyVeryDocumentedInfo-favorite_color">favorite_color</a>)
+</pre>
+
+
+A provider with some really neat documentation.
+Look on my works, ye mighty, and despair!
+
+
+### Fields
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="MyVeryDocumentedInfo-favorite_food">
+ <td><code>favorite_food</code></td>
+ <td>
+ <p>A string representing my favorite food</p>
+ </td>
+ </tr>
+ <tr id="MyVeryDocumentedInfo-favorite_color">
+ <td><code>favorite_color</code></td>
+ <td>
+ <p>A string representing my favorite color</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/provider_basic_test/input.bzl b/test/testdata/provider_basic_test/input.bzl
new file mode 100644
index 0000000..7600f2c
--- /dev/null
+++ b/test/testdata/provider_basic_test/input.bzl
@@ -0,0 +1,18 @@
+# buildifier: disable=module-docstring
+MyPoorlyDocumentedInfo = provider()
+
+MyFooInfo = provider(
+ doc = "Stores information about a foo.",
+ fields = ["bar", "baz"],
+)
+
+MyVeryDocumentedInfo = provider(
+ doc = """
+A provider with some really neat documentation.
+Look on my works, ye mighty, and despair!
+""",
+ fields = {
+ "favorite_food": "A string representing my favorite food",
+ "favorite_color": "A string representing my favorite color",
+ },
+)
diff --git a/test/testdata/providers_for_attributes_test/dep.bzl b/test/testdata/providers_for_attributes_test/dep.bzl
new file mode 100644
index 0000000..56ab3b7
--- /dev/null
+++ b/test/testdata/providers_for_attributes_test/dep.bzl
@@ -0,0 +1,5 @@
+"A file to test providers not defined in the same file."
+
+DepProviderInfo = provider(
+ doc = "This provider does something.",
+)
diff --git a/test/testdata/providers_for_attributes_test/golden.txt b/test/testdata/providers_for_attributes_test/golden.txt
new file mode 100644
index 0000000..fa44df5
--- /dev/null
+++ b/test/testdata/providers_for_attributes_test/golden.txt
@@ -0,0 +1,164 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#my_rule"></a>
+
+## my_rule
+
+<pre>
+my_rule(<a href="#my_rule-name">name</a>, <a href="#my_rule-fifth">fifth</a>, <a href="#my_rule-first">first</a>, <a href="#my_rule-fourth">fourth</a>, <a href="#my_rule-second">second</a>, <a href="#my_rule-sixth">sixth</a>, <a href="#my_rule-third">third</a>)
+</pre>
+
+This rule does things.
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_rule-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-fifth">
+ <td><code>fifth</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; optional
+ <p>
+ The dependencies of this attribute must provide: LegacyProvider, ObjectProvider; or DefaultInfo, JavaInfo
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-first">
+ <td><code>first</code></td>
+ <td>
+ <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: Label -> String</a>; optional
+ <p>
+ this is the first attribute.
+ </p>
+ <p>
+ The dependencies of this attribute must provide: MyProviderInfo, PyInfo, Unknown Provider
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-fourth">
+ <td><code>fourth</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; optional
+ <p>
+ The dependencies of this attribute must provide: ProtoInfo, DefaultInfo, JavaInfo
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-second">
+ <td><code>second</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">List of labels</a>; optional
+ <p>
+ The dependencies of this attribute must provide: CcInfo; or OtherProviderInfo, DepProviderInfo
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-sixth">
+ <td><code>sixth</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; optional
+ <p>
+ The dependencies of this attribute must provide: LegacyProvider
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-third">
+ <td><code>third</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; optional
+ <p>
+ The dependencies of this attribute must provide: OtherProviderInfo
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#MyProviderInfo"></a>
+
+## MyProviderInfo
+
+<pre>
+MyProviderInfo(<a href="#MyProviderInfo-foo">foo</a>, <a href="#MyProviderInfo-bar">bar</a>)
+</pre>
+
+
+
+### Fields
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="MyProviderInfo-foo">
+ <td><code>foo</code></td>
+ <td>
+ <p>Something foo-related.</p>
+ </td>
+ </tr>
+ <tr id="MyProviderInfo-bar">
+ <td><code>bar</code></td>
+ <td>
+ <p>Something bar-related.</p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
+<a name="#OtherProviderInfo"></a>
+
+## OtherProviderInfo
+
+<pre>
+OtherProviderInfo()
+</pre>
+
+
+
+
+
+<a name="#my_rule_impl"></a>
+
+## my_rule_impl
+
+<pre>
+my_rule_impl(<a href="#my_rule_impl-ctx">ctx</a>)
+</pre>
+
+
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_rule_impl-ctx">
+ <td><code>ctx</code></td>
+ <td>
+ required.
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/providers_for_attributes_test/input.bzl b/test/testdata/providers_for_attributes_test/input.bzl
new file mode 100644
index 0000000..774a0e9
--- /dev/null
+++ b/test/testdata/providers_for_attributes_test/input.bzl
@@ -0,0 +1,42 @@
+"""The input file for the providers for attributes test"""
+
+load(":testdata/providers_for_attributes_test/dep.bzl", "DepProviderInfo")
+
+def my_rule_impl(ctx):
+ return []
+
+MyProviderInfo = provider(
+ fields = {
+ "foo": "Something foo-related.",
+ "bar": "Something bar-related.",
+ },
+)
+
+OtherProviderInfo = provider()
+other_provider_info = OtherProviderInfo(fields = ["foo"])
+
+my_rule = rule(
+ implementation = my_rule_impl,
+ doc = "This rule does things.",
+ attrs = {
+ "first": attr.label_keyed_string_dict(
+ providers = [MyProviderInfo, PyInfo, cc_common.CcToolchainInfo],
+ doc = "this is the first attribute.",
+ ),
+ "second": attr.label_list(
+ providers = [[CcInfo], [OtherProviderInfo, DepProviderInfo]],
+ ),
+ "third": attr.label(
+ providers = [OtherProviderInfo],
+ ),
+ "fourth": attr.label(
+ providers = [ProtoInfo, DefaultInfo, JavaInfo],
+ ),
+ "fifth": attr.label(
+ providers = [["LegacyProvider", "ObjectProvider"], [DefaultInfo, JavaInfo]],
+ ),
+ "sixth": attr.label(
+ providers = ["LegacyProvider"],
+ ),
+ },
+)
diff --git a/test/testdata/pure_markdown_template_test/golden.txt b/test/testdata/pure_markdown_template_test/golden.txt
new file mode 100644
index 0000000..ecbc516
--- /dev/null
+++ b/test/testdata/pure_markdown_template_test/golden.txt
@@ -0,0 +1,90 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#example_rule"></a>
+
+## example_rule
+
+<pre>
+example_rule(<a href="#example_rule-name">name</a>, <a href="#example_rule-first">first</a>, <a href="#example_rule-second">second</a>)
+</pre>
+
+Small example of rule using a markdown template.
+
+**ATTRIBUTES**
+
+
+| Name | Description | Type | Mandatory |
+| :-------------: | :-------------: | :-------------: | :-------------: |
+| name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required |
+| first | This is the first attribute | String | optional |
+| second | - | String | optional |
+
+
+<a name="#ExampleProviderInfo"></a>
+
+## ExampleProviderInfo
+
+<pre>
+ExampleProviderInfo(<a href="#ExampleProviderInfo-foo">foo</a>, <a href="#ExampleProviderInfo-bar">bar</a>, <a href="#ExampleProviderInfo-baz">baz</a>)
+</pre>
+
+Small example of provider using a markdown template.
+
+**FIELDS**
+
+
+| Name | Description |
+| :-------------: | :-------------: |
+| foo | A string representing foo |
+| bar | A string representing bar |
+| baz | A string representing baz |
+
+
+<a name="#example_function"></a>
+
+## example_function
+
+<pre>
+example_function(<a href="#example_function-foo">foo</a>, <a href="#example_function-bar">bar</a>)
+</pre>
+
+Small example of function using a markdown template.
+
+**PARAMETERS**
+
+
+| Name | Description | Default Value |
+| :-------------: | :-------------: | :-------------: |
+| foo | This parameter does foo related things. | none |
+| bar | This parameter does bar related things. | <code>"bar"</code> |
+
+
+<a name="#example_aspect"></a>
+
+## example_aspect
+
+<pre>
+example_aspect(<a href="#example_aspect-name">name</a>, <a href="#example_aspect-first">first</a>, <a href="#example_aspect-second">second</a>)
+</pre>
+
+Small example of aspect using a markdown template.
+
+**ASPECT ATTRIBUTES**
+
+
+| Name | Type |
+| :-------------: | :-------------: |
+| deps| String |
+| attr_aspect| String |
+
+
+**ATTRIBUTES**
+
+
+| Name | Description | Type | Mandatory |
+| :-------------: | :-------------: | :-------------: | :-------------: |
+| name | A unique name for this target. | <a href="https://bazel.build/docs/build-ref.html#name">Name</a> | required |
+| first | - | <a href="https://bazel.build/docs/build-ref.html#labels">Label</a> | required |
+| second | This is the second attribute. | String | optional |
+
+
diff --git a/test/testdata/pure_markdown_template_test/input.bzl b/test/testdata/pure_markdown_template_test/input.bzl
new file mode 100644
index 0000000..23f3379
--- /dev/null
+++ b/test/testdata/pure_markdown_template_test/input.bzl
@@ -0,0 +1,44 @@
+"""Input file for markdown template test"""
+
+def example_function(foo, bar = "bar"):
+ """Small example of function using a markdown template.
+
+ Args:
+ foo: This parameter does foo related things.
+ bar: This parameter does bar related things.
+ """
+ pass
+
+ExampleProviderInfo = provider(
+ doc = "Small example of provider using a markdown template.",
+ fields = {
+ "foo": "A string representing foo",
+ "bar": "A string representing bar",
+ "baz": "A string representing baz",
+ },
+)
+
+def _rule_impl(ctx):
+ return []
+
+example_rule = rule(
+ implementation = _rule_impl,
+ doc = "Small example of rule using a markdown template.",
+ attrs = {
+ "first": attr.string(doc = "This is the first attribute"),
+ "second": attr.string(default = "2"),
+ },
+)
+
+def _aspect_impl(ctx):
+ return []
+
+example_aspect = aspect(
+ implementation = _aspect_impl,
+ doc = "Small example of aspect using a markdown template.",
+ attr_aspects = ["deps", "attr_aspect"],
+ attrs = {
+ "first": attr.label(mandatory = True, allow_single_file = True),
+ "second": attr.string(doc = "This is the second attribute."),
+ },
+)
diff --git a/test/testdata/py_rule_test/golden.txt b/test/testdata/py_rule_test/golden.txt
new file mode 100644
index 0000000..76ffdb8
--- /dev/null
+++ b/test/testdata/py_rule_test/golden.txt
@@ -0,0 +1,81 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#py_related_rule"></a>
+
+## py_related_rule
+
+<pre>
+py_related_rule(<a href="#py_related_rule-name">name</a>, <a href="#py_related_rule-fifth">fifth</a>, <a href="#py_related_rule-first">first</a>, <a href="#py_related_rule-fourth">fourth</a>, <a href="#py_related_rule-second">second</a>, <a href="#py_related_rule-sixth">sixth</a>, <a href="#py_related_rule-third">third</a>)
+</pre>
+
+This rule does python-related things.
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="py_related_rule-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="py_related_rule-fifth">
+ <td><code>fifth</code></td>
+ <td>
+ Boolean; optional
+ <p>
+ Hey look, its the fifth thing!
+ </p>
+ </td>
+ </tr>
+ <tr id="py_related_rule-first">
+ <td><code>first</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ <p>
+ this is the first doc string!
+ </p>
+ </td>
+ </tr>
+ <tr id="py_related_rule-fourth">
+ <td><code>fourth</code></td>
+ <td>
+ Boolean; optional
+ <p>
+ the fourth doc string.
+ </p>
+ </td>
+ </tr>
+ <tr id="py_related_rule-second">
+ <td><code>second</code></td>
+ <td>
+ <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a>; required
+ </td>
+ </tr>
+ <tr id="py_related_rule-sixth">
+ <td><code>sixth</code></td>
+ <td>
+ List of integers; optional
+ <p>
+ it's the sixth thing.
+ </p>
+ </td>
+ </tr>
+ <tr id="py_related_rule-third">
+ <td><code>third</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/py_rule_test/input.bzl b/test/testdata/py_rule_test/input.bzl
new file mode 100644
index 0000000..0d6bc16
--- /dev/null
+++ b/test/testdata/py_rule_test/input.bzl
@@ -0,0 +1,32 @@
+"""The input file for the python rule test"""
+
+def exercise_the_api():
+ var1 = PyRuntimeInfo
+ var2 = PyInfo
+
+exercise_the_api()
+
+def my_rule_impl(ctx):
+ return []
+
+py_related_rule = rule(
+ implementation = my_rule_impl,
+ doc = "This rule does python-related things.",
+ attrs = {
+ "first": attr.label(
+ mandatory = True,
+ doc = "this is the first doc string!",
+ allow_single_file = True,
+ ),
+ "second": attr.string_dict(mandatory = True),
+ "third": attr.output(mandatory = True),
+ "fourth": attr.bool(default = False, doc = "the fourth doc string.", mandatory = False),
+ "fifth": attr.bool(default = True, doc = "Hey look, its the fifth thing!"),
+ "sixth": attr.int_list(
+ default = range(10),
+ doc = "it's the sixth thing.",
+ mandatory = False,
+ ),
+ "_hidden": attr.string(),
+ },
+)
diff --git a/test/testdata/repo_rules_test/golden.txt b/test/testdata/repo_rules_test/golden.txt
new file mode 100644
index 0000000..dc84d8e
--- /dev/null
+++ b/test/testdata/repo_rules_test/golden.txt
@@ -0,0 +1,42 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#my_repo"></a>
+
+## my_repo
+
+<pre>
+my_repo(<a href="#my_repo-name">name</a>, <a href="#my_repo-useless">useless</a>)
+</pre>
+
+Minimal example of a repository rule.
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_repo-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this repository.
+ </p>
+ </td>
+ </tr>
+ <tr id="my_repo-useless">
+ <td><code>useless</code></td>
+ <td>
+ String; optional
+ <p>
+ This argument will be ingored. You don't have to specify it, but you may.
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/repo_rules_test/input.bzl b/test/testdata/repo_rules_test/input.bzl
new file mode 100644
index 0000000..023d92d
--- /dev/null
+++ b/test/testdata/repo_rules_test/input.bzl
@@ -0,0 +1,14 @@
+# buildifier: disable=module-docstring
+def _repo_rule_impl(ctx):
+ ctx.file("BUILD", "")
+
+my_repo = repository_rule(
+ implementation = _repo_rule_impl,
+ doc = "Minimal example of a repository rule.",
+ attrs = {
+ "useless": attr.string(
+ doc = "This argument will be ingored. You don't have to specify it, but you may.",
+ default = "ignoreme",
+ ),
+ },
+)
diff --git a/test/testdata/same_level_file_test/BUILD b/test/testdata/same_level_file_test/BUILD
new file mode 100644
index 0000000..97c2e46
--- /dev/null
+++ b/test/testdata/same_level_file_test/BUILD
@@ -0,0 +1,14 @@
+filegroup(
+ name = "srcs",
+ testonly = 0,
+ srcs = glob(["**"]),
+ visibility = ["//src:__subpackages__"],
+)
+
+exports_files(
+ [
+ "dep.bzl",
+ "golden.txt",
+ "input.bzl",
+ ],
+)
diff --git a/test/testdata/same_level_file_test/dep.bzl b/test/testdata/same_level_file_test/dep.bzl
new file mode 100644
index 0000000..87750b3
--- /dev/null
+++ b/test/testdata/same_level_file_test/dep.bzl
@@ -0,0 +1,5 @@
+# buildifier: disable=module-docstring
+# buildifier: disable=function-docstring
+def my_rule_impl(ctx):
+ _ignore = [ctx]
+ return struct()
diff --git a/test/testdata/same_level_file_test/golden.txt b/test/testdata/same_level_file_test/golden.txt
new file mode 100644
index 0000000..cf02e4c
--- /dev/null
+++ b/test/testdata/same_level_file_test/golden.txt
@@ -0,0 +1,48 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#my_rule"></a>
+
+## my_rule
+
+<pre>
+my_rule(<a href="#my_rule-name">name</a>, <a href="#my_rule-first">first</a>, <a href="#my_rule-second">second</a>)
+</pre>
+
+This is my rule. It does stuff.
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_rule-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-first">
+ <td><code>first</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ <p>
+ first my_rule doc string
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-second">
+ <td><code>second</code></td>
+ <td>
+ <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a>; required
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/same_level_file_test/input.bzl b/test/testdata/same_level_file_test/input.bzl
new file mode 100644
index 0000000..b1f67fb
--- /dev/null
+++ b/test/testdata/same_level_file_test/input.bzl
@@ -0,0 +1,15 @@
+# buildifier: disable=module-docstring
+load(":dep.bzl", "my_rule_impl")
+
+my_rule = rule(
+ implementation = my_rule_impl,
+ doc = "This is my rule. It does stuff.",
+ attrs = {
+ "first": attr.label(
+ mandatory = True,
+ doc = "first my_rule doc string",
+ allow_single_file = True,
+ ),
+ "second": attr.string_dict(mandatory = True),
+ },
+)
diff --git a/test/testdata/simple_test/golden.txt b/test/testdata/simple_test/golden.txt
new file mode 100644
index 0000000..59a0cf5
--- /dev/null
+++ b/test/testdata/simple_test/golden.txt
@@ -0,0 +1,63 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#my_rule"></a>
+
+## my_rule
+
+<pre>
+my_rule(<a href="#my_rule-name">name</a>, <a href="#my_rule-first">first</a>, <a href="#my_rule-fourth">fourth</a>, <a href="#my_rule-second">second</a>, <a href="#my_rule-third">third</a>)
+</pre>
+
+This is my rule. It does stuff.
+
+### Attributes
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_rule-name">
+ <td><code>name</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#name">Name</a>; required
+ <p>
+ A unique name for this target.
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-first">
+ <td><code>first</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ <p>
+ first doc string
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-fourth">
+ <td><code>fourth</code></td>
+ <td>
+ Boolean; optional
+ <p>
+ fourth doc string
+ </p>
+ </td>
+ </tr>
+ <tr id="my_rule-second">
+ <td><code>second</code></td>
+ <td>
+ <a href="https://bazel.build/docs/skylark/lib/dict.html">Dictionary: String -> String</a>; required
+ </td>
+ </tr>
+ <tr id="my_rule-third">
+ <td><code>third</code></td>
+ <td>
+ <a href="https://bazel.build/docs/build-ref.html#labels">Label</a>; required
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/simple_test/input.bzl b/test/testdata/simple_test/input.bzl
new file mode 100644
index 0000000..fe0ffc7
--- /dev/null
+++ b/test/testdata/simple_test/input.bzl
@@ -0,0 +1,19 @@
+# buildifier: disable=module-docstring
+def my_rule_impl(ctx):
+ return []
+
+my_rule = rule(
+ implementation = my_rule_impl,
+ doc = "This is my rule. It does stuff.",
+ attrs = {
+ "first": attr.label(
+ mandatory = True,
+ doc = "first doc string",
+ allow_single_file = True,
+ ),
+ "second": attr.string_dict(mandatory = True),
+ "third": attr.output(mandatory = True),
+ "fourth": attr.bool(default = False, doc = "fourth doc string", mandatory = False),
+ "_hidden": attr.string(),
+ },
+)
diff --git a/test/testdata/struct_default_value_test/golden.txt b/test/testdata/struct_default_value_test/golden.txt
new file mode 100644
index 0000000..44fe4a5
--- /dev/null
+++ b/test/testdata/struct_default_value_test/golden.txt
@@ -0,0 +1,69 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#check_struct_default_values"></a>
+
+## check_struct_default_values
+
+<pre>
+check_struct_default_values(<a href="#check_struct_default_values-struct_no_args">struct_no_args</a>, <a href="#check_struct_default_values-struct_arg">struct_arg</a>, <a href="#check_struct_default_values-struct_args">struct_args</a>, <a href="#check_struct_default_values-struct_int_args">struct_int_args</a>, <a href="#check_struct_default_values-struct_struct_args">struct_struct_args</a>)
+</pre>
+
+Checks the default values of structs.
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="check_struct_default_values-struct_no_args">
+ <td><code>struct_no_args</code></td>
+ <td>
+ optional. default is <code>struct()</code>
+ <p>
+ struct with no arguments
+ </p>
+ </td>
+ </tr>
+ <tr id="check_struct_default_values-struct_arg">
+ <td><code>struct_arg</code></td>
+ <td>
+ optional. default is <code>struct(foo = "bar")</code>
+ <p>
+ struct with one argument
+ </p>
+ </td>
+ </tr>
+ <tr id="check_struct_default_values-struct_args">
+ <td><code>struct_args</code></td>
+ <td>
+ optional. default is <code>struct(bar = "foo", foo = "bar")</code>
+ <p>
+ struct with multiple arguments
+ </p>
+ </td>
+ </tr>
+ <tr id="check_struct_default_values-struct_int_args">
+ <td><code>struct_int_args</code></td>
+ <td>
+ optional. default is <code>struct(one = 1, three = 3, two = 2)</code>
+ <p>
+ struct with int arguments
+ </p>
+ </td>
+ </tr>
+ <tr id="check_struct_default_values-struct_struct_args">
+ <td><code>struct_struct_args</code></td>
+ <td>
+ optional. default is <code>struct(multiple = struct(one = 1, three = 3, two = 2), none = struct(), one = struct(foo = "bar"))</code>
+ <p>
+ struct with struct arguments
+ </p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/struct_default_value_test/input.bzl b/test/testdata/struct_default_value_test/input.bzl
new file mode 100644
index 0000000..ead514b
--- /dev/null
+++ b/test/testdata/struct_default_value_test/input.bzl
@@ -0,0 +1,22 @@
+"""The input file for struct default values test"""
+
+def check_struct_default_values(
+ struct_no_args = struct(),
+ struct_arg = struct(foo = "bar"),
+ struct_args = struct(foo = "bar", bar = "foo"),
+ struct_int_args = struct(one = 1, two = 2, three = 3),
+ struct_struct_args = struct(
+ none = struct(),
+ one = struct(foo = "bar"),
+ multiple = struct(one = 1, two = 2, three = 3),
+ )):
+ """Checks the default values of structs.
+
+ Args:
+ struct_no_args: struct with no arguments
+ struct_arg: struct with one argument
+ struct_args: struct with multiple arguments
+ struct_int_args: struct with int arguments
+ struct_struct_args: struct with struct arguments
+ """
+ pass
diff --git a/test/testdata/unknown_name_test/golden.txt b/test/testdata/unknown_name_test/golden.txt
new file mode 100644
index 0000000..99e1fbd
--- /dev/null
+++ b/test/testdata/unknown_name_test/golden.txt
@@ -0,0 +1,30 @@
+<!-- Generated with Stardoc: http://skydoc.bazel.build -->
+
+<a name="#my_rule_impl"></a>
+
+## my_rule_impl
+
+<pre>
+my_rule_impl(<a href="#my_rule_impl-ctx">ctx</a>)
+</pre>
+
+
+
+### Parameters
+
+<table class="params-table">
+ <colgroup>
+ <col class="col-param" />
+ <col class="col-description" />
+ </colgroup>
+ <tbody>
+ <tr id="my_rule_impl-ctx">
+ <td><code>ctx</code></td>
+ <td>
+ required.
+ </td>
+ </tr>
+ </tbody>
+</table>
+
+
diff --git a/test/testdata/unknown_name_test/input.bzl b/test/testdata/unknown_name_test/input.bzl
new file mode 100644
index 0000000..062f49d
--- /dev/null
+++ b/test/testdata/unknown_name_test/input.bzl
@@ -0,0 +1,13 @@
+# buildifier: disable=module-docstring
+def my_rule_impl(ctx):
+ return []
+
+rule(
+ implementation = my_rule_impl,
+ attrs = {
+ "first": attr.label(mandatory = True, allow_single_file = True),
+ "second": attr.string_dict(mandatory = True),
+ "third": attr.output(mandatory = True),
+ "fourth": attr.bool(default = False, mandatory = False),
+ },
+)