Author: centic
Date: Thu Mar 14 13:20:47 2024
New Revision: 1916297

URL: http://svn.apache.org/viewvc?rev=1916297&view=rev
Log:
Bug 68778: Verify "ignoreMissingFontSystem" for 
SheetUtil.getDefaultCharWidthAsFloat()

This functionality saw some regressions at times and thus
should be verified via unit-tests. 

We can simulate failures in the low-level font-system by 
mocking the FontRenderContext and triggering exceptions
from there.

This hopefully now verifies behavior of 
SheetUtil.getDefaultCharWidthAsFloat() both with 
"ignoreMissingFontSystem" enabled and disabled.

Modified:
    poi/trunk/poi/src/main/java/org/apache/poi/ss/util/SheetUtil.java
    poi/trunk/poi/src/test/java/org/apache/poi/ss/util/TestSheetUtil.java

Modified: poi/trunk/poi/src/main/java/org/apache/poi/ss/util/SheetUtil.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/poi/src/main/java/org/apache/poi/ss/util/SheetUtil.java?rev=1916297&r1=1916296&r2=1916297&view=diff
==============================================================================
--- poi/trunk/poi/src/main/java/org/apache/poi/ss/util/SheetUtil.java (original)
+++ poi/trunk/poi/src/main/java/org/apache/poi/ss/util/SheetUtil.java Thu Mar 
14 13:20:47 2024
@@ -96,13 +96,13 @@ public class SheetUtil {
     /**
      * drawing context to measure text
      */
-    private static final FontRenderContext fontRenderContext = new 
FontRenderContext(null, true, true);
+    private static FontRenderContext fontRenderContext = new 
FontRenderContext(null, true, true);
 
     /**
      * A system property which can be enabled to not fail when the
      * font-system is not available on the current machine
      */
-    private static final boolean ignoreMissingFontSystem =
+    private static boolean ignoreMissingFontSystem =
             
Boolean.parseBoolean(System.getProperty("org.apache.poi.ss.ignoreMissingFontSystem"));
 
     /**
@@ -490,4 +490,21 @@ public class SheetUtil {
         //  live within any merged regions
         return null;
     }
+
+    // Getters/Setters are available to allow in-depth testing
+    protected static boolean isIgnoreMissingFontSystem() {
+        return ignoreMissingFontSystem;
+    }
+
+    protected static void setIgnoreMissingFontSystem(boolean value) {
+        ignoreMissingFontSystem = value;
+    }
+
+    protected static FontRenderContext getFontRenderContext() {
+        return fontRenderContext;
+    }
+
+    protected static void setFontRenderContext(FontRenderContext 
fontRenderContext) {
+        SheetUtil.fontRenderContext = fontRenderContext;
+    }
 }

Modified: poi/trunk/poi/src/test/java/org/apache/poi/ss/util/TestSheetUtil.java
URL: 
http://svn.apache.org/viewvc/poi/trunk/poi/src/test/java/org/apache/poi/ss/util/TestSheetUtil.java?rev=1916297&r1=1916296&r2=1916297&view=diff
==============================================================================
--- poi/trunk/poi/src/test/java/org/apache/poi/ss/util/TestSheetUtil.java 
(original)
+++ poi/trunk/poi/src/test/java/org/apache/poi/ss/util/TestSheetUtil.java Thu 
Mar 14 13:20:47 2024
@@ -19,10 +19,14 @@ package org.apache.poi.ss.util;
 
 import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
 
+import java.awt.font.FontRenderContext;
 import java.io.IOException;
 
 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
@@ -31,13 +35,16 @@ import org.apache.poi.ss.usermodel.CellT
 import org.apache.poi.ss.usermodel.Row;
 import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.util.ExceptionUtil;
 import org.junit.jupiter.api.Test;
+import org.mockito.stubbing.Answer;
 
 /**
  * Tests SheetUtil.
  *
  * @see org.apache.poi.ss.util.SheetUtil
  */
+@SuppressWarnings("deprecation")
 final class TestSheetUtil {
     @Test
     void testCellWithMerges() throws Exception {
@@ -220,4 +227,163 @@ final class TestSheetUtil {
             assertEquals(-1.0, SheetUtil.getColumnWidth(sheet, 0, true, 1, 2), 
0.01, "Not having any width for rows with all empty cells");
         }
     }
+
+    @Test
+    void testIsFatal() {
+        assertFalse(ExceptionUtil.isFatal(new RuntimeException()),
+                "RuntimeException should not be regarded as 'fatal'");
+        assertTrue(ExceptionUtil.isFatal(new LinkageError()),
+                "LinkageError should not be regarded as 'fatal'");
+        assertTrue(ExceptionUtil.isFatal(new UnsatisfiedLinkError()),
+                "UnsatisfiedLinkError should not be regarded as 'fatal'");
+    }
+
+    @Test
+    void testGetCharWidthWithFonts() throws IOException {
+        // verify that normal call returns a useful value
+        // (may fail if font-system is missing, but then many other tests fail 
as well)
+
+        try (Workbook wb = new HSSFWorkbook()) {
+            final float width = SheetUtil.getDefaultCharWidthAsFloat(wb);
+            assertTrue(width > 0,
+                    "Should get some useful char width, but had: " + width);
+        }
+    }
+
+    @Test
+    void testGetCharWidthWithInvalidFont() throws IOException {
+        // verify that a call with an unknown font-name returns a useful value
+        // (likely the font-system falls back to a default font here)
+        // (may fail if font-system is missing, but then many other tests fail 
as well)
+
+        try (Workbook wb = new HSSFWorkbook()) {
+            wb.getFontAt(0).setFontName("invalid font");
+
+            final float width = SheetUtil.getDefaultCharWidthAsFloat(wb);
+            assertTrue(width > 0,
+                    "Should get some useful char width, but had: " + width);
+        }
+    }
+
+    @Test
+    void testGetCharWidthWithIgnoreEnabled() throws IOException {
+        boolean previous = SheetUtil.isIgnoreMissingFontSystem();
+        SheetUtil.setIgnoreMissingFontSystem(true);
+
+        // just verify that enabling the setting "ignoreMissingFontSystem"
+        // does not cause unexpected results
+
+        try (Workbook wb = new HSSFWorkbook()) {
+            final float width = SheetUtil.getDefaultCharWidthAsFloat(wb);
+            assertTrue(width > 0,
+                    "Should get some useful char width, but had: " + width);
+        } finally {
+            // restore value
+            SheetUtil.setIgnoreMissingFontSystem(previous);
+        }
+    }
+
+    @Test
+    void testGetCharWidthWithMockedException() throws IOException {
+        FontRenderContext prevCtx = SheetUtil.getFontRenderContext();
+        final FontRenderContext ctx = mock(FontRenderContext.class, 
(Answer<Object>) invocation -> {
+            // simulate an exception in some of the calls to java.awt packages
+            throw new IllegalArgumentException("Test runtime exception");
+        });
+        SheetUtil.setFontRenderContext(ctx);
+
+        boolean previous = SheetUtil.isIgnoreMissingFontSystem();
+        SheetUtil.setIgnoreMissingFontSystem(false);
+
+        // verify that a RuntimeException in the font-system is
+        // thrown when "ignoreMissingFontSystem" is disabled
+
+        try (Workbook wb = new HSSFWorkbook()) {
+            assertThrows(IllegalArgumentException.class,
+                    () -> SheetUtil.getDefaultCharWidthAsFloat(wb),
+                    "Should get an exception because ignoreMissingFontSystem = 
false");
+        } finally {
+            // restore values
+            SheetUtil.setFontRenderContext(prevCtx);
+            SheetUtil.setIgnoreMissingFontSystem(previous);
+        }
+    }
+
+    @Test
+    void testGetCharWidthWithMockedUnsatisfiedLinkError() throws IOException {
+        FontRenderContext prevCtx = SheetUtil.getFontRenderContext();
+        final FontRenderContext ctx = mock(FontRenderContext.class, 
(Answer<Object>) invocation -> {
+            // simulate an exception in some of the calls to java.awt packages
+            throw new UnsatisfiedLinkError("Test runtime exception");
+        });
+        SheetUtil.setFontRenderContext(ctx);
+
+        boolean previous = SheetUtil.isIgnoreMissingFontSystem();
+        SheetUtil.setIgnoreMissingFontSystem(false);
+
+        // verify that a UnsatisfiedLinkError in the font-system is
+        // thrown when "ignoreMissingFontSystem" is disabled
+
+        try (Workbook wb = new HSSFWorkbook()) {
+            assertThrows(UnsatisfiedLinkError.class,
+                    () -> SheetUtil.getDefaultCharWidthAsFloat(wb),
+                    "Should get an exception because ignoreMissingFontSystem = 
false");
+        } finally {
+            // restore values
+            SheetUtil.setFontRenderContext(prevCtx);
+            SheetUtil.setIgnoreMissingFontSystem(previous);
+        }
+    }
+
+    @Test
+    void testGetCharWidthWithMockedExceptionAndIgnore() throws IOException {
+        FontRenderContext prevCtx = SheetUtil.getFontRenderContext();
+        final FontRenderContext ctx = mock(FontRenderContext.class, 
(Answer<Object>) invocation -> {
+            // simulate an exception in some of the calls to java.awt packages
+            throw new IllegalArgumentException("Test runtime exception");
+        });
+        SheetUtil.setFontRenderContext(ctx);
+
+        boolean previous = SheetUtil.isIgnoreMissingFontSystem();
+        SheetUtil.setIgnoreMissingFontSystem(true);
+
+        // verify that a RuntimeException in the font-system is
+        // ignored when "ignoreMissingFontSystem" is enabled
+
+        try (Workbook wb = new HSSFWorkbook()) {
+            final float width = SheetUtil.getDefaultCharWidthAsFloat(wb);
+            assertEquals(SheetUtil.DEFAULT_CHAR_WIDTH, width,
+                    "Should get default char width because 
ignoreMissingFontSystem = true, but had: " + width);
+        } finally {
+            // restore values
+            SheetUtil.setFontRenderContext(prevCtx);
+            SheetUtil.setIgnoreMissingFontSystem(previous);
+        }
+    }
+
+    @Test
+    void testGetCharWidthWithMockedUnsatisfiedLinkErrorAndIgnore() throws 
IOException {
+        FontRenderContext prevCtx = SheetUtil.getFontRenderContext();
+        final FontRenderContext ctx = mock(FontRenderContext.class, 
(Answer<Object>) invocation -> {
+            // simulate an exception in some of the calls to java.awt packages
+            throw new UnsatisfiedLinkError("Test runtime exception");
+        });
+        SheetUtil.setFontRenderContext(ctx);
+
+        boolean previous = SheetUtil.isIgnoreMissingFontSystem();
+        SheetUtil.setIgnoreMissingFontSystem(true);
+
+        // verify that a UnsatisfiedLinkError in the font-system is
+        // ignored when "ignoreMissingFontSystem" is enabled
+
+        try (Workbook wb = new HSSFWorkbook()) {
+            final float width = SheetUtil.getDefaultCharWidthAsFloat(wb);
+            assertEquals(SheetUtil.DEFAULT_CHAR_WIDTH, width,
+                    "Should get default char width because 
ignoreMissingFontSystem = true, but had: " + width);
+        } finally {
+            // restore values
+            SheetUtil.setFontRenderContext(prevCtx);
+            SheetUtil.setIgnoreMissingFontSystem(previous);
+        }
+    }
 }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@poi.apache.org
For additional commands, e-mail: commits-h...@poi.apache.org

Reply via email to