diff options
9 files changed, 742 insertions, 0 deletions
diff --git a/src/test/java/com/google/devtools/build/docgen/BUILD b/src/test/java/com/google/devtools/build/docgen/BUILD new file mode 100644 index 0000000000..81c2fa612b --- /dev/null +++ b/src/test/java/com/google/devtools/build/docgen/BUILD @@ -0,0 +1,59 @@ +package( + default_visibility = ["//visibility:public"], +) + +licenses(["notice"]) # Apache 2.0 + +test_suite( + name = "all_tests", + tags = ["docgen"], +) + +java_test( + name = "DocumentationTests", + size = "medium", + srcs = ["DocumentationTests.java"], + shard_count = 1, + tags = ["docgen"], + deps = [ + ":documentation-tests", + "//src/test/java/com/google/devtools/build/lib:testutil", + "//third_party:junit4", + ], +) + +java_library( + name = "documentation-tests", + testonly = 1, + srcs = [ + "DocCheckerUtilsTest.java", + "RuleDocumentationAttributeTest.java", + "RuleDocumentationTest.java", + "SkylarkDocumentationTest.java", + ], + deps = [ + ":testutil", + "//src/main/java/com/google/devtools/build/docgen:docgen_javalib", + "//src/main/java/com/google/devtools/build/lib:build-base", + "//src/main/java/com/google/devtools/build/lib:packages-internal", + "//src/main/java/com/google/devtools/build/lib:skylarkinterface", + "//src/main/java/com/google/devtools/build/lib:syntax", + "//src/main/java/com/google/devtools/build/lib/rules/cpp", + "//src/test/java/com/google/devtools/build/lib:skylark_testutil", + "//src/test/java/com/google/devtools/build/lib:syntax_testutil", + "//src/test/java/com/google/devtools/build/lib:testutil", + "//third_party:guava", + "//third_party:junit4", + "//third_party:truth", + ], +) + +java_library( + name = "testutil", + testonly = 1, + srcs = glob(["testutil/*.java"]), + deps = [ + "//src/main/java/com/google/devtools/build/lib:build-base", + "//src/main/java/com/google/devtools/build/lib:packages-internal", + ], +) diff --git a/src/test/java/com/google/devtools/build/docgen/DocCheckerUtilsTest.java b/src/test/java/com/google/devtools/build/docgen/DocCheckerUtilsTest.java new file mode 100644 index 0000000000..6e40baceed --- /dev/null +++ b/src/test/java/com/google/devtools/build/docgen/DocCheckerUtilsTest.java @@ -0,0 +1,44 @@ +// Copyright 2015 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. +package com.google.devtools.build.docgen; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * Tests for DocCheckerUtils. + */ +@RunWith(JUnit4.class) +public class DocCheckerUtilsTest { + + @Test + public void testUnclosedTags() { + assertNull(DocCheckerUtils.getFirstUnclosedTag("<html></html>")); + assertEquals("ol", DocCheckerUtils.getFirstUnclosedTag("<html><ol></html>")); + assertEquals("ol", DocCheckerUtils.getFirstUnclosedTag("<html><ol><li>foo</li></html>")); + assertEquals("ol", DocCheckerUtils.getFirstUnclosedTag("<html><ol><li/>foo<li/>bar</html>")); + } + + @Test + public void testUncheckedTagsDontFire() { + assertNull(DocCheckerUtils.getFirstUnclosedTag("<html><br></html>")); + assertNull(DocCheckerUtils.getFirstUnclosedTag("<html><li></html>")); + assertNull(DocCheckerUtils.getFirstUnclosedTag("<html><ul></html>")); + assertNull(DocCheckerUtils.getFirstUnclosedTag("<html><p></html>")); + } +} diff --git a/src/test/java/com/google/devtools/build/docgen/DocumentationTests.java b/src/test/java/com/google/devtools/build/docgen/DocumentationTests.java new file mode 100644 index 0000000000..c61090e210 --- /dev/null +++ b/src/test/java/com/google/devtools/build/docgen/DocumentationTests.java @@ -0,0 +1,25 @@ +// Copyright 2015 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. +package com.google.devtools.build.docgen; + +import com.google.devtools.build.lib.testutil.ClasspathSuite; + +import org.junit.runner.RunWith; + +/** + * Test suite for options parsing framework. + */ +@RunWith(ClasspathSuite.class) +public class DocumentationTests { +}
\ No newline at end of file diff --git a/src/test/java/com/google/devtools/build/docgen/RuleDocumentationAttributeTest.java b/src/test/java/com/google/devtools/build/docgen/RuleDocumentationAttributeTest.java new file mode 100644 index 0000000000..eec4611047 --- /dev/null +++ b/src/test/java/com/google/devtools/build/docgen/RuleDocumentationAttributeTest.java @@ -0,0 +1,157 @@ +// Copyright 2015 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. +package com.google.devtools.build.docgen; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import com.google.common.collect.ImmutableSet; +import com.google.devtools.build.docgen.testutil.TestData.BaseRule; +import com.google.devtools.build.docgen.testutil.TestData.IntermediateRule; +import com.google.devtools.build.docgen.testutil.TestData.TestRule; +import com.google.devtools.build.lib.packages.Attribute; +import com.google.devtools.build.lib.packages.BuildType; +import com.google.devtools.build.lib.rules.cpp.CppFileTypes; +import com.google.devtools.build.lib.syntax.Type; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * A test class for RuleDocumentationAttribute. + */ +@RunWith(JUnit4.class) +public class RuleDocumentationAttributeTest { + private static final ImmutableSet<String> NO_FLAGS = ImmutableSet.<String>of(); + + @Test + public void testDirectChild() { + RuleDocumentationAttribute attr1 = RuleDocumentationAttribute.create( + IntermediateRule.class, "", "", 0, NO_FLAGS); + assertEquals(1, attr1.getDefinitionClassAncestryLevel(TestRule.class)); + } + + @Test + public void testTransitiveChild() { + RuleDocumentationAttribute attr2 = RuleDocumentationAttribute.create( + BaseRule.class, "", "", 0, NO_FLAGS); + assertEquals(2, attr2.getDefinitionClassAncestryLevel(TestRule.class)); + } + + @Test + public void testClassIsNotChild() { + RuleDocumentationAttribute attr2 = RuleDocumentationAttribute.create( + IntermediateRule.class, "", "", 0, NO_FLAGS); + assertEquals(-1, attr2.getDefinitionClassAncestryLevel(BaseRule.class)); + } + + @Test + public void testClassIsSame() { + RuleDocumentationAttribute attr3 = RuleDocumentationAttribute.create( + TestRule.class, "", "", 0, NO_FLAGS); + assertEquals(0, attr3.getDefinitionClassAncestryLevel(TestRule.class)); + } + + @Test + public void testHasFlags() { + RuleDocumentationAttribute attr = RuleDocumentationAttribute.create( + TestRule.class, "", "", 0, ImmutableSet.<String>of("SOME_FLAG")); + assertTrue(attr.hasFlag("SOME_FLAG")); + } + + @Test + public void testCompareTo() { + assertTrue( + RuleDocumentationAttribute.create(TestRule.class, "a", "", 0, NO_FLAGS) + .compareTo( + RuleDocumentationAttribute.create(TestRule.class, "b", "", 0, NO_FLAGS)) + == -1); + } + + @Test + public void testCompareToWithPriorityAttributeName() { + assertTrue( + RuleDocumentationAttribute.create(TestRule.class, "a", "", 0, NO_FLAGS) + .compareTo( + RuleDocumentationAttribute.create(TestRule.class, "name", "", 0, NO_FLAGS)) + == 1); + } + + @Test + public void testEquals() { + assertEquals( + RuleDocumentationAttribute.create(TestRule.class, "a", "", 0, NO_FLAGS), + RuleDocumentationAttribute.create(IntermediateRule.class, "a", "", 0, NO_FLAGS)); + } + + @Test + public void testHashCode() { + assertEquals( + RuleDocumentationAttribute.create(TestRule.class, "a", "", 0, NO_FLAGS) + .hashCode(), + RuleDocumentationAttribute.create(IntermediateRule.class, "a", "", 0, NO_FLAGS) + .hashCode()); + } + + @Test + public void testSynopsisForStringAttribute() { + final String defaultValue = "9"; + Attribute attribute = Attribute.attr("foo_version", Type.STRING) + .value(defaultValue).build(); + RuleDocumentationAttribute attributeDoc = RuleDocumentationAttribute.create( + TestRule.class, "testrule", "${SYNOPSIS}", 0, NO_FLAGS); + attributeDoc.setAttribute(attribute); + String doc = attributeDoc.getSynopsis(); + assertEquals("String; optional; default is \"" + defaultValue + "\"", doc); + } + + @Test + public void testSynopsisForIntegerAttribute() { + final int defaultValue = 384; + Attribute attribute = Attribute.attr("bar_limit", Type.INTEGER) + .value(defaultValue).build(); + RuleDocumentationAttribute attributeDoc = RuleDocumentationAttribute.create( + TestRule.class, "testrule", "${SYNOPSIS}", 0, NO_FLAGS); + attributeDoc.setAttribute(attribute); + String doc = attributeDoc.getSynopsis(); + assertEquals("Integer; optional; default is " + defaultValue, doc); + } + + @Test + public void testSynopsisForLabelListAttribute() { + Attribute attribute = Attribute.attr("some_labels", BuildType.LABEL_LIST) + .allowedRuleClasses("foo_rule") + .allowedFileTypes() + .build(); + RuleDocumentationAttribute attributeDoc = RuleDocumentationAttribute.create( + TestRule.class, "testrule", "${SYNOPSIS}", 0, NO_FLAGS); + attributeDoc.setAttribute(attribute); + String doc = attributeDoc.getSynopsis(); + assertEquals("List of <a href=\"../build-ref.html#labels\">labels</a>; optional", doc); + } + + @Test + public void testSynopsisForMandatoryAttribute() { + Attribute attribute = Attribute.attr("baz_labels", BuildType.LABEL) + .mandatory() + .allowedFileTypes(CppFileTypes.CPP_HEADER) + .build(); + RuleDocumentationAttribute attributeDoc = RuleDocumentationAttribute.create( + TestRule.class, "testrule", "${SYNOPSIS}", 0, NO_FLAGS); + attributeDoc.setAttribute(attribute); + String doc = attributeDoc.getSynopsis(); + assertEquals("<a href=\"../build-ref.html#labels\">Label</a>; required", doc); + } +} diff --git a/src/test/java/com/google/devtools/build/docgen/RuleDocumentationTest.java b/src/test/java/com/google/devtools/build/docgen/RuleDocumentationTest.java new file mode 100644 index 0000000000..549224afff --- /dev/null +++ b/src/test/java/com/google/devtools/build/docgen/RuleDocumentationTest.java @@ -0,0 +1,201 @@ +// Copyright 2015 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. +package com.google.devtools.build.docgen; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import com.google.common.base.Joiner; +import com.google.common.collect.ImmutableSet; +import com.google.devtools.build.docgen.testutil.TestData.TestRule; +import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; +import com.google.devtools.build.lib.testutil.TestRuleClassProvider; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** + * A test class for RuleDocumentation. + */ +@RunWith(JUnit4.class) +public class RuleDocumentationTest { + + private static final ImmutableSet<String> NO_FLAGS = ImmutableSet.<String>of(); + private static final ConfiguredRuleClassProvider provider = + TestRuleClassProvider.getRuleClassProvider(); + + private static void assertContains(String base, String value) { + assertTrue(base + " is expected to contain " + value, base.contains(value)); + } + + private static void assertNotContains(String base, String value) { + assertFalse(base + " is not expected to contain " + value, base.contains(value)); + } + + private void checkAttributeForRule(RuleDocumentation rule, RuleDocumentationAttribute attr, + boolean isCommonAttribute) { + rule.addAttribute(attr); + String signature = rule.getAttributeSignature(); + StringBuilder sb = new StringBuilder(); + if (isCommonAttribute) { + sb.append("<a href=\"common-definitions.html#"); + } else { + sb.append("<a href=\"#"); + } + sb.append(attr.getGeneratedInRule(rule.getRuleName())).append("."); + sb.append(attr.getAttributeName()).append("\">").append(attr.getAttributeName()).append("</a>"); + assertContains(signature, sb.toString()); + } + + @Test + public void testVariableSubstitution() throws BuildEncyclopediaDocException { + RuleDocumentation ruleDoc = new RuleDocumentation( + "rule", "OTHER", "FOO", Joiner.on("\n").join(new String[] { + "x", + "${VAR}", + "z"}), + 0, "", ImmutableSet.<String>of(), provider); + ruleDoc.addDocVariable("VAR", "y"); + assertEquals("x\ny\nz", ruleDoc.getHtmlDocumentation()); + } + + @Test + public void testVariablesAreHidden() throws BuildEncyclopediaDocException { + RuleDocumentation ruleDoc = new RuleDocumentation( + "foo_binary", "OTHER", "FOO", Joiner.on("\n").join(new String[] { + "x", + "${ATTRIBUTE_SIGNATURE}", + "y", + "${ATTRIBUTE_DEFINITION}", + "z"}), + 0, "", ImmutableSet.<String>of(), provider); + RuleDocumentationAttribute attributeDoc = RuleDocumentationAttribute.create(TestRule.class, + "srcs", "attribute doc", 0, NO_FLAGS); + ruleDoc.addAttribute(attributeDoc); + String htmlDoc = ruleDoc.getHtmlDocumentation(); + assertContains(htmlDoc, "x\n"); + assertContains(htmlDoc, "y\n"); + assertContains(htmlDoc, "z"); + assertNotContains(htmlDoc, "${ATTRIBUTE_SIGNATURE}"); + assertNotContains(htmlDoc, "${ATTRIBUTE_DEFINITION}"); + } + + @Test + public void testSignatureContainsCommonAttribute() throws Exception { + RuleDocumentationAttribute licensesAttr = RuleDocumentationAttribute.create( + "licenses", "common", "attribute doc"); + checkAttributeForRule(new RuleDocumentation( + "java_binary", "BINARY", "JAVA", Joiner.on("\n").join(new String[] { + "${ATTRIBUTE_SIGNATURE}", + "${ATTRIBUTE_DEFINITION}"}), + 0, "", ImmutableSet.<String>of(), provider), licensesAttr, true); + } + + @Test + public void testInheritedAttributeGeneratesSignature() throws Exception { + RuleDocumentationAttribute runtimeDepsAttr = RuleDocumentationAttribute.create(TestRule.class, + "runtime_deps", "attribute doc", 0, NO_FLAGS); + checkAttributeForRule(new RuleDocumentation( + "java_binary", "BINARY", "JAVA", Joiner.on("\n").join(new String[] { + "${ATTRIBUTE_SIGNATURE}", + "${ATTRIBUTE_DEFINITION}"}), + 0, "", ImmutableSet.<String>of(), provider), runtimeDepsAttr, false); + checkAttributeForRule(new RuleDocumentation( + "java_library", "LIBRARY", "JAVA", Joiner.on("\n").join(new String[] { + "${ATTRIBUTE_SIGNATURE}", + "${ATTRIBUTE_DEFINITION}"}), + 0, "", ImmutableSet.<String>of(), provider), runtimeDepsAttr, false); + } + + @Test + public void testRuleDocFlagSubstitution() throws BuildEncyclopediaDocException { + RuleDocumentation ruleDoc = new RuleDocumentation( + "rule", "OTHER", "FOO", "x", 0, "", ImmutableSet.<String>of("DEPRECATED"), provider); + ruleDoc.addDocVariable("VAR", "y"); + assertEquals("x", ruleDoc.getHtmlDocumentation()); + } + + @Test + public void testCommandLineDocumentation() throws BuildEncyclopediaDocException { + RuleDocumentation ruleDoc = new RuleDocumentation( + "foo_binary", "OTHER", "FOO", Joiner.on("\n").join(new String[] { + "x", + "${ATTRIBUTE_SIGNATURE}", + "y", + "${ATTRIBUTE_DEFINITION}", + "z", + "${VAR}"}), + 0, "", ImmutableSet.<String>of(), provider); + ruleDoc.addDocVariable("VAR", "w"); + RuleDocumentationAttribute attributeDoc = RuleDocumentationAttribute.create(TestRule.class, + "srcs", "attribute doc", 0, NO_FLAGS); + ruleDoc.addAttribute(attributeDoc); + assertEquals("\nx\n\ny\n\nz\n\n", ruleDoc.getCommandLineDocumentation()); + } + + @Test + public void testExtractExamples() throws BuildEncyclopediaDocException { + RuleDocumentation ruleDoc = new RuleDocumentation( + "rule", "OTHER", "FOO", Joiner.on("\n").join(new String[] { + "x", + "<!-- #BLAZE_RULE.EXAMPLE -->", + "a", + "<!-- #BLAZE_RULE.END_EXAMPLE -->", + "y", + "<!-- #BLAZE_RULE.EXAMPLE -->", + "b", + "<!-- #BLAZE_RULE.END_EXAMPLE -->", + "z"}), + 0, "", ImmutableSet.<String>of(), provider); + assertEquals(ImmutableSet.<String>of("a\n", "b\n"), ruleDoc.extractExamples()); + } + + @Test + public void testCreateExceptions() throws BuildEncyclopediaDocException { + RuleDocumentation ruleDoc = new RuleDocumentation( + "foo_binary", "OTHER", "FOO", "", 10, "foo.txt", NO_FLAGS, provider); + BuildEncyclopediaDocException e = ruleDoc.createException("msg"); + assertEquals("Error in foo.txt:10: msg", e.getMessage()); + } + + @Test + public void testEquals() throws BuildEncyclopediaDocException { + assertEquals( + new RuleDocumentation("rule", "OTHER", "FOO", "x", 0, "", NO_FLAGS, provider), + new RuleDocumentation("rule", "OTHER", "FOO", "y", 0, "", NO_FLAGS, provider)); + } + + @Test + public void testNotEquals() throws BuildEncyclopediaDocException { + assertFalse( + new RuleDocumentation("rule1", "OTHER", "FOO", "x", 0, "", NO_FLAGS, provider).equals( + new RuleDocumentation("rule2", "OTHER", "FOO", "y", 0, "", NO_FLAGS, provider))); + } + + @Test + public void testCompareTo() throws BuildEncyclopediaDocException { + assertEquals(-1, + new RuleDocumentation("rule1", "OTHER", "FOO", "x", 0, "", NO_FLAGS, provider).compareTo( + new RuleDocumentation("rule2", "OTHER", "FOO", "x", 0, "", NO_FLAGS, provider))); + } + + @Test + public void testHashCode() throws BuildEncyclopediaDocException { + assertEquals( + new RuleDocumentation("rule", "OTHER", "FOO", "x", 0, "", NO_FLAGS, provider).hashCode(), + new RuleDocumentation("rule", "OTHER", "FOO", "y", 0, "", NO_FLAGS, provider).hashCode()); + } +} diff --git a/src/test/java/com/google/devtools/build/docgen/SkylarkDocumentationTest.java b/src/test/java/com/google/devtools/build/docgen/SkylarkDocumentationTest.java new file mode 100644 index 0000000000..04a3376865 --- /dev/null +++ b/src/test/java/com/google/devtools/build/docgen/SkylarkDocumentationTest.java @@ -0,0 +1,173 @@ +// Copyright 2015 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. +package com.google.devtools.build.docgen; + +import static com.google.common.truth.Truth.assertThat; +import static com.google.common.truth.Truth.assertWithMessage; + +import com.google.common.base.Function; +import com.google.common.collect.Iterables; +import com.google.devtools.build.docgen.skylark.SkylarkBuiltinMethodDoc; +import com.google.devtools.build.docgen.skylark.SkylarkJavaMethodDoc; +import com.google.devtools.build.docgen.skylark.SkylarkModuleDoc; +import com.google.devtools.build.lib.rules.SkylarkRuleContext; +import com.google.devtools.build.lib.skylark.util.SkylarkTestCase; +import com.google.devtools.build.lib.skylarkinterface.SkylarkCallable; +import com.google.devtools.build.lib.skylarkinterface.SkylarkModule; +import com.google.devtools.build.lib.syntax.Environment; +import com.google.devtools.build.lib.syntax.util.EvaluationTestCase; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + +/** + * Tests for Skylark documentation. + */ +@RunWith(JUnit4.class) +public class SkylarkDocumentationTest extends SkylarkTestCase { + + @Before + public final void createBuildFile() throws Exception { + scratch.file("foo/BUILD", + "genrule(name = 'foo',", + " cmd = 'dummy_cmd',", + " srcs = ['a.txt', 'b.img'],", + " tools = ['t.exe'],", + " outs = ['c.txt'])"); + } + + @Override + protected EvaluationTestCase createEvaluationTestCase() { + return new EvaluationTestCase(); + } + + @Test + public void testSkylarkRuleClassBuiltInItemsAreDocumented() throws Exception { + checkSkylarkTopLevelEnvItemsAreDocumented(ev.getEnvironment()); + } + + @Test + public void testSkylarkRuleImplementationBuiltInItemsAreDocumented() throws Exception { + // TODO(bazel-team): fix documentation for built in java objects coming from modules. + checkSkylarkTopLevelEnvItemsAreDocumented(ev.getEnvironment()); + } + + @SuppressWarnings("unchecked") + private void checkSkylarkTopLevelEnvItemsAreDocumented(Environment env) { + Map<String, String> docMap = new HashMap<>(); + Map<String, SkylarkModuleDoc> modules = SkylarkDocumentationCollector.collectModules(); + SkylarkModuleDoc topLevel = + modules.remove(SkylarkDocumentationCollector.getTopLevelModule().name()); + for (Entry<String, SkylarkBuiltinMethodDoc> entry : topLevel.getBuiltinMethods().entrySet()) { + docMap.put(entry.getKey(), entry.getValue().getDocumentation()); + } + for (Entry<String, SkylarkModuleDoc> entry : modules.entrySet()) { + docMap.put(entry.getKey(), entry.getValue().getDocumentation()); + } + + List<String> undocumentedItems = new ArrayList<>(); + // All built in variables are registered in the Skylark global environment. + for (String varname : env.getVariableNames()) { + if (docMap.containsKey(varname)) { + if (docMap.get(varname).isEmpty()) { + undocumentedItems.add(varname); + } + } else { + undocumentedItems.add(varname); + } + } + assertWithMessage("Undocumented Skylark Environment items: " + undocumentedItems) + .that(undocumentedItems).isEmpty(); + } + + // TODO(bazel-team): come up with better Skylark specific tests. + @Test + public void testDirectJavaMethodsAreGenerated() throws Exception { + assertThat(collect(SkylarkRuleContext.class)).isNotEmpty(); + } + + @SkylarkModule(name = "MockClassA", doc = "") + public static class MockClassA { + @SkylarkCallable(doc = "") + public Integer get() { + return 0; + } + } + + @SkylarkModule(name = "MockClassB", doc = "") + public static class MockClassB { + @SkylarkCallable(doc = "") + public MockClassA get() { + return new MockClassA(); + } + } + + @SkylarkModule(name = "MockClassC", doc = "") + public static class MockClassC extends MockClassA { + @SkylarkCallable(doc = "") + public Integer get2() { + return 0; + } + } + + @Test + public void testSkylarkJavaInterfaceExplorerOnSimpleClass() throws Exception { + Map<String, SkylarkModuleDoc> objects = collect(MockClassA.class); + assertThat(extractMethods(Iterables.getOnlyElement(objects.values()) + .getJavaMethods())).containsExactly(MockClassA.class.getMethod("get")); + } + + @Test + public void testSkylarkJavaInterfaceExplorerFindsClassFromReturnValue() throws Exception { + Map<String, SkylarkModuleDoc> objects = collect(MockClassB.class); + assertThat(extractMethods( + objects.get("MockClassA").getJavaMethods())).containsExactly( + MockClassA.class.getMethod("get")); + } + + @Test + public void testSkylarkJavaInterfaceExplorerFindsAllMethodsOnSubClass() throws Exception { + Map<String, SkylarkModuleDoc> objects = collect(MockClassC.class); + assertThat(extractMethods(Iterables.getOnlyElement(objects.values()) + .getJavaMethods())).containsExactly( + MockClassA.class.getMethod("get"), MockClassC.class.getMethod("get2")); + } + + private Iterable<Method> extractMethods(Collection<SkylarkJavaMethodDoc> methods) { + return Iterables.transform(methods, new Function<SkylarkJavaMethodDoc, Method>() { + @Override + public Method apply(SkylarkJavaMethodDoc input) { + return input.getMethod(); + } + }); + } + + private Map<String, SkylarkModuleDoc> collect(Class<?> classObject) { + Map<String, SkylarkModuleDoc> modules = new TreeMap<>(); + SkylarkDocumentationCollector.collectJavaObjects( + classObject.getAnnotation(SkylarkModule.class), classObject, modules); + return modules; + } +} diff --git a/src/test/java/com/google/devtools/build/docgen/testutil/TestData.java b/src/test/java/com/google/devtools/build/docgen/testutil/TestData.java new file mode 100644 index 0000000000..34d7d17007 --- /dev/null +++ b/src/test/java/com/google/devtools/build/docgen/testutil/TestData.java @@ -0,0 +1,78 @@ +// Copyright 2015 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. +package com.google.devtools.build.docgen.testutil; + +import static com.google.devtools.build.lib.packages.Attribute.attr; +import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST; + +import com.google.devtools.build.lib.analysis.ConfiguredTarget; +import com.google.devtools.build.lib.analysis.RuleContext; +import com.google.devtools.build.lib.analysis.RuleDefinition; +import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; +import com.google.devtools.build.lib.packages.RuleClass; +import com.google.devtools.build.lib.rules.RuleConfiguredTargetFactory; + +/** + * Rule definitions that can be used for testing. + */ +public class TestData { + public static class TestRule implements RuleDefinition { + @Override + public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) { + return builder + .add(attr("foo", LABEL_LIST)) + .build(); + } + + @Override + public Metadata getMetadata() { + return RuleDefinition.Metadata.builder().name("testrule") + .factoryClass(DummyRuleFactory.class).ancestors(IntermediateRule.class).build(); + } + } + + public static class IntermediateRule implements RuleDefinition { + @Override + public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) { + return builder.build(); + } + + @Override + public Metadata getMetadata() { + return RuleDefinition.Metadata.builder().name("testrule") + .factoryClass(DummyRuleFactory.class).ancestors(BaseRule.class).build(); + } + } + + public static class BaseRule implements RuleDefinition { + @Override + public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment environment) { + return builder.build(); + } + + @Override + public Metadata getMetadata() { + return RuleDefinition.Metadata.builder().name("base_rule") + .factoryClass(DummyRuleFactory.class).build(); + } + } + + public static class DummyRuleFactory implements RuleConfiguredTargetFactory { + @Override + public ConfiguredTarget create(RuleContext ruleContext) { + throw new IllegalStateException(); + } + } +} + diff --git a/src/test/java/com/google/devtools/build/lib/BUILD b/src/test/java/com/google/devtools/build/lib/BUILD index d3bae459dd..24ceae3592 100644 --- a/src/test/java/com/google/devtools/build/lib/BUILD +++ b/src/test/java/com/google/devtools/build/lib/BUILD @@ -792,6 +792,7 @@ java_library( srcs = glob([ "syntax/util/*.java", ]), + visibility = ["//visibility:public"], deps = [ ":foundations_testutil", ":test_runner", @@ -818,6 +819,7 @@ java_library( srcs = glob([ "skylark/util/*.java", ]), + visibility = ["//visibility:public"], deps = [ ":analysis_testutil", ":foundations_testutil", diff --git a/src/test/java/com/google/devtools/build/lib/testutil/TestConstants.java b/src/test/java/com/google/devtools/build/lib/testutil/TestConstants.java index 9278dd3454..701487fa18 100644 --- a/src/test/java/com/google/devtools/build/lib/testutil/TestConstants.java +++ b/src/test/java/com/google/devtools/build/lib/testutil/TestConstants.java @@ -72,4 +72,7 @@ public class TestConstants { public static final String TOOLS_REPOSITORY = "@bazel_tools"; public static final String TOOLS_REPOSITORY_PATH = "tools/cpp"; + + public static final ImmutableList<String> DOCS_RULES_PATHS = ImmutableList.of( + "src/main/java/com/google/devtools/build/lib/rules"); } |