You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by jo...@apache.org on 2021/09/10 11:01:20 UTC
[isis] 03/07: ISIS-2846 link tree diagram works
This is an automated email from the ASF dual-hosted git repository.
joergrade pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git
commit f848f38abbc4ec553bce83cae6315d483d48f4d4
Author: Jörg Rade <jo...@kuehne-nagel.com>
AuthorDate: Wed Sep 8 18:28:05 2021 +0200
ISIS-2846 link tree diagram works
---
.../kroviz/core/aggregator/AggregatorWithLayout.kt | 2 +
.../client/kroviz/core/event/LogEntryDecorator.kt | 156 ---------------------
.../isis/client/kroviz/core/event/ResourceProxy.kt | 46 +++---
.../client/kroviz/ui/diagram/LinkTreeDiagram.kt | 131 +++++++----------
.../apache/isis/client/kroviz/ui/diagram/Node.kt | 7 +-
.../isis/client/kroviz/ui/diagram/PumlCode.kt | 5 +
.../client/kroviz/ui/diagram/{Node.kt => Tree.kt} | 28 +++-
.../isis/client/kroviz/ui/dialog/EventLogDetail.kt | 8 +-
.../isis/client/kroviz/core/event/LogEntryTest.kt | 4 +-
.../isis/client/kroviz/ui/diagram/TreeTest.kt | 56 ++++++++
10 files changed, 163 insertions(+), 280 deletions(-)
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/AggregatorWithLayout.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/AggregatorWithLayout.kt
index 4bea388..32ed837 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/AggregatorWithLayout.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/aggregator/AggregatorWithLayout.kt
@@ -6,11 +6,13 @@ import org.apache.isis.client.kroviz.layout.Layout
import org.apache.isis.client.kroviz.to.Represention
import org.apache.isis.client.kroviz.to.TObject
import org.apache.isis.client.kroviz.ui.core.Constants
+import org.apache.isis.client.kroviz.ui.diagram.Tree
abstract class AggregatorWithLayout : BaseAggregator() {
// parentUrl is to be set in update
// and to be used in subsequent invocations
var parentUrl: String? = null
+ var tree: Tree? = null
override fun update(logEntry: LogEntry, subType: String) {
parentUrl = logEntry.url
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntryDecorator.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntryDecorator.kt
deleted file mode 100644
index f891eeb..0000000
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/LogEntryDecorator.kt
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.isis.client.kroviz.core.event
-
-import org.apache.isis.client.kroviz.to.Link
-import org.apache.isis.client.kroviz.to.Relation
-import org.apache.isis.client.kroviz.ui.core.Constants
-
-class LogEntryDecorator(val logEntry: LogEntry) {
-
- val href: String = logEntry.selfHref()
- val links: List<Link> = logEntry.getLinks()
- val linked: List<LogEntry> = EventStore.getLinked()
-
- fun findChildren(): Set<LogEntry> {
- val children = findChildrenByUpRelation()
- children.plus(findChildrenByReference())
- children.plus(findChildrenByLinks())
- return children
- }
-
- private fun findChildrenByUpRelation(): Set<LogEntry> {
- val children = mutableSetOf<LogEntry>()
- linked.forEach {
- it.getLinks().forEach { l ->
- if ((l.relation() == Relation.UP) && (l.href == href)) {
- children.add(it)
- }
- }
- }
- return children
- }
-
- private fun findChildrenByLinks(): Set<LogEntry> {
- console.log("[LED.findChildrenByLinks]")
- val children = mutableSetOf<LogEntry>()
- links.forEach {
- console.log(it.toString())
- val rel = it.relation()
- when {
- (rel == Relation.UP) -> {
- }
- (rel == Relation.SELF) -> {
- }
- else -> {
- val rsj = ResourceSpecification(it.href, Constants.subTypeJson)
- var le = EventStore.findBy(rsj)
- if (le == null) {
- val rsx = ResourceSpecification(it.href, Constants.subTypeXml)
- le = EventStore.findBy(rsx)
- }
- console.log(le.toString())
- if (le != null) children.add(le)
- }
- }
- }
- return children
- }
-
- fun findChildrenOfLogEntry(): List<LogEntry> {
- console.log("[LED.findChildrenOfLogEntry]")
- val children = mutableListOf<LogEntry>()
- val links = logEntry.getLinks()
- console.log("[links] ->")
- console.log(links)
- console.log(links.size)
- links.forEach {
- console.log(it.toString())
- when (it.relation()) {
- Relation.UP -> {
- }
- Relation.SELF -> {
- }
- else -> {
- val url = it.href
- console.log(url)
- val rsj = ResourceSpecification(url, Constants.subTypeJson)
- var le = EventStore.findBy(rsj)
- if (le == null) {
- val rsx = ResourceSpecification(url, Constants.subTypeXml)
- le = EventStore.findBy(rsx)
- }
- console.log(le.toString())
- if (le != null) children.add(le)
- }
- }
- }
- console.log("[children] ->")
- console.log(children)
- return children
- }
-
- private fun findChildrenByReference(): Set<LogEntry> {
- val str = logEntry.response
- val children = mutableSetOf<LogEntry>()
- linked.forEach {
- if (it != logEntry && str.contains(it.url)) {
- children.add(it)
- }
- }
- return children
- }
-
- fun findChildrenIn(aggregatedList: List<LogEntry>): List<LogEntry> {
- console.log("[LED.findChildrenIn]")
- console.log(aggregatedList)
- val selfUrl = href
- val children = mutableListOf<LogEntry>()
- aggregatedList.forEach {
- if (it.url != selfUrl && it.response.contains(selfUrl)) {
- children.add(it)
- }
- }
- console.log(children)
- return children
- }
-
- fun selfType(): String {
- val selfLink = logEntry.selfLink()
- return if (selfLink != null) {
- selfLink.representation().type
- } else {
- console.log("[LED.selfType]")
- console.log(logEntry)
- ""
- }
- }
-
- fun findParent(): LogEntry? {
- val url = logEntry.url
- linked.forEach {
- when {
- it.selfHref() == url -> return null
- it.response.contains(url) -> return it
- }
- }
- return null
- }
-
-}
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/ResourceProxy.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/ResourceProxy.kt
index 92d60a1..ad596a0 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/ResourceProxy.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/core/event/ResourceProxy.kt
@@ -27,6 +27,7 @@ import org.apache.isis.client.kroviz.to.Link
import org.apache.isis.client.kroviz.to.TObject
import org.apache.isis.client.kroviz.ui.core.Constants
import org.apache.isis.client.kroviz.ui.diagram.Node
+import org.apache.isis.client.kroviz.ui.diagram.Tree
/**
* Facade for RoXmlHttpRequest. If a resource is being fetched, it:
@@ -51,18 +52,6 @@ class ResourceProxy {
}
}
- private fun processCached(rs: ResourceSpecification, aggregator: BaseAggregator?) {
- val le = EventStore.findBy(rs)!!
- le.retrieveResponse()
- if (aggregator == null) {
- ResponseHandler.handle(le)
- } else {
- aggregator.update(le, le.subType)
- }
- le.setCached()
- EventStore.updateStatus(le)
- }
-
fun fetch(link: Link,
aggregator: BaseAggregator? = null,
subType: String = Constants.subTypeJson,
@@ -75,25 +64,36 @@ class ResourceProxy {
}
when {
isCached -> processCached(rs, aggregator)
- !isCached && isRest -> {
- if (aggregator is AggregatorWithLayout) {
- val child = Node(link.href)
-//FIXME aggregator.root.add(child)
- }
- RoXmlHttpRequest(aggregator).process(link, subType)
- }
+ !isCached && isRest -> process(aggregator, link, subType, referrer)
!isCached && !isRest -> RoXmlHttpRequest(aggregator).processNonREST(link, subType)
}
}
- private fun isNotRenderedYet(aggregator: BaseAggregator?): Boolean {
- if (aggregator != null && aggregator is AggregatorWithLayout) {
- return !aggregator.dpm.isRendered
+ private fun process(aggregator: BaseAggregator?, link: Link, subType: String, referrer: String) {
+ if (aggregator is AggregatorWithLayout) {
+ if (aggregator.tree == null) {
+ val root = Node(referrer, null)
+ aggregator.tree = Tree(root)
+ }
+ aggregator.tree!!.addChildToParent(link.href, referrer)
+
+ }
+ RoXmlHttpRequest(aggregator).process(link, subType)
+ }
+
+ private fun processCached(rs: ResourceSpecification, aggregator: BaseAggregator?) {
+ val le = EventStore.findBy(rs)!!
+ le.retrieveResponse()
+ if (aggregator == null) {
+ ResponseHandler.handle(le)
} else {
- return false
+ aggregator.update(le, le.subType)
}
+ le.setCached()
+ EventStore.updateStatus(le)
}
+
fun invokeKroki(pumlCode: String, aggregator: SvgDispatcher) {
RoXmlHttpRequest(aggregator).invokeKroki(pumlCode)
}
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/diagram/LinkTreeDiagram.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/diagram/LinkTreeDiagram.kt
index 9e6c480..bc3789d 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/diagram/LinkTreeDiagram.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/diagram/LinkTreeDiagram.kt
@@ -18,10 +18,10 @@
*/
package org.apache.isis.client.kroviz.ui.diagram
+import org.apache.isis.client.kroviz.core.aggregator.AggregatorWithLayout
import org.apache.isis.client.kroviz.core.aggregator.BaseAggregator
import org.apache.isis.client.kroviz.core.event.EventStore
import org.apache.isis.client.kroviz.core.event.LogEntry
-import org.apache.isis.client.kroviz.core.event.LogEntryDecorator
import org.apache.isis.client.kroviz.core.event.ResourceSpecification
import org.apache.isis.client.kroviz.to.HasLinks
import org.apache.isis.client.kroviz.ui.core.UiManager
@@ -29,102 +29,71 @@ import org.apache.isis.client.kroviz.utils.StringUtils
object LinkTreeDiagram {
- private const val NL = "\n"
- private const val prolog = "@startmindmap$NL"
- private const val epilog = "@endmindmap$NL"
private val protocolHostPort = UiManager.getUrl()
fun build(aggregator: BaseAggregator): String {
- var code = prolog
- val entryList: List<LogEntry> = EventStore.findAllBy(aggregator)
- val root = findRoot(entryList)
- if (root == null) {
- code += "* / $NL"
- code += createNodes(entryList, 2)
- } else {
- code += root.asPumlNode(1)
- val led = LogEntryDecorator(root)
- val childList = led.findChildrenOfLogEntry()
- console.log(aggregator)
- console.log(entryList)
- code += createChildNodes(childList, 2)
- }
- code += epilog
- return code
- }
-
- private fun createChildNodes(childList: List<LogEntry>, level: Int): String {
- var code = ""
- childList.forEach {
- code += createNode(it, level)
- val led = LogEntryDecorator(it)
- val kidSet = led.findChildrenOfLogEntry()
- code += createChildNodes(kidSet, level + 1)
- }
- return code
- }
-
- private fun createNode(le: LogEntry, level: Int): String {
- var code = ""
- if (isInEventStore(le.url)) {
- code += le.asPumlNode(level)
- }
- return code
- }
-
- private fun createNodes(entryList: List<LogEntry>, level: Int): String {
- var code = ""
- entryList.forEach {
- code += createNode(it, level)
- }
- return code
- }
-
- private fun findRoot(entryList: List<LogEntry>): LogEntry? {
- entryList.forEach {
- val led = LogEntryDecorator(it)
- val parent = led.findParent()
- if (parent != null && !entryList.contains(parent)) {
- return parent
- }
+ console.log("[LTD.build]")
+ val pc = PumlCode()
+ if (aggregator is AggregatorWithLayout) {
+ val tree = aggregator.tree!!
+ val root = tree.root
+ console.log(root)
+ pc.code += toPumlCode(root, 1)
}
- return null
+ pc.mindmap()
+ console.log(pc.code)
+ return pc.code
}
- private fun isInEventStore(url: String): Boolean {
+ private fun toPumlCode(node: Node, level: Int): String {
+ val url = node.key
val rs = ResourceSpecification(url)
val le = EventStore.findBy(rs)
- return (le != null)
- }
-
- fun LogEntry.asPumlNode(level: Int): String {
- val led = LogEntryDecorator(this)
- val url = this.url
- val title = StringUtils.shortTitle(url, protocolHostPort)
- val type = led.selfType()
- val depth = "*".repeat(level)
val pc = PumlCode()
- pc.add(depth).add(":")
- pc.addStereotype(type)
- pc.addLink(url, title)
- pc.addHorizontalLine()
- pc.add(traceInfo(this))
- pc.addLine(";")
+ if (le != null) {
+ val title = StringUtils.shortTitle(url, protocolHostPort)
+ val type = le.selfType()
+ val depth = "*".repeat(level)
+ pc.add(depth).add(":")
+ pc.addStereotype(type)
+ pc.addLink(url, title)
+ pc.addHorizontalLine()
+ pc.add(traceInfo(le))
+ pc.addLine(";")
+ node.children.forEach {
+ val childCode = toPumlCode(it, level + 1)
+ pc.add(childCode)
+ }
+ }
return pc.code
}
private fun traceInfo(logEntry: LogEntry): String {
- val obj = logEntry.obj!!
- val className = obj::class.simpleName!!
- val pc = PumlCode().addClass(className)
- if (obj is HasLinks) {
- obj.links.forEach {
- val url = it.href
- val title = StringUtils.shortTitle(url, protocolHostPort)
- pc.addLink(url, title)
+ val pc = PumlCode()
+ val obj = logEntry.obj
+ if (obj != null) {
+ val className = obj::class.simpleName!!
+ pc.addClass(className)
+ if (obj is HasLinks) {
+ obj.links.forEach {
+ val url = it.href
+ val title = StringUtils.shortTitle(url, protocolHostPort)
+ pc.addLink(url, title)
+ }
}
}
return pc.code
}
+ private fun LogEntry.selfType(): String {
+ val selfLink = this.selfLink()
+ return if (selfLink != null) {
+ selfLink.representation().type
+ } else {
+ console.log("[LE.selfType]")
+ console.log(this)
+ ""
+ }
+ }
+
}
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/diagram/Node.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/diagram/Node.kt
index 19bc68c..79c0930 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/diagram/Node.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/diagram/Node.kt
@@ -18,13 +18,8 @@
*/
package org.apache.isis.client.kroviz.ui.diagram
-class Node(val key: String) {
+class Node(val key: String, val parent: Node?) {
- var parent: Node? = null
val children = mutableListOf<Node>()
- fun add(child: Node) {
- children.add(child)
- }
-
}
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/diagram/PumlCode.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/diagram/PumlCode.kt
index ac5ea8d..86410eb 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/diagram/PumlCode.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/diagram/PumlCode.kt
@@ -55,6 +55,11 @@ class PumlCode() {
return this
}
+ fun mindmap(): PumlCode {
+ code += "@startmindmap$NL" + code + "@endmindmap$NL"
+ return this
+ }
+
private fun center(s: String): String {
return ".." + s + ".."
}
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/diagram/Node.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/diagram/Tree.kt
similarity index 57%
copy from incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/diagram/Node.kt
copy to incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/diagram/Tree.kt
index 19bc68c..922bc94 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/diagram/Node.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/diagram/Tree.kt
@@ -18,13 +18,31 @@
*/
package org.apache.isis.client.kroviz.ui.diagram
-class Node(val key: String) {
+class Tree(val root: Node) {
- var parent: Node? = null
- val children = mutableListOf<Node>()
+ fun addChildToParent(childUrl: String, parentUrl: String) {
+ var p = find(parentUrl, root)
+ if (p == null) {
+ p = root
+ }
+ val c = Node(childUrl, p)
+ p.children.add(c)
+ }
- fun add(child: Node) {
- children.add(child)
+ fun find(url: String, node: Node): Node? {
+ if (node.key == url) {
+ return node
+ } else {
+ var answer: Node? = null
+ node.children.forEach {
+ if (it.key == url) {
+ answer = it
+ } else {
+ answer = find(url, it)
+ }
+ }
+ return answer
+ }
}
}
diff --git a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventLogDetail.kt b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventLogDetail.kt
index 6eb29f6..e72da92 100644
--- a/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventLogDetail.kt
+++ b/incubator/clients/kroviz/src/main/kotlin/org/apache/isis/client/kroviz/ui/dialog/EventLogDetail.kt
@@ -20,7 +20,6 @@ package org.apache.isis.client.kroviz.ui.dialog
import org.apache.isis.client.kroviz.core.event.EventStore
import org.apache.isis.client.kroviz.core.event.LogEntry
-import org.apache.isis.client.kroviz.core.event.LogEntryDecorator
import org.apache.isis.client.kroviz.core.event.ResourceSpecification
import org.apache.isis.client.kroviz.to.ValueType
import org.apache.isis.client.kroviz.to.bs3.Grid
@@ -41,7 +40,7 @@ class EventLogDetail(val logEntryFromTabulator: LogEntry) : Command() {
// For a yet unknown reason, aggregators are not transmitted via tabulator.
// As a WORKAROUND, we fetch the full blown LogEntry from the EventStore again.
val rs = ResourceSpecification(logEntryFromTabulator.title)
- logEntry = EventStore.findBy(rs)?: logEntryFromTabulator // in case of xml, we use the entry passed in
+ logEntry = EventStore.findBy(rs) ?: logEntryFromTabulator // in case of xml, we use the entry passed in
}
// callback parameter
@@ -55,15 +54,10 @@ class EventLogDetail(val logEntryFromTabulator: LogEntry) : Command() {
XmlHelper.format(logEntry.response)
}
- val led = LogEntryDecorator(logEntry)
- val children = led.findChildren()
- var kids = ""
- children.forEach { kids += it.url + "\n" }
val formItems = mutableListOf<FormItem>()
formItems.add(FormItem("Url", ValueType.TEXT, logEntry.title))
formItems.add(FormItem("Response", ValueType.TEXT_AREA, responseStr, 10))
formItems.add(FormItem("Aggregators", ValueType.TEXT, content = logEntry.aggregators))
- formItems.add(FormItem("Children", ValueType.TEXT_AREA, kids, size = 5))
formItems.add(FormItem("Link Tree Diagram", ValueType.BUTTON, null, callBack = this, callBackAction = LNK))
formItems.add(FormItem("Console", ValueType.BUTTON, null, callBack = this, callBackAction = LOG))
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/event/LogEntryTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/event/LogEntryTest.kt
index 9ff7b10..dea66af 100644
--- a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/event/LogEntryTest.kt
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/core/event/LogEntryTest.kt
@@ -30,7 +30,7 @@ class LogEntryTest {
val url = "https://kroki.io"
// when
- val le = LogEntry(url)
+ val le = LogEntry(ResourceSpecification(url))
// then
assertFalse(le.title.startsWith("/"))
@@ -39,7 +39,7 @@ class LogEntryTest {
@Test
fun testCalculate() {
// given
- val le = LogEntry("http://test/url")
+ val le = LogEntry(ResourceSpecification("http://test/url"))
// when
le.setSuccess()
diff --git a/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/ui/diagram/TreeTest.kt b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/ui/diagram/TreeTest.kt
new file mode 100644
index 0000000..712bc86
--- /dev/null
+++ b/incubator/clients/kroviz/src/test/kotlin/org/apache/isis/client/kroviz/ui/diagram/TreeTest.kt
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.isis.client.kroviz.ui.diagram
+
+import kotlin.test.*
+
+class TreeTest {
+
+ @BeforeTest
+ fun setup() {
+ }
+
+ @Test
+ fun testAddChildToParent() {
+ //given
+ val url_0 = "root"
+ val url_1 = "level_1"
+ val url_1_1 = "level_1_1"
+ val url_1_2 = "level_1_2"
+ val root = Node(url_0, null)
+ val tree = Tree(root)
+
+ //when
+ tree.addChildToParent(url_1, url_0)
+ tree.addChildToParent(url_1_1, url_1)
+ tree.addChildToParent(url_1_2, url_1)
+
+ //then
+ val r = tree.find(url_0, root)!!
+ assertEquals(1, r.children.size)
+ assertNull(r.parent)
+
+ val c = tree.find(url_1, root)!!
+ assertNotNull(c.parent)
+ assertEquals(2, c.children.size)
+ assertEquals(url_1_1, c.children.first().key)
+ assertEquals(url_1_2, c.children.last().key)
+ }
+
+}