blob: 47edf7f993c4f7d742646017769d4e63cd2b3b9b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014, 2017 1C-Soft LLC and others.
* 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:
* Vladimir Piskarev (1C) - initial API and implementation
*******************************************************************************/
package org.eclipse.handly.internal.examples.basic.ui.model;
import static org.eclipse.handly.context.Contexts.EMPTY_CONTEXT;
import static org.eclipse.handly.context.Contexts.of;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.handly.buffer.Buffer;
import org.eclipse.handly.buffer.BufferChange;
import org.eclipse.handly.buffer.IBuffer;
import org.eclipse.handly.buffer.SaveMode;
import org.eclipse.handly.context.IContext;
import org.eclipse.handly.examples.basic.ui.model.FooModelCore;
import org.eclipse.handly.examples.basic.ui.model.IFooDef;
import org.eclipse.handly.examples.basic.ui.model.IFooProject;
import org.eclipse.handly.examples.basic.ui.model.IFooVar;
import org.eclipse.handly.junit.WorkspaceTestCase;
import org.eclipse.handly.model.ISourceElementInfo;
import org.eclipse.handly.model.impl.IElementImplExtension;
import org.eclipse.handly.model.impl.ISourceFileImplSupport;
import org.eclipse.handly.model.impl.WorkingCopyInfo;
import org.eclipse.handly.util.TextRange;
import org.eclipse.text.edits.DeleteEdit;
import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.ReplaceEdit;
/**
* <code>FooFile</code> working copy tests.
*/
public class FooWorkingCopyTest
extends WorkspaceTestCase
{
private FooFile workingCopy;
@Override
protected void setUp() throws Exception
{
super.setUp();
IFooProject fooProject = FooModelCore.create(setUpProject("Test002"));
workingCopy = (FooFile)fooProject.getFooFile("test.foo");
}
public void test1() throws Exception
{
doWithWorkingCopy(EMPTY_CONTEXT, new IWorkspaceRunnable()
{
@Override
public void run(IProgressMonitor monitor) throws CoreException
{
IFooDef[] defs = workingCopy.getDefs();
assertEquals(3, defs.length);
IFooDef def = workingCopy.getDef("f", 0);
assertEquals(def, defs[0]);
TextRange r =
defs[0].getSourceElementInfo().getIdentifyingRange();
BufferChange change = new BufferChange(new ReplaceEdit(
r.getOffset(), r.getLength(), "g"));
change.setSaveMode(SaveMode.LEAVE_UNSAVED);
workingCopy.hWorkingCopyInfo().getBuffer().applyChange(change,
null);
defs = workingCopy.getDefs();
assertEquals(3, defs.length);
assertEquals(def, defs[0]);
workingCopy.reconcile(null);
assertFalse(def.exists());
defs = workingCopy.getDefs();
assertEquals(3, defs.length);
assertEquals(workingCopy.getDef("g", 0), defs[0]);
}
});
}
public void test2() throws Exception
{
doWithWorkingCopy(EMPTY_CONTEXT, new IWorkspaceRunnable()
{
@Override
public void run(IProgressMonitor monitor) throws CoreException
{
IFooVar[] vars = workingCopy.getVars();
assertEquals(2, vars.length);
IFooVar var1 = workingCopy.getVar("x");
assertEquals(var1, vars[0]);
IFooVar var2 = workingCopy.getVar("y");
assertEquals(var2, vars[1]);
ISourceElementInfo info = var2.getSourceElementInfo();
TextRange r = info.getFullRange();
String var2Text = info.getSnapshot().getContents().substring(
r.getOffset(), r.getEndOffset());
BufferChange change = new BufferChange(new DeleteEdit(
r.getOffset(), r.getLength()));
change.setSaveMode(SaveMode.LEAVE_UNSAVED);
workingCopy.hWorkingCopyInfo().getBuffer().applyChange(change,
null);
vars = workingCopy.getVars();
assertEquals(2, vars.length);
assertEquals(var2, vars[1]);
workingCopy.reconcile(null);
assertFalse(var2.exists());
vars = workingCopy.getVars();
assertEquals(1, vars.length);
assertEquals(var1, vars[0]);
info = var1.getSourceElementInfo();
r = info.getFullRange();
change = new BufferChange(new InsertEdit(r.getOffset(),
var2Text));
change.setSaveMode(SaveMode.LEAVE_UNSAVED);
workingCopy.hWorkingCopyInfo().getBuffer().applyChange(change,
null);
vars = workingCopy.getVars();
assertEquals(1, vars.length);
workingCopy.reconcile(null);
vars = workingCopy.getVars();
assertEquals(2, vars.length);
assertEquals(var2, vars[0]);
assertEquals(var1, vars[1]);
}
});
}
public void testBug480397_1() throws Exception
{
// working copy for a non-existing source file
workingCopy.getParent().getResource().delete(true, null);
try (
IBuffer buffer = new Buffer(
"var x; var y; def f() {} def f(x) {} def f(x, y) {}"))
{
doWithWorkingCopy(of(ISourceFileImplSupport.WORKING_COPY_BUFFER,
buffer), new IWorkspaceRunnable()
{
@Override
public void run(IProgressMonitor monitor)
throws CoreException
{
assertFalse(workingCopy.getParent().exists());
assertTrue(workingCopy.exists());
IFooVar[] vars = workingCopy.getVars();
assertEquals(2, vars.length);
IFooDef[] defs = workingCopy.getDefs();
assertEquals(3, defs.length);
}
});
}
}
public void testBug479623() throws Exception
{
// concurrent creation/acquisition of working copy
final boolean[] stop = new boolean[1];
final boolean[] failure = new boolean[1];
Thread thread = new Thread(new Runnable()
{
@Override
public void run()
{
while (!stop[0])
{
WorkingCopyInfo info =
workingCopy.hAcquireExistingWorkingCopy(null);
if (info != null)
{
try
{
if (!info.isInitialized())
{
failure[0] = true;
return;
}
}
finally
{
workingCopy.hReleaseWorkingCopy();
}
}
}
}
});
thread.start();
try
{
doWithWorkingCopy(EMPTY_CONTEXT, new IWorkspaceRunnable()
{
@Override
public void run(IProgressMonitor monitor) throws CoreException
{
}
});
assertFalse(failure[0]);
assertTrue(thread.isAlive());
}
finally
{
stop[0] = true;
thread.join();
}
}
public void testBug480397_2() throws Exception
{
// working copy cannot be closed
doWithWorkingCopy(EMPTY_CONTEXT, new IWorkspaceRunnable()
{
@Override
public void run(IProgressMonitor monitor) throws CoreException
{
workingCopy.hClose();
assertNotNull("working copy must remain in the cache",
workingCopy.hPeekAtBody());
workingCopy.getParent().hClose();
assertNotNull("working copy must remain in the cache",
workingCopy.hPeekAtBody());
}
});
}
public void testBug480397_3() throws Exception
{
// attempting to close a non-openable element
IWorkspaceRunnable testRunnable = new IWorkspaceRunnable()
{
@Override
public void run(IProgressMonitor monitor) throws CoreException
{
IFooDef def = workingCopy.getDef("f", 0);
assertTrue(def.exists());
((IElementImplExtension)def).hClose();
assertNotNull("non-openable elements cannot be closed",
((IElementImplExtension)def).hPeekAtBody());
}
};
// non-openable elements cannot be closed, in working copy or not
doWithWorkingCopy(EMPTY_CONTEXT, testRunnable);
testRunnable.run(null);
}
private void doWithWorkingCopy(IContext context,
IWorkspaceRunnable runnable) throws CoreException
{
workingCopy.hBecomeWorkingCopy(context, null);
try
{
runnable.run(null);
}
finally
{
workingCopy.hReleaseWorkingCopy();
}
}
}