From 3a337c1641bcb5741511ae6d5a3779d82248e909 Mon Sep 17 00:00:00 2001 From: weisj Date: Wed, 10 Jun 2020 19:03:50 +0200 Subject: [PATCH] Migrated tests to JUnit. --- .github/disabled_workflows/font.yml | 51 ------- .github/workflows/gradle.yml | 21 +++ core/build.gradle.kts | 19 ++- .../weisj/darklaf/graphics/ImageUtil.java | 4 +- .../darklaf/ui/tooltip/DarkToolTipUI.java | 10 +- core/src/test/java/ClassFinder.java | 127 +++++++++++++++++ core/src/test/java/DemoLauncher.java | 128 +----------------- .../src/test/java/test/AbstractImageTest.java | 74 ++++++++++ core/src/test/java/{ => test}/FontTest.java | 48 +++---- core/src/test/java/test/TooltipTest.java | 60 ++++++++ dependencies-bom/build.gradle.kts | 2 + gradle.properties | 1 + 12 files changed, 328 insertions(+), 217 deletions(-) delete mode 100644 .github/disabled_workflows/font.yml create mode 100644 core/src/test/java/ClassFinder.java create mode 100644 core/src/test/java/test/AbstractImageTest.java rename core/src/test/java/{ => test}/FontTest.java (76%) create mode 100644 core/src/test/java/test/TooltipTest.java diff --git a/.github/disabled_workflows/font.yml b/.github/disabled_workflows/font.yml deleted file mode 100644 index 4b26c218..00000000 --- a/.github/disabled_workflows/font.yml +++ /dev/null @@ -1,51 +0,0 @@ -# -# MIT License -# -# Copyright (c) 2020 Jannis Weis -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. -# -# -name: Fonts - -on: - push: - branches: - - 'master' -jobs: - gradle: - strategy: - matrix: - os: [windows-latest, macos-latest, ubuntu-latest] - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v2 - with: - fetch-depth: 10 - - name: Set up JDK 11 - uses: actions/setup-java@v1 - with: - java-version: 11 - - name: Build - run: ./gradlew :darklaf-core:fontTest -PskipAutostyle - - name: Upload Results - uses: actions/upload-artifact@v1 - with: - name: ${{ matrix.os }}-font_test - path: build/font_test diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index 1d25e66b..a1dee0a5 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -45,6 +45,13 @@ jobs: java-version: 11 - name: Build run: ./gradlew build -PskipAutostyle --info + - name: Test + run: ./gradlew :darklaf-core:test -PskipAutostyle + - name: Upload Results + uses: actions/upload-artifact@v1 + with: + name: windows-test-results + path: build/test_results linux: name: Linux (Java 8) @@ -59,6 +66,13 @@ jobs: java-version: 8 - name: Build run: ./gradlew build -PskipAutostyle --info + - name: Test + run: ./gradlew :darklaf-core:test -PskipAutostyle + - name: Upload Results + uses: actions/upload-artifact@v1 + with: + name: linux-test-results + path: build/test_results macos: name: macOS (Java 11) @@ -73,3 +87,10 @@ jobs: java-version: 11 - name: Build run: ./gradlew build -PskipAutostyle --info + - name: Test + run: ./gradlew :darklaf-core:test -PskipAutostyle + - name: Upload Results + uses: actions/upload-artifact@v1 + with: + name: macOS-test-results + path: build/test_results diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 1d3c03fd..409e3679 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -17,6 +17,14 @@ dependencies { testImplementation("com.miglayout:miglayout-core") testImplementation("com.miglayout:miglayout-swing") testImplementation("org.swinglabs:swingx") + testImplementation("org.junit.jupiter:junit-jupiter-api") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine") +} + +tasks.test { + useJUnitPlatform() + workingDir = File(project.rootDir, "build/test_results") + workingDir.mkdirs() } val makeDocumentation by tasks.registering(JavaExec::class) { @@ -30,17 +38,6 @@ val makeDocumentation by tasks.registering(JavaExec::class) { classpath(sourceSets.main.get().runtimeClasspath, sourceSets.test.get().runtimeClasspath) } -val fontTest by tasks.registering(JavaExec::class) { - group = "Verification" - description = "Creates font sample images" - dependsOn(tasks.testClasses) - - workingDir = File(project.rootDir, "build") - workingDir.mkdirs() - main = "FontTest" - classpath(sourceSets.main.get().runtimeClasspath, sourceSets.test.get().runtimeClasspath) -} - abstract class DemoTask : JavaExec() { init { main = "DemoLauncher" diff --git a/core/src/main/java/com/github/weisj/darklaf/graphics/ImageUtil.java b/core/src/main/java/com/github/weisj/darklaf/graphics/ImageUtil.java index cb3fef21..2115e6b4 100644 --- a/core/src/main/java/com/github/weisj/darklaf/graphics/ImageUtil.java +++ b/core/src/main/java/com/github/weisj/darklaf/graphics/ImageUtil.java @@ -135,9 +135,9 @@ public final class ImageUtil { BufferedImage image; boolean scale = scalex != 1.0 || scaley != 1.0; if (scale) { - image = createCompatibleImage((int) (scalex * bounds.width), (int) (scaley * bounds.height)); + image = createCompatibleTranslucentImage((int) (scalex * bounds.width), (int) (scaley * bounds.height)); } else { - image = createCompatibleImage(bounds.width, bounds.height); + image = createCompatibleTranslucentImage(bounds.width, bounds.height); } final Graphics2D g2d = (Graphics2D) image.getGraphics(); if (scale) { diff --git a/core/src/main/java/com/github/weisj/darklaf/ui/tooltip/DarkToolTipUI.java b/core/src/main/java/com/github/weisj/darklaf/ui/tooltip/DarkToolTipUI.java index 770609fb..dfece6a1 100644 --- a/core/src/main/java/com/github/weisj/darklaf/ui/tooltip/DarkToolTipUI.java +++ b/core/src/main/java/com/github/weisj/darklaf/ui/tooltip/DarkToolTipUI.java @@ -125,11 +125,16 @@ public class DarkToolTipUI extends BasicToolTipUI implements PropertyChangeListe toolTip.putClientProperty(DarkPopupFactory.KEY_START_HIDDEN, true); toolTip.putClientProperty(DarkPopupFactory.KEY_FORCE_HEAVYWEIGHT, true); fadeAnimator = new FadeInAnimator(); - c.setOpaque(false); updateTipText(toolTip); updateStyle(); } + @Override + public void update(final Graphics g, final JComponent c) { + // Ensures no background is painted. + paint(g, c); + } + @Override protected void installListeners(final JComponent c) { super.installListeners(c); @@ -168,7 +173,7 @@ public class DarkToolTipUI extends BasicToolTipUI implements PropertyChangeListe startAnimation(); } else { Window window = DarkUIUtil.getWindow(c); - if (window.getOpacity() != 1 && !transparencySupported(window)) { + if (window != null && window.getOpacity() != 1 && !transparencySupported(window)) { window.setOpacity(1); } } @@ -236,7 +241,6 @@ public class DarkToolTipUI extends BasicToolTipUI implements PropertyChangeListe @Override public void hierarchyChanged(final HierarchyEvent e) { - Window w = SwingUtilities.getWindowAncestor(toolTip); if (toolTip.getParent() instanceof JComponent) { // For MediumWeightPopup still need to make parent non opaque. ((JComponent) toolTip.getParent()).setOpaque(false); diff --git a/core/src/test/java/ClassFinder.java b/core/src/test/java/ClassFinder.java new file mode 100644 index 00000000..1ea92473 --- /dev/null +++ b/core/src/test/java/ClassFinder.java @@ -0,0 +1,127 @@ +/* + * MIT License + * + * Copyright (c) 2020 Jannis Weis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +public class ClassFinder { + + public static List getInstancesOfType(final Class type, final String... packages) { + return getClasses(packages).filter(type::isAssignableFrom) + .filter(cls -> !cls.isInterface()) + .filter(cls -> !Modifier.isAbstract(cls.getModifiers())) + .map(ClassFinder::getInstance) + .filter(Objects::nonNull) + .map(type::cast) + .collect(Collectors.toList()); + } + + private static T getInstance(final Class type) { + try { + return type.getDeclaredConstructor().newInstance(); + } catch (InstantiationException + | IllegalAccessException + | InvocationTargetException + | NoSuchMethodException e) { + return null; + } + } + + private static Stream> getClasses(final String... packageNames) { + return Stream.of(packageNames).flatMap(wrap(ClassFinder::getClasses)); + } + + private static Stream> getClasses(final String packageName) throws IOException { + ClassLoader classLoader = ClassFinder.class.getClassLoader(); + String pack = packageName.replace(".", "/"); + Enumeration resources = classLoader.getResources(pack); + return enumerationAsStream(resources).map(ClassFinder::URLtoFile) + .filter(Objects::nonNull) + .map(dir -> findClasses(dir, packageName)) + .flatMap(List::stream); + } + + private static File URLtoFile(final URL url) { + try { + return new File(url.toURI()); + } catch (URISyntaxException e) { + return null; + } + } + + private static List> findClasses(final File dir, final String packageName) { + File directory = dir.getAbsoluteFile(); + List> classes = new ArrayList<>(); + File[] files = directory.listFiles(); + if (files == null) return classes; + for (File file : files) { + if (file.isDirectory()) { + assert !file.getName().contains("."); + classes.addAll(findClasses(file, packageName + "." + file.getName())); + } else if (file.getName().endsWith(".class")) { + try { + classes.add(Class.forName(packageName + '.' + + file.getName().substring(0, file.getName().length() - 6))); + } catch (ClassNotFoundException ignored) {} + } + } + return classes; + } + + public static Stream enumerationAsStream(final Enumeration e) { + return StreamSupport.stream(Spliterators.spliteratorUnknownSize(new Iterator() { + public T next() { + return e.nextElement(); + } + + public boolean hasNext() { + return e.hasMoreElements(); + } + }, Spliterator.ORDERED), false); + } + + public static Function wrap(final CheckedFunction wrappee) { + return t -> { + try { + return wrappee.apply(t); + } catch (final Throwable e) { + throw new RuntimeException(e); + } + }; + } + + public interface CheckedFunction { + + K apply(final T value) throws E; + } +} diff --git a/core/src/test/java/DemoLauncher.java b/core/src/test/java/DemoLauncher.java index bac075f6..f5280181 100644 --- a/core/src/test/java/DemoLauncher.java +++ b/core/src/test/java/DemoLauncher.java @@ -22,46 +22,14 @@ * SOFTWARE. * */ -import java.io.File; -import java.io.IOException; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Modifier; -import java.net.URISyntaxException; -import java.net.URL; import java.util.*; -import java.util.function.Function; import java.util.stream.Collectors; -import java.util.stream.Stream; -import java.util.stream.StreamSupport; import javax.swing.*; import ui.ComponentDemo; import ui.DemoPanel; -/* - * MIT License - * - * Copyright (c) 2020 Jannis Weis - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ public class DemoLauncher implements ComponentDemo { public static void main(final String[] args) { @@ -72,81 +40,12 @@ public class DemoLauncher implements ComponentDemo { public DemoLauncher() { Class demoType = ComponentDemo.class; - demoClasses = getClasses("ui", "icon", "defaults").filter(demoType::isAssignableFrom) - .filter(cls -> !cls.equals(DemoEntry.class)) - .filter(cls -> !cls.isInterface()) - .filter(cls -> !Modifier.isAbstract(cls.getModifiers())) - .map(this::getInstance) - .filter(Objects::nonNull) - .map(demoType::cast) - .map(DemoEntry::new) - .sorted(Comparator.comparing(DemoEntry::toString)) - .collect(Collectors.toList()); - - } - - private T getInstance(final Class type) { - try { - return type.getDeclaredConstructor().newInstance(); - } catch (InstantiationException - | IllegalAccessException - | InvocationTargetException - | NoSuchMethodException e) { - return null; - } - } - - private Stream> getClasses(final String... packageNames) { - return Stream.of(packageNames).flatMap(wrap(this::getClasses)); - } - - private Stream> getClasses(final String packageName) throws IOException { - ClassLoader classLoader = getClass().getClassLoader(); - String pack = packageName.replace(".", "/"); - Enumeration resources = classLoader.getResources(pack); - return enumerationAsStream(resources).map(this::URLtoFile) - .filter(Objects::nonNull) - .map(dir -> findClasses(dir, packageName)) - .flatMap(List::stream); - } - - private File URLtoFile(final URL url) { - try { - return new File(url.toURI()); - } catch (URISyntaxException e) { - return null; - } - } - - private List> findClasses(final File dir, final String packageName) { - File directory = dir.getAbsoluteFile(); - List> classes = new ArrayList<>(); - File[] files = directory.listFiles(); - if (files == null) return classes; - for (File file : files) { - if (file.isDirectory()) { - assert !file.getName().contains("."); - classes.addAll(findClasses(file, packageName + "." + file.getName())); - } else if (file.getName().endsWith(".class")) { - try { - classes.add(Class.forName(packageName + '.' - + file.getName().substring(0, file.getName().length() - 6))); - } catch (ClassNotFoundException ignored) {} - } - } - return classes; - } - - public Stream enumerationAsStream(final Enumeration e) { - return StreamSupport.stream(Spliterators.spliteratorUnknownSize(new Iterator() { - public T next() { - return e.nextElement(); - } - - public boolean hasNext() { - return e.hasMoreElements(); - } - }, Spliterator.ORDERED), false); + demoClasses = ClassFinder.getInstancesOfType(demoType, "ui", "icon", "defaults") + .stream() + .filter(obj -> !(obj instanceof DemoLauncher)) + .map(DemoEntry::new) + .sorted(Comparator.comparing(DemoEntry::toString)) + .collect(Collectors.toList()); } @Override @@ -167,16 +66,6 @@ public class DemoLauncher implements ComponentDemo { return "Demo Launcher"; } - private Function wrap(final CheckedFunction wrappee) { - return t -> { - try { - return wrappee.apply(t); - } catch (final Throwable e) { - throw new RuntimeException(e); - } - }; - } - private static class DemoEntry { private final ComponentDemo demo; @@ -194,9 +83,4 @@ public class DemoLauncher implements ComponentDemo { return demo.getClass().getSimpleName() + ".java"; } } - - private interface CheckedFunction { - - K apply(final T value) throws E; - } } diff --git a/core/src/test/java/test/AbstractImageTest.java b/core/src/test/java/test/AbstractImageTest.java new file mode 100644 index 00000000..0e0767be --- /dev/null +++ b/core/src/test/java/test/AbstractImageTest.java @@ -0,0 +1,74 @@ +/* + * MIT License + * + * Copyright (c) 2020 Jannis Weis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ +package test; + +import java.awt.*; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; + +import javax.imageio.ImageIO; +import javax.swing.*; + +import com.github.weisj.darklaf.graphics.ImageUtil; + +public abstract class AbstractImageTest { + private static final int SCALING_FACTOR = 3; + protected final static String WORKING_DIR = "image_test"; + private final String workingDir; + + public AbstractImageTest(final String dir) { + this.workingDir = dir != null ? WORKING_DIR + "/" + dir : WORKING_DIR; + } + + protected String getWorkingDirectory() { + return workingDir; + } + + protected void createFolder(final String folder) throws IOException { + Files.createDirectories(new File(getWorkingDirectory() + "/" + folder).toPath()); + } + + protected BufferedImage saveScreenShot(final String name, final JComponent c) { + return saveScreenShot(name, c, SCALING_FACTOR); + } + + protected String getPath(final String name) { + return getWorkingDirectory() + "/" + name; + } + + protected BufferedImage saveScreenShot(final String name, final JComponent c, final double scalingFactor) { + try { + Rectangle rect = new Rectangle(0, 0, c.getWidth(), c.getHeight()); + BufferedImage image = ImageUtil.scaledImageFromComponent(c, rect, scalingFactor, scalingFactor, false); + ImageIO.write(image, "png", new File(name + ".png")); + return image; + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/core/src/test/java/FontTest.java b/core/src/test/java/test/FontTest.java similarity index 76% rename from core/src/test/java/FontTest.java rename to core/src/test/java/test/FontTest.java index e9d86e98..7f46de67 100644 --- a/core/src/test/java/FontTest.java +++ b/core/src/test/java/test/FontTest.java @@ -22,39 +22,45 @@ * SOFTWARE. * */ +package test; + import java.awt.*; import java.awt.font.TextAttribute; -import java.awt.image.BufferedImage; -import java.io.File; import java.io.IOException; -import java.nio.file.Files; import java.text.AttributedCharacterIterator; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; -import javax.imageio.ImageIO; import javax.swing.*; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledOnOs; +import org.junit.jupiter.api.condition.OS; + import ui.DemoResources; import com.github.weisj.darklaf.LafManager; -import com.github.weisj.darklaf.graphics.ImageUtil; import com.github.weisj.darklaf.theme.IntelliJTheme; import com.github.weisj.darklaf.util.SystemInfo; -public class FontTest { +public class FontTest extends AbstractImageTest { private static final Map kerning; - private static final int SCALING_FACTOR = 3; - private static final String WORKING_DIR = "font_test"; static { kerning = Collections.singletonMap(TextAttribute.KERNING, TextAttribute.KERNING_ON); } - public static void main(final String[] args) throws IOException { + public FontTest() { + super("font"); + } + + @Test + @EnabledOnOs({OS.MAC, OS.WINDOWS, OS.LINUX}) + public void testFontChoices() throws IOException { LafManager.install(new IntelliJTheme()); JTextArea textArea = new JTextArea(); textArea.setText(DemoResources.KERNING_TEST); @@ -85,32 +91,18 @@ public class FontTest { } } - private static void createImages(final String folder, final JComponent c, - final List fontSpecs) throws IOException { + private void createImages(final String folder, final JComponent c, + final List fontSpecs) throws IOException { createFolder(folder); for (FontSpec spec : fontSpecs) { c.setFont(createFont(spec.fontName)); setFractionalMetrics(spec.useFractionalMetrics); - saveScreenShot(getPath(folder, spec), c); + Assertions.assertNotNull(saveScreenShot(getImagePath(folder, spec), c)); } } - private static void createFolder(final String folder) throws IOException { - Files.createDirectories(new File(WORKING_DIR + "/" + folder).toPath()); - } - - private static String getPath(final String folder, final FontSpec spec) { - return WORKING_DIR + "/" + folder + "/" + spec.getImageName(); - } - - private static void saveScreenShot(final String name, final JComponent c) { - try { - Rectangle rect = new Rectangle(0, 0, c.getWidth(), c.getHeight()); - BufferedImage image = ImageUtil.scaledImageFromComponent(c, rect, SCALING_FACTOR, SCALING_FACTOR, false); - ImageIO.write(image, "png", new File(name + ".png")); - } catch (IOException e) { - e.printStackTrace(); - } + private String getImagePath(final String folder, final FontSpec spec) { + return getPath(folder + "/" + spec.getImageName()); } private static void setFractionalMetrics(final boolean enabled) { diff --git a/core/src/test/java/test/TooltipTest.java b/core/src/test/java/test/TooltipTest.java new file mode 100644 index 00000000..301e541e --- /dev/null +++ b/core/src/test/java/test/TooltipTest.java @@ -0,0 +1,60 @@ +/* + * MIT License + * + * Copyright (c) 2020 Jannis Weis + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ +package test; + +import java.awt.*; +import java.awt.image.BufferedImage; + +import javax.swing.*; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledOnOs; +import org.junit.jupiter.api.condition.OS; + +import com.github.weisj.darklaf.LafManager; +import com.github.weisj.darklaf.ui.tooltip.ToolTipConstants; + +public class TooltipTest extends AbstractImageTest { + + public TooltipTest() { + super("tooltip"); + } + + @Test + @EnabledOnOs({OS.MAC, OS.WINDOWS}) + public void testTooltipTransparency() { + LafManager.install(); + JToolTip toolTip = new JToolTip(); + toolTip.setTipText("Test ToolTip"); + toolTip.putClientProperty(ToolTipConstants.KEY_STYLE, ToolTipConstants.VARIANT_BALLOON); + toolTip.setSize(toolTip.getPreferredSize()); + toolTip.doLayout(); + BufferedImage img = saveScreenShot(getPath("tooltip_mac"), toolTip); + Assertions.assertNotNull(img); + int alpha = new Color(img.getRGB(img.getMinX(), img.getMinY() + img.getHeight() - 1), true).getAlpha(); + Assertions.assertEquals(0, alpha); + } +} diff --git a/dependencies-bom/build.gradle.kts b/dependencies-bom/build.gradle.kts index 2e50eb22..958e4463 100644 --- a/dependencies-bom/build.gradle.kts +++ b/dependencies-bom/build.gradle.kts @@ -35,5 +35,7 @@ dependencies { apiv("com.formdev:svgSalamander") apiv("com.miglayout:miglayout-core", "miglayout") apiv("com.miglayout:miglayout-swing", "miglayout") + apiv("org.junit.jupiter:junit-jupiter-api", "junit") + apiv("org.junit.jupiter:junit-jupiter-engine", "junit") } } diff --git a/gradle.properties b/gradle.properties index b84fb636..900de2dc 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,3 +19,4 @@ jxlayer.version = 3.0.4 miglayout.version = 5.2 swingx.version = 1.6.1 svgSalamander.version = 1.1.2.1 +junit.version = 5.6.2