You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by hn...@apache.org on 2021/04/13 13:10:49 UTC

[myfaces-tobago] branch master updated: test(tree): add treeSelect unit test

This is an automated email from the ASF dual-hosted git repository.

hnoeth pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/myfaces-tobago.git


The following commit(s) were added to refs/heads/master by this push:
     new 9b21c19  test(tree): add treeSelect unit test
9b21c19 is described below

commit 9b21c19194ddd4dbb2a8d9331ecff24817939884
Author: Henning Noeth <hn...@apache.org>
AuthorDate: Tue Apr 13 14:50:59 2021 +0200

    test(tree): add treeSelect unit test
---
 .../internal/config/AbstractTobagoTestBase.java    |  16 ++
 .../renderkit/renderer/TreeRendererTestBase.java   |  58 +++++++
 .../renderer/TreeSelectRendererUnitTest.java       |  71 ++++++++
 .../renderer/treeSelect/treeSelect-single.html     | 184 +++++++++++++++++++++
 4 files changed, 329 insertions(+)

diff --git a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/AbstractTobagoTestBase.java b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/AbstractTobagoTestBase.java
index 74685cb..15cb79f 100644
--- a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/AbstractTobagoTestBase.java
+++ b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/config/AbstractTobagoTestBase.java
@@ -51,6 +51,10 @@ import org.apache.myfaces.tobago.component.UISelectOneRadio;
 import org.apache.myfaces.tobago.component.UISeparator;
 import org.apache.myfaces.tobago.component.UIStyle;
 import org.apache.myfaces.tobago.component.UITextarea;
+import org.apache.myfaces.tobago.component.UITree;
+import org.apache.myfaces.tobago.component.UITreeIndent;
+import org.apache.myfaces.tobago.component.UITreeNode;
+import org.apache.myfaces.tobago.component.UITreeSelect;
 import org.apache.myfaces.tobago.config.TobagoConfig;
 import org.apache.myfaces.tobago.context.TobagoContext;
 import org.apache.myfaces.tobago.internal.behavior.EventBehavior;
@@ -80,6 +84,10 @@ import org.apache.myfaces.tobago.internal.renderkit.renderer.SeparatorRenderer;
 import org.apache.myfaces.tobago.internal.renderkit.renderer.StyleRenderer;
 import org.apache.myfaces.tobago.internal.renderkit.renderer.TextareaRenderer;
 import org.apache.myfaces.tobago.internal.renderkit.renderer.TobagoClientBehaviorRenderer;
+import org.apache.myfaces.tobago.internal.renderkit.renderer.TreeIndentRenderer;
+import org.apache.myfaces.tobago.internal.renderkit.renderer.TreeNodeRenderer;
+import org.apache.myfaces.tobago.internal.renderkit.renderer.TreeRenderer;
+import org.apache.myfaces.tobago.internal.renderkit.renderer.TreeSelectRenderer;
 import org.apache.myfaces.tobago.internal.webapp.HtmlResponseWriter;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
@@ -160,6 +168,10 @@ public abstract class AbstractTobagoTestBase extends AbstractJsfTestCase {
     application.addComponent(Tags.separator.componentType(), UISeparator.class.getName());
     application.addComponent(Tags.style.componentType(), UIStyle.class.getName());
     application.addComponent(Tags.textarea.componentType(), UITextarea.class.getName());
+    application.addComponent(Tags.tree.componentType(), UITree.class.getName());
+    application.addComponent(Tags.treeNode.componentType(), UITreeNode.class.getName());
+    application.addComponent(Tags.treeIndent.componentType(), UITreeIndent.class.getName());
+    application.addComponent(Tags.treeSelect.componentType(), UITreeSelect.class.getName());
 
     application.addBehavior(AjaxBehavior.BEHAVIOR_ID, AjaxBehavior.class.getName());
     application.addBehavior(EventBehavior.BEHAVIOR_ID, EventBehavior.class.getName());
@@ -198,6 +210,10 @@ public abstract class AbstractTobagoTestBase extends AbstractJsfTestCase {
     renderKit.addRenderer(UISeparator.COMPONENT_FAMILY, RendererTypes.SEPARATOR, new SeparatorRenderer());
     renderKit.addRenderer(UIStyle.COMPONENT_FAMILY, RendererTypes.STYLE, new StyleRenderer());
     renderKit.addRenderer(UITextarea.COMPONENT_FAMILY, RendererTypes.TEXTAREA, new TextareaRenderer());
+    renderKit.addRenderer(UITree.COMPONENT_FAMILY, RendererTypes.TREE, new TreeRenderer());
+    renderKit.addRenderer(UITreeNode.COMPONENT_FAMILY, RendererTypes.TREE_NODE, new TreeNodeRenderer());
+    renderKit.addRenderer(UITreeIndent.COMPONENT_FAMILY, RendererTypes.TREE_INDENT, new TreeIndentRenderer());
+    renderKit.addRenderer(UITreeSelect.COMPONENT_FAMILY, RendererTypes.TREE_SELECT, new TreeSelectRenderer());
 
     renderKit.addClientBehaviorRenderer("org.apache.myfaces.tobago.behavior.Event", new TobagoClientBehaviorRenderer());
     renderKit.addClientBehaviorRenderer("org.apache.myfaces.tobago.behavior.Ajax", new TobagoClientBehaviorRenderer());
diff --git a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeRendererTestBase.java b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeRendererTestBase.java
new file mode 100644
index 0000000..024bb62
--- /dev/null
+++ b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeRendererTestBase.java
@@ -0,0 +1,58 @@
+/*
+ * 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.myfaces.tobago.internal.renderkit.renderer;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+
+public abstract class TreeRendererTestBase extends RendererTestBase {
+
+  DefaultMutableTreeNode getSample() {
+    final DefaultMutableTreeNode root = new DefaultMutableTreeNode("Category");
+    addNode(root, 0, "Sports");
+    addNode(root, 0, "Movies");
+    addNode(root, 0, "Music");
+    addNode(root, 1, "Classic");
+    addNode(root, 1, "Pop");
+    addNode(root, 1, "World");
+    addNode(root, 2, "Carib");
+    addNode(root, 2, "Africa");
+    addNode(root, 0, "Games");
+    addNode(root, 0, "Science");
+    addNode(root, 1, "Mathematics");
+    addNode(root, 2, "Analysis");
+    addNode(root, 2, "Algebra");
+    addNode(root, 1, "Geography");
+    addNode(root, 1, "Astronomy");
+    addNode(root, 2, "Education");
+    addNode(root, 2, "Pictures");
+    addNode(root, 3, "NGC");
+    addNode(root, 3, "Messier");
+
+    return root;
+  }
+
+  private void addNode(DefaultMutableTreeNode root, int level, Object userObject) {
+    DefaultMutableTreeNode node = root;
+    for (int i = 0; i < level; i++) {
+      node = (DefaultMutableTreeNode) node.getLastChild();
+    }
+    node.add(new DefaultMutableTreeNode(userObject));
+  }
+}
diff --git a/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeSelectRendererUnitTest.java b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeSelectRendererUnitTest.java
new file mode 100644
index 0000000..e0740ee
--- /dev/null
+++ b/tobago-core/src/test/java/org/apache/myfaces/tobago/internal/renderkit/renderer/TreeSelectRendererUnitTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.myfaces.tobago.internal.renderkit.renderer;
+
+import org.apache.myfaces.test.el.MockValueExpression;
+import org.apache.myfaces.tobago.component.RendererTypes;
+import org.apache.myfaces.tobago.component.Tags;
+import org.apache.myfaces.tobago.component.UITree;
+import org.apache.myfaces.tobago.component.UITreeIndent;
+import org.apache.myfaces.tobago.component.UITreeNode;
+import org.apache.myfaces.tobago.component.UITreeSelect;
+import org.apache.myfaces.tobago.model.Selectable;
+import org.apache.myfaces.tobago.util.ComponentUtils;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import javax.faces.component.behavior.AjaxBehavior;
+import java.io.IOException;
+
+public class TreeSelectRendererUnitTest extends TreeRendererTestBase {
+
+  @Test
+  public void treeSelectSingle() throws IOException {
+    final UITree tree = (UITree) ComponentUtils.createComponent(
+        facesContext, Tags.tree.componentType(), RendererTypes.Tree, "tree");
+    tree.setVar("node");
+    tree.setShowRoot(true);
+    tree.setSelectable(Selectable.single);
+    tree.setValue(getSample());
+    tree.getExpandedState().expandAll();
+
+    final UITreeNode treeNode = (UITreeNode) ComponentUtils.createComponent(
+        facesContext, Tags.treeNode.componentType(), RendererTypes.TreeNode, "treeNode");
+    tree.getChildren().add(treeNode);
+
+    final UITreeIndent treeIndent = (UITreeIndent) ComponentUtils.createComponent(
+        facesContext, Tags.treeIndent.componentType(), RendererTypes.TreeIndent, "treeIndent");
+    treeNode.getChildren().add(treeIndent);
+
+    final UITreeSelect treeSelect = (UITreeSelect) ComponentUtils.createComponent(
+        facesContext, Tags.treeSelect.componentType(), RendererTypes.TreeSelect, "treeSelect");
+    treeSelect.setId("treeSelect");
+    treeSelect.setValueExpression("label", new MockValueExpression("#{node.userObject}", String.class));
+    treeNode.getChildren().add(treeSelect);
+
+    final AjaxBehavior behavior =
+        (AjaxBehavior) facesContext.getApplication().createBehavior(AjaxBehavior.BEHAVIOR_ID);
+    treeSelect.addClientBehavior("change", behavior);
+
+    tree.encodeAll(facesContext);
+
+    Assertions.assertEquals(loadHtml("renderer/treeSelect/treeSelect-single.html"), formattedResult());
+  }
+}
diff --git a/tobago-core/src/test/resources/renderer/treeSelect/treeSelect-single.html b/tobago-core/src/test/resources/renderer/treeSelect/treeSelect-single.html
new file mode 100644
index 0000000..cd3576d
--- /dev/null
+++ b/tobago-core/src/test/resources/renderer/treeSelect/treeSelect-single.html
@@ -0,0 +1,184 @@
+<!--
+  ~ 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.
+  -->
+
+<tobago-tree id='tree' data-tobago-scroll-panel='true' data-tobago-selectable='single' selectable='single'>
+  <tobago-tree-node id='tree:0:treeNode' class='tobago-treeNode-markup-folder tobago-treeNode-markup-expanded' expandable='expandable' index='0' data-tobago-level='0'>
+    <span id='tree:0:treeIndent' class='tobago-treeNode-toggle'><i class='fa fa-minus-square-o' data-tobago-open='fa-minus-square-o' data-tobago-closed='fa-plus-square-o'></i></span>
+    <tobago-tree-select class='form-check-inline form-check'>
+      <input class='form-check-input' type='radio' name='tree' value='tree:0:treeSelect' id='tree:0:treeSelect'>
+      <label class='tobago-treeSelect-label form-check-label' for='tree:0:treeSelect'>Category</label>
+      <tobago-behavior event='change' client-id='tree:0:treeSelect' execute='tree:0:treeSelect tree' render='null tree'></tobago-behavior>
+    </tobago-tree-select>
+  </tobago-tree-node>
+  <tobago-tree-node id='tree:1:treeNode' index='1' data-tobago-tree-parent='tree:0:treeNode' parent='tree:0:treeNode' data-tobago-level='1'>
+    <span id='tree:1:treeIndent' class='tobago-treeNode-toggle invisible'><i class='fa fa-square-o invisible'></i></span>
+    <tobago-tree-select class='form-check-inline form-check'>
+      <input class='form-check-input' type='radio' name='tree' value='tree:1:treeSelect' id='tree:1:treeSelect'>
+      <label class='tobago-treeSelect-label form-check-label' for='tree:1:treeSelect'>Sports</label>
+      <tobago-behavior event='change' client-id='tree:1:treeSelect' execute='tree:1:treeSelect tree' render='null tree'></tobago-behavior>
+    </tobago-tree-select>
+  </tobago-tree-node>
+  <tobago-tree-node id='tree:2:treeNode' index='2' data-tobago-tree-parent='tree:0:treeNode' parent='tree:0:treeNode' data-tobago-level='1'>
+    <span id='tree:2:treeIndent' class='tobago-treeNode-toggle invisible'><i class='fa fa-square-o invisible'></i></span>
+    <tobago-tree-select class='form-check-inline form-check'>
+      <input class='form-check-input' type='radio' name='tree' value='tree:2:treeSelect' id='tree:2:treeSelect'>
+      <label class='tobago-treeSelect-label form-check-label' for='tree:2:treeSelect'>Movies</label>
+      <tobago-behavior event='change' client-id='tree:2:treeSelect' execute='tree:2:treeSelect tree' render='null tree'></tobago-behavior>
+    </tobago-tree-select>
+  </tobago-tree-node>
+  <tobago-tree-node id='tree:3:treeNode' class='tobago-treeNode-markup-folder tobago-treeNode-markup-expanded' expandable='expandable' index='3' data-tobago-tree-parent='tree:0:treeNode' parent='tree:0:treeNode' data-tobago-level='1'>
+    <span id='tree:3:treeIndent' class='tobago-treeNode-toggle'><i class='fa fa-minus-square-o' data-tobago-open='fa-minus-square-o' data-tobago-closed='fa-plus-square-o'></i></span>
+    <tobago-tree-select class='form-check-inline form-check'>
+      <input class='form-check-input' type='radio' name='tree' value='tree:3:treeSelect' id='tree:3:treeSelect'>
+      <label class='tobago-treeSelect-label form-check-label' for='tree:3:treeSelect'>Music</label>
+      <tobago-behavior event='change' client-id='tree:3:treeSelect' execute='tree:3:treeSelect tree' render='null tree'></tobago-behavior>
+    </tobago-tree-select>
+  </tobago-tree-node>
+  <tobago-tree-node id='tree:4:treeNode' index='4' data-tobago-tree-parent='tree:3:treeNode' parent='tree:3:treeNode' data-tobago-level='2'>
+    <span id='tree:4:treeIndent' class='tobago-treeNode-toggle invisible'><i class='fa fa-square-o invisible'></i></span>
+    <tobago-tree-select class='form-check-inline form-check'>
+      <input class='form-check-input' type='radio' name='tree' value='tree:4:treeSelect' id='tree:4:treeSelect'>
+      <label class='tobago-treeSelect-label form-check-label' for='tree:4:treeSelect'>Classic</label>
+      <tobago-behavior event='change' client-id='tree:4:treeSelect' execute='tree:4:treeSelect tree' render='null tree'></tobago-behavior>
+    </tobago-tree-select>
+  </tobago-tree-node>
+  <tobago-tree-node id='tree:5:treeNode' index='5' data-tobago-tree-parent='tree:3:treeNode' parent='tree:3:treeNode' data-tobago-level='2'>
+    <span id='tree:5:treeIndent' class='tobago-treeNode-toggle invisible'><i class='fa fa-square-o invisible'></i></span>
+    <tobago-tree-select class='form-check-inline form-check'>
+      <input class='form-check-input' type='radio' name='tree' value='tree:5:treeSelect' id='tree:5:treeSelect'>
+      <label class='tobago-treeSelect-label form-check-label' for='tree:5:treeSelect'>Pop</label>
+      <tobago-behavior event='change' client-id='tree:5:treeSelect' execute='tree:5:treeSelect tree' render='null tree'></tobago-behavior>
+    </tobago-tree-select>
+  </tobago-tree-node>
+  <tobago-tree-node id='tree:6:treeNode' class='tobago-treeNode-markup-folder tobago-treeNode-markup-expanded' expandable='expandable' index='6' data-tobago-tree-parent='tree:3:treeNode' parent='tree:3:treeNode' data-tobago-level='2'>
+    <span id='tree:6:treeIndent' class='tobago-treeNode-toggle'><i class='fa fa-minus-square-o' data-tobago-open='fa-minus-square-o' data-tobago-closed='fa-plus-square-o'></i></span>
+    <tobago-tree-select class='form-check-inline form-check'>
+      <input class='form-check-input' type='radio' name='tree' value='tree:6:treeSelect' id='tree:6:treeSelect'>
+      <label class='tobago-treeSelect-label form-check-label' for='tree:6:treeSelect'>World</label>
+      <tobago-behavior event='change' client-id='tree:6:treeSelect' execute='tree:6:treeSelect tree' render='null tree'></tobago-behavior>
+    </tobago-tree-select>
+  </tobago-tree-node>
+  <tobago-tree-node id='tree:7:treeNode' index='7' data-tobago-tree-parent='tree:6:treeNode' parent='tree:6:treeNode' data-tobago-level='3'>
+    <span id='tree:7:treeIndent' class='tobago-treeNode-toggle invisible'><i class='fa fa-square-o invisible'></i></span>
+    <tobago-tree-select class='form-check-inline form-check'>
+      <input class='form-check-input' type='radio' name='tree' value='tree:7:treeSelect' id='tree:7:treeSelect'>
+      <label class='tobago-treeSelect-label form-check-label' for='tree:7:treeSelect'>Carib</label>
+      <tobago-behavior event='change' client-id='tree:7:treeSelect' execute='tree:7:treeSelect tree' render='null tree'></tobago-behavior>
+    </tobago-tree-select>
+  </tobago-tree-node>
+  <tobago-tree-node id='tree:8:treeNode' index='8' data-tobago-tree-parent='tree:6:treeNode' parent='tree:6:treeNode' data-tobago-level='3'>
+    <span id='tree:8:treeIndent' class='tobago-treeNode-toggle invisible'><i class='fa fa-square-o invisible'></i></span>
+    <tobago-tree-select class='form-check-inline form-check'>
+      <input class='form-check-input' type='radio' name='tree' value='tree:8:treeSelect' id='tree:8:treeSelect'>
+      <label class='tobago-treeSelect-label form-check-label' for='tree:8:treeSelect'>Africa</label>
+      <tobago-behavior event='change' client-id='tree:8:treeSelect' execute='tree:8:treeSelect tree' render='null tree'></tobago-behavior>
+    </tobago-tree-select>
+  </tobago-tree-node>
+  <tobago-tree-node id='tree:9:treeNode' index='9' data-tobago-tree-parent='tree:0:treeNode' parent='tree:0:treeNode' data-tobago-level='1'>
+    <span id='tree:9:treeIndent' class='tobago-treeNode-toggle invisible'><i class='fa fa-square-o invisible'></i></span>
+    <tobago-tree-select class='form-check-inline form-check'>
+      <input class='form-check-input' type='radio' name='tree' value='tree:9:treeSelect' id='tree:9:treeSelect'>
+      <label class='tobago-treeSelect-label form-check-label' for='tree:9:treeSelect'>Games</label>
+      <tobago-behavior event='change' client-id='tree:9:treeSelect' execute='tree:9:treeSelect tree' render='null tree'></tobago-behavior>
+    </tobago-tree-select>
+  </tobago-tree-node>
+  <tobago-tree-node id='tree:10:treeNode' class='tobago-treeNode-markup-folder tobago-treeNode-markup-expanded' expandable='expandable' index='10' data-tobago-tree-parent='tree:0:treeNode' parent='tree:0:treeNode' data-tobago-level='1'>
+    <span id='tree:10:treeIndent' class='tobago-treeNode-toggle'><i class='fa fa-minus-square-o' data-tobago-open='fa-minus-square-o' data-tobago-closed='fa-plus-square-o'></i></span>
+    <tobago-tree-select class='form-check-inline form-check'>
+      <input class='form-check-input' type='radio' name='tree' value='tree:10:treeSelect' id='tree:10:treeSelect'>
+      <label class='tobago-treeSelect-label form-check-label' for='tree:10:treeSelect'>Science</label>
+      <tobago-behavior event='change' client-id='tree:10:treeSelect' execute='tree:10:treeSelect tree' render='null tree'></tobago-behavior>
+    </tobago-tree-select>
+  </tobago-tree-node>
+  <tobago-tree-node id='tree:11:treeNode' class='tobago-treeNode-markup-folder tobago-treeNode-markup-expanded' expandable='expandable' index='11' data-tobago-tree-parent='tree:10:treeNode' parent='tree:10:treeNode' data-tobago-level='2'>
+    <span id='tree:11:treeIndent' class='tobago-treeNode-toggle'><i class='fa fa-minus-square-o' data-tobago-open='fa-minus-square-o' data-tobago-closed='fa-plus-square-o'></i></span>
+    <tobago-tree-select class='form-check-inline form-check'>
+      <input class='form-check-input' type='radio' name='tree' value='tree:11:treeSelect' id='tree:11:treeSelect'>
+      <label class='tobago-treeSelect-label form-check-label' for='tree:11:treeSelect'>Mathematics</label>
+      <tobago-behavior event='change' client-id='tree:11:treeSelect' execute='tree:11:treeSelect tree' render='null tree'></tobago-behavior>
+    </tobago-tree-select>
+  </tobago-tree-node>
+  <tobago-tree-node id='tree:12:treeNode' index='12' data-tobago-tree-parent='tree:11:treeNode' parent='tree:11:treeNode' data-tobago-level='3'>
+    <span id='tree:12:treeIndent' class='tobago-treeNode-toggle invisible'><i class='fa fa-square-o invisible'></i></span>
+    <tobago-tree-select class='form-check-inline form-check'>
+      <input class='form-check-input' type='radio' name='tree' value='tree:12:treeSelect' id='tree:12:treeSelect'>
+      <label class='tobago-treeSelect-label form-check-label' for='tree:12:treeSelect'>Analysis</label>
+      <tobago-behavior event='change' client-id='tree:12:treeSelect' execute='tree:12:treeSelect tree' render='null tree'></tobago-behavior>
+    </tobago-tree-select>
+  </tobago-tree-node>
+  <tobago-tree-node id='tree:13:treeNode' index='13' data-tobago-tree-parent='tree:11:treeNode' parent='tree:11:treeNode' data-tobago-level='3'>
+    <span id='tree:13:treeIndent' class='tobago-treeNode-toggle invisible'><i class='fa fa-square-o invisible'></i></span>
+    <tobago-tree-select class='form-check-inline form-check'>
+      <input class='form-check-input' type='radio' name='tree' value='tree:13:treeSelect' id='tree:13:treeSelect'>
+      <label class='tobago-treeSelect-label form-check-label' for='tree:13:treeSelect'>Algebra</label>
+      <tobago-behavior event='change' client-id='tree:13:treeSelect' execute='tree:13:treeSelect tree' render='null tree'></tobago-behavior>
+    </tobago-tree-select>
+  </tobago-tree-node>
+  <tobago-tree-node id='tree:14:treeNode' index='14' data-tobago-tree-parent='tree:10:treeNode' parent='tree:10:treeNode' data-tobago-level='2'>
+    <span id='tree:14:treeIndent' class='tobago-treeNode-toggle invisible'><i class='fa fa-square-o invisible'></i></span>
+    <tobago-tree-select class='form-check-inline form-check'>
+      <input class='form-check-input' type='radio' name='tree' value='tree:14:treeSelect' id='tree:14:treeSelect'>
+      <label class='tobago-treeSelect-label form-check-label' for='tree:14:treeSelect'>Geography</label>
+      <tobago-behavior event='change' client-id='tree:14:treeSelect' execute='tree:14:treeSelect tree' render='null tree'></tobago-behavior>
+    </tobago-tree-select>
+  </tobago-tree-node>
+  <tobago-tree-node id='tree:15:treeNode' class='tobago-treeNode-markup-folder tobago-treeNode-markup-expanded' expandable='expandable' index='15' data-tobago-tree-parent='tree:10:treeNode' parent='tree:10:treeNode' data-tobago-level='2'>
+    <span id='tree:15:treeIndent' class='tobago-treeNode-toggle'><i class='fa fa-minus-square-o' data-tobago-open='fa-minus-square-o' data-tobago-closed='fa-plus-square-o'></i></span>
+    <tobago-tree-select class='form-check-inline form-check'>
+      <input class='form-check-input' type='radio' name='tree' value='tree:15:treeSelect' id='tree:15:treeSelect'>
+      <label class='tobago-treeSelect-label form-check-label' for='tree:15:treeSelect'>Astronomy</label>
+      <tobago-behavior event='change' client-id='tree:15:treeSelect' execute='tree:15:treeSelect tree' render='null tree'></tobago-behavior>
+    </tobago-tree-select>
+  </tobago-tree-node>
+  <tobago-tree-node id='tree:16:treeNode' index='16' data-tobago-tree-parent='tree:15:treeNode' parent='tree:15:treeNode' data-tobago-level='3'>
+    <span id='tree:16:treeIndent' class='tobago-treeNode-toggle invisible'><i class='fa fa-square-o invisible'></i></span>
+    <tobago-tree-select class='form-check-inline form-check'>
+      <input class='form-check-input' type='radio' name='tree' value='tree:16:treeSelect' id='tree:16:treeSelect'>
+      <label class='tobago-treeSelect-label form-check-label' for='tree:16:treeSelect'>Education</label>
+      <tobago-behavior event='change' client-id='tree:16:treeSelect' execute='tree:16:treeSelect tree' render='null tree'></tobago-behavior>
+    </tobago-tree-select>
+  </tobago-tree-node>
+  <tobago-tree-node id='tree:17:treeNode' class='tobago-treeNode-markup-folder tobago-treeNode-markup-expanded' expandable='expandable' index='17' data-tobago-tree-parent='tree:15:treeNode' parent='tree:15:treeNode' data-tobago-level='3'>
+    <span id='tree:17:treeIndent' class='tobago-treeNode-toggle'><i class='fa fa-minus-square-o' data-tobago-open='fa-minus-square-o' data-tobago-closed='fa-plus-square-o'></i></span>
+    <tobago-tree-select class='form-check-inline form-check'>
+      <input class='form-check-input' type='radio' name='tree' value='tree:17:treeSelect' id='tree:17:treeSelect'>
+      <label class='tobago-treeSelect-label form-check-label' for='tree:17:treeSelect'>Pictures</label>
+      <tobago-behavior event='change' client-id='tree:17:treeSelect' execute='tree:17:treeSelect tree' render='null tree'></tobago-behavior>
+    </tobago-tree-select>
+  </tobago-tree-node>
+  <tobago-tree-node id='tree:18:treeNode' index='18' data-tobago-tree-parent='tree:17:treeNode' parent='tree:17:treeNode' data-tobago-level='4'>
+    <span id='tree:18:treeIndent' class='tobago-treeNode-toggle invisible'><i class='fa fa-square-o invisible'></i></span>
+    <tobago-tree-select class='form-check-inline form-check'>
+      <input class='form-check-input' type='radio' name='tree' value='tree:18:treeSelect' id='tree:18:treeSelect'>
+      <label class='tobago-treeSelect-label form-check-label' for='tree:18:treeSelect'>NGC</label>
+      <tobago-behavior event='change' client-id='tree:18:treeSelect' execute='tree:18:treeSelect tree' render='null tree'></tobago-behavior>
+    </tobago-tree-select>
+  </tobago-tree-node>
+  <tobago-tree-node id='tree:19:treeNode' index='19' data-tobago-tree-parent='tree:17:treeNode' parent='tree:17:treeNode' data-tobago-level='4'>
+    <span id='tree:19:treeIndent' class='tobago-treeNode-toggle invisible'><i class='fa fa-square-o invisible'></i></span>
+    <tobago-tree-select class='form-check-inline form-check'>
+      <input class='form-check-input' type='radio' name='tree' value='tree:19:treeSelect' id='tree:19:treeSelect'>
+      <label class='tobago-treeSelect-label form-check-label' for='tree:19:treeSelect'>Messier</label>
+      <tobago-behavior event='change' client-id='tree:19:treeSelect' execute='tree:19:treeSelect tree' render='null tree'></tobago-behavior>
+    </tobago-tree-select>
+  </tobago-tree-node>
+  <input type='hidden' name='tree::selected' id='tree::selected' class='tobago-tree-selected' value='[]'>
+  <input type='hidden' name='tree::expanded' id='tree::expanded' class='tobago-tree-expanded' value='[0,3,6,10,11,15,17]'>
+  <input id='tree::scrollPosition' name='tree::scrollPosition' type='hidden' value='[0,0]' data-tobago-scroll-position='true'>
+</tobago-tree>