diff options
Diffstat (limited to 'test')
28 files changed, 916 insertions, 66 deletions
diff --git a/test/scaladoc/resources/doc-root/Any.scala b/test/scaladoc/resources/doc-root/Any.scala new file mode 100644 index 0000000000..031b7d9d8c --- /dev/null +++ b/test/scaladoc/resources/doc-root/Any.scala @@ -0,0 +1,114 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2010, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala + +/** Class `Any` is the root of the Scala class hierarchy. Every class in a Scala + * execution environment inherits directly or indirectly from this class. + */ +abstract class Any { + /** Compares the receiver object (`this`) with the argument object (`that`) for equivalence. + * + * Any implementation of this method should be an [[http://en.wikipedia.org/wiki/Equivalence_relation equivalence relation]]: + * + * - It is reflexive: for any instance `x` of type `Any`, `x.equals(x)` should return `true`. + * - It is symmetric: for any instances `x` and `y` of type `Any`, `x.equals(y)` should return `true` if and + * only if `y.equals(x)` returns `true`. + * - It is transitive: for any instances `x`, `y`, and `z` of type `AnyRef` if `x.equals(y)` returns `true` and + * `y.equals(z)` returns `true`, then `x.equals(z)` should return `true`. + * + * If you override this method, you should verify that your implementation remains an equivalence relation. + * Additionally, when overriding this method it is usually necessary to override `hashCode` to ensure that + * objects which are "equal" (`o1.equals(o2)` returns `true`) hash to the same [[scala.Int]]. + * (`o1.hashCode.equals(o2.hashCode)`). + * + * @param that the object to compare against this object for equality. + * @return `true` if the receiver object is equivalent to the argument; `false` otherwise. + */ + def equals(that: Any): Boolean + + /** Calculate a hash code value for the object. + * + * The default hashing algorithm is platform dependent. + * + * Note that it is allowed for two objects to have identical hash codes (`o1.hashCode.equals(o2.hashCode)`) yet + * not be equal (`o1.equals(o2)` returns `false`). A degenerate implementation could always return `0`. + * However, it is required that if two objects are equal (`o1.equals(o2)` returns `true`) that they have + * identical hash codes (`o1.hashCode.equals(o2.hashCode)`). Therefore, when overriding this method, be sure + * to verify that the behavior is consistent with the `equals` method. + * + * @return the hash code value for this object. + */ + def hashCode(): Int + + /** Returns a string representation of the object. + * + * The default representation is platform dependent. + * + * @return a string representation of the object. + */ + def toString(): String + + /** Returns the runtime class representation of the object. + * + * @return a class object corresponding to the runtime type of the receiver. + */ + def getClass(): Class[_] + + /** Test two objects for equality. + * The expression `x == that` is equivalent to `if (x eq null) that eq null else x.equals(that)`. + * + * @param that the object to compare against this object for equality. + * @return `true` if the receiver object is equivalent to the argument; `false` otherwise. + */ + final def ==(that: Any): Boolean = this equals that + + /** Test two objects for inequality. + * + * @param that the object to compare against this object for equality. + * @return `true` if !(this == that), false otherwise. + */ + final def != (that: Any): Boolean = !(this == that) + + /** Equivalent to `x.hashCode` except for boxed numeric types and `null`. + * For numerics, it returns a hash value which is consistent + * with value equality: if two value type instances compare + * as true, then ## will produce the same hash value for each + * of them. + * For `null` returns a hashcode where `null.hashCode` throws a + * `NullPointerException`. + * + * @return a hash value consistent with == + */ + final def ##(): Int = sys.error("##") + + /** Test whether the dynamic type of the receiver object is `T0`. + * + * Note that the result of the test is modulo Scala's erasure semantics. + * Therefore the expression `1.isInstanceOf[String]` will return `false`, while the + * expression `List(1).isInstanceOf[List[String]]` will return `true`. + * In the latter example, because the type argument is erased as part of compilation it is + * not possible to check whether the contents of the list are of the specified type. + * + * @return `true` if the receiver object is an instance of erasure of type `T0`; `false` otherwise. + */ + def isInstanceOf[T0]: Boolean = sys.error("isInstanceOf") + + /** Cast the receiver object to be of type `T0`. + * + * Note that the success of a cast at runtime is modulo Scala's erasure semantics. + * Therefore the expression `1.asInstanceOf[String]` will throw a `ClassCastException` at + * runtime, while the expression `List(1).asInstanceOf[List[String]]` will not. + * In the latter example, because the type argument is erased as part of compilation it is + * not possible to check whether the contents of the list are of the requested type. + * + * @throws ClassCastException if the receiver object is not an instance of the erasure of type `T0`. + * @return the receiver object. + */ + def asInstanceOf[T0]: T0 = sys.error("asInstanceOf") +} diff --git a/test/scaladoc/resources/doc-root/AnyRef.scala b/test/scaladoc/resources/doc-root/AnyRef.scala new file mode 100644 index 0000000000..1eefb0c806 --- /dev/null +++ b/test/scaladoc/resources/doc-root/AnyRef.scala @@ -0,0 +1,131 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2010, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala + +/** Class `AnyRef` is the root class of all ''reference types''. + * All types except the value types descend from this class. + */ +trait AnyRef extends Any { + + /** The equality method for reference types. Default implementation delegates to `eq`. + * + * See also `equals` in [[scala.Any]]. + * + * @param that the object to compare against this object for equality. + * @return `true` if the receiver object is equivalent to the argument; `false` otherwise. + */ + def equals(that: Any): Boolean = this eq that + + /** The hashCode method for reference types. See hashCode in [[scala.Any]]. + * + * @return the hash code value for this object. + */ + def hashCode: Int = sys.error("hashCode") + + /** Creates a String representation of this object. The default + * representation is platform dependent. On the java platform it + * is the concatenation of the class name, "@", and the object's + * hashcode in hexadecimal. + * + * @return a String representation of the object. + */ + def toString: String = sys.error("toString") + + /** Executes the code in `body` with an exclusive lock on `this`. + * + * @param body the code to execute + * @return the result of `body` + */ + def synchronized[T](body: => T): T + + /** Tests whether the argument (`arg0`) is a reference to the receiver object (`this`). + * + * The `eq` method implements an [[http://en.wikipedia.org/wiki/Equivalence_relation equivalence relation]] on + * non-null instances of `AnyRef`, and has three additional properties: + * + * - It is consistent: for any non-null instances `x` and `y` of type `AnyRef`, multiple invocations of + * `x.eq(y)` consistently returns `true` or consistently returns `false`. + * - For any non-null instance `x` of type `AnyRef`, `x.eq(null)` and `null.eq(x)` returns `false`. + * - `null.eq(null)` returns `true`. + * + * When overriding the `equals` or `hashCode` methods, it is important to ensure that their behavior is + * consistent with reference equality. Therefore, if two objects are references to each other (`o1 eq o2`), they + * should be equal to each other (`o1 == o2`) and they should hash to the same value (`o1.hashCode == o2.hashCode`). + * + * @param that the object to compare against this object for reference equality. + * @return `true` if the argument is a reference to the receiver object; `false` otherwise. + */ + final def eq(that: AnyRef): Boolean = sys.error("eq") + + /** Equivalent to `!(this eq that)`. + * + * @param that the object to compare against this object for reference equality. + * @return `true` if the argument is not a reference to the receiver object; `false` otherwise. + */ + final def ne(that: AnyRef): Boolean = !(this eq that) + + /** The expression `x == that` is equivalent to `if (x eq null) that eq null else x.equals(that)`. + * + * @param arg0 the object to compare against this object for equality. + * @return `true` if the receiver object is equivalent to the argument; `false` otherwise. + */ + final def ==(that: AnyRef): Boolean = + if (this eq null) that eq null + else this equals that + + /** Create a copy of the receiver object. + * + * The default implementation of the `clone` method is platform dependent. + * + * @note not specified by SLS as a member of AnyRef + * @return a copy of the receiver object. + */ + protected def clone(): AnyRef + + /** Called by the garbage collector on the receiver object when there + * are no more references to the object. + * + * The details of when and if the `finalize` method is invoked, as + * well as the interaction between `finalize` and non-local returns + * and exceptions, are all platform dependent. + * + * @note not specified by SLS as a member of AnyRef + */ + protected def finalize(): Unit + + /** A representation that corresponds to the dynamic class of the receiver object. + * + * The nature of the representation is platform dependent. + * + * @note not specified by SLS as a member of AnyRef + * @return a representation that corresponds to the dynamic class of the receiver object. + */ + def getClass(): Class[_] + + /** Wakes up a single thread that is waiting on the receiver object's monitor. + * + * @note not specified by SLS as a member of AnyRef + */ + def notify(): Unit + + /** Wakes up all threads that are waiting on the receiver object's monitor. + * + * @note not specified by SLS as a member of AnyRef + */ + def notifyAll(): Unit + + /** Causes the current Thread to wait until another Thread invokes + * the notify() or notifyAll() methods. + * + * @note not specified by SLS as a member of AnyRef + */ + def wait (): Unit + def wait (timeout: Long, nanos: Int): Unit + def wait (timeout: Long): Unit +} diff --git a/test/scaladoc/resources/doc-root/Nothing.scala b/test/scaladoc/resources/doc-root/Nothing.scala new file mode 100644 index 0000000000..eed6066039 --- /dev/null +++ b/test/scaladoc/resources/doc-root/Nothing.scala @@ -0,0 +1,23 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2010, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala + +/** `Nothing` is - together with [[scala.Null]] - at the bottom of Scala's type hierarchy. + * + * `Nothing` is a subtype of every other type (including [[scala.Null]]); there exist + * ''no instances'' of this type. Although type `Nothing` is uninhabited, it is + * nevertheless useful in several ways. For instance, the Scala library defines a value + * [[scala.collection.immutable.Nil]] of type `List[Nothing]`. Because lists are covariant in Scala, + * this makes [[scala.collection.immutable.Nil]] an instance of `List[T]`, for any element of type `T`. + * + * Another usage for Nothing is the return type for methods which never return normally. + * One example is method error in [[scala.sys]], which always throws an exception. + */ +sealed trait Nothing + diff --git a/test/scaladoc/resources/doc-root/Null.scala b/test/scaladoc/resources/doc-root/Null.scala new file mode 100644 index 0000000000..7455e78ae7 --- /dev/null +++ b/test/scaladoc/resources/doc-root/Null.scala @@ -0,0 +1,17 @@ +/* __ *\ +** ________ ___ / / ___ Scala API ** +** / __/ __// _ | / / / _ | (c) 2002-2010, LAMP/EPFL ** +** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** +** /____/\___/_/ |_/____/_/ | | ** +** |/ ** +\* */ + +package scala + +/** `Null` is - together with [[scala.Nothing]] - at the bottom of the Scala type hierarchy. + * + * `Null` is a subtype of all reference types; its only instance is the `null` reference. + * Since `Null` is not a subtype of value types, `null` is not a member of any such type. For instance, + * it is not possible to assign `null` to a variable of type [[scala.Int]]. + */ +sealed trait Null diff --git a/test/scaladoc/resources/implicits-ambiguating-res.scala b/test/scaladoc/resources/implicits-ambiguating-res.scala new file mode 100644 index 0000000000..6ed51366cb --- /dev/null +++ b/test/scaladoc/resources/implicits-ambiguating-res.scala @@ -0,0 +1,72 @@ +/** + * Test scaladoc implicits distinguishing -- supress all members by implicit conversion that are shadowed by the + * class' own members + * + * {{{ + * scala> class A { def foo(t: String) = 4 } + * defined class A + * + * scala> class B { def foo(t: Any) = 5 } + * defined class B + * + * scala> implicit def AtoB(a:A) = new B + * AtoB: (a: A)B + * + * scala> val a = new A + * a: A = A@28f553e3 + * + * scala> a.foo("T") + * res1: Int = 4 + * + * scala> a.foo(4) + * res2: Int = 5 + * }}} + */ +package scala.test.scaladoc.implicits.ambiguating +import language.implicitConversions // according to SIP18 + +/** - conv1-5 should be ambiguous + * - conv6-7 should not be ambiguous + * - conv8 should be ambiguous + * - conv9 should be ambiguous + * - conv10 and conv11 should not be ambiguous */ +class A[T] +/** conv1-9 should be the same, conv10 should be ambiguous, conv11 should be okay */ +class B extends A[Int] +/** conv1-9 should be the same, conv10 and conv11 should not be ambiguous */ +class C extends A[Double] + /** conv1-9 should be the same, conv10 should not be ambiguous while conv11 should be ambiguous */ +class D extends A[AnyRef] + +class X[T] { + def conv1: AnyRef = ??? + def conv2: T = ??? + def conv3(l: Int): AnyRef = ??? + def conv4(l: AnyRef): AnyRef = ??? + def conv5(l: AnyRef): String = ??? + def conv6(l: String)(m: String): AnyRef = ??? + def conv7(l: AnyRef)(m: AnyRef): AnyRef = ??? + def conv8(l: AnyRef): AnyRef = ??? + def conv9(l: String): AnyRef = ??? + def conv10(l: T): T = ??? + def conv11(l: T): T = ??? +} + +class Z[T] { + def conv1: AnyRef = ??? + def conv2: T = ??? + def conv3(p: Int): AnyRef = ??? + def conv4(p: AnyRef): String = ??? + def conv5(p: AnyRef): AnyRef = ??? + def conv6(p: String, q: String): AnyRef = ??? + def conv7(p: AnyRef, q: AnyRef): AnyRef = ??? + def conv8(p: String): AnyRef = ??? + def conv9(p: AnyRef): AnyRef = ??? + def conv10(p: Int): T = ??? + def conv11(p: String): T = ??? +} + +object A { + implicit def AtoX[T](a: A[T]) = new X[T] + implicit def AtoZ[T](a: A[T]) = new Z[T] +} diff --git a/test/scaladoc/resources/implicits-base-res.scala b/test/scaladoc/resources/implicits-base-res.scala index 65d7bdf67c..d6c0332c10 100644 --- a/test/scaladoc/resources/implicits-base-res.scala +++ b/test/scaladoc/resources/implicits-base-res.scala @@ -16,8 +16,9 @@ trait MyNumeric[R] * def convToManifestA(x: T) // pimpA7: with 2 constraints: T: Manifest and T <: Double * def convToMyNumericA(x: T) // pimpA6: with a constraint that there is x: MyNumeric[T] implicit in scope * def convToNumericA(x: T) // pimpA1: with a constraint that there is x: Numeric[T] implicit in scope - * def convToPimpedA(x: Bar[Foo[T]]) // pimpA5: no constraints - * def convToPimpedA(x: S) // pimpA4: with 3 constraints: T = Foo[Bar[S]], S: Foo and S: Bar + * def convToPimpedA(x: Bar[Foo[T]]) // pimpA5: no constraints, SHADOWED + * def convToPimpedA(x: S) // pimpA4: with 3 constraints: T = Foo[Bar[S]], S: Foo and S: Bar, SHADOWED + * def convToPimpedA(x: T) // pimpA0: with no constraints, SHADOWED * def convToTraversableOps(x: T) // pimpA7: with 2 constraints: T: Manifest and T <: Double * // should not be abstract! * }}} @@ -52,9 +53,10 @@ object A { * def convToManifestA(x: Double) // pimpA7: no constraints * def convToMyNumericA(x: Double) // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Double] implicit in scope * def convToNumericA(x: Double) // pimpA1: no constraintsd - * def convToPimpedA(x: Bar[Foo[Double]]) // pimpA5: no constraints + * def convToPimpedA(x: Bar[Foo[Double]]) // pimpA5: no constraints, SHADOWED + * def convToPimpedA(x: Double) // pimpA0: no constraints, SHADOWED * def convToTraversableOps(x: Double) // pimpA7: no constraints - * // should not be abstract! + * // should not be abstract! * }}} */ class B extends A[Double] @@ -68,7 +70,8 @@ object B extends A * def convToIntA(x: Int) // pimpA2: no constraints * def convToMyNumericA(x: Int) // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Int] implicit in scope * def convToNumericA(x: Int) // pimpA1: no constraints - * def convToPimpedA(x: Bar[Foo[Int]]) // pimpA5: no constraints + * def convToPimpedA(x: Int) // pimpA0: no constraints, SHADOWED + * def convToPimpedA(x: Bar[Foo[Int]]) // pimpA5: no constraints, SHADOWED * }}} */ class C extends A[Int] @@ -81,7 +84,8 @@ object C extends A * {{{ * def convToMyNumericA(x: String) // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[String] implicit in scope * def convToNumericA(x: String) // pimpA1: (if showAll is set) with a constraint that there is x: Numeric[String] implicit in scope - * def convToPimpedA(x: Bar[Foo[String]]) // pimpA5: no constraints + * def convToPimpedA(x: Bar[Foo[String]]) // pimpA5: no constraints, SHADOWED + * def convToPimpedA(x: String) // pimpA0: no constraints, SHADOWED * }}} */ class D extends A[String] diff --git a/test/scaladoc/resources/implicits-elimination-res.scala b/test/scaladoc/resources/implicits-elimination-res.scala index b23667440c..5f7135c9e8 100644 --- a/test/scaladoc/resources/implicits-elimination-res.scala +++ b/test/scaladoc/resources/implicits-elimination-res.scala @@ -2,13 +2,13 @@ * Testing scaladoc implicits elimination */ package scala.test.scaladoc.implicits.elimination { - + import language.implicitConversions // according to SIP18 /** No conversion, as B doesn't bring any member */ class A class B { class C; trait V; type T; } - object A { - implicit def toB(a: A): B = null + object A { + implicit def toB(a: A): B = null } } diff --git a/test/scaladoc/run/SI-5373.scala b/test/scaladoc/run/SI-5373.scala index 0062abbb2a..65cf8baff5 100644 --- a/test/scaladoc/run/SI-5373.scala +++ b/test/scaladoc/run/SI-5373.scala @@ -12,12 +12,12 @@ object Test extends ScaladocModelTest { def foo = () } - trait B { + trait B extends A { @bridge() def foo = () } - class C extends A with B + class C extends B } """ diff --git a/test/scaladoc/run/implicits-elimination.check b/test/scaladoc/run/SI-5780.check index 619c56180b..619c56180b 100644 --- a/test/scaladoc/run/implicits-elimination.check +++ b/test/scaladoc/run/SI-5780.check diff --git a/test/scaladoc/run/SI-5780.scala b/test/scaladoc/run/SI-5780.scala new file mode 100644 index 0000000000..809567faec --- /dev/null +++ b/test/scaladoc/run/SI-5780.scala @@ -0,0 +1,25 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.nsc.doc.model.diagram._ +import scala.tools.partest.ScaladocModelTest + +object Test extends ScaladocModelTest { + + override def code = """ + package scala.test.scaladoc.SI5780 + + object `package` { def foo: AnyRef = "hello"; class T /* so the package is not dropped */ } + """ + + // diagrams must be started. In case there's an error with dot, it should not report anything + def scaladocSettings = "-doc-root-content " + resourcePath + "/doc-root" + + 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._ + + val foo = rootPackage._package("scala")._package("test")._package("scaladoc")._package("SI5780")._method("foo") + // check that AnyRef is properly linked to its template: + assert(foo.resultType.name == "AnyRef", foo.resultType.name + " == AnyRef") + assert(foo.resultType.refEntity.size == 1, foo.resultType.refEntity + ".size == 1") + } +}
\ No newline at end of file diff --git a/test/scaladoc/run/diagrams-base.check b/test/scaladoc/run/diagrams-base.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/diagrams-base.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/diagrams-base.scala b/test/scaladoc/run/diagrams-base.scala new file mode 100644 index 0000000000..38bed06502 --- /dev/null +++ b/test/scaladoc/run/diagrams-base.scala @@ -0,0 +1,73 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.nsc.doc.model.diagram._ +import scala.tools.partest.ScaladocModelTest + +object Test extends ScaladocModelTest { + + override def code = """ + package scala.test.scaladoc.diagrams + + import language.implicitConversions + + trait A + trait B + trait C + class E extends A with B with C + object E { implicit def eToT(e: E) = new T } + + class F extends E + class G extends E + private class H extends E /* since it's private, it won't go into the diagram */ + class T { def t = true } + + class X + object X { implicit def xToE(x: X) = new E} + class Y extends X + class Z + object Z { implicit def zToE(z: Z) = new E} + """ + + // diagrams must be started. In case there's an error with dot, it should not report anything + def scaladocSettings = "-diagrams -implicits" + + 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._ + + val base = rootPackage._package("scala")._package("test")._package("scaladoc")._package("diagrams") + val E = base._class("E") + val diag = E.inheritanceDiagram.get + + // there must be a single this node + assert(diag.nodes.filter(_.isThisNode).length == 1) + + // 1. check class E diagram + assert(diag.isClassDiagram) + + val (incoming, outgoing) = diag.edges.partition(!_._1.isThisNode) + assert(incoming.length == 5) + assert(outgoing.head._2.length == 4) + + val (outgoingSuperclass, outgoingImplicit) = outgoing.head._2.partition(_.isNormalNode) + assert(outgoingSuperclass.length == 3) + assert(outgoingImplicit.length == 1) + + val (incomingSubclass, incomingImplicit) = incoming.partition(_._1.isNormalNode) + assert(incomingSubclass.length == 2) + assert(incomingImplicit.length == 3) + + val classDiag = diag.asInstanceOf[ClassDiagram] + assert(classDiag.incomingImplicits.length == 3) + assert(classDiag.outgoingImplicits.length == 1) + + // 2. check package diagram + // NOTE: Z should be eliminated because it's isolated + val packDiag = base.contentDiagram.get + assert(packDiag.isPackageDiagram) + assert(packDiag.nodes.length == 8) // check singular object removal + assert(packDiag.edges.length == 4) + assert(packDiag.edges.foldLeft(0)(_ + _._2.length) == 6) + + // TODO: Should check numbering + } +}
\ No newline at end of file diff --git a/test/scaladoc/run/diagrams-determinism.check b/test/scaladoc/run/diagrams-determinism.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/diagrams-determinism.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/diagrams-determinism.scala b/test/scaladoc/run/diagrams-determinism.scala new file mode 100644 index 0000000000..6c8db05d78 --- /dev/null +++ b/test/scaladoc/run/diagrams-determinism.scala @@ -0,0 +1,67 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.nsc.doc.model.diagram._ +import scala.tools.partest.ScaladocModelTest + +object Test extends ScaladocModelTest { + + override def code = """ + package scala.test.scaladoc.diagrams + + trait A + trait B extends A + trait C extends B + trait D extends C with A + trait E extends C with A with D + """ + + // diagrams must be started. In case there's an error with dot, it should not report anything + def scaladocSettings = "-diagrams -implicits" + + 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._ + + def diagramString(rootPackage: Package) = { + val base = rootPackage._package("scala")._package("test")._package("scaladoc")._package("diagrams") + val A = base._trait("A") + val B = base._trait("B") + val C = base._trait("C") + val D = base._trait("D") + val E = base._trait("E") + + base.contentDiagram.get.toString + "\n" + + A.inheritanceDiagram.get.toString + "\n" + + B.inheritanceDiagram.get.toString + "\n" + + C.inheritanceDiagram.get.toString + "\n" + + D.inheritanceDiagram.get.toString + "\n" + + E.inheritanceDiagram.get.toString + } + + // 1. check that several runs produce the same output + val run0 = diagramString(rootPackage) + val run1 = diagramString(model.getOrElse({sys.error("Scaladoc Model Test ERROR: No universe generated!")}).rootPackage) + val run2 = diagramString(model.getOrElse({sys.error("Scaladoc Model Test ERROR: No universe generated!")}).rootPackage) + val run3 = diagramString(model.getOrElse({sys.error("Scaladoc Model Test ERROR: No universe generated!")}).rootPackage) + + // any variance in the order of the diagram elements should crash the following tests: + assert(run0 == run1) + assert(run1 == run2) + assert(run2 == run3) + + // 2. check the order in the diagram: this node, subclasses, and then implicit conversions + def assertRightOrder(diagram: Diagram) = { + for ((node, subclasses) <- diagram.edges) + assert(subclasses == subclasses.filter(_.isThisNode) ::: + subclasses.filter(_.isNormalNode) ::: + subclasses.filter(_.isImplicitNode)) + } + + val base = rootPackage._package("scala")._package("test")._package("scaladoc")._package("diagrams") + assertRightOrder(base.contentDiagram.get) + assertRightOrder(base._trait("A").inheritanceDiagram.get) + assertRightOrder(base._trait("B").inheritanceDiagram.get) + assertRightOrder(base._trait("C").inheritanceDiagram.get) + assertRightOrder(base._trait("D").inheritanceDiagram.get) + assertRightOrder(base._trait("E").inheritanceDiagram.get) + } +}
\ No newline at end of file diff --git a/test/scaladoc/run/diagrams-filtering.check b/test/scaladoc/run/diagrams-filtering.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/diagrams-filtering.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/diagrams-filtering.scala b/test/scaladoc/run/diagrams-filtering.scala new file mode 100644 index 0000000000..8cb32180a1 --- /dev/null +++ b/test/scaladoc/run/diagrams-filtering.scala @@ -0,0 +1,93 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.nsc.doc.model.diagram._ +import scala.tools.partest.ScaladocModelTest + +object Test extends ScaladocModelTest { + + override def code = """ + package scala.test.scaladoc + + /** @contentDiagram hideNodes "scala.test.*.A" "java.*", hideEdges ("*G" -> "*E") */ + package object diagrams { + def foo = 4 + } + + package diagrams { + import language.implicitConversions + + /** @inheritanceDiagram hideIncomingImplicits, hideNodes "*E" */ + trait A + trait AA extends A + trait B + trait AAA extends B + + /** @inheritanceDiagram hideDiagram */ + trait C + trait AAAA extends C + + /** @inheritanceDiagram hideEdges("*E" -> "*A") */ + class E extends A with B with C + class F extends E + /** @inheritanceDiagram hideNodes "*G" "G" */ + class G extends E + private class H extends E /* since it's private, it won't go into the diagram */ + class T { def t = true } + object E { + implicit def eToT(e: E) = new T + implicit def eToA(e: E) = new A { } + } + } + """ + + // diagrams must be started. In case there's an error with dot, it should not report anything + def scaladocSettings = "-diagrams -implicits" + + 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._ + + // base package + // Assert we have 7 nodes and 6 edges + val base = rootPackage._package("scala")._package("test")._package("scaladoc")._package("diagrams") + val packDiag = base.contentDiagram.get + assert(packDiag.nodes.length == 6) + assert(packDiag.edges.map(_._2.length).sum == 5) + + // trait A + // Assert we have just 3 nodes and 2 edges + val A = base._trait("A") + val ADiag = A.inheritanceDiagram.get + assert(ADiag.nodes.length == 3) + assert(ADiag.edges.map(_._2.length).sum == 2) + + // trait C + val C = base._trait("C") + assert(!C.inheritanceDiagram.isDefined) + + // trait G + val G = base._trait("G") + assert(!G.inheritanceDiagram.isDefined) + + // trait E + val E = base._class("E") + val EDiag = E.inheritanceDiagram.get + + // there must be a single this node + assert(EDiag.nodes.filter(_.isThisNode).length == 1) + + // 1. check class E diagram + val (incoming, outgoing) = EDiag.edges.partition(!_._1.isThisNode) + assert(incoming.length == 2) // F and G + assert(outgoing.head._2.length == 3) // B, C and T + + val (outgoingSuperclass, outgoingImplicit) = outgoing.head._2.partition(_.isNormalNode) + assert(outgoingSuperclass.length == 2) // B and C + assert(outgoingImplicit.length == 1, outgoingImplicit) // T + + val (incomingSubclass, incomingImplicit) = incoming.partition(_._1.isNormalNode) + assert(incomingSubclass.length == 2) // F and G + assert(incomingImplicit.length == 0) + + assert(EDiag.nodes.length == 6) // E, B and C, F and G and the implicit conversion to T + } +}
\ No newline at end of file diff --git a/test/scaladoc/run/diagrams-inherited-nodes.check b/test/scaladoc/run/diagrams-inherited-nodes.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/diagrams-inherited-nodes.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/diagrams-inherited-nodes.scala b/test/scaladoc/run/diagrams-inherited-nodes.scala new file mode 100644 index 0000000000..8ac382aab8 --- /dev/null +++ b/test/scaladoc/run/diagrams-inherited-nodes.scala @@ -0,0 +1,69 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.nsc.doc.model.diagram._ +import scala.tools.partest.ScaladocModelTest + +object Test extends ScaladocModelTest { + + override def code = """ + package scala.test.scaladoc.diagrams.inherited.nodes { + + /** @contentDiagram + * @inheritanceDiagram hideDiagram */ + trait T1 { + trait A1 + trait A2 extends A1 + trait A3 extends A2 + } + + /** @contentDiagram + * @inheritanceDiagram hideDiagram */ + trait T2 extends T1 { + trait B1 extends A1 + trait B2 extends A2 with B1 + trait B3 extends A3 with B2 + } + + /** @contentDiagram + * @inheritanceDiagram hideDiagram */ + trait T3 { + self: T1 with T2 => + trait C1 extends B1 + trait C2 extends B2 with C1 + trait C3 extends B3 with C2 + } + + /** @contentDiagram + * @inheritanceDiagram hideDiagram */ + trait T4 extends T3 with T2 with T1 { + trait D1 extends C1 + trait D2 extends C2 with D1 + trait D3 extends C3 with D2 + } + } + """ + + // diagrams must be started. In case there's an error with dot, it should not report anything + def scaladocSettings = "-diagrams" + + 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._ + + // base package + // Assert we have 7 nodes and 6 edges + val base = rootPackage._package("scala")._package("test")._package("scaladoc")._package("diagrams")._package("inherited")._package("nodes") + + def checkDiagram(t: String, nodes: Int, edges: Int) = { + // trait T1 + val T = base._trait(t) + val TDiag = T.contentDiagram.get + assert(TDiag.nodes.length == nodes, t + ": " + TDiag.nodes + ".length == " + nodes) + assert(TDiag.edges.map(_._2.length).sum == edges, t + ": " + TDiag.edges.mkString("List(\n", ",\n", "\n)") + ".map(_._2.length).sum == " + edges) + } + + checkDiagram("T1", 3, 2) + checkDiagram("T2", 6, 7) + checkDiagram("T3", 3, 2) + checkDiagram("T4", 12, 17) + } +}
\ No newline at end of file diff --git a/test/scaladoc/run/implicits-ambiguating.check b/test/scaladoc/run/implicits-ambiguating.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/implicits-ambiguating.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/implicits-ambiguating.scala b/test/scaladoc/run/implicits-ambiguating.scala new file mode 100644 index 0000000000..1420593b74 --- /dev/null +++ b/test/scaladoc/run/implicits-ambiguating.scala @@ -0,0 +1,114 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.partest.ScaladocModelTest + +object Test extends ScaladocModelTest { + + // test a file instead of a piece of code + override def resourceFile = "implicits-ambiguating-res.scala" + + // start implicits + def scaladocSettings = "-implicits" + + def testModel(root: Package) = { + // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) + import access._ + + def isAmbiguous(mbr: MemberEntity): Boolean = + mbr.byConversion.map(_.source.implicitsShadowing.get(mbr).map(_.isAmbiguous).getOrElse(false)).getOrElse(false) + + // SEE THE test/resources/implicits-chaining-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: + val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._object("ambiguating") + var conv1: ImplicitConversion = null + var conv2: ImplicitConversion = null + +//// class A /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val A = base._class("A") + + conv1 = A._conversion(base._object("A").qualifiedName + ".AtoX") + conv2 = A._conversion(base._object("A").qualifiedName + ".AtoZ") + assert(conv1.members.length == 11) + assert(conv2.members.length == 11) + assert(conv1.constraints.length == 0) + assert(conv2.constraints.length == 0) + + /** - conv1-5 should be ambiguous + * - conv6-7 should not be ambiguous + * - conv8 should be ambiguous + * - conv9 should be ambiguous + * - conv10 and conv11 should not be ambiguous */ + def check1to9(cls: String): Unit = { + for (conv <- (1 to 5).map("conv" + _)) { + assert(isAmbiguous(conv1._member(conv)), cls + " - AtoX." + conv + " is ambiguous") + assert(isAmbiguous(conv2._member(conv)), cls + " - AtoZ." + conv + " is ambiguous") + } + for (conv <- (6 to 7).map("conv" + _)) { + assert(!isAmbiguous(conv1._member(conv)), cls + " - AtoX." + conv + " is not ambiguous") + assert(!isAmbiguous(conv2._member(conv)), cls + " - AtoZ." + conv + " is not ambiguous") + } + assert(isAmbiguous(conv1._member("conv8")), cls + " - AtoX.conv8 is ambiguous") + assert(isAmbiguous(conv2._member("conv8")), cls + " - AtoZ.conv8 is ambiguous") + assert(isAmbiguous(conv1._member("conv9")), cls + " - AtoX.conv9 is ambiguous") + assert(isAmbiguous(conv2._member("conv9")), cls + " - AtoZ.conv9 is ambiguous") + } + check1to9("A") + assert(!isAmbiguous(conv1._member("conv10")), "A - AtoX.conv10 is not ambiguous") + assert(!isAmbiguous(conv2._member("conv10")), "A - AtoZ.conv10 is not ambiguous") + assert(!isAmbiguous(conv1._member("conv11")), "A - AtoX.conv11 is not ambiguous") + assert(!isAmbiguous(conv2._member("conv11")), "A - AtoZ.conv11 is not ambiguous") + +//// class B /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val B = base._class("B") + + conv1 = B._conversion(base._object("A").qualifiedName + ".AtoX") + conv2 = B._conversion(base._object("A").qualifiedName + ".AtoZ") + assert(conv1.members.length == 11) + assert(conv2.members.length == 11) + assert(conv1.constraints.length == 0) + assert(conv2.constraints.length == 0) + + /** conv1-9 should be the same, conv10 should be ambiguous, conv11 should be okay */ + check1to9("B") + assert(isAmbiguous(conv1._member("conv10")), "B - AtoX.conv10 is ambiguous") + assert(isAmbiguous(conv2._member("conv10")), "B - AtoZ.conv10 is ambiguous") + assert(!isAmbiguous(conv1._member("conv11")), "B - AtoX.conv11 is not ambiguous") + assert(!isAmbiguous(conv2._member("conv11")), "B - AtoZ.conv11 is not ambiguous") + +//// class C /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val C = base._class("C") + + conv1 = C._conversion(base._object("A").qualifiedName + ".AtoX") + conv2 = C._conversion(base._object("A").qualifiedName + ".AtoZ") + assert(conv1.members.length == 11) + assert(conv2.members.length == 11) + assert(conv1.constraints.length == 0) + assert(conv2.constraints.length == 0) + + /** conv1-9 should be the same, conv10 and conv11 should not be ambiguous */ + check1to9("C") + assert(!isAmbiguous(conv1._member("conv10")), "C - AtoX.conv10 is not ambiguous") + assert(!isAmbiguous(conv2._member("conv10")), "C - AtoZ.conv10 is not ambiguous") + assert(!isAmbiguous(conv1._member("conv11")), "C - AtoX.conv11 is not ambiguous") + assert(!isAmbiguous(conv2._member("conv11")), "C - AtoZ.conv11 is not ambiguous") + +//// class D /////////////////////////////////////////////////////////////////////////////////////////////////////////// + + val D = base._class("D") + + conv1 = D._conversion(base._object("A").qualifiedName + ".AtoX") + conv2 = D._conversion(base._object("A").qualifiedName + ".AtoZ") + assert(conv1.members.length == 11) + assert(conv2.members.length == 11) + assert(conv1.constraints.length == 0) + assert(conv2.constraints.length == 0) + + /** conv1-9 should be the same, conv10 should not be ambiguous while conv11 should be ambiguous */ + check1to9("D") + assert(!isAmbiguous(conv1._member("conv10")), "D - AtoX.conv10 is not ambiguous") + assert(!isAmbiguous(conv2._member("conv10")), "D - AtoZ.conv10 is not ambiguous") + assert(isAmbiguous(conv1._member("conv11")), "D - AtoX.conv11 is ambiguous") + assert(isAmbiguous(conv2._member("conv11")), "D - AtoZ.conv11 is ambiguous") + } +}
\ No newline at end of file diff --git a/test/scaladoc/run/implicits-base.scala b/test/scaladoc/run/implicits-base.scala index 06d017ed70..3d57306f5d 100644 --- a/test/scaladoc/run/implicits-base.scala +++ b/test/scaladoc/run/implicits-base.scala @@ -14,6 +14,9 @@ object Test extends ScaladocModelTest { // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) import access._ + def isShadowed(mbr: MemberEntity): Boolean = + mbr.byConversion.map(_.source.implicitsShadowing.get(mbr).map(_.isShadowed).getOrElse(false)).getOrElse(false) + // SEE THE test/resources/implicits-base-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._package("base") var conv: ImplicitConversion = null @@ -22,8 +25,12 @@ object Test extends ScaladocModelTest { val A = base._class("A") - // the method pimped on by pimpA0 should be shadowed by the method in class A - assert(A._conversions(A.qualifiedName + ".pimpA0").isEmpty) + // def convToPimpedA(x: T) // pimpA0: with no constraints, SHADOWED + conv = A._conversion(A.qualifiedName + ".pimpA0") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(isShadowed(conv._member("convToPimpedA"))) + assert(conv._member("convToPimpedA").resultType.name == "T") // def convToNumericA: T // pimpA1: with a constraint that there is x: Numeric[T] implicit in scope conv = A._conversion(A.qualifiedName + ".pimpA1") @@ -53,6 +60,7 @@ object Test extends ScaladocModelTest { conv = A._conversion(A.qualifiedName + ".pimpA5") assert(conv.members.length == 1) assert(conv.constraints.length == 0) + assert(isShadowed(conv._member("convToPimpedA"))) assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[T]]") // def convToMyNumericA: T // pimpA6: with a constraint that there is x: MyNumeric[T] implicit in scope @@ -76,10 +84,16 @@ object Test extends ScaladocModelTest { val B = base._class("B") // these conversions should not affect B - assert(B._conversions(A.qualifiedName + ".pimpA0").isEmpty) assert(B._conversions(A.qualifiedName + ".pimpA2").isEmpty) assert(B._conversions(A.qualifiedName + ".pimpA4").isEmpty) + // def convToPimpedA(x: Double) // pimpA0: no constraints, SHADOWED + conv = B._conversion(A.qualifiedName + ".pimpA0") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(isShadowed(conv._member("convToPimpedA"))) + assert(conv._member("convToPimpedA").resultType.name == "Double") + // def convToNumericA: Double // pimpA1: no constraintsd conv = B._conversion(A.qualifiedName + ".pimpA1") assert(conv.members.length == 1) @@ -96,6 +110,7 @@ object Test extends ScaladocModelTest { conv = B._conversion(A.qualifiedName + ".pimpA5") assert(conv.members.length == 1) assert(conv.constraints.length == 0) + assert(isShadowed(conv._member("convToPimpedA"))) assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[Double]]") // def convToMyNumericA: Double // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Double] implicit in scope @@ -119,11 +134,17 @@ object Test extends ScaladocModelTest { val C = base._class("C") // these conversions should not affect C - assert(C._conversions(A.qualifiedName + ".pimpA0").isEmpty) assert(C._conversions(A.qualifiedName + ".pimpA3").isEmpty) assert(C._conversions(A.qualifiedName + ".pimpA4").isEmpty) assert(C._conversions(A.qualifiedName + ".pimpA7").isEmpty) + // def convToPimpedA(x: Int) // pimpA0: no constraints, SHADOWED + conv = C._conversion(A.qualifiedName + ".pimpA0") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(isShadowed(conv._member("convToPimpedA"))) + assert(conv._member("convToPimpedA").resultType.name == "Int") + // def convToNumericA: Int // pimpA1: no constraints conv = C._conversion(A.qualifiedName + ".pimpA1") assert(conv.members.length == 1) @@ -140,6 +161,7 @@ object Test extends ScaladocModelTest { conv = C._conversion(A.qualifiedName + ".pimpA5") assert(conv.members.length == 1) assert(conv.constraints.length == 0) + assert(isShadowed(conv._member("convToPimpedA"))) assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[Int]]") // def convToMyNumericA: Int // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Int] implicit in scope @@ -153,12 +175,18 @@ object Test extends ScaladocModelTest { val D = base._class("D") // these conversions should not affect D - assert(D._conversions(A.qualifiedName + ".pimpA0").isEmpty) assert(D._conversions(A.qualifiedName + ".pimpA2").isEmpty) assert(D._conversions(A.qualifiedName + ".pimpA3").isEmpty) assert(D._conversions(A.qualifiedName + ".pimpA4").isEmpty) assert(D._conversions(A.qualifiedName + ".pimpA7").isEmpty) + // def convToPimpedA(x: String) // pimpA0: no constraints, SHADOWED + conv = D._conversion(A.qualifiedName + ".pimpA0") + assert(conv.members.length == 1) + assert(conv.constraints.length == 0) + assert(isShadowed(conv._member("convToPimpedA"))) + assert(conv._member("convToPimpedA").resultType.name == "String") + // def convToNumericA: String // pimpA1: (if showAll is set) with a constraint that there is x: Numeric[String] implicit in scope conv = D._conversion(A.qualifiedName + ".pimpA1") assert(conv.members.length == 1) @@ -169,6 +197,7 @@ object Test extends ScaladocModelTest { conv = D._conversion(A.qualifiedName + ".pimpA5") assert(conv.members.length == 1) assert(conv.constraints.length == 0) + assert(isShadowed(conv._member("convToPimpedA"))) assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[String]]") // def convToMyNumericA: String // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[String] implicit in scope diff --git a/test/scaladoc/run/implicits-elimination.scala b/test/scaladoc/run/implicits-elimination.scala deleted file mode 100644 index ed37b9cd90..0000000000 --- a/test/scaladoc/run/implicits-elimination.scala +++ /dev/null @@ -1,23 +0,0 @@ -import scala.tools.nsc.doc.model._ -import scala.tools.partest.ScaladocModelTest -import language._ - -object Test extends ScaladocModelTest { - - // test a file instead of a piece of code - override def resourceFile = "implicits-elimination-res.scala" - - // start implicits - def scaladocSettings = "-implicits" - - def testModel(root: Package) = { - // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) - import access._ - - // SEE THE test/resources/implicits-elimination-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: - val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._package("elimination") - val A = base._class("A") - - assert(A._conversions(A.qualifiedName + ".toB").isEmpty) - } -} diff --git a/test/scaladoc/run/implicits-shadowing.scala b/test/scaladoc/run/implicits-shadowing.scala index 7835223d21..2827d31122 100644 --- a/test/scaladoc/run/implicits-shadowing.scala +++ b/test/scaladoc/run/implicits-shadowing.scala @@ -13,6 +13,9 @@ object Test extends ScaladocModelTest { // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s)) import access._ + def isShadowed(mbr: MemberEntity): Boolean = + mbr.byConversion.map(_.source.implicitsShadowing.get(mbr).map(_.isShadowed).getOrElse(false)).getOrElse(false) + // SEE THE test/resources/implicits-chaining-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE: val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._object("shadowing") var conv: ImplicitConversion = null @@ -22,12 +25,8 @@ object Test extends ScaladocModelTest { val A = base._class("A") conv = A._conversion(base._object("A").qualifiedName + ".AtoZ") - assert(conv.members.length == 5) - conv._member("conv5") - conv._member("conv8") - conv._member("conv9") - conv._member("conv10") - conv._member("conv11") + assert(conv.members.length == 11) + assert(conv.members.forall(isShadowed(_))) assert(conv.constraints.length == 0) //// class B /////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -35,11 +34,8 @@ object Test extends ScaladocModelTest { val B = base._class("B") conv = B._conversion(base._object("A").qualifiedName + ".AtoZ") - assert(conv.members.length == 4) - conv._member("conv5") - conv._member("conv8") - conv._member("conv9") - conv._member("conv11") + assert(conv.members.length == 11) + assert(conv.members.forall(isShadowed(_))) assert(conv.constraints.length == 0) //// class C /////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -47,12 +43,8 @@ object Test extends ScaladocModelTest { val C = base._class("C") conv = C._conversion(base._object("A").qualifiedName + ".AtoZ") - assert(conv.members.length == 5) - conv._member("conv5") - conv._member("conv8") - conv._member("conv9") - conv._member("conv10") - conv._member("conv11") + assert(conv.members.length == 11) + assert(conv.members.forall(isShadowed(_))) assert(conv.constraints.length == 0) //// class D /////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -60,11 +52,8 @@ object Test extends ScaladocModelTest { val D = base._class("D") conv = D._conversion(base._object("A").qualifiedName + ".AtoZ") - assert(conv.members.length == 4) - conv._member("conv5") - conv._member("conv8") - conv._member("conv9") - conv._member("conv10") + assert(conv.members.length == 11) + assert(conv.members.forall(isShadowed(_))) assert(conv.constraints.length == 0) } -}
\ No newline at end of file +} diff --git a/test/scaladoc/run/implicits-var-exp.check b/test/scaladoc/run/implicits-var-exp.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/implicits-var-exp.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/implicits-var-exp.scala b/test/scaladoc/run/implicits-var-exp.scala new file mode 100644 index 0000000000..16569fe3c2 --- /dev/null +++ b/test/scaladoc/run/implicits-var-exp.scala @@ -0,0 +1,43 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.nsc.doc.model.diagram._ +import scala.tools.partest.ScaladocModelTest + +object Test extends ScaladocModelTest { + + override def code = """ + package scala.test.scaladoc.variable.expansion { + /** + * Blah blah blah + */ + class A + + object A { + import language.implicitConversions + implicit def aToB(a: A) = new B + } + + /** + * @define coll collection + */ + class B { + /** + * foo returns a $coll + */ + def foo: Nothing = ??? + } + } + """ + + // diagrams must be started. In case there's an error with dot, it should not report anything + def scaladocSettings = "-implicits" + + 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._ + + val base = rootPackage._package("scala")._package("test")._package("scaladoc")._package("variable")._package("expansion") + val foo = base._class("A")._method("foo") + + assert(foo.comment.get.body.toString.contains("foo returns a collection"), "\"" + foo.comment.get.body.toString + "\".contains(\"foo returns a collection\")") + } +}
\ No newline at end of file diff --git a/test/scaladoc/run/package-object.check b/test/scaladoc/run/package-object.check index 4297847e73..01dbcc682f 100644 --- a/test/scaladoc/run/package-object.check +++ b/test/scaladoc/run/package-object.check @@ -1,2 +1,3 @@ -List((test.B,B), (test.A,A), (scala.AnyRef,AnyRef), (scala.Any,Any)) +List(test.B, test.A, scala.AnyRef, scala.Any) +List(B, A, AnyRef, Any) Done. diff --git a/test/scaladoc/run/package-object.scala b/test/scaladoc/run/package-object.scala index fd36a8df7b..5fb5a4ddf1 100644 --- a/test/scaladoc/run/package-object.scala +++ b/test/scaladoc/run/package-object.scala @@ -9,7 +9,8 @@ object Test extends ScaladocModelTest { import access._ val p = root._package("test") - println(p.linearization) + println(p.linearizationTemplates) + println(p.linearizationTypes) } } diff --git a/test/scaladoc/scalacheck/CommentFactoryTest.scala b/test/scaladoc/scalacheck/CommentFactoryTest.scala index 68ca68efdd..b576ba5544 100644 --- a/test/scaladoc/scalacheck/CommentFactoryTest.scala +++ b/test/scaladoc/scalacheck/CommentFactoryTest.scala @@ -5,10 +5,12 @@ import scala.tools.nsc.Global import scala.tools.nsc.doc import scala.tools.nsc.doc.model._ import scala.tools.nsc.doc.model.comment._ +import scala.tools.nsc.doc.model._ +import scala.tools.nsc.doc.model.diagram._ class Factory(val g: Global, val s: doc.Settings) extends doc.model.ModelFactory(g, s) { - thisFactory: Factory with ModelFactoryImplicitSupport with CommentFactory with doc.model.TreeFactory => + thisFactory: Factory with ModelFactoryImplicitSupport with DiagramFactory with CommentFactory with doc.model.TreeFactory => def strip(c: Comment): Option[Inline] = { c.body match { @@ -29,7 +31,7 @@ object Test extends Properties("CommentFactory") { 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 ModelFactoryImplicitSupport with CommentFactory with doc.model.TreeFactory) + (new Factory(g, settings) with ModelFactoryImplicitSupport with DiagramFactory with CommentFactory with doc.model.TreeFactory) } def parse(src: String, dst: Inline) = { |