, P extends XBreakpointP
protected void updateIcon() {
final Icon icon = calculateSpecialIcon();
- myIcon = icon != null ? icon : getType().getEnabledIcon();
+ setIcon(icon != null ? icon : getType().getEnabledIcon());
}
protected void setIcon(Icon icon) {
- myIcon = icon;
+ if (!XDebuggerUtilImpl.isEmptyExpression(getConditionExpression())) {
+ LayeredIcon newIcon = new LayeredIcon(2);
+ newIcon.setIcon(icon, 0);
+ newIcon.setIcon(AllIcons.Debugger.Question_badge, 1, 10, 6);
+ myIcon = newIcon;
+ }
+ else {
+ myIcon = icon;
+ }
}
@Nullable
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java
index 0985daa20b6b..a848d77d8722 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java
@@ -293,12 +293,11 @@ public class XLineBreakpointImpl extends XBreak
@Override
protected void updateIcon() {
- final Icon icon = calculateSpecialIcon();
- if (icon != null) {
- setIcon(icon);
- return;
+ Icon icon = calculateSpecialIcon();
+ if (icon == null) {
+ icon = isTemporary() ? myType.getTemporaryIcon() : myType.getEnabledIcon();
}
- setIcon(isTemporary() ? myType.getTemporaryIcon() : myType.getEnabledIcon());
+ setIcon(icon);
}
@Override
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java
index 5b8982ea6efb..5d36ba5952f8 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java
@@ -38,6 +38,7 @@ import com.intellij.reference.SoftReference;
import com.intellij.ui.ClickListener;
import com.intellij.ui.LayeredIcon;
import com.intellij.util.ui.JBUI;
+import com.intellij.util.ui.components.BorderLayoutPanel;
import com.intellij.xdebugger.XDebuggerBundle;
import com.intellij.xdebugger.XExpression;
import com.intellij.xdebugger.XSourcePosition;
@@ -139,22 +140,33 @@ public abstract class XDebuggerEditorBase {
}
protected JPanel decorate(JComponent component, boolean multiline, boolean showEditor) {
- JPanel panel = JBUI.Panels.simplePanel();
+ BorderLayoutPanel panel = JBUI.Panels.simplePanel();
JPanel factoryPanel = JBUI.Panels.simplePanel();
factoryPanel.add(myChooseFactory, multiline ? BorderLayout.NORTH : BorderLayout.CENTER);
panel.add(factoryPanel, BorderLayout.WEST);
if (!multiline && showEditor) {
- ComponentWithBrowseButton componentWithButton =
- new ComponentWithBrowseButton<>(component, e -> showCodeFragmentEditor(component, this));
- componentWithButton.setButtonIcon(AllIcons.Actions.ShowViewer);
- componentWithButton.getButton().setDisabledIcon(IconLoader.getDisabledIcon(AllIcons.Actions.ShowViewer));
- panel.add(componentWithButton, BorderLayout.CENTER);
- } else {
- panel.add(component, BorderLayout.CENTER);
+ component = addMultilineButton(component);
}
+ panel.addToCenter(component);
+
+ return panel;
+ }
+
+ protected JPanel addMultilineButton(JComponent component) {
+ ComponentWithBrowseButton componentWithButton =
+ new ComponentWithBrowseButton<>(component, e -> showCodeFragmentEditor(component, this));
+ componentWithButton.setButtonIcon(AllIcons.Actions.ShowViewer);
+ componentWithButton.getButton().setDisabledIcon(IconLoader.getDisabledIcon(AllIcons.Actions.ShowViewer));
+ return componentWithButton;
+ }
+
+ protected JComponent addChooser(JComponent component) {
+ BorderLayoutPanel panel = JBUI.Panels.simplePanel(component);
+ panel.setBackground(component.getBackground());
+ panel.addToRight(myChooseFactory);
return panel;
}
@@ -345,7 +357,10 @@ public abstract class XDebuggerEditorBase {
protected void doOKAction() {
super.doOKAction();
baseEditor.setExpression(inputComponent.getInputEditor().getExpression());
- IdeFocusManager.findInstance().requestFocus(baseEditor.getEditorComponent(), false);
+ JComponent component = baseEditor.getPreferredFocusedComponent();
+ if (component != null) {
+ IdeFocusManager.findInstance().requestFocus(component, false);
+ }
}
@Nullable
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java
index 0bf83c4d51bd..d5069dbf36fb 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java
@@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.ui.EditorComboBoxEditor;
import com.intellij.ui.EditorComboBoxRenderer;
+import com.intellij.ui.EditorTextField;
import com.intellij.util.ui.UIUtil;
import com.intellij.xdebugger.XExpression;
import com.intellij.xdebugger.XSourcePosition;
@@ -35,6 +36,7 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
+import java.awt.event.ActionListener;
/**
* @author nik
@@ -42,7 +44,7 @@ import java.awt.*;
public class XDebuggerExpressionComboBox extends XDebuggerEditorBase {
private final JComponent myComponent;
private final ComboBox myComboBox;
- private EditorComboBoxEditor myEditor;
+ private XDebuggerComboBoxEditor myEditor;
private XExpression myExpression;
public XDebuggerExpressionComboBox(@NotNull Project project, @NotNull XDebuggerEditorsProvider debuggerEditorsProvider, @Nullable @NonNls String historyId,
@@ -56,7 +58,7 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase {
myComboBox.setMinimumSize(minimumSize);
initEditor();
fillComboBox();
- myComponent = decorate(myComboBox, false, showEditor);
+ myComponent = showEditor ? addMultilineButton(myComboBox) : myComboBox;
}
public ComboBox getComboBox() {
@@ -70,11 +72,11 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase {
@Nullable
public Editor getEditor() {
- return myEditor.getEditor();
+ return myEditor.getEditorTextField().getEditor();
}
public JComponent getEditorComponent() {
- return myEditor.getEditorComponent();
+ return myEditor.getEditorTextField();
}
public void setEnabled(boolean enable) {
@@ -92,23 +94,7 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase {
}
private void initEditor() {
- myEditor = new EditorComboBoxEditor(getProject(), getEditorsProvider().getFileType()) {
- @Override
- public void setItem(Object anObject) {
- if (anObject == null) {
- anObject = XExpressionImpl.EMPTY_EXPRESSION;
- }
- XExpression expression = (XExpression)anObject;
- getEditorComponent().setNewDocumentAndFileType(getFileType(expression), createDocument(expression));
- }
-
- @Override
- protected void onEditorCreate(EditorEx editor) {
- editor.putUserData(DebuggerCopyPastePreprocessor.REMOVE_NEWLINES_ON_PASTE, true);
- editor.getColorsScheme().setEditorFontSize(myComboBox.getFont().getSize());
- }
- };
- myEditor.getEditorComponent().setFontInheritedFromLAF(false);
+ myEditor = new XDebuggerComboBoxEditor();
myComboBox.setEditor(myEditor);
//myEditor.setItem(myExpression);
myComboBox.setRenderer(new EditorComboBoxRenderer(myEditor));
@@ -144,20 +130,76 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase {
@Override
public XExpression getExpression() {
- Object document = myEditor.getItem();
- if (document instanceof Document) { // sometimes null on Mac
- return getEditorsProvider().createExpression(getProject(), (Document)document, myExpression.getLanguage(), myExpression.getMode());
- }
- return myExpression;
+ XExpression item = myEditor.getItem();
+ return item != null ? item : myExpression;
}
@Override
public JComponent getPreferredFocusedComponent() {
- return (JComponent)myComboBox.getEditor().getEditorComponent();
+ return myEditor.getEditorTextField();
}
@Override
public void selectAll() {
myComboBox.getEditor().selectAll();
}
+
+ private class XDebuggerComboBoxEditor implements ComboBoxEditor {
+ private final JComponent myPanel;
+ private final EditorComboBoxEditor myDelegate;
+
+ public XDebuggerComboBoxEditor() {
+ myDelegate = new EditorComboBoxEditor(getProject(), getEditorsProvider().getFileType()) {
+ @Override
+ protected void onEditorCreate(EditorEx editor) {
+ editor.putUserData(DebuggerCopyPastePreprocessor.REMOVE_NEWLINES_ON_PASTE, true);
+ editor.getColorsScheme().setEditorFontSize(myComboBox.getFont().getSize());
+ }
+ };
+ myDelegate.getEditorComponent().setFontInheritedFromLAF(false);
+ myPanel = addChooser(myDelegate.getEditorComponent());
+ }
+
+ public EditorTextField getEditorTextField() {
+ return myDelegate.getEditorComponent();
+ }
+
+ @Override
+ public JComponent getEditorComponent() {
+ return myPanel;
+ }
+
+ @Override
+ public void setItem(Object anObject) {
+ if (anObject == null) {
+ anObject = XExpressionImpl.EMPTY_EXPRESSION;
+ }
+ XExpression expression = (XExpression)anObject;
+ myDelegate.getEditorComponent().setNewDocumentAndFileType(getFileType(expression), createDocument(expression));
+ }
+
+ @Override
+ public XExpression getItem() {
+ Object document = myDelegate.getItem();
+ if (document instanceof Document) { // sometimes null on Mac
+ return getEditorsProvider().createExpression(getProject(), (Document)document, myExpression.getLanguage(), myExpression.getMode());
+ }
+ return null;
+ }
+
+ @Override
+ public void selectAll() {
+ myDelegate.selectAll();
+ }
+
+ @Override
+ public void addActionListener(ActionListener l) {
+ myDelegate.addActionListener(l);
+ }
+
+ @Override
+ public void removeActionListener(ActionListener l) {
+ myDelegate.removeActionListener(l);
+ }
+ }
}
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/SetValueInplaceEditor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/SetValueInplaceEditor.java
index 038910bdeb2e..0fc445f3436e 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/SetValueInplaceEditor.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/SetValueInplaceEditor.java
@@ -20,6 +20,7 @@ import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.ui.Messages;
import com.intellij.ui.AppUIUtil;
import com.intellij.ui.SimpleColoredComponent;
+import com.intellij.util.ui.JBUI;
import com.intellij.xdebugger.frame.XValueModifier;
import com.intellij.xdebugger.frame.presentation.XValuePresentation;
import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl;
@@ -28,6 +29,7 @@ import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValuePresentationUtil;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
@@ -39,24 +41,36 @@ public class SetValueInplaceEditor extends XDebuggerTreeInplaceEditor {
private final JPanel myEditorPanel;
private final XValueModifier myModifier;
private final XValueNodeImpl myValueNode;
+ private final int myNameOffset;
private SetValueInplaceEditor(final XValueNodeImpl node, @NotNull final String nodeName) {
super(node, "setValue");
myValueNode = node;
myModifier = myValueNode.getValueContainer().getModifier();
- myEditorPanel = new JPanel();
- myEditorPanel.setLayout(new BorderLayout(0, 0));
SimpleColoredComponent nameLabel = new SimpleColoredComponent();
+ nameLabel.getIpad().right = 0;
+ nameLabel.getIpad().left = 0;
nameLabel.setIcon(myNode.getIcon());
nameLabel.append(nodeName, XDebuggerUIConstants.VALUE_NAME_ATTRIBUTES);
XValuePresentation presentation = node.getValuePresentation();
if (presentation != null) {
XValuePresentationUtil.appendSeparator(nameLabel, presentation.getSeparator());
}
- myEditorPanel.add(nameLabel, BorderLayout.WEST);
+ myNameOffset = nameLabel.getPreferredSize().width;
+ myEditorPanel = JBUI.Panels.simplePanel(myExpressionEditor.getComponent());
+ }
- myEditorPanel.add(myExpressionEditor.getComponent(), BorderLayout.CENTER);
+ @Nullable
+ @Override
+ protected Rectangle getEditorBounds() {
+ Rectangle bounds = super.getEditorBounds();
+ if (bounds == null) {
+ return null;
+ }
+ bounds.x += myNameOffset;
+ bounds.width -= myNameOffset;
+ return bounds;
}
public static void show(final XValueNodeImpl node, @NotNull final String nodeName) {
diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/TreeInplaceEditor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/TreeInplaceEditor.java
index d60f5099d46d..a1c0a881de41 100644
--- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/TreeInplaceEditor.java
+++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/TreeInplaceEditor.java
@@ -97,10 +97,8 @@ public abstract class TreeInplaceEditor implements AWTEventListener {
protected abstract Project getProject();
private static void setInplaceEditorBounds(JComponent component, int x, int y, int width, int height) {
- int preferredHeight = component.getPreferredSize().height;
- int h = Math.max(height, preferredHeight);
- int delta = Math.max(0, h - height) / 2;
- component.setBounds(x, y - delta, width, Math.max(height, preferredHeight));
+ int h = Math.max(height, component.getPreferredSize().height);
+ component.setBounds(x, y - (h - height) / 2, width, h);
}
public final void show() {
@@ -271,7 +269,7 @@ public abstract class TreeInplaceEditor implements AWTEventListener {
}
@Nullable
- private Rectangle getEditorBounds() {
+ protected Rectangle getEditorBounds() {
final JTree tree = getTree();
Rectangle bounds = tree.getVisibleRect();
Rectangle nodeBounds = tree.getPathBounds(getNodePath());
diff --git a/plugins/copyright/src/CopyrightManager.kt b/plugins/copyright/src/CopyrightManager.kt
index c3bb5db3d7ac..16e6d23ed650 100644
--- a/plugins/copyright/src/CopyrightManager.kt
+++ b/plugins/copyright/src/CopyrightManager.kt
@@ -50,7 +50,6 @@ import com.maddyhome.idea.copyright.util.FileTypeUtil
import com.maddyhome.idea.copyright.util.NewFileTracker
import org.jdom.Element
import java.util.*
-import java.util.concurrent.atomic.AtomicReference
import java.util.function.Function
private const val DEFAULT = "default"
@@ -90,8 +89,9 @@ class CopyrightManager(private val project: Project, schemeManagerFactory: Schem
val schemeManager = schemeManagerFactory.create("copyright", object : LazySchemeProcessor, SchemeWrapper>() {
override fun createScheme(dataHolder: SchemeDataHolder>,
name: String,
- attributeProvider: Function): SchemeWrapper {
- return LazySchemeWrapper(name, dataHolder, schemeWriter)
+ attributeProvider: Function,
+ isBundled: Boolean): SchemeWrapper {
+ return CopyrightLazySchemeWrapper(name, dataHolder, schemeWriter)
}
override fun getState(scheme: SchemeWrapper) = scheme.schemeState
@@ -253,12 +253,10 @@ private fun wrapScheme(element: Element): Element {
return wrapper
}
-private class LazySchemeWrapper(name: String,
- dataHolder: SchemeDataHolder>,
- private val writer: (scheme: CopyrightProfile) -> Element,
- private val subStateTagName: String = "copyright") : SchemeWrapper(name) {
- private val dataHolder = AtomicReference(dataHolder)
-
+private class CopyrightLazySchemeWrapper(name: String,
+ dataHolder: SchemeDataHolder>,
+ writer: (scheme: CopyrightProfile) -> Element,
+ private val subStateTagName: String = "copyright") : LazySchemeWrapper(name, dataHolder, writer) {
override val lazyScheme = lazy {
val scheme = CopyrightProfile()
@Suppress("NAME_SHADOWING")
@@ -272,9 +270,4 @@ private class LazySchemeWrapper(name: String,
dataHolder.updateDigest(writer(scheme))
scheme
}
-
- override fun writeScheme(): Element {
- val dataHolder = dataHolder.get()
- return if (dataHolder == null) writer(scheme) else dataHolder.read()
- }
}
\ No newline at end of file
diff --git a/plugins/junit/test/com/intellij/execution/junit/JUnitRerunFailedTestsTest.java b/plugins/junit/test/com/intellij/execution/junit/JUnitRerunFailedTestsTest.java
index 60470ab6c0b3..98a8f3bd5c65 100644
--- a/plugins/junit/test/com/intellij/execution/junit/JUnitRerunFailedTestsTest.java
+++ b/plugins/junit/test/com/intellij/execution/junit/JUnitRerunFailedTestsTest.java
@@ -150,4 +150,20 @@ public class JUnitRerunFailedTestsTest extends LightCodeInsightFixtureTestCase
String name = ((PsiMethod)element).getName();
assertEquals("testFoo", name);
}
+
+ public void testLocatorForIgnoredClass() throws Exception {
+ PsiClass aClass = myFixture.addClass("@org.junit.Ignore" +
+ "public class TestClass {\n" +
+ " @org.junit.Test" +
+ " public void testFoo() throws Exception {}\n" +
+ "}");
+ final SMTestProxy testProxy = new SMTestProxy("TestClass", false, "java:test://TestClass.TestClass");
+ 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();
+ assertEquals(aClass, element);
+ }
}
diff --git a/plugins/junit_rt/src/com/intellij/junit4/JUnit4TestRunnerUtil.java b/plugins/junit_rt/src/com/intellij/junit4/JUnit4TestRunnerUtil.java
index 9b951b5a85a5..9f236746edc8 100644
--- a/plugins/junit_rt/src/com/intellij/junit4/JUnit4TestRunnerUtil.java
+++ b/plugins/junit_rt/src/com/intellij/junit4/JUnit4TestRunnerUtil.java
@@ -17,15 +17,16 @@ package com.intellij.junit4;
import com.intellij.junit3.TestRunnerUtil;
import org.junit.Ignore;
-import org.junit.internal.AssumptionViolatedException;
+import org.junit.internal.builders.AllDefaultPossibilitiesBuilder;
+import org.junit.internal.builders.AnnotatedBuilder;
+import org.junit.internal.builders.IgnoredBuilder;
+import org.junit.internal.builders.JUnit4Builder;
import org.junit.internal.requests.ClassRequest;
-import org.junit.internal.runners.model.EachTestNotifier;
import org.junit.runner.Description;
import org.junit.runner.Request;
import org.junit.runner.RunWith;
import org.junit.runner.Runner;
import org.junit.runner.manipulation.Filter;
-import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.Parameterized;
import org.junit.runners.model.FrameworkMethod;
@@ -284,12 +285,31 @@ public class JUnit4TestRunnerUtil {
return new ClassRequest(clazz) {
public Runner getRunner() {
try {
- return new IgnoreIgnoredTestJUnit4ClassRunner(clazz, recursively);
+ return new AllDefaultPossibilitiesBuilder(true) {
+ protected IgnoredBuilder ignoredBuilder() {
+ return new IgnoredBuilder() {
+ public Runner runnerForClass(Class testClass) {
+ return null;
+ }
+ };
+ }
+
+ protected JUnit4Builder junit4Builder() {
+ return new JUnit4Builder() {
+ public Runner runnerForClass(Class testClass) throws Throwable {
+ return new BlockJUnit4ClassRunner(testClass) {
+ protected boolean isIgnored(FrameworkMethod child) {
+ return false;
+ }
+ };
+ }
+ };
+ }
+ }.runnerForClass(clazz);
}
- catch (Exception ignored) {
- //return super runner
+ catch (Throwable throwable) {
+ return super.getRunner();
}
- return super.getRunner();
}
};
}
@@ -343,36 +363,4 @@ public class JUnit4TestRunnerUtil {
public static String testsFoundInPackageMesage(int testCount, String name) {
return MessageFormat.format(ourBundle.getString("tests.found.in.package"), new Object[]{new Integer(testCount), name});
}
-
-
- private static class IgnoreIgnoredTestJUnit4ClassRunner extends BlockJUnit4ClassRunner {
- private final boolean myRecursively;
-
- public IgnoreIgnoredTestJUnit4ClassRunner(Class clazz, boolean recursively) throws Exception {
- super(clazz);
- myRecursively = recursively;
- }
-
- protected void runChild(FrameworkMethod method, RunNotifier notifier) {
- if (!myRecursively){
- super.runChild(method, notifier);
- return;
- }
- final Description description = describeChild(method);
- final EachTestNotifier eachNotifier = new EachTestNotifier(notifier, description);
- eachNotifier.fireTestStarted();
- try {
- methodBlock(method).evaluate();
- }
- catch (AssumptionViolatedException e) {
- eachNotifier.addFailedAssumption(e);
- }
- catch (Throwable e) {
- eachNotifier.addFailure(e);
- }
- finally {
- eachNotifier.fireTestFinished();
- }
- }
- }
}
diff --git a/python/helpers/pydev/_pydev_bundle/_pydev_completer.py b/python/helpers/pydev/_pydev_bundle/_pydev_completer.py
index 380cd3aeef49..d1c10b5ecb8f 100644
--- a/python/helpers/pydev/_pydev_bundle/_pydev_completer.py
+++ b/python/helpers/pydev/_pydev_bundle/_pydev_completer.py
@@ -20,7 +20,7 @@ except ImportError:
IS_JYTHON = False
from _pydev_bundle import _pydev_imports_tipper
-from _pydevd_bundle import pydevd_vars
+from _pydevd_bundle import pydevd_xml
dir2 = _pydev_imports_tipper.generate_imports_tip_for_module
@@ -176,8 +176,8 @@ def generate_completions_as_xml(frame, act_tok):
#list(tuple(name, descr, parameters, type))
completions = completer.complete(act_tok)
- valid_xml = pydevd_vars.make_valid_xml_value
- quote = pydevd_vars.quote
+ valid_xml = pydevd_xml.make_valid_xml_value
+ quote = pydevd_xml.quote
msg = [""]
diff --git a/python/helpers/pydev/tests_pydevd_python/test_pydev_monkey.py b/python/helpers/pydev/tests_pydevd_python/test_pydev_monkey.py
index 27fa4f6b8e5d..67859a226e7a 100644
--- a/python/helpers/pydev/tests_pydevd_python/test_pydev_monkey.py
+++ b/python/helpers/pydev/tests_pydevd_python/test_pydev_monkey.py
@@ -25,6 +25,7 @@ class TestCase(unittest.TestCase):
'sys.path.append(r\'%s\'); '
'import pydevd; pydevd.settrace(host=\'127.0.0.1\', port=0, suspend=False, '
'trace_only_current_thread=False, patch_multiprocessing=True); '
+ 'sys.original_argv = []; '
'connect("127.0.0.1")' % pydev_src_dir,
pydev_monkey.patch_arg_str_win(check)
)
@@ -48,6 +49,7 @@ class TestCase(unittest.TestCase):
(
'import sys; sys.path.append(r\'%s\'); import pydevd; '
'pydevd.settrace(host=\'127.0.0.1\', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True); '
+ 'sys.original_argv = []; '
'connect(\\"127.0.0.1\\")'
) % pydev_src_dir
])
diff --git a/update-server-mock/.editorconfig b/update-server-mock/.editorconfig
new file mode 100644
index 000000000000..e3207ea27130
--- /dev/null
+++ b/update-server-mock/.editorconfig
@@ -0,0 +1,5 @@
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
\ No newline at end of file
diff --git a/update-server-mock/.gitignore b/update-server-mock/.gitignore
new file mode 100644
index 000000000000..0c426e5cfcc5
--- /dev/null
+++ b/update-server-mock/.gitignore
@@ -0,0 +1,3 @@
+/.gradle/
+/build/
+/.idea/
\ No newline at end of file
diff --git a/update-server-mock/build.gradle b/update-server-mock/build.gradle
new file mode 100644
index 000000000000..4a292c2bd602
--- /dev/null
+++ b/update-server-mock/build.gradle
@@ -0,0 +1,26 @@
+buildscript {
+ repositories { jcenter() }
+ dependencies {
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:+"
+ }
+}
+
+apply plugin: 'kotlin'
+
+repositories { jcenter() }
+dependencies {
+ compile "org.jetbrains.kotlin:kotlin-stdlib:1.0.+"
+ compile "org.apache.logging.log4j:log4j-api:2.+"
+ compile "org.apache.logging.log4j:log4j-core:2.+"
+ testCompile "junit:junit:4.+"
+ testCompile "org.assertj:assertj-core:3.+"
+}
+
+jar {
+ manifest {
+ attributes "Main-Class" : "com.intellij.updater.mock.MainKt"
+ }
+ from {
+ configurations.compile.collect { it.isDirectory() ? it : zipTree(it) }
+ }
+}
\ No newline at end of file
diff --git a/update-server-mock/lib/log4j-api-2.6.2.jar b/update-server-mock/lib/log4j-api-2.6.2.jar
new file mode 100644
index 000000000000..a40cc563e971
Binary files /dev/null and b/update-server-mock/lib/log4j-api-2.6.2.jar differ
diff --git a/update-server-mock/lib/log4j-core-2.6.2.jar b/update-server-mock/lib/log4j-core-2.6.2.jar
new file mode 100644
index 000000000000..388918f6c798
Binary files /dev/null and b/update-server-mock/lib/log4j-core-2.6.2.jar differ
diff --git a/update-server-mock/log4j.xml b/update-server-mock/log4j.xml
new file mode 100644
index 000000000000..2e4483adb2f7
--- /dev/null
+++ b/update-server-mock/log4j.xml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/update-server-mock/settings.gradle b/update-server-mock/settings.gradle
new file mode 100644
index 000000000000..2bb21458e51a
--- /dev/null
+++ b/update-server-mock/settings.gradle
@@ -0,0 +1 @@
+rootProject.name = 'update-server-mock'
\ No newline at end of file
diff --git a/update-server-mock/src/main/java/com/intellij/updater/mock/Generator.kt b/update-server-mock/src/main/java/com/intellij/updater/mock/Generator.kt
new file mode 100644
index 000000000000..c019c184377e
--- /dev/null
+++ b/update-server-mock/src/main/java/com/intellij/updater/mock/Generator.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2016 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.updater.mock
+
+class Generator {
+ private val patch = this.javaClass.classLoader.getResourceAsStream("patch/patch.jar").use { it.readBytes() }
+
+ fun generateXml(productCode: String, buildId: String, eap: Boolean): String {
+ val status = if (eap) "eap" else "release"
+ return """
+
+
+
+ $productCode
+
+
+
+
+
+
+
+
+ """.trimIndent()
+ }
+
+ fun generatePatch(): ByteArray = patch
+}
\ No newline at end of file
diff --git a/update-server-mock/src/main/java/com/intellij/updater/mock/Server.kt b/update-server-mock/src/main/java/com/intellij/updater/mock/Server.kt
new file mode 100644
index 000000000000..d2b0c1cfb236
--- /dev/null
+++ b/update-server-mock/src/main/java/com/intellij/updater/mock/Server.kt
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2016 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.updater.mock
+
+import com.sun.net.httpserver.HttpServer
+import org.apache.logging.log4j.LogManager
+import java.net.HttpURLConnection.*
+import java.net.InetSocketAddress
+import java.net.URI
+import java.time.ZonedDateTime
+import java.time.format.DateTimeFormatter
+
+class Server(private val port: Int, private val generator: Generator) {
+ private val server = HttpServer.create()
+ private val log = LogManager.getLogger(Server::class.java)
+ private val buildFormat = "([A-Z]+)-([0-9.]+)".toRegex()
+ private val tsFormat = DateTimeFormatter.ofPattern("dd/MMM/yyyy:kk:mm:ss ZZ")
+
+ fun start() {
+ server.bind(InetSocketAddress("localhost", port), 0)
+
+ server.createContext("/") { ex ->
+ val response = try {
+ process(ex.requestMethod, ex.requestURI)
+ }
+ catch(e: Exception) {
+ log.error(e)
+ Response(HTTP_INTERNAL_ERROR, "Internal error")
+ }
+
+ try {
+ val contentType = if (response.type.startsWith("text/")) "${response.type}; charset=utf-8" else response.type
+ ex.responseHeaders.add("Content-Type", contentType)
+ ex.sendResponseHeaders(response.code, response.bytes.size.toLong())
+ ex.responseBody.write(response.bytes)
+ ex.close()
+
+ log.info("${ex.remoteAddress.address.hostAddress} - - [${tsFormat.format(ZonedDateTime.now())}]" +
+ " \"${ex.requestMethod} ${ex.requestURI}\" ${ex.responseCode} ${response.bytes.size}")
+ }
+ catch(e: Exception) {
+ log.error(e)
+ }
+ }
+
+ server.start()
+ }
+
+ private fun process(method: String, uri: URI): Response {
+ val path = uri.path
+ return when {
+ method != "GET" -> Response(HTTP_BAD_REQUEST, "Didn't get")
+ path == "/" -> Response(HTTP_OK, "Mock Update Server")
+ path == "/updates/updates.xml" -> xml(uri.query ?: "")
+ path.startsWith("/patches/") -> patch(path)
+ else -> Response(HTTP_NOT_FOUND, "Miss")
+ }
+ }
+
+ private fun xml(query: String): Response {
+ val parameters = query.splitToSequence('&')
+ .filter { it.startsWith("build") || it.startsWith("eap") }
+ .map { it.split('=', limit = 2) }
+ .map { it[0] to if (it.size > 1) it[1] else "" }
+ .toMap()
+
+ val build = parameters["build"]
+ if (build != null) {
+ val match = buildFormat.find(build)
+ val productCode = match?.groups?.get(1)?.value
+ val buildId = match?.groups?.get(2)?.value
+ if (productCode != null && buildId != null) {
+ val xml = generator.generateXml(productCode, buildId, "eap" in parameters)
+ return Response(HTTP_OK, "text/xml", xml.toByteArray())
+ }
+ }
+
+ return Response(HTTP_BAD_REQUEST, "Bad parameters")
+ }
+
+ private fun patch(path: String): Response = when {
+ path.endsWith(".jar") -> Response(HTTP_OK, "binary/octet-stream", generator.generatePatch())
+ else -> Response(HTTP_BAD_REQUEST, "Bad path")
+ }
+
+ private class Response(val code: Int, val type: String, val bytes: ByteArray) {
+ constructor(code: Int, text: String) : this(code, "text/plain", text.toByteArray())
+ }
+}
\ No newline at end of file
diff --git a/update-server-mock/src/main/java/com/intellij/updater/mock/main.kt b/update-server-mock/src/main/java/com/intellij/updater/mock/main.kt
new file mode 100644
index 000000000000..a2cc4997ebbe
--- /dev/null
+++ b/update-server-mock/src/main/java/com/intellij/updater/mock/main.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2016 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.updater.mock
+
+import org.apache.logging.log4j.LogManager
+
+fun main(args: Array) {
+ if (args.size != 1) {
+ println("usage: java -jar update-server-mock.jar ")
+ System.exit(1)
+ }
+
+ val log = LogManager.getLogger(Server::class.java)
+ val port = args[0]
+ try {
+ log.info("starting the server on port '$port' ...")
+ val generator = Generator()
+ Server(port.toInt(), generator).start()
+ log.info("ready")
+ }
+ catch(e: Exception) {
+ log.error("failed to start the server", e)
+ System.exit(2)
+ }
+}
\ No newline at end of file
diff --git a/update-server-mock/src/main/resources/patch/patch.jar b/update-server-mock/src/main/resources/patch/patch.jar
new file mode 100644
index 000000000000..24f84df89007
Binary files /dev/null and b/update-server-mock/src/main/resources/patch/patch.jar differ
diff --git a/update-server-mock/src/test/java/com/intellij/updater/mock/GeneratorTest.kt b/update-server-mock/src/test/java/com/intellij/updater/mock/GeneratorTest.kt
new file mode 100644
index 000000000000..9446d181aafd
--- /dev/null
+++ b/update-server-mock/src/test/java/com/intellij/updater/mock/GeneratorTest.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2016 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.updater.mock
+
+import org.assertj.core.api.Assertions.assertThat
+import org.junit.Test
+
+class GeneratorTest {
+ @Test fun generateXml() {
+ val xml = Generator().generateXml("IC", "163.11.22", false)
+ assertThat(xml).contains("patch from=\"163.11.22\"").contains("status=\"release\"")
+ }
+
+ @Test fun generatePatch() {
+ val patch = Generator().generatePatch()
+ assertThat(patch).isNotEmpty()
+ }
+}
\ No newline at end of file
diff --git a/update-server-mock/update-server-mock.iml b/update-server-mock/update-server-mock.iml
new file mode 100644
index 000000000000..8c3258ed7d92
--- /dev/null
+++ b/update-server-mock/update-server-mock.iml
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file