Class JDoctest

java.lang.Object
net.cscott.jdoctest.JDoctest
All Implemented Interfaces:
Taglet

@Doctests public class JDoctest extends Object implements Taglet
JDoctest implementing doctests via a @doc.test taglet. This tag can be used in any kind of Element. It is not an inline tag. A "@doc.test" tag specifies an interactive javascript session, in an environment where the class' package has been imported. The output of the javascript session should match the output provided.
Author:
C. Scott Ananian
Tests:
This is an example of a test which passes:
js> "a".equals("a")
true
(EXPECT FAIL) This is an example of a test which fails:
js> 1+2
5
Doctest failure:
 1+2
Expected:
5
Actual:
3
Diff:
53
(JDoctest.java#68)
We can write tests which expect exceptions to be thrown, although it's a little clunky (implementing doctest.ELLIPSIS or doctest.IGNORE_EXCEPTION_DETAIL would make this nicer):
js> try {
  >   java.lang.String("hi").charAt(3);
  > } catch (e) {
  >   print(e.javaException.getClass().getName())
  > }
java.lang.StringIndexOutOfBoundsException
This demonstrates that the current package has been imported:
js> JDoctest
[JavaClass net.cscott.jdoctest.JDoctest]
js> Version.PACKAGE_NAME
jdoctest
Note that results referencing object hashes are properly handled in the output comparison function, even when Rhino gives a different hash at runtime:
js> o = new java.lang.Object()
java.lang.Object@1d2068d
js> o
java.lang.Object@1d2068d
js> new java.lang.Object()
java.lang.Object@1ac2f9c
Doctests are evaluated using the most recent version of ECMAScript that Rhino supports, so modern syntax may be used:
js> let squares = [1, 2, 3].map(x => x * x)
js> `squares: ${squares.join(", ")}`
squares: 1, 4, 9
We can even access private members! (On JDK 16 and later, this requires --add-opens java.base/java.lang=ALL-UNNAMED.)
js> new JDoctest().testsExpectedPass
0
  • Constructor Details

    • JDoctest

      public JDoctest()
  • Method Details

    • getName

      public String getName()
      Return the name of this custom tag.
      Specified by:
      getName in interface Taglet
      Tests:
      js> new JDoctest().getName()
      doc.test
    • getAllowedLocations

      public Set<Taglet.Location> getAllowedLocations()
      Will return all locations, since @doc.test can be used in overview, module, package, type, constructor, method, and field documentation.
      Specified by:
      getAllowedLocations in interface Taglet
      Tests:
      js> new JDoctest().getAllowedLocations()
      [OVERVIEW, MODULE, PACKAGE, TYPE, CONSTRUCTOR, METHOD, FIELD]
    • isInlineTag

      public boolean isInlineTag()
      Will return false since @doc.test is not an inline tag.
      Specified by:
      isInlineTag in interface Taglet
      Tests:
      js> new JDoctest().isInlineTag()
      false
    • init

      public void init(DocletEnvironment env, Doclet doclet)
      Initialize this Taglet. We fetch the Reporter from the standard doclet (if that is the doclet in use) so that doctest failures can be reported as javadoc errors.
      Specified by:
      init in interface Taglet
      Parameters:
      env - the doclet environment
      doclet - the doclet which instantiated this taglet
    • toString

      public String toString(List<? extends DocTree> tags, Element element)
      Given a list of DocTrees representing this custom tag, return its string representation.
      Specified by:
      toString in interface Taglet
      Parameters:
      tags - the list of DocTrees representing this custom tag.
      element - the element to which the enclosing comment belongs