org.springframework.ide.eclipse.boot.dash.test.BootDashModelStateSaverTest.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.ide.eclipse.boot.dash.test.BootDashModelStateSaverTest.java

Source

/*******************************************************************************
 * Copyright (c) 2015 Pivotal Software, Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Pivotal Software, Inc. - initial API and implementation
 *******************************************************************************/
package org.springframework.ide.eclipse.boot.dash.test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.PrintStream;

import org.apache.commons.io.FileUtils;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ISaveContext;
import org.eclipse.core.resources.ISavedState;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchManager;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.ide.eclipse.boot.dash.model.BootDashElement;
import org.springframework.ide.eclipse.boot.dash.model.BootDashElementFactory;
import org.springframework.ide.eclipse.boot.dash.model.BootDashModelStateSaver;
import org.springframework.ide.eclipse.boot.dash.test.mocks.Mocks;

/**
 * @author Kris De Volder
 */
public class BootDashModelStateSaverTest extends Mocks {

    private TestBootDashModelContext context;
    private BootDashElementFactory factory;

    /**
     * Path of the save file without save numbers, relative to the state location.
     */
    private final IPath SAVE_FILE_NAME = new Path("preferredLaunches");

    private ISavedState emptySavedState() {
        ISavedState mock = mock(ISavedState.class);
        when(mock.lookup(any(IPath.class))).thenReturn(null);
        when(mock.getSaveNumber()).thenReturn(1);
        return mock;
    }

    private ISavedState mockSavedState(int saveNumber, File saveFile) {
        ISavedState mock = mock(ISavedState.class);
        when(mock.getSaveNumber()).thenReturn(saveNumber);
        when(mock.lookup(any(IPath.class))).thenReturn(new Path(saveFile.toString()));
        return mock;
    }

    @Before
    public void setup() throws Exception {
        this.context = spy(new TestBootDashModelContext(mock(IWorkspace.class), mock(ILaunchManager.class)));
        when(context.getWorkspace().getRoot()).thenReturn(mock(IWorkspaceRoot.class));
        this.factory = mock(BootDashElementFactory.class);
    }

    ////////////////////////////////////////////////////////////////

    @Test
    public void testRestoreFromEmptyStateLocation() throws Exception {
        BootDashModelStateSaver state = new BootDashModelStateSaver(context, factory);
        state.restore(emptySavedState());

        assertTrue(state.isEmpty());
    }

    @Test
    public void testGetAndSetPreferredConfig() throws Exception {
        BootDashModelStateSaver state = new BootDashModelStateSaver(context, factory);
        assertTrue(state.isEmpty());

        IProject project = mockProject("foo", true);
        BootDashElement dashElement = mock(BootDashElement.class);
        when(factory.createOrGet(project)).thenReturn(dashElement);
        ILaunchConfiguration conf = mock(ILaunchConfiguration.class);

        state.setPreferredConfig(dashElement, conf);

        assertEquals(conf, state.getPreferredConfig(dashElement));
    }

    @Test
    public void testSaveAndRestoreEmptyState() throws Exception {
        int saveNumber = 13;
        IPath saveFilePath = context.getStateLocation().append(SAVE_FILE_NAME + "-" + saveNumber);
        File saveFile = saveFilePath.toFile();
        {
            BootDashModelStateSaver state = new BootDashModelStateSaver(context, factory);
            assertTrue(state.isEmpty());

            ISaveContext saveContext = mock(ISaveContext.class);
            when(saveContext.getSaveNumber()).thenReturn(saveNumber);

            assertFalse(saveFile.exists());

            state.prepareToSave(saveContext);
            state.saving(saveContext);
            state.doneSaving(saveContext);

            verify(saveContext).map(SAVE_FILE_NAME, saveFilePath);
            verify(saveContext).needSaveNumber();

            assertTrue(saveFile.exists());
        }
        ///////////////////////////////////////////////////////////////
        {
            BootDashModelStateSaver state = new BootDashModelStateSaver(context, factory);
            ISavedState savedState = mockSavedState(saveNumber, saveFilePath.toFile());
            assertTrue(state.isEmpty());

            state.restore(savedState); //Check this actually loaded the file somehow?

            assertTrue(state.isEmpty());
        }
    }

    @Test
    public void testSaveAndRestoreState() throws Exception {
        int saveNumber = 13;
        IPath saveFilePath = context.getStateLocation().append(SAVE_FILE_NAME + "-" + saveNumber);
        File saveFile = saveFilePath.toFile();

        IProject project = mockProject("foo", true);
        BootDashElement dashElement = mockElement(project);
        when(factory.createOrGet(project)).thenReturn(dashElement);
        when(context.getWorkspace().getRoot().getProject("foo")).thenReturn(project);

        ILaunchConfiguration conf = mock(ILaunchConfiguration.class);
        when(conf.getMemento()).thenReturn("fooMemento");
        when(context.getLaunchManager().getLaunchConfiguration("fooMemento")).thenReturn(conf);
        when(conf.exists()).thenReturn(true);

        {
            BootDashModelStateSaver state = new BootDashModelStateSaver(context, factory);
            assertTrue(state.isEmpty());

            ISaveContext saveContext = mock(ISaveContext.class);
            when(saveContext.getSaveNumber()).thenReturn(saveNumber);

            assertFalse(saveFile.exists());

            state.setPreferredConfig(dashElement, conf);

            state.prepareToSave(saveContext);
            state.saving(saveContext);
            state.doneSaving(saveContext);

            verify(saveContext).map(SAVE_FILE_NAME, saveFilePath);
            verify(saveContext).needSaveNumber();

            assertTrue(saveFile.exists());
        }
        ///////////////////////////////////////////////////////////////
        {
            BootDashModelStateSaver state = new BootDashModelStateSaver(context, factory);
            ISavedState savedState = mock(ISavedState.class);
            when(savedState.getSaveNumber()).thenReturn(saveNumber);
            when(savedState.lookup(SAVE_FILE_NAME)).thenReturn(saveFilePath);

            assertTrue(state.isEmpty());

            state.restore(savedState); //Check this actually loaded the file somehow?

            assertFalse(state.isEmpty());

            assertEquals(conf, state.getPreferredConfig(dashElement));
        }
    }

    @Test
    public void testSaveWithDeletedProject() throws Exception {
        int saveNumber = 13;
        IPath saveFilePath = context.getStateLocation().append(SAVE_FILE_NAME + "-" + saveNumber);
        File saveFile = saveFilePath.toFile();

        IProject project = mockProject("foo", true);
        BootDashElement dashElement = mockElement(project);
        when(factory.createOrGet(project)).thenReturn(dashElement);
        when(context.getWorkspace().getRoot().getProject("foo")).thenReturn(project);

        ILaunchConfiguration conf = mock(ILaunchConfiguration.class);
        when(conf.getMemento()).thenReturn("fooMemento");
        when(context.getLaunchManager().getLaunchConfiguration("fooMemento")).thenReturn(conf);
        when(conf.exists()).thenReturn(true);

        {
            BootDashModelStateSaver state = new BootDashModelStateSaver(context, factory);
            assertTrue(state.isEmpty());

            ISaveContext saveContext = mock(ISaveContext.class);
            when(saveContext.getSaveNumber()).thenReturn(saveNumber);

            assertFalse(saveFile.exists());

            state.setPreferredConfig(dashElement, conf);

            when(project.exists()).thenReturn(false); //pretend project deleted prior to save

            state.prepareToSave(saveContext);
            state.saving(saveContext);
            state.doneSaving(saveContext);

            verify(saveContext).map(SAVE_FILE_NAME, saveFilePath);
            verify(saveContext).needSaveNumber();

            assertTrue(saveFile.exists());
        }
        ///////////////////////////////////////////////////////////////
        {
            BootDashModelStateSaver state = new BootDashModelStateSaver(context, factory);
            ISavedState savedState = mock(ISavedState.class);

            when(savedState.getSaveNumber()).thenReturn(saveNumber);
            when(savedState.lookup(SAVE_FILE_NAME)).thenReturn(saveFilePath);

            assertTrue(state.isEmpty());

            state.restore(savedState); //Check this actually loaded the file somehow?

            assertTrue(state.isEmpty());

            assertEquals(null, state.getPreferredConfig(dashElement));
        }
    }

    @Test
    public void testSaveWithDeletedConf() throws Exception {
        int saveNumber = 13;
        IPath saveFilePath = context.getStateLocation().append(SAVE_FILE_NAME + "-" + saveNumber);
        File saveFile = saveFilePath.toFile();

        IProject project = mockProject("foo", true);
        BootDashElement dashElement = mockElement(project);
        when(factory.createOrGet(project)).thenReturn(dashElement);
        when(context.getWorkspace().getRoot().getProject("foo")).thenReturn(project);

        ILaunchConfiguration conf = mock(ILaunchConfiguration.class);
        when(conf.getMemento()).thenReturn("fooMemento");
        when(context.getLaunchManager().getLaunchConfiguration("fooMemento")).thenReturn(conf);
        when(conf.exists()).thenReturn(true);

        {
            BootDashModelStateSaver state = new BootDashModelStateSaver(context, factory);
            assertTrue(state.isEmpty());

            ISaveContext saveContext = mock(ISaveContext.class);
            when(saveContext.getSaveNumber()).thenReturn(saveNumber);

            assertFalse(saveFile.exists());

            state.setPreferredConfig(dashElement, conf);

            when(conf.exists()).thenReturn(false); //pretend conf deleted prior to save

            state.prepareToSave(saveContext);
            state.saving(saveContext);
            state.doneSaving(saveContext);

            verify(saveContext).map(SAVE_FILE_NAME, saveFilePath);
            verify(saveContext).needSaveNumber();

            assertTrue(saveFile.exists());
        }
        ///////////////////////////////////////////////////////////////
        {
            BootDashModelStateSaver state = new BootDashModelStateSaver(context, factory);
            ISavedState savedState = mock(ISavedState.class);
            when(savedState.getSaveNumber()).thenReturn(saveNumber);
            when(savedState.lookup(SAVE_FILE_NAME)).thenReturn(saveFilePath);

            assertTrue(state.isEmpty());

            state.restore(savedState); //Check this actually loaded the file somehow?

            assertTrue(state.isEmpty());

            assertEquals(null, state.getPreferredConfig(dashElement));
        }
    }

    @Test
    public void testRestoreWithDeletedProject() throws Exception {
        int saveNumber = 13;
        IPath saveFilePath = context.getStateLocation().append(SAVE_FILE_NAME + "-" + saveNumber);
        File saveFile = saveFilePath.toFile();

        IProject project = mockProject("foo", true);
        BootDashElement dashElement = mockElement(project);
        when(factory.createOrGet(project)).thenReturn(dashElement);
        when(context.getWorkspace().getRoot().getProject("foo")).thenReturn(project);

        ILaunchConfiguration conf = mock(ILaunchConfiguration.class);
        when(conf.getMemento()).thenReturn("fooMemento");
        when(context.getLaunchManager().getLaunchConfiguration("fooMemento")).thenReturn(conf);
        when(conf.exists()).thenReturn(true);

        {
            BootDashModelStateSaver state = new BootDashModelStateSaver(context, factory);
            assertTrue(state.isEmpty());

            ISaveContext saveContext = mock(ISaveContext.class);
            when(saveContext.getSaveNumber()).thenReturn(saveNumber);

            assertFalse(saveFile.exists());

            state.setPreferredConfig(dashElement, conf);

            state.prepareToSave(saveContext);
            state.saving(saveContext);
            state.doneSaving(saveContext);

            verify(saveContext).map(SAVE_FILE_NAME, saveFilePath);
            verify(saveContext).needSaveNumber();

            assertTrue(saveFile.exists());
        }
        ///////////////////////////////////////////////////////////////
        {
            when(project.exists()).thenReturn(false); //pretend project deleted prior to restore

            BootDashModelStateSaver state = new BootDashModelStateSaver(context, factory);
            ISavedState savedState = mock(ISavedState.class);
            when(savedState.getSaveNumber()).thenReturn(saveNumber);
            when(savedState.lookup(SAVE_FILE_NAME)).thenReturn(saveFilePath);

            assertTrue(state.isEmpty());

            state.restore(savedState); //Check this actually loaded the file somehow?

            assertTrue(state.isEmpty());

            assertEquals(null, state.getPreferredConfig(dashElement));
        }
    }

    @Test
    public void testRestoreWithDeletedConf() throws Exception {
        int saveNumber = 13;
        IPath saveFilePath = context.getStateLocation().append(SAVE_FILE_NAME + "-" + saveNumber);
        File saveFile = saveFilePath.toFile();

        IProject project = mockProject("foo", true);
        BootDashElement dashElement = mockElement(project);
        when(factory.createOrGet(project)).thenReturn(dashElement);
        when(context.getWorkspace().getRoot().getProject("foo")).thenReturn(project);

        ILaunchConfiguration conf = mock(ILaunchConfiguration.class);
        when(conf.getMemento()).thenReturn("fooMemento");
        when(context.getLaunchManager().getLaunchConfiguration("fooMemento")).thenReturn(conf);
        when(conf.exists()).thenReturn(true);

        {
            BootDashModelStateSaver state = new BootDashModelStateSaver(context, factory);
            assertTrue(state.isEmpty());

            ISaveContext saveContext = mock(ISaveContext.class);
            when(saveContext.getSaveNumber()).thenReturn(saveNumber);

            assertFalse(saveFile.exists());

            state.setPreferredConfig(dashElement, conf);

            state.prepareToSave(saveContext);
            state.saving(saveContext);
            state.doneSaving(saveContext);

            verify(saveContext).map(SAVE_FILE_NAME, saveFilePath);
            verify(saveContext).needSaveNumber();

            assertTrue(saveFile.exists());
        }
        ///////////////////////////////////////////////////////////////
        {
            when(conf.exists()).thenReturn(false); //pretend project deleted prior to restore

            BootDashModelStateSaver state = new BootDashModelStateSaver(context, factory);
            ISavedState savedState = mock(ISavedState.class);
            when(savedState.getSaveNumber()).thenReturn(saveNumber);
            when(savedState.lookup(SAVE_FILE_NAME)).thenReturn(saveFilePath);

            assertTrue(state.isEmpty());

            state.restore(savedState); //Check this actually loaded the file somehow?

            assertTrue(state.isEmpty());

            assertEquals(null, state.getPreferredConfig(dashElement));
        }
    }

    @Test
    public void testRestoreNoPriorSave() throws Exception {
        IProject project = mockProject("foo", true);

        BootDashElement dashElement = mockElement(project);
        when(factory.createOrGet(project)).thenReturn(dashElement);
        when(context.getWorkspace().getRoot().getProject("foo")).thenReturn(project);

        ILaunchConfiguration conf = mock(ILaunchConfiguration.class);
        when(conf.getMemento()).thenReturn("fooMemento");
        when(context.getLaunchManager().getLaunchConfiguration("fooMemento")).thenReturn(conf);
        when(conf.exists()).thenReturn(true);

        BootDashModelStateSaver state = new BootDashModelStateSaver(context, factory);
        ISavedState savedState = null;
        assertTrue(state.isEmpty());

        state.restore(savedState);
        assertTrue(state.isEmpty());

        assertEquals(null, state.getPreferredConfig(dashElement));
    }

    @Test
    public void testRestoreWithCorruptedSaveData() throws Exception {
        BootDashModelStateSaver state = new BootDashModelStateSaver(context, factory);
        IPath corruptFilePath = context.getStateLocation().append("test-corrupt");
        File corruptFile = corruptFilePath.toFile();
        FileUtils.write(corruptFile, "JUNK");

        int saveNumber = 13;
        ISavedState savedState = mockSavedState(saveNumber, corruptFile);
        assertTrue(state.isEmpty());

        state.restore(savedState);
        assertTrue(state.isEmpty());

        verify(context).log(exceptionWith("java.io.StreamCorruptedException"));
    }

    @Test
    public void testDoneSaving() throws Exception {
        int previousSaveNumber = 12;
        BootDashModelStateSaver state = new BootDashModelStateSaver(context, factory);
        File previousSaveFile = context.getStateLocation().append(SAVE_FILE_NAME + "-" + previousSaveNumber)
                .toFile();
        FileUtils.write(previousSaveFile, "This data really doesn't matter");

        assertTrue(previousSaveFile.exists());

        ISaveContext saveContext = mock(ISaveContext.class);
        when(saveContext.getPreviousSaveNumber()).thenReturn(previousSaveNumber);

        state.doneSaving(saveContext);

        assertFalse(previousSaveFile.exists());
    }

    ////////////////////////////////////////////////////////////////

    private Exception exceptionWith(final String snippet) {
        Matcher<Exception> matcher = new BaseMatcher<Exception>() {

            @Override
            public void describeTo(Description description) {
                description.appendText("Exception with text fragment '" + snippet + "'");
            }

            @Override
            public boolean matches(Object item) {
                if (item instanceof Throwable) {
                    return stacktrace((Throwable) item).contains(snippet);
                }
                return false;
            }

            private String stacktrace(Throwable item) {
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                PrintStream pout = new PrintStream(out);
                try {
                    item.printStackTrace(pout);
                } finally {
                    pout.close();
                }
                return new String(out.toByteArray());
            }

            @Override
            public void describeMismatch(Object item, Description mismatchDescription) {
                if (item instanceof Throwable) {
                    mismatchDescription.appendText("Expecting snippet: " + snippet);
                    mismatchDescription.appendText("\n" + stacktrace((Throwable) item));
                } else {
                    mismatchDescription.appendText("Expecting a throwable but got " + item);
                }
            }
        };
        return argThat(matcher);
    }

    private BootDashElement mockElement(IProject project) {
        BootDashElement el = mock(BootDashElement.class);
        when(el.getProject()).thenReturn(project);
        return el;
    }

    @After
    public void teardown() throws Exception {
        context.teardownn();
        factory.dispose();
    }

}