Package gov.nasa.arc.mct.gui.actions

Source Code of gov.nasa.arc.mct.gui.actions.TestDeleteAll$PseudoJTree

/*******************************************************************************
* Mission Control Technologies, Copyright (c) 2009-2012, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* The MCT platform is 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.
*
* MCT includes source code licensed under additional open source licenses. See
* the MCT Open Source Licenses file included with this distribution or the About
* MCT Licenses dialog available at runtime from the MCT Help menu for additional
* information.
*******************************************************************************/
package gov.nasa.arc.mct.gui.actions;

import gov.nasa.arc.mct.components.AbstractComponent;
import gov.nasa.arc.mct.gui.ContextAwareAction;
import gov.nasa.arc.mct.gui.MCTMutableTreeNode;
import gov.nasa.arc.mct.gui.SelectionProvider;
import gov.nasa.arc.mct.gui.View;
import gov.nasa.arc.mct.gui.housing.MCTDirectoryArea;
import gov.nasa.arc.mct.gui.housing.MCTHousing;
import gov.nasa.arc.mct.gui.impl.ActionContextImpl;
import gov.nasa.arc.mct.platform.spi.PersistenceProvider;
import gov.nasa.arc.mct.platform.spi.Platform;
import gov.nasa.arc.mct.platform.spi.PlatformAccess;
import gov.nasa.arc.mct.platform.spi.WindowManager;
import gov.nasa.arc.mct.policy.ExecutionResult;
import gov.nasa.arc.mct.policy.PolicyContext;
import gov.nasa.arc.mct.policy.PolicyInfo;
import gov.nasa.arc.mct.services.component.PolicyManager;
import gov.nasa.arc.mct.services.component.ViewInfo;
import gov.nasa.arc.mct.services.component.ViewType;

import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;

import javax.swing.JTree;
import javax.swing.tree.TreePath;

import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.testng.Assert;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class TestDeleteAll {
    private static final ResourceBundle BUNDLE =
            ResourceBundle.getBundle("gov/nasa/arc/mct/gui/actions/Bundle");
    private static final String CONFIRM = BUNDLE.getString("DeleteAllCoreText");
    private static final String ABORT = BUNDLE.getString("DeleteAllAbortText");
    private static final String OK = BUNDLE.getString("DeleteAllErrorConfirm");
   
   
    @Mock ActionContextImpl mockContext;
    @Mock MCTHousing mockHousing;
    @Mock SelectionProvider mockSelection;
    @Mock MCTDirectoryArea mockDirectory;
    @Mock Platform mockPlatform;
    @Mock PersistenceProvider mockPersistence;
    @Mock WindowManager mockWindowing;
    @Mock MCTMutableTreeNode mockNode;
    @Mock PolicyManager mockPolicy;
      
    private TreePath[] selectedTreePaths; // Since JTree can't be mocked
   
    private Platform oldPlatform;
  
    // For policy support
    private ExecutionResult yes = new ExecutionResult(null, true,  "");
    private ExecutionResult no  = new ExecutionResult(null, false, "");
    private Set<AbstractComponent> canCompose = new HashSet<AbstractComponent>();
    private Set<AbstractComponent> canDelete  = new HashSet<AbstractComponent>();
   
    private ContextAwareAction deleteAll;
   
    @BeforeClass
    public void cachePlatform() {
        oldPlatform = PlatformAccess.getPlatform();
    }
   
    @AfterClass
    public void restorePlatform() {
        new PlatformAccess().setPlatform(oldPlatform);
    }
   
    @BeforeMethod   
    public void setup() {
        MockitoAnnotations.initMocks(this);
        new PlatformAccess().setPlatform(mockPlatform);
       
        // Common setup
        Mockito.when(mockNode.getParentTree())
            .thenReturn(new PseudoJTree());
        Mockito.when(mockHousing.getSelectionProvider())
            .thenReturn(mockSelection);
        Mockito.when(mockPlatform.getPolicyManager())
            .thenReturn(mockPolicy);
        Mockito.when(mockPolicy.execute(
                Mockito.anyString(),Mockito.<PolicyContext>any()))
                .thenAnswer(new Answer<ExecutionResult>() {
                    @Override
                    public ExecutionResult answer(InvocationOnMock invocation) throws Throwable {
                        Set<AbstractComponent> set =
                                invocation.getArguments()[0].equals(
                                        PolicyInfo.CategoryType.COMPOSITION_POLICY_CATEGORY.getKey()) ?
                                                canCompose : canDelete;
                        PolicyContext context = (PolicyContext) invocation.getArguments()[1];
                        return set.contains(
                                context.getProperty(
                                        PolicyContext.PropertyName.TARGET_COMPONENT.getName(),
                                        AbstractComponent.class)) ?
                                                yes : no;
                    }                   
                });
       
        deleteAll = new DeleteAllAction();
    }
   
    @Test (dataProvider="canHandleTestCases")
    public void testCanHandle(
            boolean hasHousing,
            Collection<View> selection,
            boolean hasDirectory,
            boolean hasFirstNode,
            TreePath[] treePaths,
            boolean expected           
            ) {
        // Setup inputs
        Mockito.when(mockContext.getTargetHousing())
            .thenReturn(hasHousing ? mockHousing : null);
        Mockito.when(mockHousing.getDirectoryArea())
            .thenReturn(hasDirectory ? mockDirectory : null);
        Mockito.when(mockDirectory.getSelectedDirectoryNode())
            .thenReturn(hasFirstNode ? mockNode : null);
        Mockito.when(mockSelection.getSelectedManifestations())
            .thenReturn(selection);
           
        selectedTreePaths = treePaths;
       
        // Test can handle
        Assert.assertEquals(
                deleteAll.canHandle(mockContext),
                expected);
    }
   
    @Test (dataProvider = "isEnabledTestCases")
    public void testIsEnabled(
            boolean canComposeParent,
            boolean canDeleteParent,
            boolean[] canCompose,
            boolean[] canDelete,
            boolean expected
            ) {
        // Setup inputs
        Collection<View> selection =
                Arrays.asList(mockView(ViewType.NODE));
        Mockito.when(mockContext.getTargetHousing())
            .thenReturn(mockHousing);
        Mockito.when(mockHousing.getDirectoryArea())
            .thenReturn(mockDirectory);
        Mockito.when(mockDirectory.getSelectedDirectoryNode())
            .thenReturn(mockNode);
        Mockito.when(mockSelection.getSelectedManifestations())
            .thenReturn(selection);
       
        // Setup selected nodes, including a parent
        int nodes = Math.max(canCompose.length, canDelete.length);
        selectedTreePaths = new TreePath[nodes];
        AbstractComponent mockParent = mockComponent(canDeleteParent, canComposeParent);
        MCTMutableTreeNode mockParentNode = Mockito.mock(MCTMutableTreeNode.class);
        View mockParentView = mockView(mockParent, ViewType.NODE);
        Mockito.when(mockParentNode.getUserObject()).thenReturn(mockParentView);

        for (int i = 0; i < nodes; i++) {
            AbstractComponent mockChild =
                    mockComponent(canDelete [i % canDelete.length ],
                                  canCompose[i % canCompose.length]);
           
            TreePath mockPath = Mockito.mock(TreePath.class);
            MCTMutableTreeNode mockTreeNode = Mockito.mock(MCTMutableTreeNode.class);
            Mockito.when(mockPath.getLastPathComponent()).thenReturn(mockTreeNode);
            View mockView = mockView(mockChild, ViewType.NODE);           
            Mockito.when(mockTreeNode.getUserObject()).thenReturn(mockView);
            Mockito.when(mockTreeNode.getParent()).thenReturn(mockParentNode);
            selectedTreePaths[i] = mockPath;
        }
       
        // Verify precondition; obey ContextAwareAction life cycle
        Assert.assertTrue(deleteAll.canHandle(mockContext));
       
        // Test isEnabled
        Assert.assertEquals(deleteAll.isEnabled(), expected);
    }

    @Test (dataProvider = "actionPerformedTestCases")
    public void testActionPerformed(
            Collection<AbstractComponent> selected,
            String choice, // User choice in dialog
            final Collection<AbstractComponent> toDelete // null implies no persistence call
            ) {
        // Setup inputs
        Collection<View> selection =
                Arrays.asList(mockView(ViewType.NODE));
        Mockito.when(mockContext.getTargetHousing())
            .thenReturn(mockHousing);
        Mockito.when(mockHousing.getDirectoryArea())
            .thenReturn(mockDirectory);
        Mockito.when(mockDirectory.getSelectedDirectoryNode())
            .thenReturn(mockNode);
        Mockito.when(mockSelection.getSelectedManifestations())
            .thenReturn(selection);
        Mockito.when(mockPlatform.getPersistenceProvider())
            .thenReturn(mockPersistence);
        Mockito.when(mockPlatform.getWindowManager())
            .thenReturn(mockWindowing);
   
        // Setup selected nodes, including a parent       
        selectedTreePaths = new TreePath[selected.size()];
        AbstractComponent mockParent = mockComponent(false, true);
        MCTMutableTreeNode mockParentNode = Mockito.mock(MCTMutableTreeNode.class);
        View mockParentView = mockView(mockParent, ViewType.NODE);
        Mockito.when(mockParentNode.getUserObject()).thenReturn(mockParentView);

        int i = 0;
        for (AbstractComponent component : selected) {
            TreePath mockPath = Mockito.mock(TreePath.class);
            MCTMutableTreeNode mockTreeNode = Mockito.mock(MCTMutableTreeNode.class);
            Mockito.when(mockPath.getLastPathComponent()).thenReturn(mockTreeNode);
            View mockView = mockView(component, ViewType.NODE);           
            Mockito.when(mockTreeNode.getUserObject()).thenReturn(mockView);
            Mockito.when(mockTreeNode.getParent()).thenReturn(mockParentNode);
            selectedTreePaths[i++] = mockPath;
        }
       
        // Ensure dialog choice
        Mockito.when(mockWindowing.<Object>showInputDialog(
                Mockito.anyString(), Mockito.anyString(),
                Mockito.<Object[]>any(), Mockito.any(),
                Mockito.<Map<String,Object>>any()))
                .thenReturn(choice);
       
        // Verify precondition; obey ContextAwareAction life cycle
        Assert.assertTrue(deleteAll.canHandle(mockContext));
       
        // Verify precondition, obey life cycle
        Assert.assertEquals(deleteAll.isEnabled(), true);
       
        // Fire the action
        deleteAll.actionPerformed(Mockito.mock(ActionEvent.class));
       
        // Verify expected consequential interactions
        Mockito.verify(mockWindowing,
                Mockito.times(toDelete != null ? toDelete.size() : 0))
                .closeWindows(Mockito.anyString());
        Mockito.verify(mockPersistence,
                Mockito.times(toDelete != null ? 1 : 0))
                .delete(Mockito.argThat(
                        new ArgumentMatcher<Collection<AbstractComponent>>() {
                            @Override
                            public boolean matches(Object argument) {
                                if (argument instanceof Collection) {
                                    Collection c = (Collection) argument;
                                    return c.containsAll(toDelete) &&
                                            toDelete.containsAll(c);
                                }
                                return false;
                            }
                        }
                ));
    }
   
    @DataProvider
    public Object[][] canHandleTestCases() {
        Collection<Object[]> testCases = new ArrayList<Object[]>();
        boolean truths[] = {false, true};
       
        Collection<View> validSelection =
                Arrays.asList(mockView(ViewType.NODE));
       
        Collection<?>[] selections = {
                Collections.emptyList(),
                Arrays.asList(mockView(ViewType.OBJECT)),
                validSelection
        };
       
        TreePath[][] treePaths = {
                null,
                {},
                { Mockito.mock(TreePath.class) }
        };
       
        // Permute possible
        for (boolean hasHousing : truths) {
            for (Collection<?> selection : selections) {
                for (boolean hasDirectory : truths) {
                    for (boolean hasNode : truths) {
                        for (TreePath[] treePath : treePaths) {
                            // Based expectation on conditions
                            boolean expected =
                                    hasHousing &&
                                    (selection == validSelection) &&
                                    hasDirectory &&
                                    hasNode &&
                                    (treePath != null) &&
                                    (treePath.length != 0);
                           
                            testCases.add(new Object[]{
                                    hasHousing,
                                    selection,
                                    hasDirectory,
                                    hasNode,
                                    treePath,
                                    expected
                            });                           
                        }
                    }
                }
            }
        }
       
        Object[][] result = new Object[testCases.size()][];
        int i = 0;
        Iterator<Object[]> iter = testCases.iterator();
        while (iter.hasNext()) {
            result[i++] = iter.next();
        }
        return result;
    }

    @DataProvider
    public Object[][] isEnabledTestCases() {
        Collection<Object[]> testCases = new ArrayList<Object[]>();
        boolean truths[] = { false, true };

        // A variety of true/false arrangements to permute
        // Note: Arrays are treated as circular by test,
        //       so {true} covers {true,true,true}
        boolean groups[][] = {
                {true},
                {false},
                {false, false, false, false, true},
                {true, true, false}
        };
       
        for (boolean canComposeParent : truths) {
            for (boolean canDeleteParent : truths) {
                for (boolean[] canCompose : groups) {
                    for (boolean[] canDelete : groups) {
                        // Should only care that parent can be composed,
                        // and that all selected children can be deleted
                        boolean expected = canComposeParent;
                        for (boolean canDeleteChild : canDelete) {
                            expected &= canDeleteChild;
                        }
                        testCases.add(new Object[] {
                                canComposeParent,
                                canDeleteParent,
                                canCompose,
                                canDelete,
                                expected
                        });
                    }
                }
            }
        }
       
        Object[][] result = new Object[testCases.size()][];
        int i = 0;
        Iterator<Object[]> iter = testCases.iterator();
        while (iter.hasNext()) {
            result[i++] = iter.next();
        }
        return result;   
    }
   
    @DataProvider
    public Object[][] actionPerformedTestCases() {
        Collection<Object[]> testCases = new ArrayList<Object[]>();
        boolean[][] groups = {
                {true, true},
                {true, false},
                {false, true},
                {false, false}
        };
        boolean[] truths = { true, false };
       
        // Some other parent, somewhere
        AbstractComponent mockParent = mockComponent(false, true);
       
        for (boolean last : truths) { // Whether or not comps are the last manifestations
            for (boolean[] group : groups) {
                // Assemble object graphs
                Collection<AbstractComponent> selected = new ArrayList<AbstractComponent>();
                Collection<AbstractComponent> toDelete = new HashSet<AbstractComponent>();
                for (int i = 0; i < group.length; i++) {
                    AbstractComponent mockComponent = mockComponent(true, true);
                    Mockito.when(mockComponent.getReferencingComponents())
                        .thenReturn(Arrays.asList(mockParent));
                    toDelete.add(mockComponent);
                    selected.add(mockComponent);
                   
                    List<AbstractComponent> children = new ArrayList<AbstractComponent>();
                    for (int j = 0; j < group.length ; j++){
                        AbstractComponent mockChild = mockComponent(group[j], true);                   
                        children.add(mockChild);
                        if (group[j]) {
                            toDelete.add(mockChild);
                        }
                       
                        List<AbstractComponent> grandchildren = new ArrayList<AbstractComponent>();   
                        for (int k = 0; k < group.length; k++) {
                            AbstractComponent mockGrandchild = mockComponent(group[k], true);                     
                            grandchildren.add(mockGrandchild);
                            if (group[j] && group[k]) {
                                toDelete.add(mockGrandchild);
                            }
                            Mockito.when(mockGrandchild.getReferencingComponents())
                                .thenReturn(last ?
                                        Arrays.asList(mockChild) :
                                        Arrays.asList(mockParent, mockChild));   
                        }
                        Mockito.when(mockChild.getComponents())
                            .thenReturn(grandchildren);
                        Mockito.when(mockChild.getReferencingComponents())
                            .thenReturn(last ?
                                    Arrays.asList(mockComponent) :
                                    Arrays.asList(mockParent, mockComponent));
                    }
                    Mockito.when(mockComponent.getComponents())
                            .thenReturn(children);
                }
               
                // Can only delete if everything is deletable,
                // or there are no last manifestations.
                boolean canDelete = true;
                for (boolean delete : group) {
                   if (!delete) {
                       canDelete = !last;
                   }
                }
               
                // Exercise different choices for input dialog
                for (String choice : new String[] {CONFIRM, ABORT, OK}) {
                    if (choice.equals(ABORT) || !canDelete) {
                        toDelete = null;
                    }
                    testCases.add(new Object[]{selected,choice,toDelete});
                }
            }
        }
       
       
        Object[][] result = new Object[testCases.size()][];
        int i = 0;
        Iterator<Object[]> iter = testCases.iterator();
        while (iter.hasNext()) {
            result[i++] = iter.next();
        }
        return result;
    }  
   
    private static int counter = 0;   
    private AbstractComponent mockComponent(boolean canBeDeleted, boolean canBeComposed) {       
        final AbstractComponent mockComponent =
                Mockito.mock(AbstractComponent.class);
        Mockito.when(mockComponent.getComponents())
                .thenReturn(Collections.<AbstractComponent>emptyList());
        Mockito.when(mockComponent.getComponentId())
                .thenReturn("mock" + counter++);
        if (canBeDeleted) {
            canDelete.add(mockComponent);
        }
        if (canBeComposed) {
            canCompose.add(mockComponent);
        }
       
        return mockComponent;
    }
   
    private View mockView(ViewType vt) {
        return mockView(
                Mockito.mock(AbstractComponent.class),
                vt
                );
    }
   
    private View mockView(AbstractComponent ac, ViewType vt) {
        View view = Mockito.mock(View.class);
        ViewInfo viewInfo = Mockito.mock(ViewInfo.class);
        Mockito.when(viewInfo.getViewType()).thenReturn(vt);
        Mockito.when(view.getInfo()).thenReturn(viewInfo);
        Mockito.when(view.getManifestedComponent()).thenReturn(ac);
        return view;
    }
   
    private class PseudoJTree extends JTree {
        private static final long serialVersionUID = 1L;

        @Override
        public TreePath[] getSelectionPaths() {
            return selectedTreePaths;
        }
    }
   
}
TOP

Related Classes of gov.nasa.arc.mct.gui.actions.TestDeleteAll$PseudoJTree

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.