Package com.google.gwt.user.cellview.client

Source Code of com.google.gwt.user.cellview.client.CellTreeTest

/*
* Copyright 2010 Google Inc.
*
* 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 com.google.gwt.user.cellview.client;

import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.TreeViewModel;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
* Tests for {@link CellTree}.
*/
public class CellTreeTest extends AbstractCellTreeTestBase {

  public CellTreeTest() {
    super(false);
  }

  public void testRefreshEmptyNode() {
    // An empty data provider.
    final ListDataProvider<String> provider = new ListDataProvider<String>();
    TreeViewModel model = new TreeViewModel() {
      @Override
      public NodeInfo<?> getNodeInfo(Object value) {
        TextCell cell = new TextCell();
        return new DefaultNodeInfo<String>(provider, cell);
      }

      @Override
      public boolean isLeaf(Object value) {
        return false;
      }
    };

    // Create the tree.
    CellTree tree = createAbstractCellTree(model, null);
    tree.rootNode.listView.presenter.flush();

    // Refresh the empty list.
    provider.refresh();
    provider.flush();
    tree.rootNode.listView.presenter.flush();
  }

  /**
   * Test that CellTree handles rendering the same content, but with a different
   * underlying value.
   */
  public void testRenderSameContent() {
    final AbstractCell<Integer> intCell = new AbstractCell<Integer>() {
      @Override
      public void render(Context context, Integer value, SafeHtmlBuilder sb) {
        sb.append(value % 10); // Render the units digit only.
      }
    };

    // Create a data provider for the root node.
    final ListDataProvider<Integer> root = new ListDataProvider<Integer>();
    for (int i = 0; i < 9; i++) {
      root.getList().add(i);
    }

    TreeViewModel model = new TreeViewModel() {
      @Override
      public NodeInfo<?> getNodeInfo(Object value) {
        if (value == null) {
          // Return the root node.
          return new DefaultNodeInfo<Integer>(root, intCell);
        } else {
          // Return a child node.
          return new DefaultNodeInfo<String>(new ListDataProvider<String>(), new TextCell());
        }
      }

      @Override
      public boolean isLeaf(Object value) {
        return false;
      }
    };

    CellTree tree = createAbstractCellTree(model, null);
    RootPanel.get().add(tree);
    tree.rootNode.listView.presenter.flush();

    // Open the first child.
    TreeNode rootNode = tree.getRootTreeNode();
    assertEquals(1, rootNode.getChildValue(1));
    TreeNode child1 = rootNode.setChildOpen(1, true);
    assertFalse(child1.isDestroyed());
    assertTrue(rootNode.isChildOpen(1));

    // Replace all values in the list.
    List<Integer> oldData = root.getList();
    List<Integer> newData = new ArrayList<Integer>();
    for (int l : oldData) {
      newData.add(l + 100); // renders the same as the current value.
    }
    root.setList(newData);
    root.flush();
    tree.rootNode.listView.presenter.flush();

    // Child1 is closed and destroyed.
    assertFalse(rootNode.isChildOpen(1));
    assertTrue(child1.isDestroyed());

    RootPanel.get().remove(tree);
  }

  /**
   * Test that replacing a subset of children updates both the TreeNode value
   * and the underlying DOM correctly.
   */
  public void testReplaceChildren() {
    CellTree cellTree = (CellTree) tree;
    TreeNode root = cellTree.getRootTreeNode();

    // Open a couple of child nodes.
    TreeNode a = root.setChildOpen(0, true);
    TreeNode b = root.setChildOpen(1, true);
    assertEquals("a", a.getValue());
    assertEquals("ab", a.getChildValue(1));
    assertEquals("b", b.getValue());
    assertEquals("bc", b.getChildValue(2));

    // Replace "b" with a "new" value.
    model.getRootDataProvider().getList().set(1, "new");
    model.getRootDataProvider().flush();
    assertFalse(a.isDestroyed());
    assertTrue(b.isDestroyed());
    TreeNode newNode = root.setChildOpen(1, true);
    assertEquals("a", a.getValue());
    assertEquals("ab", a.getChildValue(1));
    assertEquals("new", newNode.getValue());
    assertEquals("newc", newNode.getChildValue(2));

    // Check the underlying DOM values.
    CellTreeNodeView<?> aImpl = cellTree.rootNode.getChildNode(0);
    CellTreeNodeView<?> newNodeImpl = cellTree.rootNode.getChildNode(1);
    assertEquals("a", aImpl.getCellParent().getInnerText());
    assertEquals(10, aImpl.ensureChildContainer().getChildCount());
    assertEquals("new", newNodeImpl.getCellParent().getInnerText());
  }

  public void testAriaSelectedAndExpanded() {
    CellTree cellTree = (CellTree) tree;
    TreeNode root = cellTree.getRootTreeNode();

    TreeNode newNode = root.setChildOpen(1, true);
    cellTree.rootNode.getChildNode(1).setSelected(true);
    model.getRootDataProvider().refresh();
    model.getRootDataProvider().flush();
    root.setChildOpen(1, true);
    CellTreeNodeView<?> newNodeImpl = cellTree.rootNode.getChildNode(1);
    assertEquals("true", newNodeImpl.getElement().getAttribute("aria-selected"));
    // Check aria-expanded on open
    assertEquals("true", newNodeImpl.getElement().getAttribute("aria-expanded"));

    // Check aria-expanded on close
    root.setChildOpen(1, false);
    newNodeImpl = cellTree.rootNode.getChildNode(1);
    assertEquals("false", newNodeImpl.getElement().getAttribute("aria-expanded"));

    cellTree.rootNode.getChildNode(1).setSelected(false);
    model.getRootDataProvider().refresh();
    model.getRootDataProvider().flush();
    root.setChildOpen(1, true);
    newNodeImpl = cellTree.rootNode.getChildNode(1);
    assertEquals("false", newNodeImpl.getElement().getAttribute("aria-selected"));
  }

  public void testSetDefaultNodeSize() {
    CellTree cellTree = (CellTree) tree;
    TreeNode root = cellTree.getRootTreeNode();
    assertEquals(10, root.getChildCount());

    TreeNode b = root.setChildOpen(1, true);
    assertEquals(10, b.getChildCount());

    // Change the default size.
    cellTree.setDefaultNodeSize(5);
    assertEquals(5, cellTree.getDefaultNodeSize());
    assertEquals(10, b.getChildCount());
    TreeNode d = root.setChildOpen(3, true);
    assertEquals(5, d.getChildCount());
  }

  public void testAriaAttributes() {
    CellTree cellTree = (CellTree) tree;
    TreeNode rootNode = cellTree.getRootTreeNode();

    // Open a child node.
    TreeNode aNode = rootNode.setChildOpen(0, true);

    // Check role="tree"
    assertEquals("tree", cellTree.rootNode.getElement().getAttribute("role"));

    // Check 1st level
    CellTreeNodeView<?> aView = cellTree.rootNode.getChildNode(0);
    CellTreeNodeView<?> bView = cellTree.rootNode.getChildNode(1);

    // Check treeitem role, level, posinset, and setsize
    assertEquals("treeitem", aView.getElement().getAttribute("role"));
    assertEquals("1", aView.getElement().getAttribute("aria-level"));
    assertEquals("1", aView.getElement().getAttribute("aria-posinset"));
    assertEquals("10", aView.getElement().getAttribute("aria-setsize"));

    assertEquals("treeitem", bView.getElement().getAttribute("role"));
    assertEquals("1", bView.getElement().getAttribute("aria-level"));
    assertEquals("2", bView.getElement().getAttribute("aria-posinset"));
    assertEquals("10", bView.getElement().getAttribute("aria-setsize"));

    // Check 2nd level
    assertTrue(aNode.getChildCount() != 0);
    assertEquals(aNode, aView.getTreeNode());
    assertTrue(aView.getChildCount() != 0);
    CellTreeNodeView<?> aViewChild = aView.getChildNode(0);

    // Check treeitem role, level, posinset, and setsize
    assertEquals("treeitem", aViewChild.getElement().getAttribute("role"));
    assertEquals("2", aViewChild.getElement().getAttribute("aria-level"));
    assertEquals("1", aViewChild.getElement().getAttribute("aria-posinset"));
    assertEquals("10", aViewChild.getElement().getAttribute("aria-setsize"));

    // Check aria-expanded
    assertEquals("true", aView.getElement().getAttribute("aria-expanded"));
    assertEquals("false", aViewChild.getElement().getAttribute("aria-expanded"));
    while (!aNode.isChildLeaf(0)) {
      aNode = aNode.setChildOpen(0, true);
      aView = aView.getChildNode(0);
    }
    assertEquals(aNode, aView.getTreeNode());
    assertEquals("", aView.getChildNode(0).getElement().getAttribute("aria-expanded"));

    // Change default size and check aria-setsize and aria-posinset
    cellTree.setDefaultNodeSize(5);
    TreeNode cNode = rootNode.setChildOpen(3, true);
    CellTreeNodeView<?> cView = cellTree.rootNode.getChildNode(3);
    assertEquals(5, cNode.getChildCount());

    CellTreeNodeView<?> cViewChildFirst = cView.getChildNode(0);
    assertEquals("1", cViewChildFirst.getElement().getAttribute("aria-posinset"));
    assertEquals("5", cViewChildFirst.getElement().getAttribute("aria-setsize"));

    CellTreeNodeView<?> cViewChildLast = cView.getChildNode(cView.getChildCount() - 1);
    assertEquals("5", cViewChildLast.getElement().getAttribute("aria-posinset"));
    assertEquals("5", cViewChildLast.getElement().getAttribute("aria-setsize"));
  }

  public void testExplicitKeyboardSelection() {
    CellTree cellTree = (CellTree) tree;
    TreeNode root = cellTree.getRootTreeNode();

    final String cellTreeKeyboardSelectedItemStyleName =
        cellTree.getStyle().cellTreeKeyboardSelectedItem();

    // Navigate through tree to level 4 nodes.
    TreeNode l1Node = root.setChildOpen(0, true); // a
    CellTreeNodeView<?> l1View = cellTree.rootNode.getChildNode(0);
    TreeNode l2Node = l1Node.setChildOpen(0, true); // aa
    CellTreeNodeView<?> l2View = l1View.getChildNode(0);
    TreeNode l3Node = l2Node.setChildOpen(0, true); // aaa
    CellTreeNodeView<?> l3View = l2View.getChildNode(0);

    ((CellTreeNodeView.TreeNodeImpl) l3Node).flush();
    CellTreeNodeView<?> l4View = l3View.getChildNode(0);
    // l4Node is leaf, cannot get a reference via setChildOpen except via non-public nodeView
    TreeNode l4Node = l4View.getTreeNode(); // aaaa

    // Set keyboard selected node to a subtree node, l3Node = first child of l2Node
    cellTree.setKeyboardSelectedTreeNode(l2Node, 0, true);
    assertEquals(l3View, cellTree.getKeyboardSelectedNode());
    assertEquals(l3Node, cellTree.getKeyboardSelectedTreeNode());
    assertTrue(CellTreeNodeView.getSelectionElement(l3View.getElement()).getClassName()
        .indexOf(cellTreeKeyboardSelectedItemStyleName) >= 0);

    // Set keyboard selected node to a leaf node.
    cellTree.setKeyboardSelectedTreeNode(l3Node, 0, true);
    assertEquals(l4View, cellTree.getKeyboardSelectedNode());
    assertEquals(l4Node, cellTree.getKeyboardSelectedTreeNode());
    assertTrue(CellTreeNodeView.getSelectionElement(l4View.getElement()).getClassName()
        .indexOf(cellTreeKeyboardSelectedItemStyleName) >= 0);

    l1Node.setChildOpen(0, false); // close l2node
    ((CellTreeNodeView.TreeNodeImpl) l1Node).flush();

    // Try to select a leaf node in closed subtree
    try {
      cellTree.setKeyboardSelectedTreeNode(l3Node, 0, true);
      fail("should have thrown");
    } catch (IllegalStateException e) {
      assertEquals(e.getMessage(), "TreeNode no longer exists.");
    }

    // Try to select a subtree node in closed subtree
    try {
      cellTree.setKeyboardSelectedTreeNode(l2Node, 0, true);
      fail("should have thrown");
    } catch (IllegalStateException e) {
      assertEquals(e.getMessage(), "TreeNode no longer exists.");
    }

    // Still ok to select closed subtree node
    cellTree.setKeyboardSelectedTreeNode(l1Node, 0, true);

    // Create another tree of same structure
    CellTree anotherTree = createAbstractCellTree(model, root.getValue());
    l1Node = anotherTree.getRootTreeNode().setChildOpen(0, true); // a
    ((CellTreeNodeView.TreeNodeImpl) l1Node).flush();

    // Now l1Node refers to a subtree node in anotherTree
    // Select in the same cell tree is ok
    anotherTree.setKeyboardSelectedTreeNode(l1Node, 0, true);

    // Select in a different tree will throw exception.
    try {
      cellTree.setKeyboardSelectedTreeNode(l1Node, 0, true);
      fail("should have thrown");
    } catch (IllegalArgumentException e) {
      assertEquals(e.getMessage(), "The tree node does not belong to the tree.");
    }
  }

  public void testKeyboardNavigationForUpAndDownKeys() {
    CellTree cellTree = (CellTree) tree;
    TreeNode root = cellTree.getRootTreeNode();

    // Open nodes: a and aj
    TreeNode l1Node = root.setChildOpen(0, true); // a
    assertEquals(l1Node.getValue(), "a");
    TreeNode l2Node = l1Node.setChildOpen(9, true); // aj
    assertEquals(l2Node.getValue(), "aj");
    // To force tree structure changes (internal flush()).
    assertEquals(l2Node.getChildCount(), 10);

    // CellTree structure with node 'a' and 'aj' opened.
    List<String> expectedNavigationPath = Arrays.asList("a",
        "aa", "ab", "ac", "ad", "ae", "af", "ag", "ah", "ai", "aj",
        "aja", "ajb", "ajc", "ajd", "aje", "ajf", "ajg", "ajh", "aji", "ajj",
        "b", "c", "d", "e", "f", "g", "h", "i", "j");

    // Default KeyboardSelected is at "a"
    assertEquals(cellTree.getKeyboardSelectedTreeNode().getValue(), "a");

    int steps = expectedNavigationPath.size() - 1;
    assertEquals(expectedNavigationPath, repeatKeyInTree(cellTree, KeyCodes.KEY_DOWN, steps));

    Collections.reverse(expectedNavigationPath);
    assertEquals(expectedNavigationPath, repeatKeyInTree(cellTree, KeyCodes.KEY_UP, steps));
  }

  /**
   * Repeats a keystroke in the CellTree that contains string values.
   * @return the nodes selected before starting and after each keystroke.
   */
  private List<String> repeatKeyInTree(CellTree cellTree, int keyCode, int keyCount) {
    List<String> values = new ArrayList<String>();
    values.add((String) cellTree.getKeyboardSelectedTreeNode().getValue());
    for (int i = 0; i < keyCount; i++) {
      cellTree.handleKeyNavigation(keyCode);
      values.add((String) cellTree.getKeyboardSelectedTreeNode().getValue());
    }
    return values;
  }

  @Override
  protected <T> CellTree createAbstractCellTree(TreeViewModel model, T rootValue) {
    return new CellTree(model, rootValue);
  }
}
TOP

Related Classes of com.google.gwt.user.cellview.client.CellTreeTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.