/*******************************************************************************
* Copyright (c) 2010 SAP AG.
* 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:
* Emil Simeonov - initial API and implementation.
* Dimitar Donchev - initial API and implementation.
* Dimitar Tenev - initial API and implementation.
* Nevena Manova - initial API and implementation.
* Georgi Konstantinov - initial API and implementation.
*******************************************************************************/
package org.eclipse.wst.sse.sieditor.test.model.commands.common;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.emf.transaction.Transaction;
import org.eclipse.wst.xml.core.internal.document.XMLModelNotifier;
import org.junit.Test;
import org.eclipse.wst.sse.sieditor.command.common.AbstractNotificationOperation;
import org.eclipse.wst.sse.sieditor.command.common.CompositeTextOperationWrapper;
import org.eclipse.wst.sse.sieditor.core.common.IEnvironment;
import org.eclipse.wst.sse.sieditor.core.common.IModelReconcileRegistry;
import org.eclipse.wst.sse.sieditor.model.api.IModelRoot;
import org.eclipse.wst.sse.sieditor.model.api.IWsdlModelRoot;
import org.eclipse.wst.sse.sieditor.model.reconcile.IModelReconciler;
import org.eclipse.wst.sse.sieditor.model.wsdl.api.IDescription;
public class CompositeTextOperationWrapperTest {
private CompositeTextOperationWrapperExpose compositeOperationWrapper;
private IModelReconciler modelReconciler;
@Test
public void reconcileOnUndo() throws Exception {
final IModelRoot modelRoot = setUpModelRoot();
final AbstractNotificationOperation operationMock = createWrapperOperation(modelRoot);
// calledInPostUndoRedo[0] - basicPatchEmfModel
// calledInPostUndoRedo[1] - fullPatchEmfModel
// calledInPostUndoRedo[2] - doReconcile
final boolean calledInPostUndoRedo[] = { false, false, false };
// calledPreAndPostOfUndoRedo[0] - preUndoRedoOfCompositeCommand
// calledPreAndPostOfUndoRedo[1] - postUndoRedoOfCompositeCommand
final boolean calledPreAndPostOfUndoRedoCompositeCommand[] = { false, false };
compositeOperationWrapper = new CompositeTextOperationWrapperExpose(operationMock) {
@Override
public void preUndoRedoOfCompositeCommand() {
assertFalse("postUndoRedoOfCompositeCommand was called before preUndoRedoOfCompositeCommand",
calledPreAndPostOfUndoRedoCompositeCommand[1]);
calledPreAndPostOfUndoRedoCompositeCommand[0] = true;
}
@Override
protected void postUndoRedoOfCompositeCommand() {
assertTrue("postUndoRedoOfCompositeCommand was called after preUndoRedoOfCompositeCommand",
calledPreAndPostOfUndoRedoCompositeCommand[0]);
calledPreAndPostOfUndoRedoCompositeCommand[1] = true;
super.postUndoRedoOfCompositeCommand();
}
@Override
protected void fullPatchEmfModel(final IModelRoot modelRoot) {
assertTrue("preUndoRedoOfCompositeCommand was not called before fullPatchEmfModel",
calledPreAndPostOfUndoRedoCompositeCommand[0]);
calledInPostUndoRedo[1] = true;
assertFalse("doReconcile was not called before fullPatchEmfModel", calledInPostUndoRedo[2]);
assertSame("operation model root should be passed for patching", modelRoot, operationMock.getModelRoot());
}
@Override
public void doReconcile() {
assertTrue("preUndoRedoOfCompositeCommand was not called before doReconcile",
calledPreAndPostOfUndoRedoCompositeCommand[0]);
assertTrue("fullPatchEmfModel was not called before doReconcile", calledInPostUndoRedo[1]);
calledInPostUndoRedo[2] = true;
}
};
assertEquals(Boolean.TRUE, compositeOperationWrapper.getOptions().get(Transaction.OPTION_NO_VALIDATION));
compositeOperationWrapper.doUndo(null, null);
assertTrue("preUndoRedoOfCompositeCommand was not called", calledPreAndPostOfUndoRedoCompositeCommand[0]);
assertTrue("fullPatchEmfModel was not called", calledInPostUndoRedo[1]);
assertTrue("postUndoRedoOfCompositeCommand was not called", calledPreAndPostOfUndoRedoCompositeCommand[1]);
}
@Test
public void reconcileOnRedo() throws Exception {
final IModelRoot modelRoot = setUpModelRoot();
final AbstractNotificationOperation operationMock = createWrapperOperation(modelRoot);
// calledInPostUndoRedo[0] - basicPatchEmfModel
// calledInPostUndoRedo[1] - fullPatchEmfModel
// calledInPostUndoRedo[2] - doReconcile
final boolean calledInPostUndoRedo[] = { false, false, false };
// calledPreAndPostOfUndoRedo[0] - preUndoRedoOfCompositeCommand
// calledPreAndPostOfUndoRedo[1] - postUndoRedoOfCompositeCommand
final boolean calledPreAndPostOfUndoRedoCompositeCommand[] = { false, false };
compositeOperationWrapper = new CompositeTextOperationWrapperExpose(operationMock) {
@Override
public void preUndoRedoOfCompositeCommand() {
assertFalse("postUndoRedoOfCompositeCommand was called before preUndoRedoOfCompositeCommand",
calledPreAndPostOfUndoRedoCompositeCommand[1]);
calledPreAndPostOfUndoRedoCompositeCommand[0] = true;
}
@Override
protected void postUndoRedoOfCompositeCommand() {
assertTrue("postUndoRedoOfCompositeCommand was called after preUndoRedoOfCompositeCommand",
calledPreAndPostOfUndoRedoCompositeCommand[0]);
calledPreAndPostOfUndoRedoCompositeCommand[1] = true;
super.postUndoRedoOfCompositeCommand();
}
@Override
protected void fullPatchEmfModel(final IModelRoot modelRoot) {
assertTrue("preUndoRedoOfCompositeCommand was not called before fullPatchEmfModel",
calledPreAndPostOfUndoRedoCompositeCommand[0]);
calledInPostUndoRedo[1] = true;
assertFalse("doReconcile was not called before fullPatchEmfModel", calledInPostUndoRedo[2]);
assertSame("operation model root should be passed for patching", modelRoot, operationMock.getModelRoot());
}
@Override
public void doReconcile() {
assertTrue("preUndoRedoOfCompositeCommand was not called before doReconcile",
calledPreAndPostOfUndoRedoCompositeCommand[0]);
assertTrue("fullPatchEmfModel was not called before doReconcile", calledInPostUndoRedo[1]);
calledInPostUndoRedo[2] = true;
}
};
assertEquals(Boolean.TRUE, compositeOperationWrapper.getOptions().get(Transaction.OPTION_NO_VALIDATION));
compositeOperationWrapper.doRedo(null, null);
assertTrue("preUndoRedoOfCompositeCommand was not called", calledPreAndPostOfUndoRedoCompositeCommand[0]);
assertTrue("fullPatchEmfModel was not called", calledInPostUndoRedo[1]);
assertTrue("postUndoRedoOfCompositeCommand was not called", calledPreAndPostOfUndoRedoCompositeCommand[1]);
}
@Test
public void reconcileOnExecute() throws Exception {
final IModelRoot modelRoot = createMock(IModelRoot.class);
final IEnvironment environment = createMock(IEnvironment.class);
expect(modelRoot.getEnv()).andReturn(environment).anyTimes();
expect(environment.getEditingDomain()).andReturn(null).anyTimes();
environment.finalizeWrapperCommandExecution();
expect(environment.getCompositeTextOperationWrapper()).andReturn(null);
expect(modelRoot.getModelObject()).andReturn(null).anyTimes();
replay(modelRoot, environment);
final AbstractNotificationOperation operationMock = createWrapperOperation(modelRoot);
final boolean called[] = { false, false, false };
compositeOperationWrapper = new CompositeTextOperationWrapperExpose(operationMock) {
@Override
public void preUndoRedoOfCompositeCommand() {
assertFalse("basicPatchModel was called before preUndoRedoOfCompositeCommand", called[1]);
assertFalse("postUndoRedoOfCompositeCommand was called before preUndoRedoOfCompositeCommand", called[2]);
called[0] = true;
}
@Override
protected void basicPatchEmfModel(final IModelRoot modelRoot) {
assertTrue("preUndoRedoOfCompositeCommand was called before basicPatchModel", called[0]);
assertFalse("postUndoRedoOfCompositeCommand was called before basicPatchModel", called[2]);
called[1] = true;
}
@Override
public void doReconcile() {
assertTrue("postUndoRedoOfCompositeCommand was called before preUndoRedoOfCompositeCommand", called[0]);
assertTrue("postUndoRedoOfCompositeCommand was called before basicPatchModel", called[1]);
called[2] = true;
}
};
compositeOperationWrapper.doExecute(null, null);
assertEquals(Boolean.TRUE, compositeOperationWrapper.getOptions().get(Transaction.OPTION_NO_VALIDATION));
assertTrue("preUndoRedoOfCompositeCommand was not called", called[0]);
assertTrue("basicPatchModel was not called", called[1]);
assertTrue("postUndoRedoOfCompositeCommand was not called", called[2]);
verify(environment);
}
@Test
public void postUndoRedoOfCompositeCommand() {
final IModelReconcileRegistry modelReconcileRegistry = createNiceMock(IModelReconcileRegistry.class);
final IModelRoot modelRoot = createNiceMock(IModelRoot.class);
final XMLModelNotifier modelNotifier = createMock(XMLModelNotifier.class);
final IEnvironment environment = createMock(IEnvironment.class);
expect(modelRoot.getEnv()).andReturn(environment).anyTimes();
expect(environment.getEditingDomain()).andReturn(null).anyTimes();
expect(modelRoot.getModelObject()).andReturn(null).anyTimes();
modelReconciler = createMock(IModelReconciler.class);
expect(modelReconciler.needsToReconcileModel(modelReconcileRegistry)).andReturn(true);
modelReconciler.reconcileModel(modelRoot, modelReconcileRegistry);
modelReconciler.modelReconciled(modelReconcileRegistry,modelNotifier);
modelNotifier.endChanging();
replay(modelReconciler, modelNotifier, modelRoot, environment);
final AbstractNotificationOperation operationMock = createWrapperOperation(modelRoot);
compositeOperationWrapper = new CompositeTextOperationWrapperExpose(operationMock) {
@Override
protected IModelReconciler modelReconciler() {
return modelReconciler;
}
@Override
protected IModelReconcileRegistry getModelReconcileRegistry() {
return modelReconcileRegistry;
}
@Override
protected IModelRoot getDocumentModelRoot() {
return modelRoot;
}
@Override
protected XMLModelNotifier modelNotifier() {
return modelNotifier;
}
@Override
protected void basicPatchEmfModel(final IModelRoot modelRoot) {
// TODO Auto-generated method stub
}
};
compositeOperationWrapper.doReconcile();
assertEquals(Boolean.TRUE, compositeOperationWrapper.getOptions().get(Transaction.OPTION_NO_VALIDATION));
verify(modelReconciler, modelNotifier);
}
// =========================================================
// helpers
// =========================================================
private IModelRoot setUpModelRoot() {
final IWsdlModelRoot modelRoot = createMock(IWsdlModelRoot.class);
final IEnvironment environment = createMock(IEnvironment.class);
final IDescription description = createMock(IDescription.class);
final IModelRoot documentModelRoot = createMock(IModelRoot.class);
expect(modelRoot.getEnv()).andReturn(environment).anyTimes();
expect(modelRoot.getRoot()).andReturn(documentModelRoot);
expect(environment.getEditingDomain()).andReturn(null).anyTimes();
expect(modelRoot.getModelObject()).andReturn(description).anyTimes();
replay(modelRoot, environment);
return modelRoot;
}
private AbstractNotificationOperation createWrapperOperation(final IModelRoot modelRoot) {
final AbstractNotificationOperation operationMock = new AbstractNotificationOperation(modelRoot, modelRoot
.getModelObject(), "label") {
@Override
public IStatus run(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
return null;
}
@Override
public IModelRoot getModelRoot() {
return modelRoot;
}
@Override
protected IStatus doExecute(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
return null;
}
};
return operationMock;
}
// =========================================================
// expose
// =========================================================
private class CompositeTextOperationWrapperExpose extends CompositeTextOperationWrapper {
public CompositeTextOperationWrapperExpose(final AbstractNotificationOperation operation) {
super(operation);
}
@Override
public IStatus doExecute(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
return super.doExecute(monitor, info);
}
@Override
protected IStatus doUndo(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
return super.doUndo(monitor, info);
}
@Override
protected IStatus doRedo(final IProgressMonitor monitor, final IAdaptable info) throws ExecutionException {
return super.doRedo(monitor, info);
}
@Override
public void doReconcile() {
super.doReconcile();
}
@Override
public void preUndoRedoOfCompositeCommand() {
super.preUndoRedoOfCompositeCommand();
}
}
}