From 2f370d41f3d10865ce1c5196fb5a44978dd539fa Mon Sep 17 00:00:00 2001 From: Andrzej Ratajczak Date: Mon, 30 Nov 2020 11:24:56 +0100 Subject: [PATCH 1/2] Diagram tests --- scala3doc-testcases/src/tests/hierarchy.scala | 21 ++++ .../dotty/dokka/model/api/membersUtils.scala | 27 +++++ .../dotty/dokka/diagram/HierarchyTest.scala | 98 +++++++++++++++++++ 3 files changed, 146 insertions(+) create mode 100644 scala3doc-testcases/src/tests/hierarchy.scala create mode 100644 scala3doc/src/dotty/dokka/model/api/membersUtils.scala create mode 100644 scala3doc/test/dotty/dokka/diagram/HierarchyTest.scala diff --git a/scala3doc-testcases/src/tests/hierarchy.scala b/scala3doc-testcases/src/tests/hierarchy.scala new file mode 100644 index 000000000000..f7d7119e354c --- /dev/null +++ b/scala3doc-testcases/src/tests/hierarchy.scala @@ -0,0 +1,21 @@ +package tests + +package hierarchy + +trait A1 +trait A2[T] +trait A3[A, B] + + +trait B1 extends A1 +trait B2 extends A1 with A2[Int] +trait B3 extends A2[Int] with A3[Int, String] + +class C1[A, B, C] extends B1 with B2 with B3 + +trait D1 +trait D2[T, R] +trait D3 + +class E1 extends C1[Int, String, Boolean] with D1 +class E2 extends C1[Int, Boolean, Any] with D2[Int, Boolean] with D3 diff --git a/scala3doc/src/dotty/dokka/model/api/membersUtils.scala b/scala3doc/src/dotty/dokka/model/api/membersUtils.scala new file mode 100644 index 000000000000..e0be963f6ddf --- /dev/null +++ b/scala3doc/src/dotty/dokka/model/api/membersUtils.scala @@ -0,0 +1,27 @@ +package dotty.dokka.model.api + +import org.jetbrains.dokka.model.DModule +import scala.jdk.CollectionConverters.{ListHasAsScala, SeqHasAsJava} +import dotty.dokka.model.api._ + +extension (m: DModule) + def visitMembers(callback: Member => Unit): Unit = + def visitClasslike(c: Member, callback: Member => Unit): Unit = + callback(c) + c.allMembers.foreach(visitClasslike(_, callback)) + m.getPackages.asScala.foreach(_.allMembers.foreach(visitClasslike(_, callback))) + +extension (s: Signature) + def getName: String = + s.map { _ match + case s: String => s + case l: Link => l.name + }.mkString + +extension (m: Member): + def getDirectParentsAsStrings: Seq[String] = + m.directParents.map(_.getName).sorted + def getParentsAsStrings: Seq[String] = + m.parents.map(_.signature.getName).sorted + def getKnownChildrenAsStrings: Seq[String] = + m.knownChildren.map(_.signature.getName).sorted diff --git a/scala3doc/test/dotty/dokka/diagram/HierarchyTest.scala b/scala3doc/test/dotty/dokka/diagram/HierarchyTest.scala new file mode 100644 index 000000000000..5d7879e4cd93 --- /dev/null +++ b/scala3doc/test/dotty/dokka/diagram/HierarchyTest.scala @@ -0,0 +1,98 @@ +package dotty.dokka.diagram + +import dotty.dokka.ScaladocTest +import dotty.dokka.Assertion.AfterDocumentablesTransformation +import dotty.dokka.kUnit +import dotty.dokka.model.api._ +import scala.jdk.CollectionConverters.{ListHasAsScala, SeqHasAsJava} +import org.junit.Assert.{assertSame, assertTrue, assertEquals} + +class HierarchyTest extends ScaladocTest("hierarchy"): + override def assertions = Seq( + AfterDocumentablesTransformation { m => + m.visitMembers { x => + if (x.getName == "C1") { + assertEquals(List("A1", "A2[Int]", "A3[Int, String]", "Any", "B1", "B2", "B3", "Object"), x.getParentsAsStrings) + assertEquals(List("B1", "B2", "B3"), x.getDirectParentsAsStrings) + assertEquals(List("E1", "E2"), x.getKnownChildrenAsStrings) + val graph = MemberExtension.getFrom(x).map(_.graph) + assertEquals(true, graph.isDefined) + assertEquals( + Seq( + "Object" -> "Any", + "A1" -> "Object", + "A2[Int]" -> "Object", + "A3[Int, String]" -> "Object", + "B1" -> "Object", + "B1" -> "A1", + "B2" -> "Object", + "B2" -> "A1", + "B2" -> "A2[Int]", + "B3" -> "Object", + "B3" -> "A2[Int]", + "B3" -> "A3[Int, String]", + "C1[A, B, C]" -> "Object", + "C1[A, B, C]" -> "B1", + "C1[A, B, C]" -> "B2", + "C1[A, B, C]" -> "B3", + "E1" -> "C1[A, B, C]", + "E2" -> "C1[A, B, C]" + ).sorted, + graph.get.edges.map((a, b) => (a.signature.getName, b.signature.getName)).sorted + ) + } + if (x.getName == "E2") { + assertEquals(List("A1", "A2[Int]", "A3[Int, String]", "Any", "B1", "B2", "B3", "C1[Int, Boolean, Any]", "D2[Int, Boolean]", "D3", "Object"), x.getParentsAsStrings) + assertEquals(List("C1[Int, Boolean, Any]", "D2[Int, Boolean]", "D3"), x.getDirectParentsAsStrings) + assertEquals(List.empty, x.getKnownChildrenAsStrings) + val graph = MemberExtension.getFrom(x).map(_.graph) + assertEquals(true, graph.isDefined) + assertEquals( + Seq( + "Object" -> "Any", + // "A1" -> "Object", // These are not applicable beacuase of bug and its workaround + // "A2[Int]" -> "Object", // More info at ClassLikeSupport.scala:37 + // "A3[Int, String]" -> "Object", + // "B1" -> "Object", + // "B1" -> "A1", + // "B2" -> "Object", + // "B2" -> "A1", + // "B2" -> "A2[Int]", + // "B3" -> "Object", + // "B3" -> "A2[Int]", + // "B3" -> "A3[Int, String]", + // "C1[Int, Boolean, Any]" -> "Object", + // "C1[Int, Boolean, Any]" -> "B1", + // "C1[Int, Boolean, Any]" -> "B2", + // "C1[Int, Boolean, Any]" -> "B3", + "E2" -> "D2[Int, Boolean]", + "E2" -> "D3", + "D2[Int, Boolean]" -> "Object", + "D3" -> "Object", + "E2" -> "C1[Int, Boolean, Any]" + ).sorted, + graph.get.edges.map((a, b) => (a.signature.getName, b.signature.getName)).sorted + ) + } + if (x.getName == "A2") { + assertEquals(List("Any", "Object"), x.getParentsAsStrings) + assertEquals(List.empty, x.getDirectParentsAsStrings) + assertEquals(List("B2", "B3", "C1[A, B, C]", "E1", "E2"), x.getKnownChildrenAsStrings) + val graph = MemberExtension.getFrom(x).map(_.graph) + assertEquals(true, graph.isDefined) + assertEquals( + Seq( + "Object" -> "Any", + "A2[T]" -> "Object", + "B2" -> "A2[T]", // These are not actually true, becuase we lose information about hierarchy in subtypes and their possible mapping to supertypes other that that type itself, e. g. linking to `Object` + "B3" -> "A2[T]", + "C1[A, B, C]" -> "A2[T]", + "E1" -> "A2[T]", + "E2" -> "A2[T]" + ).sorted, + graph.get.edges.map((a, b) => (a.signature.getName, b.signature.getName)).sorted + ) + } + } + } + ) From 9b7f7ab6edaa6bcf5dea3db3ae48d5d077fe20c9 Mon Sep 17 00:00:00 2001 From: Andrzej Ratajczak Date: Mon, 7 Dec 2020 16:31:52 +0100 Subject: [PATCH 2/2] Apply requested changes to diagram tests --- .../dotty/dokka/model/api/membersUtils.scala | 32 ++-- .../dotty/dokka/diagram/HierarchyTest.scala | 174 +++++++++--------- 2 files changed, 103 insertions(+), 103 deletions(-) diff --git a/scala3doc/src/dotty/dokka/model/api/membersUtils.scala b/scala3doc/src/dotty/dokka/model/api/membersUtils.scala index e0be963f6ddf..a780876b106f 100644 --- a/scala3doc/src/dotty/dokka/model/api/membersUtils.scala +++ b/scala3doc/src/dotty/dokka/model/api/membersUtils.scala @@ -5,23 +5,23 @@ import scala.jdk.CollectionConverters.{ListHasAsScala, SeqHasAsJava} import dotty.dokka.model.api._ extension (m: DModule) - def visitMembers(callback: Member => Unit): Unit = - def visitClasslike(c: Member, callback: Member => Unit): Unit = - callback(c) - c.allMembers.foreach(visitClasslike(_, callback)) - m.getPackages.asScala.foreach(_.allMembers.foreach(visitClasslike(_, callback))) + def visitMembers(callback: Member => Unit): Unit = + def visitClasslike(c: Member): Unit = + callback(c) + c.allMembers.foreach(visitClasslike(_)) + m.getPackages.asScala.foreach(_.allMembers.foreach(visitClasslike(_))) extension (s: Signature) - def getName: String = - s.map { _ match - case s: String => s - case l: Link => l.name - }.mkString + def getName: String = + s.map { + case s: String => s + case l: Link => l.name + }.mkString extension (m: Member): - def getDirectParentsAsStrings: Seq[String] = - m.directParents.map(_.getName).sorted - def getParentsAsStrings: Seq[String] = - m.parents.map(_.signature.getName).sorted - def getKnownChildrenAsStrings: Seq[String] = - m.knownChildren.map(_.signature.getName).sorted + def getDirectParentsAsStrings: Seq[String] = + m.directParents.map(_.getName).sorted + def getParentsAsStrings: Seq[String] = + m.parents.map(_.signature.getName).sorted + def getKnownChildrenAsStrings: Seq[String] = + m.knownChildren.map(_.signature.getName).sorted diff --git a/scala3doc/test/dotty/dokka/diagram/HierarchyTest.scala b/scala3doc/test/dotty/dokka/diagram/HierarchyTest.scala index 5d7879e4cd93..e2b166ddda19 100644 --- a/scala3doc/test/dotty/dokka/diagram/HierarchyTest.scala +++ b/scala3doc/test/dotty/dokka/diagram/HierarchyTest.scala @@ -8,91 +8,91 @@ import scala.jdk.CollectionConverters.{ListHasAsScala, SeqHasAsJava} import org.junit.Assert.{assertSame, assertTrue, assertEquals} class HierarchyTest extends ScaladocTest("hierarchy"): - override def assertions = Seq( - AfterDocumentablesTransformation { m => - m.visitMembers { x => - if (x.getName == "C1") { - assertEquals(List("A1", "A2[Int]", "A3[Int, String]", "Any", "B1", "B2", "B3", "Object"), x.getParentsAsStrings) - assertEquals(List("B1", "B2", "B3"), x.getDirectParentsAsStrings) - assertEquals(List("E1", "E2"), x.getKnownChildrenAsStrings) - val graph = MemberExtension.getFrom(x).map(_.graph) - assertEquals(true, graph.isDefined) - assertEquals( - Seq( - "Object" -> "Any", - "A1" -> "Object", - "A2[Int]" -> "Object", - "A3[Int, String]" -> "Object", - "B1" -> "Object", - "B1" -> "A1", - "B2" -> "Object", - "B2" -> "A1", - "B2" -> "A2[Int]", - "B3" -> "Object", - "B3" -> "A2[Int]", - "B3" -> "A3[Int, String]", - "C1[A, B, C]" -> "Object", - "C1[A, B, C]" -> "B1", - "C1[A, B, C]" -> "B2", - "C1[A, B, C]" -> "B3", - "E1" -> "C1[A, B, C]", - "E2" -> "C1[A, B, C]" - ).sorted, - graph.get.edges.map((a, b) => (a.signature.getName, b.signature.getName)).sorted - ) - } - if (x.getName == "E2") { - assertEquals(List("A1", "A2[Int]", "A3[Int, String]", "Any", "B1", "B2", "B3", "C1[Int, Boolean, Any]", "D2[Int, Boolean]", "D3", "Object"), x.getParentsAsStrings) - assertEquals(List("C1[Int, Boolean, Any]", "D2[Int, Boolean]", "D3"), x.getDirectParentsAsStrings) - assertEquals(List.empty, x.getKnownChildrenAsStrings) - val graph = MemberExtension.getFrom(x).map(_.graph) - assertEquals(true, graph.isDefined) - assertEquals( - Seq( - "Object" -> "Any", - // "A1" -> "Object", // These are not applicable beacuase of bug and its workaround - // "A2[Int]" -> "Object", // More info at ClassLikeSupport.scala:37 - // "A3[Int, String]" -> "Object", - // "B1" -> "Object", - // "B1" -> "A1", - // "B2" -> "Object", - // "B2" -> "A1", - // "B2" -> "A2[Int]", - // "B3" -> "Object", - // "B3" -> "A2[Int]", - // "B3" -> "A3[Int, String]", - // "C1[Int, Boolean, Any]" -> "Object", - // "C1[Int, Boolean, Any]" -> "B1", - // "C1[Int, Boolean, Any]" -> "B2", - // "C1[Int, Boolean, Any]" -> "B3", - "E2" -> "D2[Int, Boolean]", - "E2" -> "D3", - "D2[Int, Boolean]" -> "Object", - "D3" -> "Object", - "E2" -> "C1[Int, Boolean, Any]" - ).sorted, - graph.get.edges.map((a, b) => (a.signature.getName, b.signature.getName)).sorted - ) - } - if (x.getName == "A2") { - assertEquals(List("Any", "Object"), x.getParentsAsStrings) - assertEquals(List.empty, x.getDirectParentsAsStrings) - assertEquals(List("B2", "B3", "C1[A, B, C]", "E1", "E2"), x.getKnownChildrenAsStrings) - val graph = MemberExtension.getFrom(x).map(_.graph) - assertEquals(true, graph.isDefined) - assertEquals( - Seq( - "Object" -> "Any", - "A2[T]" -> "Object", - "B2" -> "A2[T]", // These are not actually true, becuase we lose information about hierarchy in subtypes and their possible mapping to supertypes other that that type itself, e. g. linking to `Object` - "B3" -> "A2[T]", - "C1[A, B, C]" -> "A2[T]", - "E1" -> "A2[T]", - "E2" -> "A2[T]" - ).sorted, - graph.get.edges.map((a, b) => (a.signature.getName, b.signature.getName)).sorted - ) - } - } + override def assertions = Seq( + AfterDocumentablesTransformation { m => + m.visitMembers { x => + if (x.getName == "C1") { + assertEquals(List("A1", "A2[Int]", "A3[Int, String]", "Any", "B1", "B2", "B3", "Object"), x.getParentsAsStrings) + assertEquals(List("B1", "B2", "B3"), x.getDirectParentsAsStrings) + assertEquals(List("E1", "E2"), x.getKnownChildrenAsStrings) + val graph = MemberExtension.getFrom(x).map(_.graph) + assertTrue("Graph is empty!", graph.isDefined) + assertEquals( + Set( + "Object" -> "Any", + "A1" -> "Object", + "A2[Int]" -> "Object", + "A3[Int, String]" -> "Object", + "B1" -> "Object", + "B1" -> "A1", + "B2" -> "Object", + "B2" -> "A1", + "B2" -> "A2[Int]", + "B3" -> "Object", + "B3" -> "A2[Int]", + "B3" -> "A3[Int, String]", + "C1[A, B, C]" -> "Object", + "C1[A, B, C]" -> "B1", + "C1[A, B, C]" -> "B2", + "C1[A, B, C]" -> "B3", + "E1" -> "C1[A, B, C]", + "E2" -> "C1[A, B, C]" + ), + graph.get.edges.map((a, b) => (a.signature.getName, b.signature.getName)).toSet + ) } - ) + if (x.getName == "E2") { + assertEquals(List("A1", "A2[Int]", "A3[Int, String]", "Any", "B1", "B2", "B3", "C1[Int, Boolean, Any]", "D2[Int, Boolean]", "D3", "Object"), x.getParentsAsStrings) + assertEquals(List("C1[Int, Boolean, Any]", "D2[Int, Boolean]", "D3"), x.getDirectParentsAsStrings) + assertEquals(List.empty, x.getKnownChildrenAsStrings) + val graph = MemberExtension.getFrom(x).map(_.graph) + assertTrue("Graph is empty!", graph.isDefined) + assertEquals( + Set( + "Object" -> "Any", + // "A1" -> "Object", // These are not applicable beacuase of bug and its workaround + // "A2[Int]" -> "Object", // More info at ClassLikeSupport.scala:37 + // "A3[Int, String]" -> "Object", + // "B1" -> "Object", + // "B1" -> "A1", + // "B2" -> "Object", + // "B2" -> "A1", + // "B2" -> "A2[Int]", + // "B3" -> "Object", + // "B3" -> "A2[Int]", + // "B3" -> "A3[Int, String]", + // "C1[Int, Boolean, Any]" -> "Object", + // "C1[Int, Boolean, Any]" -> "B1", + // "C1[Int, Boolean, Any]" -> "B2", + // "C1[Int, Boolean, Any]" -> "B3", + "E2" -> "D2[Int, Boolean]", + "E2" -> "D3", + "D2[Int, Boolean]" -> "Object", + "D3" -> "Object", + "E2" -> "C1[Int, Boolean, Any]" + ), + graph.get.edges.map((a, b) => (a.signature.getName, b.signature.getName)).toSet + ) + } + if (x.getName == "A2") { + assertEquals(List("Any", "Object"), x.getParentsAsStrings) + assertEquals(List.empty, x.getDirectParentsAsStrings) + assertEquals(List("B2", "B3", "C1[A, B, C]", "E1", "E2"), x.getKnownChildrenAsStrings) + val graph = MemberExtension.getFrom(x).map(_.graph) + assertTrue("Graph is empty!", graph.isDefined) + assertEquals( + Set( + "Object" -> "Any", + "A2[T]" -> "Object", + "B2" -> "A2[T]", // These are not actually true, becuase we lose information about hierarchy in subtypes and their possible mapping to supertypes other that that type itself, e. g. linking to `Object` + "B3" -> "A2[T]", + "C1[A, B, C]" -> "A2[T]", + "E1" -> "A2[T]", + "E2" -> "A2[T]" + ), + graph.get.edges.map((a, b) => (a.signature.getName, b.signature.getName)).toSet + ) + } + } + } + )