| /*******************************************************************************
|
| * Copyright (c) 2012, 2017 IBM Corporation and others.
|
| * All rights reserved. This program and the accompanying materials
|
| * are made available under the terms of the Eclipse Public License 2.0
|
| * which accompanies this distribution, and is available at
|
| * https://www.eclipse.org/legal/epl-2.0/
|
| *
|
| * SPDX-License-Identifier: EPL-2.0
|
| *
|
| * Contributors:
|
| * IBM Corporation - initial API and implementation
|
| *******************************************************************************/ |
| package org.eclipse.wst.jsdt.web.ui.tests.internal;
|
|
|
| import java.util.HashMap;
|
| import java.util.Iterator;
|
| import java.util.Map;
|
|
|
| import junit.extensions.TestSetup;
|
| import junit.framework.Assert;
|
| import junit.framework.Test;
|
|
|
| import org.eclipse.core.resources.IFile;
|
| import org.eclipse.core.resources.IProject;
|
| import org.eclipse.core.resources.IWorkspaceRoot;
|
| import org.eclipse.core.resources.ResourcesPlugin;
|
| import org.eclipse.core.runtime.IPath;
|
| import org.eclipse.core.runtime.NullProgressMonitor;
|
| import org.eclipse.jface.text.IDocument;
|
| import org.eclipse.ui.IEditorPart;
|
| import org.eclipse.ui.IWorkbenchPage;
|
| import org.eclipse.ui.IWorkbenchWindow;
|
| import org.eclipse.ui.PlatformUI;
|
| import org.eclipse.ui.ide.IDE;
|
| import org.eclipse.ui.texteditor.AbstractTextEditor;
|
| import org.eclipse.ui.texteditor.ITextEditor;
|
| import org.eclipse.wst.jsdt.internal.core.JavaModelManager;
|
| import org.eclipse.wst.jsdt.internal.core.search.indexing.IndexManager;
|
|
|
|
|
| /**
|
| * <p>Sets up a test project.</p>
|
| *
|
| * @see org.eclipse.wst.jsdt.ui.tests.utils
|
| * @see org.eclipse.wst.jsdt.web.ui.tests.internal
|
| */
|
| public class TestProjectSetup extends TestSetup {
|
| /** preference for ignoring WTP UI */
|
| private static final String WTP_AUTOTEST_NONINTERACTIVE = "wtp.autotest.noninteractive";
|
|
|
| /** The location of the testing files */
|
| private static final String TESTING_RESOURCES_DIR = "testFiles";
|
|
|
| /** previous value for hiding WTP UI */
|
| private String fPreviousWTPAutoTestNonInteractivePropValue = null;
|
|
|
| /** Name of the project the tests use */
|
| private final String fProjectName;
|
|
|
| /** The project that the tests use */
|
| private IProject fProject;
|
|
|
| /** The root directory to start with when looking for files */
|
| private final String fRootDirictory;
|
|
|
| /**
|
| * <p>
|
| * <code>true</code> if should delete project on tear down,
|
| * <code>false</code> to leave it for other tests to use.
|
| * </p>
|
| */
|
| private final boolean fDeleteOnTearDown;
|
|
|
| /**
|
| * Used to keep track of the already open editors so that the tests don't go through
|
| * the trouble of opening the same editors over and over again
|
| */
|
| private Map fFileToEditorMap = new HashMap();
|
|
|
| /**
|
| * <p>
|
| * <b>NOTE:</b> will not delete the project on tear down so other tests can use it.
|
| * </p>
|
| *
|
| * @param test
|
| * do setup for the given test
|
| * @param projectName
|
| * name of the project to set up
|
| * @param rootDirectory
|
| * path to the root directory to look for all files under, or <code>null</code> if
|
| * look directly under project root
|
| */
|
| public TestProjectSetup(Test test, String projectName, String rootDirectory) {
|
| super(test);
|
|
|
| this.fProjectName = projectName;
|
| this.fRootDirictory = rootDirectory;
|
| this.fDeleteOnTearDown = false;
|
| }
|
|
|
| /**
|
| * @param test
|
| * do setup for the given test
|
| * @param projectName
|
| * name of the project to set up
|
| * @param rootDirectory
|
| * path to the root directory to look for all files under, or <code>null</code> if
|
| * look directly under project root
|
| * @param deleteOnTearDown
|
| * <code>true</code> if should delete project on tear down, <code>false</code> to
|
| * leave it for other tests to use.
|
| */
|
| public TestProjectSetup(Test test, String projectName, String rootDirectory, boolean deleteOnTearDown) {
|
| super(test);
|
|
|
| this.fProjectName = projectName;
|
| this.fRootDirictory = rootDirectory;
|
| this.fDeleteOnTearDown = deleteOnTearDown;
|
| }
|
|
|
| /**
|
| * @return {@link IProject} that was setup
|
| */
|
| public IProject getProject() {
|
| return this.fProject;
|
| }
|
|
|
| /**
|
| * <p>
|
| * Given a <code>file</code> get an editor for it. If an editor has already been retrieved for
|
| * the given <code>file</code> then return the same already open editor.
|
| * </p>
|
| *
|
| * <p>
|
| * When opening the editor it will also standardized the line endings to <code>\n</code>
|
| * </p>
|
| *
|
| * @param file
|
| * open and return an editor for this
|
| * @return <code>StructuredTextEditor</code> opened from the given <code>file</code>
|
| */
|
| public AbstractTextEditor getEditor(IFile file) {
|
| AbstractTextEditor editor = (AbstractTextEditor) fFileToEditorMap.get(file);
|
|
|
| if(editor == null) {
|
| try {
|
| IWorkbenchWindow workbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
|
| IWorkbenchPage page = workbenchWindow.getActivePage();
|
| IEditorPart editorPart = null;
|
| if(file.getFileExtension().equals("js")) {
|
| editorPart = IDE.openEditor(page, file, true, true);
|
| } else if(file.getFileExtension().equals("html")) {
|
| editorPart = IDE.openEditor(page, file, "org.eclipse.wst.html.core.htmlsource.source", true);
|
| }
|
|
|
| if(editorPart instanceof AbstractTextEditor) {
|
| editor = (AbstractTextEditor) editorPart;
|
| } else {
|
| Assert.fail("Unable to open structured text editor");
|
| }
|
|
|
| if(editor != null) {
|
| standardizeLineEndings(editor);
|
| fFileToEditorMap.put(file, editor);
|
| } else {
|
| Assert.fail("Could not open editor for " + file);
|
| }
|
| } catch(Exception e) {
|
| Assert.fail("Could not open editor for " + file + " exception: " + e.getMessage());
|
| }
|
| }
|
|
|
| return editor;
|
| }
|
|
|
| /**
|
| * <p>
|
| * Given a file path in the test project attempts to get an <code>IFile</code> for it, if the
|
| * file doesn't exist the test fails.
|
| * </p>
|
| *
|
| * @param path
|
| * the name of the file to get
|
| *
|
| * @return the {@link IFile} associated with the given file path
|
| */
|
| public IFile getFile(String path) {
|
| IFile file = null;
|
|
|
| if(this.fRootDirictory != null) {
|
| file = this.fProject.getFile(this.fRootDirictory + IPath.SEPARATOR + path);
|
| } else {
|
| file = this.fProject.getFile(path);
|
| }
|
|
|
| Assert.assertTrue("Test file " + file + " can not be found", file.exists());
|
|
|
| return file;
|
| }
|
|
|
| /**
|
| * <p>
|
| * Edits the file given by the fileName. The number of characters indicated by length are
|
| * replaced by the given text beginning at the character located at the given line number and
|
| * the line character offset.
|
| * </p>
|
| *
|
| * @param fileName
|
| * @param lineNum
|
| * @param lineRelativeCharOffset
|
| * @param length
|
| * @param text
|
| * @throws Exception
|
| */
|
| public void editFile(String fileName, int lineNum, int lineRelativeCharOffset, int length, String text)
|
| throws Exception {
|
|
|
| IFile file = this.getFile(fileName);
|
| AbstractTextEditor editor = this.getEditor(file);
|
| IDocument doc = editor.getDocumentProvider().getDocument(editor.getEditorInput());
|
|
|
| int offset = doc.getLineOffset(lineNum) + lineRelativeCharOffset;
|
| doc.replace(offset, length, text);
|
|
|
| waitForIndexManager();
|
| }
|
|
|
| /**
|
| * <p>
|
| * This is run Once while the test is being setUp for all the tests.
|
| * </p>
|
| * <p>
|
| * Designed to be overridden by content assist test suite Implementers to do additional test
|
| * setup.
|
| * </p>
|
| *
|
| */
|
| public void additionalSetUp() throws Exception {
|
| // default do nothing
|
| }
|
|
|
| /**
|
| * <p>
|
| * This is run once before all of the tests
|
| * </p>
|
| *
|
| * @see junit.extensions.TestSetup#setUp()
|
| */
|
| public final void setUp() throws Exception {
|
| // setup properties
|
| String noninteractive = System.getProperty(WTP_AUTOTEST_NONINTERACTIVE);
|
| if(noninteractive != null) {
|
| fPreviousWTPAutoTestNonInteractivePropValue = noninteractive;
|
| } else {
|
| fPreviousWTPAutoTestNonInteractivePropValue = "false";
|
| }
|
| System.setProperty(WTP_AUTOTEST_NONINTERACTIVE, "true");
|
|
|
| // get project
|
| IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
|
| fProject = root.getProject(this.fProjectName);
|
|
|
| // setup project if it is not yet setup
|
| if(fProject == null || !fProject.exists()) {
|
| fProject = ProjectUtil.createProject(this.fProjectName, null, null);
|
| ProjectUtil.copyBundleEntriesIntoWorkspace(TESTING_RESOURCES_DIR + IPath.SEPARATOR + this.fProjectName,
|
| IPath.SEPARATOR + this.fProjectName);
|
| }
|
|
|
| // run any additional test setup
|
| this.additionalSetUp();
|
|
|
| // give the workspace a second to settle before running tests
|
| Thread.sleep(1000);
|
| waitForIndexManager();
|
| }
|
|
|
| /**
|
| * <p>
|
| * This is run once after all of the tests have been run
|
| * </p>
|
| *
|
| * @see junit.extensions.TestSetup#tearDown()
|
| */
|
| public void tearDown() throws Exception {
|
| // close out the editors
|
| Iterator iter = fFileToEditorMap.values().iterator();
|
| while(iter.hasNext()) {
|
| AbstractTextEditor editor = (AbstractTextEditor) iter.next();
|
| PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().closeEditor(editor, false);
|
| }
|
| this.fFileToEditorMap.clear();
|
|
|
| //delete the project
|
| if(this.fDeleteOnTearDown) {
|
| this.fProject.delete(true, new NullProgressMonitor());
|
| }
|
|
|
| // restore properties
|
| if(fPreviousWTPAutoTestNonInteractivePropValue != null) {
|
| System.setProperty(WTP_AUTOTEST_NONINTERACTIVE, fPreviousWTPAutoTestNonInteractivePropValue);
|
| }
|
| }
|
|
|
| /**
|
| * <p>
|
| * Line endings can be an issue when running tests on different OSs. This function standardizes
|
| * the line endings to use <code>\n</code>
|
| * </p>
|
| *
|
| * <p>
|
| * It will get the text from the given editor, change the line endings, and then save the editor
|
| * </p>
|
| *
|
| * @param editor
|
| * standardize the line endings of the text presented in this
|
| * editor.
|
| */
|
| private static void standardizeLineEndings(ITextEditor editor) {
|
| IDocument doc = editor.getDocumentProvider().getDocument(editor.getEditorInput());
|
| String contents = doc.get();
|
| contents = StringUtils.replace(contents, "\r\n", "\n");
|
| contents = StringUtils.replace(contents, "\r", "\n");
|
| doc.set(contents);
|
| }
|
|
|
| /**
|
| * <p>
|
| * Wait for the index manager with a time out of 10 seconds.
|
| * </p>
|
| */
|
| private static void waitForIndexManager() {
|
| waitForIndexManager(10000);
|
| }
|
|
|
| /**
|
| * <p>
|
| * Wait for the index manager for the given max time.
|
| * </p>
|
| *
|
| * @param max
|
| * maximum amount of time to wait for the index manager
|
| */
|
| private static void waitForIndexManager(long max) {
|
| // Wait for the end of indexing
|
| IndexManager indexManager = JavaModelManager.getJavaModelManager().getIndexManager();
|
| long maxWaits = max / 10;
|
| while (indexManager.awaitingJobsCount() > 0 && maxWaits-- > 0) {
|
| try {
|
| Thread.sleep(10);
|
| }
|
| catch (InterruptedException e) {
|
| return;
|
| }
|
| }
|
| }
|
| } |