Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ilya.Kazakevich
2015-05-09 01:32:33 +03:00
46 changed files with 1248 additions and 408 deletions
@@ -1769,7 +1769,12 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb
ApplicationManager.getApplication().assertIsDispatchThread(); //TODO: remove this requirement
((XDebugSessionImpl)getXdebugProcess().getSession()).reset();
myState.set(STATE_INITIAL);
myRequestManager.processDetached(this, false);
getManagerThread().schedule(new DebuggerCommandImpl() {
@Override
protected void action() throws Exception {
myRequestManager.processDetached(DebugProcessImpl.this, false);
}
});
myConnection = environment.getRemoteConnection();
getManagerThread().restartIfNeeded();
createVirtualMachine(environment.getSessionName(), environment.isPollConnection());
@@ -16,6 +16,7 @@
package com.intellij.execution;
import com.intellij.ExtensionPoints;
import com.intellij.debugger.impl.GenericDebuggerRunnerSettings;
import com.intellij.execution.configurations.*;
import com.intellij.execution.process.OSProcessHandler;
import com.intellij.execution.process.ProcessAdapter;
@@ -216,11 +217,16 @@ public abstract class JavaTestFrameworkRunnableState<T extends ModuleBasedConfig
return myForkSocket;
}
private boolean isExecutorDisabledInForkedMode() {
final RunnerSettings settings = getRunnerSettings();
return settings != null && !(settings instanceof GenericDebuggerRunnerSettings);
}
protected void appendForkInfo(Executor executor) throws ExecutionException {
final String forkMode = getForkMode();
if (Comparing.strEqual(forkMode, "none")) {
if (forkPerModule()) {
if (getRunnerSettings() != null) {
if (isExecutorDisabledInForkedMode()) {
final String actionName = UIUtil.removeMnemonic(executor.getStartActionText());
throw new CantRunException("'" + actionName + "' is disabled when per-module working directory is configured.<br/>" +
"Please specify single working directory, or change test scope to single module.");
@@ -228,7 +234,7 @@ public abstract class JavaTestFrameworkRunnableState<T extends ModuleBasedConfig
} else {
return;
}
} else if (getRunnerSettings() != null) {
} else if (isExecutorDisabledInForkedMode()) {
final String actionName = executor.getActionName();
throw new CantRunException(actionName + " is disabled in fork mode.<br/>Please change fork mode to &lt;none&gt; to " + actionName.toLowerCase(
Locale.ENGLISH) + ".");
@@ -22,10 +22,11 @@ import com.intellij.execution.junit2.info.MethodLocation;
import com.intellij.execution.testframework.sm.runner.SMTestLocator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.JavaPsiFacade;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.ClassUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
@@ -50,32 +51,27 @@ public class JavaTestLocator implements SMTestLocator {
path = path.substring(0, idx);
}
JavaPsiFacade javaPsiFacade = JavaPsiFacade.getInstance(project);
if (SUITE_PROTOCOL.equals(protocol)) {
path = StringUtil.trimEnd(path, ".");
PsiClass[] classes = javaPsiFacade.findClasses(path, scope);
if (classes.length > 0) {
PsiClass aClass = ClassUtil.findPsiClass(PsiManager.getInstance(project), path, null, true, scope);
if (aClass != null) {
results = ContainerUtil.newSmartList();
for (PsiClass aClass : classes) {
results.add(paramName != null ? PsiMemberParameterizedLocation.getParameterizedLocation(aClass, paramName)
: new PsiLocation<PsiClass>(project, aClass));
}
results.add(paramName != null ? PsiMemberParameterizedLocation.getParameterizedLocation(aClass, paramName)
: new PsiLocation<PsiClass>(project, aClass));
}
}
else if (TEST_PROTOCOL.equals(protocol)) {
String className = StringUtil.getPackageName(path);
if (!StringUtil.isEmpty(className)) {
String methodName = StringUtil.getShortName(path);
PsiClass[] classes = javaPsiFacade.findClasses(className, scope);
if (classes.length > 0) {
PsiClass aClass = ClassUtil.findPsiClass(PsiManager.getInstance(project), className, null, true, scope);
if (aClass != null) {
results = ContainerUtil.newSmartList();
for (PsiClass aClass : classes) {
PsiMethod[] methods = aClass.findMethodsByName(methodName, true);
if (methods.length > 0) {
for (PsiMethod method : methods) {
results.add(paramName != null ? new PsiMemberParameterizedLocation(project, method, aClass, paramName)
: MethodLocation.elementInClass(method, aClass));
}
PsiMethod[] methods = aClass.findMethodsByName(methodName, true);
if (methods.length > 0) {
for (PsiMethod method : methods) {
results.add(paramName != null ? new PsiMemberParameterizedLocation(project, method, aClass, paramName)
: MethodLocation.elementInClass(method, aClass));
}
}
}
@@ -109,7 +109,8 @@ public class StreamApiMigrationInspection extends BaseJavaBatchLocalInspectionTo
}
if (ExceptionUtil.getThrownCheckedExceptions(new PsiElement[] {body}).isEmpty()) {
if (isCollectCall(body, statement.getIterationParameter())) {
if (!(iteratedValueType instanceof PsiClassType && ((PsiClassType)iteratedValueType).isRaw()) &&
isCollectCall(body, statement.getIterationParameter())) {
holder.registerProblem(iteratedValue, "Can be replaced with collect call",
ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new ReplaceWithCollectCallFix());
} else if (!isTrivial(body, statement.getIterationParameter())) {
@@ -0,0 +1,22 @@
// "Replace with forEach" "false"
import java.util.*;
import java.util.stream.Collectors
class A {
public static <T> List<T> toTypedList1(Collection collection, Class<T> aClass) {
if (collection.size() == 0) {
return Collections.emptyList();
}
List<T> result = new ArrayList<>(collection.size());
for (Object obj : coll<caret>ection) {
result.add(aClass.cast(obj));
}
return result;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -286,7 +286,6 @@ public abstract class HTMLComposerImpl extends HTMLComposer {
@Override
public void appendListItem(StringBuffer buf, RefElement refElement) {
startListItem(buf);
buf.append(CLOSE_TAG);
appendElementReference(buf, refElement, true);
appendAdditionalListItemInfo(buf, refElement);
doneListItem(buf);
@@ -58,7 +58,7 @@ public class BootstrapClassLoaderUtil extends ClassUtilCore {
UrlClassLoader.Builder builder = UrlClassLoader.build()
.urls(filterClassPath(new ArrayList<URL>(classpath)))
.allowLock(false)
.allowLock()
.usePersistentClasspathIndexForLocalClassDirectories()
.useCache();
if (Boolean.valueOf(System.getProperty(PROPERTY_ALLOW_BOOTSTRAP_RESOURCES, "true"))) {
@@ -21,9 +21,9 @@ import com.intellij.diff.chains.DiffRequestProducer;
import com.intellij.diff.chains.DiffRequestProducerException;
import com.intellij.diff.requests.*;
import com.intellij.diff.tools.util.SoftHardCacheMap;
import com.intellij.diff.util.DiffTaskQueue;
import com.intellij.diff.util.DiffUserDataKeys;
import com.intellij.diff.util.DiffUserDataKeysEx.ScrollToPolicy;
import com.intellij.diff.util.WaitingBackgroundableTaskExecutor;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
@@ -33,9 +33,11 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.util.ProgressWindow;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.util.Consumer;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Convertor;
import org.jetbrains.annotations.CalledInAwt;
import org.jetbrains.annotations.CalledInBackground;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -51,7 +53,7 @@ public abstract class CacheDiffRequestChainProcessor extends DiffRequestProcesso
@NotNull private final SoftHardCacheMap<DiffRequestProducer, DiffRequest> myRequestCache =
new SoftHardCacheMap<DiffRequestProducer, DiffRequest>(5, 5);
@NotNull private final WaitingBackgroundableTaskExecutor myTaskExecutor = new WaitingBackgroundableTaskExecutor();
@NotNull private final DiffTaskQueue myQueue = new DiffTaskQueue();
public CacheDiffRequestChainProcessor(@Nullable Project project, @NotNull DiffRequestChain requestChain) {
super(project, requestChain);
@@ -62,6 +64,7 @@ public abstract class CacheDiffRequestChainProcessor extends DiffRequestProcesso
// Update
//
@CalledInAwt
public void updateRequest(final boolean force, @Nullable final ScrollToPolicy scrollToChangePolicy) {
List<? extends DiffRequestProducer> requests = myRequestChain.getRequests();
int index = myRequestChain.getIndex();
@@ -78,12 +81,13 @@ public abstract class CacheDiffRequestChainProcessor extends DiffRequestProcesso
return;
}
myTaskExecutor.execute(
new Convertor<ProgressIndicator, Runnable>() {
myQueue.executeAndTryWait(
new Function<ProgressIndicator, Runnable>() {
@Override
public Runnable convert(ProgressIndicator indicator) {
public Runnable fun(ProgressIndicator indicator) {
final DiffRequest request = loadRequest(producer, indicator);
return new Runnable() {
@CalledInAwt
@Override
public void run() {
myRequestCache.put(producer, request);
@@ -131,9 +135,10 @@ public abstract class CacheDiffRequestChainProcessor extends DiffRequestProcesso
//
@Override
@CalledInAwt
protected void onDispose() {
super.onDispose();
myTaskExecutor.abort();
Disposer.dispose(myQueue);
myRequestCache.clear();
}
@@ -299,6 +299,7 @@ public abstract class DiffRequestProcessor implements Disposable {
protected void onAfterNavigate() {
}
@CalledInAwt
protected void onDispose() {
}
@@ -20,7 +20,7 @@ import com.intellij.diff.FrameDiffTool;
import com.intellij.diff.FrameDiffTool.DiffViewer;
import com.intellij.diff.requests.ContentDiffRequest;
import com.intellij.diff.tools.util.DiffDataKeys;
import com.intellij.diff.util.WaitingBackgroundableTaskExecutor;
import com.intellij.diff.util.DiffTaskQueue;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataProvider;
@@ -31,8 +31,7 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.util.ProgressWindow;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.util.Alarm;
import com.intellij.util.containers.Convertor;
import com.intellij.util.Function;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.*;
@@ -47,9 +46,7 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
@NotNull protected final DiffContext myContext;
@NotNull protected final ContentDiffRequest myRequest;
@NotNull private final WaitingBackgroundableTaskExecutor myTaskExecutor = new WaitingBackgroundableTaskExecutor();
@NotNull private final Alarm myAlarm = new Alarm();
@NotNull private final DiffTaskQueue myTaskExecutor = new DiffTaskQueue();
@NotNull private final AtomicBoolean myDisposed = new AtomicBoolean(false);
public DiffViewerBase(@NotNull DiffContext context, @NotNull ContentDiffRequest request) {
@@ -75,15 +72,11 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
public final void dispose() {
if (!myDisposed.compareAndSet(false, true)) return;
Disposer.dispose(myAlarm);
abortRediff();
onDispose();
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
abortRediff();
onDisposeAwt();
}
});
@@ -92,14 +85,10 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
@CalledInAwt
public final void scheduleRediff() {
if (myDisposed.get()) return;
myTaskExecutor.abort();
final int modificationStamp = myTaskExecutor.getModificationStamp();
myAlarm.cancelAllRequests();
myAlarm.addRequest(new Runnable() {
myTaskExecutor.abortAndSchedule(new Runnable() {
@Override
public void run() {
if (modificationStamp != myTaskExecutor.getModificationStamp()) return;
rediff();
}
}, ProgressWindow.DEFAULT_PROGRESS_DIALOG_POSTPONE_TIME_MILLIS);
@@ -127,10 +116,10 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
int waitMillis = trySync || tryRediffSynchronously() ? ProgressWindow.DEFAULT_PROGRESS_DIALOG_POSTPONE_TIME_MILLIS : 0;
myTaskExecutor.execute(
new Convertor<ProgressIndicator, Runnable>() {
myTaskExecutor.executeAndTryWait(
new Function<ProgressIndicator, Runnable>() {
@Override
public Runnable convert(ProgressIndicator indicator) {
public Runnable fun(ProgressIndicator indicator) {
return performRediff(indicator);
}
},
@@ -199,6 +188,7 @@ public abstract class DiffViewerBase implements DiffViewer, DataProvider {
protected abstract Runnable performRediff(@NotNull ProgressIndicator indicator);
protected void onDispose() {
Disposer.dispose(myTaskExecutor);
}
@CalledInAwt
@@ -21,7 +21,7 @@ import com.intellij.openapi.progress.EmptyProgressIndicator;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.util.containers.Convertor;
import com.intellij.util.Function;
import org.jetbrains.annotations.CalledInAwt;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -34,59 +34,38 @@ import java.util.concurrent.atomic.AtomicReference;
* Executor to perform <possibly> long operations on pooled thread
* Is is used to reduce blinking, in case of fast end of background task.
*/
public class WaitingBackgroundableTaskExecutor {
public class BackgroundTaskUtil {
private static final Runnable TOO_SLOW_OPERATION = new EmptyRunnable();
private int myModificationStamp = 0;
@Nullable private ProgressIndicator myProgressIndicator;
@CalledInAwt
public int getModificationStamp() {
return myModificationStamp;
@NotNull
public static ProgressIndicator executeAndTryWait(@NotNull final Function<ProgressIndicator, Runnable> backgroundTask,
@Nullable final Runnable onSlowAction,
final int waitMillis) {
return executeAndTryWait(backgroundTask, onSlowAction, waitMillis, false);
}
@CalledInAwt
public void abort() {
if (myProgressIndicator != null) {
myProgressIndicator.cancel();
myProgressIndicator = null;
myModificationStamp++;
}
}
@CalledInAwt
public void execute(@NotNull final Convertor<ProgressIndicator, Runnable> backgroundTask,
@Nullable final Runnable onSlowAction,
final int waitMillis) {
execute(backgroundTask, onSlowAction, waitMillis, false);
}
@CalledInAwt
public void execute(@NotNull final Convertor<ProgressIndicator, Runnable> backgroundTask,
@Nullable final Runnable onSlowAction,
final int waitMillis,
final boolean forceEDT) {
abort();
myModificationStamp++;
final int modificationStamp = myModificationStamp;
@NotNull
public static ProgressIndicator executeAndTryWait(@NotNull final Function<ProgressIndicator, Runnable> backgroundTask,
@Nullable final Runnable onSlowAction,
final int waitMillis,
final boolean forceEDT) {
final ModalityState modality = ModalityState.current();
myProgressIndicator = new EmptyProgressIndicator() {
final ProgressIndicator indicator = new EmptyProgressIndicator() {
@NotNull
@Override
public ModalityState getModalityState() {
return modality;
}
};
final ProgressIndicator indicator = myProgressIndicator;
final Semaphore semaphore = new Semaphore(0);
final AtomicReference<Runnable> resultRef = new AtomicReference<Runnable>();
if (forceEDT) {
Runnable result = backgroundTask.convert(indicator);
finish(result, modificationStamp, indicator);
Runnable callback = backgroundTask.fun(indicator);
finish(callback, indicator);
}
else {
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@@ -95,18 +74,18 @@ public class WaitingBackgroundableTaskExecutor {
ProgressManager.getInstance().executeProcessUnderProgress(new Runnable() {
@Override
public void run() {
final Runnable result = backgroundTask.convert(indicator);
final Runnable callback = backgroundTask.fun(indicator);
if (indicator.isCanceled()) {
semaphore.release();
return;
}
if (!resultRef.compareAndSet(null, result)) {
if (!resultRef.compareAndSet(null, callback)) {
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
finish(result, modificationStamp, indicator);
finish(callback, indicator);
}
}, modality);
}
@@ -123,19 +102,20 @@ public class WaitingBackgroundableTaskExecutor {
}
if (!resultRef.compareAndSet(null, TOO_SLOW_OPERATION)) {
// update presentation in the same thread to reduce blinking, caused by 'invokeLater' and fast background operation
finish(resultRef.get(), modificationStamp, indicator);
finish(resultRef.get(), indicator);
}
else {
if (onSlowAction != null) onSlowAction.run();
}
}
return indicator;
}
@CalledInAwt
private void finish(@NotNull Runnable result, int modificationStamp, @NotNull ProgressIndicator indicator) {
private static void finish(@NotNull Runnable result, @NotNull ProgressIndicator indicator) {
if (indicator.isCanceled()) return;
if (myModificationStamp != modificationStamp) return;
result.run();
indicator.stop();
}
}
@@ -0,0 +1,116 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* 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.intellij.diff.util;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.util.Disposer;
import com.intellij.util.Alarm;
import com.intellij.util.Function;
import org.jetbrains.annotations.*;
import java.util.concurrent.atomic.AtomicReference;
public class DiffTaskQueue implements Disposable {
@NotNull private final Object LOCK = new Object();
@NotNull private final Alarm myAlarm = new Alarm();
private boolean myDisposed;
@NotNull private final AtomicReference<ProgressIndicator> myProgressIndicator = new AtomicReference<ProgressIndicator>();
@CalledInAny
public void dispose() {
// if EDT is awaiting for background progress in executeAndTryWait - it holds LOCK.
// so we want to try cancel indicator before getting the lock.
cancelProgress();
synchronized (LOCK) {
if (myDisposed) return;
myDisposed = true;
cancelProgress();
Disposer.dispose(myAlarm);
}
}
@CalledInAwt
public void abort() {
synchronized (LOCK) {
cancelProgress();
myAlarm.cancelAllRequests();
}
}
private void cancelProgress() {
ProgressIndicator indicator = myProgressIndicator.getAndSet(null);
if (indicator != null) indicator.cancel();
}
@CalledInAwt
public void abortAndSchedule(@NotNull final Runnable task, int millis) {
synchronized (LOCK) {
if (myDisposed) return;
abort();
myAlarm.addRequest(new Runnable() {
@Override
public void run() {
synchronized (LOCK) {
if (myDisposed) return;
}
task.run();
}
}, millis);
}
}
@CalledInAwt
public void executeAndTryWait(@NotNull final Function<ProgressIndicator, Runnable> backgroundTask,
@Nullable final Runnable onSlowAction,
final int waitMillis) {
executeAndTryWait(backgroundTask, onSlowAction, waitMillis, false);
}
@CalledInAwt
public void executeAndTryWait(@NotNull final Function<ProgressIndicator, Runnable> backgroundTask,
@Nullable final Runnable onSlowAction,
final int waitMillis,
final boolean forceEDT) {
synchronized (LOCK) {
if (myDisposed) return;
abort();
Function<ProgressIndicator, Runnable> function = new Function<ProgressIndicator, Runnable>() {
@Override
@CalledInBackground
public Runnable fun(final ProgressIndicator indicator) {
final Runnable callback = backgroundTask.fun(indicator);
return new Runnable() {
@Override
@CalledInAwt
public void run() {
synchronized (LOCK) {
if (myDisposed) return;
indicator.checkCanceled();
}
callback.run();
}
};
}
};
myProgressIndicator.set(BackgroundTaskUtil.executeAndTryWait(function, onSlowAction, waitMillis, forceEDT));
}
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -556,7 +556,7 @@ public class FileWatcher {
case CREATE:
case DELETE:
for (String p : paths) {
myDirtyPaths.dirtyPaths.add(p);
myDirtyPaths.dirtyPathsRecursive.add(p);
String parentPath = new File(p).getParent();
if (parentPath != null) {
myDirtyPaths.dirtyPaths.add(parentPath);
@@ -1,3 +1,18 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* 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.intellij.application;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
@@ -6,7 +21,7 @@ import com.intellij.ide.plugins.PluginManagerCore;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.testFramework.PlatformLangTestCase;
import com.intellij.testFramework.PlatformTestCase;
import com.intellij.testFramework.PlatformTestUtil;
import java.io.File;
@@ -15,24 +30,22 @@ import java.util.List;
/**
* @author Dmitry Avdeev
* Date: 1/9/13
* @since 9.01.2013
*/
public class BadPluginTest extends PlatformLangTestCase {
private static final String COM_YOURCOMPANY_UNIQUE_PLUGIN_ID = "com.yourcompany.unique.plugin.id";
public class BadPluginTest extends PlatformTestCase {
private static final String COM_YOUR_COMPANY_UNIQUE_PLUGIN_ID = "com.your.company.unique.plugin.id";
public void testBadPlugin() throws Exception {
IdeaPluginDescriptor plugin = PluginManager.getPlugin(PluginId.getId(COM_YOURCOMPANY_UNIQUE_PLUGIN_ID));
IdeaPluginDescriptor plugin = PluginManager.getPlugin(PluginId.getId(COM_YOUR_COMPANY_UNIQUE_PLUGIN_ID));
if (plugin == null) return;
List<String> disabledPlugins = new ArrayList<String>();
PluginManagerCore.loadDisabledPlugins(PathManager.getConfigPath(), disabledPlugins);
assertEquals(1, disabledPlugins.size());
assertEquals(COM_YOURCOMPANY_UNIQUE_PLUGIN_ID, disabledPlugins.get(0));
assertEquals(COM_YOUR_COMPANY_UNIQUE_PLUGIN_ID, disabledPlugins.get(0));
}
@Override
protected void setUp() throws Exception {
String path = PlatformTestUtil.getCommunityPath() + "/platform/platform-tests/testData/badPlugins";
File directory = createTempDirectory(false);
FileUtil.copyDir(new File(path), directory);
@@ -714,6 +714,33 @@ public class FileWatcherTest extends PlatformLangTestCase {
}
}
public void testDisplacementByIsomorphicTree() throws Exception {
File top = createTestDir("top");
File up = createTestDir(top, "up");
File middle = createTestDir(up, "middle");
File file = createTestFile(middle, "file.txt", "original content");
File up_copy = new File(top, "up_copy");
FileUtil.copyDir(up, up_copy);
FileUtil.writeToFile(file, "new content");
VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
assertNotNull(vFile);
assertEquals("new content", VfsUtilCore.loadText(vFile));
LocalFileSystem.WatchRequest request = watch(up);
try {
myAccept = true;
FileUtil.rename(up, new File(top, "up.bak"));
FileUtil.rename(up_copy, up);
assertEvent(VFileContentChangeEvent.class, file.getPath());
assertTrue(vFile.isValid());
assertEquals("original content", VfsUtilCore.loadText(vFile));
}
finally {
unwatch(request);
}
}
@NotNull
private LocalFileSystem.WatchRequest watch(File watchFile) {
@@ -21,6 +21,7 @@ import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.*;
import com.intellij.testFramework.LightPlatformTestCase;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashSet;
@@ -33,7 +34,37 @@ import java.util.Set;
import static com.intellij.openapi.util.io.IoTestUtil.*;
import static com.intellij.testFramework.PlatformTestUtil.assertPathsEqual;
public class SymlinkHandlingTest extends SymlinkTestCase {
public class SymlinkHandlingTest extends LightPlatformTestCase {
protected LocalFileSystem myFileSystem;
protected File myTempDir;
@Override
protected void setUp() throws Exception {
super.setUp();
myFileSystem = LocalFileSystem.getInstance();
myTempDir = createTestDir("temp");
}
@Override
protected void tearDown() throws Exception {
try {
super.tearDown();
}
finally {
delete(myTempDir);
}
}
@Override
protected void runTest() throws Throwable {
if (SystemInfo.areSymLinksSupported) {
super.runTest();
}
else {
System.err.println("Skipped: " + getName());
}
}
public void testMissingLink() throws Exception {
File missingFile = new File(myTempDir, "missing_file");
assertTrue(missingFile.getPath(), !missingFile.exists() || missingFile.delete());
@@ -362,6 +393,17 @@ public class SymlinkHandlingTest extends SymlinkTestCase {
return myFileSystem.findFileByPath(ioFile.getPath());
}
protected void refresh() {
assertTrue(myTempDir.getPath(), myTempDir.isDirectory() || myTempDir.mkdirs());
VirtualFile tempDir = myFileSystem.refreshAndFindFileByIoFile(myTempDir);
assertNotNull(myTempDir.getPath(), tempDir);
tempDir.getChildren();
tempDir.refresh(false, true);
VfsUtilCore.visitChildrenRecursively(tempDir, new VirtualFileVisitor() { });
}
private static void assertBrokenLink(@NotNull VirtualFile link) {
assertTrue(link.is(VFileProperty.SYMLINK));
assertEquals(0, link.getLength());
@@ -1,71 +0,0 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* 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.intellij.openapi.vfs.local;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.io.IoTestUtil;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.vfs.VirtualFileVisitor;
import com.intellij.testFramework.LightPlatformLangTestCase;
import java.io.File;
import static com.intellij.openapi.util.io.IoTestUtil.createTestDir;
public abstract class SymlinkTestCase extends LightPlatformLangTestCase {
protected LocalFileSystem myFileSystem;
protected File myTempDir;
@Override
protected void setUp() throws Exception {
super.setUp();
myFileSystem = LocalFileSystem.getInstance();
myTempDir = createTestDir("temp");
}
@Override
protected void tearDown() throws Exception {
try {
super.tearDown();
}
finally {
IoTestUtil.delete(myTempDir);
}
}
@Override
protected void runTest() throws Throwable {
if (SystemInfo.areSymLinksSupported) {
super.runTest();
}
else {
System.err.println("Skipped: " + getName());
}
}
protected void refresh() {
assertTrue(myTempDir.getPath(), myTempDir.isDirectory() || myTempDir.mkdirs());
VirtualFile tempDir = myFileSystem.refreshAndFindFileByIoFile(myTempDir);
assertNotNull(myTempDir.getPath(), tempDir);
tempDir.getChildren();
tempDir.refresh(false, true);
VfsUtilCore.visitChildrenRecursively(tempDir, new VirtualFileVisitor() { });
}
}
@@ -130,7 +130,8 @@ public class CompositeException extends Exception {
sb.append(line);
line = exceptionProcessor.fun(exception);
if (!line.endsWith("\n")) line += '\n';
if (line == null) line = "null\n";
else if (!line.endsWith("\n")) line += '\n';
stringProcessor.process(line);
sb.append(line);
}
@@ -458,15 +458,18 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
result.add(e);
}
//cleanTheWorld();
try {
myEditorListenerTracker.checkListenersLeak();
if (myEditorListenerTracker != null) {
myEditorListenerTracker.checkListenersLeak();
}
}
catch (AssertionError error) {
result.add(error);
}
try {
myThreadTracker.checkLeak();
if (myThreadTracker != null) {
myThreadTracker.checkLeak();
}
}
catch (AssertionError error) {
result.add(error);
@@ -477,9 +480,6 @@ public abstract class PlatformTestCase extends UsefulTestCase implements DataPro
catch (Throwable error) {
result.add(error);
}
//if (directoryIndex != null) {
// directoryIndex.assertAncestorConsistent();
//}
}
finally {
myProjectManager = null;
+3 -4
View File
@@ -14,12 +14,12 @@
<orderEntry type="module" module-name="platform-impl" exported="" />
<orderEntry type="library" exported="" name="Log4J" level="project" />
<orderEntry type="module" module-name="vcs-api" exported="" />
<orderEntry type="module" module-name="lvcs-impl" />
<orderEntry type="module" module-name="lvcs-impl" scope="RUNTIME" />
<orderEntry type="module" module-name="tests_bootstrap" />
<orderEntry type="module" module-name="resources-en" scope="RUNTIME" />
<orderEntry type="library" exported="" scope="TEST" name="Mocks" level="project" />
<orderEntry type="module" module-name="java-runtime" exported="" />
<orderEntry type="module" module-name="vcs-impl" />
<orderEntry type="module" module-name="vcs-impl" scope="RUNTIME" />
<orderEntry type="library" exported="" name="Groovy" level="project" />
<orderEntry type="module" module-name="platform-resources" exported="" scope="RUNTIME" />
<orderEntry type="module" module-name="dom-impl" exported="" scope="RUNTIME" />
@@ -27,5 +27,4 @@
<orderEntry type="module" module-name="images" exported="" scope="RUNTIME" />
<orderEntry type="module" module-name="RegExpSupport" exported="" scope="RUNTIME" />
</component>
</module>
</module>
@@ -86,8 +86,12 @@ public class PatienceIntLCS {
int matched = matching[0].length;
assert matched > 0;
c1 = matching[0][0];
c2 = matching[1][0];
checkReduction(c1, c2);
PatienceIntLCS patienceDiff =
new PatienceIntLCS(myFirst, mySecond, start1, matching[0][0], start2, matching[1][0], myChanges1, myChanges2);
new PatienceIntLCS(myFirst, mySecond, start1, c1, start2, c2, myChanges1, myChanges2);
patienceDiff.execute();
for (int i = 1; i < matching[0].length; i++) {
@@ -17,11 +17,11 @@ package com.intellij.util.lang;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.io.URLUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import sun.misc.Resource;
import java.io.File;
import java.io.IOException;
import java.lang.ref.SoftReference;
import java.net.URL;
@@ -30,15 +30,18 @@ import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
class JarLoader extends Loader {
private final URL myURL;
private final File myCanonicalFile;
private final boolean myCanLockJar; // true implies that the zipfile will not be modified in the lifetime of the JarLoader
private SoftReference<JarMemoryLoader> myMemoryLoader;
private volatile SoftReference<ZipFile> myZipFileSoftReference; // Used only when myCanLockJar==true
// todo drop unused parameter
JarLoader(URL url, @SuppressWarnings("unused") boolean canLockJar, int index, boolean preloadJarContents) throws IOException {
super(new URL(URLUtil.JAR_PROTOCOL, "", -1, url + "!/"), index);
myURL = url;
super(new URL("jar", "", -1, url + "!/"), index);
ZipFile zipFile = new ZipFile(getFileUrl());
myCanonicalFile = new File(FileUtil.unquote(url.getFile())).getCanonicalFile();
myCanLockJar = canLockJar;
ZipFile zipFile = getZipFile(); // IOException from opening is propagated to caller if zip file isn't valid,
try {
if (preloadJarContents) {
JarMemoryLoader loader = JarMemoryLoader.load(zipFile, getBaseURL());
@@ -48,18 +51,14 @@ class JarLoader extends Loader {
}
}
finally {
zipFile.close();
releaseZipFile(zipFile);
}
}
private String getFileUrl() throws IOException {
return FileUtil.unquote(myURL.getFile());
}
@NotNull
@Override
public ClasspathCache.LoaderData buildData() throws IOException {
ZipFile zipFile = new ZipFile(getFileUrl());
ZipFile zipFile = getZipFile();
try {
ClasspathCache.LoaderData loaderData = new ClasspathCache.LoaderData();
Enumeration<? extends ZipEntry> entries = zipFile.entries();
@@ -72,21 +71,21 @@ class JarLoader extends Loader {
return loaderData;
}
finally {
zipFile.close();
releaseZipFile(zipFile);
}
}
@Override
@Nullable
Resource getResource(String name, boolean flag) {
JarMemoryLoader loader = com.intellij.reference.SoftReference.dereference(myMemoryLoader);
JarMemoryLoader loader = myMemoryLoader != null? myMemoryLoader.get() : null;
if (loader != null) {
Resource resource = loader.getResource(name);
if (resource != null) return resource;
}
try {
ZipFile zipFile = new ZipFile(getFileUrl());
ZipFile zipFile = getZipFile();
try {
ZipEntry entry = zipFile.getEntry(name);
if (entry != null) {
@@ -94,18 +93,58 @@ class JarLoader extends Loader {
}
}
finally {
zipFile.close();
releaseZipFile(zipFile);
}
}
catch (Exception e) {
Logger.getInstance(JarLoader.class).error("url: " + myURL, e);
error("file: " + myCanonicalFile, e);
}
return null;
}
protected void error(String message, Throwable t) {
//Logger.getLogger(JarLoader.class.getName()).log(Level.SEVERE, message, t);
Logger.getInstance(JarLoader.class).error(message, t);
}
private void releaseZipFile(ZipFile zipFile) throws IOException {
// Closing of zip file when myCanLockJar=true happens in ZipFile.finalize
if (!myCanLockJar) {
zipFile.close();
}
}
@NotNull
private ZipFile getZipFile() throws IOException {
// This code is executed at least 100K times (O(number of classes needed to load)) and it takes considerable time to open ZipFile's
// such number of times so we store reference to ZipFile if we allowed to lock the file (assume it isn't changed)
if (myCanLockJar) {
SoftReference<ZipFile> zipFileSoftReference = myZipFileSoftReference;
if(zipFileSoftReference != null) {
ZipFile existingZipFile = zipFileSoftReference.get();
if (existingZipFile != null) return existingZipFile;
}
synchronized (ourLock) {
zipFileSoftReference = myZipFileSoftReference;
if(zipFileSoftReference != null) {
ZipFile existingZipFile = zipFileSoftReference.get();
if (existingZipFile != null) return existingZipFile;
}
// ZipFile's native implementation (ZipFile.c, zip_util.c) has path -> file descriptor cache
ZipFile zipFile = new ZipFile(myCanonicalFile);
myZipFileSoftReference = new SoftReference<ZipFile>(zipFile);
return zipFile;
}
} else {
return new ZipFile(myCanonicalFile);
}
}
@Override
public String toString() {
return "JarLoader [" + myURL + "]";
return "JarLoader [" + myCanonicalFile + "]";
}
private static final Object ourLock = new Object();
}
@@ -15,9 +15,7 @@
*/
package com.intellij.util.lang;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.util.containers.hash.HashMap;
import com.intellij.util.io.zip.ZipShort;
import com.intellij.openapi.util.io.FileUtilRt;
import org.jetbrains.annotations.Nullable;
import sun.misc.Resource;
@@ -26,6 +24,7 @@ import java.io.IOException;
import java.net.URL;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@@ -64,8 +63,8 @@ public class JarMemoryLoader {
ZipEntry sizeEntry = entries.nextElement();
if (sizeEntry == null || !sizeEntry.getName().equals(SIZE_ENTRY)) return null;
byte[] bytes = FileUtil.loadBytes(zipFile.getInputStream(sizeEntry), 2);
int size = ZipShort.getValue(bytes);
byte[] bytes = FileUtilRt.loadBytes(zipFile.getInputStream(sizeEntry), 2);
int size = ((bytes[1] & 0xFF) << 8) + (bytes[0] & 0xFF);
JarMemoryLoader loader = new JarMemoryLoader();
for (int i = 0; i < size && entries.hasMoreElements(); i++) {
@@ -19,9 +19,9 @@ import com.intellij.diff.chains.DiffRequestProducerException;
import com.intellij.diff.impl.DiffRequestProcessor;
import com.intellij.diff.requests.*;
import com.intellij.diff.tools.util.SoftHardCacheMap;
import com.intellij.diff.util.DiffTaskQueue;
import com.intellij.diff.util.DiffUserDataKeys;
import com.intellij.diff.util.DiffUserDataKeysEx.ScrollToPolicy;
import com.intellij.diff.util.WaitingBackgroundableTaskExecutor;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.AnActionEvent;
@@ -31,10 +31,11 @@ import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.util.ProgressWindow;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.vcs.changes.actions.diff.ChangeDiffRequestProducer;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.Convertor;
import org.jetbrains.annotations.*;
import java.util.Collections;
@@ -48,7 +49,7 @@ public abstract class CacheChangeProcessor extends DiffRequestProcessor {
@Nullable private Change myCurrentChange;
@NotNull private final WaitingBackgroundableTaskExecutor myTaskExecutor = new WaitingBackgroundableTaskExecutor();
@NotNull private final DiffTaskQueue myQueue = new DiffTaskQueue();
public CacheChangeProcessor(@NotNull Project project) {
super(project);
@@ -74,21 +75,25 @@ public abstract class CacheChangeProcessor extends DiffRequestProcessor {
// Update
//
@CalledInAwt
public void updateRequest(final boolean force, @Nullable final ScrollToPolicy scrollToChangePolicy) {
final Change change = myCurrentChange;
DiffRequest cachedRequest = loadRequestFast(change);
if (cachedRequest != null) {
applyRequest(cachedRequest, force, scrollToChangePolicy);
return;
}
myTaskExecutor.execute(
new Convertor<ProgressIndicator, Runnable>() {
// TODO: check if current loading change is the same as we want to load now? (and not interrupt loading)
myQueue.executeAndTryWait(
new Function<ProgressIndicator, Runnable>() {
@Override
public Runnable convert(ProgressIndicator indicator) {
public Runnable fun(ProgressIndicator indicator) {
final DiffRequest request = loadRequest(change, indicator);
return new Runnable() {
@Override
@CalledInAwt
public void run() {
myRequestCache.put(change, Pair.create(change, request));
applyRequest(request, force, scrollToChangePolicy);
@@ -107,6 +112,7 @@ public abstract class CacheChangeProcessor extends DiffRequestProcessor {
}
@Nullable
@CalledInAwt
@Contract("null -> !null")
protected DiffRequest loadRequestFast(@Nullable Change change) {
if (change == null) return NoDiffRequest.INSTANCE;
@@ -152,9 +158,10 @@ public abstract class CacheChangeProcessor extends DiffRequestProcessor {
//
@Override
@CalledInAwt
protected void onDispose() {
super.onDispose();
myTaskExecutor.abort();
Disposer.dispose(myQueue);
myRequestCache.clear();
}
@@ -0,0 +1,211 @@
package com.intellij.openapi.vcs.changes.committed;
import com.intellij.ide.startup.impl.StartupManagerImpl;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.ProjectLevelVcsManager;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.*;
import com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
import com.intellij.testFramework.fixtures.TempDirTestFixture;
import com.intellij.testFramework.vcs.AbstractJunitVcsTestCase;
import com.intellij.util.Processor;
import com.intellij.util.ui.UIUtil;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
import java.util.List;
import java.util.regex.Pattern;
/**
* @author irengrig
*/
public class ExternalChangesDetectionVcsTest extends AbstractJunitVcsTestCase {
private MockAbstractVcs myVcs;
private ProjectLevelVcsManagerImpl myVcsManager;
private LocalFileSystem myLFS;
private ChangeListManager myChangeListManager;
private VcsDirtyScopeManager myVcsDirtyScopeManager;
private TempDirTestFixture myTempDirTestFixture;
private File myClientRoot;
@Before
public void setUp() throws Exception {
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
try {
final IdeaTestFixtureFactory fixtureFactory = IdeaTestFixtureFactory.getFixtureFactory();
myTempDirTestFixture = fixtureFactory.createTempDirTestFixture();
myTempDirTestFixture.setUp();
myClientRoot = new File(myTempDirTestFixture.getTempDirPath(), "clientroot");
myClientRoot.mkdir();
initProject(myClientRoot, ExternalChangesDetectionVcsTest.this.getTestName());
((StartupManagerImpl)StartupManager.getInstance(myProject)).runPostStartupActivities();
myVcs = new MockAbstractVcs(myProject);
myVcs.setChangeProvider(new MyMockChangeProvider());
myVcsManager = (ProjectLevelVcsManagerImpl)ProjectLevelVcsManager.getInstance(myProject);
myVcsManager.registerVcs(myVcs);
myVcsManager.setDirectoryMapping("", myVcs.getName());
myLFS = LocalFileSystem.getInstance();
myChangeListManager = ChangeListManager.getInstance(myProject);
((ProjectComponent)myChangeListManager).projectOpened();
myVcsDirtyScopeManager = VcsDirtyScopeManager.getInstance(myProject);
((ProjectComponent)myVcsDirtyScopeManager).projectOpened();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
});
}
@After
public void tearDown() throws Exception {
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
try {
myVcsManager.unregisterVcs(myVcs);
((ProjectComponent)myChangeListManager).projectClosed();
((ProjectComponent)myVcsDirtyScopeManager).projectClosed();
tearDownProject();
if (myTempDirTestFixture != null) {
myTempDirTestFixture.tearDown();
myTempDirTestFixture = null;
}
FileUtil.delete(myClientRoot);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
});
}
@Test
public void testDeletion() throws Exception {
final File f = new File(myClientRoot, "f.txt");
f.createNewFile();
final VirtualFile vf = myLFS.refreshAndFindFileByIoFile(f);
myChangeListManager.ensureUpToDate(false);
((ChangeListManagerImpl) myChangeListManager).getUnversionedFiles().contains(vf);
FileUtil.delete(f);
myWorkingCopyDir.refresh(false, true);
myChangeListManager.ensureUpToDate(false);
((ChangeListManagerImpl) myChangeListManager).getUnversionedFiles().isEmpty();
}
@Test
public void testGeneration() throws Exception {
for (int i = 0; i < 100; i++) {
final File f = new File(myClientRoot, "f" + i + ".txt");
f.createNewFile();
}
myWorkingCopyDir.refresh(false, true);
myChangeListManager.ensureUpToDate(false);
final List<VirtualFile> unversionedFiles = ((ChangeListManagerImpl)myChangeListManager).getUnversionedFiles();
final Pattern pattern = Pattern.compile("f([0-9])+\\.txt");
int cnt = 0;
for (VirtualFile unversionedFile : unversionedFiles) {
if (VfsUtil.isAncestor(myWorkingCopyDir, unversionedFile, true)) {
++ cnt;
Assert.assertTrue(pattern.matcher(unversionedFile.getName()).matches());
}
}
Assert.assertEquals(100, cnt);
}
/*@Test
public void testMoveDir() throws Exception {
final File root = new File(myClientRoot, "was");
root.mkdir();
for (int i = 0; i < 10; i++) {
final File dir = new File(root, "dir" + i);
dir.mkdir();
for (int j = 0; j < 10; j++) {
final File f = new File(dir, "f" + j + ".txt");
f.createNewFile();
}
}
myWorkingCopyDir.refresh(false, true);
myChangeListManager.ensureUpToDate(false);
List<VirtualFile> unversionedFiles = ((ChangeListManagerImpl)myChangeListManager).getUnversionedFiles();
final Pattern pattern = Pattern.compile("f([0-9])+\\.txt");
final Pattern patternDir = Pattern.compile("dir([0-9])+");
int cnt = 0;
for (VirtualFile unversionedFile : unversionedFiles) {
if (VfsUtil.isAncestor(myWorkingCopyDir, unversionedFile, true) && (! "was".equals(unversionedFile.getName()))) {
++ cnt;
Assert.assertTrue(pattern.matcher(unversionedFile.getName()).matches() || patternDir.matcher(unversionedFile.getName()).matches());
}
}
Assert.assertEquals(110, cnt);
final File renamedFile = new File(myClientRoot, "newName");
FileUtil.copyDir(root, renamedFile);
FileUtil.delete(root);
myWorkingCopyDir.refresh(false, true);
myChangeListManager.ensureUpToDate(false);
unversionedFiles = ((ChangeListManagerImpl)myChangeListManager).getUnversionedFiles();
cnt = 0;
for (VirtualFile unversionedFile : unversionedFiles) {
if (VfsUtil.isAncestor(myWorkingCopyDir, unversionedFile, true) && (! "newName".equals(unversionedFile.getName()))) {
++ cnt;
Assert.assertTrue((pattern.matcher(unversionedFile.getName()).matches() || patternDir.matcher(unversionedFile.getName()).matches()));
if (unversionedFile.getPath().indexOf("newName") == -1) {
System.out.println("wrong " + unversionedFile.getPath());
}
}
}
Assert.assertEquals(110, cnt);
}*/
private static class MyMockChangeProvider implements ChangeProvider {
@Override
public void doCleanup(List<VirtualFile> files) {
}
@Override
public void getChanges(VcsDirtyScope dirtyScope,
final ChangelistBuilder builder,
ProgressIndicator progress,
ChangeListManagerGate addGate) throws VcsException {
for (FilePath path : dirtyScope.getDirtyFiles()) {
builder.processUnversionedFile(path.getVirtualFile());
}
final Processor<VirtualFile> processor = new Processor<VirtualFile>() {
@Override
public boolean process(final VirtualFile vf) {
builder.processUnversionedFile(vf);
return true;
}
};
for (FilePath dir : dirtyScope.getRecursivelyDirtyDirectories()) {
VfsUtil.processFilesRecursively(dir.getVirtualFile(), processor);
}
}
@Override
public boolean isModifiedDocumentTrackingRequired() {
return false;
}
}
}
@@ -0,0 +1,355 @@
package com.intellij.openapi.vcs.changes.committed;
import com.intellij.ide.startup.impl.StartupManagerImpl;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.options.Configurable;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.startup.StartupManager;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ChangeList;
import com.intellij.openapi.vcs.changes.ChangeListManager;
import com.intellij.openapi.vcs.checkin.CheckinEnvironment;
import com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl;
import com.intellij.openapi.vcs.rollback.RollbackEnvironment;
import com.intellij.openapi.vcs.rollback.RollbackProgressListener;
import com.intellij.openapi.vcs.ui.RefreshableOnComponent;
import com.intellij.openapi.vcs.update.SequentialUpdatesContext;
import com.intellij.openapi.vcs.update.UpdateEnvironment;
import com.intellij.openapi.vcs.update.UpdateSession;
import com.intellij.openapi.vcs.update.UpdatedFiles;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.UsefulTestCase;
import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory;
import com.intellij.testFramework.fixtures.TempDirTestFixture;
import com.intellij.testFramework.vcs.AbstractJunitVcsTestCase;
import com.intellij.util.NullableFunction;
import com.intellij.util.PairConsumer;
import com.intellij.util.ui.UIUtil;
import junit.framework.Assert;
import org.jetbrains.annotations.NotNull;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.File;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;
/**
* @author irengrig
* Date: 12/21/10
* Time: 2:03 PM
*/
public class VcsEventsListenerTest extends AbstractJunitVcsTestCase {
private AbstractVcs myVcs;
private ProjectLevelVcsManagerImpl myVcsManager;
private ChangeListManager myChangeListManager;
private TempDirTestFixture myTempDirFixture;
private File myClientRoot;
@Before
public void setUp() {
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
try {
final IdeaTestFixtureFactory fixtureFactory = IdeaTestFixtureFactory.getFixtureFactory();
myTempDirFixture = fixtureFactory.createTempDirTestFixture();
myTempDirFixture.setUp();
myClientRoot = new File(myTempDirFixture.getTempDirPath(), "clientroot");
myClientRoot.mkdir();
initProject(myClientRoot, VcsEventsListenerTest.this.getTestName());
((StartupManagerImpl)StartupManager.getInstance(myProject)).runPostStartupActivities();
myChangeListManager = ChangeListManager.getInstance(myProject);
myVcs = VcsActiveEnvironmentsProxy.proxyVcs(new MyVcs(myProject, "mock"));
myVcsManager = (ProjectLevelVcsManagerImpl)ProjectLevelVcsManager.getInstance(myProject);
myVcsManager.registerVcs(myVcs);
myVcsManager.setDirectoryMapping(myWorkingCopyDir.getPath(), myVcs.getName());
((ProjectComponent)myChangeListManager).projectOpened();
}
catch (Exception e) {
tearDown();
throw new RuntimeException(e);
}
}
});
}
@After
public void tearDown() {
UIUtil.invokeAndWaitIfNeeded(new Runnable() {
@Override
public void run() {
try {
if (myVcsManager != null && myVcs != null) {
myVcsManager.unregisterVcs(myVcs);
}
((ProjectComponent)myChangeListManager).projectClosed();
tearDownProject();
if (myTempDirFixture != null) {
myTempDirFixture.tearDown();
myTempDirFixture = null;
}
FileUtil.delete(myClientRoot);
}
catch (Exception e) {
throw new RuntimeException(e);
}
finally {
try {
UsefulTestCase.clearFields(this);
}
catch (IllegalAccessException e) {
//noinspection ThrowFromFinallyBlock
throw new RuntimeException(e);
}
}
}
});
}
@Test
public void testSimpleListeningWithProxy() throws Exception {
final VcsEventsListenerManager manager = myVcsManager.getVcsEventsListenerManager();
final List<VirtualFile> list = Arrays.asList(new VirtualFile[]{myWorkingCopyDir});
final MyCheckinListener listener = new MyCheckinListener(list);
final Object key = manager.addCheckin(new ForwardingListener<CheckinEnvironment>(listener));
myVcs.getCheckinEnvironment().scheduleUnversionedFilesForAddition(list);
Assert.assertTrue(listener.isChecked());
listener.assertCheckOk();
listener.reset();
manager.removeCheckin(key);
listener.reset();
myVcs.getCheckinEnvironment().scheduleUnversionedFilesForAddition(list);
Assert.assertFalse(listener.isChecked());
}
@Test
public void testSimpleListeningWithoutProxy() throws Exception {
myVcsManager.setDirectoryMapping(myWorkingCopyDir.getPath(), "svn");
testSimpleListeningWithProxy();
}
private static class MyVcs extends MockAbstractVcs {
private MyVcs(Project project, String name) {
super(project, name);
}
@Override
protected UpdateEnvironment createUpdateEnvironment() {
return new UpdateEnvironment() {
@Override
public void fillGroups(UpdatedFiles updatedFiles) {
//To change body of implemented methods use File | Settings | File Templates.
}
@NotNull
@Override
public UpdateSession updateDirectories(@NotNull FilePath[] contentRoots,
UpdatedFiles updatedFiles,
ProgressIndicator progressIndicator,
@NotNull Ref<SequentialUpdatesContext> context) throws ProcessCanceledException {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public Configurable createConfigurable(Collection<FilePath> files) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public boolean validateOptions(Collection<FilePath> roots) {
return false; //To change body of implemented methods use File | Settings | File Templates.
}
};
}
@Override
protected RollbackEnvironment createRollbackEnvironment() {
return new RollbackEnvironment() {
@Override
public String getRollbackOperationName() {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void rollbackChanges(List<Change> changes,
List<VcsException> vcsExceptions,
@NotNull RollbackProgressListener listener) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void rollbackMissingFileDeletion(List<FilePath> files,
List<VcsException> exceptions,
RollbackProgressListener listener) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void rollbackModifiedWithoutCheckout(List<VirtualFile> files,
List<VcsException> exceptions,
RollbackProgressListener listener) {
//To change body of implemented methods use File | Settings | File Templates.
}
@Override
public void rollbackIfUnchanged(VirtualFile file) {
//To change body of implemented methods use File | Settings | File Templates.
}
};
}
@Override
protected CheckinEnvironment createCheckinEnvironment() {
return new CheckinEnvironment() {
@Override
public RefreshableOnComponent createAdditionalOptionsPanel(CheckinProjectPanel panel,
PairConsumer<Object, Object> additionalDataConsumer) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public String getDefaultMessageFor(FilePath[] filesToCheckin) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public String getHelpId() {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public String getCheckinOperationName() {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public List<VcsException> commit(List<Change> changes, String preparedComment) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public List<VcsException> commit(List<Change> changes,
String preparedComment,
@NotNull NullableFunction<Object, Object> parametersHolder, Set<String> feedback) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public List<VcsException> scheduleMissingFileForDeletion(List<FilePath> files) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public List<VcsException> scheduleUnversionedFilesForAddition(List<VirtualFile> files) {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public boolean keepChangeListAfterCommit(ChangeList changeList) {
return false; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public boolean isRefreshAfterCommitNeeded() {
return true;
}
};
}
}
private static class MyCheckinListener implements CheckinEnvironment {
private boolean myChecked;
private boolean myAssertOk;
private final List<VirtualFile> myCheckList;
public MyCheckinListener(final List<VirtualFile> checkList) {
myCheckList = checkList;
myChecked = false;
myAssertOk = true;
}
@Override
public RefreshableOnComponent createAdditionalOptionsPanel(CheckinProjectPanel panel,
PairConsumer<Object, Object> additionalDataConsumer) {
return null;
}
@Override
public String getDefaultMessageFor(FilePath[] filesToCheckin) {
return null;
}
@Override
public String getHelpId() {
return null;
}
@Override
public String getCheckinOperationName() {
return null;
}
@Override
public List<VcsException> commit(List<Change> changes, String preparedComment) {
return null;
}
@Override
public List<VcsException> commit(List<Change> changes,
String preparedComment,
@NotNull NullableFunction<Object, Object> parametersHolder, Set<String> feedback) {
return null;
}
@Override
public List<VcsException> scheduleMissingFileForDeletion(List<FilePath> files) {
return null;
}
@Override
public List<VcsException> scheduleUnversionedFilesForAddition(List<VirtualFile> files) {
myChecked = true;
myAssertOk = myCheckList.equals(files);
return null;
}
@Override
public boolean keepChangeListAfterCommit(ChangeList changeList) {
return false;
}
@Override
public boolean isRefreshAfterCommitNeeded() {
return true;
}
public boolean isChecked() {
return myChecked;
}
public void assertCheckOk() {
Assert.assertTrue(myAssertOk);
}
public void reset() {
myAssertOk = true;
myChecked = false;
}
}
}
@@ -10,7 +10,10 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.text.DateFormatUtil;
import com.intellij.vcs.log.*;
import com.intellij.vcs.log.Hash;
import com.intellij.vcs.log.VcsFullCommitDetails;
import com.intellij.vcs.log.VcsRef;
import com.intellij.vcs.log.VcsShortCommitDetails;
import com.intellij.vcs.log.data.LoadingDetails;
import com.intellij.vcs.log.data.VcsLogDataHolder;
import com.intellij.vcs.log.data.VisiblePack;
@@ -157,6 +160,7 @@ public class GraphTableModel extends AbstractTableModel {
/**
* Requests the proper data provider to load more data from the log & recreate the model.
*
* @param onLoaded will be called upon task completion on the EDT.
*/
public void requestToLoadMore(@NotNull Runnable onLoaded) {
@@ -183,7 +187,9 @@ public class GraphTableModel extends AbstractTableModel {
return "";
}
else {
return data.getAuthor().getName() + (data.getAuthor().equals(data.getCommitter()) ? "" : "*");
String authorString = data.getAuthor().getName();
if (authorString.isEmpty()) authorString = data.getAuthor().getEmail();
return authorString + (data.getAuthor().equals(data.getCommitter()) ? "" : "*");
}
case DATE_COLUMN:
if (data == null || data.getAuthorTime() < 0) {
@@ -208,6 +214,7 @@ public class GraphTableModel extends AbstractTableModel {
* Returns Changes for commits at selected rows.<br/>
* Rows are given in the order as they appear in the table, i. e. in reverse chronological order. <br/>
* Changes can be returned as-is, i.e. with duplicate changes for a single file.
*
* @return Changes selected in all rows, or null if this data is not ready yet.
*/
@Nullable
@@ -15,6 +15,7 @@
*/
package git4idea.actions;
import com.intellij.dvcs.repo.Repository;
import com.intellij.openapi.actionSystem.ActionPlaces;
import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.CommonDataKeys;
@@ -114,19 +115,18 @@ public abstract class GitRepositoryAction extends DumbAwareAction {
if (files != null) {
for (VirtualFile file : files) {
GitRepositoryManager manager = GitUtil.getRepositoryManager(project);
if (manager == null) {
return false;
}
final GitRepository repositoryForFile = manager.getRepositoryForFile(file);
if (repositoryForFile != null && repositoryForFile.getState() == GitRepository.State.REBASING) {
return true;
}
if (isRebasing(manager.getRepositoryForFile(file))) return true;
}
}
if (isRebasing(GitBranchUtil.getCurrentRepository(project))) return true;
}
return false;
}
private static boolean isRebasing(@Nullable GitRepository repository) {
return repository != null && repository.getState() == Repository.State.REBASING;
}
/**
* Get git roots for the project. The method shows dialogs in the case when roots cannot be retrieved, so it should be called
* from the event dispatch thread.
@@ -130,4 +130,23 @@ public class JUnitRerunFailedTestsTest extends LightCodeInsightFixtureTestCase
});
assertNull(TestMethods.getTestPresentation(testProxy, project, searchScope));
}
public void testInnerClass() throws Exception {
myFixture.addClass("public class TestClass {\n" +
" public static class Tests extends junit.framework.TestCase {\n" +
" public void testFoo() throws Exception {}\n" +
" }\n" +
"}");
final SMTestProxy testProxy = new SMTestProxy("testFoo", false, "java:test://TestClass$Tests.testFoo");
final Project project = getProject();
final GlobalSearchScope searchScope = GlobalSearchScope.projectScope(project);
testProxy.setLocator(JavaTestLocator.INSTANCE);
Location location = testProxy.getLocation(project, searchScope);
assertNotNull(location);
PsiElement element = location.getPsiElement();
assertTrue(element instanceof PsiMethod);
String name = ((PsiMethod)element).getName();
assertEquals(name, "testFoo");
}
}
@@ -15,7 +15,7 @@
*/
package com.intellij.execution.junit;
import com.intellij.junit4.SMTestSender;
import com.intellij.junit4.JUnit4TestListener;
import com.intellij.openapi.util.text.StringUtil;
import junit.framework.Assert;
import org.junit.Test;
@@ -65,26 +65,25 @@ public class JUnitTreeByDescriptionHierarchyTest {
"##teamcity[enteredTheMatrix]\n" +
"##teamcity[rootName name = 'root' location = 'java:suite://root']\n" +
"##teamcity[testSuiteFinished name='root']\n" +
"##teamcity[testSuiteStarted name ='TestA']\n" +
"##teamcity[testSuiteStarted name ='|[0|]']\n" +
"##teamcity[testSuiteStarted name='TestA']\n" +
"##teamcity[testSuiteStarted name='|[0|]']\n" +
"##teamcity[testStarted name='testName|[0|]' locationHint='java:test://a.TestA.testName|[0|]']\n" +
"\n" +
"##teamcity[testFinished name='testName|[0|]']\n" +
"##teamcity[testSuiteFinished name='|[0|]']\n" +
"##teamcity[testSuiteStarted name ='|[1|]']\n" +
"##teamcity[testSuiteStarted name='|[1|]']\n" +
"##teamcity[testStarted name='testName|[1|]' locationHint='java:test://a.TestA.testName|[1|]']\n" +
"\n" +
"##teamcity[testFinished name='testName|[1|]']\n" +
"##teamcity[testSuiteFinished name='|[1|]']\n" +
"##teamcity[testSuiteFinished name='TestA']\n" +
"##teamcity[testSuiteStarted name ='TestB']\n" +
"##teamcity[testSuiteStarted name ='|[0|]']\n" +
"##teamcity[testSuiteStarted name='TestB']\n" +
"##teamcity[testSuiteStarted name='|[0|]']\n" +
"##teamcity[testStarted name='testName|[0|]' locationHint='java:test://a.TestB.testName|[0|]']\n" +
"\n" +
"##teamcity[testFinished name='testName|[0|]']\n" +
"##teamcity[testSuiteFinished name='|[0|]']\n" +
"##teamcity[testSuiteStarted name ='|[1|]']\n" +
"##teamcity[testSuiteStarted name='|[1|]']\n" +
"##teamcity[testStarted name='testName|[1|]' locationHint='java:test://a.TestB.testName|[1|]']\n" +
"\n" +
"##teamcity[testFinished name='testName|[1|]']\n" +
@@ -109,17 +108,16 @@ public class JUnitTreeByDescriptionHierarchyTest {
//start
"##teamcity[enteredTheMatrix]\n" +
"##teamcity[rootName name = 'TestA' comment = 'a' location = 'java:suite://a.TestA']\n" +
"##teamcity[testSuiteStarted name ='|[0|]']\n" +
"##teamcity[testSuiteStarted name='|[0|]']\n" +
"##teamcity[testStarted name='testName|[0|]' locationHint='java:test://a.TestA.testName|[0|]']\n" +
"\n" +
"##teamcity[testFinished name='testName|[0|]']\n" +
"##teamcity[testSuiteFinished name='|[0|]']\n" +
"##teamcity[testSuiteStarted name ='|[1|]']\n" +
"##teamcity[testSuiteStarted name='|[1|]']\n" +
"##teamcity[testStarted name='testName|[1|]' locationHint='java:test://a.TestA.testName|[1|]']\n" +
"\n" +
"##teamcity[testFinished name='testName|[1|]']\n" +
"##teamcity[testSuiteFinished name='|[1|]']\n" +
"##teamcity[testSuiteFinished name='TestA']\n");
"##teamcity[testSuiteFinished name='|[1|]']\n");
}
@Test
@@ -154,16 +152,15 @@ public class JUnitTreeByDescriptionHierarchyTest {
//started
"##teamcity[enteredTheMatrix]\n" +
"##teamcity[rootName name = 'root' location = 'java:suite://root']\n" +
"##teamcity[testSuiteFinished name='root']\n" +
"##teamcity[testSuiteStarted name ='ASuite1']\n" +
"##teamcity[testSuiteStarted name ='ATest']\n" +
"##teamcity[testSuiteStarted name='ASuite1']\n" +
"##teamcity[testSuiteStarted name='ATest']\n" +
"##teamcity[testStarted name='test1' locationHint='java:test://ATest.test1']\n" +
"\n" +
"##teamcity[testFinished name='test1']\n" +
"##teamcity[testSuiteFinished name='ATest']\n" +
"##teamcity[testSuiteFinished name='ASuite1']\n" +
"##teamcity[testSuiteStarted name ='ASuite2']\n" +
"##teamcity[testSuiteStarted name ='ATest']\n" +
"##teamcity[testSuiteStarted name='ASuite2']\n" +
"##teamcity[testSuiteStarted name='ATest']\n" +
"##teamcity[testStarted name='test1' locationHint='java:test://ATest.test1']\n" +
"\n" +
"##teamcity[testFinished name='test1']\n" +
@@ -173,7 +170,7 @@ public class JUnitTreeByDescriptionHierarchyTest {
private static void doTest(Description root, List<Description> tests, String expectedTree, String expectedStart) throws Exception {
final StringBuffer buf = new StringBuffer();
final SMTestSender sender = new SMTestSender(new PrintStream(new OutputStream() {
final JUnit4TestListener sender = new JUnit4TestListener(new PrintStream(new OutputStream() {
@Override
public void write(int b) throws IOException {
buf.append(new String(new byte[]{(byte)b}));
@@ -204,8 +201,37 @@ public class JUnitTreeByDescriptionHierarchyTest {
"##teamcity[rootName name = 'TestA' location = 'java:suite://TestA']\n" +
"##teamcity[testStarted name='testName' locationHint='java:test://TestA.testName']\n" +
"\n" +
"##teamcity[testFinished name='testName']\n" +
"##teamcity[testSuiteFinished name='TestA']\n");
"##teamcity[testFinished name='testName']\n");
}
@Test
public void testParameterizedTestsUpsideDown() throws Exception {
final Description aTestClass = Description.createSuiteDescription("ATest");
final ArrayList<Description> tests = new ArrayList<Description>();
final Description testMethod = Description.createSuiteDescription("testName");
aTestClass.addChild(testMethod);
for (String paramName : new String[]{"[0]", "[1]"}) {
final Description testDescription = Description.createTestDescription("ATest", "testName" + paramName);
tests.add(testDescription);
testMethod.addChild(testDescription);
}
doTest(aTestClass, tests,
"##teamcity[suiteTreeStarted name='testName' locationHint='java:suite://testName']\n" +
"##teamcity[suiteTreeNode name='testName|[0|]' locationHint='java:test://ATest.testName|[0|]']\n" +
"##teamcity[suiteTreeNode name='testName|[1|]' locationHint='java:test://ATest.testName|[1|]']\n" +
"##teamcity[suiteTreeEnded name='testName']\n",
"##teamcity[enteredTheMatrix]\n" +
"##teamcity[rootName name = 'ATest' location = 'java:suite://ATest']\n" +
"##teamcity[testSuiteStarted name='testName']\n" +
"##teamcity[testStarted name='testName|[0|]' locationHint='java:test://ATest.testName|[0|]']\n" +
"\n" +
"##teamcity[testFinished name='testName|[0|]']\n" +
"##teamcity[testStarted name='testName|[1|]' locationHint='java:test://ATest.testName|[1|]']\n" +
"\n" +
"##teamcity[testFinished name='testName|[1|]']\n" +
"##teamcity[testSuiteFinished name='testName']\n");
}
@Test
@@ -240,21 +266,20 @@ public class JUnitTreeByDescriptionHierarchyTest {
//start
"##teamcity[enteredTheMatrix]\n" +
"##teamcity[rootName name = 'root' location = 'java:suite://root']\n" +
"##teamcity[testSuiteFinished name='root']\n" +
"##teamcity[testSuiteStarted name ='ATest']\n" +
"##teamcity[testSuiteStarted name ='|[0|]']\n" +
"##teamcity[testSuiteStarted name='ATest']\n" +
"##teamcity[testSuiteStarted name='|[0|]']\n" +
"##teamcity[testStarted name='testName|[0|]' locationHint='java:test://ATest.testName|[0|]']\n" +
"\n" +
"##teamcity[testFinished name='testName|[0|]']\n" +
"##teamcity[testSuiteFinished name='|[0|]']\n" +
"##teamcity[testSuiteStarted name ='|[1|]']\n" +
"##teamcity[testSuiteStarted name='|[1|]']\n" +
"##teamcity[testStarted name='testName|[1|]' locationHint='java:test://ATest.testName|[1|]']\n" +
"\n" +
"##teamcity[testFinished name='testName|[1|]']\n" +
"##teamcity[testSuiteFinished name='|[1|]']\n" +
"##teamcity[testSuiteFinished name='ATest']\n" +
"##teamcity[testSuiteStarted name ='suite']\n" +
"##teamcity[testSuiteStarted name ='ATest']\n" +
"##teamcity[testSuiteStarted name='suite']\n" +
"##teamcity[testSuiteStarted name='ATest']\n" +
"##teamcity[testStarted name='test' locationHint='java:test://ATest.test']\n" +
"\n" +
"##teamcity[testFinished name='test']\n" +
@@ -275,7 +300,7 @@ public class JUnitTreeByDescriptionHierarchyTest {
private static void doTest(Description description, String expected) {
final StringBuffer buf = new StringBuffer();
new SMTestSender(new PrintStream(new OutputStream() {
new JUnit4TestListener(new PrintStream(new OutputStream() {
@Override
public void write(int b) throws IOException {
buf.append(new String(new byte[]{(byte)b}));
@@ -288,7 +313,7 @@ public class JUnitTreeByDescriptionHierarchyTest {
@Test
public void testProcessEmptyTestCase() throws Exception {
final Description description = Description.createSuiteDescription("TestA");
final Description emptyDescription = Description.createTestDescription(SMTestSender.EMPTY_SUITE_NAME, SMTestSender.EMPTY_SUITE_WARNING);
final Description emptyDescription = Description.createTestDescription(JUnit4TestListener.EMPTY_SUITE_NAME, JUnit4TestListener.EMPTY_SUITE_WARNING);
description.addChild(emptyDescription);
doTest(description, Collections.singletonList(emptyDescription),
"##teamcity[suiteTreeNode name='warning' locationHint='java:test://TestA.warning']\n",
@@ -298,7 +323,6 @@ public class JUnitTreeByDescriptionHierarchyTest {
"##teamcity[rootName name = 'TestA' location = 'java:suite://TestA']\n" +
"##teamcity[testStarted name='warning' locationHint='java:test://junit.framework.TestSuite$1.warning']\n" +
"\n" +
"##teamcity[testFinished name='warning']\n" +
"##teamcity[testSuiteFinished name='TestA']\n");
"##teamcity[testFinished name='warning']\n");
}
}
@@ -52,9 +52,9 @@ public class JUnit4IdeaTestRunner implements IdeaTestRunner {
description = getFilteredDescription(request, description);
}
if (myTestsListener instanceof SMTestSender) {
if (myTestsListener instanceof JUnit4TestListener) {
if (sendTree) {
((SMTestSender)myTestsListener).sendTree(description);
((JUnit4TestListener)myTestsListener).sendTree(description);
}
sendTree = false;
} else {
@@ -189,7 +189,7 @@ public class JUnit4IdeaTestRunner implements IdeaTestRunner {
public void setStreams(Object segmentedOut, Object segmentedErr, int lastIdx) {
if (JUnitStarter.SM_RUNNER) {
myTestsListener = new SMTestSender();
myTestsListener = new JUnit4TestListener();
} else {
myRegistry = new JUnit4OutputObjectRegistry((PacketProcessor)segmentedOut, lastIdx);
myTestsListener = new JUnit4TestResultsSender(myRegistry);
@@ -32,27 +32,27 @@ import org.junit.runner.notification.Failure;
import org.junit.runner.notification.RunListener;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.*;
public class SMTestSender extends RunListener {
public class JUnit4TestListener extends RunListener {
private static final String MESSAGE_LENGTH_FOR_PATTERN_MATCHING = "idea.junit.message.length.threshold";
private static final String JUNIT_FRAMEWORK_COMPARISON_NAME = ComparisonFailure.class.getName();
private static final String ORG_JUNIT_COMPARISON_NAME = "org.junit.ComparisonFailure";
public static final String EMPTY_SUITE_NAME = "junit.framework.TestSuite$1";
public static final String EMPTY_SUITE_WARNING = "warning";
private String myCurrentSuiteName;
private String myCurrentClassName;
private String myParamName;
private List myStartedSuites = new ArrayList();
private Map myParents = new HashMap();
private final PrintStream myPrintStream;
private String myRootName;
private PrintStream myPrintStream = System.out;
private final Map myParents = new HashMap();
private final Map mySuites = new HashMap();
public JUnit4TestListener() {
myPrintStream = System.out;
}
public SMTestSender() {}
public SMTestSender(PrintStream printStream) {
public JUnit4TestListener(PrintStream printStream) {
myPrintStream = printStream;
}
@@ -62,112 +62,90 @@ public class SMTestSender extends RunListener {
public void testRunStarted(Description description) throws Exception {
myPrintStream.println("##teamcity[enteredTheMatrix]");
if (myCurrentClassName != null && !myCurrentClassName.startsWith("[")) {
int lastPointIdx = myCurrentClassName.lastIndexOf('.');
String name = myCurrentClassName;
if (myRootName != null && !myRootName.startsWith("[")) {
int lastPointIdx = myRootName.lastIndexOf('.');
String name = myRootName;
String comment = null;
if (lastPointIdx >= 0) {
name = myCurrentClassName.substring(lastPointIdx + 1);
comment = myCurrentClassName.substring(0, lastPointIdx);
name = myRootName.substring(lastPointIdx + 1);
comment = myRootName.substring(0, lastPointIdx);
}
myPrintStream.println("##teamcity[rootName name = \'" + escapeName(name) +
(comment != null ? ("\' comment = \'" + escapeName(comment)) : "") + "\'" +
" location = \'java:suite://" + escapeName(myCurrentClassName) +
" location = \'java:suite://" + escapeName(myRootName) +
"\']");
myCurrentClassName = getShortName(myCurrentClassName);
myRootName = getShortName(myRootName);
}
}
public void testRunFinished(Result result) throws Exception {
if (myParamName != null) {
myPrintStream.println("##teamcity[testSuiteFinished name=\'" + escapeName(myParamName) + "\']");
}
if (myCurrentClassName != null) {
myPrintStream.println("##teamcity[testSuiteFinished name=\'" + escapeName(myCurrentClassName) + "\']");
}
if (myCurrentSuiteName != null) {
myPrintStream.println("##teamcity[testSuiteFinished name=\'" + escapeName(getShortName(myCurrentSuiteName)) + "\']");
for (int i = myStartedSuites.size() - 1; i>= 0; i--) {
Object parent = myStartedSuites.get(i);
myPrintStream.println("##teamcity[testSuiteFinished name=\'" + escapeName((String)parent) + "\']");
}
myStartedSuites.clear();
}
public void testStarted(Description description) throws Exception {
final String methodName = JUnit4ReflectionUtil.getMethodName(description);
final String classFQN = JUnit4ReflectionUtil.getClassName(description);
final int paramStart = methodName.indexOf('[');
if (myParamName != null){
myPrintStream.println("##teamcity[testSuiteFinished name=\'" + escapeName(myParamName) + "\']");
myParamName = null;
}
final List suites = (List)myParents.get(description);
if (suites != null && !suites.isEmpty()) {
String currentSuite = (String)suites.get(0);
List descriptors = (List)mySuites.get(currentSuite);
final List parents = (List)myParents.get(description);
if (parents != null) {
if (descriptors.isEmpty()) {
currentSuite = (String)suites.get(1);
descriptors = (List)mySuites.get(currentSuite);
List parentsHierarchy = (List)parents.remove(0);
int idx = 0;
String currentClass;
String currentParent;
while (idx < myStartedSuites.size() && idx < parentsHierarchy.size()) {
currentClass = (String)myStartedSuites.get(idx);
currentParent = getShortName(JUnit4ReflectionUtil.getClassName((Description)parentsHierarchy.get(parentsHierarchy.size() - 1 - idx)));
if (!currentClass.equals(currentParent)) break;
idx++;
}
if (!currentSuite.equals(myCurrentSuiteName)) {
finishCurrentSuite();
myCurrentSuiteName = currentSuite;
myPrintStream.println("##teamcity[testSuiteStarted name =\'" + escapeName(getShortName(myCurrentSuiteName)) + "\']");
for (int i = myStartedSuites.size() - 1; i >= idx; i--) {
currentClass = (String)myStartedSuites.remove(i);
myPrintStream.println("##teamcity[testSuiteFinished name=\'" + escapeName(currentClass) + "\']");
}
descriptors.remove(description);
}
else if (myCurrentSuiteName != null){
finishCurrentSuite();
myCurrentSuiteName = null;
}
String className = getShortName(classFQN);
if (!myEmptyTests.isEmpty() && isWarning(methodName, classFQN)) {
className = (String)myEmptyTests.remove(0);
}
if (!className.equals(myCurrentClassName)) {
if (myCurrentClassName != null) {
myPrintStream.println("##teamcity[testSuiteFinished name=\'" + escapeName(myCurrentClassName) + "\']");
}
myCurrentClassName = className;
myPrintStream.println("##teamcity[testSuiteStarted name =\'" + escapeName(myCurrentClassName) + "\']");
}
if (paramStart > -1) {
final String paramName = methodName.substring(paramStart, methodName.length());
if (!paramName.equals(myParamName)) {
myParamName = paramName;
myPrintStream.println("##teamcity[testSuiteStarted name =\'" + escapeName(myParamName) + "\']");
for (int i = idx; i < parentsHierarchy.size(); i++) {
Description parent = (Description)parentsHierarchy.get(parentsHierarchy.size() - 1 - i);
final String className = getShortName(JUnit4ReflectionUtil.getClassName(parent));
if (!className.equals(myRootName)) {
myPrintStream.println("##teamcity[testSuiteStarted name=\'" + escapeName(className) + "\']");
myStartedSuites.add(className);
}
}
}
myPrintStream.println("##teamcity[testStarted name=\'" + escapeName(methodName) + "\' " +
getTestMethodLocation(methodName, classFQN) + "]");
}
private void finishCurrentSuite() {
if (myCurrentClassName != null) {
myPrintStream.println("##teamcity[testSuiteFinished name=\'" + escapeName(myCurrentClassName) + "\']");
myCurrentClassName = null;
}
if (myCurrentSuiteName != null) {
myPrintStream.println("##teamcity[testSuiteFinished name=\'" + escapeName(getShortName(myCurrentSuiteName)) + "\']");
}
}
public void testFinished(Description description) throws Exception {
myPrintStream.println("\n##teamcity[testFinished name=\'" + escapeName(JUnit4ReflectionUtil.getMethodName(description)) + "\']");
}
public void testFailure(Failure failure) throws Exception {
final String failureMessage = failure.getMessage();
final String trace = failure.getTrace();
final Map attrs = new HashMap();
attrs.put("name", JUnit4ReflectionUtil.getMethodName(failure.getDescription()));
final ComparisonFailureData notification = createExceptionNotification(failure.getException());
ComparisonFailureData.registerSMAttributes(notification, trace, failureMessage, attrs);
myPrintStream.println(ServiceMessage.asString(ServiceMessageTypes.TEST_FAILED, attrs));
try {
final String trace = failure.getTrace();
final ComparisonFailureData notification = createExceptionNotification(failure.getException());
ComparisonFailureData.registerSMAttributes(notification, trace, failure.getMessage(), attrs);
}
catch (Throwable e) {
final StringWriter stringWriter = new StringWriter();
final PrintWriter writer = new PrintWriter(stringWriter);
e.printStackTrace(writer);
ComparisonFailureData.registerSMAttributes(null, stringWriter.toString(), e.getMessage(), attrs);
}
finally {
myPrintStream.println(ServiceMessage.asString(ServiceMessageTypes.TEST_FAILED, attrs));
}
}
public void testAssumptionFailure(Failure failure) {
@@ -249,39 +227,29 @@ public class SMTestSender extends RunListener {
return messageLength < threshold;
}
private final List myEmptyTests = new ArrayList();
private void sendTree(Description description, Description parent, Description suiteParent) {
private void sendTree(Description description, Description parent, List currentParents) {
List pParents = new ArrayList(3);
pParents.addAll(currentParents);
if (parent != null && !myRootName.equals(JUnit4ReflectionUtil.getClassName(parent))) {
pParents.add(0, parent);
}
String className = JUnit4ReflectionUtil.getClassName(description);
if (description.getChildren().isEmpty()) {
final String methodName = JUnit4ReflectionUtil.getMethodName((Description)description);
if (methodName != null) {
if (isWarning(methodName, className)) {
className = JUnit4ReflectionUtil.getClassName(parent);
myEmptyTests.add(getShortName(className));
}
myPrintStream.println("##teamcity[suiteTreeNode name=\'" + escapeName(methodName) + "\' " + getTestMethodLocation(methodName, className) + "]");
}
if (suiteParent != null ) {
final String parentFQName = JUnit4ReflectionUtil.getClassName(suiteParent);
if (!myCurrentClassName.equals(parentFQName)) {
if (parent != null) {
List parents = (List)myParents.get(description);
if (parents == null) {
parents = new ArrayList();
parents = new ArrayList(1);
myParents.put(description, parents);
}
if (!parents.contains(parentFQName)) {
parents.add(parentFQName);
}
List descriptors = (List)mySuites.get(parentFQName);
if (descriptors == null) {
descriptors = new ArrayList();
mySuites.put(parentFQName, descriptors);
}
descriptors.add(description);
parents.add(pParents);
}
if (isWarning(methodName, className)) {
className = JUnit4ReflectionUtil.getClassName(parent);
}
myPrintStream.println("##teamcity[suiteTreeNode name=\'" + escapeName(methodName) + "\' " + getTestMethodLocation(methodName, className) + "]");
}
return;
@@ -292,8 +260,7 @@ public class SMTestSender extends RunListener {
for (Iterator iterator = tests.iterator(); iterator.hasNext(); ) {
final Object next = iterator.next();
final Description nextDescription = (Description)next;
final List childTests = nextDescription.getChildren();
if ((myCurrentClassName == null || !myCurrentClassName.equals(className)) && !pass) {
if ((myRootName == null || !myRootName.equals(className)) && !pass) {
pass = true;
String locationHint = className;
if (isParameter((Description)description)) {
@@ -308,7 +275,7 @@ public class SMTestSender extends RunListener {
}
myPrintStream.println("##teamcity[suiteTreeStarted name=\'" + escapeName(getShortName(className)) + "\' locationHint=\'java:suite://" + escapeName(locationHint) + "\']");
}
sendTree(nextDescription, description, isParameter(description) ? null : childTests.isEmpty() && parent != null ? parent : description);
sendTree(nextDescription, description, pParents);
}
if (pass) {
myPrintStream.println("##teamcity[suiteTreeEnded name=\'" + escapeName(getShortName(JUnit4ReflectionUtil.getClassName((Description)description))) + "\']");
@@ -329,8 +296,8 @@ public class SMTestSender extends RunListener {
}
public void sendTree(Description description) {
myCurrentClassName = JUnit4ReflectionUtil.getClassName((Description)description);
sendTree(description, null, null);
myRootName = JUnit4ReflectionUtil.getClassName((Description)description);
sendTree(description, null, new ArrayList());
}
private static String getShortName(String fqName) {
@@ -29,8 +29,6 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class JUnit4TestResultsSender extends RunListener {
private static final String JUNIT_FRAMEWORK_COMPARISON_NAME = ComparisonFailure.class.getName();
@@ -108,7 +106,7 @@ public class JUnit4TestResultsSender extends RunListener {
private static PacketFactory createExceptionNotification(Throwable assertion) {
if (assertion instanceof KnownException) return ((KnownException)assertion).getPacketFactory();
final ComparisonFailureData notification = SMTestSender.createExceptionNotification(assertion);
final ComparisonFailureData notification = JUnit4TestListener.createExceptionNotification(assertion);
if (notification != null) {
return ComparisonDetailsExtractor.create(assertion, notification.getExpected(), notification.getActual());
}
@@ -120,4 +120,10 @@ public class TrelloTask extends Task {
public TaskRepository getRepository() {
return myRepository;
}
@NotNull
@Override
public String getNumber() {
return myCard.getIdShort();
}
}
@@ -36,9 +36,9 @@ import static com.intellij.tasks.trello.model.TrelloLabel.LabelColor;
@SuppressWarnings("UnusedDeclaration")
public class TrelloCard extends TrelloModel {
public static final String REQUIRED_FIELDS = "closed,desc,idMembers,idBoard,idList,labels,name,url,dateLastActivity";
public static final String REQUIRED_FIELDS = "closed,desc,idMembers,idBoard,idList,idShort,labels,name,url,dateLastActivity";
private String idBoard, idList;
private String idBoard, idList, idShort;
private List<String> idMembers;
private String name;
@SerializedName("desc")
@@ -77,6 +77,11 @@ public class TrelloCard extends TrelloModel {
return idList;
}
@NotNull
public String getIdShort() {
return idShort;
}
@NotNull
public List<String> getIdMembers() {
return idMembers;
@@ -18,12 +18,8 @@ package org.testng;
import jetbrains.buildServer.messages.serviceMessages.ServiceMessage;
import org.testng.collections.Lists;
import org.testng.xml.XmlClass;
import org.testng.xml.XmlInclude;
import org.testng.xml.XmlSuite;
import org.testng.xml.XmlTest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@@ -51,27 +47,6 @@ public class IDEARemoteTestNG extends TestNG {
int testCount= 0;
for (XmlSuite suite : suites) {
System.out.println("##teamcity[suiteTreeStarted name=\'" + suite.getName() + "\' locationHint=\'java:suite://" + suite.getName() + "\']");
final List<XmlTest> tests = suite.getTests();
for (XmlTest test : tests) {
for (XmlClass aClass : test.getXmlClasses()) {
final String shortName = IDEATestNGRemoteListener.getShortName(aClass.getName());
System.out.println("##teamcity[suiteTreeStarted name=\'" +
shortName + "\' locationHint=\'java:suite://" + aClass.getName() + "\']");
if (myParam != null) {
for (XmlInclude include : aClass.getIncludedMethods()) {
aClass.setIncludedMethods(Arrays.asList(new XmlInclude(include.getName(), Arrays.asList(Integer.parseInt(myParam)), 0)));
}
}
System.out.println("##teamcity[suiteTreeEnded name=\'" + shortName + "\']");
}
testCount += test.getClasses().size();
}
System.out.println("##teamcity[suiteTreeEnded name=\'" + suite.getName() + "\']");
}
final HashMap<String, String> map = new HashMap<String, String>();
map.put("count", String.valueOf(testCount));
System.out.println(ServiceMessage.asString("testCount", map));
+6 -2
View File
@@ -2,6 +2,7 @@ __author__ = 'traff'
import threading
import os
import tempfile
from _prof_imports import Stats, FuncStat, Function
class ProfDaemonThread(threading.Thread):
@@ -16,9 +17,12 @@ class ProfDaemonThread(threading.Thread):
def OnRun(self):
pass
def generate_snapshot_filepath(basepath):
def generate_snapshot_filepath(basepath, local_temp_dir=False):
if basepath is None:
return None
basepath = 'snapshot'
if local_temp_dir:
basepath = os.path.join(tempfile.gettempdir(), os.path.basename(basepath))
n = 0
path = basepath + '.pstat'
while os.path.exists(path):
+5 -3
View File
@@ -67,7 +67,7 @@ class Profiler(object):
def process(self, message):
if hasattr(message, 'save_snapshot'):
self.save_snapshot(message.id, generate_snapshot_filepath(message.save_snapshot.filepath) if not remote_run else None)
self.save_snapshot(message.id, generate_snapshot_filepath(message.save_snapshot.filepath, remote_run), remote_run)
else:
raise AssertionError("Unknown request %s" % dir(message))
@@ -84,7 +84,7 @@ class Profiler(object):
pydev_imports.execfile(file, globals, globals) # execute the script
self.stop_profiling()
self.save_snapshot(0, generate_snapshot_filepath(base_snapshot_path) if not remote_run else None)
self.save_snapshot(0, generate_snapshot_filepath(base_snapshot_path, remote_run), remote_run)
def start_profiling(self):
self.profiling_backend.enable()
@@ -104,11 +104,13 @@ class Profiler(object):
self.profiling_backend.dump_stats(filename)
return filename
def save_snapshot(self, id, filename):
def save_snapshot(self, id, filename, send_stat=False):
self.stop_profiling()
if filename is not None:
filename = self.dump_snapshot(filename)
print('Snapshot saved to %s' % filename)
if not send_stat:
response = ProfilerResponse(id=id, snapshot_filepath=filename)
else:
response = ProfilerResponse(id=id)
+1 -2
View File
@@ -24,8 +24,7 @@ class YappiProfile(object):
self.stats = yappi.convert2pstats(yappi.get_func_stats()).stats
def getstats(self):
if self.stats is None:
self.create_stats()
self.create_stats()
return self.stats
@@ -24,16 +24,27 @@ import com.jetbrains.python.psi.PyStringLiteralExpression;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.regex.Pattern;
/**
* @author vlan
*/
public class PyTypingAnnotationInjector extends PyInjectorBase {
public static final Pattern RE_TYPING_ANNOTATION = Pattern.compile("\\s*\\S+(\\[.*\\])?\\s*");
@Nullable
@Override
public Language getInjectedLanguage(@NotNull PsiElement context) {
if (context instanceof PyStringLiteralExpression && PsiTreeUtil.getParentOfType(context, PyAnnotation.class, true) != null) {
return PyDocstringLanguageDialect.getInstance();
if (context instanceof PyStringLiteralExpression) {
final PyStringLiteralExpression expr = (PyStringLiteralExpression)context;
if (PsiTreeUtil.getParentOfType(context, PyAnnotation.class, true) != null && isTypingAnnotation(expr.getStringValue())) {
return PyDocstringLanguageDialect.getInstance();
}
}
return null;
}
private static boolean isTypingAnnotation(@NotNull String s) {
return RE_TYPING_ANNOTATION.matcher(s).matches();
}
}
@@ -23,6 +23,7 @@ import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.ide.fileTemplates.FileTemplate;
import com.intellij.ide.fileTemplates.FileTemplateManager;
import com.intellij.ide.scratch.ScratchFileService;
import com.intellij.injected.editor.VirtualFileWindow;
import com.intellij.lang.ASTFactory;
import com.intellij.lang.ASTNode;
@@ -1803,6 +1804,16 @@ public class PyUtil {
return type == builtinCache.getObjectType() || type == builtinCache.getOldstyleClassobjType();
}
public static boolean isInScratchFile(@NotNull PsiElement element) {
final ScratchFileService service = ScratchFileService.getInstance();
final PsiFile file = element.getContainingFile();
if (file != null) {
final VirtualFile virtualFile = file.getVirtualFile();
return service != null && virtualFile != null && service.getRootType(virtualFile) != null;
}
return false;
}
/**
* This helper class allows to collect various information about AST nodes composing {@link PyStringLiteralExpression}.
*/
@@ -37,6 +37,7 @@ import com.jetbrains.python.codeInsight.userSkeletons.PyUserSkeletonsUtil;
import com.jetbrains.python.console.PydevConsoleRunner;
import com.jetbrains.python.facet.PythonPathContributingFacet;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.PyUtil;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
import com.jetbrains.python.psi.impl.PyImportResolver;
import com.jetbrains.python.sdk.PySdkUtil;
@@ -84,7 +85,7 @@ public class QualifiedNameResolverImpl implements RootVisitor, QualifiedNameReso
@Override
public QualifiedNameResolver fromElement(@NotNull PsiElement foothold) {
myContext.setFromElement(foothold);
if (PydevConsoleRunner.isInPydevConsole(foothold)) {
if (PydevConsoleRunner.isInPydevConsole(foothold) || PyUtil.isInScratchFile(foothold)) {
withAllModules();
Sdk sdk = PydevConsoleRunner.getConsoleSdk(foothold);
if (sdk != null) {
@@ -15,6 +15,15 @@
*/
package com.jetbrains.python;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiLanguageInjectionHost;
import com.intellij.testFramework.LightProjectDescriptor;
import com.jetbrains.python.documentation.PythonDocumentationProvider;
import com.jetbrains.python.fixtures.PyTestCase;
@@ -25,6 +34,8 @@ import com.jetbrains.python.psi.types.TypeEvalContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* Tests for a type system based on mypy's typing module.
*
@@ -306,6 +317,59 @@ public class PyTypingTest extends PyTestCase {
" pass\n");
}
public void testStringLiteralInjection() {
doTestInjectedText("class C:\n" +
" def foo(self, expr: '<caret>C'):\n" +
" pass\n",
"C");
}
public void testStringLiteralInjectionParameterizedType() {
doTestInjectedText("from typing import Union, List\n" +
"\n" +
"class C:\n" +
" def foo(self, expr: '<caret>Union[List[C], C]'):\n" +
" pass\n",
"Union[List[C], C]");
}
// PY-15810
public void testNoStringLiteralInjectionForNonTypingStrings() {
doTestNoInjectedText("class C:\n" +
" def foo(self, expr: '<caret>foo bar'):\n" +
" pass\n");
}
private void doTestNoInjectedText(@NotNull String text) {
myFixture.configureByText(PythonFileType.INSTANCE, text);
final InjectedLanguageManager languageManager = InjectedLanguageManager.getInstance(myFixture.getProject());
final PsiLanguageInjectionHost host = languageManager.getInjectionHost(getElementAtCaret());
assertNull(host);
}
private void doTestInjectedText(@NotNull String text, @NotNull String expected) {
myFixture.configureByText(PythonFileType.INSTANCE, text);
final InjectedLanguageManager languageManager = InjectedLanguageManager.getInstance(myFixture.getProject());
final PsiLanguageInjectionHost host = languageManager.getInjectionHost(getElementAtCaret());
assertNotNull(host);
final List<Pair<PsiElement, TextRange>> files = languageManager.getInjectedPsiFiles(host);
assertNotNull(files);
assertFalse(files.isEmpty());
final PsiElement injected = files.get(0).getFirst();
assertEquals(expected, injected.getText());
}
@NotNull
private PsiElement getElementAtCaret() {
final Editor editor = myFixture.getEditor();
final Document document = editor.getDocument();
final PsiFile file = PsiDocumentManager.getInstance(myFixture.getProject()).getPsiFile(document);
assertNotNull(file);
final PsiElement element = file.findElementAt(myFixture.getCaretOffset());
assertNotNull(element);
return element;
}
private void doTest(@NotNull String expectedType, @NotNull String text) {
myFixture.copyDirectoryToProject("typing", "");
myFixture.configureByText(PythonFileType.INSTANCE, text);