blob: b81a4c196616fa7a57304bc2de2c412592735f52 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004 IBM Corporation 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jface.tests.images;
import junit.framework.Assert;
import junit.framework.TestCase;
import org.eclipse.jface.resource.ColorDescriptor;
import org.eclipse.jface.resource.DeviceResourceDescriptor;
import org.eclipse.jface.resource.DeviceResourceException;
import org.eclipse.jface.resource.DeviceResourceManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.LocalResourceManager;
import org.eclipse.jface.resource.ResourceManager;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.plugin.AbstractUIPlugin;
/**
* @since 3.1
*/
public class ResourceManagerTest extends TestCase {
private DeviceResourceDescriptor[] descriptors;
private Image testImage;
private Image testImage2;
private Color testColor;
private Color testColor2;
private int numDupes;
private DeviceResourceManager globalResourceManager;
private static ImageDescriptor getImage(String path) {
return AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.ui.tests", path);
}
private static final class TestDescriptor extends DeviceResourceDescriptor {
DeviceResourceDescriptor toWrap;
public static int refCount = 0;
public TestDescriptor(DeviceResourceDescriptor toWrap) {
this.toWrap = toWrap;
}
/* (non-Javadoc)
* @see org.eclipse.jface.resource.DeviceResourceDescriptor#createResource(org.eclipse.swt.graphics.Device)
*/
public Object createResource(Device device) throws DeviceResourceException {
Object result = toWrap.createResource(device);
refCount++;
return result;
}
/* (non-Javadoc)
* @see org.eclipse.jface.resource.DeviceResourceDescriptor#destroyResource(java.lang.Object)
*/
public void destroyResource(Object previouslyCreatedObject) {
refCount--;
toWrap.destroyResource(previouslyCreatedObject);
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object arg0) {
if (arg0 instanceof TestDescriptor) {
TestDescriptor td = (TestDescriptor)arg0;
return td.toWrap.equals(toWrap);
}
return false;
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return toWrap.hashCode();
}
}
/* (non-Javadoc)
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
super.setUp();
TestDescriptor.refCount = 0;
Display display = Display.getCurrent();
globalResourceManager = new DeviceResourceManager(display);
testImage = getImage("icons/anything.gif").createImage(display);
testImage2 = getImage("icons/binary_co.gif").createImage(display);
testColor = new Color(display, new RGB(10, 40, 20));
testColor2 = new Color(display, new RGB(230, 100, 26));
// Array of resource descriptors containing at least one duplicate of each type.
// If you modify this array, be sure to adjust numDupes as well. Note that some
// tests index the array directly, so it is a good idea to always add to this
// array rather than remove from it.
descriptors = new DeviceResourceDescriptor[] {
new TestDescriptor(getImage("icons/anything.gif")),
new TestDescriptor(getImage("icons/anything.gif")),
new TestDescriptor(getImage("icons/binary_co.gif")),
new TestDescriptor(getImage("icons/binary_co.gif")),
new TestDescriptor(getImage("icons/mockeditorpart1.gif")),
new TestDescriptor(getImage("icons/view.gif")), // 5
new TestDescriptor(ImageDescriptor.createFromImage(testImage2)),
new TestDescriptor(ImageDescriptor.createFromImage(testImage)),
new TestDescriptor(ImageDescriptor.createFromImage(testImage)),
new TestDescriptor(ImageDescriptor.createFromImage(testImage, display)),
new TestDescriptor(ImageDescriptor.createFromImage(testImage, display)), // 10
new TestDescriptor(ImageDescriptor.createFromImage(testImage2, display)),
new TestDescriptor(ColorDescriptor.createFrom(new RGB(10, 200, 54))),
new TestDescriptor(ColorDescriptor.createFrom(new RGB(10, 200, 54))),
new TestDescriptor(ColorDescriptor.createFrom(new RGB(200, 220, 54))),
new TestDescriptor(ColorDescriptor.createFrom(testColor)), // 15
new TestDescriptor(ColorDescriptor.createFrom(testColor)),
new TestDescriptor(ColorDescriptor.createFrom(testColor2)),
new TestDescriptor(ColorDescriptor.createFrom(testColor, display)),
new TestDescriptor(ColorDescriptor.createFrom(testColor, display)),
new TestDescriptor(ColorDescriptor.createFrom(testColor2, display))
};
// Let the tests know how many duplicates are in the array
numDupes = 7;
}
/* (non-Javadoc)
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
super.tearDown();
globalResourceManager.dispose();
Assert.assertEquals("Detected leaks", 0, TestDescriptor.refCount);
testImage.dispose();
testImage2.dispose();
}
protected void validateResource(Object resource) throws Exception {
Assert.assertNotNull("Allocated resource was null", resource);
if (resource instanceof Image) {
Image image = (Image) resource;
Assert.assertTrue("Image is disposed", !image.isDisposed());
return;
}
}
/**
* Tests that the descriptors themselves w
*
* @throws Exception
*/
public void testDescriptorAllocations() throws Exception {
Display display = Display.getCurrent();
// Allocate resources directly using the descriptors.
Object[] resources = new Object[descriptors.length];
for (int i = 0; i < descriptors.length; i++) {
DeviceResourceDescriptor next = descriptors[i];
Object resource = next.createResource(display);
// Ensure that this resource was allocated correctly
validateResource(resource);
resources[i] = resource;
}
// Allocating resources without the manager will not reuse duplicates, so we
// should get exactly one resource per descriptor.
Assert.assertEquals("Expecting one resource to be allocated per descriptor",
descriptors.length, TestDescriptor.refCount);
// Deallocate resources directly using the descriptors
for (int i = 0; i < descriptors.length; i++) {
DeviceResourceDescriptor next = descriptors[i];
next.destroyResource(resources[i]);
}
}
public void testDeviceManagerAllocations() throws Exception {
Display display = Display.getCurrent();
// Allocate resources directly using the descriptors.
Object[] resources = new Object[descriptors.length];
for (int i = 0; i < descriptors.length; i++) {
DeviceResourceDescriptor next = descriptors[i];
Object resource = globalResourceManager.create(next);
// Ensure that this resource was allocated correctly
validateResource(resource);
resources[i] = resource;
}
Assert.assertEquals("Descriptors created from Images should not reallocate Images when the original can be reused",
testImage, resources[9]);
// Allocating resources without the manager will reuse duplicates, so the number
// of resources should equal the number of unique descriptors.
Assert.assertEquals("Duplicate descriptors should be reused",
descriptors.length - numDupes,
TestDescriptor.refCount);
// Deallocate resources directly using the descriptors
for (int i = 0; i < descriptors.length; i++) {
DeviceResourceDescriptor next = descriptors[i];
globalResourceManager.destroy(next);
}
}
private void allocateResources(ResourceManager mgr, int[] toAllocate) throws Exception {
for (int i = 0; i < toAllocate.length; i++) {
int j = toAllocate[i];
validateResource(mgr.create(descriptors[j]));
}
}
private void deallocateResources(ResourceManager mgr, int[] toDeallocate) throws DeviceResourceException {
for (int i = 0; i < toDeallocate.length; i++) {
int j = toDeallocate[i];
mgr.destroy(descriptors[j]);
}
}
public void testLocalManagerAllocations() throws Exception {
// These arrays are indices into the descriptors array. For example, {0,1,7}
// is a quick shorthand to indicate we should allocate resources 0, 1, and 7.
int[] gResources = {0, 1, 5, 3, 7, 12, 13, 14};
int[] lm1Resources = {0, 2, 3, 4, 11, 12, 13, 15};
int[] lm2Resources = {0, 1, 6, 7, 8, 12, 14, 16};
LocalResourceManager lm1 = new LocalResourceManager(globalResourceManager);
LocalResourceManager lm2 = new LocalResourceManager(globalResourceManager);
// Allocate a bunch of global resources
allocateResources(globalResourceManager, gResources);
// Remember how many global resources were allocated
int initialCount = TestDescriptor.refCount;
// Allocate a bunch of resources in lm1
allocateResources(lm1, lm1Resources);
// Remember how many global + lm1 resources there are
int lm1Count = TestDescriptor.refCount;
// Allocate and deallocate a bunch of resources in lm2
// Ensure that all the lm2 resources were deallocated (we should be
// back down to the count we had after we allocated lm1 resources)
allocateResources(lm2, lm2Resources);
deallocateResources(lm2, lm2Resources);
Assert.assertEquals(lm1Count, TestDescriptor.refCount);
// Dispose lm2 (shouldn't do anything since we already deallocated all of its resources)
// Ensure that this doesn't change any refcounts
lm2.dispose();
Assert.assertEquals(lm1Count, TestDescriptor.refCount);
// Dispose lm1 without first deallocating its resources. This should correctly detect
// what needs to be deallocated from lm1 without affecting any global resources.
// If everything works, we should be back to the resource count we had after allocating
// the global resources.
lm1.dispose();
Assert.assertEquals(initialCount, TestDescriptor.refCount);
}
}