This is an automated email from the ASF dual-hosted git repository. benw pushed a commit to branch TAP5-2745 in repository https://gitbox.apache.org/repos/asf/tapestry-5.git
commit 83c24a77eeea6e79b8fbccaec465a56c535d39a8 Author: Ben Weidig <b...@netzgut.net> AuthorDate: Sun Jun 25 11:25:35 2023 +0200 TAP5-2745: Tree component supports empty TreeModel --- .../apache/tapestry5/corelib/components/Tree.java | 7 +++-- .../apache/tapestry5/tree/DefaultTreeModel.java | 1 - .../tapestry5/integration/app1/TreeTests.groovy | 11 ++++++++ .../apache/tapestry5/integration/app1/Stuff.java | 13 ++++++++- .../tapestry5/integration/app1/pages/Index.java | 2 ++ .../integration/app1/pages/TreeNoRootsDemo.java | 31 ++++++++++++++++++++++ .../integration/app1/pages/TreeNoRootsDemo.tml | 7 +++++ 7 files changed, 68 insertions(+), 4 deletions(-) diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Tree.java b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Tree.java index 96f7752db..7167574a4 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Tree.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Tree.java @@ -255,8 +255,6 @@ public class Tree public RenderNodes(List<TreeNode> nodes) { - assert !nodes.isEmpty(); - this.nodes = F.flow(nodes).reverse(); } @@ -265,6 +263,11 @@ public class Tree writer.element("ul"); queue.push(RENDER_CLOSE_TAG); + // TAP5-2745: Support empty tree model + if (nodes.isEmpty()) { + return; + } + queue.push(toRenderCommand(nodes.first(), true)); nodes.rest().each(new Worker<TreeNode>() diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/tree/DefaultTreeModel.java b/tapestry-core/src/main/java/org/apache/tapestry5/tree/DefaultTreeModel.java index 38780b0a0..45343cff3 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/tree/DefaultTreeModel.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/tree/DefaultTreeModel.java @@ -133,7 +133,6 @@ public class DefaultTreeModel<T> implements TreeModel<T> assert encoder != null; assert adapter != null; assert roots != null; - assert !roots.isEmpty(); this.encoder = encoder; this.adapter = adapter; diff --git a/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/TreeTests.groovy b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/TreeTests.groovy index 5301a60ea..753155706 100644 --- a/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/TreeTests.groovy +++ b/tapestry-core/src/test/groovy/org/apache/tapestry5/integration/app1/TreeTests.groovy @@ -16,6 +16,8 @@ package org.apache.tapestry5.integration.app1 import org.testng.annotations.Test +import spock.lang.Issue + class TreeTests extends App1TestCase { @Test @@ -68,4 +70,13 @@ class TreeTests extends App1TestCase { waitForCssSelectorToAppear "span.selected-leaf-node" } + + @Issue("TAP5-2745") + @Test + void no_roots() { + openLinks "Tree Component No Roots Demo" + + assertTrue isElementPresent('css=.tree-container') + assertFalse isElementPresent('css=.tree-container span.tree-icon') + } } diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/Stuff.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/Stuff.java index 5fb9fed14..7291e4def 100644 --- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/Stuff.java +++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/Stuff.java @@ -19,6 +19,7 @@ import org.apache.tapestry5.commons.util.CollectionFactory; import org.apache.tapestry5.tree.DefaultTreeModel; import org.apache.tapestry5.tree.TreeModel; +import java.util.Collections; import java.util.List; import java.util.UUID; @@ -97,9 +98,19 @@ public class Stuff } public static TreeModel<Stuff> createTreeModel() + { + return createTreeModel(Stuff.ROOT.children); + } + + public static TreeModel<Stuff> createEmptyTreeModel() + { + return createTreeModel(Collections.emptyList()); + } + + private static TreeModel<Stuff> createTreeModel(List<Stuff> children) { ValueEncoder<Stuff> encoder = new StuffValueEncoder(); - return new DefaultTreeModel<Stuff>(encoder, new StuffTreeModelAdapter(), Stuff.ROOT.children); + return new DefaultTreeModel<Stuff>(encoder, new StuffTreeModelAdapter(), children); } } diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java index 348118a36..a121afb37 100644 --- a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java +++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java @@ -129,6 +129,8 @@ public class Index new Item("TreeSelectionDemo", "Tree Component Selection Demo", "Demo of Selection with Tree Component"), + new Item("TreeNoRootsDemo", "Tree Component No Roots Demo", "Demo of No Roots with Tree Component"), + new Item("InvalidExpressionInDynamicTemplate", "Invalid Dynamic Expression", "Invalid expression in a Dynamic Template"), diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/TreeNoRootsDemo.java b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/TreeNoRootsDemo.java new file mode 100644 index 000000000..c4a085984 --- /dev/null +++ b/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/TreeNoRootsDemo.java @@ -0,0 +1,31 @@ +// Copyright 2011 The Apache Software Foundation +// +// Licensed 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.tapestry5.integration.app1.pages; + +import org.apache.tapestry5.annotations.InjectComponent; +import org.apache.tapestry5.corelib.components.Tree; +import org.apache.tapestry5.integration.app1.Stuff; +import org.apache.tapestry5.tree.TreeModel; + +public class TreeNoRootsDemo +{ + @InjectComponent + private Tree tree; + + public TreeModel<Stuff> getStuffModel() + { + return Stuff.createEmptyTreeModel(); + } +} diff --git a/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/TreeNoRootsDemo.tml b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/TreeNoRootsDemo.tml new file mode 100644 index 000000000..32e587ade --- /dev/null +++ b/tapestry-core/src/test/resources/org/apache/tapestry5/integration/app1/pages/TreeNoRootsDemo.tml @@ -0,0 +1,7 @@ +<t:border xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd"> + + <h1>Tree No Roots Demo</h1> + + <t:tree class="test-hook" t:id="tree" model="stuffModel"/> + +</t:border> \ No newline at end of file