/* * Copyright (C) 2015 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.android.switchaccess.builders; import android.annotation.TargetApi; import android.content.Context; import android.os.Build; import android.text.TextUtils; import android.view.accessibility.AccessibilityNodeInfo; import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat; import com.android.switchaccess.ClearFocusNode; import com.android.switchaccess.ContextMenuItem; import com.android.switchaccess.ContextMenuNode; import com.android.switchaccess.GlobalActionNode; import com.android.switchaccess.OptionScanNode; import com.android.switchaccess.OptionScanSelectionNode; import com.android.switchaccess.SwitchAccessNodeCompat; import com.android.talkback.BuildConfig; import com.android.switchaccess.SwitchAccessWindowInfo; import com.android.switchaccess.test.ShadowAccessibilityNodeInfo; import com.android.switchaccess.treebuilding.BinaryTreeBuilder; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricGradleTestRunner; import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import java.util.Arrays; import java.util.List; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertTrue; import static org.junit.Assert.assertFalse; /** * Tests for BinaryTreeBuilder */ @Config( constants = BuildConfig.class, sdk = 21, shadows = { ShadowAccessibilityNodeInfo.class, ShadowAccessibilityNodeInfo.ShadowAccessibilityAction.class}) @TargetApi(Build.VERSION_CODES.LOLLIPOP) @RunWith(RobolectricGradleTestRunner.class) public class BinaryTreeBuilderTest { private final Context mContext = RuntimeEnvironment.application.getApplicationContext(); BinaryTreeBuilder mBinaryTreeBuilder; OptionScanNode mBaseTree; @Before public void setUp() { ShadowAccessibilityNodeInfo.resetObtainedInstances(); mBaseTree = new ClearFocusNode(); mBinaryTreeBuilder = new BinaryTreeBuilder(mContext) { @Override public OptionScanNode addViewHierarchyToTree(SwitchAccessNodeCompat node, OptionScanNode treeToBuildOn) { return null; } @Override public OptionScanNode addWindowListToTree(List<SwitchAccessWindowInfo> windowList, OptionScanNode treeToBuildOn) { return null; } }; } @After public void tearDown() { assertFalse(ShadowAccessibilityNodeInfo.areThereUnrecycledNodes(true)); } @Test public void testAddCompatToTree_nodeWithNoActions_shouldAddNothing() { SwitchAccessNodeCompat compatWithNoActions = new SwitchAccessNodeCompat(AccessibilityNodeInfo.obtain()); compatWithNoActions.setClickable(false); OptionScanNode resultTree = mBinaryTreeBuilder.addCompatToTree(compatWithNoActions, mBaseTree); compatWithNoActions.recycle(); assertTrue(resultTree instanceof ClearFocusNode); } @Test public void testAddCompatToTree_scrollableNode_shouldAddContextMenu() { AccessibilityNodeInfo info = AccessibilityNodeInfo.obtain(); info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD); info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD); info.setVisibleToUser(true); SwitchAccessNodeCompat compatWithScrollActions = new SwitchAccessNodeCompat(info); OptionScanNode resultTree = mBinaryTreeBuilder.addCompatToTree(compatWithScrollActions, mBaseTree); OptionScanSelectionNode selectionNode = (OptionScanSelectionNode) resultTree; compatWithScrollActions.recycle(); assertEquals(2, selectionNode.getChildCount()); assertTrue(selectionNode.getChild(0) instanceof ContextMenuNode); assertTrue(selectionNode.getChild(1) instanceof ClearFocusNode); resultTree.recycle(); } @Test public void testAddCompatToTree_invisibleNode_shouldAddNothing() { SwitchAccessNodeCompat invisibleCompat = new SwitchAccessNodeCompat(AccessibilityNodeInfo.obtain()); invisibleCompat.setScrollable(true); invisibleCompat.setVisibleToUser(false); OptionScanNode resultTree = mBinaryTreeBuilder.addCompatToTree(invisibleCompat, mBaseTree); invisibleCompat.recycle(); assertTrue(resultTree instanceof ClearFocusNode); } @Test public void testBuildContextMenuTreeWithNullList_shouldHaveClearFocusNode() { OptionScanNode node = mBinaryTreeBuilder.buildContextMenu(null); Assert.assertTrue(node instanceof ClearFocusNode); node.recycle(); } @Test public void testBuildContextMenuTreeWithTwoItems_shouldHaveExpectedStructure() { CharSequence globalActionLabel0 = "global action label 0"; CharSequence globalActionLabel1 = "global action label 1"; ContextMenuItem globalNode0 = new GlobalActionNode(0, null, globalActionLabel0); ContextMenuItem globalNode1 = new GlobalActionNode(1, null, globalActionLabel1); ContextMenuNode contextMenuTree = (ContextMenuNode) mBinaryTreeBuilder .buildContextMenu(Arrays.asList(globalNode0, globalNode1)); Assert.assertEquals(2, contextMenuTree.getChildCount()); GlobalActionNode firstActionNode = (GlobalActionNode) contextMenuTree.getChild(0); Assert.assertTrue(TextUtils.equals(globalActionLabel0, firstActionNode.getActionLabel(mContext))); ContextMenuNode secondLevelOfMenu = (ContextMenuNode) contextMenuTree.getChild(1); Assert.assertEquals(2, secondLevelOfMenu.getChildCount()); GlobalActionNode secondActionNode = (GlobalActionNode) secondLevelOfMenu.getChild(0); Assert.assertTrue(TextUtils.equals(globalActionLabel1, secondActionNode.getActionLabel(mContext))); Assert.assertTrue(secondLevelOfMenu.getChild(1) instanceof ClearFocusNode); contextMenuTree.recycle(); } }