/* * Copyright 2010 The Rabbit Eclipse Plug-in Project * * 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 rabbit.tracking.internal.trackers; import rabbit.data.store.model.ContinuousEvent; import rabbit.tracking.internal.IdleDetector; import rabbit.tracking.internal.TrackingPlugin; import rabbit.tracking.internal.trackers.AbstractPartTracker; import rabbit.tracking.internal.util.WorkbenchUtil; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; 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.CoreException; import org.eclipse.jdt.ui.actions.OpenJavaBrowsingPerspectiveAction; import org.eclipse.ui.IEditorDescriptor; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.WorkbenchException; import org.eclipse.ui.part.FileEditorInput; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Observable; /** * Test {@link AbstractPartTracker} */ public abstract class AbstractPartTrackerTest<E extends ContinuousEvent> extends AbstractTrackerTest<E> { protected AbstractPartTracker<E> tracker; @BeforeClass public static void setUpBeforeClass() { new OpenJavaBrowsingPerspectiveAction().run(); } @Before public void setup() { tracker = createTracker(); } @Test public void testChangeEditor() throws Exception { IEditorPart editor = openNewEditor(); long preStart = System.currentTimeMillis(); tracker.setEnabled(true); long postStart = System.currentTimeMillis(); Thread.sleep(20); long preEnd = System.currentTimeMillis(); openNewEditor(); long postEnd = System.currentTimeMillis(); assertEquals(1, tracker.getData().size()); E event = tracker.getData().iterator().next(); assertTrue(hasSamePart(event, editor)); long start = event.getInterval().getStartMillis(); long end = event.getInterval().getEndMillis(); checkTime(preStart, start, postStart, preEnd, end, postEnd); } @Test public void testCloseEditor() throws Exception { IEditorPart editor = openNewEditor(); long preStart = System.currentTimeMillis(); tracker.setEnabled(true); long postStart = System.currentTimeMillis(); assertTrue(tracker.getData().isEmpty()); Thread.sleep(20); long preEnd = System.currentTimeMillis(); editor.getEditorSite().getPage().closeEditor(editor, false); long postEnd = System.currentTimeMillis(); assertEquals(1, tracker.getData().size()); E event = tracker.getData().iterator().next(); assertTrue(hasSamePart(event, editor)); long start = event.getInterval().getStartMillis(); long end = event.getInterval().getEndMillis(); checkTime(preStart, start, postStart, preEnd, end, postEnd); } @Test public void testCloseWindow() throws Exception { IWorkbenchWindow win = openNewWindow(); IEditorPart editor = openNewEditor(); long preStart = System.currentTimeMillis(); tracker.setEnabled(true); long postStart = System.currentTimeMillis(); assertTrue(tracker.getData().isEmpty()); Thread.sleep(20); long preEnd = System.currentTimeMillis(); win.close(); long postEnd = System.currentTimeMillis(); assertEquals(1, tracker.getData().size()); E event = tracker.getData().iterator().next(); assertTrue(hasSamePart(event, editor)); long start = event.getInterval().getStartMillis(); long end = event.getInterval().getEndMillis(); checkTime(preStart, start, postStart, preEnd, end, postEnd); } @Test public void testDisabled() throws Exception { tracker.setEnabled(false); // Test IPerspectiveListener. Thread.sleep(30); openNewEditor(); assertTrue(tracker.getData().isEmpty()); // Test IWindowListener. Thread.sleep(20); IWorkbenchWindow win = openNewWindow(); assertTrue(tracker.getData().isEmpty()); win.close(); // Test IdleDetector Thread.sleep(20); callIdleDetectorToNotify(); assertTrue(tracker.getData().isEmpty()); } /** * Test when the tracker is set to be enabled, if there is no active workbench * window, no data will be recorded. */ @Test public void testEnable_noActiveWorkbenchWindow() throws Exception { IWorkbenchWindow win = WorkbenchUtil.getActiveWindow(); win.getShell().setMinimized(true); try { tracker.setEnabled(true); Thread.sleep(20); tracker.setEnabled(false); assertEquals(0, tracker.getData().size()); } finally { win.getShell().setMinimized(false); } } @Test public void testEnableThenDisable() throws Exception { IEditorPart editor = openNewEditor(); long preStart = System.currentTimeMillis(); tracker.setEnabled(true); long postStart = System.currentTimeMillis(); Thread.sleep(20); long preEnd = System.currentTimeMillis(); tracker.setEnabled(false); long postEnd = System.currentTimeMillis(); assertEquals(1, tracker.getData().size()); E event = tracker.getData().iterator().next(); assertTrue(hasSamePart(event, editor)); long start = event.getInterval().getStartMillis(); long end = event.getInterval().getEndMillis(); checkTime(preStart, start, postStart, preEnd, end, postEnd); } @Test public void testIdleDetector() throws Exception { IEditorPart editor = openNewEditor(); long preStart = System.currentTimeMillis(); tracker.setEnabled(true); long postStart = System.currentTimeMillis(); Thread.sleep(20); long preEnd = System.currentTimeMillis(); callIdleDetectorToNotify(); long postEnd = System.currentTimeMillis(); assertEquals(1, tracker.getData().size()); E event = tracker.getData().iterator().next(); assertTrue(hasSamePart(event, editor)); long start = event.getInterval().getStartMillis(); long end = event.getInterval().getEndMillis(); checkTime(preStart, start, postStart, preEnd, end, postEnd); } @Test public void testObserverIsAdded() { IdleDetector dt = TrackingPlugin.getDefault().getIdleDetector(); tracker.setEnabled(false); // It should remove itself from the observable int count = dt.countObservers(); tracker.setEnabled(true); // It should add itself to the observable assertEquals(count + 1, dt.countObservers()); } @Test public void testWindowDeactivated() throws Exception { IEditorPart editor = openNewEditor(); IWorkbenchWindow win = null; try { long preStart = System.currentTimeMillis(); tracker.setEnabled(true); long postStart = System.currentTimeMillis(); assertEquals(0, tracker.getData().size()); Thread.sleep(30); long preEnd = System.currentTimeMillis(); win = openNewWindow(); long postEnd = System.currentTimeMillis(); assertEquals(1, tracker.getData().size()); E event = tracker.getData().iterator().next(); assertTrue(hasSamePart(event, editor)); long start = event.getInterval().getStartMillis(); long end = event.getInterval().getEndMillis(); checkTime(preStart, start, postStart, preEnd, end, postEnd); } finally { if (win != null) { win.close(); } } } protected void callIdleDetectorToNotify() throws Exception { Field isActive = IdleDetector.class.getDeclaredField("isActive"); isActive.setAccessible(true); Method setChanged = Observable.class.getDeclaredMethod("setChanged"); setChanged.setAccessible(true); Method notifyObservers = Observable.class.getDeclaredMethod("notifyObservers"); notifyObservers.setAccessible(true); IdleDetector detector = TrackingPlugin.getDefault().getIdleDetector(); detector.setRunning(true); isActive.set(detector, false); setChanged.invoke(detector); notifyObservers.invoke(detector); detector.setRunning(false); } @Override protected abstract E createEvent(); @Override protected abstract AbstractPartTracker<E> createTracker(); /** * Gets a file for testing. * * @return A test file. */ protected IFile getFileForTesting() throws CoreException, FileNotFoundException, IOException { IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IProject project = root.getProject("Tmp"); if (!project.exists()) { project.create(null); } if (!project.isOpen()) { project.open(null); } IFile file = project.getFile(System.nanoTime() + ".txt"); if (!file.exists()) { File tmpFile = File.createTempFile("tmp", "txt"); FileInputStream stream = new FileInputStream(tmpFile); file.create(stream, false, null); stream.close(); } return file; } /** * Test that the event is recorded for the given part. * * @param event The event. * @param part The part expected. * @return True if the event is recorded for the given part, false if the * event is recorded for a different part. */ protected abstract boolean hasSamePart(E event, IWorkbenchPart part); /** * Opens a new editor. * * @return The newly opened editor. */ protected IEditorPart openNewEditor() throws Exception { IEditorDescriptor desc = PlatformUI.getWorkbench().getEditorRegistry().getDefaultEditor( "a.txt"); return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().openEditor( new FileEditorInput(getFileForTesting()), desc.getId(), true); } /** * Opens a new window. * * @return The newly opened window. */ protected IWorkbenchWindow openNewWindow() throws WorkbenchException { return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getWorkbench().openWorkbenchWindow( null); } }