From 5632167f6cacec16d82b1961d233d7e761cf6036 Mon Sep 17 00:00:00 2001
From: Vlad Ureche
Date: Tue, 27 Mar 2012 10:35:40 +0200
Subject: Fixes SI-5373
And adds basic support for scaladoc model tests (class
partest.ScaladocModelTest)
---
build.xml | 3 +-
src/compiler/scala/tools/nsc/doc/DocFactory.scala | 18 +-
.../scala/tools/nsc/doc/html/page/Template.scala | 2 +-
.../scala/tools/nsc/doc/model/ModelFactory.scala | 5 +-
.../scala/tools/partest/ScaladocModelTest.scala | 124 ++++
test/scaladoc/run/SI-5373.check | 1 +
test/scaladoc/run/SI-5373.scala | 34 +
test/scaladoc/scala/IndexScriptTest.scala | 52 --
test/scaladoc/scala/IndexTest.scala | 82 ---
test/scaladoc/scala/html.flags | 1 -
test/scaladoc/scala/html/HtmlFactoryTest.flags | 1 -
test/scaladoc/scala/html/HtmlFactoryTest.scala | 730 ---------------------
test/scaladoc/scala/model/CommentFactoryTest.scala | 155 -----
test/scaladoc/scalacheck/CommentFactoryTest.scala | 155 +++++
test/scaladoc/scalacheck/HtmlFactoryTest.flags | 1 +
test/scaladoc/scalacheck/HtmlFactoryTest.scala | 730 +++++++++++++++++++++
test/scaladoc/scalacheck/IndexScriptTest.scala | 52 ++
test/scaladoc/scalacheck/IndexTest.scala | 82 +++
18 files changed, 1198 insertions(+), 1030 deletions(-)
create mode 100644 src/partest/scala/tools/partest/ScaladocModelTest.scala
create mode 100644 test/scaladoc/run/SI-5373.check
create mode 100644 test/scaladoc/run/SI-5373.scala
delete mode 100644 test/scaladoc/scala/IndexScriptTest.scala
delete mode 100644 test/scaladoc/scala/IndexTest.scala
delete mode 100644 test/scaladoc/scala/html.flags
delete mode 100644 test/scaladoc/scala/html/HtmlFactoryTest.flags
delete mode 100644 test/scaladoc/scala/html/HtmlFactoryTest.scala
delete mode 100644 test/scaladoc/scala/model/CommentFactoryTest.scala
create mode 100644 test/scaladoc/scalacheck/CommentFactoryTest.scala
create mode 100644 test/scaladoc/scalacheck/HtmlFactoryTest.flags
create mode 100644 test/scaladoc/scalacheck/HtmlFactoryTest.scala
create mode 100644 test/scaladoc/scalacheck/IndexScriptTest.scala
create mode 100644 test/scaladoc/scalacheck/IndexTest.scala
diff --git a/build.xml b/build.xml
index 2f655c2077..b5fead5bec 100644
--- a/build.xml
+++ b/build.xml
@@ -1916,7 +1916,8 @@ BOOTRAPING TEST AND TEST SUITE
-
+
+
diff --git a/src/compiler/scala/tools/nsc/doc/DocFactory.scala b/src/compiler/scala/tools/nsc/doc/DocFactory.scala
index 9a025b0d14..f32564f097 100644
--- a/src/compiler/scala/tools/nsc/doc/DocFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/DocFactory.scala
@@ -8,7 +8,7 @@ package doc
import scala.util.control.ControlThrowable
import reporters.Reporter
-import util.NoPosition
+import util.{ NoPosition, BatchSourceFile}
import io.{ File, Directory }
import DocParser.Parsed
@@ -46,13 +46,19 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor
override def forScaladoc = true
}
- /** Creates a scaladoc site for all symbols defined in this call's `files`,
- * as well as those defined in `files` of previous calls to the same processor.
+ /** Creates a scaladoc site for all symbols defined in this call's `source`,
+ * as well as those defined in `sources` of previous calls to the same processor.
* @param files The list of paths (relative to the compiler's source path,
* or absolute) of files to document. */
- def makeUniverse(files: List[String]): Option[Universe] = {
+ def makeUniverse(source: Either[List[String], String]): Option[Universe] = {
assert(settings.docformat.value == "html")
- new compiler.Run() compile files
+ source match {
+ case Left(files) =>
+ new compiler.Run() compile files
+ case Right(sourceCode) =>
+ new compiler.Run() compileSources List(new BatchSourceFile("newSource", sourceCode))
+ }
+
if (reporter.hasErrors)
return None
@@ -111,7 +117,7 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor
docletInstance match {
case universer: Universer =>
- val universe = makeUniverse(files) getOrElse { throw NoCompilerRunException }
+ val universe = makeUniverse(Left(files)) getOrElse { throw NoCompilerRunException }
universer setUniverse universe
docletInstance match {
diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
index c8c5f1ec11..f059b5c0cb 100644
--- a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
@@ -35,7 +35,7 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
val valueMembers =
- tpl.methods.filterNot(_.isBridge) ++ tpl.values ++ tpl.templates.filter(x => x.isObject || x.isPackage) sorted
+ tpl.methods ++ tpl.values ++ tpl.templates.filter(x => x.isObject || x.isPackage) sorted
val (absValueMembers, nonAbsValueMembers) =
valueMembers partition (_.isAbstract)
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
index 496d004fd8..dd1c75c322 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
@@ -247,7 +247,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
protected lazy val memberSyms =
// Only this class's constructors are part of its members, inherited constructors are not.
- sym.info.members.filter(s => localShouldDocument(s) && (!s.isConstructor || s.owner == sym))
+ sym.info.members.filter(s => localShouldDocument(s) && (!s.isConstructor || s.owner == sym) && !isPureBridge(sym) )
val members = memberSyms flatMap (makeMember(_, this))
val templates = members collect { case c: DocTemplateEntity => c }
@@ -705,4 +705,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
def localShouldDocument(aSym: Symbol): Boolean = {
!aSym.isPrivate && (aSym.isProtected || aSym.privateWithin == NoSymbol) && !aSym.isSynthetic
}
+
+ /** Filter '@bridge' methods only if *they don't override non-bridge methods*. See SI-5373 for details */
+ def isPureBridge(sym: Symbol) = sym.isBridge && sym.allOverriddenSymbols.forall(_.isBridge)
}
diff --git a/src/partest/scala/tools/partest/ScaladocModelTest.scala b/src/partest/scala/tools/partest/ScaladocModelTest.scala
new file mode 100644
index 0000000000..2eb026ceee
--- /dev/null
+++ b/src/partest/scala/tools/partest/ScaladocModelTest.scala
@@ -0,0 +1,124 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Vlad Ureche
+ */
+
+package scala.tools.partest
+
+import scala.tools.partest._
+import java.io._
+import scala.tools.nsc._
+import scala.tools.nsc.util.CommandLineParser
+import scala.tools.nsc.doc.{Settings, DocFactory, Universe}
+import scala.tools.nsc.doc.model._
+import scala.tools.nsc.reporters.ConsoleReporter
+
+/** A class for testing scaladoc model generation
+ * - you need to specify the code in the `code` method
+ * - you need to override the testModel method to test the model
+ * - you may specify extra parameters to send to scaladoc in `scaladocSettings`
+ * {{{
+ import scala.tools.nsc.doc.model._
+ import scala.tools.partest.ScaladocModelTest
+
+ object Test extends ScaladocModelTest {
+
+ def code = """ ... """
+ def scaladocSettings = ""
+ def testModel(rootPackage: Package) = {
+ // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s))
+ import access._
+
+ // just need to check the member exists, access methods will throw an error if there's a problem
+ rootPackage._package("scala")._package("test")._class("C")._method("foo")
+ }
+ }
+ * }}}
+ */
+abstract class ScaladocModelTest extends DirectTest {
+
+ /** Override this to give scaladoc command line parameters */
+ def scaladocSettings: String
+
+ /** Override this to test the model */
+ def testModel(root: Package): Unit
+
+ // Implementation follows:
+ override def extraSettings: String = "-usejavacp"
+
+ override def show(): Unit = {
+ // redirect err to out, for logging
+ val prevErr = System.err
+ System.setErr(System.out)
+
+ try {
+ // 1 - compile with scaladoc and get the model out
+ val args = scaladocSettings.split(" ")
+ val universe = model(args:_*).getOrElse({sys.error("Scaladoc Model Test ERROR: No universe generated!")})
+ // 2 - check the model generated
+ testModel(universe.rootPackage)
+ } catch {
+ case e =>
+ println(e)
+ e.printStackTrace
+ }
+ // set err back to the real err handler
+ System.setErr(prevErr)
+ }
+
+ // create a new scaladoc compiler
+ def newDocFactory(args: String*): DocFactory = {
+ val settings = new Settings(_ => ())
+ val command = new ScalaDoc.Command((CommandLineParser tokenize extraSettings) ++ args.toList, settings)
+ val docFact = new DocFactory(new ConsoleReporter(settings), settings)
+ docFact
+ }
+
+ // compile with scaladoc and output the result
+ def model(args: String*): Option[Universe] = newDocFactory(args: _*).makeUniverse(Right(code))
+
+ // so we don't get the newSettings warning
+ override def isDebug = false
+
+
+ // finally, enable easy navigation inside the entities
+ object access {
+
+ // Make it easy to access things
+ class TemplateAccess(tpl: DocTemplateEntity) {
+
+ def _class(name: String): DocTemplateEntity = getTheFirst(_classes(name), tpl.qualifiedName + ".class(" + name + ")")
+ def _classes(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).flatMap({ case c: Class => List(c)})
+
+ def _trait(name: String): DocTemplateEntity = getTheFirst(_traits(name), tpl.qualifiedName + ".trait(" + name + ")")
+ def _traits(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).flatMap({ case t: Trait => List(t)})
+
+ def _object(name: String): DocTemplateEntity = getTheFirst(_objects(name), tpl.qualifiedName + ".object(" + name + ")")
+ def _objects(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).flatMap({ case o: Object => List(o)})
+
+ def _method(name: String): Def = getTheFirst(_methods(name), tpl.qualifiedName + ".method(" + name + ")")
+ def _methods(name: String): List[Def] = tpl.methods.filter(_.name == name)
+
+ def _value(name: String): Val = getTheFirst(_values(name), tpl.qualifiedName + ".value(" + name + ")")
+ def _values(name: String): List[Val] = tpl.values.filter(_.name == name)
+
+ def getTheFirst[T](list: List[T], expl: String): T = {
+ if (list.length == 1)
+ list.head
+ else if (list.length == 0)
+ sys.error("Error getting " + expl + ": No such element. All elements in list: [" + list.mkString(", ") + "]")
+ else
+ sys.error("Error getting " + expl + ": " + list.length + " elements with this name. " +
+ "All elements in list: [" + list.mkString(", ") + "]")
+ }
+ }
+
+ class PackageAccess(pack: Package) extends TemplateAccess(pack) {
+ def _package(name: String): Package = getTheFirst(_packages(name), pack.qualifiedName + ".package(" + name + ")")
+ def _packages(name: String): List[Package] = pack.packages.filter(_.name == name)
+ }
+
+ implicit def templateAccess(tpl: DocTemplateEntity) = new TemplateAccess(tpl)
+ implicit def packageAccess(pack: Package) = new PackageAccess(pack)
+ }
+}
diff --git a/test/scaladoc/run/SI-5373.check b/test/scaladoc/run/SI-5373.check
new file mode 100644
index 0000000000..c55eb001cf
--- /dev/null
+++ b/test/scaladoc/run/SI-5373.check
@@ -0,0 +1 @@
+model contains 6 documentable templates
diff --git a/test/scaladoc/run/SI-5373.scala b/test/scaladoc/run/SI-5373.scala
new file mode 100644
index 0000000000..af433a1844
--- /dev/null
+++ b/test/scaladoc/run/SI-5373.scala
@@ -0,0 +1,34 @@
+import scala.tools.nsc.doc.model._
+import scala.tools.partest.ScaladocModelTest
+
+object Test extends ScaladocModelTest {
+
+ def code = """
+ import scala.annotation.bridge
+
+ package scala.test {
+
+ trait A {
+ def foo = ()
+ }
+
+ trait B {
+ @bridge()
+ def foo = ()
+ }
+
+ class C extends A with B
+ }
+ """
+
+ // no need for special settings
+ def scaladocSettings = ""
+
+ def testModel(rootPackage: Package) = {
+ // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s))
+ import access._
+
+ // just need to check the member exists, access methods will throw an error if there's a problem
+ rootPackage._package("scala")._package("test")._class("C")._method("foo")
+ }
+}
\ No newline at end of file
diff --git a/test/scaladoc/scala/IndexScriptTest.scala b/test/scaladoc/scala/IndexScriptTest.scala
deleted file mode 100644
index e0372020fd..0000000000
--- a/test/scaladoc/scala/IndexScriptTest.scala
+++ /dev/null
@@ -1,52 +0,0 @@
-import org.scalacheck._
-import org.scalacheck.Prop._
-
-import scala.tools.nsc.doc
-import scala.tools.nsc.doc.html.page.IndexScript
-import java.net.{URLClassLoader, URLDecoder}
-
-object Test extends Properties("IndexScript") {
-
- def getClasspath = {
- val loader = Thread.currentThread.getContextClassLoader
- val paths = loader.asInstanceOf[URLClassLoader].getURLs
- val morepaths = loader.getParent.asInstanceOf[URLClassLoader].getURLs
- (paths ++ morepaths).map(u => URLDecoder.decode(u.getPath)).mkString(java.io.File.pathSeparator)
- }
-
- val docFactory = {
- val settings = new doc.Settings({Console.err.println(_)})
- settings.classpath.value = getClasspath
- val reporter = new scala.tools.nsc.reporters.ConsoleReporter(settings)
- new doc.DocFactory(reporter, settings)
- }
-
- val indexModelFactory = doc.model.IndexModelFactory
-
- def createIndexScript(path: String) =
- docFactory.makeUniverse(List(path)) match {
- case Some(universe) => {
- val index = new IndexScript(universe,
- indexModelFactory.makeIndex(universe))
- Some(index)
- }
- case _ =>
- None
- }
-
- property("allPackages") = {
- createIndexScript("src/compiler/scala/tools/nsc/doc/html/page/Index.scala") match {
- case Some(index) =>
- index.allPackages.map(_.toString) == List(
- "scala",
- "scala.tools",
- "scala.tools.nsc",
- "scala.tools.nsc.doc",
- "scala.tools.nsc.doc.html",
- "scala.tools.nsc.doc.html.page"
- )
- case None =>
- false
- }
- }
-}
diff --git a/test/scaladoc/scala/IndexTest.scala b/test/scaladoc/scala/IndexTest.scala
deleted file mode 100644
index c14fd98297..0000000000
--- a/test/scaladoc/scala/IndexTest.scala
+++ /dev/null
@@ -1,82 +0,0 @@
-import org.scalacheck._
-import org.scalacheck.Prop._
-
-import scala.tools.nsc.doc
-import scala.tools.nsc.doc.html.page.Index
-import java.net.{URLClassLoader, URLDecoder}
-
-object Test extends Properties("Index") {
-
- def getClasspath = {
- // these things can be tricky
- // this test previously relied on the assumption that the current thread's classloader is an url classloader and contains all the classpaths
- // does partest actually guarantee this? to quote Leonard Nimoy: The answer, of course, is no.
- // this test _will_ fail again some time in the future.
- val paths = Thread.currentThread.getContextClassLoader.asInstanceOf[URLClassLoader].getURLs.map(u => URLDecoder.decode(u.getPath))
- val morepaths = Thread.currentThread.getContextClassLoader.getParent.asInstanceOf[URLClassLoader].getURLs.map(u => URLDecoder.decode(u.getPath))
- (paths ++ morepaths).mkString(java.io.File.pathSeparator)
- }
-
- val docFactory = {
- val settings = new doc.Settings({Console.err.println(_)})
-
- settings.classpath.value = getClasspath
- println(settings.classpath.value)
-
- val reporter = new scala.tools.nsc.reporters.ConsoleReporter(settings)
-
- new doc.DocFactory(reporter, settings)
- }
-
- val indexModelFactory = doc.model.IndexModelFactory
-
- def createIndex(path: String): Option[Index] = {
-
- val maybeUniverse = {
- //val stream = new java.io.ByteArrayOutputStream
- //val original = Console.out
- //Console.setOut(stream)
-
- val result = docFactory.makeUniverse(List(path))
-
- // assert(stream.toString == "model contains 2 documentable templates\n")
- //Console.setOut(original)
-
- result
- }
-
- maybeUniverse match {
- case Some(universe) => {
- val index = new Index(universe, indexModelFactory.makeIndex(universe))
- return Some(index)
- }
- case _ => return None
- }
-
- }
-
- property("path") = {
- createIndex("src/compiler/scala/tools/nsc/doc/html/page/Index.scala") match {
- case Some(index) =>
- index.path == List("index.html")
- case None => false
- }
- }
-
- property("title") = {
- createIndex("src/compiler/scala/tools/nsc/doc/html/page/Index.scala") match {
- case Some(index) =>
- index.title == ""
-
- case None => false
- }
- }
- property("browser contants a script element") = {
- createIndex("src/compiler/scala/tools/nsc/doc/html/page/Index.scala") match {
- case Some(index) =>
- (index.browser \ "script").size == 1
-
- case None => false
- }
- }
-}
diff --git a/test/scaladoc/scala/html.flags b/test/scaladoc/scala/html.flags
deleted file mode 100644
index b2264ec4f4..0000000000
--- a/test/scaladoc/scala/html.flags
+++ /dev/null
@@ -1 +0,0 @@
--encoding UTF-8
\ No newline at end of file
diff --git a/test/scaladoc/scala/html/HtmlFactoryTest.flags b/test/scaladoc/scala/html/HtmlFactoryTest.flags
deleted file mode 100644
index b2264ec4f4..0000000000
--- a/test/scaladoc/scala/html/HtmlFactoryTest.flags
+++ /dev/null
@@ -1 +0,0 @@
--encoding UTF-8
\ No newline at end of file
diff --git a/test/scaladoc/scala/html/HtmlFactoryTest.scala b/test/scaladoc/scala/html/HtmlFactoryTest.scala
deleted file mode 100644
index 28c7a4b94f..0000000000
--- a/test/scaladoc/scala/html/HtmlFactoryTest.scala
+++ /dev/null
@@ -1,730 +0,0 @@
-import org.scalacheck._
-import org.scalacheck.Prop._
-
-import java.net.{URLClassLoader, URLDecoder}
-
-object XMLUtil {
- import scala.xml._
-
- def stripGroup(seq: Node): Node = {
- seq match {
- case group: Group => {
- { group.nodes.map(stripGroup _) }
- }
- case e: Elem => {
- val child = e.child.map(stripGroup _)
- Elem(e.prefix, e.label, e.attributes, e.scope, child : _*)
- }
- case _ => seq
- }
- }
-}
-
-object Test extends Properties("HtmlFactory") {
-
- final val RESOURCES = "test/scaladoc/resources/"
-
- import scala.tools.nsc.doc.{DocFactory, Settings}
- import scala.tools.nsc.doc.model.IndexModelFactory
- import scala.tools.nsc.doc.html.HtmlFactory
- import scala.tools.nsc.doc.html.page.ReferenceIndex
-
- def getClasspath = {
- // these things can be tricky
- // this test previously relied on the assumption that the current thread's classloader is an url classloader and contains all the classpaths
- // does partest actually guarantee this? to quote Leonard Nimoy: The answer, of course, is no.
- // this test _will_ fail again some time in the future.
- val paths = Thread.currentThread.getContextClassLoader.asInstanceOf[URLClassLoader].getURLs.map(u => URLDecoder.decode(u.getPath))
- val morepaths = Thread.currentThread.getContextClassLoader.getParent.asInstanceOf[URLClassLoader].getURLs.map(u => URLDecoder.decode(u.getPath))
- (paths ++ morepaths).mkString(java.io.File.pathSeparator)
- }
-
- def createFactory = {
- val settings = new Settings({Console.err.println(_)})
- settings.classpath.value = getClasspath
-
- val reporter = new scala.tools.nsc.reporters.ConsoleReporter(settings)
- new DocFactory(reporter, settings)
- }
-
- def createTemplates(basename: String) = {
- val result = scala.collection.mutable.Map[String, scala.xml.NodeSeq]()
-
- createFactory.makeUniverse(List(RESOURCES+basename)) match {
- case Some(universe) => {
- val index = IndexModelFactory.makeIndex(universe)
- (new HtmlFactory(universe, index)).writeTemplates((page) => {
- result += (page.absoluteLinkTo(page.path) -> page.body)
- })
- }
- case _ => ;
- }
-
- result
- }
-
- def createReferenceIndex(basename: String) = {
- createFactory.makeUniverse(List(RESOURCES+basename)) match {
- case Some(universe) => {
- val index = IndexModelFactory.makeIndex(universe)
- val pages = index.firstLetterIndex.map({
- case (key, value) => {
- val page = new ReferenceIndex(key, index, universe)
- page.absoluteLinkTo(page.path) -> page.body
- }
- })
- Some(pages)
- }
- case _ =>
- None
- }
- }
-
- def createTemplate(scala: String) = {
- val html = scala.stripSuffix(".scala") + ".html"
- createTemplates(scala)(html)
- }
-
- /**
- * This tests the text without the markup - ex:
- *
- *
- *
- * implicit
- * def
- *
- *
- * test(): Int
- *
- *
- *
- * becomes:
- *
- * implicit def test(): Int
- *
- * and is required to contain the text in the given checks
- *
- * NOTE: Comparison is done ignoring all whitespace
- */
- def checkText(scalaFile: String, debug: Boolean = true)(checks: (Option[String], String, Boolean)*): Boolean = {
- val htmlFile = scalaFile.stripSuffix(".scala") + ".html"
- val htmlAllFiles = createTemplates(scalaFile)
- var result = true
-
- for ((fileHint, check, expected) <- checks) {
- // resolve the file to be checked
- val fileName = fileHint match {
- case Some(file) =>
- if (file endsWith ".html")
- file
- else
- file + ".html"
- case None =>
- htmlFile
- }
- val fileTextPretty = htmlAllFiles(fileName).text.replace('→',' ').replaceAll("\\s+"," ")
- val fileText = fileTextPretty.replaceAll(" ", "")
-
- val checkTextPretty = check.replace('→',' ').replaceAll("\\s+"," ")
- val checkText = checkTextPretty.replaceAll(" ", "")
-
- val checkValue = fileText.contains(checkText) == expected
- if (debug && (!checkValue)) {
- Console.err.println("")
- Console.err.println("HTML Check failed for resource file " + scalaFile + ":")
- Console.err.println("Could not match: \n" + checkTextPretty)
- Console.err.println("In the extracted HTML text: \n" + fileTextPretty)
- Console.err.println("NOTE: The whitespaces are eliminated before matching!")
- Console.err.println("")
- }
- result &&= checkValue
- }
-
- result
- }
-
-
- def shortComments(root: scala.xml.Node) =
- XMLUtil.stripGroup(root).descendant.flatMap {
- case e: scala.xml.Elem => {
- if (e.attribute("class").toString.contains("shortcomment")) {
- Some(e)
- } else {
- None
- }
- }
- case _ => None
- }
-
- property("Trac #3790") = {
- createTemplate("Trac3790.scala") match {
- case node: scala.xml.Node => {
- val comments = shortComments(node)
-
- comments.exists { _.toString.contains(">A lazy String\n
") } &&
- comments.exists { _.toString.contains(">A non-lazy String\n") }
- }
- case _ => false
- }
- }
-
- property("Trac #4306") = {
- val files = createTemplates("Trac4306.scala")
- files("com/example/trac4306/foo/package$$Bar.html") != None
- }
-
- property("Trac #4366") = {
- createTemplate("Trac4366.scala") match {
- case node: scala.xml.Node => {
- shortComments(node).exists { n => {
- val str = n.toString
- str.contains("foo
") && str.contains("")
- } }
- }
- case _ => false
- }
- }
-
- property("Trac #4358") = {
- createTemplate("Trac4358.scala") match {
- case node: scala.xml.Node =>
- ! shortComments(node).exists {
- _.toString.contains("i.")
- }
- case _ => false
- }
- }
-
- property("Trac #4180") = {
- createTemplate("Trac4180.scala") != None
- }
-
- property("Trac #4372") = {
- createTemplate("Trac4372.scala") match {
- case node: scala.xml.Node => {
- val html = node.toString
- html.contains("+:") &&
- html.contains("-:") &&
- html.contains("""(n: Int): Int""")
- }
- case _ => false
- }
- }
-
- property("Trac #4374 - public") = {
- val files = createTemplates("Trac4374.scala")
- files("WithPublic.html") match {
- case node: scala.xml.Node => {
- val s = node.toString
- s.contains("""href="WithPublic$.html"""") &&
- files.get("WithPublic$.html") != None
- }
- case _ => false
- }
- }
-
- property("Trac #4374 - private") = {
- val files = createTemplates("Trac4374.scala")
- files("WithPrivate.html") match {
- case node: scala.xml.Node => {
- val s = node.toString
- ! s.contains("""href="WithPrivate$.html"""") &&
- files.get("WithPrivate$.html") == None
- }
- case _ => false
- }
- }
-
- property("Trac #3484") = {
- val files = createTemplates("Trac3484.scala")
-
- files("Collection.html") match {
- case node: scala.xml.Node => {
- val s = node.toString
- s.contains(""": Traversable[B]""")
- }
- case _ => false
- }
- }
-
- property("Trac #3484 - SR704") = {
- val files = createTemplates("Trac3484.scala")
-
- files("SR704.html") match {
- case node: scala.xml.Node => {
- val s = node.toString
- s.contains("Hello Mister John.")
- }
- case _ => false
- }
- }
-
- property("Trac #4325 - files") = {
- val files = createTemplates("Trac4325.scala")
-
- files.get("WithSynthetic.html") != None &&
- files.get("WithSynthetic$.html") == None &&
- files.get("WithObject.html") != None &&
- files.get("WithObject$.html") != None
- }
-
- property("Trac #4325 - Don't link to syntetic companion") = {
- val files = createTemplates("Trac4325.scala")
-
- files("WithSynthetic.html") match {
- case node: scala.xml.Node => {
- val s = node.toString
- ! s.contains("""href="WithSynthetic$.html"""")
- }
- case _ => false
- }
- }
-
- property("Trac #4325 - Link to companion") = {
- val files = createTemplates("Trac4325.scala")
-
- files("WithObject.html") match {
- case node: scala.xml.Node => {
- val s = node.toString
- s.contains("""href="WithObject$.html"""")
- }
- case _ => false
- }
- }
-
- property("Trac #4420 - no whitespace at end of line") = {
- val files = createTemplates("Trac4420.scala")
-
- files("TestA.html") match {
- case node: scala.xml.Node => {
- val s = node.toString
- s.contains("""See YYY for more details""")
- }
- case _ => false
- }
- }
- //
- // property("Trac #484 - refinements and existentials") = {
- // val files = createTemplates("Trac484.scala")
- // val lines = """
- // |type Bar = AnyRef { type Dingus <: T forSome { type T <: String } }
- // |type Foo = AnyRef { ... /* 3 definitions in type refinement */ }
- // |def g(x: T forSome { type T <: String }): String
- // |def h(x: Float): AnyRef { def quux(x: Int,y: Int): Int }
- // |def hh(x: Float): AnyRef { def quux(x: Int,y: Int): Int }
- // |def j(x: Int): Bar
- // |def k(): AnyRef { type Dingus <: T forSome { type T <: String } }
- // """.stripMargin.trim.lines map (_.trim)
- //
- // files("RefinementAndExistentials.html") match {
- // case node: scala.xml.Node => {
- // val s = node.text.replaceAll("\\s+", " ")
- // lines forall (s contains _)
- // }
- // case _ => false
- // }
- // }
-
- property("Trac #4289") = {
- val files = createTemplates("Trac4289.scala")
-
- files("Subclass.html") match {
- case node: scala.xml.Node => {
- node.toString.contains {
- """returns123
"""
- }
- }
- case _ => false
- }
- }
-
- property("Trac #4409") = {
- createTemplate("Trac4409.scala") match {
- case node: scala.xml.Node => {
- ! node.toString.contains("""since""")
- }
- case _ => false
- }
- }
-
- property("Trac #4452") = {
- createTemplate("Trac4452.scala") match {
- case node: scala.xml.Node =>
- ! node.toString.contains(">*")
- case _ => false
- }
- }
-
- property("Trac #4471") = {
- createReferenceIndex("Trac4471.scala") match {
- case Some(pages) =>
- (pages.get("index/index-f.html") match {
- case Some(node) => node.toString.contains(">A")
- case _ => false
- }) && (pages.get("index/index-b.html") match {
- case Some(node) => node.toString.contains(">bar")
- case _ => false
- })
- case _ => false
- }
- }
-
- property("SI-4641") = {
- createReferenceIndex("SI_4641.scala") match {
- case Some(pages) => pages.contains("index/index-_.html")
- case _ => false
- }
- }
-
- property("SI-4421") = {
- createTemplate("SI_4421.scala") match {
- case node: scala.xml.Node => {
- val html = node.toString
- html.contains(">Example:") && html.contains(">Note<")
- }
- case _ => false
- }
- }
-
- property("SI-4589") = {
- createTemplate("SI_4589.scala") match {
- case node: scala.xml.Node => {
- val html = node.toString
- html.contains(">x0123456789: <") &&
- html.contains(">x012345678901234567890123456789: <")
- }
- case _ => false
- }
- }
-
- property("Should decode symbolic type alias name.") = {
- createTemplate("SI_4715.scala") match {
- case node: scala.xml.Node => {
- val html = node.toString
- html.contains(">: :+:[<")
- }
- case _ => false
- }
- }
-
- property("Shouldn't drop type arguments to aliased tuple.") = {
- createTemplate("SI_4676.scala") match {
- case node: scala.xml.Node => {
- node.toString.contains(">ss: (String, String)<")
- }
- case _ => false
- }
- }
-
- property("Default arguments of synthesized constructor") = {
- val files = createTemplates("SI_4287.scala")
-
- files("ClassWithSugar.html") match {
- case node: scala.xml.Node => {
- node.toString.contains(">123<")
- }
- case _ => false
- }
- }
-
- property("Default arguments of synthesized constructor") = {
- createTemplate("SI_4507.scala") match {
- case node: scala.xml.Node =>
- ! node.toString.contains("- returns silently when evaluating true and true
")
- case _ => false
- }
- }
-
- property("Use cases and links should not crash scaladoc") = {
- createTemplate("SI_4898.scala")
- true
- }
-
- property("Use cases should override their original members") =
- checkText("SI_5054_q1.scala")(
- (None,"""def test(): Int""", true)
- //Disabled because the full signature is now displayed
- //(None,"""def test(implicit lost: Int): Int""", false)
- )
-
- property("Use cases should keep their flags - final should not be lost") =
- checkText("SI_5054_q2.scala")((None, """final def test(): Int""", true))
-
- property("Use cases should keep their flags - implicit should not be lost") =
- checkText("SI_5054_q3.scala")((None, """implicit def test(): Int""", true))
-
- property("Use cases should keep their flags - real abstract should not be lost") =
- checkText("SI_5054_q4.scala")((None, """abstract def test(): Int""", true))
-
- property("Use cases should keep their flags - traits should not be affected") =
- checkText("SI_5054_q5.scala")((None, """def test(): Int""", true))
-
- property("Use cases should keep their flags - traits should not be affected") =
- checkText("SI_5054_q6.scala")((None, """abstract def test(): Int""", true))
-
- property("Use case individual signature test") =
- checkText("SI_5054_q7.scala")(
- (None, """abstract def test2(explicit: Int): Int [use case] This takes the explicit value passed.""", true),
- (None, """abstract def test1(): Int [use case] This takes the implicit value in scope.""", true)
- )
-
- property("Display correct \"Definition classes\"") =
- checkText("SI_5287.scala")(
- (None,
- """def method(): Int
- [use case] The usecase explanation
- [use case] The usecase explanation
- Definition Classes SI_5287 SI_5287_B SI_5287_A""", true)
- ) // the explanation appears twice, as small comment and full comment
-
- property("Correct comment inheritance for overriding") =
- checkText("implicit-inheritance-override.scala")(
- (Some("Base"),
- """def function[T](arg1: T, arg2: String): Double
- The base comment.
- The base comment. And another sentence...
- T the type of the first argument
- arg1 The T term comment
- arg2 The string comment
- returns The return comment
- """, true),
- (Some("DerivedA"),
- """def function[T](arg1: T, arg2: String): Double
- Overriding the comment, the params and returns comments should stay the same.
- Overriding the comment, the params and returns comments should stay the same.
- T the type of the first argument
- arg1 The T term comment
- arg2 The string comment
- returns The return comment
- """, true),
- (Some("DerivedB"),
- """def function[T](arg1: T, arg2: String): Double
- T the type of the first argument
- arg1 The overridden T term comment
- arg2 The overridden string comment
- returns The return comment
- """, true),
- (Some("DerivedC"),
- """def function[T](arg1: T, arg2: String): Double
- T the type of the first argument
- arg1 The T term comment
- arg2 The string comment
- returns The overridden return comment
- """, true),
- (Some("DerivedD"),
- """def function[T](arg1: T, arg2: String): Double
- T The overriden type parameter comment
- arg1 The T term comment
- arg2 The string comment
- returns The return comment
- """, true)
- )
-
- for (useCaseFile <- List("UseCaseInheritance", "UseCaseOverrideInheritance")) {
- property("Correct comment inheritance for usecases") =
- checkText("implicit-inheritance-usecase.scala")(
- (Some(useCaseFile),
- """def missing_arg[T](arg1: T): Double
- [use case]
- [use case]
- T The type parameter
- arg1 The T term comment
- returns The return comment
- """, true),
- (Some(useCaseFile),
- """def missing_targ(arg1: Int, arg2: String): Double
- [use case]
- [use case]
- arg1 The T term comment
- arg2 The string comment
- returns The return comment
- """, true),
- (Some(useCaseFile),
- """def overridden_arg1[T](implicit arg1: T, arg2: String): Double
- [use case]
- [use case]
- T The type parameter
- arg1 The overridden T term comment
- arg2 The string comment
- returns The return comment
- """, true),
- (Some(useCaseFile),
- """def overridden_targ[T](implicit arg1: T, arg2: String): Double
- [use case]
- [use case]
- T The overridden type parameter comment
- arg1 The T term comment
- arg2 The string comment
- returns The return comment
- """, true),
- (Some(useCaseFile),
- """def overridden_return[T](implicit arg1: T, arg2: String): Double
- [use case]
- [use case]
- T The type parameter
- arg1 The T term comment
- arg2 The string comment
- returns The overridden return comment
- """, true),
- (Some(useCaseFile),
- """def added_arg[T](implicit arg1: T, arg2: String, arg3: Float): Double
- [use case]
- [use case]
- T The type parameter
- arg1 The T term comment
- arg2 The string comment
- arg3 The added float comment
- returns The return comment
- """, true),
- (Some(useCaseFile),
- """def overridden_comment[T](implicit arg1: T, arg2: String): Double
- [use case] The overridden comment.
- [use case] The overridden comment.
- T The type parameter
- arg1 The T term comment
- arg2 The string comment
- returns The return comment
- """, true)
- )
- }
-
- property("Correct explicit inheritance for override") =
- checkText("explicit-inheritance-override.scala")(
- (Some("InheritDocDerived"),
- """def function[T](arg1: T, arg2: String): Double
- Starting line
- Starting line
- The base comment. And another sentence...
- The base comment. And another sentence...
- Ending line
- T StartT the type of the first argument EndT
- arg1 Start1 The T term comment End1
- arg2 Start2 The string comment End2
- returns StartRet The return comment EndRet""", true),
- (Some("InheritDocDerived"),
- """Definition Classes InheritDocDerived → InheritDocBase
- Example: StartExample function[Int](3, "something") EndExample
- Version StartVer 0.0.2 EndVer
- Since StartSince 0.0.1 EndSince
- Exceptions thrown
- SomeException StartEx if the function is not called with correct parameters EndEx
- SomeOtherException StartSOE Should Warn EndSOE
- To do StartTodo Call mom. And dad! EndTodo
- Note StartNote Be careful! EndNote
- See also StartSee The Manual EndSee
- """, true))
-
- property("Correct explicit inheritance for usecase") =
- checkText("explicit-inheritance-usecase.scala")(
- (Some("UseCaseInheritDoc"),
- """def function[T](arg1: T, arg2: String): Double
- [use case] Starting line
- [use case] Starting line
- The base comment. And another sentence...
- The base comment. And another sentence...
- Ending line
- T StartT the type of the first argument EndT
- arg1 Start1 The T term comment End1
- arg2 Start2 The string comment End2
- returns StartRet The return comment EndRet""", true),
- (Some("UseCaseInheritDoc"),
- """Example: StartExample function[Int](3,"something") EndExample
- Version StartVer 0.0.2 EndVer
- Since StartSince 0.0.1 EndSince
- Exceptions thrown
- SomeException StartEx if the function is not called with correct parameters EndEx
- SomeOtherException StartSOE Should Warn EndSOE
- To do StartTodo Call mom. And dad! EndTodo
- Note StartNote Be careful! EndNote
- See also StartSee The Manual EndSee
- """, true))
-
- property("Correct explicit inheritance in corner cases") =
- checkText("inheritdoc-corner-cases.scala")(
- (Some("D"),
- """def hello1: Int
- Inherited: Hello 1 comment
- Inherited: Hello 1 comment
- Definition Classes D → A
- """, true),
- (Some("D"),
- """def hello2: Int
- Inherited: Hello 2 comment
- Inherited: Hello 2 comment
- Definition Classes D → B
- """, true),
- (Some("G"),
- """def hello1: Int
- Inherited: Hello 1 comment
- Inherited: Hello 1 comment
- Definition Classes G → D → A
- """, true),
- (Some("G"),
- """def hello2: Int
- Inherited: Hello 2 comment
- Inherited: Hello 2 comment
- Definition Classes G → D → B
- """, true),
- (Some("I"),
- """def hello1(i: Int): Unit
- [use case] Inherited: Hello 1 comment
- [use case] Inherited: Hello 1 comment
- Definition Classes I → G → D → A
- """, true)
- // traits E, F and H shouldn't crash scaladoc but we don't need to check the output
- )
-
- property("Indentation normalization for code blocks") = {
- val files = createTemplates("code-indent.scala")
-
- files("C.html") match {
- case node: scala.xml.Node => {
- val s = node.toString
- s.contains("a typicial indented\ncomment on multiple\ncomment lines
") &&
- s.contains("one liner
") &&
- s.contains("two lines, one useful
") &&
- s.contains("line1\nline2\nline3\nline4
") &&
- s.contains("a ragged example\na (condition)\n the t h e n branch\nan alternative\n the e l s e branch
") &&
- s.contains("l1\n\nl2\n\nl3\n\nl4\n\nl5
")
- }
- case _ => false
- }
- }
-
- {
- val files = createTemplates("basic.scala")
- //println(files)
-
- property("class") = files.get("com/example/p1/Clazz.html") match {
- case Some(node: scala.xml.Node) => {
- property("implicit convertion") =
- node.toString contains "implicit "
-
- property("gt4s") =
- node.toString contains "title=\"gt4s: $colon$colon\""
-
- property("gt4s of a deprecated method") =
- node.toString contains "title=\"gt4s: $colon$colon$colon$colon. Deprecated: "
- true
- }
- case _ => false
- }
- property("package") = files.get("com/example/p1/package.html") != None
-
- property("package object") = files("com/example/p1/package.html") match {
- case node: scala.xml.Node =>
- node.toString contains "com.example.p1.package#packageObjectMethod"
- case _ => false
- }
-
- property("lower bound") = files("com/example/p1/LowerBound.html") match {
- case node: scala.xml.Node => true
- case _ => false
- }
-
- property("upper bound") = files("com/example/p1/UpperBound.html") match {
- case node: scala.xml.Node => true
- case _ => false
- }
- }
-}
diff --git a/test/scaladoc/scala/model/CommentFactoryTest.scala b/test/scaladoc/scala/model/CommentFactoryTest.scala
deleted file mode 100644
index 69c314a64c..0000000000
--- a/test/scaladoc/scala/model/CommentFactoryTest.scala
+++ /dev/null
@@ -1,155 +0,0 @@
-import org.scalacheck._
-import org.scalacheck.Prop._
-
-import scala.tools.nsc.Global
-import scala.tools.nsc.doc
-import scala.tools.nsc.doc.model.comment._
-
-class Factory(val g: Global, val s: doc.Settings)
- extends doc.model.ModelFactory(g, s) {
- thisFactory: Factory with CommentFactory with doc.model.TreeFactory =>
-
- def strip(c: Comment): Option[Inline] = {
- c.body match {
- case Body(List(Paragraph(Chain(List(Summary(inner)))))) => Some(inner)
- case _ => None
- }
- }
-
- def parseComment(s: String): Option[Inline] =
- strip(parse(s, "", scala.tools.nsc.util.NoPosition))
-
- def createBody(s: String) =
- parse(s, "", scala.tools.nsc.util.NoPosition).body
-}
-
-object Test extends Properties("CommentFactory") {
- val factory = {
- val settings = new doc.Settings((str: String) => {})
- val reporter = new scala.tools.nsc.reporters.ConsoleReporter(settings)
- val g = new Global(settings, reporter)
- (new Factory(g, settings) with CommentFactory with doc.model.TreeFactory)
- }
-
- def parse(src: String, dst: Inline) = {
- factory.parseComment(src) match {
- case Some(inline) =>
- inline == dst
- case _ =>
- false
- }
- }
-
- property("parse") = parse(
- "/** One two three */",
- Text("One two three")
- )
- property("parse") = parse(
- "/** One `two` three */",
- Chain(List(Text("One "), Monospace(Text("two")), Text(" three")))
- )
-
- property("parse") = parse(
- """
-/** One two
- * three */""",
- Text("One two\nthree")
- )
- property("parse") = parse(
- """
-/** One `two`
- * three */""",
- Chain(List(Text("One "), Monospace(Text("two")), Text("\n"), Text("three")))
- )
-
- property("parse") = parse(
- """
-/** One `two`
- * three */""",
- Chain(List(Text("One "), Monospace(Text("two")), Text("\n"), Text(" three")))
- )
-
- property("parse") = parse(
- """
-/** One
- * `two` three */""",
- Chain(List(Text("One"), Text("\n"), Monospace(Text("two")), Text(" three")))
- )
-
- property("Trac #4361 - ^...^") = parse(
- """
-/**
- * hello ^world^ */""",
- Chain(List(Text("hello "), Superscript(Text("world"))))
- )
-
- property("Trac #4361 - single ^ symbol") = parse(
- """
-/**
- *
- * hello ^world
- *
- *
- */""",
- Chain(List(Text(""), Text("\n"),
-
-
- HtmlTag("\nhello ^world\n
")))
- )
-
- property("Trac #4366 - body") = {
- val body = factory.createBody(
- """
- /**
- * foo
has been deprecated and will be removed in a future version. Please call bar
instead.
- */
- """
- )
-
- body == Body(List(Paragraph(Chain(List(
- Summary(Chain(List(HtmlTag("foo
has been deprecated and will be removed in a future version. Please call bar
instead."), Text("\n"), Text(""))))
- )))))
- }
-
- property("Trac #4366 - summary") = {
- val body = factory.createBody(
- """
- /**
- * foo
has been deprecated and will be removed in a future version. Please call bar
instead.
- */
- """
- )
- body.summary == Some(Chain(List(HtmlTag("foo
has been deprecated and will be removed in a future version. Please call bar
instead."), Text("\n"), Text(""))))
- }
-
- property("Trac #4358 - body") = {
- factory.createBody(
- """
- /**
- * Implicit conversion that invokes the expect
method on the EasyMock
companion object (i.e., the
- * static expect
method in Java class org.easymock.EasyMock
).
- */
- """
- ) match {
- case Body(List(Paragraph(Chain(List(Summary(Chain(List(Chain(List(
- Text("Implicit conversion that invokes the "),
- HtmlTag("expect
"),
- Text(" method on the "),
- HtmlTag("EasyMock
"),
- Text(" companion object ("),
- HtmlTag("i.e."),
- Text(", the\nstatic "),
- HtmlTag("expect
"),
- Text(" method in Java class "),
- HtmlTag("org.easymock.EasyMock
"),
- Text(")")
- )), Text(".")))), Text("\n")))))) =>
- true
- case other => {
- println(other)
- false
- }
- }
- }
-
-}
diff --git a/test/scaladoc/scalacheck/CommentFactoryTest.scala b/test/scaladoc/scalacheck/CommentFactoryTest.scala
new file mode 100644
index 0000000000..69c314a64c
--- /dev/null
+++ b/test/scaladoc/scalacheck/CommentFactoryTest.scala
@@ -0,0 +1,155 @@
+import org.scalacheck._
+import org.scalacheck.Prop._
+
+import scala.tools.nsc.Global
+import scala.tools.nsc.doc
+import scala.tools.nsc.doc.model.comment._
+
+class Factory(val g: Global, val s: doc.Settings)
+ extends doc.model.ModelFactory(g, s) {
+ thisFactory: Factory with CommentFactory with doc.model.TreeFactory =>
+
+ def strip(c: Comment): Option[Inline] = {
+ c.body match {
+ case Body(List(Paragraph(Chain(List(Summary(inner)))))) => Some(inner)
+ case _ => None
+ }
+ }
+
+ def parseComment(s: String): Option[Inline] =
+ strip(parse(s, "", scala.tools.nsc.util.NoPosition))
+
+ def createBody(s: String) =
+ parse(s, "", scala.tools.nsc.util.NoPosition).body
+}
+
+object Test extends Properties("CommentFactory") {
+ val factory = {
+ val settings = new doc.Settings((str: String) => {})
+ val reporter = new scala.tools.nsc.reporters.ConsoleReporter(settings)
+ val g = new Global(settings, reporter)
+ (new Factory(g, settings) with CommentFactory with doc.model.TreeFactory)
+ }
+
+ def parse(src: String, dst: Inline) = {
+ factory.parseComment(src) match {
+ case Some(inline) =>
+ inline == dst
+ case _ =>
+ false
+ }
+ }
+
+ property("parse") = parse(
+ "/** One two three */",
+ Text("One two three")
+ )
+ property("parse") = parse(
+ "/** One `two` three */",
+ Chain(List(Text("One "), Monospace(Text("two")), Text(" three")))
+ )
+
+ property("parse") = parse(
+ """
+/** One two
+ * three */""",
+ Text("One two\nthree")
+ )
+ property("parse") = parse(
+ """
+/** One `two`
+ * three */""",
+ Chain(List(Text("One "), Monospace(Text("two")), Text("\n"), Text("three")))
+ )
+
+ property("parse") = parse(
+ """
+/** One `two`
+ * three */""",
+ Chain(List(Text("One "), Monospace(Text("two")), Text("\n"), Text(" three")))
+ )
+
+ property("parse") = parse(
+ """
+/** One
+ * `two` three */""",
+ Chain(List(Text("One"), Text("\n"), Monospace(Text("two")), Text(" three")))
+ )
+
+ property("Trac #4361 - ^...^") = parse(
+ """
+/**
+ * hello ^world^ */""",
+ Chain(List(Text("hello "), Superscript(Text("world"))))
+ )
+
+ property("Trac #4361 - single ^ symbol") = parse(
+ """
+/**
+ *
+ * hello ^world
+ *
+ *
+ */""",
+ Chain(List(Text(""), Text("\n"),
+
+
+ HtmlTag("\nhello ^world\n
")))
+ )
+
+ property("Trac #4366 - body") = {
+ val body = factory.createBody(
+ """
+ /**
+ * foo
has been deprecated and will be removed in a future version. Please call bar
instead.
+ */
+ """
+ )
+
+ body == Body(List(Paragraph(Chain(List(
+ Summary(Chain(List(HtmlTag("foo
has been deprecated and will be removed in a future version. Please call bar
instead."), Text("\n"), Text(""))))
+ )))))
+ }
+
+ property("Trac #4366 - summary") = {
+ val body = factory.createBody(
+ """
+ /**
+ * foo
has been deprecated and will be removed in a future version. Please call bar
instead.
+ */
+ """
+ )
+ body.summary == Some(Chain(List(HtmlTag("foo
has been deprecated and will be removed in a future version. Please call bar
instead."), Text("\n"), Text(""))))
+ }
+
+ property("Trac #4358 - body") = {
+ factory.createBody(
+ """
+ /**
+ * Implicit conversion that invokes the expect
method on the EasyMock
companion object (i.e., the
+ * static expect
method in Java class org.easymock.EasyMock
).
+ */
+ """
+ ) match {
+ case Body(List(Paragraph(Chain(List(Summary(Chain(List(Chain(List(
+ Text("Implicit conversion that invokes the "),
+ HtmlTag("expect
"),
+ Text(" method on the "),
+ HtmlTag("EasyMock
"),
+ Text(" companion object ("),
+ HtmlTag("i.e."),
+ Text(", the\nstatic "),
+ HtmlTag("expect
"),
+ Text(" method in Java class "),
+ HtmlTag("org.easymock.EasyMock
"),
+ Text(")")
+ )), Text(".")))), Text("\n")))))) =>
+ true
+ case other => {
+ println(other)
+ false
+ }
+ }
+ }
+
+}
diff --git a/test/scaladoc/scalacheck/HtmlFactoryTest.flags b/test/scaladoc/scalacheck/HtmlFactoryTest.flags
new file mode 100644
index 0000000000..b2264ec4f4
--- /dev/null
+++ b/test/scaladoc/scalacheck/HtmlFactoryTest.flags
@@ -0,0 +1 @@
+-encoding UTF-8
\ No newline at end of file
diff --git a/test/scaladoc/scalacheck/HtmlFactoryTest.scala b/test/scaladoc/scalacheck/HtmlFactoryTest.scala
new file mode 100644
index 0000000000..5b6f75426e
--- /dev/null
+++ b/test/scaladoc/scalacheck/HtmlFactoryTest.scala
@@ -0,0 +1,730 @@
+import org.scalacheck._
+import org.scalacheck.Prop._
+
+import java.net.{URLClassLoader, URLDecoder}
+
+object XMLUtil {
+ import scala.xml._
+
+ def stripGroup(seq: Node): Node = {
+ seq match {
+ case group: Group => {
+ { group.nodes.map(stripGroup _) }
+ }
+ case e: Elem => {
+ val child = e.child.map(stripGroup _)
+ Elem(e.prefix, e.label, e.attributes, e.scope, child : _*)
+ }
+ case _ => seq
+ }
+ }
+}
+
+object Test extends Properties("HtmlFactory") {
+
+ final val RESOURCES = "test/scaladoc/resources/"
+
+ import scala.tools.nsc.doc.{DocFactory, Settings}
+ import scala.tools.nsc.doc.model.IndexModelFactory
+ import scala.tools.nsc.doc.html.HtmlFactory
+ import scala.tools.nsc.doc.html.page.ReferenceIndex
+
+ def getClasspath = {
+ // these things can be tricky
+ // this test previously relied on the assumption that the current thread's classloader is an url classloader and contains all the classpaths
+ // does partest actually guarantee this? to quote Leonard Nimoy: The answer, of course, is no.
+ // this test _will_ fail again some time in the future.
+ val paths = Thread.currentThread.getContextClassLoader.asInstanceOf[URLClassLoader].getURLs.map(u => URLDecoder.decode(u.getPath))
+ val morepaths = Thread.currentThread.getContextClassLoader.getParent.asInstanceOf[URLClassLoader].getURLs.map(u => URLDecoder.decode(u.getPath))
+ (paths ++ morepaths).mkString(java.io.File.pathSeparator)
+ }
+
+ def createFactory = {
+ val settings = new Settings({Console.err.println(_)})
+ settings.classpath.value = getClasspath
+
+ val reporter = new scala.tools.nsc.reporters.ConsoleReporter(settings)
+ new DocFactory(reporter, settings)
+ }
+
+ def createTemplates(basename: String) = {
+ val result = scala.collection.mutable.Map[String, scala.xml.NodeSeq]()
+
+ createFactory.makeUniverse(Left(List(RESOURCES+basename))) match {
+ case Some(universe) => {
+ val index = IndexModelFactory.makeIndex(universe)
+ (new HtmlFactory(universe, index)).writeTemplates((page) => {
+ result += (page.absoluteLinkTo(page.path) -> page.body)
+ })
+ }
+ case _ => ;
+ }
+
+ result
+ }
+
+ def createReferenceIndex(basename: String) = {
+ createFactory.makeUniverse(Left(List(RESOURCES+basename))) match {
+ case Some(universe) => {
+ val index = IndexModelFactory.makeIndex(universe)
+ val pages = index.firstLetterIndex.map({
+ case (key, value) => {
+ val page = new ReferenceIndex(key, index, universe)
+ page.absoluteLinkTo(page.path) -> page.body
+ }
+ })
+ Some(pages)
+ }
+ case _ =>
+ None
+ }
+ }
+
+ def createTemplate(scala: String) = {
+ val html = scala.stripSuffix(".scala") + ".html"
+ createTemplates(scala)(html)
+ }
+
+ /**
+ * This tests the text without the markup - ex:
+ *
+ *
+ *
+ * implicit
+ * def
+ *
+ *
+ * test(): Int
+ *
+ *
+ *
+ * becomes:
+ *
+ * implicit def test(): Int
+ *
+ * and is required to contain the text in the given checks
+ *
+ * NOTE: Comparison is done ignoring all whitespace
+ */
+ def checkText(scalaFile: String, debug: Boolean = true)(checks: (Option[String], String, Boolean)*): Boolean = {
+ val htmlFile = scalaFile.stripSuffix(".scala") + ".html"
+ val htmlAllFiles = createTemplates(scalaFile)
+ var result = true
+
+ for ((fileHint, check, expected) <- checks) {
+ // resolve the file to be checked
+ val fileName = fileHint match {
+ case Some(file) =>
+ if (file endsWith ".html")
+ file
+ else
+ file + ".html"
+ case None =>
+ htmlFile
+ }
+ val fileTextPretty = htmlAllFiles(fileName).text.replace('→',' ').replaceAll("\\s+"," ")
+ val fileText = fileTextPretty.replaceAll(" ", "")
+
+ val checkTextPretty = check.replace('→',' ').replaceAll("\\s+"," ")
+ val checkText = checkTextPretty.replaceAll(" ", "")
+
+ val checkValue = fileText.contains(checkText) == expected
+ if (debug && (!checkValue)) {
+ Console.err.println("")
+ Console.err.println("HTML Check failed for resource file " + scalaFile + ":")
+ Console.err.println("Could not match: \n" + checkTextPretty)
+ Console.err.println("In the extracted HTML text: \n" + fileTextPretty)
+ Console.err.println("NOTE: The whitespaces are eliminated before matching!")
+ Console.err.println("")
+ }
+ result &&= checkValue
+ }
+
+ result
+ }
+
+
+ def shortComments(root: scala.xml.Node) =
+ XMLUtil.stripGroup(root).descendant.flatMap {
+ case e: scala.xml.Elem => {
+ if (e.attribute("class").toString.contains("shortcomment")) {
+ Some(e)
+ } else {
+ None
+ }
+ }
+ case _ => None
+ }
+
+ property("Trac #3790") = {
+ createTemplate("Trac3790.scala") match {
+ case node: scala.xml.Node => {
+ val comments = shortComments(node)
+
+ comments.exists { _.toString.contains(">A lazy String\n") } &&
+ comments.exists { _.toString.contains(">A non-lazy String\n") }
+ }
+ case _ => false
+ }
+ }
+
+ property("Trac #4306") = {
+ val files = createTemplates("Trac4306.scala")
+ files("com/example/trac4306/foo/package$$Bar.html") != None
+ }
+
+ property("Trac #4366") = {
+ createTemplate("Trac4366.scala") match {
+ case node: scala.xml.Node => {
+ shortComments(node).exists { n => {
+ val str = n.toString
+ str.contains("foo
") && str.contains("")
+ } }
+ }
+ case _ => false
+ }
+ }
+
+ property("Trac #4358") = {
+ createTemplate("Trac4358.scala") match {
+ case node: scala.xml.Node =>
+ ! shortComments(node).exists {
+ _.toString.contains("i.")
+ }
+ case _ => false
+ }
+ }
+
+ property("Trac #4180") = {
+ createTemplate("Trac4180.scala") != None
+ }
+
+ property("Trac #4372") = {
+ createTemplate("Trac4372.scala") match {
+ case node: scala.xml.Node => {
+ val html = node.toString
+ html.contains("+:") &&
+ html.contains("-:") &&
+ html.contains("""(n: Int): Int""")
+ }
+ case _ => false
+ }
+ }
+
+ property("Trac #4374 - public") = {
+ val files = createTemplates("Trac4374.scala")
+ files("WithPublic.html") match {
+ case node: scala.xml.Node => {
+ val s = node.toString
+ s.contains("""href="WithPublic$.html"""") &&
+ files.get("WithPublic$.html") != None
+ }
+ case _ => false
+ }
+ }
+
+ property("Trac #4374 - private") = {
+ val files = createTemplates("Trac4374.scala")
+ files("WithPrivate.html") match {
+ case node: scala.xml.Node => {
+ val s = node.toString
+ ! s.contains("""href="WithPrivate$.html"""") &&
+ files.get("WithPrivate$.html") == None
+ }
+ case _ => false
+ }
+ }
+
+ property("Trac #3484") = {
+ val files = createTemplates("Trac3484.scala")
+
+ files("Collection.html") match {
+ case node: scala.xml.Node => {
+ val s = node.toString
+ s.contains(""": Traversable[B]""")
+ }
+ case _ => false
+ }
+ }
+
+ property("Trac #3484 - SR704") = {
+ val files = createTemplates("Trac3484.scala")
+
+ files("SR704.html") match {
+ case node: scala.xml.Node => {
+ val s = node.toString
+ s.contains("Hello Mister John.")
+ }
+ case _ => false
+ }
+ }
+
+ property("Trac #4325 - files") = {
+ val files = createTemplates("Trac4325.scala")
+
+ files.get("WithSynthetic.html") != None &&
+ files.get("WithSynthetic$.html") == None &&
+ files.get("WithObject.html") != None &&
+ files.get("WithObject$.html") != None
+ }
+
+ property("Trac #4325 - Don't link to syntetic companion") = {
+ val files = createTemplates("Trac4325.scala")
+
+ files("WithSynthetic.html") match {
+ case node: scala.xml.Node => {
+ val s = node.toString
+ ! s.contains("""href="WithSynthetic$.html"""")
+ }
+ case _ => false
+ }
+ }
+
+ property("Trac #4325 - Link to companion") = {
+ val files = createTemplates("Trac4325.scala")
+
+ files("WithObject.html") match {
+ case node: scala.xml.Node => {
+ val s = node.toString
+ s.contains("""href="WithObject$.html"""")
+ }
+ case _ => false
+ }
+ }
+
+ property("Trac #4420 - no whitespace at end of line") = {
+ val files = createTemplates("Trac4420.scala")
+
+ files("TestA.html") match {
+ case node: scala.xml.Node => {
+ val s = node.toString
+ s.contains("""See YYY for more details""")
+ }
+ case _ => false
+ }
+ }
+ //
+ // property("Trac #484 - refinements and existentials") = {
+ // val files = createTemplates("Trac484.scala")
+ // val lines = """
+ // |type Bar = AnyRef { type Dingus <: T forSome { type T <: String } }
+ // |type Foo = AnyRef { ... /* 3 definitions in type refinement */ }
+ // |def g(x: T forSome { type T <: String }): String
+ // |def h(x: Float): AnyRef { def quux(x: Int,y: Int): Int }
+ // |def hh(x: Float): AnyRef { def quux(x: Int,y: Int): Int }
+ // |def j(x: Int): Bar
+ // |def k(): AnyRef { type Dingus <: T forSome { type T <: String } }
+ // """.stripMargin.trim.lines map (_.trim)
+ //
+ // files("RefinementAndExistentials.html") match {
+ // case node: scala.xml.Node => {
+ // val s = node.text.replaceAll("\\s+", " ")
+ // lines forall (s contains _)
+ // }
+ // case _ => false
+ // }
+ // }
+
+ property("Trac #4289") = {
+ val files = createTemplates("Trac4289.scala")
+
+ files("Subclass.html") match {
+ case node: scala.xml.Node => {
+ node.toString.contains {
+ """- returns
123
"""
+ }
+ }
+ case _ => false
+ }
+ }
+
+ property("Trac #4409") = {
+ createTemplate("Trac4409.scala") match {
+ case node: scala.xml.Node => {
+ ! node.toString.contains("""since""")
+ }
+ case _ => false
+ }
+ }
+
+ property("Trac #4452") = {
+ createTemplate("Trac4452.scala") match {
+ case node: scala.xml.Node =>
+ ! node.toString.contains(">*")
+ case _ => false
+ }
+ }
+
+ property("Trac #4471") = {
+ createReferenceIndex("Trac4471.scala") match {
+ case Some(pages) =>
+ (pages.get("index/index-f.html") match {
+ case Some(node) => node.toString.contains(">A")
+ case _ => false
+ }) && (pages.get("index/index-b.html") match {
+ case Some(node) => node.toString.contains(">bar")
+ case _ => false
+ })
+ case _ => false
+ }
+ }
+
+ property("SI-4641") = {
+ createReferenceIndex("SI_4641.scala") match {
+ case Some(pages) => pages.contains("index/index-_.html")
+ case _ => false
+ }
+ }
+
+ property("SI-4421") = {
+ createTemplate("SI_4421.scala") match {
+ case node: scala.xml.Node => {
+ val html = node.toString
+ html.contains(">Example:") && html.contains(">Note<")
+ }
+ case _ => false
+ }
+ }
+
+ property("SI-4589") = {
+ createTemplate("SI_4589.scala") match {
+ case node: scala.xml.Node => {
+ val html = node.toString
+ html.contains(">x0123456789: <") &&
+ html.contains(">x012345678901234567890123456789: <")
+ }
+ case _ => false
+ }
+ }
+
+ property("Should decode symbolic type alias name.") = {
+ createTemplate("SI_4715.scala") match {
+ case node: scala.xml.Node => {
+ val html = node.toString
+ html.contains(">: :+:[<")
+ }
+ case _ => false
+ }
+ }
+
+ property("Shouldn't drop type arguments to aliased tuple.") = {
+ createTemplate("SI_4676.scala") match {
+ case node: scala.xml.Node => {
+ node.toString.contains(">ss: (String, String)<")
+ }
+ case _ => false
+ }
+ }
+
+ property("Default arguments of synthesized constructor") = {
+ val files = createTemplates("SI_4287.scala")
+
+ files("ClassWithSugar.html") match {
+ case node: scala.xml.Node => {
+ node.toString.contains(">123<")
+ }
+ case _ => false
+ }
+ }
+
+ property("Default arguments of synthesized constructor") = {
+ createTemplate("SI_4507.scala") match {
+ case node: scala.xml.Node =>
+ ! node.toString.contains("- returns silently when evaluating true and true
")
+ case _ => false
+ }
+ }
+
+ property("Use cases and links should not crash scaladoc") = {
+ createTemplate("SI_4898.scala")
+ true
+ }
+
+ property("Use cases should override their original members") =
+ checkText("SI_5054_q1.scala")(
+ (None,"""def test(): Int""", true)
+ //Disabled because the full signature is now displayed
+ //(None,"""def test(implicit lost: Int): Int""", false)
+ )
+
+ property("Use cases should keep their flags - final should not be lost") =
+ checkText("SI_5054_q2.scala")((None, """final def test(): Int""", true))
+
+ property("Use cases should keep their flags - implicit should not be lost") =
+ checkText("SI_5054_q3.scala")((None, """implicit def test(): Int""", true))
+
+ property("Use cases should keep their flags - real abstract should not be lost") =
+ checkText("SI_5054_q4.scala")((None, """abstract def test(): Int""", true))
+
+ property("Use cases should keep their flags - traits should not be affected") =
+ checkText("SI_5054_q5.scala")((None, """def test(): Int""", true))
+
+ property("Use cases should keep their flags - traits should not be affected") =
+ checkText("SI_5054_q6.scala")((None, """abstract def test(): Int""", true))
+
+ property("Use case individual signature test") =
+ checkText("SI_5054_q7.scala")(
+ (None, """abstract def test2(explicit: Int): Int [use case] This takes the explicit value passed.""", true),
+ (None, """abstract def test1(): Int [use case] This takes the implicit value in scope.""", true)
+ )
+
+ property("Display correct \"Definition classes\"") =
+ checkText("SI_5287.scala")(
+ (None,
+ """def method(): Int
+ [use case] The usecase explanation
+ [use case] The usecase explanation
+ Definition Classes SI_5287 SI_5287_B SI_5287_A""", true)
+ ) // the explanation appears twice, as small comment and full comment
+
+ property("Correct comment inheritance for overriding") =
+ checkText("implicit-inheritance-override.scala")(
+ (Some("Base"),
+ """def function[T](arg1: T, arg2: String): Double
+ The base comment.
+ The base comment. And another sentence...
+ T the type of the first argument
+ arg1 The T term comment
+ arg2 The string comment
+ returns The return comment
+ """, true),
+ (Some("DerivedA"),
+ """def function[T](arg1: T, arg2: String): Double
+ Overriding the comment, the params and returns comments should stay the same.
+ Overriding the comment, the params and returns comments should stay the same.
+ T the type of the first argument
+ arg1 The T term comment
+ arg2 The string comment
+ returns The return comment
+ """, true),
+ (Some("DerivedB"),
+ """def function[T](arg1: T, arg2: String): Double
+ T the type of the first argument
+ arg1 The overridden T term comment
+ arg2 The overridden string comment
+ returns The return comment
+ """, true),
+ (Some("DerivedC"),
+ """def function[T](arg1: T, arg2: String): Double
+ T the type of the first argument
+ arg1 The T term comment
+ arg2 The string comment
+ returns The overridden return comment
+ """, true),
+ (Some("DerivedD"),
+ """def function[T](arg1: T, arg2: String): Double
+ T The overriden type parameter comment
+ arg1 The T term comment
+ arg2 The string comment
+ returns The return comment
+ """, true)
+ )
+
+ for (useCaseFile <- List("UseCaseInheritance", "UseCaseOverrideInheritance")) {
+ property("Correct comment inheritance for usecases") =
+ checkText("implicit-inheritance-usecase.scala")(
+ (Some(useCaseFile),
+ """def missing_arg[T](arg1: T): Double
+ [use case]
+ [use case]
+ T The type parameter
+ arg1 The T term comment
+ returns The return comment
+ """, true),
+ (Some(useCaseFile),
+ """def missing_targ(arg1: Int, arg2: String): Double
+ [use case]
+ [use case]
+ arg1 The T term comment
+ arg2 The string comment
+ returns The return comment
+ """, true),
+ (Some(useCaseFile),
+ """def overridden_arg1[T](implicit arg1: T, arg2: String): Double
+ [use case]
+ [use case]
+ T The type parameter
+ arg1 The overridden T term comment
+ arg2 The string comment
+ returns The return comment
+ """, true),
+ (Some(useCaseFile),
+ """def overridden_targ[T](implicit arg1: T, arg2: String): Double
+ [use case]
+ [use case]
+ T The overridden type parameter comment
+ arg1 The T term comment
+ arg2 The string comment
+ returns The return comment
+ """, true),
+ (Some(useCaseFile),
+ """def overridden_return[T](implicit arg1: T, arg2: String): Double
+ [use case]
+ [use case]
+ T The type parameter
+ arg1 The T term comment
+ arg2 The string comment
+ returns The overridden return comment
+ """, true),
+ (Some(useCaseFile),
+ """def added_arg[T](implicit arg1: T, arg2: String, arg3: Float): Double
+ [use case]
+ [use case]
+ T The type parameter
+ arg1 The T term comment
+ arg2 The string comment
+ arg3 The added float comment
+ returns The return comment
+ """, true),
+ (Some(useCaseFile),
+ """def overridden_comment[T](implicit arg1: T, arg2: String): Double
+ [use case] The overridden comment.
+ [use case] The overridden comment.
+ T The type parameter
+ arg1 The T term comment
+ arg2 The string comment
+ returns The return comment
+ """, true)
+ )
+ }
+
+ property("Correct explicit inheritance for override") =
+ checkText("explicit-inheritance-override.scala")(
+ (Some("InheritDocDerived"),
+ """def function[T](arg1: T, arg2: String): Double
+ Starting line
+ Starting line
+ The base comment. And another sentence...
+ The base comment. And another sentence...
+ Ending line
+ T StartT the type of the first argument EndT
+ arg1 Start1 The T term comment End1
+ arg2 Start2 The string comment End2
+ returns StartRet The return comment EndRet""", true),
+ (Some("InheritDocDerived"),
+ """Definition Classes InheritDocDerived → InheritDocBase
+ Example: StartExample function[Int](3, "something") EndExample
+ Version StartVer 0.0.2 EndVer
+ Since StartSince 0.0.1 EndSince
+ Exceptions thrown
+ SomeException StartEx if the function is not called with correct parameters EndEx
+ SomeOtherException StartSOE Should Warn EndSOE
+ To do StartTodo Call mom. And dad! EndTodo
+ Note StartNote Be careful! EndNote
+ See also StartSee The Manual EndSee
+ """, true))
+
+ property("Correct explicit inheritance for usecase") =
+ checkText("explicit-inheritance-usecase.scala")(
+ (Some("UseCaseInheritDoc"),
+ """def function[T](arg1: T, arg2: String): Double
+ [use case] Starting line
+ [use case] Starting line
+ The base comment. And another sentence...
+ The base comment. And another sentence...
+ Ending line
+ T StartT the type of the first argument EndT
+ arg1 Start1 The T term comment End1
+ arg2 Start2 The string comment End2
+ returns StartRet The return comment EndRet""", true),
+ (Some("UseCaseInheritDoc"),
+ """Example: StartExample function[Int](3,"something") EndExample
+ Version StartVer 0.0.2 EndVer
+ Since StartSince 0.0.1 EndSince
+ Exceptions thrown
+ SomeException StartEx if the function is not called with correct parameters EndEx
+ SomeOtherException StartSOE Should Warn EndSOE
+ To do StartTodo Call mom. And dad! EndTodo
+ Note StartNote Be careful! EndNote
+ See also StartSee The Manual EndSee
+ """, true))
+
+ property("Correct explicit inheritance in corner cases") =
+ checkText("inheritdoc-corner-cases.scala")(
+ (Some("D"),
+ """def hello1: Int
+ Inherited: Hello 1 comment
+ Inherited: Hello 1 comment
+ Definition Classes D → A
+ """, true),
+ (Some("D"),
+ """def hello2: Int
+ Inherited: Hello 2 comment
+ Inherited: Hello 2 comment
+ Definition Classes D → B
+ """, true),
+ (Some("G"),
+ """def hello1: Int
+ Inherited: Hello 1 comment
+ Inherited: Hello 1 comment
+ Definition Classes G → D → A
+ """, true),
+ (Some("G"),
+ """def hello2: Int
+ Inherited: Hello 2 comment
+ Inherited: Hello 2 comment
+ Definition Classes G → D → B
+ """, true),
+ (Some("I"),
+ """def hello1(i: Int): Unit
+ [use case] Inherited: Hello 1 comment
+ [use case] Inherited: Hello 1 comment
+ Definition Classes I → G → D → A
+ """, true)
+ // traits E, F and H shouldn't crash scaladoc but we don't need to check the output
+ )
+
+ property("Indentation normalization for code blocks") = {
+ val files = createTemplates("code-indent.scala")
+
+ files("C.html") match {
+ case node: scala.xml.Node => {
+ val s = node.toString
+ s.contains("a typicial indented\ncomment on multiple\ncomment lines
") &&
+ s.contains("one liner
") &&
+ s.contains("two lines, one useful
") &&
+ s.contains("line1\nline2\nline3\nline4
") &&
+ s.contains("a ragged example\na (condition)\n the t h e n branch\nan alternative\n the e l s e branch
") &&
+ s.contains("l1\n\nl2\n\nl3\n\nl4\n\nl5
")
+ }
+ case _ => false
+ }
+ }
+
+ {
+ val files = createTemplates("basic.scala")
+ //println(files)
+
+ property("class") = files.get("com/example/p1/Clazz.html") match {
+ case Some(node: scala.xml.Node) => {
+ property("implicit convertion") =
+ node.toString contains "implicit "
+
+ property("gt4s") =
+ node.toString contains "title=\"gt4s: $colon$colon\""
+
+ property("gt4s of a deprecated method") =
+ node.toString contains "title=\"gt4s: $colon$colon$colon$colon. Deprecated: "
+ true
+ }
+ case _ => false
+ }
+ property("package") = files.get("com/example/p1/package.html") != None
+
+ property("package object") = files("com/example/p1/package.html") match {
+ case node: scala.xml.Node =>
+ node.toString contains "com.example.p1.package#packageObjectMethod"
+ case _ => false
+ }
+
+ property("lower bound") = files("com/example/p1/LowerBound.html") match {
+ case node: scala.xml.Node => true
+ case _ => false
+ }
+
+ property("upper bound") = files("com/example/p1/UpperBound.html") match {
+ case node: scala.xml.Node => true
+ case _ => false
+ }
+ }
+}
diff --git a/test/scaladoc/scalacheck/IndexScriptTest.scala b/test/scaladoc/scalacheck/IndexScriptTest.scala
new file mode 100644
index 0000000000..5aef38e00a
--- /dev/null
+++ b/test/scaladoc/scalacheck/IndexScriptTest.scala
@@ -0,0 +1,52 @@
+import org.scalacheck._
+import org.scalacheck.Prop._
+
+import scala.tools.nsc.doc
+import scala.tools.nsc.doc.html.page.IndexScript
+import java.net.{URLClassLoader, URLDecoder}
+
+object Test extends Properties("IndexScript") {
+
+ def getClasspath = {
+ val loader = Thread.currentThread.getContextClassLoader
+ val paths = loader.asInstanceOf[URLClassLoader].getURLs
+ val morepaths = loader.getParent.asInstanceOf[URLClassLoader].getURLs
+ (paths ++ morepaths).map(u => URLDecoder.decode(u.getPath)).mkString(java.io.File.pathSeparator)
+ }
+
+ val docFactory = {
+ val settings = new doc.Settings({Console.err.println(_)})
+ settings.classpath.value = getClasspath
+ val reporter = new scala.tools.nsc.reporters.ConsoleReporter(settings)
+ new doc.DocFactory(reporter, settings)
+ }
+
+ val indexModelFactory = doc.model.IndexModelFactory
+
+ def createIndexScript(path: String) =
+ docFactory.makeUniverse(Left(List(path))) match {
+ case Some(universe) => {
+ val index = new IndexScript(universe,
+ indexModelFactory.makeIndex(universe))
+ Some(index)
+ }
+ case _ =>
+ None
+ }
+
+ property("allPackages") = {
+ createIndexScript("src/compiler/scala/tools/nsc/doc/html/page/Index.scala") match {
+ case Some(index) =>
+ index.allPackages.map(_.toString) == List(
+ "scala",
+ "scala.tools",
+ "scala.tools.nsc",
+ "scala.tools.nsc.doc",
+ "scala.tools.nsc.doc.html",
+ "scala.tools.nsc.doc.html.page"
+ )
+ case None =>
+ false
+ }
+ }
+}
diff --git a/test/scaladoc/scalacheck/IndexTest.scala b/test/scaladoc/scalacheck/IndexTest.scala
new file mode 100644
index 0000000000..29e337da2b
--- /dev/null
+++ b/test/scaladoc/scalacheck/IndexTest.scala
@@ -0,0 +1,82 @@
+import org.scalacheck._
+import org.scalacheck.Prop._
+
+import scala.tools.nsc.doc
+import scala.tools.nsc.doc.html.page.Index
+import java.net.{URLClassLoader, URLDecoder}
+
+object Test extends Properties("Index") {
+
+ def getClasspath = {
+ // these things can be tricky
+ // this test previously relied on the assumption that the current thread's classloader is an url classloader and contains all the classpaths
+ // does partest actually guarantee this? to quote Leonard Nimoy: The answer, of course, is no.
+ // this test _will_ fail again some time in the future.
+ val paths = Thread.currentThread.getContextClassLoader.asInstanceOf[URLClassLoader].getURLs.map(u => URLDecoder.decode(u.getPath))
+ val morepaths = Thread.currentThread.getContextClassLoader.getParent.asInstanceOf[URLClassLoader].getURLs.map(u => URLDecoder.decode(u.getPath))
+ (paths ++ morepaths).mkString(java.io.File.pathSeparator)
+ }
+
+ val docFactory = {
+ val settings = new doc.Settings({Console.err.println(_)})
+
+ settings.classpath.value = getClasspath
+ println(settings.classpath.value)
+
+ val reporter = new scala.tools.nsc.reporters.ConsoleReporter(settings)
+
+ new doc.DocFactory(reporter, settings)
+ }
+
+ val indexModelFactory = doc.model.IndexModelFactory
+
+ def createIndex(path: String): Option[Index] = {
+
+ val maybeUniverse = {
+ //val stream = new java.io.ByteArrayOutputStream
+ //val original = Console.out
+ //Console.setOut(stream)
+
+ val result = docFactory.makeUniverse(Left(List(path)))
+
+ // assert(stream.toString == "model contains 2 documentable templates\n")
+ //Console.setOut(original)
+
+ result
+ }
+
+ maybeUniverse match {
+ case Some(universe) => {
+ val index = new Index(universe, indexModelFactory.makeIndex(universe))
+ return Some(index)
+ }
+ case _ => return None
+ }
+
+ }
+
+ property("path") = {
+ createIndex("src/compiler/scala/tools/nsc/doc/html/page/Index.scala") match {
+ case Some(index) =>
+ index.path == List("index.html")
+ case None => false
+ }
+ }
+
+ property("title") = {
+ createIndex("src/compiler/scala/tools/nsc/doc/html/page/Index.scala") match {
+ case Some(index) =>
+ index.title == ""
+
+ case None => false
+ }
+ }
+ property("browser contants a script element") = {
+ createIndex("src/compiler/scala/tools/nsc/doc/html/page/Index.scala") match {
+ case Some(index) =>
+ (index.browser \ "script").size == 1
+
+ case None => false
+ }
+ }
+}
--
cgit v1.2.3