PY-18125: test added

This commit is contained in:
Ilya.Kazakevich
2016-01-12 22:49:43 +03:00
parent 5f57460d2c
commit ed27ad6d45
6 changed files with 125 additions and 33 deletions

View File

@@ -109,7 +109,7 @@ public class CreateTestAction extends PsiElementBaseIntentionAction {
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
@Override
public void run() {
PsiFile e = PyTestCreator.generateTest(project, d);
PsiFile e = PyTestCreator.generateTestAndNavigate(project, d);
final PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
documentManager.commitAllDocuments();
}

View File

@@ -30,6 +30,7 @@ import com.intellij.util.IncorrectOperationException;
import com.jetbrains.python.PythonFileType;
import com.jetbrains.python.codeInsight.imports.AddImportHelper;
import com.jetbrains.python.psi.*;
import org.jetbrains.annotations.NotNull;
import java.util.List;
@@ -43,11 +44,13 @@ public class PyTestCreator implements TestCreator {
public boolean isAvailable(Project project, Editor editor, PsiFile file) {
CreateTestAction action = new CreateTestAction();
PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
if (element != null)
if (element != null) {
return action.isAvailable(project, editor, element);
}
return false;
}
@Override
public void createTest(Project project, Editor editor, PsiFile file) {
try {
CreateTestAction action = new CreateTestAction();
@@ -61,41 +64,20 @@ public class PyTestCreator implements TestCreator {
}
}
public static PsiFile generateTest(final Project project, final CreateTestDialog dialog) {
/**
* Generates test, puts it into file and navigates to newly created class
*
* @return file with test
*/
static PsiFile generateTestAndNavigate(@NotNull final Project project, @NotNull final CreateTestDialog dialog) {
return PostprocessReformattingAspect.getInstance(project).postponeFormattingInside(new Computable<PsiFile>() {
public PsiFile compute() {
return ApplicationManager.getApplication().runWriteAction(new Computable<PsiFile>() {
public PsiFile compute() {
try {
IdeDocumentHistory.getInstance(project).includeCurrentPlaceAsChangePlace();
String fileName = dialog.getFileName();
if (!fileName.endsWith(".py"))
fileName = fileName + "." + PythonFileType.INSTANCE.getDefaultExtension();
StringBuilder fileText = new StringBuilder();
fileText.append("class ").append(dialog.getClassName()).append("(TestCase):\n\t");
List<String> methods = dialog.getMethods();
if (methods.size() == 0)
fileText.append("pass\n");
for (String method : methods) {
fileText.append("def ").append(method).append("(self):\n\tself.fail()\n\n\t");
}
PsiFile psiFile = PyUtil.getOrCreateFile(
dialog.getTargetDir() + "/" + fileName, project);
AddImportHelper.addOrUpdateFromImportStatement(psiFile, "unittest", "TestCase", null, AddImportHelper.ImportPriority.BUILTIN,
null);
PyElement createdClass = PyElementGenerator.getInstance(project).createFromText(
LanguageLevel.forElement(psiFile), PyClass.class, fileText.toString());
createdClass = (PyElement)psiFile.addAfter(createdClass, psiFile.getLastChild());
PostprocessReformattingAspect.getInstance(project).doPostponedFormatting(psiFile.getViewProvider());
CodeStyleManager.getInstance(project).reformat(psiFile);
createdClass.navigate(false);
return psiFile;
final PyElement testClass = generateTest(project, dialog);
testClass.navigate(false);
return testClass.getContainingFile();
}
catch (IncorrectOperationException e) {
LOG.warn(e);
@@ -106,4 +88,43 @@ public class PyTestCreator implements TestCreator {
}
});
}
/**
* Generates test, puts it into file and returns class element for test
*
* @return newly created test class
*/
@NotNull
static PyElement generateTest(@NotNull final Project project, @NotNull final CreateTestDialog dialog) {
IdeDocumentHistory.getInstance(project).includeCurrentPlaceAsChangePlace();
String fileName = dialog.getFileName();
if (!fileName.endsWith(".py")) {
fileName = fileName + "." + PythonFileType.INSTANCE.getDefaultExtension();
}
StringBuilder fileText = new StringBuilder();
fileText.append("class ").append(dialog.getClassName()).append("(TestCase):\n\t");
List<String> methods = dialog.getMethods();
if (methods.size() == 0) {
fileText.append("pass\n");
}
for (String method : methods) {
fileText.append("def ").append(method).append("(self):\n\tself.fail()\n\n\t");
}
PsiFile psiFile = PyUtil.getOrCreateFile(
dialog.getTargetDir() + "/" + fileName, project);
AddImportHelper.addOrUpdateFromImportStatement(psiFile, "unittest", "TestCase", null, AddImportHelper.ImportPriority.BUILTIN,
null);
PyElement createdClass = PyElementGenerator.getInstance(project).createFromText(
LanguageLevel.forElement(psiFile), PyClass.class, fileText.toString());
createdClass = (PyElement)psiFile.addAfter(createdClass, psiFile.getLastChild());
PostprocessReformattingAspect.getInstance(project).doPostponedFormatting(psiFile.getViewProvider());
CodeStyleManager.getInstance(project).reformat(psiFile);
return createdClass;
}
}

View File

@@ -1310,7 +1310,7 @@ public class PyUtil {
);
}
catch (IOException e) {
throw new IncorrectOperationException(String.format("Cannot create file '%s'", path));
throw new IncorrectOperationException(String.format("Cannot create file '%s'", path), (Throwable)e);
}
}
else {

View File

@@ -0,0 +1,9 @@
from unittest import TestCase
class Spam(TestCase):
def eggs(self):
self.fail()
def eggs_and_ham(self):
self.fail()

View File

@@ -0,0 +1,6 @@
class Spam:
def eggs(self):
pass
def eggs_and_ham(self):
pass

View File

@@ -0,0 +1,56 @@
/*
* Copyright 2000-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.jetbrains.python.codeInsight.testIntegration;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.jetbrains.python.fixtures.PyTestCase;
import org.easymock.IMocksControl;
import java.util.Arrays;
import static org.easymock.classextension.EasyMock.createNiceControl;
import static org.easymock.classextension.EasyMock.expect;
/**
* Checks how test classes are created
* @author Ilya.Kazakevich
*/
public final class PyTestCreatorTest extends PyTestCase {
public void testCreateTest() throws Exception {
myFixture.configureByFile("/create_tests/create_tst.py");
final IMocksControl mockControl = createNiceControl();
final CreateTestDialog dialog = mockControl.createMock(CreateTestDialog.class);
expect(dialog.getFileName()).andReturn("tests.py").anyTimes();
expect(dialog.getClassName()).andReturn("Spam").anyTimes();
// Target dir is first module source
final VirtualFile root = ModuleRootManager.getInstance(myFixture.getModule()).getSourceRoots()[0];
expect(dialog.getTargetDir()).andReturn(root.getCanonicalPath()).anyTimes();
expect(dialog.getMethods()).andReturn(Arrays.asList("eggs", "eggs_and_ham")).anyTimes();
mockControl.replay();
WriteCommandAction.runWriteCommandAction(myFixture.getProject(), () -> {
final PsiFile file = PyTestCreator.generateTest(myFixture.getProject(), dialog).getContainingFile();
myFixture.configureByText(file.getFileType(), file.getText());
myFixture.checkResultByFile("/create_tests/create_tst.expected.py");
});
}
}