Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,23 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assumptions.assumeTrue;

import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;

import org.eclipse.core.runtime.Platform.OS;
import org.eclipse.jface.resource.FontDescriptor;
import org.eclipse.jface.resource.FontRegistry;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
Expand Down Expand Up @@ -122,4 +128,175 @@ private static void waitForDisplayInstantiation(AtomicReference<Display> display
}
}

@Test
public void defaultFont_isStableAcrossLookupsOfOtherNames() {
FontRegistry fontRegistry = new FontRegistry();
fontRegistry.put("myfont", new FontData[] { new FontData("Arial", 12, SWT.NORMAL) });

Font defaultFont = fontRegistry.get(JFaceResources.DEFAULT_FONT);
fontRegistry.get("myfont");
fontRegistry.get("neverRegisteredName");

assertSame(defaultFont, fontRegistry.get(JFaceResources.DEFAULT_FONT));
}

@Test
public void get_fontFromNonUIThreadFallback_doesNotOverwriteDefaultFont() throws Throwable {
FontRegistry fontRegistry = new FontRegistry();
fontRegistry.put("myfont", new FontData[] { new FontData("Arial", 12, SWT.NORMAL) });
Font defaultFont = fontRegistry.get(JFaceResources.DEFAULT_FONT);

AtomicReference<Font> fontFromNonUIThread = new AtomicReference<>();
AtomicReference<Throwable> failureFromNonUIThread = new AtomicReference<>();
Thread nonUiThread = new Thread(() -> {
try {
fontFromNonUIThread.set(fontRegistry.get("myfont"));
} catch (Throwable t) {
failureFromNonUIThread.set(t);
}
});
nonUiThread.start();
nonUiThread.join();

if (failureFromNonUIThread.get() != null) {
throw failureFromNonUIThread.get();
}
assertSame(defaultFont, fontFromNonUIThread.get());
assertSame(defaultFont, fontRegistry.get(JFaceResources.DEFAULT_FONT));
}

@Test
public void get_returnsSameFontInstanceOnRepeatedCalls() {
FontRegistry fontRegistry = new FontRegistry();
fontRegistry.put("myfont", new FontData[] { new FontData("Arial", 12, SWT.NORMAL) });

Font first = fontRegistry.get("myfont");
Font second = fontRegistry.get("myfont");

assertSame(first, second);
}

@Test
public void get_forNameThatWasNeverRegistered_returnsDefaultFontAndIsStableAfterwards() {
FontRegistry fontRegistry = new FontRegistry();

Font first = fontRegistry.get("neverRegisteredName");
Font second = fontRegistry.get("neverRegisteredName");

assertSame(fontRegistry.get(JFaceResources.DEFAULT_FONT), first);
assertSame(first, second);
}

@Test
public void getBoldAndGetItalic_returnSameInstanceOnRepeatedCalls() {
FontRegistry fontRegistry = new FontRegistry();
fontRegistry.put("myfont", new FontData[] { new FontData("Arial", 12, SWT.NORMAL) });

assertSame(fontRegistry.getBold("myfont"), fontRegistry.getBold("myfont"));
assertSame(fontRegistry.getItalic("myfont"), fontRegistry.getItalic("myfont"));
}

@Test
public void put_firesPropertyChangeOnlyWhenDataActuallyChanges() {
FontRegistry fontRegistry = new FontRegistry();
List<PropertyChangeEvent> events = new ArrayList<>();
fontRegistry.addListener(events::add);

fontRegistry.put("myfont", new FontData[] { new FontData("Arial", 12, SWT.NORMAL) });
assertEquals(1, events.size());
assertEquals("myfont", events.get(0).getProperty());

// re-putting the same data must not fire a change
fontRegistry.put("myfont", new FontData[] { new FontData("Arial", 12, SWT.NORMAL) });
assertEquals(1, events.size());

fontRegistry.put("myfont", new FontData[] { new FontData("Arial", 18, SWT.NORMAL) });
assertEquals(2, events.size());
}

@Test
public void put_withNewData_disposesOldFontOnlyOnDisplayDispose() {
assumeTrue(OS.isWindows(), "multiple Display instance only allowed on Windows");

FontRegistry fontRegistry = new FontRegistry();
Display secondDisplay = initializeDisplayInSeparateThread();
try {
Font original = secondDisplay.syncCall(() -> {
fontRegistry.put("myfont", new FontData[] { new FontData("Arial", 12, SWT.NORMAL) });
return fontRegistry.get("myfont");
});

secondDisplay
.syncExec(() -> fontRegistry.put("myfont", new FontData[] { new FontData("Arial", 18, SWT.BOLD) }));
// the font may still be in use elsewhere, so it must not be disposed right away
assertFalse(original.isDisposed(), "previous font must stay usable until its display is disposed");

secondDisplay.syncExec(secondDisplay::dispose);
assertTrue(original.isDisposed(), "stale font must be disposed once its display is disposed");
} finally {
if (!secondDisplay.isDisposed()) {
secondDisplay.syncExec(secondDisplay::dispose);
}
}
}

@Test
public void put_withNewData_invalidatesCachedBoldAndItalicFonts() {
FontRegistry fontRegistry = new FontRegistry();
fontRegistry.put("myfont", new FontData[] { new FontData("Arial", 12, SWT.NORMAL) });
Font originalBold = fontRegistry.getBold("myfont");
Font originalItalic = fontRegistry.getItalic("myfont");

fontRegistry.put("myfont", new FontData[] { new FontData("Arial", 18, SWT.NORMAL) });

Font updatedBold = fontRegistry.getBold("myfont");
Font updatedItalic = fontRegistry.getItalic("myfont");

assertNotEquals(originalBold, updatedBold);
assertNotEquals(originalItalic, updatedItalic);
assertEquals(18, updatedBold.getFontData()[0].getHeight());
assertEquals(18, updatedItalic.getFontData()[0].getHeight());
}

@Test
public void put_withNewData_invalidatesPreviouslyCachedFont() {
FontRegistry fontRegistry = new FontRegistry();
fontRegistry.put("myfont", new FontData[] { new FontData("Arial", 12, SWT.NORMAL) });
Font original = fontRegistry.get("myfont");

fontRegistry.put("myfont", new FontData[] { new FontData("Arial", 18, SWT.BOLD) });
Font updated = fontRegistry.get("myfont");

assertNotEquals(original, updated);
assertEquals(18, updated.getFontData()[0].getHeight());
}

@Test
public void hasValueForAndGetKeySet_reflectOnlyRegisteredNames() {
FontRegistry fontRegistry = new FontRegistry();
assertFalse(fontRegistry.hasValueFor("myfont"));
assertFalse(fontRegistry.getKeySet().contains("myfont"));

fontRegistry.put("myfont", new FontData[] { new FontData("Arial", 12, SWT.NORMAL) });
assertTrue(fontRegistry.hasValueFor("myfont"));
assertTrue(fontRegistry.getKeySet().contains("myfont"));

// falling back to the default for an unregistered name must not register it
fontRegistry.get("neverRegisteredName");
assertFalse(fontRegistry.hasValueFor("neverRegisteredName"));
assertFalse(fontRegistry.getKeySet().contains("neverRegisteredName"));
}

@Test
public void getFontDataAndGetDescriptor_fallBackToDefaultForUnregisteredName() {
FontRegistry fontRegistry = new FontRegistry();

assertArrayEquals(fontRegistry.getFontData(JFaceResources.DEFAULT_FONT),
fontRegistry.getFontData("neverRegisteredName"));

FontDescriptor defaultDescriptor = fontRegistry.getDescriptor(JFaceResources.DEFAULT_FONT);
FontDescriptor fallbackDescriptor = fontRegistry.getDescriptor("neverRegisteredName");
assertEquals(defaultDescriptor, fallbackDescriptor);
}

}
Loading