diff options
author | David Chen <dzc@google.com> | 2016-02-24 22:17:42 +0000 |
---|---|---|
committer | Philipp Wollermann <philwo@google.com> | 2016-02-25 14:13:22 +0000 |
commit | ac13e22630ef3bd6cc67cda14633f976b5ffc044 (patch) | |
tree | 70d0ff60ab00b93128ec73fdcf495c72b6898115 /src | |
parent | 6e30521e0d230ba8138cb8bbe3bf3f4fb4fbfa60 (diff) |
Add syntax for referencing docs in other rule families.
This CL implements a new `${link rule.attribute}` syntax which can be used to
reference the documentation of rules and attributes of other rule families. For
example, `${link cc_library.deps}` will generate a link to the documentation for
the `deps` attribute of the `cc_library` rule. Similarly, this syntax can also
be used to reference sections of static documentation, for example
`${link common-definitions.label-expansion}`.
--
MOS_MIGRATED_REVID=115492361
Diffstat (limited to 'src')
10 files changed, 299 insertions, 50 deletions
diff --git a/src/main/java/com/google/devtools/build/docgen/BuildDocCollector.java b/src/main/java/com/google/devtools/build/docgen/BuildDocCollector.java index 72de708448..7bb4f71993 100644 --- a/src/main/java/com/google/devtools/build/docgen/BuildDocCollector.java +++ b/src/main/java/com/google/devtools/build/docgen/BuildDocCollector.java @@ -122,10 +122,25 @@ public class BuildDocCollector { } processAttributeDocs(ruleDocEntries.values(), attributeDocEntries); + RuleLinkExpander expander = buildRuleLinkExpander(ruleDocEntries.values()); + for (RuleDocumentation rule : ruleDocEntries.values()) { + rule.setRuleLinkExpander(expander); + } return ruleDocEntries; } /** + * Generates an index mapping rule name to its normalized rule family name. + */ + private RuleLinkExpander buildRuleLinkExpander(Iterable<RuleDocumentation> rules) { + Map<String, String> index = new HashMap<>(); + for (RuleDocumentation rule : rules) { + index.put(rule.getRuleName(), RuleFamily.normalize(rule.getRuleFamily())); + } + return new RuleLinkExpander(index); + } + + /** * Go through all attributes of all documented rules and search the best attribute documentation * if exists. The best documentation is the closest documentation in the ancestor graph. E.g. if * java_library.deps documented in $rule and $java_rule then the one in $java_rule is going to diff --git a/src/main/java/com/google/devtools/build/docgen/DocgenConsts.java b/src/main/java/com/google/devtools/build/docgen/DocgenConsts.java index c0e2639b8d..d50a29971b 100644 --- a/src/main/java/com/google/devtools/build/docgen/DocgenConsts.java +++ b/src/main/java/com/google/devtools/build/docgen/DocgenConsts.java @@ -93,6 +93,16 @@ public class DocgenConsts { } /** + * Reference to another rule or Build Encyclopedia section. + * + * <p>The format of a link reference is rule.attribute (e.g. cc_library.deps). In the case of + * static pages such as common definitions the format is page.heading + * (e.g. common-definitions.label-expansion). + */ + public static final Pattern BLAZE_RULE_LINK = Pattern.compile( + "\\$\\{link (([a-z_-]+)(\\.([a-z_-]+))?)\\}"); + + /** * i.e. <!-- #BLAZE_RULE(NAME = RULE_NAME, TYPE = RULE_TYPE, FAMILY = RULE_FAMILY) --> * i.e. <!-- #BLAZE_RULE(...)[DEPRECATED] --> */ diff --git a/src/main/java/com/google/devtools/build/docgen/RuleDocumentation.java b/src/main/java/com/google/devtools/build/docgen/RuleDocumentation.java index 6da7f41262..2fec7c495a 100644 --- a/src/main/java/com/google/devtools/build/docgen/RuleDocumentation.java +++ b/src/main/java/com/google/devtools/build/docgen/RuleDocumentation.java @@ -57,28 +57,29 @@ public class RuleDocumentation implements Comparable<RuleDocumentation> { private final Set<RuleDocumentationAttribute> attributes = new TreeSet<>(); private final ConfiguredRuleClassProvider ruleClassProvider; + private RuleLinkExpander linkExpander; + /** * Creates a RuleDocumentation from the rule's name, type, family and raw html documentation * (meaning without expanding the variables in the doc). */ RuleDocumentation(String ruleName, String ruleType, String ruleFamily, String htmlDocumentation, int startLineCount, String fileName, ImmutableSet<String> flags, - ConfiguredRuleClassProvider ruleClassProvider) - throws BuildEncyclopediaDocException { + ConfiguredRuleClassProvider ruleClassProvider) throws BuildEncyclopediaDocException { Preconditions.checkNotNull(ruleName); - this.ruleName = ruleName; - try { - this.ruleType = RuleType.valueOf(ruleType); - } catch (IllegalArgumentException e) { - throw new BuildEncyclopediaDocException( - fileName, startLineCount, "Invalid rule type " + ruleType); - } - this.ruleFamily = ruleFamily; - this.htmlDocumentation = htmlDocumentation; - this.startLineCount = startLineCount; - this.fileName = fileName; - this.flags = flags; - this.ruleClassProvider = ruleClassProvider; + this.ruleName = ruleName; + try { + this.ruleType = RuleType.valueOf(ruleType); + } catch (IllegalArgumentException e) { + throw new BuildEncyclopediaDocException( + fileName, startLineCount, "Invalid rule type " + ruleType); + } + this.ruleFamily = ruleFamily; + this.htmlDocumentation = htmlDocumentation; + this.startLineCount = startLineCount; + this.fileName = fileName; + this.flags = flags; + this.ruleClassProvider = ruleClassProvider; } /** @@ -165,16 +166,35 @@ public class RuleDocumentation implements Comparable<RuleDocumentation> { } /** + * Sets the {@link RuleLinkExpander} to be used to expand links in the HTML documentation for + * both this RuleDocumentation and all {@link RuleDocumentationAttribute}s associated with this + * rule. + */ + public void setRuleLinkExpander(RuleLinkExpander linkExpander) { + this.linkExpander = linkExpander; + for (RuleDocumentationAttribute attribute : attributes) { + attribute.setRuleLinkExpander(linkExpander); + } + } + + /** * Returns the html documentation in the exact format it should be written into the Build * Encyclopedia (expanding variables). */ - public String getHtmlDocumentation() { + public String getHtmlDocumentation() throws BuildEncyclopediaDocException { String expandedDoc = htmlDocumentation; // Substituting variables for (Entry<String, String> docVariable : docVariables.entrySet()) { expandedDoc = expandedDoc.replace("${" + docVariable.getKey() + "}", expandBuiltInVariables(docVariable.getKey(), docVariable.getValue())); } + if (linkExpander != null) { + try { + expandedDoc = linkExpander.expand(expandedDoc); + } catch (IllegalArgumentException e) { + throw new BuildEncyclopediaDocException(fileName, startLineCount, e.getMessage()); + } + } return expandedDoc; } diff --git a/src/main/java/com/google/devtools/build/docgen/RuleDocumentationAttribute.java b/src/main/java/com/google/devtools/build/docgen/RuleDocumentationAttribute.java index 518a2c45c5..b1b60fb1bd 100644 --- a/src/main/java/com/google/devtools/build/docgen/RuleDocumentationAttribute.java +++ b/src/main/java/com/google/devtools/build/docgen/RuleDocumentationAttribute.java @@ -60,7 +60,10 @@ public class RuleDocumentationAttribute implements Comparable<RuleDocumentationA private final String attributeName; private final String htmlDocumentation; private final String commonType; + // Used to expand rule link references in the attribute documentation. + private RuleLinkExpander linkExpander; private int startLineCnt; + private String fileName; private Set<String> flags; private Attribute attribute; @@ -71,7 +74,7 @@ public class RuleDocumentationAttribute implements Comparable<RuleDocumentationA static RuleDocumentationAttribute create( String attributeName, String commonType, String htmlDocumentation) { RuleDocumentationAttribute docAttribute = new RuleDocumentationAttribute( - null, attributeName, htmlDocumentation, 0, ImmutableSet.<String>of(), commonType); + null, attributeName, htmlDocumentation, 0, "", ImmutableSet.<String>of(), commonType); return docAttribute; } @@ -80,14 +83,15 @@ public class RuleDocumentationAttribute implements Comparable<RuleDocumentationA * defined rule attributes. */ static RuleDocumentationAttribute create(Class<? extends RuleDefinition> definitionClass, - String attributeName, String htmlDocumentation, int startLineCnt, Set<String> flags) { + String attributeName, String htmlDocumentation, int startLineCnt, String fileName, + Set<String> flags) { return new RuleDocumentationAttribute(definitionClass, attributeName, htmlDocumentation, - startLineCnt, flags, null); + startLineCnt, fileName, flags, null); } private RuleDocumentationAttribute(Class<? extends RuleDefinition> definitionClass, - String attributeName, String htmlDocumentation, int startLineCnt, Set<String> flags, - String commonType) { + String attributeName, String htmlDocumentation, int startLineCnt, String fileName, + Set<String> flags, String commonType) { Preconditions.checkNotNull(attributeName, "AttributeName must not be null."); this.definitionClass = definitionClass; this.attributeName = attributeName; @@ -119,10 +123,25 @@ public class RuleDocumentationAttribute implements Comparable<RuleDocumentationA } /** - * Returns the raw html documentation of the rule attribute. + * Sets the {@link RuleLinkExpander} to be used to expand links in the HTML documentation. */ - public String getHtmlDocumentation() { - return htmlDocumentation; + public void setRuleLinkExpander(RuleLinkExpander linkExpander) { + this.linkExpander = linkExpander; + } + + /** + * Returns the html documentation of the rule attribute. + */ + public String getHtmlDocumentation() throws BuildEncyclopediaDocException { + String expandedHtmlDoc = htmlDocumentation; + if (linkExpander != null) { + try { + expandedHtmlDoc = linkExpander.expand(expandedHtmlDoc); + } catch (IllegalArgumentException e) { + throw new BuildEncyclopediaDocException(fileName, startLineCnt, e.getMessage()); + } + } + return expandedHtmlDoc; } private String getDefaultValue() { diff --git a/src/main/java/com/google/devtools/build/docgen/RuleLinkExpander.java b/src/main/java/com/google/devtools/build/docgen/RuleLinkExpander.java new file mode 100644 index 0000000000..8ac8cbc795 --- /dev/null +++ b/src/main/java/com/google/devtools/build/docgen/RuleLinkExpander.java @@ -0,0 +1,106 @@ +// Copyright 2014 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.common.collect.ImmutableSet; + +import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; + +/** + * Helper class used for expanding link references in rule and attribute documentation. + * + * <p>See {@link com.google.devtools.build.docgen.DocgenConsts.BLAZE_RULE_LINK} for the regex used + * to match link references. + */ +class RuleLinkExpander { + private static final String EXAMPLES_SUFFIX = "_examples"; + private static final String ARGS_SUFFIX = "_args"; + + private static final Set<String> STATIC_PAGES = ImmutableSet.<String>of( + "common-definitions", + "make-variables", + "predefined-python-variables"); + + private final Map<String, String> ruleIndex; + + RuleLinkExpander(Map<String, String> ruleIndex) { + this.ruleIndex = ruleIndex; + } + + private void appendRuleLink(Matcher matcher, StringBuffer sb, String ruleName, String ref) { + String ruleFamily = ruleIndex.get(ruleName); + String link = ruleFamily + ".html#" + ref; + matcher.appendReplacement(sb, Matcher.quoteReplacement(link)); + } + + /** + * Expands all rule references in the input HTML documentation. + * + * @param htmlDoc The input HTML documentation with ${link foo.bar} references. + * @return The HTML documentation with all link references expanded. + */ + public String expand(String htmlDoc) throws IllegalArgumentException { + Matcher matcher = DocgenConsts.BLAZE_RULE_LINK.matcher(htmlDoc); + StringBuffer sb = new StringBuffer(htmlDoc.length()); + while (matcher.find()) { + // The first capture group matches the entire reference, e.g. "cc_binary.deps". + String ref = matcher.group(1); + // The second capture group only matches the rule name, e.g. "cc_binary" in "cc_binary.deps". + String name = matcher.group(2); + + // The name in the reference is the name of a rule. Get the rule family for the rule and + // replace the reference with a link with the form of rule-family.html#rule.attribute. For + // example, ${link cc_library.deps} expands to c-cpp.html#cc_library.deps. + if (ruleIndex.containsKey(name)) { + appendRuleLink(matcher, sb, name, ref); + continue; + } + + // The name is referencing the examples or arguments of a rule (e.g. "cc_library_args" or + // "cc_library_examples"). Strip the suffix and then try matching the name to a rule family. + if (name.endsWith(EXAMPLES_SUFFIX) || name.endsWith(ARGS_SUFFIX)) { + String ruleName = name.substring( + 0, name.indexOf(name.endsWith(EXAMPLES_SUFFIX) ? EXAMPLES_SUFFIX : ARGS_SUFFIX)); + if (ruleIndex.containsKey(ruleName)) { + appendRuleLink(matcher, sb, ruleName, ref); + continue; + } + } + + // The name is not the name of a rule but is the name of a static page, such as + // common-definitions. Generate a link to that page, and append the page heading if + // specified. For example, ${link common-definitions.label-expansion} expands to + // common-definitions.html#label-expansion. + if (STATIC_PAGES.contains(name)) { + String link = name + ".html"; + // The fourth capture group matches the attribute name, or page heading, e.g. + // "label-expansion" in "common-definitions.label-expansion". + String pageHeading = matcher.group(4); + if (pageHeading != null) { + link = link + "#" + pageHeading; + } + matcher.appendReplacement(sb, Matcher.quoteReplacement(link)); + continue; + } + + // If the reference does not match any rule or static page, throw an exception. + throw new IllegalArgumentException( + "link tag does not match any rule or BE page: " + matcher.group()); + } + matcher.appendTail(sb); + return sb.toString(); + } +} diff --git a/src/main/java/com/google/devtools/build/docgen/SourceFileReader.java b/src/main/java/com/google/devtools/build/docgen/SourceFileReader.java index 651b46efc8..78f0b6dae0 100644 --- a/src/main/java/com/google/devtools/build/docgen/SourceFileReader.java +++ b/src/main/java/com/google/devtools/build/docgen/SourceFileReader.java @@ -214,7 +214,7 @@ public class SourceFileReader { // End of a attribute, create RuleDocumentationAttribute object docAttributes.put(attributeName, RuleDocumentationAttribute.create( ruleClassProvider.getRuleClassDefinition(ruleName), - attributeName, sb.toString(), startLineCnt, flags)); + attributeName, sb.toString(), startLineCnt, javaSourceFilePath, flags)); sb = new StringBuilder(); inBlazeAttributeDocs = false; } diff --git a/src/test/java/com/google/devtools/build/docgen/BUILD b/src/test/java/com/google/devtools/build/docgen/BUILD index 81c2fa612b..7d04dec7ea 100644 --- a/src/test/java/com/google/devtools/build/docgen/BUILD +++ b/src/test/java/com/google/devtools/build/docgen/BUILD @@ -29,6 +29,7 @@ java_library( "DocCheckerUtilsTest.java", "RuleDocumentationAttributeTest.java", "RuleDocumentationTest.java", + "RuleLinkExpanderTest.java", "SkylarkDocumentationTest.java", ], deps = [ diff --git a/src/test/java/com/google/devtools/build/docgen/RuleDocumentationAttributeTest.java b/src/test/java/com/google/devtools/build/docgen/RuleDocumentationAttributeTest.java index 89bb1bbf15..03b270c4fc 100644 --- a/src/test/java/com/google/devtools/build/docgen/RuleDocumentationAttributeTest.java +++ b/src/test/java/com/google/devtools/build/docgen/RuleDocumentationAttributeTest.java @@ -39,69 +39,67 @@ public class RuleDocumentationAttributeTest { @Test public void testDirectChild() { RuleDocumentationAttribute attr1 = RuleDocumentationAttribute.create( - IntermediateRule.class, "", "", 0, NO_FLAGS); + IntermediateRule.class, "", "", 0, "", NO_FLAGS); assertEquals(1, attr1.getDefinitionClassAncestryLevel(TestRule.class)); } @Test public void testTransitiveChild() { RuleDocumentationAttribute attr2 = RuleDocumentationAttribute.create( - BaseRule.class, "", "", 0, NO_FLAGS); + BaseRule.class, "", "", 0, "", NO_FLAGS); assertEquals(2, attr2.getDefinitionClassAncestryLevel(TestRule.class)); } @Test public void testClassIsNotChild() { RuleDocumentationAttribute attr2 = RuleDocumentationAttribute.create( - IntermediateRule.class, "", "", 0, NO_FLAGS); + IntermediateRule.class, "", "", 0, "", NO_FLAGS); assertEquals(-1, attr2.getDefinitionClassAncestryLevel(BaseRule.class)); } @Test public void testClassIsSame() { RuleDocumentationAttribute attr3 = RuleDocumentationAttribute.create( - TestRule.class, "", "", 0, NO_FLAGS); + 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")); + 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); + assertEquals( + -1, + RuleDocumentationAttribute.create(TestRule.class, "a", "", 0, "", NO_FLAGS).compareTo( + RuleDocumentationAttribute.create(TestRule.class, "b", "", 0, "", NO_FLAGS))); } @Test public void testCompareToWithPriorityAttributeName() { - assertTrue( - RuleDocumentationAttribute.create(TestRule.class, "a", "", 0, NO_FLAGS) - .compareTo( - RuleDocumentationAttribute.create(TestRule.class, "name", "", 0, NO_FLAGS)) - == 1); + assertEquals( + 1, + RuleDocumentationAttribute.create(TestRule.class, "a", "", 0, "", NO_FLAGS).compareTo( + RuleDocumentationAttribute.create(TestRule.class, "name", "", 0, "", NO_FLAGS))); } @Test public void testEquals() { assertEquals( - RuleDocumentationAttribute.create(TestRule.class, "a", "", 0, NO_FLAGS), - RuleDocumentationAttribute.create(IntermediateRule.class, "a", "", 0, NO_FLAGS)); + 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) + RuleDocumentationAttribute.create(TestRule.class, "a", "", 0, "", NO_FLAGS) .hashCode(), - RuleDocumentationAttribute.create(IntermediateRule.class, "a", "", 0, NO_FLAGS) + RuleDocumentationAttribute.create(IntermediateRule.class, "a", "", 0, "", NO_FLAGS) .hashCode()); } @@ -111,7 +109,7 @@ public class RuleDocumentationAttributeTest { Attribute attribute = Attribute.attr("foo_version", Type.STRING) .value(defaultValue).build(); RuleDocumentationAttribute attributeDoc = RuleDocumentationAttribute.create( - TestRule.class, "testrule", "", 0, NO_FLAGS); + TestRule.class, "testrule", "", 0, "", NO_FLAGS); attributeDoc.setAttribute(attribute); String doc = attributeDoc.getSynopsis(); assertEquals("String; optional; default is \"" + defaultValue + "\"", doc); @@ -123,7 +121,7 @@ public class RuleDocumentationAttributeTest { Attribute attribute = Attribute.attr("bar_limit", Type.INTEGER) .value(defaultValue).build(); RuleDocumentationAttribute attributeDoc = RuleDocumentationAttribute.create( - TestRule.class, "testrule", "", 0, NO_FLAGS); + TestRule.class, "testrule", "", 0, "", NO_FLAGS); attributeDoc.setAttribute(attribute); String doc = attributeDoc.getSynopsis(); assertEquals("Integer; optional; default is " + defaultValue, doc); @@ -136,7 +134,7 @@ public class RuleDocumentationAttributeTest { .allowedFileTypes() .build(); RuleDocumentationAttribute attributeDoc = RuleDocumentationAttribute.create( - TestRule.class, "testrule", "", 0, NO_FLAGS); + TestRule.class, "testrule", "", 0, "", NO_FLAGS); attributeDoc.setAttribute(attribute); String doc = attributeDoc.getSynopsis(); assertEquals("List of <a href=\"../build-ref.html#labels\">labels</a>; optional", doc); @@ -149,7 +147,7 @@ public class RuleDocumentationAttributeTest { .allowedFileTypes(CppFileTypes.CPP_HEADER) .build(); RuleDocumentationAttribute attributeDoc = RuleDocumentationAttribute.create( - TestRule.class, "testrule", "", 0, NO_FLAGS); + TestRule.class, "testrule", "", 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 index d77c9eaabc..d7c6f6c4bc 100644 --- a/src/test/java/com/google/devtools/build/docgen/RuleDocumentationTest.java +++ b/src/test/java/com/google/devtools/build/docgen/RuleDocumentationTest.java @@ -81,7 +81,7 @@ public class RuleDocumentationTest { @Test public void testInheritedAttributeGeneratesSignature() throws Exception { RuleDocumentationAttribute runtimeDepsAttr = RuleDocumentationAttribute.create(TestRule.class, - "runtime_deps", "attribute doc", 0, NO_FLAGS); + "runtime_deps", "attribute doc", 0, "", NO_FLAGS); checkAttributeForRule( new RuleDocumentation( "java_binary", "BINARY", "JAVA", "", 0, "", ImmutableSet.<String>of(), provider), @@ -111,7 +111,7 @@ public class RuleDocumentationTest { 0, "", ImmutableSet.<String>of(), provider); ruleDoc.addDocVariable("VAR", "w"); RuleDocumentationAttribute attributeDoc = RuleDocumentationAttribute.create(TestRule.class, - "srcs", "attribute doc", 0, NO_FLAGS); + "srcs", "attribute doc", 0, "", NO_FLAGS); ruleDoc.addAttribute(attributeDoc); assertEquals("\nx\ny\nz\n\n", ruleDoc.getCommandLineDocumentation()); } diff --git a/src/test/java/com/google/devtools/build/docgen/RuleLinkExpanderTest.java b/src/test/java/com/google/devtools/build/docgen/RuleLinkExpanderTest.java new file mode 100644 index 0000000000..2694b0e464 --- /dev/null +++ b/src/test/java/com/google/devtools/build/docgen/RuleLinkExpanderTest.java @@ -0,0 +1,80 @@ +// 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 com.google.common.collect.ImmutableMap; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link RuleLinkExpander}. */ +@RunWith(JUnit4.class) +public class RuleLinkExpanderTest { + private RuleLinkExpander expander; + + @Before public void setUp() { + expander = new RuleLinkExpander(ImmutableMap.<String, String>builder() + .put("cc_library", "c-cpp") + .put("cc_binary", "c-cpp") + .put("java_binary", "java") + .put("proto_library", "protocol-buffer") + .build()); + } + + @Test public void testRule() { + String docs = "<a href=\"${link java_binary}\">java_binary rule</a>"; + String expected = "<a href=\"java.html#java_binary\">java_binary rule</a>"; + assertEquals(expected, expander.expand(docs)); + } + + @Test public void testRuleAndAttribute() { + String docs = "<a href=\"${link java_binary.runtime_deps}\">runtime_deps attribute</a>"; + String expected = "<a href=\"java.html#java_binary.runtime_deps\">runtime_deps attribute</a>"; + assertEquals(expected, expander.expand(docs)); + } + + @Test public void testRuleExamples() { + String docs = "<a href=\"${link cc_binary_examples}\">examples</a>"; + String expected = "<a href=\"c-cpp.html#cc_binary_examples\">examples</a>"; + assertEquals(expected, expander.expand(docs)); + } + + @Test public void testRuleArgs() { + String docs = "<a href=\"${link cc_binary_args}\">args</a>"; + String expected = "<a href=\"c-cpp.html#cc_binary_args\">args</a>"; + assertEquals(expected, expander.expand(docs)); + } + + @Test public void testStaticPageRef() { + String docs = "<a href=\"${link common-definitions}\">Common Definitions</a>"; + String expected = "<a href=\"common-definitions.html\">Common Definitions</a>"; + assertEquals(expected, expander.expand(docs)); + } + + @Test public void testStaticPageWithHeadingRef() { + String docs = "<a href=\"${link common-definitions.label-expansion}\">Label Expansion</a>"; + String expected = "<a href=\"common-definitions.html#label-expansion\">Label Expansion</a>"; + assertEquals(expected, expander.expand(docs)); + } + + @Test(expected = IllegalArgumentException.class) + public void testRefNotFound() { + String docs = "<a href=\"${link foo.bar}\">bar</a>"; + expander.expand(docs); + } +} |