/** * Copyright (c) 2005-2011 by Appcelerator, Inc. All Rights Reserved. * Licensed under the terms of the Eclipse Public License (EPL). * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ package com.python.pydev.refactoring.tdd; import java.io.ByteArrayInputStream; import java.util.ArrayList; import java.util.List; import junit.framework.Test; import junit.framework.TestSuite; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.Path; import org.eclipse.jface.text.BadLocationException; import org.eclipse.jface.text.IDocument; import org.eclipse.jface.text.contentassist.ICompletionProposal; import org.eclipse.jface.text.contentassist.ICompletionProposalExtension2; import org.python.pydev.core.MisconfigurationException; import org.python.pydev.core.callbacks.ICallbackListener; import org.python.pydev.core.docutils.PySelection; import org.python.pydev.core.docutils.StringUtils; import org.python.pydev.core.parser.IParserObserver; import org.python.pydev.core.parser.ISimpleNode; import org.python.pydev.editor.PyEdit; import org.python.pydev.editor.codecompletion.revisited.javaintegration.AbstractWorkbenchTestCase; import org.python.pydev.editorinput.PyOpenEditor; import org.python.pydev.parser.PyParser; import org.python.pydev.plugin.PydevPlugin; import com.aptana.shared_core.callbacks.ICallback; import com.aptana.shared_core.structure.Tuple; import com.python.pydev.analysis.AnalysisRequestsTestWorkbench; import com.python.pydev.analysis.builder.AnalysisParserObserver; import com.python.pydev.analysis.builder.AnalysisRunner; public class TddTestWorkbench extends AbstractWorkbenchTestCase implements IParserObserver { public static Test suite() { TestSuite suite = new TestSuite(TddTestWorkbench.class.getName()); suite.addTestSuite(TddTestWorkbench.class); if (suite.countTestCases() == 0) { throw new Error("There are no test cases to run"); } else { return suite; } } private PyParser parser; private int parserNotified; public void testCheckTddQuickFixes() throws Exception { //We have to wait a bit until the info is setup for the tests to work... waitForModulesManagerSetup(); checkCreateMethod4(); checkCreateMethod3(); checkCreateMethodAtField0(); checkCreateMethodAtField(); checkCreateFieldAtField(); checkCreateField(); checkCreateNewModule4(); checkCreateFieldAtClass5(); checkCreateConstant(); checkCreateFieldAtClass4(); checkCreateMethod2(); checkCreateFieldAtClass3(); checkCreateFieldAtClass2(); checkCreateFieldAtClass(); checkCreateMethodAtClass(); checkCreateMethodAtClass2(); checkCreateClass(); checkCreateClassWithParams(); checkCreateClassWithParams2(); checkCreateClassInit(); checkCreateClassInit2(); checkCreateClassInit3(); checkCreateClassAtOtherModule(); checkCreateMethod(); checkCreateMethodAtOtherModule(); checkCreateBoundMethod(); checkCreateMethodAtOtherModule2(); checkCreateMethodAtOtherModule4(); checkCreateNewModule(); checkCreateNewModule2(); checkCreateNewModuleWithClass(); checkCreateNewModule3(); checkCreateNewModuleWithClass2(); checkCreateNewModuleWithClass3(); checkCreateNewMethodInClass(); } private void checkCreateField() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents = "" + "class Err(object):\n" + "\n" + " def Foo(self):\n" + " self._suggestion_not_there.get()" + ""; setContentsAndWaitReparseAndError(mod1Contents, false); //no error here TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); IDocument doc = editor.getDocument(); int offset = doc.getLength(); PySelection ps = new PySelection(doc, offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); try { waitForQuickFixProps(quickFix, ps, offset, "Create _suggestion_not_there field at Err").apply( editor.getISourceViewer(), '\n', 0, offset); assertContentsEqual("" + "class Err(object):\n" + "\n" + " \n" + " def __init__(self):\n" + " self._suggestion_not_there = None\n" + " \n" + " \n" + "\n" + " def Foo(self):\n" + " self._suggestion_not_there.get()" + "", editor.getDocument().get()); } finally { editor.doRevertToSaved(); } } private void checkCreateMethodAtField0() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents = "" + "class A:\n" + " pass\n" + "\n" + "class B:\n" + "\n" + " def __init__(self, *args):\n" + " self._a = A()\n" + " self._a.Foo()" + ""; setContentsAndWaitReparseAndError(mod1Contents, false); //no error here TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); IDocument doc = editor.getDocument(); int offset = doc.getLength(); PySelection ps = new PySelection(doc, offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); try { waitForQuickFixProps(quickFix, ps, offset, "Create Foo method at A (pack1.pack2.mod1)").apply( editor.getISourceViewer(), '\n', 0, offset); assertContentsEqual("" + "class A:\n" + " \n" + " \n" + " def Foo(self):\n" + " pass\n" + " \n" + " \n" + "\n" + "\n" + "class B:\n" + "\n" + " def __init__(self, *args):\n" + " self._a = A()\n" + " self._a.Foo()" + "", editor.getDocument().get()); } finally { editor.doRevertToSaved(); } } private void checkCreateMethodAtField() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents = "" + "class Bar(object):\n" + " pass\n" + "\n" + "class MyTestClass(object):\n" + " \n" + " def __init__(self):\n" + " self.bar = Bar()\n" + " \n" + " def test_1(self):\n" + " self.bar.something()" + ""; setContentsAndWaitReparseAndError(mod1Contents, false); //no error here TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); IDocument doc = editor.getDocument(); int offset = doc.getLength(); PySelection ps = new PySelection(doc, offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); try { waitForQuickFixProps(quickFix, ps, offset, "Create something method at Bar (pack1.pack2.mod1)").apply( editor.getISourceViewer(), '\n', 0, offset); assertContentsEqual("" + "class Bar(object):\n" + " \n" + " \n" + " def something(self):\n" + " pass\n" + " \n" + " \n" + "\n" + "\n" + "class MyTestClass(object):\n" + " \n" + " def __init__(self):\n" + " self.bar = Bar()\n" + " \n" + " def test_1(self):\n" + " self.bar.something()" + "", editor.getDocument().get()); } finally { editor.doRevertToSaved(); } } private void checkCreateFieldAtField() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents = "" + "class Bar(object):\n" + " pass\n" + "\n" + "class MyTestClass(object):\n" + " \n" + " def __init__(self):\n" + " self.bar = Bar()\n" + " \n" + " def test_1(self):\n" + " self.bar.something" + ""; setContentsAndWaitReparseAndError(mod1Contents, false); //no error here TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); IDocument doc = editor.getDocument(); int offset = doc.getLength(); PySelection ps = new PySelection(doc, offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); try { waitForQuickFixProps(quickFix, ps, offset, "Create something field at Bar (pack1.pack2.mod1)").apply( editor.getISourceViewer(), '\n', 0, offset); assertContentsEqual("" + "class Bar(object):\n" + " \n" + " \n" + " def __init__(self):\n" + " self.something = None\n" + " \n" + " \n" + "\n" + "\n" + "class MyTestClass(object):\n" + " \n" + " def __init__(self):\n" + " self.bar = Bar()\n" + " \n" + " def test_1(self):\n" + " self.bar.something" + "", editor.getDocument().get()); } finally { editor.doRevertToSaved(); } } private void checkCreateBoundMethod() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents = "" + "class Foo(object):\n" + " def m1(self):\n" + " self.bar()"; setContentsAndWaitReparseAndError(mod1Contents, false); //no error here TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); IDocument doc = editor.getDocument(); int offset = doc.getLength() - "r()".length(); PySelection ps = new PySelection(doc, offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); try { waitForQuickFixProps(quickFix, ps, offset, "Create bar method at Foo").apply(editor.getISourceViewer(), '\n', 0, offset); assertContentsEqual("" + "class Foo(object):\n" + "\n" + " \n" + " def bar(self):\n" + " pass\n" + " \n" + " \n" + " def m1(self):\n" + " self.bar()" + "", editor.getDocument().get()); } finally { editor.doRevertToSaved(); } } private void checkCreateNewMethodInClass() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents = "" + "class MyClass(object):\n" + " pass\n" + "\n" + "def makeTestObj():\n" + " return MyClass()\n" + "\n" + "def makeTestObj2():\n" + " return makeTestObj()\n" + "\n" + "def testName():\n" + " obj = makeTestObj2()\n" + " obj.unimplementedFunction()"; setContentsAndWaitReparseAndError(mod1Contents, false); //no error here TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); IDocument doc = editor.getDocument(); int offset = doc.getLength() - "()".length(); PySelection ps = new PySelection(doc, offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); try { waitForQuickFixProps(quickFix, ps, offset, "Create unimplementedFunction method at MyClass (pack1.pack2.mod1)").apply( editor.getISourceViewer(), '\n', 0, offset); assertContentsEqual("" + "class MyClass(object):\n" + " \n" + " \n" + " def unimplementedFunction(self):\n" + " pass\n" + " \n" + " \n" + "\n" + "\n" + "def makeTestObj():\n" + " return MyClass()\n" + "\n" + "def makeTestObj2():\n" + " return makeTestObj()\n" + "\n" + "def testName():\n" + " obj = makeTestObj2()\n" + " obj.unimplementedFunction()" + "", editor.getDocument().get()); } finally { editor.doRevertToSaved(); } } private void checkCreateMethod3() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents = "" + "print i\n" + //just to have an error "class Foo(object):\n" + "\n" + "\n" + " def m1(self):\n" + " self.m2" + "" + ""; setContentsAndWaitReparseAndError(mod1Contents); TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length(); PySelection ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); try { waitForQuickFixProps(quickFix, ps, offset, "Create m2 method at Foo").apply(editor.getISourceViewer(), '\n', 0, offset); assertContentsEqual("" + "print i\n" + //just to have an error "class Foo(object):\n" + "\n" + "\n" + " def m2(self):\n" + " pass\n" + " \n" + " \n" + " def m1(self):\n" + " self.m2" + "" + "", editor.getDocument().get()); } finally { editor.doRevertToSaved(); } } private void checkCreateMethod4() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents = "" + "print i\n" + //just to have an error "class Foo(object):\n" + "\n" + "#comment\n" + "\n" + " def m1(self):\n" + " self.m2" + "" + ""; setContentsAndWaitReparseAndError(mod1Contents); TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length(); PySelection ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); try { waitForQuickFixProps(quickFix, ps, offset, "Create m2 method at Foo").apply(editor.getISourceViewer(), '\n', 0, offset); assertContentsEqual("" + "print i\n" + //just to have an error "class Foo(object):\n" + "\n" + "#comment\n" + "\n" + "\n" + " def m2(self):\n" + " pass\n" + " \n" + " \n" + " def m1(self):\n" + " self.m2" + "" + "", editor.getDocument().get()); } finally { editor.doRevertToSaved(); } } private void checkCreateMethod2() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents = "" + "print i\n" + //just to have an error "class Foo(object):\n" + "\n" + "\n" + " def m1(self):\n" + " self.m2()" + "" + ""; setContentsAndWaitReparseAndError(mod1Contents); TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length(); PySelection ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); try { waitForQuickFixProps(quickFix, ps, offset, "Create m2 method at Foo").apply(editor.getISourceViewer(), '\n', 0, offset); assertContentsEqual("" + "print i\n" + //just to have an error "class Foo(object):\n" + "\n" + "\n" + " def m2(self):\n" + " pass\n" + " \n" + " \n" + " def m1(self):\n" + " self.m2()" + "" + "", editor.getDocument().get()); } finally { editor.doRevertToSaved(); } } private void checkCreateMethod() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents = "Foo"; setContentsAndWaitReparseAndError(mod1Contents); TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); PySelection ps = new PySelection(editor.getDocument(), 0); assertTrue(quickFix.isValid(ps, "", editor, 0)); List<ICompletionProposal> props = quickFix.getProps(ps, PydevPlugin.getImageCache(), editor.getEditorFile(), editor.getPythonNature(), editor, 0); try { findCompletion(props, "Create Foo method").apply(editor.getISourceViewer(), '\n', 0, 0); assertContentsEqual("" + "def Foo():\n" + " pass\n" + "\n" + "\n" + "Foo" + "", editor.getDocument() .get()); } finally { editor.doRevertToSaved(); } } private void checkCreateMethodAtOtherModule() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; TddCodeGenerationQuickFixParticipant quickFix; PySelection ps; IFile mod2 = initFile.getParent().getFile(new Path("other_module2.py")); mod2.create(new ByteArrayInputStream("".getBytes()), true, null); PyEdit editor2 = (PyEdit) PyOpenEditor.doOpenEditor(mod2); try { goToManual(AnalysisRequestsTestWorkbench.TIME_FOR_ANALYSIS); //give it a bit more time... mod1Contents = "" + "import other_module2\n" + "other_module2.Foo(a, b)"; setContentsAndWaitReparseAndError(mod1Contents); quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length() - "o(a, b)".length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); waitForQuickFixProps(quickFix, ps, offset, "Create Foo method at other_module2.py").apply( editor.getISourceViewer(), '\n', 0, offset); assertContentsEqual("" + "def Foo(a, b):\n" + " pass\n" + "\n" + "\n" + "", editor2.getDocument().get()); } finally { editor2.close(false); mod2.delete(true, null); } } private void checkCreateMethodAtOtherModule2() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; TddCodeGenerationQuickFixParticipant quickFix; PySelection ps; IFile mod2 = initFile.getParent().getFile(new Path("other_module3.py")); String str = "" + "class Bar(object):\n" + " pass\n" + ""; mod2.create(new ByteArrayInputStream(str.getBytes()), true, null); PyEdit editor2 = (PyEdit) PyOpenEditor.doOpenEditor(mod2); try { goToManual(AnalysisRequestsTestWorkbench.TIME_FOR_ANALYSIS); //give it a bit more time... mod1Contents = "" + "import other_module3\n" + "other_module3.Bar.Foo(10, 20)"; setContentsAndWaitReparseAndError(mod1Contents); quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length() - "o(a, b)".length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); waitForQuickFixProps(quickFix, ps, offset, "Create Foo classmethod at Bar in other_module3.py").apply( editor.getISourceViewer(), '\n', 0, offset); assertContentsEqual("" + "class Bar(object):\n" + " \n" + " \n" + " @classmethod\n" + " def Foo(cls, param1, param2):\n" + " pass\n" + " \n" + " \n" + "\n" + "", editor2.getDocument().get()); } finally { editor2.close(false); mod2.delete(true, null); } } private void checkCreateMethodAtOtherModule4() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; TddCodeGenerationQuickFixParticipant quickFix; PySelection ps; IFile mod2 = initFile.getParent().getFile(new Path("other_module4.py")); String str = ""; mod2.create(new ByteArrayInputStream(str.getBytes()), true, null); PyEdit editor2 = (PyEdit) PyOpenEditor.doOpenEditor(mod2); try { goToManual(AnalysisRequestsTestWorkbench.TIME_FOR_ANALYSIS); //give it a bit more time... mod1Contents = "" + "from pack1.pack2.other_module4 import Foo"; setContentsAndWaitReparseAndError(mod1Contents); quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); waitForQuickFixProps(quickFix, ps, offset, "Create Foo class at other_module4.py").apply( editor.getISourceViewer(), '\n', 0, offset); assertContentsEqual("" + "class Foo(object):\n" + " pass\n" + "\n" + "\n" + "", editor2.getDocument() .get()); } finally { editor2.close(false); mod2.delete(true, null); } } private void checkCreateNewModule() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; TddCodeGenerationQuickFixParticipant quickFix; PySelection ps; IFile mod2 = initFile.getParent().getFile(new Path("module_new.py")); final List<PyEdit> pyEditCreated = new ArrayList<PyEdit>(); ICallbackListener<PyEdit> listener = new ICallbackListener<PyEdit>() { public Object call(PyEdit obj) { pyEditCreated.add(obj); return null; } }; PyEdit.onPyEditCreated.registerListener(listener); try { goToManual(AnalysisRequestsTestWorkbench.TIME_FOR_ANALYSIS); //give it a bit more time... mod1Contents = "" + "import pack1.pack2.module_new"; setContentsAndWaitReparseAndError(mod1Contents); quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); assertTrue(!mod2.exists()); waitForQuickFixProps(quickFix, ps, offset, "Create pack1.pack2.module_new module").apply( editor.getISourceViewer(), '\n', 0, offset); assertTrue(mod2.exists()); assertEquals(1, pyEditCreated.size()); } finally { for (PyEdit edit : pyEditCreated) { edit.close(false); } PyEdit.onPyEditCreated.unregisterListener(listener); mod2.delete(true, null); } } private void checkCreateNewModule4() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; TddCodeGenerationQuickFixParticipant quickFix; PySelection ps; IFile mod3 = initFile.getParent().getFile(new Path("module_new3.py")); final List<PyEdit> pyEditCreated = new ArrayList<PyEdit>(); ICallbackListener<PyEdit> listener = new ICallbackListener<PyEdit>() { public Object call(PyEdit obj) { pyEditCreated.add(obj); return null; } }; PyEdit.onPyEditCreated.registerListener(listener); try { goToManual(AnalysisRequestsTestWorkbench.TIME_FOR_ANALYSIS); //give it a bit more time... mod1Contents = "" + "from pack1.pack2 import module_new3"; setContentsAndWaitReparseAndError(mod1Contents); quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); assertTrue(!mod3.exists()); waitForQuickFixProps(quickFix, ps, offset, "Create module_new3 module").apply(editor.getISourceViewer(), '\n', 0, offset); assertTrue(mod3.exists()); assertEquals(1, pyEditCreated.size()); } finally { for (PyEdit edit : pyEditCreated) { edit.close(false); } PyEdit.onPyEditCreated.unregisterListener(listener); mod3.delete(true, null); } } private void checkCreateNewModule2() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; TddCodeGenerationQuickFixParticipant quickFix; PySelection ps; List<ICompletionProposal> props; IFile mod2 = initFile.getParent().getFile(new Path("pack2a/module_new.py")); final List<PyEdit> pyEditCreated = new ArrayList<PyEdit>(); ICallbackListener<PyEdit> listener = new ICallbackListener<PyEdit>() { public Object call(PyEdit obj) { pyEditCreated.add(obj); return null; } }; PyEdit.onPyEditCreated.registerListener(listener); try { goToManual(AnalysisRequestsTestWorkbench.TIME_FOR_ANALYSIS); //give it a bit more time... mod1Contents = "" + "import pack1.pack2.pack2a.module_new"; setContentsAndWaitReparseAndError(mod1Contents); quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); props = waitForQuickFixProps(quickFix, ps, offset); assertTrue(!mod2.exists()); findCompletion(props, "Create pack1.pack2.pack2a.module_new module").apply(editor.getISourceViewer(), '\n', 0, offset); assertTrue(mod2.exists()); assertEquals(1, pyEditCreated.size()); } finally { for (PyEdit edit : pyEditCreated) { edit.close(false); } PyEdit.onPyEditCreated.unregisterListener(listener); mod2.delete(true, null); } } private void checkCreateNewModule3() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; TddCodeGenerationQuickFixParticipant quickFix; PySelection ps; List<ICompletionProposal> props; IFile mod2 = initFile.getParent().getParent().getParent().getFile(new Path("newpack/module_new.py")); final List<PyEdit> pyEditCreated = new ArrayList<PyEdit>(); ICallbackListener<PyEdit> listener = new ICallbackListener<PyEdit>() { public Object call(PyEdit obj) { pyEditCreated.add(obj); return null; } }; PyEdit.onPyEditCreated.registerListener(listener); try { //Create module goToManual(AnalysisRequestsTestWorkbench.TIME_FOR_ANALYSIS); //give it a bit more time... mod1Contents = "" + "import newpack.module_new"; setContentsAndWaitReparseAndError(mod1Contents); quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); props = waitForQuickFixProps(quickFix, ps, offset); assertTrue(!mod2.exists()); findCompletion(props, "Create newpack.module_new module").apply(editor.getISourceViewer(), '\n', 0, offset); assertTrue(mod2.exists()); assertEquals(1, pyEditCreated.size()); PyEdit editCreated = pyEditCreated.get(0); //Create class at module mod1Contents = "" + "from newpack import module_new\n" + "module_new.NewClass"; setContentsAndWaitReparseAndError(mod1Contents); quickFix = new TddCodeGenerationQuickFixParticipant(); offset = mod1Contents.length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); props = waitForQuickFixProps(quickFix, ps, offset); findCompletion(props, "Create NewClass class at module_new.py").apply(editor.getISourceViewer(), '\n', 0, offset); String contents = editCreated.getDocument().get(); assertContentsEqual("" + "class NewClass(object):\n" + " pass\n" + "\n" + "\n" + "", contents); editCreated.getSite().getPage().saveEditor(editCreated, false); //Create __init__ at class. mod1Contents = "" + "'''\n" + "'''\n" + "" + "def bar():\n" + " from newpack import module_new\n" + " module_new.NewClass(param)"; //the 'undefined param' will be the error setContentsAndWaitReparseAndError(mod1Contents); quickFix = new TddCodeGenerationQuickFixParticipant(); offset = mod1Contents.length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); props = waitForQuickFixProps(quickFix, ps, offset); findCompletion(props, "Create NewClass __init__ (newpack.module_new)").apply(editor.getISourceViewer(), '\n', 0, offset); contents = editCreated.getDocument().get(); assertContentsEqual("" + "class NewClass(object):\n" + " \n" + " \n" + " def __init__(self, param):\n" + " pass\n" + " \n" + " \n" + "\n" + "\n" + "\n" + "", contents); } finally { for (PyEdit edit : pyEditCreated) { edit.close(false); } PyEdit.onPyEditCreated.unregisterListener(listener); mod2.delete(true, null); } } private ICompletionProposalExtension2 waitForQuickFixProps(TddCodeGenerationQuickFixParticipant quickFix, PySelection ps, int offset, String expectedCompletion) throws MisconfigurationException, BadLocationException { long initialTime = System.currentTimeMillis(); List<ICompletionProposal> props; while (true) { props = waitForQuickFixProps(quickFix, ps, offset); ICompletionProposalExtension2 completion = findCompletion(props, expectedCompletion, false); if (completion != null) { return completion; } if (System.currentTimeMillis() - initialTime > 10000) { break; //Give it 10 seconds to work. } goToManual(200); } // throws exception if not used. return findCompletion(props, expectedCompletion); } private List<ICompletionProposal> waitForQuickFixProps(TddCodeGenerationQuickFixParticipant quickFix, PySelection ps, int offset) throws BadLocationException, MisconfigurationException { for (int i = 0; i < 10; i++) { List<ICompletionProposal> props = quickFix.getProps(ps, PydevPlugin.getImageCache(), editor.getEditorFile(), editor.getPythonNature(), editor, offset); if (props.size() > 0) { return props; } goToManual(700); } throw new AssertionError("Could not find any proposals after " + 700 * 10 / 1000 + " seconds."); } private void checkCreateNewModuleWithClass2() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; TddCodeGenerationQuickFixParticipant quickFix; PySelection ps; List<ICompletionProposal> props; IFile mod2 = initFile.getParent().getParent().getParent().getFile(new Path("newpack2/module_new.py")); final List<PyEdit> pyEditCreated = new ArrayList<PyEdit>(); ICallbackListener<PyEdit> listener = new ICallbackListener<PyEdit>() { public Object call(PyEdit obj) { pyEditCreated.add(obj); return null; } }; PyEdit.onPyEditCreated.registerListener(listener); try { goToManual(AnalysisRequestsTestWorkbench.TIME_FOR_ANALYSIS); //give it a bit more time... mod1Contents = "" + "from newpack2.module_new import Foo"; setContentsAndWaitReparseAndError(mod1Contents); quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); props = waitForQuickFixProps(quickFix, ps, offset); assertTrue(!mod2.exists()); findCompletion(props, "Create Foo class at new module newpack2.module_new").apply( editor.getISourceViewer(), '\n', 0, offset); assertTrue("Expected: " + mod2 + " to exist.", mod2.exists()); assertEquals(1, pyEditCreated.size()); } finally { for (PyEdit edit : pyEditCreated) { edit.close(false); } PyEdit.onPyEditCreated.unregisterListener(listener); mod2.delete(true, null); } } private void checkCreateNewModuleWithClass3() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; TddCodeGenerationQuickFixParticipant quickFix; PySelection ps; List<ICompletionProposal> props; IFile mod2 = initFile.getParent().getParent().getParent().getFile(new Path("newpack2/module_new9.py")); final List<PyEdit> pyEditCreated = new ArrayList<PyEdit>(); ICallbackListener<PyEdit> listener = new ICallbackListener<PyEdit>() { public Object call(PyEdit obj) { pyEditCreated.add(obj); return null; } }; PyEdit.onPyEditCreated.registerListener(listener); try { goToManual(AnalysisRequestsTestWorkbench.TIME_FOR_ANALYSIS); //give it a bit more time... mod1Contents = "" + "class Foo:\n from newpack2.module_new9 import Foo"; setContentsAndWaitReparseAndError(mod1Contents); quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); props = waitForQuickFixProps(quickFix, ps, offset); assertTrue(!mod2.exists()); findCompletion(props, "Create Foo class at new module newpack2.module_new9").apply( editor.getISourceViewer(), '\n', 0, offset); assertTrue("Expected: " + mod2 + " to exist.", mod2.exists()); assertEquals(1, pyEditCreated.size()); } finally { for (PyEdit edit : pyEditCreated) { edit.close(false); } PyEdit.onPyEditCreated.unregisterListener(listener); mod2.delete(true, null); } } private void checkCreateNewModuleWithClass() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; TddCodeGenerationQuickFixParticipant quickFix; PySelection ps; List<ICompletionProposal> props; IFile mod2 = initFile.getParent().getFolder(new Path("pack3")).getFile(new Path("module_new2.py")); final List<PyEdit> pyEditCreated = new ArrayList<PyEdit>(); ICallbackListener<PyEdit> listener = new ICallbackListener<PyEdit>() { public Object call(PyEdit obj) { pyEditCreated.add(obj); return null; } }; PyEdit.onPyEditCreated.registerListener(listener); try { goToManual(AnalysisRequestsTestWorkbench.TIME_FOR_ANALYSIS); //give it a bit more time... mod1Contents = "" + "from pack1.pack2.pack3.module_new2 import Foo"; setContentsAndWaitReparseAndError(mod1Contents); quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); props = waitForQuickFixProps(quickFix, ps, offset); assertTrue(!mod2.exists()); findCompletion(props, "Create Foo class at new module pack1.pack2.pack3.module_new2").apply( editor.getISourceViewer(), '\n', 0, offset); assertTrue(mod2.exists()); assertEquals(1, pyEditCreated.size()); assertContentsEqual("" + "class Foo(object):\n" + " pass\n" + "\n" + "\n" + "", pyEditCreated.get(0) .getDocument().get()); } finally { for (PyEdit edit : pyEditCreated) { edit.close(false); } PyEdit.onPyEditCreated.unregisterListener(listener); mod2.delete(true, null); } } private void checkCreateClass() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents = "Foo"; setContentsAndWaitReparseAndError(mod1Contents); TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); PySelection ps = new PySelection(editor.getDocument(), 0); assertTrue(quickFix.isValid(ps, "", editor, 0)); List<ICompletionProposal> props = quickFix.getProps(ps, PydevPlugin.getImageCache(), editor.getEditorFile(), editor.getPythonNature(), editor, 0); try { findCompletion(props, "Create Foo class").apply(editor.getISourceViewer(), '\n', 0, 0); assertContentsEqual("" + "class Foo(object):\n" + " pass\n" + "\n" + "\n" + "Foo" + "", editor .getDocument().get()); } finally { editor.doRevertToSaved(); } } private void checkCreateMethodAtClass() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents = "" + "print i\n" + //just to have error on reparse. "class Foo(object):\n" + " 'doc'\n" + "\n" + "foo = Foo()\n" + "foo.Met1()"; setContentsAndWaitReparseAndError(mod1Contents); TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length() - 1; PySelection ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); List<ICompletionProposal> props = waitForQuickFixProps(quickFix, ps, offset); try { findCompletion(props, "Create Met1 method at Foo (pack1.pack2.mod1)").apply(editor.getISourceViewer(), '\n', 0, offset); String expected = "" + "print i\n" + "class Foo(object):\n" + " 'doc'\n" + "\n" + " \n" + " def Met1(self):\n" + " pass\n" + " \n" + " \n" + "\n" + "foo = Foo()\n" + "foo.Met1()"; assertContentsEqual(expected, editor.getDocument().get()); } finally { editor.doRevertToSaved(); } } private void checkCreateFieldAtClass() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents = "" + "print i\n" + //just to have error on reparse. "class Foo(object):\n" + " 'doc'\n" + " def existing(self):\n" + " pass\n" + "foo = Foo()\n" + "foo.new_field"; setContentsAndWaitReparseAndError(mod1Contents); TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length() - 1; PySelection ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); List<ICompletionProposal> props = waitForQuickFixProps(quickFix, ps, offset); try { findCompletion(props, "Create new_field field at Foo (pack1.pack2.mod1)").apply(editor.getISourceViewer(), '\n', 0, offset); String expected = "" + "print i\n" + "class Foo(object):\n" + " 'doc'\n" + "\n" + " \n" + " def __init__(self):\n" + " self.new_field = None\n" + " \n" + " \n" + " def existing(self):\n" + " pass\n" + "foo = Foo()\n" + "foo.new_field"; assertContentsEqual(expected, editor.getDocument().get()); } finally { editor.doRevertToSaved(); } } private void checkCreateFieldAtClass5() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents = "" + "print i\n" + "class Foo(object):\n" + " 'doc'\n" + " def bar(self):\n" + " self.a = 10"; setContentsAndWaitReparseAndError(mod1Contents); TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length() - 1; PySelection ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); List<ICompletionProposal> props = waitForQuickFixProps(quickFix, ps, offset); try { findCompletion(props, "Create a field at Foo").apply(editor.getISourceViewer(), '\n', 0, offset); String expected = "" + "print i\n" + "class Foo(object):\n" + " 'doc'\n" + "\n" + " \n" + " def __init__(self):\n" + " self.a = None\n" + " \n" + " \n" + " def bar(self):\n" + " self.a = 10"; assertContentsEqual(expected, editor.getDocument().get()); } finally { editor.doRevertToSaved(); } } private void checkCreateFieldAtClass3() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents = "" + "print i\n" + "class Foo(object):\n" + " 'doc'\n" + " def __init__(self):\n" + " self.a = 10\n" + "\n" + "foo = Foo()\n" + "foo.new_field"; setContentsAndWaitReparseAndError(mod1Contents); TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length() - 1; PySelection ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); List<ICompletionProposal> props = waitForQuickFixProps(quickFix, ps, offset); try { findCompletion(props, "Create new_field field at Foo (pack1.pack2.mod1)").apply(editor.getISourceViewer(), '\n', 0, offset); String expected = "" + "print i\n" + "class Foo(object):\n" + " 'doc'\n" + " def __init__(self):\n" + " self.a = 10\n" + " self.new_field = None\n" + "\n" + "foo = Foo()\n" + "foo.new_field"; assertContentsEqual(expected, editor.getDocument().get()); } finally { editor.doRevertToSaved(); } } private void checkCreateFieldAtClass4() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents = "" + "print i\n" + "class Foo(object):\n" + " def bar(self):\n" + " self.new_field\n" + " def __init__(self):\n" + " self.a = 10" + ""; String secondPart = "ld\n" + " def __init__(self):\n" + " self.a = 10" + ""; setContentsAndWaitReparseAndError(mod1Contents); TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length() - secondPart.length(); PySelection ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); List<ICompletionProposal> props = waitForQuickFixProps(quickFix, ps, offset); try { findCompletion(props, "Create new_field field at Foo").apply(editor.getISourceViewer(), '\n', 0, offset); String expected = "" + "print i\n" + "class Foo(object):\n" + " def bar(self):\n" + " self.new_field\n" + " def __init__(self):\n" + " self.a = 10\n" + " self.new_field = None" + ""; assertContentsEqual(expected, editor.getDocument().get()); } finally { editor.doRevertToSaved(); } } private void checkCreateConstant() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents = "" + "print i\n" + "class Foo(object):\n" + " def bar(self):\n" + " self.BAR" + ""; setContentsAndWaitReparseAndError(mod1Contents); TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length(); PySelection ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); List<ICompletionProposal> props = waitForQuickFixProps(quickFix, ps, offset); try { findCompletion(props, "Create BAR constant at Foo").apply(editor.getISourceViewer(), '\n', 0, offset); String expected = "" + "print i\n" + "class Foo(object):\n" + "\n" + " BAR = None\n" + " def bar(self):\n" + " self.BAR" + ""; assertContentsEqual(expected, editor.getDocument().get()); } finally { editor.doRevertToSaved(); } } private void checkCreateFieldAtClass2() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents = "" + "print i\n" + "class Foo(object):\n" + " 'doc'\n" + " def __init__(self):\n" + " pass\n" + "\n" + "foo = Foo()\n" + "foo.new_field"; setContentsAndWaitReparseAndError(mod1Contents); TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length() - 1; PySelection ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); List<ICompletionProposal> props = waitForQuickFixProps(quickFix, ps, offset); try { findCompletion(props, "Create new_field field at Foo (pack1.pack2.mod1)").apply(editor.getISourceViewer(), '\n', 0, offset); String expected = "" + "print i\n" + "class Foo(object):\n" + " 'doc'\n" + " def __init__(self):\n" + " self.new_field = None\n" + //note we changed the pass for the field! "\n" + "foo = Foo()\n" + "foo.new_field"; assertContentsEqual(expected, editor.getDocument().get()); } finally { editor.doRevertToSaved(); } } private void checkCreateMethodAtClass2() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents = "" + "print i\n" + //just to have error on reparse. "class Foo(object):\n" + " 'doc'\n" + "\n" + "foo = Foo()\n" + "foo.Met1(param1=10)"; setContentsAndWaitReparseAndError(mod1Contents); TddCodeGenerationQuickFixParticipant quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length() - 1; PySelection ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); List<ICompletionProposal> props = waitForQuickFixProps(quickFix, ps, offset); try { findCompletion(props, "Create Met1 method at Foo (pack1.pack2.mod1)").apply(editor.getISourceViewer(), '\n', 0, offset); String expected = "" + "print i\n" + "class Foo(object):\n" + " 'doc'\n" + "\n" + " \n" + " def Met1(self, param1):\n" + " pass\n" + " \n" + " \n" + "\n" + "foo = Foo()\n" + "foo.Met1(param1=10)"; assertContentsEqual(expected, editor.getDocument().get()); } finally { editor.doRevertToSaved(); } } private void checkCreateClassWithParams() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; TddCodeGenerationQuickFixParticipant quickFix; PySelection ps; List<ICompletionProposal> props; mod1Contents = "Foo(call1(ueo), 'aa,bb', 10, cc)"; setContentsAndWaitReparseAndError(mod1Contents); quickFix = new TddCodeGenerationQuickFixParticipant(); ps = new PySelection(editor.getDocument(), 0); assertTrue(quickFix.isValid(ps, "", editor, 0)); props = quickFix.getProps(ps, PydevPlugin.getImageCache(), editor.getEditorFile(), editor.getPythonNature(), editor, 0); try { findCompletion(props, "Create Foo class").apply(editor.getISourceViewer(), '\n', 0, 0); assertContentsEqual("" + "class Foo(object):\n" + " \n" + " def __init__(self, call_1, param1, param2, cc):\n" + " pass\n" + "\n" + "\n" + "Foo(call1(ueo), 'aa,bb', 10, cc)" + "", editor.getDocument().get()); } finally { editor.doRevertToSaved(); } } private void checkCreateClassWithParams2() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; TddCodeGenerationQuickFixParticipant quickFix; PySelection ps; List<ICompletionProposal> props; mod1Contents = "Foo(a=10, b=20)"; setContentsAndWaitReparseAndError(mod1Contents); quickFix = new TddCodeGenerationQuickFixParticipant(); ps = new PySelection(editor.getDocument(), 0); assertTrue(quickFix.isValid(ps, "", editor, 0)); props = quickFix.getProps(ps, PydevPlugin.getImageCache(), editor.getEditorFile(), editor.getPythonNature(), editor, 0); try { findCompletion(props, "Create Foo class").apply(editor.getISourceViewer(), '\n', 0, 0); assertContentsEqual("" + "class Foo(object):\n" + " \n" + " def __init__(self, a, b):\n" + " pass\n" + "\n" + "\n" + "Foo(a=10, b=20)" + "", editor.getDocument().get()); } finally { editor.doRevertToSaved(); } } private void checkCreateClassInit() throws CoreException, BadLocationException, MisconfigurationException { baseCheckCreateClassInit("o(a=10, b=20".length()); } private void checkCreateClassInit2() throws CoreException, BadLocationException, MisconfigurationException { baseCheckCreateClassInit(0); } private void checkCreateClassInit3() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; TddCodeGenerationQuickFixParticipant quickFix; PySelection ps; List<ICompletionProposal> props; mod1Contents = "" + "print i\n" + //this is just so that we have an error (which we'll wait in the reparse -- even though we won't use it). "\n" + "class Foo:\n" + " 'comment'\n" + " def bar(self):\n" + " pass\n" + "Foo(a=10, b=20)"; setContentsAndWaitReparseAndError(mod1Contents); quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length(); ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); props = waitForQuickFixProps(quickFix, ps, offset); try { findCompletion(props, "Create Foo __init__ (pack1.pack2.mod1)").apply(editor.getISourceViewer(), '\n', 0, offset); assertContentsEqual("" + "print i\n" + "\n" + "class Foo:\n" + " 'comment'\n" + "\n" + " \n" + " def __init__(self, a, b):\n" + " pass\n" + " \n" + " \n" + " def bar(self):\n" + " pass\n" + "Foo(a=10, b=20)" + "", editor.getDocument().get()); } finally { editor.doRevertToSaved(); } } private void baseCheckCreateClassInit(int minusOffset) throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; TddCodeGenerationQuickFixParticipant quickFix; PySelection ps; List<ICompletionProposal> props; mod1Contents = "" + "print i\n" + //this is just so that we have an error (which we'll wait in the reparse -- even though we won't use it). "\n" + "class Foo:\n" + " 'comment'\n" + "\n" + "Foo(a=10, b=20)"; setContentsAndWaitReparseAndError(mod1Contents); quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length() - minusOffset; ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); props = waitForQuickFixProps(quickFix, ps, offset); try { findCompletion(props, "Create Foo __init__ (pack1.pack2.mod1)").apply(editor.getISourceViewer(), '\n', 0, offset); assertContentsEqual("" + "print i\n" + "\n" + "class Foo:\n" + " 'comment'\n" + "\n" + " \n" + " def __init__(self, a, b):\n" + " pass\n" + " \n" + " \n" + "\n" + "Foo(a=10, b=20)" + "", editor.getDocument().get()); } finally { editor.doRevertToSaved(); } } private void checkCreateClassAtOtherModule() throws CoreException, BadLocationException, MisconfigurationException { String mod1Contents; TddCodeGenerationQuickFixParticipant quickFix; PySelection ps; List<ICompletionProposal> props; IFile mod2 = initFile.getParent().getFile(new Path("other_module.py")); mod2.create(new ByteArrayInputStream("".getBytes()), true, null); PyEdit editor2 = (PyEdit) PyOpenEditor.doOpenEditor(mod2); try { goToManual(AnalysisRequestsTestWorkbench.TIME_FOR_ANALYSIS); //give it a bit more time... mod1Contents = "" + "import other_module\n" + "other_module.Foo"; setContentsAndWaitReparseAndError(mod1Contents); quickFix = new TddCodeGenerationQuickFixParticipant(); int offset = mod1Contents.length() - 1; ps = new PySelection(editor.getDocument(), offset); assertTrue(quickFix.isValid(ps, "", editor, offset)); props = waitForQuickFixProps(quickFix, ps, offset); findCompletion(props, "Create Foo class at other_module.py").apply(editor.getISourceViewer(), '\n', 0, offset); assertContentsEqual("" + "class Foo(object):\n" + " pass\n" + "\n" + "\n" + "", editor2.getDocument() .get()); } finally { editor2.close(false); mod2.delete(true, null); } } private ICompletionProposalExtension2 findCompletion(List<ICompletionProposal> props, String expectedCompletion) { return findCompletion(props, expectedCompletion, true); } private ICompletionProposalExtension2 findCompletion(List<ICompletionProposal> props, String expectedCompletion, boolean throwException) { List<String> buf = new ArrayList<String>(1 + (2 * props.size())); buf.add("Available:"); for (ICompletionProposal iCompletionProposal : props) { if (iCompletionProposal.getDisplayString().equals(expectedCompletion)) { ICompletionProposalExtension2 p = (ICompletionProposalExtension2) iCompletionProposal; return p; } buf.add("\n"); buf.add(iCompletionProposal.getDisplayString()); } if (throwException) { throw new AssertionError("Could not find completion: " + expectedCompletion + "\n" + com.aptana.shared_core.string.StringUtils.join("\n", buf)); } return null; } private void setContentsAndWaitReparseAndError(String mod1Contents) throws CoreException { setContentsAndWaitReparseAndError(mod1Contents, true); } private void setContentsAndWaitReparseAndError(String mod1Contents, boolean waitForError) throws CoreException { setFileContents(mod1Contents); parser = editor.getParser(); parser.addParseListener(this); ICallback<Boolean, Object> parseHappenedCondition = getParseHappenedCondition(); while (!parser.forceReparse(new Tuple<String, Boolean>(AnalysisParserObserver.ANALYSIS_PARSER_OBSERVER_FORCE, true))) { goToManual(50); } goToIdleLoopUntilCondition(parseHappenedCondition); if (waitForError) { goToIdleLoopUntilCondition(getHasBothErrorMarkersCondition(editor.getIFile())); } goToManual(500); } private void assertContentsEqual(String expected, String generated) { assertEquals(StringUtils.replaceNewLines(expected, "\n"), StringUtils.replaceNewLines(generated, "\n")); } public void parserChanged(ISimpleNode root, IAdaptable file, IDocument doc) { parser.removeParseListener(this); this.parserNotified += 1; } public void parserError(Throwable error, IAdaptable file, IDocument doc) { parser.removeParseListener(this); this.parserNotified += 1; } private ICallback<Boolean, Object> getParseHappenedCondition() { final int currentNotified = this.parserNotified; return new ICallback<Boolean, Object>() { public Boolean call(Object arg) { return parserNotified > currentNotified; } }; } /** * Callback that'll check if there are error markers in the mod1.py resource */ private ICallback<Boolean, Object> getHasBothErrorMarkersCondition(final IFile file) { return new ICallback<Boolean, Object>() { public Boolean call(Object arg) { try { //must have both problems: syntax and analysis error!! IMarker[] markers = file.findMarkers(AnalysisRunner.PYDEV_ANALYSIS_PROBLEM_MARKER, false, IResource.DEPTH_ZERO); return markers.length > 0; } catch (CoreException e) { throw new RuntimeException(e); } } }; } }