diff --git a/python/src/META-INF/python-plugin-common.xml b/python/src/META-INF/python-plugin-common.xml index de9a60e03b8e..9a05e17ea07a 100644 --- a/python/src/META-INF/python-plugin-common.xml +++ b/python/src/META-INF/python-plugin-common.xml @@ -360,6 +360,8 @@ implementationClass="com.jetbrains.python.buildout.config.BuildoutCfgHighlighterFactory"/> + diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/PyDictLiteralFormToConstructorIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/PyDictLiteralFormToConstructorIntention.java index 2937526ae471..b34b8aa87fb5 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/PyDictLiteralFormToConstructorIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/PyDictLiteralFormToConstructorIntention.java @@ -37,12 +37,22 @@ public class PyDictLiteralFormToConstructorIntention extends BaseIntentionAction if (dictExpression != null) { PyKeyValueExpression[] elements = dictExpression.getElements(); + boolean canConvert = true; if (elements.length != 0) { for (PyKeyValueExpression element : elements) { - if (! (element.getKey() instanceof PyStringLiteralExpression)) return false; + PyExpression key = element.getKey(); + if (! (key instanceof PyStringLiteralExpression)) canConvert = false; + String str = ((PyStringLiteralExpression)key).getStringValue(); + if(Character.isDigit(str.charAt(0))) canConvert = false; + try { + Integer.parseInt(str) ; + canConvert = false; + } catch (NumberFormatException e) { + // pass + } } } - return true; + if (canConvert) return true; } return false; } diff --git a/python/src/com/jetbrains/python/testing/PythonTestConfigurationsModel.java b/python/src/com/jetbrains/python/testing/PythonTestConfigurationsModel.java index c0759397658f..d0552c0d3758 100644 --- a/python/src/com/jetbrains/python/testing/PythonTestConfigurationsModel.java +++ b/python/src/com/jetbrains/python/testing/PythonTestConfigurationsModel.java @@ -16,87 +16,36 @@ package com.jetbrains.python.testing; +import com.intellij.openapi.project.Project; +import com.intellij.ui.CollectionComboBoxModel; import com.jetbrains.python.PyBundle; -import javax.swing.*; -import javax.swing.event.ListDataListener; -import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; /** * User: catherine */ -public class PythonTestConfigurationsModel implements ComboBoxModel { + +public class PythonTestConfigurationsModel extends CollectionComboBoxModel { public static final String PYTHONS_UNITTEST_NAME = PyBundle.message("runcfg.unittest.display_name"); public static final String PYTHONS_NOSETEST_NAME = PyBundle.message("runcfg.nosetests.display_name"); public static final String PY_TEST_NAME = PyBundle.message("runcfg.pytest.display_name"); - private static final PythonTestConfigurationsModel INSTANCE = new PythonTestConfigurationsModel(); - private final List myConfigurationTypes = new ArrayList(); - private Set myListDataListeners = new HashSet(); - - private String myDefault; private String myProjectConfiguration; - private String myGlobalSelected; + private Project myProject; - private PythonTestConfigurationsModel() { - myDefault = PYTHONS_UNITTEST_NAME; - myProjectConfiguration = PYTHONS_UNITTEST_NAME; - myGlobalSelected = myDefault; + public PythonTestConfigurationsModel(final List items, final Object selection, Project project) { + super(items, selection); + myProject = project; + myProjectConfiguration = TestRunnerService.getInstance(myProject).getProjectConfiguration(); } - - public void addConfiguration(final String newConfiguration, boolean changeSelection) { - myConfigurationTypes.add(newConfiguration); - if (changeSelection) { - setSelectedItem(newConfiguration); - } - } - public void reset() { - myDefault = myProjectConfiguration; setSelectedItem(myProjectConfiguration); } public void apply() { - myProjectConfiguration = myGlobalSelected; - } - - @Override - public void setSelectedItem(Object o) { - if (myGlobalSelected != o) { - myGlobalSelected = (String)o; - } - } - - @Override - public Object getSelectedItem() { - return myGlobalSelected; - } - - @Override - public int getSize() { - return myConfigurationTypes.size(); - } - - @Override - public Object getElementAt(int i) { - return myConfigurationTypes.get(i); - } - - @Override - public void addListDataListener(ListDataListener listDataListener) { - myListDataListeners.add(listDataListener); - } - - @Override - public void removeListDataListener(ListDataListener listDataListener) { - myListDataListeners.remove(listDataListener); - } - - public static PythonTestConfigurationsModel getInstance() { - return INSTANCE; + myProjectConfiguration = (String)getSelectedItem(); + TestRunnerService.getInstance(myProject).setProjectConfiguration(myProjectConfiguration); } public Object getProjectConfiguration() { diff --git a/python/src/com/jetbrains/python/testing/PythonUnitTestConfigurationProducer.java b/python/src/com/jetbrains/python/testing/PythonUnitTestConfigurationProducer.java index 472239c99856..53e0ac215fea 100644 --- a/python/src/com/jetbrains/python/testing/PythonUnitTestConfigurationProducer.java +++ b/python/src/com/jetbrains/python/testing/PythonUnitTestConfigurationProducer.java @@ -12,7 +12,6 @@ import com.intellij.execution.configurations.ConfigurationTypeUtil; import com.intellij.execution.junit.RuntimeConfigurationProducer; import com.intellij.facet.Facet; import com.intellij.facet.FacetManager; -import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -29,7 +28,6 @@ import java.util.List; public class PythonUnitTestConfigurationProducer extends RuntimeConfigurationProducer { private PsiElement myPsiElement; - private boolean isActive = true; public PythonUnitTestConfigurationProducer() { super(ConfigurationTypeUtil.findConfigurationType(PythonUnitTestConfigurationType.class)); @@ -42,17 +40,19 @@ public class PythonUnitTestConfigurationProducer extends RuntimeConfigurationPro @Override protected RunnerAndConfigurationSettings createConfigurationByElement(Location location, ConfigurationContext context) { - if (!isActive) return null; + PsiElement element = location.getPsiElement(); + if (! (TestRunnerService.getInstance(element.getProject()).getProjectConfiguration().equals( + PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME))) return null; RunnerAndConfigurationSettings settings; + /*Module module = location.getModule(); - Module module = location.getModule(); if (module != null) { for (RunnableUnitTestFilter f : Extensions.getExtensions(RunnableUnitTestFilter.EP_NAME)) { if (f.isRunnableUnitTest(location.getPsiElement().getContainingFile(), module)) { return null; } } - } + }*/ if (PythonUnitTestRunnableScriptFilter.isIfNameMain(location)) { return null; @@ -215,9 +215,6 @@ public class PythonUnitTestConfigurationProducer extends RuntimeConfigurationPro } return null; } - public void setActive(boolean active) { - isActive = active; - } public int compareTo(Object o) { return PREFERED; diff --git a/python/src/com/jetbrains/python/testing/PythonUnitTestConfigurationType.java b/python/src/com/jetbrains/python/testing/PythonUnitTestConfigurationType.java index ce7785e7e4c6..b817dc0885d8 100644 --- a/python/src/com/jetbrains/python/testing/PythonUnitTestConfigurationType.java +++ b/python/src/com/jetbrains/python/testing/PythonUnitTestConfigurationType.java @@ -27,13 +27,11 @@ public class PythonUnitTestConfigurationType extends ConfigurationTypeBase { private final static Icon ICON = IconLoader.getIcon("/com/jetbrains/python/icons/python.png"); private static class PythonUnitTestConfigurationFactory extends ConfigurationFactory { - final private PythonTestConfigurationsModel myModel = PythonTestConfigurationsModel.getInstance(); protected PythonUnitTestConfigurationFactory(ConfigurationType configurationType) { super(configurationType); } public RunConfiguration createTemplateConfiguration(Project project) { - myModel.addConfiguration(PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME, false); return new PythonUnitTestRunConfiguration(new RunConfigurationModule(project), this, ""); } } diff --git a/python/src/com/jetbrains/python/testing/TestRunnerConfigurable.java b/python/src/com/jetbrains/python/testing/TestRunnerConfigurable.java index f5b71b11e91e..4887637350e4 100644 --- a/python/src/com/jetbrains/python/testing/TestRunnerConfigurable.java +++ b/python/src/com/jetbrains/python/testing/TestRunnerConfigurable.java @@ -3,13 +3,11 @@ package com.jetbrains.python.testing; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.options.NonDefaultProjectConfigurable; -import com.jetbrains.python.testing.nosetest.PythonNoseTestConfigurationProducer; -import com.jetbrains.python.testing.pytest.PyTestConfigurationProducer; +import com.intellij.openapi.project.Project; import org.jetbrains.annotations.Nls; import javax.swing.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; +import java.util.List; /** * User: catherine @@ -18,7 +16,11 @@ public class TestRunnerConfigurable implements Configurable, NonDefaultProjectCo private JPanel myMainPanel; private JComboBox myComboBox; private PythonTestConfigurationsModel myModel; + private Project myProject; + public TestRunnerConfigurable(Project project) { + myProject = project; + } @Nls @Override public String getDisplayName() { @@ -37,35 +39,16 @@ public class TestRunnerConfigurable implements Configurable, NonDefaultProjectCo @Override public JComponent createComponent() { - myModel = PythonTestConfigurationsModel.getInstance(); + List configurations = TestRunnerService.getInstance(myProject).getConfigurations(); + myModel = new PythonTestConfigurationsModel(configurations, TestRunnerService.getInstance(myProject).getProjectConfiguration(), + myProject); updateConfigurations(); return myMainPanel; } private void updateConfigurations() { myComboBox.setModel(myModel); - myComboBox.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent actionEvent) { - JComboBox cb = (JComboBox)actionEvent.getSource(); - String selectedItem = (String)cb.getSelectedItem(); - if (selectedItem.equals(PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME)) { - PythonUnitTestConfigurationProducer.getInstance(PythonUnitTestConfigurationProducer.class).setActive(true); - PythonNoseTestConfigurationProducer.getInstance(PythonNoseTestConfigurationProducer.class).setActive(false); - PyTestConfigurationProducer.getInstance(PyTestConfigurationProducer.class).setActive(false); - } - else if (selectedItem.equals(PythonTestConfigurationsModel.PYTHONS_NOSETEST_NAME)) { - PythonNoseTestConfigurationProducer.getInstance(PythonNoseTestConfigurationProducer.class).setActive(true); - PythonUnitTestConfigurationProducer.getInstance(PythonUnitTestConfigurationProducer.class).setActive(false); - PyTestConfigurationProducer.getInstance(PyTestConfigurationProducer.class).setActive(false); - } - else if (selectedItem.equals(PythonTestConfigurationsModel.PY_TEST_NAME)) { - PyTestConfigurationProducer.getInstance(PyTestConfigurationProducer.class).setActive(true); - PythonNoseTestConfigurationProducer.getInstance(PythonNoseTestConfigurationProducer.class).setActive(false); - PythonUnitTestConfigurationProducer.getInstance(PythonUnitTestConfigurationProducer.class).setActive(false); - } - } - }); + } @Override diff --git a/python/src/com/jetbrains/python/testing/TestRunnerService.java b/python/src/com/jetbrains/python/testing/TestRunnerService.java new file mode 100644 index 000000000000..aaca9cc3d93d --- /dev/null +++ b/python/src/com/jetbrains/python/testing/TestRunnerService.java @@ -0,0 +1,55 @@ +package com.jetbrains.python.testing; + +import com.intellij.openapi.components.*; +import com.intellij.openapi.project.Project; +import com.intellij.util.xmlb.XmlSerializerUtil; + +import java.util.ArrayList; +import java.util.List; + +/** + * User: catherine + */ +@State(name = "TestRunnerService", + storages = { + @Storage(id = "default", file = "$PROJECT_FILE$"), + @Storage(id = "dir", file = "$PROJECT_CONFIG_DIR$/testrunner.xml", scheme = StorageScheme.DIRECTORY_BASED) + } +) +public class TestRunnerService implements PersistentStateComponent { + private List myConfigurations = new ArrayList(); + public String PROJECT_CONFIGURATION = PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME; + + public TestRunnerService() { + myConfigurations.add(PythonTestConfigurationsModel.PYTHONS_UNITTEST_NAME); + myConfigurations.add(PythonTestConfigurationsModel.PYTHONS_NOSETEST_NAME); + myConfigurations.add(PythonTestConfigurationsModel.PY_TEST_NAME); + } + + public List getConfigurations() { + return myConfigurations; + } + public void registerConfiguration(final String newConfiguration) { + myConfigurations.add(newConfiguration); + } + @Override + public TestRunnerService getState() { + return this; + } + + @Override + public void loadState(TestRunnerService state) { + XmlSerializerUtil.copyBean(state, this); + } + + public void setProjectConfiguration(String projectConfiguration) { + PROJECT_CONFIGURATION = projectConfiguration; + } + + public static TestRunnerService getInstance(Project project) { + return ServiceManager.getService(project, TestRunnerService.class); + } + public String getProjectConfiguration() { + return PROJECT_CONFIGURATION; + } +} diff --git a/python/src/com/jetbrains/python/testing/nosetest/PythonNoseTestConfigurationProducer.java b/python/src/com/jetbrains/python/testing/nosetest/PythonNoseTestConfigurationProducer.java index 9872fcc34369..f7e70a5c958e 100644 --- a/python/src/com/jetbrains/python/testing/nosetest/PythonNoseTestConfigurationProducer.java +++ b/python/src/com/jetbrains/python/testing/nosetest/PythonNoseTestConfigurationProducer.java @@ -12,7 +12,6 @@ import com.intellij.execution.configurations.ConfigurationTypeUtil; import com.intellij.execution.junit.RuntimeConfigurationProducer; import com.intellij.facet.Facet; import com.intellij.facet.FacetManager; -import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -22,7 +21,10 @@ import com.intellij.psi.util.PsiTreeUtil; import com.jetbrains.python.PythonModuleTypeBase; import com.jetbrains.python.facet.PythonFacetSettings; import com.jetbrains.python.psi.*; -import com.jetbrains.python.testing.*; +import com.jetbrains.python.testing.PythonTestConfigurationsModel; +import com.jetbrains.python.testing.PythonUnitTestRunnableScriptFilter; +import com.jetbrains.python.testing.PythonUnitTestUtil; +import com.jetbrains.python.testing.TestRunnerService; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -30,7 +32,6 @@ import java.util.List; public class PythonNoseTestConfigurationProducer extends RuntimeConfigurationProducer { private PsiElement myPsiElement; - private boolean isActive = false; public PythonNoseTestConfigurationProducer() { super(ConfigurationTypeUtil.findConfigurationType(PythonNoseTestRunConfigurationType.class)); @@ -43,37 +44,34 @@ public class PythonNoseTestConfigurationProducer extends RuntimeConfigurationPro @Override protected RunnerAndConfigurationSettings createConfigurationByElement(Location location, ConfigurationContext context) { - if (!isActive) return null; + PsiElement element = location.getPsiElement(); + if (! (TestRunnerService.getInstance(element.getProject()).getProjectConfiguration().equals( + PythonTestConfigurationsModel.PYTHONS_NOSETEST_NAME))) return null; RunnerAndConfigurationSettings settings; + /*Module module = location.getModule(); - Module module = location.getModule(); if (module != null) { for (RunnableUnitTestFilter f : Extensions.getExtensions(RunnableUnitTestFilter.EP_NAME)) { if (f.isRunnableUnitTest(location.getPsiElement().getContainingFile(), module)) { return null; } } - } - + }*/ if (PythonUnitTestRunnableScriptFilter.isIfNameMain(location)) { return null; } - settings = createConfigurationFromFolder(location); if (settings != null) return settings; - final PyElement pyElement = PsiTreeUtil.getParentOfType(location.getPsiElement(), PyElement.class); if (pyElement != null) { settings = createConfigurationFromFunction(location, pyElement); if (settings != null) return settings; - settings = createConfigurationFromClass(location, pyElement); if (settings != null) return settings; } settings = createConfigurationFromFile(location, location.getPsiElement()); if (settings != null) return settings; - return null; } @@ -222,7 +220,4 @@ public class PythonNoseTestConfigurationProducer extends RuntimeConfigurationPro return PREFERED; } - public void setActive(boolean active) { - isActive = active; - } } \ No newline at end of file diff --git a/python/src/com/jetbrains/python/testing/nosetest/PythonNoseTestRunConfigurationType.java b/python/src/com/jetbrains/python/testing/nosetest/PythonNoseTestRunConfigurationType.java index 241c23e63af5..20d2b3b584f5 100644 --- a/python/src/com/jetbrains/python/testing/nosetest/PythonNoseTestRunConfigurationType.java +++ b/python/src/com/jetbrains/python/testing/nosetest/PythonNoseTestRunConfigurationType.java @@ -4,7 +4,6 @@ import com.intellij.execution.configurations.*; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.IconLoader; import com.jetbrains.python.PyBundle; -import com.jetbrains.python.testing.PythonTestConfigurationsModel; import javax.swing.*; @@ -27,13 +26,11 @@ public class PythonNoseTestRunConfigurationType extends ConfigurationTypeBase { private final static Icon ICON = IconLoader.getIcon("/com/jetbrains/python/icons/python.png"); private static class PythonNoseTestConfigurationFactory extends ConfigurationFactory { - final private PythonTestConfigurationsModel myModel = PythonTestConfigurationsModel.getInstance(); protected PythonNoseTestConfigurationFactory(ConfigurationType configurationType) { super(configurationType); } public RunConfiguration createTemplateConfiguration(Project project) { - myModel.addConfiguration(PythonTestConfigurationsModel.PYTHONS_NOSETEST_NAME, false); return new PythonNoseTestRunConfiguration(new RunConfigurationModule(project), this, ""); } } diff --git a/python/src/com/jetbrains/python/testing/pytest/PyTestConfigurationProducer.java b/python/src/com/jetbrains/python/testing/pytest/PyTestConfigurationProducer.java index 312322225587..6cfd5876e87a 100644 --- a/python/src/com/jetbrains/python/testing/pytest/PyTestConfigurationProducer.java +++ b/python/src/com/jetbrains/python/testing/pytest/PyTestConfigurationProducer.java @@ -20,7 +20,9 @@ import com.intellij.psi.util.PsiTreeUtil; import com.jetbrains.python.psi.PyFile; import com.jetbrains.python.psi.PyFunction; import com.jetbrains.python.psi.PyStatement; +import com.jetbrains.python.testing.PythonTestConfigurationsModel; import com.jetbrains.python.testing.PythonUnitTestConfigurationProducer; +import com.jetbrains.python.testing.TestRunnerService; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -29,7 +31,6 @@ import java.util.List; public class PyTestConfigurationProducer extends RuntimeConfigurationProducer { private PsiElement myPsiElement; - private boolean isActive = false; public PyTestConfigurationProducer() { super(ConfigurationTypeUtil.findConfigurationType(PyTestRunConfigurationType.class)); @@ -42,8 +43,10 @@ public class PyTestConfigurationProducer extends RuntimeConfigurationProducer { @Override protected RunnerAndConfigurationSettings createConfigurationByElement(Location location, ConfigurationContext context) { - if (!isActive) return null; PsiElement element = location.getPsiElement(); + if (! (TestRunnerService.getInstance(element.getProject()).getProjectConfiguration().equals( + PythonTestConfigurationsModel.PY_TEST_NAME))) return null; + PsiFileSystemItem file = element instanceof PsiDirectory ? (PsiDirectory)element : element.getContainingFile(); if (file == null) return null; myPsiElement = file; @@ -119,7 +122,4 @@ public class PyTestConfigurationProducer extends RuntimeConfigurationProducer { } return PREFERED; } - public void setActive(boolean active) { - isActive = active; - } } \ No newline at end of file diff --git a/python/src/com/jetbrains/python/testing/pytest/PyTestRunConfigurationType.java b/python/src/com/jetbrains/python/testing/pytest/PyTestRunConfigurationType.java index a8407f62ff9f..e176f7baf130 100644 --- a/python/src/com/jetbrains/python/testing/pytest/PyTestRunConfigurationType.java +++ b/python/src/com/jetbrains/python/testing/pytest/PyTestRunConfigurationType.java @@ -7,7 +7,6 @@ import com.intellij.execution.configurations.RunConfigurationModule; import com.intellij.openapi.project.Project; import com.jetbrains.python.PyBundle; import com.jetbrains.python.PythonFileType; -import com.jetbrains.python.testing.PythonTestConfigurationsModel; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -41,13 +40,11 @@ public class PyTestRunConfigurationType implements ConfigurationType { private static class PyTestRunConfigurationFactory extends ConfigurationFactory { - final private PythonTestConfigurationsModel myModel = PythonTestConfigurationsModel.getInstance(); protected PyTestRunConfigurationFactory(ConfigurationType type) { super(type); } public RunConfiguration createTemplateConfiguration(Project project) { - myModel.addConfiguration(PythonTestConfigurationsModel.PY_TEST_NAME, false); return new PyTestRunConfiguration("", new RunConfigurationModule(project), this); } }