/******************************************************************************* * Copyright (c) 2017 Alex Xu and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Alex Xu - initial API and implementation *******************************************************************************/ package org.eclipse.php.ui.tests.editor; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.nio.file.Paths; import java.util.LinkedHashMap; import java.util.Map; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.Path; import org.eclipse.php.core.PHPVersion; import org.eclipse.php.core.tests.PDTTUtils; import org.eclipse.php.core.tests.PdttFile; import org.eclipse.php.core.tests.TestSuiteWatcher; import org.eclipse.php.core.tests.TestUtils; import org.eclipse.php.core.tests.runner.AbstractPDTTRunner.Context; import org.eclipse.php.core.tests.runner.PDTTList; import org.eclipse.php.core.tests.runner.PDTTList.AfterList; import org.eclipse.php.core.tests.runner.PDTTList.BeforeList; import org.eclipse.php.core.tests.runner.PDTTList.Parameters; import org.eclipse.php.internal.ui.editor.PHPStructuredEditor; import org.eclipse.php.ui.tests.PHPTestEditor; import org.eclipse.php.ui.tests.PHPUiTests; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.events.VerifyEvent; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.part.FileEditorInput; import org.eclipse.wst.sse.ui.internal.StructuredTextViewer; import org.junit.ClassRule; import org.junit.Test; import org.junit.rules.TestWatcher; import org.junit.runner.RunWith; import org.osgi.framework.Bundle; @SuppressWarnings("restriction") @RunWith(PDTTList.class) public class BracketInserterTests { @ClassRule public static TestWatcher watcher = new TestSuiteWatcher(); private IProject project; private IFile testFile; private PHPVersion phpVersion; private PHPStructuredEditor fEditor; @Parameters public static final Map<PHPVersion, String[]> TESTS = new LinkedHashMap<PHPVersion, String[]>(); public static final String DEFAULT_CURSOR = "|"; static { TESTS.put(PHPVersion.PHP7_1, new String[] { "/workspace/bracket-inserter" }); }; @Context public static Bundle getBundle() { return PHPUiTests.getDefault().getBundle(); } public BracketInserterTests(PHPVersion version, String[] fileNames) { this.phpVersion = version; } @BeforeList public void setUpSuite() throws Exception { project = TestUtils.createProject("Bracket_Inserter_" + this.phpVersion); ResourcesPlugin.getWorkspace().getRoot().getProject("Bracket_Inserter_" + this.phpVersion); } @AfterList public void tearDownSuite() throws Exception { TestUtils.deleteProject(project); } @Test public void typing(String fileName) throws Exception { final PdttFile pdttFile = new PdttFile(PHPUiTests.getDefault().getBundle(), fileName); doTyping(pdttFile); } private void doTyping(final PdttFile pdttFile) throws Exception { final String pdttFileData = pdttFile.getFile(); final String cursor = getCursor(pdttFile) != null ? getCursor(pdttFile) : DEFAULT_CURSOR; final int offset = pdttFileData.lastIndexOf(cursor); final String data = pdttFileData.substring(0, offset) + pdttFileData.substring(offset + 1); final Exception[] exception = new Exception[1]; final String[] result = new String[1]; // Wait for UI Display.getDefault().syncExec(new Runnable() { @Override public void run() { try { pdttFile.applyPreferences(); String fileName = Paths.get(pdttFile.getFileName()).getFileName().toString(); fileName = fileName.substring(0, fileName.indexOf('.')) + ".php"; char c; if (pdttFile.getOther() != null && !pdttFile.getOther().isEmpty()) { c = pdttFile.getOther().charAt(0); } else { c = '\n'; } createFiles(data, fileName); openEditor(); result[0] = executeTyping(offset, c); closeEditor(); deleteFiles(); } catch (Exception e) { exception[0] = e; } } }); if (exception[0] != null) throw exception[0]; PDTTUtils.assertContents(pdttFile.getExpected(), result[0]); } private void deleteFiles() throws Exception { if (testFile != null) { TestUtils.deleteFile(testFile); } } private String getCursor(PdttFile pdttFile) { Map<String, String> config = pdttFile.getConfig(); return config.get("cursor"); } private void openEditor() throws Exception { IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); IWorkbenchPage page = workbenchWindow.getActivePage(); IEditorInput input = new FileEditorInput(testFile); /* * This should take care of testing init, createPartControl, * beginBackgroundOperation, endBackgroundOperation methods */ IEditorPart part = page.openEditor(input, PHPTestEditor.ID, false); if (part instanceof PHPStructuredEditor) { fEditor = (PHPStructuredEditor) part; } else { assertTrue("Unable to open php editor", false); } } private void closeEditor() { fEditor.doSave(null); fEditor.getSite().getPage().closeEditor(fEditor, false); fEditor = null; } private String executeTyping(int offset, char character) { StructuredTextViewer viewer = null; Display display = Display.getDefault(); long timeout = System.currentTimeMillis() + 3000; while ((System.currentTimeMillis() < timeout) && ((viewer = fEditor.getTextViewer()) == null)) { if (!display.readAndDispatch()) { display.sleep(); } } if (viewer == null) { fail("fEditor.getTextViewer() returns null for file " + testFile.getFullPath() + "(" + testFile.getLocation() + ")"); } StyledText textWidget = viewer.getTextWidget(); textWidget.setCaretOffset(offset); String oldContent = fEditor.getDocument().get(); Event e = new Event(); e.character = character; e.display = Display.getDefault(); e.type = SWT.KeyDown; e.widget = textWidget; VerifyEvent ve = new VerifyEvent(e); // Workaround,need to find a better way to test it fEditor.getfBracketInserter().verifyKey(ve); String newContent = fEditor.getDocument().get(); if (oldContent.equals(newContent)) { // workaround, while the BracketInserter didn't close bracket, // insert the character at cursor to get right content textWidget.insert(String.valueOf(character)); return fEditor.getDocument().get(); } return newContent; } private void createFiles(String content, String fileName) throws Exception { testFile = TestUtils.createFile(project, new Path(fileName).lastSegment(), content); TestUtils.waitForIndexer(); } }