Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.
PDT Dev2Dev - Unit tests for CodeDataResolver and ContentAssistSupport
About a month ago I was honored to fix several bugs related to code links in the PHP Editor, which caused me to develop a light and simple way of testing CodeDataResolver class and yesterday I ported similar solution into test of ContentAssistSupport.
Getting Offset
The main problem in testing editor related issues is you should operate with offsets, which are not visually exposed. So I built a trivial utility Utils.getOffset() which translates the visual line and position for the specified document to the absolute offset. The utility's declaration is:
public class lib.org.eclipse.php.test.headless.core.Utils { public static int getOffset(int line, int offsetAtLine, IDocument testDocument) throws Exception; }
It means you can put 2 numbers you see in bottom of your eclipse editor, decrement them by 1 and receive the offset in the document. The only incomfortability of working with the utility is that there is no way to work with hard tabs (\t).
Writing Tests
Since we have the utility, we can easily wrap it with the needed functionality, like:
public class org.eclipse.php.test.gui.ui.editor.contentassist.TestContentAssistSupport { private ICompletionProposal[] getProposals(int line, int position) throws Exception { IDocument document = viewer.getDocument(); int offset = Utils.getOffset(line, position, document); viewer.setSelectedRange(offset, 0); return processor.computeCompletionProposals(viewer, offset); } }
and
public class org.eclipse.php.test.headless.core.util.TestCodeDataResolver { private CodeData[] resolve(int line, int position) throws Exception { final int offset = Utils.getOffset(line, position, testDocument); return resolve(offset); } }
Afterwards, you should just edit the tested .php file, see at which point do you want to get completion/link, write down the point location and create the tests, like:
13:// test method completion after literal operator: 14:$var->doSomething() and $var->doSomething();
public void testMethodAfterLiteralOperator() throws Exception { ICompletionProposal[] computeCompletionProposals = getProposals(13, 30); Assert.assertEquals(1, computeCompletionProposals.length); Assert.assertTrue(computeCompletionProposals[0].getDisplayString().startsWith("doSomething()")); }
or
46:// test this reference: 47:class Class6 { 48: function function1() { 49: $this->function1(); 50: }
public void testThisReference() throws Exception { final CodeData[] codeData = resolve(48, 12); Assert.assertEquals(1, codeData.length); Assert.assertTrue(codeData[0] instanceof PHPClassData); Assert.assertEquals("Class6", codeData[0].getName()); final int modifiers = ((PHPClassData)codeData[0]).getModifiers(); Assert.assertEquals(0, modifiers & PHPModifier.INTERFACE); }
That's all folks. --Seva Lapsha 09:40, 21 October 2007 (EDT)